Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions clang/lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3822,14 +3822,19 @@ QualType Sema::CheckTemplateIdType(ElaboratedTypeKeyword Keyword,
AliasTemplate->getTemplateParameters()->getDepth());

LocalInstantiationScope Scope(*this);
InstantiatingTemplate Inst(
*this, /*PointOfInstantiation=*/TemplateLoc,
/*Entity=*/AliasTemplate,
/*TemplateArgs=*/TemplateArgLists.getInnermost());

// Diagnose uses of this alias.
(void)DiagnoseUseOfDecl(AliasTemplate, TemplateLoc);

// FIXME: The TemplateArgs passed here are not used for the context note,
// nor they should, because this note will be pointing to the specialization
// anyway. These arguments are needed for a hack for instantiating lambdas
// in the pattern of the alias. In getTemplateInstantiationArgs, these
// arguments will be used for collating the template arguments needed to
// instantiate the lambda.
InstantiatingTemplate Inst(*this, /*PointOfInstantiation=*/TemplateLoc,
/*Entity=*/AliasTemplate,
/*TemplateArgs=*/CTAI.SugaredConverted);
if (Inst.isInvalid())
return QualType();

Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Sema/SemaTemplateInstantiate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1271,6 +1271,12 @@ void Sema::PrintInstantiationStack(InstantiationContextDiagFuncRef DiagFunc) {
PDiag(diag::note_building_deduction_guide_here));
break;
case CodeSynthesisContext::TypeAliasTemplateInstantiation:
// Workaround for a workaround: don't produce a note if we are merely
// instantiating some other template which contains this alias template.
// This would be redundant either with the error itself, or some other
// context note attached to it.
if (Active->NumTemplateArgs == 0)
break;
DiagFunc(Active->PointOfInstantiation,
PDiag(diag::note_template_type_alias_instantiation_here)
<< cast<TypeAliasTemplateDecl>(Active->Entity)
Expand Down
18 changes: 10 additions & 8 deletions clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1580,17 +1580,19 @@ Decl *TemplateDeclInstantiator::InstantiateTypeAliasTemplateDecl(
if (!InstParams)
return nullptr;

TypeAliasDecl *Pattern = D->getTemplatedDecl();
Sema::InstantiatingTemplate InstTemplate(
SemaRef, D->getBeginLoc(), D,
D->getTemplateDepth() >= TemplateArgs.getNumLevels()
? ArrayRef<TemplateArgument>()
: (TemplateArgs.begin() + TemplateArgs.getNumLevels() - 1 -
D->getTemplateDepth())
->Args);
// FIXME: This is a hack for instantiating lambdas in the pattern of the
// alias. We are not really instantiating the alias at its template level,
// that only happens in CheckTemplateId, this is only for outer templates
// which contain it. In getTemplateInstantiationArgs, the template arguments
// used here would be used for collating the template arguments needed to
// instantiate the lambda. Pass an empty argument list, so this workaround
// doesn't get confused if there is an outer alias being instantiated.
Sema::InstantiatingTemplate InstTemplate(SemaRef, D->getBeginLoc(), D,
ArrayRef<TemplateArgument>());
if (InstTemplate.isInvalid())
return nullptr;

TypeAliasDecl *Pattern = D->getTemplatedDecl();
TypeAliasTemplateDecl *PrevAliasTemplate = nullptr;
if (getPreviousDeclForInstantiation<TypedefNameDecl>(Pattern)) {
DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName());
Expand Down
17 changes: 6 additions & 11 deletions clang/test/SemaTemplate/alias-template-deprecated.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,19 @@ using UsingInstWithCPPAttr [[deprecated("Do not use this")]] = NoAttr<int>;
void bar() {
NoAttr<int> obj; // Okay

// expected-warning@+2 {{'UsingWithAttr' is deprecated}}
// expected-note@+1 {{in instantiation of template type alias 'UsingWithAttr' requested here}}
// expected-warning@+1 {{'UsingWithAttr' is deprecated}}
UsingWithAttr<int> objUsingWA;

// expected-warning@+2 {{'UsingWithAttr' is deprecated}}
// expected-note@+1 {{in instantiation of template type alias 'UsingWithAttr' requested here}}
// expected-warning@+1 {{'UsingWithAttr' is deprecated}}
NoAttr<UsingWithAttr<int>> s;

// expected-note@+1 {{'DepInt' has been explicitly marked deprecated here}}
using DepInt [[deprecated]] = int;
// expected-warning@+3 {{'UsingWithAttr' is deprecated}}
// expected-warning@+2 {{'DepInt' is deprecated}}
// expected-note@+1 {{in instantiation of template type alias 'UsingWithAttr' requested here}}
// expected-warning@+2 {{'UsingWithAttr' is deprecated}}
// expected-warning@+1 {{'DepInt' is deprecated}}
using X = UsingWithAttr<DepInt>;

// expected-warning@+2 {{'UsingWithAttr' is deprecated}}
// expected-note@+1 {{in instantiation of template type alias 'UsingWithAttr' requested here}}
// expected-warning@+1 {{'UsingWithAttr' is deprecated}}
UsingWithAttr<int>().foo();

// expected-warning@+1 {{'UsingInstWithAttr' is deprecated}}
Expand All @@ -74,8 +70,7 @@ void bar() {
// expected-warning@+1 {{'UsingTDWithAttr' is deprecated}}
UsingTDWithAttr objUTDWA;

// expected-warning@+2 {{'UsingWithCPPAttr' is deprecated}}
// expected-note@+1 {{in instantiation of template type alias 'UsingWithCPPAttr' requested here}}
// expected-warning@+1 {{'UsingWithCPPAttr' is deprecated}}
UsingWithCPPAttr<int> objUsingWCPPA;

// expected-warning@+1 {{'UsingInstWithCPPAttr' is deprecated: Do not use this}}
Expand Down
8 changes: 8 additions & 0 deletions clang/test/SemaTemplate/alias-templates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,3 +312,11 @@ namespace resolved_nttp {

using TC2 = decltype(C<bool, 2, 3>::p); // expected-note {{instantiation of}}
}

namespace OuterSubstFailure {
template <class T> struct A {
template <class> using B = T&;
// expected-error@-1 {{cannot form a reference to 'void'}}
};
template struct A<void>; // expected-note {{requested here}}
} // namespace OuterSubstFailure