diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Parse/ParseCXXInlineMethods.cpp | 5 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 15 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 5 |
3 files changed, 21 insertions, 4 deletions
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp index 87e2f34374..1e1a0e2b07 100644 --- a/lib/Parse/ParseCXXInlineMethods.cpp +++ b/lib/Parse/ParseCXXInlineMethods.cpp @@ -23,7 +23,7 @@ using namespace clang; /// and store its tokens for parsing after the C++ class is complete. Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo, - const VirtSpecifiers& VS) { + const VirtSpecifiers& VS, ExprResult& Init) { assert(D.isFunctionDeclarator() && "This isn't a function declarator!"); assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) && "Current token not a '{', ':' or 'try'!"); @@ -40,7 +40,8 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, ParsingDeclarator &D, else { // FIXME: pass template information through FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D, move(TemplateParams), 0, - VS, 0, /*IsDefinition*/true); + VS, Init.release(), + /*IsDefinition*/true); } HandleMemberFunctionDefaultArgs(D, FnD); diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index ccc245016e..ecf66a79db 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -1581,6 +1581,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext); VirtSpecifiers VS; + ExprResult Init; if (Tok.isNot(tok::colon)) { // Don't parse FOO:BAR as if it were a typo for FOO::BAR. @@ -1602,6 +1603,17 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, // If attributes exist after the declarator, but before an '{', parse them. MaybeParseGNUAttributes(DeclaratorInfo); + // MSVC permits pure specifier on inline functions declared at class scope. + // Hence check for =0 before checking for function definition. + if (getLang().Microsoft && Tok.is(tok::equal) && + DeclaratorInfo.isFunctionDeclarator() && + NextToken().is(tok::numeric_constant)) { + ConsumeToken(); + Init = ParseInitializer(); + if (Init.isInvalid()) + SkipUntil(tok::comma, true, true); + } + // function-definition: if (Tok.is(tok::l_brace) || (DeclaratorInfo.isFunctionDeclarator() && @@ -1631,7 +1643,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, return; } - ParseCXXInlineMethodDef(AS, DeclaratorInfo, TemplateInfo, VS); + ParseCXXInlineMethodDef(AS, DeclaratorInfo, TemplateInfo, VS, Init); // Consume the optional ';' if (Tok.is(tok::semi)) ConsumeToken(); @@ -1646,7 +1658,6 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, llvm::SmallVector<Decl *, 8> DeclsInGroup; ExprResult BitfieldSize; - ExprResult Init; bool Deleted = false; SourceLocation DefaultLoc; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index b598b46743..29343886f7 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -6308,6 +6308,11 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, WP.disableCheckFallThrough(); } + // MSVC permits the use of pure specifier (=0) on function definition, + // defined at class scope, warn about this non standard construct. + if (getLangOptions().Microsoft && FD->isPure()) + Diag(FD->getLocation(), diag::warn_pure_function_definition); + if (!FD->isInvalidDecl()) { DiagnoseUnusedParameters(FD->param_begin(), FD->param_end()); DiagnoseSizeOfParametersAndReturnValue(FD->param_begin(), FD->param_end(), |