1 //===- USRGeneration.cpp - Routines for USR generation --------------------===// 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 "clang/Index/USRGeneration.h" 10 #include "clang/AST/ASTContext.h" 11 #include "clang/AST/Attr.h" 12 #include "clang/AST/DeclCXX.h" 13 #include "clang/AST/DeclTemplate.h" 14 #include "clang/AST/DeclVisitor.h" 15 #include "clang/AST/ODRHash.h" 16 #include "clang/Basic/FileManager.h" 17 #include "clang/Lex/PreprocessingRecord.h" 18 #include "llvm/Support/Path.h" 19 #include "llvm/Support/raw_ostream.h" 20 21 using namespace clang; 22 using namespace clang::index; 23 24 //===----------------------------------------------------------------------===// 25 // USR generation. 26 //===----------------------------------------------------------------------===// 27 28 /// \returns true on error. 29 static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc, 30 const SourceManager &SM, bool IncludeOffset) { 31 if (Loc.isInvalid()) { 32 return true; 33 } 34 Loc = SM.getExpansionLoc(Loc); 35 const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(Loc); 36 OptionalFileEntryRef FE = SM.getFileEntryRefForID(Decomposed.first); 37 if (FE) { 38 OS << llvm::sys::path::filename(FE->getName()); 39 } else { 40 // This case really isn't interesting. 41 return true; 42 } 43 if (IncludeOffset) { 44 // Use the offest into the FileID to represent the location. Using 45 // a line/column can cause us to look back at the original source file, 46 // which is expensive. 47 OS << '@' << Decomposed.second; 48 } 49 return false; 50 } 51 52 static StringRef GetExternalSourceContainer(const NamedDecl *D) { 53 if (!D) 54 return StringRef(); 55 if (auto *attr = D->getExternalSourceSymbolAttr()) { 56 return attr->getDefinedIn(); 57 } 58 return StringRef(); 59 } 60 61 namespace { 62 class USRGenerator : public ConstDeclVisitor<USRGenerator> { 63 SmallVectorImpl<char> &Buf; 64 llvm::raw_svector_ostream Out; 65 ASTContext *Context; 66 const LangOptions &LangOpts; 67 bool IgnoreResults = false; 68 bool generatedLoc = false; 69 70 llvm::DenseMap<const Type *, unsigned> TypeSubstitutions; 71 72 public: 73 USRGenerator(ASTContext *Ctx, SmallVectorImpl<char> &Buf, 74 const LangOptions &LangOpts) 75 : Buf(Buf), Out(Buf), Context(Ctx), LangOpts(LangOpts) { 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 VisitBindingDecl(const BindingDecl *D); 101 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D); 102 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D); 103 void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D); 104 void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D); 105 void VisitConceptDecl(const ConceptDecl *D); 106 107 void VisitLinkageSpecDecl(const LinkageSpecDecl *D) { 108 IgnoreResults = true; // No USRs for linkage specs themselves. 109 } 110 111 void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { 112 IgnoreResults = true; 113 } 114 115 void VisitUsingDecl(const UsingDecl *D) { 116 VisitDeclContext(D->getDeclContext()); 117 Out << "@UD@"; 118 119 bool EmittedDeclName = !EmitDeclName(D); 120 assert(EmittedDeclName && "EmitDeclName can not fail for UsingDecls"); 121 (void)EmittedDeclName; 122 } 123 124 bool ShouldGenerateLocation(const NamedDecl *D); 125 126 bool isLocal(const NamedDecl *D) { 127 return D->getParentFunctionOrMethod() != nullptr; 128 } 129 130 void GenExtSymbolContainer(const NamedDecl *D); 131 132 /// Generate the string component containing the location of the 133 /// declaration. 134 bool GenLoc(const Decl *D, bool IncludeOffset); 135 136 /// String generation methods used both by the visitation methods 137 /// and from other clients that want to directly generate USRs. These 138 /// methods do not construct complete USRs (which incorporate the parents 139 /// of an AST element), but only the fragments concerning the AST element 140 /// itself. 141 142 /// Generate a USR for an Objective-C class. 143 void GenObjCClass(StringRef cls, StringRef ExtSymDefinedIn, 144 StringRef CategoryContextExtSymbolDefinedIn) { 145 generateUSRForObjCClass(cls, Out, ExtSymDefinedIn, 146 CategoryContextExtSymbolDefinedIn); 147 } 148 149 /// Generate a USR for an Objective-C class category. 150 void GenObjCCategory(StringRef cls, StringRef cat, 151 StringRef clsExt, StringRef catExt) { 152 generateUSRForObjCCategory(cls, cat, Out, clsExt, catExt); 153 } 154 155 /// Generate a USR fragment for an Objective-C property. 156 void GenObjCProperty(StringRef prop, bool isClassProp) { 157 generateUSRForObjCProperty(prop, isClassProp, Out); 158 } 159 160 /// Generate a USR for an Objective-C protocol. 161 void GenObjCProtocol(StringRef prot, StringRef ext) { 162 generateUSRForObjCProtocol(prot, Out, ext); 163 } 164 165 void VisitType(QualType T); 166 void VisitTemplateParameterList(const TemplateParameterList *Params); 167 void VisitTemplateName(TemplateName Name); 168 void VisitTemplateArgument(const TemplateArgument &Arg); 169 170 void VisitMSGuidDecl(const MSGuidDecl *D); 171 172 /// Emit a Decl's name using NamedDecl::printName() and return true if 173 /// the decl had no name. 174 bool EmitDeclName(const NamedDecl *D); 175 }; 176 } // end anonymous namespace 177 178 //===----------------------------------------------------------------------===// 179 // Generating USRs from ASTS. 180 //===----------------------------------------------------------------------===// 181 182 bool USRGenerator::EmitDeclName(const NamedDecl *D) { 183 DeclarationName N = D->getDeclName(); 184 if (N.isEmpty()) 185 return true; 186 Out << N; 187 return false; 188 } 189 190 bool USRGenerator::ShouldGenerateLocation(const NamedDecl *D) { 191 if (D->isExternallyVisible()) 192 return false; 193 if (D->getParentFunctionOrMethod()) 194 return true; 195 SourceLocation Loc = D->getLocation(); 196 if (Loc.isInvalid()) 197 return false; 198 const SourceManager &SM = Context->getSourceManager(); 199 return !SM.isInSystemHeader(Loc); 200 } 201 202 void USRGenerator::VisitDeclContext(const DeclContext *DC) { 203 if (const NamedDecl *D = dyn_cast<NamedDecl>(DC)) 204 Visit(D); 205 else if (isa<LinkageSpecDecl>(DC)) // Linkage specs are transparent in USRs. 206 VisitDeclContext(DC->getParent()); 207 } 208 209 void USRGenerator::VisitFieldDecl(const FieldDecl *D) { 210 // The USR for an ivar declared in a class extension is based on the 211 // ObjCInterfaceDecl, not the ObjCCategoryDecl. 212 if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D)) 213 Visit(ID); 214 else 215 VisitDeclContext(D->getDeclContext()); 216 Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@"); 217 if (EmitDeclName(D)) { 218 // Bit fields can be anonymous. 219 IgnoreResults = true; 220 return; 221 } 222 } 223 224 void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) { 225 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) 226 return; 227 228 if (D->getType().isNull()) { 229 IgnoreResults = true; 230 return; 231 } 232 233 const unsigned StartSize = Buf.size(); 234 VisitDeclContext(D->getDeclContext()); 235 if (Buf.size() == StartSize) 236 GenExtSymbolContainer(D); 237 238 bool IsTemplate = false; 239 if (FunctionTemplateDecl *FunTmpl = D->getDescribedFunctionTemplate()) { 240 IsTemplate = true; 241 Out << "@FT@"; 242 VisitTemplateParameterList(FunTmpl->getTemplateParameters()); 243 } else 244 Out << "@F@"; 245 246 PrintingPolicy Policy(LangOpts); 247 // Forward references can have different template argument names. Suppress the 248 // template argument names in constructors to make their USR more stable. 249 Policy.SuppressTemplateArgsInCXXConstructors = true; 250 D->getDeclName().print(Out, Policy); 251 252 if ((!LangOpts.CPlusPlus || D->isExternC()) && 253 !D->hasAttr<OverloadableAttr>()) 254 return; 255 256 if (D->isFunctionTemplateSpecialization()) { 257 Out << '<'; 258 if (const TemplateArgumentList *SpecArgs = 259 D->getTemplateSpecializationArgs()) { 260 for (const auto &Arg : SpecArgs->asArray()) { 261 Out << '#'; 262 VisitTemplateArgument(Arg); 263 } 264 } else if (const ASTTemplateArgumentListInfo *SpecArgsWritten = 265 D->getTemplateSpecializationArgsAsWritten()) { 266 for (const auto &ArgLoc : SpecArgsWritten->arguments()) { 267 Out << '#'; 268 VisitTemplateArgument(ArgLoc.getArgument()); 269 } 270 } 271 Out << '>'; 272 } 273 274 QualType CanonicalType = D->getType().getCanonicalType(); 275 // Mangle in type information for the arguments. 276 if (const auto *FPT = CanonicalType->getAs<FunctionProtoType>()) { 277 for (QualType PT : FPT->param_types()) { 278 Out << '#'; 279 VisitType(PT); 280 } 281 } 282 if (D->isVariadic()) 283 Out << '.'; 284 if (IsTemplate) { 285 // Function templates can be overloaded by return type, for example: 286 // \code 287 // template <class T> typename T::A foo() {} 288 // template <class T> typename T::B foo() {} 289 // \endcode 290 Out << '#'; 291 VisitType(D->getReturnType()); 292 } 293 Out << '#'; 294 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { 295 if (MD->isStatic()) 296 Out << 'S'; 297 // FIXME: OpenCL: Need to consider address spaces 298 if (unsigned quals = MD->getMethodQualifiers().getCVRUQualifiers()) 299 Out << (char)('0' + quals); 300 switch (MD->getRefQualifier()) { 301 case RQ_None: break; 302 case RQ_LValue: Out << '&'; break; 303 case RQ_RValue: Out << "&&"; break; 304 } 305 } 306 } 307 308 void USRGenerator::VisitNamedDecl(const NamedDecl *D) { 309 VisitDeclContext(D->getDeclContext()); 310 Out << "@"; 311 312 if (EmitDeclName(D)) { 313 // The string can be empty if the declaration has no name; e.g., it is 314 // the ParmDecl with no name for declaration of a function pointer type, 315 // e.g.: void (*f)(void *); 316 // In this case, don't generate a USR. 317 IgnoreResults = true; 318 } 319 } 320 321 void USRGenerator::VisitVarDecl(const VarDecl *D) { 322 // VarDecls can be declared 'extern' within a function or method body, 323 // but their enclosing DeclContext is the function, not the TU. We need 324 // to check the storage class to correctly generate the USR. 325 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) 326 return; 327 328 VisitDeclContext(D->getDeclContext()); 329 330 if (VarTemplateDecl *VarTmpl = D->getDescribedVarTemplate()) { 331 Out << "@VT"; 332 VisitTemplateParameterList(VarTmpl->getTemplateParameters()); 333 } else if (const VarTemplatePartialSpecializationDecl *PartialSpec 334 = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) { 335 Out << "@VP"; 336 VisitTemplateParameterList(PartialSpec->getTemplateParameters()); 337 } 338 339 // Variables always have simple names. 340 StringRef s = D->getName(); 341 342 // The string can be empty if the declaration has no name; e.g., it is 343 // the ParmDecl with no name for declaration of a function pointer type, e.g.: 344 // void (*f)(void *); 345 // In this case, don't generate a USR. 346 if (s.empty()) 347 IgnoreResults = true; 348 else 349 Out << '@' << s; 350 351 // For a template specialization, mangle the template arguments. 352 if (const VarTemplateSpecializationDecl *Spec 353 = dyn_cast<VarTemplateSpecializationDecl>(D)) { 354 const TemplateArgumentList &Args = Spec->getTemplateArgs(); 355 Out << '>'; 356 for (unsigned I = 0, N = Args.size(); I != N; ++I) { 357 Out << '#'; 358 VisitTemplateArgument(Args.get(I)); 359 } 360 } 361 } 362 363 void USRGenerator::VisitBindingDecl(const BindingDecl *D) { 364 if (isLocal(D) && GenLoc(D, /*IncludeOffset=*/true)) 365 return; 366 VisitNamedDecl(D); 367 } 368 369 void USRGenerator::VisitNonTypeTemplateParmDecl( 370 const NonTypeTemplateParmDecl *D) { 371 GenLoc(D, /*IncludeOffset=*/true); 372 } 373 374 void USRGenerator::VisitTemplateTemplateParmDecl( 375 const TemplateTemplateParmDecl *D) { 376 GenLoc(D, /*IncludeOffset=*/true); 377 } 378 379 void USRGenerator::VisitNamespaceDecl(const NamespaceDecl *D) { 380 if (IgnoreResults) 381 return; 382 VisitDeclContext(D->getDeclContext()); 383 if (D->isAnonymousNamespace()) { 384 Out << "@aN"; 385 return; 386 } 387 Out << "@N@" << D->getName(); 388 } 389 390 void USRGenerator::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { 391 VisitFunctionDecl(D->getTemplatedDecl()); 392 } 393 394 void USRGenerator::VisitClassTemplateDecl(const ClassTemplateDecl *D) { 395 VisitTagDecl(D->getTemplatedDecl()); 396 } 397 398 void USRGenerator::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { 399 VisitDeclContext(D->getDeclContext()); 400 if (!IgnoreResults) 401 Out << "@NA@" << D->getName(); 402 } 403 404 static const ObjCCategoryDecl *getCategoryContext(const NamedDecl *D) { 405 if (auto *CD = dyn_cast<ObjCCategoryDecl>(D->getDeclContext())) 406 return CD; 407 if (auto *ICD = dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext())) 408 return ICD->getCategoryDecl(); 409 return nullptr; 410 } 411 412 void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) { 413 const DeclContext *container = D->getDeclContext(); 414 if (const ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) { 415 Visit(pd); 416 } 417 else { 418 // The USR for a method declared in a class extension or category is based on 419 // the ObjCInterfaceDecl, not the ObjCCategoryDecl. 420 const ObjCInterfaceDecl *ID = D->getClassInterface(); 421 if (!ID) { 422 IgnoreResults = true; 423 return; 424 } 425 auto *CD = getCategoryContext(D); 426 VisitObjCContainerDecl(ID, CD); 427 } 428 // Ideally we would use 'GenObjCMethod', but this is such a hot path 429 // for Objective-C code that we don't want to use 430 // DeclarationName::getAsString(). 431 Out << (D->isInstanceMethod() ? "(im)" : "(cm)") 432 << DeclarationName(D->getSelector()); 433 } 434 435 void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D, 436 const ObjCCategoryDecl *CatD) { 437 switch (D->getKind()) { 438 default: 439 llvm_unreachable("Invalid ObjC container."); 440 case Decl::ObjCInterface: 441 case Decl::ObjCImplementation: 442 GenObjCClass(D->getName(), GetExternalSourceContainer(D), 443 GetExternalSourceContainer(CatD)); 444 break; 445 case Decl::ObjCCategory: { 446 const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D); 447 const ObjCInterfaceDecl *ID = CD->getClassInterface(); 448 if (!ID) { 449 // Handle invalid code where the @interface might not 450 // have been specified. 451 // FIXME: We should be able to generate this USR even if the 452 // @interface isn't available. 453 IgnoreResults = true; 454 return; 455 } 456 // Specially handle class extensions, which are anonymous categories. 457 // We want to mangle in the location to uniquely distinguish them. 458 if (CD->IsClassExtension()) { 459 Out << "objc(ext)" << ID->getName() << '@'; 460 GenLoc(CD, /*IncludeOffset=*/true); 461 } 462 else 463 GenObjCCategory(ID->getName(), CD->getName(), 464 GetExternalSourceContainer(ID), 465 GetExternalSourceContainer(CD)); 466 467 break; 468 } 469 case Decl::ObjCCategoryImpl: { 470 const ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D); 471 const ObjCInterfaceDecl *ID = CD->getClassInterface(); 472 if (!ID) { 473 // Handle invalid code where the @interface might not 474 // have been specified. 475 // FIXME: We should be able to generate this USR even if the 476 // @interface isn't available. 477 IgnoreResults = true; 478 return; 479 } 480 GenObjCCategory(ID->getName(), CD->getName(), 481 GetExternalSourceContainer(ID), 482 GetExternalSourceContainer(CD)); 483 break; 484 } 485 case Decl::ObjCProtocol: { 486 const ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D); 487 GenObjCProtocol(PD->getName(), GetExternalSourceContainer(PD)); 488 break; 489 } 490 } 491 } 492 493 void USRGenerator::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { 494 // The USR for a property declared in a class extension or category is based 495 // on the ObjCInterfaceDecl, not the ObjCCategoryDecl. 496 if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D)) 497 VisitObjCContainerDecl(ID, getCategoryContext(D)); 498 else 499 Visit(cast<Decl>(D->getDeclContext())); 500 GenObjCProperty(D->getName(), D->isClassProperty()); 501 } 502 503 void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { 504 if (ObjCPropertyDecl *PD = D->getPropertyDecl()) { 505 VisitObjCPropertyDecl(PD); 506 return; 507 } 508 509 IgnoreResults = true; 510 } 511 512 void USRGenerator::VisitTagDecl(const TagDecl *D) { 513 // Add the location of the tag decl to handle resolution across 514 // translation units. 515 if (!isa<EnumDecl>(D) && 516 ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) 517 return; 518 519 GenExtSymbolContainer(D); 520 521 D = D->getCanonicalDecl(); 522 VisitDeclContext(D->getDeclContext()); 523 524 bool AlreadyStarted = false; 525 if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) { 526 if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) { 527 AlreadyStarted = true; 528 529 switch (D->getTagKind()) { 530 case TagTypeKind::Interface: 531 case TagTypeKind::Class: 532 case TagTypeKind::Struct: 533 Out << "@ST"; 534 break; 535 case TagTypeKind::Union: 536 Out << "@UT"; 537 break; 538 case TagTypeKind::Enum: 539 llvm_unreachable("enum template"); 540 } 541 VisitTemplateParameterList(ClassTmpl->getTemplateParameters()); 542 } else if (const ClassTemplatePartialSpecializationDecl *PartialSpec 543 = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) { 544 AlreadyStarted = true; 545 546 switch (D->getTagKind()) { 547 case TagTypeKind::Interface: 548 case TagTypeKind::Class: 549 case TagTypeKind::Struct: 550 Out << "@SP"; 551 break; 552 case TagTypeKind::Union: 553 Out << "@UP"; 554 break; 555 case TagTypeKind::Enum: 556 llvm_unreachable("enum partial specialization"); 557 } 558 VisitTemplateParameterList(PartialSpec->getTemplateParameters()); 559 } 560 } 561 562 if (!AlreadyStarted) { 563 switch (D->getTagKind()) { 564 case TagTypeKind::Interface: 565 case TagTypeKind::Class: 566 case TagTypeKind::Struct: 567 Out << "@S"; 568 break; 569 case TagTypeKind::Union: 570 Out << "@U"; 571 break; 572 case TagTypeKind::Enum: 573 Out << "@E"; 574 break; 575 } 576 } 577 578 Out << '@'; 579 assert(Buf.size() > 0); 580 const unsigned off = Buf.size() - 1; 581 582 if (EmitDeclName(D)) { 583 if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) { 584 Buf[off] = 'A'; 585 Out << '@' << *TD; 586 } else { 587 if (D->isEmbeddedInDeclarator() && !D->isFreeStanding()) { 588 printLoc(Out, D->getLocation(), Context->getSourceManager(), true); 589 } else { 590 Buf[off] = 'a'; 591 if (auto *ED = dyn_cast<EnumDecl>(D)) { 592 // Distinguish USRs of anonymous enums by using their first 593 // enumerator. 594 auto enum_range = ED->enumerators(); 595 if (enum_range.begin() != enum_range.end()) { 596 Out << '@' << **enum_range.begin(); 597 } 598 } 599 } 600 } 601 } 602 603 // For a class template specialization, mangle the template arguments. 604 if (const ClassTemplateSpecializationDecl *Spec 605 = dyn_cast<ClassTemplateSpecializationDecl>(D)) { 606 const TemplateArgumentList &Args = Spec->getTemplateArgs(); 607 Out << '>'; 608 for (unsigned I = 0, N = Args.size(); I != N; ++I) { 609 Out << '#'; 610 VisitTemplateArgument(Args.get(I)); 611 } 612 } 613 } 614 615 void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) { 616 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) 617 return; 618 const DeclContext *DC = D->getDeclContext(); 619 if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC)) 620 Visit(DCN); 621 Out << "@T@"; 622 Out << D->getName(); 623 } 624 625 void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { 626 GenLoc(D, /*IncludeOffset=*/true); 627 } 628 629 void USRGenerator::GenExtSymbolContainer(const NamedDecl *D) { 630 StringRef Container = GetExternalSourceContainer(D); 631 if (!Container.empty()) 632 Out << "@M@" << Container; 633 } 634 635 bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) { 636 if (generatedLoc) 637 return IgnoreResults; 638 generatedLoc = true; 639 640 // Guard against null declarations in invalid code. 641 if (!D) { 642 IgnoreResults = true; 643 return true; 644 } 645 646 // Use the location of canonical decl. 647 D = D->getCanonicalDecl(); 648 649 IgnoreResults = 650 IgnoreResults || printLoc(Out, D->getBeginLoc(), 651 Context->getSourceManager(), IncludeOffset); 652 653 return IgnoreResults; 654 } 655 656 static void printQualifier(llvm::raw_ostream &Out, const LangOptions &LangOpts, 657 NestedNameSpecifier *NNS) { 658 // FIXME: Encode the qualifier, don't just print it. 659 PrintingPolicy PO(LangOpts); 660 PO.SuppressTagKeyword = true; 661 PO.SuppressUnwrittenScope = true; 662 PO.ConstantArraySizeAsWritten = false; 663 PO.AnonymousTagLocations = false; 664 NNS->print(Out, PO); 665 } 666 667 void USRGenerator::VisitType(QualType T) { 668 // This method mangles in USR information for types. It can possibly 669 // just reuse the naming-mangling logic used by codegen, although the 670 // requirements for USRs might not be the same. 671 ASTContext &Ctx = *Context; 672 673 do { 674 T = Ctx.getCanonicalType(T); 675 Qualifiers Q = T.getQualifiers(); 676 unsigned qVal = 0; 677 if (Q.hasConst()) 678 qVal |= 0x1; 679 if (Q.hasVolatile()) 680 qVal |= 0x2; 681 if (Q.hasRestrict()) 682 qVal |= 0x4; 683 if(qVal) 684 Out << ((char) ('0' + qVal)); 685 686 // Mangle in ObjC GC qualifiers? 687 688 if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) { 689 Out << 'P'; 690 T = Expansion->getPattern(); 691 } 692 693 if (const BuiltinType *BT = T->getAs<BuiltinType>()) { 694 switch (BT->getKind()) { 695 case BuiltinType::Void: 696 Out << 'v'; break; 697 case BuiltinType::Bool: 698 Out << 'b'; break; 699 case BuiltinType::UChar: 700 Out << 'c'; break; 701 case BuiltinType::Char8: 702 Out << 'u'; break; 703 case BuiltinType::Char16: 704 Out << 'q'; break; 705 case BuiltinType::Char32: 706 Out << 'w'; break; 707 case BuiltinType::UShort: 708 Out << 's'; break; 709 case BuiltinType::UInt: 710 Out << 'i'; break; 711 case BuiltinType::ULong: 712 Out << 'l'; break; 713 case BuiltinType::ULongLong: 714 Out << 'k'; break; 715 case BuiltinType::UInt128: 716 Out << 'j'; break; 717 case BuiltinType::Char_U: 718 case BuiltinType::Char_S: 719 Out << 'C'; break; 720 case BuiltinType::SChar: 721 Out << 'r'; break; 722 case BuiltinType::WChar_S: 723 case BuiltinType::WChar_U: 724 Out << 'W'; break; 725 case BuiltinType::Short: 726 Out << 'S'; break; 727 case BuiltinType::Int: 728 Out << 'I'; break; 729 case BuiltinType::Long: 730 Out << 'L'; break; 731 case BuiltinType::LongLong: 732 Out << 'K'; break; 733 case BuiltinType::Int128: 734 Out << 'J'; break; 735 case BuiltinType::Float16: 736 case BuiltinType::Half: 737 Out << 'h'; break; 738 case BuiltinType::Float: 739 Out << 'f'; break; 740 case BuiltinType::Double: 741 Out << 'd'; break; 742 case BuiltinType::LongDouble: 743 Out << 'D'; break; 744 case BuiltinType::Float128: 745 Out << 'Q'; break; 746 case BuiltinType::NullPtr: 747 Out << 'n'; break; 748 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 749 case BuiltinType::Id: \ 750 Out << "@BT@" << #Suffix << "_" << #ImgType; break; 751 #include "clang/Basic/OpenCLImageTypes.def" 752 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ 753 case BuiltinType::Id: \ 754 Out << "@BT@" << #ExtType; break; 755 #include "clang/Basic/OpenCLExtensionTypes.def" 756 case BuiltinType::OCLEvent: 757 Out << "@BT@OCLEvent"; break; 758 case BuiltinType::OCLClkEvent: 759 Out << "@BT@OCLClkEvent"; break; 760 case BuiltinType::OCLQueue: 761 Out << "@BT@OCLQueue"; break; 762 case BuiltinType::OCLReserveID: 763 Out << "@BT@OCLReserveID"; break; 764 case BuiltinType::OCLSampler: 765 Out << "@BT@OCLSampler"; break; 766 #define SVE_TYPE(Name, Id, SingletonId) \ 767 case BuiltinType::Id: \ 768 Out << "@BT@" << Name; break; 769 #include "clang/Basic/AArch64SVEACLETypes.def" 770 #define PPC_VECTOR_TYPE(Name, Id, Size) \ 771 case BuiltinType::Id: \ 772 Out << "@BT@" << #Name; break; 773 #include "clang/Basic/PPCTypes.def" 774 #define RVV_TYPE(Name, Id, SingletonId) \ 775 case BuiltinType::Id: \ 776 Out << "@BT@" << Name; break; 777 #include "clang/Basic/RISCVVTypes.def" 778 #define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id: 779 #include "clang/Basic/WebAssemblyReferenceTypes.def" 780 #define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) \ 781 case BuiltinType::Id: \ 782 Out << "@BT@" << #Name; \ 783 break; 784 #include "clang/Basic/AMDGPUTypes.def" 785 #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \ 786 case BuiltinType::Id: \ 787 Out << "@BT@" << #Name; \ 788 break; 789 #include "clang/Basic/HLSLIntangibleTypes.def" 790 case BuiltinType::ShortAccum: 791 Out << "@BT@ShortAccum"; break; 792 case BuiltinType::Accum: 793 Out << "@BT@Accum"; break; 794 case BuiltinType::LongAccum: 795 Out << "@BT@LongAccum"; break; 796 case BuiltinType::UShortAccum: 797 Out << "@BT@UShortAccum"; break; 798 case BuiltinType::UAccum: 799 Out << "@BT@UAccum"; break; 800 case BuiltinType::ULongAccum: 801 Out << "@BT@ULongAccum"; break; 802 case BuiltinType::ShortFract: 803 Out << "@BT@ShortFract"; break; 804 case BuiltinType::Fract: 805 Out << "@BT@Fract"; break; 806 case BuiltinType::LongFract: 807 Out << "@BT@LongFract"; break; 808 case BuiltinType::UShortFract: 809 Out << "@BT@UShortFract"; break; 810 case BuiltinType::UFract: 811 Out << "@BT@UFract"; break; 812 case BuiltinType::ULongFract: 813 Out << "@BT@ULongFract"; break; 814 case BuiltinType::SatShortAccum: 815 Out << "@BT@SatShortAccum"; break; 816 case BuiltinType::SatAccum: 817 Out << "@BT@SatAccum"; break; 818 case BuiltinType::SatLongAccum: 819 Out << "@BT@SatLongAccum"; break; 820 case BuiltinType::SatUShortAccum: 821 Out << "@BT@SatUShortAccum"; break; 822 case BuiltinType::SatUAccum: 823 Out << "@BT@SatUAccum"; break; 824 case BuiltinType::SatULongAccum: 825 Out << "@BT@SatULongAccum"; break; 826 case BuiltinType::SatShortFract: 827 Out << "@BT@SatShortFract"; break; 828 case BuiltinType::SatFract: 829 Out << "@BT@SatFract"; break; 830 case BuiltinType::SatLongFract: 831 Out << "@BT@SatLongFract"; break; 832 case BuiltinType::SatUShortFract: 833 Out << "@BT@SatUShortFract"; break; 834 case BuiltinType::SatUFract: 835 Out << "@BT@SatUFract"; break; 836 case BuiltinType::SatULongFract: 837 Out << "@BT@SatULongFract"; break; 838 case BuiltinType::BFloat16: 839 Out << "@BT@__bf16"; break; 840 case BuiltinType::Ibm128: 841 Out << "@BT@__ibm128"; break; 842 case BuiltinType::ObjCId: 843 Out << 'o'; break; 844 case BuiltinType::ObjCClass: 845 Out << 'O'; break; 846 case BuiltinType::ObjCSel: 847 Out << 'e'; break; 848 #define BUILTIN_TYPE(Id, SingletonId) 849 #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id: 850 #include "clang/AST/BuiltinTypes.def" 851 case BuiltinType::Dependent: 852 // If you're adding a new builtin type, please add its name prefixed 853 // with "@BT@" to `Out` (see cases above). 854 IgnoreResults = true; 855 break; 856 } 857 return; 858 } 859 860 // If we have already seen this (non-built-in) type, use a substitution 861 // encoding. 862 llvm::DenseMap<const Type *, unsigned>::iterator Substitution 863 = TypeSubstitutions.find(T.getTypePtr()); 864 if (Substitution != TypeSubstitutions.end()) { 865 Out << 'S' << Substitution->second << '_'; 866 return; 867 } else { 868 // Record this as a substitution. 869 unsigned Number = TypeSubstitutions.size(); 870 TypeSubstitutions[T.getTypePtr()] = Number; 871 } 872 873 if (const PointerType *PT = T->getAs<PointerType>()) { 874 Out << '*'; 875 T = PT->getPointeeType(); 876 continue; 877 } 878 if (const ObjCObjectPointerType *OPT = T->getAs<ObjCObjectPointerType>()) { 879 Out << '*'; 880 T = OPT->getPointeeType(); 881 continue; 882 } 883 if (const RValueReferenceType *RT = T->getAs<RValueReferenceType>()) { 884 Out << "&&"; 885 T = RT->getPointeeType(); 886 continue; 887 } 888 if (const ReferenceType *RT = T->getAs<ReferenceType>()) { 889 Out << '&'; 890 T = RT->getPointeeType(); 891 continue; 892 } 893 if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) { 894 Out << 'F'; 895 VisitType(FT->getReturnType()); 896 Out << '('; 897 for (const auto &I : FT->param_types()) { 898 Out << '#'; 899 VisitType(I); 900 } 901 Out << ')'; 902 if (FT->isVariadic()) 903 Out << '.'; 904 return; 905 } 906 if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) { 907 Out << 'B'; 908 T = BT->getPointeeType(); 909 continue; 910 } 911 if (const ComplexType *CT = T->getAs<ComplexType>()) { 912 Out << '<'; 913 T = CT->getElementType(); 914 continue; 915 } 916 if (const TagType *TT = T->getAs<TagType>()) { 917 Out << '$'; 918 VisitTagDecl(TT->getDecl()); 919 return; 920 } 921 if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) { 922 Out << '$'; 923 VisitObjCInterfaceDecl(OIT->getDecl()); 924 return; 925 } 926 if (const ObjCObjectType *OIT = T->getAs<ObjCObjectType>()) { 927 Out << 'Q'; 928 VisitType(OIT->getBaseType()); 929 for (auto *Prot : OIT->getProtocols()) 930 VisitObjCProtocolDecl(Prot); 931 return; 932 } 933 if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) { 934 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex(); 935 return; 936 } 937 if (const TemplateSpecializationType *Spec 938 = T->getAs<TemplateSpecializationType>()) { 939 Out << '>'; 940 VisitTemplateName(Spec->getTemplateName()); 941 Out << Spec->template_arguments().size(); 942 for (const auto &Arg : Spec->template_arguments()) 943 VisitTemplateArgument(Arg); 944 return; 945 } 946 if (const DependentNameType *DNT = T->getAs<DependentNameType>()) { 947 Out << '^'; 948 printQualifier(Out, LangOpts, DNT->getQualifier()); 949 Out << ':' << DNT->getIdentifier()->getName(); 950 return; 951 } 952 if (const InjectedClassNameType *InjT = T->getAs<InjectedClassNameType>()) { 953 T = InjT->getInjectedSpecializationType(); 954 continue; 955 } 956 if (const auto *VT = T->getAs<VectorType>()) { 957 Out << (T->isExtVectorType() ? ']' : '['); 958 Out << VT->getNumElements(); 959 T = VT->getElementType(); 960 continue; 961 } 962 if (const auto *const AT = dyn_cast<ArrayType>(T)) { 963 Out << '{'; 964 switch (AT->getSizeModifier()) { 965 case ArraySizeModifier::Static: 966 Out << 's'; 967 break; 968 case ArraySizeModifier::Star: 969 Out << '*'; 970 break; 971 case ArraySizeModifier::Normal: 972 Out << 'n'; 973 break; 974 } 975 if (const auto *const CAT = dyn_cast<ConstantArrayType>(T)) 976 Out << CAT->getSize(); 977 978 T = AT->getElementType(); 979 continue; 980 } 981 982 // Unhandled type. 983 Out << ' '; 984 break; 985 } while (true); 986 } 987 988 void USRGenerator::VisitTemplateParameterList( 989 const TemplateParameterList *Params) { 990 if (!Params) 991 return; 992 Out << '>' << Params->size(); 993 for (TemplateParameterList::const_iterator P = Params->begin(), 994 PEnd = Params->end(); 995 P != PEnd; ++P) { 996 Out << '#'; 997 if (isa<TemplateTypeParmDecl>(*P)) { 998 if (cast<TemplateTypeParmDecl>(*P)->isParameterPack()) 999 Out<< 'p'; 1000 Out << 'T'; 1001 continue; 1002 } 1003 1004 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) { 1005 if (NTTP->isParameterPack()) 1006 Out << 'p'; 1007 Out << 'N'; 1008 VisitType(NTTP->getType()); 1009 continue; 1010 } 1011 1012 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P); 1013 if (TTP->isParameterPack()) 1014 Out << 'p'; 1015 Out << 't'; 1016 VisitTemplateParameterList(TTP->getTemplateParameters()); 1017 } 1018 } 1019 1020 void USRGenerator::VisitTemplateName(TemplateName Name) { 1021 if (TemplateDecl *Template = Name.getAsTemplateDecl()) { 1022 if (TemplateTemplateParmDecl *TTP 1023 = dyn_cast<TemplateTemplateParmDecl>(Template)) { 1024 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex(); 1025 return; 1026 } 1027 1028 Visit(Template); 1029 return; 1030 } 1031 1032 // FIXME: Visit dependent template names. 1033 } 1034 1035 void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) { 1036 switch (Arg.getKind()) { 1037 case TemplateArgument::Null: 1038 break; 1039 1040 case TemplateArgument::Declaration: 1041 Visit(Arg.getAsDecl()); 1042 break; 1043 1044 case TemplateArgument::NullPtr: 1045 break; 1046 1047 case TemplateArgument::TemplateExpansion: 1048 Out << 'P'; // pack expansion of... 1049 [[fallthrough]]; 1050 case TemplateArgument::Template: 1051 VisitTemplateName(Arg.getAsTemplateOrTemplatePattern()); 1052 break; 1053 1054 case TemplateArgument::Expression: 1055 // FIXME: Visit expressions. 1056 break; 1057 1058 case TemplateArgument::Pack: 1059 Out << 'p' << Arg.pack_size(); 1060 for (const auto &P : Arg.pack_elements()) 1061 VisitTemplateArgument(P); 1062 break; 1063 1064 case TemplateArgument::Type: 1065 VisitType(Arg.getAsType()); 1066 break; 1067 1068 case TemplateArgument::Integral: 1069 Out << 'V'; 1070 VisitType(Arg.getIntegralType()); 1071 Out << Arg.getAsIntegral(); 1072 break; 1073 1074 case TemplateArgument::StructuralValue: { 1075 Out << 'S'; 1076 VisitType(Arg.getStructuralValueType()); 1077 ODRHash Hash{}; 1078 Hash.AddStructuralValue(Arg.getAsStructuralValue()); 1079 Out << Hash.CalculateHash(); 1080 break; 1081 } 1082 } 1083 } 1084 1085 void USRGenerator::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) { 1086 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) 1087 return; 1088 VisitDeclContext(D->getDeclContext()); 1089 Out << "@UUV@"; 1090 printQualifier(Out, LangOpts, D->getQualifier()); 1091 EmitDeclName(D); 1092 } 1093 1094 void USRGenerator::VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) { 1095 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) 1096 return; 1097 VisitDeclContext(D->getDeclContext()); 1098 Out << "@UUT@"; 1099 printQualifier(Out, LangOpts, D->getQualifier()); 1100 Out << D->getName(); // Simple name. 1101 } 1102 1103 void USRGenerator::VisitConceptDecl(const ConceptDecl *D) { 1104 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) 1105 return; 1106 VisitDeclContext(D->getDeclContext()); 1107 Out << "@CT@"; 1108 EmitDeclName(D); 1109 } 1110 1111 void USRGenerator::VisitMSGuidDecl(const MSGuidDecl *D) { 1112 VisitDeclContext(D->getDeclContext()); 1113 Out << "@MG@"; 1114 D->NamedDecl::printName(Out); 1115 } 1116 1117 //===----------------------------------------------------------------------===// 1118 // USR generation functions. 1119 //===----------------------------------------------------------------------===// 1120 1121 static void combineClassAndCategoryExtContainers(StringRef ClsSymDefinedIn, 1122 StringRef CatSymDefinedIn, 1123 raw_ostream &OS) { 1124 if (ClsSymDefinedIn.empty() && CatSymDefinedIn.empty()) 1125 return; 1126 if (CatSymDefinedIn.empty()) { 1127 OS << "@M@" << ClsSymDefinedIn << '@'; 1128 return; 1129 } 1130 OS << "@CM@" << CatSymDefinedIn << '@'; 1131 if (ClsSymDefinedIn != CatSymDefinedIn) { 1132 OS << ClsSymDefinedIn << '@'; 1133 } 1134 } 1135 1136 void clang::index::generateUSRForObjCClass(StringRef Cls, raw_ostream &OS, 1137 StringRef ExtSymDefinedIn, 1138 StringRef CategoryContextExtSymbolDefinedIn) { 1139 combineClassAndCategoryExtContainers(ExtSymDefinedIn, 1140 CategoryContextExtSymbolDefinedIn, OS); 1141 OS << "objc(cs)" << Cls; 1142 } 1143 1144 void clang::index::generateUSRForObjCCategory(StringRef Cls, StringRef Cat, 1145 raw_ostream &OS, 1146 StringRef ClsSymDefinedIn, 1147 StringRef CatSymDefinedIn) { 1148 combineClassAndCategoryExtContainers(ClsSymDefinedIn, CatSymDefinedIn, OS); 1149 OS << "objc(cy)" << Cls << '@' << Cat; 1150 } 1151 1152 void clang::index::generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS) { 1153 OS << '@' << Ivar; 1154 } 1155 1156 void clang::index::generateUSRForObjCMethod(StringRef Sel, 1157 bool IsInstanceMethod, 1158 raw_ostream &OS) { 1159 OS << (IsInstanceMethod ? "(im)" : "(cm)") << Sel; 1160 } 1161 1162 void clang::index::generateUSRForObjCProperty(StringRef Prop, bool isClassProp, 1163 raw_ostream &OS) { 1164 OS << (isClassProp ? "(cpy)" : "(py)") << Prop; 1165 } 1166 1167 void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS, 1168 StringRef ExtSymDefinedIn) { 1169 if (!ExtSymDefinedIn.empty()) 1170 OS << "@M@" << ExtSymDefinedIn << '@'; 1171 OS << "objc(pl)" << Prot; 1172 } 1173 1174 void clang::index::generateUSRForGlobalEnum(StringRef EnumName, raw_ostream &OS, 1175 StringRef ExtSymDefinedIn) { 1176 if (!ExtSymDefinedIn.empty()) 1177 OS << "@M@" << ExtSymDefinedIn; 1178 OS << "@E@" << EnumName; 1179 } 1180 1181 void clang::index::generateUSRForEnumConstant(StringRef EnumConstantName, 1182 raw_ostream &OS) { 1183 OS << '@' << EnumConstantName; 1184 } 1185 1186 bool clang::index::generateUSRForDecl(const Decl *D, 1187 SmallVectorImpl<char> &Buf) { 1188 if (!D) 1189 return true; 1190 return generateUSRForDecl(D, Buf, D->getASTContext().getLangOpts()); 1191 } 1192 1193 bool clang::index::generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &Buf, 1194 const LangOptions &LangOpts) { 1195 if (!D) 1196 return true; 1197 // We don't ignore decls with invalid source locations. Implicit decls, like 1198 // C++'s operator new function, can have invalid locations but it is fine to 1199 // create USRs that can identify them. 1200 1201 // Check if the declaration has explicit external USR specified. 1202 auto *CD = D->getCanonicalDecl(); 1203 if (auto *ExternalSymAttr = CD->getAttr<ExternalSourceSymbolAttr>()) { 1204 if (!ExternalSymAttr->getUSR().empty()) { 1205 llvm::raw_svector_ostream Out(Buf); 1206 Out << ExternalSymAttr->getUSR(); 1207 return false; 1208 } 1209 } 1210 USRGenerator UG(&D->getASTContext(), Buf, LangOpts); 1211 UG.Visit(D); 1212 return UG.ignoreResults(); 1213 } 1214 1215 bool clang::index::generateUSRForMacro(const MacroDefinitionRecord *MD, 1216 const SourceManager &SM, 1217 SmallVectorImpl<char> &Buf) { 1218 if (!MD) 1219 return true; 1220 return generateUSRForMacro(MD->getName()->getName(), MD->getLocation(), 1221 SM, Buf); 1222 1223 } 1224 1225 bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc, 1226 const SourceManager &SM, 1227 SmallVectorImpl<char> &Buf) { 1228 if (MacroName.empty()) 1229 return true; 1230 1231 llvm::raw_svector_ostream Out(Buf); 1232 1233 // Assume that system headers are sane. Don't put source location 1234 // information into the USR if the macro comes from a system header. 1235 bool ShouldGenerateLocation = Loc.isValid() && !SM.isInSystemHeader(Loc); 1236 1237 Out << getUSRSpacePrefix(); 1238 if (ShouldGenerateLocation) 1239 printLoc(Out, Loc, SM, /*IncludeOffset=*/true); 1240 Out << "@macro@"; 1241 Out << MacroName; 1242 return false; 1243 } 1244 1245 bool clang::index::generateUSRForType(QualType T, ASTContext &Ctx, 1246 SmallVectorImpl<char> &Buf) { 1247 return generateUSRForType(T, Ctx, Buf, Ctx.getLangOpts()); 1248 } 1249 1250 bool clang::index::generateUSRForType(QualType T, ASTContext &Ctx, 1251 SmallVectorImpl<char> &Buf, 1252 const LangOptions &LangOpts) { 1253 if (T.isNull()) 1254 return true; 1255 T = T.getCanonicalType(); 1256 1257 USRGenerator UG(&Ctx, Buf, LangOpts); 1258 UG.VisitType(T); 1259 return UG.ignoreResults(); 1260 } 1261 1262 bool clang::index::generateFullUSRForModule(const Module *Mod, 1263 raw_ostream &OS) { 1264 if (!Mod->Parent) 1265 return generateFullUSRForTopLevelModuleName(Mod->Name, OS); 1266 if (generateFullUSRForModule(Mod->Parent, OS)) 1267 return true; 1268 return generateUSRFragmentForModule(Mod, OS); 1269 } 1270 1271 bool clang::index::generateFullUSRForTopLevelModuleName(StringRef ModName, 1272 raw_ostream &OS) { 1273 OS << getUSRSpacePrefix(); 1274 return generateUSRFragmentForModuleName(ModName, OS); 1275 } 1276 1277 bool clang::index::generateUSRFragmentForModule(const Module *Mod, 1278 raw_ostream &OS) { 1279 return generateUSRFragmentForModuleName(Mod->Name, OS); 1280 } 1281 1282 bool clang::index::generateUSRFragmentForModuleName(StringRef ModName, 1283 raw_ostream &OS) { 1284 OS << "@M@" << ModName; 1285 return false; 1286 } 1287