summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorDaniel Jasper <djasper@google.com>2016-12-19 10:09:25 +0000
committerDaniel Jasper <djasper@google.com>2016-12-19 10:09:25 +0000
commit9949ead55ad85698096af2fda29e8c6bb00a09b9 (patch)
treecb7551d743a7326e28591672cc19f3c5ff0a2004 /clang/lib/Sema
parent03b8be575e36f847387e314cfab75c2ae54e831f (diff)
downloadbcm5719-llvm-9949ead55ad85698096af2fda29e8c6bb00a09b9.tar.gz
bcm5719-llvm-9949ead55ad85698096af2fda29e8c6bb00a09b9.zip
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
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp74
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp14
-rw-r--r--clang/lib/Sema/SemaOverload.cpp8
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp193
-rw-r--r--clang/lib/Sema/SemaTemplateVariadic.cpp19
-rw-r--r--clang/lib/Sema/TreeTransform.h142
6 files changed, 158 insertions, 292 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 21bdd945f06..ac643af1490 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -8533,18 +8533,12 @@ void Sema::PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir) {
Decl *Sema::ActOnUsingDeclaration(Scope *S,
AccessSpecifier AS,
SourceLocation UsingLoc,
- SourceLocation TypenameLoc,
CXXScopeSpec &SS,
UnqualifiedId &Name,
- SourceLocation EllipsisLoc,
- AttributeList *AttrList) {
+ AttributeList *AttrList,
+ SourceLocation TypenameLoc) {
assert(S->getFlags() & Scope::DeclScope && "Invalid Scope.");
- if (SS.isEmpty()) {
- Diag(Name.getLocStart(), diag::err_using_requires_qualname);
- return nullptr;
- }
-
switch (Name.getKind()) {
case UnqualifiedId::IK_ImplicitSelfParam:
case UnqualifiedId::IK_Identifier:
@@ -8590,23 +8584,14 @@ Decl *Sema::ActOnUsingDeclaration(Scope *S,
<< FixItHint::CreateInsertion(SS.getRange().getBegin(), "using ");
}
- if (EllipsisLoc.isInvalid()) {
- if (DiagnoseUnexpandedParameterPack(SS, UPPC_UsingDeclaration) ||
- DiagnoseUnexpandedParameterPack(TargetNameInfo, UPPC_UsingDeclaration))
- return nullptr;
- } else {
- if (!SS.getScopeRep()->containsUnexpandedParameterPack() &&
- !TargetNameInfo.containsUnexpandedParameterPack()) {
- Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
- << SourceRange(SS.getBeginLoc(), TargetNameInfo.getEndLoc());
- EllipsisLoc = SourceLocation();
- }
- }
+ if (DiagnoseUnexpandedParameterPack(SS, UPPC_UsingDeclaration) ||
+ DiagnoseUnexpandedParameterPack(TargetNameInfo, UPPC_UsingDeclaration))
+ return nullptr;
- NamedDecl *UD =
- BuildUsingDeclaration(S, AS, UsingLoc, TypenameLoc.isValid(), TypenameLoc,
- SS, TargetNameInfo, EllipsisLoc, AttrList,
- /*IsInstantiation*/false);
+ NamedDecl *UD = BuildUsingDeclaration(S, AS, UsingLoc, SS,
+ TargetNameInfo, AttrList,
+ /* IsInstantiation */ false,
+ TypenameLoc.isValid(), TypenameLoc);
if (UD)
PushOnScopeChains(UD, S, /*AddToContext*/ false);
@@ -8669,7 +8654,6 @@ bool Sema::CheckUsingShadowDecl(UsingDecl *Using, NamedDecl *Orig,
diag::err_using_decl_nested_name_specifier_is_current_class)
<< Using->getQualifierLoc().getSourceRange();
Diag(Orig->getLocation(), diag::note_using_decl_target);
- Using->setInvalidDecl();
return true;
}
@@ -8679,7 +8663,6 @@ bool Sema::CheckUsingShadowDecl(UsingDecl *Using, NamedDecl *Orig,
<< cast<CXXRecordDecl>(CurContext)
<< Using->getQualifierLoc().getSourceRange();
Diag(Orig->getLocation(), diag::note_using_decl_target);
- Using->setInvalidDecl();
return true;
}
}
@@ -8703,7 +8686,7 @@ bool Sema::CheckUsingShadowDecl(UsingDecl *Using, NamedDecl *Orig,
// We can have UsingDecls in our Previous results because we use the same
// LookupResult for checking whether the UsingDecl itself is a valid
// redeclaration.
- if (isa<UsingDecl>(D) || isa<UsingPackDecl>(D))
+ if (isa<UsingDecl>(D))
continue;
if (IsEquivalentForUsingDecl(Context, D, Target)) {
@@ -8749,7 +8732,6 @@ bool Sema::CheckUsingShadowDecl(UsingDecl *Using, NamedDecl *Orig,
Diag(Target->getLocation(), diag::note_using_decl_target);
Diag(OldDecl->getLocation(), diag::note_using_decl_conflict);
- Using->setInvalidDecl();
return true;
}
@@ -8762,7 +8744,6 @@ bool Sema::CheckUsingShadowDecl(UsingDecl *Using, NamedDecl *Orig,
Diag(Using->getLocation(), diag::err_using_decl_conflict);
Diag(Target->getLocation(), diag::note_using_decl_target);
Diag(Tag->getLocation(), diag::note_using_decl_conflict);
- Using->setInvalidDecl();
return true;
}
@@ -8772,7 +8753,6 @@ bool Sema::CheckUsingShadowDecl(UsingDecl *Using, NamedDecl *Orig,
Diag(Using->getLocation(), diag::err_using_decl_conflict);
Diag(Target->getLocation(), diag::note_using_decl_target);
Diag(NonTag->getLocation(), diag::note_using_decl_conflict);
- Using->setInvalidDecl();
return true;
}
@@ -8980,19 +8960,23 @@ private:
/// the lookup differently for these declarations.
NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
SourceLocation UsingLoc,
- bool HasTypenameKeyword,
- SourceLocation TypenameLoc,
CXXScopeSpec &SS,
DeclarationNameInfo NameInfo,
- SourceLocation EllipsisLoc,
AttributeList *AttrList,
- bool IsInstantiation) {
+ bool IsInstantiation,
+ bool HasTypenameKeyword,
+ SourceLocation TypenameLoc) {
assert(!SS.isInvalid() && "Invalid CXXScopeSpec.");
SourceLocation IdentLoc = NameInfo.getLoc();
assert(IdentLoc.isValid() && "Invalid TargetName location.");
// FIXME: We ignore attributes for now.
+ if (SS.isEmpty()) {
+ Diag(IdentLoc, diag::err_using_requires_qualname);
+ return nullptr;
+ }
+
// For an inheriting constructor declaration, the name of the using
// declaration is the name of a constructor in this class, not in the
// base class.
@@ -9058,17 +9042,16 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
DeclContext *LookupContext = computeDeclContext(SS);
NamedDecl *D;
NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
- if (!LookupContext || EllipsisLoc.isValid()) {
+ if (!LookupContext) {
if (HasTypenameKeyword) {
// FIXME: not all declaration name kinds are legal here
D = UnresolvedUsingTypenameDecl::Create(Context, CurContext,
UsingLoc, TypenameLoc,
QualifierLoc,
- IdentLoc, NameInfo.getName(),
- EllipsisLoc);
+ IdentLoc, NameInfo.getName());
} else {
D = UnresolvedUsingValueDecl::Create(Context, CurContext, UsingLoc,
- QualifierLoc, NameInfo, EllipsisLoc);
+ QualifierLoc, NameInfo);
}
D->setAccess(AS);
CurContext->addDecl(D);
@@ -9228,19 +9211,6 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
return UD;
}
-NamedDecl *Sema::BuildUsingPackDecl(NamedDecl *InstantiatedFrom,
- ArrayRef<NamedDecl *> Expansions) {
- assert(isa<UnresolvedUsingValueDecl>(InstantiatedFrom) ||
- isa<UnresolvedUsingTypenameDecl>(InstantiatedFrom) ||
- isa<UsingPackDecl>(InstantiatedFrom));
-
- auto *UPD =
- UsingPackDecl::Create(Context, CurContext, InstantiatedFrom, Expansions);
- UPD->setAccess(InstantiatedFrom->getAccess());
- CurContext->addDecl(UPD);
- return UPD;
-}
-
/// Additional checks for a using declaration referring to a constructor name.
bool Sema::CheckInheritingConstructorUsingDecl(UsingDecl *UD) {
assert(!UD->hasTypename() && "expecting a constructor name");
@@ -9294,7 +9264,7 @@ bool Sema::CheckUsingDeclRedeclaration(SourceLocation UsingLoc,
// scope?
if (Qual->isDependent() && !HasTypenameKeyword) {
for (auto *D : Prev) {
- if (!isa<TypeDecl>(D) && !isa<UsingDecl>(D) && !isa<UsingPackDecl>(D)) {
+ if (!isa<TypeDecl>(D) && !isa<UsingDecl>(D)) {
bool OldCouldBeEnumerator =
isa<UnresolvedUsingValueDecl>(D) || isa<EnumConstantDecl>(D);
Diag(NameLoc,
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 5c3900adbde..74beeac7244 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -7462,11 +7462,17 @@ Sema::CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc,
UnqualifiedId &Name) {
DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name);
- // Check for an unexpanded parameter pack.
- auto UPPC = IsIfExists ? UPPC_IfExists : UPPC_IfNotExists;
- if (DiagnoseUnexpandedParameterPack(SS, UPPC) ||
- DiagnoseUnexpandedParameterPack(TargetNameInfo, UPPC))
+ // Check for unexpanded parameter packs.
+ SmallVector<UnexpandedParameterPack, 4> Unexpanded;
+ collectUnexpandedParameterPacks(SS, Unexpanded);
+ collectUnexpandedParameterPacks(TargetNameInfo, Unexpanded);
+ if (!Unexpanded.empty()) {
+ DiagnoseUnexpandedParameterPacks(KeywordLoc,
+ IsIfExists? UPPC_IfExists
+ : UPPC_IfNotExists,
+ Unexpanded);
return IER_Error;
+ }
return CheckMicrosoftIfExistsSymbol(S, SS, TargetNameInfo);
}
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 2129729dab9..d49142b8d85 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -981,7 +981,7 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old,
Match = *I;
return Ovl_Match;
}
- } else if (isa<UsingDecl>(OldD) || isa<UsingPackDecl>(OldD)) {
+ } else if (isa<UsingDecl>(OldD)) {
// We can overload with these, which can show up when doing
// redeclaration checks for UsingDecls.
assert(Old.getLookupKind() == LookupUsingDeclName);
@@ -11420,12 +11420,6 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
assert(!R.empty() && "lookup results empty despite recovery");
- // If recovery created an ambiguity, just bail out.
- if (R.isAmbiguous()) {
- R.suppressDiagnostics();
- return ExprError();
- }
-
// Build an implicit member call if appropriate. Just drop the
// casts and such from the call, we don't really care.
ExprResult NewFn = ExprError();
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index dbc322ebfdc..0956a1cc502 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2495,76 +2495,35 @@ Decl *TemplateDeclInstantiator::VisitConstructorUsingShadowDecl(
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;
- }
+Decl * TemplateDeclInstantiator
+ ::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
+ NestedNameSpecifierLoc QualifierLoc
+ = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(),
+ TemplateArgs);
+ if (!QualifierLoc)
+ 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));
- }
+ CXXScopeSpec SS;
+ SS.Adopt(QualifierLoc);
- auto *NewD = SemaRef.BuildUsingPackDecl(D, Expansions);
- if (isDeclWithinFunction(D))
- SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewD);
- return NewD;
- }
+ // 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);
- UnresolvedUsingTypenameDecl *TD = dyn_cast<UnresolvedUsingTypenameDecl>(D);
- SourceLocation TypenameLoc = TD ? TD->getTypenameLoc() : SourceLocation();
+ return UD;
+}
+Decl * TemplateDeclInstantiator
+ ::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
NestedNameSpecifierLoc QualifierLoc
- = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(),
- TemplateArgs);
+ = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), TemplateArgs);
if (!QualifierLoc)
return nullptr;
@@ -2574,48 +2533,17 @@ Decl *TemplateDeclInstantiator::instantiateUnresolvedUsingDecl(
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);
+ 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::VisitUnresolvedUsingTypenameDecl(
- UnresolvedUsingTypenameDecl *D) {
- return instantiateUnresolvedUsingDecl(D);
-}
-
-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 @@ static bool isInstantiationOf(UsingShadowDecl *Pattern,
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 @@ static bool isInstantiationOfStaticDataMember(VarDecl *Pattern,
// 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 @@ static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) {
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 *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
}
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());
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 54556b505ee..c8bc2c38809 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -390,18 +390,21 @@ void Sema::collectUnexpandedParameterPacks(QualType T,
void Sema::collectUnexpandedParameterPacks(TypeLoc TL,
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);
-}
+}
-void Sema::collectUnexpandedParameterPacks(
- NestedNameSpecifierLoc NNS,
- SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
+void Sema::collectUnexpandedParameterPacks(CXXScopeSpec &SS,
+ SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
+ NestedNameSpecifier *Qualifier = SS.getScopeRep();
+ if (!Qualifier)
+ return;
+
+ NestedNameSpecifierLoc QualifierLoc(Qualifier, SS.location_data());
CollectUnexpandedParameterPacksVisitor(Unexpanded)
- .TraverseNestedNameSpecifierLoc(NNS);
+ .TraverseNestedNameSpecifierLoc(QualifierLoc);
}
-void Sema::collectUnexpandedParameterPacks(
- const DeclarationNameInfo &NameInfo,
- SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
+void Sema::collectUnexpandedParameterPacks(const DeclarationNameInfo &NameInfo,
+ SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
CollectUnexpandedParameterPacksVisitor(Unexpanded)
.TraverseDeclarationNameInfo(NameInfo);
}
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 849fdac7ec6..a76a078fd00 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -457,10 +457,6 @@ public:
return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
}
- /// Transform the set of declarations in an OverloadExpr.
- bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
- LookupResult &R);
-
/// \brief Transform the given nested-name-specifier with source-location
/// information.
///
@@ -825,7 +821,7 @@ public:
/// \brief Rebuild an unresolved typename type, given the decl that
/// the UnresolvedUsingTypenameDecl was transformed to.
- QualType RebuildUnresolvedUsingType(SourceLocation NameLoc, Decl *D);
+ QualType RebuildUnresolvedUsingType(Decl *D);
/// \brief Build a new typedef type.
QualType RebuildTypedefType(TypedefNameDecl *Typedef) {
@@ -5165,7 +5161,7 @@ TreeTransform<Derived>::TransformUnresolvedUsingType(TypeLocBuilder &TLB,
QualType Result = TL.getType();
if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
- Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
+ Result = getDerived().RebuildUnresolvedUsingType(D);
if (Result.isNull())
return QualType();
}
@@ -9798,71 +9794,44 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
Destroyed);
}
-template <typename Derived>
-bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
- bool RequiresADL,
- LookupResult &R) {
+template<typename Derived>
+ExprResult
+TreeTransform<Derived>::TransformUnresolvedLookupExpr(
+ UnresolvedLookupExpr *Old) {
+ LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
+ Sema::LookupOrdinaryName);
+
// Transform all the decls.
- bool AllEmptyPacks = true;
- for (auto *OldD : Old->decls()) {
- Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
+ for (UnresolvedLookupExpr::decls_iterator I = Old->decls_begin(),
+ E = Old->decls_end(); I != E; ++I) {
+ NamedDecl *InstD = static_cast<NamedDecl*>(
+ getDerived().TransformDecl(Old->getNameLoc(),
+ *I));
if (!InstD) {
// Silently ignore these if a UsingShadowDecl instantiated to nothing.
// This can happen because of dependent hiding.
- if (isa<UsingShadowDecl>(OldD))
+ if (isa<UsingShadowDecl>(*I))
continue;
else {
R.clear();
- return true;
+ return ExprError();
}
}
- // Expand using pack declarations.
- ArrayRef<NamedDecl*> Decls = cast<NamedDecl>(InstD);
- if (auto *UPD = dyn_cast<UsingPackDecl>(InstD))
- Decls = UPD->expansions();
-
// Expand using declarations.
- for (auto *D : Decls) {
- if (auto *UD = dyn_cast<UsingDecl>(D)) {
- for (auto *SD : UD->shadows())
- R.addDecl(SD);
- } else {
- R.addDecl(D);
- }
+ if (isa<UsingDecl>(InstD)) {
+ UsingDecl *UD = cast<UsingDecl>(InstD);
+ for (auto *I : UD->shadows())
+ R.addDecl(I);
+ continue;
}
- AllEmptyPacks &= Decls.empty();
- };
-
- // C++ [temp.res]/8.4.2:
- // The program is ill-formed, no diagnostic required, if [...] lookup for
- // a name in the template definition found a using-declaration, but the
- // lookup in the corresponding scope in the instantiation odoes not find
- // any declarations because the using-declaration was a pack expansion and
- // the corresponding pack is empty
- if (AllEmptyPacks && !RequiresADL) {
- getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
- << isa<UnresolvedMemberExpr>(Old) << Old->getNameInfo().getName();
- return true;
+ R.addDecl(InstD);
}
// Resolve a kind, but don't do any further analysis. If it's
// ambiguous, the callee needs to deal with it.
R.resolveKind();
- return false;
-}
-
-template<typename Derived>
-ExprResult
-TreeTransform<Derived>::TransformUnresolvedLookupExpr(
- UnresolvedLookupExpr *Old) {
- LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
- Sema::LookupOrdinaryName);
-
- // Transform the declaration set.
- if (TransformOverloadExprDecls(Old, Old->requiresADL(), R))
- return ExprError();
// Rebuild the nested-name qualifier, if present.
CXXScopeSpec SS;
@@ -10730,9 +10699,35 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old)
LookupResult R(SemaRef, Old->getMemberNameInfo(),
Sema::LookupOrdinaryName);
- // Transform the declaration set.
- if (TransformOverloadExprDecls(Old, /*RequiresADL*/false, R))
- return ExprError();
+ // Transform all the decls.
+ for (UnresolvedMemberExpr::decls_iterator I = Old->decls_begin(),
+ E = Old->decls_end(); I != E; ++I) {
+ NamedDecl *InstD = static_cast<NamedDecl*>(
+ getDerived().TransformDecl(Old->getMemberLoc(),
+ *I));
+ if (!InstD) {
+ // Silently ignore these if a UsingShadowDecl instantiated to nothing.
+ // This can happen because of dependent hiding.
+ if (isa<UsingShadowDecl>(*I))
+ continue;
+ else {
+ R.clear();
+ return ExprError();
+ }
+ }
+
+ // Expand using declarations.
+ if (isa<UsingDecl>(InstD)) {
+ UsingDecl *UD = cast<UsingDecl>(InstD);
+ for (auto *I : UD->shadows())
+ R.addDecl(I);
+ continue;
+ }
+
+ R.addDecl(InstD);
+ }
+
+ R.resolveKind();
// Determine the naming class.
if (Old->getNamingClass()) {
@@ -11847,48 +11842,21 @@ QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
}
template<typename Derived>
-QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
- Decl *D) {
+QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(Decl *D) {
assert(D && "no decl found");
if (D->isInvalidDecl()) return QualType();
// FIXME: Doesn't account for ObjCInterfaceDecl!
TypeDecl *Ty;
- if (auto *UPD = dyn_cast<UsingPackDecl>(D)) {
- // A valid resolved using typename pack expansion decl can have multiple
- // UsingDecls, but they must each have exactly one type, and it must be
- // the same type in every case. But we must have at least one expansion!
- if (UPD->expansions().empty()) {
- getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
- << UPD->isCXXClassMember() << UPD;
- return QualType();
- }
-
- // We might still have some unresolved types. Try to pick a resolved type
- // if we can. The final instantiation will check that the remaining
- // unresolved types instantiate to the type we pick.
- QualType FallbackT;
- QualType T;
- for (auto *E : UPD->expansions()) {
- QualType ThisT = RebuildUnresolvedUsingType(Loc, E);
- if (ThisT.isNull())
- continue;
- else if (ThisT->getAs<UnresolvedUsingType>())
- FallbackT = ThisT;
- else if (T.isNull())
- T = ThisT;
- else
- assert(getSema().Context.hasSameType(ThisT, T) &&
- "mismatched resolved types in using pack expansion");
- }
- return T.isNull() ? FallbackT : T;
- } else if (auto *Using = dyn_cast<UsingDecl>(D)) {
+ if (isa<UsingDecl>(D)) {
+ UsingDecl *Using = cast<UsingDecl>(D);
assert(Using->hasTypename() &&
"UnresolvedUsingTypenameDecl transformed to non-typename using");
// A valid resolved using typename decl points to exactly one type decl.
assert(++Using->shadow_begin() == Using->shadow_end());
Ty = cast<TypeDecl>((*Using->shadow_begin())->getTargetDecl());
+
} else {
assert(isa<UnresolvedUsingTypenameDecl>(D) &&
"UnresolvedUsingTypenameDecl transformed to non-using decl");
OpenPOWER on IntegriCloud