[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