summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp440
1 files changed, 287 insertions, 153 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp
index 48bdd2a..18d352b 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp
@@ -495,7 +495,6 @@ bool ResultBuilder::isInterestingDecl(const NamedDecl *ND,
AsNestedNameSpecifier = false;
ND = ND->getUnderlyingDecl();
- unsigned IDNS = ND->getIdentifierNamespace();
// Skip unnamed entities.
if (!ND->getDeclName())
@@ -503,7 +502,7 @@ bool ResultBuilder::isInterestingDecl(const NamedDecl *ND,
// Friend declarations and declarations introduced due to friends are never
// added as results.
- if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
+ if (ND->getFriendObjectKind() == Decl::FOK_Undeclared)
return false;
// Class template (partial) specializations are never added as results.
@@ -800,8 +799,8 @@ void ResultBuilder::MaybeAddConstructorResults(Result R) {
DeclarationName ConstructorName
= Context.DeclarationNames.getCXXConstructorName(
Context.getCanonicalType(RecordTy));
- DeclContext::lookup_const_result Ctors = Record->lookup(ConstructorName);
- for (DeclContext::lookup_const_iterator I = Ctors.begin(),
+ DeclContext::lookup_result Ctors = Record->lookup(ConstructorName);
+ for (DeclContext::lookup_iterator I = Ctors.begin(),
E = Ctors.end();
I != E; ++I) {
R.Declaration = *I;
@@ -2018,7 +2017,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
if (SemaRef.getLangOpts().C11) {
// _Alignof
Builder.AddResultTypeChunk("size_t");
- if (SemaRef.getASTContext().Idents.get("alignof").hasMacroDefinition())
+ if (SemaRef.PP.isMacroDefined("alignof"))
Builder.AddTypedTextChunk("alignof");
else
Builder.AddTypedTextChunk("_Alignof");
@@ -2086,15 +2085,14 @@ static void AddResultTypeChunk(ASTContext &Context,
Result.getAllocator()));
}
-static void MaybeAddSentinel(ASTContext &Context,
+static void MaybeAddSentinel(Preprocessor &PP,
const NamedDecl *FunctionOrMethod,
CodeCompletionBuilder &Result) {
if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
if (Sentinel->getSentinel() == 0) {
- if (Context.getLangOpts().ObjC1 &&
- Context.Idents.get("nil").hasMacroDefinition())
+ if (PP.getLangOpts().ObjC1 && PP.isMacroDefined("nil"))
Result.AddTextChunk(", nil");
- else if (Context.Idents.get("NULL").hasMacroDefinition())
+ else if (PP.isMacroDefined("NULL"))
Result.AddTextChunk(", NULL");
else
Result.AddTextChunk(", (void*)0");
@@ -2118,8 +2116,7 @@ static std::string formatObjCParamQualifiers(unsigned ObjCQuals) {
return Result;
}
-static std::string FormatFunctionParameter(ASTContext &Context,
- const PrintingPolicy &Policy,
+static std::string FormatFunctionParameter(const PrintingPolicy &Policy,
const ParmVarDecl *Param,
bool SuppressName = false,
bool SuppressBlock = false) {
@@ -2218,7 +2215,7 @@ static std::string FormatFunctionParameter(ASTContext &Context,
for (unsigned I = 0, N = Block.getNumParams(); I != N; ++I) {
if (I)
Params += ", ";
- Params += FormatFunctionParameter(Context, Policy, Block.getParam(I),
+ Params += FormatFunctionParameter(Policy, Block.getParam(I),
/*SuppressName=*/false,
/*SuppressBlock=*/true);
@@ -2248,7 +2245,7 @@ static std::string FormatFunctionParameter(ASTContext &Context,
}
/// \brief Add function parameter chunks to the given code completion string.
-static void AddFunctionParameterChunks(ASTContext &Context,
+static void AddFunctionParameterChunks(Preprocessor &PP,
const PrintingPolicy &Policy,
const FunctionDecl *Function,
CodeCompletionBuilder &Result,
@@ -2266,7 +2263,7 @@ static void AddFunctionParameterChunks(ASTContext &Context,
Result.getCodeCompletionTUInfo());
if (!FirstParameter)
Opt.AddChunk(CodeCompletionString::CK_Comma);
- AddFunctionParameterChunks(Context, Policy, Function, Opt, P, true);
+ AddFunctionParameterChunks(PP, Policy, Function, Opt, P, true);
Result.AddOptionalChunk(Opt.TakeString());
break;
}
@@ -2279,9 +2276,8 @@ static void AddFunctionParameterChunks(ASTContext &Context,
InOptional = false;
// Format the placeholder string.
- std::string PlaceholderStr = FormatFunctionParameter(Context, Policy,
- Param);
-
+ std::string PlaceholderStr = FormatFunctionParameter(Policy, Param);
+
if (Function->isVariadic() && P == N - 1)
PlaceholderStr += ", ...";
@@ -2296,7 +2292,7 @@ static void AddFunctionParameterChunks(ASTContext &Context,
if (Proto->getNumParams() == 0)
Result.AddPlaceholderChunk("...");
- MaybeAddSentinel(Context, Function, Result);
+ MaybeAddSentinel(PP, Function, Result);
}
}
@@ -2309,7 +2305,11 @@ static void AddTemplateParameterChunks(ASTContext &Context,
unsigned Start = 0,
bool InDefaultArg = false) {
bool FirstParameter = true;
-
+
+ // Prefer to take the template parameter names from the first declaration of
+ // the template.
+ Template = cast<TemplateDecl>(Template->getCanonicalDecl());
+
TemplateParameterList *Params = Template->getTemplateParameters();
TemplateParameterList::iterator PEnd = Params->end();
if (MaxParameters)
@@ -2572,11 +2572,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
}
if (Kind == RK_Macro) {
- const MacroDirective *MD = PP.getMacroDirectiveHistory(Macro);
- assert(MD && "Not a macro?");
- const MacroInfo *MI = MD->getMacroInfo();
- assert((!MD->isDefined() || MI) && "missing MacroInfo for define");
-
+ const MacroInfo *MI = PP.getMacroInfo(Macro);
Result.AddTypedTextChunk(
Result.getAllocator().CopyString(Macro->getName()));
@@ -2651,7 +2647,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
Ctx, Policy);
AddTypedNameChunk(Ctx, Policy, ND, Result);
Result.AddChunk(CodeCompletionString::CK_LeftParen);
- AddFunctionParameterChunks(Ctx, Policy, Function, Result);
+ AddFunctionParameterChunks(PP, Policy, Function, Result);
Result.AddChunk(CodeCompletionString::CK_RightParen);
AddFunctionTypeQualsToCompletionString(Result, Function);
return Result.TakeString();
@@ -2705,7 +2701,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
// Add the function parameters
Result.AddChunk(CodeCompletionString::CK_LeftParen);
- AddFunctionParameterChunks(Ctx, Policy, Function, Result);
+ AddFunctionParameterChunks(PP, Policy, Function, Result);
Result.AddChunk(CodeCompletionString::CK_RightParen);
AddFunctionTypeQualsToCompletionString(Result, Function);
return Result.TakeString();
@@ -2766,7 +2762,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
std::string Arg;
if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
- Arg = FormatFunctionParameter(Ctx, Policy, *P, true);
+ Arg = FormatFunctionParameter(Policy, *P, true);
else {
(*P)->getType().getAsStringInternal(Arg, Policy);
Arg = "(" + formatObjCParamQualifiers((*P)->getObjCDeclQualifier())
@@ -2797,7 +2793,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
Result.AddPlaceholderChunk(", ...");
}
- MaybeAddSentinel(Ctx, Method, Result);
+ MaybeAddSentinel(PP, Method, Result);
}
return Result.TakeString();
@@ -2812,73 +2808,115 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
return Result.TakeString();
}
+/// \brief Add function overload parameter chunks to the given code completion
+/// string.
+static void AddOverloadParameterChunks(ASTContext &Context,
+ const PrintingPolicy &Policy,
+ const FunctionDecl *Function,
+ const FunctionProtoType *Prototype,
+ CodeCompletionBuilder &Result,
+ unsigned CurrentArg,
+ unsigned Start = 0,
+ bool InOptional = false) {
+ bool FirstParameter = true;
+ unsigned NumParams = Function ? Function->getNumParams()
+ : Prototype->getNumParams();
+
+ for (unsigned P = Start; P != NumParams; ++P) {
+ if (Function && Function->getParamDecl(P)->hasDefaultArg() && !InOptional) {
+ // When we see an optional default argument, put that argument and
+ // the remaining default arguments into a new, optional string.
+ CodeCompletionBuilder Opt(Result.getAllocator(),
+ Result.getCodeCompletionTUInfo());
+ if (!FirstParameter)
+ Opt.AddChunk(CodeCompletionString::CK_Comma);
+ // Optional sections are nested.
+ AddOverloadParameterChunks(Context, Policy, Function, Prototype, Opt,
+ CurrentArg, P, /*InOptional=*/true);
+ Result.AddOptionalChunk(Opt.TakeString());
+ return;
+ }
+
+ if (FirstParameter)
+ FirstParameter = false;
+ else
+ Result.AddChunk(CodeCompletionString::CK_Comma);
+
+ InOptional = false;
+
+ // Format the placeholder string.
+ std::string Placeholder;
+ if (Function)
+ Placeholder = FormatFunctionParameter(Policy, Function->getParamDecl(P));
+ else
+ Placeholder = Prototype->getParamType(P).getAsString(Policy);
+
+ if (P == CurrentArg)
+ Result.AddCurrentParameterChunk(
+ Result.getAllocator().CopyString(Placeholder));
+ else
+ Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Placeholder));
+ }
+
+ if (Prototype && Prototype->isVariadic()) {
+ CodeCompletionBuilder Opt(Result.getAllocator(),
+ Result.getCodeCompletionTUInfo());
+ if (!FirstParameter)
+ Opt.AddChunk(CodeCompletionString::CK_Comma);
+
+ if (CurrentArg < NumParams)
+ Opt.AddPlaceholderChunk("...");
+ else
+ Opt.AddCurrentParameterChunk("...");
+
+ Result.AddOptionalChunk(Opt.TakeString());
+ }
+}
+
CodeCompletionString *
CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
- unsigned CurrentArg,
- Sema &S,
- CodeCompletionAllocator &Allocator,
- CodeCompletionTUInfo &CCTUInfo) const {
+ unsigned CurrentArg, Sema &S,
+ CodeCompletionAllocator &Allocator,
+ CodeCompletionTUInfo &CCTUInfo,
+ bool IncludeBriefComments) const {
PrintingPolicy Policy = getCompletionPrintingPolicy(S);
// FIXME: Set priority, availability appropriately.
CodeCompletionBuilder Result(Allocator,CCTUInfo, 1, CXAvailability_Available);
FunctionDecl *FDecl = getFunction();
- AddResultTypeChunk(S.Context, Policy, FDecl, Result);
- const FunctionProtoType *Proto
+ const FunctionProtoType *Proto
= dyn_cast<FunctionProtoType>(getFunctionType());
if (!FDecl && !Proto) {
// Function without a prototype. Just give the return type and a
// highlighted ellipsis.
const FunctionType *FT = getFunctionType();
- Result.AddTextChunk(GetCompletionTypeString(FT->getReturnType(), S.Context,
- Policy, Result.getAllocator()));
+ Result.AddResultTypeChunk(Result.getAllocator().CopyString(
+ FT->getReturnType().getAsString(Policy)));
Result.AddChunk(CodeCompletionString::CK_LeftParen);
Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "...");
Result.AddChunk(CodeCompletionString::CK_RightParen);
return Result.TakeString();
}
-
- if (FDecl)
+
+ if (FDecl) {
+ if (IncludeBriefComments && CurrentArg < FDecl->getNumParams())
+ if (auto RC = S.getASTContext().getRawCommentForAnyRedecl(
+ FDecl->getParamDecl(CurrentArg)))
+ Result.addBriefComment(RC->getBriefText(S.getASTContext()));
+ AddResultTypeChunk(S.Context, Policy, FDecl, Result);
Result.AddTextChunk(
- Result.getAllocator().CopyString(FDecl->getNameAsString()));
- else
- Result.AddTextChunk(Result.getAllocator().CopyString(
+ Result.getAllocator().CopyString(FDecl->getNameAsString()));
+ } else {
+ Result.AddResultTypeChunk(
+ Result.getAllocator().CopyString(
Proto->getReturnType().getAsString(Policy)));
+ }
Result.AddChunk(CodeCompletionString::CK_LeftParen);
- unsigned NumParams = FDecl ? FDecl->getNumParams() : Proto->getNumParams();
- for (unsigned I = 0; I != NumParams; ++I) {
- if (I)
- Result.AddChunk(CodeCompletionString::CK_Comma);
-
- std::string ArgString;
- QualType ArgType;
-
- if (FDecl) {
- ArgString = FDecl->getParamDecl(I)->getNameAsString();
- ArgType = FDecl->getParamDecl(I)->getOriginalType();
- } else {
- ArgType = Proto->getParamType(I);
- }
-
- ArgType.getAsStringInternal(ArgString, Policy);
-
- if (I == CurrentArg)
- Result.AddChunk(CodeCompletionString::CK_CurrentParameter,
- Result.getAllocator().CopyString(ArgString));
- else
- Result.AddTextChunk(Result.getAllocator().CopyString(ArgString));
- }
-
- if (Proto && Proto->isVariadic()) {
- Result.AddChunk(CodeCompletionString::CK_Comma);
- if (CurrentArg < NumParams)
- Result.AddTextChunk("...");
- else
- Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "...");
- }
+ AddOverloadParameterChunks(S.getASTContext(), Policy, FDecl, Proto, Result,
+ CurrentArg);
Result.AddChunk(CodeCompletionString::CK_RightParen);
-
+
return Result.TakeString();
}
@@ -2990,8 +3028,9 @@ static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
for (Preprocessor::macro_iterator M = PP.macro_begin(),
MEnd = PP.macro_end();
M != MEnd; ++M) {
- if (IncludeUndefined || M->first->hasMacroDefinition()) {
- if (MacroInfo *MI = M->second->getMacroInfo())
+ auto MD = PP.getMacroDefinition(M->first);
+ if (IncludeUndefined || MD) {
+ if (MacroInfo *MI = MD.getMacroInfo())
if (MI->isUsedForHeaderGuard())
continue;
@@ -3816,7 +3855,74 @@ static bool anyNullArguments(ArrayRef<Expr *> Args) {
return false;
}
-void Sema::CodeCompleteCall(Scope *S, Expr *FnIn, ArrayRef<Expr *> Args) {
+typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
+
+static void mergeCandidatesWithResults(Sema &SemaRef,
+ SmallVectorImpl<ResultCandidate> &Results,
+ OverloadCandidateSet &CandidateSet,
+ SourceLocation Loc) {
+ if (!CandidateSet.empty()) {
+ // Sort the overload candidate set by placing the best overloads first.
+ std::stable_sort(
+ CandidateSet.begin(), CandidateSet.end(),
+ [&](const OverloadCandidate &X, const OverloadCandidate &Y) {
+ return isBetterOverloadCandidate(SemaRef, X, Y, Loc);
+ });
+
+ // Add the remaining viable overload candidates as code-completion results.
+ for (auto &Candidate : CandidateSet)
+ if (Candidate.Viable)
+ Results.push_back(ResultCandidate(Candidate.Function));
+ }
+}
+
+/// \brief Get the type of the Nth parameter from a given set of overload
+/// candidates.
+static QualType getParamType(Sema &SemaRef,
+ ArrayRef<ResultCandidate> Candidates,
+ unsigned N) {
+
+ // Given the overloads 'Candidates' for a function call matching all arguments
+ // up to N, return the type of the Nth parameter if it is the same for all
+ // overload candidates.
+ QualType ParamType;
+ for (auto &Candidate : Candidates) {
+ if (auto FType = Candidate.getFunctionType())
+ if (auto Proto = dyn_cast<FunctionProtoType>(FType))
+ if (N < Proto->getNumParams()) {
+ if (ParamType.isNull())
+ ParamType = Proto->getParamType(N);
+ else if (!SemaRef.Context.hasSameUnqualifiedType(
+ ParamType.getNonReferenceType(),
+ Proto->getParamType(N).getNonReferenceType()))
+ // Otherwise return a default-constructed QualType.
+ return QualType();
+ }
+ }
+
+ return ParamType;
+}
+
+static void CodeCompleteOverloadResults(Sema &SemaRef, Scope *S,
+ MutableArrayRef<ResultCandidate> Candidates,
+ unsigned CurrentArg,
+ bool CompleteExpressionWithCurrentArg = true) {
+ QualType ParamType;
+ if (CompleteExpressionWithCurrentArg)
+ ParamType = getParamType(SemaRef, Candidates, CurrentArg);
+
+ if (ParamType.isNull())
+ SemaRef.CodeCompleteOrdinaryName(S, Sema::PCC_Expression);
+ else
+ SemaRef.CodeCompleteExpression(S, ParamType);
+
+ if (!Candidates.empty())
+ SemaRef.CodeCompleter->ProcessOverloadCandidates(SemaRef, CurrentArg,
+ Candidates.data(),
+ Candidates.size());
+}
+
+void Sema::CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args) {
if (!CodeCompleter)
return;
@@ -3825,7 +3931,7 @@ void Sema::CodeCompleteCall(Scope *S, Expr *FnIn, ArrayRef<Expr *> Args) {
// results. We may want to revisit this strategy in the future,
// e.g., by merging the two kinds of results.
- Expr *Fn = (Expr *)FnIn;
+ // FIXME: Provide support for variadic template functions.
// Ignore type-dependent call expressions entirely.
if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args) ||
@@ -3838,92 +3944,120 @@ void Sema::CodeCompleteCall(Scope *S, Expr *FnIn, ArrayRef<Expr *> Args) {
SourceLocation Loc = Fn->getExprLoc();
OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal);
- // FIXME: What if we're calling something that isn't a function declaration?
- // FIXME: What if we're calling a pseudo-destructor?
- // FIXME: What if we're calling a member function?
-
- typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
SmallVector<ResultCandidate, 8> Results;
Expr *NakedFn = Fn->IgnoreParenCasts();
- if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
+ if (auto ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
AddOverloadedCallCandidates(ULE, Args, CandidateSet,
- /*PartialOverloading=*/ true);
- else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
- FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
- if (FDecl) {
- if (!getLangOpts().CPlusPlus ||
- !FDecl->getType()->getAs<FunctionProtoType>())
- Results.push_back(ResultCandidate(FDecl));
+ /*PartialOverloading=*/true);
+ else if (auto UME = dyn_cast<UnresolvedMemberExpr>(NakedFn)) {
+ TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr;
+ if (UME->hasExplicitTemplateArgs()) {
+ UME->copyTemplateArgumentsInto(TemplateArgsBuffer);
+ TemplateArgs = &TemplateArgsBuffer;
+ }
+ SmallVector<Expr *, 12> ArgExprs(1, UME->getBase());
+ ArgExprs.append(Args.begin(), Args.end());
+ UnresolvedSet<8> Decls;
+ Decls.append(UME->decls_begin(), UME->decls_end());
+ AddFunctionCandidates(Decls, ArgExprs, CandidateSet, TemplateArgs,
+ /*SuppressUsedConversions=*/false,
+ /*PartialOverloading=*/true);
+ } else {
+ FunctionDecl *FD = nullptr;
+ if (auto MCE = dyn_cast<MemberExpr>(NakedFn))
+ FD = dyn_cast<FunctionDecl>(MCE->getMemberDecl());
+ else if (auto DRE = dyn_cast<DeclRefExpr>(NakedFn))
+ FD = dyn_cast<FunctionDecl>(DRE->getDecl());
+ if (FD) { // We check whether it's a resolved function declaration.
+ if (!getLangOpts().CPlusPlus ||
+ !FD->getType()->getAs<FunctionProtoType>())
+ Results.push_back(ResultCandidate(FD));
else
- // FIXME: access?
- AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none), Args,
- CandidateSet, false, /*PartialOverloading*/true);
+ AddOverloadCandidate(FD, DeclAccessPair::make(FD, FD->getAccess()),
+ Args, CandidateSet,
+ /*SuppressUsedConversions=*/false,
+ /*PartialOverloading=*/true);
+
+ } else if (auto DC = NakedFn->getType()->getAsCXXRecordDecl()) {
+ // If expression's type is CXXRecordDecl, it may overload the function
+ // call operator, so we check if it does and add them as candidates.
+ // A complete type is needed to lookup for member function call operators.
+ if (!RequireCompleteType(Loc, NakedFn->getType(), 0)) {
+ DeclarationName OpName = Context.DeclarationNames
+ .getCXXOperatorName(OO_Call);
+ LookupResult R(*this, OpName, Loc, LookupOrdinaryName);
+ LookupQualifiedName(R, DC);
+ R.suppressDiagnostics();
+ SmallVector<Expr *, 12> ArgExprs(1, NakedFn);
+ ArgExprs.append(Args.begin(), Args.end());
+ AddFunctionCandidates(R.asUnresolvedSet(), ArgExprs, CandidateSet,
+ /*ExplicitArgs=*/nullptr,
+ /*SuppressUsedConversions=*/false,
+ /*PartialOverloading=*/true);
+ }
+ } else {
+ // Lastly we check whether expression's type is function pointer or
+ // function.
+ QualType T = NakedFn->getType();
+ if (!T->getPointeeType().isNull())
+ T = T->getPointeeType();
+
+ if (auto FP = T->getAs<FunctionProtoType>()) {
+ if (!TooManyArguments(FP->getNumParams(), Args.size(),
+ /*PartialOverloading=*/true) ||
+ FP->isVariadic())
+ Results.push_back(ResultCandidate(FP));
+ } else if (auto FT = T->getAs<FunctionType>())
+ // No prototype and declaration, it may be a K & R style function.
+ Results.push_back(ResultCandidate(FT));
}
}
-
- QualType ParamType;
-
- if (!CandidateSet.empty()) {
- // Sort the overload candidate set by placing the best overloads first.
- std::stable_sort(
- CandidateSet.begin(), CandidateSet.end(),
- [&](const OverloadCandidate &X, const OverloadCandidate &Y) {
- return isBetterOverloadCandidate(*this, X, Y, Loc);
- });
- // Add the remaining viable overload candidates as code-completion reslults.
- for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
- CandEnd = CandidateSet.end();
- Cand != CandEnd; ++Cand) {
- if (Cand->Viable)
- Results.push_back(ResultCandidate(Cand->Function));
- }
-
- // From the viable candidates, try to determine the type of this parameter.
- for (unsigned I = 0, N = Results.size(); I != N; ++I) {
- if (const FunctionType *FType = Results[I].getFunctionType())
- if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
- if (Args.size() < Proto->getNumParams()) {
- if (ParamType.isNull())
- ParamType = Proto->getParamType(Args.size());
- else if (!Context.hasSameUnqualifiedType(
- ParamType.getNonReferenceType(),
- Proto->getParamType(Args.size())
- .getNonReferenceType())) {
- ParamType = QualType();
- break;
- }
- }
- }
- } else {
- // Try to determine the parameter type from the type of the expression
- // being called.
- QualType FunctionType = Fn->getType();
- if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
- FunctionType = Ptr->getPointeeType();
- else if (const BlockPointerType *BlockPtr
- = FunctionType->getAs<BlockPointerType>())
- FunctionType = BlockPtr->getPointeeType();
- else if (const MemberPointerType *MemPtr
- = FunctionType->getAs<MemberPointerType>())
- FunctionType = MemPtr->getPointeeType();
-
- if (const FunctionProtoType *Proto
- = FunctionType->getAs<FunctionProtoType>()) {
- if (Args.size() < Proto->getNumParams())
- ParamType = Proto->getParamType(Args.size());
+ mergeCandidatesWithResults(*this, Results, CandidateSet, Loc);
+ CodeCompleteOverloadResults(*this, S, Results, Args.size(),
+ !CandidateSet.empty());
+}
+
+void Sema::CodeCompleteConstructor(Scope *S, QualType Type, SourceLocation Loc,
+ ArrayRef<Expr *> Args) {
+ if (!CodeCompleter)
+ return;
+
+ // A complete type is needed to lookup for constructors.
+ if (RequireCompleteType(Loc, Type, 0))
+ return;
+
+ CXXRecordDecl *RD = Type->getAsCXXRecordDecl();
+ if (!RD) {
+ CodeCompleteExpression(S, Type);
+ return;
+ }
+
+ // FIXME: Provide support for member initializers.
+ // FIXME: Provide support for variadic template constructors.
+
+ OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal);
+
+ for (auto C : LookupConstructors(RD)) {
+ if (auto FD = dyn_cast<FunctionDecl>(C)) {
+ AddOverloadCandidate(FD, DeclAccessPair::make(FD, C->getAccess()),
+ Args, CandidateSet,
+ /*SuppressUsedConversions=*/false,
+ /*PartialOverloading=*/true);
+ } else if (auto FTD = dyn_cast<FunctionTemplateDecl>(C)) {
+ AddTemplateOverloadCandidate(FTD,
+ DeclAccessPair::make(FTD, C->getAccess()),
+ /*ExplicitTemplateArgs=*/nullptr,
+ Args, CandidateSet,
+ /*SuppressUsedConversions=*/false,
+ /*PartialOverloading=*/true);
}
}
- if (ParamType.isNull())
- CodeCompleteOrdinaryName(S, PCC_Expression);
- else
- CodeCompleteExpression(S, ParamType);
-
- if (!Results.empty())
- CodeCompleter->ProcessOverloadCandidates(*this, Args.size(), Results.data(),
- Results.size());
+ SmallVector<ResultCandidate, 8> Results;
+ mergeCandidatesWithResults(*this, Results, CandidateSet, Loc);
+ CodeCompleteOverloadResults(*this, S, Results, Args.size());
}
void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
@@ -4981,7 +5115,7 @@ void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS,
// an action, e.g.,
// IBAction)<#selector#>:(id)sender
if (DS.getObjCDeclQualifier() == 0 && !IsParameter &&
- Context.Idents.get("IBAction").hasMacroDefinition()) {
+ PP.isMacroDefined("IBAction")) {
CodeCompletionBuilder Builder(Results.getAllocator(),
Results.getCodeCompletionTUInfo(),
CCP_CodePattern, CXAvailability_Available);
OpenPOWER on IntegriCloud