mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-07 08:15:48 +02:00
Bug 530692 - Avoid EvalFunctionCall storing the evaluation for the implicit 'this' twice
EvalFunctionCall.fImplicitThis is sometimes redundant in that the
owner evaluation is already stored by one of the arguments. In
such cases, storing the owner separately in fImplicitThis can lead
to exponential complexity in chained method calls.
We resolve the duplication by computing the implicit this from the
function name evaluation instead of storing it where possible.
This was already implemented for cases where the function name
evaluation is an EvalMemberAccess in commit 659ff8c4a7
. This
commit extends the approach to cases where the function name
evaluation is an EvalID.
Change-Id: Ic71e81b4692c51ffb8e15b3da9fc2dff1a554f05
This commit is contained in:
parent
be792e53ea
commit
276fda83a5
2 changed files with 90 additions and 1 deletions
|
@ -10576,4 +10576,79 @@ public class AST2TemplateTests extends AST2CPPTestBase {
|
|||
public void testTemplateAliasWithVariadicArgs_530086b() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// template<bool, typename _Tp = void>
|
||||
// struct enable_if {};
|
||||
//
|
||||
// template<typename _Tp>
|
||||
// struct enable_if<true, _Tp> { typedef _Tp type; };
|
||||
//
|
||||
// template<typename _Tp> _Tp&& declval();
|
||||
//
|
||||
// template<typename _Signature> class function;
|
||||
//
|
||||
// template<typename _Res, typename... _ArgTypes>
|
||||
// class function<_Res(_ArgTypes...)>
|
||||
// {
|
||||
// template<typename _Func,
|
||||
// typename _Res2 = decltype(declval<_Func&>()(declval<_ArgTypes>()...))>
|
||||
// struct _Callable { };
|
||||
//
|
||||
// public:
|
||||
// template<typename _Functor,
|
||||
// typename = typename enable_if<_Callable<_Functor>::value, void>::type>
|
||||
// function(_Functor);
|
||||
// };
|
||||
//
|
||||
// void do_with_cql_env(function<void(int&)> func);
|
||||
//
|
||||
// void test_range_queries() {
|
||||
// do_with_cql_env([] (auto& e) {
|
||||
// return e.create_table([](auto ks_name) {
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// }).then([&e] {
|
||||
// return e.foo();
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
public void testLongDependentFunctionCallChain_530692() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,6 +85,8 @@ public final class EvalFunctionCall extends CPPDependentEvaluation {
|
|||
if (fArguments.length > 0) {
|
||||
if (fArguments[0] instanceof EvalMemberAccess) {
|
||||
return ((EvalMemberAccess) fArguments[0]).getOwnerEval();
|
||||
} else if (fArguments[0] instanceof EvalID) {
|
||||
return ((EvalID) fArguments[0]).getFieldOwner();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,6 +223,8 @@ public final class EvalFunctionCall extends CPPDependentEvaluation {
|
|||
if (args == fArguments)
|
||||
return this;
|
||||
|
||||
ICPPEvaluation implicitThis = fImplicitThis;
|
||||
|
||||
if (args[0] instanceof EvalFunctionSet && getOverload() == null) {
|
||||
// Resolve the function using the parameters of the function call.
|
||||
EvalFunctionSet functionSet = (EvalFunctionSet) args[0];
|
||||
|
@ -230,9 +234,19 @@ public final class EvalFunctionCall extends CPPDependentEvaluation {
|
|||
if (args[0] == EvalFixed.INCOMPLETE) {
|
||||
return args[0];
|
||||
}
|
||||
|
||||
// For functions sets of member functions, EvalFunctionSet does not store
|
||||
// the value of the object on which the member function is called.
|
||||
// If this value was previously elided (not stored explicitly in
|
||||
// fImplicitThis to avoid duplication with the copy stored in fArguments[0]),
|
||||
// starts storing it in fImplicitThis because *someone* needs to store
|
||||
// the value for correct constexpr evaluation.
|
||||
if (implicitThis == null) {
|
||||
implicitThis = getImplicitThis();
|
||||
}
|
||||
}
|
||||
|
||||
ICPPEvaluation newImplicitThis = fImplicitThis != null ? fImplicitThis.instantiate(context, maxDepth) : null;
|
||||
ICPPEvaluation newImplicitThis = implicitThis != null ? implicitThis.instantiate(context, maxDepth) : null;
|
||||
return new EvalFunctionCall(args, newImplicitThis, getTemplateDefinition());
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue