Revert r279486 "Fix regression introduced by r279164"
Build bots seem unhappy and as Richard was leaving he asked me to revert this for him. Doing so. llvm-svn: 279500
This commit is contained in:
parent
567631bdd4
commit
c6c937f2a6
|
@ -11274,6 +11274,7 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD,
|
|||
SkipBody->ShouldSkip = true;
|
||||
if (auto *TD = Definition->getDescribedFunctionTemplate())
|
||||
makeMergedDefinitionVisible(TD, FD->getLocation());
|
||||
else
|
||||
makeMergedDefinitionVisible(const_cast<FunctionDecl*>(Definition),
|
||||
FD->getLocation());
|
||||
return;
|
||||
|
|
|
@ -487,6 +487,8 @@ bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation,
|
|||
QualType InstantiationTy;
|
||||
if (TagDecl *TD = dyn_cast<TagDecl>(Instantiation))
|
||||
InstantiationTy = Context.getTypeDeclType(TD);
|
||||
else
|
||||
InstantiationTy = cast<FunctionDecl>(Instantiation)->getType();
|
||||
if (!Complain || (PatternDef && PatternDef->isInvalidDecl())) {
|
||||
// Say nothing
|
||||
} else if (PatternDef) {
|
||||
|
@ -498,30 +500,15 @@ bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation,
|
|||
// we're lexically inside it.
|
||||
Instantiation->setInvalidDecl();
|
||||
} else if (InstantiatedFromMember) {
|
||||
if (isa<FunctionDecl>(Instantiation)) {
|
||||
Diag(PointOfInstantiation,
|
||||
diag::err_explicit_instantiation_undefined_member)
|
||||
<< 1 << Instantiation->getDeclName() << Instantiation->getDeclContext();
|
||||
} else {
|
||||
Diag(PointOfInstantiation,
|
||||
diag::err_implicit_instantiate_member_undefined)
|
||||
<< InstantiationTy;
|
||||
}
|
||||
Diag(Pattern->getLocation(), isa<FunctionDecl>(Instantiation)
|
||||
? diag::note_explicit_instantiation_here
|
||||
: diag::note_member_declared_at);
|
||||
Diag(Pattern->getLocation(), diag::note_member_declared_at);
|
||||
} else {
|
||||
if (isa<FunctionDecl>(Instantiation))
|
||||
Diag(PointOfInstantiation,
|
||||
diag::err_explicit_instantiation_undefined_func_template)
|
||||
<< Pattern;
|
||||
else
|
||||
Diag(PointOfInstantiation, diag::err_template_instantiate_undefined)
|
||||
<< (TSK != TSK_ImplicitInstantiation)
|
||||
<< InstantiationTy;
|
||||
Diag(Pattern->getLocation(), isa<FunctionDecl>(Instantiation)
|
||||
? diag::note_explicit_instantiation_here
|
||||
: diag::note_template_decl_here);
|
||||
Diag(Pattern->getLocation(), diag::note_template_decl_here);
|
||||
}
|
||||
|
||||
// In general, Instantiation isn't marked invalid to get more than one
|
||||
|
|
|
@ -3554,38 +3554,23 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
|
|||
const FunctionDecl *PatternDecl = Function->getTemplateInstantiationPattern();
|
||||
assert(PatternDecl && "instantiating a non-template");
|
||||
|
||||
const FunctionDecl *PatternDef = PatternDecl->getDefinition();
|
||||
Stmt *Pattern = PatternDef->getBody(PatternDef);
|
||||
if (PatternDef)
|
||||
PatternDecl = PatternDef;
|
||||
Stmt *Pattern = PatternDecl->getBody(PatternDecl);
|
||||
assert(PatternDecl && "template definition is not a template");
|
||||
if (!Pattern) {
|
||||
// Try to find a defaulted definition
|
||||
PatternDecl->isDefined(PatternDecl);
|
||||
}
|
||||
assert(PatternDecl && "template definition is not a template");
|
||||
|
||||
// FIXME: We need to track the instantiation stack in order to know which
|
||||
// definitions should be visible within this instantiation.
|
||||
if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Function,
|
||||
Function->getInstantiatedFromMemberFunction(),
|
||||
PatternDecl, PatternDef, TSK,
|
||||
/*Complain*/DefinitionRequired)) {
|
||||
if (DefinitionRequired)
|
||||
Function->setInvalidDecl();
|
||||
else if (TSK == TSK_ExplicitInstantiationDefinition) {
|
||||
// Try again at the end of the translation unit (at which point a
|
||||
// definition will be required).
|
||||
assert(!Recursive);
|
||||
PendingInstantiations.push_back(
|
||||
std::make_pair(Function, PointOfInstantiation));
|
||||
} else if (TSK == TSK_ImplicitInstantiation) {
|
||||
if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) {
|
||||
Diag(PointOfInstantiation, diag::warn_func_template_missing)
|
||||
<< Function;
|
||||
Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);
|
||||
if (getLangOpts().CPlusPlus11)
|
||||
Diag(PointOfInstantiation, diag::note_inst_declaration_hint)
|
||||
<< Function;
|
||||
}
|
||||
}
|
||||
|
||||
PatternDecl, PatternDecl, TSK,
|
||||
/*Complain*/DefinitionRequired))
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Postpone late parsed template instantiations.
|
||||
if (PatternDecl->isLateTemplateParsed() &&
|
||||
|
@ -3619,9 +3604,40 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
|
|||
Pattern = PatternDecl->getBody(PatternDecl);
|
||||
}
|
||||
|
||||
// Note, we should never try to instantiate a deleted function template.
|
||||
assert((Pattern || PatternDecl->isDefaulted()) &&
|
||||
"unexpected kind of function template definition");
|
||||
// FIXME: Check if we could sink these diagnostics in
|
||||
// DiagnoseUninstantiableTemplate.
|
||||
if (!Pattern && !PatternDecl->isDefaulted()) {
|
||||
if (DefinitionRequired) {
|
||||
if (Function->getPrimaryTemplate())
|
||||
Diag(PointOfInstantiation,
|
||||
diag::err_explicit_instantiation_undefined_func_template)
|
||||
<< Function->getPrimaryTemplate();
|
||||
else
|
||||
Diag(PointOfInstantiation,
|
||||
diag::err_explicit_instantiation_undefined_member)
|
||||
<< 1 << Function->getDeclName() << Function->getDeclContext();
|
||||
|
||||
if (PatternDecl)
|
||||
Diag(PatternDecl->getLocation(),
|
||||
diag::note_explicit_instantiation_here);
|
||||
Function->setInvalidDecl();
|
||||
} else if (TSK == TSK_ExplicitInstantiationDefinition) {
|
||||
assert(!Recursive);
|
||||
PendingInstantiations.push_back(
|
||||
std::make_pair(Function, PointOfInstantiation));
|
||||
} else if (TSK == TSK_ImplicitInstantiation) {
|
||||
if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) {
|
||||
Diag(PointOfInstantiation, diag::warn_func_template_missing)
|
||||
<< Function;
|
||||
Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);
|
||||
if (getLangOpts().CPlusPlus11)
|
||||
Diag(PointOfInstantiation, diag::note_inst_declaration_hint)
|
||||
<< Function;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// C++1y [temp.explicit]p10:
|
||||
// Except for inline functions, declarations with types deduced from their
|
||||
|
|
|
@ -6890,10 +6890,6 @@ bool Sema::hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested,
|
|||
return false;
|
||||
}
|
||||
D = ED->getDefinition();
|
||||
} else if (auto *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
if (auto *Pattern = FD->getTemplateInstantiationPattern())
|
||||
FD = Pattern;
|
||||
D = FD->getDefinition();
|
||||
}
|
||||
assert(D && "missing definition for pattern of instantiated definition");
|
||||
|
||||
|
@ -6901,7 +6897,7 @@ bool Sema::hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested,
|
|||
if (isVisible(D))
|
||||
return true;
|
||||
|
||||
// The external source may have additional definitions of this entity that are
|
||||
// The external source may have additional definitions of this type that are
|
||||
// visible, so complete the redeclaration chain now and ask again.
|
||||
if (auto *Source = Context.getExternalSource()) {
|
||||
Source->CompleteRedeclChain(D);
|
||||
|
|
|
@ -3,4 +3,3 @@ template<typename T> struct B;
|
|||
|
||||
template<typename, typename> struct A {};
|
||||
template<typename T> struct B : A<T> {};
|
||||
template<typename T> inline auto C(T) {}
|
||||
|
|
|
@ -3,9 +3,7 @@ template<typename T> struct B;
|
|||
|
||||
template<typename, typename> struct A {};
|
||||
template<typename T> struct B : A<T> {};
|
||||
template<typename T> inline auto C(T) {}
|
||||
|
||||
inline void f() {
|
||||
B<int> bi;
|
||||
C(0);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -fmodules -fno-modules-error-recovery -std=c++14 \
|
||||
// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fno-modules-error-recovery \
|
||||
// RUN: -fmodule-name=X -emit-module %S/Inputs/merge-template-pattern-visibility/module.modulemap -x c++ \
|
||||
// RUN: -fmodules-local-submodule-visibility -o %t/X.pcm
|
||||
// RUN: -fmodules-local-submodule-visibility
|
||||
|
|
Loading…
Reference in New Issue