[cfe-commits] r42395 - in /cfe/trunk: AST/Expr.cpp Lex/IdentifierTable.cpp Parse/ParseObjc.cpp Sema/ASTStreamer.cpp Sema/Sema.h Sema/SemaDecl.cpp Sema/SemaExpr.cpp 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/DeclSpec.h

Steve Naroff snaroff at apple.com
Thu Sep 27 07:38:14 PDT 2007


Author: snaroff
Date: Thu Sep 27 09:38:14 2007
New Revision: 42395

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

Add SelectorInfo (similar in spirit to IdentifierInfo). The key difference is SelectorInfo is not string-oriented, it is a unique aggregate of IdentifierInfo's (using a folding set).  SelectorInfo also has a richer API that simplifies the parser/action interface. 3 noteworthy benefits:

#1: It is cleaner. I never "liked" storing keyword selectors (i.e. foo:bar:baz) in the IdentifierTable.

#2: It is more space efficient. Since Cocoa keyword selectors can be quite long, this technique is space saving. For Cocoa.h, pulling the keyword selectors out saves ~180k. The cost of the SelectorInfo data is ~100k. Saves ~80k, or 43%.

#3: It results in many API simplifications. Here are some highlights:

- Removed 3 actions (ActOnKeywordMessage, ActOnUnaryMessage, & one flavor of ObjcBuildMethodDeclaration that was specific to unary messages).
- Removed 3 funky structs from DeclSpec.h (ObjcKeywordMessage, ObjcKeywordDecl, and ObjcKeywordInfo).
- Removed 2 ivars and 2 constructors from ObjCMessageExpr (fyi, this space savings has not been measured).

I am happy with the way it turned out (though it took a bit more hacking than I expected). Given the central role of selectors in ObjC, making sure this is "right" will pay dividends later.

Thanks to Chris for talking this through with me and suggesting this approach. 


Modified:
    cfe/trunk/AST/Expr.cpp
    cfe/trunk/Lex/IdentifierTable.cpp
    cfe/trunk/Parse/ParseObjc.cpp
    cfe/trunk/Sema/ASTStreamer.cpp
    cfe/trunk/Sema/Sema.h
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/Sema/SemaExpr.cpp
    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/DeclSpec.h

Modified: cfe/trunk/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Expr.cpp?rev=42395&r1=42394&r2=42395&view=diff

==============================================================================
--- cfe/trunk/AST/Expr.cpp (original)
+++ cfe/trunk/AST/Expr.cpp Thu Sep 27 09:38:14 2007
@@ -15,8 +15,6 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Lex/IdentifierTable.h"
-// is this bad layering? I (snaroff) don't think so. Want Chris to weigh in.
-#include "clang/Parse/DeclSpec.h" 
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
@@ -870,51 +868,53 @@
   return Result;
 }
 
-// constructor for unary messages.
-ObjCMessageExpr::ObjCMessageExpr(
-  IdentifierInfo *clsName, IdentifierInfo &methName, QualType retType, 
-  SourceLocation LBrac, SourceLocation RBrac)
-  : Expr(ObjCMessageExprClass, retType), Selector(methName) {
-  ClassName = clsName;
-  LBracloc = LBrac;
-  RBracloc = RBrac;
-}
-
-ObjCMessageExpr::ObjCMessageExpr(
-  Expr *fn, IdentifierInfo &methName, QualType retType, 
-  SourceLocation LBrac, SourceLocation RBrac)
-  : Expr(ObjCMessageExprClass, retType), Selector(methName), ClassName(0) {
-  SubExprs = new Expr*[1];
-  SubExprs[RECEIVER] = fn;
-  LBracloc = LBrac;
-  RBracloc = RBrac;
-}
-
-// constructor for keyword messages.
-ObjCMessageExpr::ObjCMessageExpr(
-  Expr *fn, IdentifierInfo &selInfo, ObjcKeywordMessage *keys, unsigned numargs, 
-  QualType retType, SourceLocation LBrac, SourceLocation RBrac)
+// constructor for instance messages.
+ObjCMessageExpr::ObjCMessageExpr(Expr *receiver, SelectorInfo *selInfo,
+                QualType retType, SourceLocation LBrac, SourceLocation RBrac,
+                Expr **ArgExprs)
   : Expr(ObjCMessageExprClass, retType), Selector(selInfo), ClassName(0) {
-  SubExprs = new Expr*[numargs+1];
-  SubExprs[RECEIVER] = fn;
-  for (unsigned i = 0; i != numargs; ++i)
-    SubExprs[i+ARGS_START] = static_cast<Expr *>(keys[i].KeywordExpr);
+  unsigned numArgs = selInfo->getNumArgs();
+  SubExprs = new Expr*[numArgs+1];
+  SubExprs[RECEIVER] = receiver;
+  if (numArgs) {
+    for (unsigned i = 0; i != numArgs; ++i)
+      SubExprs[i+ARGS_START] = static_cast<Expr *>(ArgExprs[i]);
+  }
   LBracloc = LBrac;
   RBracloc = RBrac;
 }
 
-ObjCMessageExpr::ObjCMessageExpr(
-  IdentifierInfo *clsName, IdentifierInfo &selInfo, ObjcKeywordMessage *keys, 
-  unsigned numargs, QualType retType, SourceLocation LBrac, SourceLocation RBrac)
+// constructor for class messages. 
+// FIXME: clsName should be typed to ObjCInterfaceType
+ObjCMessageExpr::ObjCMessageExpr(IdentifierInfo *clsName, SelectorInfo *selInfo,
+                QualType retType, SourceLocation LBrac, SourceLocation RBrac,
+                Expr **ArgExprs)
   : Expr(ObjCMessageExprClass, retType), Selector(selInfo), ClassName(clsName) {
-  SubExprs = new Expr*[numargs+1];
+  unsigned numArgs = selInfo->getNumArgs();
+  SubExprs = new Expr*[numArgs+1];
   SubExprs[RECEIVER] = 0;
-  for (unsigned i = 0; i != numargs; ++i)
-    SubExprs[i+ARGS_START] = static_cast<Expr *>(keys[i].KeywordExpr);
+  if (numArgs) {
+    for (unsigned i = 0; i != numArgs; ++i)
+      SubExprs[i+ARGS_START] = static_cast<Expr *>(ArgExprs[i]);
+  }
   LBracloc = LBrac;
   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
@@ -1090,6 +1090,6 @@
   return reinterpret_cast<Stmt**>(&SubExprs[0]);
 }
 Stmt::child_iterator ObjCMessageExpr::child_end() {
-  return reinterpret_cast<Stmt**>(&SubExprs[NumArgs+ARGS_START]);
+  return reinterpret_cast<Stmt**>(&SubExprs[getNumArgs()+ARGS_START]);
 }
 

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

==============================================================================
--- cfe/trunk/Lex/IdentifierTable.cpp (original)
+++ cfe/trunk/Lex/IdentifierTable.cpp Thu Sep 27 09:38:14 2007
@@ -33,6 +33,28 @@
   return specId ? specId->getObjCKeywordID() : tok::objc_not_keyword;
 }
 
+char *SelectorInfo::getName(llvm::SmallString<128> methodName) {
+  int len=0;
+  methodName[0] = '\0';
+  if (NumArgs) {
+    keyword_iterator KeyIter = keyword_begin();
+    for (unsigned int i = 0; i < NumArgs; i++) {
+      if (KeyIter[i]) {
+        methodName += KeyIter[i]->getName();
+        len += strlen(KeyIter[i]->getName());
+      }
+      methodName += ":";
+      len++;
+    }
+  } else {
+    IdentifierInfo **UnaryInfo = reinterpret_cast<IdentifierInfo **>(this+1);
+    methodName += UnaryInfo[0]->getName();
+    len += strlen(UnaryInfo[0]->getName());
+  }
+  methodName[len] = '\0';
+  return &methodName[0];
+}
+
 //===----------------------------------------------------------------------===//
 // IdentifierInfo Implementation
 //===----------------------------------------------------------------------===//
@@ -209,3 +231,4 @@
   // Compute statistics about the memory allocated for identifiers.
   HashTable.getAllocator().PrintStats();
 }
+

Modified: cfe/trunk/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseObjc.cpp?rev=42395&r1=42394&r2=42395&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Thu Sep 27 09:38:14 2007
@@ -463,6 +463,52 @@
   return Ty;
 }
 
+static SelectorInfo *ObjcGetUnarySelectorInfo(
+  IdentifierInfo *unarySel,
+  llvm::FoldingSet<SelectorInfo> &SelTab) 
+{
+  // 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;
+}
+
+static SelectorInfo *ObjcGetKeywordSelectorInfo(
+  llvm::SmallVectorImpl<IdentifierInfo *> &IIV,
+  llvm::FoldingSet<SelectorInfo> &SelTab) 
+{  
+  // Unique selector, to guarantee there is one per name.
+  llvm::FoldingSetNodeID ID;
+  SelectorInfo::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
+  // 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]);
+  SelTab.InsertNode(SI, InsertPos);
+  return SI;
+}
+
 ///   objc-method-decl:
 ///     objc-selector
 ///     objc-keyword-selector objc-parmlist[opt]
@@ -491,9 +537,10 @@
 ///   objc-keyword-attributes:         [OBJC2]
 ///     __attribute__((unused))
 ///
