Implement parsing for message sends in Objective-C++. Message sends in
Objective-C++ have a more complex grammar than in Objective-C
(surprise!), because

  (1) The receiver of an instance message can be a qualified name such
  as ::I or identity<I>::type.
  (2) Expressions in C++ can start with a type.

The receiver grammar isn't actually ambiguous; it just takes a bit of
work to parse past the type before deciding whether we have a type or
expression. We do this in two places within the grammar: once for
message sends and once when we're determining whether a []'d clause in
an initializer list is a message send or a C99 designated initializer.

This implementation of Objective-C++ message sends contains one known
extension beyond GCC's implementation, which is to permit a
typename-specifier as the receiver type for a class message, e.g.,

  [typename compute_receiver_type<T>::type method];

Note that the same effect can be achieved in GCC by way of a typedef,
e.g.,

  typedef typename computed_receiver_type<T>::type Computed;
  [Computed method];

so this is merely a convenience.

Note also that message sends still cannot involve dependent types or
values.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102031 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index ef35dcb..588825b 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -29,30 +29,6 @@
 #include "llvm/ADT/SmallString.h"
 using namespace clang;
 
-/// PrecedenceLevels - These are precedences for the binary/ternary operators in
-/// the C99 grammar.  These have been named to relate with the C99 grammar
-/// productions.  Low precedences numbers bind more weakly than high numbers.
-namespace prec {
-  enum Level {
-    Unknown         = 0,    // Not binary operator.
-    Comma           = 1,    // ,
-    Assignment      = 2,    // =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
-    Conditional     = 3,    // ?
-    LogicalOr       = 4,    // ||
-    LogicalAnd      = 5,    // &&
-    InclusiveOr     = 6,    // |
-    ExclusiveOr     = 7,    // ^
-    And             = 8,    // &
-    Equality        = 9,    // ==, !=
-    Relational      = 10,   //  >=, <=, >, <
-    Shift           = 11,   // <<, >>
-    Additive        = 12,   // -, +
-    Multiplicative  = 13,   // *, /, %
-    PointerToMember = 14    // .*, ->*
-  };
-}
-
-
 /// getBinOpPrecedence - Return the precedence of the specified binary operator
 /// token.  This returns:
 ///
@@ -297,10 +273,10 @@
 /// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
 /// LHS and has a precedence of at least MinPrec.
 Parser::OwningExprResult
-Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, unsigned MinPrec) {
-  unsigned NextTokPrec = getBinOpPrecedence(Tok.getKind(),
-                                            GreaterThanIsOperator,
-                                            getLang().CPlusPlus0x);
+Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, prec::Level MinPrec) {
+  prec::Level NextTokPrec = getBinOpPrecedence(Tok.getKind(),
+                                               GreaterThanIsOperator,
+                                               getLang().CPlusPlus0x);
   SourceLocation ColonLoc;
 
   while (1) {
@@ -363,7 +339,7 @@
 
     // Remember the precedence of this operator and get the precedence of the
     // operator immediately to the right of the RHS.
-    unsigned ThisPrec = NextTokPrec;
+    prec::Level ThisPrec = NextTokPrec;
     NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
                                      getLang().CPlusPlus0x);
 
@@ -380,7 +356,8 @@
       // is okay, to bind exactly as tightly.  For example, compile A=B=C=D as
       // A=(B=(C=D)), where each paren is a level of recursion here.
       // The function takes ownership of the RHS.
-      RHS = ParseRHSOfBinaryExpression(move(RHS), ThisPrec + !isRightAssoc);
+      RHS = ParseRHSOfBinaryExpression(move(RHS), 
+                            static_cast<prec::Level>(ThisPrec + !isRightAssoc));
       if (RHS.isInvalid())
         return move(RHS);