13 #include "clang/AST/ASTContext.h"
14 #include "clang/AST/ASTTypeTraits.h"
15 #include "clang/AST/Decl.h"
16 #include "clang/AST/DeclBase.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/DeclTemplate.h"
19 #include "clang/AST/DeclarationName.h"
20 #include "clang/AST/NestedNameSpecifier.h"
21 #include "clang/AST/PrettyPrinter.h"
22 #include "clang/AST/RecursiveASTVisitor.h"
23 #include "clang/AST/TemplateBase.h"
24 #include "clang/Basic/SourceLocation.h"
25 #include "clang/Basic/SourceManager.h"
26 #include "clang/Basic/Specifiers.h"
27 #include "clang/Index/USRGeneration.h"
28 #include "llvm/ADT/ArrayRef.h"
29 #include "llvm/ADT/Optional.h"
30 #include "llvm/ADT/STLExtras.h"
31 #include "llvm/ADT/StringRef.h"
32 #include "llvm/Support/Casting.h"
33 #include "llvm/Support/ScopedPrinter.h"
34 #include "llvm/Support/raw_ostream.h"
42 llvm::Optional<llvm::ArrayRef<TemplateArgumentLoc>>
43 getTemplateSpecializationArgLocs(
const NamedDecl &ND) {
44 if (
auto *Func = llvm::dyn_cast<FunctionDecl>(&ND)) {
45 if (
const ASTTemplateArgumentListInfo *Args =
46 Func->getTemplateSpecializationArgsAsWritten())
47 return Args->arguments();
48 }
else if (
auto *Cls =
49 llvm::dyn_cast<ClassTemplatePartialSpecializationDecl>(&ND)) {
50 if (
auto *Args = Cls->getTemplateArgsAsWritten())
51 return Args->arguments();
52 }
else if (
auto *Var =
53 llvm::dyn_cast<VarTemplatePartialSpecializationDecl>(&ND)) {
54 if (
auto *Args = Var->getTemplateArgsAsWritten())
55 return Args->arguments();
56 }
else if (
auto *Var = llvm::dyn_cast<VarTemplateSpecializationDecl>(&ND))
57 return Var->getTemplateArgsInfo().arguments();
64 bool isTemplateSpecializationKind(
const NamedDecl *D,
65 TemplateSpecializationKind
Kind) {
66 if (
const auto *TD = dyn_cast<T>(D))
67 return TD->getTemplateSpecializationKind() ==
Kind;
71 bool isTemplateSpecializationKind(
const NamedDecl *D,
72 TemplateSpecializationKind
Kind) {
73 return isTemplateSpecializationKind<FunctionDecl>(D,
Kind) ||
74 isTemplateSpecializationKind<CXXRecordDecl>(D,
Kind) ||
75 isTemplateSpecializationKind<VarDecl>(D,
Kind);
80 llvm::DenseSet<const NamespaceDecl *>
81 getUsingNamespaceDirectives(
const DeclContext *DestContext,
82 SourceLocation Until) {
83 const auto &SM = DestContext->getParentASTContext().getSourceManager();
84 llvm::DenseSet<const NamespaceDecl *> VisibleNamespaceDecls;
85 for (
const auto *DC = DestContext; DC; DC = DC->getLookupParent()) {
86 for (
const auto *D : DC->decls()) {
87 if (!SM.isWrittenInSameFile(D->getLocation(), Until) ||
88 !SM.isBeforeInTranslationUnit(D->getLocation(), Until))
90 if (
auto *UDD = llvm::dyn_cast<UsingDirectiveDecl>(D))
91 VisibleNamespaceDecls.insert(
92 UDD->getNominatedNamespace()->getCanonicalDecl());
95 return VisibleNamespaceDecls;
105 const DeclContext *SourceContext,
106 llvm::function_ref<
bool(NestedNameSpecifier *)> IsVisible) {
107 std::vector<const NestedNameSpecifier *>
Parents;
108 bool ReachedNS =
false;
109 for (
const DeclContext *CurContext = SourceContext; CurContext;
110 CurContext = CurContext->getLookupParent()) {
112 if (CurContext->Encloses(DestContext))
115 NestedNameSpecifier *NNS =
nullptr;
116 if (
auto *TD = llvm::dyn_cast<TagDecl>(CurContext)) {
119 NNS = NestedNameSpecifier::Create(
Context,
nullptr,
false,
120 TD->getTypeForDecl());
123 auto *NSD = llvm::cast<NamespaceDecl>(CurContext);
124 NNS = NestedNameSpecifier::Create(
Context,
nullptr, NSD);
127 if (NSD->isAnonymousNamespace() || NSD->isInlineNamespace())
140 llvm::raw_string_ostream
OS(Result);
149 return isTemplateSpecializationKind(D, TSK_ImplicitInstantiation);
153 return isTemplateSpecializationKind(D, TSK_ExplicitSpecialization);
158 D->getASTContext().getSourceManager());
162 auto L = D.getLocation();
164 return SM.getSpellingLoc(L);
165 return SM.getExpansionLoc(L);
170 llvm::raw_string_ostream
OS(QName);
171 PrintingPolicy Policy(ND.getASTContext().getLangOpts());
176 Policy.SuppressUnwrittenScope =
true;
177 ND.printQualifiedName(
OS, Policy);
179 assert(!StringRef(QName).startswith(
"::"));
184 return N.isIdentifier() && !N.getAsIdentifierInfo();
188 if (
auto *V = llvm::dyn_cast<DeclaratorDecl>(&ND))
189 return V->getQualifierLoc();
190 if (
auto *T = llvm::dyn_cast<TagDecl>(&ND))
191 return T->getQualifierLoc();
192 return NestedNameSpecifierLoc();
196 const UsingDirectiveDecl &D) {
197 PrintingPolicy
PP(
Ctx.getLangOpts());
199 llvm::raw_string_ostream
Out(
Name);
201 if (
auto *Qual = D.getQualifier())
202 Qual->print(
Out,
PP);
203 D.getNominatedNamespaceAsWritten()->printName(
Out);
209 llvm::raw_string_ostream
Out(
Name);
210 PrintingPolicy
PP(
Ctx.getLangOpts());
212 PP.SuppressTemplateArgsInCXXConstructors =
true;
215 if (
auto *UD = llvm::dyn_cast<UsingDirectiveDecl>(&ND)) {
216 Out <<
"using namespace ";
217 if (
auto *Qual = UD->getQualifier())
218 Qual->print(
Out,
PP);
219 UD->getNominatedNamespaceAsWritten()->printName(
Out);
225 if (isa<NamespaceDecl>(ND))
226 return "(anonymous namespace)";
227 if (
auto *Cls = llvm::dyn_cast<RecordDecl>(&ND)) {
230 return (
"(anonymous " + Cls->getKindName() +
")").str();
232 if (isa<EnumDecl>(ND))
233 return "(anonymous enum)";
234 return "(anonymous)";
239 Qualifier->print(
Out,
PP);
241 ND.getDeclName().print(
Out,
PP);
249 std::string TemplateArgs;
250 llvm::raw_string_ostream
OS(TemplateArgs);
251 PrintingPolicy Policy(ND.getASTContext().getLangOpts());
252 if (llvm::Optional<llvm::ArrayRef<TemplateArgumentLoc>> Args =
253 getTemplateSpecializationArgLocs(ND)) {
254 printTemplateArgumentList(
OS, *Args, Policy);
255 }
else if (
auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) {
256 if (
const TypeSourceInfo *TSI = Cls->getTypeAsWritten()) {
260 auto STL = TSI->getTypeLoc().getAs<TemplateSpecializationTypeLoc>();
261 llvm::SmallVector<TemplateArgumentLoc, 8> ArgLocs;
262 ArgLocs.reserve(STL.getNumArgs());
263 for (
unsigned I = 0; I < STL.getNumArgs(); ++I)
264 ArgLocs.push_back(STL.getArgLoc(I));
265 printTemplateArgumentList(
OS, ArgLocs, Policy);
270 printTemplateArgumentList(
OS, Cls->getTemplateArgs().asArray(), Policy);
278 for (
const auto *
Ctx = &DC;
Ctx !=
nullptr;
Ctx =
Ctx->getParent())
279 if (
const auto *NS = dyn_cast<NamespaceDecl>(
Ctx))
280 if (!NS->isAnonymousNamespace() && !NS->isInlineNamespace())
286 llvm::SmallString<128> USR;
287 if (index::generateUSRForDecl(D, USR))
292 llvm::Optional<SymbolID>
getSymbolID(
const llvm::StringRef MacroName,
294 const SourceManager &SM) {
297 llvm::SmallString<128> USR;
298 if (index::generateUSRForMacro(MacroName, MI->getDefinitionLoc(), SM, USR))
304 std::string
printType(
const QualType QT,
const DeclContext &CurContext) {
306 llvm::raw_string_ostream
OS(Result);
312 llvm::ArrayRef<std::string>{});
313 PrintingPolicy
PP(CurContext.getParentASTContext().getPrintingPolicy());
314 PP.SuppressScope =
true;
315 PP.SuppressTagKeyword =
true;
321 if (
const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D))
322 if (
const auto *TSI = CTSD->getTypeAsWritten())
323 return TSI->getType();
324 return D->getASTContext().getTypeDeclType(D);
336 class DeducedTypeVisitor :
public RecursiveASTVisitor<DeducedTypeVisitor> {
337 SourceLocation SearchedLocation;
340 DeducedTypeVisitor(SourceLocation SearchedLocation)
341 : SearchedLocation(SearchedLocation) {}
348 bool VisitDeclaratorDecl(DeclaratorDecl *D) {
349 if (!D->getTypeSourceInfo() ||
350 D->getTypeSourceInfo()->getTypeLoc().getBeginLoc() != SearchedLocation)
353 if (
auto *AT = D->getType()->getContainedAutoType()) {
354 if (!AT->getDeducedType().isNull())
366 bool VisitFunctionDecl(FunctionDecl *D) {
367 if (!D->getTypeSourceInfo())
370 auto CurLoc = D->getReturnTypeSourceRange().getBegin();
372 if (CurLoc.isInvalid() && dyn_cast<CXXConversionDecl>(D))
373 CurLoc = D->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
375 if (CurLoc.isInvalid())
376 CurLoc = D->getSourceRange().getBegin();
377 if (CurLoc != SearchedLocation)
380 const AutoType *AT = D->getReturnType()->getContainedAutoType();
381 if (AT && !AT->getDeducedType().isNull()) {
383 }
else if (
auto DT = dyn_cast<DecltypeType>(D->getReturnType())) {
386 if (!DT->getUnderlyingType().isNull())
388 }
else if (!D->getReturnType().isNull()) {
397 bool VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
398 if (TL.getBeginLoc() != SearchedLocation)
405 const DecltypeType *DT = dyn_cast<DecltypeType>(TL.getTypePtr());
406 while (DT && !DT->getUnderlyingType().isNull()) {
408 DT = dyn_cast<DecltypeType>(
DeducedType.getTypePtr());
418 SourceLocation
Loc) {
421 DeducedTypeVisitor V(
Loc);
422 V.TraverseAST(ASTCtx);
423 if (V.DeducedType.isNull())
425 return V.DeducedType;
429 const DeclContext *DestContext,
431 const NamedDecl *ND) {
432 auto VisibleNamespaceDecls =
435 Context, DestContext, ND->getDeclContext(),
436 [&](NestedNameSpecifier *NNS) {
439 const auto *CanonNSD = NNS->getAsNamespace()->getCanonicalDecl();
440 return llvm::any_of(VisibleNamespaceDecls,
441 [CanonNSD](
const NamespaceDecl *NSD) {
442 return NSD->getCanonicalDecl() == CanonNSD;
448 const DeclContext *DestContext,
450 llvm::ArrayRef<std::string> VisibleNamespaces) {
451 for (llvm::StringRef NS : VisibleNamespaces) {
452 assert(NS.endswith(
"::"));
456 Context, DestContext, ND->getDeclContext(),
457 [&](NestedNameSpecifier *NNS) {
458 return llvm::any_of(VisibleNamespaces, [&](llvm::StringRef
Namespace) {
460 llvm::raw_string_ostream
OS(NS);
461 NNS->print(
OS,
Context.getPrintingPolicy());
470 auto *VD = llvm::dyn_cast_or_null<ValueDecl>(D);
471 return VD && !VD->getType().isNull() && VD->getType()->isUndeducedType();