diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaCXXScopeSpec.cpp | 13 | ||||
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 62 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 40 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 44 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 52 | ||||
-rw-r--r-- | lib/Sema/SemaExprMember.cpp | 16 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 19 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/SemaLambda.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 43 | ||||
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 35 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 27 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateVariadic.cpp | 14 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 9 |
16 files changed, 237 insertions, 176 deletions
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index 2370c41997..93912dae03 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -429,8 +429,9 @@ namespace { // Callback to only accept typo corrections that can be a valid C++ member // intializer: either a non-static field member or a base class. -class NestedNameSpecifierValidatorCCC : public CorrectionCandidateCallback { - public: +class NestedNameSpecifierValidatorCCC final + : public CorrectionCandidateCallback { +public: explicit NestedNameSpecifierValidatorCCC(Sema &SRef) : SRef(SRef) {} @@ -438,6 +439,10 @@ class NestedNameSpecifierValidatorCCC : public CorrectionCandidateCallback { return SRef.isAcceptableNestedNameSpecifier(candidate.getCorrectionDecl()); } + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<NestedNameSpecifierValidatorCCC>(*this); + } + private: Sema &SRef; }; @@ -614,9 +619,9 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo, // different kind of error, so look for typos. DeclarationName Name = Found.getLookupName(); Found.clear(); + NestedNameSpecifierValidatorCCC CCC(*this); if (TypoCorrection Corrected = CorrectTypo( - Found.getLookupNameInfo(), Found.getLookupKind(), S, &SS, - llvm::make_unique<NestedNameSpecifierValidatorCCC>(*this), + Found.getLookupNameInfo(), Found.getLookupKind(), S, &SS, CCC, CTK_ErrorRecovery, LookupCtx, EnteringContext)) { if (LookupCtx) { bool DroppedSpecifier = diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 08b61e1987..0946a24676 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -6407,8 +6407,9 @@ void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, SourceLocation TemplateKWLoc; UnqualifiedId id; id.setIdentifier(Super, SuperLoc); - ExprResult SuperExpr = - ActOnIdExpression(S, SS, TemplateKWLoc, id, false, false); + ExprResult SuperExpr = ActOnIdExpression(S, SS, TemplateKWLoc, id, + /*HasTrailingLParen=*/false, + /*IsAddressOfOperand=*/false); return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(), SelIdents, AtArgumentExpression); } diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 4aa9dc25ac..92595f63f7 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -61,7 +61,7 @@ Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType) { namespace { -class TypeNameValidatorCCC : public CorrectionCandidateCallback { +class TypeNameValidatorCCC final : public CorrectionCandidateCallback { public: TypeNameValidatorCCC(bool AllowInvalid, bool WantClass = false, bool AllowTemplates = false, @@ -105,6 +105,10 @@ class TypeNameValidatorCCC : public CorrectionCandidateCallback { return !WantClassName && candidate.isKeyword(); } + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<TypeNameValidatorCCC>(*this); + } + private: bool AllowInvalidDecl; bool WantClassName; @@ -367,11 +371,10 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, case LookupResult::NotFound: case LookupResult::NotFoundInCurrentInstantiation: if (CorrectedII) { - TypoCorrection Correction = - CorrectTypo(Result.getLookupNameInfo(), Kind, S, SS, - llvm::make_unique<TypeNameValidatorCCC>( - true, isClassName, AllowDeducedTemplate), - CTK_ErrorRecovery); + TypeNameValidatorCCC CCC(/*AllowInvalid=*/true, isClassName, + AllowDeducedTemplate); + TypoCorrection Correction = CorrectTypo(Result.getLookupNameInfo(), Kind, + S, SS, CCC, CTK_ErrorRecovery); IdentifierInfo *NewII = Correction.getCorrectionAsIdentifierInfo(); TemplateTy Template; bool MemberOfUnknownSpecialization; @@ -664,11 +667,12 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II, // There may have been a typo in the name of the type. Look up typo // results, in case we have something that we can suggest. + TypeNameValidatorCCC CCC(/*AllowInvalid=*/false, /*WantClass=*/false, + /*AllowTemplates=*/IsTemplateName, + /*AllowNonTemplates=*/!IsTemplateName); if (TypoCorrection Corrected = CorrectTypo(DeclarationNameInfo(II, IILoc), LookupOrdinaryName, S, SS, - llvm::make_unique<TypeNameValidatorCCC>( - false, false, IsTemplateName, !IsTemplateName), - CTK_ErrorRecovery)) { + CCC, CTK_ErrorRecovery)) { // FIXME: Support error recovery for the template-name case. bool CanRecover = !IsTemplateName; if (Corrected.isKeyword()) { @@ -843,8 +847,7 @@ static ParsedType buildNestedType(Sema &S, CXXScopeSpec &SS, Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, SourceLocation NameLoc, const Token &NextToken, - bool IsAddressOfOperand, - std::unique_ptr<CorrectionCandidateCallback> CCC) { + bool IsAddressOfOperand, CorrectionCandidateCallback *CCC) { DeclarationNameInfo NameInfo(Name, NameLoc); ObjCMethodDecl *CurMethod = getCurMethodDecl(); @@ -926,10 +929,9 @@ Corrected: // close to this name. if (!SecondTry && CCC) { SecondTry = true; - if (TypoCorrection Corrected = CorrectTypo(Result.getLookupNameInfo(), - Result.getLookupKind(), S, - &SS, std::move(CCC), - CTK_ErrorRecovery)) { + if (TypoCorrection Corrected = + CorrectTypo(Result.getLookupNameInfo(), Result.getLookupKind(), S, + &SS, *CCC, CTK_ErrorRecovery)) { unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest; unsigned QualifiedDiag = diag::err_no_member_suggest; @@ -1865,10 +1867,10 @@ ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id, if (!IDecl && DoTypoCorrection) { // Perform typo correction at the given location, but only if we // find an Objective-C class name. - if (TypoCorrection C = CorrectTypo( - DeclarationNameInfo(Id, IdLoc), LookupOrdinaryName, TUScope, nullptr, - llvm::make_unique<DeclFilterCCC<ObjCInterfaceDecl>>(), - CTK_ErrorRecovery)) { + DeclFilterCCC<ObjCInterfaceDecl> CCC{}; + if (TypoCorrection C = + CorrectTypo(DeclarationNameInfo(Id, IdLoc), LookupOrdinaryName, + TUScope, nullptr, CCC, CTK_ErrorRecovery)) { diagnoseTypo(C, PDiag(diag::err_undef_interface_suggest) << Id); IDecl = C.getCorrectionDeclAs<ObjCInterfaceDecl>(); Id = IDecl->getIdentifier(); @@ -7688,7 +7690,7 @@ namespace { // Callback to only accept typo corrections that have a non-zero edit distance. // Also only accept corrections that have the same parent decl. -class DifferentNameValidatorCCC : public CorrectionCandidateCallback { +class DifferentNameValidatorCCC final : public CorrectionCandidateCallback { public: DifferentNameValidatorCCC(ASTContext &Context, FunctionDecl *TypoFD, CXXRecordDecl *Parent) @@ -7720,6 +7722,10 @@ class DifferentNameValidatorCCC : public CorrectionCandidateCallback { return false; } + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<DifferentNameValidatorCCC>(*this); + } + private: ASTContext &Context; FunctionDecl *OriginalFD; @@ -7767,6 +7773,8 @@ static NamedDecl *DiagnoseInvalidRedeclaration( assert(!Prev.isAmbiguous() && "Cannot have an ambiguity in previous-declaration lookup"); CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD); + DifferentNameValidatorCCC CCC(SemaRef.Context, NewFD, + MD ? MD->getParent() : nullptr); if (!Prev.empty()) { for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end(); Func != FuncEnd; ++Func) { @@ -7783,10 +7791,8 @@ static NamedDecl *DiagnoseInvalidRedeclaration( // If the qualified name lookup yielded nothing, try typo correction } else if ((Correction = SemaRef.CorrectTypo( Prev.getLookupNameInfo(), Prev.getLookupKind(), S, - &ExtraArgs.D.getCXXScopeSpec(), - llvm::make_unique<DifferentNameValidatorCCC>( - SemaRef.Context, NewFD, MD ? MD->getParent() : nullptr), - Sema::CTK_ErrorRecovery, IsLocalFriend ? nullptr : NewDC))) { + &ExtraArgs.D.getCXXScopeSpec(), CCC, Sema::CTK_ErrorRecovery, + IsLocalFriend ? nullptr : NewDC))) { // Set up everything for the call to ActOnFunctionDeclarator ExtraArgs.D.SetIdentifier(Correction.getCorrectionAsIdentifierInfo(), ExtraArgs.D.getIdentifierLoc()); @@ -13538,10 +13544,10 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, // function declaration is going to be treated as an error. if (Diags.getDiagnosticLevel(diag_id, Loc) >= DiagnosticsEngine::Error) { TypoCorrection Corrected; - if (S && - (Corrected = CorrectTypo( - DeclarationNameInfo(&II, Loc), LookupOrdinaryName, S, nullptr, - llvm::make_unique<DeclFilterCCC<FunctionDecl>>(), CTK_NonError))) + DeclFilterCCC<FunctionDecl> CCC{}; + if (S && (Corrected = + CorrectTypo(DeclarationNameInfo(&II, Loc), LookupOrdinaryName, + S, nullptr, CCC, CTK_NonError))) diagnoseTypo(Corrected, PDiag(diag::note_function_suggestion), /*ErrorRecovery*/false); } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 55e176f4c7..9f9e117ab9 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -3781,7 +3781,7 @@ namespace { // Callback to only accept typo corrections that can be a valid C++ member // intializer: either a non-static field member or a base class. -class MemInitializerValidatorCCC : public CorrectionCandidateCallback { +class MemInitializerValidatorCCC final : public CorrectionCandidateCallback { public: explicit MemInitializerValidatorCCC(CXXRecordDecl *ClassDecl) : ClassDecl(ClassDecl) {} @@ -3795,6 +3795,10 @@ public: return false; } + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<MemInitializerValidatorCCC>(*this); + } + private: CXXRecordDecl *ClassDecl; }; @@ -3924,11 +3928,10 @@ Sema::BuildMemInitializer(Decl *ConstructorD, // If no results were found, try to correct typos. TypoCorrection Corr; + MemInitializerValidatorCCC CCC(ClassDecl); if (R.empty() && BaseType.isNull() && - (Corr = CorrectTypo( - R.getLookupNameInfo(), R.getLookupKind(), S, &SS, - llvm::make_unique<MemInitializerValidatorCCC>(ClassDecl), - CTK_ErrorRecovery, ClassDecl))) { + (Corr = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS, + CCC, CTK_ErrorRecovery, ClassDecl))) { if (FieldDecl *Member = Corr.getCorrectionDeclAs<FieldDecl>()) { // We have found a non-static data member with a similar // name to what was typed; complain and initialize that @@ -9353,13 +9356,17 @@ static bool IsUsingDirectiveInToplevelContext(DeclContext *CurContext) { namespace { // Callback to only accept typo corrections that are namespaces. -class NamespaceValidatorCCC : public CorrectionCandidateCallback { +class NamespaceValidatorCCC final : public CorrectionCandidateCallback { public: bool ValidateCandidate(const TypoCorrection &candidate) override { if (NamedDecl *ND = candidate.getCorrectionDecl()) return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND); return false; } + + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<NamespaceValidatorCCC>(*this); + } }; } @@ -9369,9 +9376,9 @@ static bool TryNamespaceTypoCorrection(Sema &S, LookupResult &R, Scope *Sc, SourceLocation IdentLoc, IdentifierInfo *Ident) { R.clear(); + NamespaceValidatorCCC CCC{}; if (TypoCorrection Corrected = - S.CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), Sc, &SS, - llvm::make_unique<NamespaceValidatorCCC>(), + S.CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), Sc, &SS, CCC, Sema::CTK_ErrorRecovery)) { if (DeclContext *DC = S.computeDeclContext(SS, false)) { std::string CorrectedStr(Corrected.getAsString(S.getLangOpts())); @@ -9866,7 +9873,7 @@ static CXXBaseSpecifier *findDirectBaseWithType(CXXRecordDecl *Derived, } namespace { -class UsingValidatorCCC : public CorrectionCandidateCallback { +class UsingValidatorCCC final : public CorrectionCandidateCallback { public: UsingValidatorCCC(bool HasTypenameKeyword, bool IsInstantiation, NestedNameSpecifier *NNS, CXXRecordDecl *RequireMemberOf) @@ -9936,6 +9943,10 @@ public: return !HasTypenameKeyword; } + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<UsingValidatorCCC>(*this); + } + private: bool HasTypenameKeyword; bool IsInstantiation; @@ -10092,12 +10103,11 @@ NamedDecl *Sema::BuildUsingDeclaration( isa<TranslationUnitDecl>(LookupContext) && getSourceManager().isInSystemHeader(UsingLoc)) return nullptr; - if (TypoCorrection Corrected = CorrectTypo( - R.getLookupNameInfo(), R.getLookupKind(), S, &SS, - llvm::make_unique<UsingValidatorCCC>( - HasTypenameKeyword, IsInstantiation, SS.getScopeRep(), - dyn_cast<CXXRecordDecl>(CurContext)), - CTK_ErrorRecovery)) { + UsingValidatorCCC CCC(HasTypenameKeyword, IsInstantiation, SS.getScopeRep(), + dyn_cast<CXXRecordDecl>(CurContext)); + if (TypoCorrection Corrected = + CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS, CCC, + CTK_ErrorRecovery)) { // We reject candidates where DroppedSpecifier == true, hence the // literal '0' below. diagnoseTypo(Corrected, PDiag(diag::err_no_member_suggest) diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 76b2129211..7fa561012f 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -499,7 +499,7 @@ namespace { // Callback to only accept typo corrections that are Objective-C classes. // If an ObjCInterfaceDecl* is given to the constructor, then the validation // function will reject corrections to that class. -class ObjCInterfaceValidatorCCC : public CorrectionCandidateCallback { +class ObjCInterfaceValidatorCCC final : public CorrectionCandidateCallback { public: ObjCInterfaceValidatorCCC() : CurrentIDecl(nullptr) {} explicit ObjCInterfaceValidatorCCC(ObjCInterfaceDecl *IDecl) @@ -510,6 +510,10 @@ class ObjCInterfaceValidatorCCC : public CorrectionCandidateCallback { return ID && !declaresSameEntity(ID, CurrentIDecl); } + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<ObjCInterfaceValidatorCCC>(*this); + } + private: ObjCInterfaceDecl *CurrentIDecl; }; @@ -549,11 +553,10 @@ ActOnSuperClassOfClassInterface(Scope *S, if (!PrevDecl) { // Try to correct for a typo in the superclass name without correcting // to the class we're defining. + ObjCInterfaceValidatorCCC CCC(IDecl); if (TypoCorrection Corrected = CorrectTypo( - DeclarationNameInfo(SuperName, SuperLoc), - LookupOrdinaryName, TUScope, - nullptr, llvm::make_unique<ObjCInterfaceValidatorCCC>(IDecl), - CTK_ErrorRecovery)) { + DeclarationNameInfo(SuperName, SuperLoc), LookupOrdinaryName, + TUScope, nullptr, CCC, CTK_ErrorRecovery)) { diagnoseTypo(Corrected, PDiag(diag::err_undef_superclass_suggest) << SuperName << ClassName); PrevDecl = Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>(); @@ -1292,11 +1295,10 @@ Sema::FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, for (const IdentifierLocPair &Pair : ProtocolId) { ObjCProtocolDecl *PDecl = LookupProtocol(Pair.first, Pair.second); if (!PDecl) { + DeclFilterCCC<ObjCProtocolDecl> CCC{}; TypoCorrection Corrected = CorrectTypo( - DeclarationNameInfo(Pair.first, Pair.second), - LookupObjCProtocolName, TUScope, nullptr, - llvm::make_unique<DeclFilterCCC<ObjCProtocolDecl>>(), - CTK_ErrorRecovery); + DeclarationNameInfo(Pair.first, Pair.second), LookupObjCProtocolName, + TUScope, nullptr, CCC, CTK_ErrorRecovery); if ((PDecl = Corrected.getCorrectionDeclAs<ObjCProtocolDecl>())) diagnoseTypo(Corrected, PDiag(diag::err_undeclared_protocol_suggest) << Pair.first); @@ -1334,7 +1336,8 @@ Sema::FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, namespace { // Callback to only accept typo corrections that are either // Objective-C protocols or valid Objective-C type arguments. -class ObjCTypeArgOrProtocolValidatorCCC : public CorrectionCandidateCallback { +class ObjCTypeArgOrProtocolValidatorCCC final + : public CorrectionCandidateCallback { ASTContext &Context; Sema::LookupNameKind LookupKind; public: @@ -1381,6 +1384,10 @@ class ObjCTypeArgOrProtocolValidatorCCC : public CorrectionCandidateCallback { return false; } + + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<ObjCTypeArgOrProtocolValidatorCCC>(*this); + } }; } // end anonymous namespace @@ -1670,12 +1677,10 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( } // Perform typo correction on the name. - TypoCorrection corrected = CorrectTypo( - DeclarationNameInfo(identifiers[i], identifierLocs[i]), lookupKind, S, - nullptr, - llvm::make_unique<ObjCTypeArgOrProtocolValidatorCCC>(Context, - lookupKind), - CTK_ErrorRecovery); + ObjCTypeArgOrProtocolValidatorCCC CCC(Context, lookupKind); + TypoCorrection corrected = + CorrectTypo(DeclarationNameInfo(identifiers[i], identifierLocs[i]), + lookupKind, S, nullptr, CCC, CTK_ErrorRecovery); if (corrected) { // Did we find a protocol? if (auto proto = corrected.getCorrectionDeclAs<ObjCProtocolDecl>()) { @@ -1967,9 +1972,10 @@ Decl *Sema::ActOnStartClassImplementation( } else { // We did not find anything with the name ClassName; try to correct for // typos in the class name. - TypoCorrection Corrected = CorrectTypo( - DeclarationNameInfo(ClassName, ClassLoc), LookupOrdinaryName, TUScope, - nullptr, llvm::make_unique<ObjCInterfaceValidatorCCC>(), CTK_NonError); + ObjCInterfaceValidatorCCC CCC{}; + TypoCorrection Corrected = + CorrectTypo(DeclarationNameInfo(ClassName, ClassLoc), + LookupOrdinaryName, TUScope, nullptr, CCC, CTK_NonError); if (Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) { // Suggest the (potentially) correct interface name. Don't provide a // code-modification hint or use the typo name for recovery, because diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 3af87b6fd4..29b8bff947 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -911,8 +911,9 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, UnqualifiedId Name; Name.setIdentifier(PP.getIdentifierInfo("__builtin_trap"), E->getBeginLoc()); - ExprResult TrapFn = ActOnIdExpression(TUScope, SS, TemplateKWLoc, - Name, true, false); + ExprResult TrapFn = ActOnIdExpression(TUScope, SS, TemplateKWLoc, Name, + /*HasTrailingLParen=*/true, + /*IsAddressOfOperand=*/false); if (TrapFn.isInvalid()) return ExprError(); @@ -1905,11 +1906,10 @@ static void emitEmptyLookupTypoDiagnostic( /// Diagnose an empty lookup. /// /// \return false if new lookup candidates were found -bool -Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, - std::unique_ptr<CorrectionCandidateCallback> CCC, - TemplateArgumentListInfo *ExplicitTemplateArgs, - ArrayRef<Expr *> Args, TypoExpr **Out) { +bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, + CorrectionCandidateCallback &CCC, + TemplateArgumentListInfo *ExplicitTemplateArgs, + ArrayRef<Expr *> Args, TypoExpr **Out) { DeclarationName Name = R.getLookupName(); unsigned diagnostic = diag::err_undeclared_var_use; @@ -1998,7 +1998,7 @@ Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, assert(!ExplicitTemplateArgs && "Diagnosing an empty lookup with explicit template args!"); *Out = CorrectTypoDelayed( - R.getLookupNameInfo(), R.getLookupKind(), S, &SS, std::move(CCC), + R.getLookupNameInfo(), R.getLookupKind(), S, &SS, CCC, [=](const TypoCorrection &TC) { emitEmptyLookupTypoDiagnostic(TC, *this, SS, Name, TypoLoc, Args, diagnostic, diagnostic_suggest); @@ -2006,9 +2006,9 @@ Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, nullptr, CTK_ErrorRecovery); if (*Out) return true; - } else if (S && (Corrected = - CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, - &SS, std::move(CCC), CTK_ErrorRecovery))) { + } else if (S && + (Corrected = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), + S, &SS, CCC, CTK_ErrorRecovery))) { std::string CorrectedStr(Corrected.getAsString(getLangOpts())); bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && Name.getAsString() == CorrectedStr; @@ -2157,7 +2157,7 @@ ExprResult Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, - std::unique_ptr<CorrectionCandidateCallback> CCC, + CorrectionCandidateCallback *CCC, bool IsInlineAsmIdentifier, Token *KeywordReplacement) { assert(!(IsAddressOfOperand && HasTrailingLParen) && "cannot be direct & operand and have a trailing lparen"); @@ -2279,9 +2279,9 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, // If this name wasn't predeclared and if this is not a function // call, diagnose the problem. TypoExpr *TE = nullptr; - auto DefaultValidator = llvm::make_unique<CorrectionCandidateCallback>( - II, SS.isValid() ? SS.getScopeRep() : nullptr); - DefaultValidator->IsAddressOfOperand = IsAddressOfOperand; + DefaultFilterCCC DefaultValidator(II, SS.isValid() ? SS.getScopeRep() + : nullptr); + DefaultValidator.IsAddressOfOperand = IsAddressOfOperand; assert((!CCC || CCC->IsAddressOfOperand == IsAddressOfOperand) && "Typo correction callback misconfigured"); if (CCC) { @@ -2293,9 +2293,8 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, // FIXME: DiagnoseEmptyLookup produces bad diagnostics if we're looking for // a template name, but we happen to have always already looked up the name // before we get here if it must be a template name. - if (DiagnoseEmptyLookup(S, SS, R, - CCC ? std::move(CCC) : std::move(DefaultValidator), - nullptr, None, &TE)) { + if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator, nullptr, + None, &TE)) { if (TE && KeywordReplacement) { auto &State = getTypoExprState(TE); auto BestTC = State.Consumer->getNextCorrection(); @@ -2549,8 +2548,10 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, SelfName.setKind(UnqualifiedIdKind::IK_ImplicitSelfParam); CXXScopeSpec SelfScopeSpec; SourceLocation TemplateKWLoc; - ExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, - SelfName, false, false); + ExprResult SelfExpr = + ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, SelfName, + /*HasTrailingLParen=*/false, + /*IsAddressOfOperand=*/false); if (SelfExpr.isInvalid()) return ExprError(); @@ -4893,7 +4894,7 @@ Sema::getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto, } namespace { -class FunctionCallCCC : public FunctionCallFilterCCC { +class FunctionCallCCC final : public FunctionCallFilterCCC { public: FunctionCallCCC(Sema &SemaRef, const IdentifierInfo *FuncName, unsigned NumArgs, MemberExpr *ME) @@ -4909,6 +4910,10 @@ public: return FunctionCallFilterCCC::ValidateCandidate(candidate); } + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<FunctionCallCCC>(*this); + } + private: const IdentifierInfo *const FunctionName; }; @@ -4921,11 +4926,10 @@ static TypoCorrection TryTypoCorrectionForCall(Sema &S, Expr *Fn, DeclarationName FuncName = FDecl->getDeclName(); SourceLocation NameLoc = ME ? ME->getMemberLoc() : Fn->getBeginLoc(); + FunctionCallCCC CCC(S, FuncName.getAsIdentifierInfo(), Args.size(), ME); if (TypoCorrection Corrected = S.CorrectTypo( DeclarationNameInfo(FuncName, NameLoc), Sema::LookupOrdinaryName, - S.getScopeForContext(S.CurContext), nullptr, - llvm::make_unique<FunctionCallCCC>(S, FuncName.getAsIdentifierInfo(), - Args.size(), ME), + S.getScopeForContext(S.CurContext), nullptr, CCC, Sema::CTK_ErrorRecovery)) { if (NamedDecl *ND = Corrected.getFoundDecl()) { if (Corrected.isOverloaded()) { diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index 2f9c8d6ee2..b07bba5584 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -590,7 +590,7 @@ namespace { // Callback to only accept typo corrections that are either a ValueDecl or a // FunctionTemplateDecl and are declared in the current record or, for a C++ // classes, one of its base classes. -class RecordMemberExprValidatorCCC : public CorrectionCandidateCallback { +class RecordMemberExprValidatorCCC final : public CorrectionCandidateCallback { public: explicit RecordMemberExprValidatorCCC(const RecordType *RTy) : Record(RTy->getDecl()) { @@ -628,6 +628,10 @@ public: return false; } + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<RecordMemberExprValidatorCCC>(*this); + } + private: const RecordDecl *const Record; }; @@ -696,9 +700,9 @@ static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, }; QueryState Q = {R.getSema(), R.getLookupNameInfo(), R.getLookupKind(), R.redeclarationKind()}; + RecordMemberExprValidatorCCC CCC(RTy); TE = SemaRef.CorrectTypoDelayed( - R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS, - llvm::make_unique<RecordMemberExprValidatorCCC>(RTy), + R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS, CCC, [=, &SemaRef](const TypoCorrection &TC) { if (TC) { assert(!TC.isKeyword() && @@ -1331,11 +1335,11 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, if (!IV) { // Attempt to correct for typos in ivar names. - auto Validator = llvm::make_unique<DeclFilterCCC<ObjCIvarDecl>>(); - Validator->IsObjCIvarLookup = IsArrow; + DeclFilterCCC<ObjCIvarDecl> Validator{}; + Validator.IsObjCIvarLookup = IsArrow; if (TypoCorrection Corrected = S.CorrectTypo( R.getLookupNameInfo(), Sema::LookupMemberName, nullptr, nullptr, - std::move(Validator), Sema::CTK_ErrorRecovery, IDecl)) { + Validator, Sema::CTK_ErrorRecovery, IDecl)) { IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>(); S.diagnoseTypo( Corrected, diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index d6c656e06b..818a981b49 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -1946,11 +1946,10 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, } // Attempt to correct for typos in property names. - if (TypoCorrection Corrected = - CorrectTypo(DeclarationNameInfo(MemberName, MemberLoc), - LookupOrdinaryName, nullptr, nullptr, - llvm::make_unique<DeclFilterCCC<ObjCPropertyDecl>>(), - CTK_ErrorRecovery, IFace, false, OPT)) { + DeclFilterCCC<ObjCPropertyDecl> CCC{}; + if (TypoCorrection Corrected = CorrectTypo( + DeclarationNameInfo(MemberName, MemberLoc), LookupOrdinaryName, + nullptr, nullptr, CCC, CTK_ErrorRecovery, IFace, false, OPT)) { DeclarationName TypoResult = Corrected.getCorrection(); if (TypoResult.isIdentifier() && TypoResult.getAsIdentifierInfo() == Member) { @@ -2107,7 +2106,7 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, namespace { -class ObjCInterfaceOrSuperCCC : public CorrectionCandidateCallback { +class ObjCInterfaceOrSuperCCC final : public CorrectionCandidateCallback { public: ObjCInterfaceOrSuperCCC(ObjCMethodDecl *Method) { // Determine whether "super" is acceptable in the current context. @@ -2119,6 +2118,10 @@ class ObjCInterfaceOrSuperCCC : public CorrectionCandidateCallback { return candidate.getCorrectionDeclAs<ObjCInterfaceDecl>() || candidate.isKeyword("super"); } + + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<ObjCInterfaceOrSuperCCC>(*this); + } }; } // end anonymous namespace @@ -2194,9 +2197,9 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S, } } + ObjCInterfaceOrSuperCCC CCC(getCurMethodDecl()); if (TypoCorrection Corrected = CorrectTypo( - Result.getLookupNameInfo(), Result.getLookupKind(), S, nullptr, - llvm::make_unique<ObjCInterfaceOrSuperCCC>(getCurMethodDecl()), + Result.getLookupNameInfo(), Result.getLookupKind(), S, nullptr, CCC, CTK_ErrorRecovery, nullptr, false, nullptr, false)) { if (Corrected.isKeyword()) { // If we've found the keyword "super" (the only keyword that would be diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 090192e2ac..24786886da 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -2208,7 +2208,7 @@ namespace { // Callback to only accept typo corrections that are for field members of // the given struct or union. -class FieldInitializerValidatorCCC : public CorrectionCandidateCallback { +class FieldInitializerValidatorCCC final : public CorrectionCandidateCallback { public: explicit FieldInitializerValidatorCCC(RecordDecl *RD) : Record(RD) {} @@ -2218,6 +2218,10 @@ class FieldInitializerValidatorCCC : public CorrectionCandidateCallback { return FD && FD->getDeclContext()->getRedeclContext()->Equals(Record); } + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<FieldInitializerValidatorCCC>(*this); + } + private: RecordDecl *Record; }; @@ -2420,10 +2424,10 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, // Name lookup didn't find anything. // Determine whether this was a typo for another field name. + FieldInitializerValidatorCCC CCC(RT->getDecl()); if (TypoCorrection Corrected = SemaRef.CorrectTypo( DeclarationNameInfo(FieldName, D->getFieldLoc()), - Sema::LookupMemberName, /*Scope=*/nullptr, /*SS=*/nullptr, - llvm::make_unique<FieldInitializerValidatorCCC>(RT->getDecl()), + Sema::LookupMemberName, /*Scope=*/nullptr, /*SS=*/nullptr, CCC, Sema::CTK_ErrorRecovery, RT->getDecl())) { SemaRef.diagnoseTypo( Corrected, diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 4ed9fdc359..5ec05b1ba0 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -1079,8 +1079,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, if (R.empty()) { // FIXME: Disable corrections that would add qualification? CXXScopeSpec ScopeSpec; - if (DiagnoseEmptyLookup(CurScope, ScopeSpec, R, - llvm::make_unique<DeclFilterCCC<VarDecl>>())) + DeclFilterCCC<VarDecl> Validator{}; + if (DiagnoseEmptyLookup(CurScope, ScopeSpec, R, Validator)) continue; } diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 86960e0a1d..f27a9591dd 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -4572,8 +4572,7 @@ static void AddKeywordsToConsumer(Sema &SemaRef, std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer( const DeclarationNameInfo &TypoName, Sema::LookupNameKind LookupKind, - Scope *S, CXXScopeSpec *SS, - std::unique_ptr<CorrectionCandidateCallback> CCC, + Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, DeclContext *MemberContext, bool EnteringContext, const ObjCObjectPointerType *OPT, bool ErrorRecovery) { @@ -4635,9 +4634,13 @@ std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer( TypoName.getBeginLoc()); } - CorrectionCandidateCallback &CCCRef = *CCC; + // Extend the lifetime of the callback. We delayed this until here + // to avoid allocations in the hot path (which is where no typo correction + // occurs). Note that CorrectionCandidateCallback is polymorphic and + // initially stack-allocated. + std::unique_ptr<CorrectionCandidateCallback> ClonedCCC = CCC.clone(); auto Consumer = llvm::make_unique<TypoCorrectionConsumer>( - *this, TypoName, LookupKind, S, SS, std::move(CCC), MemberContext, + *this, TypoName, LookupKind, S, SS, std::move(ClonedCCC), MemberContext, EnteringContext); // Perform name lookup to find visible, similarly-named entities. @@ -4689,7 +4692,9 @@ std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer( } } - AddKeywordsToConsumer(*this, *Consumer, S, CCCRef, SS && SS->isNotEmpty()); + AddKeywordsToConsumer(*this, *Consumer, S, + *Consumer->getCorrectionValidator(), + SS && SS->isNotEmpty()); // Build the NestedNameSpecifiers for the KnownNamespaces, if we're going // to search those namespaces. @@ -4743,19 +4748,18 @@ std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer( TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, - std::unique_ptr<CorrectionCandidateCallback> CCC, + CorrectionCandidateCallback &CCC, CorrectTypoKind Mode, DeclContext *MemberContext, bool EnteringContext, const ObjCObjectPointerType *OPT, bool RecordFailure) { - assert(CCC && "CorrectTypo requires a CorrectionCandidateCallback"); - // Always let the ExternalSource have the first chance at correction, even // if we would otherwise have given up. if (ExternalSource) { - if (TypoCorrection Correction = ExternalSource->CorrectTypo( - TypoName, LookupKind, S, SS, *CCC, MemberContext, EnteringContext, OPT)) + if (TypoCorrection Correction = + ExternalSource->CorrectTypo(TypoName, LookupKind, S, SS, CCC, + MemberContext, EnteringContext, OPT)) return Correction; } @@ -4763,12 +4767,12 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, // WantObjCSuper is only true for CTC_ObjCMessageReceiver and for // some instances of CTC_Unknown, while WantRemainingKeywords is true // for CTC_Unknown but not for CTC_ObjCMessageReceiver. - bool ObjCMessageReceiver = CCC->WantObjCSuper && !CCC->WantRemainingKeywords; + bool ObjCMessageReceiver = CCC.WantObjCSuper && !CCC.WantRemainingKeywords; IdentifierInfo *Typo = TypoName.getName().getAsIdentifierInfo(); - auto Consumer = makeTypoCorrectionConsumer( - TypoName, LookupKind, S, SS, std::move(CCC), MemberContext, - EnteringContext, OPT, Mode == CTK_ErrorRecovery); + auto Consumer = makeTypoCorrectionConsumer(TypoName, LookupKind, S, SS, CCC, + MemberContext, EnteringContext, + OPT, Mode == CTK_ErrorRecovery); if (!Consumer) return TypoCorrection(); @@ -4878,16 +4882,13 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, /// needed. TypoExpr *Sema::CorrectTypoDelayed( const DeclarationNameInfo &TypoName, Sema::LookupNameKind LookupKind, - Scope *S, CXXScopeSpec *SS, - std::unique_ptr<CorrectionCandidateCallback> CCC, + Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, TypoDiagnosticGenerator TDG, TypoRecoveryCallback TRC, CorrectTypoKind Mode, DeclContext *MemberContext, bool EnteringContext, const ObjCObjectPointerType *OPT) { - assert(CCC && "CorrectTypoDelayed requires a CorrectionCandidateCallback"); - - auto Consumer = makeTypoCorrectionConsumer( - TypoName, LookupKind, S, SS, std::move(CCC), MemberContext, - EnteringContext, OPT, Mode == CTK_ErrorRecovery); + auto Consumer = makeTypoCorrectionConsumer(TypoName, LookupKind, S, SS, CCC, + MemberContext, EnteringContext, + OPT, Mode == CTK_ErrorRecovery); // Give the external sema source a chance to correct the typo. TypoCorrection ExternalTypo; diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index f541d75ce5..dbccb69aad 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -1955,6 +1955,11 @@ public: } return false; } + + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<VarDeclFilterCCC>(*this); + } + }; class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { @@ -1972,6 +1977,10 @@ public: } return false; } + + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<VarOrFuncDeclFilterCCC>(*this); + } }; } // namespace @@ -1988,9 +1997,10 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, VarDecl *VD; if (!Lookup.isSingleResult()) { - if (TypoCorrection Corrected = CorrectTypo( - Id, LookupOrdinaryName, CurScope, nullptr, - llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { + VarDeclFilterCCC CCC(*this); + if (TypoCorrection Corrected = + CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, + CTK_ErrorRecovery)) { diagnoseTypo(Corrected, PDiag(Lookup.empty() ? diag::err_undeclared_var_use_suggest @@ -14379,9 +14389,9 @@ void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, Lookup.suppressDiagnostics(); if (!Lookup.isSingleResult()) { + VarOrFuncDeclFilterCCC CCC(*this); if (TypoCorrection Corrected = - CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, - llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), + CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, CTK_ErrorRecovery)) { diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) << Id.getName()); diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 2f6f94313b..eea9298a56 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -11892,15 +11892,6 @@ public: } -static std::unique_ptr<CorrectionCandidateCallback> -MakeValidator(Sema &SemaRef, MemberExpr *ME, size_t NumArgs, - bool HasTemplateArgs, bool AllowTypoCorrection) { - if (!AllowTypoCorrection) - return llvm::make_unique<NoTypoCorrectionCCC>(); - return llvm::make_unique<FunctionCallFilterCCC>(SemaRef, NumArgs, - HasTemplateArgs, ME); -} - /// Attempts to recover from a call where no functions were found. /// /// Returns true if new candidates were found. @@ -11935,16 +11926,22 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(), Sema::LookupOrdinaryName); bool DoDiagnoseEmptyLookup = EmptyLookup; - if (!DiagnoseTwoPhaseLookup(SemaRef, Fn->getExprLoc(), SS, R, - OverloadCandidateSet::CSK_Normal, - ExplicitTemplateArgs, Args, - &DoDiagnoseEmptyLookup) && - (!DoDiagnoseEmptyLookup || SemaRef.DiagnoseEmptyLookup( - S, SS, R, - MakeValidator(SemaRef, dyn_cast<MemberExpr>(Fn), Args.size(), - ExplicitTemplateArgs != nullptr, AllowTypoCorrection), - ExplicitTemplateArgs, Args))) - return ExprError(); + if (!DiagnoseTwoPhaseLookup( + SemaRef, Fn->getExprLoc(), SS, R, OverloadCandidateSet::CSK_Normal, + ExplicitTemplateArgs, Args, &DoDiagnoseEmptyLookup)) { + NoTypoCorrectionCCC NoTypoValidator{}; + FunctionCallFilterCCC FunctionCallValidator(SemaRef, Args.size(), + ExplicitTemplateArgs != nullptr, + dyn_cast<MemberExpr>(Fn)); + CorrectionCandidateCallback &Validator = + AllowTypoCorrection + ? static_cast<CorrectionCandidateCallback &>(FunctionCallValidator) + : static_cast<CorrectionCandidateCallback &>(NoTypoValidator); + if (!DoDiagnoseEmptyLookup || + SemaRef.DiagnoseEmptyLookup(S, SS, R, Validator, ExplicitTemplateArgs, + Args)) + return ExprError(); + } assert(!R.empty() && "lookup results empty despite recovery"); diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 3f642b5c42..1010370838 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -410,14 +410,14 @@ bool Sema::LookupTemplateName(LookupResult &Found, DeclarationName Name = Found.getLookupName(); Found.clear(); // Simple filter callback that, for keywords, only accepts the C++ *_cast - auto FilterCCC = llvm::make_unique<CorrectionCandidateCallback>(); - FilterCCC->WantTypeSpecifiers = false; - FilterCCC->WantExpressionKeywords = false; - FilterCCC->WantRemainingKeywords = false; - FilterCCC->WantCXXNamedCasts = true; - if (TypoCorrection Corrected = CorrectTypo( - Found.getLookupNameInfo(), Found.getLookupKind(), S, &SS, - std::move(FilterCCC), CTK_ErrorRecovery, LookupCtx)) { + DefaultFilterCCC FilterCCC{}; + FilterCCC.WantTypeSpecifiers = false; + FilterCCC.WantExpressionKeywords = false; + FilterCCC.WantRemainingKeywords = false; + FilterCCC.WantCXXNamedCasts = true; + if (TypoCorrection Corrected = + CorrectTypo(Found.getLookupNameInfo(), Found.getLookupKind(), S, + &SS, FilterCCC, CTK_ErrorRecovery, LookupCtx)) { Found.setLookupName(Corrected.getCorrection()); if (auto *ND = Corrected.getFoundDecl()) Found.addDecl(ND); @@ -579,13 +579,16 @@ void Sema::diagnoseExprIntendedAsTemplateName(Scope *S, ExprResult TemplateName, return S.getAsTemplateNameDecl(ND); return Candidate.isKeyword(); } + + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<TemplateCandidateFilter>(*this); + } }; DeclarationName Name = NameInfo.getName(); - if (TypoCorrection Corrected = - CorrectTypo(NameInfo, LookupKind, S, &SS, - llvm::make_unique<TemplateCandidateFilter>(*this), - CTK_ErrorRecovery, LookupCtx)) { + TemplateCandidateFilter CCC(*this); + if (TypoCorrection Corrected = CorrectTypo(NameInfo, LookupKind, S, &SS, CCC, + CTK_ErrorRecovery, LookupCtx)) { auto *ND = Corrected.getFoundDecl(); if (ND) ND = getAsTemplateNameDecl(ND); diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index faf90c093f..d06b7d49b4 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -924,12 +924,16 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) { namespace { // Callback to only accept typo corrections that refer to parameter packs. -class ParameterPackValidatorCCC : public CorrectionCandidateCallback { +class ParameterPackValidatorCCC final : public CorrectionCandidateCallback { public: bool ValidateCandidate(const TypoCorrection &candidate) override { NamedDecl *ND = candidate.getCorrectionDecl(); return ND && ND->isParameterPack(); } + + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<ParameterPackValidatorCCC>(*this); + } }; } @@ -965,18 +969,18 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, break; case LookupResult::NotFound: - case LookupResult::NotFoundInCurrentInstantiation: + case LookupResult::NotFoundInCurrentInstantiation: { + ParameterPackValidatorCCC CCC{}; if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, nullptr, - llvm::make_unique<ParameterPackValidatorCCC>(), - CTK_ErrorRecovery)) { + CCC, CTK_ErrorRecovery)) { diagnoseTypo(Corrected, PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name, PDiag(diag::note_parameter_pack_here)); ParameterPack = Corrected.getCorrectionDecl(); } break; - + } case LookupResult::FoundOverloaded: case LookupResult::FoundUnresolvedValue: break; diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index d4a6fc8ff6..d5516bc7a9 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -5913,7 +5913,8 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type, id.setIdentifier(Attr.getArgAsIdent(0)->Ident, Attr.getLoc()); ExprResult AddrSpace = S.ActOnIdExpression( - S.getCurScope(), SS, TemplateKWLoc, id, false, false); + S.getCurScope(), SS, TemplateKWLoc, id, /*HasTrailingLParen=*/false, + /*IsAddressOfOperand=*/false); if (AddrSpace.isInvalid()) return; @@ -7043,7 +7044,8 @@ static void HandleVectorSizeAttr(QualType &CurType, const ParsedAttr &Attr, Id.setIdentifier(Attr.getArgAsIdent(0)->Ident, Attr.getLoc()); ExprResult Size = S.ActOnIdExpression(S.getCurScope(), SS, TemplateKWLoc, - Id, false, false); + Id, /*HasTrailingLParen=*/false, + /*IsAddressOfOperand=*/false); if (Size.isInvalid()) return; @@ -7080,7 +7082,8 @@ static void HandleExtVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr, id.setIdentifier(Attr.getArgAsIdent(0)->Ident, Attr.getLoc()); ExprResult Size = S.ActOnIdExpression(S.getCurScope(), SS, TemplateKWLoc, - id, false, false); + id, /*HasTrailingLParen=*/false, + /*IsAddressOfOperand=*/false); if (Size.isInvalid()) return; |