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