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/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 7583cca..3d3d7c2 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -2757,25 +2757,32 @@
void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
AccessSpecifier& CurAS) {
- bool Result;
+ IfExistsCondition Result;
if (ParseMicrosoftIfExistsCondition(Result))
return;
- if (Tok.isNot(tok::l_brace)) {
+ 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 declarations below.
+ break;
+
+ case IEB_Dependent:
+ Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
+ << Result.IsIfExists;
+ // Fall through to skip.
+
+ case IEB_Skip:
+ Braces.skipToEnd();
return;
}
- // Condition is true, parse the declaration.
- while (Tok.isNot(tok::r_brace)) {
-
+ while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
// __if_exists, __if_not_exists can nest.
if ((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists))) {
ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
@@ -2808,10 +2815,6 @@
// Parse all the comma separated declarators.
ParseCXXClassMemberDeclaration(CurAS, 0);
}
-
- if (Tok.isNot(tok::r_brace)) {
- Diag(Tok, diag::err_expected_rbrace);
- return;
- }
- ConsumeBrace();
+
+ Braces.consumeClose();
}