diff options
author | Daniel Jasper <djasper@google.com> | 2016-12-19 10:09:25 +0000 |
---|---|---|
committer | Daniel Jasper <djasper@google.com> | 2016-12-19 10:09:25 +0000 |
commit | 9949ead55ad85698096af2fda29e8c6bb00a09b9 (patch) | |
tree | cb7551d743a7326e28591672cc19f3c5ff0a2004 /clang/lib/Sema | |
parent | 03b8be575e36f847387e314cfab75c2ae54e831f (diff) | |
download | bcm5719-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.cpp | 74 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 193 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateVariadic.cpp | 19 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 142 |
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"); |