clang-tools  15.0.0git
AST.cpp
Go to the documentation of this file.
1 //===--- AST.cpp - Utility AST functions -----------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "AST.h"
10 
11 #include "SourceCode.h"
12 #include "clang/AST/ASTContext.h"
13 #include "clang/AST/ASTTypeTraits.h"
14 #include "clang/AST/Decl.h"
15 #include "clang/AST/DeclBase.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/DeclTemplate.h"
18 #include "clang/AST/DeclarationName.h"
19 #include "clang/AST/NestedNameSpecifier.h"
20 #include "clang/AST/PrettyPrinter.h"
21 #include "clang/AST/RecursiveASTVisitor.h"
22 #include "clang/AST/Stmt.h"
23 #include "clang/AST/TemplateBase.h"
24 #include "clang/AST/TypeLoc.h"
25 #include "clang/Basic/SourceLocation.h"
26 #include "clang/Basic/SourceManager.h"
27 #include "clang/Basic/Specifiers.h"
28 #include "clang/Index/USRGeneration.h"
29 #include "llvm/ADT/ArrayRef.h"
30 #include "llvm/ADT/Optional.h"
31 #include "llvm/ADT/STLExtras.h"
32 #include "llvm/ADT/StringRef.h"
33 #include "llvm/Support/Casting.h"
34 #include "llvm/Support/raw_ostream.h"
35 #include <string>
36 #include <vector>
37 
38 namespace clang {
39 namespace clangd {
40 
41 namespace {
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  if (auto *Args = Var->getTemplateArgsInfo())
58  return Args->arguments();
59  }
60  // We return None for ClassTemplateSpecializationDecls because it does not
61  // contain TemplateArgumentLoc information.
62  return llvm::None;
63 }
64 
65 template <class T>
66 bool isTemplateSpecializationKind(const NamedDecl *D,
67  TemplateSpecializationKind Kind) {
68  if (const auto *TD = dyn_cast<T>(D))
69  return TD->getTemplateSpecializationKind() == Kind;
70  return false;
71 }
72 
73 bool isTemplateSpecializationKind(const NamedDecl *D,
74  TemplateSpecializationKind Kind) {
75  return isTemplateSpecializationKind<FunctionDecl>(D, Kind) ||
76  isTemplateSpecializationKind<CXXRecordDecl>(D, Kind) ||
77  isTemplateSpecializationKind<VarDecl>(D, Kind);
78 }
79 
80 // Store all UsingDirectiveDecls in parent contexts of DestContext, that were
81 // introduced before InsertionPoint.
82 llvm::DenseSet<const NamespaceDecl *>
83 getUsingNamespaceDirectives(const DeclContext *DestContext,
84  SourceLocation Until) {
85  const auto &SM = DestContext->getParentASTContext().getSourceManager();
86  llvm::DenseSet<const NamespaceDecl *> VisibleNamespaceDecls;
87  for (const auto *DC = DestContext; DC; DC = DC->getLookupParent()) {
88  for (const auto *D : DC->decls()) {
89  if (!SM.isWrittenInSameFile(D->getLocation(), Until) ||
90  !SM.isBeforeInTranslationUnit(D->getLocation(), Until))
91  continue;
92  if (auto *UDD = llvm::dyn_cast<UsingDirectiveDecl>(D))
93  VisibleNamespaceDecls.insert(
94  UDD->getNominatedNamespace()->getCanonicalDecl());
95  }
96  }
97  return VisibleNamespaceDecls;
98 }
99 
100 // Goes over all parents of SourceContext until we find a common ancestor for
101 // DestContext and SourceContext. Any qualifier including and above common
102 // ancestor is redundant, therefore we stop at lowest common ancestor.
103 // In addition to that stops early whenever IsVisible returns true. This can be
104 // used to implement support for "using namespace" decls.
105 std::string
106 getQualification(ASTContext &Context, const DeclContext *DestContext,
107  const DeclContext *SourceContext,
108  llvm::function_ref<bool(NestedNameSpecifier *)> IsVisible) {
109  std::vector<const NestedNameSpecifier *> Parents;
110  bool ReachedNS = false;
111  for (const DeclContext *CurContext = SourceContext; CurContext;
112  CurContext = CurContext->getLookupParent()) {
113  // Stop once we reach a common ancestor.
114  if (CurContext->Encloses(DestContext))
115  break;
116 
117  NestedNameSpecifier *NNS = nullptr;
118  if (auto *TD = llvm::dyn_cast<TagDecl>(CurContext)) {
119  // There can't be any more tag parents after hitting a namespace.
120  assert(!ReachedNS);
121  (void)ReachedNS;
122  NNS = NestedNameSpecifier::Create(Context, nullptr, false,
123  TD->getTypeForDecl());
124  } else if (auto *NSD = llvm::dyn_cast<NamespaceDecl>(CurContext)) {
125  ReachedNS = true;
126  NNS = NestedNameSpecifier::Create(Context, nullptr, NSD);
127  // Anonymous and inline namespace names are not spelled while qualifying
128  // a name, so skip those.
129  if (NSD->isAnonymousNamespace() || NSD->isInlineNamespace())
130  continue;
131  } else {
132  // Other types of contexts cannot be spelled in code, just skip over
133  // them.
134  continue;
135  }
136  // Stop if this namespace is already visible at DestContext.
137  if (IsVisible(NNS))
138  break;
139 
140  Parents.push_back(NNS);
141  }
142 
143  // Go over name-specifiers in reverse order to create necessary qualification,
144  // since we stored inner-most parent first.
145  std::string Result;
146  llvm::raw_string_ostream OS(Result);
147  for (const auto *Parent : llvm::reverse(Parents))
148  Parent->print(OS, Context.getPrintingPolicy());
149  return OS.str();
150 }
151 
152 } // namespace
153 
154 bool isImplicitTemplateInstantiation(const NamedDecl *D) {
155  return isTemplateSpecializationKind(D, TSK_ImplicitInstantiation);
156 }
157 
158 bool isExplicitTemplateSpecialization(const NamedDecl *D) {
159  return isTemplateSpecializationKind(D, TSK_ExplicitSpecialization);
160 }
161 
163  return !isSpelledInSource(D->getLocation(),
164  D->getASTContext().getSourceManager());
165 }
166 
167 SourceLocation nameLocation(const clang::Decl &D, const SourceManager &SM) {
168  auto L = D.getLocation();
169  if (isSpelledInSource(L, SM))
170  return SM.getSpellingLoc(L);
171  return SM.getExpansionLoc(L);
172 }
173 
174 std::string printQualifiedName(const NamedDecl &ND) {
175  std::string QName;
176  llvm::raw_string_ostream OS(QName);
177  PrintingPolicy Policy(ND.getASTContext().getLangOpts());
178  // Note that inline namespaces are treated as transparent scopes. This
179  // reflects the way they're most commonly used for lookup. Ideally we'd
180  // include them, but at query time it's hard to find all the inline
181  // namespaces to query: the preamble doesn't have a dedicated list.
182  Policy.SuppressUnwrittenScope = true;
183  ND.printQualifiedName(OS, Policy);
184  OS.flush();
185  assert(!StringRef(QName).startswith("::"));
186  return QName;
187 }
188 
189 static bool isAnonymous(const DeclarationName &N) {
190  return N.isIdentifier() && !N.getAsIdentifierInfo();
191 }
192 
193 NestedNameSpecifierLoc getQualifierLoc(const NamedDecl &ND) {
194  if (auto *V = llvm::dyn_cast<DeclaratorDecl>(&ND))
195  return V->getQualifierLoc();
196  if (auto *T = llvm::dyn_cast<TagDecl>(&ND))
197  return T->getQualifierLoc();
198  return NestedNameSpecifierLoc();
199 }
200 
201 std::string printUsingNamespaceName(const ASTContext &Ctx,
202  const UsingDirectiveDecl &D) {
203  PrintingPolicy PP(Ctx.getLangOpts());
204  std::string Name;
205  llvm::raw_string_ostream Out(Name);
206 
207  if (auto *Qual = D.getQualifier())
208  Qual->print(Out, PP);
209  D.getNominatedNamespaceAsWritten()->printName(Out);
210  return Out.str();
211 }
212 
213 std::string printName(const ASTContext &Ctx, const NamedDecl &ND) {
214  std::string Name;
215  llvm::raw_string_ostream Out(Name);
216  PrintingPolicy PP(Ctx.getLangOpts());
217  // We don't consider a class template's args part of the constructor name.
218  PP.SuppressTemplateArgsInCXXConstructors = true;
219 
220  // Handle 'using namespace'. They all have the same name - <using-directive>.
221  if (auto *UD = llvm::dyn_cast<UsingDirectiveDecl>(&ND)) {
222  Out << "using namespace ";
223  if (auto *Qual = UD->getQualifier())
224  Qual->print(Out, PP);
225  UD->getNominatedNamespaceAsWritten()->printName(Out);
226  return Out.str();
227  }
228 
229  if (isAnonymous(ND.getDeclName())) {
230  // Come up with a presentation for an anonymous entity.
231  if (isa<NamespaceDecl>(ND))
232  return "(anonymous namespace)";
233  if (auto *Cls = llvm::dyn_cast<RecordDecl>(&ND)) {
234  if (Cls->isLambda())
235  return "(lambda)";
236  return ("(anonymous " + Cls->getKindName() + ")").str();
237  }
238  if (isa<EnumDecl>(ND))
239  return "(anonymous enum)";
240  return "(anonymous)";
241  }
242 
243  // Print nested name qualifier if it was written in the source code.
244  if (auto *Qualifier = getQualifierLoc(ND).getNestedNameSpecifier())
245  Qualifier->print(Out, PP);
246  // Print the name itself.
247  ND.getDeclName().print(Out, PP);
248  // Print template arguments.
250 
251  return Out.str();
252 }
253 
254 std::string printTemplateSpecializationArgs(const NamedDecl &ND) {
255  std::string TemplateArgs;
256  llvm::raw_string_ostream OS(TemplateArgs);
257  PrintingPolicy Policy(ND.getASTContext().getLangOpts());
258  if (llvm::Optional<llvm::ArrayRef<TemplateArgumentLoc>> Args =
259  getTemplateSpecializationArgLocs(ND)) {
260  printTemplateArgumentList(OS, *Args, Policy);
261  } else if (auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) {
262  if (const TypeSourceInfo *TSI = Cls->getTypeAsWritten()) {
263  // ClassTemplateSpecializationDecls do not contain
264  // TemplateArgumentTypeLocs, they only have TemplateArgumentTypes. So we
265  // create a new argument location list from TypeSourceInfo.
266  auto STL = TSI->getTypeLoc().getAs<TemplateSpecializationTypeLoc>();
267  llvm::SmallVector<TemplateArgumentLoc> ArgLocs;
268  ArgLocs.reserve(STL.getNumArgs());
269  for (unsigned I = 0; I < STL.getNumArgs(); ++I)
270  ArgLocs.push_back(STL.getArgLoc(I));
271  printTemplateArgumentList(OS, ArgLocs, Policy);
272  } else {
273  // FIXME: Fix cases when getTypeAsWritten returns null inside clang AST,
274  // e.g. friend decls. Currently we fallback to Template Arguments without
275  // location information.
276  printTemplateArgumentList(OS, Cls->getTemplateArgs().asArray(), Policy);
277  }
278  }
279  OS.flush();
280  return TemplateArgs;
281 }
282 
283 std::string printNamespaceScope(const DeclContext &DC) {
284  for (const auto *Ctx = &DC; Ctx != nullptr; Ctx = Ctx->getParent())
285  if (const auto *NS = dyn_cast<NamespaceDecl>(Ctx))
286  if (!NS->isAnonymousNamespace() && !NS->isInlineNamespace())
287  return printQualifiedName(*NS) + "::";
288  return "";
289 }
290 
291 static llvm::StringRef
292 getNameOrErrForObjCInterface(const ObjCInterfaceDecl *ID) {
293  return ID ? ID->getName() : "<<error-type>>";
294 }
295 
296 std::string printObjCMethod(const ObjCMethodDecl &Method) {
297  std::string Name;
298  llvm::raw_string_ostream OS(Name);
299 
300  OS << (Method.isInstanceMethod() ? '-' : '+') << '[';
301 
302  // Should always be true.
303  if (const ObjCContainerDecl *C =
304  dyn_cast<ObjCContainerDecl>(Method.getDeclContext()))
305  OS << printObjCContainer(*C);
306 
307  Method.getSelector().print(OS << ' ');
308  if (Method.isVariadic())
309  OS << ", ...";
310 
311  OS << ']';
312  OS.flush();
313  return Name;
314 }
315 
316 std::string printObjCContainer(const ObjCContainerDecl &C) {
317  if (const ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(&C)) {
318  std::string Name;
319  llvm::raw_string_ostream OS(Name);
320  const ObjCInterfaceDecl *Class = Category->getClassInterface();
321  OS << getNameOrErrForObjCInterface(Class) << '(' << Category->getName()
322  << ')';
323  OS.flush();
324  return Name;
325  }
326  if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(&C)) {
327  std::string Name;
328  llvm::raw_string_ostream OS(Name);
329  const ObjCInterfaceDecl *Class = CID->getClassInterface();
330  OS << getNameOrErrForObjCInterface(Class) << '(' << CID->getName() << ')';
331  OS.flush();
332  return Name;
333  }
334  return C.getNameAsString();
335 }
336 
338  llvm::SmallString<128> USR;
339  if (index::generateUSRForDecl(D, USR))
340  return {};
341  return SymbolID(USR);
342 }
343 
344 SymbolID getSymbolID(const llvm::StringRef MacroName, const MacroInfo *MI,
345  const SourceManager &SM) {
346  if (MI == nullptr)
347  return {};
348  llvm::SmallString<128> USR;
349  if (index::generateUSRForMacro(MacroName, MI->getDefinitionLoc(), SM, USR))
350  return {};
351  return SymbolID(USR);
352 }
353 
354 std::string printType(const QualType QT, const DeclContext &CurContext,
355  const llvm::StringRef Placeholder) {
356  std::string Result;
357  llvm::raw_string_ostream OS(Result);
358  PrintingPolicy PP(CurContext.getParentASTContext().getPrintingPolicy());
359  PP.SuppressTagKeyword = true;
360  PP.SuppressUnwrittenScope = true;
361 
362  class PrintCB : public PrintingCallbacks {
363  public:
364  PrintCB(const DeclContext *CurContext) : CurContext(CurContext) {}
365  virtual ~PrintCB() {}
366  virtual bool isScopeVisible(const DeclContext *DC) const override {
367  return DC->Encloses(CurContext);
368  }
369 
370  private:
371  const DeclContext *CurContext;
372  };
373  PrintCB PCB(&CurContext);
374  PP.Callbacks = &PCB;
375 
376  QT.print(OS, PP, Placeholder);
377  return OS.str();
378 }
379 
380 bool hasReservedName(const Decl &D) {
381  if (const auto *ND = llvm::dyn_cast<NamedDecl>(&D))
382  if (const auto *II = ND->getIdentifier())
383  return isReservedName(II->getName());
384  return false;
385 }
386 
387 bool hasReservedScope(const DeclContext &DC) {
388  for (const DeclContext *D = &DC; D; D = D->getParent()) {
389  if (D->isTransparentContext() || D->isInlineNamespace())
390  continue;
391  if (const auto *ND = llvm::dyn_cast<NamedDecl>(D))
392  if (hasReservedName(*ND))
393  return true;
394  }
395  return false;
396 }
397 
398 QualType declaredType(const TypeDecl *D) {
399  if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D))
400  if (const auto *TSI = CTSD->getTypeAsWritten())
401  return TSI->getType();
402  return D->getASTContext().getTypeDeclType(D);
403 }
404 
405 namespace {
406 /// Computes the deduced type at a given location by visiting the relevant
407 /// nodes. We use this to display the actual type when hovering over an "auto"
408 /// keyword or "decltype()" expression.
409 /// FIXME: This could have been a lot simpler by visiting AutoTypeLocs but it
410 /// seems that the AutoTypeLocs that can be visited along with their AutoType do
411 /// not have the deduced type set. Instead, we have to go to the appropriate
412 /// DeclaratorDecl/FunctionDecl and work our back to the AutoType that does have
413 /// a deduced type set. The AST should be improved to simplify this scenario.
414 class DeducedTypeVisitor : public RecursiveASTVisitor<DeducedTypeVisitor> {
415  SourceLocation SearchedLocation;
416 
417 public:
418  DeducedTypeVisitor(SourceLocation SearchedLocation)
419  : SearchedLocation(SearchedLocation) {}
420 
421  // Handle auto initializers:
422  //- auto i = 1;
423  //- decltype(auto) i = 1;
424  //- auto& i = 1;
425  //- auto* i = &a;
426  bool VisitDeclaratorDecl(DeclaratorDecl *D) {
427  if (!D->getTypeSourceInfo() ||
428  D->getTypeSourceInfo()->getTypeLoc().getBeginLoc() != SearchedLocation)
429  return true;
430 
431  if (auto *AT = D->getType()->getContainedAutoType()) {
432  DeducedType = AT->desugar();
433  }
434  return true;
435  }
436 
437  // Handle auto return types:
438  //- auto foo() {}
439  //- auto& foo() {}
440  //- auto foo() -> int {}
441  //- auto foo() -> decltype(1+1) {}
442  //- operator auto() const { return 10; }
443  bool VisitFunctionDecl(FunctionDecl *D) {
444  if (!D->getTypeSourceInfo())
445  return true;
446  // Loc of auto in return type (c++14).
447  auto CurLoc = D->getReturnTypeSourceRange().getBegin();
448  // Loc of "auto" in operator auto()
449  if (CurLoc.isInvalid() && isa<CXXConversionDecl>(D))
450  CurLoc = D->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
451  // Loc of "auto" in function with trailing return type (c++11).
452  if (CurLoc.isInvalid())
453  CurLoc = D->getSourceRange().getBegin();
454  if (CurLoc != SearchedLocation)
455  return true;
456 
457  const AutoType *AT = D->getReturnType()->getContainedAutoType();
458  if (AT && !AT->getDeducedType().isNull()) {
459  DeducedType = AT->getDeducedType();
460  } else if (auto *DT = dyn_cast<DecltypeType>(D->getReturnType())) {
461  // auto in a trailing return type just points to a DecltypeType and
462  // getContainedAutoType does not unwrap it.
463  if (!DT->getUnderlyingType().isNull())
464  DeducedType = DT->getUnderlyingType();
465  } else if (!D->getReturnType().isNull()) {
466  DeducedType = D->getReturnType();
467  }
468  return true;
469  }
470 
471  // Handle non-auto decltype, e.g.:
472  // - auto foo() -> decltype(expr) {}
473  // - decltype(expr);
474  bool VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
475  if (TL.getBeginLoc() != SearchedLocation)
476  return true;
477 
478  // A DecltypeType's underlying type can be another DecltypeType! E.g.
479  // int I = 0;
480  // decltype(I) J = I;
481  // decltype(J) K = J;
482  const DecltypeType *DT = dyn_cast<DecltypeType>(TL.getTypePtr());
483  while (DT && !DT->getUnderlyingType().isNull()) {
484  DeducedType = DT->getUnderlyingType();
485  DT = dyn_cast<DecltypeType>(DeducedType.getTypePtr());
486  }
487  return true;
488  }
489 
490  // Handle functions/lambdas with `auto` typed parameters.
491  // We deduce the type if there's exactly one instantiation visible.
492  bool VisitParmVarDecl(ParmVarDecl *PVD) {
493  if (!PVD->getType()->isDependentType())
494  return true;
495  // 'auto' here does not name an AutoType, but an implicit template param.
496  TemplateTypeParmTypeLoc Auto =
497  getContainedAutoParamType(PVD->getTypeSourceInfo()->getTypeLoc());
498  if (Auto.isNull() || Auto.getNameLoc() != SearchedLocation)
499  return true;
500 
501  // We expect the TTP to be attached to this function template.
502  // Find the template and the param index.
503  auto *Templated = llvm::dyn_cast<FunctionDecl>(PVD->getDeclContext());
504  if (!Templated)
505  return true;
506  auto *FTD = Templated->getDescribedFunctionTemplate();
507  if (!FTD)
508  return true;
509  int ParamIndex = paramIndex(*FTD, *Auto.getDecl());
510  if (ParamIndex < 0) {
511  assert(false && "auto TTP is not from enclosing function?");
512  return true;
513  }
514 
515  // Now find the instantiation and the deduced template type arg.
516  auto *Instantiation =
517  llvm::dyn_cast_or_null<FunctionDecl>(getOnlyInstantiation(Templated));
518  if (!Instantiation)
519  return true;
520  const auto *Args = Instantiation->getTemplateSpecializationArgs();
521  if (Args->size() != FTD->getTemplateParameters()->size())
522  return true; // no weird variadic stuff
523  DeducedType = Args->get(ParamIndex).getAsType();
524  return true;
525  }
526 
527  static int paramIndex(const TemplateDecl &TD, NamedDecl &Param) {
528  unsigned I = 0;
529  for (auto *ND : *TD.getTemplateParameters()) {
530  if (&Param == ND)
531  return I;
532  ++I;
533  }
534  return -1;
535  }
536 
537  QualType DeducedType;
538 };
539 } // namespace
540 
541 llvm::Optional<QualType> getDeducedType(ASTContext &ASTCtx,
542  SourceLocation Loc) {
543  if (!Loc.isValid())
544  return {};
545  DeducedTypeVisitor V(Loc);
546  V.TraverseAST(ASTCtx);
547  if (V.DeducedType.isNull())
548  return llvm::None;
549  return V.DeducedType;
550 }
551 
552 TemplateTypeParmTypeLoc getContainedAutoParamType(TypeLoc TL) {
553  if (auto QTL = TL.getAs<QualifiedTypeLoc>())
554  return getContainedAutoParamType(QTL.getUnqualifiedLoc());
555  if (llvm::isa<PointerType, ReferenceType, ParenType>(TL.getTypePtr()))
556  return getContainedAutoParamType(TL.getNextTypeLoc());
557  if (auto FTL = TL.getAs<FunctionTypeLoc>())
558  return getContainedAutoParamType(FTL.getReturnLoc());
559  if (auto TTPTL = TL.getAs<TemplateTypeParmTypeLoc>()) {
560  if (TTPTL.getTypePtr()->getDecl()->isImplicit())
561  return TTPTL;
562  }
563  return {};
564 }
565 
566 template <typename TemplateDeclTy>
567 static NamedDecl *getOnlyInstantiationImpl(TemplateDeclTy *TD) {
568  NamedDecl *Only = nullptr;
569  for (auto *Spec : TD->specializations()) {
570  if (Spec->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
571  continue;
572  if (Only != nullptr)
573  return nullptr;
574  Only = Spec;
575  }
576  return Only;
577 }
578 
579 NamedDecl *getOnlyInstantiation(NamedDecl *TemplatedDecl) {
580  if (TemplateDecl *TD = TemplatedDecl->getDescribedTemplate()) {
581  if (auto *CTD = llvm::dyn_cast<ClassTemplateDecl>(TD))
582  return getOnlyInstantiationImpl(CTD);
583  if (auto *FTD = llvm::dyn_cast<FunctionTemplateDecl>(TD))
584  return getOnlyInstantiationImpl(FTD);
585  if (auto *VTD = llvm::dyn_cast<VarTemplateDecl>(TD))
586  return getOnlyInstantiationImpl(VTD);
587  }
588  return nullptr;
589 }
590 
591 std::vector<const Attr *> getAttributes(const DynTypedNode &N) {
592  std::vector<const Attr *> Result;
593  if (const auto *TL = N.get<TypeLoc>()) {
594  for (AttributedTypeLoc ATL = TL->getAs<AttributedTypeLoc>(); !ATL.isNull();
595  ATL = ATL.getModifiedLoc().getAs<AttributedTypeLoc>()) {
596  if (const Attr *A = ATL.getAttr())
597  Result.push_back(A);
598  assert(!ATL.getModifiedLoc().isNull());
599  }
600  }
601  if (const auto *S = N.get<AttributedStmt>()) {
602  for (; S != nullptr; S = dyn_cast<AttributedStmt>(S->getSubStmt()))
603  for (const Attr *A : S->getAttrs())
604  if (A)
605  Result.push_back(A);
606  }
607  if (const auto *D = N.get<Decl>()) {
608  for (const Attr *A : D->attrs())
609  if (A)
610  Result.push_back(A);
611  }
612  return Result;
613 }
614 
615 std::string getQualification(ASTContext &Context,
616  const DeclContext *DestContext,
617  SourceLocation InsertionPoint,
618  const NamedDecl *ND) {
619  auto VisibleNamespaceDecls =
620  getUsingNamespaceDirectives(DestContext, InsertionPoint);
621  return getQualification(
622  Context, DestContext, ND->getDeclContext(),
623  [&](NestedNameSpecifier *NNS) {
624  if (NNS->getKind() != NestedNameSpecifier::Namespace)
625  return false;
626  const auto *CanonNSD = NNS->getAsNamespace()->getCanonicalDecl();
627  return llvm::any_of(VisibleNamespaceDecls,
628  [CanonNSD](const NamespaceDecl *NSD) {
629  return NSD->getCanonicalDecl() == CanonNSD;
630  });
631  });
632 }
633 
634 std::string getQualification(ASTContext &Context,
635  const DeclContext *DestContext,
636  const NamedDecl *ND,
637  llvm::ArrayRef<std::string> VisibleNamespaces) {
638  for (llvm::StringRef NS : VisibleNamespaces) {
639  assert(NS.endswith("::"));
640  (void)NS;
641  }
642  return getQualification(
643  Context, DestContext, ND->getDeclContext(),
644  [&](NestedNameSpecifier *NNS) {
645  return llvm::any_of(VisibleNamespaces, [&](llvm::StringRef Namespace) {
646  std::string NS;
647  llvm::raw_string_ostream OS(NS);
648  NNS->print(OS, Context.getPrintingPolicy());
649  return OS.str() == Namespace;
650  });
651  });
652 }
653 
654 bool hasUnstableLinkage(const Decl *D) {
655  // Linkage of a ValueDecl depends on the type.
656  // If that's not deduced yet, deducing it may change the linkage.
657  auto *VD = llvm::dyn_cast_or_null<ValueDecl>(D);
658  return VD && !VD->getType().isNull() && VD->getType()->isUndeducedType();
659 }
660 
661 bool isDeeplyNested(const Decl *D, unsigned MaxDepth) {
662  size_t ContextDepth = 0;
663  for (auto *Ctx = D->getDeclContext(); Ctx && !Ctx->isTranslationUnit();
664  Ctx = Ctx->getParent()) {
665  if (++ContextDepth == MaxDepth)
666  return true;
667  }
668  return false;
669 }
670 } // namespace clangd
671 } // namespace clang
clang::clangd::isSpelledInSource
bool isSpelledInSource(SourceLocation Loc, const SourceManager &SM)
Returns true if the token at Loc is spelled in the source code.
Definition: SourceCode.cpp:230
Loc
SourceLocation Loc
Definition: KernelNameRestrictionCheck.cpp:45
RecursiveASTVisitor
clang::clangd::hasUnstableLinkage
bool hasUnstableLinkage(const Decl *D)
Whether we must avoid computing linkage for D during code completion.
Definition: AST.cpp:654
clang::clangd::declaredType
QualType declaredType(const TypeDecl *D)
Definition: AST.cpp:398
clang::clangd::isImplicitTemplateInstantiation
bool isImplicitTemplateInstantiation(const NamedDecl *D)
Indicates if D is a template instantiation implicitly generated by the compiler, e....
Definition: AST.cpp:154
clang::clangd::TypeHierarchyDirection::Parents
@ Parents
clang::clangd::WantDiagnostics::Auto
@ Auto
Diagnostics must not be generated for this snapshot.
Kind
BindArgumentKind Kind
Definition: AvoidBindCheck.cpp:59
Ctx
Context Ctx
Definition: TUScheduler.cpp:495
clang::clangd::getQualifierLoc
NestedNameSpecifierLoc getQualifierLoc(const NamedDecl &ND)
Returns a nested name specifier loc of ND if it was present in the source, e.g.
Definition: AST.cpp:193
clang::clangd::printObjCMethod
std::string printObjCMethod(const ObjCMethodDecl &Method)
Print the Objective-C method name, including the full container name, e.g.
Definition: AST.cpp:296
clang::clangd::printNamespaceScope
std::string printNamespaceScope(const DeclContext &DC)
Returns the first enclosing namespace scope starting from DC.
Definition: AST.cpp:283
clang::clangd::nameLocation
SourceLocation nameLocation(const clang::Decl &D, const SourceManager &SM)
Find the source location of the identifier for D.
Definition: AST.cpp:167
clang::clangd::getDeducedType
llvm::Optional< QualType > getDeducedType(ASTContext &ASTCtx, SourceLocation Loc)
Retrieves the deduced type at a given location (auto, decltype).
Definition: AST.cpp:541
clang::clangd::printType
std::string printType(const QualType QT, const DeclContext &CurContext, const llvm::StringRef Placeholder)
Returns a QualType as string.
Definition: AST.cpp:354
ns1::ns2::A
@ A
Definition: CategoricalFeature.h:3
clang::clangd::isReservedName
bool isReservedName(llvm::StringRef Name)
Returns true if Name is reserved, like _Foo or __Vector_base.
Definition: SourceCode.h:334
ns1::ns2::D
@ D
Definition: CategoricalFeature.h:3
clang::clangd::printName
std::string printName(const ASTContext &Ctx, const NamedDecl &ND)
Prints unqualified name of the decl for the purpose of displaying it to the user.
Definition: AST.cpp:213
Decl
const FunctionDecl * Decl
Definition: AvoidBindCheck.cpp:100
clang::clangd::printQualifiedName
std::string printQualifiedName(const NamedDecl &ND)
Returns the qualified name of ND.
Definition: AST.cpp:174
Args
llvm::json::Object Args
Definition: Trace.cpp:138
clang::clangd::printTemplateSpecializationArgs
std::string printTemplateSpecializationArgs(const NamedDecl &ND)
Prints template arguments of a decl as written in the source code, including enclosing '<' and '>',...
Definition: AST.cpp:254
clang::clangd::getOnlyInstantiation
NamedDecl * getOnlyInstantiation(NamedDecl *TemplatedDecl)
Definition: AST.cpp:579
clang::clangd::hasReservedScope
bool hasReservedScope(const DeclContext &DC)
Returns true if this scope would be written with a reserved name.
Definition: AST.cpp:387
clang::doc::SymbolID
std::array< uint8_t, 20 > SymbolID
Definition: Representation.h:30
Name
Token Name
Definition: MacroToEnumCheck.cpp:89
clang::clangd::CompletionItemKind::Method
@ Method
clang::clangd::getQualification
std::string getQualification(ASTContext &Context, const DeclContext *DestContext, const NamedDecl *ND, llvm::ArrayRef< std::string > VisibleNamespaces)
This function uses the VisibleNamespaces to figure out if a shorter qualification is sufficient for N...
Definition: AST.cpp:634
clang::clangd::getContainedAutoParamType
TemplateTypeParmTypeLoc getContainedAutoParamType(TypeLoc TL)
Definition: AST.cpp:552
clang::tidy::bugprone::PP
static Preprocessor * PP
Definition: BadSignalToKillThreadCheck.cpp:29
Parent
const Node * Parent
Definition: ExtractFunction.cpp:157
clang::clangd::getOnlyInstantiationImpl
static NamedDecl * getOnlyInstantiationImpl(TemplateDeclTy *TD)
Definition: AST.cpp:567
clang::clangd::getSymbolID
SymbolID getSymbolID(const Decl *D)
Gets the symbol ID for a declaration. Returned SymbolID might be null.
Definition: AST.cpp:337
SourceCode.h
clang::clangd::getQualification
std::string getQualification(ASTContext &Context, const DeclContext *DestContext, SourceLocation InsertionPoint, const NamedDecl *ND)
Gets the nested name specifier necessary for spelling ND in DestContext, at InsertionPoint.
Definition: AST.cpp:615
DeducedType
QualType DeducedType
Definition: AST.cpp:537
clang::clangd::isAnonymous
static bool isAnonymous(const DeclarationName &N)
Definition: AST.cpp:189
ID
static char ID
Definition: Logger.cpp:74
clang::clangd::isDeeplyNested
bool isDeeplyNested(const Decl *D, unsigned MaxDepth)
Checks whether D is more than MaxDepth away from translation unit scope.
Definition: AST.cpp:661
C
const Criteria C
Definition: FunctionCognitiveComplexityCheck.cpp:93
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
OS
llvm::raw_string_ostream OS
Definition: TraceTests.cpp:160
clang::clangd::isExplicitTemplateSpecialization
bool isExplicitTemplateSpecialization(const NamedDecl *D)
Indicates if D is an explicit template specialization, e.g.
Definition: AST.cpp:158
clang::clangd::hasReservedName
bool hasReservedName(const Decl &D)
Returns true if this is a NamedDecl with a reserved name.
Definition: AST.cpp:380
clang::clangd::isImplementationDetail
bool isImplementationDetail(const Decl *D)
Returns true if the declaration is considered implementation detail based on heuristics.
Definition: AST.cpp:162
clang::clangd::printObjCContainer
std::string printObjCContainer(const ObjCContainerDecl &C)
Print the Objective-C container name including categories, e.g. MyClass,.
Definition: AST.cpp:316
Out
CompiledFragmentImpl & Out
Definition: ConfigCompile.cpp:99
clang::clangd::getAttributes
std::vector< const Attr * > getAttributes(const DynTypedNode &N)
Return attributes attached directly to a node.
Definition: AST.cpp:591
clang::clangd::getNameOrErrForObjCInterface
static llvm::StringRef getNameOrErrForObjCInterface(const ObjCInterfaceDecl *ID)
Definition: AST.cpp:292
clang::clangd::SymbolID
Definition: SymbolID.h:32
clang::clangd::Context
A context is an immutable container for per-request data that must be propagated through layers that ...
Definition: Context.h:69
clang::clangd::printUsingNamespaceName
std::string printUsingNamespaceName(const ASTContext &Ctx, const UsingDirectiveDecl &D)
Returns the name of the namespace inside the 'using namespace' directive, as written in the code.
Definition: AST.cpp:201
AST.h