-Parser::DeclTy *Parser::ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation mLoc,
-					    tok::ObjCKeywordKind MethodImplKind) {
-
+Parser::DeclTy *Parser::ParseObjCMethodDecl(tok::TokenKind mType, 
+                                            SourceLocation mLoc,
+					    tok::ObjCKeywordKind MethodImplKind)
+{
   TypeTy *ReturnType = 0;
   AttributeList *methodAttrs = 0;
   
@@ -502,38 +549,39 @@
     ReturnType = ParseObjCTypeName();
   IdentifierInfo *selIdent = ParseObjCSelector();
 
-  llvm::SmallVector<ObjcKeywordDecl, 12> KeyInfo;
-  
+  llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
+  llvm::SmallVector<Action::TypeTy *, 12> KeyTypes;
+  llvm::SmallVector<IdentifierInfo *, 12> ArgNames;
+    
   if (Tok.getKind() == tok::colon) {
+    Action::TypeTy *TypeInfo;
     
     while (1) {
-      ObjcKeywordDecl KeyInfoDecl;
-      KeyInfoDecl.SelectorName = selIdent;
+      KeyIdents.push_back(selIdent);
       
       // Each iteration parses a single keyword argument.
       if (Tok.getKind() != tok::colon) {
         Diag(Tok, diag::err_expected_colon);
         break;
       }
-      KeyInfoDecl.ColonLoc = ConsumeToken(); // Eat the ':'.
+      ConsumeToken(); // Eat the ':'.
       if (Tok.getKind() == tok::l_paren) // Parse the argument type.
-        KeyInfoDecl.TypeInfo = ParseObjCTypeName();
-
+        TypeInfo = ParseObjCTypeName();
+      else
+        TypeInfo = 0;
+      KeyTypes.push_back(TypeInfo);
+      
       // If attributes exist before the argument name, parse them.
       if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
-        KeyInfoDecl.AttrList = ParseAttributes();
+        ParseAttributes(); // FIXME: pass attributes through.
 
       if (Tok.getKind() != tok::identifier) {
         Diag(Tok, diag::err_expected_ident); // missing argument name.
         break;
       }
-      KeyInfoDecl.ArgumentName = Tok.getIdentifierInfo();
+      ArgNames.push_back(Tok.getIdentifierInfo());
       ConsumeToken(); // Eat the identifier.
       
-      // Rather than call out to the actions, package up the info locally, 
-      // like we do for Declarator.      
-      KeyInfo.push_back(KeyInfoDecl);
-      
       // Check for another keyword selector.
       selIdent = ParseObjCSelector();
       if (!selIdent && Tok.getKind() != tok::colon)
@@ -558,9 +606,11 @@
     // If attributes exist after the method, parse them.
     if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute) 
       methodAttrs = ParseAttributes();
-    return Actions.ObjcBuildMethodDeclaration(mLoc, mType, 
-                                              ReturnType, 
-                                              &KeyInfo[0], KeyInfo.size(), 
+      
+    SelectorInfo *SI = ObjcGetKeywordSelectorInfo(KeyIdents, 
+                                                  PP.getSelectorTable());
+    return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, SI, 
+                                              &KeyTypes[0], &ArgNames[0],
 					      methodAttrs, MethodImplKind);
   } else if (!selIdent) {
     Diag(Tok, diag::err_expected_ident); // missing selector name.
@@ -569,9 +619,9 @@
   if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute) 
     methodAttrs = ParseAttributes();
 
-  return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, 
-                                            selIdent, methodAttrs,
-					    MethodImplKind);
+  SelectorInfo *SI = ObjcGetUnarySelectorInfo(selIdent, PP.getSelectorTable());
+  return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, SI, 
+                                            0, 0, methodAttrs, MethodImplKind);
 }
 
 ///   objc-protocol-refs:
@@ -1107,19 +1157,21 @@
   }
   // Parse objc-selector
   IdentifierInfo *selIdent = ParseObjCSelector();
-  llvm::SmallVector<ObjcKeywordMessage, 12> KeyInfo;
+
+  llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
+  llvm::SmallVector<Action::ExprTy *, 12> KeyExprs;
+
   if (Tok.getKind() == tok::colon) {
     while (1) {
       // Each iteration parses a single keyword argument.
-      ObjcKeywordMessage KeyInfoMess;
-      KeyInfoMess.SelectorName = selIdent;
+      KeyIdents.push_back(selIdent);
 
       if (Tok.getKind() != tok::colon) {
         Diag(Tok, diag::err_expected_colon);
         SkipUntil(tok::semi);
         return true;
       }
-      KeyInfoMess.ColonLoc = ConsumeToken(); // Eat the ':'.
+      ConsumeToken(); // Eat the ':'.
       ///  Parse the expression after ':' 
       ExprResult Res = ParseAssignmentExpression();
       if (Res.isInvalid) {
@@ -1127,11 +1179,7 @@
         return Res;
       }
       // We have a valid expression.
-      KeyInfoMess.KeywordExpr = Res.Val;
-      
-      // Rather than call out to the actions, package up the info locally, 
-      // like we do for Declarator.      
-      KeyInfo.push_back(KeyInfoMess);
+      KeyExprs.push_back(Res.Val);
       
       // Check for another keyword selector.
       selIdent = ParseObjCSelector();
@@ -1157,20 +1205,22 @@
   }
   SourceLocation RBracloc = ConsumeBracket(); // consume ']'
   
-  if (KeyInfo.size()) {
+  if (KeyIdents.size()) {
+    SelectorInfo *SI = ObjcGetKeywordSelectorInfo(KeyIdents, 
+                                                  PP.getSelectorTable());
     // We've just parsed a keyword message.
     if (ReceiverName) 
-      return Actions.ActOnKeywordMessage(ReceiverName, 
-                                         &KeyInfo[0], KeyInfo.size(),
-                                         LBracloc, RBracloc);
-    return Actions.ActOnKeywordMessage(ReceiverExpr, 
-                                       &KeyInfo[0], KeyInfo.size(),
-                                       LBracloc, RBracloc);
+      return Actions.ActOnClassMessage(ReceiverName, SI, LBracloc, RBracloc,
+                                       &KeyExprs[0]);
+    return Actions.ActOnInstanceMessage(ReceiverExpr, SI, LBracloc, RBracloc,
+                                        &KeyExprs[0]);
   }
+  SelectorInfo *SI = ObjcGetUnarySelectorInfo(selIdent, PP.getSelectorTable());
+
   // We've just parsed a unary message (a message with no arguments).
   if (ReceiverName) 
-    return Actions.ActOnUnaryMessage(ReceiverName, selIdent, LBracloc,RBracloc);
-  return Actions.ActOnUnaryMessage(ReceiverExpr, selIdent, LBracloc,RBracloc);
+    return Actions.ActOnClassMessage(ReceiverName, SI, LBracloc, RBracloc, 0);
+  return Actions.ActOnInstanceMessage(ReceiverExpr, SI, LBracloc, RBracloc, 0);
 }
 
 Parser::ExprResult Parser::ParseObjCStringLiteral() {

Modified: cfe/trunk/Sema/ASTStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/ASTStreamer.cpp?rev=42395&r1=42394&r2=42395&view=diff

==============================================================================
--- cfe/trunk/Sema/ASTStreamer.cpp (original)
+++ cfe/trunk/Sema/ASTStreamer.cpp Thu Sep 27 09:38:14 2007
@@ -98,7 +98,7 @@
   }
   
   ASTContext Context(PP.getSourceManager(), PP.getTargetInfo(),
-                     PP.getIdentifierTable());
+                     PP.getIdentifierTable(), PP.getSelectorTable());
   
   ASTStreamer Streamer(PP, Context, MainFileID);
   

Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=42395&r1=42394&r2=42395&view=diff

