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. llvm-svn: 42023
This commit is contained in:
parent
ffb47d0679
commit
73d534a2e0
|
@ -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 @@ void ASTContext::PrintStats() const {
|
|||
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 @@ void ASTContext::PrintStats() const {
|
|||
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 @@ void ASTContext::PrintStats() const {
|
|||
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 @@ QualType ASTContext::getCFConstantStringType() {
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,11 @@ static unsigned nEnumDecls = 0;
|
|||
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 @@ void Decl::PrintStats() {
|
|||
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 @@ void Decl::PrintStats() {
|
|||
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 @@ void Decl::addDeclKind(const Kind k) {
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -209,3 +209,34 @@ void IdentifierTable::PrintStats() const {
|
|||
// 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();
|
||||
}
|
||||
|
|
|
@ -1239,13 +1239,37 @@ void Sema::ObjcAddMethodsToClass(DeclTy *ClassDecl,
|
|||
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 @@ Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc,
|
|||
}
|
||||
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,
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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>"; };
|
||||
|
|
|
@ -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 @@ class ASTContext {
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
// 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
|
||||
|
|
|
@ -23,10 +23,11 @@ class IdentifierInfo;
|
|||
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 @@ public:
|
|||
/// 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 @@ public:
|
|||
|| 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 @@ private:
|
|||
///
|
||||
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) :
|
||||
|
|
|
@ -45,9 +45,8 @@ public:
|
|||
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 @@ private:
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue