summaryrefslogtreecommitdiffstats
path: root/lib/Parse/ParseCXXInlineMethods.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Parse/ParseCXXInlineMethods.cpp')
-rw-r--r--lib/Parse/ParseCXXInlineMethods.cpp52
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
OpenPOWER on IntegriCloud