==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Thu Sep 27 09:38:14 2007
@@ -391,32 +391,25 @@
                                           DeclTy **Fields, unsigned NumFields);
   
   virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc, 
-	            tok::TokenKind MethodType, TypeTy *ReturnType,
-     		    ObjcKeywordDecl *Keywords, unsigned NumKeywords, 
-     		    AttributeList *AttrList,
-		    tok::ObjCKeywordKind MethodImplKind);
-  virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc, 
- 	     	    tok::TokenKind MethodType, TypeTy *ReturnType,
-     		    IdentifierInfo *SelectorName, AttributeList *AttrList,
-		    tok::ObjCKeywordKind MethodImplKind);
+    tok::TokenKind MethodType, TypeTy *ReturnType, SelectorInfo *Sel,
+    // optional arguments. The number of types/arguments is obtained
+    // from the Sel.getNumArgs().
+    TypeTy **ArgTypes, IdentifierInfo **ArgNames,
+    AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind);
                     
-  // This actions handles keyword message to classes.
-  virtual ExprResult ActOnKeywordMessage(
-    IdentifierInfo *receivingClassName, 
-    ObjcKeywordMessage *Keywords, unsigned NumKeywords,
-    SourceLocation lbrac, SourceLocation rbrac);
-  // This action handles keyword messages to instances.
-  virtual ExprResult ActOnKeywordMessage(ExprTy *receiver, 
-    ObjcKeywordMessage *Keywords, unsigned NumKeywords,
-    SourceLocation lbrac, SourceLocation rbrac);
-  // This actions handles unary message to classes.
-  virtual ExprResult ActOnUnaryMessage(
-    IdentifierInfo *receivingClassName, IdentifierInfo *selName,
-    SourceLocation lbrac, SourceLocation rbrac);
-  // This action handles unary messages to instances.
-  virtual ExprResult ActOnUnaryMessage(
-    ExprTy *receiver, IdentifierInfo *sName,
-    SourceLocation lbrac, SourceLocation rbrac);
+  // ActOnClassMessage - 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 ActOnClassMessage(
+    IdentifierInfo *receivingClassName, SelectorInfo *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,
+    SourceLocation lbrac, SourceLocation rbrac, ExprTy **ArgExprs);
 private:
   // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
   // functions and arrays to their respective pointers (C99 6.3.2.1). 

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

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Thu Sep 27 09:38:14 2007
@@ -1567,65 +1567,25 @@
 }
 
 Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc, 
