summaryrefslogtreecommitdiff
path: root/lib/Index/USRGeneration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Index/USRGeneration.cpp')
-rw-r--r--lib/Index/USRGeneration.cpp115
1 files changed, 98 insertions, 17 deletions
diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp
index 73dddd9a8b366..ed469f677a34e 100644
--- a/lib/Index/USRGeneration.cpp
+++ b/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->getAttr<ExternalSourceSymbolAttr>()) {
+ 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;
@@ -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());
@@ -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;
@@ -866,12 +910,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;
}
@@ -890,10 +956,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)