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