Fix some interactions between C++11 and C++14 features and using-declarations:
* a dependent non-type using-declaration within a function template can be
valid, as it can refer to an enumerator, so don't reject it in the template
definition
* we can partially substitute into a dependent using-declaration if it appears
within a (local class in a) generic lambda within a function template, which
means an UnresolvedUsing*Decl doesn't necessarily instantiate to a UsingDecl.
llvm-svn: 290071
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 6b6abc7..0956a1c 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2430,8 +2430,8 @@
}
if (!NewUD->isInvalidDecl() &&
- SemaRef.CheckUsingDeclQualifier(D->getUsingLoc(), SS, NameInfo,
- D->getLocation()))
+ SemaRef.CheckUsingDeclQualifier(D->getUsingLoc(), D->hasTypename(),
+ SS, NameInfo, D->getLocation()))
NewUD->setInvalidDecl();
SemaRef.Context.setInstantiatedFromUsingDecl(NewUD, D);
@@ -2515,7 +2515,7 @@
/*instantiation*/ true,
/*typename*/ true, D->getTypenameLoc());
if (UD)
- SemaRef.Context.setInstantiatedFromUsingDecl(cast<UsingDecl>(UD), D);
+ SemaRef.Context.setInstantiatedFromUsingDecl(UD, D);
return UD;
}
@@ -2539,7 +2539,7 @@
/*instantiation*/ true,
/*typename*/ false, SourceLocation());
if (UD)
- SemaRef.Context.setInstantiatedFromUsingDecl(cast<UsingDecl>(UD), D);
+ SemaRef.Context.setInstantiatedFromUsingDecl(UD, D);
return UD;
}
@@ -4520,13 +4520,13 @@
}
static bool isInstantiationOf(UnresolvedUsingValueDecl *Pattern,
- UsingDecl *Instance,
+ NamedDecl *Instance,
ASTContext &C) {
return declaresSameEntity(C.getInstantiatedFromUsingDecl(Instance), Pattern);
}
static bool isInstantiationOf(UnresolvedUsingTypenameDecl *Pattern,
- UsingDecl *Instance,
+ NamedDecl *Instance,
ASTContext &C) {
return declaresSameEntity(C.getInstantiatedFromUsingDecl(Instance), Pattern);
}
@@ -4550,15 +4550,13 @@
// D is the prospective pattern
static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) {
if (D->getKind() != Other->getKind()) {
- if (UnresolvedUsingTypenameDecl *UUD
- = dyn_cast<UnresolvedUsingTypenameDecl>(D)) {
+ if (auto *UUD = dyn_cast<UnresolvedUsingTypenameDecl>(D)) {
if (UsingDecl *UD = dyn_cast<UsingDecl>(Other)) {
return isInstantiationOf(UUD, UD, Ctx);
}
}
- if (UnresolvedUsingValueDecl *UUD
- = dyn_cast<UnresolvedUsingValueDecl>(D)) {
+ if (auto *UUD = dyn_cast<UnresolvedUsingValueDecl>(D)) {
if (UsingDecl *UD = dyn_cast<UsingDecl>(Other)) {
return isInstantiationOf(UUD, UD, Ctx);
}
@@ -4567,31 +4565,31 @@
return false;
}
- if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Other))
+ if (auto *Record = dyn_cast<CXXRecordDecl>(Other))
return isInstantiationOf(cast<CXXRecordDecl>(D), Record);
- if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Other))
+ if (auto *Function = dyn_cast<FunctionDecl>(Other))
return isInstantiationOf(cast<FunctionDecl>(D), Function);
- if (EnumDecl *Enum = dyn_cast<EnumDecl>(Other))
+ if (auto *Enum = dyn_cast<EnumDecl>(Other))
return isInstantiationOf(cast<EnumDecl>(D), Enum);
- if (VarDecl *Var = dyn_cast<VarDecl>(Other))
+ if (auto *Var = dyn_cast<VarDecl>(Other))
if (Var->isStaticDataMember())
return isInstantiationOfStaticDataMember(cast<VarDecl>(D), Var);
- if (ClassTemplateDecl *Temp = dyn_cast<ClassTemplateDecl>(Other))
+ if (auto *Temp = dyn_cast<ClassTemplateDecl>(Other))
return isInstantiationOf(cast<ClassTemplateDecl>(D), Temp);
- if (FunctionTemplateDecl *Temp = dyn_cast<FunctionTemplateDecl>(Other))
+ if (auto *Temp = dyn_cast<FunctionTemplateDecl>(Other))
return isInstantiationOf(cast<FunctionTemplateDecl>(D), Temp);
- if (ClassTemplatePartialSpecializationDecl *PartialSpec
- = dyn_cast<ClassTemplatePartialSpecializationDecl>(Other))
+ if (auto *PartialSpec =
+ dyn_cast<ClassTemplatePartialSpecializationDecl>(Other))
return isInstantiationOf(cast<ClassTemplatePartialSpecializationDecl>(D),
PartialSpec);
- if (FieldDecl *Field = dyn_cast<FieldDecl>(Other)) {
+ if (auto *Field = dyn_cast<FieldDecl>(Other)) {
if (!Field->getDeclName()) {
// This is an unnamed field.
return declaresSameEntity(Ctx.getInstantiatedFromUnnamedFieldDecl(Field),
@@ -4599,14 +4597,20 @@
}
}
- if (UsingDecl *Using = dyn_cast<UsingDecl>(Other))
+ if (auto *Using = dyn_cast<UsingDecl>(Other))
return isInstantiationOf(cast<UsingDecl>(D), Using, Ctx);
- if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(Other))
+ if (auto *Using = dyn_cast<UnresolvedUsingValueDecl>(Other))
+ return isInstantiationOf(cast<UnresolvedUsingValueDecl>(D), Using, Ctx);
+
+ if (auto *Using = dyn_cast<UnresolvedUsingTypenameDecl>(Other))
+ return isInstantiationOf(cast<UnresolvedUsingTypenameDecl>(D), Using, Ctx);
+
+ if (auto *Shadow = dyn_cast<UsingShadowDecl>(Other))
return isInstantiationOf(cast<UsingShadowDecl>(D), Shadow, Ctx);
- return D->getDeclName() && isa<NamedDecl>(Other) &&
- D->getDeclName() == cast<NamedDecl>(Other)->getDeclName();
+ return D->getDeclName() &&
+ D->getDeclName() == cast<NamedDecl>(Other)->getDeclName();
}
template<typename ForwardIterator>