Rework the way we track which declarations are "used" during
compilation, and (hopefully) introduce RAII objects for changing the
"potentially evaluated" state at all of the necessary places within
Sema and Parser. Other changes:

  - Set the unevaluated/potentially-evaluated context appropriately
    during template instantiation.
  - We now recognize three different states while parsing or
    instantiating expressions: unevaluated, potentially evaluated, and
    potentially potentially evaluated (for C++'s typeid).
  - When we're in a potentially potentially-evaluated context, queue
    up MarkDeclarationReferenced calls in a stack. For C++ typeid
    expressions that are potentially evaluated, we will play back
    these MarkDeclarationReferenced calls when we exit the
    corresponding potentially potentially-evaluated context.
  - Non-type template arguments are now parsed as constant
    expressions, so they are not potentially-evaluated.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73899 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 4a07d05..13b32ac 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -279,7 +279,8 @@
   // C++ [basic.def.odr]p2:
   //   An expression is potentially evaluated unless it appears where an 
   //   integral constant expression is required (see 5.19) [...].
-  EnterUnevaluatedOperand Unevaluated(Actions);
+  EnterExpressionEvaluationContext Unevaluated(Actions,
+                                               Action::Unevaluated);
   
   OwningExprResult LHS(ParseCastExpression(false));
   if (LHS.isInvalid()) return move(LHS);
@@ -983,7 +984,8 @@
     //
     // The GNU typeof and alignof extensions also behave as unevaluated
     // operands.
-    EnterUnevaluatedOperand Unevaluated(Actions);
+    EnterExpressionEvaluationContext Unevaluated(Actions,
+                                                 Action::Unevaluated);
     Operand = ParseCastExpression(true/*isUnaryExpression*/);
   } else {
     // If it starts with a '(', we know that it is either a parenthesized
@@ -999,7 +1001,8 @@
     //
     // The GNU typeof and alignof extensions also behave as unevaluated
     // operands.
-    EnterUnevaluatedOperand Unevaluated(Actions);
+    EnterExpressionEvaluationContext Unevaluated(Actions,
+                                                 Action::Unevaluated);
     Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/,
                                    CastTy, RParenLoc);
     CastRange = SourceRange(LParenLoc, RParenLoc);
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 87aa5dc..2be44a4 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -384,10 +384,9 @@
     //
     // Note that we can't tell whether the expression is an lvalue of a 
     // polymorphic class type until after we've parsed the expression, so
-    // we treat the expression as an unevaluated operand and let semantic
-    // analysis cope with case where the expression is not an unevaluated
-    // operand.
-    EnterUnevaluatedOperand Unevaluated(Actions);
+    // we the expression is potentially potentially evaluated.
+    EnterExpressionEvaluationContext Unevaluated(Actions,
+                                       Action::PotentiallyPotentiallyEvaluated);
     Result = ParseExpression();
 
     // Match the ')'.
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index a9f75d8..eabe10f 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -750,7 +750,7 @@
 /// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]).
 ///
 ///       template-argument: [C++ 14.2]
-///         assignment-expression
+///         constant-expression
 ///         type-id
 ///         id-expression
 void *Parser::ParseTemplateArgument(bool &ArgIsType) {
@@ -768,7 +768,7 @@
     return TypeArg.get();
   }
 
-  OwningExprResult ExprArg = ParseAssignmentExpression();
+  OwningExprResult ExprArg = ParseConstantExpression();
   if (ExprArg.isInvalid() || !ExprArg.get())
     return 0;