Author: fpichet Date: Fri May 6 15:48:22 2011 New Revision: 131014 URL: http://llvm.org/viewvc/llvm-project?rev=131014&view=rev Log: Add support for Microsoft __if_exists and __if_not_exists construct inside function definition. Allow to include or exclude code depending on if a symbol exists or not. Just like a #ifdef but for C/C++ symbols.
More doc: http://msdn.microsoft.com/en-us/library/x7wy9xh3(v=VS.100).aspx Support at class and namespace scopes will be added later. Modified: cfe/trunk/include/clang/Basic/TokenKinds.def cfe/trunk/include/clang/Parse/Parser.h cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Parse/ParseStmt.cpp cfe/trunk/lib/Sema/SemaExprCXX.cpp cfe/trunk/test/Parser/MicrosoftExtensions.cpp Modified: cfe/trunk/include/clang/Basic/TokenKinds.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=131014&r1=131013&r2=131014&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/TokenKinds.def (original) +++ cfe/trunk/include/clang/Basic/TokenKinds.def Fri May 6 15:48:22 2011 @@ -451,6 +451,8 @@ KEYWORD(__finally , KEYMS | KEYBORLAND) KEYWORD(__leave , KEYMS | KEYBORLAND) KEYWORD(__int64 , KEYMS) +KEYWORD(__if_exists , KEYMS) +KEYWORD(__if_not_exists , KEYMS) ALIAS("__int8" , char , KEYMS) ALIAS("__int16" , short , KEYMS) ALIAS("__int32" , int , KEYMS) Modified: cfe/trunk/include/clang/Parse/Parser.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=131014&r1=131013&r2=131014&view=diff ============================================================================== --- cfe/trunk/include/clang/Parse/Parser.h (original) +++ cfe/trunk/include/clang/Parse/Parser.h Fri May 6 15:48:22 2011 @@ -1308,7 +1308,8 @@ StmtResult ParseReturnStatement(ParsedAttributes &Attr); StmtResult ParseAsmStatement(bool &msAsm); StmtResult FuzzyParseMicrosoftAsmStatement(SourceLocation AsmLoc); - bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, + void ParseMicrosoftIfExistsStatement(StmtVector &Stmts); +bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, llvm::SmallVectorImpl<ExprTy *> &Constraints, llvm::SmallVectorImpl<ExprTy *> &Exprs); Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=131014&r1=131013&r2=131014&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Fri May 6 15:48:22 2011 @@ -2385,6 +2385,8 @@ bool CheckCaseExpression(Expr *expr); + bool CheckMicrosoftIfExistsSymbol(CXXScopeSpec &SS, UnqualifiedId &Name); + //===------------------------- "Block" Extension ------------------------===// /// ActOnBlockStart - This callback is invoked when a block literal is Modified: cfe/trunk/lib/Parse/ParseStmt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=131014&r1=131013&r2=131014&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseStmt.cpp (original) +++ cfe/trunk/lib/Parse/ParseStmt.cpp Fri May 6 15:48:22 2011 @@ -741,6 +741,12 @@ continue; } + if (getLang().Microsoft && (Tok.is(tok::kw___if_exists) || + Tok.is(tok::kw___if_not_exists))) { + ParseMicrosoftIfExistsStatement(Stmts); + continue; + } + StmtResult R; if (Tok.isNot(tok::kw___extension__)) { R = ParseStatementOrDeclaration(Stmts, false); @@ -2000,3 +2006,67 @@ return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, Block.take()); } + +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); + 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)) { + SkipUntil(tok::r_brace, false); + return; + } + + // Condition is true, parse the statements. + while (Tok.isNot(tok::r_brace)) { + StmtResult R = ParseStatementOrDeclaration(Stmts, false); + if (R.isUsable()) + Stmts.push_back(R.release()); + } + + if (Tok.isNot(tok::r_brace)) { + Diag(Tok, diag::err_expected_rbrace); + return; + } + ConsumeBrace(); +} Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=131014&r1=131013&r2=131014&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri May 6 15:48:22 2011 @@ -4295,3 +4295,18 @@ return MaybeCreateStmtWithCleanups(FullStmt); } + +bool Sema::CheckMicrosoftIfExistsSymbol(CXXScopeSpec &SS, + UnqualifiedId &Name) { + DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name); + DeclarationName TargetName = TargetNameInfo.getName(); + if (!TargetName) + return false; + + // Do the redeclaration lookup in the current scope. + LookupResult R(*this, TargetNameInfo, Sema::LookupAnyName, + Sema::NotForRedeclaration); + R.suppressDiagnostics(); + LookupParsedName(R, getCurScope(), &SS); + return !R.empty(); +} Modified: cfe/trunk/test/Parser/MicrosoftExtensions.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=131014&r1=131013&r2=131014&view=diff ============================================================================== --- cfe/trunk/test/Parser/MicrosoftExtensions.cpp (original) +++ cfe/trunk/test/Parser/MicrosoftExtensions.cpp Fri May 6 15:48:22 2011 @@ -164,3 +164,36 @@ }; __int64 x7 = __int64(0); + + + + +class IF_EXISTS { +private: + typedef int Type; +}; + +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++; + } + +} _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
