[cfe-commits] r103285 - /cfe/trunk/tools/libclang/CIndexUSRs.cpp

Ted Kremenek kremenek at apple.com
Fri May 7 13:07:23 PDT 2010


Author: kremenek
Date: Fri May  7 15:07:23 2010
New Revision: 103285

URL: http://llvm.org/viewvc/llvm-project?rev=103285&view=rev
Log:
Switch USR generation over from NamedDecl::getNameAsString() to NamedDecl::printName().

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

Modified: cfe/trunk/tools/libclang/CIndexUSRs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexUSRs.cpp?rev=103285&r1=103284&r2=103285&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexUSRs.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexUSRs.cpp Fri May  7 15:07:23 2010
@@ -28,13 +28,33 @@
 
 namespace {
 class USRGenerator : public DeclVisitor<USRGenerator> {
-  llvm::raw_ostream &Out;
+  llvm::SmallString<1024> Buf;
+  llvm::raw_svector_ostream Out;
   bool IgnoreResults;
   ASTUnit *AU;
   bool generatedLoc;
 public:
-  USRGenerator(ASTUnit *au, llvm::raw_ostream &out)
-    : Out(out), IgnoreResults(false), AU(au), generatedLoc(false) {}
+  USRGenerator(const CXCursor *C = 0)
+    : Out(Buf),
+      IgnoreResults(false),
+      AU(C ? cxcursor::getCursorASTUnit(*C) : 0),
+      generatedLoc(false)
+  {
+    // Add the USR space prefix.
+    Out << "c:";
+  }
+
+  llvm::StringRef str() {
+    return Out.str();
+  }
+
+  USRGenerator* operator->() { return this; }
+
+  template <typename T>
+  llvm::raw_svector_ostream &operator<<(const T &x) {
+    Out << x;
+    return Out;
+  }
 
   bool ignoreResults() const { return IgnoreResults; }
 
@@ -68,10 +88,6 @@
   /// of an AST element), but only the fragments concerning the AST element
   /// itself.
 
-  /// Generate a USR fragment for a named declaration.  This does
-  /// not include the USR component for the parent.
-  void GenNamedDecl(llvm::StringRef name);
-
   /// Generate a USR for an Objective-C class.
   void GenObjCClass(llvm::StringRef cls);
   /// Generate a USR for an Objective-C class category.
@@ -88,31 +104,10 @@
   void GenObjCProtocol(llvm::StringRef prot);
 
   void VisitType(QualType T);
-};
 
-class StringUSRGenerator {
-private:
-  llvm::SmallString<1024> StrBuf;
-  llvm::raw_svector_ostream Out;
-  USRGenerator UG;
-public:
-  StringUSRGenerator(const CXCursor *C = 0)
-    : Out(StrBuf), UG(C ? cxcursor::getCursorASTUnit(*C) : 0, Out) {
-    // Add the USR space prefix.
-    Out << "c:";
-  }
-
-  llvm::StringRef str() {
-    return Out.str();
-  }
-
-  USRGenerator* operator->() { return &UG; }
-
-  template <typename T>
-  llvm::raw_svector_ostream &operator<<(const T &x) {
-    Out << x;
-    return Out;
-  }
+  /// Emit a Decl's name using NamedDecl::printName() and return true if
+  ///  the decl had no name.
+  bool EmitDeclName(const NamedDecl *D);
 };
 
 } // end anonymous namespace
@@ -121,6 +116,15 @@
 // Generating USRs from ASTS.
 //===----------------------------------------------------------------------===//
 
+bool USRGenerator::EmitDeclName(const NamedDecl *D) {
+  Out.flush();
+  const unsigned startSize = Buf.size();
+  D->printName(Out);
+  Out.flush();
+  const unsigned endSize = Buf.size();
+  return startSize == endSize;
+}
+
 static bool InAnonymousNamespace(const Decl *D) {
   if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D->getDeclContext()))
     return ND->isAnonymousNamespace();
@@ -137,14 +141,13 @@
 }
 
 void USRGenerator::VisitFieldDecl(FieldDecl *D) {
-  const std::string &s = D->getNameAsString();
-  if (s.empty()) {
+  VisitDeclContext(D->getDeclContext());
+  Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@");
+  if (EmitDeclName(D)) {
     // Bit fields can be anonymous.
     IgnoreResults = true;
     return;
   }
-  VisitDeclContext(D->getDeclContext());
-  Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@") << s;
 }
 
 void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
@@ -152,7 +155,8 @@
     return;
 
   VisitDeclContext(D->getDeclContext());
-  Out << "@F@" << D->getNameAsString();
+  Out << "@F@";
+  D->printName(Out);
 
   ASTContext &Ctx = AU->getASTContext();
   if (!Ctx.getLangOptions().CPlusPlus || D->isExternC())
@@ -171,15 +175,15 @@
 
 void USRGenerator::VisitNamedDecl(NamedDecl *D) {
   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())
+  Out << "@";
+
+  if (EmitDeclName(D)) {
+    // 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.
     IgnoreResults = true;
-  else
-    GenNamedDecl(s);
+  }
 }
 
 void USRGenerator::VisitVarDecl(VarDecl *D) {
@@ -201,7 +205,7 @@
   if (s.empty())
     IgnoreResults = true;
   else
-    GenNamedDecl(s);
+    Out << '@' << s;
 }
 
 void USRGenerator::VisitNamespaceDecl(NamespaceDecl *D) {
@@ -217,8 +221,12 @@
 
 void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) {
   Visit(cast<Decl>(D->getDeclContext()));
-  GenObjCMethod(DeclarationName(D->getSelector()).getAsString(),
-                D->isInstanceMethod());
+  // Ideally we would use 'GenObjCMethod', but this is such a hot path
+  // for Objective-C code that we don't want to use
+  // DeclarationName::getAsString().
+  Out << (D->isInstanceMethod() ? "(im)" : "(cm)");
+  DeclarationName N(D->getSelector());
+  N.printName(Out);
 }
 
 void USRGenerator::VisitObjCClassDecl(ObjCClassDecl *D) {
@@ -305,19 +313,19 @@
     case TagDecl::TK_enum:   Out << "@E"; break;
   }
 
