diff options
author | Bruno Ricci <riccibrun@gmail.com> | 2019-03-25 17:08:51 +0000 |
---|---|---|
committer | Bruno Ricci <riccibrun@gmail.com> | 2019-03-25 17:08:51 +0000 |
commit | 62e8a2946b0928cb349cee4acb6fb64f950312f2 (patch) | |
tree | 894b2af2e7d0770e86f21d997b4175f983ab73ac /lib/Sema/SemaExpr.cpp | |
parent | a24f0488377773a35bfc27e25a4f8ed01c9fe2b3 (diff) | |
download | clang-62e8a2946b0928cb349cee4acb6fb64f950312f2.tar.gz |
[Sema][NFCI] Don't allocate storage for the various CorrectionCandidateCallback unless we are going to do some typo correction
The various CorrectionCandidateCallbacks are currently heap-allocated
unconditionally. This was needed because of delayed typo correction.
However these allocations represent currently 15.4% of all allocations
(number of allocations) when parsing all of Boost (!), mostly because
of ParseCastExpression, ParseStatementOrDeclarationAfterAttrtibutes
and isCXXDeclarationSpecifier. Note that all of these callback objects
are small. Let's not do this.
Instead initially allocate the callback on the stack, and only do a
heap allocation if we are going to do some typo correction. Do this by:
1. Adding a clone function to each callback, which will do a polymorphic
clone of the callback. This clone function is required to be implemented
by every callback (of which there is a fair amount). Make sure this is
the case by making it pure virtual.
2. Use this clone function when we are going to try to correct a typo.
This additionally cut the time of -fsyntax-only on all of Boost by 0.5%
(not that much, but still something). No functional changes intended.
Differential Revision: https://reviews.llvm.org/D58827
Reviewed By: rnk
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@356925 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 52 |
1 files changed, 28 insertions, 24 deletions
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()) { |