[cfe-commits] r42023 - in /cfe/trunk: AST/ASTContext.cpp AST/Decl.cpp Lex/IdentifierTable.cpp Sema/SemaDecl.cpp clang.xcodeproj/project.pbxproj include/clang/AST/ASTContext.h include/clang/AST/Decl.h include/clang/Lex/IdentifierTable.h

Steve Naroff snaroff at apple.com
Mon Sep 17 07:16:14 PDT 2007


Author: snaroff
Date: Mon Sep 17 09:16:13 2007
New Revision: 42023

URL: http://llvm.org/viewvc/llvm-project?rev=42023&view=rev
Log:

Add support for ObjC keyword selectors.

- Add SelectorInfo/SelectorTable classes, modeled after IdentifierInfo/IdentifierTable.
- Add SelectorTable instance to ASTContext, created lazily through ASTContext::getSelectorInfo().
- Add SelectorInfo slot to ObjcMethodDecl.
- Add helper function to derive a SelectorInfo from ObjcKeywordInfo.

Misc: Got the Decl stats stuff up and running again...it was missing support for ObjC AST's.


Modified:
    cfe/trunk/AST/ASTContext.cpp
    cfe/trunk/AST/Decl.cpp
    cfe/trunk/Lex/IdentifierTable.cpp
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/clang.xcodeproj/project.pbxproj
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/Lex/IdentifierTable.h

Modified: cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/ASTContext.cpp?rev=42023&r1=42022&r2=42023&view=diff

==============================================================================
--- cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/trunk/AST/ASTContext.cpp Mon Sep 17 09:16:13 2007
@@ -16,6 +16,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/ADT/SmallVector.h"
+#include "clang/Lex/IdentifierTable.h"
 using namespace clang;
 
 enum FloatingRank {
@@ -44,6 +45,7 @@
   unsigned NumFunctionNP = 0, NumTypeName = 0, NumTagged = 0, NumReference = 0;
   
   unsigned NumTagStruct = 0, NumTagUnion = 0, NumTagEnum = 0, NumTagClass = 0;
+  unsigned NumObjcInterfaces = 0;
   
   for (unsigned i = 0, e = Types.size(); i != e; ++i) {
     Type *T = Types[i];
@@ -74,7 +76,9 @@
       case Decl::Class:  ++NumTagClass; break; 
       case Decl::Enum:   ++NumTagEnum; break;
       }
-    } else {
+    } else if (isa<ObjcInterfaceType>(T))
+      ++NumObjcInterfaces;
+    else {
       assert(0 && "Unknown type!");
     }
   }
@@ -93,12 +97,16 @@
   fprintf(stderr, "      %d union types\n", NumTagUnion);
   fprintf(stderr, "      %d class types\n", NumTagClass);
   fprintf(stderr, "      %d enum types\n", NumTagEnum);
+  fprintf(stderr, "    %d interface types\n", NumObjcInterfaces);
   fprintf(stderr, "Total bytes = %d\n", int(NumBuiltin*sizeof(BuiltinType)+
     NumPointer*sizeof(PointerType)+NumArray*sizeof(ArrayType)+
     NumComplex*sizeof(ComplexType)+NumVector*sizeof(VectorType)+
     NumFunctionP*sizeof(FunctionTypeProto)+
     NumFunctionNP*sizeof(FunctionTypeNoProto)+
     NumTypeName*sizeof(TypedefType)+NumTagged*sizeof(TagType)));
+  
+  if (Selectors)
+    Selectors->PrintStats();
 }
 
 
@@ -801,3 +809,11 @@
   
   return getTagDeclType(CFConstantStringTypeDecl);
 }
+
+SelectorInfo &ASTContext::getSelectorInfo(const char *NameStart, 
+                                          const char *NameEnd) {
+  if (!Selectors) // create the table lazily
+    Selectors = new SelectorTable();
+  return Selectors->get(NameStart, NameEnd);
+}
+

Modified: cfe/trunk/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Decl.cpp?rev=42023&r1=42022&r2=42023&view=diff

==============================================================================
--- cfe/trunk/AST/Decl.cpp (original)
+++ cfe/trunk/AST/Decl.cpp Mon Sep 17 09:16:13 2007
@@ -26,6 +26,11 @@
 static unsigned nTypedef = 0;
 static unsigned nFieldDecls = 0;
 static unsigned nInterfaceDecls = 0;
