[cfe-commits] r103212 - in /cfe/trunk: test/Index/usrs.cpp test/Index/usrs.m tools/libclang/CIndexUSRs.cpp

Ted Kremenek kremenek at apple.com
Thu May 6 16:38:28 PDT 2010


Author: kremenek
Date: Thu May  6 18:38:28 2010
New Revision: 103212

URL: http://llvm.org/viewvc/llvm-project?rev=103212&view=rev
Log:
Add USR support for C++ namespaces, and unify mangling of location information in USRs
for anonymous symbols.

Added:
    cfe/trunk/test/Index/usrs.cpp
Modified:
    cfe/trunk/test/Index/usrs.m
    cfe/trunk/tools/libclang/CIndexUSRs.cpp

Added: cfe/trunk/test/Index/usrs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/usrs.cpp?rev=103212&view=auto
==============================================================================
--- cfe/trunk/test/Index/usrs.cpp (added)
+++ cfe/trunk/test/Index/usrs.cpp Thu May  6 18:38:28 2010
@@ -0,0 +1,73 @@
+namespace foo {
+  int x;
+  void bar(int z);
+}
+namespace bar {
+  typedef int QType;
+  void bar(QType z);
+}
+
+class ClsA {
+public:
+  int a, b;
+  ClsA(int A, int B) : a(A), b(B) {}
+};
+
+namespace foo {
+  class ClsB : public ClsA {
+  public:
+    ClsB() : ClsA(1, 2) {}
+    int result() const;
+  };
+}
+
+int foo::ClsB::result() const {
+  return a + b;
+}
+
+namespace {
+  class ClsC : public foo::ClsB {};
+  int w;
+}
+
+int z;
+
+namespace foo { namespace taz {
+  int x;
+  static inline int add(int a, int b) { return a + b; }
+  void sub(int a, int b);
+}
+}
+
+// RUN: c-index-test -test-load-source-usrs all %s | FileCheck %s
+// CHECK: usrs.cpp c:@N at foo Extent=[1:11 - 4:2]
+// CHECK: usrs.cpp c:@N at foo@x Extent=[2:3 - 2:8]
+// CHECK: usrs.cpp c:@N at foo@F at bar Extent=[3:8 - 3:18]
+// CHECK: usrs.cpp c:usrs.cpp at 3:12 at N@foo at F@bar at z Extent=[3:12 - 3:17]
+// CHECK: usrs.cpp c:@N at bar Extent=[5:11 - 8:2]
+// CHECK: usrs.cpp c:usrs.cpp at 6:15 at N@bar at T@QType Extent=[6:15 - 6:20]
+// CHECK: usrs.cpp c:@N at bar@F at bar Extent=[7:8 - 7:20]
+// CHECK: usrs.cpp c:usrs.cpp at 7:12 at N@bar at F@bar at z Extent=[7:12 - 7:19]
+// CHECK: usrs.cpp c:@C at ClsA Extent=[10:1 - 14:2]
+// CHECK: usrs.cpp c:@C at ClsA@FI at a Extent=[12:7 - 12:8]
+// CHECK: usrs.cpp c:@C at ClsA@FI at b Extent=[12:10 - 12:11]
+// CHECK: usrs.cpp c:@C at ClsA@F at ClsA Extent=[13:3 - 13:37]
+// CHECK: usrs.cpp c:usrs.cpp at 13:8 at C@ClsA at F@ClsA at A Extent=[13:8 - 13:13]
+// CHECK: usrs.cpp c:usrs.cpp at 13:15 at C@ClsA at F@ClsA at B Extent=[13:15 - 13:20]
+// CHECK: usrs.cpp c:@N at foo Extent=[16:11 - 22:2]
+// CHECK: usrs.cpp c:@N at foo@C at ClsB Extent=[17:3 - 21:4]
+// CHECK: usrs.cpp c:@N at foo@C at ClsB@F at ClsB Extent=[19:5 - 19:27]
+// CHECK: usrs.cpp c:@N at foo@C at ClsB@F at result Extent=[20:9 - 20:17]
+// CHECK: usrs.cpp c:@N at foo@C at ClsB@F at result Extent=[24:16 - 26:2]
+// CHECK: usrs.cpp c:@aN at C@ClsC Extent=[29:3 - 29:35]
+// CHECK: usrs.cpp c:@aN at w Extent=[30:3 - 30:8]
+// CHECK: usrs.cpp c:@z Extent=[33:1 - 33:6]
+// CHECK: usrs.cpp c:@N at foo Extent=[35:11 - 40:2]
+// CHECK: usrs.cpp c:@N at foo@N at taz Extent=[35:27 - 39:2]
+// CHECK: usrs.cpp c:@N at foo@N at taz@x Extent=[36:3 - 36:8]
+// CHECK: usrs.cpp c:usrs.cpp at 37:21 at N@foo at N@taz at F@add Extent=[37:21 - 37:56]
+// CHECK: usrs.cpp c:usrs.cpp at 37:25 at N@foo at N@taz at F@add at a Extent=[37:25 - 37:30]
+// CHECK: usrs.cpp c:usrs.cpp at 37:32 at N@foo at N@taz at F@add at b Extent=[37:32 - 37:37]
+// CHECK: usrs.cpp c:@N at foo@N at taz@F at sub Extent=[38:8 - 38:25]
+// CHECK: usrs.cpp c:usrs.cpp at 38:12 at N@foo at N@taz at F@sub at a Extent=[38:12 - 38:17]
+// CHECK: usrs.cpp c:usrs.cpp at 38:19 at N@foo at N@taz at F@sub at b Extent=[38:19 - 38:24]

