Rework Microsoft __if_exists/__if_not_exists parsing and semantic
analysis to separate dependent names from non-dependent names. For
dependent names, we'll behave differently from Visual C++:

  - For __if_exists/__if_not_exists at class scope, we'll just warn
    and then ignore them.
  - For __if_exists/__if_not_exists in statements, we'll treat the
    inner statement as a compound statement, which we only instantiate
    in templates where the dependent name (after instantiation)
    exists. This behavior is different from VC++, but it's as close as
    we can get without encroaching ridiculousness.

The latter part (dependent statements) is not yet implemented.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142864 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 8968a43..5c2ed4e 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -2136,19 +2136,43 @@
 }
 
 void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
-  bool Result;
+  IfExistsCondition Result;
   if (ParseMicrosoftIfExistsCondition(Result))
     return;
 
-  if (Tok.isNot(tok::l_brace)) {
+  // Handle dependent statements by parsing the braces as a compound statement.
+  // This is not the same behavior as Visual C++, which don't treat this as a
+  // compound statement, but for Clang's type checking we can't have anything
+  // inside these braces escaping to the surrounding code.
+  if (Result.Behavior == IEB_Dependent) {
+    if (!Tok.is(tok::l_brace)) {
+      Diag(Tok, diag::err_expected_lbrace);
+      return;      
+    }
+    
+    ParsedAttributes Attrs(AttrFactory);
+    StmtResult Compound = ParseCompoundStatement(Attrs);
+    // FIXME: We're dropping these statements on the floor.
+    return;
+  }
+  
+  BalancedDelimiterTracker Braces(*this, tok::l_brace);
+  if (Braces.consumeOpen()) {
     Diag(Tok, diag::err_expected_lbrace);
     return;
   }
-  ConsumeBrace();
 
-  // Condition is false skip all inside the {}.
-  if (!Result) {
-    SkipUntil(tok::r_brace, false);
+  switch (Result.Behavior) {
+  case IEB_Parse:
+    // Parse the statements below.
+    break;
+      
+  case IEB_Dependent:
+    llvm_unreachable("Dependent case handled above");
+    break;
+      
+  case IEB_Skip:
+    Braces.skipToEnd();
     return;
   }
 
@@ -2158,10 +2182,5 @@
     if (R.isUsable())
       Stmts.push_back(R.release());
   }
-
-  if (Tok.isNot(tok::r_brace)) {
-    Diag(Tok, diag::err_expected_rbrace);
-    return;
-  }
-  ConsumeBrace();
+  Braces.consumeClose();
 }