Fix USRs for 'extern' variables declaration in functions/method bodies.
Fix USRs for @synthesize.
Add more USR tests.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101954 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/CIndex/CIndexUSRs.cpp b/tools/CIndex/CIndexUSRs.cpp
index d67f97a..58870b9 100644
--- a/tools/CIndex/CIndexUSRs.cpp
+++ b/tools/CIndex/CIndexUSRs.cpp
@@ -46,11 +46,13 @@
void VisitNamespaceDecl(NamespaceDecl *D);
void VisitObjCClassDecl(ObjCClassDecl *CD);
void VisitObjCContainerDecl(ObjCContainerDecl *CD);
- void VisitObjCMethodDecl(ObjCMethodDecl *MD);
void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *P);
+ void VisitObjCMethodDecl(ObjCMethodDecl *MD);
void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
+ void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
void VisitTagDecl(TagDecl *D);
void VisitTypedefDecl(TypedefDecl *D);
+ void VisitVarDecl(VarDecl *D);
/// Generate the string component containing the location of the
/// declaration.
@@ -132,7 +134,7 @@
return;
}
VisitDeclContext(D->getDeclContext());
- Out << "@FI@" << s;
+ Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@") << s;
}
void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
@@ -153,6 +155,24 @@
GenNamedDecl(s);
}
+void USRGenerator::VisitVarDecl(VarDecl *D) {
+ // VarDecls can be declared 'extern' within a function or method body,
+ // but their enclosing DeclContext is the function, not the TU. We need
+ // to check the storage class to correctly generate the USR.
+ if (!D->hasExternalStorage())
+ VisitDeclContext(D->getDeclContext());
+
+ const std::string &s = D->getNameAsString();
+ // The string can be empty if the declaration has no name; e.g., it is
+ // the ParmDecl with no name for declaration of a function pointer type, e.g.:
+ // void (*f)(void *);
+ // In this case, don't generate a USR.
+ if (s.empty())
+ IgnoreResults = true;
+ else
+ GenNamedDecl(s);
+}
+
void USRGenerator::VisitNamespaceDecl(NamespaceDecl *D) {
VisitDeclContext(D->getDeclContext());
Out << "@N@" << D;
@@ -223,6 +243,15 @@
GenObjCProperty(D->getName());
}
+void USRGenerator::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+ if (ObjCPropertyDecl *PD = D->getPropertyDecl()) {
+ VisitObjCPropertyDecl(PD);
+ return;
+ }
+
+ IgnoreResults = true;
+}
+
void USRGenerator::VisitTagDecl(TagDecl *D) {
D = D->getCanonicalDecl();
VisitDeclContext(D->getDeclContext());
@@ -369,6 +398,9 @@
if (SUG->ignoreResults())
return createCXString("");
+ // For development testing.
+ // assert(SUG.str().size() > 2);
+
// Return a copy of the string that must be disposed by the caller.
return createCXString(SUG.str(), true);
}