Modified: cfe/trunk/test/Index/usrs.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/usrs.m?rev=103212&r1=103211&r2=103212&view=diff
==============================================================================
--- cfe/trunk/test/Index/usrs.m (original)
+++ cfe/trunk/test/Index/usrs.m Thu May  6 18:38:28 2010
@@ -49,18 +49,18 @@
 static int local_func(int x) { return x; }
 
 // CHECK: usrs.m c:usrs.m at 3:19 at F@my_helper Extent=[3:19 - 3:60]
-// CHECK: usrs.m c:usrs.m at 3:29 at x Extent=[3:29 - 3:34]
-// CHECK: usrs.m c:usrs.m at 3:36 at y Extent=[3:36 - 3:41]
-// CHECK: usrs.m c:@Ea at usrs.m@5:1 Extent=[5:1 - 8:2]
-// CHECK: usrs.m c:@Ea at usrs.m@5:1 at ABA Extent=[6:3 - 6:6]
-// CHECK: usrs.m c:@Ea at usrs.m@5:1 at CADABA Extent=[7:3 - 7:9]
-// CHECK: usrs.m c:@Ea at usrs.m@10:1 Extent=[10:1 - 13:2]
-// CHECK: usrs.m c:@Ea at usrs.m@10:1 at FOO Extent=[11:3 - 11:6]
-// CHECK: usrs.m c:@Ea at usrs.m@10:1 at BAR Extent=[12:3 - 12:6]
+// CHECK: usrs.m c:usrs.m at 3:29 at F@my_helper at x Extent=[3:29 - 3:34]
+// CHECK: usrs.m c:usrs.m at 3:36 at F@my_helper at y Extent=[3:36 - 3:41]
+// CHECK: usrs.m c:usrs.m at 5:1 at Ea Extent=[5:1 - 8:2]
+// CHECK: usrs.m c:usrs.m at 5:1 at Ea@ABA Extent=[6:3 - 6:6]
+// CHECK: usrs.m c:usrs.m at 5:1 at Ea@CADABA Extent=[7:3 - 7:9]
+// CHECK: usrs.m c:usrs.m at 10:1 at Ea Extent=[10:1 - 13:2]
+// CHECK: usrs.m c:usrs.m at 10:1 at Ea@FOO Extent=[11:3 - 11:6]
+// CHECK: usrs.m c:usrs.m at 10:1 at Ea@BAR Extent=[12:3 - 12:6]
 // CHECK: usrs.m c:@SA at MyStruct Extent=[15:9 - 18:2]
 // CHECK: usrs.m c:@SA at MyStruct@FI at wa Extent=[16:7 - 16:9]
 // CHECK: usrs.m c:@SA at MyStruct@FI at moo Extent=[17:7 - 17:10]
-// CHECK: usrs.m c:@T at usrs.m@18:3 at MyStruct Extent=[18:3 - 18:11]
+// CHECK: usrs.m c:usrs.m at 18:3 at T@MyStruct Extent=[18:3 - 18:11]
 // CHECK: usrs.m c:@E at Pizza Extent=[20:1 - 23:2]
 // CHECK: usrs.m c:@E at Pizza@CHEESE Extent=[21:3 - 21:9]
 // CHECK: usrs.m c:@E at Pizza@MUSHROOMS Extent=[22:3 - 22:12]
