diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-01-21 15:46:19 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-01-21 15:46:19 +0000 |
commit | ff59f676d04eeeabe29935d16d581ead23a21ef0 (patch) | |
tree | 088e00193a8f19163107573b00f6a54f82031c1f | |
parent | 232085d50a4f33b8590f32697ae32924c165fa61 (diff) | |
download | bcm5719-llvm-ff59f676d04eeeabe29935d16d581ead23a21ef0.tar.gz bcm5719-llvm-ff59f676d04eeeabe29935d16d581ead23a21ef0.zip |
Teach code-completion to deal with calls to functions without prototypes.
llvm-svn: 94076
-rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 36 | ||||
-rw-r--r-- | clang/test/CodeCompletion/call.c | 15 |
2 files changed, 36 insertions, 15 deletions
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index a4cda014aae..fcd419bb10f 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -2234,30 +2234,36 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn, // FIXME: What if we're calling a pseudo-destructor? // FIXME: What if we're calling a member function? + typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate; + llvm::SmallVector<ResultCandidate, 8> Results; + Expr *NakedFn = Fn->IgnoreParenCasts(); if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn)) AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet, /*PartialOverloading=*/ true); else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) { FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl()); - if (FDecl) - AddOverloadCandidate(FDecl, Args, NumArgs, CandidateSet, - false, false, /*PartialOverloading*/ true); + if (FDecl) { + if (!FDecl->getType()->getAs<FunctionProtoType>()) + Results.push_back(ResultCandidate(FDecl)); + else + AddOverloadCandidate(FDecl, Args, NumArgs, CandidateSet, + false, false, /*PartialOverloading*/ true); + } } - // Sort the overload candidate set by placing the best overloads first. - std::stable_sort(CandidateSet.begin(), CandidateSet.end(), - IsBetterOverloadCandidate(*this)); + if (!CandidateSet.empty()) { + // 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::OverloadCandidate ResultCandidate; - llvm::SmallVector<ResultCandidate, 8> Results; - - for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(), - CandEnd = CandidateSet.end(); - Cand != CandEnd; ++Cand) { - if (Cand->Viable) - Results.push_back(ResultCandidate(Cand->Function)); + // 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)); + } } if (Results.empty()) diff --git a/clang/test/CodeCompletion/call.c b/clang/test/CodeCompletion/call.c new file mode 100644 index 00000000000..8210389ffa5 --- /dev/null +++ b/clang/test/CodeCompletion/call.c @@ -0,0 +1,15 @@ +// Note: the run lines follow their respective tests, since line/column +// matter in this test. +void f0(float x, float y); +void f1(); +void test() { + f0(0, 0); + g0(0, 0); + f1(0, 0); + // RUN: %clang_cc1 -std=c89 -fsyntax-only -code-completion-at=%s:6:6 %s -o - | FileCheck -check-prefix=CC1 %s + // CHECK-CC1: f0(<#float x#>, float y) + // RUN: %clang_cc1 -std=c89 -fsyntax-only -code-completion-at=%s:6:9 %s -o - | FileCheck -check-prefix=CC2 %s + // CHECK-CC2: f0(float x, <#float y#>) + // RUN: %clang_cc1 -std=c89 -fsyntax-only -code-completion-at=%s:8:6 %s -o - | FileCheck -check-prefix=CC3 %s + // CHECK-CC3: f1() +} |