diff options
author | Francois Pichet <pichet2000@gmail.com> | 2011-05-07 17:30:27 +0000 |
---|---|---|
committer | Francois Pichet <pichet2000@gmail.com> | 2011-05-07 17:30:27 +0000 |
commit | f986038beed360c031de8654cfba43a5d3184605 (patch) | |
tree | 5b6ae7f387be4cc23ef8f0e026273afe02633707 /lib/Parse/Parser.cpp | |
parent | 00c93a10c3504b77dad4467766bfca3248defbfb (diff) |
Add support for _if_exists and __if_not_exists at namespace/global scope.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131050 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/Parser.cpp')
-rw-r--r-- | lib/Parse/Parser.cpp | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 4d08699bdd..263a4916b6 100644 --- a/lib/Parse/Parser.cpp +++ b/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(); +} |