diff options
Diffstat (limited to 'lib/Parse/ParseStmt.cpp')
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 8968a43480..5c2ed4e5f5 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -2136,19 +2136,43 @@ StmtResult Parser::ParseCXXCatchBlock() { } 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 @@ void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) { if (R.isUsable()) Stmts.push_back(R.release()); } - - if (Tok.isNot(tok::r_brace)) { - Diag(Tok, diag::err_expected_rbrace); - return; - } - ConsumeBrace(); + Braces.consumeClose(); } |