- Refactored ObjcKeywordInfo into ObjcKeywordInfo, ObjcKeywordDecl, and ObjcKeywordMessage.
- Removed helper ObjcGetSelectorInfo(), moving the code directly into ObjcBuildMethodDeclaration().
- Many refinements to ParseObjCMessageExpression().
- Add ActOnMessageExpression().

Next step, finish the message actions and (finally) create/instantiate an ObjcMessageExpr AST.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42050 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Parse/ParseObjc.cpp b/Parse/ParseObjc.cpp
index e396f37..d61d621 100644
--- a/Parse/ParseObjc.cpp
+++ b/Parse/ParseObjc.cpp
@@ -486,12 +486,12 @@
     ReturnType = ParseObjCTypeName();
   IdentifierInfo *selIdent = ParseObjCSelector();
 
-  llvm::SmallVector<ObjcKeywordInfo, 12> KeyInfo;
+  llvm::SmallVector<ObjcKeywordDecl, 12> KeyInfo;
   
   if (Tok.getKind() == tok::colon) {
     
     while (1) {
-      ObjcKeywordInfo KeyInfoDecl;
+      ObjcKeywordDecl KeyInfoDecl;
       KeyInfoDecl.SelectorName = selIdent;
       
       // Each iteration parses a single keyword argument.
@@ -514,11 +514,11 @@
       KeyInfoDecl.ArgumentName = Tok.getIdentifierInfo();
       ConsumeToken(); // Eat the identifier.
       
-      // Rather than call out to the actions, try packaging up the info
-      // locally, like we do for Declarator.
-      // FIXME: add Actions.BuildObjCKeyword()
-      
+      // 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)
         break;
@@ -984,28 +984,52 @@
 Parser::ExprResult Parser::ParseObjCMessageExpression() {
   assert(Tok.getKind() == tok::l_square && "'[' expected");
   SourceLocation Loc = ConsumeBracket(); // consume '['
+  IdentifierInfo *ReceiverName = 0;
+  ExprTy *ReceiverExpr = 0;
   // Parse receiver
   if (Tok.getKind() == tok::identifier &&
-      Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope))
+      Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope)) {
+    ReceiverName = Tok.getIdentifierInfo();
     ConsumeToken();
-  else
-    ParseAssignmentExpression();
+  } else {
+    ExprResult Res = ParseAssignmentExpression();
+    if (Res.isInvalid) {
+      SkipUntil(tok::identifier);
+      return Res;
+    }
+    ReceiverExpr = Res.Val;
+  }
   // Parse objc-selector
   IdentifierInfo *selIdent = ParseObjCSelector();
+  llvm::SmallVector<ObjcKeywordMessage, 12> KeyInfo;
   if (Tok.getKind() == tok::colon) {
     while (1) {
       // Each iteration parses a single keyword argument.
+      ObjcKeywordMessage KeyInfoMess;
+      KeyInfoMess.SelectorName = selIdent;
+
       if (Tok.getKind() != tok::colon) {
         Diag(Tok, diag::err_expected_colon);
         SkipUntil(tok::semi);
-        return 0;
+        return true;
       }
-      ConsumeToken(); // Eat the ':'.
+      KeyInfoMess.ColonLoc = ConsumeToken(); // Eat the ':'.
       ///  Parse the expression after ':' 
-      ParseAssignmentExpression();
-      IdentifierInfo *keywordSelector = ParseObjCSelector();
+      ExprResult Res = ParseAssignmentExpression();
+      if (Res.isInvalid) {
+        SkipUntil(tok::identifier);
+        return Res;
+      }
+      // We have a valid expression.
+      KeyInfoMess.KeywordExpr = Res.Val;
       
-      if (!keywordSelector && Tok.getKind() != tok::colon)
+      // Rather than call out to the actions, package up the info locally, 
+      // like we do for Declarator.      
+      KeyInfo.push_back(KeyInfoMess);
+      
+      // Check for another keyword selector.
+      selIdent = ParseObjCSelector();
+      if (!selIdent && Tok.getKind() != tok::colon)
         break;
       // We have a selector or a colon, continue parsing.
     }
@@ -1026,7 +1050,12 @@
     return 0;
   }
   ConsumeBracket(); // consume ']'
-  return 0; // FIXME: return a message expr AST!
+  
+  if (ReceiverName) 
+    return Actions.ActOnMessageExpression(ReceiverName, 
+                                          &KeyInfo[0], KeyInfo.size());
+  return Actions.ActOnMessageExpression(ReceiverExpr, 
+                                          &KeyInfo[0], KeyInfo.size());
 }
 
 Parser::ExprResult Parser::ParseObjCStringLiteral() {