[Frontend] Correctly handle instantiating ctors with skipped bodies

Summary:
Previsouly clang tried instantiating member initializers even if ctor
body was skipped, this caused spurious errors (see the test).

Reviewers: sepavloff, klimek

Reviewed By: sepavloff

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D41492

llvm-svn: 321520
This commit is contained in:
Ilya Biryukov
2017-12-28 13:05:46 +00:00
parent d71ad177eb
commit 95f0d3286b
2 changed files with 29 additions and 13 deletions

View File

@@ -3932,22 +3932,22 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
TemplateArgs))
return;
if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Function)) {
// If this is a constructor, instantiate the member initializers.
InstantiateMemInitializers(Ctor, cast<CXXConstructorDecl>(PatternDecl),
TemplateArgs);
// If this is an MS ABI dllexport default constructor, instantiate any
// default arguments.
if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
Ctor->isDefaultConstructor()) {
InstantiateDefaultCtorDefaultArgs(*this, Ctor);
}
}
if (PatternDecl->hasSkippedBody()) {
ActOnSkippedFunctionBody(Function);
} else {
if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Function)) {
// If this is a constructor, instantiate the member initializers.
InstantiateMemInitializers(Ctor, cast<CXXConstructorDecl>(PatternDecl),
TemplateArgs);
// If this is an MS ABI dllexport default constructor, instantiate any
// default arguments.
if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
Ctor->isDefaultConstructor()) {
InstantiateDefaultCtorDefaultArgs(*this, Ctor);
}
}
// Instantiate the function body.
StmtResult Body = SubstStmt(Pattern, TemplateArgs);

View File

@@ -0,0 +1,16 @@
// RUN: env CINDEXTEST_SKIP_FUNCTION_BODIES=1 c-index-test -test-load-source all %s 2>&1 \
// RUN: | FileCheck --implicit-check-not "error:" %s
template <class T>
struct Foo {
template <class = int>
Foo(int &a) : a(a) {
}
int &a;
};
int bar = Foo<int>(bar).a + Foo<int>(bar).a;
// CHECK-NOT: error: constructor for 'Foo<int>' must explicitly initialize the reference