diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp | 143 |
1 files changed, 119 insertions, 24 deletions
diff --git a/contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp b/contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp index 58f61c3..21054b0 100644 --- a/contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp +++ b/contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp @@ -46,6 +46,15 @@ static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc, return false; } +static StringRef GetExternalSourceContainer(const NamedDecl *D) { + if (!D) + return StringRef(); + if (auto *attr = D->getExternalSourceSymbolAttr()) { + return attr->getDefinedIn(); + } + return StringRef(); +} + namespace { class USRGenerator : public ConstDeclVisitor<USRGenerator> { SmallVectorImpl<char> &Buf; @@ -79,7 +88,8 @@ public: void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D); void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D); void VisitClassTemplateDecl(const ClassTemplateDecl *D); - void VisitObjCContainerDecl(const ObjCContainerDecl *CD); + void VisitObjCContainerDecl(const ObjCContainerDecl *CD, + const ObjCCategoryDecl *CatD = nullptr); void VisitObjCMethodDecl(const ObjCMethodDecl *MD); void VisitObjCPropertyDecl(const ObjCPropertyDecl *D); void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D); @@ -116,6 +126,8 @@ public: return D->getParentFunctionOrMethod() != nullptr; } + void GenExtSymbolContainer(const NamedDecl *D); + /// Generate the string component containing the location of the /// declaration. bool GenLoc(const Decl *D, bool IncludeOffset); @@ -127,13 +139,16 @@ public: /// itself. /// Generate a USR for an Objective-C class. - void GenObjCClass(StringRef cls) { - generateUSRForObjCClass(cls, Out); + void GenObjCClass(StringRef cls, StringRef ExtSymDefinedIn, + StringRef CategoryContextExtSymbolDefinedIn) { + generateUSRForObjCClass(cls, Out, ExtSymDefinedIn, + CategoryContextExtSymbolDefinedIn); } /// Generate a USR for an Objective-C class category. - void GenObjCCategory(StringRef cls, StringRef cat) { - generateUSRForObjCCategory(cls, cat, Out); + void GenObjCCategory(StringRef cls, StringRef cat, + StringRef clsExt, StringRef catExt) { + generateUSRForObjCCategory(cls, cat, Out, clsExt, catExt); } /// Generate a USR fragment for an Objective-C property. @@ -142,8 +157,8 @@ public: } /// Generate a USR for an Objective-C protocol. - void GenObjCProtocol(StringRef prot) { - generateUSRForObjCProtocol(prot, Out); + void GenObjCProtocol(StringRef prot, StringRef ext) { + generateUSRForObjCProtocol(prot, Out, ext); } void VisitType(QualType T); @@ -204,7 +219,11 @@ void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) { if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) return; + const unsigned StartSize = Buf.size(); VisitDeclContext(D->getDeclContext()); + if (Buf.size() == StartSize) + GenExtSymbolContainer(D); + bool IsTemplate = false; if (FunctionTemplateDecl *FunTmpl = D->getDescribedFunctionTemplate()) { IsTemplate = true; @@ -310,7 +329,7 @@ void USRGenerator::VisitVarDecl(const VarDecl *D) { // For a template specialization, mangle the template arguments. if (const VarTemplateSpecializationDecl *Spec = dyn_cast<VarTemplateSpecializationDecl>(D)) { - const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs(); + const TemplateArgumentList &Args = Spec->getTemplateArgs(); Out << '>'; for (unsigned I = 0, N = Args.size(); I != N; ++I) { Out << '#'; @@ -367,7 +386,16 @@ void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) { IgnoreResults = true; return; } - Visit(ID); + auto getCategoryContext = [](const ObjCMethodDecl *D) -> + const ObjCCategoryDecl * { + if (auto *CD = dyn_cast<ObjCCategoryDecl>(D->getDeclContext())) + return CD; + if (auto *ICD = dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext())) + return ICD->getCategoryDecl(); + return nullptr; + }; + auto *CD = getCategoryContext(D); + VisitObjCContainerDecl(ID, CD); } // Ideally we would use 'GenObjCMethod', but this is such a hot path // for Objective-C code that we don't want to use @@ -376,13 +404,15 @@ void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) { << DeclarationName(D->getSelector()); } -void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D) { +void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D, + const ObjCCategoryDecl *CatD) { switch (D->getKind()) { default: llvm_unreachable("Invalid ObjC container."); case Decl::ObjCInterface: case Decl::ObjCImplementation: - GenObjCClass(D->getName()); + GenObjCClass(D->getName(), GetExternalSourceContainer(D), + GetExternalSourceContainer(CatD)); break; case Decl::ObjCCategory: { const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D); @@ -402,7 +432,9 @@ void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D) { GenLoc(CD, /*IncludeOffset=*/true); } else - GenObjCCategory(ID->getName(), CD->getName()); + GenObjCCategory(ID->getName(), CD->getName(), + GetExternalSourceContainer(ID), + GetExternalSourceContainer(CD)); break; } @@ -417,12 +449,16 @@ void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D) { IgnoreResults = true; return; } - GenObjCCategory(ID->getName(), CD->getName()); + GenObjCCategory(ID->getName(), CD->getName(), + GetExternalSourceContainer(ID), + GetExternalSourceContainer(CD)); break; } - case Decl::ObjCProtocol: - GenObjCProtocol(cast<ObjCProtocolDecl>(D)->getName()); + case Decl::ObjCProtocol: { + const ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D); + GenObjCProtocol(PD->getName(), GetExternalSourceContainer(PD)); break; + } } } @@ -452,6 +488,8 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) { ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) return; + GenExtSymbolContainer(D); + D = D->getCanonicalDecl(); VisitDeclContext(D->getDeclContext()); @@ -521,7 +559,7 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) { // For a class template specialization, mangle the template arguments. if (const ClassTemplateSpecializationDecl *Spec = dyn_cast<ClassTemplateSpecializationDecl>(D)) { - const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs(); + const TemplateArgumentList &Args = Spec->getTemplateArgs(); Out << '>'; for (unsigned I = 0, N = Args.size(); I != N; ++I) { Out << '#'; @@ -544,6 +582,12 @@ void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { GenLoc(D, /*IncludeOffset=*/true); } +void USRGenerator::GenExtSymbolContainer(const NamedDecl *D) { + StringRef Container = GetExternalSourceContainer(D); + if (!Container.empty()) + Out << "@M@" << Container; +} + bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) { if (generatedLoc) return IgnoreResults; @@ -654,7 +698,6 @@ void USRGenerator::VisitType(QualType T) { case BuiltinType::OCLEvent: case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: - case BuiltinType::OCLNDRange: case BuiltinType::OCLReserveID: case BuiltinType::OCLSampler: IgnoreResults = true; @@ -768,7 +811,13 @@ void USRGenerator::VisitType(QualType T) { T = InjT->getInjectedSpecializationType(); continue; } - + if (const auto *VT = T->getAs<VectorType>()) { + Out << (T->isExtVectorType() ? ']' : '['); + Out << VT->getNumElements(); + T = VT->getElementType(); + continue; + } + // Unhandled type. Out << ' '; break; @@ -867,12 +916,34 @@ void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) { // USR generation functions. //===----------------------------------------------------------------------===// -void clang::index::generateUSRForObjCClass(StringRef Cls, raw_ostream &OS) { +static void combineClassAndCategoryExtContainers(StringRef ClsSymDefinedIn, + StringRef CatSymDefinedIn, + raw_ostream &OS) { + if (ClsSymDefinedIn.empty() && CatSymDefinedIn.empty()) + return; + if (CatSymDefinedIn.empty()) { + OS << "@M@" << ClsSymDefinedIn << '@'; + return; + } + OS << "@CM@" << CatSymDefinedIn << '@'; + if (ClsSymDefinedIn != CatSymDefinedIn) { + OS << ClsSymDefinedIn << '@'; + } +} + +void clang::index::generateUSRForObjCClass(StringRef Cls, raw_ostream &OS, + StringRef ExtSymDefinedIn, + StringRef CategoryContextExtSymbolDefinedIn) { + combineClassAndCategoryExtContainers(ExtSymDefinedIn, + CategoryContextExtSymbolDefinedIn, OS); OS << "objc(cs)" << Cls; } void clang::index::generateUSRForObjCCategory(StringRef Cls, StringRef Cat, - raw_ostream &OS) { + raw_ostream &OS, + StringRef ClsSymDefinedIn, + StringRef CatSymDefinedIn) { + combineClassAndCategoryExtContainers(ClsSymDefinedIn, CatSymDefinedIn, OS); OS << "objc(cy)" << Cls << '@' << Cat; } @@ -891,10 +962,25 @@ void clang::index::generateUSRForObjCProperty(StringRef Prop, bool isClassProp, OS << (isClassProp ? "(cpy)" : "(py)") << Prop; } -void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS) { +void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS, + StringRef ExtSymDefinedIn) { + if (!ExtSymDefinedIn.empty()) + OS << "@M@" << ExtSymDefinedIn << '@'; OS << "objc(pl)" << Prot; } +void clang::index::generateUSRForGlobalEnum(StringRef EnumName, raw_ostream &OS, + StringRef ExtSymDefinedIn) { + if (!ExtSymDefinedIn.empty()) + OS << "@M@" << ExtSymDefinedIn; + OS << "@E@" << EnumName; +} + +void clang::index::generateUSRForEnumConstant(StringRef EnumConstantName, + raw_ostream &OS) { + OS << '@' << EnumConstantName; +} + bool clang::index::generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &Buf) { if (!D) @@ -911,21 +997,30 @@ bool clang::index::generateUSRForDecl(const Decl *D, bool clang::index::generateUSRForMacro(const MacroDefinitionRecord *MD, const SourceManager &SM, SmallVectorImpl<char> &Buf) { + if (!MD) + return true; + return generateUSRForMacro(MD->getName()->getName(), MD->getLocation(), + SM, Buf); + +} + +bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc, + const SourceManager &SM, + SmallVectorImpl<char> &Buf) { // Don't generate USRs for things with invalid locations. - if (!MD || MD->getLocation().isInvalid()) + if (MacroName.empty() || Loc.isInvalid()) return true; llvm::raw_svector_ostream Out(Buf); // Assume that system headers are sane. Don't put source location // information into the USR if the macro comes from a system header. - SourceLocation Loc = MD->getLocation(); bool ShouldGenerateLocation = !SM.isInSystemHeader(Loc); Out << getUSRSpacePrefix(); if (ShouldGenerateLocation) printLoc(Out, Loc, SM, /*IncludeOffset=*/true); Out << "@macro@"; - Out << MD->getName()->getName(); + Out << MacroName; return false; } |