diff options
author | dim <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
commit | c72c57c9e9b69944e3e009cd5e209634839581d3 (patch) | |
tree | 4fc2f184c499d106f29a386c452b49e5197bf63d /lib/Parse/ParseCXXInlineMethods.cpp | |
parent | 5b20025c30d23d521e12c1f33ec8fa6b821952cd (diff) | |
download | FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.zip FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.tar.gz |
Vendor import of clang trunk r178860:
http://llvm.org/svn/llvm-project/cfe/trunk@178860
Diffstat (limited to 'lib/Parse/ParseCXXInlineMethods.cpp')
-rw-r--r-- | lib/Parse/ParseCXXInlineMethods.cpp | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp index 9c5c0597..bc634b5 100644 --- a/lib/Parse/ParseCXXInlineMethods.cpp +++ b/lib/Parse/ParseCXXInlineMethods.cpp @@ -11,18 +11,25 @@ // //===----------------------------------------------------------------------===// -#include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/Parser.h" +#include "RAIIObjectsForParser.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/Parse/ParseDiagnostic.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/Scope.h" -#include "clang/AST/DeclTemplate.h" -#include "RAIIObjectsForParser.h" using namespace clang; +/// Get the FunctionDecl for a function or function template decl. +static FunctionDecl *getFunctionDecl(Decl *D) { + if (FunctionDecl *fn = dyn_cast<FunctionDecl>(D)) + return fn; + return cast<FunctionTemplateDecl>(D)->getTemplatedDecl(); +} + /// ParseCXXInlineMethodDef - We parsed and verified that the specified /// Declarator is a well formed C++ inline method definition. Now lex its body /// and store its tokens for parsing after the C++ class is complete. -Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, +NamedDecl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, AttributeList *AccessAttrs, ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo, @@ -38,7 +45,7 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data() : 0, TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0); - Decl *FnD; + NamedDecl *FnD; D.setFunctionDefinitionKind(DefinitionKind); if (D.getDeclSpec().isFriendSpecified()) FnD = Actions.ActOnFriendFunctionDecl(getCurScope(), D, @@ -75,7 +82,7 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, bool Delete = false; SourceLocation KWLoc; if (Tok.is(tok::kw_delete)) { - Diag(Tok, getLangOpts().CPlusPlus0x ? + Diag(Tok, getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_deleted_function : diag::ext_deleted_function); @@ -83,7 +90,7 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Actions.SetDeclDeleted(FnD, KWLoc); Delete = true; } else if (Tok.is(tok::kw_default)) { - Diag(Tok, getLangOpts().CPlusPlus0x ? + Diag(Tok, getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_defaulted_function : diag::ext_defaulted_function); @@ -117,11 +124,7 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, if (FnD) { LateParsedTemplatedFunction *LPT = new LateParsedTemplatedFunction(FnD); - FunctionDecl *FD = 0; - if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(FnD)) - FD = FunTmpl->getTemplatedDecl(); - else - FD = cast<FunctionDecl>(FnD); + FunctionDecl *FD = getFunctionDecl(FnD); Actions.CheckForFunctionRedefinition(FD); LateParsedTemplateMap[FD] = LPT; @@ -176,6 +179,19 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, getCurrentClass().LateParsedDeclarations.pop_back(); } + // If this is a friend function, mark that it's late-parsed so that + // it's still known to be a definition even before we attach the + // parsed body. Sema needs to treat friend function definitions + // differently during template instantiation, and it's possible for + // the containing class to be instantiated before all its member + // function definitions are parsed. + // + // If you remove this, you can remove the code that clears the flag + // after parsing the member. + if (D.getDeclSpec().isFriendSpecified()) { + getFunctionDecl(FnD)->setLateTemplateParsed(true); + } + return FnD; } @@ -293,8 +309,8 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { // Introduce the parameters into scope and parse their default // arguments. - ParseScope PrototypeScope(this, - Scope::FunctionPrototypeScope|Scope::DeclScope); + ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope | + Scope::FunctionDeclarationScope | Scope::DeclScope); for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) { // Introduce the parameter into scope. Actions.ActOnDelayedCXXMethodParameter(getCurScope(), @@ -322,7 +338,7 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { LM.DefaultArgs[I].Param); ExprResult DefArgResult; - if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) { + if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); DefArgResult = ParseBraceInitializer(); } else @@ -391,7 +407,7 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) { PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false); // Consume the previously pushed token. - ConsumeAnyToken(); + ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) && "Inline method not starting with '{', ':' or 'try'"); @@ -427,6 +443,9 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) { ParseFunctionStatementBody(LM.D, FnScope); + // Clear the late-template-parsed bit if we set it before. + if (LM.D) getFunctionDecl(LM.D)->setLateTemplateParsed(false); + if (Tok.getLocation() != origLoc) { // Due to parsing error, we either went over the cached tokens or // there are still cached tokens left. If it's the latter case skip the @@ -491,7 +510,7 @@ void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) { PP.EnterTokenStream(MI.Toks.data(), MI.Toks.size(), true, false); // Consume the previously pushed token. - ConsumeAnyToken(); + ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); SourceLocation EqualLoc; @@ -651,7 +670,7 @@ bool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) { ConsumeBrace(); // In C++03, this has to be the start of the function body, which // means the initializer is malformed; we'll diagnose it later. - if (!getLangOpts().CPlusPlus0x) + if (!getLangOpts().CPlusPlus11) return false; } |