diff options
author | Alexis Hunt <alercah@gmail.com> | 2011-05-12 06:15:49 +0000 |
---|---|---|
committer | Alexis Hunt <alercah@gmail.com> | 2011-05-12 06:15:49 +0000 |
commit | 5a7fa250ab789d87237b846f96f66082711090f0 (patch) | |
tree | 7853327a172aef2c3393af72d070aff63c406d35 /clang/lib/Parse/ParseCXXInlineMethods.cpp | |
parent | f92197cf96af4f620a22303060f9b2bc7bfbc950 (diff) | |
download | bcm5719-llvm-5a7fa250ab789d87237b846f96f66082711090f0.tar.gz bcm5719-llvm-5a7fa250ab789d87237b846f96f66082711090f0.zip |
Properly parse the 'default' and 'delete' keywords.
They are actually grammatically considered definitions and parsed
accordingly.
This fixes the outstanding bugs regarding defaulting functions after
their declarations.
We now really nicely diagnose the following construct (try it!)
int foo() = delete, bar;
Still todo: Defaulted functions other than default constructors
Test cases (including for the above construct)
llvm-svn: 131228
Diffstat (limited to 'clang/lib/Parse/ParseCXXInlineMethods.cpp')
-rw-r--r-- | clang/lib/Parse/ParseCXXInlineMethods.cpp | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 1e1a0e2b070..dee00275e7e 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -25,8 +25,9 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo, 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'!"); + assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try) || + Tok.is(tok::equal)) && + "Current token not a '{', ':', '=', or 'try'!"); MultiTemplateParamsArg TemplateParams(Actions, TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data() : 0, @@ -48,6 +49,40 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, ParsingDeclarator &D, D.complete(FnD); + if (Tok.is(tok::equal)) { + ConsumeToken(); + + bool Delete = false; + SourceLocation KWLoc; + if (Tok.is(tok::kw_delete)) { + if (!getLang().CPlusPlus0x) + Diag(Tok, diag::warn_deleted_function_accepted_as_extension); + + KWLoc = ConsumeToken(); + Actions.SetDeclDeleted(FnD, KWLoc); + Delete = true; + } else if (Tok.is(tok::kw_default)) { + if (!getLang().CPlusPlus0x) + Diag(Tok, diag::warn_defaulted_function_accepted_as_extension); + + KWLoc = ConsumeToken(); + Actions.SetDeclDefaulted(FnD, KWLoc); + } else { + llvm_unreachable("function definition after = not 'delete' or 'default'"); + } + + if (Tok.is(tok::comma)) { + Diag(KWLoc, diag::err_default_delete_in_multiple_declaration) + << Delete; + SkipUntil(tok::semi); + } else { + ExpectAndConsume(tok::semi, diag::err_expected_semi_after, + Delete ? "delete" : "default", tok::semi); + } + + return FnD; + } + // In delayed template parsing mode, if we are within a class template // or if we are about to parse function member template then consume // the tokens and store them for parsing at the end of the translation unit. |