+static unsigned nClassDecls = 0;
+static unsigned nMethodDecls = 0;
+static unsigned nProtocolDecls = 0;
+static unsigned nIvarDecls = 0;
+
 static bool StatSwitch = false;
 
 const char *Decl::getDeclKindName() {
@@ -73,7 +78,8 @@
   fprintf(stderr, "*** Decl Stats:\n");
   fprintf(stderr, "  %d decls total.\n", 
 	  int(nFuncs+nBlockVars+nFileVars+nParmVars+nFieldDecls+nSUC+
-	      nEnumDecls+nEnumConst+nTypedef));
+	      nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+
+	      nMethodDecls+nProtocolDecls+nIvarDecls));
   fprintf(stderr, "    %d function decls, %d each (%d bytes)\n", 
 	  nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
   fprintf(stderr, "    %d block variable decls, %d each (%d bytes)\n", 
@@ -99,12 +105,29 @@
 	  int(nEnumConst*sizeof(EnumConstantDecl)));
   fprintf(stderr, "    %d typedef decls, %d each (%d bytes)\n", 
 	  nTypedef, (int)sizeof(TypedefDecl),int(nTypedef*sizeof(TypedefDecl)));
+  // Objective-C decls...
+  fprintf(stderr, "    %d interface decls, %d each (%d bytes)\n", 
+	  nInterfaceDecls, (int)sizeof(ObjcInterfaceDecl),
+	  int(nInterfaceDecls*sizeof(ObjcInterfaceDecl)));
+  fprintf(stderr, "    %d instance variable decls, %d each (%d bytes)\n", 
+	  nIvarDecls, (int)sizeof(ObjcIvarDecl),
+	  int(nIvarDecls*sizeof(ObjcIvarDecl)));
+  fprintf(stderr, "    %d class decls, %d each (%d bytes)\n", 
+	  nClassDecls, (int)sizeof(ObjcClassDecl),
+	  int(nClassDecls*sizeof(ObjcClassDecl)));
+  fprintf(stderr, "    %d method decls, %d each (%d bytes)\n", 
+	  nMethodDecls, (int)sizeof(ObjcMethodDecl),
+	  int(nMethodDecls*sizeof(ObjcMethodDecl)));
+  fprintf(stderr, "    %d protocol decls, %d each (%d bytes)\n", 
+	  nProtocolDecls, (int)sizeof(ObjcProtocolDecl),
+	  int(nProtocolDecls*sizeof(ObjcProtocolDecl)));
+
   fprintf(stderr, "Total bytes = %d\n", 
 	  int(nFuncs*sizeof(FunctionDecl)+nBlockVars*sizeof(BlockVarDecl)+
 	      nFileVars*sizeof(FileVarDecl)+nParmVars*sizeof(ParmVarDecl)+
 	      nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
 	      nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
-	      nTypedef*sizeof(TypedefDecl)));
+	      nTypedef*sizeof(TypedefDecl)) /* FIXME: add Objc decls */);
 }
 
 void Decl::addDeclKind(const Kind k) {
@@ -142,11 +165,17 @@
       nInterfaceDecls++;
       break;
     case ObjcClass:
+      nClassDecls++;
+      break;
     case ObjcMethod:
     case ObjcProtoMethod:
+      nMethodDecls++;
+      break;
     case ObjcProtocol:
+      nProtocolDecls++;
+      break;
     case ObjcIvar:
-      assert(0 && "FIXME: Count these decls!");
+      nIvarDecls++;
       break;
   }
 }

Modified: cfe/trunk/Lex/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Lex/IdentifierTable.cpp?rev=42023&r1=42022&r2=42023&view=diff

==============================================================================
--- cfe/trunk/Lex/IdentifierTable.cpp (original)
+++ cfe/trunk/Lex/IdentifierTable.cpp Mon Sep 17 09:16:13 2007
@@ -209,3 +209,34 @@
   // Compute statistics about the memory allocated for identifiers.
   HashTable.getAllocator().PrintStats();
 }