@@ -72,16 +72,16 @@
 // CHECK: usrs.m c:objc(cs)Foo(cm)kingkong Extent=[30:1 - 30:17]
 // CHECK: usrs.m c:objc(cs)Foo(im)d1 Extent=[31:15 - 31:17]
 // CHECK: usrs.m c:objc(cs)Foo(im)setD1: Extent=[31:15 - 31:17]
-// CHECK: usrs.m c:usrs.m at 31:15 at d1 Extent=[31:15 - 31:17]
+// CHECK: usrs.m c:usrs.m at 31:15objc(cs)Foo(im)setD1:@d1 Extent=[31:15 - 31:17]
 // CHECK: usrs.m c:objc(cs)Foo Extent=[34:1 - 45:2]
 // CHECK: usrs.m c:objc(cs)Foo(im)godzilla Extent=[35:1 - 39:2]
-// CHECK: usrs.m c:usrs.m at 36:10 at a Extent=[36:10 - 36:19]
-// CHECK: usrs.m c:@z Extent=[37:10 - 37:15]
+// CHECK: usrs.m c:usrs.m at 36:10objc(cs)Foo(im)godzilla at a Extent=[36:10 - 36:19]
+// CHECK: usrs.m c:objc(cs)Foo(im)godzilla at z Extent=[37:10 - 37:15]
 // CHECK: usrs.m c:objc(cs)Foo(cm)kingkong Extent=[40:1 - 43:2]
-// CHECK: usrs.m c:usrs.m at 41:3 at local_var Extent=[41:3 - 41:16]
+// CHECK: usrs.m c:usrs.m at 41:3objc(cs)Foo(cm)kingkong at local_var Extent=[41:3 - 41:16]
 // CHECK: usrs.m c:objc(cs)Foo at d1 Extent=[44:13 - 44:15]
 // CHECK: usrs.m c:objc(cs)Foo(py)d1 Extent=[44:1 - 44:15]
 // CHECK: usrs.m c:@z Extent=[47:1 - 47:6]
 // CHECK: usrs.m c:usrs.m at 49:12 at F@local_func Extent=[49:12 - 49:43]
-// CHECK: usrs.m c:usrs.m at 49:23 at x Extent=[49:23 - 49:28]
+// CHECK: usrs.m c:usrs.m at 49:23 at F@local_func at x Extent=[49:23 - 49:28]
 

Modified: cfe/trunk/tools/libclang/CIndexUSRs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexUSRs.cpp?rev=103212&r1=103211&r2=103212&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexUSRs.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexUSRs.cpp Thu May  6 18:38:28 2010
@@ -31,9 +31,10 @@
   llvm::raw_ostream &Out;
   bool IgnoreResults;
   ASTUnit *AU;
+  bool generatedLoc;
 public:
   USRGenerator(ASTUnit *au, llvm::raw_ostream &out)
-    : Out(out), IgnoreResults(false), AU(au) {}
+    : Out(out), IgnoreResults(false), AU(au), generatedLoc(false) {}
 
   bool ignoreResults() const { return IgnoreResults; }
 
@@ -55,7 +56,7 @@
 
   /// Generate the string component containing the location of the
   ///  declaration.
-  void GenLoc(const Decl *D);
+  bool GenLoc(const Decl *D);
 
   /// String generation methods used both by the visitation methods
   /// and from other clients that want to directly generate USRs.  These
@@ -114,6 +115,16 @@
 // Generating USRs from ASTS.
 //===----------------------------------------------------------------------===//
 
+static bool InAnonymousNamespace(const Decl *D) {
+  if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D->getDeclContext()))
+    return ND->isAnonymousNamespace();
+  return false;
+}
+
+static inline bool ShouldGenerateLocation(const NamedDecl *D) {
+  return D->getLinkage() != ExternalLinkage && !InAnonymousNamespace(D);
+}
+
 void USRGenerator::VisitDeclContext(DeclContext *DC) {
   if (NamedDecl *D = dyn_cast<NamedDecl>(DC))
     Visit(D);
@@ -131,15 +142,11 @@
 }
 
 void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
-  if (D->getLinkage() != ExternalLinkage) {
-    GenLoc(D);
-    if (IgnoreResults)
-      return;
-  }
-  else
-    VisitDeclContext(D->getDeclContext());
+  if (ShouldGenerateLocation(D) && GenLoc(D))
+    return;
 
