1 //===- USRGeneration.cpp - Routines for USR generation --------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "clang/Index/USRGeneration.h" 11 #include "clang/AST/ASTContext.h" 12 #include "clang/AST/DeclTemplate.h" 13 #include "clang/AST/DeclVisitor.h" 14 #include "clang/Lex/PreprocessingRecord.h" 15 #include "llvm/Support/Path.h" 16 #include "llvm/Support/raw_ostream.h" 17 18 using namespace clang; 19 using namespace clang::index; 20 21 //===----------------------------------------------------------------------===// 22 // USR generation. 23 //===----------------------------------------------------------------------===// 24 25 /// \returns true on error. 26 static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc, 27 const SourceManager &SM, bool IncludeOffset) { 28 if (Loc.isInvalid()) { 29 return true; 30 } 31 Loc = SM.getExpansionLoc(Loc); 32 const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(Loc); 33 const FileEntry *FE = SM.getFileEntryForID(Decomposed.first); 34 if (FE) { 35 OS << llvm::sys::path::filename(FE->getName()); 36 } else { 37 // This case really isn't interesting. 38 return true; 39 } 40 if (IncludeOffset) { 41 // Use the offest into the FileID to represent the location. Using 42 // a line/column can cause us to look back at the original source file, 43 // which is expensive. 44 OS << '@' << Decomposed.second; 45 } 46 return false; 47 } 48 49 static StringRef GetExternalSourceContainer(const NamedDecl *D) { 50 if (!D) 51 return StringRef(); 52 if (auto *attr = D->getExternalSourceSymbolAttr()) { 53 return attr->getDefinedIn(); 54 } 55 return StringRef(); 56 } 57 58 namespace { 59 class USRGenerator : public ConstDeclVisitor<USRGenerator> { 60 SmallVectorImpl<char> &Buf; 61 llvm::raw_svector_ostream Out; 62 bool IgnoreResults; 63 ASTContext *Context; 64 bool generatedLoc; 65 66 llvm::DenseMap<const Type *, unsigned> TypeSubstitutions; 67 68 public: 69 explicit USRGenerator(ASTContext *Ctx, SmallVectorImpl<char> &Buf) 70 : Buf(Buf), 71 Out(Buf), 72 IgnoreResults(false), 73 Context(Ctx), 74 generatedLoc(false) 75 { 76 // Add the USR space prefix. 77 Out << getUSRSpacePrefix(); 78 } 79 80 bool ignoreResults() const { return IgnoreResults; } 81 82 // Visitation methods from generating USRs from AST elements. 83 void VisitDeclContext(const DeclContext *D); 84 void VisitFieldDecl(const FieldDecl *D); 85 void VisitFunctionDecl(const FunctionDecl *D); 86 void VisitNamedDecl(const NamedDecl *D); 87 void VisitNamespaceDecl(const NamespaceDecl *D); 88 void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D); 89 void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D); 90 void VisitClassTemplateDecl(const ClassTemplateDecl *D); 91 void VisitObjCContainerDecl(const ObjCContainerDecl *CD, 92 const ObjCCategoryDecl *CatD = nullptr); 93 void VisitObjCMethodDecl(const ObjCMethodDecl *MD); 94 void VisitObjCPropertyDecl(const ObjCPropertyDecl *D); 95 void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D); 96 void VisitTagDecl(const TagDecl *D); 97 void VisitTypedefDecl(const TypedefDecl *D); 98 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D); 99 void VisitVarDecl(const VarDecl *D); 100 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D); 101 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D); 102 103 void VisitLinkageSpecDecl(const LinkageSpecDecl *D) { 104 IgnoreResults = true; 105 } 106 107 void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { 108 IgnoreResults = true; 109 } 110 111 void VisitUsingDecl(const UsingDecl *D) { 112 IgnoreResults = true; 113 } 114 115 void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) { 116 IgnoreResults = true; 117 } 118 119 void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) { 120 IgnoreResults = true; 121 } 122 123 bool ShouldGenerateLocation(const NamedDecl *D); 124 125 bool isLocal(const NamedDecl *D) { 126 return D->getParentFunctionOrMethod() != nullptr; 127 } 128 129 void GenExtSymbolContainer(const NamedDecl *D); 130 131 /// Generate the string component containing the location of the 132 /// declaration. 133 bool GenLoc(const Decl *D, bool IncludeOffset); 134 135 /// String generation methods used both by the visitation methods 136 /// and from other clients that want to directly generate USRs. These 137 /// methods do not construct complete USRs (which incorporate the parents 138 /// of an AST element), but only the fragments concerning the AST element 139 /// itself. 140 141 /// Generate a USR for an Objective-C class. 142 void GenObjCClass(StringRef cls, StringRef ExtSymDefinedIn, 143 StringRef CategoryContextExtSymbolDefinedIn) { 144 generateUSRForObjCClass(cls, Out, ExtSymDefinedIn, 145 CategoryContextExtSymbolDefinedIn); 146 } 147 148 /// Generate a USR for an Objective-C class category. 149 void GenObjCCategory(StringRef cls, StringRef cat, 150 StringRef clsExt, StringRef catExt) { 151 generateUSRForObjCCategory(cls, cat, Out, clsExt, catExt); 152 } 153 154 /// Generate a USR fragment for an Objective-C property. 155 void GenObjCProperty(StringRef prop, bool isClassProp) { 156 generateUSRForObjCProperty(prop, isClassProp, Out); 157 } 158 159 /// Generate a USR for an Objective-C protocol. 160 void GenObjCProtocol(StringRef prot, StringRef ext) { 161 generateUSRForObjCProtocol(prot, Out, ext); 162 } 163 164 void VisitType(QualType T); 165 void VisitTemplateParameterList(const TemplateParameterList *Params); 166 void VisitTemplateName(TemplateName Name); 167 void VisitTemplateArgument(const TemplateArgument &Arg); 168 169 /// Emit a Decl's name using NamedDecl::printName() and return true if 170 /// the decl had no name. 171 bool EmitDeclName(const NamedDecl *D); 172 }; 173 } // end anonymous namespace 174 175 //===----------------------------------------------------------------------===// 176 // Generating USRs from ASTS. 177 //===----------------------------------------------------------------------===// 178 179 bool USRGenerator::EmitDeclName(const NamedDecl *D) { 180 const unsigned startSize = Buf.size(); 181 D->printName(Out); 182 const unsigned endSize = Buf.size(); 183 return startSize == endSize; 184 } 185 186 bool USRGenerator::ShouldGenerateLocation(const NamedDecl *D) { 187 if (D->isExternallyVisible()) 188 return false; 189 if (D->getParentFunctionOrMethod()) 190 return true; 191 SourceLocation Loc = D->getLocation(); 192 if (Loc.isInvalid()) 193 return false; 194 const SourceManager &SM = Context->getSourceManager(); 195 return !SM.isInSystemHeader(Loc); 196 } 197 198 void USRGenerator::VisitDeclContext(const DeclContext *DC) { 199 if (const NamedDecl *D = dyn_cast<NamedDecl>(DC)) 200 Visit(D); 201 } 202 203 void USRGenerator::VisitFieldDecl(const FieldDecl *D) { 204 // The USR for an ivar declared in a class extension is based on the 205 // ObjCInterfaceDecl, not the ObjCCategoryDecl. 206 if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D)) 207 Visit(ID); 208 else 209 VisitDeclContext(D->getDeclContext()); 210 Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@"); 211 if (EmitDeclName(D)) { 212 // Bit fields can be anonymous. 213 IgnoreResults = true; 214 return; 215 } 216 } 217 218 void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) { 219 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) 220 return; 221 222 const unsigned StartSize = Buf.size(); 223 VisitDeclContext(D->getDeclContext()); 224 if (Buf.size() == StartSize) 225 GenExtSymbolContainer(D); 226 227 bool IsTemplate = false; 228 if (FunctionTemplateDecl *FunTmpl = D->getDescribedFunctionTemplate()) { 229 IsTemplate = true; 230 Out << "@FT@"; 231 VisitTemplateParameterList(FunTmpl->getTemplateParameters()); 232 } else 233 Out << "@F@"; 234 235 PrintingPolicy Policy(Context->getLangOpts()); 236 // Forward references can have different template argument names. Suppress the 237 // template argument names in constructors to make their USR more stable. 238 Policy.SuppressTemplateArgsInCXXConstructors = true; 239 D->getDeclName().print(Out, Policy); 240 241 ASTContext &Ctx = *Context; 242 if ((!Ctx.getLangOpts().CPlusPlus || D->isExternC()) && 243 !D->hasAttr<OverloadableAttr>()) 244 return; 245 246 if (const TemplateArgumentList * 247 SpecArgs = D->getTemplateSpecializationArgs()) { 248 Out << '<'; 249 for (unsigned I = 0, N = SpecArgs->size(); I != N; ++I) { 250 Out << '#'; 251 VisitTemplateArgument(SpecArgs->get(I)); 252 } 253 Out << '>'; 254 } 255 256 // Mangle in type information for the arguments. 257 for (auto PD : D->parameters()) { 258 Out << '#'; 259 VisitType(PD->getType()); 260 } 261 if (D->isVariadic()) 262 Out << '.'; 263 if (IsTemplate) { 264 // Function templates can be overloaded by return type, for example: 265 // \code 266 // template <class T> typename T::A foo() {} 267 // template <class T> typename T::B foo() {} 268 // \endcode 269 Out << '#'; 270 VisitType(D->getReturnType()); 271 } 272 Out << '#'; 273 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { 274 if (MD->isStatic()) 275 Out << 'S'; 276 if (unsigned quals = MD->getTypeQualifiers()) 277 Out << (char)('0' + quals); 278 switch (MD->getRefQualifier()) { 279 case RQ_None: break; 280 case RQ_LValue: Out << '&'; break; 281 case RQ_RValue: Out << "&&"; break; 282 } 283 } 284 } 285 286 void USRGenerator::VisitNamedDecl(const NamedDecl *D) { 287 VisitDeclContext(D->getDeclContext()); 288 Out << "@"; 289 290 if (EmitDeclName(D)) { 291 // The string can be empty if the declaration has no name; e.g., it is 292 // the ParmDecl with no name for declaration of a function pointer type, 293 // e.g.: void (*f)(void *); 294 // In this case, don't generate a USR. 295 IgnoreResults = true; 296 } 297 } 298 299 void USRGenerator::VisitVarDecl(const VarDecl *D) { 300 // VarDecls can be declared 'extern' within a function or method body, 301 // but their enclosing DeclContext is the function, not the TU. We need 302 // to check the storage class to correctly generate the USR. 303 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) 304 return; 305 306 VisitDeclContext(D->getDeclContext()); 307 308 if (VarTemplateDecl *VarTmpl = D->getDescribedVarTemplate()) { 309 Out << "@VT"; 310 VisitTemplateParameterList(VarTmpl->getTemplateParameters()); 311 } else if (const VarTemplatePartialSpecializationDecl *PartialSpec 312 = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) { 313 Out << "@VP"; 314 VisitTemplateParameterList(PartialSpec->getTemplateParameters()); 315 } 316 317 // Variables always have simple names. 318 StringRef s = D->getName(); 319 320 // The string can be empty if the declaration has no name; e.g., it is 321 // the ParmDecl with no name for declaration of a function pointer type, e.g.: 322 // void (*f)(void *); 323 // In this case, don't generate a USR. 324 if (s.empty()) 325 IgnoreResults = true; 326 else 327 Out << '@' << s; 328 329 // For a template specialization, mangle the template arguments. 330 if (const VarTemplateSpecializationDecl *Spec 331 = dyn_cast<VarTemplateSpecializationDecl>(D)) { 332 const TemplateArgumentList &Args = Spec->getTemplateArgs(); 333 Out << '>'; 334 for (unsigned I = 0, N = Args.size(); I != N; ++I) { 335 Out << '#'; 336 VisitTemplateArgument(Args.get(I)); 337 } 338 } 339 } 340 341 void USRGenerator::VisitNonTypeTemplateParmDecl( 342 const NonTypeTemplateParmDecl *D) { 343 GenLoc(D, /*IncludeOffset=*/true); 344 } 345 346 void USRGenerator::VisitTemplateTemplateParmDecl( 347 const TemplateTemplateParmDecl *D) { 348 GenLoc(D, /*IncludeOffset=*/true); 349 } 350 351 void USRGenerator::VisitNamespaceDecl(const NamespaceDecl *D) { 352 if (D->isAnonymousNamespace()) { 353 Out << "@aN"; 354 return; 355 } 356 357 VisitDeclContext(D->getDeclContext()); 358 if (!IgnoreResults) 359 Out << "@N@" << D->getName(); 360 } 361 362 void USRGenerator::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { 363 VisitFunctionDecl(D->getTemplatedDecl()); 364 } 365 366 void USRGenerator::VisitClassTemplateDecl(const ClassTemplateDecl *D) { 367 VisitTagDecl(D->getTemplatedDecl()); 368 } 369 370 void USRGenerator::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { 371 VisitDeclContext(D->getDeclContext()); 372 if (!IgnoreResults) 373 Out << "@NA@" << D->getName(); 374 } 375 376 void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) { 377 const DeclContext *container = D->getDeclContext(); 378 if (const ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) { 379 Visit(pd); 380 } 381 else { 382 // The USR for a method declared in a class extension or category is based on 383 // the ObjCInterfaceDecl, not the ObjCCategoryDecl. 384 const ObjCInterfaceDecl *ID = D->getClassInterface(); 385 if (!ID) { 386 IgnoreResults = true; 387 return; 388 } 389 auto getCategoryContext = [](const ObjCMethodDecl *D) -> 390 const ObjCCategoryDecl * { 391 if (auto *CD = dyn_cast<ObjCCategoryDecl>(D->getDeclContext())) 392 return CD; 393 if (auto *ICD = dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext())) 394 return ICD->getCategoryDecl(); 395 return nullptr; 396 }; 397 auto *CD = getCategoryContext(D); 398 VisitObjCContainerDecl(ID, CD); 399 } 400 // Ideally we would use 'GenObjCMethod', but this is such a hot path 401 // for Objective-C code that we don't want to use 402 // DeclarationName::getAsString(). 403 Out << (D->isInstanceMethod() ? "(im)" : "(cm)") 404 << DeclarationName(D->getSelector()); 405 } 406 407 void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D, 408 const ObjCCategoryDecl *CatD) { 409 switch (D->getKind()) { 410 default: 411 llvm_unreachable("Invalid ObjC container."); 412 case Decl::ObjCInterface: 413 case Decl::ObjCImplementation: 414 GenObjCClass(D->getName(), GetExternalSourceContainer(D), 415 GetExternalSourceContainer(CatD)); 416 break; 417 case Decl::ObjCCategory: { 418 const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D); 419 const ObjCInterfaceDecl *ID = CD->getClassInterface(); 420 if (!ID) { 421 // Handle invalid code where the @interface might not 422 // have been specified. 423 // FIXME: We should be able to generate this USR even if the 424 // @interface isn't available. 425 IgnoreResults = true; 426 return; 427 } 428 // Specially handle class extensions, which are anonymous categories. 429 // We want to mangle in the location to uniquely distinguish them. 430 if (CD->IsClassExtension()) { 431 Out << "objc(ext)" << ID->getName() << '@'; 432 GenLoc(CD, /*IncludeOffset=*/true); 433 } 434 else 435 GenObjCCategory(ID->getName(), CD->getName(), 436 GetExternalSourceContainer(ID), 437 GetExternalSourceContainer(CD)); 438 439 break; 440 } 441 case Decl::ObjCCategoryImpl: { 442 const ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D); 443 const ObjCInterfaceDecl *ID = CD->getClassInterface(); 444 if (!ID) { 445 // Handle invalid code where the @interface might not 446 // have been specified. 447 // FIXME: We should be able to generate this USR even if the 448 // @interface isn't available. 449 IgnoreResults = true; 450 return; 451 } 452 GenObjCCategory(ID->getName(), CD->getName(), 453 GetExternalSourceContainer(ID), 454 GetExternalSourceContainer(CD)); 455 break; 456 } 457 case Decl::ObjCProtocol: { 458 const ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D); 459 GenObjCProtocol(PD->getName(), GetExternalSourceContainer(PD)); 460 break; 461 } 462 } 463 } 464 465 void USRGenerator::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { 466 // The USR for a property declared in a class extension or category is based 467 // on the ObjCInterfaceDecl, not the ObjCCategoryDecl. 468 if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D)) 469 Visit(ID); 470 else 471 Visit(cast<Decl>(D->getDeclContext())); 472 GenObjCProperty(D->getName(), D->isClassProperty()); 473 } 474 475 void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { 476 if (ObjCPropertyDecl *PD = D->getPropertyDecl()) { 477 VisitObjCPropertyDecl(PD); 478 return; 479 } 480 481 IgnoreResults = true; 482 } 483 484 void USRGenerator::VisitTagDecl(const TagDecl *D) { 485 // Add the location of the tag decl to handle resolution across 486 // translation units. 487 if (!isa<EnumDecl>(D) && 488 ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) 489 return; 490 491 GenExtSymbolContainer(D); 492 493 D = D->getCanonicalDecl(); 494 VisitDeclContext(D->getDeclContext()); 495 496 bool AlreadyStarted = false; 497 if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) { 498 if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) { 499 AlreadyStarted = true; 500 501 switch (D->getTagKind()) { 502 case TTK_Interface: 503 case TTK_Class: 504 case TTK_Struct: Out << "@ST"; break; 505 case TTK_Union: Out << "@UT"; break; 506 case TTK_Enum: llvm_unreachable("enum template"); 507 } 508 VisitTemplateParameterList(ClassTmpl->getTemplateParameters()); 509 } else if (const ClassTemplatePartialSpecializationDecl *PartialSpec 510 = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) { 511 AlreadyStarted = true; 512 513 switch (D->getTagKind()) { 514 case TTK_Interface: 515 case TTK_Class: 516 case TTK_Struct: Out << "@SP"; break; 517 case TTK_Union: Out << "@UP"; break; 518 case TTK_Enum: llvm_unreachable("enum partial specialization"); 519 } 520 VisitTemplateParameterList(PartialSpec->getTemplateParameters()); 521 } 522 } 523 524 if (!AlreadyStarted) { 525 switch (D->getTagKind()) { 526 case TTK_Interface: 527 case TTK_Class: 528 case TTK_Struct: Out << "@S"; break; 529 case TTK_Union: Out << "@U"; break; 530 case TTK_Enum: Out << "@E"; break; 531 } 532 } 533 534 Out << '@'; 535 assert(Buf.size() > 0); 536 const unsigned off = Buf.size() - 1; 537 538 if (EmitDeclName(D)) { 539 if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) { 540 Buf[off] = 'A'; 541 Out << '@' << *TD; 542 } 543 else { 544 if (D->isEmbeddedInDeclarator() && !D->isFreeStanding()) { 545 printLoc(Out, D->getLocation(), Context->getSourceManager(), true); 546 } else { 547 Buf[off] = 'a'; 548 if (auto *ED = dyn_cast<EnumDecl>(D)) { 549 // Distinguish USRs of anonymous enums by using their first enumerator. 550 auto enum_range = ED->enumerators(); 551 if (enum_range.begin() != enum_range.end()) { 552 Out << '@' << **enum_range.begin(); 553 } 554 } 555 } 556 } 557 } 558 559 // For a class template specialization, mangle the template arguments. 560 if (const ClassTemplateSpecializationDecl *Spec 561 = dyn_cast<ClassTemplateSpecializationDecl>(D)) { 562 const TemplateArgumentList &Args = Spec->getTemplateArgs(); 563 Out << '>'; 564 for (unsigned I = 0, N = Args.size(); I != N; ++I) { 565 Out << '#'; 566 VisitTemplateArgument(Args.get(I)); 567 } 568 } 569 } 570 571 void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) { 572 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) 573 return; 574 const DeclContext *DC = D->getDeclContext(); 575 if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC)) 576 Visit(DCN); 577 Out << "@T@"; 578 Out << D->getName(); 579 } 580 581 void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { 582 GenLoc(D, /*IncludeOffset=*/true); 583 } 584 585 void USRGenerator::GenExtSymbolContainer(const NamedDecl *D) { 586 StringRef Container = GetExternalSourceContainer(D); 587 if (!Container.empty()) 588 Out << "@M@" << Container; 589 } 590 591 bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) { 592 if (generatedLoc) 593 return IgnoreResults; 594 generatedLoc = true; 595 596 // Guard against null declarations in invalid code. 597 if (!D) { 598 IgnoreResults = true; 599 return true; 600 } 601 602 // Use the location of canonical decl. 603 D = D->getCanonicalDecl(); 604 605 IgnoreResults = 606 IgnoreResults || printLoc(Out, D->getLocStart(), 607 Context->getSourceManager(), IncludeOffset); 608 609 return IgnoreResults; 610 } 611 612 void USRGenerator::VisitType(QualType T) { 613 // This method mangles in USR information for types. It can possibly 614 // just reuse the naming-mangling logic used by codegen, although the 615 // requirements for USRs might not be the same. 616 ASTContext &Ctx = *Context; 617 618 do { 619 T = Ctx.getCanonicalType(T); 620 Qualifiers Q = T.getQualifiers(); 621 unsigned qVal = 0; 622 if (Q.hasConst()) 623 qVal |= 0x1; 624 if (Q.hasVolatile()) 625 qVal |= 0x2; 626 if (Q.hasRestrict()) 627 qVal |= 0x4; 628 if(qVal) 629 Out << ((char) ('0' + qVal)); 630 631 // Mangle in ObjC GC qualifiers? 632 633 if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) { 634 Out << 'P'; 635 T = Expansion->getPattern(); 636 } 637 638 if (const BuiltinType *BT = T->getAs<BuiltinType>()) { 639 unsigned char c = '\0'; 640 switch (BT->getKind()) { 641 case BuiltinType::Void: 642 c = 'v'; break; 643 case BuiltinType::Bool: 644 c = 'b'; break; 645 case BuiltinType::UChar: 646 c = 'c'; break; 647 case BuiltinType::Char16: 648 c = 'q'; break; 649 case BuiltinType::Char32: 650 c = 'w'; break; 651 case BuiltinType::UShort: 652 c = 's'; break; 653 case BuiltinType::UInt: 654 c = 'i'; break; 655 case BuiltinType::ULong: 656 c = 'l'; break; 657 case BuiltinType::ULongLong: 658 c = 'k'; break; 659 case BuiltinType::UInt128: 660 c = 'j'; break; 661 case BuiltinType::Char_U: 662 case BuiltinType::Char_S: 663 c = 'C'; break; 664 case BuiltinType::SChar: 665 c = 'r'; break; 666 case BuiltinType::WChar_S: 667 case BuiltinType::WChar_U: 668 c = 'W'; break; 669 case BuiltinType::Short: 670 c = 'S'; break; 671 case BuiltinType::Int: 672 c = 'I'; break; 673 case BuiltinType::Long: 674 c = 'L'; break; 675 case BuiltinType::LongLong: 676 c = 'K'; break; 677 case BuiltinType::Int128: 678 c = 'J'; break; 679 case BuiltinType::Half: 680 c = 'h'; break; 681 case BuiltinType::Float: 682 c = 'f'; break; 683 case BuiltinType::Double: 684 c = 'd'; break; 685 case BuiltinType::LongDouble: 686 c = 'D'; break; 687 case BuiltinType::Float128: 688 c = 'Q'; break; 689 case BuiltinType::NullPtr: 690 c = 'n'; break; 691 #define BUILTIN_TYPE(Id, SingletonId) 692 #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id: 693 #include "clang/AST/BuiltinTypes.def" 694 case BuiltinType::Dependent: 695 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 696 case BuiltinType::Id: 697 #include "clang/Basic/OpenCLImageTypes.def" 698 case BuiltinType::OCLEvent: 699 case BuiltinType::OCLClkEvent: 700 case BuiltinType::OCLQueue: 701 case BuiltinType::OCLReserveID: 702 case BuiltinType::OCLSampler: 703 IgnoreResults = true; 704 return; 705 case BuiltinType::ObjCId: 706 c = 'o'; break; 707 case BuiltinType::ObjCClass: 708 c = 'O'; break; 709 case BuiltinType::ObjCSel: 710 c = 'e'; break; 711 } 712 Out << c; 713 return; 714 } 715 716 // If we have already seen this (non-built-in) type, use a substitution 717 // encoding. 718 llvm::DenseMap<const Type *, unsigned>::iterator Substitution 719 = TypeSubstitutions.find(T.getTypePtr()); 720 if (Substitution != TypeSubstitutions.end()) { 721 Out << 'S' << Substitution->second << '_'; 722 return; 723 } else { 724 // Record this as a substitution. 725 unsigned Number = TypeSubstitutions.size(); 726 TypeSubstitutions[T.getTypePtr()] = Number; 727 } 728 729 if (const PointerType *PT = T->getAs<PointerType>()) { 730 Out << '*'; 731 T = PT->getPointeeType(); 732 continue; 733 } 734 if (const ObjCObjectPointerType *OPT = T->getAs<ObjCObjectPointerType>()) { 735 Out << '*'; 736 T = OPT->getPointeeType(); 737 continue; 738 } 739 if (const RValueReferenceType *RT = T->getAs<RValueReferenceType>()) { 740 Out << "&&"; 741 T = RT->getPointeeType(); 742 continue; 743 } 744 if (const ReferenceType *RT = T->getAs<ReferenceType>()) { 745 Out << '&'; 746 T = RT->getPointeeType(); 747 continue; 748 } 749 if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) { 750 Out << 'F'; 751 VisitType(FT->getReturnType()); 752 for (const auto &I : FT->param_types()) 753 VisitType(I); 754 if (FT->isVariadic()) 755 Out << '.'; 756 return; 757 } 758 if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) { 759 Out << 'B'; 760 T = BT->getPointeeType(); 761 continue; 762 } 763 if (const ComplexType *CT = T->getAs<ComplexType>()) { 764 Out << '<'; 765 T = CT->getElementType(); 766 continue; 767 } 768 if (const TagType *TT = T->getAs<TagType>()) { 769 Out << '$'; 770 VisitTagDecl(TT->getDecl()); 771 return; 772 } 773 if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) { 774 Out << '$'; 775 VisitObjCInterfaceDecl(OIT->getDecl()); 776 return; 777 } 778 if (const ObjCObjectType *OIT = T->getAs<ObjCObjectType>()) { 779 Out << 'Q'; 780 VisitType(OIT->getBaseType()); 781 for (auto *Prot : OIT->getProtocols()) 782 VisitObjCProtocolDecl(Prot); 783 return; 784 } 785 if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) { 786 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex(); 787 return; 788 } 789 if (const TemplateSpecializationType *Spec 790 = T->getAs<TemplateSpecializationType>()) { 791 Out << '>'; 792 VisitTemplateName(Spec->getTemplateName()); 793 Out << Spec->getNumArgs(); 794 for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I) 795 VisitTemplateArgument(Spec->getArg(I)); 796 return; 797 } 798 if (const DependentNameType *DNT = T->getAs<DependentNameType>()) { 799 Out << '^'; 800 // FIXME: Encode the qualifier, don't just print it. 801 PrintingPolicy PO(Ctx.getLangOpts()); 802 PO.SuppressTagKeyword = true; 803 PO.SuppressUnwrittenScope = true; 804 PO.ConstantArraySizeAsWritten = false; 805 PO.AnonymousTagLocations = false; 806 DNT->getQualifier()->print(Out, PO); 807 Out << ':' << DNT->getIdentifier()->getName(); 808 return; 809 } 810 if (const InjectedClassNameType *InjT = T->getAs<InjectedClassNameType>()) { 811 T = InjT->getInjectedSpecializationType(); 812 continue; 813 } 814 if (const auto *VT = T->getAs<VectorType>()) { 815 Out << (T->isExtVectorType() ? ']' : '['); 816 Out << VT->getNumElements(); 817 T = VT->getElementType(); 818 continue; 819 } 820 821 // Unhandled type. 822 Out << ' '; 823 break; 824 } while (true); 825 } 826 827 void USRGenerator::VisitTemplateParameterList( 828 const TemplateParameterList *Params) { 829 if (!Params) 830 return; 831 Out << '>' << Params->size(); 832 for (TemplateParameterList::const_iterator P = Params->begin(), 833 PEnd = Params->end(); 834 P != PEnd; ++P) { 835 Out << '#'; 836 if (isa<TemplateTypeParmDecl>(*P)) { 837 if (cast<TemplateTypeParmDecl>(*P)->isParameterPack()) 838 Out<< 'p'; 839 Out << 'T'; 840 continue; 841 } 842 843 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) { 844 if (NTTP->isParameterPack()) 845 Out << 'p'; 846 Out << 'N'; 847 VisitType(NTTP->getType()); 848 continue; 849 } 850 851 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P); 852 if (TTP->isParameterPack()) 853 Out << 'p'; 854 Out << 't'; 855 VisitTemplateParameterList(TTP->getTemplateParameters()); 856 } 857 } 858 859 void USRGenerator::VisitTemplateName(TemplateName Name) { 860 if (TemplateDecl *Template = Name.getAsTemplateDecl()) { 861 if (TemplateTemplateParmDecl *TTP 862 = dyn_cast<TemplateTemplateParmDecl>(Template)) { 863 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex(); 864 return; 865 } 866 867 Visit(Template); 868 return; 869 } 870 871 // FIXME: Visit dependent template names. 872 } 873 874 void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) { 875 switch (Arg.getKind()) { 876 case TemplateArgument::Null: 877 break; 878 879 case TemplateArgument::Declaration: 880 Visit(Arg.getAsDecl()); 881 break; 882 883 case TemplateArgument::NullPtr: 884 break; 885 886 case TemplateArgument::TemplateExpansion: 887 Out << 'P'; // pack expansion of... 888 // Fall through 889 case TemplateArgument::Template: 890 VisitTemplateName(Arg.getAsTemplateOrTemplatePattern()); 891 break; 892 893 case TemplateArgument::Expression: 894 // FIXME: Visit expressions. 895 break; 896 897 case TemplateArgument::Pack: 898 Out << 'p' << Arg.pack_size(); 899 for (const auto &P : Arg.pack_elements()) 900 VisitTemplateArgument(P); 901 break; 902 903 case TemplateArgument::Type: 904 VisitType(Arg.getAsType()); 905 break; 906 907 case TemplateArgument::Integral: 908 Out << 'V'; 909 VisitType(Arg.getIntegralType()); 910 Out << Arg.getAsIntegral(); 911 break; 912 } 913 } 914 915 //===----------------------------------------------------------------------===// 916 // USR generation functions. 917 //===----------------------------------------------------------------------===// 918 919 static void combineClassAndCategoryExtContainers(StringRef ClsSymDefinedIn, 920 StringRef CatSymDefinedIn, 921 raw_ostream &OS) { 922 if (ClsSymDefinedIn.empty() && CatSymDefinedIn.empty()) 923 return; 924 if (CatSymDefinedIn.empty()) { 925 OS << "@M@" << ClsSymDefinedIn << '@'; 926 return; 927 } 928 OS << "@CM@" << CatSymDefinedIn << '@'; 929 if (ClsSymDefinedIn != CatSymDefinedIn) { 930 OS << ClsSymDefinedIn << '@'; 931 } 932 } 933 934 void clang::index::generateUSRForObjCClass(StringRef Cls, raw_ostream &OS, 935 StringRef ExtSymDefinedIn, 936 StringRef CategoryContextExtSymbolDefinedIn) { 937 combineClassAndCategoryExtContainers(ExtSymDefinedIn, 938 CategoryContextExtSymbolDefinedIn, OS); 939 OS << "objc(cs)" << Cls; 940 } 941 942 void clang::index::generateUSRForObjCCategory(StringRef Cls, StringRef Cat, 943 raw_ostream &OS, 944 StringRef ClsSymDefinedIn, 945 StringRef CatSymDefinedIn) { 946 combineClassAndCategoryExtContainers(ClsSymDefinedIn, CatSymDefinedIn, OS); 947 OS << "objc(cy)" << Cls << '@' << Cat; 948 } 949 950 void clang::index::generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS) { 951 OS << '@' << Ivar; 952 } 953 954 void clang::index::generateUSRForObjCMethod(StringRef Sel, 955 bool IsInstanceMethod, 956 raw_ostream &OS) { 957 OS << (IsInstanceMethod ? "(im)" : "(cm)") << Sel; 958 } 959 960 void clang::index::generateUSRForObjCProperty(StringRef Prop, bool isClassProp, 961 raw_ostream &OS) { 962 OS << (isClassProp ? "(cpy)" : "(py)") << Prop; 963 } 964 965 void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS, 966 StringRef ExtSymDefinedIn) { 967 if (!ExtSymDefinedIn.empty()) 968 OS << "@M@" << ExtSymDefinedIn << '@'; 969 OS << "objc(pl)" << Prot; 970 } 971 972 void clang::index::generateUSRForGlobalEnum(StringRef EnumName, raw_ostream &OS, 973 StringRef ExtSymDefinedIn) { 974 if (!ExtSymDefinedIn.empty()) 975 OS << "@M@" << ExtSymDefinedIn; 976 OS << "@E@" << EnumName; 977 } 978 979 void clang::index::generateUSRForEnumConstant(StringRef EnumConstantName, 980 raw_ostream &OS) { 981 OS << '@' << EnumConstantName; 982 } 983 984 bool clang::index::generateUSRForDecl(const Decl *D, 985 SmallVectorImpl<char> &Buf) { 986 if (!D) 987 return true; 988 // We don't ignore decls with invalid source locations. Implicit decls, like 989 // C++'s operator new function, can have invalid locations but it is fine to 990 // create USRs that can identify them. 991 992 USRGenerator UG(&D->getASTContext(), Buf); 993 UG.Visit(D); 994 return UG.ignoreResults(); 995 } 996 997 bool clang::index::generateUSRForMacro(const MacroDefinitionRecord *MD, 998 const SourceManager &SM, 999 SmallVectorImpl<char> &Buf) { 1000 if (!MD) 1001 return true; 1002 return generateUSRForMacro(MD->getName()->getName(), MD->getLocation(), 1003 SM, Buf); 1004 1005 } 1006 1007 bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc, 1008 const SourceManager &SM, 1009 SmallVectorImpl<char> &Buf) { 1010 // Don't generate USRs for things with invalid locations. 1011 if (MacroName.empty() || Loc.isInvalid()) 1012 return true; 1013 1014 llvm::raw_svector_ostream Out(Buf); 1015 1016 // Assume that system headers are sane. Don't put source location 1017 // information into the USR if the macro comes from a system header. 1018 bool ShouldGenerateLocation = !SM.isInSystemHeader(Loc); 1019 1020 Out << getUSRSpacePrefix(); 1021 if (ShouldGenerateLocation) 1022 printLoc(Out, Loc, SM, /*IncludeOffset=*/true); 1023 Out << "@macro@"; 1024 Out << MacroName; 1025 return false; 1026 } 1027