r205064 - libclang/libIndex: USR generation: mangle source location into USRs for macros,

Dmitri Gribenko gribozavr at gmail.com
Fri Mar 28 15:21:27 PDT 2014


Author: gribozavr
Date: Fri Mar 28 17:21:26 2014
New Revision: 205064

URL: http://llvm.org/viewvc/llvm-project?rev=205064&view=rev
Log:
libclang/libIndex: USR generation: mangle source location into USRs for macros,
unless the macro comes from a system header

Added:
    cfe/trunk/test/Index/Inputs/usrs-system.h
Modified:
    cfe/trunk/include/clang/Index/USRGeneration.h
    cfe/trunk/lib/Index/USRGeneration.cpp
    cfe/trunk/test/Index/usrs.m
    cfe/trunk/tools/libclang/CIndexUSRs.cpp

Modified: cfe/trunk/include/clang/Index/USRGeneration.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Index/USRGeneration.h?rev=205064&r1=205063&r2=205064&view=diff
==============================================================================
--- cfe/trunk/include/clang/Index/USRGeneration.h (original)
+++ cfe/trunk/include/clang/Index/USRGeneration.h Fri Mar 28 17:21:26 2014
@@ -14,7 +14,9 @@
 #include "llvm/ADT/StringRef.h"
 
 namespace clang {
-  class Decl;
+class Decl;
+class MacroDefinition;
+class SourceManager;
 
 namespace index {
 
@@ -22,7 +24,7 @@ static inline StringRef getUSRSpacePrefi
   return "c:";
 }
 
-/// \brief Generate a USR for a Decl, including the prefix.
+/// \brief Generate a USR for a Decl, including the USR prefix.
 /// \returns true if the results should be ignored, false otherwise.
 bool generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &Buf);
 
@@ -47,6 +49,12 @@ void generateUSRForObjCProperty(StringRe
 /// \brief Generate a USR fragment for an Objective-C protocol.
 void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS);
 
+/// \brief Generate a USR for a macro, including the USR prefix.
+///
+/// \returns true on error, false on success.
+bool generateUSRForMacro(const MacroDefinition *MD, const SourceManager &SM,
+                         SmallVectorImpl<char> &Buf);
+
 } // namespace index
 } // namespace clang
 

Modified: cfe/trunk/lib/Index/USRGeneration.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/USRGeneration.cpp?rev=205064&r1=205063&r2=205064&view=diff
==============================================================================
--- cfe/trunk/lib/Index/USRGeneration.cpp (original)
+++ cfe/trunk/lib/Index/USRGeneration.cpp Fri Mar 28 17:21:26 2014
@@ -11,6 +11,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/DeclVisitor.h"
+#include "clang/Lex/PreprocessingRecord.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
@@ -22,6 +23,30 @@ using namespace clang::index;
 // USR generation.
 //===----------------------------------------------------------------------===//
 
