clang-tools  16.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/DeclObjC.h"
18 #include "clang/AST/DeclTemplate.h"
19 #include "clang/AST/DeclarationName.h"
20 #include "clang/AST/ExprCXX.h"
21 #include "clang/AST/NestedNameSpecifier.h"
22 #include "clang/AST/PrettyPrinter.h"
23 #include "clang/AST/RecursiveASTVisitor.h"
24 #include "clang/AST/Stmt.h"
25 #include "clang/AST/TemplateBase.h"
26 #include "clang/AST/TypeLoc.h"
27 #include "clang/Basic/Builtins.h"
28 #include "clang/Basic/SourceLocation.h"
29 #include "clang/Basic/SourceManager.h"
30 #include "clang/Basic/Specifiers.h"
31 #include "clang/Index/USRGeneration.h"
32 #include "llvm/ADT/ArrayRef.h"
33 #include "llvm/ADT/None.h"
34 #include "llvm/ADT/Optional.h"
35 #include "llvm/ADT/STLExtras.h"
36 #include "llvm/ADT/SmallSet.h"
37 #include "llvm/ADT/StringRef.h"
38 #include "llvm/Support/Casting.h"
39 #include "llvm/Support/raw_ostream.h"
40 #include <iterator>
41 #include <string>
42 #include <vector>
43 
44 namespace clang {
45 namespace clangd {
46 
47 namespace {
48 llvm::Optional<llvm::ArrayRef<TemplateArgumentLoc>>
49 getTemplateSpecializationArgLocs(const NamedDecl &ND) {
50  if (auto *Func = llvm::dyn_cast<FunctionDecl>(&ND)) {
51  if (const ASTTemplateArgumentListInfo *Args =
52  Func->getTemplateSpecializationArgsAsWritten())
53  return Args->arguments();
54  } else if (auto *Cls =
55  llvm::dyn_cast<ClassTemplatePartialSpecializationDecl>(&ND)) {
56  if (auto *Args = Cls->getTemplateArgsAsWritten())
57  return Args->arguments();
58  } else if (auto *Var =
59  llvm::dyn_cast<VarTemplatePartialSpecializationDecl>(&ND)) {
60  if (auto *Args = Var->getTemplateArgsAsWritten())
61  return Args->arguments();
62  } else if (auto *Var = llvm::dyn_cast<VarTemplateSpecializationDecl>(&ND)) {
63  if (auto *Args = Var->getTemplateArgsInfo())
64  return Args->arguments();
65  }
66  // We return None for ClassTemplateSpecializationDecls because it does not
67  // contain TemplateArgumentLoc information.
68  return llvm::None;
69 }
70 
71 template <class T>
72 bool isTemplateSpecializationKind(const NamedDecl *D,
73  TemplateSpecializationKind Kind) {
74  if (const auto *TD = dyn_cast<T>(D))
75  return TD->getTemplateSpecializationKind() == Kind;
76  return false;
77 }
78 
79 bool isTemplateSpecializationKind(const NamedDecl *D,
80  TemplateSpecializationKind Kind) {
81  return isTemplateSpecializationKind<FunctionDecl>(D, Kind) ||
82  isTemplateSpecializationKind<CXXRecordDecl>(D, Kind) ||
83  isTemplateSpecializationKind<VarDecl>(D, Kind);
84 }
85 
86 // Store all UsingDirectiveDecls in parent contexts of DestContext, that were
87 // introduced before InsertionPoint.
88 llvm::DenseSet<const NamespaceDecl *>
89 getUsingNamespaceDirectives(const DeclContext *DestContext,
90  SourceLocation Until) {
91  const auto &SM = DestContext->getParentASTContext().getSourceManager();
92  llvm::DenseSet<const NamespaceDecl *> VisibleNamespaceDecls;
93  for (const auto *DC = DestContext; DC; DC = DC->getLookupParent()) {
94  for (const auto *D : DC->decls()) {
95  if (!SM.isWrittenInSameFile(D->getLocation(), Until) ||
96  !SM.isBeforeInTranslationUnit(D->getLocation(), Until))
97  continue;
98  if (auto *UDD = llvm::dyn_cast<UsingDirectiveDecl>(D))
99  VisibleNamespaceDecls.insert(
100  UDD->getNominatedNamespace()->getCanonicalDecl());
101  }
102  }
103  return VisibleNamespaceDecls;
104 }
105 
106 // Goes over all parents of SourceContext until we find a common ancestor for
107 // DestContext and SourceContext. Any qualifier including and above common
108 // ancestor is redundant, therefore we stop at lowest common ancestor.
109 // In addition to that stops early whenever IsVisible returns true. This can be
110 // used to implement support for "using namespace" decls.
111 std::string
112 getQualification(ASTContext &Context, const DeclContext *DestContext,
113  const DeclContext *SourceContext,
114  llvm::function_ref<bool(NestedNameSpecifier *)> IsVisible) {
115  std::vector<const NestedNameSpecifier *> Parents;
116  bool ReachedNS = false;
117  for (const DeclContext *CurContext = SourceContext; CurContext;
118  CurContext = CurContext->getLookupParent()) {
119  // Stop once we reach a common ancestor.
120  if (CurContext->Encloses(DestContext))
121  break;
122 
123  NestedNameSpecifier *NNS = nullptr;
124  if (auto *TD = llvm::dyn_cast<TagDecl>(CurContext)) {
125  // There can't be any more tag parents after hitting a namespace.
126  assert(!ReachedNS);
127  (void)ReachedNS;
128  NNS = NestedNameSpecifier::Create(Context, nullptr, false,
129  TD->getTypeForDecl());
130  } else if (auto *NSD = llvm::dyn_cast<NamespaceDecl>(CurContext)) {
131  ReachedNS = true;
132  NNS = NestedNameSpecifier::Create(Context, nullptr, NSD);
133  // Anonymous and inline namespace names are not spelled while qualifying
134  // a name, so skip those.
135  if (NSD->isAnonymousNamespace() || NSD->isInlineNamespace())
136  continue;
137  } else {
138  // Other types of contexts cannot be spelled in code, just skip over
139  // them.
140  continue;
141  }
142  // Stop if this namespace is already visible at DestContext.
143  if (IsVisible(NNS))
144  break;
145 
146  Parents.push_back(NNS);
147  }
148 
149  // Go over name-specifiers in reverse order to create necessary qualification,
150  // since we stored inner-most parent first.
151  std::string Result;
152  llvm::raw_string_ostream OS(Result);
153  for (const auto *Parent : llvm::reverse(Parents))
154  Parent->print(OS, Context.getPrintingPolicy());
155  return OS.str();
156 }
157 
158 } // namespace
159 
160 bool isImplicitTemplateInstantiation(const NamedDecl *D) {
161  return isTemplateSpecializationKind(D, TSK_ImplicitInstantiation);
162 }
163 
164 bool isExplicitTemplateSpecialization(const NamedDecl *D) {
165  return isTemplateSpecializationKind(D, TSK_ExplicitSpecialization);
166 }
167 
169  return !isSpelledInSource(D->getLocation(),
170  D->getASTContext().getSourceManager());
171 }
172 
173 SourceLocation nameLocation(const clang::Decl &D, const SourceManager &SM) {
174  auto L = D.getLocation();
175  // For `- (void)foo` we want `foo` not the `-`.
176  if (const auto *MD = dyn_cast<ObjCMethodDecl>(&D))
177  L = MD->getSelectorStartLoc();
178  if (isSpelledInSource(L, SM))
179  return SM.getSpellingLoc(L);
180  return SM.getExpansionLoc(L);
181 }
182 
183 std::string printQualifiedName(const NamedDecl &ND) {
184  std::string QName;
185  llvm::raw_string_ostream OS(QName);
186  PrintingPolicy Policy(ND.getASTContext().getLangOpts());
187  // Note that inline namespaces are treated as transparent scopes. This
188  // reflects the way they're most commonly used for lookup. Ideally we'd
189  // include them, but at query time it's hard to find all the inline
190  // namespaces to query: the preamble doesn't have a dedicated list.
191  Policy.SuppressUnwrittenScope = true;
192  // (unnamed struct), not (unnamed struct at /path/to/foo.cc:42:1).
193  // In clangd, context is usually available and paths are mostly noise.
194  Policy.AnonymousTagLocations = false;
195  ND.printQualifiedName(OS, Policy);
196  OS.flush();
197  assert(!StringRef(QName).startswith("::"));
198  return QName;
199 }
200 
201 static bool isAnonymous(const DeclarationName &N) {
202  return N.isIdentifier() && !N.getAsIdentifierInfo();
203 }
204 
205 NestedNameSpecifierLoc getQualifierLoc(const NamedDecl &ND) {
206  if (auto *V = llvm::dyn_cast<DeclaratorDecl>(&ND))
207  return V->getQualifierLoc();
208  if (auto *T = llvm::dyn_cast<TagDecl>(&ND))
209  return T->getQualifierLoc();
210  return NestedNameSpecifierLoc();
211 }
212 
213 std::string printUsingNamespaceName(const ASTContext &Ctx,
214  const UsingDirectiveDecl &D) {
215  PrintingPolicy PP(Ctx.getLangOpts());
216  std::string Name;
217  llvm::raw_string_ostream Out(Name);
218 
219  if (auto *Qual = D.getQualifier())
220  Qual->print(Out, PP);
221  D.getNominatedNamespaceAsWritten()->printName(Out);
222  return Out.str();
223 }
224 
225 std::string printName(const ASTContext &Ctx, const NamedDecl &ND) {
226  std::string Name;
227  llvm::raw_string_ostream Out(Name);
228  PrintingPolicy PP(Ctx.getLangOpts());
229  // We don't consider a class template's args part of the constructor name.
230  PP.SuppressTemplateArgsInCXXConstructors = true;
231 
232  // Handle 'using namespace'. They all have the same name - <using-directive>.
233  if (auto *UD = llvm::dyn_cast<UsingDirectiveDecl>(&ND)) {
234  Out << "using namespace ";
235  if (auto *Qual = UD->getQualifier())
236  Qual->print(Out, PP);
237  UD->getNominatedNamespaceAsWritten()->printName(Out);
238  return Out.str();
239  }
240 
241  if (isAnonymous(ND.getDeclName())) {
242  // Come up with a presentation for an anonymous entity.
243  if (isa<NamespaceDecl>(ND))
244  return "(anonymous namespace)";
245  if (auto *Cls = llvm::dyn_cast<RecordDecl>(&ND)) {
246  if (Cls->isLambda())
247  return "(lambda)";
248  return ("(anonymous " + Cls->getKindName() + ")").str();
249  }
250  if (isa<EnumDecl>(ND))
251  return "(anonymous enum)";
252  return "(anonymous)";
253  }
254 
255  // Print nested name qualifier if it was written in the source code.
256  if (auto *Qualifier = getQualifierLoc(ND).getNestedNameSpecifier())
257  Qualifier->print(Out, PP);
258  // Print the name itself.
259  ND.getDeclName().print(Out, PP);
260  // Print template arguments.
262 
263  return Out.str();
264 }
265 
266 std::string printTemplateSpecializationArgs(const NamedDecl &ND) {
267  std::string TemplateArgs;
268  llvm::raw_string_ostream OS(TemplateArgs);
269  PrintingPolicy Policy(ND.getASTContext().getLangOpts());
270  if (llvm::Optional<llvm::ArrayRef<TemplateArgumentLoc>> Args =
271  getTemplateSpecializationArgLocs(ND)) {
272  printTemplateArgumentList(OS, *Args, Policy);
273  } else if (auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) {
274  if (const TypeSourceInfo *TSI = Cls->getTypeAsWritten()) {
275  // ClassTemplateSpecializationDecls do not contain
276  // TemplateArgumentTypeLocs, they only have TemplateArgumentTypes. So we
277  // create a new argument location list from TypeSourceInfo.
278  auto STL = TSI->getTypeLoc().getAs<TemplateSpecializationTypeLoc>();
279  llvm::SmallVector<TemplateArgumentLoc> ArgLocs;
280  ArgLocs.reserve(STL.getNumArgs());
281  for (unsigned I = 0; I < STL.getNumArgs(); ++I)
282  ArgLocs.push_back(STL.getArgLoc(I));
283  printTemplateArgumentList(OS, ArgLocs, Policy);
284  } else {
285  // FIXME: Fix cases when getTypeAsWritten returns null inside clang AST,
286  // e.g. friend decls. Currently we fallback to Template Arguments without
287  // location information.
288  printTemplateArgumentList(OS, Cls->getTemplateArgs().asArray(), Policy);
289  }
290  }
291  OS.flush();
292  return TemplateArgs;
293 }
294 
295 std::string printNamespaceScope(const DeclContext &DC) {
296  for (const auto *Ctx = &DC; Ctx != nullptr; Ctx = Ctx->getParent())
297  if (const auto *NS = dyn_cast<NamespaceDecl>(Ctx))
298  if (!NS->isAnonymousNamespace() && !NS->isInlineNamespace())
299  return printQualifiedName(*NS) + "::";
300  return "";
301 }
302 
303 static llvm::StringRef
304 getNameOrErrForObjCInterface(const ObjCInterfaceDecl *ID) {
305  return ID ? ID->getName() : "<<error-type>>";
306 }
307 
308 std::string printObjCMethod(const ObjCMethodDecl &Method) {
309  std::string Name;
310  llvm::raw_string_ostream OS(Name);
311 
312  OS << (Method.isInstanceMethod() ? '-' : '+') << '[';
313 
314  // Should always be true.
315  if (const ObjCContainerDecl *C =
316  dyn_cast<ObjCContainerDecl>(Method.getDeclContext()))
317  OS << printObjCContainer(*C);
318 
319  Method.getSelector().print(OS << ' ');
320  if (Method.isVariadic())
321  OS << ", ...";
322 
323  OS << ']';
324  OS.flush();
325  return Name;
326 }
327 
328 std::string printObjCContainer(const ObjCContainerDecl &C) {
329  if (const ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(&C)) {
330  std::string Name;
331  llvm::raw_string_ostream OS(Name);
332  const ObjCInterfaceDecl *Class = Category->getClassInterface();
333  OS << getNameOrErrForObjCInterface(Class) << '(' << Category->getName()
334  << ')';
335  OS.flush();
336  return Name;
337  }
338  if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(&C)) {
339  std::string Name;
340  llvm::raw_string_ostream OS(Name);
341  const ObjCInterfaceDecl *Class = CID->getClassInterface();
342  OS << getNameOrErrForObjCInterface(Class) << '(' << CID->getName() << ')';
343  OS.flush();
344  return Name;
345  }
346  return C.getNameAsString();
347 }
348 
350  llvm::SmallString<128> USR;
351  if (index::generateUSRForDecl(D, USR))
352  return {};
353  return SymbolID(USR);
354 }
355 
356 SymbolID getSymbolID(const llvm::StringRef MacroName, const MacroInfo *MI,
357  const SourceManager &SM) {
358  if (MI == nullptr)
359  return {};
360  llvm::SmallString<128> USR;
361  if (index::generateUSRForMacro(MacroName, MI->getDefinitionLoc(), SM, USR))
362  return {};
363  return SymbolID(USR);
364 }
365 
366 const ObjCImplDecl *getCorrespondingObjCImpl(const ObjCContainerDecl *D) {
367  if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(D))
368  return ID->getImplementation();
369  if (const auto *CD = dyn_cast<ObjCCategoryDecl>(D)) {
370  if (CD->IsClassExtension()) {
371  if (const auto *ID = CD->getClassInterface())
372  return ID->getImplementation();
373  return nullptr;
374  }
375  return CD->getImplementation();
376  }
377  return nullptr;
378 }
379 
380 std::string printType(const QualType QT, const DeclContext &CurContext,
381  const llvm::StringRef Placeholder) {
382  std::string Result;
383  llvm::raw_string_ostream OS(Result);
384  PrintingPolicy PP(CurContext.getParentASTContext().getPrintingPolicy());
385  PP.SuppressTagKeyword = true;
386  PP.SuppressUnwrittenScope = true;
387 
388  class PrintCB : public PrintingCallbacks {
389  public:
390  PrintCB(const DeclContext *CurContext) : CurContext(CurContext) {}
391  virtual ~PrintCB() {}
392  bool isScopeVisible(const DeclContext *DC) const override {
393  return DC->Encloses(CurContext);
394  }
395 
396  private:
397  const DeclContext *CurContext;
398  };
399  PrintCB PCB(&CurContext);
400  PP.Callbacks = &PCB;
401 
402  QT.print(OS, PP, Placeholder);
403  return OS.str();
404 }
405 
406 bool hasReservedName(const Decl &D) {
407  if (const auto *ND = llvm::dyn_cast<NamedDecl>(&D))
408  if (const auto *II = ND->getIdentifier())
409  return isReservedName(II->getName());
410  return false;
411 }
412 
413 bool hasReservedScope(const DeclContext &DC) {
414  for (const DeclContext *D = &DC; D; D = D->getParent()) {
415  if (D->isTransparentContext() || D->isInlineNamespace())
416  continue;
417  if (const auto *ND = llvm::dyn_cast<NamedDecl>(D))
418  if (hasReservedName(*ND))
419  return true;
420  }
421  return false;
422 }
423 
424 QualType declaredType(const TypeDecl *D) {
425  if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D))
426  if (const auto *TSI = CTSD->getTypeAsWritten())
427  return TSI->getType();
428  return D->getASTContext().getTypeDeclType(D);
429 }
430 
431 namespace {
432 /// Computes the deduced type at a given location by visiting the relevant
433 /// nodes. We use this to display the actual type when hovering over an "auto"
434 /// keyword or "decltype()" expression.
435 /// FIXME: This could have been a lot simpler by visiting AutoTypeLocs but it
436 /// seems that the AutoTypeLocs that can be visited along with their AutoType do
437 /// not have the deduced type set. Instead, we have to go to the appropriate
438 /// DeclaratorDecl/FunctionDecl and work our back to the AutoType that does have
439 /// a deduced type set. The AST should be improved to simplify this scenario.
440 class DeducedTypeVisitor : public RecursiveASTVisitor<DeducedTypeVisitor> {
441  SourceLocation SearchedLocation;
442 
443 public:
444  DeducedTypeVisitor(SourceLocation SearchedLocation)
445  : SearchedLocation(SearchedLocation) {}
446 
447  // Handle auto initializers:
448  //- auto i = 1;
449  //- decltype(auto) i = 1;
450  //- auto& i = 1;
451  //- auto* i = &a;
452  bool VisitDeclaratorDecl(DeclaratorDecl *D) {
453  if (!D->getTypeSourceInfo() ||
454  D->getTypeSourceInfo()->getTypeLoc().getBeginLoc() != SearchedLocation)
455  return true;
456 
457  if (auto *AT = D->getType()->getContainedAutoType()) {
458  DeducedType = AT->desugar();
459  }
460  return true;
461  }
462 
463  // Handle auto return types:
464  //- auto foo() {}
465  //- auto& foo() {}
466  //- auto foo() -> int {}
467  //- auto foo() -> decltype(1+1) {}
468  //- operator auto() const { return 10; }
469  bool VisitFunctionDecl(FunctionDecl *D) {
470  if (!D->getTypeSourceInfo())
471  return true;
472  // Loc of auto in return type (c++14).
473  auto CurLoc = D->getReturnTypeSourceRange().getBegin();
474  // Loc of "auto" in operator auto()
475  if (CurLoc.isInvalid() && isa<CXXConversionDecl>(D))
476  CurLoc = D->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
477  // Loc of "auto" in function with trailing return type (c++11).
478  if (CurLoc.isInvalid())
479  CurLoc = D->getSourceRange().getBegin();
480  if (CurLoc != SearchedLocation)
481  return true;
482 
483  const AutoType *AT = D->getReturnType()->getContainedAutoType();
484  if (AT && !AT->getDeducedType().isNull()) {
485  DeducedType = AT->getDeducedType();
486  } else if (auto *DT = dyn_cast<DecltypeType>(D->getReturnType())) {
487  // auto in a trailing return type just points to a DecltypeType and
488  // getContainedAutoType does not unwrap it.
489  if (!DT->getUnderlyingType().isNull())
490  DeducedType = DT->getUnderlyingType();
491  } else if (!D->getReturnType().isNull()) {
492  DeducedType = D->getReturnType();
493  }
494  return true;
495  }
496 
497  // Handle non-auto decltype, e.g.:
498  // - auto foo() -> decltype(expr) {}
499  // - decltype(expr);
500  bool VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
501  if (TL.getBeginLoc() != SearchedLocation)
502  return true;
503 
504  // A DecltypeType's underlying type can be another DecltypeType! E.g.
505  // int I = 0;
506  // decltype(I) J = I;
507  // decltype(J) K = J;
508  const DecltypeType *DT = dyn_cast<DecltypeType>(TL.getTypePtr());
509  while (DT && !DT->getUnderlyingType().isNull()) {
510  DeducedType = DT->getUnderlyingType();
511  DT = dyn_cast<DecltypeType>(DeducedType.getTypePtr());
512  }
513  return true;
514  }
515 
516  // Handle functions/lambdas with `auto` typed parameters.
517  // We deduce the type if there's exactly one instantiation visible.
518  bool VisitParmVarDecl(ParmVarDecl *PVD) {
519  if (!PVD->getType()->isDependentType())
520  return true;
521  // 'auto' here does not name an AutoType, but an implicit template param.
522  TemplateTypeParmTypeLoc Auto =
523  getContainedAutoParamType(PVD->getTypeSourceInfo()->getTypeLoc());
524  if (Auto.isNull() || Auto.getNameLoc() != SearchedLocation)
525  return true;
526 
527  // We expect the TTP to be attached to this function template.
528  // Find the template and the param index.
529  auto *Templated = llvm::dyn_cast<FunctionDecl>(PVD->getDeclContext());
530  if (!Templated)
531  return true;
532  auto *FTD = Templated->getDescribedFunctionTemplate();
533  if (!FTD)
534  return true;
535  int ParamIndex = paramIndex(*FTD, *Auto.getDecl());
536  if (ParamIndex < 0) {
537  assert(false && "auto TTP is not from enclosing function?");
538  return true;
539  }
540 
541  // Now find the instantiation and the deduced template type arg.
542  auto *Instantiation =
543  llvm::dyn_cast_or_null<FunctionDecl>(getOnlyInstantiation(Templated));
544  if (!Instantiation)
545  return true;
546  const auto *Args = Instantiation->getTemplateSpecializationArgs();
547  if (Args->size() != FTD->getTemplateParameters()->size())
548  return true; // no weird variadic stuff
549  DeducedType = Args->get(ParamIndex).getAsType();
550  return true;
551  }
552 
553  static int paramIndex(const TemplateDecl &TD, NamedDecl &Param) {
554  unsigned I = 0;
555  for (auto *ND : *TD.getTemplateParameters()) {
556  if (&Param == ND)
557  return I;
558  ++I;
559  }
560  return -1;
561  }
562 
563  QualType DeducedType;
564 };
565 } // namespace
566 
567 llvm::Optional<QualType> getDeducedType(ASTContext &ASTCtx,
568  SourceLocation Loc) {
569  if (!Loc.isValid())
570  return {};
571  DeducedTypeVisitor V(Loc);
572  V.TraverseAST(ASTCtx);
573  if (V.DeducedType.isNull())
574  return llvm::None;
575  return V.DeducedType;
576 }
577 
578 TemplateTypeParmTypeLoc getContainedAutoParamType(TypeLoc TL) {
579  if (auto QTL = TL.getAs<QualifiedTypeLoc>())
580  return getContainedAutoParamType(QTL.getUnqualifiedLoc());
581  if (llvm::isa<PointerType, ReferenceType, ParenType>(TL.getTypePtr()))
582  return getContainedAutoParamType(TL.getNextTypeLoc());
583  if (auto FTL = TL.getAs<FunctionTypeLoc>())
584  return getContainedAutoParamType(FTL.getReturnLoc());
585  if (auto TTPTL = TL.getAs<TemplateTypeParmTypeLoc>()) {
586  if (TTPTL.getTypePtr()->getDecl()->isImplicit())
587  return TTPTL;
588  }
589  return {};
590 }
591 
592 template <typename TemplateDeclTy>
593 static NamedDecl *getOnlyInstantiationImpl(TemplateDeclTy *TD) {
594  NamedDecl *Only = nullptr;
595  for (auto *Spec : TD->specializations()) {
596  if (Spec->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
597  continue;
598  if (Only != nullptr)
599  return nullptr;
600  Only = Spec;
601  }
602  return Only;
603 }
604 
605 NamedDecl *getOnlyInstantiation(NamedDecl *TemplatedDecl) {
606  if (TemplateDecl *TD = TemplatedDecl->getDescribedTemplate()) {
607  if (auto *CTD = llvm::dyn_cast<ClassTemplateDecl>(TD))
608  return getOnlyInstantiationImpl(CTD);
609  if (auto *FTD = llvm::dyn_cast<FunctionTemplateDecl>(TD))
610  return getOnlyInstantiationImpl(FTD);
611  if (auto *VTD = llvm::dyn_cast<VarTemplateDecl>(TD))
612  return getOnlyInstantiationImpl(VTD);
613  }
614  return nullptr;
615 }
616 
617 std::vector<const Attr *> getAttributes(const DynTypedNode &N) {
618  std::vector<const Attr *> Result;
619  if (const auto *TL = N.get<TypeLoc>()) {
620  for (AttributedTypeLoc ATL = TL->getAs<AttributedTypeLoc>(); !ATL.isNull();
621  ATL = ATL.getModifiedLoc().getAs<AttributedTypeLoc>()) {
622  if (const Attr *A = ATL.getAttr())
623  Result.push_back(A);
624  assert(!ATL.getModifiedLoc().isNull());
625  }
626  }
627  if (const auto *S = N.get<AttributedStmt>()) {
628  for (; S != nullptr; S = dyn_cast<AttributedStmt>(S->getSubStmt()))
629  for (const Attr *A : S->getAttrs())
630  if (A)
631  Result.push_back(A);
632  }
633  if (const auto *D = N.get<Decl>()) {
634  for (const Attr *A : D->attrs())
635  if (A)
636  Result.push_back(A);
637  }
638  return Result;
639 }
640 
641 std::string getQualification(ASTContext &Context,
642  const DeclContext *DestContext,
643  SourceLocation InsertionPoint,
644  const NamedDecl *ND) {
645  auto VisibleNamespaceDecls =
646  getUsingNamespaceDirectives(DestContext, InsertionPoint);
647  return getQualification(
648  Context, DestContext, ND->getDeclContext(),
649  [&](NestedNameSpecifier *NNS) {
650  if (NNS->getKind() != NestedNameSpecifier::Namespace)
651  return false;
652  const auto *CanonNSD = NNS->getAsNamespace()->getCanonicalDecl();
653  return llvm::any_of(VisibleNamespaceDecls,
654  [CanonNSD](const NamespaceDecl *NSD) {
655  return NSD->getCanonicalDecl() == CanonNSD;
656  });
657  });
658 }
659 
660 std::string getQualification(ASTContext &Context,
661  const DeclContext *DestContext,
662  const NamedDecl *ND,
663  llvm::ArrayRef<std::string> VisibleNamespaces) {
664  for (llvm::StringRef NS : VisibleNamespaces) {
665  assert(NS.endswith("::"));
666  (void)NS;
667  }
668  return getQualification(
669  Context, DestContext, ND->getDeclContext(),
670  [&](NestedNameSpecifier *NNS) {
671  return llvm::any_of(VisibleNamespaces, [&](llvm::StringRef Namespace) {
672  std::string NS;
673  llvm::raw_string_ostream OS(NS);
674  NNS->print(OS, Context.getPrintingPolicy());
675  return OS.str() == Namespace;
676  });
677  });
678 }
679 
680 bool hasUnstableLinkage(const Decl *D) {
681  // Linkage of a ValueDecl depends on the type.
682  // If that's not deduced yet, deducing it may change the linkage.
683  auto *VD = llvm::dyn_cast_or_null<ValueDecl>(D);
684  return VD && !VD->getType().isNull() && VD->getType()->isUndeducedType();
685 }
686 
687 bool isDeeplyNested(const Decl *D, unsigned MaxDepth) {
688  size_t ContextDepth = 0;
689  for (auto *Ctx = D->getDeclContext(); Ctx && !Ctx->isTranslationUnit();
690  Ctx = Ctx->getParent()) {
691  if (++ContextDepth == MaxDepth)
692  return true;
693  }
694  return false;
695 }
696 
697 namespace {
698 
699 // returns true for `X` in `template <typename... X> void foo()`
700 bool isTemplateTypeParameterPack(NamedDecl *D) {
701  if (const auto *TTPD = dyn_cast<TemplateTypeParmDecl>(D)) {
702  return TTPD->isParameterPack();
703  }
704  return false;
705 }
706 
707 // Returns the template parameter pack type from an instantiated function
708 // template, if it exists, nullptr otherwise.
709 const TemplateTypeParmType *getFunctionPackType(const FunctionDecl *Callee) {
710  if (const auto *TemplateDecl = Callee->getPrimaryTemplate()) {
711  auto TemplateParams = TemplateDecl->getTemplateParameters()->asArray();
712  // find the template parameter pack from the back
713  const auto It = std::find_if(TemplateParams.rbegin(), TemplateParams.rend(),
714  isTemplateTypeParameterPack);
715  if (It != TemplateParams.rend()) {
716  const auto *TTPD = dyn_cast<TemplateTypeParmDecl>(*It);
717  return TTPD->getTypeForDecl()->castAs<TemplateTypeParmType>();
718  }
719  }
720  return nullptr;
721 }
722 
723 // Returns the template parameter pack type that this parameter was expanded
724 // from (if in the Args... or Args&... or Args&&... form), if this is the case,
725 // nullptr otherwise.
726 const TemplateTypeParmType *getUnderylingPackType(const ParmVarDecl *Param) {
727  const auto *PlainType = Param->getType().getTypePtr();
728  if (auto *RT = dyn_cast<ReferenceType>(PlainType))
729  PlainType = RT->getPointeeTypeAsWritten().getTypePtr();
730  if (const auto *SubstType = dyn_cast<SubstTemplateTypeParmType>(PlainType)) {
731  const auto *ReplacedParameter = SubstType->getReplacedParameter();
732  if (ReplacedParameter->isParameterPack()) {
733  return ReplacedParameter->getTypeForDecl()
734  ->castAs<TemplateTypeParmType>();
735  }
736  }
737  return nullptr;
738 }
739 
740 // This visitor walks over the body of an instantiated function template.
741 // The template accepts a parameter pack and the visitor records whether
742 // the pack parameters were forwarded to another call. For example, given:
743 //
744 // template <typename T, typename... Args>
745 // auto make_unique(Args... args) {
746 // return unique_ptr<T>(new T(args...));
747 // }
748 //
749 // When called as `make_unique<std::string>(2, 'x')` this yields a function
750 // `make_unique<std::string, int, char>` with two parameters.
751 // The visitor records that those two parameters are forwarded to the
752 // `constructor std::string(int, char);`.
753 //
754 // This information is recorded in the `ForwardingInfo` split into fully
755 // resolved parameters (passed as argument to a parameter that is not an
756 // expanded template type parameter pack) and forwarding parameters (passed to a
757 // parameter that is an expanded template type parameter pack).
758 class ForwardingCallVisitor
759  : public RecursiveASTVisitor<ForwardingCallVisitor> {
760 public:
761  ForwardingCallVisitor(ArrayRef<const ParmVarDecl *> Parameters)
762  : Parameters{Parameters}, PackType{getUnderylingPackType(
763  Parameters.front())} {}
764 
765  bool VisitCallExpr(CallExpr *E) {
766  auto *Callee = getCalleeDeclOrUniqueOverload(E);
767  if (Callee) {
768  handleCall(Callee, E->arguments());
769  }
770  return !Info.has_value();
771  }
772 
773  bool VisitCXXConstructExpr(CXXConstructExpr *E) {
774  auto *Callee = E->getConstructor();
775  if (Callee) {
776  handleCall(Callee, E->arguments());
777  }
778  return !Info.has_value();
779  }
780 
781  // The expanded parameter pack to be resolved
782  ArrayRef<const ParmVarDecl *> Parameters;
783  // The type of the parameter pack
784  const TemplateTypeParmType *PackType;
785 
786  struct ForwardingInfo {
787  // If the parameters were resolved to another FunctionDecl, these are its
788  // first non-variadic parameters (i.e. the first entries of the parameter
789  // pack that are passed as arguments bound to a non-pack parameter.)
790  ArrayRef<const ParmVarDecl *> Head;
791  // If the parameters were resolved to another FunctionDecl, these are its
792  // variadic parameters (i.e. the entries of the parameter pack that are
793  // passed as arguments bound to a pack parameter.)
794  ArrayRef<const ParmVarDecl *> Pack;
795  // If the parameters were resolved to another FunctionDecl, these are its
796  // last non-variadic parameters (i.e. the last entries of the parameter pack
797  // that are passed as arguments bound to a non-pack parameter.)
798  ArrayRef<const ParmVarDecl *> Tail;
799  // If the parameters were resolved to another forwarding FunctionDecl, this
800  // is it.
801  Optional<FunctionDecl *> PackTarget;
802  };
803 
804  // The output of this visitor
805  Optional<ForwardingInfo> Info;
806 
807 private:
808  // inspects the given callee with the given args to check whether it
809  // contains Parameters, and sets Info accordingly.
810  void handleCall(FunctionDecl *Callee, typename CallExpr::arg_range Args) {
811  // Skip functions with less parameters, they can't be the target.
812  if (Callee->parameters().size() < Parameters.size())
813  return;
814  if (llvm::any_of(Args,
815  [](const Expr *E) { return isa<PackExpansionExpr>(E); })) {
816  return;
817  }
818  auto PackLocation = findPack(Args);
819  if (!PackLocation)
820  return;
821  ArrayRef<ParmVarDecl *> MatchingParams =
822  Callee->parameters().slice(*PackLocation, Parameters.size());
823  // Check whether the function has a parameter pack as the last template
824  // parameter
825  if (const auto *TTPT = getFunctionPackType(Callee)) {
826  // In this case: Separate the parameters into head, pack and tail
827  auto IsExpandedPack = [&](const ParmVarDecl *P) {
828  return getUnderylingPackType(P) == TTPT;
829  };
830  ForwardingInfo FI;
831  FI.Head = MatchingParams.take_until(IsExpandedPack);
832  FI.Pack =
833  MatchingParams.drop_front(FI.Head.size()).take_while(IsExpandedPack);
834  FI.Tail = MatchingParams.drop_front(FI.Head.size() + FI.Pack.size());
835  FI.PackTarget = Callee;
836  Info = FI;
837  return;
838  }
839  // Default case: assume all parameters were fully resolved
840  ForwardingInfo FI;
841  FI.Head = MatchingParams;
842  Info = FI;
843  }
844 
845  // Returns the beginning of the expanded pack represented by Parameters
846  // in the given arguments, if it is there.
847  llvm::Optional<size_t> findPack(typename CallExpr::arg_range Args) {
848  // find the argument directly referring to the first parameter
849  assert(Parameters.size() <= static_cast<size_t>(llvm::size(Args)));
850  for (auto Begin = Args.begin(), End = Args.end() - Parameters.size() + 1;
851  Begin != End; ++Begin) {
852  if (const auto *RefArg = unwrapForward(*Begin)) {
853  if (Parameters.front() != RefArg->getDecl())
854  continue;
855  // Check that this expands all the way until the last parameter.
856  // It's enough to look at the last parameter, because it isn't possible
857  // to expand without expanding all of them.
858  auto ParamEnd = Begin + Parameters.size() - 1;
859  RefArg = unwrapForward(*ParamEnd);
860  if (!RefArg || Parameters.back() != RefArg->getDecl())
861  continue;
862  return std::distance(Args.begin(), Begin);
863  }
864  }
865  return llvm::None;
866  }
867 
868  static FunctionDecl *getCalleeDeclOrUniqueOverload(CallExpr *E) {
869  Decl *CalleeDecl = E->getCalleeDecl();
870  auto *Callee = dyn_cast_or_null<FunctionDecl>(CalleeDecl);
871  if (!Callee) {
872  if (auto *Lookup = dyn_cast<UnresolvedLookupExpr>(E->getCallee())) {
873  Callee = resolveOverload(Lookup, E);
874  }
875  }
876  // Ignore the callee if the number of arguments is wrong (deal with va_args)
877  if (Callee && Callee->getNumParams() == E->getNumArgs())
878  return Callee;
879  return nullptr;
880  }
881 
882  static FunctionDecl *resolveOverload(UnresolvedLookupExpr *Lookup,
883  CallExpr *E) {
884  FunctionDecl *MatchingDecl = nullptr;
885  if (!Lookup->requiresADL()) {
886  // Check whether there is a single overload with this number of
887  // parameters
888  for (auto *Candidate : Lookup->decls()) {
889  if (auto *FuncCandidate = dyn_cast_or_null<FunctionDecl>(Candidate)) {
890  if (FuncCandidate->getNumParams() == E->getNumArgs()) {
891  if (MatchingDecl) {
892  // there are multiple candidates - abort
893  return nullptr;
894  }
895  MatchingDecl = FuncCandidate;
896  }
897  }
898  }
899  }
900  return MatchingDecl;
901  }
902 
903  // Tries to get to the underlying argument by unwrapping implicit nodes and
904  // std::forward.
905  static const DeclRefExpr *unwrapForward(const Expr *E) {
906  E = E->IgnoreImplicitAsWritten();
907  // There might be an implicit copy/move constructor call on top of the
908  // forwarded arg.
909  // FIXME: Maybe mark implicit calls in the AST to properly filter here.
910  if (const auto *Const = dyn_cast<CXXConstructExpr>(E))
911  if (Const->getConstructor()->isCopyOrMoveConstructor())
912  E = Const->getArg(0)->IgnoreImplicitAsWritten();
913  if (const auto *Call = dyn_cast<CallExpr>(E)) {
914  const auto Callee = Call->getBuiltinCallee();
915  if (Callee == Builtin::BIforward) {
916  return dyn_cast<DeclRefExpr>(
917  Call->getArg(0)->IgnoreImplicitAsWritten());
918  }
919  }
920  return dyn_cast<DeclRefExpr>(E);
921  }
922 };
923 
924 } // namespace
925 
926 SmallVector<const ParmVarDecl *>
927 resolveForwardingParameters(const FunctionDecl *D, unsigned MaxDepth) {
928  auto Parameters = D->parameters();
929  // If the function has a template parameter pack
930  if (const auto *TTPT = getFunctionPackType(D)) {
931  // Split the parameters into head, pack and tail
932  auto IsExpandedPack = [TTPT](const ParmVarDecl *P) {
933  return getUnderylingPackType(P) == TTPT;
934  };
935  ArrayRef<const ParmVarDecl *> Head = Parameters.take_until(IsExpandedPack);
936  ArrayRef<const ParmVarDecl *> Pack =
937  Parameters.drop_front(Head.size()).take_while(IsExpandedPack);
938  ArrayRef<const ParmVarDecl *> Tail =
939  Parameters.drop_front(Head.size() + Pack.size());
940  SmallVector<const ParmVarDecl *> Result(Parameters.size());
941  // Fill in non-pack parameters
942  auto HeadIt = std::copy(Head.begin(), Head.end(), Result.begin());
943  auto TailIt = std::copy(Tail.rbegin(), Tail.rend(), Result.rbegin());
944  // Recurse on pack parameters
945  size_t Depth = 0;
946  const FunctionDecl *CurrentFunction = D;
947  llvm::SmallSet<const FunctionTemplateDecl *, 4> SeenTemplates;
948  if (const auto *Template = D->getPrimaryTemplate()) {
949  SeenTemplates.insert(Template);
950  }
951  while (!Pack.empty() && CurrentFunction && Depth < MaxDepth) {
952  // Find call expressions involving the pack
953  ForwardingCallVisitor V{Pack};
954  V.TraverseStmt(CurrentFunction->getBody());
955  if (!V.Info) {
956  break;
957  }
958  // If we found something: Fill in non-pack parameters
959  auto Info = V.Info.value();
960  HeadIt = std::copy(Info.Head.begin(), Info.Head.end(), HeadIt);
961  TailIt = std::copy(Info.Tail.rbegin(), Info.Tail.rend(), TailIt);
962  // Prepare next recursion level
963  Pack = Info.Pack;
964  CurrentFunction = Info.PackTarget.value_or(nullptr);
965  Depth++;
966  // If we are recursing into a previously encountered function: Abort
967  if (CurrentFunction) {
968  if (const auto *Template = CurrentFunction->getPrimaryTemplate()) {
969  bool NewFunction = SeenTemplates.insert(Template).second;
970  if (!NewFunction) {
971  return {Parameters.begin(), Parameters.end()};
972  }
973  }
974  }
975  }
976  // Fill in the remaining unresolved pack parameters
977  HeadIt = std::copy(Pack.begin(), Pack.end(), HeadIt);
978  assert(TailIt.base() == HeadIt);
979  return Result;
980  }
981  return {Parameters.begin(), Parameters.end()};
982 }
983 
984 bool isExpandedFromParameterPack(const ParmVarDecl *D) {
985  return getUnderylingPackType(D) != nullptr;
986 }
987 
988 } // namespace clangd
989 } // namespace clang
Pack
ArrayRef< const ParmVarDecl * > Pack
Definition: AST.cpp:794
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
Tail
ArrayRef< const ParmVarDecl * > Tail
Definition: AST.cpp:798
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:680
E
const Expr * E
Definition: AvoidBindCheck.cpp:88
clang::clangd::declaredType
QualType declaredType(const TypeDecl *D)
Definition: AST.cpp:424
Head
ArrayRef< const ParmVarDecl * > Head
Definition: AST.cpp:790
clang::clangd::isExpandedFromParameterPack
bool isExpandedFromParameterPack(const ParmVarDecl *D)
Checks whether D is instantiated from a function parameter pack whose type is a bare type parameter p...
Definition: AST.cpp:984
clang::doc::MD
static GeneratorRegistry::Add< MDGenerator > MD(MDGenerator::Format, "Generator for MD output.")
USR
std::string USR
Definition: SymbolInfoTests.cpp:25
clang::clangd::isImplicitTemplateInstantiation
bool isImplicitTemplateInstantiation(const NamedDecl *D)
Indicates if D is a template instantiation implicitly generated by the compiler, e....
Definition: AST.cpp:160
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:553
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:205
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:308
clang::clangd::printNamespaceScope
std::string printNamespaceScope(const DeclContext &DC)
Returns the first enclosing namespace scope starting from DC.
Definition: AST.cpp:295
clang::clangd::nameLocation
SourceLocation nameLocation(const clang::Decl &D, const SourceManager &SM)
Find the source location of the identifier for D.
Definition: AST.cpp:173
clang::clangd::resolveForwardingParameters
SmallVector< const ParmVarDecl * > resolveForwardingParameters(const FunctionDecl *D, unsigned MaxDepth)
Recursively resolves the parameters of a FunctionDecl that forwards its parameters to another functio...
Definition: AST.cpp:927
clang::clangd::getDeducedType
llvm::Optional< QualType > getDeducedType(ASTContext &ASTCtx, SourceLocation Loc)
Retrieves the deduced type at a given location (auto, decltype).
Definition: AST.cpp:567
clang::clangd::printType
std::string printType(const QualType QT, const DeclContext &CurContext, const llvm::StringRef Placeholder)
Returns a QualType as string.
Definition: AST.cpp:380
Info
Optional< ForwardingInfo > Info
Definition: AST.cpp:805
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:329
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:225
Decl
const FunctionDecl * Decl
Definition: AvoidBindCheck.cpp:100
PackTarget
Optional< FunctionDecl * > PackTarget
Definition: AST.cpp:801
clang::clangd::printQualifiedName
std::string printQualifiedName(const NamedDecl &ND)
Returns the qualified name of ND.
Definition: AST.cpp:183
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:266
clang::clangd::getOnlyInstantiation
NamedDecl * getOnlyInstantiation(NamedDecl *TemplatedDecl)
Definition: AST.cpp:605
clang::clangd::hasReservedScope
bool hasReservedScope(const DeclContext &DC)
Returns true if this scope would be written with a reserved name.
Definition: AST.cpp:413
clang::doc::SymbolID
std::array< uint8_t, 20 > SymbolID
Definition: Representation.h:31
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:660
clang::clangd::getContainedAutoParamType
TemplateTypeParmTypeLoc getContainedAutoParamType(TypeLoc TL)
Definition: AST.cpp:578
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:593
clang::clangd::getSymbolID
SymbolID getSymbolID(const Decl *D)
Gets the symbol ID for a declaration. Returned SymbolID might be null.
Definition: AST.cpp:349
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:641
DeducedType
QualType DeducedType
Definition: AST.cpp:563
clang::clangd::getCorrespondingObjCImpl
const ObjCImplDecl * getCorrespondingObjCImpl(const ObjCContainerDecl *D)
Return the corresponding implementation/definition for the given ObjC container if it has one,...
Definition: AST.cpp:366
clang::clangd::isAnonymous
static bool isAnonymous(const DeclarationName &N)
Definition: AST.cpp:201
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:687
Candidate
ExpectedMatch Candidate
Definition: FuzzyMatchTests.cpp:46
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
PackType
const TemplateTypeParmType * PackType
Definition: AST.cpp:784
clang::clangd::isExplicitTemplateSpecialization
bool isExplicitTemplateSpecialization(const NamedDecl *D)
Indicates if D is an explicit template specialization, e.g.
Definition: AST.cpp:164
clang::clangd::hasReservedName
bool hasReservedName(const Decl &D)
Returns true if this is a NamedDecl with a reserved name.
Definition: AST.cpp:406
clang::clangd::isImplementationDetail
bool isImplementationDetail(const Decl *D)
Returns true if the declaration is considered implementation detail based on heuristics.
Definition: AST.cpp:168
Parameters
ArrayRef< const ParmVarDecl * > Parameters
Definition: AST.cpp:782
clang::clangd::printObjCContainer
std::string printObjCContainer(const ObjCContainerDecl &C)
Print the Objective-C container name including categories, e.g. MyClass,.
Definition: AST.cpp:328
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:617
clang::clangd::getNameOrErrForObjCInterface
static llvm::StringRef getNameOrErrForObjCInterface(const ObjCInterfaceDecl *ID)
Definition: AST.cpp:304
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:213
AST.h
Const
bool Const
Definition: ExtractFunction.cpp:370