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 "FindTarget.h"
12 #include "SourceCode.h"
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 "clang/Lex/Lexer.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/ScopedPrinter.h"
35 #include "llvm/Support/raw_ostream.h"
36 #include <string>
37 #include <vector>
38 
39 namespace clang {
40 namespace clangd {
41 
42 namespace {
43 llvm::Optional<llvm::ArrayRef<TemplateArgumentLoc>>
44 getTemplateSpecializationArgLocs(const NamedDecl &ND) {
45   if (auto *Func = llvm::dyn_cast<FunctionDecl>(&ND)) {
46     if (const ASTTemplateArgumentListInfo *Args =
47             Func->getTemplateSpecializationArgsAsWritten())
48       return Args->arguments();
49   } else if (auto *Cls =
50                  llvm::dyn_cast<ClassTemplatePartialSpecializationDecl>(&ND)) {
51     if (auto *Args = Cls->getTemplateArgsAsWritten())
52       return Args->arguments();
53   } else if (auto *Var =
54                  llvm::dyn_cast<VarTemplatePartialSpecializationDecl>(&ND)) {
55     if (auto *Args = Var->getTemplateArgsAsWritten())
56       return Args->arguments();
57   } else if (auto *Var = llvm::dyn_cast<VarTemplateSpecializationDecl>(&ND))
58     return Var->getTemplateArgsInfo().arguments();
59   // We return None for ClassTemplateSpecializationDecls because it does not
60   // contain TemplateArgumentLoc information.
61   return llvm::None;
62 }
63 
64 template <class T>
65 bool isTemplateSpecializationKind(const NamedDecl *D,
66                                   TemplateSpecializationKind Kind) {
67   if (const auto *TD = dyn_cast<T>(D))
68     return TD->getTemplateSpecializationKind() == Kind;
69   return false;
70 }
71 
72 bool isTemplateSpecializationKind(const NamedDecl *D,
73                                   TemplateSpecializationKind Kind) {
74   return isTemplateSpecializationKind<FunctionDecl>(D, Kind) ||
75          isTemplateSpecializationKind<CXXRecordDecl>(D, Kind) ||
76          isTemplateSpecializationKind<VarDecl>(D, Kind);
77 }
78 
79 // Store all UsingDirectiveDecls in parent contexts of DestContext, that were
80 // introduced before InsertionPoint.
81 llvm::DenseSet<const NamespaceDecl *>
82 getUsingNamespaceDirectives(const DeclContext *DestContext,
83                             SourceLocation Until) {
84   const auto &SM = DestContext->getParentASTContext().getSourceManager();
85   llvm::DenseSet<const NamespaceDecl *> VisibleNamespaceDecls;
86   for (const auto *DC = DestContext; DC; DC = DC->getLookupParent()) {
87     for (const auto *D : DC->decls()) {
88       if (!SM.isWrittenInSameFile(D->getLocation(), Until) ||
89           !SM.isBeforeInTranslationUnit(D->getLocation(), Until))
90         continue;
91       if (auto *UDD = llvm::dyn_cast<UsingDirectiveDecl>(D))
92         VisibleNamespaceDecls.insert(
93             UDD->getNominatedNamespace()->getCanonicalDecl());
94     }
95   }
96   return VisibleNamespaceDecls;
97 }
98 
99 // Goes over all parents of SourceContext until we find a comman ancestor for
100 // DestContext and SourceContext. Any qualifier including and above common
101 // ancestor is redundant, therefore we stop at lowest common ancestor.
102 // In addition to that stops early whenever IsVisible returns true. This can be
103 // used to implement support for "using namespace" decls.
104 std::string
105 getQualification(ASTContext &Context, const DeclContext *DestContext,
106                  const DeclContext *SourceContext,
107                  llvm::function_ref<bool(NestedNameSpecifier *)> IsVisible) {
108   std::vector<const NestedNameSpecifier *> Parents;
109   bool ReachedNS = false;
110   for (const DeclContext *CurContext = SourceContext; CurContext;
111        CurContext = CurContext->getLookupParent()) {
112     // Stop once we reach a common ancestor.
113     if (CurContext->Encloses(DestContext))
114       break;
115 
116     NestedNameSpecifier *NNS = nullptr;
117     if (auto *TD = llvm::dyn_cast<TagDecl>(CurContext)) {
118       // There can't be any more tag parents after hitting a namespace.
119       assert(!ReachedNS);
120       NNS = NestedNameSpecifier::Create(Context, nullptr, false,
121                                         TD->getTypeForDecl());
122     } else {
123       ReachedNS = true;
124       auto *NSD = llvm::cast<NamespaceDecl>(CurContext);
125       NNS = NestedNameSpecifier::Create(Context, nullptr, NSD);
126       // Anonymous and inline namespace names are not spelled while qualifying a
127       // name, so skip those.
128       if (NSD->isAnonymousNamespace() || NSD->isInlineNamespace())
129         continue;
130     }
131     // Stop if this namespace is already visible at DestContext.
132     if (IsVisible(NNS))
133       break;
134 
135     Parents.push_back(NNS);
136   }
137 
138   // Go over name-specifiers in reverse order to create necessary qualification,
139   // since we stored inner-most parent first.
140   std::string Result;
141   llvm::raw_string_ostream OS(Result);
142   for (const auto *Parent : llvm::reverse(Parents))
143     Parent->print(OS, Context.getPrintingPolicy());
144   return OS.str();
145 }
146 
147 } // namespace
148 
149 bool isImplicitTemplateInstantiation(const NamedDecl *D) {
150   return isTemplateSpecializationKind(D, TSK_ImplicitInstantiation);
151 }
152 
153 bool isExplicitTemplateSpecialization(const NamedDecl *D) {
154   return isTemplateSpecializationKind(D, TSK_ExplicitSpecialization);
155 }
156 
157 bool isImplementationDetail(const Decl *D) {
158   return !isSpelledInSource(D->getLocation(),
159                             D->getASTContext().getSourceManager());
160 }
161 
162 SourceLocation nameLocation(const clang::Decl &D, const SourceManager &SM) {
163   auto L = D.getLocation();
164   if (isSpelledInSource(L, SM))
165     return SM.getSpellingLoc(L);
166   return SM.getExpansionLoc(L);
167 }
168 
169 std::string printQualifiedName(const NamedDecl &ND) {
170   std::string QName;
171   llvm::raw_string_ostream OS(QName);
172   PrintingPolicy Policy(ND.getASTContext().getLangOpts());
173   // Note that inline namespaces are treated as transparent scopes. This
174   // reflects the way they're most commonly used for lookup. Ideally we'd
175   // include them, but at query time it's hard to find all the inline
176   // namespaces to query: the preamble doesn't have a dedicated list.
177   Policy.SuppressUnwrittenScope = true;
178   ND.printQualifiedName(OS, Policy);
179   OS.flush();
180   assert(!StringRef(QName).startswith("::"));
181   return QName;
182 }
183 
184 static bool isAnonymous(const DeclarationName &N) {
185   return N.isIdentifier() && !N.getAsIdentifierInfo();
186 }
187 
188 NestedNameSpecifierLoc getQualifierLoc(const NamedDecl &ND) {
189   if (auto *V = llvm::dyn_cast<DeclaratorDecl>(&ND))
190     return V->getQualifierLoc();
191   if (auto *T = llvm::dyn_cast<TagDecl>(&ND))
192     return T->getQualifierLoc();
193   return NestedNameSpecifierLoc();
194 }
195 
196 std::string printUsingNamespaceName(const ASTContext &Ctx,
197                                     const UsingDirectiveDecl &D) {
198   PrintingPolicy PP(Ctx.getLangOpts());
199   std::string Name;
200   llvm::raw_string_ostream Out(Name);
201 
202   if (auto *Qual = D.getQualifier())
203     Qual->print(Out, PP);
204   D.getNominatedNamespaceAsWritten()->printName(Out);
205   return Out.str();
206 }
207 
208 std::string printName(const ASTContext &Ctx, const NamedDecl &ND) {
209   std::string Name;
210   llvm::raw_string_ostream Out(Name);
211   PrintingPolicy PP(Ctx.getLangOpts());
212   // We don't consider a class template's args part of the constructor name.
213   PP.SuppressTemplateArgsInCXXConstructors = true;
214 
215   // Handle 'using namespace'. They all have the same name - <using-directive>.
216   if (auto *UD = llvm::dyn_cast<UsingDirectiveDecl>(&ND)) {
217     Out << "using namespace ";
218     if (auto *Qual = UD->getQualifier())
219       Qual->print(Out, PP);
220     UD->getNominatedNamespaceAsWritten()->printName(Out);
221     return Out.str();
222   }
223 
224   if (isAnonymous(ND.getDeclName())) {
225     // Come up with a presentation for an anonymous entity.
226     if (isa<NamespaceDecl>(ND))
227       return "(anonymous namespace)";
228     if (auto *Cls = llvm::dyn_cast<RecordDecl>(&ND)) {
229       if (Cls->isLambda())
230         return "(lambda)";
231       return ("(anonymous " + Cls->getKindName() + ")").str();
232     }
233     if (isa<EnumDecl>(ND))
234       return "(anonymous enum)";
235     return "(anonymous)";
236   }
237 
238   // Print nested name qualifier if it was written in the source code.
239   if (auto *Qualifier = getQualifierLoc(ND).getNestedNameSpecifier())
240     Qualifier->print(Out, PP);
241   // Print the name itself.
242   ND.getDeclName().print(Out, PP);
243   // Print template arguments.
244   Out << printTemplateSpecializationArgs(ND);
245 
246   return Out.str();
247 }
248 
249 std::string printTemplateSpecializationArgs(const NamedDecl &ND) {
250   std::string TemplateArgs;
251   llvm::raw_string_ostream OS(TemplateArgs);
252   PrintingPolicy Policy(ND.getASTContext().getLangOpts());
253   if (llvm::Optional<llvm::ArrayRef<TemplateArgumentLoc>> Args =
254           getTemplateSpecializationArgLocs(ND)) {
255     printTemplateArgumentList(OS, *Args, Policy);
256   } else if (auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) {
257     if (const TypeSourceInfo *TSI = Cls->getTypeAsWritten()) {
258       // ClassTemplateSpecializationDecls do not contain
259       // TemplateArgumentTypeLocs, they only have TemplateArgumentTypes. So we
260       // create a new argument location list from TypeSourceInfo.
261       auto STL = TSI->getTypeLoc().getAs<TemplateSpecializationTypeLoc>();
262       llvm::SmallVector<TemplateArgumentLoc, 8> ArgLocs;
263       ArgLocs.reserve(STL.getNumArgs());
264       for (unsigned I = 0; I < STL.getNumArgs(); ++I)
265         ArgLocs.push_back(STL.getArgLoc(I));
266       printTemplateArgumentList(OS, ArgLocs, Policy);
267     } else {
268       // FIXME: Fix cases when getTypeAsWritten returns null inside clang AST,
269       // e.g. friend decls. Currently we fallback to Template Arguments without
270       // location information.
271       printTemplateArgumentList(OS, Cls->getTemplateArgs().asArray(), Policy);
272     }
273   }
274   OS.flush();
275   return TemplateArgs;
276 }
277 
278 std::string printNamespaceScope(const DeclContext &DC) {
279   for (const auto *Ctx = &DC; Ctx != nullptr; Ctx = Ctx->getParent())
280     if (const auto *NS = dyn_cast<NamespaceDecl>(Ctx))
281       if (!NS->isAnonymousNamespace() && !NS->isInlineNamespace())
282         return printQualifiedName(*NS) + "::";
283   return "";
284 }
285 
286 llvm::Optional<SymbolID> getSymbolID(const Decl *D) {
287   llvm::SmallString<128> USR;
288   if (index::generateUSRForDecl(D, USR))
289     return None;
290   return SymbolID(USR);
291 }
292 
293 llvm::Optional<SymbolID> getSymbolID(const llvm::StringRef MacroName,
294                                      const MacroInfo *MI,
295                                      const SourceManager &SM) {
296   if (MI == nullptr)
297     return None;
298   llvm::SmallString<128> USR;
299   if (index::generateUSRForMacro(MacroName, MI->getDefinitionLoc(), SM, USR))
300     return None;
301   return SymbolID(USR);
302 }
303 
304 // FIXME: This should be handled while printing underlying decls instead.
305 std::string printType(const QualType QT, const DeclContext &CurContext) {
306   std::string Result;
307   llvm::raw_string_ostream OS(Result);
308   auto Decls = explicitReferenceTargets(
309       ast_type_traits::DynTypedNode::create(QT), DeclRelation::Alias);
310   if (!Decls.empty())
311     OS << getQualification(CurContext.getParentASTContext(), &CurContext,
312                            Decls.front(),
313                            /*VisibleNamespaces=*/llvm::ArrayRef<std::string>{});
314   PrintingPolicy PP(CurContext.getParentASTContext().getPrintingPolicy());
315   PP.SuppressScope = true;
316   PP.SuppressTagKeyword = true;
317   QT.print(OS, PP);
318   return OS.str();
319 }
320 
321 QualType declaredType(const TypeDecl *D) {
322   if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D))
323     if (const auto *TSI = CTSD->getTypeAsWritten())
324       return TSI->getType();
325   return D->getASTContext().getTypeDeclType(D);
326 }
327 
328 namespace {
329 /// Computes the deduced type at a given location by visiting the relevant
330 /// nodes. We use this to display the actual type when hovering over an "auto"
331 /// keyword or "decltype()" expression.
332 /// FIXME: This could have been a lot simpler by visiting AutoTypeLocs but it
333 /// seems that the AutoTypeLocs that can be visited along with their AutoType do
334 /// not have the deduced type set. Instead, we have to go to the appropriate
335 /// DeclaratorDecl/FunctionDecl and work our back to the AutoType that does have
336 /// a deduced type set. The AST should be improved to simplify this scenario.
337 class DeducedTypeVisitor : public RecursiveASTVisitor<DeducedTypeVisitor> {
338   SourceLocation SearchedLocation;
339 
340 public:
341   DeducedTypeVisitor(SourceLocation SearchedLocation)
342       : SearchedLocation(SearchedLocation) {}
343 
344   // Handle auto initializers:
345   //- auto i = 1;
346   //- decltype(auto) i = 1;
347   //- auto& i = 1;
348   //- auto* i = &a;
349   bool VisitDeclaratorDecl(DeclaratorDecl *D) {
350     if (!D->getTypeSourceInfo() ||
351         D->getTypeSourceInfo()->getTypeLoc().getBeginLoc() != SearchedLocation)
352       return true;
353 
354     if (auto *AT = D->getType()->getContainedAutoType()) {
355       if (!AT->getDeducedType().isNull())
356         DeducedType = AT->getDeducedType();
357     }
358     return true;
359   }
360 
361   // Handle auto return types:
362   //- auto foo() {}
363   //- auto& foo() {}
364   //- auto foo() -> int {}
365   //- auto foo() -> decltype(1+1) {}
366   //- operator auto() const { return 10; }
367   bool VisitFunctionDecl(FunctionDecl *D) {
368     if (!D->getTypeSourceInfo())
369       return true;
370     // Loc of auto in return type (c++14).
371     auto CurLoc = D->getReturnTypeSourceRange().getBegin();
372     // Loc of "auto" in operator auto()
373     if (CurLoc.isInvalid() && dyn_cast<CXXConversionDecl>(D))
374       CurLoc = D->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
375     // Loc of "auto" in function with trailing return type (c++11).
376     if (CurLoc.isInvalid())
377       CurLoc = D->getSourceRange().getBegin();
378     if (CurLoc != SearchedLocation)
379       return true;
380 
381     const AutoType *AT = D->getReturnType()->getContainedAutoType();
382     if (AT && !AT->getDeducedType().isNull()) {
383       DeducedType = AT->getDeducedType();
384     } else if (auto DT = dyn_cast<DecltypeType>(D->getReturnType())) {
385       // auto in a trailing return type just points to a DecltypeType and
386       // getContainedAutoType does not unwrap it.
387       if (!DT->getUnderlyingType().isNull())
388         DeducedType = DT->getUnderlyingType();
389     } else if (!D->getReturnType().isNull()) {
390       DeducedType = D->getReturnType();
391     }
392     return true;
393   }
394 
395   // Handle non-auto decltype, e.g.:
396   // - auto foo() -> decltype(expr) {}
397   // - decltype(expr);
398   bool VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
399     if (TL.getBeginLoc() != SearchedLocation)
400       return true;
401 
402     // A DecltypeType's underlying type can be another DecltypeType! E.g.
403     //  int I = 0;
404     //  decltype(I) J = I;
405     //  decltype(J) K = J;
406     const DecltypeType *DT = dyn_cast<DecltypeType>(TL.getTypePtr());
407     while (DT && !DT->getUnderlyingType().isNull()) {
408       DeducedType = DT->getUnderlyingType();
409       DT = dyn_cast<DecltypeType>(DeducedType.getTypePtr());
410     }
411     return true;
412   }
413 
414   QualType DeducedType;
415 };
416 } // namespace
417 
418 llvm::Optional<QualType> getDeducedType(ASTContext &ASTCtx,
419                                         SourceLocation Loc) {
420   Token Tok;
421   // Only try to find a deduced type if the token is auto or decltype.
422   if (!Loc.isValid() ||
423       Lexer::getRawToken(Loc, Tok, ASTCtx.getSourceManager(),
424                          ASTCtx.getLangOpts(), false) ||
425       !Tok.is(tok::raw_identifier) ||
426       !(Tok.getRawIdentifier() == "auto" ||
427         Tok.getRawIdentifier() == "decltype")) {
428     return {};
429   }
430   DeducedTypeVisitor V(Loc);
431   V.TraverseAST(ASTCtx);
432   if (V.DeducedType.isNull())
433     return llvm::None;
434   return V.DeducedType;
435 }
436 
437 std::string getQualification(ASTContext &Context,
438                              const DeclContext *DestContext,
439                              SourceLocation InsertionPoint,
440                              const NamedDecl *ND) {
441   auto VisibleNamespaceDecls =
442       getUsingNamespaceDirectives(DestContext, InsertionPoint);
443   return getQualification(
444       Context, DestContext, ND->getDeclContext(),
445       [&](NestedNameSpecifier *NNS) {
446         if (NNS->getKind() != NestedNameSpecifier::Namespace)
447           return false;
448         const auto *CanonNSD = NNS->getAsNamespace()->getCanonicalDecl();
449         return llvm::any_of(VisibleNamespaceDecls,
450                             [CanonNSD](const NamespaceDecl *NSD) {
451                               return NSD->getCanonicalDecl() == CanonNSD;
452                             });
453       });
454 }
455 
456 std::string getQualification(ASTContext &Context,
457                              const DeclContext *DestContext,
458                              const NamedDecl *ND,
459                              llvm::ArrayRef<std::string> VisibleNamespaces) {
460   for (llvm::StringRef NS : VisibleNamespaces) {
461     assert(NS.endswith("::"));
462     (void)NS;
463   }
464   return getQualification(
465       Context, DestContext, ND->getDeclContext(),
466       [&](NestedNameSpecifier *NNS) {
467         return llvm::any_of(VisibleNamespaces, [&](llvm::StringRef Namespace) {
468           std::string NS;
469           llvm::raw_string_ostream OS(NS);
470           NNS->print(OS, Context.getPrintingPolicy());
471           return OS.str() == Namespace;
472         });
473       });
474 }
475 
476 bool hasUnstableLinkage(const Decl *D) {
477   // Linkage of a ValueDecl depends on the type.
478   // If that's not deduced yet, deducing it may change the linkage.
479   auto *VD = llvm::dyn_cast_or_null<ValueDecl>(D);
480   return VD && !VD->getType().isNull() && VD->getType()->isUndeducedType();
481 }
482 
483 } // namespace clangd
484 } // namespace clang
485