-                      tok::TokenKind MethodType, TypeTy *ReturnType,
-                      ObjcKeywordDecl *Keywords, unsigned NumKeywords,
-                      AttributeList *AttrList,
-		      tok::ObjCKeywordKind MethodDeclKind) {
-  assert(NumKeywords && "Selector must be specified");
-
-  // Derive the selector name from the keyword declarations.
-  int len=0;
-  for (unsigned int i = 0; i < NumKeywords; i++) {
-    if (Keywords[i].SelectorName)
-      len += strlen(Keywords[i].SelectorName->getName());
-    len++;
-  }
-  llvm::SmallString<128> methodName;
-  methodName[0] = '\0';
-  for (unsigned int i = 0; i < NumKeywords; i++) {
-    if (Keywords[i].SelectorName)
-      methodName += Keywords[i].SelectorName->getName();
-    methodName += ":";
-  }
-  methodName[len] = '\0';
-  IdentifierInfo &SelName = Context.Idents.get(&methodName[0], 
-                                               &methodName[0]+len);
+    tok::TokenKind MethodType, TypeTy *ReturnType, SelectorInfo *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 < NumKeywords; i++) {
-    ObjcKeywordDecl *arg = &Keywords[i];
+  for (unsigned i = 0; i < Sel->getNumArgs(); i++) {
     // FIXME: arg->AttrList must be stored too!
-    ParmVarDecl* Param = new ParmVarDecl(arg->ColonLoc, arg->ArgumentName, 
-					 QualType::getFromOpaquePtr(arg->TypeInfo), 
+    ParmVarDecl* Param = new ParmVarDecl(SourceLocation(/*FIXME*/), ArgNames[i], 
+					 QualType::getFromOpaquePtr(ArgTypes[i]), 
 					 VarDecl::None, 0);
-    // FIXME: 'InvalidType' does not get set by caller yet.
-    if (arg->InvalidType)
-      Param->setInvalidDecl();
     Params.push_back(Param);
   }
   QualType resultDeclType = QualType::getFromOpaquePtr(ReturnType);
-  ObjcMethodDecl* ObjcMethod =  new ObjcMethodDecl(MethodLoc, 
-				      SelName, resultDeclType,
-		      		      0, -1, AttrList, MethodType == tok::minus);
-  ObjcMethod->setMethodParams(&Params[0], NumKeywords);
-  if (MethodDeclKind == tok::objc_optional)
-    ObjcMethod->setDeclImplementation(ObjcMethodDecl::Optional);
-  else
-    ObjcMethod->setDeclImplementation(ObjcMethodDecl::Required);
-  return ObjcMethod;
-}
-
-Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc,  
-                      tok::TokenKind MethodType, TypeTy *ReturnType,
-                      IdentifierInfo *SelectorName, AttributeList *AttrList,
-		      tok::ObjCKeywordKind MethodDeclKind) {
-  const char *methodName = SelectorName->getName();
-  IdentifierInfo &SelName = Context.Idents.get(methodName, 
-                                              methodName+strlen(methodName));
-  QualType resultDeclType = QualType::getFromOpaquePtr(ReturnType);
-  ObjcMethodDecl* ObjcMethod = new ObjcMethodDecl(MethodLoc, 
-			             SelName, resultDeclType, 0, -1,
-                                     AttrList, MethodType == tok::minus);
+  ObjcMethodDecl* ObjcMethod =  new ObjcMethodDecl(MethodLoc, Sel,
+                                      resultDeclType, 0, -1, AttrList, 
+                                      MethodType == tok::minus);
+  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=42395&r1=42394&r2=42395&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Thu Sep 27 09:38:14 2007
@@ -1871,76 +1871,31 @@
   return new ObjCEncodeExpr(t, EncodedType, AtLoc, RParenLoc);
 }
 
-static IdentifierInfo &DeriveSelector(ObjcKeywordMessage *Keywords, 
-                                    unsigned NumKeywords,
-                                    ASTContext &Context) {
-  // Derive the selector name from the keyword declarations.
-  int len=0;
-  for (unsigned int i = 0; i < NumKeywords; i++) {
-    if (Keywords[i].SelectorName)
-      len += strlen(Keywords[i].SelectorName->getName());
-    len++;
-  }
-  llvm::SmallString<128> methodName;
-  methodName[0] = '\0';
-  for (unsigned int i = 0; i < NumKeywords; i++) {
-    if (Keywords[i].SelectorName)
-      methodName += Keywords[i].SelectorName->getName();
-    methodName += ":";
-  }
-  methodName[len] = '\0';
-  return Context.Idents.get(&methodName[0], &methodName[0]+len);
-}
-
-// This actions handles keyword message to classes.
-Sema::ExprResult Sema::ActOnKeywordMessage(
-  IdentifierInfo *receivingClassName, 
-  ObjcKeywordMessage *Keywords, unsigned NumKeywords,
-  SourceLocation lbrac, SourceLocation rbrac)
+// ActOnClassMessage - used for both unary and keyword messages.
+// ArgExprs is optional - if it is present, the number of expressions
+// is obtained from Sel.getNumArgs().
+Sema::ExprResult Sema::ActOnClassMessage(
+  IdentifierInfo *receivingClassName, SelectorInfo *Sel,
+  SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args)
 {
-  IdentifierInfo &SelName = DeriveSelector(Keywords, NumKeywords, Context);
   assert(receivingClassName && "missing receiver class name");
 
-  return new ObjCMessageExpr(receivingClassName, SelName, Keywords, NumKeywords, 
-                             Context.IntTy/*FIXME*/, lbrac, rbrac);
-}
-
-// This action handles keyword messages to instances.
-Sema::ExprResult Sema::ActOnKeywordMessage(
-  ExprTy *receiver, ObjcKeywordMessage *Keywords, unsigned NumKeywords,
-  SourceLocation lbrac, SourceLocation rbrac) {
-  IdentifierInfo &SelName = DeriveSelector(Keywords, NumKeywords, Context);
-  assert(receiver && "missing receiver expression");
-  
-  Expr *RExpr = static_cast<Expr *>(receiver);
-  return new ObjCMessageExpr(RExpr, SelName, Keywords, NumKeywords, 
-                             Context.IntTy/*FIXME*/, lbrac, rbrac);
-}
-    
-// This actions handles unary message to classes.
-Sema::ExprResult Sema::ActOnUnaryMessage(
-  IdentifierInfo *receivingClassName, IdentifierInfo *selName,
-  SourceLocation lbrac, SourceLocation rbrac) {
-  assert(receivingClassName && "missing receiver class name");
-  
-  // FIXME: this should be passed in...
-  IdentifierInfo &SName = Context.Idents.get(
-           selName->getName(), selName->getName()+strlen(selName->getName()));
-  return new ObjCMessageExpr(receivingClassName, SName,
-                             Context.IntTy/*FIXME*/, lbrac, rbrac);
+  Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
+  return new ObjCMessageExpr(receivingClassName, Sel, 
+                             Context.IntTy/*FIXME*/, lbrac, rbrac, ArgExprs);
 }
 
