diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/Sema.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 7 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 19 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 21 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 15 |
5 files changed, 62 insertions, 1 deletions
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 403cf6246c..dc1270243d 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -142,6 +142,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()), ExternalSource(0), CodeCompleter(CodeCompleter), CurContext(0), PackContext(0), VisContext(0), + LateTemplateParser(0), OpaqueParser(0), IdResolver(pp.getLangOptions()), CXXTypeInfoDecl(0), MSVCGuidDecl(0), GlobalNewDeleteDeclared(false), CompleteTranslationUnit(CompleteTranslationUnit), diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index e506dd502a..2abc6dafa8 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5748,8 +5748,13 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { // See if this is a redefinition. // But don't complain if we're in GNU89 mode and the previous definition // was an extern inline function. + + // FIXME: This code doesn't complain about multiple definition for late + // parsed template function. + bool IsLateParsingRedefinition = LateTemplateParser && + FD->isLateTemplateParsed(); const FunctionDecl *Definition; - if (FD->hasBody(Definition) && + if (FD->hasBody(Definition) && !IsLateParsingRedefinition && !canRedefineFunction(Definition, getLangOptions())) { if (getLangOptions().GNUMode && Definition->isInlineSpecified() && Definition->getStorageClass() == SC_Extern) diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 53a7c73998..5f3f600c8c 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -3166,6 +3166,25 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { } } +void Sema::ActOnReenterDeclaratorTemplateScope(Scope *S, DeclaratorDecl *D) { + if (!D) + return; + + int NumParamList = D->getNumTemplateParameterLists(); + for (int i = 0; i < NumParamList; i++) { + TemplateParameterList* Params = D->getTemplateParameterList(i); + for (TemplateParameterList::iterator Param = Params->begin(), + ParamEnd = Params->end(); + Param != ParamEnd; ++Param) { + NamedDecl *Named = cast<NamedDecl>(*Param); + if (Named->getDeclName()) { + S->AddDecl(Named); + IdResolver.AddDecl(Named); + } + } + } +} + void Sema::ActOnReenterTemplateScope(Scope *S, Decl *D) { if (!D) return; diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 49e4a87fd1..08eb654236 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -6381,3 +6381,24 @@ Sema::getTemplateArgumentBindingsText(const TemplateParameterList *Params, Out << ']'; return Out.str(); } + +void Sema::MarkAsLateParsedTemplate(FunctionDecl *FD, bool Flag) { + if (!FD) + return; + FD->setLateTemplateParsed(Flag); +} + +bool Sema::IsInsideALocalClassWithinATemplateFunction() { + DeclContext *DC = CurContext; + + while (DC) { + if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(CurContext)) { + const FunctionDecl *FD = RD->isLocalClass(); + return (FD && FD->getTemplatedKind() != FunctionDecl::TK_NonTemplate); + } else if (DC->isTranslationUnit() || DC->isNamespace()) + return false; + + DC = DC->getParent(); + } + return false; +} diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 0ff7ff4d40..588501f50e 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2262,6 +2262,21 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, if (PatternDecl) Pattern = PatternDecl->getBody(PatternDecl); + // Postpone late parsed template instantiations. + if (PatternDecl->isLateTemplateParsed() && !LateTemplateParser) { + PendingInstantiations.push_back( + std::make_pair(Function, PointOfInstantiation)); + return; + } + + // Call the LateTemplateParser callback if there a need to late parse + // a templated function definition. + if (!Pattern && PatternDecl && PatternDecl->isLateTemplateParsed() && + LateTemplateParser) { + LateTemplateParser(OpaqueParser, (FunctionDecl*)PatternDecl); + Pattern = PatternDecl->getBody(PatternDecl); + } + if (!Pattern) { if (DefinitionRequired) { if (Function->getPrimaryTemplate()) |