-  const std::string &s = D->getNameAsString();
-  const TypedefDecl *TD = 0;
-  if (s.empty()) {
-    TD = D->getTypedefForAnonDecl();
-    Out << (TD ? 'A' : 'a');
-  }
-
-  if (s.empty()) {
-    if (TD)
+  Out << '@';
+  Out.flush();
+  assert(Buf.size() > 0);
+  const unsigned off = Buf.size() - 1;
+
+  if (EmitDeclName(D)) {
+    if (const TypedefDecl *TD = D->getTypedefForAnonDecl()) {
+      Buf[off] = 'A';
       Out << '@' << TD;
+    }
+    else
+      Buf[off] = 'a';
   }
-  else
-    Out << '@' << s;
 }
 
 void USRGenerator::VisitTypedefDecl(TypedefDecl *D) {
@@ -480,10 +488,6 @@
 // General purpose USR generation methods.
 //===----------------------------------------------------------------------===//
 
-void USRGenerator::GenNamedDecl(llvm::StringRef name) {
-  Out << "@" << name;
-}
-
 void USRGenerator::GenObjCClass(llvm::StringRef cls) {
   Out << "objc(cs)" << cls;
 }
@@ -493,7 +497,7 @@
 }
 
 void USRGenerator::GenObjCIvar(llvm::StringRef ivar) {
-  GenNamedDecl(ivar);
+  Out << '@' << ivar;
 }
 
 void USRGenerator::GenObjCMethod(llvm::StringRef meth, bool isInstanceMethod) {
@@ -546,17 +550,19 @@
           break;
     }
 
-  StringUSRGenerator SUG(&C);
-  SUG->Visit(D);
+  USRGenerator UG(&C);
+  UG->Visit(D);
 
-  if (SUG->ignoreResults())
+  if (UG->ignoreResults())
     return createCXString("");
 
+#if 0
   // For development testing.
-  // assert(SUG.str().size() > 2);
+  assert(UG.str().size() > 2);
+#endif
 
     // Return a copy of the string that must be disposed by the caller.
-  return createCXString(SUG.str(), true);
+  return createCXString(UG.str(), true);
 }
 
 extern "C" {
@@ -568,56 +574,56 @@
       return getDeclCursorUSR(C);
 
   if (K == CXCursor_MacroDefinition) {
-    StringUSRGenerator SUG(&C);
-    SUG << "macro@"
-        << cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart();
-    return createCXString(SUG.str(), true);
+    USRGenerator UG(&C);
+    UG << "macro@"
+       << cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart();
+    return createCXString(UG.str(), true);
   }
 
   return createCXString("");
 }
 
 CXString clang_constructUSR_ObjCIvar(const char *name, CXString classUSR) {
-  StringUSRGenerator SUG;
-  SUG << extractUSRSuffix(clang_getCString(classUSR));
-  SUG->GenObjCIvar(name);
-  return createCXString(SUG.str(), true);
+  USRGenerator UG;
+  UG << extractUSRSuffix(clang_getCString(classUSR));
+  UG->GenObjCIvar(name);
+  return createCXString(UG.str(), true);
 }
 
 CXString clang_constructUSR_ObjCMethod(const char *name,
                                        unsigned isInstanceMethod,
                                        CXString classUSR) {
-  StringUSRGenerator SUG;
-  SUG << extractUSRSuffix(clang_getCString(classUSR));
-  SUG->GenObjCMethod(name, isInstanceMethod);
-  return createCXString(SUG.str(), true);
+  USRGenerator UG;
+  UG << extractUSRSuffix(clang_getCString(classUSR));
+  UG->GenObjCMethod(name, isInstanceMethod);
+  return createCXString(UG.str(), true);
 }
 
 CXString clang_constructUSR_ObjCClass(const char *name) {
-  StringUSRGenerator SUG;
-  SUG->GenObjCClass(name);
-  return createCXString(SUG.str(), true);
+  USRGenerator UG;
+  UG->GenObjCClass(name);
+  return createCXString(UG.str(), true);
 }
 
 CXString clang_constructUSR_ObjCProtocol(const char *name) {
-  StringUSRGenerator SUG;
-  SUG->GenObjCProtocol(name);
-  return createCXString(SUG.str(), true);
+  USRGenerator UG;
+  UG->GenObjCProtocol(name);
+  return createCXString(UG.str(), true);
 }
 
 CXString clang_constructUSR_ObjCCategory(const char *class_name,
                                          const char *category_name) {
-  StringUSRGenerator SUG;
-  SUG->GenObjCCategory(class_name, category_name);
-  return createCXString(SUG.str(), true);
+  USRGenerator UG;
+  UG->GenObjCCategory(class_name, category_name);
+  return createCXString(UG.str(), true);
 }
 
 CXString clang_constructUSR_ObjCProperty(const char *property,
                                          CXString classUSR) {
-  StringUSRGenerator SUG;
-  SUG << extractUSRSuffix(clang_getCString(classUSR));
-  SUG->GenObjCProperty(property);
-  return createCXString(SUG.str(), true);
+  USRGenerator UG;
+  UG << extractUSRSuffix(clang_getCString(classUSR));
+  UG->GenObjCProperty(property);
+  return createCXString(UG.str(), true);
 }
 
 } // end extern "C"





More information about the cfe-commits mailing list