From 2664b7c6f75c72342a453bb041371b68df5d98c5 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Wed, 14 May 2014 03:28:25 -0400 Subject: [PATCH] Bug 432701 - Expose the default value of a function parameter in the AST and store it in the index Change-Id: I4e180442bf2f2fe49d71e406a73253c6796e381b Signed-off-by: Nathan Ridge Reviewed-on: https://git.eclipse.org/r/26499 Tested-by: Hudson CI Reviewed-by: Sergey Prigogin Tested-by: Sergey Prigogin --- .../core/parser/tests/ast2/AST2CPPTests.java | 11 ++++ .../tests/IndexCPPBindingResolutionTest.java | 10 +++ .../cdt/core/dom/ast/cpp/ICPPParameter.java | 11 +++- .../core/dom/parser/ProblemBinding.java | 3 + .../dom/parser/cpp/CPPBuiltinParameter.java | 5 ++ .../parser/cpp/CPPFunctionSpecialization.java | 28 +++------ .../cpp/CPPLambdaExpressionParameter.java | 5 ++ .../core/dom/parser/cpp/CPPParameter.java | 10 +++ .../cpp/CPPParameterSpecialization.java | 15 ++++- .../parser/cpp/semantics/CPPTemplates.java | 61 +++++++++++++++---- .../cpp/semantics/EvalFunctionCall.java | 11 +++- .../composite/cpp/CompositeCPPParameter.java | 6 ++ .../eclipse/cdt/internal/core/pdom/PDOM.java | 7 ++- .../cdt/internal/core/pdom/db/Database.java | 2 +- .../core/pdom/dom/cpp/PDOMCPPParameter.java | 34 ++++++++--- .../cpp/PDOMCPPParameterSpecialization.java | 21 ++++++- 16 files changed, 187 insertions(+), 53 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index c76133a3a7f..fecbd68f63b 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -10663,4 +10663,15 @@ public class AST2CPPTests extends AST2TestBase { IVariable waldo = helper.assertNonProblem("waldo"); assertNull(waldo.getInitialValue().numericalValue()); } + + + // constexpr int foo(int a = 42) { + // return a; + // } + // constexpr int waldo = foo(); + public void testNameLookupInDefaultArgument_432701() throws Exception { + BindingAssertionHelper helper = getAssertionHelper(); + IVariable waldo = helper.assertNonProblem("waldo"); + assertEquals(42, waldo.getInitialValue().numericalValue().longValue()); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java index 940b0012d31..56941e1d3e7 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java @@ -1824,4 +1824,14 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti public void testInheritedConstructorFromUnknownClass() throws Exception { checkBindings(); } + + // constexpr int foo(int a = 42) { + // return a; + // } + + // constexpr int waldo = foo(); + public void testNameLookupInDefaultArgument_432701() throws Exception { + IVariable waldo = getBindingFromASTName("waldo", 5); + assertEquals(42, waldo.getInitialValue().numericalValue().longValue()); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPParameter.java index 7ac37d22210..458dd185a6f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPParameter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2009 IBM Corporation and others. + * Copyright (c) 2005, 2014 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,10 +8,12 @@ * Contributors: * Andrew Niefer (IBM) - Initial API and implementation * Markus Schorn (Wind River Systems) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.core.dom.ast.cpp; import org.eclipse.cdt.core.dom.ast.IParameter; +import org.eclipse.cdt.core.dom.ast.IValue; /** * @noextend This interface is not intended to be extended by clients. @@ -27,6 +29,13 @@ public interface ICPPParameter extends IParameter, ICPPVariable { * if there is a default value or not. */ public boolean hasDefaultValue(); + + /** + * Returns the default value of this parameter if it has one, + * or null otherwise. + * @since 5.7 + */ + public IValue getDefaultValue(); /** * Returns whether this parameter is a parameter pack. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java index 300adbeeb28..8a1f90f3107 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java @@ -387,6 +387,9 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I public boolean hasDefaultValue() { return false; } + public IValue getDefaultValue() { + return null; + } public boolean isParameterPack() { return false; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBuiltinParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBuiltinParameter.java index 3b3793f7b85..9ad98b059d6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBuiltinParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBuiltinParameter.java @@ -90,6 +90,11 @@ public class CPPBuiltinParameter extends PlatformObject implements ICPPParameter return false; } + @Override + public IValue getDefaultValue() { + return null; + } + @Override public boolean isMutable() { return false; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java index f0d4e6f27aa..d2e1f13c2ae 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2012 IBM Corporation and others. + * Copyright (c) 2005, 2014 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,6 +10,7 @@ * Bryan Wilkinson (QNX) * Markus Schorn (Wind River Systems) * Sergey Prigogin (Google) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -56,28 +57,13 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP return (ICPPFunction) getSpecializedBinding(); } + public void setParameters(ICPPParameter[] params) { + assert fParams == null; + fParams = params; + } + @Override public ICPPParameter[] getParameters() { - if (fParams == null) { - ICPPFunction function = getFunction(); - ICPPParameter[] params = function.getParameters(); - if (params.length == 0) { - fParams= params; - } else { - // Because of parameter packs there can be more or less parameters in the specialization - final ICPPTemplateParameterMap tparMap = getTemplateParameterMap(); - IType[] ptypes= getType().getParameterTypes(); - final int length = ptypes.length; - ICPPParameter par= null; - fParams = new ICPPParameter[length]; - for (int i = 0; i < length; i++) { - if (i < params.length) { - par= params[i]; - } // else reuse last parameter (which should be a pack) - fParams[i] = new CPPParameterSpecialization(par, this, ptypes[i], tparMap); - } - } - } return fParams; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPLambdaExpressionParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPLambdaExpressionParameter.java index 4b39dce8daf..c39a92b0e0e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPLambdaExpressionParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPLambdaExpressionParameter.java @@ -131,6 +131,11 @@ public class CPPLambdaExpressionParameter extends PlatformObject implements ICPP public boolean hasDefaultValue() { return false; } + + @Override + public IValue getDefaultValue() { + return null; + } @Override public ILinkage getLinkage() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java index 4cae2deaf51..5fd69858443 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java @@ -35,6 +35,7 @@ import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; +import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.core.runtime.PlatformObject; @@ -241,6 +242,15 @@ public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPI return getInitializer() != null; } + @Override + public IValue getDefaultValue() { + IASTInitializer init = getInitializer(); + if (init != null) { + return SemanticUtil.getValueOfInitializer(init, getType(), Value.MAX_RECURSION_DEPTH); + } + return null; + } + @Override public ILinkage getLinkage() { return Linkage.CPP_LINKAGE; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterSpecialization.java index 82c3cfe8e75..2c83fdbf2c7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2010 IBM Corporation and others. + * Copyright (c) 2005, 2014 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * Andrew Niefer (IBM) - Initial API and implementation * Markus Schorn (Wind River Systems) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -23,10 +24,13 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; */ public class CPPParameterSpecialization extends CPPSpecialization implements ICPPParameter { private final IType fType; + private final IValue fDefaultValue; - public CPPParameterSpecialization(ICPPParameter orig, IBinding owner, IType type, ICPPTemplateParameterMap tpmap) { + public CPPParameterSpecialization(ICPPParameter orig, IBinding owner, IType type, IValue defaultValue, + ICPPTemplateParameterMap tpmap) { super(orig, owner, tpmap); fType= type; + fDefaultValue = defaultValue; } private ICPPParameter getParameter(){ @@ -88,7 +92,12 @@ public class CPPParameterSpecialization extends CPPSpecialization implements ICP @Override public boolean hasDefaultValue() { - return getParameter().hasDefaultValue(); + return fDefaultValue != null; + } + + @Override + public IValue getDefaultValue() { + return fDefaultValue; } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 1c358594f66..84e702b9540 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2013 IBM Corporation and others. + * Copyright (c) 2005, 2014 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -136,6 +136,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodTemplateSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameterPackType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameterSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateDefinition; @@ -830,18 +831,46 @@ public class CPPTemplates { ICPPClassSpecialization within = getSpecializationContext(owner); ICPPFunctionType type= (ICPPFunctionType) instantiateType(func.getType(), tpMap, -1, within, point); IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), tpMap, -1, within, point); + CPPFunctionSpecialization spec; if (owner instanceof ICPPClassType && template instanceof ICPPMethod) { if (template instanceof ICPPConstructor) { - instance = new CPPConstructorInstance((ICPPConstructor) template, (ICPPClassType) owner, tpMap, args, type, exceptionSpecs); + spec = new CPPConstructorInstance((ICPPConstructor) template, (ICPPClassType) owner, tpMap, args, type, exceptionSpecs); } else { - instance = new CPPMethodInstance((ICPPMethod) template, (ICPPClassType) owner, tpMap, args, type, exceptionSpecs); + spec = new CPPMethodInstance((ICPPMethod) template, (ICPPClassType) owner, tpMap, args, type, exceptionSpecs); } } else { - instance = new CPPFunctionInstance((ICPPFunction) template, owner, tpMap, args, type, exceptionSpecs); + spec = new CPPFunctionInstance((ICPPFunction) template, owner, tpMap, args, type, exceptionSpecs); } + spec.setParameters(specializeParameters(func.getParameters(), spec, tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point)); + instance = (ICPPTemplateInstance) spec; } return instance; } + + public static ICPPParameter[] specializeParameters(ICPPParameter[] parameters, ICPPFunction functionSpec, + ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth, + IASTNode point) { + if (parameters.length == 0) { + return parameters; + } + + // Because of parameter packs there can be more or less parameters in the specialization + IType[] specializedParameterTypes = functionSpec.getType().getParameterTypes(); + final int length = specializedParameterTypes.length; + ICPPParameter par = null; + ICPPParameter[] result = new ICPPParameter[length]; + for (int i = 0; i < length; i++) { + if (i < parameters.length) { + par = parameters[i]; + } // else reuse last parameter (which should be a pack) + IValue defaultValue = par.getDefaultValue(); + IValue specializedValue = CPPTemplates.instantiateValue(defaultValue, tpMap, + packOffset, within, maxdepth, point); + result[i] = new CPPParameterSpecialization(par, functionSpec, specializedParameterTypes[i], + specializedValue, tpMap); + } + return result; + } public static IBinding createSpecialization(ICPPClassSpecialization owner, IBinding decl, IASTNode point) { IBinding spec = null; @@ -883,6 +912,7 @@ public class CPPTemplates { ICPPFunctionType type= (ICPPFunctionType) instantiateType(func.getType(), tpMap, -1, within, point); IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), tpMap, -1, within, point); + CPPFunctionSpecialization functionSpec = null; if (decl instanceof ICPPFunctionTemplate) { if (decl instanceof ICPPMethod) { CPPMethodTemplateSpecialization methodSpec; @@ -893,19 +923,25 @@ public class CPPTemplates { } methodSpec.setTemplateParameters(CPPTemplates.specializeTemplateParameters(methodSpec, (ICPPScope) methodSpec.getScope(), ((ICPPFunctionTemplate) decl).getTemplateParameters(), owner, point)); - spec = methodSpec; + functionSpec = methodSpec; } else { IBinding oldOwner = decl.getOwner(); - spec = new CPPFunctionTemplateSpecialization((ICPPFunctionTemplate) decl, oldOwner, tpMap, type, exceptionSpecs); + functionSpec = new CPPFunctionTemplateSpecialization((ICPPFunctionTemplate) decl, oldOwner, tpMap, type, exceptionSpecs); } } else if (decl instanceof ICPPConstructor) { - spec = new CPPConstructorSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs); + functionSpec = new CPPConstructorSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs); } else if (decl instanceof ICPPMethod) { - spec = new CPPMethodSpecialization((ICPPMethod) decl, owner, tpMap, type, exceptionSpecs); + functionSpec = new CPPMethodSpecialization((ICPPMethod) decl, owner, tpMap, type, exceptionSpecs); } else if (decl instanceof ICPPFunction) { IBinding oldOwner = decl.getOwner(); - spec = new CPPFunctionSpecialization((ICPPFunction) decl, oldOwner, tpMap, type, exceptionSpecs); + functionSpec = new CPPFunctionSpecialization((ICPPFunction) decl, oldOwner, tpMap, type, exceptionSpecs); } + if (functionSpec != null) { + functionSpec.setParameters(specializeParameters(func.getParameters(), functionSpec, tpMap, -1, within, + Value.MAX_RECURSION_DEPTH, point)); + } + spec = functionSpec; + } else if (decl instanceof ITypedef) { IType type= instantiateType(((ITypedef) decl).getType(), tpMap, -1, getSpecializationContext(owner), point); spec = new CPPTypedefSpecialization(decl, owner, tpMap, type); @@ -1485,8 +1521,11 @@ public class CPPTemplates { IType newType = instantiateType(origInstance.getType(), tpMap, packOffset, within, point); IType[] newExceptionSpecs = instantiateTypes(origInstance.getExceptionSpecification(), tpMap, packOffset, within, point); - return new CPPFunctionInstance((ICPPFunction) origInstance.getTemplateDefinition(), origInstance.getOwner(), - newMap, newArgs, (ICPPFunctionType) newType, newExceptionSpecs); + CPPFunctionInstance result = new CPPFunctionInstance((ICPPFunction) origInstance.getTemplateDefinition(), + origInstance.getOwner(), newMap, newArgs, (ICPPFunctionType) newType, newExceptionSpecs); + result.setParameters(specializeParameters(origInstance.getParameters(), result, tpMap, packOffset, + within, maxdepth, point)); + return result; } } return binding; 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 d3efaa513a8..67ea32446d5 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Wind River Systems, Inc. and others. + * Copyright (c) 2012, 2014 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * Markus Schorn - initial API and implementation * Sergey Prigogin (Google) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; @@ -263,8 +264,12 @@ public class EvalFunctionCall extends CPPDependentEvaluation { if (j < fArguments.length) { map.put(i, fArguments[j++]); } else if (param.hasDefaultValue()) { - IValue value = param.getInitialValue(); - map.put(i, value.getEvaluation()); + IValue value = param.getDefaultValue(); + ICPPEvaluation eval = value.getEvaluation(); + if (eval == null) { + eval = new EvalFixed(param.getType(), ValueCategory.PRVALUE, value); + } + map.put(i, eval); } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPParameter.java index 3ce3c42abe6..d95ec6aad21 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPParameter.java @@ -11,6 +11,7 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.index.composite.cpp; +import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; @@ -24,6 +25,11 @@ class CompositeCPPParameter extends CompositeCPPVariable implements ICPPParamete public boolean hasDefaultValue() { return ((ICPPParameter)rbinding).hasDefaultValue(); } + + @Override + public IValue getDefaultValue() { + return cf.getCompositeValue(((ICPPParameter)rbinding).getDefaultValue()); + } @Override public boolean isParameterPack() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index e15c1db6d56..fe37d18f636 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -251,10 +251,11 @@ public class PDOM extends PlatformObject implements IPDOM { * CDT 8.4 development (versions not supported on the 8.3.x branch) * 170.0 - Unconditionally store arguments of EvalTypeId, bug 430230. * 171.0 - Replacement headers for Organize Includes, bug 414692. + * 172.0 - Store default values for function parameters, bug 432701. */ - private static final int MIN_SUPPORTED_VERSION= version(171, 0); - private static final int MAX_SUPPORTED_VERSION= version(171, Short.MAX_VALUE); - private static final int DEFAULT_VERSION = version(171, 0); + private static final int MIN_SUPPORTED_VERSION= version(172, 0); + private static final int MAX_SUPPORTED_VERSION= version(172, Short.MAX_VALUE); + private static final int DEFAULT_VERSION = version(172, 0); private static int version(int major, int minor) { return (major << 16) + minor; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java index a03f2176e62..fbea564bc35 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java @@ -79,7 +79,7 @@ public class Database { // The lower bound for TYPE_SIZE is 1 + PTR_SIZE, but a slightly larger space for types stored // inline produces in a slightly smaller overall database size. public static final int TYPE_SIZE = 2 + PTR_SIZE; // size of a type in the database in bytes - public static final int VALUE_SIZE = TYPE_SIZE; // size of a value in the database in bytes + public static final int VALUE_SIZE = 1 + PTR_SIZE; // size of a value in the database in bytes public static final int EVALUATION_SIZE = TYPE_SIZE; // size of an evaluation in the database in bytes public static final int ARGUMENT_SIZE = TYPE_SIZE; // size of a template argument in the database in bytes public static final long MAX_DB_SIZE= ((long) 1 << (Integer.SIZE + BLOCK_SIZE_DELTA_BITS)); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPParameter.java index 723887e99a1..0f1958f41a8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPParameter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 QNX Software Systems and others. + * Copyright (c) 2006, 2014 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -9,6 +9,7 @@ * Doug Schaefer (QNX) - Initial API and implementation * Markus Schorn (Wind River Systems) * IBM Corporation + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; @@ -20,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.parser.util.CharArrayUtils; +import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexFragment; import org.eclipse.cdt.internal.core.index.IIndexScope; @@ -37,16 +39,15 @@ import org.eclipse.core.runtime.CoreException; class PDOMCPPParameter extends PDOMNamedNode implements ICPPParameter, IPDOMBinding { private static final int NEXT_PARAM = PDOMNamedNode.RECORD_SIZE; private static final int ANNOTATIONS = NEXT_PARAM + Database.PTR_SIZE; - private static final int FLAGS = ANNOTATIONS + 1; + private static final int DEFAULT_VALUE = ANNOTATIONS + 1; @SuppressWarnings("hiding") - protected static final int RECORD_SIZE = FLAGS + 1; + protected static final int RECORD_SIZE = DEFAULT_VALUE + Database.VALUE_SIZE; static { assert RECORD_SIZE <= 22; // 23 would yield a 32-byte block } - private static final byte FLAG_DEFAULT_VALUE = 0x1; - private final IType fType; + private volatile IValue fDefaultValue = Value.NOT_INITIALIZED; public PDOMCPPParameter(PDOMLinkage linkage, long record, IType type) { super(linkage, record); @@ -57,9 +58,10 @@ class PDOMCPPParameter extends PDOMNamedNode implements ICPPParameter, IPDOMBind throws CoreException { super(linkage, parent, param.getNameCharArray()); fType= null; // This constructor is used for adding parameters to the database, only. + fDefaultValue = param.getDefaultValue(); Database db = getDB(); - db.putByte(record + FLAGS, param.hasDefaultValue() ? FLAG_DEFAULT_VALUE : 0); + linkage.storeValue(record + DEFAULT_VALUE, fDefaultValue); db.putRecPtr(record + NEXT_PARAM, next == null ? 0 : next.getRecord()); storeAnnotations(db, param); @@ -74,9 +76,9 @@ class PDOMCPPParameter extends PDOMNamedNode implements ICPPParameter, IPDOMBind final Database db = getDB(); // Bug 297438: Don't clear the property of having a default value. if (newPar.hasDefaultValue()) { - db.putByte(record + FLAGS, FLAG_DEFAULT_VALUE); + getLinkage().storeValue(record + DEFAULT_VALUE, newPar.getDefaultValue()); } else if (newPar.isParameterPack()) { - db.putByte(record + FLAGS, (byte) 0); + getLinkage().storeValue(record + DEFAULT_VALUE, null); } storeAnnotations(db, newPar); @@ -181,7 +183,20 @@ class PDOMCPPParameter extends PDOMNamedNode implements ICPPParameter, IPDOMBind @Override public boolean hasDefaultValue() { - return hasFlag(FLAG_DEFAULT_VALUE, false, FLAGS); + return getDefaultValue() != null; + } + + @Override + public IValue getDefaultValue() { + if (fDefaultValue == Value.NOT_INITIALIZED) { + try { + fDefaultValue = getLinkage().loadValue(record + DEFAULT_VALUE); + } catch (CoreException e) { + CCorePlugin.log(e); + fDefaultValue = null; + } + } + return fDefaultValue; } @Override @@ -234,6 +249,7 @@ class PDOMCPPParameter extends PDOMNamedNode implements ICPPParameter, IPDOMBind } private void flatDelete(PDOMLinkage linkage) throws CoreException { + linkage.storeValue(record + DEFAULT_VALUE, null); super.delete(linkage); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPParameterSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPParameterSpecialization.java index 9df7e6faf47..ad4af4ed2dd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPParameterSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPParameterSpecialization.java @@ -11,6 +11,7 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; +import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IType; @@ -20,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; +import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.dom.IPDOMBinding; @@ -31,10 +33,12 @@ import org.eclipse.core.runtime.CoreException; */ class PDOMCPPParameterSpecialization extends PDOMCPPSpecialization implements ICPPParameter { private static final int NEXT_PARAM = PDOMCPPSpecialization.RECORD_SIZE; + private static final int DEFAULT_VALUE = NEXT_PARAM + Database.PTR_SIZE; @SuppressWarnings("hiding") - private static final int RECORD_SIZE = NEXT_PARAM + Database.PTR_SIZE; + private static final int RECORD_SIZE = DEFAULT_VALUE + Database.VALUE_SIZE; private final IType fType; + private volatile IValue fDefaultValue = Value.NOT_INITIALIZED; public PDOMCPPParameterSpecialization(PDOMLinkage linkage, long record, IType t) { super(linkage, record); @@ -45,9 +49,11 @@ class PDOMCPPParameterSpecialization extends PDOMCPPSpecialization implements IC PDOMCPPParameter original, PDOMCPPParameterSpecialization next) throws CoreException { super(linkage, parent, (ICPPSpecialization) astParam, original); fType= null; // This constructor is used for adding parameters to the database, only. + fDefaultValue = astParam.getDefaultValue(); Database db = getDB(); db.putRecPtr(record + NEXT_PARAM, next == null ? 0 : next.getRecord()); + linkage.storeValue(record + DEFAULT_VALUE, fDefaultValue); } @Override @@ -109,6 +115,19 @@ class PDOMCPPParameterSpecialization extends PDOMCPPSpecialization implements IC public boolean hasDefaultValue() { return getParameter().hasDefaultValue(); } + + @Override + public IValue getDefaultValue() { + if (fDefaultValue == Value.NOT_INITIALIZED) { + try { + fDefaultValue = getLinkage().loadValue(record + DEFAULT_VALUE); + } catch (CoreException e) { + CCorePlugin.log(e); + fDefaultValue = null; + } + } + return fDefaultValue; + } @Override public boolean isParameterPack() {