Add support for Microsoft __if_exists, __if_not_exists extension at class scope.

Example:

typedef int TYPE;
class C {
  __if_exists(TYPE) {
     TYPE a;
  }
  __if_not_exists(TYPE) {
     this will never be parsed.
  }
};


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132052 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Francois Pichet 2011-05-25 10:19:49 +00:00
Родитель d1e015eb44
Коммит 563a645de8
4 изменённых файлов: 98 добавлений и 4 удалений

Просмотреть файл

@ -1310,7 +1310,9 @@ private:
StmtResult FuzzyParseMicrosoftAsmStatement(SourceLocation AsmLoc);
bool ParseMicrosoftIfExistsCondition(bool& Result);
void ParseMicrosoftIfExistsStatement(StmtVector &Stmts);
void ParseMicrosoftIfExistsDeclaration();
void ParseMicrosoftIfExistsExternalDeclaration();
void ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
AccessSpecifier& CurAS);
bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
llvm::SmallVectorImpl<ExprTy *> &Constraints,
llvm::SmallVectorImpl<ExprTy *> &Exprs);

Просмотреть файл

@ -1929,6 +1929,12 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
// Each iteration of this loop reads one member-declaration.
if (getLang().Microsoft && (Tok.is(tok::kw___if_exists) ||
Tok.is(tok::kw___if_not_exists))) {
ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
continue;
}
// Check for extraneous top-level semicolon.
if (Tok.is(tok::semi)) {
Diag(Tok, diag::ext_extra_struct_semi)
@ -2528,3 +2534,64 @@ void Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs,
ExpectAndConsume(tok::r_square, diag::err_expected_rsquare);
}
}
void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
AccessSpecifier& CurAS) {
bool Result;
if (ParseMicrosoftIfExistsCondition(Result))
return;
if (Tok.isNot(tok::l_brace)) {
Diag(Tok, diag::err_expected_lbrace);
return;
}
ConsumeBrace();
// Condition is false skip all inside the {}.
if (!Result) {
SkipUntil(tok::r_brace, false);
return;
}
// Condition is true, parse the declaration.
while (Tok.isNot(tok::r_brace)) {
// __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);
continue;
}
// Check for extraneous top-level semicolon.
if (Tok.is(tok::semi)) {
Diag(Tok, diag::ext_extra_struct_semi)
<< DeclSpec::getSpecifierName((DeclSpec::TST)TagType)
<< FixItHint::CreateRemoval(Tok.getLocation());
ConsumeToken();
continue;
}
AccessSpecifier AS = getAccessSpecifierIfPresent();
if (AS != AS_none) {
// Current token is a C++ access specifier.
CurAS = AS;
SourceLocation ASLoc = Tok.getLocation();
ConsumeToken();
if (Tok.is(tok::colon))
Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
else
Diag(Tok, diag::err_expected_colon);
ConsumeToken();
continue;
}
// Parse all the comma separated declarators.
ParseCXXClassMemberDeclaration(CurAS);
}
if (Tok.isNot(tok::r_brace)) {
Diag(Tok, diag::err_expected_rbrace);
return;
}
ConsumeBrace();
}

Просмотреть файл

@ -656,7 +656,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
case tok::kw___if_exists:
case tok::kw___if_not_exists:
ParseMicrosoftIfExistsDeclaration();
ParseMicrosoftIfExistsExternalDeclaration();
return DeclGroupPtrTy();
default:
@ -1474,7 +1474,7 @@ bool Parser::ParseMicrosoftIfExistsCondition(bool& Result) {
return false;
}
void Parser::ParseMicrosoftIfExistsDeclaration() {
void Parser::ParseMicrosoftIfExistsExternalDeclaration() {
bool Result;
if (ParseMicrosoftIfExistsCondition(Result))
return;

Просмотреть файл

@ -168,7 +168,7 @@ __interface MicrosoftInterface {
__int64 x7 = __int64(0);
namespace If_exists_test {
class IF_EXISTS {
private:
@ -210,6 +210,31 @@ __if_not_exists(IF_EXISTS::Type_not) {
int var244;
}
class IF_EXISTS_CLASS_TEST {
__if_exists(IF_EXISTS::Type) {
// __if_exists, __if_not_exists can nest
__if_not_exists(IF_EXISTS::Type_not) {
int var123;
}
int var23;
}
__if_exists(IF_EXISTS::Type_not) {
this wont compile.
}
__if_not_exists(IF_EXISTS::Type) {
this wont compile.
}
__if_not_exists(IF_EXISTS::Type_not) {
int var244;
}
};
}
int __identifier(generic) = 3;
class inline_definition_pure_spec {