aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaCodeComplete.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-09-22 15:41:20 +0000
committerDouglas Gregor <dgregor@apple.com>2009-09-22 15:41:20 +0000
commit9c6a0e92dbf89897eae6106b24bfd017f269bfd0 (patch)
tree0cf2ed937ce5e34365078d5fdadcfedbd3afdf74 /lib/Sema/SemaCodeComplete.cpp
parente119e84ea5ea66eb2090aec05310c23e9d6f63fc (diff)
Implement code completion within a function call, triggered after the
opening parentheses and after each comma. We gather the set of visible overloaded functions, perform "partial" overloading based on the set of arguments that we have thus far, and return the still-viable results sorted by the likelihood that they will be the best candidate. Most of the changes in this patch are a refactoring of the overloading routines for a function call, since we needed to separate out the notion of building an overload set (common to code-completion and normal semantic analysis) and then what to do with that overload set. As part of this change, I've pushed explicit template arguments into a few more subroutines. There is still much more work to do in this area. Function templates won't be handled well (unless we happen to deduce all of the template arguments before we hit the completion point), nor will overloaded function-call operators or calls to member functions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82549 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaCodeComplete.cpp')
-rw-r--r--lib/Sema/SemaCodeComplete.cpp72
1 files changed, 72 insertions, 0 deletions
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 52e7d0e005..757bb62711 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -1070,6 +1070,78 @@ void Sema::CodeCompleteCase(Scope *S) {
HandleCodeCompleteResults(CodeCompleter, Results.data(), Results.size());
}
+namespace {
+ struct IsBetterOverloadCandidate {
+ Sema &S;
+
+ public:
+ explicit IsBetterOverloadCandidate(Sema &S) : S(S) { }
+
+ bool
+ operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
+ return S.isBetterOverloadCandidate(X, Y);
+ }
+ };
+}
+
+void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
+ ExprTy **ArgsIn, unsigned NumArgs) {
+ if (!CodeCompleter)
+ return;
+
+ Expr *Fn = (Expr *)FnIn;
+ Expr **Args = (Expr **)ArgsIn;
+
+ // Ignore type-dependent call expressions entirely.
+ if (Fn->isTypeDependent() ||
+ Expr::hasAnyTypeDependentArguments(Args, NumArgs))
+ return;
+
+ NamedDecl *Function;
+ DeclarationName UnqualifiedName;
+ NestedNameSpecifier *Qualifier;
+ SourceRange QualifierRange;
+ bool ArgumentDependentLookup;
+ bool HasExplicitTemplateArgs;
+ const TemplateArgument *ExplicitTemplateArgs;
+ unsigned NumExplicitTemplateArgs;
+
+ DeconstructCallFunction(Fn,
+ Function, UnqualifiedName, Qualifier, QualifierRange,
+ ArgumentDependentLookup, HasExplicitTemplateArgs,
+ ExplicitTemplateArgs, NumExplicitTemplateArgs);
+
+
+ // 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?
+
+ // Build an overload candidate set based on the functions we find.
+ OverloadCandidateSet CandidateSet;
+ AddOverloadedCallCandidates(Function, UnqualifiedName,
+ ArgumentDependentLookup, HasExplicitTemplateArgs,
+ ExplicitTemplateArgs, NumExplicitTemplateArgs,
+ Args, NumArgs,
+ CandidateSet,
+ /*PartialOverloading=*/true);
+
+ // Sort the overload candidate set by placing the best overloads first.
+ std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
+ IsBetterOverloadCandidate(*this));
+
+ // Add the remaining viable overload candidates as code-completion reslults.
+ typedef CodeCompleteConsumer::Result Result;
+ ResultBuilder Results(*this);
+ for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
+ CandEnd = CandidateSet.end();
+ Cand != CandEnd; ++Cand) {
+ if (Cand->Viable)
+ Results.MaybeAddResult(Result(Cand->Function, 0), 0);
+ }
+
+ HandleCodeCompleteResults(CodeCompleter, Results.data(), Results.size());
+}
+
void Sema::CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
bool EnteringContext) {
if (!SS.getScopeRep() || !CodeCompleter)