aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-04-20 23:15:40 +0000
committerTed Kremenek <kremenek@apple.com>2010-04-20 23:15:40 +0000
commite542f7723a929d42bd9e4dfa526b4ede915b91a7 (patch)
tree360646a8c605c1a98bca9a90c24f09f28052599e
parentbecc308ff32df8c5738ffb958f8033189d62d6f2 (diff)
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
-rw-r--r--test/Index/usrs.m74
-rw-r--r--tools/CIndex/CIndexUSRs.cpp36
-rw-r--r--tools/c-index-test/c-index-test.c7
3 files changed, 112 insertions, 5 deletions
diff --git a/test/Index/usrs.m b/test/Index/usrs.m
new file mode 100644
index 0000000000..28771aebc1
--- /dev/null
+++ b/test/Index/usrs.m
@@ -0,0 +1,74 @@
+// RUN: c-index-test -test-load-source-usrs all %s | FileCheck %s
+
+enum {
+ ABA,
+ CADABA
+};
+
+enum {
+ FOO,
+ BAR
+};
+
+typedef struct {
+ int wa;
+ int moo;
+} MyStruct;
+
+enum Pizza {
+ CHEESE,
+ MUSHROOMS
+};
+
+@interface Foo {
+ id x;
+ id y;
+}
+- (id) godzilla;
++ (id) kingkong;
+@property int d1;
+@end
+
+@implementation Foo
+- (id) godzilla {
+ static int a = 0;
+ extern int z;
+ return 0;
+}
++ (id) kingkong {
+ return 0;
+}
+@synthesize d1;
+@end
+
+int z;
+
+// CHECK: usrs.m c:@Ea@usrs.m@3:1 Extent=[3:1 - 6:2]
+// CHECK: usrs.m c:@Ea@usrs.m@3:1@ABA Extent=[4:3 - 4:6]
+// CHECK: usrs.m c:@Ea@usrs.m@3:1@CADABA Extent=[5:3 - 5:9]
+// CHECK: usrs.m c:@Ea@usrs.m@8:1 Extent=[8:1 - 11:2]
+// CHECK: usrs.m c:@Ea@usrs.m@8:1@FOO Extent=[9:3 - 9:6]
+// CHECK: usrs.m c:@Ea@usrs.m@8:1@BAR Extent=[10:3 - 10:6]
+// CHECK: usrs.m c:@SA@MyStruct Extent=[13:9 - 16:2]
+// CHECK: usrs.m c:@SA@MyStruct@FI@wa Extent=[14:7 - 14:9]
+// CHECK: usrs.m c:@SA@MyStruct@FI@moo Extent=[15:7 - 15:10]
+// CHECK: usrs.m c:@T@usrs.m@16:3@MyStruct Extent=[16:3 - 16:11]
+// CHECK: usrs.m c:@E@Pizza Extent=[18:1 - 21:2]
+// CHECK: usrs.m c:@E@Pizza@CHEESE Extent=[19:3 - 19:9]
+// CHECK: usrs.m c:@E@Pizza@MUSHROOMS Extent=[20:3 - 20:12]
+// CHECK: usrs.m c:objc(cs)Foo Extent=[23:1 - 30:5]
+// CHECK: usrs.m c:objc(cs)Foo@x Extent=[24:6 - 24:7]
+// CHECK: usrs.m c:objc(cs)Foo@y Extent=[25:6 - 25:7]
+// CHECK: usrs.m c:objc(cs)Foo(py)d1 Extent=[29:15 - 29:17]
+// CHECK: usrs.m c:objc(cs)Foo(im)godzilla Extent=[27:1 - 27:17]
+// CHECK: usrs.m c:objc(cs)Foo(cm)kingkong Extent=[28:1 - 28:17]
+// CHECK: usrs.m c:objc(cs)Foo(im)d1 Extent=[29:15 - 29:17]
+// CHECK: usrs.m c:objc(cs)Foo(im)setD1: Extent=[29:15 - 29:17]
+// CHECK: usrs.m c:objc(cs)Foo Extent=[32:1 - 42:2]
+// CHECK: usrs.m c:objc(cs)Foo(im)godzilla Extent=[33:1 - 37:2]
+// CHECK: usrs.m c:@z Extent=[35:10 - 35:15]
+// CHECK: usrs.m c:objc(cs)Foo(cm)kingkong Extent=[38:1 - 40:2]
+// CHECK: usrs.m c:objc(cs)Foo@d1 Extent=[41:13 - 41:15]
+// CHECK: usrs.m c:objc(cs)Foo(py)d1 Extent=[41:1 - 41:15]
+// CHECK: usrs.m c:@z Extent=[44:1 - 44:6]
+
diff --git a/tools/CIndex/CIndexUSRs.cpp b/tools/CIndex/CIndexUSRs.cpp
index d67f97a5a6..58870b930b 100644
--- a/tools/CIndex/CIndexUSRs.cpp
+++ b/tools/CIndex/CIndexUSRs.cpp
@@ -46,11 +46,13 @@ public:
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 @@ void USRGenerator::VisitFieldDecl(FieldDecl *D) {
return;
}
VisitDeclContext(D->getDeclContext());
- Out << "@FI@" << s;
+ Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@") << s;
}
void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
@@ -153,6 +155,24 @@ void USRGenerator::VisitNamedDecl(NamedDecl *D) {
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 @@ void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
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 @@ static CXString getDeclCursorUSR(const CXCursor &C) {
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);
}
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index c15b69cb1c..494181675c 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -372,12 +372,13 @@ enum CXChildVisitResult USRVisitor(CXCursor C, CXCursor parent,
VisitorData *Data = (VisitorData *)ClientData;
if (!Data->Filter || (C.kind == *(enum CXCursorKind *)Data->Filter)) {
CXString USR = clang_getCursorUSR(C);
- if (!clang_getCString(USR)) {
+ const char *cstr = clang_getCString(USR);
+ if (!cstr || cstr[0] == '\0') {
clang_disposeString(USR);
return CXChildVisit_Recurse;
}
- printf("// %s: %s %s", FileCheckPrefix, GetCursorSource(C),
- clang_getCString(USR));
+ printf("// %s: %s %s", FileCheckPrefix, GetCursorSource(C), cstr);
+
PrintCursorExtent(C);
printf("\n");
clang_disposeString(USR);