Revert "[c++1z] P0195R2: Support pack-expansion of using-declarations."
This reverts commit r290080 as it leads to many Clang crashes, e.g.:
http://lab.llvm.org:8011/builders/clang-cmake-aarch64-quick/builds/1814
llvm-svn: 290092
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index dbc322e..0956a1c 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2495,73 +2495,8 @@
return nullptr;
}
-template <typename T>
-Decl *TemplateDeclInstantiator::instantiateUnresolvedUsingDecl(
- T *D, bool InstantiatingPackElement) {
- // If this is a pack expansion, expand it now.
- if (D->isPackExpansion() && !InstantiatingPackElement) {
- SmallVector<UnexpandedParameterPack, 2> Unexpanded;
- SemaRef.collectUnexpandedParameterPacks(D->getQualifierLoc(), Unexpanded);
- SemaRef.collectUnexpandedParameterPacks(D->getNameInfo(), Unexpanded);
-
- // Determine whether the set of unexpanded parameter packs can and should
- // be expanded.
- bool Expand = true;
- bool RetainExpansion = false;
- Optional<unsigned> NumExpansions;
- if (SemaRef.CheckParameterPacksForExpansion(
- D->getEllipsisLoc(), D->getSourceRange(), Unexpanded, TemplateArgs,
- Expand, RetainExpansion, NumExpansions))
- return nullptr;
-
- // This declaration cannot appear within a function template signature,
- // so we can't have a partial argument list for a parameter pack.
- assert(!RetainExpansion &&
- "should never need to retain an expansion for UsingPackDecl");
-
- if (!Expand) {
- // We cannot fully expand the pack expansion now, so substitute into the
- // pattern and create a new pack expansion.
- Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1);
- return instantiateUnresolvedUsingDecl(D, true);
- }
-
- // Within a function, we don't have any normal way to check for conflicts
- // between shadow declarations from different using declarations in the
- // same pack expansion, but this is always ill-formed because all expansions
- // must produce (conflicting) enumerators.
- //
- // Sadly we can't just reject this in the template definition because it
- // could be valid if the pack is empty or has exactly one expansion.
- if (D->getDeclContext()->isFunctionOrMethod() && *NumExpansions > 1) {
- SemaRef.Diag(D->getEllipsisLoc(),
- diag::err_using_decl_redeclaration_expansion);
- return nullptr;
- }
-
- // Instantiate the slices of this pack and build a UsingPackDecl.
- SmallVector<NamedDecl*, 8> Expansions;
- for (unsigned I = 0; I != *NumExpansions; ++I) {
- Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
- Decl *Slice = instantiateUnresolvedUsingDecl(D, true);
- if (!Slice)
- return nullptr;
- // Note that we can still get unresolved using declarations here, if we
- // had arguments for all packs but the pattern also contained other
- // template arguments (this only happens during partial substitution, eg
- // into the body of a generic lambda in a function template).
- Expansions.push_back(cast<NamedDecl>(Slice));
- }
-
- auto *NewD = SemaRef.BuildUsingPackDecl(D, Expansions);
- if (isDeclWithinFunction(D))
- SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewD);
- return NewD;
- }
-
- UnresolvedUsingTypenameDecl *TD = dyn_cast<UnresolvedUsingTypenameDecl>(D);
- SourceLocation TypenameLoc = TD ? TD->getTypenameLoc() : SourceLocation();
-
+Decl * TemplateDeclInstantiator
+ ::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
NestedNameSpecifierLoc QualifierLoc
= SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(),
TemplateArgs);
@@ -2571,51 +2506,44 @@
CXXScopeSpec SS;
SS.Adopt(QualifierLoc);
- DeclarationNameInfo NameInfo
- = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
-
- // Produce a pack expansion only if we're not instantiating a particular
- // slice of a pack expansion.
- bool InstantiatingSlice = D->getEllipsisLoc().isValid() &&
- SemaRef.ArgumentPackSubstitutionIndex != -1;
- SourceLocation EllipsisLoc =
- InstantiatingSlice ? SourceLocation() : D->getEllipsisLoc();
-
- NamedDecl *UD = SemaRef.BuildUsingDeclaration(
- /*Scope*/ nullptr, D->getAccess(), D->getUsingLoc(),
- /*HasTypename*/ TD, TypenameLoc, SS, NameInfo, EllipsisLoc, nullptr,
- /*IsInstantiation*/ true);
+ // Since NameInfo refers to a typename, it cannot be a C++ special name.
+ // Hence, no transformation is required for it.
+ DeclarationNameInfo NameInfo(D->getDeclName(), D->getLocation());
+ NamedDecl *UD =
+ SemaRef.BuildUsingDeclaration(/*Scope*/ nullptr, D->getAccess(),
+ D->getUsingLoc(), SS, NameInfo, nullptr,
+ /*instantiation*/ true,
+ /*typename*/ true, D->getTypenameLoc());
if (UD)
SemaRef.Context.setInstantiatedFromUsingDecl(UD, D);
return UD;
}
-Decl *TemplateDeclInstantiator::VisitUnresolvedUsingTypenameDecl(
- UnresolvedUsingTypenameDecl *D) {
- return instantiateUnresolvedUsingDecl(D);
+Decl * TemplateDeclInstantiator
+ ::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
+ NestedNameSpecifierLoc QualifierLoc
+ = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), TemplateArgs);
+ if (!QualifierLoc)
+ return nullptr;
+
+ CXXScopeSpec SS;
+ SS.Adopt(QualifierLoc);
+
+ DeclarationNameInfo NameInfo
+ = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
+
+ NamedDecl *UD =
+ SemaRef.BuildUsingDeclaration(/*Scope*/ nullptr, D->getAccess(),
+ D->getUsingLoc(), SS, NameInfo, nullptr,
+ /*instantiation*/ true,
+ /*typename*/ false, SourceLocation());
+ if (UD)
+ SemaRef.Context.setInstantiatedFromUsingDecl(UD, D);
+
+ return UD;
}
-Decl *TemplateDeclInstantiator::VisitUnresolvedUsingValueDecl(
- UnresolvedUsingValueDecl *D) {
- return instantiateUnresolvedUsingDecl(D);
-}
-
-Decl *TemplateDeclInstantiator::VisitUsingPackDecl(UsingPackDecl *D) {
- SmallVector<NamedDecl*, 8> Expansions;
- for (auto *UD : D->expansions()) {
- if (auto *NewUD =
- SemaRef.FindInstantiatedDecl(D->getLocation(), UD, TemplateArgs))
- Expansions.push_back(cast<NamedDecl>(NewUD));
- else
- return nullptr;
- }
-
- auto *NewD = SemaRef.BuildUsingPackDecl(D, Expansions);
- if (isDeclWithinFunction(D))
- SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewD);
- return NewD;
-}
Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl(
ClassScopeFunctionSpecializationDecl *Decl) {
@@ -4585,36 +4513,22 @@
Pattern);
}
-static bool isInstantiationOf(UsingDecl *Pattern, UsingDecl *Instance,
+static bool isInstantiationOf(UsingDecl *Pattern,
+ UsingDecl *Instance,
ASTContext &C) {
return declaresSameEntity(C.getInstantiatedFromUsingDecl(Instance), Pattern);
}
-template<typename T>
-static bool isInstantiationOfUnresolvedUsingDecl(T *Pattern, Decl *Other,
- ASTContext &Ctx) {
- // An unresolved using declaration can instantiate to an unresolved using
- // declaration, or to a using declaration or a using declaration pack.
- //
- // Multiple declarations can claim to be instantiated from an unresolved
- // using declaration if it's a pack expansion. We want the UsingPackDecl
- // in that case, not the individual UsingDecls within the pack.
- bool OtherIsPackExpansion;
- NamedDecl *OtherFrom;
- if (auto *OtherUUD = dyn_cast<T>(Other)) {
- OtherIsPackExpansion = OtherUUD->isPackExpansion();
- OtherFrom = Ctx.getInstantiatedFromUsingDecl(OtherUUD);
- } else if (auto *OtherUPD = dyn_cast<UsingPackDecl>(Other)) {
- OtherIsPackExpansion = true;
- OtherFrom = OtherUPD->getInstantiatedFromUsingDecl();
- } else if (auto *OtherUD = dyn_cast<UsingDecl>(Other)) {
- OtherIsPackExpansion = false;
- OtherFrom = Ctx.getInstantiatedFromUsingDecl(OtherUD);
- } else {
- return false;
- }
- return Pattern->isPackExpansion() == OtherIsPackExpansion &&
- declaresSameEntity(OtherFrom, Pattern);
+static bool isInstantiationOf(UnresolvedUsingValueDecl *Pattern,
+ NamedDecl *Instance,
+ ASTContext &C) {
+ return declaresSameEntity(C.getInstantiatedFromUsingDecl(Instance), Pattern);
+}
+
+static bool isInstantiationOf(UnresolvedUsingTypenameDecl *Pattern,
+ NamedDecl *Instance,
+ ASTContext &C) {
+ return declaresSameEntity(C.getInstantiatedFromUsingDecl(Instance), Pattern);
}
static bool isInstantiationOfStaticDataMember(VarDecl *Pattern,
@@ -4635,14 +4549,21 @@
// Other is the prospective instantiation
// D is the prospective pattern
static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) {
- if (auto *UUD = dyn_cast<UnresolvedUsingTypenameDecl>(D))
- return isInstantiationOfUnresolvedUsingDecl(UUD, Other, Ctx);
+ if (D->getKind() != Other->getKind()) {
+ if (auto *UUD = dyn_cast<UnresolvedUsingTypenameDecl>(D)) {
+ if (UsingDecl *UD = dyn_cast<UsingDecl>(Other)) {
+ return isInstantiationOf(UUD, UD, Ctx);
+ }
+ }
- if (auto *UUD = dyn_cast<UnresolvedUsingValueDecl>(D))
- return isInstantiationOfUnresolvedUsingDecl(UUD, Other, Ctx);
+ if (auto *UUD = dyn_cast<UnresolvedUsingValueDecl>(D)) {
+ if (UsingDecl *UD = dyn_cast<UsingDecl>(Other)) {
+ return isInstantiationOf(UUD, UD, Ctx);
+ }
+ }
- if (D->getKind() != Other->getKind())
return false;
+ }
if (auto *Record = dyn_cast<CXXRecordDecl>(Other))
return isInstantiationOf(cast<CXXRecordDecl>(D), Record);
@@ -4679,6 +4600,12 @@
if (auto *Using = dyn_cast<UsingDecl>(Other))
return isInstantiationOf(cast<UsingDecl>(D), Using, Ctx);
+ 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);
@@ -4919,8 +4846,6 @@
}
NamedDecl *Result = nullptr;
- // FIXME: If the name is a dependent name, this lookup won't necessarily
- // find it. Does that ever matter?
if (D->getDeclName()) {
DeclContext::lookup_result Found = ParentDC->lookup(D->getDeclName());
Result = findInstantiationOf(Context, D, Found.begin(), Found.end());