-// This action handles unary messages to instances.
-Sema::ExprResult Sema::ActOnUnaryMessage(
-  ExprTy *receiver, IdentifierInfo *selName,
-  SourceLocation lbrac, SourceLocation rbrac) {
+// ActOnInstanceMessage - used for both unary and keyword messages.
+// ArgExprs is optional - if it is present, the number of expressions
+// is obtained from Sel.getNumArgs().
+Sema::ExprResult Sema::ActOnInstanceMessage(
+  ExprTy *receiver, SelectorInfo *Sel,
+  SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args) 
+{
   assert(receiver && "missing receiver expression");
   
   Expr *RExpr = static_cast<Expr *>(receiver);
-  // FIXME: this should be passed in...
-  IdentifierInfo &SName = Context.Idents.get(
-           selName->getName(), selName->getName()+strlen(selName->getName()));
-  return new ObjCMessageExpr(RExpr, SName,
-                             Context.IntTy/*FIXME*/, lbrac, rbrac);
+  Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
+  return new ObjCMessageExpr(RExpr, Sel,
+                             Context.IntTy/*FIXME*/, lbrac, rbrac, ArgExprs);
 }
-

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

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Sep 27 09:38:14 2007
@@ -14,17 +14,19 @@
 #ifndef LLVM_CLANG_AST_ASTCONTEXT_H
 #define LLVM_CLANG_AST_ASTCONTEXT_H
 
+#include "clang/Lex/IdentifierTable.h" // FIXME: Move IdentifierTable to Basic
 #include "clang/AST/Builtins.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/Type.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/FoldingSet.h"
 #include <vector>
 
 namespace clang {
   class TargetInfo;
-  
+
 /// 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.
 class ASTContext {
@@ -46,6 +48,7 @@
   SourceManager &SourceMgr;
   TargetInfo &Target;
   IdentifierTable &Idents;
+  llvm::FoldingSet<SelectorInfo> &Selectors;
   Builtin::Context BuiltinInfo;
 
   // Builtin Types.
@@ -58,8 +61,10 @@
   QualType FloatTy, DoubleTy, LongDoubleTy;
   QualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
   
-  ASTContext(SourceManager &SM, TargetInfo &t, IdentifierTable &idents) : 
-    CFConstantStringTypeDecl(0), SourceMgr(SM), Target(t), Idents(idents) {
+  ASTContext(SourceManager &SM, TargetInfo &t, IdentifierTable &idents,
+             llvm::FoldingSet<SelectorInfo> &sels) : 
+    CFConstantStringTypeDecl(0), SourceMgr(SM), Target(t), 
+    Idents(idents), Selectors(sels) {
     InitBuiltinTypes();
     BuiltinInfo.InitializeBuiltins(idents, Target);
   }    

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

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Thu Sep 27 09:38:14 2007
@@ -20,6 +20,7 @@
 
 namespace clang {
 class IdentifierInfo;
+class SelectorInfo;
 class Expr;
 class Stmt;
 class FunctionDecl;
@@ -665,7 +666,7 @@
   enum ImplementationControl { None, Required, Optional };
 private:
   // A unigue name for this method.
-  IdentifierInfo &Selector;
+  SelectorInfo *Selector;
   
   // Type of this method.
   QualType MethodDeclType;
@@ -683,14 +684,14 @@
   ImplementationControl DeclImplementation : 2;
 
 public:
-  ObjcMethodDecl(SourceLocation L, IdentifierInfo &SelId, QualType T,
+  ObjcMethodDecl(SourceLocation L, SelectorInfo *SelInfo, QualType T,
 		 ParmVarDecl **paramInfo = 0, int numParams=-1,
 		 AttributeList *M = 0, bool isInstance = true, 
 		 Decl *PrevDecl = 0)
-    : Decl(ObjcMethod), Selector(SelId), MethodDeclType(T), 
+    : Decl(ObjcMethod), Selector(SelInfo), MethodDeclType(T), 
       ParamInfo(paramInfo), NumMethodParams(numParams),
       MethodAttrs(M), IsInstance(isInstance) {}
-
+#if 0
   ObjcMethodDecl(Kind DK, SourceLocation L, IdentifierInfo &SelId, QualType T,
 		 ParmVarDecl **paramInfo = 0, int numParams=-1,
 		 AttributeList *M = 0, bool isInstance = true, 
@@ -698,7 +699,7 @@
     : Decl(DK), Selector(SelId), MethodDeclType(T), 
       ParamInfo(paramInfo), NumMethodParams(numParams),
       MethodAttrs(M), IsInstance(isInstance) {}
-
+#endif
   virtual ~ObjcMethodDecl();
   QualType getMethodType() const { return MethodDeclType; }
   unsigned getNumMethodParams() const { return NumMethodParams; }

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

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Thu Sep 27 09:38:14 2007
@@ -22,9 +22,9 @@
 
 namespace clang {
   class IdentifierInfo;
+  class SelectorInfo;
   class Decl;
   class ASTContext;
-  struct ObjcKeywordMessage;
   
 /// Expr - This represents one expression.  Note that Expr's are subclasses of
 /// Stmt.  This allows an expression to be transparently used any place a Stmt
@@ -1073,36 +1073,25 @@
 
 class ObjCMessageExpr : public Expr {
   enum { RECEIVER=0, ARGS_START=1 };
-  
-  // The following 3 slots are only used for keyword messages.
-  // Adding a subclass could save us some space. For now, we keep it simple.
+
   Expr **SubExprs;
-  unsigned NumArgs;
   
   // A unigue name for this message.
-  IdentifierInfo &Selector;
-  
-  IdentifierInfo **KeyIdents;
+  SelectorInfo *Selector;
   
-  IdentifierInfo *ClassName;
+  IdentifierInfo *ClassName; // optional - 0 for instance messages.
   
   SourceLocation LBracloc, RBracloc;
 public:
-  // constructor for unary messages. 
+  // constructor for class messages. 
   // FIXME: clsName should be typed to ObjCInterfaceType
-  ObjCMessageExpr(IdentifierInfo *clsName, IdentifierInfo &selInfo,
-                  QualType retType, SourceLocation LBrac, SourceLocation RBrac);
-  ObjCMessageExpr(Expr *receiver, IdentifierInfo &selInfo,
-                  QualType retType, SourceLocation LBrac, SourceLocation RBrac);
-                  
-  // constructor for keyword messages.
-  // FIXME: clsName should be typed to ObjCInterfaceType
-  ObjCMessageExpr(IdentifierInfo *clsName, IdentifierInfo &selInfo,
-                  ObjcKeywordMessage *keys, unsigned numargs, QualType retType, 
-                  SourceLocation LBrac, SourceLocation RBrac);
-  ObjCMessageExpr(Expr *receiver, IdentifierInfo &selInfo,
-                  ObjcKeywordMessage *keys, unsigned numargs, QualType retType, 
-                  SourceLocation LBrac, SourceLocation RBrac);
+  ObjCMessageExpr(IdentifierInfo *clsName, SelectorInfo *selInfo,
+                  QualType retType, SourceLocation LBrac, SourceLocation RBrac,
+                  Expr **ArgExprs);
+  // constructor for instance messages.
+  ObjCMessageExpr(Expr *receiver, SelectorInfo *selInfo,
+                  QualType retType, SourceLocation LBrac, SourceLocation RBrac,
+                  Expr **ArgExprs);
   ~ObjCMessageExpr() {
     delete [] SubExprs;
   }
@@ -1112,17 +1101,12 @@
   
   /// getNumArgs - Return the number of actual arguments to this call.
   ///
-  unsigned getNumArgs() const { return NumArgs; }
+  unsigned getNumArgs() const;
   
   /// getArg - Return the specified argument.
-  Expr *getArg(unsigned Arg) {
-    assert(Arg < NumArgs && "Arg access out of range!");
-    return SubExprs[Arg+ARGS_START];
-  }
-  const Expr *getArg(unsigned Arg) const {
-    assert(Arg < NumArgs && "Arg access out of range!");
-    return SubExprs[Arg+ARGS_START];
-  }
+  Expr *getArg(unsigned Arg);
+  const Expr *getArg(unsigned Arg) const;
+
   SourceRange getSourceRange() const { return SourceRange(LBracloc, RBracloc); }
 
   static bool classof(const Stmt *T) {

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

==============================================================================
--- cfe/trunk/include/clang/Lex/IdentifierTable.h (original)
+++ cfe/trunk/include/clang/Lex/IdentifierTable.h Thu Sep 27 09:38:14 2007
@@ -14,8 +14,12 @@
 #ifndef LLVM_CLANG_LEX_IDENTIFIERTABLE_H
 #define LLVM_CLANG_LEX_IDENTIFIERTABLE_H
 
+// FIXME: Move this header header/module to the "Basic" library. Unlike Lex,
+// this data is long-lived.
 #include "clang/Basic/TokenKinds.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/SmallString.h"
 #include <string> 
 #include <cassert> 
 
@@ -166,6 +170,65 @@
   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 {
+  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");
+    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.
+  char *getName(llvm::SmallString<128> methodBuffer);
+
+  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;
+  keyword_iterator keyword_begin() const {
+    return reinterpret_cast<keyword_iterator>(this+1);
+  }
+  keyword_iterator keyword_end() const { 
+    return keyword_begin()+NumArgs; 
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, 
+                      keyword_iterator ArgTys, unsigned NumArgs) {
+    ID.AddInteger(NumArgs);
+    if (NumArgs) { // handle keyword selector.
+      for (unsigned i = 0; i != NumArgs; ++i)
+        ID.AddPointer(ArgTys[i]);
+    } else // handle unary selector.
+      ID.AddPointer(ArgTys[0]);
+  }
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, keyword_begin(), NumArgs);
+  }
+};
+
 }  // 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=42395&r1=42394&r2=42395&view=diff

==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Thu Sep 27 09:38:14 2007
@@ -18,6 +18,7 @@
 #include "clang/Lex/Lexer.h"
 #include "clang/Lex/MacroExpander.h"
 #include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/FoldingSet.h"
 
 namespace clang {
   
@@ -73,6 +74,15 @@
   /// the program, including program keywords.
   IdentifierTable Identifiers;
   
+  /// Selectors - This table contains all the selectors in the program. Unlike
+  /// IdentifierTable above, this table *isn't* populated by the preprocessor.
+  /// It is declared/instantiated here because it's role/lifetime is 
+  /// conceptually similar the IdentifierTable. In addition, the current control
+  /// 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;
+  
   /// PragmaHandlers - This tracks all of the pragmas that the client registered
   /// with this preprocessor.
   PragmaNamespace *PragmaHandlers;
@@ -132,7 +142,8 @@
   HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
 
   IdentifierTable &getIdentifierTable() { return Identifiers; }
-
+  llvm::FoldingSet<SelectorInfo> &getSelectorTable() { return Selectors; }
+  
   /// SetCommentRetentionState - Control whether or not the preprocessor retains
   /// comments in output.
   void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) {

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=42395&r1=42394&r2=42395&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Thu Sep 27 09:38:14 2007
@@ -21,14 +21,13 @@
   // Semantic.
   class DeclSpec;
   class Declarator;
-  struct ObjcKeywordDecl;
-  struct ObjcKeywordMessage;
   class AttributeList;
   // Parse.
   class Scope;
   class Action;
+  class SelectorInfo;
   // Lex.
-  class IdentifierInfo;
+  class IdentifierInfo; // FIXME: should be in Basic, not Lex.
   class Token;
 
 /// Action - As the parser reads the input file and recognizes the productions
@@ -472,41 +471,27 @@
     return 0;
   }
   virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc, 
-    tok::TokenKind MethodType, TypeTy *ReturnType,
-    ObjcKeywordDecl *Keywords, unsigned NumKeywords, 
-    AttributeList *AttrList,
-    tok::ObjCKeywordKind MethodImplKind) {
-    return 0;
-  }
-  virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc, 
-    tok::TokenKind MethodType, TypeTy *ReturnType,
-    IdentifierInfo *SelectorName, AttributeList *AttrList,
-    tok::ObjCKeywordKind MethodImplKind) {
-    return 0;
-  }
-  // This actions handles keyword message to classes.
-  virtual ExprResult ActOnKeywordMessage(
-    IdentifierInfo *receivingClassName, 
-    ObjcKeywordMessage *Keywords, unsigned NumKeywords,
-    SourceLocation lbrac, SourceLocation rbrac) {
-    return 0;
-  }
-  // This action handles keyword messages to instances.
-  virtual ExprResult ActOnKeywordMessage(ExprTy *receiver, 
-    ObjcKeywordMessage *Keywords, unsigned NumKeywords,
-    SourceLocation lbrac, SourceLocation rbrac) {
-    return 0;
-  }
-  // This actions handles unary message to classes.
-  virtual ExprResult ActOnUnaryMessage(
-    IdentifierInfo *receivingClassName, IdentifierInfo *selName,
-    SourceLocation lbrac, SourceLocation rbrac) {
-    return 0;
-  }
-  // This action handles unary messages to instances.
-  virtual ExprResult ActOnUnaryMessage(
-    ExprTy *receiver, IdentifierInfo *sName,
-    SourceLocation lbrac, SourceLocation rbrac) {
+    tok::TokenKind MethodType, TypeTy *ReturnType, SelectorInfo *Sel,
+    // optional arguments. The number of types/arguments is obtained
+    // from the Sel.getNumArgs().
+    TypeTy **ArgTypes, IdentifierInfo **ArgNames,
+    AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind) {
+    return 0;
+  }
+  // ActOnClassMessage - 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 ActOnClassMessage(
+    IdentifierInfo *receivingClassName, SelectorInfo *Sel,
+    SourceLocation lbrac, SourceLocation rbrac, ExprTy **ArgExprs) {
+    return 0;
+  }
+  // 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,
+    SourceLocation lbrac, SourceLocation rbrac, ExprTy **ArgExprs) {
     return 0;
   }
   virtual DeclTy *ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc,

Modified: cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=42395&r1=42394&r2=42395&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Parse/DeclSpec.h Thu Sep 27 09:38:14 2007
@@ -562,26 +562,6 @@
   bool getInvalidType() { return InvalidType; }
 };
 
-/// ObjCKeyword* - The following 3 small value structures capture keyword
-/// information passed from the parser to the actions. Like Declarator above,
-/// instances of these structures are transient objects that live on the stack.
-struct ObjcKeywordInfo {
-  IdentifierInfo *SelectorName; // optional
-  SourceLocation SelectorLoc;
-  SourceLocation ColonLoc;
-};
-
-struct ObjcKeywordDecl : ObjcKeywordInfo {
-  Action::TypeTy *TypeInfo; // optional
-  IdentifierInfo *ArgumentName;
-  AttributeList *AttrList;
-  bool InvalidType;  // FIXME: is this used?
-};
-  
-struct ObjcKeywordMessage : ObjcKeywordInfo {
-  Action::ExprTy *KeywordExpr;
-};
-
 } // end namespace clang
 
 #endif





More information about the cfe-commits mailing list