diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaCodeComplete.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Sema/SemaCodeComplete.cpp | 90 |
1 files changed, 68 insertions, 22 deletions
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaCodeComplete.cpp b/contrib/llvm-project/clang/lib/Sema/SemaCodeComplete.cpp index 0a8a27068ebf..c2785fd60fc2 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaCodeComplete.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaCodeComplete.cpp @@ -2294,6 +2294,29 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S, Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); Builder.AddChunk(CodeCompletionString::CK_RightBrace); Results.AddResult(Result(Builder.TakeString())); + + if (SemaRef.getLangOpts().CPlusPlus11 || SemaRef.getLangOpts().ObjC) { + // for ( range_declaration (:|in) range_expression ) { statements } + Builder.AddTypedTextChunk("for"); + Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); + Builder.AddChunk(CodeCompletionString::CK_LeftParen); + Builder.AddPlaceholderChunk("range-declaration"); + Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); + if (SemaRef.getLangOpts().ObjC) + Builder.AddTextChunk("in"); + else + Builder.AddChunk(CodeCompletionString::CK_Colon); + Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); + Builder.AddPlaceholderChunk("range-expression"); + Builder.AddChunk(CodeCompletionString::CK_RightParen); + Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); + Builder.AddChunk(CodeCompletionString::CK_LeftBrace); + Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); + Builder.AddPlaceholderChunk("statements"); + Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); + Builder.AddChunk(CodeCompletionString::CK_RightBrace); + Results.AddResult(Result(Builder.TakeString())); + } } if (S->getContinueParent()) { @@ -2700,6 +2723,10 @@ static std::string formatObjCParamQualifiers(unsigned ObjCQuals, case NullabilityKind::Unspecified: Result += "null_unspecified "; break; + + case NullabilityKind::NullableResult: + llvm_unreachable("Not supported as a context-sensitive keyword!"); + break; } } } @@ -3502,9 +3529,11 @@ CodeCompletionString *CodeCompletionResult::createCodeCompletionStringForDecl( Result.AddTypedTextChunk(""); } unsigned Idx = 0; + // The extra Idx < Sel.getNumArgs() check is needed due to legacy C-style + // method parameters. for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(), PEnd = Method->param_end(); - P != PEnd; (void)++P, ++Idx) { + P != PEnd && Idx < Sel.getNumArgs(); (void)++P, ++Idx) { if (Idx > 0) { std::string Keyword; if (Idx > StartParameter) @@ -4256,7 +4285,7 @@ void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, DS.getParsedSpecifiers() == DeclSpec::PQ_TypeSpecifier && DS.getTypeSpecType() == DeclSpec::TST_typename && DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified && - DS.getTypeSpecSign() == DeclSpec::TSS_unspecified && + DS.getTypeSpecSign() == TypeSpecifierSign::Unspecified && !DS.isTypeAltiVecVector() && S && (S->getFlags() & Scope::DeclScope) != 0 && (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope | @@ -5395,8 +5424,8 @@ void Sema::CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D, AddTypeQualifierResults(DS, Results, LangOpts); if (LangOpts.CPlusPlus11) { Results.AddResult("noexcept"); - if (D.getContext() == DeclaratorContext::MemberContext && - !D.isCtorOrDtor() && !D.isStaticMember()) { + if (D.getContext() == DeclaratorContext::Member && !D.isCtorOrDtor() && + !D.isStaticMember()) { if (!VS || !VS->isFinalSpecified()) Results.AddResult("final"); if (!VS || !VS->isOverrideSpecified()) @@ -5500,7 +5529,7 @@ typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate; static void mergeCandidatesWithResults( Sema &SemaRef, SmallVectorImpl<ResultCandidate> &Results, - OverloadCandidateSet &CandidateSet, SourceLocation Loc) { + OverloadCandidateSet &CandidateSet, SourceLocation Loc, size_t ArgSize) { // Sort the overload candidate set by placing the best overloads first. llvm::stable_sort(CandidateSet, [&](const OverloadCandidate &X, const OverloadCandidate &Y) { @@ -5510,8 +5539,19 @@ static void mergeCandidatesWithResults( // Add the remaining viable overload candidates as code-completion results. for (OverloadCandidate &Candidate : CandidateSet) { - if (Candidate.Function && Candidate.Function->isDeleted()) - continue; + if (Candidate.Function) { + if (Candidate.Function->isDeleted()) + continue; + if (!Candidate.Function->isVariadic() && + Candidate.Function->getNumParams() <= ArgSize && + // Having zero args is annoying, normally we don't surface a function + // with 2 params, if you already have 2 params, because you are + // inserting the 3rd now. But with zero, it helps the user to figure + // out there are no overloads that take any arguments. Hence we are + // keeping the overload. + ArgSize > 0) + continue; + } if (Candidate.Viable) Results.push_back(ResultCandidate(Candidate.Function)); } @@ -5562,22 +5602,25 @@ QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn, // FIXME: Provide support for variadic template functions. // Ignore type-dependent call expressions entirely. - if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args) || - Expr::hasAnyTypeDependentArguments(Args)) { + if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args)) return QualType(); - } + // In presence of dependent args we surface all possible signatures using the + // non-dependent args in the prefix. Afterwards we do a post filtering to make + // sure provided candidates satisfy parameter count restrictions. + auto ArgsWithoutDependentTypes = + Args.take_while([](Expr *Arg) { return !Arg->isTypeDependent(); }); + + SmallVector<ResultCandidate, 8> Results; + Expr *NakedFn = Fn->IgnoreParenCasts(); // Build an overload candidate set based on the functions we find. SourceLocation Loc = Fn->getExprLoc(); OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal); - SmallVector<ResultCandidate, 8> Results; - - Expr *NakedFn = Fn->IgnoreParenCasts(); - if (auto ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn)) - AddOverloadedCallCandidates(ULE, Args, CandidateSet, + if (auto ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn)) { + AddOverloadedCallCandidates(ULE, ArgsWithoutDependentTypes, CandidateSet, /*PartialOverloading=*/true); - else if (auto UME = dyn_cast<UnresolvedMemberExpr>(NakedFn)) { + } else if (auto UME = dyn_cast<UnresolvedMemberExpr>(NakedFn)) { TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr; if (UME->hasExplicitTemplateArgs()) { UME->copyTemplateArgumentsInto(TemplateArgsBuffer); @@ -5587,7 +5630,8 @@ QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn, // Add the base as first argument (use a nullptr if the base is implicit). SmallVector<Expr *, 12> ArgExprs( 1, UME->isImplicitAccess() ? nullptr : UME->getBase()); - ArgExprs.append(Args.begin(), Args.end()); + ArgExprs.append(ArgsWithoutDependentTypes.begin(), + ArgsWithoutDependentTypes.end()); UnresolvedSet<8> Decls; Decls.append(UME->decls_begin(), UME->decls_end()); const bool FirstArgumentIsBase = !UME->isImplicitAccess() && UME->getBase(); @@ -5606,7 +5650,7 @@ QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn, Results.push_back(ResultCandidate(FD)); else AddOverloadCandidate(FD, DeclAccessPair::make(FD, FD->getAccess()), - Args, CandidateSet, + ArgsWithoutDependentTypes, CandidateSet, /*SuppressUserConversions=*/false, /*PartialOverloading=*/true); @@ -5621,7 +5665,8 @@ QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn, LookupQualifiedName(R, DC); R.suppressDiagnostics(); SmallVector<Expr *, 12> ArgExprs(1, NakedFn); - ArgExprs.append(Args.begin(), Args.end()); + ArgExprs.append(ArgsWithoutDependentTypes.begin(), + ArgsWithoutDependentTypes.end()); AddFunctionCandidates(R.asUnresolvedSet(), ArgExprs, CandidateSet, /*ExplicitArgs=*/nullptr, /*SuppressUserConversions=*/false, @@ -5635,7 +5680,8 @@ QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn, T = T->getPointeeType(); if (auto FP = T->getAs<FunctionProtoType>()) { - if (!TooManyArguments(FP->getNumParams(), Args.size(), + if (!TooManyArguments(FP->getNumParams(), + ArgsWithoutDependentTypes.size(), /*PartialOverloading=*/true) || FP->isVariadic()) Results.push_back(ResultCandidate(FP)); @@ -5644,7 +5690,7 @@ QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn, Results.push_back(ResultCandidate(FT)); } } - mergeCandidatesWithResults(*this, Results, CandidateSet, Loc); + mergeCandidatesWithResults(*this, Results, CandidateSet, Loc, Args.size()); QualType ParamType = ProduceSignatureHelp(*this, S, Results, Args.size(), OpenParLoc); return !CandidateSet.empty() ? ParamType : QualType(); @@ -5685,7 +5731,7 @@ QualType Sema::ProduceConstructorSignatureHelp(Scope *S, QualType Type, } SmallVector<ResultCandidate, 8> Results; - mergeCandidatesWithResults(*this, Results, CandidateSet, Loc); + mergeCandidatesWithResults(*this, Results, CandidateSet, Loc, Args.size()); return ProduceSignatureHelp(*this, S, Results, Args.size(), OpenParLoc); } |