diff options
author | Francis Visoiu Mistrih <francisvm@yahoo.com> | 2019-02-15 03:06:15 +0000 |
---|---|---|
committer | Francis Visoiu Mistrih <francisvm@yahoo.com> | 2019-02-15 03:06:15 +0000 |
commit | 0650f897a470730159d70e1617c9697c65b514d4 (patch) | |
tree | 9e225372c4c8af11e342f96517dee0e55cd8f962 /clang/lib | |
parent | 3fb7d4f55fa028ce57dbdf533835b583fc10ecf8 (diff) | |
download | bcm5719-llvm-0650f897a470730159d70e1617c9697c65b514d4.tar.gz bcm5719-llvm-0650f897a470730159d70e1617c9697c65b514d4.zip |
Revert "Fix implementation of [temp.local]p4."
This reverts commit 40bd10b770813bd1471d46f514545437516aa4ba.
This seems to now emit an error when building the sanitizer tests:
http://green.lab.llvm.org/green/job/clang-stage1-configure-RA/53965/consoleFull.
llvm-svn: 354097
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 18 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 142 |
4 files changed, 71 insertions, 112 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index d6e44af0ebe..a9e6eb12c0d 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1017,8 +1017,7 @@ Corrected: case LookupResult::Ambiguous: if (getLangOpts().CPlusPlus && NextToken.is(tok::less) && - hasAnyAcceptableTemplateNames(Result, /*AllowFunctionTemplates=*/true, - /*AllowDependent=*/false)) { + hasAnyAcceptableTemplateNames(Result)) { // C++ [temp.local]p3: // A lookup that finds an injected-class-name (10.2) can result in an // ambiguity in certain cases (for example, if it is found in more than @@ -1042,9 +1041,7 @@ Corrected: } if (getLangOpts().CPlusPlus && NextToken.is(tok::less) && - (IsFilteredTemplateName || - hasAnyAcceptableTemplateNames(Result, /*AllowFunctionTemplates=*/true, - /*AllowDependent=*/false))) { + (IsFilteredTemplateName || hasAnyAcceptableTemplateNames(Result))) { // C++ [temp.names]p3: // After name lookup (3.4) finds that a name is a template-name or that // an operator-function-id or a literal- operator-id refers to a set of @@ -1063,16 +1060,15 @@ Corrected: Template = Context.getOverloadedTemplateName(Result.begin(), Result.end()); } else { - auto *TD = cast<TemplateDecl>(getAsTemplateNameDecl( - *Result.begin(), /*AllowFunctionTemplates=*/true, - /*AllowDependent=*/false)); + TemplateDecl *TD + = cast<TemplateDecl>((*Result.begin())->getUnderlyingDecl()); IsFunctionTemplate = isa<FunctionTemplateDecl>(TD); IsVarTemplate = isa<VarTemplateDecl>(TD); if (SS.isSet() && !SS.isInvalid()) - Template = - Context.getQualifiedTemplateName(SS.getScopeRep(), - /*TemplateKeyword=*/false, TD); + Template = Context.getQualifiedTemplateName(SS.getScopeRep(), + /*TemplateKeyword=*/false, + TD); else Template = TemplateName(TD); } diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 7457d1cb022..8badbbd3ead 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1128,6 +1128,7 @@ static bool checkTupleLikeDecomposition(Sema &S, } } } + S.FilterAcceptableTemplateNames(MemberGet); } unsigned I = 0; diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 86960e0a1db..249be780985 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -2172,27 +2172,11 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, DeclContext::lookup_iterator FirstD = FirstPath->Decls.begin(); DeclContext::lookup_iterator CurrentD = Path->Decls.begin(); - // Get the decl that we should use for deduplicating this lookup. - auto GetRepresentativeDecl = [&](NamedDecl *D) -> Decl * { - // C++ [temp.local]p3: - // A lookup that finds an injected-class-name (10.2) can result in - // an ambiguity in certain cases (for example, if it is found in - // more than one base class). If all of the injected-class-names - // that are found refer to specializations of the same class - // template, and if the name is used as a template-name, the - // reference refers to the class template itself and not a - // specialization thereof, and is not ambiguous. - if (R.isTemplateNameLookup()) - if (auto *TD = getAsTemplateNameDecl(D)) - D = TD; - return D->getUnderlyingDecl()->getCanonicalDecl(); - }; - while (FirstD != FirstPath->Decls.end() && CurrentD != Path->Decls.end()) { - if (GetRepresentativeDecl(*FirstD) != - GetRepresentativeDecl(*CurrentD)) - break; + if ((*FirstD)->getUnderlyingDecl()->getCanonicalDecl() != + (*CurrentD)->getUnderlyingDecl()->getCanonicalDecl()) + break; ++FirstD; ++CurrentD; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 3f642b5c426..2e73096a9ba 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -66,20 +66,17 @@ static Expr *clang::formAssociatedConstraints(TemplateParameterList *Params, /// Determine whether the declaration found is acceptable as the name /// of a template and, if so, return that template declaration. Otherwise, -/// returns null. -/// -/// Note that this may return an UnresolvedUsingValueDecl if AllowDependent -/// is true. In all other cases it will return a TemplateDecl (or null). -NamedDecl *Sema::getAsTemplateNameDecl(NamedDecl *D, - bool AllowFunctionTemplates, - bool AllowDependent) { - D = D->getUnderlyingDecl(); +/// returns NULL. +static NamedDecl *isAcceptableTemplateName(ASTContext &Context, + NamedDecl *Orig, + bool AllowFunctionTemplates) { + NamedDecl *D = Orig->getUnderlyingDecl(); if (isa<TemplateDecl>(D)) { if (!AllowFunctionTemplates && isa<FunctionTemplateDecl>(D)) return nullptr; - return D; + return Orig; } if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) { @@ -110,29 +107,54 @@ NamedDecl *Sema::getAsTemplateNameDecl(NamedDecl *D, // 'using Dependent::foo;' can resolve to a template name. // 'using typename Dependent::foo;' cannot (not even if 'foo' is an // injected-class-name). - if (AllowDependent && isa<UnresolvedUsingValueDecl>(D)) + if (isa<UnresolvedUsingValueDecl>(D)) return D; return nullptr; } void Sema::FilterAcceptableTemplateNames(LookupResult &R, - bool AllowFunctionTemplates, - bool AllowDependent) { + bool AllowFunctionTemplates) { + // The set of class templates we've already seen. + llvm::SmallPtrSet<ClassTemplateDecl *, 8> ClassTemplates; LookupResult::Filter filter = R.makeFilter(); while (filter.hasNext()) { NamedDecl *Orig = filter.next(); - if (!getAsTemplateNameDecl(Orig, AllowFunctionTemplates, AllowDependent)) + NamedDecl *Repl = isAcceptableTemplateName(Context, Orig, + AllowFunctionTemplates); + if (!Repl) filter.erase(); + else if (Repl != Orig) { + + // C++ [temp.local]p3: + // A lookup that finds an injected-class-name (10.2) can result in an + // ambiguity in certain cases (for example, if it is found in more than + // one base class). If all of the injected-class-names that are found + // refer to specializations of the same class template, and if the name + // is used as a template-name, the reference refers to the class + // template itself and not a specialization thereof, and is not + // ambiguous. + if (ClassTemplateDecl *ClassTmpl = dyn_cast<ClassTemplateDecl>(Repl)) + if (!ClassTemplates.insert(ClassTmpl).second) { + filter.erase(); + continue; + } + + // FIXME: we promote access to public here as a workaround to + // the fact that LookupResult doesn't let us remember that we + // found this template through a particular injected class name, + // which means we end up doing nasty things to the invariants. + // Pretending that access is public is *much* safer. + filter.replace(Repl, AS_public); + } } filter.done(); } bool Sema::hasAnyAcceptableTemplateNames(LookupResult &R, - bool AllowFunctionTemplates, - bool AllowDependent) { + bool AllowFunctionTemplates) { for (LookupResult::iterator I = R.begin(), IEnd = R.end(); I != IEnd; ++I) - if (getAsTemplateNameDecl(*I, AllowFunctionTemplates, AllowDependent)) + if (isAcceptableTemplateName(Context, *I, AllowFunctionTemplates)) return true; return false; @@ -176,45 +198,20 @@ TemplateNameKind Sema::isTemplateName(Scope *S, MemberOfUnknownSpecialization)) return TNK_Non_template; if (R.empty()) return TNK_Non_template; - - NamedDecl *D = nullptr; if (R.isAmbiguous()) { - // If we got an ambiguity involving a non-function template, treat this - // as a template name, and pick an arbitrary template for error recovery. - bool AnyFunctionTemplates = false; - for (NamedDecl *FoundD : R) { - if (NamedDecl *FoundTemplate = getAsTemplateNameDecl(FoundD)) { - if (isa<FunctionTemplateDecl>(FoundTemplate)) - AnyFunctionTemplates = true; - else { - D = FoundTemplate; - break; - } - } - } - - // If we didn't find any templates at all, this isn't a template name. - // Leave the ambiguity for a later lookup to diagnose. - if (!D && !AnyFunctionTemplates) { - R.suppressDiagnostics(); - return TNK_Non_template; - } + // Suppress diagnostics; we'll redo this lookup later. + R.suppressDiagnostics(); - // If the only templates were function templates, filter out the rest. - // We'll diagnose the ambiguity later. - if (!D) - FilterAcceptableTemplateNames(R); + // FIXME: we might have ambiguous templates, in which case we + // should at least parse them properly! + return TNK_Non_template; } - // At this point, we have either picked a single template name declaration D - // or we have a non-empty set of results R containing either one template name - // declaration or a set of function templates. - TemplateName Template; TemplateNameKind TemplateKind; unsigned ResultCount = R.end() - R.begin(); - if (!D && ResultCount > 1) { + if (ResultCount > 1) { // We assume that we'll preserve the qualifier from a function // template name in other ways. Template = Context.getOverloadedTemplateName(R.begin(), R.end()); @@ -222,19 +219,12 @@ TemplateNameKind Sema::isTemplateName(Scope *S, // We'll do this lookup again later. R.suppressDiagnostics(); + } else if (isa<UnresolvedUsingValueDecl>((*R.begin())->getUnderlyingDecl())) { + // We don't yet know whether this is a template-name or not. + MemberOfUnknownSpecialization = true; + return TNK_Non_template; } else { - if (!D) { - D = getAsTemplateNameDecl(*R.begin()); - assert(D && "unambiguous result is not a template name"); - } - - if (isa<UnresolvedUsingValueDecl>(D)) { - // We don't yet know whether this is a template-name or not. - MemberOfUnknownSpecialization = true; - return TNK_Non_template; - } - - TemplateDecl *TD = cast<TemplateDecl>(D); + TemplateDecl *TD = cast<TemplateDecl>((*R.begin())->getUnderlyingDecl()); if (SS.isSet() && !SS.isInvalid()) { NestedNameSpecifier *Qualifier = SS.getScopeRep(); @@ -326,8 +316,6 @@ bool Sema::LookupTemplateName(LookupResult &Found, bool EnteringContext, bool &MemberOfUnknownSpecialization, SourceLocation TemplateKWLoc) { - Found.setTemplateNameLookup(true); - // Determine where to perform name lookup MemberOfUnknownSpecialization = false; DeclContext *LookupCtx = nullptr; @@ -402,9 +390,6 @@ bool Sema::LookupTemplateName(LookupResult &Found, IsDependent |= Found.wasNotFoundInCurrentInstantiation(); } - if (Found.isAmbiguous()) - return false; - if (Found.empty() && !IsDependent) { // If we did not find any names, attempt to correct any typos. DeclarationName Name = Found.getLookupName(); @@ -422,9 +407,7 @@ bool Sema::LookupTemplateName(LookupResult &Found, if (auto *ND = Corrected.getFoundDecl()) Found.addDecl(ND); FilterAcceptableTemplateNames(Found); - if (Found.isAmbiguous()) { - Found.clear(); - } else if (!Found.empty()) { + if (!Found.empty()) { if (LookupCtx) { std::string CorrectedStr(Corrected.getAsString(getLangOpts())); bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && @@ -474,19 +457,14 @@ bool Sema::LookupTemplateName(LookupResult &Found, // Note: C++11 does not perform this second lookup. LookupResult FoundOuter(*this, Found.getLookupName(), Found.getNameLoc(), LookupOrdinaryName); - FoundOuter.setTemplateNameLookup(true); LookupName(FoundOuter, S); - // FIXME: We silently accept an ambiguous lookup here, in violation of - // [basic.lookup]/1. FilterAcceptableTemplateNames(FoundOuter, /*AllowFunctionTemplates=*/false); - NamedDecl *OuterTemplate; if (FoundOuter.empty()) { // - if the name is not found, the name found in the class of the // object expression is used, otherwise - } else if (FoundOuter.isAmbiguous() || !FoundOuter.isSingleResult() || - !(OuterTemplate = - getAsTemplateNameDecl(FoundOuter.getFoundDecl()))) { + } else if (!FoundOuter.getAsSingle<ClassTemplateDecl>() || + FoundOuter.isAmbiguous()) { // - if the name is found in the context of the entire // postfix-expression and does not name a class template, the name // found in the class of the object expression is used, otherwise @@ -496,8 +474,8 @@ bool Sema::LookupTemplateName(LookupResult &Found, // entity as the one found in the class of the object expression, // otherwise the program is ill-formed. if (!Found.isSingleResult() || - getAsTemplateNameDecl(Found.getFoundDecl())->getCanonicalDecl() != - OuterTemplate->getCanonicalDecl()) { + Found.getFoundDecl()->getCanonicalDecl() + != FoundOuter.getFoundDecl()->getCanonicalDecl()) { Diag(Found.getNameLoc(), diag::ext_nested_name_member_ref_lookup_ambiguous) << Found.getLookupName() @@ -567,8 +545,7 @@ void Sema::diagnoseExprIntendedAsTemplateName(Scope *S, ExprResult TemplateName, // Try to correct the name by looking for templates and C++ named casts. struct TemplateCandidateFilter : CorrectionCandidateCallback { - Sema &S; - TemplateCandidateFilter(Sema &S) : S(S) { + TemplateCandidateFilter() { WantTypeSpecifiers = false; WantExpressionKeywords = false; WantRemainingKeywords = false; @@ -576,7 +553,7 @@ void Sema::diagnoseExprIntendedAsTemplateName(Scope *S, ExprResult TemplateName, }; bool ValidateCandidate(const TypoCorrection &Candidate) override { if (auto *ND = Candidate.getCorrectionDecl()) - return S.getAsTemplateNameDecl(ND); + return isAcceptableTemplateName(ND->getASTContext(), ND, true); return Candidate.isKeyword(); } }; @@ -584,11 +561,12 @@ void Sema::diagnoseExprIntendedAsTemplateName(Scope *S, ExprResult TemplateName, DeclarationName Name = NameInfo.getName(); if (TypoCorrection Corrected = CorrectTypo(NameInfo, LookupKind, S, &SS, - llvm::make_unique<TemplateCandidateFilter>(*this), + llvm::make_unique<TemplateCandidateFilter>(), CTK_ErrorRecovery, LookupCtx)) { auto *ND = Corrected.getFoundDecl(); if (ND) - ND = getAsTemplateNameDecl(ND); + ND = isAcceptableTemplateName(Context, ND, + /*AllowFunctionTemplates*/ true); if (ND || Corrected.isKeyword()) { if (LookupCtx) { std::string CorrectedStr(Corrected.getAsString(getLangOpts())); @@ -4284,7 +4262,7 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S, LookupOrdinaryName); bool MOUS; if (!LookupTemplateName(R, S, SS, ObjectType.get(), EnteringContext, - MOUS, TemplateKWLoc) && !R.isAmbiguous()) + MOUS, TemplateKWLoc)) Diag(Name.getBeginLoc(), diag::err_no_member) << DNI.getName() << LookupCtx << SS.getRange(); return TNK_Non_template; |