From 659ff8c4a7c913a34ab8a3d40234854cb8c169be Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Mon, 12 Dec 2016 23:10:56 -0500 Subject: [PATCH] Avoid EvalFunctionCall storing the evaluation for the implicit 'this' twice In cases where the function argument was an EvalMemberAccess with an ownerEval storing the evaluation for the implicit 'this', the field EvalFunctionCall.fImplicitThis was duplicating this storage, leading to exponential space usage in chained method calls. Change-Id: I56e775143b47a3a7f986c2d86312f122c2d4bcff --- .../cpp/semantics/EvalFunctionCall.java | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java index d8547445f0d..276faf3a1db 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java @@ -59,7 +59,7 @@ public final class EvalFunctionCall extends CPPDependentEvaluation { public EvalFunctionCall(ICPPEvaluation[] args, ICPPEvaluation owner, IBinding templateDefinition) { super(templateDefinition); fArguments = args; - fImplicitThis = owner; + fImplicitThis = getImplicitThis() == owner ? null : owner; } public EvalFunctionCall(ICPPEvaluation[] args, ICPPEvaluation owner, IASTNode pointOfDefinition) { @@ -73,6 +73,19 @@ public final class EvalFunctionCall extends CPPDependentEvaluation { public ICPPEvaluation[] getArguments() { return fArguments; } + + private ICPPEvaluation getImplicitThis() { + if (fImplicitThis != null) + return fImplicitThis; + + if (fArguments.length > 0) { + if (fArguments[0] instanceof EvalMemberAccess) { + return ((EvalMemberAccess) fArguments[0]).getOwnerEval(); + } + } + + return null; + } @Override public boolean isInitializerList() { @@ -245,17 +258,18 @@ public final class EvalFunctionCall extends CPPDependentEvaluation { args[i] = arg; } + ICPPEvaluation implicitThis = getImplicitThis(); ICPPEvaluation owner = null; if (functionBinding instanceof ICPPMethod) { - if (fImplicitThis instanceof EvalBinding) { - IBinding ownerBinding = ((EvalBinding) fImplicitThis).getBinding(); + if (implicitThis instanceof EvalBinding) { + IBinding ownerBinding = ((EvalBinding) implicitThis).getBinding(); if (record.getVariable(ownerBinding) != null) { - owner = new EvalReference(record, ownerBinding, fImplicitThis.getTemplateDefinition()); + owner = new EvalReference(record, ownerBinding, implicitThis.getTemplateDefinition()); } else { - owner = fImplicitThis; + owner = implicitThis; } - } else if (fImplicitThis != null) { - owner = fImplicitThis.computeForFunctionCall(record, context); + } else if (implicitThis != null) { + owner = implicitThis.computeForFunctionCall(record, context); } else { owner = record.getImplicitThis(); } @@ -281,7 +295,8 @@ public final class EvalFunctionCall extends CPPDependentEvaluation { if (!function.isConstexpr()) return EvalFixed.INCOMPLETE; - ActivationRecord record = createActivationRecord(function.getParameters(), fArguments, fImplicitThis, context.getPoint()); + ActivationRecord record = createActivationRecord(function.getParameters(), fArguments, + getImplicitThis(), context.getPoint()); ICPPExecution bodyExec = CPPFunction.getFunctionBodyExecution(function, context.getPoint()); if (bodyExec == null) { if (!(function instanceof ICPPTemplateInstance)