Implement a new identifier-classification scheme where Sema
performs name lookup for an identifier and resolves it to a
type/expression/template/etc. in the same step. This scheme is
intended to improve both performance (by reducing the number of
redundant name lookups for a given identifier token) and error
recovery (by giving Sema a chance to correct type names before the
parser has decided that the identifier isn't a type name). For
example, this allows us to properly typo-correct type names at the
beginning of a statement:

t.c:6:3: error: use of undeclared identifier 'integer'; did you mean
'Integer'?
  integer *i = 0;
  ^~~~~~~
  Integer
t.c:1:13: note: 'Integer' declared here
typedef int Integer;
            ^


Previously, we wouldn't give a Fix-It because the typo correction
occurred after the parser had checked whether "integer" was a type
name (via Sema::getTypeName(), which isn't allowed to typo-correct)
and therefore decided to parse "integer * i = 0" as an expression. By
typo-correcting earlier, we typo-correct to the type name Integer and
parse this as a declaration. 

Moreover, in this context, we can also typo-correct identifiers to
keywords, e.g.,

t.c:7:3: error: use of undeclared identifier 'vid'; did you mean
'void'?
  vid *p = i;
  ^~~
  void

and recover appropriately.

Note that this is very much a work-in-progress. The new
Sema::ClassifyName is only used for expression-or-declaration
disambiguation in C at the statement level. The next steps will be to
make this work for the same disambiguation in C++ (where
functional-style casts make some trouble), then push it
further into the parser to eliminate more redundant name lookups.

Fixes <rdar://problem/7963833> for C and starts us down the path of
<rdar://problem/8172000>.




git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130082 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 0ad153f..cd8f9c5 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -175,8 +175,10 @@
 ///         assignment-expression ...[opt]
 ///         expression ',' assignment-expression ...[opt]
 ///
-ExprResult Parser::ParseExpression() {
-  ExprResult LHS(ParseAssignmentExpression());
+/// \param Primary if non-empty, an already-parsed expression that will be used
+/// as the first primary expression.
+ExprResult Parser::ParseExpression(ExprResult Primary) {
+  ExprResult LHS(ParseAssignmentExpression(Primary));
   return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
 }
 
@@ -213,16 +215,26 @@
 
 /// ParseAssignmentExpression - Parse an expr that doesn't include commas.
 ///
-ExprResult Parser::ParseAssignmentExpression() {
+/// \param Primary if non-empty, an already-parsed expression that will be used
+/// as the first primary expression.
+ExprResult Parser::ParseAssignmentExpression(ExprResult Primary) {
   if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
+    if (Primary.isUsable())
+      Actions.CodeCompletePostfixExpression(getCurScope(), Primary);
+    else
+      Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
     ConsumeCodeCompletionToken();
   }
 
-  if (Tok.is(tok::kw_throw))
+  if (!Primary.isUsable() && Tok.is(tok::kw_throw))
     return ParseThrowExpression();
 
-  ExprResult LHS(ParseCastExpression(false));
+  ExprResult LHS;
+  if (Primary.get() || Primary.isInvalid())
+    LHS = ParsePostfixExpressionSuffix(Primary);
+  else
+    LHS = ParseCastExpression(false, false, ParsedType());
+  
   return ParseRHSOfBinaryExpression(move(LHS), prec::Assignment);
 }
 
@@ -415,8 +427,8 @@
 /// due to member pointers.
 ///
 ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
-                                                     bool isAddressOfOperand,
-                                                     ParsedType TypeOfCast) {
+                                       bool isAddressOfOperand,
+                                       ParsedType TypeOfCast) {
   bool NotCastExpr;
   ExprResult Res = ParseCastExpression(isUnaryExpression,
                                        isAddressOfOperand,