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