[cfe-commits] r42452 - in /cfe/trunk: AST/Expr.cpp Lex/IdentifierTable.cpp Parse/ParseObjc.cpp Sema/Sema.h Sema/SemaDecl.cpp Sema/SemaExpr.cpp clang.xcodeproj/project.pbxproj include/clang/AST/ASTContext.h include/clang/AST/Decl.h include/clang/AST/Expr.h include/clang/Lex/IdentifierTable.h include/clang/Lex/Preprocessor.h include/clang/Parse/Action.h include/clang/Parse/Parser.h
Steve Naroff
snaroff at apple.com
Fri Sep 28 15:22:11 PDT 2007
Author: snaroff
Date: Fri Sep 28 17:22:11 2007
New Revision: 42452
URL: http://llvm.org/viewvc/llvm-project?rev=42452&view=rev
Log:
Yesterday I discovered that 78% of all selectors in "Cocoa.h" take 0/1 argument.
This motivated implementing a devious clattner inspired solution:-)
This approach uses a small value "Selector" class to point to an IdentifierInfo for the 0/1 case. For multi-keyword selectors, we instantiate a MultiKeywordSelector object (previously known as SelectorInfo). Now, the incremental cost for selectors is only 24,800 for Cocoa.h! This saves 156,592 bytes, or 86%!! The size reduction is also the result of getting rid of the AST slot, which was not strictly necessary (we will associate a selector with it's method using another table...most likely in Sema).
This change was critical to make now, before we have too many clients.
I still need to add some comments to the Selector class...will likely add later today/tomorrow.
Modified:
cfe/trunk/AST/Expr.cpp
cfe/trunk/Lex/IdentifierTable.cpp
cfe/trunk/Parse/ParseObjc.cpp
cfe/trunk/Sema/Sema.h
cfe/trunk/Sema/SemaDecl.cpp
cfe/trunk/Sema/SemaExpr.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/AST/Expr.h
cfe/trunk/include/clang/Lex/IdentifierTable.h
cfe/trunk/include/clang/Lex/Preprocessor.h
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/include/clang/Parse/Parser.h
Modified: cfe/trunk/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Expr.cpp?rev=42452&r1=42451&r2=42452&view=diff
==============================================================================
--- cfe/trunk/AST/Expr.cpp (original)
+++ cfe/trunk/AST/Expr.cpp Fri Sep 28 17:22:11 2007
@@ -869,11 +869,11 @@
}
// constructor for instance messages.
-ObjCMessageExpr::ObjCMessageExpr(Expr *receiver, SelectorInfo *selInfo,
+ObjCMessageExpr::ObjCMessageExpr(Expr *receiver, Selector selInfo,
QualType retType, SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs)
- : Expr(ObjCMessageExprClass, retType), Selector(selInfo), ClassName(0) {
- unsigned numArgs = selInfo->getNumArgs();
+ : Expr(ObjCMessageExprClass, retType), SelName(selInfo), ClassName(0) {
+ unsigned numArgs = selInfo.getNumArgs();
SubExprs = new Expr*[numArgs+1];
SubExprs[RECEIVER] = receiver;
if (numArgs) {
@@ -886,11 +886,11 @@
// constructor for class messages.
// FIXME: clsName should be typed to ObjCInterfaceType
-ObjCMessageExpr::ObjCMessageExpr(IdentifierInfo *clsName, SelectorInfo *selInfo,
+ObjCMessageExpr::ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
QualType retType, SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs)
- : Expr(ObjCMessageExprClass, retType), Selector(selInfo), ClassName(clsName) {
- unsigned numArgs = selInfo->getNumArgs();
+ : Expr(ObjCMessageExprClass, retType), SelName(selInfo), ClassName(clsName) {
+ unsigned numArgs = selInfo.getNumArgs();
SubExprs = new Expr*[numArgs+1];
SubExprs[RECEIVER] = 0;
if (numArgs) {
@@ -901,21 +901,6 @@
RBracloc = RBrac;
}
-// The following 3 methods are defined here (instead of Epxr.h) to avoid
-// importing "IdentifierTable.h" into the header.
-unsigned ObjCMessageExpr::getNumArgs() const { return Selector->getNumArgs(); }
-
-/// getArg - Return the specified argument.
-Expr *ObjCMessageExpr::getArg(unsigned Arg) {
- assert(Arg < Selector->getNumArgs() && "Arg access out of range!");
- return SubExprs[Arg+ARGS_START];
-}
-const Expr *ObjCMessageExpr::getArg(unsigned Arg) const {
- assert(Arg < Selector->getNumArgs() && "Arg access out of range!");
- return SubExprs[Arg+ARGS_START];
-}
-
-
//===----------------------------------------------------------------------===//
// Child Iterators for iterating over subexpressions/substatements
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/Lex/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Lex/IdentifierTable.cpp?rev=42452&r1=42451&r2=42452&view=diff
==============================================================================
--- cfe/trunk/Lex/IdentifierTable.cpp (original)
+++ cfe/trunk/Lex/IdentifierTable.cpp Fri Sep 28 17:22:11 2007
@@ -33,27 +33,33 @@
return specId ? specId->getObjCKeywordID() : tok::objc_not_keyword;
}
-char *SelectorInfo::getName(llvm::SmallVectorImpl<char> &methodName) {
- int len=0;
+char *MultiKeywordSelector::getName(llvm::SmallVectorImpl<char> &methodName) {
methodName[0] = '\0';
- if (NumArgs) {
- keyword_iterator KeyIter = keyword_begin();
- for (unsigned int i = 0; i < NumArgs; i++) {
- if (KeyIter[i]) {
- unsigned KeyLen = strlen(KeyIter[i]->getName());
- methodName.append(KeyIter[i]->getName(), KeyIter[i]->getName()+KeyLen);
- len += KeyLen;
- }
- methodName.push_back(':');
- len++;
+ keyword_iterator KeyIter = keyword_begin();
+ for (unsigned int i = 0; i < NumArgs; i++) {
+ if (KeyIter[i]) {
+ unsigned KeyLen = strlen(KeyIter[i]->getName());
+ methodName.append(KeyIter[i]->getName(), KeyIter[i]->getName()+KeyLen);
}
- } else {
- IdentifierInfo **UnaryInfo = reinterpret_cast<IdentifierInfo **>(this+1);
- unsigned NameLen = strlen(UnaryInfo[0]->getName());
- methodName.append(UnaryInfo[0]->getName(), UnaryInfo[0]->getName()+NameLen);
- len += NameLen;
+ methodName.push_back(':');
+ }
+ methodName.push_back('\0');
+ return &methodName[0];
+}
+
+char *Selector::getName(llvm::SmallVectorImpl<char> &methodName) {
+ methodName[0] = '\0';
+ IdentifierInfo *II = getAsIdentifierInfo();
+ if (II) {
+ unsigned NameLen = strlen(II->getName());
+ methodName.append(II->getName(), II->getName()+NameLen);
+ if (getNumArgs() == 1)
+ methodName.push_back(':');
+ methodName.push_back('\0');
+ } else { // We have a multiple keyword selector (no embedded flags).
+ MultiKeywordSelector *SI = reinterpret_cast<MultiKeywordSelector *>(InfoPtr);
+ SI->getName(methodName);
}
- methodName[len] = '\0';
return &methodName[0];
}
Modified: cfe/trunk/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseObjc.cpp?rev=42452&r1=42451&r2=42452&view=diff
==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Fri Sep 28 17:22:11 2007
@@ -502,50 +502,35 @@
return Ty;
}
-static SelectorInfo *ObjcGetUnarySelectorInfo(
- IdentifierInfo *unarySel,
- llvm::FoldingSet<SelectorInfo> &SelTab)
+Selector Parser::ObjcGetUnarySelector(IdentifierInfo *unarySel)
{
- // Unique selector, to guarantee there is one per name.
- llvm::SmallVector<IdentifierInfo *, 1> IIV;
- llvm::FoldingSetNodeID ID;
-
- IIV.push_back(unarySel);
- SelectorInfo::Profile(ID, &IIV[0], 0);
-
- void *InsertPos = 0;
- if (SelectorInfo *SI = SelTab.FindNodeOrInsertPos(ID, InsertPos))
- return SI;
-
- // SelectorInfo objects are not allocated with new because they have a
- // variable size array (for parameter types) at the end of them.
- SelectorInfo *SI =
- (SelectorInfo*)malloc(sizeof(SelectorInfo) + sizeof(IdentifierInfo *));
- new (SI) SelectorInfo(IIV[0]);
- SelTab.InsertNode(SI, InsertPos);
- return SI;
+ return Selector(unarySel, 0);
}
-static SelectorInfo *ObjcGetKeywordSelectorInfo(
- llvm::SmallVectorImpl<IdentifierInfo *> &IIV,
- llvm::FoldingSet<SelectorInfo> &SelTab)
-{
+Selector Parser::ObjcGetKeywordSelector(
+ llvm::SmallVectorImpl<IdentifierInfo *> &IIV)
+{
+ if (IIV.size() == 1)
+ return Selector(IIV[0], 1);
+
+ llvm::FoldingSet<MultiKeywordSelector> &SelTab = PP.getSelectorTable();
+
// Unique selector, to guarantee there is one per name.
llvm::FoldingSetNodeID ID;
- SelectorInfo::Profile(ID, &IIV[0], IIV.size());
+ MultiKeywordSelector::Profile(ID, &IIV[0], IIV.size());
void *InsertPos = 0;
- if (SelectorInfo *SI = SelTab.FindNodeOrInsertPos(ID, InsertPos))
- return SI;
-
- // SelectorInfo objects are not allocated with new because they have a
+ if (MultiKeywordSelector *SI = SelTab.FindNodeOrInsertPos(ID, InsertPos)) {
+ return Selector(SI);
+ }
+ // MultiKeywordSelector objects are not allocated with new because they have a
// variable size array (for parameter types) at the end of them.
- SelectorInfo *SI =
- (SelectorInfo*)malloc(sizeof(SelectorInfo) +
- IIV.size()*sizeof(IdentifierInfo *));
- new (SI) SelectorInfo(IIV.size(), &IIV[0]);
+ MultiKeywordSelector *SI =
+ (MultiKeywordSelector*)malloc(sizeof(MultiKeywordSelector) +
+ IIV.size()*sizeof(IdentifierInfo *));
+ new (SI) MultiKeywordSelector(IIV.size(), &IIV[0]);
SelTab.InsertNode(SI, InsertPos);
- return SI;
+ return Selector(SI);
}
/// objc-method-decl:
@@ -646,9 +631,8 @@
if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
methodAttrs = ParseAttributes();
- SelectorInfo *SI = ObjcGetKeywordSelectorInfo(KeyIdents,
- PP.getSelectorTable());
- return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, SI,
+ Selector Sel = ObjcGetKeywordSelector(KeyIdents);
+ return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, Sel,
&KeyTypes[0], &ArgNames[0],
methodAttrs, MethodImplKind);
} else if (!selIdent) {
@@ -658,8 +642,8 @@
if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
methodAttrs = ParseAttributes();
- SelectorInfo *SI = ObjcGetUnarySelectorInfo(selIdent, PP.getSelectorTable());
- return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, SI,
+ Selector Sel = ObjcGetUnarySelector(selIdent);
+ return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, Sel,
0, 0, methodAttrs, MethodImplKind);
}
@@ -1255,21 +1239,20 @@
SourceLocation RBracloc = ConsumeBracket(); // consume ']'
if (KeyIdents.size()) {
- SelectorInfo *SI = ObjcGetKeywordSelectorInfo(KeyIdents,
- PP.getSelectorTable());
+ Selector sel = ObjcGetKeywordSelector(KeyIdents);
// We've just parsed a keyword message.
if (ReceiverName)
- return Actions.ActOnClassMessage(ReceiverName, SI, LBracloc, RBracloc,
+ return Actions.ActOnClassMessage(ReceiverName, sel, LBracloc, RBracloc,
&KeyExprs[0]);
- return Actions.ActOnInstanceMessage(ReceiverExpr, SI, LBracloc, RBracloc,
+ return Actions.ActOnInstanceMessage(ReceiverExpr, sel, LBracloc, RBracloc,
&KeyExprs[0]);
}
- SelectorInfo *SI = ObjcGetUnarySelectorInfo(selIdent, PP.getSelectorTable());
+ Selector sel = ObjcGetUnarySelector(selIdent);
// We've just parsed a unary message (a message with no arguments).
if (ReceiverName)
- return Actions.ActOnClassMessage(ReceiverName, SI, LBracloc, RBracloc, 0);
- return Actions.ActOnInstanceMessage(ReceiverExpr, SI, LBracloc, RBracloc, 0);
+ return Actions.ActOnClassMessage(ReceiverName, sel, LBracloc, RBracloc, 0);
+ return Actions.ActOnInstanceMessage(ReceiverExpr, sel, LBracloc, RBracloc, 0);
}
Parser::ExprResult Parser::ParseObjCStringLiteral() {
Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=42452&r1=42451&r2=42452&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Fri Sep 28 17:22:11 2007
@@ -391,7 +391,7 @@
DeclTy **Fields, unsigned NumFields);
virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc,
- tok::TokenKind MethodType, TypeTy *ReturnType, SelectorInfo *Sel,
+ tok::TokenKind MethodType, TypeTy *ReturnType, Selector Sel,
// optional arguments. The number of types/arguments is obtained
// from the Sel.getNumArgs().
TypeTy **ArgTypes, IdentifierInfo **ArgNames,
@@ -401,14 +401,14 @@
// ArgExprs is optional - if it is present, the number of expressions
// is obtained from Sel.getNumArgs().
virtual ExprResult ActOnClassMessage(
- IdentifierInfo *receivingClassName, SelectorInfo *Sel,
+ IdentifierInfo *receivingClassName, Selector Sel,
SourceLocation lbrac, SourceLocation rbrac, ExprTy **ArgExprs);
// ActOnInstanceMessage - used for both unary and keyword messages.
// ArgExprs is optional - if it is present, the number of expressions
// is obtained from Sel.getNumArgs().
virtual ExprResult ActOnInstanceMessage(
- ExprTy *receiver, SelectorInfo *Sel,
+ ExprTy *receiver, Selector Sel,
SourceLocation lbrac, SourceLocation rbrac, ExprTy **ArgExprs);
private:
// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=42452&r1=42451&r2=42452&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Fri Sep 28 17:22:11 2007
@@ -1178,23 +1178,23 @@
/// Declared in protocol, and those referenced by it.
///
static void CheckProtocolMethodDefs(Sema* objSema, ObjcProtocolDecl *PDecl,
- const llvm::DenseMap<const SelectorInfo*, char>& InsMap,
- const llvm::DenseMap<const SelectorInfo*, char>& ClsMap) {
+ const llvm::DenseMap<void *, char>& InsMap,
+ const llvm::DenseMap<void *, char>& ClsMap) {
// check unimplemented instance methods.
ObjcMethodDecl** methods = PDecl->getInsMethods();
for (int j = 0; j < PDecl->getNumInsMethods(); j++)
- if (!InsMap.count(methods[j]->getSelector())) {
+ if (!InsMap.count(methods[j]->getSelector().getAsOpaquePtr())) {
llvm::SmallString<128> buf;
objSema->Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
- methods[j]->getSelector()->getName(buf));
+ methods[j]->getSelector().getName(buf));
}
// check unimplemented class methods
methods = PDecl->getClsMethods();
for (int j = 0; j < PDecl->getNumClsMethods(); j++)
- if (!ClsMap.count(methods[j]->getSelector())) {
+ if (!ClsMap.count(methods[j]->getSelector().getAsOpaquePtr())) {
llvm::SmallString<128> buf;
objSema->Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
- methods[j]->getSelector()->getName(buf));
+ methods[j]->getSelector().getName(buf));
}
// Check on this protocols's referenced protocols, recursively
@@ -1206,35 +1206,35 @@
static void ImplMethodsVsClassMethods(Sema* objSema,
ObjcImplementationDecl* IMPDecl,
ObjcInterfaceDecl* IDecl) {
- llvm::DenseMap<const SelectorInfo*, char> InsMap;
+ llvm::DenseMap<void *, char> InsMap;
// Check and see if instance methods in class interface have been
// implemented in the implementation class.
ObjcMethodDecl **methods = IMPDecl->getInsMethods();
for (int i=0; i < IMPDecl->getNumInsMethods(); i++) {
- InsMap[methods[i]->getSelector()] = 'a';
+ InsMap[methods[i]->getSelector().getAsOpaquePtr()] = 'a';
}
methods = IDecl->getInsMethods();
for (int j = 0; j < IDecl->getNumInsMethods(); j++)
- if (!InsMap.count(methods[j]->getSelector())) {
+ if (!InsMap.count(methods[j]->getSelector().getAsOpaquePtr())) {
llvm::SmallString<128> buf;
objSema->Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
- methods[j]->getSelector()->getName(buf));
+ methods[j]->getSelector().getName(buf));
}
- llvm::DenseMap<const SelectorInfo*, char> ClsMap;
+ llvm::DenseMap<void *, char> ClsMap;
// Check and see if class methods in class interface have been
// implemented in the implementation class.
methods = IMPDecl->getClsMethods();
for (int i=0; i < IMPDecl->getNumClsMethods(); i++) {
- ClsMap[methods[i]->getSelector()] = 'a';
+ ClsMap[methods[i]->getSelector().getAsOpaquePtr()] = 'a';
}
methods = IDecl->getClsMethods();
for (int j = 0; j < IDecl->getNumClsMethods(); j++)
- if (!ClsMap.count(methods[j]->getSelector())) {
+ if (!ClsMap.count(methods[j]->getSelector().getAsOpaquePtr())) {
llvm::SmallString<128> buf;
objSema->Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
- methods[j]->getSelector()->getName(buf));
+ methods[j]->getSelector().getName(buf));
}
// Check the protocol list for unimplemented methods in the @implementation
@@ -1650,14 +1650,14 @@
}
Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc,
- tok::TokenKind MethodType, TypeTy *ReturnType, SelectorInfo *Sel,
+ tok::TokenKind MethodType, TypeTy *ReturnType, Selector Sel,
// optional arguments. The number of types/arguments is obtained
// from the Sel.getNumArgs().
TypeTy **ArgTypes, IdentifierInfo **ArgNames,
AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind) {
llvm::SmallVector<ParmVarDecl*, 16> Params;
- for (unsigned i = 0; i < Sel->getNumArgs(); i++) {
+ for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
// FIXME: arg->AttrList must be stored too!
ParmVarDecl* Param = new ParmVarDecl(SourceLocation(/*FIXME*/), ArgNames[i],
QualType::getFromOpaquePtr(ArgTypes[i]),
@@ -1668,7 +1668,7 @@
ObjcMethodDecl* ObjcMethod = new ObjcMethodDecl(MethodLoc, Sel,
resultDeclType, 0, -1, AttrList,
MethodType == tok::minus);
- ObjcMethod->setMethodParams(&Params[0], Sel->getNumArgs());
+ ObjcMethod->setMethodParams(&Params[0], Sel.getNumArgs());
if (MethodDeclKind == tok::objc_optional)
ObjcMethod->setDeclImplementation(ObjcMethodDecl::Optional);
else
Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=42452&r1=42451&r2=42452&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Fri Sep 28 17:22:11 2007
@@ -1875,7 +1875,7 @@
// ArgExprs is optional - if it is present, the number of expressions
// is obtained from Sel.getNumArgs().
Sema::ExprResult Sema::ActOnClassMessage(
- IdentifierInfo *receivingClassName, SelectorInfo *Sel,
+ IdentifierInfo *receivingClassName, Selector Sel,
SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args)
{
assert(receivingClassName && "missing receiver class name");
@@ -1889,7 +1889,7 @@
// ArgExprs is optional - if it is present, the number of expressions
// is obtained from Sel.getNumArgs().
Sema::ExprResult Sema::ActOnInstanceMessage(
- ExprTy *receiver, SelectorInfo *Sel,
+ ExprTy *receiver, Selector Sel,
SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args)
{
assert(receiver && "missing receiver expression");
Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=42452&r1=42451&r2=42452&view=diff
==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Fri Sep 28 17:22:11 2007
@@ -733,7 +733,6 @@
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
- compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
projectDirPath = "";
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=42452&r1=42451&r2=42452&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Fri Sep 28 17:22:11 2007
@@ -48,7 +48,7 @@
SourceManager &SourceMgr;
TargetInfo &Target;
IdentifierTable &Idents;
- llvm::FoldingSet<SelectorInfo> &Selectors;
+ llvm::FoldingSet<MultiKeywordSelector> &Selectors;
Builtin::Context BuiltinInfo;
// Builtin Types.
@@ -62,7 +62,7 @@
QualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
ASTContext(SourceManager &SM, TargetInfo &t, IdentifierTable &idents,
- llvm::FoldingSet<SelectorInfo> &sels) :
+ llvm::FoldingSet<MultiKeywordSelector> &sels) :
CFConstantStringTypeDecl(0), SourceMgr(SM), Target(t),
Idents(idents), Selectors(sels) {
InitBuiltinTypes();
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=42452&r1=42451&r2=42452&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Fri Sep 28 17:22:11 2007
@@ -17,10 +17,9 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/AST/Type.h"
#include "llvm/ADT/APSInt.h"
+#include "clang/Lex/IdentifierTable.h" // FIXME: should be in Basic, not Lex.
namespace clang {
-class IdentifierInfo;
-class SelectorInfo;
class Expr;
class Stmt;
class FunctionDecl;
@@ -676,7 +675,7 @@
enum ImplementationControl { None, Required, Optional };
private:
// A unigue name for this method.
- SelectorInfo *Selector;
+ Selector SelName;
// Type of this method.
QualType MethodDeclType;
@@ -697,11 +696,11 @@
ImplementationControl DeclImplementation : 2;
public:
- ObjcMethodDecl(SourceLocation L, SelectorInfo *SelInfo, QualType T,
+ ObjcMethodDecl(SourceLocation L, Selector SelInfo, QualType T,
ParmVarDecl **paramInfo = 0, int numParams=-1,
AttributeList *M = 0, bool isInstance = true,
Decl *PrevDecl = 0)
- : Decl(ObjcMethod), Selector(SelInfo), MethodDeclType(T),
+ : Decl(ObjcMethod), SelName(SelInfo), MethodDeclType(T),
ParamInfo(paramInfo), NumMethodParams(numParams),
MethodAttrs(M), Loc(L), IsInstance(isInstance) {}
#if 0
@@ -714,7 +713,7 @@
MethodAttrs(M), IsInstance(isInstance) {}
#endif
virtual ~ObjcMethodDecl();
- SelectorInfo *getSelector() const { return Selector; }
+ Selector getSelector() const { return SelName; }
QualType getMethodType() const { return MethodDeclType; }
unsigned getNumMethodParams() const { return NumMethodParams; }
ParmVarDecl *getMethodParamDecl(unsigned i) {
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=42452&r1=42451&r2=42452&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Fri Sep 28 17:22:11 2007
@@ -19,10 +19,11 @@
#include "clang/AST/Decl.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/APFloat.h"
+#include "clang/Lex/IdentifierTable.h" // FIXME: should be in Basic, not Lex.
namespace clang {
class IdentifierInfo;
- class SelectorInfo;
+ class Selector;
class Decl;
class ASTContext;
@@ -1077,7 +1078,7 @@
Expr **SubExprs;
// A unigue name for this message.
- SelectorInfo *Selector;
+ Selector SelName;
IdentifierInfo *ClassName; // optional - 0 for instance messages.
@@ -1085,11 +1086,11 @@
public:
// constructor for class messages.
// FIXME: clsName should be typed to ObjCInterfaceType
- ObjCMessageExpr(IdentifierInfo *clsName, SelectorInfo *selInfo,
+ ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
QualType retType, SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs);
// constructor for instance messages.
- ObjCMessageExpr(Expr *receiver, SelectorInfo *selInfo,
+ ObjCMessageExpr(Expr *receiver, Selector selInfo,
QualType retType, SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs);
~ObjCMessageExpr() {
@@ -1100,12 +1101,17 @@
Expr *getReceiver() { return SubExprs[RECEIVER]; }
/// getNumArgs - Return the number of actual arguments to this call.
- ///
- unsigned getNumArgs() const;
-
- /// getArg - Return the specified argument.
- Expr *getArg(unsigned Arg);
- const Expr *getArg(unsigned Arg) const;
+ unsigned getNumArgs() const { return SelName.getNumArgs(); }
+
+/// getArg - Return the specified argument.
+ Expr *getArg(unsigned Arg) {
+ assert(Arg < SelName.getNumArgs() && "Arg access out of range!");
+ return SubExprs[Arg+ARGS_START];
+ }
+ const Expr *getArg(unsigned Arg) const {
+ assert(Arg < SelName.getNumArgs() && "Arg access out of range!");
+ return SubExprs[Arg+ARGS_START];
+ }
SourceRange getSourceRange() const { return SourceRange(LBracloc, RBracloc); }
Modified: cfe/trunk/include/clang/Lex/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/IdentifierTable.h?rev=42452&r1=42451&r2=42452&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/IdentifierTable.h (original)
+++ cfe/trunk/include/clang/Lex/IdentifierTable.h Fri Sep 28 17:22:11 2007
@@ -170,28 +170,24 @@
void AddKeywords(const LangOptions &LangOpts);
};
-/// SelectorInfo - One of these variable length records is kept for each parsed
-/// selector (similar in spirit to IdentifierInfo). We use a folding set to
-/// unique aggregate names (keyword selectors in ObjC parlance).
-class SelectorInfo : public llvm::FoldingSetNode {
+/// MultiKeywordSelector - One of these variable length records is kept for each
+/// parsed selector (similar in spirit to IdentifierInfo). We use a folding set
+/// to unique aggregate names (keyword selectors in ObjC parlance).
+class MultiKeywordSelector : public llvm::FoldingSetNode {
+ friend class Selector; // Only Selector can access me.
+ friend class Parser; // Only Parser can instantiate me.
+
unsigned NumArgs;
- void *ActionInfo; // Managed by the ObjC actions module.
-public:
+
// Constructor for keyword selectors.
- SelectorInfo(unsigned nKeys, IdentifierInfo **IIV) {
- assert(nKeys && "SelectorInfo(): not a keyword selector");
+ MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV) {
+ assert((nKeys > 1) && "not a multi-keyword selector");
NumArgs = nKeys;
// Fill in the trailing keyword array.
IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(this+1);
for (unsigned i = 0; i != nKeys; ++i)
KeyInfo[i] = IIV[i];
}
- // Constructor for unary selectors (no colons/arguments).
- SelectorInfo(IdentifierInfo *unarySelector) {
- NumArgs = 0;
- IdentifierInfo **UnaryInfo = reinterpret_cast<IdentifierInfo **>(this+1);
- UnaryInfo[0] = unarySelector;
- }
// Derive the full selector name, placing the result into methodBuffer.
// As a convenience, a pointer to the first character is returned.
// Example usage: llvm::SmallString<128> mbuf; Selector->getName(mbuf);
@@ -199,23 +195,18 @@
unsigned getNumArgs() const { return NumArgs; }
- // Predicates to identify the selector type.
- bool isKeywordSelector() const { return NumArgs > 0; }
- bool isUnarySelector() const { return NumArgs == 0; }
-
- /// getActionInfo/setActionInfo - The actions module is allowed to
- /// associate arbitrary metadata with this selector.
- template<typename T>
- T *getActionInfo() const { return static_cast<T*>(ActionInfo); }
- void setActionInfo(void *T) { ActionInfo = T; }
-
- typedef const IdentifierInfo *const *keyword_iterator;
+ typedef IdentifierInfo *const *keyword_iterator;
keyword_iterator keyword_begin() const {
return reinterpret_cast<keyword_iterator>(this+1);
}
keyword_iterator keyword_end() const {
return keyword_begin()+NumArgs;
}
+ IdentifierInfo *getIdentifierInfoForSlot(unsigned i) {
+ assert((i < NumArgs) && "getIdentifierInfoForSlot(): illegal index");
+ return keyword_begin()[i];
+ }
+public:
static void Profile(llvm::FoldingSetNodeID &ID,
keyword_iterator ArgTys, unsigned NumArgs) {
ID.AddInteger(NumArgs);
@@ -230,6 +221,85 @@
}
};
+class Selector {
+ enum IdentifierInfoFlag {
+ ZeroArg = 0x1,
+ OneArg = 0x2,
+ ArgFlags = ZeroArg|OneArg
+ };
+ uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo.
+
+ Selector(IdentifierInfo *II, unsigned nArgs) {
+ InfoPtr = reinterpret_cast<uintptr_t>(II);
+ if (nArgs == 0)
+ InfoPtr |= ZeroArg;
+ else if (nArgs == 1)
+ InfoPtr |= OneArg;
+ else
+ assert(1 && "nArgs not equal to 0/1");
+ }
+ Selector(MultiKeywordSelector *SI) {
+ InfoPtr = reinterpret_cast<uintptr_t>(SI);
+ }
+ friend class Parser; // only the Parser can create these.
+
+ IdentifierInfo *getAsIdentifierInfo() const {
+ if (InfoPtr & ArgFlags)
+ return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
+ return 0;
+ }
+ MultiKeywordSelector *getAsMultiKeywordSelector() const {
+ if (InfoPtr & ArgFlags)
+ return 0;
+ return reinterpret_cast<MultiKeywordSelector *>(InfoPtr);
+ }
+public:
+ unsigned getIdentifierInfoFlag() const {
+ return InfoPtr & ArgFlags;
+ }
+ /// operator==/!= - Indicate whether the specified selectors are identical.
+ bool operator==(const Selector &RHS) const {
+ return InfoPtr == RHS.InfoPtr;
+ }
+ bool operator!=(const Selector &RHS) const {
+ return InfoPtr != RHS.InfoPtr;
+ }
+ void *getAsOpaquePtr() const {
+ return reinterpret_cast<void*>(InfoPtr);
+ }
+ // Predicates to identify the selector type.
+ bool isKeywordSelector() const {
+ return getIdentifierInfoFlag() != ZeroArg;
+ }
+ bool isUnarySelector() const {
+ return getIdentifierInfoFlag() == ZeroArg;
+ }
+ unsigned getNumArgs() const {
+ unsigned IIF = getIdentifierInfoFlag();
+ if (IIF == ZeroArg)
+ return 0;
+ if (IIF == OneArg)
+ return 1;
+ // We point to a MultiKeywordSelector (pointer doesn't contain any flags).
+ MultiKeywordSelector *SI = reinterpret_cast<MultiKeywordSelector *>(InfoPtr);
+ return SI->getNumArgs();
+ }
+ IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) {
+ IdentifierInfo *II = getAsIdentifierInfo();
+ if (II) {
+ assert(((argIndex == 0) || (argIndex == 1)) && "illegal keyword index");
+ return II;
+ }
+ // We point to a MultiKeywordSelector (pointer doesn't contain any flags).
+ MultiKeywordSelector *SI = reinterpret_cast<MultiKeywordSelector *>(InfoPtr);
+ return SI->getIdentifierInfoForSlot(argIndex);
+ }
+ // Derive the full selector name, placing the result into methodBuffer.
+ // As a convenience, a pointer to the first character is returned.
+ // Example usage: llvm::SmallString<128> mbuf; Selector->getName(mbuf);
+ char *getName(llvm::SmallVectorImpl<char> &methodBuffer);
+};
+
} // end namespace clang
#endif
Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=42452&r1=42451&r2=42452&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Fri Sep 28 17:22:11 2007
@@ -81,7 +81,7 @@
/// flow (in clang::ParseAST()), make it convenient to put here.
/// FIXME: Make sure the lifetime of Identifiers/Selectors *isn't* tied to
/// the lifetime fo the preprocessor.
- llvm::FoldingSet<SelectorInfo> Selectors;
+ llvm::FoldingSet<MultiKeywordSelector> Selectors;
/// PragmaHandlers - This tracks all of the pragmas that the client registered
/// with this preprocessor.
@@ -142,7 +142,7 @@
HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
IdentifierTable &getIdentifierTable() { return Identifiers; }
- llvm::FoldingSet<SelectorInfo> &getSelectorTable() { return Selectors; }
+ llvm::FoldingSet<MultiKeywordSelector> &getSelectorTable() { return Selectors; }
/// SetCommentRetentionState - Control whether or not the preprocessor retains
/// comments in output.
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=42452&r1=42451&r2=42452&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Fri Sep 28 17:22:11 2007
@@ -16,6 +16,7 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TokenKinds.h"
+#include "clang/Lex/IdentifierTable.h" // FIXME: should be in Basic, not Lex.
namespace clang {
// Semantic.
@@ -25,9 +26,8 @@
// Parse.
class Scope;
class Action;
- class SelectorInfo;
+ class Selector;
// Lex.
- class IdentifierInfo; // FIXME: should be in Basic, not Lex.
class Token;
/// Action - As the parser reads the input file and recognizes the productions
@@ -471,7 +471,7 @@
return 0;
}
virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc,
- tok::TokenKind MethodType, TypeTy *ReturnType, SelectorInfo *Sel,
+ tok::TokenKind MethodType, TypeTy *ReturnType, Selector Sel,
// optional arguments. The number of types/arguments is obtained
// from the Sel.getNumArgs().
TypeTy **ArgTypes, IdentifierInfo **ArgNames,
@@ -482,7 +482,7 @@
// ArgExprs is optional - if it is present, the number of expressions
// is obtained from Sel.getNumArgs().
virtual ExprResult ActOnClassMessage(
- IdentifierInfo *receivingClassName, SelectorInfo *Sel,
+ IdentifierInfo *receivingClassName, Selector Sel,
SourceLocation lbrac, SourceLocation rbrac, ExprTy **ArgExprs) {
return 0;
}
@@ -490,7 +490,7 @@
// ArgExprs is optional - if it is present, the number of expressions
// is obtained from Sel.getNumArgs().
virtual ExprResult ActOnInstanceMessage(
- ExprTy *receiver, SelectorInfo *Sel,
+ ExprTy *receiver, Selector Sel,
SourceLocation lbrac, SourceLocation rbrac, ExprTy **ArgExprs) {
return 0;
}
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=42452&r1=42451&r2=42452&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Sep 28 17:22:11 2007
@@ -302,6 +302,9 @@
void ParseObjCInstanceMethodDefinition();
void ParseObjCClassMethodDefinition();
+
+ Selector ObjcGetUnarySelector(IdentifierInfo *unarySel);
+ Selector ObjcGetKeywordSelector(llvm::SmallVectorImpl<IdentifierInfo *> &IIV);
//===--------------------------------------------------------------------===//
// C99 6.5: Expressions.
More information about the cfe-commits
mailing list