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 < [email protected]>: > 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 <[email protected]>: > > >> >> On Thu Jan 22 2015 at 10:18:15 PM Francisco Lopes da Silva < >> [email protected]> 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 >>> [email protected] >>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >>> >> >> _______________________________________________ >> cfe-commits mailing list >> [email protected] >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >> >> >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
