[cfe-commits] r146447 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseInit.cpp test/Parser/MicrosoftExtensions.cpp test/SemaTemplate/ms-if-exists.cpp
Francois Pichet
pichet2000 at gmail.com
Mon Dec 12 15:24:39 PST 2011
Author: fpichet
Date: Mon Dec 12 17:24:39 2011
New Revision: 146447
URL: http://llvm.org/viewvc/llvm-project?rev=146447&view=rev
Log:
Implement the Microsoft __if_exists/if_not_exists extension in initializer-list.
Necessary to parse Microsoft ATL code.
Example:
int array[] = {
0,
__if_exists(CLASS::Type) {2, }
3
};
will declare an array of 2 or 3 elements depending on if CLASS::Type exists or not.
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseInit.cpp
cfe/trunk/test/Parser/MicrosoftExtensions.cpp
cfe/trunk/test/SemaTemplate/ms-if-exists.cpp
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=146447&r1=146446&r2=146447&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Dec 12 17:24:39 2011
@@ -1548,6 +1548,8 @@
void ParseMicrosoftIfExistsExternalDeclaration();
void ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
AccessSpecifier& CurAS);
+ bool ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
+ bool &InitExprsOk);
bool ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
SmallVectorImpl<Expr *> &Constraints,
SmallVectorImpl<Expr *> &Exprs);
Modified: cfe/trunk/lib/Parse/ParseInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseInit.cpp?rev=146447&r1=146446&r2=146447&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseInit.cpp (original)
+++ cfe/trunk/lib/Parse/ParseInit.cpp Mon Dec 12 17:24:39 2011
@@ -340,6 +340,17 @@
bool InitExprsOk = true;
while (1) {
+ // Handle Microsoft __if_exists/if_not_exists if necessary.
+ if (getLang().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
+ Tok.is(tok::kw___if_not_exists))) {
+ if (ParseMicrosoftIfExistsBraceInitializer(InitExprs, InitExprsOk)) {
+ if (Tok.isNot(tok::comma)) break;
+ ConsumeToken();
+ }
+ if (Tok.is(tok::r_brace)) break;
+ continue;
+ }
+
// Parse: designation[opt] initializer
// If we know that this cannot be a designation, just parse the nested
@@ -392,3 +403,66 @@
return ExprError(); // an error occurred.
}
+
+// Return true if a comma (or closing brace) is necessary after the
+// __if_exists/if_not_exists statement.
+bool Parser::ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
+ bool &InitExprsOk) {
+ bool trailingComma = false;
+ IfExistsCondition Result;
+ if (ParseMicrosoftIfExistsCondition(Result))
+ return false;
+
+ BalancedDelimiterTracker Braces(*this, tok::l_brace);
+ if (Braces.consumeOpen()) {
+ Diag(Tok, diag::err_expected_lbrace);
+ return 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 false;
+ }
+
+ while (Tok.isNot(tok::eof)) {
+ trailingComma = false;
+ // If we know that this cannot be a designation, just parse the nested
+ // initializer directly.
+ ExprResult SubElt;
+ if (MayBeDesignationStart(Tok.getKind(), PP))
+ SubElt = ParseInitializerWithPotentialDesignator();
+ else
+ SubElt = ParseInitializer();
+
+ if (Tok.is(tok::ellipsis))
+ SubElt = Actions.ActOnPackExpansion(SubElt.get(), ConsumeToken());
+
+ // If we couldn't parse the subelement, bail out.
+ if (!SubElt.isInvalid())
+ InitExprs.push_back(SubElt.release());
+ else
+ InitExprsOk = false;
+
+ if (Tok.is(tok::comma)) {
+ ConsumeToken();
+ trailingComma = true;
+ }
+
+ if (Tok.is(tok::r_brace))
+ break;
+ }
+
+ Braces.consumeClose();
+
+ return !trailingComma;
+}
Modified: cfe/trunk/test/Parser/MicrosoftExtensions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=146447&r1=146446&r2=146447&view=diff
==============================================================================
--- cfe/trunk/test/Parser/MicrosoftExtensions.cpp (original)
+++ cfe/trunk/test/Parser/MicrosoftExtensions.cpp Mon Dec 12 17:24:39 2011
@@ -215,6 +215,35 @@
int var244;
}
+int __if_exists_init_list() {
+
+ int array1[] = {
+ 0,
+ __if_exists(IF_EXISTS::Type) {2, }
+ 3
+ };
+
+ int array2[] = {
+ 0,
+ __if_exists(IF_EXISTS::Type_not) { this wont compile }
+ 3
+ };
+
+ int array3[] = {
+ 0,
+ __if_not_exists(IF_EXISTS::Type_not) {2, }
+ 3
+ };
+
+ int array4[] = {
+ 0,
+ __if_not_exists(IF_EXISTS::Type) { this wont compile }
+ 3
+ };
+
+}
+
+
class IF_EXISTS_CLASS_TEST {
__if_exists(IF_EXISTS::Type) {
// __if_exists, __if_not_exists can nest
Modified: cfe/trunk/test/SemaTemplate/ms-if-exists.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/ms-if-exists.cpp?rev=146447&r1=146446&r2=146447&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/ms-if-exists.cpp (original)
+++ cfe/trunk/test/SemaTemplate/ms-if-exists.cpp Mon Dec 12 17:24:39 2011
@@ -47,6 +47,12 @@
int *i = t; // expected-error{{no viable conversion from 'HasFoo' to 'int *'}}
{ }
}
+
+ int array2[] = {
+ 0,
+ __if_exists(T::bar) {2, }// expected-warning{{dependent __if_exists declarations are ignored}}
+ 3
+ };
}
template void f(HasFoo); // expected-note{{in instantiation of function template specialization 'f<HasFoo>' requested here}}
More information about the cfe-commits
mailing list