summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Parse/Parser.h2
-rw-r--r--clang/lib/Parse/ParseStmt.cpp41
-rw-r--r--clang/lib/Parse/Parser.cpp83
-rw-r--r--clang/test/Parser/MicrosoftExtensions.cpp22
4 files changed, 105 insertions, 43 deletions
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index adf72d0a4b9..611c5d63aab 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -1308,7 +1308,9 @@ private:
StmtResult ParseReturnStatement(ParsedAttributes &Attr);
StmtResult ParseAsmStatement(bool &msAsm);
StmtResult FuzzyParseMicrosoftAsmStatement(SourceLocation AsmLoc);
+ bool ParseMicrosoftIfExistsCondition(bool& Result);
void ParseMicrosoftIfExistsStatement(StmtVector &Stmts);
+ void ParseMicrosoftIfExistsDeclaration();
bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
llvm::SmallVectorImpl<ExprTy *> &Constraints,
llvm::SmallVectorImpl<ExprTy *> &Exprs);
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 12ab5e2767e..6cc8b57b61f 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -2008,51 +2008,18 @@ StmtResult Parser::ParseCXXCatchBlock() {
}
void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
- assert((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists)) &&
- "Expected '__if_exists' or '__if_not_exists'");
- Token Condition = Tok;
- SourceLocation IfExistsLoc = ConsumeToken();
-
- SourceLocation LParenLoc = Tok.getLocation();
- if (Tok.isNot(tok::l_paren)) {
- Diag(Tok, diag::err_expected_lparen_after) << IfExistsLoc;
- SkipUntil(tok::semi);
+ bool Result;
+ if (ParseMicrosoftIfExistsCondition(Result))
return;
- }
- ConsumeParen(); // eat the '('.
- // Parse nested-name-specifier.
- CXXScopeSpec SS;
- ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
-
- // Check nested-name specifier.
- if (SS.isInvalid()) {
- SkipUntil(tok::semi);
- return;
- }
-
- // Parse the unqualified-id.
- UnqualifiedId Name;
- if (ParseUnqualifiedId(SS, false, true, true, ParsedType(), Name)) {
- SkipUntil(tok::semi);
- return;
- }
-
- if (MatchRHSPunctuation(tok::r_paren, LParenLoc).isInvalid())
- return;
-
if (Tok.isNot(tok::l_brace)) {
Diag(Tok, diag::err_expected_lbrace);
return;
}
ConsumeBrace();
- // Check if the symbol exists.
- bool Exist = Actions.CheckMicrosoftIfExistsSymbol(SS, Name);
-
- // If the condition is false skip the tokens until the '}'
- if ((Condition.is(tok::kw___if_exists) && !Exist) ||
- (Condition.is(tok::kw___if_not_exists) && Exist)) {
+ // Condition is false skip all inside the {}.
+ if (!Result) {
SkipUntil(tok::r_brace, false);
return;
}
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 4d08699bdd3..263a4916b63 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -20,6 +20,7 @@
#include "RAIIObjectsForParser.h"
#include "ParsePragma.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ASTConsumer.h"
using namespace clang;
Parser::Parser(Preprocessor &pp, Sema &actions)
@@ -653,6 +654,11 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
// FIXME: Detect C++ linkage specifications here?
goto dont_know;
+ case tok::kw___if_exists:
+ case tok::kw___if_not_exists:
+ ParseMicrosoftIfExistsDeclaration();
+ return DeclGroupPtrTy();
+
default:
dont_know:
// We can't tell whether this is a function-definition or declaration yet.
@@ -1374,3 +1380,80 @@ void Parser::CodeCompleteMacroArgument(IdentifierInfo *Macro,
void Parser::CodeCompleteNaturalLanguage() {
Actions.CodeCompleteNaturalLanguage();
}
+
+bool Parser::ParseMicrosoftIfExistsCondition(bool& Result) {
+ assert((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists)) &&
+ "Expected '__if_exists' or '__if_not_exists'");
+ Token Condition = Tok;
+ SourceLocation IfExistsLoc = ConsumeToken();
+
+ SourceLocation LParenLoc = Tok.getLocation();
+ if (Tok.isNot(tok::l_paren)) {
+ Diag(Tok, diag::err_expected_lparen_after) << IfExistsLoc;
+ SkipUntil(tok::semi);
+ return true;
+ }
+ ConsumeParen(); // eat the '('.
+
+ // Parse nested-name-specifier.
+ CXXScopeSpec SS;
+ ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
+
+ // Check nested-name specifier.
+ if (SS.isInvalid()) {
+ SkipUntil(tok::semi);
+ return true;
+ }
+
+ // Parse the unqualified-id.
+ UnqualifiedId Name;
+ if (ParseUnqualifiedId(SS, false, true, true, ParsedType(), Name)) {
+ SkipUntil(tok::semi);
+ return true;
+ }
+
+ if (MatchRHSPunctuation(tok::r_paren, LParenLoc).isInvalid())
+ return true;
+
+ // Check if the symbol exists.
+ bool Exist = Actions.CheckMicrosoftIfExistsSymbol(SS, Name);
+
+ Result = ((Condition.is(tok::kw___if_exists) && Exist) ||
+ (Condition.is(tok::kw___if_not_exists) && !Exist));
+
+ return false;
+}
+
+void Parser::ParseMicrosoftIfExistsDeclaration() {
+ 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)) {
+ ParsedAttributesWithRange attrs(AttrFactory);
+ MaybeParseCXX0XAttributes(attrs);
+ MaybeParseMicrosoftAttributes(attrs);
+ DeclGroupPtrTy Result = ParseExternalDeclaration(attrs);
+ if (Result && !getCurScope()->getParent())
+ Actions.getASTConsumer().HandleTopLevelDecl(Result.get());
+ }
+
+ if (Tok.isNot(tok::r_brace)) {
+ Diag(Tok, diag::err_expected_rbrace);
+ return;
+ }
+ ConsumeBrace();
+}
diff --git a/clang/test/Parser/MicrosoftExtensions.cpp b/clang/test/Parser/MicrosoftExtensions.cpp
index 933231d5f70..292d3e1239d 100644
--- a/clang/test/Parser/MicrosoftExtensions.cpp
+++ b/clang/test/Parser/MicrosoftExtensions.cpp
@@ -174,26 +174,36 @@ private:
};
int __if_exists_test() {
-
int b=0;
-
-
__if_exists(IF_EXISTS::Type) {
b++;
b++;
}
-
__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) {
b++;
b++;
}
+}
+
+
+__if_exists(IF_EXISTS::Type) {
+ 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;
}
OpenPOWER on IntegriCloud