+
+/// PrintStats - Print statistics about how well the identifier table is doing
+/// at hashing identifiers.
+void SelectorTable::PrintStats() const {
+  unsigned NumBuckets = HashTable.getNumBuckets();
+  unsigned NumIdentifiers = HashTable.getNumItems();
+  unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers;
+  unsigned AverageIdentifierSize = 0;
+  unsigned MaxIdentifierLength = 0;
+  
+  // TODO: Figure out maximum times an identifier had to probe for -stats.
+  for (llvm::StringMap<SelectorInfo, llvm::BumpPtrAllocator>::const_iterator
+       I = HashTable.begin(), E = HashTable.end(); I != E; ++I) {
+    unsigned IdLen = I->getKeyLength();
+    AverageIdentifierSize += IdLen;
+    if (MaxIdentifierLength < IdLen)
+      MaxIdentifierLength = IdLen;
+  }
+  
+  fprintf(stderr, "\n*** Selector Table Stats:\n");
+  fprintf(stderr, "# Selectors:   %d\n", NumIdentifiers);
+  fprintf(stderr, "# Empty Buckets: %d\n", NumEmptyBuckets);
+  fprintf(stderr, "Hash density (#selectors per bucket): %f\n",
+          NumIdentifiers/(double)NumBuckets);
+  fprintf(stderr, "Ave selector length: %f\n",
+          (AverageIdentifierSize/(double)NumIdentifiers));
+  fprintf(stderr, "Max selector length: %d\n", MaxIdentifierLength);
+  
+  // Compute statistics about the memory allocated for identifiers.
+  HashTable.getAllocator().PrintStats();
+}

Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=42023&r1=42022&r2=42023&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Mon Sep 17 09:16:13 2007
@@ -1239,13 +1239,37 @@
   return;
 }
 
