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