+/// \returns true on error.
+static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc,
+                     const SourceManager &SM, bool IncludeOffset) {
+  if (Loc.isInvalid()) {
+    return true;
+  }
+  Loc = SM.getExpansionLoc(Loc);
+  const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(Loc);
+  const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
+  if (FE) {
+    OS << llvm::sys::path::filename(FE->getName());
+  } else {
+    // This case really isn't interesting.
+    return true;
+  }
+  if (IncludeOffset) {
+    // Use the offest into the FileID to represent the location.  Using
+    // a line/column can cause us to look back at the original source file,
+    // which is expensive.
+    OS << '@' << Decomposed.second;
+  }
+  return false;
+}
+
 namespace {
 class USRGenerator : public ConstDeclVisitor<USRGenerator> {
   SmallVectorImpl<char> &Buf;
@@ -465,7 +490,7 @@ bool USRGenerator::GenLoc(const Decl *D,
   if (generatedLoc)
     return IgnoreResults;
   generatedLoc = true;
-  
+
   // Guard against null declarations in invalid code.
   if (!D) {
     IgnoreResults = true;
@@ -475,29 +500,10 @@ bool USRGenerator::GenLoc(const Decl *D,
   // Use the location of canonical decl.
   D = D->getCanonicalDecl();
 
-  const SourceManager &SM = Context->getSourceManager();
-  SourceLocation L = D->getLocStart();
-  if (L.isInvalid()) {
-    IgnoreResults = true;
-    return true;
-  }
-  L = SM.getExpansionLoc(L);
-  const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(L);
-  const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
-  if (FE) {
-    Out << llvm::sys::path::filename(FE->getName());
-  }
-  else {
-    // This case really isn't interesting.
-    IgnoreResults = true;
-    return true;
-  }
-  if (IncludeOffset) {
-    // Use the offest into the FileID to represent the location.  Using
-    // a line/column can cause us to look back at the original source file,
-    // which is expensive.
-    Out << '@' << Decomposed.second;
-  }
+  IgnoreResults =
+      IgnoreResults || printLoc(Out, D->getLocStart(),
+                                Context->getSourceManager(), IncludeOffset);
+
   return IgnoreResults;
 }
 
@@ -799,3 +805,26 @@ bool clang::index::generateUSRForDecl(co
   UG.Visit(D);
   return UG.ignoreResults();
 }
+
+bool clang::index::generateUSRForMacro(const MacroDefinition *MD,
+                                       const SourceManager &SM,
+                                       SmallVectorImpl<char> &Buf) {
+  // Don't generate USRs for things with invalid locations.
+  if (!MD || MD->getLocation().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()->getNameStart();
+  return false;
+}
+

Added: cfe/trunk/test/Index/Inputs/usrs-system.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Inputs/usrs-system.h?rev=205064&view=auto
==============================================================================
--- cfe/trunk/test/Index/Inputs/usrs-system.h (added)
+++ cfe/trunk/test/Index/Inputs/usrs-system.h Fri Mar 28 17:21:26 2014
@@ -0,0 +1 @@
+#define MACRO_FROM_SYSTEM_HEADER_1 meow

Modified: cfe/trunk/test/Index/usrs.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/usrs.m?rev=205064&r1=205063&r2=205064&view=diff
==============================================================================
--- cfe/trunk/test/Index/usrs.m (original)
+++ cfe/trunk/test/Index/usrs.m Fri Mar 28 17:21:26 2014
@@ -89,7 +89,24 @@ int test_multi_declaration(void) {
 -(int)methodWithFn:(void (*)(int *p))fn;
 @end
 
-// RUN: c-index-test -test-load-source-usrs all -target x86_64-apple-macosx10.7 %s | FileCheck %s
+#include <usrs-system.h>
+
+#define MACRO1 123
+
+#define MACRO2 123
+#undef MACRO2
+#define MACRO2 789
+
+#define MACRO3(X) 123, X
+#define MACRO3(X) 789, X
+
+// RUN: c-index-test -test-load-source-usrs all -target x86_64-apple-macosx10.7 %s -isystem %S/Inputs | FileCheck %s
+// CHECK: usrs-system.h c:@macro at MACRO_FROM_SYSTEM_HEADER_1 Extent=[1:9 - 1:40]
+// CHECK: usrs.m c:usrs.m at 1265@macro at MACRO1 Extent=[94:9 - 94:19]
+// CHECK: usrs.m c:usrs.m at 1285@macro at MACRO2 Extent=[96:9 - 96:19]
+// CHECK: usrs.m c:usrs.m at 1318@macro at MACRO2 Extent=[98:9 - 98:19]
+// CHECK: usrs.m c:usrs.m at 1338@macro at MACRO3 Extent=[100:9 - 100:25]
+// CHECK: usrs.m c:usrs.m at 1363@macro at MACRO3 Extent=[101:9 - 101:25]
 // CHECK: usrs.m c:usrs.m at F@my_helper Extent=[3:1 - 3:60]
 // CHECK: usrs.m c:usrs.m at 95@F at my_helper@x Extent=[3:29 - 3:34]
 // CHECK: usrs.m c:usrs.m at 102@F at my_helper@y Extent=[3:36 - 3:41]
@@ -153,7 +170,13 @@ int test_multi_declaration(void) {
 // CHECK: usrs.m c:objc(cs)CWithExt2(im)pro_ext Extent=[88:23 - 88:30]
 // CHECK: usrs.m c:objc(cs)CWithExt2(im)setPro_ext: Extent=[88:23 - 88:30]
 
-// RUN: c-index-test -test-load-source all %s | FileCheck -check-prefix=CHECK-source %s
+// RUN: c-index-test -test-load-source all %s -isystem %S/Inputs | FileCheck -check-prefix=CHECK-source %s
+// CHECK-source: usrs-system.h:1:9: macro definition=MACRO_FROM_SYSTEM_HEADER_1 Extent=[1:9 - 1:40]
+// CHECK-source: usrs.m:94:9: macro definition=MACRO1 Extent=[94:9 - 94:19]
+// CHECK-source: usrs.m:96:9: macro definition=MACRO2 Extent=[96:9 - 96:19]
+// CHECK-source: usrs.m:98:9: macro definition=MACRO2 Extent=[98:9 - 98:19]
+// CHECK-source: usrs.m:100:9: macro definition=MACRO3 Extent=[100:9 - 100:25]
+// CHECK-source: usrs.m:101:9: macro definition=MACRO3 Extent=[101:9 - 101:25]
 // CHECK-source: usrs.m:3:19: FunctionDecl=my_helper:3:19 (Definition) Extent=[3:1 - 3:60]
 // CHECK-source: usrs.m:3:33: ParmDecl=x:3:33 (Definition) Extent=[3:29 - 3:34]
 // CHECK-source: usrs.m:3:40: ParmDecl=y:3:40 (Definition) Extent=[3:36 - 3:41]

Modified: cfe/trunk/tools/libclang/CIndexUSRs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexUSRs.cpp?rev=205064&r1=205063&r2=205064&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexUSRs.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexUSRs.cpp Fri Mar 28 17:21:26 2014
@@ -14,8 +14,10 @@
 #include "CIndexer.h"
 #include "CXCursor.h"
 #include "CXString.h"
+#include "CXTranslationUnit.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Frontend/ASTUnit.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -73,10 +75,16 @@ CXString clang_getCursorUSR(CXCursor C)
     if (!buf)
       return cxstring::createEmpty();
 
-    buf->Data += getUSRSpacePrefix();
-    buf->Data += "macro@";
-    buf->Data +=
-        cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart();
+    bool Ignore = generateUSRForMacro(cxcursor::getCursorMacroDefinition(C),
+                                      cxtu::getASTUnit(TU)->getSourceManager(),
+                                      buf->Data);
+    if (Ignore) {
+      buf->dispose();
+      return cxstring::createEmpty();
+    }
+
+    // Return the C-string, but don't make a copy since it is already in
+    // the string buffer.
     buf->Data.push_back('\0');
     return createCXString(buf);
   }





More information about the cfe-commits mailing list