diff options
Diffstat (limited to 'lib/Parse/ParseCXXInlineMethods.cpp')
-rw-r--r-- | lib/Parse/ParseCXXInlineMethods.cpp | 52 |
1 files changed, 43 insertions, 9 deletions
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp index 3994738..87e2f34 100644 --- a/lib/Parse/ParseCXXInlineMethods.cpp +++ b/lib/Parse/ParseCXXInlineMethods.cpp @@ -15,6 +15,7 @@ #include "clang/Parse/Parser.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/Scope.h" +#include "clang/AST/DeclTemplate.h" using namespace clang; /// ParseCXXInlineMethodDef - We parsed and verified that the specified @@ -37,13 +38,6 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, ParsingDeclarator &D, FnD = Actions.ActOnFriendFunctionDecl(getCurScope(), D, true, move(TemplateParams)); else { // FIXME: pass template information through - if (VS.isOverrideSpecified()) - Diag(VS.getOverrideLoc(), diag::ext_override_inline) << "override"; - if (VS.isFinalSpecified()) - Diag(VS.getFinalLoc(), diag::ext_override_inline) << "final"; - if (VS.isNewSpecified()) - Diag(VS.getNewLoc(), diag::ext_override_inline) << "new"; - FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D, move(TemplateParams), 0, VS, 0, /*IsDefinition*/true); @@ -53,6 +47,37 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, ParsingDeclarator &D, D.complete(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. + if (getLang().DelayedTemplateParsing && + ((Actions.CurContext->isDependentContext() || + TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) && + !Actions.IsInsideALocalClassWithinATemplateFunction()) && + !D.getDeclSpec().isFriendSpecified()) { + + if (FnD) { + LateParsedTemplatedFunction *LPT = + new LateParsedTemplatedFunction(this, FnD); + + FunctionDecl *FD = 0; + if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(FnD)) + FD = FunTmpl->getTemplatedDecl(); + else + FD = cast<FunctionDecl>(FnD); + Actions.CheckForFunctionRedefinition(FD); + + LateParsedTemplateMap[FD] = LPT; + Actions.MarkAsLateParsedTemplate(FD); + LexTemplateFunctionForLateParsing(LPT->Toks); + } else { + CachedTokens Toks; + LexTemplateFunctionForLateParsing(Toks); + } + + return FnD; + } + // Consume the tokens and store them for later parsing. LexedMethod* LM = new LexedMethod(this, FnD); @@ -94,6 +119,14 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, ParsingDeclarator &D, } } + + if (!FnD) { + // If semantic analysis could not build a function declaration, + // just throw away the late-parsed declaration. + delete getCurrentClass().LateParsedDeclarations.back(); + getCurrentClass().LateParsedDeclarations.pop_back(); + } + return FnD; } @@ -261,7 +294,7 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) { Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D); if (Tok.is(tok::kw_try)) { - ParseFunctionTryBlock(LM.D); + ParseFunctionTryBlock(LM.D, FnScope); assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc, Tok.getLocation()) && "ParseFunctionTryBlock went over the cached tokens!"); @@ -276,13 +309,14 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) { // Error recovery. if (!Tok.is(tok::l_brace)) { + FnScope.Exit(); Actions.ActOnFinishFunctionBody(LM.D, 0); return; } } else Actions.ActOnDefaultCtorInitializers(LM.D); - ParseFunctionStatementBody(LM.D); + ParseFunctionStatementBody(LM.D, FnScope); if (Tok.getLocation() != origLoc) { // Due to parsing error, we either went over the cached tokens or |