Rework the Parser-Sema interaction for Objective-C message
sends. Major changes include:

  - Expanded the interface from two actions (ActOnInstanceMessage,
    ActOnClassMessage), where ActOnClassMessage also handled sends to
    "super" by checking whether the identifier was "super", to three
    actions (ActOnInstanceMessage, ActOnClassMessage,
    ActOnSuperMessage). Code completion has the same changes.
  - The parser now resolves the type to which we are sending a class
    message, so ActOnClassMessage now accepts a TypeTy* (rather than
    an IdentifierInfo *). This opens the door to more interesting
    types (for Objective-C++ support).
  - Split ActOnInstanceMessage and ActOnClassMessage into parser
    action functions (with their original names) and semantic
    functions (BuildInstanceMessage and BuildClassMessage,
    respectively). At present, this split is onyl used by
    ActOnSuperMessage, which decides which kind of super message it
    has and forwards to the appropriate Build*Message. In the future,
    Build*Message will be used by template instantiation.
  - Use getObjCMessageKind() within the disambiguation of Objective-C
    message sends vs. array designators.

Two notes about substandard bits in this patch:
  - There is some redundancy in the code in ParseObjCMessageExpr and
  ParseInitializerWithPotentialDesignator; this will be addressed
  shortly by centralizing the mapping from identifiers to type names
  for the message receiver.
  - There is some #if 0'd code that won't likely ever be used---it
  handles the use of 'super' in methods whose class does not have a
  superclass---but could be used to model GCC's behavior more
  closely. This code will die in my next check-in, but I want it in
  Subversion.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102021 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseInit.cpp b/lib/Parse/ParseInit.cpp
index 123908d..b0735b3 100644
--- a/lib/Parse/ParseInit.cpp
+++ b/lib/Parse/ParseInit.cpp
@@ -129,13 +129,16 @@
     // send to 'super', parse this as a message send expression.
     if (getLang().ObjC1 && Tok.is(tok::identifier)) {
       IdentifierInfo *II = Tok.getIdentifierInfo();
-
+      SourceLocation IILoc = Tok.getLocation();
       // Three cases. This is a message send to a type: [type foo]
       // This is a message send to super:  [super foo]
       // This is a message sent to an expr:  [super.bar foo]
-      if (Actions.getTypeName(*II, Tok.getLocation(), CurScope) ||
-          (II == Ident_super && GetLookAheadToken(1).isNot(tok::period) &&
-           CurScope->isInObjcMethodScope())) {
+      switch (Action::ObjCMessageKind Kind
+                = Actions.getObjCMessageKind(CurScope, II, IILoc, 
+                                             II == Ident_super,
+                                             NextToken().is(tok::period))) {
+      case Action::ObjCSuperMessage:
+      case Action::ObjCClassMessage: {
         // If we have exactly one array designator, this used the GNU
         // 'designation: array-designator' extension, otherwise there should be no
         // designators at all!
@@ -146,9 +149,47 @@
         else if (Desig.getNumDesignators() > 0)
           Diag(Tok, diag::err_expected_equal_designator);
 
-        SourceLocation NameLoc = ConsumeToken();
-        return ParseAssignmentExprWithObjCMessageExprStart(
-                                       StartLoc, NameLoc, II, ExprArg(Actions));
+        if (Kind == Action::ObjCSuperMessage)
+          return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
+                                                             ConsumeToken(),
+                                                             0,
+                                                             ExprArg(Actions));
+
+        // FIXME: This code is redundant with ParseObjCMessageExpr.
+        // Create the type that corresponds to the identifier (which
+        // names an Objective-C class).
+        TypeTy *Type = 0;
+        if (TypeTy *TyName = Actions.getTypeName(*II, IILoc, CurScope)) {
+          DeclSpec DS;
+          const char *PrevSpec = 0;
+          unsigned DiagID = 0;
+          if (!DS.SetTypeSpecType(DeclSpec::TST_typename, IILoc, PrevSpec,
+                                  DiagID, TyName)) {
+            DS.SetRangeEnd(IILoc);
+            Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+            TypeResult Ty = Actions.ActOnTypeName(CurScope, DeclaratorInfo);
+            if (!Ty.isInvalid())
+              Type = Ty.get();
+          }
+        }
+
+        ConsumeToken(); // The identifier.
+        if (!Type) {
+          SkipUntil(tok::r_square);
+          return ExprError();
+        }
+
+        return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 
+                                                           SourceLocation(), 
+                                                           Type, 
+                                                           ExprArg(Actions));
+      }
+
+      case Action::ObjCInstanceMessage:
+        // Fall through; we'll just parse the expression and
+        // (possibly) treat this like an Objective-C message send
+        // later.
+        break;
       }
     }