11 #include "clang/AST/ASTContext.h" 12 #include "clang/AST/Decl.h" 13 #include "clang/AST/DeclTemplate.h" 14 #include "clang/AST/TemplateBase.h" 15 #include "clang/Basic/SourceLocation.h" 16 #include "clang/Basic/SourceManager.h" 17 #include "clang/Index/USRGeneration.h" 18 #include "llvm/ADT/Optional.h" 19 #include "llvm/Support/Casting.h" 20 #include "llvm/Support/ScopedPrinter.h" 21 #include "llvm/Support/raw_ostream.h" 27 llvm::Optional<llvm::ArrayRef<TemplateArgumentLoc>>
28 getTemplateSpecializationArgLocs(
const NamedDecl &ND) {
29 if (
auto *Func = llvm::dyn_cast<FunctionDecl>(&ND)) {
30 if (
const ASTTemplateArgumentListInfo *Args =
31 Func->getTemplateSpecializationArgsAsWritten())
32 return Args->arguments();
33 }
else if (
auto *Cls =
34 llvm::dyn_cast<ClassTemplatePartialSpecializationDecl>(&ND)) {
35 if (
auto *Args = Cls->getTemplateArgsAsWritten())
36 return Args->arguments();
37 }
else if (
auto *Var = llvm::dyn_cast<VarTemplateSpecializationDecl>(&ND))
38 return Var->getTemplateArgsInfo().arguments();
52 const auto &SM = D->getASTContext().getSourceManager();
53 auto Loc = D->getLocation();
56 if (
Loc.isMacroID()) {
57 std::string PrintLoc = SM.getSpellingLoc(
Loc).printToString(SM);
58 if (llvm::StringRef(PrintLoc).startswith(
"<scratch") ||
59 llvm::StringRef(PrintLoc).startswith(
"<command line>"))
68 const auto &SM = D->getASTContext().getSourceManager();
71 return SM.getExpansionRange(D->getLocation()).getBegin();
72 return SM.getSpellingLoc(D->getLocation());
77 llvm::raw_string_ostream OS(QName);
78 PrintingPolicy Policy(ND.getASTContext().getLangOpts());
83 Policy.SuppressUnwrittenScope =
true;
84 ND.printQualifiedName(OS, Policy);
86 assert(!StringRef(QName).startswith(
"::"));
90 std::string
printName(
const ASTContext &
Ctx,
const NamedDecl &ND) {
92 llvm::raw_string_ostream Out(Name);
93 PrintingPolicy PP(Ctx.getLangOpts());
95 if (
auto *UD = llvm::dyn_cast<UsingDirectiveDecl>(&ND)) {
96 Out <<
"using namespace ";
97 if (
auto *Qual = UD->getQualifier())
99 UD->getNominatedNamespaceAsWritten()->printName(Out);
102 ND.getDeclName().print(Out, PP);
103 if (!Out.str().empty()) {
108 if (isa<NamespaceDecl>(ND))
109 return "(anonymous namespace)";
110 if (
auto *Cls = llvm::dyn_cast<RecordDecl>(&ND))
111 return (
"(anonymous " + Cls->getKindName() +
")").str();
112 if (isa<EnumDecl>(ND))
113 return "(anonymous enum)";
114 return "(anonymous)";
118 std::string TemplateArgs;
119 llvm::raw_string_ostream OS(TemplateArgs);
120 PrintingPolicy Policy(ND.getASTContext().getLangOpts());
121 if (llvm::Optional<llvm::ArrayRef<TemplateArgumentLoc>> Args =
122 getTemplateSpecializationArgLocs(ND)) {
123 printTemplateArgumentList(OS, *Args, Policy);
124 }
else if (
auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) {
125 if (
const TypeSourceInfo *TSI = Cls->getTypeAsWritten()) {
129 auto STL = TSI->getTypeLoc().getAs<TemplateSpecializationTypeLoc>();
130 llvm::SmallVector<TemplateArgumentLoc, 8> ArgLocs;
131 ArgLocs.reserve(STL.getNumArgs());
132 for (
unsigned I = 0; I < STL.getNumArgs(); ++I)
133 ArgLocs.push_back(STL.getArgLoc(I));
134 printTemplateArgumentList(OS, ArgLocs, Policy);
139 printTemplateArgumentList(OS, Cls->getTemplateArgs().asArray(), Policy);
147 for (
const auto *
Ctx = &DC;
Ctx !=
nullptr;
Ctx =
Ctx->getParent())
148 if (
const auto *NS = dyn_cast<NamespaceDecl>(
Ctx))
149 if (!NS->isAnonymousNamespace() && !NS->isInlineNamespace())
155 llvm::SmallString<128> USR;
156 if (index::generateUSRForDecl(D, USR))
163 const SourceManager &SM) {
166 llvm::SmallString<128> USR;
167 if (index::generateUSRForMacro(II.getName(), MI->getDefinitionLoc(), SM, USR))
173 const llvm::StringRef CurrentNamespace) {
174 llvm::SmallVector<llvm::StringRef, 8> OriginalParts;
175 llvm::SmallVector<llvm::StringRef, 8> CurrentParts;
176 llvm::SmallVector<llvm::StringRef, 8>
Result;
177 OriginalName.split(OriginalParts,
"::");
178 CurrentNamespace.split(CurrentParts,
"::");
179 auto MinLength = std::min(CurrentParts.size(), OriginalParts.size());
181 unsigned DifferentAt = 0;
182 while (DifferentAt < MinLength &&
183 CurrentParts[DifferentAt] == OriginalParts[DifferentAt]) {
187 for (
unsigned i = DifferentAt; i < OriginalParts.size(); ++i) {
188 Result.push_back(OriginalParts[i]);
190 return join(Result,
"::");
194 PrintingPolicy PP(Context.getParentASTContext().getPrintingPolicy());
195 PP.SuppressTagKeyword = 1;
SourceLocation Loc
'#' location in the include directive
std::string printName(const ASTContext &Ctx, const NamedDecl &ND)
Prints unqualified name of the decl for the purpose of displaying it to the user. ...
std::string printType(const QualType QT, const DeclContext &Context)
Returns a QualType as string.
std::string printQualifiedName(const NamedDecl &ND)
Returns the qualified name of ND.
llvm::Optional< SymbolID > getSymbolID(const Decl *D)
Gets the symbol ID for a declaration, if possible.
std::string printNamespaceScope(const DeclContext &DC)
Returns the first enclosing namespace scope starting from DC.
SourceLocation findNameLoc(const clang::Decl *D)
Find the identifier source location of the given D.
Documents should not be synced at all.
std::string printTemplateSpecializationArgs(const NamedDecl &ND)
Prints template arguments of a decl as written in the source code, including enclosing '<' and '>'...
bool isSpelledInSourceCode(const Decl *D)
static constexpr llvm::StringLiteral Name
A context is an immutable container for per-request data that must be propagated through layers that ...
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
bool isImplementationDetail(const Decl *D)
Returns true if the declaration is considered implementation detail based on heuristics.
static std::string join(ArrayRef< SpecialMemberFunctionsCheck::SpecialMemberFunctionKind > SMFS, llvm::StringRef AndOr)
std::string shortenNamespace(const llvm::StringRef OriginalName, const llvm::StringRef CurrentNamespace)
Try to shorten the OriginalName by removing namespaces from the left of the string that are redundant...
std::array< uint8_t, 20 > SymbolID