r226865 - Sema: code completion for pointer and reference to functions.
Manuel Klimek
klimek at google.com
Fri Jan 23 05:03:37 PST 2015
I think it would be good to add comments that explain that, so the next
person will not be confused :)
Thanks!
On Fri Jan 23 2015 at 1:28:36 PM Francisco Lopes <
francisco.mailing.lists at oblita.com> wrote:
> You made me recall that not only TooManyArguments must be checked, but
> also if the prototype is variadic.
>
> 2015-01-23 10:25 GMT-02:00 Francisco Lopes <
> francisco.mailing.lists at oblita.com>:
>
> Hi Manuel,
>>
>> FunctionType doesn't have getNumParams(). At this point it shouldn't have
>> a prototype, so it should
>> be a function without one (FunctionNoPrototype), K & R style.
>>
>>
>> 2015-01-23 8:14 GMT-02:00 Manuel Klimek <klimek at google.com>:
>>
>>
>>>
>>> On Thu Jan 22 2015 at 10:18:15 PM Francisco Lopes da Silva <
>>> oblita at gmail.com> wrote:
>>>
>>>> Author: francisco.lopes
>>>> Date: Thu Jan 22 15:14:08 2015
>>>> New Revision: 226865
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=226865&view=rev
>>>> Log:
>>>> Sema: code completion for pointer and reference to functions.
>>>>
>>>> Added:
>>>> cfe/trunk/test/Index/complete-pointer-and-reference-to-
>>>> functions.cpp
>>>> Modified:
>>>> cfe/trunk/lib/Sema/SemaCodeComplete.cpp
>>>>
>>>> Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
>>>> SemaCodeComplete.cpp?rev=226865&r1=226864&r2=226865&view=diff
>>>> ============================================================
>>>> ==================
>>>> --- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
>>>> +++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Thu Jan 22 15:14:08 2015
>>>> @@ -3896,7 +3896,6 @@ void Sema::CodeCompleteCall(Scope *S, Ex
>>>>
>>>> // FIXME: Provide support for highlighting optional parameters.
>>>> // FIXME: Provide support for variadic template functions.
>>>> - // FIXME: Provide support for pointers and references to functions.
>>>>
>>>> // Ignore type-dependent call expressions entirely.
>>>> if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args) ||
>>>> @@ -3928,30 +3927,13 @@ void Sema::CodeCompleteCall(Scope *S, Ex
>>>> AddFunctionCandidates(Decls, ArgExprs, CandidateSet, TemplateArgs,
>>>> /*SuppressUsedConversions=*/false,
>>>> /*PartialOverloading=*/true);
>>>> - } else if (auto DC = NakedFn->getType()->getCanonicalTypeInternal()
>>>> - ->getAsCXXRecordDecl()) {
>>>> - // If it's a CXXRecordDecl, it may overload the function call
>>>> operator,
>>>> - // so we check if it does and add them as candidates.
>>>> - 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, as a possibly resolved expression, whether it
>>>> can be
>>>> - // converted to a function.
>>>> 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) {
>>>> + if (FD) { // We check whether it's a resolved function declaration.
>>>> if (!getLangOpts().CPlusPlus ||
>>>> !FD->getType()->getAs<FunctionProtoType>())
>>>> Results.push_back(ResultCandidate(FD));
>>>> @@ -3960,6 +3942,34 @@ void Sema::CodeCompleteCall(Scope *S, Ex
>>>> 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.
>>>> + 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))
>>>> + Results.push_back(ResultCandidate(FP));
>>>> + } else if (auto FT = T->getAs<FunctionType>())
>>>>
>>>
>>> Why don't we have to check for TooManyArguments here?
>>>
>>>
>>>> + Results.push_back(ResultCandidate(FT));
>>>> }
>>>> }
>>>>
>>>>
>>>> Added: cfe/trunk/test/Index/complete-pointer-and-reference-to-
>>>> functions.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/
>>>> complete-pointer-and-reference-to-functions.cpp?rev=226865&view=auto
>>>> ============================================================
>>>> ==================
>>>> --- cfe/trunk/test/Index/complete-pointer-and-reference-to-functions.cpp
>>>> (added)
>>>> +++ cfe/trunk/test/Index/complete-pointer-and-reference-to-functions.cpp
>>>> Thu Jan 22 15:14:08 2015
>>>> @@ -0,0 +1,34 @@
>>>> +// Note: the run lines follow their respective tests, since line/column
>>>> +// matter in this test.
>>>> +
>>>> +template<class T> void (&foo(T))(T);
>>>> +template<class T> void (*bar(T))(T);
>>>> +
>>>> +int main() {
>>>> + foo(42)(42);
>>>> + bar(42)(42);
>>>> +}
>>>> +
>>>> +// RUN: c-index-test -code-completion-at=%s:8:11 %s | FileCheck
>>>> -check-prefix=CHECK-CC1 %s
>>>> +// CHECK-CC1: OverloadCandidate:{Text void}{LeftParen
>>>> (}{CurrentParameter int}{RightParen )} (1)
>>>> +// CHECK-CC1: Completion contexts:
>>>> +// CHECK-CC1-NEXT: Any type
>>>> +// CHECK-CC1-NEXT: Any value
>>>> +// CHECK-CC1-NEXT: Enum tag
>>>> +// CHECK-CC1-NEXT: Union tag
>>>> +// CHECK-CC1-NEXT: Struct tag
>>>> +// CHECK-CC1-NEXT: Class name
>>>> +// CHECK-CC1-NEXT: Nested name specifier
>>>> +// CHECK-CC1-NEXT: Objective-C interface
>>>> +
>>>> +// RUN: c-index-test -code-completion-at=%s:9:11 %s | FileCheck
>>>> -check-prefix=CHECK-CC2 %s
>>>> +// CHECK-CC2: OverloadCandidate:{Text void}{LeftParen
>>>> (}{CurrentParameter int}{RightParen )} (1)
>>>> +// CHECK-CC2: Completion contexts:
>>>> +// CHECK-CC2-NEXT: Any type
>>>> +// CHECK-CC2-NEXT: Any value
>>>> +// CHECK-CC2-NEXT: Enum tag
>>>> +// CHECK-CC2-NEXT: Union tag
>>>> +// CHECK-CC2-NEXT: Struct tag
>>>> +// CHECK-CC2-NEXT: Class name
>>>> +// CHECK-CC2-NEXT: Nested name specifier
>>>> +// CHECK-CC2-NEXT: Objective-C interface
>>>>
>>>>
>>>> _______________________________________________
>>>> cfe-commits mailing list
>>>> cfe-commits at cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>>
>>>
>>> _______________________________________________
>>> cfe-commits mailing list
>>> cfe-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150123/21ea67c0/attachment.html>
More information about the cfe-commits
mailing list