-  Out << "@F@" << D;
+  VisitDeclContext(D->getDeclContext());
+  Out << "@F@" << D->getNameAsString();
 }
 
 void USRGenerator::VisitNamedDecl(NamedDecl *D) {
@@ -159,11 +166,10 @@
   // 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->getLinkage() != ExternalLinkage) {
-    GenLoc(D);
-    if (IgnoreResults)
-      return;
-  }
+  if (ShouldGenerateLocation(D) && GenLoc(D))
+    return;
+
+  VisitDeclContext(D->getDeclContext());
 
   // Variables always have simple names.
   llvm::StringRef s = D->getName();
@@ -179,8 +185,14 @@
 }
 
 void USRGenerator::VisitNamespaceDecl(NamespaceDecl *D) {
+  if (D->isAnonymousNamespace()) {
+    Out << "@aN";
+    return;
+  }
+
   VisitDeclContext(D->getDeclContext());
-  Out << "@N@" << D;
+  if (!IgnoreResults)
+    Out << "@N@" << D->getName();
 }
 
 void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) {
@@ -258,8 +270,14 @@
 }
 
 void USRGenerator::VisitTagDecl(TagDecl *D) {
+  // Add the location of the tag decl to handle resolution across
+  // translation units.
+  if (ShouldGenerateLocation(D) && GenLoc(D))
+    return;
+  
   D = D->getCanonicalDecl();
   VisitDeclContext(D->getDeclContext());
+
   switch (D->getTagKind()) {
     case TagDecl::TK_struct: Out << "@S"; break;
     case TagDecl::TK_class:  Out << "@C"; break;
@@ -274,15 +292,6 @@
     Out << (TD ? 'A' : 'a');
   }
 
-  // Add the location of the tag decl to handle resolution across
-  // translation units.
-  if (D->getLinkage() == NoLinkage) {
-    Out << '@';
-    GenLoc(D);
-    if (IgnoreResults)
-      return;
-  }
-
   if (s.empty()) {
     if (TD)
       Out << '@' << TD;
@@ -292,25 +301,25 @@
 }
 
 void USRGenerator::VisitTypedefDecl(TypedefDecl *D) {
+  if (ShouldGenerateLocation(D) && GenLoc(D))
+    return;
   DeclContext *DC = D->getDeclContext();
   if (NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
     Visit(DCN);
   Out << "@T@";
-  if (D->getLinkage() == NoLinkage) {
-    GenLoc(D);
-    if (IgnoreResults)
-      return;
-    Out << '@';
-  }
   Out << D->getName();
 }
 
-void USRGenerator::GenLoc(const Decl *D) {
+bool USRGenerator::GenLoc(const Decl *D) {
+  if (generatedLoc)
+    return IgnoreResults;
+  generatedLoc = true;
+
   const SourceManager &SM = AU->getSourceManager();
   SourceLocation L = D->getLocStart();
   if (L.isInvalid()) {
     IgnoreResults = true;
-    return;
+    return true;
   }
   L = SM.getInstantiationLoc(L);
   const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(L);
@@ -322,11 +331,13 @@
   else {
     // This case really isn't interesting.
     IgnoreResults = true;
-    return;
+    return true;
   }
   Out << '@'
       << SM.getLineNumber(Decomposed.first, Decomposed.second) << ':'
       << SM.getColumnNumber(Decomposed.first, Decomposed.second);
+  
+  return IgnoreResults;
 }
 
 //===----------------------------------------------------------------------===//
@@ -383,6 +394,7 @@
         // Generate USRs for all entities with external linkage.
         break;
       case NoLinkage:
+      case UniqueExternalLinkage:
         // We allow enums, typedefs, and structs that have no linkage to
         // have USRs that are anchored to the file they were defined in
         // (e.g., the header).  This is a little gross, but in principal
@@ -390,14 +402,12 @@
         // are referred to across multiple translation units.
         if (isa<TagDecl>(ND) || isa<TypedefDecl>(ND) ||
             isa<EnumConstantDecl>(ND) || isa<FieldDecl>(ND) ||
-            isa<VarDecl>(ND))
+            isa<VarDecl>(ND) || isa<NamespaceDecl>(ND))
           break;
         // Fall-through.
       case InternalLinkage:
         if (isa<FunctionDecl>(ND))
           break;
-      case UniqueExternalLinkage:
-        return createCXString("");
     }
 
   StringUSRGenerator SUG(&C);





More information about the cfe-commits mailing list