From: Kaelyn Takata Date: Mon, 27 Oct 2014 18:07:29 +0000 (+0000) Subject: Pass around CorrectionCandidateCallbacks as unique_ptrs so X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=07ccb0381ae81807ab0900d090dc7179b7440589;p=clang Pass around CorrectionCandidateCallbacks as unique_ptrs so TypoCorrectionConsumer can keep the callback around as long as needed. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@220693 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 6526d471b6..b1a8fc1394 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -591,8 +591,9 @@ private: /// Annotation was successful. ANK_Success }; - AnnotatedNameKind TryAnnotateName(bool IsAddressOfOperand, - CorrectionCandidateCallback *CCC = nullptr); + AnnotatedNameKind + TryAnnotateName(bool IsAddressOfOperand, + std::unique_ptr CCC = nullptr); /// Push a tok::annot_cxxscope token onto the token stream. void AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation); diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index ba15f38d93..ba9a0feeb2 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1568,13 +1568,11 @@ public: /// expression. /// /// \param CCC The correction callback, if typo correction is desired. - NameClassification ClassifyName(Scope *S, - CXXScopeSpec &SS, - IdentifierInfo *&Name, - SourceLocation NameLoc, - const Token &NextToken, - bool IsAddressOfOperand, - CorrectionCandidateCallback *CCC = nullptr); + NameClassification + ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, + SourceLocation NameLoc, const Token &NextToken, + bool IsAddressOfOperand, + std::unique_ptr CCC = nullptr); Decl *ActOnDeclarator(Scope *S, Declarator &D); @@ -2671,7 +2669,7 @@ public: TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, - CorrectionCandidateCallback &CCC, + std::unique_ptr CCC, CorrectTypoKind Mode, DeclContext *MemberContext = nullptr, bool EnteringContext = false, @@ -3402,12 +3400,11 @@ public: // Primary Expressions. SourceRange getExprRange(Expr *E) const; - ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - UnqualifiedId &Id, - bool HasTrailingLParen, bool IsAddressOfOperand, - CorrectionCandidateCallback *CCC = nullptr, - bool IsInlineAsmIdentifier = false); + ExprResult ActOnIdExpression( + Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, + UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, + std::unique_ptr CCC = nullptr, + bool IsInlineAsmIdentifier = false); void DecomposeUnqualifiedId(const UnqualifiedId &Id, TemplateArgumentListInfo &Buffer, @@ -3416,7 +3413,7 @@ public: bool DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, - CorrectionCandidateCallback &CCC, + std::unique_ptr CCC, TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr, ArrayRef Args = None); diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h index 9f0d39a11d..92359be2da 100644 --- a/include/clang/Sema/SemaInternal.h +++ b/include/clang/Sema/SemaInternal.h @@ -93,15 +93,15 @@ class TypoCorrectionConsumer : public VisibleDeclConsumer { typedef std::map TypoEditDistanceMap; public: - explicit TypoCorrectionConsumer(Sema &SemaRef, - const DeclarationNameInfo &TypoName, - Sema::LookupNameKind LookupKind, - Scope *S, CXXScopeSpec *SS, - CorrectionCandidateCallback &CCC, - DeclContext *MemberContext, - bool EnteringContext) + TypoCorrectionConsumer(Sema &SemaRef, + const DeclarationNameInfo &TypoName, + Sema::LookupNameKind LookupKind, + Scope *S, CXXScopeSpec *SS, + std::unique_ptr CCC, + DeclContext *MemberContext, + bool EnteringContext) : Typo(TypoName.getName().getAsIdentifierInfo()), SemaRef(SemaRef), S(S), - SS(SS), CorrectionValidator(CCC), MemberContext(MemberContext), + SS(SS), CorrectionValidator(std::move(CCC)), MemberContext(MemberContext), Result(SemaRef, TypoName, LookupKind), Namespaces(SemaRef.Context, SemaRef.CurContext, SS), EnteringContext(EnteringContext), SearchNamespaces(false) { @@ -226,7 +226,7 @@ private: Sema &SemaRef; Scope *S; CXXScopeSpec *SS; - CorrectionCandidateCallback &CorrectionValidator; + std::unique_ptr CorrectionValidator; DeclContext *MemberContext; LookupResult Result; NamespaceSpecifierSet Namespaces; diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 4489b94215..60840c6f51 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -883,13 +883,13 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, UnqualifiedId Name; CXXScopeSpec ScopeSpec; SourceLocation TemplateKWLoc; - CastExpressionIdValidator Validator(isTypeCast != NotTypeCast, - isTypeCast != IsTypeCast); - Validator.IsAddressOfOperand = isAddressOfOperand; + auto Validator = llvm::make_unique( + isTypeCast != NotTypeCast, isTypeCast != IsTypeCast); + Validator->IsAddressOfOperand = isAddressOfOperand; Name.setIdentifier(&II, ILoc); Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec, TemplateKWLoc, Name, Tok.is(tok::l_paren), - isAddressOfOperand, &Validator); + isAddressOfOperand, std::move(Validator)); break; } case tok::char_constant: // constant: character-constant diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index cf689998ea..3bf66c3f2e 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -185,9 +185,9 @@ Retry: if (Next.isNot(tok::coloncolon)) { // Try to limit which sets of keywords should be included in typo // correction based on what the next token is. - StatementFilterCCC Validator(Next); - if (TryAnnotateName(/*IsAddressOfOperand*/false, &Validator) - == ANK_Error) { + if (TryAnnotateName(/*IsAddressOfOperand*/ false, + llvm::make_unique(Next)) == + ANK_Error) { // Handle errors here by skipping up to the next semicolon or '}', and // eat the semicolon if that's what stopped us. SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp index 8463138e85..4b1375dfc1 100644 --- a/lib/Parse/ParseTentative.cpp +++ b/lib/Parse/ParseTentative.cpp @@ -1131,14 +1131,14 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult, // a parse error one way or another. In that case, tell the caller that // this is ambiguous. Typo-correct to type and expression keywords and // to types and identifiers, in order to try to recover from errors. - CorrectionCandidateCallback TypoCorrection; - TypoCorrection.WantRemainingKeywords = false; - TypoCorrection.WantTypeSpecifiers = + auto TypoCorrection = llvm::make_unique(); + TypoCorrection->WantRemainingKeywords = false; + TypoCorrection->WantTypeSpecifiers = Next.is(tok::l_paren) || Next.is(tok::r_paren) || Next.is(tok::greater) || Next.is(tok::l_brace) || Next.is(tok::identifier); switch (TryAnnotateName(false /* no nested name specifier */, - &TypoCorrection)) { + std::move(TypoCorrection))) { case ANK_Error: return TPResult::Error; case ANK_TentativeDecl: diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 93e893e723..90d2815b4f 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -1327,7 +1327,7 @@ void Parser::AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation) { /// no typo correction will be performed. Parser::AnnotatedNameKind Parser::TryAnnotateName(bool IsAddressOfOperand, - CorrectionCandidateCallback *CCC) { + std::unique_ptr CCC) { assert(Tok.is(tok::identifier) || Tok.is(tok::annot_cxxscope)); const bool EnteringContext = false; @@ -1365,9 +1365,9 @@ Parser::TryAnnotateName(bool IsAddressOfOperand, // after a scope specifier, because in general we can't recover from typos // there (eg, after correcting 'A::tempalte B::C' [sic], we would need to // jump back into scope specifier parsing). - Sema::NameClassification Classification - = Actions.ClassifyName(getCurScope(), SS, Name, NameLoc, Next, - IsAddressOfOperand, SS.isEmpty() ? CCC : nullptr); + Sema::NameClassification Classification = Actions.ClassifyName( + getCurScope(), SS, Name, NameLoc, Next, IsAddressOfOperand, + SS.isEmpty() ? std::move(CCC) : nullptr); switch (Classification.getKind()) { case Sema::NC_Error: diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index 739cba7233..0193e80a75 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -575,12 +575,11 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, // We haven't found anything, and we're not recovering from a // different kind of error, so look for typos. DeclarationName Name = Found.getLookupName(); - NestedNameSpecifierValidatorCCC Validator(*this); Found.clear(); - if (TypoCorrection Corrected = - CorrectTypo(Found.getLookupNameInfo(), Found.getLookupKind(), S, - &SS, Validator, CTK_ErrorRecovery, LookupCtx, - EnteringContext)) { + if (TypoCorrection Corrected = CorrectTypo( + Found.getLookupNameInfo(), Found.getLookupKind(), S, &SS, + llvm::make_unique(*this), + CTK_ErrorRecovery, LookupCtx, EnteringContext)) { if (LookupCtx) { bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index f16ef0cd43..16a84ffd30 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -286,10 +286,10 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, case LookupResult::NotFound: case LookupResult::NotFoundInCurrentInstantiation: if (CorrectedII) { - TypeNameValidatorCCC Validator(true, isClassName); - TypoCorrection Correction = CorrectTypo(Result.getLookupNameInfo(), - Kind, S, SS, Validator, - CTK_ErrorRecovery); + TypoCorrection Correction = CorrectTypo( + Result.getLookupNameInfo(), Kind, S, SS, + llvm::make_unique(true, isClassName), + CTK_ErrorRecovery); IdentifierInfo *NewII = Correction.getCorrectionAsIdentifierInfo(); TemplateTy Template; bool MemberOfUnknownSpecialization; @@ -523,10 +523,11 @@ 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 Validator(false, false, AllowClassTemplates); - if (TypoCorrection Corrected = CorrectTypo(DeclarationNameInfo(II, IILoc), - LookupOrdinaryName, S, SS, - Validator, CTK_ErrorRecovery)) { + if (TypoCorrection Corrected = + CorrectTypo(DeclarationNameInfo(II, IILoc), LookupOrdinaryName, S, SS, + llvm::make_unique( + false, false, AllowClassTemplates), + CTK_ErrorRecovery)) { if (Corrected.isKeyword()) { // We corrected to a keyword. diagnoseTypo(Corrected, PDiag(diag::err_unknown_typename_suggest) << II); @@ -686,13 +687,11 @@ static ParsedType buildNestedType(Sema &S, CXXScopeSpec &SS, return S.CreateParsedType(T, Builder.getTypeSourceInfo(Context, T)); } -Sema::NameClassification Sema::ClassifyName(Scope *S, - CXXScopeSpec &SS, - IdentifierInfo *&Name, - SourceLocation NameLoc, - const Token &NextToken, - bool IsAddressOfOperand, - CorrectionCandidateCallback *CCC) { +Sema::NameClassification +Sema::ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, + SourceLocation NameLoc, const Token &NextToken, + bool IsAddressOfOperand, + std::unique_ptr CCC) { DeclarationNameInfo NameInfo(Name, NameLoc); ObjCMethodDecl *CurMethod = getCurMethodDecl(); @@ -769,7 +768,7 @@ Corrected: SecondTry = true; if (TypoCorrection Corrected = CorrectTypo(Result.getLookupNameInfo(), Result.getLookupKind(), S, - &SS, *CCC, + &SS, std::move(CCC), CTK_ErrorRecovery)) { unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest; unsigned QualifiedDiag = diag::err_no_member_suggest; @@ -1585,10 +1584,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. - DeclFilterCCC Validator; - if (TypoCorrection C = CorrectTypo(DeclarationNameInfo(Id, IdLoc), - LookupOrdinaryName, TUScope, nullptr, - Validator, CTK_ErrorRecovery)) { + if (TypoCorrection C = CorrectTypo( + DeclarationNameInfo(Id, IdLoc), LookupOrdinaryName, TUScope, nullptr, + llvm::make_unique>(), + CTK_ErrorRecovery)) { diagnoseTypo(C, PDiag(diag::err_undef_interface_suggest) << Id); IDecl = C.getCorrectionDeclAs(); Id = IDecl->getIdentifier(); @@ -6424,8 +6423,6 @@ static NamedDecl *DiagnoseInvalidRedeclaration( assert(!Prev.isAmbiguous() && "Cannot have an ambiguity in previous-declaration lookup"); CXXMethodDecl *MD = dyn_cast(NewFD); - DifferentNameValidatorCCC Validator(SemaRef.Context, NewFD, - MD ? MD->getParent() : nullptr); if (!Prev.empty()) { for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end(); Func != FuncEnd; ++Func) { @@ -6441,9 +6438,11 @@ 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(), Validator, - Sema::CTK_ErrorRecovery, IsLocalFriend ? nullptr : NewDC))) { + Prev.getLookupNameInfo(), Prev.getLookupKind(), S, + &ExtraArgs.D.getCXXScopeSpec(), + llvm::make_unique( + SemaRef.Context, NewFD, MD ? MD->getParent() : nullptr), + Sema::CTK_ErrorRecovery, IsLocalFriend ? nullptr : NewDC))) { // Set up everything for the call to ActOnFunctionDeclarator ExtraArgs.D.SetIdentifier(Correction.getCorrectionAsIdentifierInfo(), ExtraArgs.D.getIdentifierLoc()); @@ -10635,10 +10634,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; - DeclFilterCCC Validator; - if (S && (Corrected = CorrectTypo(DeclarationNameInfo(&II, Loc), - LookupOrdinaryName, S, nullptr, Validator, - CTK_NonError))) + if (S && + (Corrected = CorrectTypo( + DeclarationNameInfo(&II, Loc), LookupOrdinaryName, S, nullptr, + llvm::make_unique>(), CTK_NonError))) diagnoseTypo(Corrected, PDiag(diag::note_function_suggestion), /*ErrorRecovery*/false); } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index e6c9944d44..9adba66c41 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2830,10 +2830,11 @@ Sema::BuildMemInitializer(Decl *ConstructorD, // If no results were found, try to correct typos. TypoCorrection Corr; - MemInitializerValidatorCCC Validator(ClassDecl); if (R.empty() && BaseType.isNull() && - (Corr = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS, - Validator, CTK_ErrorRecovery, ClassDecl))) { + (Corr = CorrectTypo( + R.getLookupNameInfo(), R.getLookupKind(), S, &SS, + llvm::make_unique(ClassDecl), + CTK_ErrorRecovery, ClassDecl))) { if (FieldDecl *Member = Corr.getCorrectionDeclAs()) { // We have found a non-static data member with a similar // name to what was typed; complain and initialize that @@ -7264,12 +7265,11 @@ static bool TryNamespaceTypoCorrection(Sema &S, LookupResult &R, Scope *Sc, CXXScopeSpec &SS, SourceLocation IdentLoc, IdentifierInfo *Ident) { - NamespaceValidatorCCC Validator; R.clear(); - if (TypoCorrection Corrected = S.CorrectTypo(R.getLookupNameInfo(), - R.getLookupKind(), Sc, &SS, - Validator, - Sema::CTK_ErrorRecovery)) { + if (TypoCorrection Corrected = + S.CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), Sc, &SS, + llvm::make_unique(), + Sema::CTK_ErrorRecovery)) { if (DeclContext *DC = S.computeDeclContext(SS, false)) { std::string CorrectedStr(Corrected.getAsString(S.getLangOpts())); bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && @@ -7895,11 +7895,12 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS, // Try to correct typos if possible. if (R.empty()) { - UsingValidatorCCC CCC(HasTypenameKeyword, IsInstantiation, SS.getScopeRep(), - dyn_cast(CurContext)); - if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(), - R.getLookupKind(), S, &SS, CCC, - CTK_ErrorRecovery)){ + if (TypoCorrection Corrected = CorrectTypo( + R.getLookupNameInfo(), R.getLookupKind(), S, &SS, + llvm::make_unique( + HasTypenameKeyword, IsInstantiation, SS.getScopeRep(), + dyn_cast(CurContext)), + CTK_ErrorRecovery)) { // We reject any correction for which ND would be NULL. NamedDecl *ND = Corrected.getCorrectionDecl(); diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 90a6264cb1..5a1903f262 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -516,10 +516,11 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc, if (!PrevDecl) { // Try to correct for a typo in the superclass name without correcting // to the class we're defining. - ObjCInterfaceValidatorCCC Validator(IDecl); - if (TypoCorrection Corrected = CorrectTypo( - DeclarationNameInfo(SuperName, SuperLoc), LookupOrdinaryName, TUScope, - nullptr, Validator, CTK_ErrorRecovery)) { + if (TypoCorrection Corrected = + CorrectTypo(DeclarationNameInfo(SuperName, SuperLoc), + LookupOrdinaryName, TUScope, nullptr, + llvm::make_unique(IDecl), + CTK_ErrorRecovery)) { diagnoseTypo(Corrected, PDiag(diag::err_undef_superclass_suggest) << SuperName << ClassName); PrevDecl = Corrected.getCorrectionDeclAs(); @@ -786,10 +787,10 @@ Sema::FindProtocolDeclaration(bool WarnOnDeclarations, ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolId[i].first, ProtocolId[i].second); if (!PDecl) { - DeclFilterCCC Validator; TypoCorrection Corrected = CorrectTypo( DeclarationNameInfo(ProtocolId[i].first, ProtocolId[i].second), - LookupObjCProtocolName, TUScope, nullptr, Validator, + LookupObjCProtocolName, TUScope, nullptr, + llvm::make_unique>(), CTK_ErrorRecovery); if ((PDecl = Corrected.getCorrectionDeclAs())) diagnoseTypo(Corrected, PDiag(diag::err_undeclared_protocol_suggest) @@ -1027,11 +1028,9 @@ Decl *Sema::ActOnStartClassImplementation( } else { // We did not find anything with the name ClassName; try to correct for // typos in the class name. - ObjCInterfaceValidatorCCC Validator; - TypoCorrection Corrected = - CorrectTypo(DeclarationNameInfo(ClassName, ClassLoc), - LookupOrdinaryName, TUScope, nullptr, Validator, - CTK_NonError); + TypoCorrection Corrected = CorrectTypo( + DeclarationNameInfo(ClassName, ClassLoc), LookupOrdinaryName, TUScope, + nullptr, llvm::make_unique(), CTK_NonError); if (Corrected.getCorrectionDeclAs()) { // 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 319e0f4f4f..1081408195 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1674,10 +1674,11 @@ Sema::DecomposeUnqualifiedId(const UnqualifiedId &Id, /// Diagnose an empty lookup. /// /// \return false if new lookup candidates were found -bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, - CorrectionCandidateCallback &CCC, - TemplateArgumentListInfo *ExplicitTemplateArgs, - ArrayRef Args) { +bool +Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, + std::unique_ptr CCC, + TemplateArgumentListInfo *ExplicitTemplateArgs, + ArrayRef Args) { DeclarationName Name = R.getLookupName(); unsigned diagnostic = diag::err_undeclared_var_use; @@ -1795,7 +1796,7 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, // We didn't find anything, so try to correct for a typo. TypoCorrection Corrected; if (S && (Corrected = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), - S, &SS, CCC, CTK_ErrorRecovery))) { + S, &SS, std::move(CCC), CTK_ErrorRecovery))) { std::string CorrectedStr(Corrected.getAsString(getLangOpts())); bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && Name.getAsString() == CorrectedStr; @@ -1942,14 +1943,12 @@ recoverFromMSUnqualifiedLookup(Sema &S, ASTContext &Context, TemplateArgs); } -ExprResult Sema::ActOnIdExpression(Scope *S, - CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - UnqualifiedId &Id, - bool HasTrailingLParen, - bool IsAddressOfOperand, - CorrectionCandidateCallback *CCC, - bool IsInlineAsmIdentifier) { +ExprResult +Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, UnqualifiedId &Id, + bool HasTrailingLParen, bool IsAddressOfOperand, + std::unique_ptr CCC, + bool IsInlineAsmIdentifier) { assert(!(IsAddressOfOperand && HasTrailingLParen) && "cannot be direct & operand and have a trailing lparen"); if (SS.isInvalid()) @@ -2061,11 +2060,12 @@ ExprResult Sema::ActOnIdExpression(Scope *S, // If this name wasn't predeclared and if this is not a function // call, diagnose the problem. - CorrectionCandidateCallback DefaultValidator; - DefaultValidator.IsAddressOfOperand = IsAddressOfOperand; + auto DefaultValidator = llvm::make_unique(); + DefaultValidator->IsAddressOfOperand = IsAddressOfOperand; assert((!CCC || CCC->IsAddressOfOperand == IsAddressOfOperand) && "Typo correction callback misconfigured"); - if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator)) + if (DiagnoseEmptyLookup(S, SS, R, + CCC ? std::move(CCC) : std::move(DefaultValidator))) return ExprError(); assert(!R.empty() && @@ -4088,11 +4088,12 @@ static TypoCorrection TryTypoCorrectionForCall(Sema &S, Expr *Fn, MemberExpr *ME = dyn_cast(Fn); DeclarationName FuncName = FDecl->getDeclName(); SourceLocation NameLoc = ME ? ME->getMemberLoc() : Fn->getLocStart(); - FunctionCallCCC CCC(S, FuncName.getAsIdentifierInfo(), Args.size(), ME); if (TypoCorrection Corrected = S.CorrectTypo( DeclarationNameInfo(FuncName, NameLoc), Sema::LookupOrdinaryName, - S.getScopeForContext(S.CurContext), nullptr, CCC, + S.getScopeForContext(S.CurContext), nullptr, + llvm::make_unique(S, FuncName.getAsIdentifierInfo(), + Args.size(), ME), Sema::CTK_ErrorRecovery)) { if (NamedDecl *ND = Corrected.getCorrectionDecl()) { if (Corrected.isOverloaded()) { diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index ef7898208c..aca3df1ea2 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -622,11 +622,10 @@ LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, // We didn't find anything with the given name, so try to correct // for typos. DeclarationName Name = R.getLookupName(); - RecordMemberExprValidatorCCC Validator(RTy); - TypoCorrection Corrected = SemaRef.CorrectTypo(R.getLookupNameInfo(), - R.getLookupKind(), nullptr, - &SS, Validator, - Sema::CTK_ErrorRecovery, DC); + TypoCorrection Corrected = + SemaRef.CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS, + llvm::make_unique(RTy), + Sema::CTK_ErrorRecovery, DC); R.clear(); if (Corrected.isResolved() && !Corrected.isKeyword()) { R.setLookupName(Corrected.getCorrection()); @@ -1262,11 +1261,11 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, if (!IV) { // Attempt to correct for typos in ivar names. - DeclFilterCCC Validator; - Validator.IsObjCIvarLookup = IsArrow; + auto Validator = llvm::make_unique>(); + Validator->IsObjCIvarLookup = IsArrow; if (TypoCorrection Corrected = S.CorrectTypo( R.getLookupNameInfo(), Sema::LookupMemberName, nullptr, nullptr, - Validator, Sema::CTK_ErrorRecovery, IDecl)) { + std::move(Validator), Sema::CTK_ErrorRecovery, IDecl)) { IV = Corrected.getCorrectionDeclAs(); S.diagnoseTypo( Corrected, diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index ac28d83382..40ab95b6ec 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -1744,10 +1744,11 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, } // Attempt to correct for typos in property names. - DeclFilterCCC Validator; - if (TypoCorrection Corrected = CorrectTypo( - DeclarationNameInfo(MemberName, MemberLoc), LookupOrdinaryName, - nullptr, nullptr, Validator, CTK_ErrorRecovery, IFace, false, OPT)) { + if (TypoCorrection Corrected = + CorrectTypo(DeclarationNameInfo(MemberName, MemberLoc), + LookupOrdinaryName, nullptr, nullptr, + llvm::make_unique>(), + CTK_ErrorRecovery, IFace, false, OPT)) { diagnoseTypo(Corrected, PDiag(diag::err_property_not_found_suggest) << MemberName << QualType(OPT, 0)); DeclarationName TypoResult = Corrected.getCorrection(); @@ -1972,11 +1973,10 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S, } } - ObjCInterfaceOrSuperCCC Validator(getCurMethodDecl()); - if (TypoCorrection Corrected = - CorrectTypo(Result.getLookupNameInfo(), Result.getLookupKind(), S, - nullptr, Validator, CTK_ErrorRecovery, nullptr, false, - nullptr, false)) { + if (TypoCorrection Corrected = CorrectTypo( + Result.getLookupNameInfo(), Result.getLookupKind(), S, nullptr, + llvm::make_unique(getCurMethodDecl()), + CTK_ErrorRecovery, nullptr, false, nullptr, false)) { if (Corrected.isKeyword()) { // If we've found the keyword "super" (the only keyword that would be // returned by CorrectTypo), this is a send to super. diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 7a2fa08e28..d1e51de621 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -1911,11 +1911,11 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, // Name lookup didn't find anything. // Determine whether this was a typo for another field name. - FieldInitializerValidatorCCC Validator(RT->getDecl()); if (TypoCorrection Corrected = SemaRef.CorrectTypo( DeclarationNameInfo(FieldName, D->getFieldLoc()), Sema::LookupMemberName, /*Scope=*/nullptr, /*SS=*/nullptr, - Validator, Sema::CTK_ErrorRecovery, RT->getDecl())) { + llvm::make_unique(RT->getDecl()), + Sema::CTK_ErrorRecovery, RT->getDecl())) { SemaRef.diagnoseTypo( Corrected, SemaRef.PDiag(diag::err_field_designator_unknown_suggest) diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 2b2b16d3bd..a8f47d0047 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -1049,8 +1049,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, if (R.empty()) { // FIXME: Disable corrections that would add qualification? CXXScopeSpec ScopeSpec; - DeclFilterCCC Validator; - if (DiagnoseEmptyLookup(CurScope, ScopeSpec, R, Validator)) + if (DiagnoseEmptyLookup(CurScope, ScopeSpec, R, + llvm::make_unique>())) continue; } diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index b85ef5d8c4..aef1dc2d5e 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -3389,7 +3389,7 @@ void TypoCorrectionConsumer::addCorrection(TypoCorrection Correction) { // If the correction is resolved but is not viable, ignore it. if (Correction.isResolved() && - !isCandidateViable(CorrectionValidator, Correction)) + !isCandidateViable(*CorrectionValidator, Correction)) return; TypoResultList &CList = @@ -3473,7 +3473,7 @@ bool TypoCorrectionConsumer::resolveCorrection(TypoCorrection &Candidate) { retry_lookup: LookupPotentialTypoResult(SemaRef, Result, Name, S, TempSS, TempMemberContext, EnteringContext, - CorrectionValidator.IsObjCIvarLookup, + CorrectionValidator->IsObjCIvarLookup, Name == Typo && !Candidate.WillReplaceSpecifier()); switch (Result.getResultKind()) { case LookupResult::NotFound: @@ -3504,7 +3504,7 @@ retry_lookup: // Store all of the Decls for overloaded symbols for (auto *TRD : Result) Candidate.addCorrectionDecl(TRD); - if (!isCandidateViable(CorrectionValidator, Candidate)) { + if (!isCandidateViable(*CorrectionValidator, Candidate)) { if (SearchNamespaces) QualifiedResults.push_back(Candidate); break; @@ -4014,17 +4014,19 @@ static void checkCorrectionVisibility(Sema &SemaRef, TypoCorrection &TC) { TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, - CorrectionCandidateCallback &CCC, + std::unique_ptr 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)) + TypoName, LookupKind, S, SS, *CCC, MemberContext, EnteringContext, OPT)) return Correction; } @@ -4079,13 +4081,15 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, TypoName.getLocStart()); } - TypoCorrectionConsumer Consumer(*this, TypoName, LookupKind, S, SS, CCC, - MemberContext, EnteringContext); + CorrectionCandidateCallback &CCCRef = *CCC; + TypoCorrectionConsumer Consumer(*this, TypoName, LookupKind, S, SS, + std::move(CCC), MemberContext, + EnteringContext); // If a callback object considers an empty typo correction candidate to be // viable, assume it does not do any actual validation of the candidates. TypoCorrection EmptyCorrection; - bool ValidatingCallback = !isCandidateViable(CCC, EmptyCorrection); + bool ValidatingCallback = !isCandidateViable(CCCRef, EmptyCorrection); // Perform name lookup to find visible, similarly-named entities. bool IsUnqualifiedLookup = false; @@ -4120,7 +4124,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, // keyword case, we'll end up adding the keyword below. if (Cached->second) { if (!Cached->second.isKeyword() && - isCandidateViable(CCC, Cached->second)) { + isCandidateViable(CCCRef, Cached->second)) { // Do not use correction that is unaccessible in the given scope. NamedDecl *CorrectionDecl = Cached->second.getCorrectionDecl(); DeclarationNameInfo NameInfo(CorrectionDecl->getDeclName(), @@ -4177,7 +4181,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, } } - AddKeywordsToConsumer(*this, Consumer, S, CCC, SS && SS->isNotEmpty()); + AddKeywordsToConsumer(*this, Consumer, S, CCCRef, SS && SS->isNotEmpty()); // If we haven't found anything, we're done. if (Consumer.empty()) @@ -4244,7 +4248,8 @@ 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. - else if (SecondBestTC && CCC.WantObjCSuper && !CCC.WantRemainingKeywords) { + else if (SecondBestTC && CCCRef.WantObjCSuper && + !CCCRef.WantRemainingKeywords) { // Prefer 'super' when we're completing in a message-receiver // context. diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index b7c773dd16..5407ba66fd 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -646,10 +646,9 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, VarDecl *VD; if (!Lookup.isSingleResult()) { - VarDeclFilterCCC Validator(*this); - if (TypoCorrection Corrected = - CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, Validator, - CTK_ErrorRecovery)) { + if (TypoCorrection Corrected = CorrectTypo( + Id, LookupOrdinaryName, CurScope, nullptr, + llvm::make_unique(*this), CTK_ErrorRecovery)) { diagnoseTypo(Corrected, PDiag(Lookup.empty() ? diag::err_undeclared_var_use_suggest diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 9d43c85a0a..40f446bb7b 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -10561,6 +10561,15 @@ public: } +static std::unique_ptr +MakeValidator(Sema &SemaRef, MemberExpr *ME, size_t NumArgs, + bool HasTemplateArgs, bool AllowTypoCorrection) { + if (!AllowTypoCorrection) + return llvm::make_unique(); + return llvm::make_unique(SemaRef, NumArgs, + HasTemplateArgs, ME); +} + /// Attempts to recover from a call where no functions were found. /// /// Returns true if new candidates were found. @@ -10594,19 +10603,15 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(), Sema::LookupOrdinaryName); - FunctionCallFilterCCC Validator(SemaRef, Args.size(), - ExplicitTemplateArgs != nullptr, - dyn_cast(Fn)); - NoTypoCorrectionCCC RejectAll; - CorrectionCandidateCallback *CCC = AllowTypoCorrection ? - (CorrectionCandidateCallback*)&Validator : - (CorrectionCandidateCallback*)&RejectAll; if (!DiagnoseTwoPhaseLookup(SemaRef, Fn->getExprLoc(), SS, R, OverloadCandidateSet::CSK_Normal, ExplicitTemplateArgs, Args) && (!EmptyLookup || - SemaRef.DiagnoseEmptyLookup(S, SS, R, *CCC, - ExplicitTemplateArgs, Args))) + SemaRef.DiagnoseEmptyLookup( + S, SS, R, + MakeValidator(SemaRef, dyn_cast(Fn), Args.size(), + ExplicitTemplateArgs != nullptr, AllowTypoCorrection), + 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 428f24fd2d..42b42a5703 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -318,15 +318,14 @@ void Sema::LookupTemplateName(LookupResult &Found, DeclarationName Name = Found.getLookupName(); Found.clear(); // Simple filter callback that, for keywords, only accepts the C++ *_cast - CorrectionCandidateCallback 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)) { + auto FilterCCC = llvm::make_unique(); + 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)) { Found.setLookupName(Corrected.getCorrection()); if (Corrected.getCorrectionDecl()) Found.addDecl(Corrected.getCorrectionDecl()); diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index 79c0666480..8a84e00a59 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -838,7 +838,6 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, LookupName(R, S); NamedDecl *ParameterPack = nullptr; - ParameterPackValidatorCCC Validator; switch (R.getResultKind()) { case LookupResult::Found: ParameterPack = R.getFoundDecl(); @@ -846,9 +845,10 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, case LookupResult::NotFound: case LookupResult::NotFoundInCurrentInstantiation: - if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(), - R.getLookupKind(), S, nullptr, - Validator, CTK_ErrorRecovery)) { + if (TypoCorrection Corrected = + CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, nullptr, + llvm::make_unique(), + CTK_ErrorRecovery)) { diagnoseTypo(Corrected, PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name, PDiag(diag::note_parameter_pack_here));