aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseStmt.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-10-24 22:31:10 +0000
committerDouglas Gregor <dgregor@apple.com>2011-10-24 22:31:10 +0000
commit3896fc5d4daaf003e451e797e37de57dd8cf9cd5 (patch)
tree85063bfcf30ec1556106e76048709cf5c811aace /lib/Parse/ParseStmt.cpp
parentb000459901bc1c5a55246da83550ad427ad4c4ff (diff)
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
Diffstat (limited to 'lib/Parse/ParseStmt.cpp')
-rw-r--r--lib/Parse/ParseStmt.cpp43
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();
}