Call ActOnStartOfFunctionDecl/ActOnFinishFunctionBody when
instantiating the definition of a function from a template. llvm-svn: 71869
This commit is contained in:
parent
f6e9ece507
commit
67da0d97e6
|
@ -414,6 +414,8 @@ public:
|
|||
virtual void ActOnStartOfObjCMethodDef(Scope *S, DeclPtrTy D);
|
||||
|
||||
virtual DeclPtrTy ActOnFinishFunctionBody(DeclPtrTy Decl, StmtArg Body);
|
||||
DeclPtrTy ActOnFinishFunctionBody(DeclPtrTy Decl, StmtArg Body,
|
||||
bool IsInstantiation);
|
||||
void DiagnoseInvalidJumps(Stmt *Body);
|
||||
virtual DeclPtrTy ActOnFileScopeAsmDecl(SourceLocation Loc, ExprArg expr);
|
||||
|
||||
|
|
|
@ -3002,7 +3002,8 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
|
|||
Diag(FD->getLocation(), diag::warn_missing_prototype) << FD;
|
||||
}
|
||||
|
||||
PushDeclContext(FnBodyScope, FD);
|
||||
if (FnBodyScope)
|
||||
PushDeclContext(FnBodyScope, FD);
|
||||
|
||||
// Check the validity of our function parameters
|
||||
CheckParmsForFunctionDef(FD);
|
||||
|
@ -3013,7 +3014,7 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
|
|||
Param->setOwningFunction(FD);
|
||||
|
||||
// If this has an identifier, add it to the scope stack.
|
||||
if (Param->getIdentifier())
|
||||
if (Param->getIdentifier() && FnBodyScope)
|
||||
PushOnScopeChains(Param, FnBodyScope);
|
||||
}
|
||||
|
||||
|
@ -3039,8 +3040,12 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
|
|||
return DeclPtrTy::make(FD);
|
||||
}
|
||||
|
||||
|
||||
Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg) {
|
||||
return ActOnFinishFunctionBody(D, move(BodyArg), false);
|
||||
}
|
||||
|
||||
Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
|
||||
bool IsInstantiation) {
|
||||
Decl *dcl = D.getAs<Decl>();
|
||||
Stmt *Body = BodyArg.takeAs<Stmt>();
|
||||
if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(dcl)) {
|
||||
|
@ -3053,7 +3058,9 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg) {
|
|||
Body->Destroy(Context);
|
||||
return DeclPtrTy();
|
||||
}
|
||||
PopDeclContext();
|
||||
if (!IsInstantiation)
|
||||
PopDeclContext();
|
||||
|
||||
// Verify and clean out per-function state.
|
||||
|
||||
assert(&getLabelMap() == &FunctionLabelMap && "Didn't pop block right?");
|
||||
|
|
|
@ -2332,14 +2332,14 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
|
|||
//
|
||||
// This check comes when we actually try to perform the
|
||||
// instantiation.
|
||||
if (SpecializationRequiresInstantiation &&
|
||||
InstantiateClassTemplateSpecialization(Specialization, true))
|
||||
return true;
|
||||
if (SpecializationRequiresInstantiation)
|
||||
InstantiateClassTemplateSpecialization(Specialization, true);
|
||||
else {
|
||||
// Instantiate the members of this class template specialization.
|
||||
InstantiatingTemplate Inst(*this, TemplateLoc, Specialization);
|
||||
InstantiateClassTemplateSpecializationMembers(TemplateLoc, Specialization);
|
||||
}
|
||||
|
||||
// Instantiate the members of this class template specialization.
|
||||
InstantiatingTemplate Inst(*this, TemplateLoc, Specialization);
|
||||
InstantiateClassTemplateSpecializationMembers(TemplateLoc, Specialization);
|
||||
|
||||
return DeclPtrTy::make(Specialization);
|
||||
}
|
||||
|
||||
|
|
|
@ -587,6 +587,8 @@ void Sema::InstantiateFunctionDefinition(FunctionDecl *Function) {
|
|||
|
||||
// FIXME: add to the instantiation stack.
|
||||
|
||||
ActOnStartOfFunctionDef(0, DeclPtrTy::make(Function));
|
||||
|
||||
// Introduce a new scope where local variable instantiations will be
|
||||
// recorded.
|
||||
LocalInstantiationScope Scope(*this);
|
||||
|
@ -605,10 +607,9 @@ void Sema::InstantiateFunctionDefinition(FunctionDecl *Function) {
|
|||
// Instantiate the function body.
|
||||
OwningStmtResult Body
|
||||
= InstantiateStmt(Pattern, getTemplateInstantiationArgs(Function));
|
||||
if (Body.isInvalid())
|
||||
Function->setInvalidDecl(true);
|
||||
else
|
||||
Function->setBody(Body.takeAs<Stmt>());
|
||||
|
||||
ActOnFinishFunctionBody(DeclPtrTy::make(Function), move(Body),
|
||||
/*IsInstantiation=*/true);
|
||||
|
||||
CurContext = PreviousContext;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// RUN: clang-cc -fsyntax-only -verify %s
|
||||
|
||||
template<typename T, typename U>
|
||||
struct X0 {
|
||||
void f(T x, U y) {
|
||||
|
@ -50,3 +49,12 @@ template <typename T> struct X4 {
|
|||
|
||||
template struct X4<void>; // expected-note{{in instantiation of template class 'X4<void>' requested here}}
|
||||
template struct X4<int>; // expected-note{{in instantiation of template class 'X4<int>' requested here}}
|
||||
|
||||
struct Incomplete; // expected-note{{forward declaration}}
|
||||
|
||||
template<typename T> struct X5 {
|
||||
T f() { } // expected-error{{incomplete result type}}
|
||||
};
|
||||
void test_X5(X5<Incomplete> x5); // okay!
|
||||
|
||||
template struct X5<Incomplete>; // expected-note{{instantiation}}
|
||||
|
|
Loading…
Reference in New Issue