diff options
author | Kristóf Umann <dkszelethus@gmail.com> | 2021-11-10 15:03:06 +0100 |
---|---|---|
committer | Kristóf Umann <dkszelethus@gmail.com> | 2022-01-24 16:37:11 +0100 |
commit | 3ad35ba4dea5240dd58476f0c85f0fe096d6c7ce (patch) | |
tree | 305497eb39abd8620e53988cb26fa4c07721e628 /clang/lib/Frontend/FrontendActions.cpp | |
parent | 4d53f88d1a18e288362e1077ae09c98c843593ba (diff) | |
download | llvm-3ad35ba4dea5240dd58476f0c85f0fe096d6c7ce.zip llvm-3ad35ba4dea5240dd58476f0c85f0fe096d6c7ce.tar.gz llvm-3ad35ba4dea5240dd58476f0c85f0fe096d6c7ce.tar.bz2 |
[Templight] Don't display empty strings for names of unnamed template parameters
Patch originally by oktal3000: https://github.com/mikael-s-persson/templight/pull/40
When a template parameter is unnamed, the name of -templight-dump might return
an empty string. This is fine, they are unnamed after all, but it might be more
user friendly to at least describe what entity is unnamed.
Differential Revision: https://reviews.llvm.org/D115521
Diffstat (limited to 'clang/lib/Frontend/FrontendActions.cpp')
-rw-r--r-- | clang/lib/Frontend/FrontendActions.cpp | 95 |
1 files changed, 82 insertions, 13 deletions
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 5b77c3e..ad2e603 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -8,9 +8,10 @@ #include "clang/Frontend/FrontendActions.h" #include "clang/AST/ASTConsumer.h" +#include "clang/AST/Decl.h" #include "clang/Basic/FileManager.h" -#include "clang/Basic/TargetInfo.h" #include "clang/Basic/LangStandard.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Frontend/ASTConsumers.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendDiagnostic.h" @@ -23,6 +24,7 @@ #include "clang/Sema/TemplateInstCallback.h" #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/ASTWriter.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" @@ -480,25 +482,92 @@ private: Out << "---" << YAML << "\n"; } + static void printEntryName(const Sema &TheSema, const Decl *Entity, + llvm::raw_string_ostream &OS) { + auto *NamedTemplate = cast<NamedDecl>(Entity); + + PrintingPolicy Policy = TheSema.Context.getPrintingPolicy(); + // FIXME: Also ask for FullyQualifiedNames? + Policy.SuppressDefaultTemplateArgs = false; + NamedTemplate->getNameForDiagnostic(OS, Policy, true); + + if (!OS.str().empty()) + return; + + Decl *Ctx = Decl::castFromDeclContext(NamedTemplate->getDeclContext()); + NamedDecl *NamedCtx = dyn_cast_or_null<NamedDecl>(Ctx); + + if (const auto *Decl = dyn_cast<TagDecl>(NamedTemplate)) { + if (const auto *R = dyn_cast<RecordDecl>(Decl)) { + if (R->isLambda()) { + OS << "lambda at "; + Decl->getLocation().print(OS, TheSema.getSourceManager()); + return; + } + } + OS << "unnamed " << Decl->getKindName(); + return; + } + + if (const auto *Decl = dyn_cast<ParmVarDecl>(NamedTemplate)) { + OS << "unnamed function parameter " << Decl->getFunctionScopeIndex() + << " "; + if (Decl->getFunctionScopeDepth() > 0) + OS << "(at depth " << Decl->getFunctionScopeDepth() << ") "; + OS << "of "; + NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true); + return; + } + + if (const auto *Decl = dyn_cast<TemplateTypeParmDecl>(NamedTemplate)) { + if (const Type *Ty = Decl->getTypeForDecl()) { + if (const auto *TTPT = dyn_cast_or_null<TemplateTypeParmType>(Ty)) { + OS << "unnamed template type parameter " << TTPT->getIndex() << " "; + if (TTPT->getDepth() > 0) + OS << "(at depth " << TTPT->getDepth() << ") "; + OS << "of "; + NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true); + return; + } + } + } + + if (const auto *Decl = dyn_cast<NonTypeTemplateParmDecl>(NamedTemplate)) { + OS << "unnamed template non-type parameter " << Decl->getIndex() << " "; + if (Decl->getDepth() > 0) + OS << "(at depth " << Decl->getDepth() << ") "; + OS << "of "; + NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true); + return; + } + + if (const auto *Decl = dyn_cast<TemplateTemplateParmDecl>(NamedTemplate)) { + OS << "unnamed template template parameter " << Decl->getIndex() << " "; + if (Decl->getDepth() > 0) + OS << "(at depth " << Decl->getDepth() << ") "; + OS << "of "; + NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true); + return; + } + + llvm_unreachable("Failed to retrieve a name for this entry!"); + OS << "unnamed identifier"; + } + template <bool BeginInstantiation> static TemplightEntry getTemplightEntry(const Sema &TheSema, const CodeSynthesisContext &Inst) { TemplightEntry Entry; Entry.Kind = toString(Inst.Kind); Entry.Event = BeginInstantiation ? "Begin" : "End"; - if (auto *NamedTemplate = dyn_cast_or_null<NamedDecl>(Inst.Entity)) { - llvm::raw_string_ostream OS(Entry.Name); - PrintingPolicy Policy = TheSema.Context.getPrintingPolicy(); - // FIXME: Also ask for FullyQualifiedNames? - Policy.SuppressDefaultTemplateArgs = false; - NamedTemplate->getNameForDiagnostic(OS, Policy, true); - const PresumedLoc DefLoc = + llvm::raw_string_ostream OS(Entry.Name); + printEntryName(TheSema, Inst.Entity, OS); + const PresumedLoc DefLoc = TheSema.getSourceManager().getPresumedLoc(Inst.Entity->getLocation()); - if(!DefLoc.isInvalid()) - Entry.DefinitionLocation = std::string(DefLoc.getFilename()) + ":" + - std::to_string(DefLoc.getLine()) + ":" + - std::to_string(DefLoc.getColumn()); - } + if (!DefLoc.isInvalid()) + Entry.DefinitionLocation = std::string(DefLoc.getFilename()) + ":" + + std::to_string(DefLoc.getLine()) + ":" + + std::to_string(DefLoc.getColumn()); const PresumedLoc PoiLoc = TheSema.getSourceManager().getPresumedLoc(Inst.PointOfInstantiation); if (!PoiLoc.isInvalid()) { |