clang API Documentation
00001 //===- USRGeneration.cpp - Routines for USR generation --------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "clang/Index/USRGeneration.h" 00011 #include "clang/AST/ASTContext.h" 00012 #include "clang/AST/DeclTemplate.h" 00013 #include "clang/AST/DeclVisitor.h" 00014 #include "clang/Lex/PreprocessingRecord.h" 00015 #include "llvm/ADT/SmallString.h" 00016 #include "llvm/Support/Path.h" 00017 #include "llvm/Support/raw_ostream.h" 00018 00019 using namespace clang; 00020 using namespace clang::index; 00021 00022 //===----------------------------------------------------------------------===// 00023 // USR generation. 00024 //===----------------------------------------------------------------------===// 00025 00026 /// \returns true on error. 00027 static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc, 00028 const SourceManager &SM, bool IncludeOffset) { 00029 if (Loc.isInvalid()) { 00030 return true; 00031 } 00032 Loc = SM.getExpansionLoc(Loc); 00033 const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(Loc); 00034 const FileEntry *FE = SM.getFileEntryForID(Decomposed.first); 00035 if (FE) { 00036 OS << llvm::sys::path::filename(FE->getName()); 00037 } else { 00038 // This case really isn't interesting. 00039 return true; 00040 } 00041 if (IncludeOffset) { 00042 // Use the offest into the FileID to represent the location. Using 00043 // a line/column can cause us to look back at the original source file, 00044 // which is expensive. 00045 OS << '@' << Decomposed.second; 00046 } 00047 return false; 00048 } 00049 00050 namespace { 00051 class USRGenerator : public ConstDeclVisitor<USRGenerator> { 00052 SmallVectorImpl<char> &Buf; 00053 llvm::raw_svector_ostream Out; 00054 bool IgnoreResults; 00055 ASTContext *Context; 00056 bool generatedLoc; 00057 00058 llvm::DenseMap<const Type *, unsigned> TypeSubstitutions; 00059 00060 public: 00061 explicit USRGenerator(ASTContext *Ctx, SmallVectorImpl<char> &Buf) 00062 : Buf(Buf), 00063 Out(Buf), 00064 IgnoreResults(false), 00065 Context(Ctx), 00066 generatedLoc(false) 00067 { 00068 // Add the USR space prefix. 00069 Out << getUSRSpacePrefix(); 00070 } 00071 00072 bool ignoreResults() const { return IgnoreResults; } 00073 00074 // Visitation methods from generating USRs from AST elements. 00075 void VisitDeclContext(const DeclContext *D); 00076 void VisitFieldDecl(const FieldDecl *D); 00077 void VisitFunctionDecl(const FunctionDecl *D); 00078 void VisitNamedDecl(const NamedDecl *D); 00079 void VisitNamespaceDecl(const NamespaceDecl *D); 00080 void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D); 00081 void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D); 00082 void VisitClassTemplateDecl(const ClassTemplateDecl *D); 00083 void VisitObjCContainerDecl(const ObjCContainerDecl *CD); 00084 void VisitObjCMethodDecl(const ObjCMethodDecl *MD); 00085 void VisitObjCPropertyDecl(const ObjCPropertyDecl *D); 00086 void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D); 00087 void VisitTagDecl(const TagDecl *D); 00088 void VisitTypedefDecl(const TypedefDecl *D); 00089 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D); 00090 void VisitVarDecl(const VarDecl *D); 00091 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D); 00092 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D); 00093 void VisitLinkageSpecDecl(const LinkageSpecDecl *D) { 00094 IgnoreResults = true; 00095 } 00096 void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { 00097 IgnoreResults = true; 00098 } 00099 void VisitUsingDecl(const UsingDecl *D) { 00100 IgnoreResults = true; 00101 } 00102 void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) { 00103 IgnoreResults = true; 00104 } 00105 void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) { 00106 IgnoreResults = true; 00107 } 00108 00109 bool ShouldGenerateLocation(const NamedDecl *D); 00110 00111 bool isLocal(const NamedDecl *D) { 00112 return D->getParentFunctionOrMethod() != nullptr; 00113 } 00114 00115 /// Generate the string component containing the location of the 00116 /// declaration. 00117 bool GenLoc(const Decl *D, bool IncludeOffset); 00118 00119 /// String generation methods used both by the visitation methods 00120 /// and from other clients that want to directly generate USRs. These 00121 /// methods do not construct complete USRs (which incorporate the parents 00122 /// of an AST element), but only the fragments concerning the AST element 00123 /// itself. 00124 00125 /// Generate a USR for an Objective-C class. 00126 void GenObjCClass(StringRef cls) { 00127 generateUSRForObjCClass(cls, Out); 00128 } 00129 /// Generate a USR for an Objective-C class category. 00130 void GenObjCCategory(StringRef cls, StringRef cat) { 00131 generateUSRForObjCCategory(cls, cat, Out); 00132 } 00133 /// Generate a USR fragment for an Objective-C property. 00134 void GenObjCProperty(StringRef prop) { 00135 generateUSRForObjCProperty(prop, Out); 00136 } 00137 /// Generate a USR for an Objective-C protocol. 00138 void GenObjCProtocol(StringRef prot) { 00139 generateUSRForObjCProtocol(prot, Out); 00140 } 00141 00142 void VisitType(QualType T); 00143 void VisitTemplateParameterList(const TemplateParameterList *Params); 00144 void VisitTemplateName(TemplateName Name); 00145 void VisitTemplateArgument(const TemplateArgument &Arg); 00146 00147 /// Emit a Decl's name using NamedDecl::printName() and return true if 00148 /// the decl had no name. 00149 bool EmitDeclName(const NamedDecl *D); 00150 }; 00151 00152 } // end anonymous namespace 00153 00154 //===----------------------------------------------------------------------===// 00155 // Generating USRs from ASTS. 00156 //===----------------------------------------------------------------------===// 00157 00158 bool USRGenerator::EmitDeclName(const NamedDecl *D) { 00159 Out.flush(); 00160 const unsigned startSize = Buf.size(); 00161 D->printName(Out); 00162 Out.flush(); 00163 const unsigned endSize = Buf.size(); 00164 return startSize == endSize; 00165 } 00166 00167 bool USRGenerator::ShouldGenerateLocation(const NamedDecl *D) { 00168 if (D->isExternallyVisible()) 00169 return false; 00170 if (D->getParentFunctionOrMethod()) 00171 return true; 00172 const SourceManager &SM = Context->getSourceManager(); 00173 return !SM.isInSystemHeader(D->getLocation()); 00174 } 00175 00176 void USRGenerator::VisitDeclContext(const DeclContext *DC) { 00177 if (const NamedDecl *D = dyn_cast<NamedDecl>(DC)) 00178 Visit(D); 00179 } 00180 00181 void USRGenerator::VisitFieldDecl(const FieldDecl *D) { 00182 // The USR for an ivar declared in a class extension is based on the 00183 // ObjCInterfaceDecl, not the ObjCCategoryDecl. 00184 if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D)) 00185 Visit(ID); 00186 else 00187 VisitDeclContext(D->getDeclContext()); 00188 Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@"); 00189 if (EmitDeclName(D)) { 00190 // Bit fields can be anonymous. 00191 IgnoreResults = true; 00192 return; 00193 } 00194 } 00195 00196 void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) { 00197 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) 00198 return; 00199 00200 VisitDeclContext(D->getDeclContext()); 00201 if (FunctionTemplateDecl *FunTmpl = D->getDescribedFunctionTemplate()) { 00202 Out << "@FT@"; 00203 VisitTemplateParameterList(FunTmpl->getTemplateParameters()); 00204 } else 00205 Out << "@F@"; 00206 D->printName(Out); 00207 00208 ASTContext &Ctx = *Context; 00209 if (!Ctx.getLangOpts().CPlusPlus || D->isExternC()) 00210 return; 00211 00212 if (const TemplateArgumentList * 00213 SpecArgs = D->getTemplateSpecializationArgs()) { 00214 Out << '<'; 00215 for (unsigned I = 0, N = SpecArgs->size(); I != N; ++I) { 00216 Out << '#'; 00217 VisitTemplateArgument(SpecArgs->get(I)); 00218 } 00219 Out << '>'; 00220 } 00221 00222 // Mangle in type information for the arguments. 00223 for (auto PD : D->params()) { 00224 Out << '#'; 00225 VisitType(PD->getType()); 00226 } 00227 if (D->isVariadic()) 00228 Out << '.'; 00229 Out << '#'; 00230 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { 00231 if (MD->isStatic()) 00232 Out << 'S'; 00233 if (unsigned quals = MD->getTypeQualifiers()) 00234 Out << (char)('0' + quals); 00235 } 00236 } 00237 00238 void USRGenerator::VisitNamedDecl(const NamedDecl *D) { 00239 VisitDeclContext(D->getDeclContext()); 00240 Out << "@"; 00241 00242 if (EmitDeclName(D)) { 00243 // The string can be empty if the declaration has no name; e.g., it is 00244 // the ParmDecl with no name for declaration of a function pointer type, 00245 // e.g.: void (*f)(void *); 00246 // In this case, don't generate a USR. 00247 IgnoreResults = true; 00248 } 00249 } 00250 00251 void USRGenerator::VisitVarDecl(const VarDecl *D) { 00252 // VarDecls can be declared 'extern' within a function or method body, 00253 // but their enclosing DeclContext is the function, not the TU. We need 00254 // to check the storage class to correctly generate the USR. 00255 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) 00256 return; 00257 00258 VisitDeclContext(D->getDeclContext()); 00259 00260 // Variables always have simple names. 00261 StringRef s = D->getName(); 00262 00263 // The string can be empty if the declaration has no name; e.g., it is 00264 // the ParmDecl with no name for declaration of a function pointer type, e.g.: 00265 // void (*f)(void *); 00266 // In this case, don't generate a USR. 00267 if (s.empty()) 00268 IgnoreResults = true; 00269 else 00270 Out << '@' << s; 00271 } 00272 00273 void USRGenerator::VisitNonTypeTemplateParmDecl( 00274 const NonTypeTemplateParmDecl *D) { 00275 GenLoc(D, /*IncludeOffset=*/true); 00276 return; 00277 } 00278 00279 void USRGenerator::VisitTemplateTemplateParmDecl( 00280 const TemplateTemplateParmDecl *D) { 00281 GenLoc(D, /*IncludeOffset=*/true); 00282 return; 00283 } 00284 00285 void USRGenerator::VisitNamespaceDecl(const NamespaceDecl *D) { 00286 if (D->isAnonymousNamespace()) { 00287 Out << "@aN"; 00288 return; 00289 } 00290 00291 VisitDeclContext(D->getDeclContext()); 00292 if (!IgnoreResults) 00293 Out << "@N@" << D->getName(); 00294 } 00295 00296 void USRGenerator::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { 00297 VisitFunctionDecl(D->getTemplatedDecl()); 00298 } 00299 00300 void USRGenerator::VisitClassTemplateDecl(const ClassTemplateDecl *D) { 00301 VisitTagDecl(D->getTemplatedDecl()); 00302 } 00303 00304 void USRGenerator::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { 00305 VisitDeclContext(D->getDeclContext()); 00306 if (!IgnoreResults) 00307 Out << "@NA@" << D->getName(); 00308 } 00309 00310 void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) { 00311 const DeclContext *container = D->getDeclContext(); 00312 if (const ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) { 00313 Visit(pd); 00314 } 00315 else { 00316 // The USR for a method declared in a class extension or category is based on 00317 // the ObjCInterfaceDecl, not the ObjCCategoryDecl. 00318 const ObjCInterfaceDecl *ID = D->getClassInterface(); 00319 if (!ID) { 00320 IgnoreResults = true; 00321 return; 00322 } 00323 Visit(ID); 00324 } 00325 // Ideally we would use 'GenObjCMethod', but this is such a hot path 00326 // for Objective-C code that we don't want to use 00327 // DeclarationName::getAsString(). 00328 Out << (D->isInstanceMethod() ? "(im)" : "(cm)") 00329 << DeclarationName(D->getSelector()); 00330 } 00331 00332 void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D) { 00333 switch (D->getKind()) { 00334 default: 00335 llvm_unreachable("Invalid ObjC container."); 00336 case Decl::ObjCInterface: 00337 case Decl::ObjCImplementation: 00338 GenObjCClass(D->getName()); 00339 break; 00340 case Decl::ObjCCategory: { 00341 const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D); 00342 const ObjCInterfaceDecl *ID = CD->getClassInterface(); 00343 if (!ID) { 00344 // Handle invalid code where the @interface might not 00345 // have been specified. 00346 // FIXME: We should be able to generate this USR even if the 00347 // @interface isn't available. 00348 IgnoreResults = true; 00349 return; 00350 } 00351 // Specially handle class extensions, which are anonymous categories. 00352 // We want to mangle in the location to uniquely distinguish them. 00353 if (CD->IsClassExtension()) { 00354 Out << "objc(ext)" << ID->getName() << '@'; 00355 GenLoc(CD, /*IncludeOffset=*/true); 00356 } 00357 else 00358 GenObjCCategory(ID->getName(), CD->getName()); 00359 00360 break; 00361 } 00362 case Decl::ObjCCategoryImpl: { 00363 const ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D); 00364 const ObjCInterfaceDecl *ID = CD->getClassInterface(); 00365 if (!ID) { 00366 // Handle invalid code where the @interface might not 00367 // have been specified. 00368 // FIXME: We should be able to generate this USR even if the 00369 // @interface isn't available. 00370 IgnoreResults = true; 00371 return; 00372 } 00373 GenObjCCategory(ID->getName(), CD->getName()); 00374 break; 00375 } 00376 case Decl::ObjCProtocol: 00377 GenObjCProtocol(cast<ObjCProtocolDecl>(D)->getName()); 00378 break; 00379 } 00380 } 00381 00382 void USRGenerator::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { 00383 // The USR for a property declared in a class extension or category is based 00384 // on the ObjCInterfaceDecl, not the ObjCCategoryDecl. 00385 if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D)) 00386 Visit(ID); 00387 else 00388 Visit(cast<Decl>(D->getDeclContext())); 00389 GenObjCProperty(D->getName()); 00390 } 00391 00392 void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { 00393 if (ObjCPropertyDecl *PD = D->getPropertyDecl()) { 00394 VisitObjCPropertyDecl(PD); 00395 return; 00396 } 00397 00398 IgnoreResults = true; 00399 } 00400 00401 void USRGenerator::VisitTagDecl(const TagDecl *D) { 00402 // Add the location of the tag decl to handle resolution across 00403 // translation units. 00404 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) 00405 return; 00406 00407 D = D->getCanonicalDecl(); 00408 VisitDeclContext(D->getDeclContext()); 00409 00410 bool AlreadyStarted = false; 00411 if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) { 00412 if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) { 00413 AlreadyStarted = true; 00414 00415 switch (D->getTagKind()) { 00416 case TTK_Interface: 00417 case TTK_Struct: Out << "@ST"; break; 00418 case TTK_Class: Out << "@CT"; break; 00419 case TTK_Union: Out << "@UT"; break; 00420 case TTK_Enum: llvm_unreachable("enum template"); 00421 } 00422 VisitTemplateParameterList(ClassTmpl->getTemplateParameters()); 00423 } else if (const ClassTemplatePartialSpecializationDecl *PartialSpec 00424 = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) { 00425 AlreadyStarted = true; 00426 00427 switch (D->getTagKind()) { 00428 case TTK_Interface: 00429 case TTK_Struct: Out << "@SP"; break; 00430 case TTK_Class: Out << "@CP"; break; 00431 case TTK_Union: Out << "@UP"; break; 00432 case TTK_Enum: llvm_unreachable("enum partial specialization"); 00433 } 00434 VisitTemplateParameterList(PartialSpec->getTemplateParameters()); 00435 } 00436 } 00437 00438 if (!AlreadyStarted) { 00439 switch (D->getTagKind()) { 00440 case TTK_Interface: 00441 case TTK_Struct: Out << "@S"; break; 00442 case TTK_Class: Out << "@C"; break; 00443 case TTK_Union: Out << "@U"; break; 00444 case TTK_Enum: Out << "@E"; break; 00445 } 00446 } 00447 00448 Out << '@'; 00449 Out.flush(); 00450 assert(Buf.size() > 0); 00451 const unsigned off = Buf.size() - 1; 00452 00453 if (EmitDeclName(D)) { 00454 if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) { 00455 Buf[off] = 'A'; 00456 Out << '@' << *TD; 00457 } 00458 else 00459 Buf[off] = 'a'; 00460 } 00461 00462 // For a class template specialization, mangle the template arguments. 00463 if (const ClassTemplateSpecializationDecl *Spec 00464 = dyn_cast<ClassTemplateSpecializationDecl>(D)) { 00465 const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs(); 00466 Out << '>'; 00467 for (unsigned I = 0, N = Args.size(); I != N; ++I) { 00468 Out << '#'; 00469 VisitTemplateArgument(Args.get(I)); 00470 } 00471 } 00472 } 00473 00474 void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) { 00475 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) 00476 return; 00477 const DeclContext *DC = D->getDeclContext(); 00478 if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC)) 00479 Visit(DCN); 00480 Out << "@T@"; 00481 Out << D->getName(); 00482 } 00483 00484 void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { 00485 GenLoc(D, /*IncludeOffset=*/true); 00486 return; 00487 } 00488 00489 bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) { 00490 if (generatedLoc) 00491 return IgnoreResults; 00492 generatedLoc = true; 00493 00494 // Guard against null declarations in invalid code. 00495 if (!D) { 00496 IgnoreResults = true; 00497 return true; 00498 } 00499 00500 // Use the location of canonical decl. 00501 D = D->getCanonicalDecl(); 00502 00503 IgnoreResults = 00504 IgnoreResults || printLoc(Out, D->getLocStart(), 00505 Context->getSourceManager(), IncludeOffset); 00506 00507 return IgnoreResults; 00508 } 00509 00510 void USRGenerator::VisitType(QualType T) { 00511 // This method mangles in USR information for types. It can possibly 00512 // just reuse the naming-mangling logic used by codegen, although the 00513 // requirements for USRs might not be the same. 00514 ASTContext &Ctx = *Context; 00515 00516 do { 00517 T = Ctx.getCanonicalType(T); 00518 Qualifiers Q = T.getQualifiers(); 00519 unsigned qVal = 0; 00520 if (Q.hasConst()) 00521 qVal |= 0x1; 00522 if (Q.hasVolatile()) 00523 qVal |= 0x2; 00524 if (Q.hasRestrict()) 00525 qVal |= 0x4; 00526 if(qVal) 00527 Out << ((char) ('0' + qVal)); 00528 00529 // Mangle in ObjC GC qualifiers? 00530 00531 if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) { 00532 Out << 'P'; 00533 T = Expansion->getPattern(); 00534 } 00535 00536 if (const BuiltinType *BT = T->getAs<BuiltinType>()) { 00537 unsigned char c = '\0'; 00538 switch (BT->getKind()) { 00539 case BuiltinType::Void: 00540 c = 'v'; break; 00541 case BuiltinType::Bool: 00542 c = 'b'; break; 00543 case BuiltinType::Char_U: 00544 case BuiltinType::UChar: 00545 c = 'c'; break; 00546 case BuiltinType::Char16: 00547 c = 'q'; break; 00548 case BuiltinType::Char32: 00549 c = 'w'; break; 00550 case BuiltinType::UShort: 00551 c = 's'; break; 00552 case BuiltinType::UInt: 00553 c = 'i'; break; 00554 case BuiltinType::ULong: 00555 c = 'l'; break; 00556 case BuiltinType::ULongLong: 00557 c = 'k'; break; 00558 case BuiltinType::UInt128: 00559 c = 'j'; break; 00560 case BuiltinType::Char_S: 00561 case BuiltinType::SChar: 00562 c = 'C'; break; 00563 case BuiltinType::WChar_S: 00564 case BuiltinType::WChar_U: 00565 c = 'W'; break; 00566 case BuiltinType::Short: 00567 c = 'S'; break; 00568 case BuiltinType::Int: 00569 c = 'I'; break; 00570 case BuiltinType::Long: 00571 c = 'L'; break; 00572 case BuiltinType::LongLong: 00573 c = 'K'; break; 00574 case BuiltinType::Int128: 00575 c = 'J'; break; 00576 case BuiltinType::Half: 00577 c = 'h'; break; 00578 case BuiltinType::Float: 00579 c = 'f'; break; 00580 case BuiltinType::Double: 00581 c = 'd'; break; 00582 case BuiltinType::LongDouble: 00583 c = 'D'; break; 00584 case BuiltinType::NullPtr: 00585 c = 'n'; break; 00586 #define BUILTIN_TYPE(Id, SingletonId) 00587 #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id: 00588 #include "clang/AST/BuiltinTypes.def" 00589 case BuiltinType::Dependent: 00590 case BuiltinType::OCLImage1d: 00591 case BuiltinType::OCLImage1dArray: 00592 case BuiltinType::OCLImage1dBuffer: 00593 case BuiltinType::OCLImage2d: 00594 case BuiltinType::OCLImage2dArray: 00595 case BuiltinType::OCLImage3d: 00596 case BuiltinType::OCLEvent: 00597 case BuiltinType::OCLSampler: 00598 IgnoreResults = true; 00599 return; 00600 case BuiltinType::ObjCId: 00601 c = 'o'; break; 00602 case BuiltinType::ObjCClass: 00603 c = 'O'; break; 00604 case BuiltinType::ObjCSel: 00605 c = 'e'; break; 00606 } 00607 Out << c; 00608 return; 00609 } 00610 00611 // If we have already seen this (non-built-in) type, use a substitution 00612 // encoding. 00613 llvm::DenseMap<const Type *, unsigned>::iterator Substitution 00614 = TypeSubstitutions.find(T.getTypePtr()); 00615 if (Substitution != TypeSubstitutions.end()) { 00616 Out << 'S' << Substitution->second << '_'; 00617 return; 00618 } else { 00619 // Record this as a substitution. 00620 unsigned Number = TypeSubstitutions.size(); 00621 TypeSubstitutions[T.getTypePtr()] = Number; 00622 } 00623 00624 if (const PointerType *PT = T->getAs<PointerType>()) { 00625 Out << '*'; 00626 T = PT->getPointeeType(); 00627 continue; 00628 } 00629 if (const ReferenceType *RT = T->getAs<ReferenceType>()) { 00630 Out << '&'; 00631 T = RT->getPointeeType(); 00632 continue; 00633 } 00634 if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) { 00635 Out << 'F'; 00636 VisitType(FT->getReturnType()); 00637 for (const auto &I : FT->param_types()) 00638 VisitType(I); 00639 if (FT->isVariadic()) 00640 Out << '.'; 00641 return; 00642 } 00643 if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) { 00644 Out << 'B'; 00645 T = BT->getPointeeType(); 00646 continue; 00647 } 00648 if (const ComplexType *CT = T->getAs<ComplexType>()) { 00649 Out << '<'; 00650 T = CT->getElementType(); 00651 continue; 00652 } 00653 if (const TagType *TT = T->getAs<TagType>()) { 00654 Out << '$'; 00655 VisitTagDecl(TT->getDecl()); 00656 return; 00657 } 00658 if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) { 00659 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex(); 00660 return; 00661 } 00662 if (const TemplateSpecializationType *Spec 00663 = T->getAs<TemplateSpecializationType>()) { 00664 Out << '>'; 00665 VisitTemplateName(Spec->getTemplateName()); 00666 Out << Spec->getNumArgs(); 00667 for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I) 00668 VisitTemplateArgument(Spec->getArg(I)); 00669 return; 00670 } 00671 00672 // Unhandled type. 00673 Out << ' '; 00674 break; 00675 } while (true); 00676 } 00677 00678 void USRGenerator::VisitTemplateParameterList( 00679 const TemplateParameterList *Params) { 00680 if (!Params) 00681 return; 00682 Out << '>' << Params->size(); 00683 for (TemplateParameterList::const_iterator P = Params->begin(), 00684 PEnd = Params->end(); 00685 P != PEnd; ++P) { 00686 Out << '#'; 00687 if (isa<TemplateTypeParmDecl>(*P)) { 00688 if (cast<TemplateTypeParmDecl>(*P)->isParameterPack()) 00689 Out<< 'p'; 00690 Out << 'T'; 00691 continue; 00692 } 00693 00694 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) { 00695 if (NTTP->isParameterPack()) 00696 Out << 'p'; 00697 Out << 'N'; 00698 VisitType(NTTP->getType()); 00699 continue; 00700 } 00701 00702 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P); 00703 if (TTP->isParameterPack()) 00704 Out << 'p'; 00705 Out << 't'; 00706 VisitTemplateParameterList(TTP->getTemplateParameters()); 00707 } 00708 } 00709 00710 void USRGenerator::VisitTemplateName(TemplateName Name) { 00711 if (TemplateDecl *Template = Name.getAsTemplateDecl()) { 00712 if (TemplateTemplateParmDecl *TTP 00713 = dyn_cast<TemplateTemplateParmDecl>(Template)) { 00714 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex(); 00715 return; 00716 } 00717 00718 Visit(Template); 00719 return; 00720 } 00721 00722 // FIXME: Visit dependent template names. 00723 } 00724 00725 void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) { 00726 switch (Arg.getKind()) { 00727 case TemplateArgument::Null: 00728 break; 00729 00730 case TemplateArgument::Declaration: 00731 Visit(Arg.getAsDecl()); 00732 break; 00733 00734 case TemplateArgument::NullPtr: 00735 break; 00736 00737 case TemplateArgument::TemplateExpansion: 00738 Out << 'P'; // pack expansion of... 00739 // Fall through 00740 case TemplateArgument::Template: 00741 VisitTemplateName(Arg.getAsTemplateOrTemplatePattern()); 00742 break; 00743 00744 case TemplateArgument::Expression: 00745 // FIXME: Visit expressions. 00746 break; 00747 00748 case TemplateArgument::Pack: 00749 Out << 'p' << Arg.pack_size(); 00750 for (const auto &P : Arg.pack_elements()) 00751 VisitTemplateArgument(P); 00752 break; 00753 00754 case TemplateArgument::Type: 00755 VisitType(Arg.getAsType()); 00756 break; 00757 00758 case TemplateArgument::Integral: 00759 Out << 'V'; 00760 VisitType(Arg.getIntegralType()); 00761 Out << Arg.getAsIntegral(); 00762 break; 00763 } 00764 } 00765 00766 //===----------------------------------------------------------------------===// 00767 // USR generation functions. 00768 //===----------------------------------------------------------------------===// 00769 00770 void clang::index::generateUSRForObjCClass(StringRef Cls, raw_ostream &OS) { 00771 OS << "objc(cs)" << Cls; 00772 } 00773 00774 void clang::index::generateUSRForObjCCategory(StringRef Cls, StringRef Cat, 00775 raw_ostream &OS) { 00776 OS << "objc(cy)" << Cls << '@' << Cat; 00777 } 00778 00779 void clang::index::generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS) { 00780 OS << '@' << Ivar; 00781 } 00782 00783 void clang::index::generateUSRForObjCMethod(StringRef Sel, 00784 bool IsInstanceMethod, 00785 raw_ostream &OS) { 00786 OS << (IsInstanceMethod ? "(im)" : "(cm)") << Sel; 00787 } 00788 00789 void clang::index::generateUSRForObjCProperty(StringRef Prop, raw_ostream &OS) { 00790 OS << "(py)" << Prop; 00791 } 00792 00793 void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS) { 00794 OS << "objc(pl)" << Prot; 00795 } 00796 00797 bool clang::index::generateUSRForDecl(const Decl *D, 00798 SmallVectorImpl<char> &Buf) { 00799 // Don't generate USRs for things with invalid locations. 00800 if (!D || D->getLocStart().isInvalid()) 00801 return true; 00802 00803 USRGenerator UG(&D->getASTContext(), Buf); 00804 UG.Visit(D); 00805 return UG.ignoreResults(); 00806 } 00807 00808 bool clang::index::generateUSRForMacro(const MacroDefinition *MD, 00809 const SourceManager &SM, 00810 SmallVectorImpl<char> &Buf) { 00811 // Don't generate USRs for things with invalid locations. 00812 if (!MD || MD->getLocation().isInvalid()) 00813 return true; 00814 00815 llvm::raw_svector_ostream Out(Buf); 00816 00817 // Assume that system headers are sane. Don't put source location 00818 // information into the USR if the macro comes from a system header. 00819 SourceLocation Loc = MD->getLocation(); 00820 bool ShouldGenerateLocation = !SM.isInSystemHeader(Loc); 00821 00822 Out << getUSRSpacePrefix(); 00823 if (ShouldGenerateLocation) 00824 printLoc(Out, Loc, SM, /*IncludeOffset=*/true); 00825 Out << "@macro@"; 00826 Out << MD->getName()->getName(); 00827 return false; 00828 } 00829