[cfe-commits] r101403 - /cfe/trunk/tools/CIndex/CIndexUSRs.cpp

Ted Kremenek kremenek at apple.com
Thu Apr 15 14:51:14 PDT 2010


Author: kremenek
Date: Thu Apr 15 16:51:13 2010
New Revision: 101403

URL: http://llvm.org/viewvc/llvm-project?rev=101403&view=rev
Log:
Better support USRs for anonymous enums, structs, by including the location where
the tag was declared.  WIP.

Modified:
    cfe/trunk/tools/CIndex/CIndexUSRs.cpp

Modified: cfe/trunk/tools/CIndex/CIndexUSRs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndexUSRs.cpp?rev=101403&r1=101402&r2=101403&view=diff
==============================================================================
--- cfe/trunk/tools/CIndex/CIndexUSRs.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndexUSRs.cpp Thu Apr 15 16:51:13 2010
@@ -14,9 +14,11 @@
 #include "CIndexer.h"
 #include "CXCursor.h"
 #include "clang/AST/DeclVisitor.h"
+#include "clang/Frontend/ASTUnit.h"
 #include "clang/Lex/PreprocessingRecord.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/raw_ostream.h"
+
 using namespace clang;
 using namespace clang::cxstring;
 
@@ -48,6 +50,10 @@
   void VisitTagDecl(TagDecl *D);
   void VisitTypedefDecl(TypedefDecl *D);
 
+  /// Generate the string component containing the location of the
+  ///  declaration.
+  void GenLoc(const Decl *D);
+
   /// String generation methods used both by the visitation methods
   /// and from other clients that want to directly generate USRs.  These
   /// methods do not construct complete USRs (which incorporate the parents
@@ -198,6 +204,7 @@
 }
 
 void USRGenerator::VisitTagDecl(TagDecl *D) {
+  D = D->getCanonicalDecl();
   VisitDeclContext(D->getDeclContext());
   switch (D->getTagKind()) {
     case TagDecl::TK_struct: Out << "@S^"; break;
@@ -206,7 +213,14 @@
     case TagDecl::TK_enum:   Out << "@E^"; break;
   }
 
-  // FIXME: Better support for anonymous structures and enums.
+  // Add the location of the tag decl to handle resolution across
+  // translation units.
+  if (D->getLinkage() == NoLinkage) {
+    GenLoc(D);
+    if (IgnoreResults)
+      return;
+  }
+
   const std::string &s = D->getNameAsString();
   if (s.empty()) {
     if (TypedefDecl *TD = D->getTypedefForAnonDecl())
@@ -222,7 +236,31 @@
   DeclContext *DC = D->getDeclContext();
   if (NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
     Visit(DCN);
-  Out << "typedef@" << D->getName();
+  Out << "typedef@";
+  GenLoc(D);
+  Out << D->getName();
+}
+
+void USRGenerator::GenLoc(const Decl *D) {
+  const SourceManager &SM = AU->getSourceManager();
+  SourceLocation L = D->getLocStart();
+  if (L.isInvalid()) {
+    IgnoreResults = true;
+    return;
+  }
+  L = SM.getInstantiationLoc(L);
+  const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(L);
+  const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
+  if (FE)
+    Out << FE->getName();
+  else {
+    // This case really isn't interesting.
+    IgnoreResults = true;
+    return;
+  }
+  Out << SM.getLineNumber(Decomposed.first, Decomposed.second) << ':'
+      << SM.getColumnNumber(Decomposed.first, Decomposed.second)
+      << '^';
 }
 
 //===----------------------------------------------------------------------===//
@@ -282,7 +320,8 @@
         // (e.g., the header).  This is a little gross, but in principal
         // enums/anonymous structs/etc. defined in a common header file
         // are referred to across multiple translation units.
-        if (isa<TagDecl>(ND))
+        if (isa<TagDecl>(ND) || isa<TypedefDecl>(ND) ||
+            isa<EnumConstantDecl>(ND))
           break;
         // Fall-through.
       case InternalLinkage:





More information about the cfe-commits mailing list