+/// Build objective-c style method name.
+static SelectorInfo &
+  ObjcGetSelectorInfo(ObjcKeywordInfo* KeyInfo, unsigned numKeyInfo,
+                      ASTContext &Context)
+{
+  int len=0;
+  char *methodName;
+  for (unsigned int i = 0; i < numKeyInfo; i++) {
+    IdentifierInfo *selectorName = KeyInfo[i].SelectorName;
+    if (selectorName)
+      len += strlen(selectorName->getName());
+    len++;
+  }
+  methodName = (char *) alloca (len + 1);
+  methodName[0] = '\0';
+  for (unsigned int i = 0; i < numKeyInfo; i++) {
+    IdentifierInfo *selectorName = KeyInfo[i].SelectorName;
+    if (selectorName)
+      strcat(methodName, selectorName->getName());
+    strcat(methodName, ":");
+  }
+  return Context.getSelectorInfo(methodName, methodName+len);
+}
+
+
 Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc, 
                       tok::TokenKind MethodType, TypeTy *ReturnType,
                       ObjcKeywordInfo *Keywords, unsigned NumKeywords,
                       AttributeList *AttrList) {
   assert(NumKeywords && "Selector must be specified");
-  // FIXME: SelectorName to be changed to comform to objc's abi for method names
-  IdentifierInfo *SelectorName = Keywords[0].SelectorName;
+  SelectorInfo &SelName = ObjcGetSelectorInfo(Keywords, NumKeywords, Context);
   llvm::SmallVector<ParmVarDecl*, 16> Params;
 
   for (unsigned i = 0; i < NumKeywords; i++) {
@@ -1261,7 +1285,7 @@
   }
   QualType resultDeclType = QualType::getFromOpaquePtr(ReturnType);
   ObjcMethodDecl* ObjcMethod =  new ObjcMethodDecl(MethodLoc, 
-				      SelectorName, resultDeclType, 
+				      SelName, resultDeclType, 
 				      0, -1, AttrList, MethodType == tok::minus);
   ObjcMethod->setMethodParams(&Params[0], NumKeywords);
   return ObjcMethod;
@@ -1270,9 +1294,11 @@
 Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc,  
                       tok::TokenKind MethodType, TypeTy *ReturnType,
                       IdentifierInfo *SelectorName, AttributeList *AttrList) {
-  // FIXME: SelectorName to be changed to comform to objc's abi for method names
+  const char *methodName = SelectorName->getName();
+  SelectorInfo &SelName = Context.getSelectorInfo(methodName, 
+                                                  methodName+strlen(methodName));
   QualType resultDeclType = QualType::getFromOpaquePtr(ReturnType);
-  return new ObjcMethodDecl(MethodLoc, SelectorName, resultDeclType, 0, -1,
+  return new ObjcMethodDecl(MethodLoc, SelName, resultDeclType, 0, -1,
 			    AttrList, MethodType == tok::minus);
 }
 

Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=42023&r1=42022&r2=42023&view=diff

==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Mon Sep 17 09:16:13 2007
@@ -227,7 +227,7 @@
 		35AE0F680C9B4CC200CC1279 /* UnintializedValues.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UnintializedValues.cpp; path = Analysis/UnintializedValues.cpp; sourceTree = "<group>"; };
 		84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = "<group>"; };
 		84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = "<group>"; };
-		8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
+		8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
 		DE01DA480B12ADA300AC22CE /* PPCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCallbacks.h; sourceTree = "<group>"; };
 		DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExprCXX.cpp; path = Parse/ParseExprCXX.cpp; sourceTree = "<group>"; };
 		DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = "<group>"; };

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=42023&r1=42022&r2=42023&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Sep 17 09:16:13 2007
@@ -24,6 +24,7 @@
 
 namespace clang {
   class TargetInfo;
+  class SelectorTable;
   
 /// ASTContext - This class holds long-lived AST nodes (such as types and
 /// decls) that can be referred to throughout the semantic analysis of a file.
@@ -38,7 +39,7 @@
   llvm::FoldingSet<FunctionTypeProto> FunctionTypeProtos;
   llvm::DenseMap<const RecordDecl*, const RecordLayout*> RecordLayoutInfo;
   RecordDecl *CFConstantStringTypeDecl;
-  llvm::StringMap<char> SelectorNames;
+  SelectorTable *Selectors;
 public:
   SourceManager &SourceMgr;
   TargetInfo &Target;
@@ -56,7 +57,8 @@
   QualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
   
   ASTContext(SourceManager &SM, TargetInfo &t, IdentifierTable &idents) : 
-    CFConstantStringTypeDecl(0), SourceMgr(SM), Target(t), Idents(idents) {
+    CFConstantStringTypeDecl(0), Selectors(0), 
+    SourceMgr(SM), Target(t), Idents(idents) {
     InitBuiltinTypes();
     BuiltinInfo.InitializeBuiltins(idents, Target);
   }    
@@ -182,10 +184,8 @@
   //                            Objective-C
   //===--------------------------------------------------------------------===//
   
-  /// getSelectorName - Return a uniqued character string for the selector.
-  char &getSelectorName(const char *NameStart, const char *NameEnd) {
-    return SelectorNames.GetOrCreateValue(NameStart, NameEnd).getValue();
-  }
+  /// getSelectorInfo - Return a uniqued character string for the selector.
+  SelectorInfo &getSelectorInfo(const char *NameStart, const char *NameEnd);
 
 private:
   ASTContext(const ASTContext&); // DO NOT IMPLEMENT

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=42023&r1=42022&r2=42023&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Mon Sep 17 09:16:13 2007
@@ -23,10 +23,11 @@
 class Expr;
 class Stmt;
 class FunctionDecl;
+class AttributeList;
 class ObjcIvarDecl;
 class ObjcMethodDecl;
-class AttributeList;
 class ObjcProtoMethodDecl;
+class SelectorInfo;
 
 
 /// Decl - This represents one declaration (or definition), e.g. a variable, 
@@ -614,20 +615,35 @@
 /// ObjcMethodDecl - An instance of this class is created to represent an instance
 /// or class method declaration.
 class ObjcMethodDecl : public Decl {
+  // A unigue name for this method.
+  SelectorInfo &Selector;
+  
+  // Type of this method.
+  QualType MethodDeclType;
+  /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
+  /// parameters of this Method.  This is null if there are no formals.  
+  ParmVarDecl **ParamInfo;
+  int NumMethodParams;  // -1 if no parameters
+  
+  /// List of attributes for this method declaration.
+  AttributeList *MethodAttrs;
+
+  /// instance (true) or class (false) method.
+  bool IsInstance : 1;
 public:
-  ObjcMethodDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
+  ObjcMethodDecl(SourceLocation L, SelectorInfo &SelId, QualType T,
 		 ParmVarDecl **paramInfo = 0, int numParams=-1,
 		 AttributeList *M = 0, bool isInstance = true, 
 		 Decl *PrevDecl = 0)
-    : Decl(ObjcMethod), MethodDeclType(T), 
+    : Decl(ObjcMethod), Selector(SelId), MethodDeclType(T), 
       ParamInfo(paramInfo), NumMethodParams(numParams),
       MethodAttrs(M), IsInstance(isInstance) {}
 
-  ObjcMethodDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
+  ObjcMethodDecl(Kind DK, SourceLocation L, SelectorInfo &SelId, QualType T,
 		 ParmVarDecl **paramInfo = 0, int numParams=-1,
 		 AttributeList *M = 0, bool isInstance = true, 
 		 Decl *PrevDecl = 0)
-    : Decl(DK), MethodDeclType(T), 
+    : Decl(DK), Selector(SelId), MethodDeclType(T), 
       ParamInfo(paramInfo), NumMethodParams(numParams),
       MethodAttrs(M), IsInstance(isInstance) {}
 
@@ -649,20 +665,6 @@
 	   || D->getKind() == ObjcProtoMethod; 
   }
   static bool classof(const ObjcMethodDecl *D) { return true; }
-
-private:
-  // Type of this method.
-  QualType MethodDeclType;
-  /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
-  /// parameters of this Method.  This is null if there are no formals.  
-  ParmVarDecl **ParamInfo;
-  int NumMethodParams;  // -1 if no parameters
-  
-  /// List of attributes for this method declaration.
-  AttributeList *MethodAttrs;
-
-  /// instance (true) or class (false) method.
-  bool IsInstance : 1;
 };
 
 /// ObjcProtoMethodDecl - Each instance represents a method declared
@@ -670,7 +672,7 @@
 ///
 class ObjcProtoMethodDecl : ObjcMethodDecl {
 public:
-  ObjcProtoMethodDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
+  ObjcProtoMethodDecl(SourceLocation L, SelectorInfo &Id, QualType T,
                       ParmVarDecl **paramInfo = 0, int numParams=-1,
                       AttributeList *M = 0, bool isInstance = true,
                       Decl *PrevDecl = 0) :

Modified: cfe/trunk/include/clang/Lex/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/IdentifierTable.h?rev=42023&r1=42022&r2=42023&view=diff

==============================================================================
--- cfe/trunk/include/clang/Lex/IdentifierTable.h (original)
+++ cfe/trunk/include/clang/Lex/IdentifierTable.h Mon Sep 17 09:16:13 2007
@@ -45,9 +45,8 @@
   IdentifierInfo();
   ~IdentifierInfo();
 
-  /// getName - Return the actual string for this identifier.  The length of
-  /// this string is stored in NameLen, and the returned string is properly null
-  /// terminated.
+  /// getName - Return the actual string for this identifier.  The returned 
+  /// string is properly null terminated.
   ///
   const char *getName() const {
     // String data is stored immediately after the IdentifierInfo object.
@@ -167,6 +166,54 @@
   void AddKeywords(const LangOptions &LangOpts);
 };
 
+/// SelectorInfo - One of these records is kept for each selector. Selectors
+/// are created as a by-product of parsing a method declaration/definition, 
+/// message expression, or @selector expression.
+class SelectorInfo {
+  void *ObjcMethodDecl;  // FIXME: add setter/getter.
+  
+  SelectorInfo(const SelectorInfo&);  // NONCOPYABLE.
+public:
+  SelectorInfo() : ObjcMethodDecl(0) {}
+
+  /// getName - Return the actual string for this selector.  The returned 
+  /// string is properly null terminated.
+  ///
+  const char *getName() const {
+    // String data is stored immediately after the IdentifierInfo object.
+    return (const char*)(this+1);
+  }
+};
+
+/// SelectorTable - This table implements an efficient mapping from strings to
+/// SelectorInfo nodes.  
+class SelectorTable {
+  // Shark shows that using MallocAllocator is *much* slower than using this
+  // BumpPtrAllocator!
+  typedef llvm::StringMap<SelectorInfo, llvm::BumpPtrAllocator> HashTableTy;
+  HashTableTy HashTable;
+public:
+  SelectorTable() : HashTable(4096) { }
+  
+  /// get - Return the selector info for the specified name.
+  ///
+  SelectorInfo &get(const char *NameStart, const char *NameEnd) {
+    return HashTable.GetOrCreateValue(NameStart, NameEnd).getValue();
+  }
+  SelectorInfo &get(const char *Name) {
+    return get(Name, Name+strlen(Name));
+  }
+  typedef HashTableTy::const_iterator iterator;
+  typedef HashTableTy::const_iterator const_iterator;
+  
+  iterator begin() const { return HashTable.begin(); }
+  iterator end() const   { return HashTable.end(); }
+  
+  /// PrintStats - Print some statistics to stderr that indicate how well the
+  /// hashing is doing.
+  void PrintStats() const;
+};
+
 }  // end namespace clang
 
 #endif





More information about the cfe-commits mailing list