1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-19 15:05:36 +02:00

Bug 490475. Support the evaluation of C++14 constexpr functions

Change-Id: I05029f26b6d33cbeeab8138a270b38c4018b64b5
Signed-off-by: Toni Suter <tsuter@hsr.ch>
Signed-off-by: Silvano Brugnoni <sbrugnon@hsr.ch>
This commit is contained in:
Toni Suter 2016-09-16 08:01:06 +02:00 committed by Nathan Ridge
parent 46d0c9633b
commit 25d4502b80
239 changed files with 12731 additions and 1742 deletions

View file

@ -165,7 +165,7 @@ public class ScanfFormatStringSecurityChecker extends AbstractIndexAstChecker {
IType expressionType = idExpression.getExpressionType();
if (expressionType instanceof IArrayType) {
IArrayType arrayExpressionType = (IArrayType) expressionType;
long arraySize = arrayExpressionType.getSize().numericalValue().longValue();
long arraySize = arrayExpressionType.getSize().numberValue().longValue();
if (argumentSize > arraySize) {
reportProblem(ER_ID, idExpression, idExpression.getRawSignature());
}

View file

@ -60,7 +60,7 @@ import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTRangeBasedForStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTryBlockStatement;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.ValueFactory;
import org.eclipse.osgi.util.NLS;
/**
@ -581,11 +581,11 @@ public class ControlFlowGraphBuilder {
if (node instanceof ICfgData) {
IASTNode ast = (IASTNode) ((ICfgData) node).getData();
if (ast instanceof IASTExpression) {
IValue dvalue = Value.create((IASTExpression) ast);
Long numericalValue = dvalue.numericalValue();
IValue dvalue = ValueFactory.create((IASTExpression) ast);
Number numericalValue = dvalue.numberValue();
if (numericalValue == null)
return false;
return numericalValue == testvalue;
return numericalValue.longValue() == testvalue;
}
}
return false;

View file

@ -7789,11 +7789,11 @@ public class AST2CPPTests extends AST2TestBase {
public void testCastInEnumeratorValue_446380() throws Exception {
BindingAssertionHelper ba= getAssertionHelper();
IEnumerator i2 = ba.assertNonProblem("i2", IEnumerator.class);
Long v2 = i2.getValue().numericalValue();
Number v2 = i2.getValue().numberValue();
assertNotNull(v2);
assertEquals(1, v2.intValue());
IEnumerator i3 = ba.assertNonProblem("i3", IEnumerator.class);
Long v3 = i3.getValue().numericalValue();
Number v3 = i3.getValue().numberValue();
assertNotNull(v3);
assertEquals(2, v3.intValue());
ICPPFunction f = ba.assertNonProblemOnFirstIdentifier("f(i3)",ICPPFunction.class);
@ -11302,7 +11302,7 @@ public class AST2CPPTests extends AST2TestBase {
// to its end, the IDE would appear to hang.
BindingAssertionHelper helper = getAssertionHelper();
IVariable waldo = helper.assertNonProblem("waldo");
assertNull(waldo.getInitialValue().numericalValue());
assertNull(waldo.getInitialValue().numberValue());
}
// constexpr int foo(int a = 42) {
@ -11956,6 +11956,43 @@ public class AST2CPPTests extends AST2TestBase {
public void testEnumDeclaredLaterInClass_491747() throws Exception {
parseAndCheckBindings();
}
// class S {
// static S waldo;
// };
// void foo(const S& = S());
public void testValueRepresentationOfClassWithStaticMemberOfOwnType_490475() throws Exception {
BindingAssertionHelper helper = getAssertionHelper();
ICPPFunction foo = helper.assertNonProblem("foo");
// Trigger computation of value representation of S().
foo.getParameters()[0].getDefaultValue();
}
// class S {
// S waldo; // invalid
// };
// void foo(const S& = S());
public void testClassDirectlyAggregatingItself_490475() throws Exception {
BindingAssertionHelper helper = getAssertionHelper();
ICPPFunction foo = helper.assertNonProblem("foo");
// Trigger computation of value representation of S().
foo.getParameters()[0].getDefaultValue();
}
// class T;
// class S {
// T waldo; // invalid
// };
// class T {
// S waldo;
// };
// void foo(const T& = T());
public void testClassIndirectlyAggregatingItself_490475() throws Exception {
BindingAssertionHelper helper = getAssertionHelper();
ICPPFunction foo = helper.assertNonProblem("foo");
// Trigger computation of value representation of S().
foo.getParameters()[0].getDefaultValue();
}
// namespace std {
// template<typename T> class initializer_list;

View file

@ -94,7 +94,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
@ -3077,12 +3077,12 @@ public class AST2TemplateTests extends AST2TestBase {
ICPPTemplateInstance ci1= assertInstance(t.getType(), ICPPTemplateInstance.class, ICPPClassType.class);
ICPPTemplateParameterMap args1= ci1.getTemplateParameterMap();
assertEquals(1, args1.getAllParameterPositions().length);
assertEquals(256, args1.getArgument(0).getNonTypeValue().numericalValue().intValue());
assertEquals(256, args1.getArgument(0).getNonTypeValue().numberValue().intValue());
ICPPTemplateInstance ct= ba.assertNonProblem("C<_256> ", 7, ICPPTemplateInstance.class, ICPPClassType.class);
ICPPTemplateParameterMap args= ct.getTemplateParameterMap();
assertEquals(1, args.getAllParameterPositions().length);
assertEquals(256, args.getArgument(0).getNonTypeValue().numericalValue().intValue());
assertEquals(256, args.getArgument(0).getNonTypeValue().numberValue().intValue());
ba.assertNonProblem("foo(t)", 3);
ba.assertNonProblem("bar(t)", 3);
@ -3101,7 +3101,7 @@ public class AST2TemplateTests extends AST2TestBase {
ICPPDeferredClassInstance ci= ba.assertNonProblem("C<y>", 4, ICPPDeferredClassInstance.class);
ICPPTemplateArgument[] args= ci.getTemplateArguments();
assertEquals(1, args.length);
assertEquals(0, Value.isTemplateParameter(args[0].getNonTypeValue()));
assertEquals(0, IntegralValue.isTemplateParameter(args[0].getNonTypeValue()));
}
// template<int x>
@ -6961,8 +6961,8 @@ public class AST2TemplateTests extends AST2TestBase {
ICPPSpecialization buffRef = assertionHelper.assertNonProblem("myA.buff[0] = 1;", "buff", ICPPSpecialization.class);
assertEquals(buff, buffRef.getSpecializedBinding());
assertEquals(Long.valueOf(4),buffRef.getTemplateParameterMap().getArgument(0).getNonTypeValue().numericalValue());
assertEquals(Long.valueOf(5),buffRef.getTemplateParameterMap().getArgument(1).getNonTypeValue().numericalValue());
assertEquals(Long.valueOf(4),buffRef.getTemplateParameterMap().getArgument(0).getNonTypeValue().numberValue());
assertEquals(Long.valueOf(5),buffRef.getTemplateParameterMap().getArgument(1).getNonTypeValue().numberValue());
}
// template<typename T, int Size>
@ -6986,7 +6986,7 @@ public class AST2TemplateTests extends AST2TestBase {
assertEquals(buff, buffRef.getSpecializedBinding());
assertSameType(buffRef.getTemplateParameterMap().getArgument(0).getTypeValue(), new CPPBasicType(IBasicType.Kind.eInt, 0));
assertEquals(Long.valueOf(5),buffRef.getTemplateParameterMap().getArgument(1).getNonTypeValue().numericalValue());
assertEquals(Long.valueOf(5),buffRef.getTemplateParameterMap().getArgument(1).getNonTypeValue().numberValue());
}
// template<typename T>
@ -8008,7 +8008,7 @@ public class AST2TemplateTests extends AST2TestBase {
BindingAssertionHelper ah = getAssertionHelper();
IEnumerator binding = ah.assertNonProblem("C<bool>::id", "id");
IValue value = binding.getValue();
Long num = value.numericalValue();
Number num = value.numberValue();
assertNotNull(num);
assertEquals(1, num.longValue());
}
@ -9433,6 +9433,7 @@ public class AST2TemplateTests extends AST2TestBase {
//
// template <class T>
// struct D {
// D(T);
// T t;
// };
//
@ -9602,4 +9603,43 @@ public class AST2TemplateTests extends AST2TestBase {
public void testDisambiguationInNoexceptSpecifier_467332() throws Exception {
parseAndCheckBindings();
}
// template <typename T>
// struct C {
// T field;
// void meow();
// };
// struct S {
// template <typename U>
// auto operator()(U u) -> decltype(C<U>{u});
// };
// int main() {
// S()(0).meow(); // ERROR: Method 'meow' could not be resolved
// }
public void testBraceInitialization_490475a() throws Exception {
parseAndCheckBindings();
}
// struct S {
// int x;
// int y;
// };
//
// constexpr int foo(S a, S b) {
// return a.x - b.x;
// }
//
// constexpr S a = S{8, 0};
// constexpr S b = S{21, 0};
//
// constexpr int waldo = foo(a, b);
public void testBraceInitialization_490475b() throws Exception {
BindingAssertionHelper helper = getAssertionHelper();
IVariable waldo = helper.assertNonProblem("waldo");
// TODO(nathanridge):
// Actually test that we get the correct value.
// For this, we need to add support for aggregate initialization in EvalTypeId.
// For now, just test that attempting to evaluate doesn't throw an exception.
waldo.getInitialValue();
}
}

View file

@ -514,7 +514,7 @@ public class AST2TestBase extends BaseTestCase {
protected static void assertConstantValue(long expected, IVariable constant) {
IValue value = constant.getInitialValue();
assertNotNull(value);
Long numericalValue = value.numericalValue();
Number numericalValue = value.numberValue();
assertNotNull(numericalValue);
assertEquals(expected, numericalValue.longValue());
}

View file

@ -5752,7 +5752,7 @@ public class AST2Tests extends AST2TestBase {
v= (IVariable) bh.assertNonProblem("b=", 1);
checkValue(v.getInitialValue(), 0);
v= (IVariable) bh.assertNonProblem("c=", 1);
assertNull(v.getInitialValue().numericalValue());
assertNull(v.getInitialValue().numberValue());
IEnumerator e= (IEnumerator) bh.assertNonProblem("e0", 2);
checkValue(e.getValue(), 0);
@ -5769,7 +5769,7 @@ public class AST2Tests extends AST2TestBase {
private void checkValue(IValue initialValue, int i) {
assertNotNull(initialValue);
final Long numericalValue = initialValue.numericalValue();
final Number numericalValue = initialValue.numberValue();
assertNotNull(numericalValue);
assertEquals(i, numericalValue.intValue());
}
@ -6976,10 +6976,10 @@ public class AST2Tests extends AST2TestBase {
IASTEnumerationSpecifier enumSpec = (IASTEnumerationSpecifier)((IASTSimpleDeclaration) tu.getDeclarations()[0]).getDeclSpecifier();
IEnumerator enumeratorBinding = (IEnumerator) enumSpec.getEnumerators()[0].getName().resolveBinding();
IValue value = enumeratorBinding.getValue();
assertEquals(2, value.numericalValue().longValue());
assertEquals(2, value.numberValue().longValue());
IEnumerator enumeratorBinding2 = (IEnumerator) enumSpec.getEnumerators()[1].getName().resolveBinding();
IValue value2 = enumeratorBinding2.getValue();
assertEquals(1, value2.numericalValue().longValue());
assertEquals(1, value2.numberValue().longValue());
}
}
@ -7413,7 +7413,8 @@ public class AST2Tests extends AST2TestBase {
ITypedef tdef= (ITypedef) sdecl.getDeclarators()[0].getName().resolveBinding();
IArrayType at= (IArrayType) tdef.getType();
IValue v= at.getSize();
assertTrue(v.numericalValue() == 4);
assertNotNull(v.numberValue());
assertTrue(v.numberValue().longValue() == 4);
}
}
@ -7500,7 +7501,7 @@ public class AST2Tests extends AST2TestBase {
BindingAssertionHelper helper = new BindingAssertionHelper(code, true);
ICPPTemplateInstance f = helper.assertNonProblem("f(STRINGIFY", "f");
// 7 characters for "foobar" + the null terminator.
assertEquals(7, f.getTemplateArguments()[0].getNonTypeValue().numericalValue().longValue());
assertEquals(7, f.getTemplateArguments()[0].getNonTypeValue().numberValue().longValue());
}
// typedef unsigned char u8;

View file

@ -0,0 +1,67 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import junit.framework.Test;
import junit.framework.TestSuite;
public class AllConstexprEvalTests {
public static Test suite() throws Exception {
final TestSuite suite = new TestSuite();
suite.addTest(ConstructorTests.NonIndexing.suite());
suite.addTest(ConstructorTests.SingleProject.suite());
suite.addTest(MemberFunctionTests.NonIndexing.suite());
suite.addTest(MemberFunctionTests.SingleProject.suite());
suite.addTest(MemberVariableTests.NonIndexing.suite());
suite.addTest(MemberVariableTests.SingleProject.suite());
suite.addTest(FunctionTests.NonIndexing.suite());
suite.addTest(FunctionTests.SingleProject.suite());
suite.addTest(FunctionTemplateTests.NonIndexing.suite());
suite.addTest(FunctionTemplateTests.SingleProject.suite());
suite.addTest(ClassTemplateTests.NonIndexing.suite());
suite.addTest(ClassTemplateTests.SingleProject.suite());
suite.addTest(IfStatementTests.NonIndexing.suite());
suite.addTest(IfStatementTests.SingleProject.suite());
suite.addTest(SwitchStatementTests.NonIndexing.suite());
suite.addTest(SwitchStatementTests.SingleProject.suite());
suite.addTest(WhileStatementTests.NonIndexing.suite());
suite.addTest(WhileStatementTests.SingleProject.suite());
suite.addTest(DoWhileStatementTests.NonIndexing.suite());
suite.addTest(DoWhileStatementTests.SingleProject.suite());
suite.addTest(ForStatementTests.NonIndexing.suite());
suite.addTest(ForStatementTests.SingleProject.suite());
suite.addTest(RangeBasedForStatementTests.NonIndexing.suite());
suite.addTest(RangeBasedForStatementTests.SingleProject.suite());
suite.addTest(BinaryOperatorOverloadingTests.NonIndexing.suite());
suite.addTest(BinaryOperatorOverloadingTests.SingleProject.suite());
suite.addTest(UnaryOperatorOverloadingTests.NonIndexing.suite());
suite.addTest(UnaryOperatorOverloadingTests.SingleProject.suite());
suite.addTest(ArrayTests.NonIndexing.suite());
suite.addTest(ArrayTests.SingleProject.suite());
suite.addTest(BinaryExpressionTests.NonIndexing.suite());
suite.addTest(BinaryExpressionTests.SingleProject.suite());
suite.addTest(UnaryExpressionTests.NonIndexing.suite());
suite.addTest(UnaryExpressionTests.SingleProject.suite());
suite.addTest(ReferenceTests.NonIndexing.suite());
suite.addTest(ReferenceTests.SingleProject.suite());
suite.addTest(TypeAliasTests.NonIndexing.suite());
suite.addTest(TypeAliasTests.SingleProject.suite());
suite.addTest(PointerTests.NonIndexing.suite());
suite.addTest(PointerTests.SingleProject.suite());
suite.addTest(UserDefinedLiteralTests.NonIndexing.suite());
suite.addTest(UserDefinedLiteralTests.SingleProject.suite());
suite.addTest(IntegralValueTests.NonIndexing.suite());
suite.addTest(IntegralValueTests.SingleProject.suite());
suite.addTest(FloatingPointValueTests.NonIndexing.suite());
suite.addTest(FloatingPointValueTests.SingleProject.suite());
suite.addTest(CStringValueTests.NonIndexing.suite());
suite.addTest(CStringValueTests.SingleProject.suite());
return suite;
}
}

View file

@ -0,0 +1,244 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import junit.framework.TestSuite;
public class ArrayTests extends TestBase {
public static class NonIndexing extends ArrayTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends ArrayTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// constexpr int f() {
// int foo[3][2] { {1,2}, {2, 3},{ 4, 5} };
// return foo[2][1];
// }
// constexpr int x = f();
public void testInitializationOfMultiDimensionalArrays() throws Exception {
assertEvaluationEquals(5);
}
// constexpr int f() {
// int foo[3] { 1, 2, 3 };
// foo[1] = foo[0] + foo[2];
// return foo[1];
// }
// constexpr int x = f();
public void testAssignmentOfArrays() throws Exception {
assertEvaluationEquals(4);
}
// constexpr int f() {
// int foo[3][2] { {1,2}, {2, 3},{ 4, 5} };
// foo[0][1] = 3;
// return foo[0][1];
// }
// constexpr int x = f();
public void testAssignmentOfMultiDimensionalArrays() throws Exception {
assertEvaluationEquals(3);
}
// constexpr int a[2][2] { { 1, 2 }, { 3, 4 } };
// constexpr int f() {
// return a[0][0];
// }
// constexpr auto x = f();
public void testGlobalArrayAccessValue() throws Exception {
assertEvaluationEquals(1);
}
// constexpr int f() {
// int x[2][2] { { 1, 2 }, { 3, 4 } };
// int &xref { x[1][1] };
// int &xref2 { x[1][1] };
// xref++;
// xref = xref * xref2;
// return x[1][1];
// }
// constexpr auto x = f();
public void testReferenceToArrayCell() throws Exception {
assertEvaluationEquals(25);
}
// constexpr int f() {
// int bar[2] { 3, 7 };
// (*bar)++;
// return bar[0];
// }
// constexpr int x = f();
public void testPointerDereferencingOnArrayName() throws Exception {
assertEvaluationEquals(4);
}
// class S {
// int arr[4];
// public:
// constexpr S():arr{5,6,7,8} {}
// constexpr int *getPtr() {
// return arr;
// }
// };
// constexpr int f() {
// S s{};
// int *ptr = s.getPtr();
// return *ptr;
// }
// constexpr int x = f();
public void testPointerToArrayReturnedFromMemberFunction1() throws Exception {
assertEvaluationEquals(5);
}
// class S {
// int arr[4];
// public:
// constexpr S():arr{5,7,9,11} {}
// constexpr int *getPtr() {
// return arr;
// }
// };
// constexpr int f() {
// S s{};
// int *ptr = s.getPtr();
// ptr += 2;
// return *ptr;
// }
// constexpr int x = f();
public void testPointerToArrayReturnedFromMemberFunction2() throws Exception {
assertEvaluationEquals(9);
}
// class S {
// int arr[4];
// public:
// constexpr S():arr{5,7,9,11} {}
// constexpr int *getBegin() {
// return arr;
// }
// constexpr int *getEnd() {
// return arr + 4;
// }
// };
//
// constexpr int f() {
// S s{};
// int *begin = s.getBegin();
// int *end = s.getEnd();
// int sum = 0;
// for(; begin != end; begin++) {
// sum += *begin;
// }
// return sum;
// }
// constexpr int x = f();
public void testPointerToArrayReturnedFromMemberFunction3() throws Exception {
assertEvaluationEquals(32);
}
// constexpr int f() {
// int arr[] = {1, 2, 3};
// int (&arrRef)[3] = arr;
// return arrRef[2];
// }
// constexpr int x = f();
public void testReferenceToArray1() throws Exception {
assertEvaluationEquals(3);
}
// constexpr int f() {
// int arr[] = {1, 2, 3};
// int (&arrRef)[3] = arr;
// arrRef[2] *= 2;
// return arr[2];
// }
// constexpr int x = f();
public void testReferenceToArray2() throws Exception {
assertEvaluationEquals(6);
}
// constexpr int f() {
// int arr[] = {1, 2, 3};
// int (&arrRef)[3] = arr;
// for(int& i : arrRef) {
// i *= 2;
// }
// return arr[2];
// }
// constexpr int x = f();
public void testReferenceToArray3() throws Exception {
assertEvaluationEquals(6);
}
// constexpr int f() {
// int bar[2][2] { { 3, 5 }, {7, 11 } };
// int * bar_ptr { bar[1] };
// (*bar_ptr)++;
// return *bar_ptr;
// }
// constexpr int x = f();
public void testPointerArithmeticsOnMultidimensionalArray() throws Exception {
assertEvaluationEquals(8);
}
// constexpr void g(int * array) {
// array[0] = 1337;
// }
// constexpr int f() {
// int bar[2] { 1, 2 };
// g(bar);
// return bar[0];
// }
// constexpr int x = f();
public void testPassArrayToFunctionAsPointerAndModifyCell() throws Exception {
assertEvaluationEquals(1337);
}
// constexpr void g(int array[2][2]) {
// array[1][0] = 1337;
// }
// constexpr int f() {
// int bar[2][2] { { 3, 5 }, { 7, 11 } };
// g(bar);
// return bar[1][0];
// }
// constexpr int x = f();
public void testPassMultiDimensionalArrayToFunctionAsPointerAndModifyCell() throws Exception {
assertEvaluationEquals(1337);
}
// constexpr int f() {
// int foo[] { 1, 2, 3, 4, 5 };
// return foo[2];
// }
// constexpr int x = f();
public void testInitializationOfArrays() throws Exception {
assertEvaluationEquals(3);
}
}

View file

@ -0,0 +1,55 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import junit.framework.TestSuite;
public class BinaryExpressionTests extends TestBase {
public static class NonIndexing extends BinaryExpressionTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends BinaryExpressionTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// constexpr bool f() {
// bool a { true };
// return a && false;
// }
// constexpr int x = f();
public void testSimpleBooleanValues() throws Exception {
assertEvaluationEquals(false);
}
// constexpr int f() {
// int x = 5;
// (x=3)++;
// return x;
// }
// constexpr auto x = f();
public void testAssignmentReturnsLValue() throws Exception {
assertEvaluationEquals(4);
}
// constexpr int addTwice(int op1, int op2) {
// op1 += op2;
// op1 += op2;
// return op1;
// }
// constexpr int x = addTwice(2, 5);
public void testBinaryExpressionSequence() throws Exception {
assertEvaluationEquals(12);
}
}

View file

@ -0,0 +1,188 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import junit.framework.TestSuite;
public class BinaryOperatorOverloadingTests extends TestBase {
public static class NonIndexing extends BinaryOperatorOverloadingTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends BinaryOperatorOverloadingTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// struct S {
// constexpr S(int x):x{x} {}
// constexpr int operator+(S const& other) {
// return 12;
// }
// private:
// int x;
// };
//
// constexpr int f() {
// S s1{2};
// S s2{3};
// int x = s1 + s2;
// return x;
// }
// constexpr int x = f();
public void testOverloadedPlusOperatorAsMemberFunction() throws Exception {
assertEvaluationEquals(12);
}
// struct S {
// constexpr S(int x):x{x} {}
// constexpr S operator*(S const& other) {
// return S{x * other.x * 2};
// }
// int x;
// };
//
// constexpr int f() {
// S s1{2};
// S s2{3};
// S s3 = s1 * s2;
// return s3.x;
// }
// constexpr int x = f();
public void testOverloadedMultiplicationOperatorAsMemberFunction() throws Exception {
assertEvaluationEquals(12);
}
// struct S {
// constexpr S(int x, int y):x{x}, y{y} {}
// int x, y;
// };
// constexpr S operator+(S const& s1, S const& s2) {
// return S{s1.x + s2.x + 2, s1.y + s2.y + 4};
// }
//
// constexpr int f() {
// S s1{2, 4};
// S s2{3, 6};
// S s3 = s1 + s2;
// return s3.y;
// }
// constexpr int x = f();
public void testOverloadedPlusOperatorAsNonMemberFunction() throws Exception {
assertEvaluationEquals(14);
}
// struct S {
// constexpr S(int x, int y):x{x*2}, y{y+1} {
// }
// constexpr S operator+(S const& other) {
// S result{x + other.x, y + other.y*2};
// return result;
// }
// int x, y;
// };
// constexpr int f() {
// S s1{2,4};
// S s2{4,8};
// S result{s1 + s2};
// return result.y;
// }
// constexpr int x = f();
public void testOverloadedOperatorPlusComplex1() throws Exception {
assertEvaluationEquals(24);
}
// struct S {
// constexpr S(int x, int y):x{x*2}, y{y+1} {
// }
// constexpr S operator+(S const& other) {
// S result{x + other.x, y + other.y*2};
// return result;
// }
// int x, y;
// };
// constexpr int f() {
// S s1{2,4};
// S s2{4,8};
// S result = s1 + s2;
// return result.x;
// }
// constexpr int x = f();
public void testOverloadedOperatorPlusComplex2() throws Exception {
assertEvaluationEquals(24);
}
// struct S {
// constexpr S(int x, int y):x{x*2}, y{y+1} {
// }
// constexpr S operator+(S const& other) {
// return S{x + other.x, y + other.y*2};
// }
// int x, y;
// };
// constexpr int f() {
// S s1{2,4};
// S s2{4,8};
// S result{s1 + s2};
// return result.y;
// }
// constexpr int x = f();
public void testOverloadedOperatorPlusComplex3() throws Exception {
assertEvaluationEquals(24);
}
// class Point {
// int x, y;
// public:
// constexpr Point(int x, int y):x{x}, y{y} {}
// constexpr bool operator==(Point const& other) const {
// return x == other.x && y == other.y;
// }
// };
// constexpr int f() {
// Point p1{2,4};
// Point p2{2,4};
// return p1 == p2 ? 20 : 40;
// }
// constexpr int x = f();
public void testOverloadedOperatorEquals() throws Exception {
assertEvaluationEquals(20);
}
// class Point {
// int x, y;
// public:
// constexpr Point(int x, int y):x{x}, y{y} {}
// constexpr Point& operator=(Point const& other) {
// x = 2 * other.x;
// y = 2 * other.y;
// return *this;
// }
// constexpr int getY() const { return y; }
// };
// constexpr int f() {
// Point p1{0, 0};
// Point p2{2,5};
// p1 = p2;
// return p1.getY();
// }
// constexpr int x = f();
public void testOverloadedOperatorAssign() throws Exception {
assertEvaluationEquals(10);
}
}

View file

@ -0,0 +1,98 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import junit.framework.TestSuite;
public class CStringValueTests extends TestBase {
public static class NonIndexing extends CStringValueTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends CStringValueTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// constexpr auto x = "Hello, World!";
public void testWithoutPrefix() throws Exception {
assertEvaluationEquals("Hello, World!");
}
// constexpr auto y = "Hello, World!";
// constexpr auto x = y;
public void testStringAssignment() throws Exception {
assertEvaluationEquals("Hello, World!");
}
// constexpr auto x = L"Hello, World!";
public void testLPrefix() throws Exception {
assertEvaluationEquals("Hello, World!");
}
// constexpr auto x = u8"Hello, World!";
public void testu8Prefix() throws Exception {
assertEvaluationEquals("Hello, World!");
}
// constexpr auto x = u"Hello, World!";
public void testuPrefix() throws Exception {
assertEvaluationEquals("Hello, World!");
}
// constexpr auto x = U"Hello, World!";
public void testUPrefix() throws Exception {
assertEvaluationEquals("Hello, World!");
}
//constexpr auto x = R"(This is
//a "raw" \n\n
// literal\0end)";
public void testRawStringLiteral() throws Exception {
assertEvaluationEquals("This is\na \"raw\" \\n\\n\n\tliteral\\0end");
}
//constexpr auto x = R"ab(This is)"
//a "raw" literal)ab";
public void testRawStringLiteralWithDelimiter() throws Exception {
assertEvaluationEquals("This is)\"\na \"raw\" literal");
}
// constexpr auto x = "line 1\n"
// "line 2\n"
// "line 3";
public void testCStringLiteralConcatenation() throws Exception {
assertEvaluationEquals("line 1\nline 2\nline 3");
}
// constexpr auto x = "PI = \u03C0";
public void test16bitUnicodeEscapeSequence() throws Exception {
assertEvaluationEquals("PI = \u03C0");
}
// constexpr int len(const char *str) {
// int len = 0;
// while(str[len] != '\0') {
// len++;
// }
// return len;
// }
//
// constexpr int f() {
// const char *str = "hello";
// return len(str);
// }
// constexpr int x = f();
public void testCStringParam() throws Exception {
assertEvaluationEquals(5);
}
}

View file

@ -0,0 +1,150 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import junit.framework.TestSuite;
public class ClassTemplateTests extends TestBase {
public static class NonIndexing extends ClassTemplateTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends ClassTemplateTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// template<typename T>
// struct Point {
// T x;
// T y;
// constexpr T len() {
// return x * x + y * y;
// }
// };
// constexpr int f() {
// Point<int> a{3,4} ;
// return a.len();
// }
// constexpr int x = f();
public void testInstantiationOfClassTemplate() throws Exception {
assertEvaluationEquals(25);
}
// template<int X>
// struct Multiplier {
// int y;
// constexpr int product() {
// return X * y;
// }
// };
// constexpr int f() {
// Multiplier<5> m{7};
// return m.product();
// }
// constexpr int x = f();
public void testInstantiationOfClassTemplateWithNontypeTemplateParameter1() throws Exception {
assertEvaluationEquals(35);
}
// template<int X, int Y>
// struct Multiplier {
// int x = X;
// int y = Y;
// constexpr int product() {
// return x * y;
// }
// };
// constexpr int f() {
// Multiplier<5, 7> m{};
// return m.product();
// }
// constexpr int x = f();
public void testInstantiationOfClassTemplateWithNontypeTemplateParameter2() throws Exception {
assertEvaluationEquals(35);
}
// template<int X, int Y>
// struct Adder {
// constexpr int sum() {
// return X + Y;
// }
// };
//
// template<int Y>
// using FiveAdder = Adder<5, Y>;
//
// constexpr int f() {
// FiveAdder<12> adder{};
// return adder.sum();
// }
// constexpr int x = f();
public void testAliasTemplate1() throws Exception {
assertEvaluationEquals(17);
}
// template<int T>
// struct X {
// constexpr int get() const {
// return T;
// }
// };
// template<int T>
// struct S : X<2*T> {
// };
// constexpr int f() {
// S<5> s{};
// return s.get();
// }
// constexpr int x = f();
public void testInstantiationOfBaseClassTemplate1() throws Exception {
assertEvaluationEquals(10);
}
// template<int T>
// struct X {
// int x = 2*T;
// };
// template<int T>
// struct S : X<T> {
// constexpr int get() const {
// return 3 * this->x;
// }
// };
// constexpr int f() {
// S<5> s{};
// return s.get();
// }
// constexpr int x = f();
public void testInstantiationOfBaseClassTemplate2() throws Exception {
assertEvaluationEquals(30);
}
// template<int I>
// struct S {
// constexpr S():x{I*2} {}
// int x;
// };
//
// constexpr int f() {
// S<5> s{};
// return s.x;
// }
// constexpr int x = f();
public void testTemplateArgumentInMemberInitializerList() throws Exception {
assertEvaluationEquals(10);
}
}

View file

@ -0,0 +1,557 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import junit.framework.TestSuite;
public class ConstructorTests extends TestBase {
public static class NonIndexing extends ConstructorTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends ConstructorTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// struct S {
// int x;
// constexpr S(int i) : x{i*i} {}
// };
// constexpr auto f() {
// S s(5);
// return s.x;
// }
// constexpr auto x = f();
public void testConstexprConstructorChainInitializers() throws Exception {
assertEvaluationEquals(25);
}
// struct S {
// int x;
// constexpr S(int i) : x{i*i} { x++; }
// };
// constexpr auto f() {
// S s(5);
// return s.x;
// }
// constexpr auto x = f();
public void testConstexprConstructorConstructorBody() throws Exception {
assertEvaluationEquals(26);
}
// struct S {
// int x;
// constexpr S(int i) : x{i*i} { x++; }
// };
// constexpr auto f() {
// S s = S(5);
// return s.x;
// }
// constexpr auto x = f();
public void testConstexprConstructorCopyConstruction() throws Exception {
assertEvaluationEquals(26);
}
// struct S {
// int x;
// constexpr S(int i) : x{i*i} { x++; }
// };
// constexpr auto f() {
// S s = S(5);
// return s.x;
// }
// constexpr auto var = f();
public void testIdempotence() throws Exception {
// Querying a value a second time should produce the same result.
assertEvaluationEquals(26);
assertEvaluationEquals(26);
}
// struct S {
// int x;
// constexpr S() : x{5} { x++; x++; }
// };
// constexpr auto f() {
// S s;
// return s.x;
// }
// constexpr auto x = f();
public void testConstexprConstructorDefaultConstruction() throws Exception {
assertEvaluationEquals(7);
}
// struct Base {
// int base_member;
// constexpr Base(int i) : base_member(i) {}
// };
// struct Derived : Base {
// int derived_member;
// constexpr Derived(int i) : Base(2), derived_member(i) {}
// };
// constexpr auto f() {
// Derived t(1);
// return t.base_member + t.derived_member;
// }
// constexpr auto x = f();
public void testConstexprConstructorInheritance() throws Exception {
assertEvaluationEquals(3);
}
// struct point {
// int x, y;
// };
//
// constexpr int f() {
// point p{2,3};
// return p.y;
// }
// constexpr int x = f();
public void testInitializationOfCompositeValues() throws Exception {
assertEvaluationEquals(3);
}
// struct T {
// constexpr T(int i):x{2*i} {}
// constexpr int get() const { return x; }
// int x;
// };
// struct S {
// T t{2};
// };
// constexpr int f() {
// S s;
// return s.t.get();
// }
// constexpr int x = f();
public void testNestedConstructorCall() throws Exception {
assertEvaluationEquals(4);
}
// struct S {
// constexpr int get() const {
// return x + y;
// }
// private:
// int x = 2;
// int y = 4;
// };
// constexpr int f(S s) {
// return s.get();
// }
// constexpr int x = f(S{});
public void testImplicitConstructorOfLiteralTypeWithImplicitDestructorIsConstexpr() throws Exception {
assertEvaluationEquals(6);
}
// struct S {
// constexpr int get() const {
// return x + y;
// }
// ~S()=default;
// private:
// int x = 2;
// int y = 4;
// };
// constexpr int f(S s) {
// return s.get();
// }
// constexpr int x = f(S{});
public void testImplicitConstructorOfLiteralTypeWithDefaultedDestructorIsConstexpr() throws Exception {
assertEvaluationEquals(6);
}
// struct S {
// constexpr int get() const {
// return x + y;
// }
// ~S() {}
// private:
// int x = 2;
// int y = 4;
// };
// constexpr int f(S s) {
// return s.get();
// }
// constexpr int x = f(S{});
public void testImplicitConstructorOfLiteralTypeWithUserDefinedDestructorIsNotConstexpr() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
// struct S {
// int x = 2;
// int y = 4;
// };
// constexpr int f(S s) {
// return s.x;
// }
// constexpr int x = f(S{});
public void testImplicitConstructorOfAggregateTypeIsConstexpr() throws Exception {
assertEvaluationEquals(2);
}
// struct S {
// S() {}
// int x = 2;
// int y = 4;
// };
// constexpr int f(S s) {
// return s.x;
// }
// constexpr int x = f(S{});
public void testUserDefinedDefaultConstructorIsNotConstexpr() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
// struct S {
// constexpr S(int x):x{x+1} {
// }
// int x;
// };
// constexpr int f() {
// S s(5);
// return s.x;
// }
// constexpr int x = f();
public void testCtorCall() throws Exception {
assertEvaluationEquals(6);
}
// struct S {
// constexpr S(int x):x{x} {
// }
// int x;
// };
//
// constexpr int f() {
// S s1{5};
// S s2{s1.x * 10};
// s1.x = 10;
// return s2.x;
// }
// constexpr int x = f();
public void testArgumentEvaluation() throws Exception {
assertEvaluationEquals(50);
}
// struct B {
// int x, y;
// };
// struct A {
// int m, n, k;
// B b;
// };
// constexpr int f() {
// A a{1, 2, 3, { 4, 5 } };
// return a.b.y;
// }
// constexpr int x = f();
public void testInitializationOfNestedCompositeValues() throws Exception {
assertEvaluationEquals(5);
}
// struct point {
// int x, y;
// };
//
// constexpr int f() {
// point p{2,3};
// p.x = p.y * p.y; // 3 * 3
// return p.x;
// }
// constexpr int x = f();
public void testAssignmentOfCompositeValues() throws Exception {
assertEvaluationEquals(9);
}
// struct B {
// int x, y;
// };
// struct A {
// int m, n, k;
// B b;
// };
//
// constexpr int f() {
// A a{1, 2, 3, { 4, 5 } };
// a.b.y = a.k + a.b.x; // 3 + 4
// return a.b.y;
// }
// constexpr int x = f();
public void testAssignmentOfNestedCompositeValues() throws Exception {
assertEvaluationEquals(7);
}
// struct S {
// int x = 1, y = 3;
// };
// constexpr auto f() {
// S s;
// s.x++;
// return s.x;
// }
// constexpr auto x = f();
public void testStructDefaultInitialization() throws Exception {
assertEvaluationEquals(2);
}
// struct S {
// int x = 1, y = 3;
// };
// constexpr auto f() {
// S s{5, 7};
// s.x++;
// return s.x;
// }
// constexpr auto x = f();
public void testStructDefaultInitializationOverride() throws Exception {
assertEvaluationEquals(6);
}
// struct T {
// int a = 7;
// };
// struct S {
// int x = 1;
// T t;
// };
// constexpr auto f() {
// S s;
// s.t.a++;
// return s.t.a;
// }
// constexpr auto x = f();
public void testNestedStructDefaultInitialization() throws Exception {
assertEvaluationEquals(8);
}
// struct S {
// constexpr S(int x, int y):x{x}, y{y*2} {}
// constexpr int getY() const {
// return y;
// }
// private:
// int x;
// int y;
// };
// constexpr S f() {
// return S{3, 5};
// }
// constexpr int x = f().getY();
public void testSimpleTypeConstructorExpression2() throws Exception {
assertEvaluationEquals(10);
}
// struct S {
// int x, y;
// };
// constexpr S s{1,5};
// constexpr int x = s.y;
public void testInitialValueOfComposite() throws Exception {
assertEvaluationEquals(5);
}
// struct Point {
// constexpr Point(int x, int y):x{x}, y{y*2} {
// }
// int x, y;
// };
// constexpr int f() {
// Point p{5, 6};
// return p.y;
// }
// constexpr int x = f();
public void testCtorInitializerList() throws Exception {
assertEvaluationEquals(12);
}
// struct Point {
// constexpr Point(int x, int y):x{x}, y{y*2} {
// }
// int x, y;
// };
// constexpr int f() {
// Point p(5, 6);
// return p.y;
// }
// constexpr int x = f();
public void testCtorConstructorInitializer() throws Exception {
assertEvaluationEquals(12);
}
// struct Point {
// constexpr Point(int x, int y):x{x}, y{y*2} {
// }
// int x, y;
// };
// constexpr int f() {
// Point p = {5, 6};
// return p.y;
// }
// constexpr int x = f();
public void testCtorEqualsInitializer() throws Exception {
assertEvaluationEquals(12);
}
// struct S {
// constexpr S(int x):x{x*2} {
// }
// int x;
// };
// constexpr int f() {
// S s = 6;
// return s.x;
// }
// constexpr int x = f();
public void testCtorImplicitConversion() throws Exception {
assertEvaluationEquals(12);
}
// struct Point {
// constexpr Point(int x, int y):x{x}, y{y*2} {
// }
// int x, y;
// };
// constexpr int f() {
// Point p1{5, 6};
// Point p2 = p1;
// return p2.y;
// }
// constexpr int x = f();
public void testCtorLvalueCopyConstruction() throws Exception {
assertEvaluationEquals(12);
}
// struct Point {
// constexpr Point(int x, int y):x{x}, y{y*2} {
// }
// int x, y;
// };
// constexpr int f() {
// Point p = Point{5, 6};
// return p.y;
// }
// constexpr int x = f();
public void testCtorRvalueCopyConstruction() throws Exception {
assertEvaluationEquals(12);
}
// struct T {
// int y = 7, z = 11;
// };
// struct S {
// int x = 1;
// T t{8, 12};
// };
// constexpr auto f() {
// S s;
// s.t.y++;
// s.t.z++;
// return s.t.y + s.t.z;
// }
// constexpr auto x = f();
public void testNestedStructDefaultInitializationOverride() throws Exception {
assertEvaluationEquals(22);
}
// struct T {
// int member;
// constexpr T(int i) : member(i) {}
// };
// constexpr auto x = T(2).member;
public void testFundamentalTypeDirectInitializationWithParenthesis() throws Exception {
assertEvaluationEquals(2);
}
// struct Base {
// int x = 5;
// };
// struct Derived : Base {
// int y = 10;
// };
// constexpr int f() {
// Derived d{};
// return d.x;
// }
// constexpr int x = f();
public void testInheritedMemberVariable1() throws Exception {
assertEvaluationEquals(5);
}
// struct X {
// constexpr X(int y):y{2*y} {}
// int y;
// };
// struct Base {
// X x{5};
// };
// struct Derived : Base {
// int n = 2 * x.y;
// };
// constexpr int f() {
// Derived d{};
// return d.n;
// }
// constexpr int x = f();
public void testInheritedMemberVariable2() throws Exception {
assertEvaluationEquals(20);
}
// struct S {
// constexpr S(int x):x{x} {
// }
// int x;
// int y{2 * x};
// };
// constexpr int f() {
// S s{5};
// return s.y;
// }
// constexpr int x = f();
public void testOrderOfFieldInitialization() throws Exception {
assertEvaluationEquals(10);
}
}

View file

@ -0,0 +1,92 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import junit.framework.TestSuite;
public class DoWhileStatementTests extends TestBase {
public static class NonIndexing extends DoWhileStatementTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends DoWhileStatementTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// constexpr int f(int n) {
// int sum { 0 };
// int i { 0 };
// do {
// sum += i;
// i++;
// } while (i <= n);
// return sum;
// }
// constexpr int x = f(10);
public void testDoWhile() throws Exception {
assertEvaluationEquals(55);
}
// constexpr int f() {
// int sum { 0 };
// do {
// sum++;
// } while (true);
// return sum;
// }
// constexpr int x = f();
public void testDoWhileInfiniteLoop() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
// constexpr int f() {
// int sum { 0 };
// do {
// return 42;
// } while (true);
// return sum;
// }
// constexpr int x = f();
public void testDoWhileReturn() throws Exception {
assertEvaluationEquals(42);
}
// constexpr int f(int n) {
// int sum { 0 };
// do
// --n, ++sum;
// while(n > 0);
// return sum;
// }
// constexpr int x = f(10);
public void testDoWhileWithNonCompoundBodyStatement() throws Exception {
assertEvaluationEquals(10);
}
// constexpr int f(int n) {
// int sum { 0 };
// do
// return 42;
// while(n > 0);
// return sum;
// }
// constexpr int x = f(10);
public void testDoWhileWithReturnInNonCompoundBodyStatement() throws Exception {
assertEvaluationEquals(42);
}
}

View file

@ -0,0 +1,111 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import junit.framework.TestSuite;
public class FloatingPointValueTests extends TestBase {
public static class NonIndexing extends FloatingPointValueTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends FloatingPointValueTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// constexpr auto x = 2.5;
public void testDoubleLiteral() throws Exception {
assertEvaluationEquals(2.5);
}
// constexpr auto x = .5f;
public void testFloatLiteral() throws Exception {
assertEvaluationEquals(0.5);
}
// constexpr auto x = 2.l;
public void testLongDoubleLiteral() throws Exception {
assertEvaluationEquals(2.0);
}
// constexpr auto x = 123.456e-67;
public void testDoubleLiteralWithScientificNotation() throws Exception {
assertEvaluationEquals(123.456e-67);
}
// constexpr auto x = .1E4f;
public void testFloatLiteralWithScientificNotation() throws Exception {
assertEvaluationEquals(.1E4f);
}
// constexpr double f() {
// double x = 5.5;
// double y = 2.1;
// return x * 4 + y / 3;
// }
// constexpr double x = f();
public void testBinaryOperationsWithFloatingPointNumbers() throws Exception {
assertEvaluationEquals(22.7);
}
// constexpr bool f() {
// double x = 5.0;
// int y = 5;
// return x == y;
// }
// constexpr bool x = f();
public void testComparisonBetweenFloatingPointValueAndIntegralValue1() throws Exception {
assertEvaluationEquals(true);
}
// constexpr bool f() {
// double x = 5.1;
// int y = 5;
// return x == y;
// }
// constexpr bool x = f();
public void testComparisonBetweenFloatingPointValueAndIntegralValue2() throws Exception {
assertEvaluationEquals(false);
}
// constexpr auto x = float{} + float();
public void testFloatDefaultValue() throws Exception {
assertEvaluationEquals(0);
}
// constexpr auto f() {
// float x{};
// return x;
// }
// constexpr auto x = f();
public void testFloatValueInitialization() throws Exception {
assertEvaluationEquals(0);
}
// constexpr auto x = double{} + double();
public void testDoubleDefaultValue() throws Exception {
assertEvaluationEquals(0);
}
// constexpr auto f() {
// double x{};
// return x;
// }
// constexpr auto x = f();
public void testDoubleValueInitialization() throws Exception {
assertEvaluationEquals(0);
}
}

View file

@ -0,0 +1,207 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import junit.framework.TestSuite;
public class ForStatementTests extends TestBase {
public static class NonIndexing extends ForStatementTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends ForStatementTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// constexpr int f(int n) {
// int sum { 0 };
// for (int i = 0; i <= n; i++) {
// sum += i;
// }
// return sum;
// }
// constexpr int x = f(10);
public void testSimpleIndexBasedForLoop() throws Exception {
assertEvaluationEquals(55);
}
// constexpr int f(int n) {
// int sum { 0 };
// for (int i = 0; i <= n; i++) {
// sum += i;
// return 42;
// }
// return sum;
// }
// constexpr int x = f(10);
public void testReturnInIndexBasedForLoop() throws Exception {
assertEvaluationEquals(42);
}
// constexpr int f(int n) {
// int sum { 0 };
// for (int i = 0; true; i++) {
// sum += i;
// }
// return sum;
// }
// constexpr int x = f(10);
public void testInfiniteLoopInIndexBasedForLoop() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
// constexpr int f(int n) {
// int sum { 0 };
// int i { 0 };
// for (; i < n; i++) {
// sum += i;
// }
// return sum;
// }
// constexpr int x = f(10);
public void testIndexBasedForLoopWithEmptyInitializationStatement() throws Exception {
assertEvaluationEquals(45);
}
// constexpr int f(int n) {
// int sum { 0 };
// for (int i = 0; i < n;) {
// sum += i++;
// }
// return sum;
// }
// constexpr int x = f(10);
public void testIndexBasedForLoopWithEmptyIterationSequence() throws Exception {
assertEvaluationEquals(45);
}
// constexpr int f(int n) {
// int sum { 0 };
// for (int i = 0; i <= n; i++)
// sum += i;
// return sum;
// }
// constexpr int x = f(10);
public void testIndexBasedForLoopWithNonCompoundBodyStatement() throws Exception {
assertEvaluationEquals(55);
}
// constexpr int f(int n) {
// int sum { 0 };
// for (int i = 0; i <= n; i++)
// return 42;
// return sum;
// }
// constexpr int x = f(10);
public void testIndexBasedForLoopWithReturnInNonCompoundBodyStatement() throws Exception {
assertEvaluationEquals(42);
}
// constexpr int f() {
// int sum = 0;
// for(int i = 0; i < 10; ++i) {
// sum++;
// continue;
// sum++;
// }
// return sum;
// }
// constexpr int x = f();
public void testIndexBasedForLoopWithContinueStatement() throws Exception {
assertEvaluationEquals(10);
}
// constexpr int f() {
// int sum = 0;
// int arr[] = {1,2,3,4,5,6,7,8,9,10};
// for(int i = 0; i < 10; ++i) {
// if(i % 2 == 0) {
// continue;
// }
// sum += arr[i];
// }
// return sum;
// }
// constexpr int x = f();
public void testIndexBasedForLoopWithNestedContinueStatement() throws Exception {
assertEvaluationEquals(30);
}
// constexpr int f() {
// int sum = 0;
// int arr[] = {1,2,3,4,5,6,7,8,9,10};
// for(int i = 0; i < 10; ++i) {
// if(i == 5) {
// break;
// }
// sum += arr[i];
// }
// return sum;
// }
// constexpr int x = f();
public void testIndexBasedForLoopWithNestedBreakStatement() throws Exception {
assertEvaluationEquals(15);
}
// constexpr int triple(int x) {
// return x * 3;
// }
// constexpr int f() {
// int sum = 0;
// for(int y = 4; int x = triple(y); y--) {
// sum += x;
// }
// return sum;
// }
// constexpr int x = f();
public void testDeclarationInForStatementCondition1() throws Exception {
assertEvaluationEquals(30);
}
// constexpr int f() {
// int count = 0;
// for(;;) {
// if(count++ > 10) {
// break;
// }
// }
// return count;
// }
// constexpr int x = f();
public void testInfiniteForLoop() throws Exception {
assertEvaluationEquals(12);
}
// constexpr int fac(int n) {
// int result = 1;
// for(int i = 1; i <= n; result *= i++);
// return result;
// }
// constexpr int x = fac(5);
public void testForLoopWithNullStatementAsBody() throws Exception {
assertEvaluationEquals(120);
}
}

View file

@ -0,0 +1,375 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import junit.framework.TestSuite;
public class FunctionTemplateTests extends TestBase {
public static class NonIndexing extends FunctionTemplateTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends FunctionTemplateTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// template<typename T>
// constexpr T add(T a, T b) {
// return a + b;
// }
// constexpr auto x = add(5.5, 6.3);
public void testImplicitTemplateInstantiation() throws Exception {
assertEvaluationEquals(11.8);
}
// class Integer {
// int i;
// public:
// constexpr Integer(int i):i{i} {}
// constexpr int get() const { return i; }
// };
// template<typename T>
// constexpr int f() {
// T t{10};
// return t.get();
// }
// constexpr int x = f<Integer>();
public void testExplicitTemplateInstantiation() throws Exception {
assertEvaluationEquals(10);
}
// template<int I>
// constexpr int f() {
// int result = I * 4;
// return result;
// }
// constexpr int x = f<5>();
public void testTemplateWithNonTypeTemplateParameter() throws Exception {
assertEvaluationEquals(20);
}
// template<typename T>
// constexpr T sum(T v) {
// return v;
// }
// template<typename T, typename... Args>
// constexpr T sum(T first, Args... args) {
// return first + sum(args...);
// }
// constexpr int x = sum(1,2,3,4,5);
public void testVariadicTemplate() throws Exception {
assertEvaluationEquals(15);
}
// template<typename... Args>
// constexpr int count(Args... args) {
// return sizeof...(args);
// }
// constexpr int x = count(1,2,3,4,5);
public void testParameterPackSizeof() throws Exception {
assertEvaluationEquals(5);
}
// class Integer {
// int i;
// public:
// constexpr Integer(int i):i{i} {}
// constexpr int get() const { return i; }
// constexpr bool operator<=(Integer const& rhs) const { return i <= rhs.i; }
// constexpr Integer& operator++() { ++i; return *this; }
// constexpr Integer& operator*=(Integer const& rhs) { i *= rhs.i; return *this; }
// };
//
// template<typename T>
// constexpr int fac(T n) {
// T total{1};
// for(T i{1}; i <= n; ++i) {
// total *= i;
// }
// return total.get();
// }
// constexpr int x = fac(Integer{5});
public void testTemplateInstantiationOfForLoop() throws Exception {
assertEvaluationEquals(120);
}
// class Integer {
// int i;
// public:
// constexpr Integer(int i):i{i} {}
// constexpr int get() const { return i; }
// constexpr bool operator<=(Integer const& rhs) const { return i <= rhs.i; }
// constexpr Integer& operator++() { ++i; return *this; }
// constexpr Integer& operator+=(Integer const& rhs) { i += rhs.i; return *this; }
// };
// template<typename T>
// constexpr int f(T n) {
// T sum { 0 };
// T i { 0 };
// do {
// sum += i;
// ++i;
// } while (i <= n);
// return sum.get();
// }
// constexpr int x = f(Integer{10});
public void testTemplateInstantiationOfDoWhileLoop() throws Exception {
assertEvaluationEquals(55);
}
// template<typename T>
// constexpr T add(T a, T b) {
// ;
// return a + b;
// }
// constexpr auto x = add(5.5, 6.3);
public void testNullStatementInFunctionTemplate() throws Exception {
assertEvaluationEquals(11.8);
}
// class Integer {
// int i;
// public:
// constexpr Integer(int i):i{i} {}
// constexpr int get() const { return i; }
// constexpr bool operator<=(Integer const& rhs) const { return i <= rhs.i; }
// constexpr Integer& operator++() { ++i; return *this; }
// constexpr Integer& operator*=(Integer const& rhs) { i *= rhs.i; return *this; }
// };
//
// template<typename T>
// constexpr int fac(T n) {
// T total{1};
// T i{1};
// while(i <= n) {
// total *= i;
// ++i;
// }
// return total.get();
// }
// constexpr int x = fac(Integer{5});
public void testTemplateInstantiationOfWhileLoop() throws Exception {
assertEvaluationEquals(120);
}
// template<typename T>
// constexpr T div(T a, T b) {
// if(b > 0) {
// return a / b;
// }
// return -1;
// }
// constexpr auto x = div(11.5, 2.0);
public void testTemplateInstantiationOfIfStatement() throws Exception {
assertEvaluationEquals(5.75);
}
// constexpr int count(int first) { return 1; }
// constexpr int count(double first) { return 4; }
// template<typename T, typename... Args>
// constexpr int count(T first, Args... args) {
// return count(first) + count(args...);
// }
// constexpr int x = count(1, 0.5, 3.4, 5, 2.2);
public void testVariadicTemplateWithVaryingTypes() throws Exception {
assertEvaluationEquals(14);
}
// template<typename... Args>
// constexpr int sum(Args... args) {
// int sum = 0;
// for(auto x : {args...}) {
// sum += x;
// }
// return sum;
// }
// constexpr long long x = sum(1,2,3,4,5);
public void testExpansionOfVariadicTemplateParameterIntoInitializerList() throws Exception {
assertEvaluationEquals(15);
}
// template<typename... Args>
// constexpr int sum(Args... args) {
// int sum = 0;
// for(auto x : {(args*2)...}) {
// sum += x;
// }
// return sum;
// }
// constexpr long long x = sum(1,2,3,4,5);
public void testExpressionInVariadicTemplateParameterExpansion1() throws Exception {
assertEvaluationEquals(30);
}
// template<typename... Indices>
// constexpr int sumOfPrimes(Indices... indices) {
// // all prime numbers below 100
// int primes[] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
// int sum = 0;
// for(int prime : {primes[indices]...}) {
// sum += prime;
// }
// return sum;
// }
// constexpr int x = sumOfPrimes(0, 4, 9, 11, 19);
public void testExpressionInVariadicTemplateParameterExpansion2() throws Exception {
assertEvaluationEquals(150);
}
// template<unsigned... Ints>
// class index_sequence{};
//
// template<int... indices>
// constexpr int sumOfPrimes(index_sequence<indices...>) {
// // all prime numbers below 100
// int primes[] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
// int sum = 0;
// for(int prime : {primes[indices]...}) {
// sum += prime;
// }
// return sum;
// }
// constexpr int x = sumOfPrimes(index_sequence<0, 4, 9, 11, 19>{});
public void testIndexSequence1() throws Exception {
assertEvaluationEquals(150);
}
// template<typename T, int size>
// constexpr int getArrayLength(T(&)[size]){
// return size;
// }
// constexpr int f() {
// int arr[10]{};
// return getArrayLength(arr);
// }
// constexpr int x = f();
public void testFunctionTemplateWithArrayParameter1() throws Exception {
assertEvaluationEquals(10);
}
// template<typename T, int size>
// constexpr void doubleArrayContents(T(&arr)[size]) {
// for(int i = 0; i < size; i++) {
// arr[i] *= 2;
// }
// }
// constexpr int f() {
// int arr[]{1,2,3,4,5};
// doubleArrayContents(arr);
// return arr[3];
// }
// constexpr int x = f();
public void testFunctionTemplateWithArrayParameter2() throws Exception {
assertEvaluationEquals(8);
}
// struct S {
// constexpr S(int n):x{n*2} {}
// constexpr int get() { return x; }
// private:
// int x;
// };
// template<int N>
// constexpr int f() {
// S s{N};
// return s.get();
// }
// constexpr int x = f<10>();
public void testInstantiationOfConstructorInFunctionTemplate1() throws Exception {
assertEvaluationEquals(20);
}
// struct Number {
// constexpr Number(int):isFP{false} {}
// constexpr Number(double):isFP{true} {}
// constexpr bool isFloatingPoint() { return isFP; }
// private:
// bool isFP;
// };
// template<typename T>
// constexpr bool f() {
// Number n{T{}};
// return n.isFloatingPoint();
// }
// constexpr bool x = f<double>();
public void testInstantiationOfConstructorInFunctionTemplate2() throws Exception {
assertEvaluationEquals(true);
}
// template<int A, int B>
// struct Adder {
// constexpr int sum() {
// return A + B;
// }
// };
// template<int A, int B>
// constexpr int f() {
// switch(Adder<A, B>{}.sum()) {
// case 10:
// return 1;
// case 11:
// return 2;
// case 12:
// return 3;
// default:
// return 4;
// }
// }
// constexpr int x = f<9,2>();
public void testInstantiationOfSwitchStatement() throws Exception {
assertEvaluationEquals(2);
}
// template<typename T>
// constexpr int f() {
// typedef T myType;
// myType x = 5;
// x *= 5;
// return x;
// }
// constexpr int x = f<int>();
public void testInstantiationOfTypedefDeclaration() throws Exception {
assertEvaluationEquals(25);
}
// template<typename T>
// constexpr int f() {
// using myint = T;
// myint x = 5;
// x *= 5;
// return x;
// }
// constexpr int x = f<int>();
public void testInstantiationOfAliasDeclaration() throws Exception {
assertEvaluationEquals(25);
}
}

View file

@ -0,0 +1,248 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPExecution;
import junit.framework.TestSuite;
public class FunctionTests extends TestBase {
public static class NonIndexing extends FunctionTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends FunctionTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// struct S {
// int x;
// };
// constexpr int g(S const& s) {
// return s.x;
// }
// constexpr int f() {
// S s{5};
// return g(s);
// }
// constexpr int x = f();
public void testAccessMemberOfCompositeParameter() throws Exception {
assertEvaluationEquals(5);
}
// constexpr int function(int n) { return n > 0 ? n + function(n-1) : n; }
// constexpr int x = function(10);
public void testRecursion() throws Exception {
assertEvaluationEquals(55);
}
// constexpr int helper(int n) {
// int m = 5;
// return m + n;
// }
// constexpr int function() {
// int value = helper(5);
// return value + helper(5);
// }
// constexpr int x = function();
public void testEvaluationOfConstexprFunctionCalls() throws Exception {
assertEvaluationEquals(20);
}
// constexpr int g(int i) {
// i++;
// return i;
// }
//
// constexpr auto f() {
// int a = 3;
// int b = g(a);
// b++;
// return a;
// }
// constexpr auto x = f();
public void testFunctionReturnValueIsCopiedAndNotReferenced() throws Exception {
assertEvaluationEquals(3);
}
// constexpr void incr(int x) {
// x = x + 1;
// }
// constexpr int f() {
// int a { 5 };
// incr(a);
// return a;
// }
// constexpr auto x = f();
public void testPassingIntByValue() throws Exception {
assertEvaluationEquals(5);
}
// constexpr void incr(int &x) {
// x++;
// }
// constexpr int f() {
// int a { 5 };
// incr(a);
// return a;
// }
// constexpr auto x = f();
public void testPassingIntByReference1() throws Exception {
assertEvaluationEquals(6);
}
// constexpr void incr(int &x, int &y) {
// x++;
// y++;
// }
// constexpr int f() {
// int a { 5 };
// incr(a, a);
// return a;
// }
// constexpr auto x = f();
public void testPassingIntByReference2() throws Exception {
assertEvaluationEquals(7);
}
// struct S {
// int x;
// };
// constexpr void g(S s) {
// s.x++;
// }
// constexpr int f() {
// S s{5};
// g(s);
// return s.x;
// }
// constexpr int x = f();
public void testPassingCompositeByValue() throws Exception {
assertEvaluationEquals(5);
}
// struct Point { int x, y; };
// constexpr void incr(Point &point) {
// point.x++;
// }
// constexpr int f() {
// Point p{ 2, 4 };
// incr(p);
// return p.x;
// }
// constexpr auto x = f();
public void testPassingCompositeByReference() throws Exception {
assertEvaluationEquals(3);
}
// constexpr int a[2][2] { { 1, 2 }, { 3, 4 } };
// constexpr int const * g() {
// return a[0];
// }
// constexpr int f() {
// return g()[1];
// }
// constexpr auto x = f();
public void testPointerReturnValue() throws Exception {
assertEvaluationEquals(2);
}
// int const y { 5 };
// constexpr int const & g() {
// return y;
// }
// constexpr int f() {
// return g() + 1;
// }
// constexpr auto x = f();
public void testReferenceReturnValue() throws Exception {
assertEvaluationEquals(6);
}
// constexpr void side_effect(int array[], int length) {
// for (int i = 0; i < length; ++i) {
// array[i]++;
// }
// }
// constexpr int f() {
// int array[4] { 1, 2, 3, 4 };
// side_effect(array, 4);
// return array[0];
// }
// constexpr auto x = f();
public void testSideEffectsOnArrayParameter() throws Exception {
assertEvaluationEquals(2);
}
// constexpr int f(int a) {
// {
// int a = 5;
// return a;
// }
// return a;
// }
// constexpr int x = f(10);
public void testBlockScopeValueLookup1() throws Exception {
assertEvaluationEquals(5);
}
// constexpr int f(int a) {
// {
// int a = 5;
// }
// return a;
// }
// constexpr int x = f(10);
public void testBlockScopeValueLookup2() throws Exception {
assertEvaluationEquals(10);
}
// char foo();
// constexpr int almost = sizeof(foo());
// constexpr int x = almost;
public void testSizeofCallToRegularFunction() throws Exception {
assertEvaluationEquals(1);
}
// int f() {
// return 5;
// }
// int x = f();
public void testNonConstexprFunctionDoesntStoreBodyExecution() throws Exception {
IASTInitializerClause clause = getLastDeclarationInitializer();
IASTFunctionCallExpression funcExpr = (IASTFunctionCallExpression)clause;
IASTIdExpression idExpr = (IASTIdExpression)funcExpr.getFunctionNameExpression();
ICPPFunction function = (ICPPFunction)idExpr.getName().resolveBinding();
ICPPExecution bodyExec = CPPFunction.getFunctionBodyExecution(function, clause);
assertNull(bodyExec);
}
}

View file

@ -0,0 +1,197 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import junit.framework.TestSuite;
public class IfStatementTests extends TestBase {
public static class NonIndexing extends IfStatementTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends IfStatementTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// constexpr int f() {
// if (true) {
// return 1;
// }
// return 0;
// }
// constexpr int x = f();
public void testSimpleIfTrueBranch() throws Exception {
assertEvaluationEquals(1);
}
// constexpr int f() {
// if (false) {
// return 1;
// }
// return 0;
// }
// constexpr int x = f();
public void testSimpleIfFalseBranch() throws Exception {
assertEvaluationEquals(0);
}
// constexpr int f() {
// if (true) {
// return 1;
// } else {
// return 0;
// }
// }
// constexpr int x = f();
public void testIfElseTrueBranch() throws Exception {
assertEvaluationEquals(1);
}
// constexpr int f() {
// if (false) {
// return 1;
// } else {
// return 0;
// }
// }
// constexpr int x = f();
public void testSimpleIfElseFalseBranch() throws Exception {
assertEvaluationEquals(0);
}
// constexpr int f() {
// if (false) {
// return 1;
// } else if (true) {
// return 2;
// } else {
// return 0;
// }
// }
// constexpr int x = f();
public void testNestedIfTrueBranch() throws Exception {
assertEvaluationEquals(2);
}
// constexpr int f() {
// if (false) {
// return 1;
// } else if (false) {
// return 2;
// } else {
// return 0;
// }
// }
// constexpr int x = f();
public void testNestedIfFalseBranch() throws Exception {
assertEvaluationEquals(0);
}
// constexpr int f() {
// if (true)
// return 1;
// return 0;
// }
// constexpr int x = f();
public void testIfStatementWithNonCompoundThenClause() throws Exception {
assertEvaluationEquals(1);
}
// constexpr int f() {
// if (false)
// return 1;
// else
// return 0;
// }
// constexpr int x = f();
public void testIfStatementWithNonCompoundElseClause() throws Exception {
assertEvaluationEquals(0);
}
// constexpr int f() {
// int i;
// if (true) {
// i = 10;
// } else {
// i = 20;
// }
// return i;
// }
// constexpr int x = f();
public void testIfStatementWithNonReturnClauses() throws Exception {
assertEvaluationEquals(10);
}
// constexpr int f() {
// int i;
// if (false)
// i = 10;
// else
// i = 20;
// return i;
// }
// constexpr int x = f();
public void testIfStatementWithNonReturnClausesAndNonCompoundElseClause() throws Exception {
assertEvaluationEquals(20);
}
// constexpr int f(int y) {
// if(int x = y*2) {
// return 14 / x;
// } else {
// return 0;
// }
// }
// constexpr int x = f(1);
public void testDeclarationInIfStatementCondition1() throws Exception {
assertEvaluationEquals(7);
}
// constexpr int f(int y) {
// if(int x = y*2) {
// return 14 / x;
// } else {
// return 0;
// }
// }
// constexpr int x = f(0);
public void testDeclarationInIfStatementCondition2() throws Exception {
assertEvaluationEquals(0);
}
// constexpr int g(int x) {
// return x * 2;
// }
// constexpr int f(int y) {
// if(int x = g(y)) {
// return 14 / x;
// } else {
// return 0;
// }
// }
// constexpr int x = f(1);
public void testDeclarationInIfStatementCondition3() throws Exception {
assertEvaluationEquals(7);
}
}

View file

@ -0,0 +1,259 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import junit.framework.TestSuite;
public class IntegralValueTests extends TestBase {
public static class NonIndexing extends IntegralValueTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends IntegralValueTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// constexpr auto x = int{} + int();
public void testIntDefaultValue() throws Exception {
assertEvaluationEquals(0);
}
// constexpr auto f() {
// int x{};
// return x;
// }
// constexpr auto x = f();
public void testIntValueInitialization() throws Exception {
assertEvaluationEquals(0);
}
// constexpr auto x = long{} + long();
public void testLongDefaultValue() throws Exception {
assertEvaluationEquals(0);
}
// constexpr auto f() {
// long x{};
// return x;
// }
// constexpr auto x = f();
public void testLongValueInitialization() throws Exception {
assertEvaluationEquals(0);
}
// constexpr auto x = short{} + short();
public void testShortDefaultValue() throws Exception {
assertEvaluationEquals(0);
}
// constexpr auto f() {
// short x{};
// return x;
// }
// constexpr auto x = f();
public void testShortValueInitialization() throws Exception {
assertEvaluationEquals(0);
}
// constexpr auto x = bool{} + bool();
public void testBooleanDefaulValue() throws Exception {
assertEvaluationEquals(false);
}
// constexpr auto f() {
// bool x{};
// return x;
// }
// constexpr auto x = f();
public void testBoolValueInitialization() throws Exception {
assertEvaluationEquals(0);
}
// constexpr auto x = char{} + char();
public void testCharDefaultValue() throws Exception {
assertEvaluationEquals(0);
}
// constexpr auto f() {
// char x{'c'};
// return x;
// }
// constexpr auto x = f();
public void testCharValueInitialization() throws Exception {
assertEvaluationEquals('c');
}
// constexpr int mul(int op1, int op2) {
// int result = op1 * op2;
// return result;
// }
// constexpr int x = mul(2, 5);
public void testDeclarationWithEqualsInitializerInSequence() throws Exception {
assertEvaluationEquals(10);
}
// constexpr int mul(int op1, int op2) {
// int intermediate1 { op1 };
// int intermediate2 { op2 };
// return intermediate1 * intermediate2;
// }
// constexpr int x = mul(2, 5);
public void testDeclarationWithDefaultInitializationInSequence() throws Exception {
assertEvaluationEquals(10);
}
// constexpr int f() {
// int i(5);
// i++;
// return i;
// }
// constexpr int x = f();
public void testDirectInitializationOnFundamentalTypes() throws Exception {
assertEvaluationEquals(6);
}
// constexpr int f() {
// int invalid;
// return invalid;
// }
// constexpr int x = f();
public void testUseOfUninitializedVariableIsError() throws Exception {
assertEvaluationEquals(IntegralValue.UNKNOWN);
}
// constexpr auto f() {
// int x = 1, y = 1, z = 1;
// return x + y + z;
// }
// constexpr auto x = f();
public void testDeclarationWithMultipleDeclarators() throws Exception {
assertEvaluationEquals(3);
}
// constexpr int f() {
// int i{5};
// i++;
// return i;
// }
// constexpr int x = f();
public void testSimpleTypeConstructionInitializerList() throws Exception {
assertEvaluationEquals(6);
}
// constexpr int f() {
// int i(5);
// i++;
// return i;
// }
// constexpr int x = f();
public void testSimpleTypeConstructionConstructorInitializer() throws Exception {
assertEvaluationEquals(6);
}
// constexpr int f() {
// int i = 5;
// i++;
// return i;
// }
// constexpr int x = f();
public void testSimpleTypeConstructionEqualsInitializer1() throws Exception {
assertEvaluationEquals(6);
}
// constexpr int f() {
// int i = {5};
// i++;
// return i;
// }
// constexpr int x = f();
public void testSimpleTypeConstructionEqualsInitializer2() throws Exception {
assertEvaluationEquals(6);
}
// constexpr int f() {
// int a { 3 };
// int b = a;
// b++;
// return a + b;
// }
// constexpr int x = f();
public void testCopyInitialization() throws Exception {
assertEvaluationEquals(7);
}
// constexpr int f() {
// int y = 0, x = 5;
// x++;
// return x;
// }
// constexpr auto x = f();
public void testMultipleDeclaratorsInOneDeclaration() throws Exception {
assertEvaluationEquals(6);
}
// constexpr int f() {
// return int{5};
// }
// constexpr int x = f();
public void testSimpleTypeConstructorExpression1() throws Exception {
assertEvaluationEquals(5);
}
// constexpr int f() {
// int a { 1 }; // declaration
// a = ++a * ++a; // assignment / side effects
// return a; // returns 6
// }
// constexpr auto x = f();
public void testSideEffects2() throws Exception {
assertEvaluationEquals(6);
}
// constexpr int x = 2;
// constexpr int y = x * 4;
public void testAccessGlobalVariableFromGlobalConstexpr() throws Exception {
assertEvaluationEquals(8);
}
// constexpr int x = 2;
// constexpr int f() { return x * 4; }
// constexpr int y = f();
public void testAccessGlobalVariableFromConstexprFunction() throws Exception {
assertEvaluationEquals(8);
}
// constexpr int x = 0x2a;
public void testHexLiteral() throws Exception {
assertEvaluationEquals(42);
}
}

View file

@ -0,0 +1,184 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import junit.framework.TestSuite;
public class MemberFunctionTests extends TestBase {
public static class NonIndexing extends MemberFunctionTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends MemberFunctionTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// struct S {
// int x, y;
// constexpr int member() {
// return 4;
// }
// };
// constexpr int f() {
// S s{3,7};
// return s.member();
// }
// constexpr auto x = f();
public void testMemberFunctionCall() throws Exception {
assertEvaluationEquals(4);
}
// struct S {
// int x, y;
// constexpr int member() {
// y++;
// return y;
// }
// };
// constexpr int f() {
// S s{3,7};
// return s.member();
// }
// constexpr auto x = f();
public void testMemberFunctionWithImplicitThis() throws Exception {
assertEvaluationEquals(8);
}
// class Point {
// int x, y;
// public:
// constexpr Point(int x, int y):x{x}, y{y} {}
// constexpr int getY() const;
// };
// constexpr int Point::getY() const { return y; }
//
// constexpr int f() {
// Point p{4,5};
// return p.getY();
// }
// constexpr int x = f();
public void testExternallyDefinedMemberFunction() throws Exception {
assertEvaluationEquals(5);
}
// class S {
// int x;
// public:
// constexpr S(int x):x{x} {}
// constexpr void inc() { x += 30; }
// constexpr int get() const { return x; }
// };
//
// constexpr int f() {
// S s{20};
// s.inc();
// return s.get();
// }
// constexpr int x = f();
public void testPlusEqualsWithinMemberFunction() throws Exception {
assertEvaluationEquals(50);
}
// class Point {
// int x, y;
// public:
// constexpr Point(int x, int y):x{x}, y{y} {}
// constexpr int getY() const { return this->y; }
// };
// constexpr int f() {
// Point p{10,40};
// return p.getY();
// }
// constexpr int x = f();
public void testMemberAccessThroughThisPointer() throws Exception {
assertEvaluationEquals(40);
}
// struct S {
// int x, y;
// constexpr int member() {
// y = member2();
// return y;
// }
// constexpr int member2() {
// y++;
// return y;
// }
// };
// constexpr int f() {
// S s{3,7};
// return s.member();
// }
// constexpr auto x = f();
public void testNestedMemberFunctionCallsWithImplicitThis() throws Exception {
assertEvaluationEquals(8);
}
// struct S {
// constexpr S(int x, int y):x{x}, y{y*2} {}
// constexpr int getY() const {
// return y;
// }
// private:
// int x;
// int y;
// };
//
// constexpr S s{3, 5};
// constexpr int f() { return s.getY(); }
// constexpr int x = f();
public void testGlobalMemberFunctionCallFromConstexprFunction() throws Exception {
assertEvaluationEquals(10);
}
// struct S {
// constexpr S(int x, int y):x{x}, y{y*2} {}
// constexpr int getY() const {
// return y;
// }
// private:
// int x;
// int y;
// };
// constexpr S s{3, 5};
// constexpr int x = s.getY();
public void testGlobalMemberFunctionCallFromGlobalConstexpr() throws Exception {
assertEvaluationEquals(10);
}
// struct S {
// constexpr S(int x, int y):x{x}, y{y} {}
// constexpr int add(S const& other) const {
// return y + other.x * 2;
// }
// private:
// int x, y;
// };
//
// constexpr int f() {
// S s1{2, 5};
// S s2{5, 4};
// return s1.add(s2);
// }
// constexpr int x = f();
public void testManualAddMemberFunction() throws Exception {
assertEvaluationEquals(15);
}
}

View file

@ -0,0 +1,117 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import junit.framework.TestSuite;
public class MemberVariableTests extends TestBase {
public static class NonIndexing extends MemberVariableTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends MemberVariableTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// struct Point { int x, y; };
// constexpr int f() {
// Point p{ 2, 4 };
// p.x++;
// return p.x;
// }
// constexpr auto x = f();
public void testIncrementOnCompositeValues() throws Exception {
assertEvaluationEquals(3);
}
// struct S {
// int x, y;
// };
// constexpr int f() {
// const S s{3,7};
// return s.y;
// }
// constexpr auto x = f();
public void testMemberAccessWithConstObject() throws Exception {
assertEvaluationEquals(7);
}
// struct S {
// int x, y;
// };
// constexpr S s{5, 6};
// constexpr int f() { return s.y; }
// constexpr auto x = f();
public void testGlobalMemberAccessFromConstexprFunction() throws Exception {
assertEvaluationEquals(6);
}
// struct S {
// int x, y;
// };
// constexpr S s{5, 6};
// constexpr auto x = s.y;
public void testGlobalMemberAccessFromGlobalConstexpr() throws Exception {
assertEvaluationEquals(6);
}
// struct T {
// constexpr T(int x):x{2*x}{}
// int x;
// };
// struct S {
// T t{5};
// int i = t.x * 2;
// };
// constexpr int f() {
// S s{};
// return s.i;
// }
// constexpr int x = f();
public void testFieldDependsOnOtherField() throws Exception {
assertEvaluationEquals(20);
}
// class S {
// int arr[4]{2,4,6,8};
// public:
// constexpr int *getPtr() {
// return arr;
// }
// };
// constexpr int f() {
// S s{};
// int *ptr = s.getPtr()+2;
// return *ptr;
// }
// constexpr int x = f();
public void testMemberInitializationWithoutUserDefinedCtor() throws Exception {
assertEvaluationEquals(6);
}
// struct S {
// static const int x = 5;
// };
// constexpr int f() {
// return S::x;
// }
// constexpr int x = f();
public void testAccessOfStaticField() throws Exception {
assertEvaluationEquals(5);
}
}

View file

@ -0,0 +1,355 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import junit.framework.TestSuite;
public class PointerTests extends TestBase {
public static class NonIndexing extends PointerTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends PointerTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// constexpr int f() {
// int bar[2] { 3, 7 };
// int * bar_ptr { bar };
// bar_ptr++;
// return *bar_ptr;
// }
// constexpr int x = f();
public void testPointerArithmeticsPostFixIncr() throws Exception {
assertEvaluationEquals(7);
}
// constexpr int f() {
// int bar[2] { 3, 7 };
// int * bar_ptr { bar };
// bar_ptr++;
// bar_ptr--;
// return *bar_ptr;
// }
// constexpr int x = f();
public void testPointerArithmeticsPostFixDecr() throws Exception {
assertEvaluationEquals(3);
}
// constexpr int f() {
// int n { 0 };
// int * nPtr { &n };
// nPtr++;
// return *nPtr;
// }
// constexpr int x = f();
public void testDereferencingOfPointerToInvalidMemoryShouldFail() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar + 2 };
// return *bar_ptr;
// }
// constexpr int x = f();
public void testPointerArithmeticInDeclaration() throws Exception {
assertEvaluationEquals(7);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar };
// int * bar_ptr2 { bar + 3 };
// return bar_ptr2 - bar_ptr;
// }
// constexpr int x = f();
public void testSubtractionOfPointersToSameArrayShouldYieldDistance() throws Exception {
assertEvaluationEquals(3);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar };
// bar_ptr = bar_ptr + 1;
// return *bar_ptr;
// }
// constexpr int x = f();
public void testPointerAddition() throws Exception {
assertEvaluationEquals(5);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar };
// bar_ptr += 2;
// return *bar_ptr;
// }
// constexpr int x = f();
public void testPointerAdditionAndAssignment() throws Exception {
assertEvaluationEquals(7);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar + 2};
// bar_ptr = bar_ptr - 2;
// return *bar_ptr;
// }
// constexpr int x = f();
public void testPointerSubtraction() throws Exception {
assertEvaluationEquals(3);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar + 2 };
// bar_ptr -= 2;
// return *bar_ptr;
// }
// constexpr int x = f();
public void testPointerSubtractionAndAssignment() throws Exception {
assertEvaluationEquals(3);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar };
// int * bar_ptr2 { bar_ptr };
// return *bar_ptr2;
// }
// constexpr int x = f();
public void testPointerDeclarationFromPointer() throws Exception {
assertEvaluationEquals(3);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar };
// int * bar_ptr2 { bar_ptr };
// bar_ptr++;
// return *bar_ptr2;
// }
// constexpr int x = f();
public void testPointersHaveSeparatePositions() throws Exception {
assertEvaluationEquals(3);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar };
// int * bar_ptr2 { bar_ptr + 1 };
// return *bar_ptr2;
// }
// constexpr int x = f();
public void testPointerAdditionInDeclaration() throws Exception {
assertEvaluationEquals(5);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar + 3 };
// int * bar_ptr2 { bar_ptr - 1 };
// return *bar_ptr2;
// }
// constexpr int x = f();
public void testPointerSubtractionInDeclaration() throws Exception {
assertEvaluationEquals(7);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar + 3 };
// bar_ptr++;
// return *bar_ptr;
// }
// constexpr int x = f();
public void testDereferencingOnePastTheEndPointerIsInvalid() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar + 3 };
// bar_ptr++;
// bar_ptr--;
// return *bar_ptr;
// }
// constexpr int x = f();
public void testDereferencingIncrementedOnePastTheEndAndThenDecrementedBackInRageAgainPointerIsValid() throws Exception {
assertEvaluationEquals(11);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar + 3 };
// bar_ptr += 2;
// bar_ptr -= 2;
// return *bar_ptr;
// }
// constexpr int x = f();
public void testDereferencingIncrementedTWOPastTheEndAndThenDecrementedBackInRageAgainPointerIsInvalid() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar };
// bar_ptr--;
// return *bar_ptr;
// }
// constexpr int x = f();
public void testPointerWithNegativePositionIsInvalid() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar };
// bar_ptr--;
// bar_ptr++;
// return *bar_ptr;
// }
// constexpr int x = f();
public void testPointerThatOnceHasNegativePositionStaysInvalid() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar + 4 };
// return *bar_ptr;
// }
// constexpr int x = f();
public void testPointerDeclaredOnePastTheEndIsInvalid() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar + 4 };
// bar_ptr--;
// return *bar_ptr;
// }
// constexpr int x = f();
public void testPointerDeclaredOnePastTheEndAndThenDecrementedBackInRageAgainIsValid() throws Exception {
assertEvaluationEquals(11);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar + 5 };
// bar_ptr -= 2;
// return *bar_ptr;
// }
// constexpr int x = f();
public void testPointerDeclaredTwoPastTheEndAndThenDecrementedBackInRageAgainStaysInvalid() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar - 1 };
// return *bar_ptr;
// }
// constexpr int x = f();
public void testPointerDeclaredWithNegativePositionIsInvalid() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int * bar_ptr { bar - 1 };
// bar_ptr++;
// return *bar_ptr;
// }
// constexpr int x = f();
public void testPointerDelcaredWithNegativePositionStaysInvalid() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
// constexpr int f() {
// int a { 1 }; // declaration
// int b { 2 };
// int * ptr { &a };
// ptr = &b;
// return *ptr;
// }
// constexpr auto x = f();
public void testPointerAssignment() throws Exception {
assertEvaluationEquals(2);
}
// constexpr auto f() {
// int x { 1 };
// int * x_ptr { &x };
// *x_ptr = 2;
// return *x_ptr;
// }
// constexpr auto x = f();
public void testPointerValueAssignment() throws Exception {
assertEvaluationEquals(2);
}
// struct S {
// int x, y;
// };
// constexpr int f() {
// S s { 1, 2 };
// int * s_ptr { &s.x };
// *s_ptr = 3;
// return *s_ptr;
// }
// constexpr auto x = f();
public void testPointerToStructMember() throws Exception {
assertEvaluationEquals(3);
}
// constexpr int f() {
// int a { 5 };
// int * aPtr { &a };
// (*aPtr)++;
// return a;
// }
// constexpr auto x = f();
public void testPointer() throws Exception {
assertEvaluationEquals(6);
}
}

View file

@ -0,0 +1,399 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import junit.framework.TestSuite;
public class RangeBasedForStatementTests extends TestBase {
public static class NonIndexing extends RangeBasedForStatementTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends RangeBasedForStatementTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int sum { 0 };
// for (auto i : bar) {
// sum += i;
// }
// return sum;
// }
// constexpr int x = f();
public void testSimpleRangeBasedForLoop() throws Exception {
assertEvaluationEquals(26);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int sum { 0 };
// for (auto i : bar) {
// return 42;
// }
// return sum;
// }
// constexpr int x = f();
public void testReturnInRangeBasedForLoop() throws Exception {
assertEvaluationEquals(42);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int sum { 0 };
// for (auto& i : bar) {
// i++;
// }
// for (auto i : bar) {
// sum += i;
// }
// return sum;
// }
// constexpr int x = f();
public void testRangeBasedForLoopReferences() throws Exception {
assertEvaluationEquals(30);
}
// constexpr void incr(int & i) {
// i++;
// }
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int sum { 0 };
// for (auto& i : bar) {
// incr(i);
// }
// for (auto i : bar) {
// sum += i;
// }
// return sum;
// }
// constexpr int x = f();
public void testPassReferenceObtainedFromRangeBasedForLoopToFunctionAndModify() throws Exception {
assertEvaluationEquals(30);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int sum { 0 };
// for (auto i : bar)
// sum += i;
// return sum;
// }
// constexpr int x = f();
public void testRangeBasedForLoopWithNonCompoundBodyStatement() throws Exception {
assertEvaluationEquals(26);
}
// constexpr int f() {
// int bar[4] { 3, 5, 7, 11 };
// int sum { 0 };
// for (auto i : bar)
// return 42;
// return sum;
// }
// constexpr int x = f();
public void testRangeBasedForLoopWithReturnInNonCompoundBodyStatement() throws Exception {
assertEvaluationEquals(42);
}
// class Range {
// int arr[5];
// public:
// constexpr Range():arr{1,2,3,4,5} {}
// constexpr const int* begin() const { return arr; }
// constexpr const int* end() const { return arr + 5; }
// };
// constexpr int f() {
// Range range{};
// int sum{0};
// for(int x : range) {
// sum += x;
// }
// return sum;
// }
// constexpr int x = f();
public void testRangeBasedForLoopOverCustomType() throws Exception {
assertEvaluationEquals(15);
}
// class Range {
// int arr[5];
// public:
// constexpr Range():arr{1,2,3,4,5} {}
// constexpr int* begin() {
// return arr;
// }
// constexpr int* end() {
// return arr + 5;
// }
// };
// constexpr int f() {
// Range range{};
// int sum{0};
// for(int &x : range) {
// x++;
// }
// for(int const& x : range) {
// sum += x;
// }
// return sum;
// }
// constexpr int x = f();
public void testRangeBasedForLoopThatModifiesElementsInCustomType() throws Exception {
assertEvaluationEquals(20);
}
// class Range {
// int arr1[5];
// int arr2[5];
// public:
// constexpr Range():arr1{1,2,3,4,5}, arr2{6,7,8,9,10} {}
// constexpr int* begin() { return arr1; }
// constexpr int* end() { return arr1 + 5; }
// constexpr const int* begin() const { return arr2; }
// constexpr const int* end() const { return arr2 + 5; }
// };
// constexpr int f() {
// Range range{};
// int sum{0};
// for(int x : range) {
// sum += x;
// }
// return sum;
// }
// constexpr int x = f();
public void testRangeBasedForLoopOverNonConstRangeChoosesNonConstBeginEnd() throws Exception {
assertEvaluationEquals(15);
}
// class Range {
// int arr1[5];
// int arr2[5];
// public:
// constexpr Range():arr1{1,2,3,4,5}, arr2{6,7,8,9,10} {}
// constexpr int* begin() { return arr1; }
// constexpr int* end() { return arr1 + 5; }
// constexpr const int* begin() const { return arr2; }
// constexpr const int* end() const { return arr2 + 5; }
// };
// constexpr int f() {
// const Range range{};
// int sum{0};
// for(int x : range) {
// sum += x;
// }
// return sum;
// }
// constexpr int x = f();
public void testRangeBasedForLoopOverConstRangeChoosesConstBeginEnd() throws Exception {
assertEvaluationEquals(40);
}
// class Range {
// int arr1[5];
// int arr2[5];
// public:
// constexpr Range():arr1{1,2,3,4,5}, arr2{6,7,8,9,10} {}
// constexpr int* begin() { return arr1; }
// constexpr int* end() { return arr1 + 5; }
// constexpr const int* begin() const { return arr2; }
// constexpr const int* end() const { return arr2 + 5; }
// };
// constexpr int f() {
// Range range{};
// Range const& rangeRef = range;
// int sum{0};
// for(int x : rangeRef) {
// sum += x;
// }
// return sum;
// }
// constexpr int x = f();
public void testRangeBasedForLoopOverConstRefRangeChoosesConstBeginEnd() throws Exception {
assertEvaluationEquals(40);
}
// class Range {
// int arr[5];
// public:
// constexpr Range():arr{1,2,3,4,5} {}
// constexpr const int* begin(int i) const { return arr + i; }
// constexpr const int* end() const { return arr + 5; }
// };
// constexpr int f() {
// Range range{};
// int sum{0};
// for(int x : range) {
// sum += x;
// }
// return sum;
// }
// constexpr int x = f();
public void testRangeBasedForLoopOverCustomTypeWithInvalidBeginMemberFunction() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
// class Range {
// int arr[5];
// public:
// constexpr Range():arr{1,2,3,4,5} {}
// constexpr const int* begin(int i = 0) const { return arr + i; }
// constexpr const int* end() const { return arr + 5; }
// };
// constexpr int f() {
// Range range{};
// int sum{0};
// for(int x : range) {
// sum += x;
// }
// return sum;
// }
// constexpr int x = f();
public void testRangeBasedForLoopOverCustomTypeWithBeginMemberFunctionWithDefaultParameterValue() throws Exception {
assertEvaluationEquals(15);
}
// namespace ns {
// class Vec {
// public:
// int arr1[5];
// constexpr Vec():arr1{1,2,3,4,5} {}
// };
// constexpr int const* begin(Vec const& v) { return v.arr1; }
// constexpr int const* end(Vec const& v) { return v.arr1 + 5; }
// }
//
//
// constexpr int f() {
// ns::Vec v{};
// int sum{0};
// for(int x : v) {
// sum += x;
// }
// return sum;
// }
// constexpr int x = f();
public void testDoesArgumentDependentLookupIfBeginEndMemberFunctionsDontExist() throws Exception {
assertEvaluationEquals(15);
}
// namespace ns {
// class Vec {
// public:
// int arr1[5];
// int arr2[5];
// constexpr Vec():arr1{1,2,3,4,5}, arr2{6,7,8,9,10} {}
// constexpr int const* begin() const { return arr2; }
// constexpr int const* end() const { return arr2 + 5; }
// };
// constexpr int const* begin(Vec const& v) { return v.arr1; }
// constexpr int const* end(Vec const& v) { return v.arr1 + 5; }
// }
//
//
// constexpr int f() {
// ns::Vec v{};
// int sum{0};
// for(int x : v) {
// sum += x;
// }
// return sum;
// }
// constexpr int x = f();
public void testChoosesMemberFunctionsOverFreeFunctions() throws Exception {
assertEvaluationEquals(40);
}
// namespace ns {
// class Vec {
// public:
// int arr1[5];
// constexpr Vec():arr1{1,2,3,4,5} {}
// constexpr int const* begin() const { return arr1; }
// };
// constexpr int const* end(Vec const& v) { return v.arr1 + 5; }
// }
//
//
// constexpr int f() {
// ns::Vec v{};
// int sum{0};
// for(int x : v) {
// sum += x;
// }
// return sum;
// }
// constexpr int x = f();
public void testDoesntMixMemberFunctionsAndFreeFunctions() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
// namespace ns {
// class Vec {
// int arr[5];
// public:
// constexpr Vec():arr{1,2,3,4,5} {}
// constexpr int const* start() const { return arr; }
// constexpr int size() const { return 5; }
// };
// template<typename T>
// constexpr int const* begin(T const& t) { return t.start(); }
// template<typename T>
// constexpr int const* end(T const& t) { return t.start() + t.size(); }
// }
//
// constexpr int f() {
// ns::Vec v{};
// int sum{0};
// for(int x : v) {
// sum += x;
// }
// return sum;
// }
// constexpr int x = f();
public void testWorksWithBeginEndTemplates() throws Exception {
assertEvaluationEquals(15);
}
// constexpr int f() {
// int sum = 0;
// for(auto x : {1,2,3,4,5}) {
// sum += x;
// }
// return sum;
// }
// constexpr int x = f();
public void testRangeBasedForLoopOverInitializerList() throws Exception {
assertEvaluationEquals(15);
}
}

View file

@ -0,0 +1,73 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import junit.framework.TestSuite;
public class ReferenceTests extends TestBase {
public static class NonIndexing extends ReferenceTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends ReferenceTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// constexpr int f() {
// int a { 1 };
// int &aRef { a };
// aRef++;
// return a;
// }
// constexpr int x = f();
public void testSideEffectsOnReferences() throws Exception {
assertEvaluationEquals(2);
}
// constexpr int f() {
// int a { 1 };
// int &aRef { a };
// aRef = aRef + 1;
// return a;
// }
// constexpr int x = f();
public void testAssignmentsOnReferences() throws Exception {
assertEvaluationEquals(2);
}
// constexpr int f() {
// int a { 1 };
// int &aRef { a };
// int &aRefRef { aRef };
// aRefRef++;
// return a;
// }
// constexpr auto x = f();
public void testSideEffectsOnNestedReferences() throws Exception {
assertEvaluationEquals(2);
}
// constexpr int f() {
// int a { 1 };
// int &aRef { a };
// int &aRefRef { aRef };
// aRefRef = aRef + aRefRef;
// return a;
// }
// constexpr auto x = f();
public void testAssignmentOnNestedReferences() throws Exception {
assertEvaluationEquals(2);
}
}

View file

@ -0,0 +1,247 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import junit.framework.TestSuite;
public class SwitchStatementTests extends TestBase {
public static class NonIndexing extends SwitchStatementTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends SwitchStatementTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// constexpr int f() {
// int x { 1 };
// switch (x) {
// case 1:
// return 1;
// case 2:
// return 2;
// default:
// return -1;
// }
// }
// constexpr int x = f();
public void testSwitchFirstCase() throws Exception {
assertEvaluationEquals(1);
}
// constexpr int f() {
// int x { 2 };
// switch (x) {
// case 1:
// return 1;
// case 2:
// return 2;
// default:
// return -1;
// }
// }
// constexpr int x = f();
public void testSwitchMiddleCase() throws Exception {
assertEvaluationEquals(2);
}
// constexpr int f() {
// int x { 3 };
// switch (x) {
// case 1:
// return 1;
// case 2:
// return 2;
// default:
// return -1;
// }
// }
// constexpr int x = f();
public void testSwitchDefault() throws Exception {
assertEvaluationEquals(-1);
}
// constexpr int f() {
// int x { 1 };
// switch (x) {
// case 1:
// case 2:
// return 2;
// default:
// return -1;
// }
// }
// constexpr int x = f();
public void testSwitchFallThrough() throws Exception {
assertEvaluationEquals(2);
}
// constexpr int f() {
// int x { 1 };
// int y = 10;
// switch(x)
// case 1:
// y++;
// y--;
// return y;
// }
// constexpr int x = f();
public void testSwitchWithOnlyOneClause1() throws Exception {
assertEvaluationEquals(10);
}
// constexpr int f() {
// int x { 0 };
// int y = 10;
// switch(x)
// case 1:
// y++;
// y--;
// return y;
// }
// constexpr int x = f();
public void testSwitchWithOnlyOneClause2() throws Exception {
assertEvaluationEquals(9);
}
// constexpr int f() {
// int x { 2 };
// int y = 2;
// switch (x) {
// case 1:
// y = 10;
// break;
// case 2:
// y = 20;
// break;
// default:
// y = 30;
// }
// return y;
// }
// constexpr int x = f();
public void testSwitchBreak() throws Exception {
assertEvaluationEquals(20);
}
// constexpr int f() {
// int x { 3 };
// int y = 2;
// switch (x) {
// case 1:
// y = 10;
// break;
// case 2:
// y = 20;
// break;
// }
// return y;
// }
// constexpr int x = f();
public void testSwitchNoMatchingCaseAndNoDefault() throws Exception {
assertEvaluationEquals(2);
}
// class Point {
// int x, y;
// public:
// constexpr Point(int x, int y):x{x}, y{y*2} {}
// constexpr int getY() const { return y; }
// };
// constexpr int f() {
// int x { 2 };
// int y = 5;
// constexpr Point p{4, 1};
//
// switch (x) {
// case 1:
// y = 10;
// break;
// case p.getY():
// y = 20;
// break;
// }
// return y;
// }
// constexpr int x = f();
public void testSwitchCaseConstants() throws Exception {
assertEvaluationEquals(20);
}
// constexpr int triple(int x) {
// return x * 3;
// }
// constexpr int f(int y) {
// switch(int x = triple(y)) {
// case 9:
// return 1;
// case 12:
// return 2;
// case 15:
// return 3;
// default:
// return 4;
// }
// }
// constexpr int x = f(5);
public void testDeclarationInSwitchStatementController() throws Exception {
assertEvaluationEquals(3);
}
// enum Color { RED, GREEN, BLUE };
// constexpr int f(Color color) {
// switch(color) {
// case RED:
// return 1;
// case GREEN:
// return 2;
// case BLUE:
// return 3;
// }
// }
// constexpr int x = f(BLUE);
public void testSwitchOnEnumValue() throws Exception {
assertEvaluationEquals(3);
}
// constexpr int f() {
// int arr[] = {1,2,1,3,5,6,1,2,0};
// int sum{};
// for(int i : arr) {
// switch(i) {
// case 1:
// sum++;
// break;
// default:
// continue;
// sum += 2;
// }
// }
// return sum;
// }
// constexpr int x = f();
public void testSwitchWithNestedContinueStatement() throws Exception {
assertEvaluationEquals(3);
}
}

View file

@ -0,0 +1,207 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
import org.eclipse.cdt.core.dom.parser.IScannerExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.cpp.ANSICPPParserExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.cpp.GPPScannerExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.cpp.ICPPParserExtensionConfiguration;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.parser.FileContent;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.IncludeFileContentProvider;
import org.eclipse.cdt.core.parser.NullLogService;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.cdt.core.parser.tests.ASTComparer;
import org.eclipse.cdt.core.testplugin.CTestPlugin;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser;
import org.eclipse.cdt.internal.core.dom.parser.CStringValue;
import org.eclipse.cdt.internal.core.dom.parser.FloatingPointValue;
import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluationOwner;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.parser.ParserException;
import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor;
import org.eclipse.cdt.internal.index.tests.IndexBindingResolutionTestBase;
public class TestBase extends IndexBindingResolutionTestBase {
private static final String TEST_CODE = "<testcode>";
private static final IParserLogService NULL_LOG = new NullLogService();
private static final ScannerInfo SCANNER_INFO = new ScannerInfo(getStdMap());
private static Map<String, String> getStdMap() {
Map<String, String> map = new HashMap<>();
map.put("__SIZEOF_SHORT__", "2");
map.put("__SIZEOF_INT__", "4");
map.put("__SIZEOF_LONG__", "8");
map.put("__SIZEOF_POINTER__", "8");
return map;
}
protected void assertEvaluationEquals(boolean expectedValue) throws Exception {
IValue value = getValue();
Number num = value.numberValue();
assertNotNull(num);
assertEquals(expectedValue == false, num.longValue() == 0);
}
protected void assertEvaluationEquals(char expectedValue) throws Exception {
IValue value = getValue();
Number num = value.numberValue();
assertNotNull(num);
assertEquals(expectedValue, num.longValue());
}
protected void assertEvaluationEquals(long expectedValue) throws Exception {
IValue value = getValue();
Number num = value.numberValue();
assertNotNull(num);
assertEquals(expectedValue, num.longValue());
}
protected void assertEvaluationEquals(IValue expectedValue) throws Exception {
IValue value = getValue();
assertEquals(expectedValue, value);
}
protected void assertEvaluationEquals(String expectedValue) throws Exception {
IValue value = getValue();
assertInstance(value, CStringValue.class);
CStringValue cstrValue = (CStringValue) value;
assertEquals(expectedValue, cstrValue.cStringValue());
}
protected void assertEvaluationEquals(double expectedValue) throws Exception {
IValue value = getValue();
assertInstance(value, FloatingPointValue.class);
FloatingPointValue floatingPointValue = (FloatingPointValue) value;
assertEquals(expectedValue, floatingPointValue.numberValue().doubleValue(), 0.001);
}
private IValue getValue() throws Exception {
ICPPASTInitializerClause point = getLastDeclarationInitializer();
ICPPEvaluation evaluation = ((ICPPEvaluationOwner)point).getEvaluation();
return evaluation.getValue(point);
}
protected ICPPASTInitializerClause getLastDeclarationInitializer() throws Exception {
IASTTranslationUnit tu = strategy.getAst(0);
IASTSimpleDeclaration declaration = (IASTSimpleDeclaration) tu.getChildren()[tu.getChildren().length - 1];
IASTEqualsInitializer initializer = (IASTEqualsInitializer) declaration.getDeclarators()[0].getInitializer();
return (ICPPASTInitializerClause) initializer.getInitializerClause();
}
protected class NonIndexingTestStrategy implements ITestStrategy {
private ICProject cproject;
private StringBuilder[] testData;
private IASTTranslationUnit ast;
@Override
public ICProject getCProject() {
return cproject;
}
@Override
public StringBuilder[] getTestData() {
return testData;
}
@Override
public int getAstCount() {
return 1;
}
@Override
public IASTTranslationUnit getAst(int index) {
return ast;
}
@Override
public StringBuilder getAstSource(int index) {
return testData[0];
}
@Override
public void setUp() throws Exception {
CTestPlugin plugin = CTestPlugin.getDefault();
StringBuilder[] builders = TestSourceReader.getContentsForTest(plugin.getBundle(), "parser", TestBase.this.getClass(), getName(), 2);
if(builders.length == 2) {
builders[0].append(builders[1].toString());
}
testData = new StringBuilder[] { builders[0] };
ast = parse(testData[0].toString());
}
@Override
public void tearDown() throws Exception {
}
@Override
public IIndex getIndex() {
return null;
}
@Override
public boolean isCompositeIndex() {
return false;
}
}
protected static IASTTranslationUnit parse(String code) throws ParserException {
IScanner scanner = createScanner(FileContent.create(TEST_CODE, code.toCharArray()), ParserLanguage.CPP, ParserMode.COMPLETE_PARSE, SCANNER_INFO);
AbstractGNUSourceCodeParser parser = null;
ICPPParserExtensionConfiguration config = new ANSICPPParserExtensionConfiguration();
parser = new GNUCPPSourceParser(scanner, ParserMode.COMPLETE_PARSE, NULL_LOG, config, null);
parser.setMaximumTrivialExpressionsInAggregateInitializers(Integer.MAX_VALUE);
IASTTranslationUnit tu = parser.parse();
assertTrue(tu.isFrozen());
validateCopy(tu);
if (parser.encounteredError()) {
throw new ParserException("FAILURE"); //$NON-NLS-1$
}
assertEquals(CPPVisitor.getProblems(tu).length, 0);
assertEquals(0, tu.getPreprocessorProblems().length);
return tu;
}
private static IScanner createScanner(FileContent codeReader, ParserLanguage lang, ParserMode mode,
IScannerInfo scannerInfo) {
IScannerExtensionConfiguration configuration = GPPScannerExtensionConfiguration.getInstance(scannerInfo);
IScanner scanner = new CPreprocessor(codeReader, scannerInfo, lang, NULL_LOG, configuration,
IncludeFileContentProvider.getSavedFilesProvider());
return scanner;
}
private static <T extends IASTNode> T validateCopy(T tu) {
IASTNode copy = tu.copy();
assertFalse(copy.isFrozen());
ASTComparer.assertCopy(tu, copy);
return (T) copy;
}
}

View file

@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import junit.framework.TestSuite;
public class TypeAliasTests extends TestBase {
public static class NonIndexing extends TypeAliasTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends TypeAliasTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// constexpr int f() {
// typedef int myint;
// myint x = 5;
// x *= 5;
// return x;
// }
// constexpr int x = f();
public void testTypedefDeclaration() throws Exception {
assertEvaluationEquals(25);
}
// constexpr int f() {
// using myint = int;
// myint x = 5;
// x *= 5;
// return x;
// }
// constexpr int x = f();
public void testAliasDeclaration() throws Exception {
assertEvaluationEquals(25);
}
}

View file

@ -0,0 +1,133 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import junit.framework.TestSuite;
public class UnaryExpressionTests extends TestBase {
public static class NonIndexing extends UnaryExpressionTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends UnaryExpressionTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// constexpr int doubleIncrement(int n) {
// ++n;
// ++n;
// return n;
// }
// constexpr int x = doubleIncrement(0);
public void testSimpleSequence() throws Exception {
assertEvaluationEquals(2);
}
// constexpr int function() {
// int n { 0 };
// int m { n++ };
// int o { n++ };
// return n;
// }
// constexpr int x = function();
public void testAssignmentWithPostfixIncrSideEffects() throws Exception {
assertEvaluationEquals(2);
}
// constexpr int function() {
// int n { 0 };
// int m { n-- };
// int o { n-- };
// return n;
// }
// constexpr int x = function();
public void testAssignmentWithPostfixDecrSideEffects() throws Exception {
assertEvaluationEquals(-2);
}
// constexpr int function() {
// int n { 0 };
// int m { --n };
// int o { --n };
// return n;
// }
// constexpr int x = function();
public void testAssignmentWithPrefixDecrSideEffects() throws Exception {
assertEvaluationEquals(-2);
}
// constexpr int function() {
// int n { 0 };
// int m { ++n };
// int o { ++n };
// return n;
// }
// constexpr int x = function();
public void testAssignmentWithPrefixIncrSideEffects() throws Exception {
assertEvaluationEquals(2);
}
// constexpr int function() {
// int n { 0 };
// return n++;
// }
// constexpr int x = function();
public void testPostfixIncrSemantics() throws Exception {
assertEvaluationEquals(0);
}
// constexpr int function() {
// int n { 0 };
// return n++;
// }
// constexpr int x = function();
public void testPostfixDecrSemantics() throws Exception {
assertEvaluationEquals(0);
}
// constexpr int function() {
// int n { 0 };
// return ++n;
// }
// constexpr int x = function();
public void testPrefixIncrSemantics() throws Exception {
assertEvaluationEquals(1);
}
// constexpr int function() {
// int n { 0 };
// return --n;
// }
// constexpr int x = function();
public void testPrefixDecrSemantics() throws Exception {
assertEvaluationEquals(-1);
}
// constexpr int f() {
// int x = 2;
// ++(++x);
// return x;
// }
// constexpr int x = f();
public void testPrefixIncrementReturnsLvalue() throws Exception {
assertEvaluationEquals(4);
}
}

View file

@ -0,0 +1,73 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import junit.framework.TestSuite;
public class UnaryOperatorOverloadingTests extends TestBase {
public static class NonIndexing extends UnaryOperatorOverloadingTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends UnaryOperatorOverloadingTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// class Point {
// int x, y;
// public:
// constexpr Point(int x, int y):x{x}, y{y} {}
// constexpr Point& operator++() {
// ++x;
// ++y;
// return *this;
// }
// constexpr int getY() const { return y; }
// };
//
// constexpr int f() {
// Point p{4,5};
// ++p;
// return p.getY();
// }
// constexpr int x = f();
public void testPrefixIncrementAsMemberFunction() throws Exception {
assertEvaluationEquals(6);
}
// class Point {
// int x, y;
// friend constexpr Point& operator++(Point&);
// public:
// constexpr Point(int x, int y):x{x}, y{y} {}
// constexpr int getY() const {
// return y;
// }
// };
//
// constexpr Point& operator++(Point& p) {
// ++p.x;
// ++p.y;
// return p;
// }
//
// constexpr int f() {
// Point p{4,5};
// ++p;
// return p.getY();
// }
// constexpr int x = f();
public void testPrefixIncrementAsNonMemberFunction() throws Exception {
assertEvaluationEquals(6);
}
}

View file

@ -0,0 +1,193 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import junit.framework.TestSuite;
public class UserDefinedLiteralTests extends TestBase {
public static class NonIndexing extends UserDefinedLiteralTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends UserDefinedLiteralTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// constexpr unsigned long long operator"" _min(unsigned long long minutes) {
// return minutes * 60;
// }
// constexpr auto x = 25_min;
public void testUserDefinedIntegerLiteral() throws Exception {
assertEvaluationEquals(1500);
}
// constexpr unsigned long long operator"" _capitals(const char* str, unsigned long size) {
// unsigned long long count = 0;
// for(int i = 0; i < size; ++i) {
// if(str[i] >= 'A' && str[i] <= 'Z') {
// count++;
// }
// }
// return count;
// }
// constexpr auto x = "HAllO"_capitals;
public void testUserDefinedStringLiteral() throws Exception {
assertEvaluationEquals(3);
}
// constexpr bool operator "" _v(char c) {
// switch(c) {
// case 'a':
// case 'e':
// case 'i':
// case 'o':
// case 'u':
// return true;
// default:
// return false;
// }
// }
// constexpr auto x = 'a'_v;
public void testUserDefinedCharacterLiteral() throws Exception {
assertEvaluationEquals(true);
}
// constexpr long double operator"" _deg(long double deg) {
// return deg * 3.141592 / 180;
// }
// constexpr auto x = 100.0_deg;
public void testUserDefinedFloatingPointLiteral() throws Exception {
assertEvaluationEquals(1.74533);
}
// constexpr unsigned long long operator "" _l(const char *str) {
// int l = 0;
// while(str[l] != '\0') {
// l++;
// }
// return l;
// }
// constexpr auto x = 20000_l;
public void testFallbackToRawLiteralOperator() throws Exception {
assertEvaluationEquals(5);
}
// template <char... STR>
// constexpr unsigned operator"" _l() {
// return 5;
// }
// constexpr int x = 123.20_l;
public void testRawLiteralOperatorTemplate() throws Exception {
assertEvaluationEquals(5);
}
// constexpr unsigned operator "" _l(unsigned long long x) {
// return 10;
// }
// constexpr unsigned operator "" _l(const char *str) {
// return 20;
// }
// constexpr int x = 120_l;
public void testChoosesCookedLiteralOverRawLiteralOperatorIfAvailable() throws Exception {
assertEvaluationEquals(10);
}
// constexpr unsigned operator "" _l(unsigned long long x) {
// return 10;
// }
// template <char... STR>
// constexpr unsigned operator"" _l() {
// return 20;
// }
// constexpr int x = 120_l;
public void testChoosesCookedLiteralOverRawLiteralTemplateIfAvailable() throws Exception {
assertEvaluationEquals(10);
}
// constexpr unsigned operator "" _l(long double x) {
// return 10;
// }
// constexpr unsigned operator "" _l(const char *str) {
// return 20;
// }
// constexpr int x = 120_l;
public void testFallsBackToRawLiteralOperatorIfParameterTypeDoesntMatchUnsignedLongLong() throws Exception {
assertEvaluationEquals(20);
}
// constexpr unsigned operator "" _l(long double x) {
// return 10;
// }
// template <char... STR>
// constexpr unsigned operator"" _l() {
// return 20;
// }
// constexpr int x = 120_l;
public void testFallsBackToRawLiteralOperatorTemplateIfParameterTypeDoesntMatchUnsignedLongLong() throws Exception {
assertEvaluationEquals(20);
}
// constexpr unsigned operator "" _l(unsigned long long x) {
// return 10;
// }
// constexpr unsigned operator "" _l(const char *str) {
// return 20;
// }
// constexpr int x = 120.0_l;
public void testFallsBackToRawLiteralOperatorIfParameterTypeDoesntMatchLongDouble() throws Exception {
assertEvaluationEquals(20);
}
// constexpr unsigned operator "" _l(unsigned long long x) {
// return 10;
// }
// template <char... STR>
// constexpr unsigned operator"" _l() {
// return 20;
// }
// constexpr int x = 120.0_l;
public void testFallsBackToRawLiteralOperatorTemplateIfParameterTypeDoesntMatchLongDouble() throws Exception {
assertEvaluationEquals(20);
}
// constexpr unsigned operator "" _l(const char *str) {
// return 20;
// }
// constexpr int x = "hello"_l;
public void testIgnoresRawLiteralOperatorForUserDefinedStringLiterals() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
// template <char... STR>
// constexpr unsigned operator"" _l() {
// return 20;
// }
// constexpr int x = "hello"_l;
public void testIgnoresRawLiteralOperatorTemplateForUserDefinedStringLiterals() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
}

View file

@ -0,0 +1,107 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import junit.framework.TestSuite;
public class WhileStatementTests extends TestBase {
public static class NonIndexing extends WhileStatementTests {
public NonIndexing() {setStrategy(new NonIndexingTestStrategy());}
public static TestSuite suite() {return suite(NonIndexing.class);}
}
public static class SingleProject extends WhileStatementTests {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true, false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
// constexpr int f(int n) {
// int sum { 0 };
// while (n > 0) {
// sum += n;
// n--;
// }
// return sum;
// }
// constexpr int x = f(10);
public void testWhileLoopWithConditionalExpression() throws Exception {
assertEvaluationEquals(55);
}
// constexpr int f(int n) {
// int sum { 0 };
// while (true) {
// sum += n;
// n--;
// }
// return sum;
// }
// constexpr int x = f(10);
public void testEvalShouldAbortOnWhileWitInfiniteLoop() throws Exception {
assertEvaluationEquals(IntegralValue.ERROR);
}
// constexpr int f(int n) {
// int sum { 0 };
// while (true) {
// sum += n;
// return 42;
// }
// return sum;
// }
// constexpr int x = f(10);
public void testReturnInWhileStatement() throws Exception {
assertEvaluationEquals(42);
}
// constexpr int f(int n) {
// int sum { 0 };
// while (n > 0)
// sum += n--;
// return sum;
// }
// constexpr int x = f(10);
public void testWhileLoopWithNonCompoundBodyStatement() throws Exception {
assertEvaluationEquals(55);
}
// constexpr int f(int n) {
// int sum { 0 };
// while (n > 0)
// return 42;
// return sum;
// }
// constexpr int x = f(10);
public void testWhileLoopWithReturnInNonCompoundBodyStatement() throws Exception {
assertEvaluationEquals(42);
}
// constexpr int triple(int x) {
// return x * 3;
// }
// constexpr int f(int y) {
// int sum = 0;
// while(int x = triple(y--)) {
// sum += x;
// }
// return sum;
// }
// constexpr int x = f(4);
public void testDeclarationInWhileStatementCondition1() throws Exception {
assertEvaluationEquals(30);
}
}

View file

@ -530,15 +530,21 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
}
}
class SinglePDOMTestStrategy extends BaseTestStrategy {
protected class SinglePDOMTestStrategy extends BaseTestStrategy {
private IIndex index;
private ICProject cproject;
private StringBuilder[] testData;
private IASTTranslationUnit ast;
private final boolean cpp;
private final boolean shouldRequireHeaderFile;
public SinglePDOMTestStrategy(boolean cpp) {
this(cpp, true);
}
public SinglePDOMTestStrategy(boolean cpp, boolean shouldRequireHeaderFile) {
this.cpp = cpp;
this.shouldRequireHeaderFile = shouldRequireHeaderFile;
}
@Override
@ -578,8 +584,16 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
Bundle b = CTestPlugin.getDefault().getBundle();
testData = TestSourceReader.getContentsForTest(b, "parser", IndexBindingResolutionTestBase.this.getClass(), getName(), 2);
if (testData.length < 2)
if(testData.length < 1) {
fail("Insufficient test data");
} else if(shouldRequireHeaderFile && testData.length == 1) {
fail("Insufficient test data");
} else if(testData.length == 1) {
StringBuilder newTestData[] = new StringBuilder[2];
newTestData[0] = new StringBuilder();
newTestData[1] = testData[0];
testData = newTestData;
}
testData[1].insert(0, "#include \"header.h\" " + END_OF_ADDED_CODE_MARKER + "\n");
String headerContents = testData[0].toString();

View file

@ -1949,10 +1949,10 @@ public class IndexBugsTests extends BaseTestCase {
try {
BindingAssertionHelper aHelper = new BindingAssertionHelper(a, testData[1], index);
IEnumerator e1 = aHelper.assertNonProblem("e;", 1, IEnumerator.class);
assertEquals(1, e1.getValue().numericalValue().longValue());
assertEquals(1, e1.getValue().numberValue().longValue());
BindingAssertionHelper bHelper = new BindingAssertionHelper(b, testData[3], index);
IEnumerator e2 = bHelper.assertNonProblem("e;", 1, IEnumerator.class);
assertEquals(2, e2.getValue().numericalValue().longValue());
assertEquals(2, e2.getValue().numberValue().longValue());
} finally {
index.releaseReadLock();
}

View file

@ -385,7 +385,7 @@ public class IndexCBindingResolutionTest extends IndexBindingResolutionTestBase
v= (IVariable) getBindingFromASTName("b;", 1);
checkValue(v.getInitialValue(), 0);
v= (IVariable) getBindingFromASTName("c;", 1);
assertNull(v.getInitialValue().numericalValue());
assertNull(v.getInitialValue().numberValue());
IEnumerator e= (IEnumerator) getBindingFromASTName("e0", 2);
checkValue(e.getValue(), 0);
@ -401,7 +401,7 @@ public class IndexCBindingResolutionTest extends IndexBindingResolutionTestBase
private void checkValue(IValue initialValue, int i) {
assertNotNull(initialValue);
final Long numericalValue = initialValue.numericalValue();
final Number numericalValue = initialValue.numberValue();
assertNotNull(numericalValue);
assertEquals(i, numericalValue.intValue());
}

View file

@ -175,7 +175,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
private void asserValueEquals(IValue initialValue, long i) {
assertNotNull(initialValue);
final Long numericalValue = initialValue.numericalValue();
final Number numericalValue = initialValue.numberValue();
assertNotNull(numericalValue);
assertEquals(i, numericalValue.longValue());
}
@ -1476,7 +1476,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
v= (IVariable) getBindingFromASTName("b;", 1);
asserValueEquals(v.getInitialValue(), 0);
v= (IVariable) getBindingFromASTName("c;", 1);
assertNull(v.getInitialValue().numericalValue());
assertNull(v.getInitialValue().numberValue());
IEnumerator e= (IEnumerator) getBindingFromASTName("e0", 2);
asserValueEquals(e.getValue(), 0);
@ -1893,7 +1893,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// constexpr int waldo = foo();
public void testNameLookupInDefaultArgument_432701() {
IVariable waldo = getBindingFromASTName("waldo", 5);
assertEquals(42, waldo.getInitialValue().numericalValue().longValue());
assertEquals(42, waldo.getInitialValue().numberValue().longValue());
}
// struct function {

View file

@ -62,6 +62,7 @@ import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper.MethodKind;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
@ -1486,7 +1487,7 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
ICPPTemplateParameterMap paramMap = c256.getTemplateParameterMap();
assertEquals(1, paramMap.getAllParameterPositions().length);
ICPPTemplateArgument arg = paramMap.getArgument(0);
assertEquals(Long.valueOf(256), arg.getNonTypeValue().numericalValue());
assertEquals(Long.valueOf(256), arg.getNonTypeValue().numberValue());
assertInstance(arg.getTypeOfNonTypeValue(), ICPPBasicType.class);
ICPPFunction foo = getBindingFromASTName("foo(t)", 3, ICPPFunction.class);
@ -2213,7 +2214,7 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
public void testDependentEnumValue_389009() throws Exception {
IEnumerator binding = getBindingFromASTName("id;", 2, IEnumerator.class);
IValue value = binding.getValue();
Long num = value.numericalValue();
Number num = value.numberValue();
assertNotNull(num);
assertEquals(1, num.longValue());
}
@ -2956,4 +2957,42 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
public void testStackOverflow_462764() throws Exception {
checkBindings();
}
// template <typename>
// struct base {
// constexpr base() {}
// };
//
// template <typename T>
// struct derived : base<T> {
// constexpr derived() : base<T>() {}
// };
// derived<int> waldo;
public void testSerializationOfUnknownConstructor_490475() throws Exception {
IASTName waldoName = findName("waldo", 5);
IVariable waldo = getBindingFromASTName("waldo", 5);
IType derivedInt = waldo.getType();
assertInstance(derivedInt, ICPPClassSpecialization.class);
ICPPClassType derived = ((ICPPClassSpecialization) derivedInt).getSpecializedBinding();
ICPPMethod constructor = ClassTypeHelper.getMethodInClass(derived, MethodKind.DEFAULT_CTOR, null);
assertInstance(constructor, ICPPConstructor.class);
// Trigger deserialization of constructor chain execution
((ICPPConstructor) constructor).getConstructorChainExecution(waldoName);
}
// template <typename F>
// struct S {
// F f;
// };
//
// template <typename F>
// auto foo(F f) -> decltype(S<F>{f});
// void bar() {
// foo([]{});
// }
public void testBracedInitList_490475() throws Exception {
checkBindings();
}
}

View file

@ -213,7 +213,7 @@ public class IndexUpdateTests extends IndexTestBase {
if (value == null)
assertNull(v);
else
assertEquals(value, v.numericalValue());
assertEquals(value, v.numberValue());
} finally {
fIndex.releaseReadLock();
}

View file

@ -386,7 +386,7 @@ public class CPPClassTemplateTests extends PDOMInlineCodeTestBase {
ICPPTemplateArgument aT2DefaultArgument = templateParameterAT2.getDefaultValue();
assertNotNull(aT2DefaultArgument);
assertTrue(new CPPBasicType(IBasicType.Kind.eInt, 0).isSameType(aT2DefaultArgument.getTypeOfNonTypeValue()));
assertEquals(5, aT2DefaultArgument.getNonTypeValue().numericalValue().longValue());
assertEquals(5, aT2DefaultArgument.getNonTypeValue().numberValue().longValue());
assertEquals(0, templateParameterAT2.getTemplateNestingLevel());
assertDeclarationCount(pdom, "S", 1);

View file

@ -12,10 +12,6 @@
*******************************************************************************/
package org.eclipse.cdt.core.suite;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.cdescriptor.tests.CDescriptorOldTests;
import org.eclipse.cdt.core.cdescriptor.tests.CDescriptorTests;
import org.eclipse.cdt.core.envvar.IEnvironmentVariableManagerTests;
@ -29,6 +25,7 @@ import org.eclipse.cdt.core.model.tests.AllCoreTests;
import org.eclipse.cdt.core.model.tests.ElementDeltaTests;
import org.eclipse.cdt.core.model.tests.WorkingCopyTests;
import org.eclipse.cdt.core.parser.tests.ParserTestSuite;
import org.eclipse.cdt.core.parser.tests.ast2.constexprevaluation.AllConstexprEvalTests;
import org.eclipse.cdt.core.parser.tests.rewrite.RewriteTests;
import org.eclipse.cdt.core.resources.tests.RefreshScopeTests;
import org.eclipse.cdt.internal.index.tests.IndexTests;
@ -41,6 +38,10 @@ import org.eclipse.cdt.utils.StorableCdtVariablesTest;
import org.eclipse.cdt.utils.UNCPathConverterTest;
import org.eclipse.cdt.utils.WeakHashSetTest;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* @author vhirsl
*/
@ -68,10 +69,11 @@ public class AutomatedIntegrationSuite extends TestSuite {
if (System.getProperty("cdt.skip.known.test.failures") == null) {
suite.addTest(CDescriptorTests.suite());
}
suite.addTest(AllConstexprEvalTests.suite());
suite.addTest(ParserTestSuite.suite());
suite.addTest(CDescriptorOldTests.suite());
suite.addTest(IEnvironmentVariableManagerTests.suite());
suite.addTest(ErrorParserTests.suite());
suite.addTest(ParserTestSuite.suite());
suite.addTest(AllCoreTests.suite());
suite.addTest(ElementDeltaTests.suite());
suite.addTest(WorkingCopyTests.suite());

View file

@ -360,7 +360,7 @@ public class BaseTestCase extends TestCase {
protected static void assertVariableValue(IVariable var, long expectedValue) {
assertNotNull(var.getInitialValue());
assertNotNull(var.getInitialValue().numericalValue());
assertEquals(expectedValue, var.getInitialValue().numericalValue().longValue());
assertNotNull(var.getInitialValue().numberValue());
assertEquals(expectedValue, var.getInitialValue().numberValue().longValue());
}
}

View file

@ -44,7 +44,7 @@ import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTTypeId;
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
import org.eclipse.cdt.internal.core.dom.parser.c.ICInternalBinding;
@ -309,14 +309,14 @@ public class ASTTypeUtil {
}
}
IValue val= ((IArrayType) type).getSize();
if (val != null && val != Value.UNKNOWN) {
if (val != null && val != IntegralValue.UNKNOWN) {
if (normalize) {
if (needSpace) {
result.append(SPACE); needSpace = false;
}
result.append(val.getSignature());
} else {
Long v= val.numericalValue();
Number v= val.numberValue();
if (v != null) {
if (needSpace) {
result.append(SPACE); needSpace = false;

View file

@ -11,7 +11,9 @@
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.core.runtime.CoreException;
/**
* Models a value of a variable, enumerator or expression.
@ -22,13 +24,44 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
*/
public interface IValue {
/**
* Returns the value as a number, or {@code null} if it is not possible.
* Returns the value as a Long number, or {@code null} if it is not possible.
* @deprecated Use numberValue() instead.
*/
@Deprecated
Long numericalValue();
/**
* Returns the evaluation object if this value is dependent, or {@code null} otherwise.
* If {@link #numericalValue()} returns {@code null}, {@link #getEvaluation()} returns
* Returns the value as a number, or {@code null} if it is not possible.
* @since 6.0
*/
Number numberValue();
/**
* If this value consists of sub-values, returns the number of these sub-values. Otherwise returns 1.
* @since 6.0
*/
int numberOfSubValues();
/**
* If this value consists of sub-values, returns the sub-value at the given index.
* Otherwise, returns this value (represented as an ICPPEvaluation) if the index 0 is passed.
* EvalFixed.INCOMPLETE is returned if the given index is out of bounds.
* @noreference This method is not intended to be referenced by clients.
*/
ICPPEvaluation getSubValue(int index);
/**
* If this value consists of sub-values, returns an array containing all of them.
* Otherwise, returns an array containing 1 element representing this value.
* Not all implementations implement this; some may return {@code null}.
* @noreference This method is not intended to be referenced by clients.
*/
ICPPEvaluation[] getAllSubValues();
/**
* Returns the evaluation object if this value cannot be represented as a single numerical value, or
* {@code null} otherwise. This cam happen if the value is dependent, or it's a composite value.
* If {@link #numberValue()} returns {@code null}, {@link #getEvaluation()} returns
* not {@code null} and vice versa.
* @noreference This method is not intended to be referenced by clients.
*/
@ -53,4 +86,24 @@ public interface IValue {
*/
@Deprecated
IBinding[] getUnknownBindings();
/**
* If this value consists of sub-values, set the sub-value at the given position to the given new value.
* Otherwise, set this value to the given new value.
* Not all implementations implement this; for some, a call to this may have no effect.
* @noreference This method is not intended to be referenced by clients.
*/
void setSubValue(int position, ICPPEvaluation newValue);
/**
* Make a deep copy of this value.
* @since 6.0
*/
IValue clone();
/**
* Serialize this value to the given type marhsal buffer.
* @noreference This method is not intended to be referenced by clients.
*/
void marshal(ITypeMarshalBuffer buffer) throws CoreException;
}

View file

@ -11,7 +11,6 @@
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
/**
* C++ specific initializer clause.
@ -20,9 +19,4 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
* @since 5.5
*/
public interface ICPPASTInitializerClause extends IASTInitializerClause {
/**
* Returns the evaluation object for this expression.
* @noreference This method is not intended to be referenced by clients.
*/
ICPPEvaluation getEvaluation();
}

View file

@ -10,10 +10,22 @@
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPExecution;
/**
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPConstructor extends ICPPMethod {
public static final ICPPConstructor[] EMPTY_CONSTRUCTOR_ARRAY = {};
/**
* For a constexpr constructor returns the ICPPExecution for its constructor chain. Otherwise returns
* {@code null}.
* @param point The point of instantiation for name lookups.
* @since 6.0
* @noreference This method is not intended to be referenced by clients.
*/
public ICPPExecution getConstructorChainExecution(IASTNode point);
}

View file

@ -18,4 +18,10 @@ import org.eclipse.cdt.core.dom.ast.IField;
*/
public interface ICPPField extends IField, ICPPMember, ICPPVariable {
public static final ICPPField[] EMPTY_CPPFIELD_ARRAY = {};
/**
* Returns the position of this field within its class owner's declared fields.
* @since 6.0
*/
byte getFieldPosition();
}

View file

@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPExecution;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.parser.ParserException;
@ -173,10 +174,15 @@ public abstract class ASTAmbiguousNode extends ASTNode {
return false;
}
public final ICPPEvaluation getEvaluation() {
public final ICPPEvaluation getEvaluation() {
logAmbiguousNodeError();
return EvalFixed.INCOMPLETE;
}
public final ICPPExecution getExecution() {
logAmbiguousNodeError();
return null;
}
private void logAmbiguousNodeError() {
CCorePlugin.log(new ParserException("Encountered an ambiguous node \"" + //$NON-NLS-1$

View file

@ -127,7 +127,7 @@ public abstract class ASTEnumerator extends ASTNode implements IASTEnumerator, I
}
}
if (integralValue == null) {
integralValue= Value.UNKNOWN;
integralValue= IntegralValue.UNKNOWN;
}
}
return integralValue;
@ -151,7 +151,7 @@ public abstract class ASTEnumerator extends ASTNode implements IASTEnumerator, I
IValue val;
IASTExpression expr= etor.getValue();
if (expr != null) {
val= Value.create(expr);
val= ValueFactory.create(expr);
previousExplicitValue = val;
delta = 1;
if (fixedType == null) {
@ -163,9 +163,9 @@ public abstract class ASTEnumerator extends ASTNode implements IASTEnumerator, I
}
} else {
if (previousExplicitValue != null) {
val = Value.incrementedValue(previousExplicitValue, delta);
val = IntegralValue.incrementedValue(previousExplicitValue, delta);
} else {
val = Value.create(delta);
val = IntegralValue.create(delta);
}
delta++;
if (fixedType == null && type instanceof IBasicType) {
@ -196,7 +196,7 @@ public abstract class ASTEnumerator extends ASTNode implements IASTEnumerator, I
* @return the type of the incremented value
*/
public static IBasicType getTypeOfIncrementedValue(IBasicType type, IValue val) {
Long numericalValue = val.numericalValue();
Number numericalValue = val.numberValue();
if (numericalValue != null) {
long longValue = numericalValue.longValue();
if ((type.getKind() != Kind.eInt && type.getKind() != Kind.eInt128) ||

View file

@ -0,0 +1,254 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.core.runtime.CoreException;
public class CStringValue implements IValue {
private static final Map<Character, Character> escapeSequences;
static {
Map<Character, Character> map = new HashMap<Character, Character>();
map.put('\'', '\'');
map.put('"', '"');
map.put('?', '?');
map.put('\\', '\\');
map.put('a', '\007');
map.put('b', '\b');
map.put('f', '\f');
map.put('n', '\n');
map.put('r', '\r');
map.put('t', '\t');
map.put('v', '\013');
escapeSequences = Collections.unmodifiableMap(map);
}
private final char[] fFixedValue;
private String fParsedValue;
private CStringValue(char[] fixedValue) {
fFixedValue = fixedValue;
}
public static IValue create(char[] fixedValue) {
return new CStringValue(fixedValue);
}
public String cStringValue() {
if (fParsedValue == null) {
fParsedValue = parseString();
}
return fParsedValue;
}
private int indexOfStartQuote() {
final int len = fFixedValue.length;
int i = 0;
while(i < len && fFixedValue[i] != '"') {
++i;
}
if(i >= len) {
return -1;
} else {
return i;
}
}
private int indexOfEndQuote() {
int i = fFixedValue.length - 1;
while(i >= 0 && fFixedValue[i] != '"') {
--i;
}
if(i < 0) {
return -1;
} else {
return i;
}
}
private boolean isRawStringLiteral() {
for(int i = 0; i < indexOfStartQuote(); ++i) {
if(fFixedValue[i] == 'R') {
return true;
}
}
return false;
}
private int getDelimiterLength() {
if(isRawStringLiteral()) {
int i = indexOfStartQuote();
int len = 0;
while(i < fFixedValue.length && fFixedValue[i] != '(') {
++i;
++len;
}
return len;
}
return 0;
}
private int getStart() {
return indexOfStartQuote() + getDelimiterLength() + 1;
}
private int getEnd() {
return indexOfEndQuote() - getDelimiterLength() - 1;
}
private String parseString() {
// TODO: Reuse code between this and CPPASTLiteralExpression.computeStringLiteralSize().
boolean isRaw = isRawStringLiteral();
int end = getEnd();
StringBuilder builder = new StringBuilder();
for(int i = getStart(); i <= end; ++i) {
if(!isRaw && fFixedValue[i] == '\\' && i < end) {
++i;
//C-Strings are null-terminated. Therefore, a '\0' character
//denotes the end of the string, even if the literal contains
//more characters after that
if(fFixedValue[i] == '0') {
break;
} else {
i = parseEscapeSequence(i, builder);
}
} else {
builder.append(fFixedValue[i]);
}
}
return builder.toString();
}
private int parseEscapeSequence(int i, StringBuilder builder) {
char c = fFixedValue[i];
Character escapeSequence = escapeSequences.get(c);
if(escapeSequence != null) {
builder.append(escapeSequence);
} else if(c == 'u' && i + 4 <= getEnd()) {
StringBuilder hexStr = new StringBuilder();
++i;
for(int end = i + 4; i < end; ++i) {
hexStr.append(fFixedValue[i]);
}
int codePoint = Integer.parseInt(hexStr.toString(), 16);
builder.append(Character.toChars(codePoint));
}
return i;
}
@Override
public Long numericalValue() {
return null;
}
@Override
public Number numberValue() {
return null;
}
@Override
public int numberOfSubValues() {
String str = cStringValue();
return str.length();
}
@Override
public ICPPEvaluation getSubValue(int index) {
String str = cStringValue();
Character c = null;
if(index >= 0 && index < str.length()) {
c = str.charAt(index);
} else if(index == str.length()) {
c = '\0';
}
if(c != null) {
IValue val = IntegralValue.create(c);
return new EvalFixed(CPPBasicType.CHAR, ValueCategory.PRVALUE, val);
}
return null;
}
@Override
public ICPPEvaluation[] getAllSubValues() {
return null;
}
@Override
public ICPPEvaluation getEvaluation() {
return null;
}
@Override
public char[] getSignature() {
return fFixedValue;
}
@Override
public int hashCode() {
return CharArrayUtils.hash(getSignature());
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof CStringValue)) {
return false;
}
final CStringValue rhs = (CStringValue) obj;
if (fFixedValue != null)
return CharArrayUtils.equals(fFixedValue, rhs.fFixedValue);
return CharArrayUtils.equals(getSignature(), rhs.getSignature());
}
@Deprecated
@Override
public char[] getInternalExpression() {
return CharArrayUtils.EMPTY_CHAR_ARRAY;
}
@Deprecated
@Override
public IBinding[] getUnknownBindings() {
return IBinding.EMPTY_BINDING_ARRAY;
}
@Override
public void setSubValue(int position, ICPPEvaluation newValue) {
}
@Override
public IValue clone() {
char[] newFixedValue = Arrays.copyOf(fFixedValue, fFixedValue.length);
return new CStringValue(newFixedValue);
}
@Override
public void marshal(ITypeMarshalBuffer buf) throws CoreException {
buf.putShort(ITypeMarshalBuffer.C_STRING_VALUE);
buf.putCharArray(fFixedValue);
}
public static IValue unmarshal(short firstBytes, ITypeMarshalBuffer buf) throws CoreException {
return new CStringValue(buf.getCharArray());
}
}

View file

@ -0,0 +1,268 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ActivationRecord;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalInitList;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUtil;
import org.eclipse.core.runtime.CoreException;
public class CompositeValue implements IValue {
private final ICPPEvaluation[] values;
private ICPPEvaluation evaluation;
public CompositeValue(ICPPEvaluation evaluation, ICPPEvaluation[] values) {
this.evaluation = evaluation;
this.values = values;
}
@Override
public Long numericalValue() {
return null;
}
@Override
public Number numberValue() {
return null;
}
@Override
public ICPPEvaluation getEvaluation() {
return evaluation;
}
@Override
public char[] getSignature() {
if(evaluation != null) {
return evaluation.getSignature();
}
return new char[]{};
}
@Deprecated
@Override
public char[] getInternalExpression() {
return CharArrayUtils.EMPTY_CHAR_ARRAY;
}
@Deprecated
@Override
public IBinding[] getUnknownBindings() {
return IBinding.EMPTY_BINDING_ARRAY;
}
@Override
public int numberOfSubValues() {
return values.length;
}
@Override
public ICPPEvaluation getSubValue(final int index) {
return rangeIsValid(index) ? values[index] : EvalFixed.INCOMPLETE;
}
private boolean rangeIsValid(final int index) {
return numberOfSubValues() > index && index >= 0;
}
public static IValue create(EvalInitList initList) {
ICPPEvaluation[] values = new ICPPEvaluation[initList.getClauses().length];
for (int i = 0; i < initList.getClauses().length; i++) {
ICPPEvaluation eval = initList.getClauses()[i];
values[i] = new EvalFixed(eval.getType(null), eval.getValueCategory(null), eval.getValue(null));
}
return new CompositeValue(initList, values);
}
/**
* Creates a value representing an instance of the given array type initialized with
* the elements of the given initializer list.
*/
public static IValue create(EvalInitList initList, IArrayType type) {
Number arraySize = type.getSize().numberValue();
if (arraySize == null) {
// Array size is dependent. TODO: Handle this?
return IntegralValue.UNKNOWN;
}
IType elementType = type.getType();
ICPPEvaluation[] values = new ICPPEvaluation[arraySize.intValue()];
for (int i = 0; i < initList.getClauses().length; i++) {
ICPPEvaluation eval = initList.getClauses()[i];
IValue value = getValue(elementType, eval);
values[i] = new EvalFixed(elementType, eval.getValueCategory(null), value);
}
return new CompositeValue(initList, values);
}
/**
* Gets the value of an evaluation, interpreted as a value of the given type.
*/
private static IValue getValue(IType type, ICPPEvaluation eval) {
IValue value;
if (type instanceof IArrayType && eval instanceof EvalInitList) {
value = CompositeValue.create((EvalInitList) eval, (IArrayType) type);
} else if (type instanceof ICompositeType && eval instanceof EvalInitList) {
value = CompositeValue.create((EvalInitList) eval, (ICompositeType) type);
} else if (eval instanceof EvalInitList) {
value = IntegralValue.UNKNOWN;
} else {
value = eval.getValue(null);
}
return value;
}
/**
* Creates a value representing an instance of the given composite type initialized with
* the elements of the given initializer list.
*/
public static IValue create(EvalInitList initList, ICompositeType type) {
IField[] fields = type.getFields();
ICPPEvaluation[] values = new ICPPEvaluation[fields.length];
for (int i = 0; i < fields.length; i++) {
IField field = fields[i];
ICPPEvaluation eval = initList.getClauses()[i];
IType fieldType = field.getType();
IValue value = getValue(fieldType, eval);
values[i] = new EvalFixed(fieldType, eval.getValueCategory(null), value);
}
return new CompositeValue(initList, values);
}
// The set of class types for which composite value creation is in progress on each thread.
// Used to guard against infinite recursion due to a class (invalidly) aggregating itself.
private static final ThreadLocal<Set<ICPPClassType>> fCreateInProgress =
new ThreadLocal<Set<ICPPClassType>>() {
@Override
protected Set<ICPPClassType> initialValue() {
return new HashSet<>();
}
};
/**
* Creates a value representing an instance of a class type, with the values of the fields
* determined by the default member initializers only. Constructors are not considered
* when determining the values of the fields.
*/
public static CompositeValue create(ICPPClassType classType) {
Set<ICPPClassType> recursionProtectionSet = fCreateInProgress.get();
if (!recursionProtectionSet.add(classType)) {
return new CompositeValue(null, ICPPEvaluation.EMPTY_ARRAY);
}
try {
ActivationRecord record = new ActivationRecord();
ICPPEvaluation[] values = new ICPPEvaluation[ClassTypeHelper.getFields(classType, null).length];
// recursively create all the base class member variables
ICPPBase[] bases = ClassTypeHelper.getBases(classType, null);
for(ICPPBase base : bases) {
IBinding baseClass = base.getBaseClass();
if(baseClass instanceof ICPPClassType) {
ICPPClassType baseClassType = (ICPPClassType) baseClass;
ICPPField[] baseFields = ClassTypeHelper.getDeclaredFields(baseClassType, null);
IValue compValue = CompositeValue.create(baseClassType);
for(ICPPField baseField : baseFields) {
int fieldPos = CPPASTFieldReference.getFieldPosition(baseField);
record.update(baseField, compValue.getSubValue(fieldPos));
// TODO(nathanridge): This won't work with multiple inheritance, since 'fieldPos'
// is a field position in the base class' hierarchy, while values[] expects
// as index a field position in classType's hierarchy.
values[fieldPos] = compValue.getSubValue(fieldPos);
}
}
}
ICPPField[] fields = ClassTypeHelper.getDeclaredFields(classType, null);
for (ICPPField field : fields) {
final ICPPEvaluation value = EvalUtil.getVariableValue(field, record);
int fieldPos = CPPASTFieldReference.getFieldPosition(field);
record.update(field, value);
values[fieldPos] = value;
}
return new CompositeValue(null, values);
} finally {
recursionProtectionSet.remove(classType);
}
}
@Override
public ICPPEvaluation[] getAllSubValues() {
return values;
}
@Override
public void setSubValue(int position, ICPPEvaluation newValue) {
values[position] = newValue;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("["); //$NON-NLS-1$
for(int i = 0; i < values.length; i++) {
if(values[i] != null) {
builder.append(values[i].toString());
} else {
builder.append("<null>"); //$NON-NLS-1$
}
if(i != values.length-1) {
builder.append(", "); //$NON-NLS-1$
}
}
builder.append("]"); //$NON-NLS-1$
return builder.toString();
}
@Override
public IValue clone() {
ICPPEvaluation[] newValues = new ICPPEvaluation[values.length];
for(int i = 0; i < newValues.length; i++) {
ICPPEvaluation eval = values[i];
IValue newValue = eval.getValue(null).clone();
newValues[i] = new EvalFixed(eval.getType(null), eval.getValueCategory(null), newValue);
}
return new CompositeValue(evaluation, newValues);
}
@Override
public void marshal(ITypeMarshalBuffer buf) throws CoreException {
buf.putShort(ITypeMarshalBuffer.COMPOSITE_VALUE);
buf.marshalEvaluation(evaluation, true);
buf.putInt(values.length);
for(ICPPEvaluation value : values) {
buf.marshalEvaluation(value, true);
}
}
public static IValue unmarshal(short firstBytes, ITypeMarshalBuffer buf) throws CoreException {
ICPPEvaluation evaluation = (ICPPEvaluation)buf.unmarshalEvaluation();
int len = buf.getInt();
ICPPEvaluation values[] = new ICPPEvaluation[len];
for(int i = 0; i < len; i++) {
values[i] = (ICPPEvaluation)buf.unmarshalEvaluation();
}
return new CompositeValue(evaluation, values);
}
}

View file

@ -0,0 +1,184 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import java.util.Arrays;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.core.runtime.CoreException;
public class FloatingPointValue implements IValue {
private final char[] fFixedValue;
private FloatingPointValue(char[] fixedValue) {
fFixedValue = fixedValue;
}
public static FloatingPointValue create(char[] fixedValue) {
return new FloatingPointValue(fixedValue);
}
public static FloatingPointValue create(double value) {
return new FloatingPointValue(toCharArray(value));
}
@Override
public Long numericalValue() {
return null; // not a Long
}
@Override
public Number numberValue() {
return parseDouble(fFixedValue);
}
private static Double parseDouble(char[] value) {
double result = 0.0;
int i = 0;
int len = value.length;
while(i < len && value[i] >= '0' && value[i] <= '9') {
int digit = value[i] - '0';
result = result * 10 + digit;
++i;
}
if(i < len && value[i] == '.') {
++i;
}
double div = 10.0;
while(i < len && value[i] >= '0' && value[i] <= '9') {
int digit = value[i] - '0';
result += digit / div;
div *= 10.0;
++i;
}
if(i < len && (value[i] == 'e' || value[i] == 'E')) {
++i;
}
boolean exponentIsPositive = true;
if(i < len && (value[i] == '+' || value[i] == '-')) {
exponentIsPositive = (value[i] == '+');
++i;
}
int exponent = 0;
while(i < len && value[i] >= '0' && value[i] <= '9') {
int digit = value[i] - '0';
exponent = exponent * 10 + digit;
++i;
}
if(i < len && (value[i] == 'l' || value[i] == 'L' || value[i] == 'f' || value[i] == 'F')) {
++i;
}
if(i == len) {
if(!exponentIsPositive) {
exponent *= -1;
}
return result * Math.pow(10, exponent);
}
return null;
}
@Override
public int numberOfSubValues() {
return 1;
}
@Override
public ICPPEvaluation getSubValue(int index) {
if(index == 0) {
return getEvaluation();
}
return EvalFixed.INCOMPLETE;
}
@Override
public ICPPEvaluation[] getAllSubValues() {
return new ICPPEvaluation[]{ getEvaluation() };
}
@Override
public ICPPEvaluation getEvaluation() {
return null;
}
@Override
public char[] getSignature() {
return fFixedValue;
}
@Override
public int hashCode() {
return CharArrayUtils.hash(getSignature());
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof FloatingPointValue)) {
return false;
}
final FloatingPointValue rhs = (FloatingPointValue) obj;
if (fFixedValue != null)
return CharArrayUtils.equals(fFixedValue, rhs.fFixedValue);
return CharArrayUtils.equals(getSignature(), rhs.getSignature());
}
@Deprecated
@Override
public char[] getInternalExpression() {
return CharArrayUtils.EMPTY_CHAR_ARRAY;
}
@Deprecated
@Override
public IBinding[] getUnknownBindings() {
return IBinding.EMPTY_BINDING_ARRAY;
}
@Override
public void setSubValue(int position, ICPPEvaluation newValue) {
}
private static char[] toCharArray(double value) {
StringBuilder buf= new StringBuilder();
buf.append(value);
return CharArrayUtils.extractChars(buf);
}
@Override
public String toString() {
return new String(getSignature());
}
@Override
public IValue clone() {
char[] newFixedValue = Arrays.copyOf(fFixedValue, fFixedValue.length);
return new FloatingPointValue(newFixedValue);
}
@Override
public void marshal(ITypeMarshalBuffer buf) throws CoreException {
buf.putShort(ITypeMarshalBuffer.FLOATING_POINT_VALUE);
buf.putCharArray(fFixedValue);
}
public static IValue unmarshal(short firstBytes, ITypeMarshalBuffer buf) throws CoreException {
return new FloatingPointValue(buf.getCharArray());
}
}

View file

@ -13,8 +13,14 @@ package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.core.runtime.CoreException;
/**
* Interface for marshalling types for storage in the index.
* Interface for marshalling ICPPEvaluation objects for storage in the index.
*/
public interface ISerializableEvaluation {
/**
* Marshals an ICPPEvaluation object for storage in the index.
*
* @param buffer The buffer that will hold the marshalled ICPPEvaluation object.
* @param includeValue Specifies whether nested IValue objects should be marshalled as well.
* */
void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException;
}

View file

@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.core.runtime.CoreException;
/**
* Interface for marshalling ICPPExecution objects for storage in the index.
*/
public interface ISerializableExecution {
/**
* Marshals an ICPPExecution object for storage in the index.
*
* @param buffer The buffer that will hold the marshalled ICPPExecution object.
* @param includeValue Specifies whether nested IValue objects should be marshalled as well.
* */
void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException;
}

View file

@ -23,42 +23,76 @@ import org.eclipse.core.runtime.CoreException;
* Buffer for marshalling and unmarshalling types.
*/
public interface ITypeMarshalBuffer {
final static byte BASIC_TYPE = 0x01;
final static byte POINTER_TYPE = 0x02;
final static byte ARRAY_TYPE = 0x03;
final static byte CVQUALIFIER_TYPE = 0x04;
final static byte FUNCTION_TYPE = 0x05;
final static byte REFERENCE_TYPE = 0x06;
final static byte POINTER_TO_MEMBER_TYPE = 0x07;
final static byte PACK_EXPANSION_TYPE = 0x08;
final static byte PROBLEM_TYPE = 0x09;
final static byte VALUE = 0x0A;
final static byte DEPENDENT_EXPRESSION_TYPE = 0x0B;
final static byte UNKNOWN_MEMBER = 0x0C;
final static byte UNKNOWN_MEMBER_CLASS_INSTANCE = 0x0D;
final static byte DEFERRED_CLASS_INSTANCE = 0x0E;
final static byte TYPE_TRANSFORMATION = 0x0F;
final static byte UNKNOWN_MEMBER_TYPE = 0x10;
final static byte
BASIC_TYPE = 0x01,
POINTER_TYPE = 0x02,
ARRAY_TYPE = 0x03,
CVQUALIFIER_TYPE = 0x04,
FUNCTION_TYPE = 0x05,
REFERENCE_TYPE = 0x06,
POINTER_TO_MEMBER_TYPE = 0x07,
PACK_EXPANSION_TYPE = 0x08,
PROBLEM_TYPE = 0x09,
VALUE = 0x0A,
DEPENDENT_EXPRESSION_TYPE = 0x0B,
UNKNOWN_MEMBER = 0x0C,
UNKNOWN_MEMBER_CLASS_INSTANCE = 0x0D,
DEFERRED_CLASS_INSTANCE = 0x0E,
TYPE_TRANSFORMATION = 0x0F,
UNKNOWN_MEMBER_TYPE = 0x10,
INITIALIZER_LIST_TYPE = 0x11,
DEFERRED_FUNCTION = 0x12;
// Can add more types up to 0x1C, after that it will collide with TypeMarshalBuffer.UNSTORABLE_TYPE.
final static byte
INTEGRAL_VALUE = 0x01,
FLOATING_POINT_VALUE = 0x02,
C_STRING_VALUE = 0x03,
COMPOSITE_VALUE = 0x04;
// Can add more values up to 0x1C, after that it will collide with TypeMarshalBuffer.UNSTORABLE_TYPE.
final static byte
EVAL_BINARY = 0x01,
EVAL_BINARY_TYPE_ID = 0x02,
EVAL_BINDING = 0x03,
EVAL_COMMA = 0x04,
EVAL_COMPOUND = 0x05,
EVAL_CONDITIONAL = 0x06,
EVAL_FIXED = 0x07,
EVAL_FUNCTION_CALL = 0x08,
EVAL_FUNCTION_SET = 0x09,
EVAL_ID = 0x0A,
EVAL_INIT_LIST = 0x0B,
EVAL_MEMBER_ACCESS = 0x0C,
EVAL_PARAMETER_PACK = 0x0D,
EVAL_TYPE_ID = 0x0E,
EVAL_UNARY = 0x0F,
EVAL_UNARY_TYPE_ID = 0x10;
EVAL_BINARY = 0x01,
EVAL_BINARY_TYPE_ID = 0x02,
EVAL_BINDING = 0x03,
EVAL_COMMA = 0x04,
EVAL_COMPOUND = 0x05,
EVAL_CONDITIONAL = 0x06,
EVAL_FIXED = 0x07,
EVAL_FUNCTION_CALL = 0x08,
EVAL_FUNCTION_SET = 0x09,
EVAL_ID = 0x0A,
EVAL_INIT_LIST = 0x0B,
EVAL_MEMBER_ACCESS = 0x0C,
EVAL_PARAMETER_PACK = 0x0D,
EVAL_TYPE_ID = 0x0E,
EVAL_UNARY = 0x0F,
EVAL_UNARY_TYPE_ID = 0x10,
EVAL_CONSTRUCTOR = 0x11,
EVAL_REFERENCE = 0x12,
EVAL_POINTER = 0x13,
EVAL_COMPOSITE_ACCESS = 0x14;
// Can add more evaluations up to 0x1C, after that it will collide with TypeMarshalBuffer.UNSTORABLE_TYPE.
final static byte
EXEC_COMPOUND_STATEMENT = 0x01,
EXEC_BREAK = 0x02,
EXEC_CASE = 0x03,
EXEC_CONTINUE = 0x04,
EXEC_DECLARATION_STATEMENT = 0x05,
EXEC_DECLARATOR = 0x06,
EXEC_DEFAULT = 0x07,
EXEC_SIMPLE_DECLARATION = 0x08,
EXEC_RETURN = 0x09,
EXEC_EXPRESSION_STATEMENT = 0x0A,
EXEC_IF = 0x0B,
EXEC_WHILE = 0x0C,
EXEC_DO = 0x0D,
EXEC_FOR = 0x0E,
EXEC_RANGE_BASED_FOR = 0x0F,
EXEC_SWITCH = 0x10,
EXEC_CONSTRUCTOR_CHAIN = 0x11;
// Can add more executions up to 0x1C, after that it will collide with TypeMarshalBuffer.UNSTORABLE_TYPE.
static final short KIND_MASK = 0x001F;
@ -82,6 +116,7 @@ public interface ITypeMarshalBuffer {
IValue unmarshalValue() throws CoreException;
IBinding unmarshalBinding() throws CoreException;
ISerializableEvaluation unmarshalEvaluation() throws CoreException;
ISerializableExecution unmarshalExecution() throws CoreException;
ICPPTemplateArgument unmarshalTemplateArgument() throws CoreException;
int getByte() throws CoreException;
int getFixedInt() throws CoreException;
@ -107,6 +142,7 @@ public interface ITypeMarshalBuffer {
void marshalValue(IValue value) throws CoreException;
void marshalBinding(IBinding binding) throws CoreException;
void marshalEvaluation(ISerializableEvaluation eval, boolean includeValue) throws CoreException;
void marshalExecution(ISerializableExecution exec, boolean includeValue) throws CoreException;
void marshalTemplateArgument(ICPPTemplateArgument arg) throws CoreException;
void putByte(byte data);
void putFixedInt(int data);

View file

@ -0,0 +1,349 @@
/*******************************************************************************
* Copyright (c) 2008, 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import java.util.Arrays;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.pdom.dom.TypeMarshalBuffer;
import org.eclipse.core.runtime.CoreException;
/**
* Represents values of variables, enumerators or expressions. The primary purpose of
* the representation is to support instantiation of templates with non-type template parameters.
*/
public class IntegralValue implements IValue {
public static final int MAX_RECURSION_DEPTH = 25;
// IntegralValue.THIS represents the this pointer inside a member function / constructor.
public static final IntegralValue THIS = new IntegralValue("this".toCharArray(), null); //$NON-NLS-1$
// IntegralValue.UNKNOWN indicates general inability to determine a value. It doesn't have to be an error,
// it could be that evaluation ran into a performance limit, or that we can't model this kind of
// value (such as a pointer to a function).
public static final IntegralValue UNKNOWN = new IntegralValue("<unknown>".toCharArray(), null) { //$NON-NLS-1$
@Override
public void setSubValue(int position, ICPPEvaluation newValue) {
throw new UnsupportedOperationException();
}
};
// IntegralValue.ERROR indicates that an error, such as a substitution failure, occurred during evaluation.
public static final IntegralValue ERROR= new IntegralValue("<error>".toCharArray(), null); //$NON-NLS-1$
public static final IntegralValue NOT_INITIALIZED= new IntegralValue("<__>".toCharArray(), null); //$NON-NLS-1$
private static final char UNIQUE_CHAR = '_';
private final static IntegralValue[] TYPICAL= {
new IntegralValue(new char[] {'0'}, null),
new IntegralValue(new char[] {'1'}, null),
new IntegralValue(new char[] {'2'}, null),
new IntegralValue(new char[] {'3'}, null),
new IntegralValue(new char[] {'4'}, null),
new IntegralValue(new char[] {'5'}, null),
new IntegralValue(new char[] {'6'}, null)};
private static int sUnique= 0;
// The following invariant always holds: (fFixedValue == null) != (fEvaluation == null)
private final char[] fFixedValue;
private ICPPEvaluation fEvaluation;
private char[] fSignature;
private IntegralValue(char[] fixedValue, ICPPEvaluation evaluation) {
assert (fixedValue == null) != (evaluation == null);
fFixedValue = fixedValue;
fEvaluation = evaluation;
}
@Override
public Long numericalValue() {
return (Long) numberValue(); // IntegralValue.numberValue() always returns a Long
}
@Override
public Number numberValue() {
return fFixedValue == null ? null : parseLong(fFixedValue);
}
@Override
public ICPPEvaluation getEvaluation() {
return fEvaluation;
}
@Override
public char[] getSignature() {
if (fSignature == null) {
fSignature = fFixedValue != null ? fFixedValue : fEvaluation.getSignature();
}
return fSignature;
}
@Deprecated
@Override
public char[] getInternalExpression() {
return CharArrayUtils.EMPTY_CHAR_ARRAY;
}
@Deprecated
@Override
public IBinding[] getUnknownBindings() {
return IBinding.EMPTY_BINDING_ARRAY;
}
@Override
public void marshal(ITypeMarshalBuffer buf) throws CoreException {
if (UNKNOWN == this) {
buf.putShort((short) (ITypeMarshalBuffer.INTEGRAL_VALUE | ITypeMarshalBuffer.FLAG1));
} else if(THIS == this) {
buf.putShort((short) (ITypeMarshalBuffer.INTEGRAL_VALUE | ITypeMarshalBuffer.FLAG5));
} else {
Number num= numberValue();
if (num != null) {
long lv= num.longValue();
if (lv >= 0) {
buf.putShort((short) (ITypeMarshalBuffer.INTEGRAL_VALUE | ITypeMarshalBuffer.FLAG2));
buf.putLong(lv);
} else {
buf.putShort((short) (ITypeMarshalBuffer.INTEGRAL_VALUE | ITypeMarshalBuffer.FLAG3));
buf.putLong(-lv);
}
} else if (fFixedValue != null) {
buf.putShort((short) (ITypeMarshalBuffer.INTEGRAL_VALUE | ITypeMarshalBuffer.FLAG4));
buf.putCharArray(fFixedValue);
} else {
buf.putShort(ITypeMarshalBuffer.INTEGRAL_VALUE);
fEvaluation.marshal(buf, true);
}
}
}
public static IValue unmarshal(short firstBytes, ITypeMarshalBuffer buf) throws CoreException {
if (firstBytes == TypeMarshalBuffer.NULL_TYPE)
return IntegralValue.UNKNOWN;
if ((firstBytes & ITypeMarshalBuffer.FLAG1) != 0)
return IntegralValue.UNKNOWN;
if ((firstBytes & ITypeMarshalBuffer.FLAG2) != 0)
return IntegralValue.create(buf.getLong());
if ((firstBytes & ITypeMarshalBuffer.FLAG3) != 0)
return IntegralValue.create(-buf.getLong());
if ((firstBytes & ITypeMarshalBuffer.FLAG4) != 0)
return new IntegralValue(buf.getCharArray(), null);
if ((firstBytes & ITypeMarshalBuffer.FLAG5) != 0)
return IntegralValue.THIS;
ISerializableEvaluation eval= buf.unmarshalEvaluation();
if (eval instanceof ICPPEvaluation)
return new IntegralValue(null, (ICPPEvaluation) eval);
return IntegralValue.UNKNOWN;
}
@Override
public int hashCode() {
return CharArrayUtils.hash(getSignature());
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof IntegralValue)) {
return false;
}
final IntegralValue rhs = (IntegralValue) obj;
return CharArrayUtils.equals(getSignature(), rhs.getSignature());
}
/**
* For debugging only.
*/
@Override
public String toString() {
return new String(getSignature());
}
/**
* Creates a value representing the given number.
*/
public static IntegralValue create(long value) {
if (value >= 0 && value < TYPICAL.length)
return TYPICAL[(int) value];
return new IntegralValue(toCharArray(value), null);
}
/**
* Creates a value object representing the given boolean value.
*/
public static IntegralValue create(boolean value) {
return create(value ? 1 : 0);
}
/**
* Creates a value representing the given template parameter
* in the given template.
*/
public static IntegralValue create(ICPPTemplateDefinition template, ICPPTemplateNonTypeParameter tntp) {
EvalBinding eval = new EvalBinding(tntp, null, template);
return new IntegralValue(null, eval);
}
/**
* Create a value wrapping the given evaluation.
*/
public static IntegralValue create(ICPPEvaluation eval) {
return new IntegralValue(null, eval);
}
public static IValue incrementedValue(IValue value, int increment) {
if (value == UNKNOWN)
return UNKNOWN;
Number val = value.numberValue();
if (val != null) {
return create(val.longValue() + increment);
}
ICPPEvaluation arg1 = value.getEvaluation();
EvalFixed arg2 = new EvalFixed(CPPBasicType.INT, ValueCategory.PRVALUE, create(increment));
return create(new EvalBinary(IASTBinaryExpression.op_plus, arg1, arg2, arg1.getTemplateDefinition()));
}
/**
* Tests whether the value is a template parameter (or a parameter pack).
*
* @return the parameter id of the parameter, or <code>-1</code> if it is not a template
* parameter.
*/
public static int isTemplateParameter(IValue tval) {
ICPPEvaluation eval = tval.getEvaluation();
if (eval instanceof EvalBinding) {
return ((EvalBinding) eval).getTemplateParameterID();
}
return -1;
}
/**
* Tests whether the value references some template parameter.
*/
public static boolean referencesTemplateParameter(IValue tval) {
ICPPEvaluation eval = tval.getEvaluation();
if (eval == null)
return false;
return eval.referencesTemplateParameter();
}
/**
* Tests whether the value depends on a template parameter.
*/
public static boolean isDependentValue(IValue nonTypeValue) {
if (nonTypeValue == null)
return false;
ICPPEvaluation eval = nonTypeValue.getEvaluation();
return eval != null && eval.isValueDependent();
}
/**
* Creates a value off its canonical representation.
*/
public static IValue fromInternalRepresentation(ICPPEvaluation evaluation) {
return new IntegralValue(null, evaluation);
}
/**
* Creates a unique value needed during template instantiation.
*/
public static IValue unique() {
StringBuilder buf= new StringBuilder(10);
buf.append(UNIQUE_CHAR);
buf.append(++sUnique);
return new IntegralValue(CharArrayUtils.extractChars(buf), null);
}
/**
* Parses a long, returns <code>null</code> if not possible
*/
private static Long parseLong(char[] value) {
final long maxvalue= Long.MAX_VALUE / 10;
final int len= value.length;
boolean negative= false;
long result = 0;
int i= 0;
if (len > 0 && value[0] == '-') {
negative = true;
i++;
}
if (i == len)
return null;
for (; i < len; i++) {
if (result > maxvalue)
return null;
final int digit= (value[i] - '0');
if (digit < 0 || digit > 9)
return null;
result= result * 10 + digit;
}
return negative ? -result : result;
}
/**
* Converts long to a char array
*/
private static char[] toCharArray(long value) {
StringBuilder buf= new StringBuilder();
buf.append(value);
return CharArrayUtils.extractChars(buf);
}
@Override
public int numberOfSubValues() {
return 1;
}
@Override
public ICPPEvaluation getSubValue(int index) {
return index == 0 ? (fEvaluation != null ? fEvaluation : EvalFixed.INCOMPLETE) : EvalFixed.INCOMPLETE;
}
@Override
public ICPPEvaluation[] getAllSubValues() {
return new ICPPEvaluation[] { getEvaluation() };
}
@Override
public void setSubValue(int position, ICPPEvaluation newValue) {
if (fEvaluation == null) {
throw new RuntimeException("trying to set incomplete value"); //$NON-NLS-1$
}
if (position == 0) {
fEvaluation = newValue;
} else {
throw new RuntimeException("invalid offset in POD value: " + position); //$NON-NLS-1$
}
}
@Override
public IValue clone() {
char[] newFixedValue = fFixedValue != null ? Arrays.copyOf(fFixedValue, fFixedValue.length) : null;
return new IntegralValue(newFixedValue, fEvaluation);
}
}

View file

@ -30,8 +30,10 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.parser.ParserMessages;
import org.eclipse.core.runtime.PlatformObject;
@ -326,6 +328,10 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
public IValue getInitialValue() {
return null;
}
public ICPPEvaluation getInitializerEvaluation() {
return EvalFixed.INCOMPLETE;
}
public boolean isAnonymous() {
return false;

View file

@ -273,7 +273,7 @@ public class SizeofCalculator {
IValue value = type.getSize();
if (value == null)
return null;
Long numElements = value.numericalValue();
Number numElements = value.numberValue();
if (numElements == null)
return null;
IType elementType = type.getType();

View file

@ -1,740 +0,0 @@
/*******************************************************************************
* Copyright (c) 2008, 2016 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_alignof;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_nothrow_constructor;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_nothrow_copy;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_trivial_assign;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_trivial_constructor;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_trivial_copy;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_trivial_destructor;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_virtual_destructor;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_abstract;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_class;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_empty;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_enum;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_final;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_literal_type;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_pod;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_polymorphic;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_standard_layout;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_trivial;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_trivially_copyable;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_union;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_sizeof;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_typeid;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_typeof;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeTraits;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException;
import org.eclipse.cdt.internal.core.pdom.dom.TypeMarshalBuffer;
import org.eclipse.core.runtime.CoreException;
/**
* Represents values of variables, enumerators or expressions. The primary purpose of
* the representation is to support instantiation of templates with non-type template parameters.
*/
public class Value implements IValue {
public static final int MAX_RECURSION_DEPTH = 25;
// Value.UNKNOWN indicates general inability to determine a value. It doesn't have to be an error,
// it could be that evaluation ran into a performance limit, or that we can't model this kind of
// value (such as a pointer to a function).
public static final Value UNKNOWN= new Value("<unknown>".toCharArray(), null); //$NON-NLS-1$
// Value.ERROR indicates that an error, such as a substitution failure, occurred during evaluation.
public static final Value ERROR= new Value("<error>".toCharArray(), null); //$NON-NLS-1$
public static final Value NOT_INITIALIZED= new Value("<__>".toCharArray(), null); //$NON-NLS-1$
private static final Number VALUE_CANNOT_BE_DETERMINED = new Number() {
@Override
public int intValue() { throw new UnsupportedOperationException(); }
@Override
public long longValue() { throw new UnsupportedOperationException(); }
@Override
public float floatValue() { throw new UnsupportedOperationException(); }
@Override
public double doubleValue() { throw new UnsupportedOperationException(); }
};
private static final char UNIQUE_CHAR = '_';
private final static IValue[] TYPICAL= {
new Value(new char[] {'0'}, null),
new Value(new char[] {'1'}, null),
new Value(new char[] {'2'}, null),
new Value(new char[] {'3'}, null),
new Value(new char[] {'4'}, null),
new Value(new char[] {'5'}, null),
new Value(new char[] {'6'}, null)};
private static int sUnique= 0;
// The following invariant always holds: (fFixedValue == null) != (fEvaluation == null)
private final char[] fFixedValue;
private final ICPPEvaluation fEvaluation;
private char[] fSignature;
private Value(char[] fixedValue, ICPPEvaluation evaluation) {
assert (fixedValue == null) != (evaluation == null);
fFixedValue = fixedValue;
fEvaluation = evaluation;
}
@Override
public Long numericalValue() {
return fFixedValue == null ? null : parseLong(fFixedValue);
}
@Override
public ICPPEvaluation getEvaluation() {
return fEvaluation;
}
@Override
public char[] getSignature() {
if (fSignature == null) {
fSignature = fFixedValue != null ? fFixedValue : fEvaluation.getSignature();
}
return fSignature;
}
@Deprecated
@Override
public char[] getInternalExpression() {
return CharArrayUtils.EMPTY_CHAR_ARRAY;
}
@Deprecated
@Override
public IBinding[] getUnknownBindings() {
return IBinding.EMPTY_BINDING_ARRAY;
}
public void marshal(ITypeMarshalBuffer buf) throws CoreException {
if (UNKNOWN == this) {
buf.putShort((short) (ITypeMarshalBuffer.VALUE | ITypeMarshalBuffer.FLAG1));
} else {
Long num= numericalValue();
if (num != null) {
long lv= num;
if (lv >= 0) {
buf.putShort((short) (ITypeMarshalBuffer.VALUE | ITypeMarshalBuffer.FLAG2));
buf.putLong(lv);
} else {
buf.putShort((short) (ITypeMarshalBuffer.VALUE | ITypeMarshalBuffer.FLAG3));
buf.putLong(-lv);
}
} else if (fFixedValue != null) {
buf.putShort((short) (ITypeMarshalBuffer.VALUE | ITypeMarshalBuffer.FLAG4));
buf.putCharArray(fFixedValue);
} else {
buf.putShort(ITypeMarshalBuffer.VALUE);
fEvaluation.marshal(buf, true);
}
}
}
public static IValue unmarshal(ITypeMarshalBuffer buf) throws CoreException {
short firstBytes= buf.getShort();
if (firstBytes == TypeMarshalBuffer.NULL_TYPE)
return Value.UNKNOWN;
if ((firstBytes & ITypeMarshalBuffer.FLAG1) != 0)
return Value.UNKNOWN;
if ((firstBytes & ITypeMarshalBuffer.FLAG2) != 0)
return Value.create(buf.getLong());
if ((firstBytes & ITypeMarshalBuffer.FLAG3) != 0)
return Value.create(-buf.getLong());
if ((firstBytes & ITypeMarshalBuffer.FLAG4) != 0)
return new Value(buf.getCharArray(), null);
ISerializableEvaluation eval= buf.unmarshalEvaluation();
if (eval instanceof ICPPEvaluation)
return new Value(null, (ICPPEvaluation) eval);
return Value.UNKNOWN;
}
@Override
public int hashCode() {
return CharArrayUtils.hash(getSignature());
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Value)) {
return false;
}
final Value rhs = (Value) obj;
if (fFixedValue != null)
return CharArrayUtils.equals(fFixedValue, rhs.fFixedValue);
return CharArrayUtils.equals(getSignature(), rhs.getSignature());
}
/**
* For debugging only.
*/
@Override
public String toString() {
return new String(getSignature());
}
/**
* Creates a value representing the given number.
*/
public static IValue create(long value) {
if (value >= 0 && value < TYPICAL.length)
return TYPICAL[(int) value];
return new Value(toCharArray(value), null);
}
/**
* Creates a value object representing the given boolean value.
*/
public static IValue create(boolean value) {
return create(value ? 1 : 0);
}
/**
* Creates a value representing the given template parameter
* in the given template.
*/
public static IValue create(ICPPTemplateDefinition template, ICPPTemplateNonTypeParameter tntp) {
EvalBinding eval = new EvalBinding(tntp, null, template);
return new Value(null, eval);
}
/**
* Create a value wrapping the given evaluation.
*/
public static IValue create(ICPPEvaluation eval) {
return new Value(null, eval);
}
public static IValue evaluateBinaryExpression(final int op, final long v1, final long v2) {
Number val = applyBinaryOperator(op, v1, v2);
if (val != null && val != VALUE_CANNOT_BE_DETERMINED)
return create(val.longValue());
return UNKNOWN;
}
public static IValue evaluateUnaryExpression(final int unaryOp, final long value) {
Number val = applyUnaryOperator(unaryOp, value);
if (val != null && val != VALUE_CANNOT_BE_DETERMINED)
return create(val.longValue());
return UNKNOWN;
}
public static IValue evaluateUnaryTypeIdExpression(int operator, IType type, IASTNode point) {
Number val = applyUnaryTypeIdOperator(operator, type, point);
if (val != null && val != VALUE_CANNOT_BE_DETERMINED)
return create(val.longValue());
return UNKNOWN;
}
public static IValue evaluateBinaryTypeIdExpression(IASTBinaryTypeIdExpression.Operator operator,
IType type1, IType type2, IASTNode point) {
Number val = applyBinaryTypeIdOperator(operator, type1, type2, point);
if (val != null && val != VALUE_CANNOT_BE_DETERMINED)
return create(val.longValue());
return UNKNOWN;
}
public static IValue incrementedValue(IValue value, int increment) {
if (value == UNKNOWN)
return UNKNOWN;
Long val = value.numericalValue();
if (val != null) {
return create(val.longValue() + increment);
}
ICPPEvaluation arg1 = value.getEvaluation();
EvalFixed arg2 = new EvalFixed(CPPBasicType.INT, ValueCategory.PRVALUE, create(increment));
return create(new EvalBinary(IASTBinaryExpression.op_plus, arg1, arg2, arg1.getTemplateDefinition()));
}
private static Number applyUnaryTypeIdOperator(int operator, IType type, IASTNode point) {
switch (operator) {
case op_sizeof:
return getSize(type, point);
case op_alignof:
return getAlignment(type, point);
case op_typeid:
break;
case op_has_nothrow_copy:
break; // TODO(sprigogin): Implement
case op_has_nothrow_constructor:
break; // TODO(sprigogin): Implement
case op_has_trivial_assign:
break; // TODO(sprigogin): Implement
case op_has_trivial_constructor:
break; // TODO(sprigogin): Implement
case op_has_trivial_copy:
return !(type instanceof ICPPClassType) ||
TypeTraits.hasTrivialCopyCtor((ICPPClassType) type, point) ? 1 : 0;
case op_has_trivial_destructor:
break; // TODO(sprigogin): Implement
case op_has_virtual_destructor:
break; // TODO(sprigogin): Implement
case op_is_abstract:
return type instanceof ICPPClassType &&
TypeTraits.isAbstract((ICPPClassType) type, point) ? 1 : 0;
case op_is_class:
return type instanceof ICompositeType &&
((ICompositeType) type).getKey() != ICompositeType.k_union ? 1 : 0;
case op_is_empty:
return TypeTraits.isEmpty(type, point) ? 1 : 0;
case op_is_enum:
return type instanceof IEnumeration ? 1 : 0;
case op_is_final:
return type instanceof ICPPClassType && ((ICPPClassType) type).isFinal() ? 1 : 0;
case op_is_literal_type:
break; // TODO(sprigogin): Implement
case op_is_pod:
return TypeTraits.isPOD(type, point) ? 1 : 0;
case op_is_polymorphic:
return type instanceof ICPPClassType &&
TypeTraits.isPolymorphic((ICPPClassType) type, point) ? 1 : 0;
case op_is_standard_layout:
return TypeTraits.isStandardLayout(type, point) ? 1 : 0;
case op_is_trivial:
return type instanceof ICPPClassType &&
TypeTraits.isTrivial((ICPPClassType) type, point) ? 1 : 0;
case op_is_trivially_copyable:
return TypeTraits.isTriviallyCopyable(type, point) ? 1 : 0;
case op_is_union:
return type instanceof ICompositeType &&
((ICompositeType) type).getKey() == ICompositeType.k_union ? 1 : 0;
case op_typeof:
break;
}
return VALUE_CANNOT_BE_DETERMINED;
}
public static Number applyBinaryTypeIdOperator(IASTBinaryTypeIdExpression.Operator operator,
IType type1, IType type2, IASTNode point) {
switch (operator) {
case __is_base_of:
type1 = SemanticUtil.getNestedType(type1, TDEF);
type2 = SemanticUtil.getNestedType(type2, TDEF);
if (type1 instanceof ICPPClassType && type2 instanceof ICPPClassType &&
(type1.isSameType(type2) ||
ClassTypeHelper.isSubclass((ICPPClassType) type2, (ICPPClassType) type1, point))) {
return 1;
}
return 0;
case __is_trivially_assignable:
return VALUE_CANNOT_BE_DETERMINED; // TODO: Implement.
}
return VALUE_CANNOT_BE_DETERMINED;
}
private static Number getAlignment(IType type, IASTNode point) {
SizeAndAlignment sizeAndAlignment = SizeofCalculator.getSizeAndAlignment(type, point);
if (sizeAndAlignment == null)
return VALUE_CANNOT_BE_DETERMINED;
return sizeAndAlignment.alignment;
}
private static Number getSize(IType type, IASTNode point) {
SizeAndAlignment sizeAndAlignment = SizeofCalculator.getSizeAndAlignment(type, point);
if (sizeAndAlignment == null)
return VALUE_CANNOT_BE_DETERMINED;
return sizeAndAlignment.size;
}
/**
* Tests whether the value is a template parameter (or a parameter pack).
*
* @return the parameter id of the parameter, or <code>-1</code> if it is not a template
* parameter.
*/
public static int isTemplateParameter(IValue tval) {
ICPPEvaluation eval = tval.getEvaluation();
if (eval instanceof EvalBinding) {
return ((EvalBinding) eval).getTemplateParameterID();
}
return -1;
}
/**
* Tests whether the value references some template parameter.
*/
public static boolean referencesTemplateParameter(IValue tval) {
ICPPEvaluation eval = tval.getEvaluation();
if (eval == null)
return false;
return eval.referencesTemplateParameter();
}
/**
* Tests whether the value depends on a template parameter.
*/
public static boolean isDependentValue(IValue nonTypeValue) {
if (nonTypeValue == null)
return false;
ICPPEvaluation eval = nonTypeValue.getEvaluation();
return eval != null && eval.isValueDependent();
}
/**
* Creates the value for an expression.
*/
public static IValue create(IASTExpression expr) {
Number val= evaluate(expr);
if (val == VALUE_CANNOT_BE_DETERMINED)
return UNKNOWN;
if (val != null)
return create(val.longValue());
if (expr instanceof ICPPASTInitializerClause) {
ICPPEvaluation evaluation = ((ICPPASTInitializerClause) expr).getEvaluation();
return evaluation.getValue(expr);
}
return UNKNOWN;
}
/**
* Creates a value off its canonical representation.
*/
public static IValue fromInternalRepresentation(ICPPEvaluation evaluation) {
return new Value(null, evaluation);
}
/**
* Creates a unique value needed during template instantiation.
*/
public static IValue unique() {
StringBuilder buf= new StringBuilder(10);
buf.append(UNIQUE_CHAR);
buf.append(++sUnique);
return new Value(CharArrayUtils.extractChars(buf), null);
}
/**
* Computes the canonical representation of the value of the expression.
* Returns a {@code Number} for numerical values or {@code null}, otherwise.
* @throws UnknownValueException
*/
private static Number evaluate(IASTExpression exp) {
if (exp == null)
return VALUE_CANNOT_BE_DETERMINED;
if (exp instanceof IASTArraySubscriptExpression) {
return VALUE_CANNOT_BE_DETERMINED;
}
if (exp instanceof IASTBinaryExpression) {
return evaluateBinaryExpression((IASTBinaryExpression) exp);
}
if (exp instanceof IASTCastExpression) { // must be ahead of unary
return evaluate(((IASTCastExpression) exp).getOperand());
}
if (exp instanceof IASTUnaryExpression) {
return evaluateUnaryExpression((IASTUnaryExpression) exp);
}
if (exp instanceof IASTConditionalExpression) {
IASTConditionalExpression cexpr= (IASTConditionalExpression) exp;
Number v= evaluate(cexpr.getLogicalConditionExpression());
if (v == null || v == VALUE_CANNOT_BE_DETERMINED)
return v;
if (v.longValue() == 0) {
return evaluate(cexpr.getNegativeResultExpression());
}
final IASTExpression pe = cexpr.getPositiveResultExpression();
if (pe == null) // gnu-extension allows to omit the positive expression.
return v;
return evaluate(pe);
}
if (exp instanceof IASTIdExpression) {
IBinding b= ((IASTIdExpression) exp).getName().resolvePreBinding();
return evaluateBinding(b);
}
if (exp instanceof IASTLiteralExpression) {
IASTLiteralExpression litEx= (IASTLiteralExpression) exp;
switch (litEx.getKind()) {
case IASTLiteralExpression.lk_false:
case IASTLiteralExpression.lk_nullptr:
return Long.valueOf(0);
case IASTLiteralExpression.lk_true:
return Long.valueOf(1);
case IASTLiteralExpression.lk_integer_constant:
try {
return ExpressionEvaluator.getNumber(litEx.getValue());
} catch (EvalException e) {
return VALUE_CANNOT_BE_DETERMINED;
}
case IASTLiteralExpression.lk_char_constant:
try {
final char[] image= litEx.getValue();
if (image.length > 1 && image[0] == 'L')
return ExpressionEvaluator.getChar(image, 2);
return ExpressionEvaluator.getChar(image, 1);
} catch (EvalException e) {
return VALUE_CANNOT_BE_DETERMINED;
}
}
}
if (exp instanceof IASTTypeIdExpression) {
IASTTypeIdExpression typeIdExp = (IASTTypeIdExpression) exp;
ASTTranslationUnit ast = (ASTTranslationUnit) exp.getTranslationUnit();
final IType type = ast.createType(typeIdExp.getTypeId());
if (type instanceof ICPPUnknownType)
return null;
return applyUnaryTypeIdOperator(typeIdExp.getOperator(), type, exp);
}
if (exp instanceof IASTBinaryTypeIdExpression) {
IASTBinaryTypeIdExpression typeIdExp = (IASTBinaryTypeIdExpression) exp;
ASTTranslationUnit ast = (ASTTranslationUnit) exp.getTranslationUnit();
IType t1= ast.createType(typeIdExp.getOperand1());
IType t2= ast.createType(typeIdExp.getOperand2());
if (CPPTemplates.isDependentType(t1) || CPPTemplates.isDependentType(t2))
return null;
return applyBinaryTypeIdOperator(typeIdExp.getOperator(), t1, t2, exp);
}
if (exp instanceof IASTFunctionCallExpression || exp instanceof ICPPASTSimpleTypeConstructorExpression) {
return null; // The value will be obtained from the evaluation.
}
return VALUE_CANNOT_BE_DETERMINED;
}
/**
* Extract a value off a binding.
*/
private static Number evaluateBinding(IBinding b) {
if (b instanceof IType) {
return VALUE_CANNOT_BE_DETERMINED;
}
if (b instanceof ICPPTemplateNonTypeParameter) {
return null;
}
if (b instanceof ICPPUnknownBinding) {
return null;
}
IValue value= null;
if (b instanceof IVariable) {
value= ((IVariable) b).getInitialValue();
} else if (b instanceof IEnumerator) {
value= ((IEnumerator) b).getValue();
}
if (value != null && value != Value.UNKNOWN) {
return value.numericalValue();
}
return VALUE_CANNOT_BE_DETERMINED;
}
private static Number evaluateUnaryExpression(IASTUnaryExpression exp) {
final int unaryOp= exp.getOperator();
if (unaryOp == IASTUnaryExpression.op_sizeof) {
final IASTExpression operand = exp.getOperand();
if (operand != null) {
IType type = operand.getExpressionType();
if (type instanceof ICPPUnknownType)
return null;
ASTTranslationUnit ast = (ASTTranslationUnit) exp.getTranslationUnit();
SizeofCalculator calculator = ast.getSizeofCalculator();
SizeAndAlignment info = calculator.sizeAndAlignment(type);
if (info != null)
return info.size;
}
return VALUE_CANNOT_BE_DETERMINED;
}
if (unaryOp == IASTUnaryExpression.op_amper || unaryOp == IASTUnaryExpression.op_star ||
unaryOp == IASTUnaryExpression.op_sizeofParameterPack) {
return VALUE_CANNOT_BE_DETERMINED;
}
final Number value= evaluate(exp.getOperand());
if (value == null || value == VALUE_CANNOT_BE_DETERMINED)
return value;
return applyUnaryOperator(unaryOp, value.longValue());
}
private static Number applyUnaryOperator(final int unaryOp, final long value) {
switch (unaryOp) {
case IASTUnaryExpression.op_bracketedPrimary:
case IASTUnaryExpression.op_plus:
return value;
}
switch (unaryOp) {
case IASTUnaryExpression.op_prefixIncr:
case IASTUnaryExpression.op_postFixIncr:
return value + 1;
case IASTUnaryExpression.op_prefixDecr:
case IASTUnaryExpression.op_postFixDecr:
return value - 1;
case IASTUnaryExpression.op_minus:
return -value;
case IASTUnaryExpression.op_tilde:
return ~value;
case IASTUnaryExpression.op_not:
return value == 0 ? 1 : 0;
}
return VALUE_CANNOT_BE_DETERMINED;
}
private static Number evaluateBinaryExpression(IASTBinaryExpression exp) {
final int op= exp.getOperator();
switch (op) {
case IASTBinaryExpression.op_equals:
if (exp.getOperand1().equals(exp.getOperand2()))
return Long.valueOf(1);
break;
case IASTBinaryExpression.op_notequals:
if (exp.getOperand1().equals(exp.getOperand2()))
return Long.valueOf(0);
break;
}
final Number o1= evaluate(exp.getOperand1());
if (o1 == null || o1 == VALUE_CANNOT_BE_DETERMINED)
return o1;
final Number o2= evaluate(exp.getOperand2());
if (o2 == null || o2 == VALUE_CANNOT_BE_DETERMINED)
return o2;
return applyBinaryOperator(op, o1.longValue(), o2.longValue());
}
private static Number applyBinaryOperator(final int op, final long v1, final long v2) {
switch (op) {
case IASTBinaryExpression.op_multiply:
return v1 * v2;
case IASTBinaryExpression.op_divide:
if (v2 == 0)
return VALUE_CANNOT_BE_DETERMINED;
return v1 / v2;
case IASTBinaryExpression.op_modulo:
if (v2 == 0)
return VALUE_CANNOT_BE_DETERMINED;
return v1 % v2;
case IASTBinaryExpression.op_plus:
return v1 + v2;
case IASTBinaryExpression.op_minus:
return v1 - v2;
case IASTBinaryExpression.op_shiftLeft:
return v1 << v2;
case IASTBinaryExpression.op_shiftRight:
return v1 >> v2;
case IASTBinaryExpression.op_lessThan:
return v1 < v2 ? 1 : 0;
case IASTBinaryExpression.op_greaterThan:
return v1 > v2 ? 1 : 0;
case IASTBinaryExpression.op_lessEqual:
return v1 <= v2 ? 1 : 0;
case IASTBinaryExpression.op_greaterEqual:
return v1 >= v2 ? 1 : 0;
case IASTBinaryExpression.op_binaryAnd:
return v1 & v2;
case IASTBinaryExpression.op_binaryXor:
return v1 ^ v2;
case IASTBinaryExpression.op_binaryOr:
return v1 | v2;
case IASTBinaryExpression.op_logicalAnd:
return v1 != 0 && v2 != 0 ? 1 : 0;
case IASTBinaryExpression.op_logicalOr:
return v1 != 0 || v2 != 0 ? 1 : 0;
case IASTBinaryExpression.op_equals:
return v1 == v2 ? 1 : 0;
case IASTBinaryExpression.op_notequals:
return v1 != v2 ? 1 : 0;
case IASTBinaryExpression.op_max:
return Math.max(v1, v2);
case IASTBinaryExpression.op_min:
return Math.min(v1, v2);
}
return VALUE_CANNOT_BE_DETERMINED;
}
/**
* Parses a long, returns <code>null</code> if not possible
*/
private static Long parseLong(char[] value) {
final long maxvalue= Long.MAX_VALUE / 10;
final int len= value.length;
boolean negative= false;
long result = 0;
int i= 0;
if (len > 0 && value[0] == '-') {
negative = true;
i++;
}
if (i == len)
return null;
for (; i < len; i++) {
if (result > maxvalue)
return null;
final int digit= (value[i] - '0');
if (digit < 0 || digit > 9)
return null;
result= result * 10 + digit;
}
return negative ? -result : result;
}
/**
* Converts long to a char array
*/
private static char[] toCharArray(long value) {
StringBuilder buf= new StringBuilder();
buf.append(value);
return CharArrayUtils.extractChars(buf);
}
}

View file

@ -0,0 +1,586 @@
/*******************************************************************************
* Copyright (c) 2008, 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_alignof;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_nothrow_constructor;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_nothrow_copy;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_trivial_assign;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_trivial_constructor;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_trivial_copy;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_trivial_destructor;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_virtual_destructor;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_abstract;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_class;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_empty;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_enum;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_final;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_literal_type;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_pod;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_polymorphic;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_standard_layout;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_trivial;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_trivially_copyable;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_union;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_sizeof;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_typeid;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_typeof;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluationOwner;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeTraits;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException;
public class ValueFactory {
/**
* Creates the value for an expression.
*/
public static IValue create(IASTExpression expr) {
IValue val= evaluate(expr);
if (val != null) {
return val;
}
if (expr instanceof ICPPEvaluationOwner) {
ICPPEvaluation evaluation = ((ICPPEvaluationOwner) expr).getEvaluation();
return evaluation.getValue(expr);
}
return IntegralValue.UNKNOWN;
}
public static IValue evaluateUnaryExpression(final int unaryOp, final IValue value) {
IValue val = applyUnaryOperator(unaryOp, value);
if (isInvalidValue(val))
return IntegralValue.UNKNOWN;
return val;
}
public static IValue evaluateBinaryExpression(final int op, final IValue v1, final IValue v2) {
if(v1 instanceof FloatingPointValue && v2 instanceof FloatingPointValue) {
FloatingPointValue fv1 = (FloatingPointValue)v1;
FloatingPointValue fv2 = (FloatingPointValue)v2;
return applyBinaryOperator(op, fv1.numberValue().doubleValue(), fv2.numberValue().doubleValue());
} else if(v1 instanceof FloatingPointValue && v2 instanceof IntegralValue) {
FloatingPointValue fv1 = (FloatingPointValue)v1;
IntegralValue iv2 = (IntegralValue)v2;
return applyBinaryOperator(op, fv1.numberValue().doubleValue(), iv2.numberValue().doubleValue());
} else if(v1 instanceof IntegralValue && v2 instanceof FloatingPointValue) {
IntegralValue iv1 = (IntegralValue)v1;
FloatingPointValue fv2 = (FloatingPointValue)v2;
return applyBinaryOperator(op, iv1.numberValue().doubleValue(), fv2.numberValue().doubleValue());
} else if(v1 instanceof IntegralValue && v2 instanceof IntegralValue) {
IntegralValue iv1 = (IntegralValue)v1;
IntegralValue iv2 = (IntegralValue)v2;
return applyBinaryOperator(op, iv1.numberValue().longValue(), iv2.numberValue().longValue());
}
return IntegralValue.UNKNOWN;
}
private static IValue applyBinaryOperator(final int op, final double v1, final double v2) {
Double doubleValue = null;
Long longValue = null;
switch (op) {
case IASTBinaryExpression.op_multiply:
doubleValue = v1 * v2;
break;
case IASTBinaryExpression.op_divide:
if (v2 != 0) {
doubleValue = v1 / v2;
}
break;
case IASTBinaryExpression.op_plus:
doubleValue = v1 + v2;
break;
case IASTBinaryExpression.op_minus:
doubleValue = v1 - v2;
break;
case IASTBinaryExpression.op_lessThan:
longValue = v1 < v2 ? 1l : 0l;
break;
case IASTBinaryExpression.op_greaterThan:
longValue = v1 > v2 ? 1l : 0l;
break;
case IASTBinaryExpression.op_lessEqual:
longValue = v1 <= v2 ? 1l : 0l;
break;
case IASTBinaryExpression.op_greaterEqual:
longValue = v1 >= v2 ? 1l : 0l;
break;
case IASTBinaryExpression.op_logicalAnd:
longValue = v1 != 0 && v2 != 0 ? 1l : 0l;
break;
case IASTBinaryExpression.op_logicalOr:
longValue = v1 != 0 || v2 != 0 ? 1l : 0l;
break;
case IASTBinaryExpression.op_equals:
longValue = v1 == v2 ? 1l : 0l;
break;
case IASTBinaryExpression.op_notequals:
longValue = v1 != v2 ? 1l : 0l;
break;
}
if(doubleValue != null) {
return FloatingPointValue.create(doubleValue);
} else if(longValue != null) {
return IntegralValue.create(longValue);
} else {
return IntegralValue.UNKNOWN;
}
}
private static IntegralValue applyBinaryOperator(final int op, final long v1, final long v2) {
Long value = null;
switch (op) {
case IASTBinaryExpression.op_multiply:
value = v1 * v2;
break;
case IASTBinaryExpression.op_divide:
if (v2 != 0) {
value = v1 / v2;
}
break;
case IASTBinaryExpression.op_modulo:
if (v2 != 0) {
value = v1 % v2;
}
break;
case IASTBinaryExpression.op_plus:
value = v1 + v2;
break;
case IASTBinaryExpression.op_minus:
value = v1 - v2;
break;
case IASTBinaryExpression.op_shiftLeft:
value = v1 << v2;
break;
case IASTBinaryExpression.op_shiftRight:
value = v1 >> v2;
break;
case IASTBinaryExpression.op_lessThan:
value = v1 < v2 ? 1l : 0l;
break;
case IASTBinaryExpression.op_greaterThan:
value = v1 > v2 ? 1l : 0l;
break;
case IASTBinaryExpression.op_lessEqual:
value = v1 <= v2 ? 1l : 0l;
break;
case IASTBinaryExpression.op_greaterEqual:
value = v1 >= v2 ? 1l : 0l;
break;
case IASTBinaryExpression.op_binaryAnd:
value = v1 & v2;
break;
case IASTBinaryExpression.op_binaryXor:
value = v1 ^ v2;
break;
case IASTBinaryExpression.op_binaryOr:
value = v1 | v2;
break;
case IASTBinaryExpression.op_logicalAnd:
value = v1 != 0 && v2 != 0 ? 1l : 0l;
break;
case IASTBinaryExpression.op_logicalOr:
value = v1 != 0 || v2 != 0 ? 1l : 0l;
break;
case IASTBinaryExpression.op_equals:
value = v1 == v2 ? 1l : 0l;
break;
case IASTBinaryExpression.op_notequals:
value = v1 != v2 ? 1l : 0l;
break;
case IASTBinaryExpression.op_max:
value = Math.max(v1, v2);
break;
case IASTBinaryExpression.op_min:
value = Math.min(v1, v2);
break;
}
if(value != null) {
return IntegralValue.create(value);
} else {
return IntegralValue.UNKNOWN;
}
}
public static IValue evaluateUnaryTypeIdExpression(int operator, IType type, IASTNode point) {
IValue val = applyUnaryTypeIdOperator(operator, type, point);
if (isInvalidValue(val))
return IntegralValue.UNKNOWN;
return val;
}
public static IValue evaluateBinaryTypeIdExpression(IASTBinaryTypeIdExpression.Operator operator,
IType type1, IType type2, IASTNode point) {
IValue val = applyBinaryTypeIdOperator(operator, type1, type2, point);
if (isInvalidValue(val))
return IntegralValue.UNKNOWN;
return val;
}
/**
* Computes the canonical representation of the value of the expression.
*/
private static IValue evaluate(IASTExpression exp) {
if (exp == null)
return IntegralValue.UNKNOWN;
if (exp instanceof IASTArraySubscriptExpression) {
return IntegralValue.UNKNOWN;
}
if (exp instanceof IASTBinaryExpression) {
return evaluateBinaryExpression((IASTBinaryExpression) exp);
}
if (exp instanceof IASTCastExpression) { // must be ahead of unary
return evaluate(((IASTCastExpression) exp).getOperand());
}
if (exp instanceof IASTUnaryExpression) {
return evaluateUnaryExpression((IASTUnaryExpression) exp);
}
if (exp instanceof IASTConditionalExpression) {
IASTConditionalExpression cexpr= (IASTConditionalExpression) exp;
IValue v= evaluate(cexpr.getLogicalConditionExpression());
if (isInvalidValue(v) || v.numberValue() == null)
return v;
if (v.numberValue().longValue() == 0) {
return evaluate(cexpr.getNegativeResultExpression());
}
final IASTExpression pe = cexpr.getPositiveResultExpression();
if (pe == null) // gnu-extension allows to omit the positive expression.
return v;
return evaluate(pe);
}
if (exp instanceof IASTIdExpression) {
IBinding b= ((IASTIdExpression) exp).getName().resolvePreBinding();
return evaluateBinding(b);
}
if (exp instanceof IASTLiteralExpression) {
IASTLiteralExpression litEx= (IASTLiteralExpression) exp;
switch (litEx.getKind()) {
case IASTLiteralExpression.lk_false:
case IASTLiteralExpression.lk_nullptr:
return IntegralValue.create(0);
case IASTLiteralExpression.lk_true:
return IntegralValue.create(1);
case IASTLiteralExpression.lk_integer_constant:
try {
return IntegralValue.create(ExpressionEvaluator.getNumber(litEx.getValue()));
} catch (EvalException e) {
return IntegralValue.UNKNOWN;
}
case IASTLiteralExpression.lk_char_constant:
try {
final char[] image= litEx.getValue();
if (image.length > 1 && image[0] == 'L')
return IntegralValue.create(ExpressionEvaluator.getChar(image, 2));
return IntegralValue.create(ExpressionEvaluator.getChar(image, 1));
} catch (EvalException e) {
return IntegralValue.UNKNOWN;
}
case IASTLiteralExpression.lk_float_constant:
return FloatingPointValue.create(litEx.getValue());
case IASTLiteralExpression.lk_string_literal:
return CStringValue.create(litEx.getValue());
}
}
if (exp instanceof IASTTypeIdExpression) {
IASTTypeIdExpression typeIdExp = (IASTTypeIdExpression) exp;
ASTTranslationUnit ast = (ASTTranslationUnit) exp.getTranslationUnit();
final IType type = ast.createType(typeIdExp.getTypeId());
if (type instanceof ICPPUnknownType)
return null;
return applyUnaryTypeIdOperator(typeIdExp.getOperator(), type, exp);
}
if (exp instanceof IASTBinaryTypeIdExpression) {
IASTBinaryTypeIdExpression typeIdExp = (IASTBinaryTypeIdExpression) exp;
ASTTranslationUnit ast = (ASTTranslationUnit) exp.getTranslationUnit();
IType t1= ast.createType(typeIdExp.getOperand1());
IType t2= ast.createType(typeIdExp.getOperand2());
if (CPPTemplates.isDependentType(t1) || CPPTemplates.isDependentType(t2))
return null;
return applyBinaryTypeIdOperator(typeIdExp.getOperator(), t1, t2, exp);
}
if (exp instanceof IASTFunctionCallExpression || exp instanceof ICPPASTSimpleTypeConstructorExpression) {
return null; // The value will be obtained from the evaluation.
}
return IntegralValue.UNKNOWN;
}
/**
* Extract a value off a binding.
*/
private static IValue evaluateBinding(IBinding b) {
if (b instanceof IType) {
return IntegralValue.UNKNOWN;
}
if (b instanceof ICPPTemplateNonTypeParameter) {
return null;
}
if (b instanceof ICPPUnknownBinding) {
return null;
}
IValue value= null;
if (b instanceof IVariable) {
value= ((IVariable) b).getInitialValue();
} else if (b instanceof IEnumerator) {
value= ((IEnumerator) b).getValue();
}
if (isInvalidValue(value)) {
return IntegralValue.UNKNOWN;
}
return value;
}
private static IValue applyUnaryTypeIdOperator(int operator, IType type, IASTNode point) {
switch (operator) {
case op_sizeof:
return getSize(type, point);
case op_alignof:
return getAlignment(type, point);
case op_typeid:
break;
case op_has_nothrow_copy:
break; // TODO(sprigogin): Implement
case op_has_nothrow_constructor:
break; // TODO(sprigogin): Implement
case op_has_trivial_assign:
break; // TODO(sprigogin): Implement
case op_has_trivial_constructor:
break; // TODO(sprigogin): Implement
case op_has_trivial_copy:
return IntegralValue.create(!(type instanceof ICPPClassType) ||
TypeTraits.hasTrivialCopyCtor((ICPPClassType) type, point) ? 1 : 0);
case op_has_trivial_destructor:
break; // TODO(sprigogin): Implement
case op_has_virtual_destructor:
break; // TODO(sprigogin): Implement
case op_is_abstract:
return IntegralValue.create(type instanceof ICPPClassType &&
TypeTraits.isAbstract((ICPPClassType) type, point) ? 1 : 0);
case op_is_class:
return IntegralValue.create(type instanceof ICompositeType &&
((ICompositeType) type).getKey() != ICompositeType.k_union ? 1 : 0);
case op_is_empty:
return IntegralValue.create(TypeTraits.isEmpty(type, point) ? 1 : 0);
case op_is_enum:
return IntegralValue.create(type instanceof IEnumeration ? 1 : 0);
case op_is_final:
return IntegralValue.create(type instanceof ICPPClassType && ((ICPPClassType) type).isFinal() ? 1 : 0);
case op_is_literal_type:
break; // TODO(sprigogin): Implement
case op_is_pod:
return IntegralValue.create(TypeTraits.isPOD(type, point) ? 1 : 0);
case op_is_polymorphic:
return IntegralValue.create(type instanceof ICPPClassType &&
TypeTraits.isPolymorphic((ICPPClassType) type, point) ? 1 : 0);
case op_is_standard_layout:
return IntegralValue.create(TypeTraits.isStandardLayout(type, point) ? 1 : 0);
case op_is_trivial:
return IntegralValue.create(type instanceof ICPPClassType &&
TypeTraits.isTrivial((ICPPClassType) type, point) ? 1 : 0);
case op_is_trivially_copyable:
return IntegralValue.create(TypeTraits.isTriviallyCopyable(type, point) ? 1 : 0);
case op_is_union:
return IntegralValue.create(type instanceof ICompositeType &&
((ICompositeType) type).getKey() == ICompositeType.k_union ? 1 : 0);
case op_typeof:
break;
}
return IntegralValue.UNKNOWN;
}
private static IValue getAlignment(IType type, IASTNode point) {
SizeAndAlignment sizeAndAlignment = SizeofCalculator.getSizeAndAlignment(type, point);
if (sizeAndAlignment == null)
return IntegralValue.UNKNOWN;
return IntegralValue.create(sizeAndAlignment.alignment);
}
private static IValue getSize(IType type, IASTNode point) {
SizeAndAlignment sizeAndAlignment = SizeofCalculator.getSizeAndAlignment(type, point);
if (sizeAndAlignment == null)
return IntegralValue.UNKNOWN;
return IntegralValue.create(sizeAndAlignment.size);
}
private static IValue evaluateUnaryExpression(IASTUnaryExpression exp) {
final int unaryOp= exp.getOperator();
if (unaryOp == IASTUnaryExpression.op_sizeof) {
final IASTExpression operand = exp.getOperand();
if (operand != null) {
IType type = operand.getExpressionType();
if (type instanceof ICPPUnknownType)
return null;
ASTTranslationUnit ast = (ASTTranslationUnit) exp.getTranslationUnit();
SizeofCalculator calculator = ast.getSizeofCalculator();
SizeAndAlignment info = calculator.sizeAndAlignment(type);
if (info != null)
return IntegralValue.create(info.size);
}
return IntegralValue.UNKNOWN;
}
if (unaryOp == IASTUnaryExpression.op_amper || unaryOp == IASTUnaryExpression.op_star ||
unaryOp == IASTUnaryExpression.op_sizeofParameterPack) {
return IntegralValue.UNKNOWN;
}
final IValue value= evaluate(exp.getOperand());
if (isInvalidValue(value))
return value;
if (isDeferredValue(value))
return null; // the value will be computed using the evaluation
return applyUnaryOperator(unaryOp, value);
}
private static IValue applyUnaryOperator(final int unaryOp, final IValue value) {
if(isInvalidValue(value) || value.numberValue() == null) {
return IntegralValue.UNKNOWN;
}
if(!(value instanceof IntegralValue) && !(value instanceof FloatingPointValue)) {
return IntegralValue.UNKNOWN;
}
switch (unaryOp) {
case IASTUnaryExpression.op_bracketedPrimary:
case IASTUnaryExpression.op_plus:
return value;
case IASTUnaryExpression.op_prefixIncr:
case IASTUnaryExpression.op_postFixIncr:
if(value instanceof IntegralValue) {
return IntegralValue.create(value.numberValue().longValue() + 1);
} else {
FloatingPointValue fpv = (FloatingPointValue) value;
return FloatingPointValue.create(fpv.numberValue().doubleValue() + 1);
}
case IASTUnaryExpression.op_prefixDecr:
case IASTUnaryExpression.op_postFixDecr:
if(value instanceof IntegralValue) {
return IntegralValue.create(value.numberValue().longValue() - 1);
} else {
FloatingPointValue fpv = (FloatingPointValue) value;
return FloatingPointValue.create(fpv.numberValue().doubleValue() - 1);
}
case IASTUnaryExpression.op_minus:
if(value instanceof IntegralValue) {
return IntegralValue.create(-value.numberValue().longValue());
} else {
FloatingPointValue fpv = (FloatingPointValue) value;
return FloatingPointValue.create(-fpv.numberValue().doubleValue());
}
case IASTUnaryExpression.op_tilde:
if(value instanceof IntegralValue) {
return IntegralValue.create(~value.numberValue().longValue());
} else {
return IntegralValue.UNKNOWN;
}
case IASTUnaryExpression.op_not:
if(value instanceof IntegralValue) {
Long num = value.numberValue().longValue();
return IntegralValue.create(num == 0 ? 1 : 0);
} else {
FloatingPointValue fpv = (FloatingPointValue) value;
Double num = fpv.numberValue().doubleValue();
return IntegralValue.create(num == 0 ? 1 : 0);
}
}
return IntegralValue.UNKNOWN;
}
private static IValue evaluateBinaryExpression(IASTBinaryExpression exp) {
final int op= exp.getOperator();
// Optimization: if the operator is == or != and the AST nodes
// themselves are equal, we know the answer without having to
// do any evaluation.
if (op == IASTBinaryExpression.op_equals && exp.getOperand1().equals(exp.getOperand2())) {
return IntegralValue.create(true);
}
if (op == IASTBinaryExpression.op_notequals && exp.getOperand1().equals(exp.getOperand2())) {
return IntegralValue.create(false);
}
final IValue o1= evaluate(exp.getOperand1());
if (isInvalidValue(o1))
return o1;
final IValue o2= evaluate(exp.getOperand2());
if (isInvalidValue(o2))
return o2;
if (isDeferredValue(o1) || isDeferredValue(o2))
return null; // the value will be computed using the evaluation
return evaluateBinaryExpression(op, o1, o2);
}
private static IValue applyBinaryTypeIdOperator(IASTBinaryTypeIdExpression.Operator operator,
IType type1, IType type2, IASTNode point) {
switch (operator) {
case __is_base_of:
type1 = SemanticUtil.getNestedType(type1, TDEF);
type2 = SemanticUtil.getNestedType(type2, TDEF);
if (type1 instanceof ICPPClassType && type2 instanceof ICPPClassType &&
(type1.isSameType(type2) ||
ClassTypeHelper.isSubclass((ICPPClassType) type2, (ICPPClassType) type1, point))) {
return IntegralValue.create(1);
}
return IntegralValue.create(0);
case __is_trivially_assignable:
return IntegralValue.UNKNOWN; // TODO: Implement.
}
return IntegralValue.UNKNOWN;
}
private static boolean isInvalidValue(IValue value) {
return value == null || value == IntegralValue.UNKNOWN || value == IntegralValue.ERROR;
}
private static boolean isDeferredValue(IValue value) {
return value instanceof IntegralValue && ((IntegralValue) value).numberValue() == null;
}
}

View file

@ -51,6 +51,7 @@ import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTRangeBasedForStatement;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluationOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
/**
@ -213,7 +214,7 @@ public abstract class VariableReadWriteFlags {
private IType getArgumentType(IASTInitializerClause argument) {
if (argument instanceof ICPPASTInitializerClause) {
return ((ICPPASTInitializerClause) argument).getEvaluation().getType(argument);
return ((ICPPEvaluationOwner) argument).getEvaluation().getType(argument);
} else if (argument instanceof IASTExpression) {
return ((IASTExpression) argument).getExpressionType();
}

View file

@ -23,13 +23,14 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableType;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.ValueFactory;
import org.eclipse.core.runtime.CoreException;
public class CArrayType implements ICArrayType, ITypeContainer, ISerializableType {
IType type;
private IASTExpression sizeExpression;
private IValue value= Value.NOT_INITIALIZED;
private IValue value= IntegralValue.NOT_INITIALIZED;
private boolean isConst;
private boolean isVolatile;
private boolean isRestrict;
@ -130,18 +131,18 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
@Override
public IValue getSize() {
if (value != Value.NOT_INITIALIZED)
if (value != IntegralValue.NOT_INITIALIZED)
return value;
if (sizeExpression == null)
return value= null;
return value= Value.create(sizeExpression);
return value= ValueFactory.create(sizeExpression);
}
@Override
public boolean hasSize() {
return value == Value.NOT_INITIALIZED ? sizeExpression != null : value != null;
return value == IntegralValue.NOT_INITIALIZED ? sizeExpression != null : value != null;
}
@Override
@ -175,9 +176,9 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
val= getSize();
if (val != null) {
firstBytes |= ITypeMarshalBuffer.FLAG6;
Long num= val.numericalValue();
Number num= val.numberValue();
if (num != null) {
nval= num;
nval= num.longValue();
if (nval >= 0) {
firstBytes |= ITypeMarshalBuffer.FLAG7;
}
@ -195,7 +196,7 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
public static IType unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException {
IValue value= null;
if ((firstBytes & ITypeMarshalBuffer.FLAG7) != 0) {
value = Value.create(buffer.getLong());
value = IntegralValue.create(buffer.getLong());
} else if ((firstBytes & ITypeMarshalBuffer.FLAG6) != 0) {
value = buffer.unmarshalValue();
}

View file

@ -24,7 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.ASTEnumerator;
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.IntegralValue;
import org.eclipse.core.runtime.PlatformObject;
/**
@ -37,7 +37,7 @@ public class CEnumerator extends PlatformObject implements IEnumerator {
}
@Override
public IValue getValue() {
return Value.UNKNOWN;
return IntegralValue.UNKNOWN;
}
}
@ -99,7 +99,7 @@ public class CEnumerator extends PlatformObject implements IEnumerator {
if (parent instanceof ASTEnumerator)
return ((ASTEnumerator) parent).getIntegralValue();
return Value.UNKNOWN;
return IntegralValue.UNKNOWN;
}
@Override

View file

@ -33,7 +33,8 @@ import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.ValueFactory;
import org.eclipse.core.runtime.PlatformObject;
/**
@ -160,7 +161,7 @@ public class CVariable extends PlatformObject implements ICInternalBinding, IVar
public IValue getInitialValue() {
Set<CVariable> recursionProtectionSet = fInitialValueInProgress.get();
if (!recursionProtectionSet.add(this)) {
return Value.UNKNOWN;
return IntegralValue.UNKNOWN;
}
try {
if (declarations != null) {
@ -186,11 +187,11 @@ public class CVariable extends PlatformObject implements ICInternalBinding, IVar
final IASTInitializerClause initClause = ((IASTEqualsInitializer) init)
.getInitializerClause();
if (initClause instanceof IASTExpression) {
return Value.create((IASTExpression) initClause);
return ValueFactory.create((IASTExpression) initClause);
}
}
if (init != null)
return Value.UNKNOWN;
return IntegralValue.UNKNOWN;
}
return null;
}

View file

@ -110,7 +110,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.ValueFactory;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.parser.util.ContentAssistMatcherFactory;
@ -1746,9 +1746,9 @@ public class CVisitor extends ASTQueries {
IType expressionType = expression.getExpressionType();
if (expressionType instanceof IBasicType) {
IValue value = Value.create(expression);
if (value != null && value.numericalValue() != null) {
return value.numericalValue().longValue() == 0;
IValue value = ValueFactory.create(expression);
if (value != null && value.numberValue() != null) {
return value.numberValue().longValue() == 0;
}
}

View file

@ -32,7 +32,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTArraySubscriptExpression extends ASTNode
implements ICPPASTArraySubscriptExpression, IASTAmbiguityParent {
implements ICPPASTArraySubscriptExpression, IASTAmbiguityParent, ICPPEvaluationOwner {
private ICPPASTExpression arrayExpression;
private ICPPASTInitializerClause subscriptExp;
private ICPPEvaluation evaluation;
@ -195,7 +195,10 @@ public class CPPASTArraySubscriptExpression extends ASTNode
private ICPPEvaluation computeEvaluation() {
if (arrayExpression == null || subscriptExp == null)
return EvalFixed.INCOMPLETE;
return new EvalBinary(EvalBinary.op_arrayAccess, arrayExpression.getEvaluation(), subscriptExp.getEvaluation(), this);
return new EvalBinary(EvalBinary.op_arrayAccess,
((ICPPEvaluationOwner)arrayExpression).getEvaluation(),
((ICPPEvaluationOwner)subscriptExp).getEvaluation(),
this);
}
@Override

View file

@ -36,7 +36,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpression, IASTAmbiguityParent {
public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpression, IASTAmbiguityParent, ICPPEvaluationOwner {
private int fOperator;
private ICPPASTExpression fOperand1;
private ICPPASTInitializerClause fOperand2;
@ -280,7 +280,9 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
if (fOperand1 == null || fOperand2 == null)
return EvalFixed.INCOMPLETE;
return new EvalBinary(fOperator, fOperand1.getEvaluation(), fOperand2.getEvaluation(), this);
ICPPEvaluation eval1 = ((ICPPEvaluationOwner)fOperand1).getEvaluation();
ICPPEvaluation eval2 = ((ICPPEvaluationOwner)fOperand2).getEvaluation();
return new EvalBinary(fOperator, eval1, eval2, this);
}
@Override

View file

@ -25,7 +25,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinaryTypeId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTBinaryTypeIdExpression extends ASTNode implements ICPPASTExpression, IASTBinaryTypeIdExpression {
public class CPPASTBinaryTypeIdExpression extends ASTNode implements ICPPASTExpression, IASTBinaryTypeIdExpression, ICPPEvaluationOwner {
private Operator fOperator;
private IASTTypeId fOperand1;
private IASTTypeId fOperand2;

View file

@ -13,11 +13,12 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecBreak;
/**
* @author jcamelon
*/
public class CPPASTBreakStatement extends CPPASTAttributeOwner implements IASTBreakStatement {
public class CPPASTBreakStatement extends CPPASTAttributeOwner implements IASTBreakStatement, ICPPExecutionOwner {
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitStatements) {
@ -50,4 +51,9 @@ public class CPPASTBreakStatement extends CPPASTAttributeOwner implements IASTBr
CPPASTBreakStatement copy = new CPPASTBreakStatement();
return copy(copy, style);
}
@Override
public ICPPExecution getExecution() {
return new ExecBreak();
}
}

View file

@ -15,11 +15,12 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecCase;
/**
* @author jcamelon
*/
public class CPPASTCaseStatement extends CPPASTAttributeOwner implements IASTCaseStatement {
public class CPPASTCaseStatement extends CPPASTAttributeOwner implements IASTCaseStatement, ICPPExecutionOwner {
private IASTExpression expression;
public CPPASTCaseStatement() {
@ -89,4 +90,11 @@ public class CPPASTCaseStatement extends CPPASTAttributeOwner implements IASTCas
}
super.replace(child, other);
}
@Override
public ICPPExecution getExecution() {
ICPPEvaluationOwner caseExpr = (ICPPEvaluationOwner)getExpression();
ICPPEvaluation caseExprEval = caseExpr.getEvaluation();
return new ExecCase(caseExprEval);
}
}

View file

@ -33,7 +33,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
/**
* Cast expression for C++
*/
public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpression, IASTAmbiguityParent {
public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpression, IASTAmbiguityParent, ICPPEvaluationOwner {
private int fOperator;
private ICPPASTExpression fOperand;
private IASTTypeId fTypeId;
@ -167,7 +167,7 @@ public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpressi
if (type == null || type instanceof IProblemType)
return EvalFixed.INCOMPLETE;
return new EvalTypeId(type, this, fOperand.getEvaluation());
return new EvalTypeId(type, this, false, ((ICPPEvaluationOwner)fOperand).getEvaluation());
}
@Override

View file

@ -20,11 +20,12 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecCompoundStatement;
/**
* @author jcamelon
*/
public class CPPASTCompoundStatement extends CPPASTAttributeOwner implements ICPPASTCompoundStatement {
public class CPPASTCompoundStatement extends CPPASTAttributeOwner implements ICPPASTCompoundStatement, ICPPExecutionOwner {
private IASTStatement[] statements = new IASTStatement[2];
private ICPPScope scope;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
@ -120,4 +121,9 @@ public class CPPASTCompoundStatement extends CPPASTAttributeOwner implements ICP
}
super.replace(child, other);
}
@Override
public ICPPExecution getExecution() {
return new ExecCompoundStatement(this.statements);
}
}

View file

@ -24,18 +24,21 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalCompound;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalCompoundStatementExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
/**
* Gnu-extension: ({ ... })
*/
public class CPPASTCompoundStatementExpression extends ASTNode
implements IGNUASTCompoundStatementExpression, ICPPASTExpression {
implements IGNUASTCompoundStatementExpression, ICPPASTExpression, ICPPEvaluationOwner {
private IASTCompoundStatement fStatement;
private ICPPEvaluation fEval;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTCompoundStatementExpression() {
}
public CPPASTCompoundStatementExpression(IASTCompoundStatement statement) {
setCompoundStatement(statement);
}
@ -73,11 +76,11 @@ public class CPPASTCompoundStatementExpression extends ASTNode
if (fStatement != null) {
IASTStatement[] statements = fStatement.getStatements();
if (statements.length > 0) {
IASTStatement lastStatement = statements[statements.length - 1];
if (lastStatement instanceof IASTExpressionStatement) {
ICPPASTExpression expression =
(ICPPASTExpression) ((IASTExpressionStatement) lastStatement).getExpression();
fEval= new EvalCompound(expression.getEvaluation(), this);
IASTStatement st = statements[statements.length - 1];
if (st instanceof IASTExpressionStatement) {
IASTExpressionStatement exprStmt = (IASTExpressionStatement)st;
ICPPEvaluationOwner evalOwner = (ICPPEvaluationOwner)exprStmt.getExpression();
fEval= new EvalCompoundStatementExpression(evalOwner.getEvaluation(), this);
}
}
}

View file

@ -29,7 +29,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalConditional;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTConditionalExpression extends ASTNode
implements IASTConditionalExpression, ICPPASTExpression, IASTAmbiguityParent {
implements IASTConditionalExpression, ICPPASTExpression, IASTAmbiguityParent, ICPPEvaluationOwner {
private ICPPASTExpression fCondition;
private ICPPASTExpression fPositive;
private ICPPASTExpression fNegative;
@ -179,9 +179,10 @@ public class CPPASTConditionalExpression extends ASTNode
if (fCondition == null || fNegative == null) {
fEval= EvalFixed.INCOMPLETE;
} else {
final ICPPEvaluation condEval = fCondition.getEvaluation();
final ICPPEvaluation posEval = fPositive == null ? null : fPositive.getEvaluation();
fEval= new EvalConditional(condEval, posEval, fNegative.getEvaluation(),
final ICPPEvaluation condEval = ((ICPPEvaluationOwner)fCondition).getEvaluation();
final ICPPEvaluation posEval = fPositive == null ? null : ((ICPPEvaluationOwner)fPositive).getEvaluation();
final ICPPEvaluation negEval = ((ICPPEvaluationOwner)fNegative).getEvaluation();
fEval= new EvalConditional(condEval, posEval, negEval,
isThrowExpression(fPositive), isThrowExpression(fNegative), this);
}
}

View file

@ -13,11 +13,12 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTContinueStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecContinue;
/**
* @author jcamelon
*/
public class CPPASTContinueStatement extends CPPASTAttributeOwner implements IASTContinueStatement {
public class CPPASTContinueStatement extends CPPASTAttributeOwner implements IASTContinueStatement, ICPPExecutionOwner {
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitStatements) {
@ -50,4 +51,9 @@ public class CPPASTContinueStatement extends CPPASTAttributeOwner implements IAS
CPPASTContinueStatement copy = new CPPASTContinueStatement();
return copy(copy, style);
}
@Override
public ICPPExecution getExecution() {
return new ExecContinue();
}
}

View file

@ -20,12 +20,13 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecDeclarationStatement;
/**
* @author jcamelon
*/
public class CPPASTDeclarationStatement extends ASTNode
implements IASTDeclarationStatement, IASTAmbiguityParent {
implements IASTDeclarationStatement, IASTAmbiguityParent, ICPPExecutionOwner {
private IASTDeclaration declaration;
public CPPASTDeclarationStatement() {
@ -116,4 +117,13 @@ public class CPPASTDeclarationStatement extends ASTNode
// Declaration statements don't have attributes.
throw new UnsupportedOperationException();
}
@Override
public ICPPExecution getExecution() {
if(declaration instanceof ICPPExecutionOwner) {
ICPPExecutionOwner execOwner = (ICPPExecutionOwner)declaration;
return new ExecDeclarationStatement(execOwner.getExecution());
}
return null;
}
}

View file

@ -32,18 +32,22 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
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.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecIncomplete;
/**
* C++ specific declarator.
*/
public class CPPASTDeclarator extends CPPASTAttributeOwner implements ICPPASTDeclarator,
IASTImplicitNameOwner {
IASTImplicitNameOwner, ICPPExecutionOwner {
private IASTInitializer initializer;
private IASTName name;
private IASTImplicitName[] implicitNames;
@ -303,4 +307,18 @@ public class CPPASTDeclarator extends CPPASTAttributeOwner implements ICPPASTDec
}
super.replace(child, other);
}
@Override
public ICPPExecution getExecution() {
final ICPPBinding binding = (ICPPBinding)getName().resolveBinding();
ICPPEvaluation initializerEval = null;
if(binding instanceof CPPVariable) {
CPPVariable variable = (CPPVariable)binding;
initializerEval = variable.getInitializerEvaluation();
}
if(initializerEval == EvalFixed.INCOMPLETE) {
return ExecIncomplete.INSTANCE;
}
return new ExecDeclarator(binding, initializerEval);
}
}

View file

@ -57,7 +57,7 @@ public class CPPASTDecltypeSpecifier extends ASTNode
StringBuilder buffer = new StringBuilder();
buffer.append(Keywords.cDECLTYPE);
buffer.append(Keywords.cpLPAREN);
buffer.append(fDecltypeExpression.getEvaluation().getSignature());
buffer.append(((ICPPEvaluationOwner)fDecltypeExpression).getEvaluation().getSignature());
buffer.append(Keywords.cpRPAREN);
final int len = buffer.length();
fSignature = new char[len];

View file

@ -13,11 +13,12 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecDefault;
/**
* @author jcamelon
*/
public class CPPASTDefaultStatement extends CPPASTAttributeOwner implements IASTDefaultStatement {
public class CPPASTDefaultStatement extends CPPASTAttributeOwner implements IASTDefaultStatement, ICPPExecutionOwner {
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitStatements) {
@ -50,4 +51,9 @@ public class CPPASTDefaultStatement extends CPPASTAttributeOwner implements IAST
CPPASTDefaultStatement copy = new CPPASTDefaultStatement();
return copy(copy, style);
}
@Override
public ICPPExecution getExecution() {
return new ExecDefault();
}
}

View file

@ -27,14 +27,14 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpression, IASTAmbiguityParent {
private static final ICPPEvaluation EVALUATION = new EvalFixed(CPPSemantics.VOID_TYPE, PRVALUE, Value.UNKNOWN);
public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpression, IASTAmbiguityParent, ICPPEvaluationOwner {
private static final ICPPEvaluation EVALUATION = new EvalFixed(CPPSemantics.VOID_TYPE, PRVALUE, IntegralValue.UNKNOWN);
private IASTExpression operand;
private boolean isGlobal;

View file

@ -23,7 +23,7 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
* Implementation for designated initializers.
*/
public class CPPASTDesignatedInitializer extends ASTNode
implements ICPPASTDesignatedInitializer, IASTAmbiguityParent {
implements ICPPASTDesignatedInitializer, IASTAmbiguityParent, ICPPEvaluationOwner {
private ICPPASTInitializerClause rhs;
private ICPPASTDesignator[] designators = ICPPASTDesignator.EMPTY_ARRAY;
private int designatorsPos;
@ -83,7 +83,7 @@ public class CPPASTDesignatedInitializer extends ASTNode
@Override
public ICPPEvaluation getEvaluation() {
return rhs.getEvaluation();
return ((ICPPEvaluationOwner)rhs).getEvaluation();
}
@Override

View file

@ -16,11 +16,13 @@ import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecDo;
/**
* @author jcamelon
*/
public class CPPASTDoStatement extends CPPASTAttributeOwner implements IASTDoStatement {
public class CPPASTDoStatement extends CPPASTAttributeOwner implements IASTDoStatement, ICPPExecutionOwner {
private IASTStatement body;
private IASTExpression condition;
@ -115,4 +117,12 @@ public class CPPASTDoStatement extends CPPASTAttributeOwner implements IASTDoSta
}
super.replace(child, other);
}
@Override
public ICPPExecution getExecution() {
ICPPEvaluationOwner conditionExpr = (ICPPEvaluationOwner)getCondition();
ICPPEvaluation conditionEval = conditionExpr.getEvaluation();
ICPPExecution bodyExec = EvalUtil.getExecutionFromStatement(getBody());
return new ExecDo(conditionEval, bodyExec);
}
}

View file

@ -21,7 +21,6 @@ import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
@ -31,7 +30,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallColl
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalComma;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionList, IASTAmbiguityParent {
public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionList, IASTAmbiguityParent, ICPPEvaluationOwner {
private IASTExpression[] expressions = new IASTExpression[2];
/**
@ -188,7 +187,7 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
ICPPEvaluation[] evals= new ICPPEvaluation[exprs.length];
for (int i = 0; i < evals.length; i++) {
evals[i]= ((ICPPASTExpression) exprs[i]).getEvaluation();
evals[i]= ((ICPPEvaluationOwner) exprs[i]).getEvaluation();
}
return new EvalComma(evals, this);
}

View file

@ -15,11 +15,12 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecExpressionStatement;
/**
* @author jcamelon
*/
public class CPPASTExpressionStatement extends CPPASTAttributeOwner implements IASTExpressionStatement {
public class CPPASTExpressionStatement extends CPPASTAttributeOwner implements IASTExpressionStatement, ICPPExecutionOwner {
private IASTExpression expression;
public CPPASTExpressionStatement() {
@ -89,4 +90,11 @@ public class CPPASTExpressionStatement extends CPPASTAttributeOwner implements I
}
super.replace(child, other);
}
@Override
public ICPPExecution getExecution() {
ICPPEvaluationOwner evalOwner = (ICPPEvaluationOwner)getExpression();
ICPPEvaluation exprEval = evalOwner.getEvaluation();
return new ExecExpressionStatement(exprEval);
}
}

View file

@ -15,6 +15,7 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ALLCVQ;
import java.util.ArrayList;
import java.util.Arrays;
@ -36,7 +37,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
@ -50,20 +53,21 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallColl
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalMemberAccess;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
public class CPPASTFieldReference extends ASTNode
implements ICPPASTFieldReference, IASTAmbiguityParent, ICPPASTCompletionContext {
private boolean fIsTemplate;
private boolean fIsDeref;
private ICPPASTExpression fOwner;
private IASTName fName;
private IASTImplicitName[] fImplicitNames;
implements ICPPASTFieldReference, IASTAmbiguityParent, ICPPASTCompletionContext, ICPPEvaluationOwner {
private boolean fIsTemplate;
private boolean fIsDeref;
private ICPPASTExpression fOwner;
private IASTName fName;
private IASTImplicitName[] fImplicitNames;
private ICPPEvaluation fEvaluation;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTFieldReference() {
public CPPASTFieldReference() {
}
public CPPASTFieldReference(IASTName name, IASTExpression owner) {
setFieldName(name);
setFieldOwner(owner);
@ -86,57 +90,57 @@ public class CPPASTFieldReference extends ASTNode
@Override
public boolean isTemplate() {
return fIsTemplate;
}
return fIsTemplate;
}
@Override
@Override
public void setIsTemplate(boolean value) {
assertNotFrozen();
fIsTemplate = value;
}
assertNotFrozen();
fIsTemplate = value;
}
@Override
@Override
public ICPPASTExpression getFieldOwner() {
return fOwner;
}
return fOwner;
}
@Override
@Override
public void setFieldOwner(IASTExpression expression) {
assertNotFrozen();
fOwner = (ICPPASTExpression) expression;
if (expression != null) {
assertNotFrozen();
fOwner = (ICPPASTExpression) expression;
if (expression != null) {
expression.setParent(this);
expression.setPropertyInParent(FIELD_OWNER);
}
}
}
@Override
@Override
public IASTName getFieldName() {
return fName;
}
return fName;
}
@Override
@Override
public void setFieldName(IASTName name) {
assertNotFrozen();
this.fName = name;
if (name != null) {
assertNotFrozen();
this.fName = name;
if (name != null) {
name.setParent(this);
name.setPropertyInParent(FIELD_NAME);
}
}
}
@Override
@Override
public boolean isPointerDereference() {
return fIsDeref;
}
return fIsDeref;
}
@Override
@Override
public void setIsPointerDereference(boolean value) {
assertNotFrozen();
fIsDeref = value;
}
@Override
assertNotFrozen();
fIsDeref = value;
}
@Override
public IASTImplicitName[] getImplicitNames() {
if (fImplicitNames == null) {
if (!fIsDeref)
@ -147,24 +151,25 @@ public class CPPASTFieldReference extends ASTNode
EvalMemberAccess.getFieldOwnerType(fOwner.getExpressionType(), fIsDeref, this, functionBindings, false);
if (functionBindings.isEmpty())
return fImplicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
// Create a name to wrap each binding
fImplicitNames = new IASTImplicitName[functionBindings.size()];
int i= -1;
int i = -1;
for (ICPPFunction op : functionBindings) {
if (op != null && !(op instanceof CPPImplicitFunction)) {
CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.ARROW, this);
CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.ARROW,
this);
operatorName.setBinding(op);
operatorName.computeOperatorOffsets(fOwner, true);
fImplicitNames[++i] = operatorName;
}
}
fImplicitNames= ArrayUtil.trimAt(IASTImplicitName.class, fImplicitNames, i);
fImplicitNames = ArrayUtil.trimAt(IASTImplicitName.class, fImplicitNames, i);
}
return fImplicitNames;
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
@ -174,41 +179,47 @@ public class CPPASTFieldReference extends ASTNode
return fImplicitDestructorNames;
}
@Override
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) {
switch (action.visit(this)) {
case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP: return true;
default: break;
}
if (action.shouldVisitExpressions) {
switch (action.visit(this)) {
case ASTVisitor.PROCESS_ABORT:
return false;
case ASTVisitor.PROCESS_SKIP:
return true;
default:
break;
}
}
if (fOwner != null && !fOwner.accept(action))
return false;
if (action.shouldVisitImplicitNames) {
for (IASTImplicitName name : getImplicitNames()) {
if (!name.accept(action))
return false;
}
}
if (fName != null && !fName.accept(action))
return false;
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (fOwner != null && !fOwner.accept(action))
return false;
if (action.shouldVisitExpressions) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP: return true;
default: break;
}
if (action.shouldVisitImplicitNames) {
for (IASTImplicitName name : getImplicitNames()) {
if (!name.accept(action))
return false;
}
}
return true;
}
if (fName != null && !fName.accept(action))
return false;
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitExpressions) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT:
return false;
case ASTVisitor.PROCESS_SKIP:
return true;
default:
break;
}
}
return true;
}
@Override
public int getRoleForName(IASTName n) {
@ -217,14 +228,14 @@ public class CPPASTFieldReference extends ASTNode
return r_unclear;
}
@Override
@Override
public void replace(IASTNode child, IASTNode other) {
if (child == fOwner) {
other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent());
fOwner = (ICPPASTExpression) other;
}
}
if (child == fOwner) {
other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent());
fOwner = (ICPPASTExpression) other;
}
}
@Override
public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) {
@ -237,39 +248,40 @@ public class CPPASTFieldReference extends ASTNode
if (i != j)
bindings[j] = binding;
j++;
}
}
}
if (j < bindings.length)
return Arrays.copyOfRange(bindings, 0, j);
return bindings;
}
@Override
public IBinding[] findBindings(IASTName n, boolean isPrefix) {
return findBindings(n, isPrefix, null);
}
/**
* For a pointer dereference expression e1->e2, return the type that e1 ultimately evaluates to
* after chaining overloaded class member access operators <code>operator->()</code> calls.
*/
@Override
/**
* For a pointer dereference expression e1->e2, return the type that e1
* ultimately evaluates to after chaining overloaded class member access
* operators <code>operator->()</code> calls.
*/
@Override
public IType getFieldOwnerType() {
return EvalMemberAccess.getFieldOwnerType(fOwner.getExpressionType(), fIsDeref, this, null, true);
}
return EvalMemberAccess.getFieldOwnerType(fOwner.getExpressionType(), fIsDeref, this, null, true);
}
@Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
fEvaluation= createEvaluation();
fEvaluation = createEvaluation();
}
return fEvaluation;
}
private ICPPEvaluation createEvaluation() {
ICPPEvaluation ownerEval = fOwner.getEvaluation();
ICPPEvaluation ownerEval = ((ICPPEvaluationOwner)fOwner).getEvaluation();
if (!ownerEval.isTypeDependent()) {
IType ownerType= EvalMemberAccess.getFieldOwnerType(ownerEval.getType(this), fIsDeref, this, null, false);
if (ownerType != null) {
@ -277,10 +289,11 @@ public class CPPASTFieldReference extends ASTNode
if (binding instanceof CPPFunctionSet)
binding= fName.resolveBinding();
if (binding instanceof IProblemBinding || binding instanceof IType || binding instanceof ICPPConstructor)
if (binding instanceof IProblemBinding || binding instanceof IType || binding instanceof ICPPConstructor) {
return EvalFixed.INCOMPLETE;
}
return new EvalMemberAccess(ownerType, ownerEval.getValueCategory(this), binding, fIsDeref, this);
return new EvalMemberAccess(ownerType, ownerEval.getValueCategory(this), binding, ownerEval, fIsDeref, this);
}
}
@ -306,12 +319,31 @@ public class CPPASTFieldReference extends ASTNode
}
return new EvalID(ownerEval, qualifier, fName.getSimpleID(), false, true, fIsDeref, args, this);
}
public static int getFieldPosition(ICPPField field) {
final ICPPClassType ownerType = field.getClassOwner();
final ICPPClassType[] baseClasses = ClassTypeHelper.getAllBases(ownerType, null);
int baseFields = 0;
for(ICPPClassType baseClass : baseClasses) {
baseFields += ClassTypeHelper.getDeclaredFields(baseClass, null).length;
}
return baseFields + field.getFieldPosition();
}
public static int getFieldPosition(IBinding binding, IType ownerType) {
final IType nestedType = SemanticUtil.getNestedType(ownerType, ALLCVQ);
if(nestedType instanceof ICPPClassType && binding instanceof ICPPField) {
final ICPPField field = (ICPPField)binding;
return getFieldPosition(field);
}
return -1;
}
@Override
public IType getExpressionType() {
return getEvaluation().getType(this);
}
@Override
public boolean isLValue() {
return getValueCategory() == LVALUE;

View file

@ -22,11 +22,14 @@ import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecFor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecSimpleDeclaration;
/**
* For statement in C++
*/
public class CPPASTForStatement extends CPPASTAttributeOwner implements ICPPASTForStatement {
public class CPPASTForStatement extends CPPASTAttributeOwner implements ICPPASTForStatement, ICPPExecutionOwner {
private IScope fScope;
private IASTStatement fInit;
@ -222,4 +225,17 @@ public class CPPASTForStatement extends CPPASTAttributeOwner implements ICPPASTF
public IASTDeclaration getConditionDeclaration() {
return fCondDeclaration;
}
@Override
public ICPPExecution getExecution() {
ICPPExecution initializerExec = EvalUtil.getExecutionFromStatement(getInitializerStatement());
ICPPEvaluationOwner conditionExpr = (ICPPEvaluationOwner)getConditionExpression();
ICPPExecutionOwner conditionDecl = (ICPPExecutionOwner)getConditionDeclaration();
ICPPEvaluation conditionExprEval = conditionExpr != null ? conditionExpr.getEvaluation() : null;
ExecSimpleDeclaration conditionDeclExec = conditionDecl != null ? (ExecSimpleDeclaration)conditionDecl.getExecution() : null;
ICPPEvaluationOwner iterationExpr = (ICPPEvaluationOwner)getIterationExpression();
ICPPEvaluation iterationEval = iterationExpr != null ? iterationExpr.getEvaluation() : null;
ICPPExecution bodyExec = EvalUtil.getExecutionFromStatement(getBody());
return new ExecFor(initializerExec, conditionExprEval, conditionDeclExec, iterationEval, bodyExec);
}
}

View file

@ -32,8 +32,8 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
@ -49,7 +49,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.LookupData;
public class CPPASTFunctionCallExpression extends ASTNode
implements ICPPASTFunctionCallExpression, IASTAmbiguityParent {
implements ICPPASTFunctionCallExpression, IASTAmbiguityParent, ICPPEvaluationOwner {
private ICPPASTExpression fFunctionName;
private IASTInitializerClause[] fArguments;
@ -281,11 +281,17 @@ public class CPPASTFunctionCallExpression extends ASTNode
return conversion;
ICPPEvaluation[] args= new ICPPEvaluation[fArguments.length + 1];
args[0]= fFunctionName.getEvaluation();
args[0]= ((ICPPEvaluationOwner)fFunctionName).getEvaluation();
for (int i = 1; i < args.length; i++) {
args[i]= ((ICPPASTInitializerClause) fArguments[i - 1]).getEvaluation();
args[i]= ((ICPPEvaluationOwner) fArguments[i - 1]).getEvaluation();
}
return new EvalFunctionCall(args, this);
ICPPEvaluation fieldOwnerEval = null;
if (fFunctionName instanceof ICPPASTFieldReference) {
ICPPASTFieldReference fieldRef = (ICPPASTFieldReference)fFunctionName;
ICPPEvaluationOwner fieldOwner = (ICPPEvaluationOwner)fieldRef.getFieldOwner();
fieldOwnerEval = fieldOwner.getEvaluation();
}
return new EvalFunctionCall(args, fieldOwnerEval, this);
}
private ICPPEvaluation checkForExplicitTypeConversion() {
@ -295,9 +301,10 @@ public class CPPASTFunctionCallExpression extends ASTNode
if (b instanceof IType) {
ICPPEvaluation[] args= new ICPPEvaluation[fArguments.length];
for (int i = 0; i < args.length; i++) {
args[i]= ((ICPPASTInitializerClause) fArguments[i]).getEvaluation();
args[i]= ((ICPPEvaluationOwner) fArguments[i]).getEvaluation();
}
return new EvalTypeId((IType) b, this, args);
return new EvalTypeId((IType) b, this, false, args);
}
}
return null;

View file

@ -33,7 +33,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.FunctionSetType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
public class CPPASTIdExpression extends ASTNode
implements IASTIdExpression, ICPPASTExpression, ICPPASTCompletionContext {
implements IASTIdExpression, ICPPASTExpression, ICPPASTCompletionContext, ICPPEvaluationOwner {
private IASTName fName;
private ICPPEvaluation fEvaluation;
private IASTImplicitDestructorName[] fImplicitDestructorNames;

View file

@ -20,11 +20,14 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecIf;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecSimpleDeclaration;
/**
* If statement in C++
*/
public class CPPASTIfStatement extends CPPASTAttributeOwner implements ICPPASTIfStatement {
public class CPPASTIfStatement extends CPPASTAttributeOwner implements ICPPASTIfStatement, ICPPExecutionOwner {
private IASTExpression condition;
private IASTStatement thenClause;
private IASTStatement elseClause;
@ -214,4 +217,15 @@ public class CPPASTIfStatement extends CPPASTAttributeOwner implements ICPPASTIf
scope = new CPPBlockScope(this);
return scope;
}
}
@Override
public ICPPExecution getExecution() {
ICPPEvaluationOwner conditionExpr = (ICPPEvaluationOwner)getConditionExpression();
ICPPExecutionOwner conditionDecl = (ICPPExecutionOwner)getConditionDeclaration();
ICPPEvaluation conditionExprEval = conditionExpr != null ? conditionExpr.getEvaluation() : null;
ExecSimpleDeclaration conditionDeclExec = conditionDecl != null ? (ExecSimpleDeclaration)conditionDecl.getExecution() : null;
ICPPExecution thenClauseExec = EvalUtil.getExecutionFromStatement(getThenClause());
ICPPExecution elseClauseExec = getElseClause() != null ? EvalUtil.getExecutionFromStatement(getElseClause()) : null;
return new ExecIf(conditionExprEval, conditionDeclExec, thenClauseExec, elseClauseExec);
}
}

View file

@ -27,7 +27,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalInitList;
/**
* e.g.: int a[]= {1,2,3};
*/
public class CPPASTInitializerList extends ASTNode implements ICPPASTInitializerList, IASTAmbiguityParent {
public class CPPASTInitializerList extends ASTNode implements ICPPASTInitializerList, IASTAmbiguityParent, ICPPEvaluationOwner {
private static final ICPPASTInitializerClause[] NO_CLAUSES = {};
private ICPPASTInitializerClause[] initializers;
private int initializersPos= -1;
@ -166,7 +166,8 @@ public class CPPASTInitializerList extends ASTNode implements ICPPASTInitializer
final ICPPASTInitializerClause[] clauses = getClauses();
ICPPEvaluation[] evals= new ICPPEvaluation[clauses.length];
for (int i = 0; i < evals.length; i++) {
evals[i]= clauses[i].getEvaluation();
ICPPEvaluationOwner clause = (ICPPEvaluationOwner)clauses[i];
evals[i]= clause.getEvaluation();
}
return new EvalInitList(evals, this);
}

View file

@ -23,13 +23,13 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
/**
* Implementation for lambda expressions.
*/
public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpression {
public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpression, ICPPEvaluationOwner {
private static final ICPPASTCapture[] NO_CAPTURES = {};
private CaptureDefault fCaptureDefault;
@ -208,7 +208,7 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
@Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
fEvaluation= new EvalFixed(new CPPClosureType(this), PRVALUE, Value.UNKNOWN);
fEvaluation= new EvalFixed(new CPPClosureType(this), PRVALUE, IntegralValue.UNKNOWN);
}
return fEvaluation;
}

View file

@ -23,30 +23,36 @@ import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.CStringValue;
import org.eclipse.cdt.internal.core.dom.parser.FloatingPointValue;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFunctionCall;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException;
/**
* Represents a C++ literal.
*/
public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralExpression {
private static final EvalFixed EVAL_TRUE = new EvalFixed(CPPBasicType.BOOLEAN, PRVALUE, Value.create(1));
private static final EvalFixed EVAL_FALSE = new EvalFixed(CPPBasicType.BOOLEAN, PRVALUE, Value.create(0));
private static final EvalFixed EVAL_NULL_PTR = new EvalFixed(CPPBasicType.NULL_PTR, PRVALUE, Value.create(0));
public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralExpression, ICPPEvaluationOwner {
private static final EvalFixed EVAL_TRUE = new EvalFixed(CPPBasicType.BOOLEAN, PRVALUE, IntegralValue.create(true));
private static final EvalFixed EVAL_FALSE = new EvalFixed(CPPBasicType.BOOLEAN, PRVALUE, IntegralValue.create(false));
private static final EvalFixed EVAL_NULL_PTR = new EvalFixed(CPPBasicType.NULL_PTR, PRVALUE, IntegralValue.create(0));
public static final CPPASTLiteralExpression INT_ZERO =
new CPPASTLiteralExpression(lk_integer_constant, new char[] {'0'});
@ -224,7 +230,7 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
}
private int computeStringLiteralSize() {
int start = 0, end = fValue.length - 1;
int start = 0, end = fValue.length - 1 - getSuffix().length;
boolean isRaw = false;
// Skip past a prefix affecting the character type.
@ -289,7 +295,7 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
if (fStringLiteralSize == -1) {
fStringLiteralSize = computeStringLiteralSize();
}
return Value.create(fStringLiteralSize);
return IntegralValue.create(fStringLiteralSize);
}
private IType getStringType() {
@ -643,49 +649,99 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
return fEvaluation;
}
private ICPPEvaluation createEvaluation() {
private ICPPEvaluation createLiteralEvaluation() {
switch (fKind) {
case lk_this: {
IScope scope = CPPVisitor.getContainingScope(this);
IType type= CPPVisitor.getImpliedObjectType(scope);
if (type == null)
return EvalFixed.INCOMPLETE;
return new EvalFixed(new CPPPointerType(type), PRVALUE, Value.UNKNOWN);
}
case lk_true:
return EVAL_TRUE;
case lk_false:
return EVAL_FALSE;
case lk_char_constant:
return new EvalFixed(getCharType(), PRVALUE, createCharValue());
case lk_float_constant:
return new EvalFixed(classifyTypeOfFloatLiteral(), PRVALUE, Value.UNKNOWN);
case lk_integer_constant:
return new EvalFixed(classifyTypeOfIntLiteral(), PRVALUE, createIntValue());
case lk_string_literal:
return new EvalFixed(getStringType(), LVALUE, Value.UNKNOWN);
case lk_nullptr:
return EVAL_NULL_PTR;
case lk_this: {
IScope scope = CPPVisitor.getContainingScope(this);
IType type= CPPVisitor.getImpliedObjectType(scope);
if (type == null)
return EvalFixed.INCOMPLETE;
return new EvalFixed(new CPPPointerType(type), PRVALUE, IntegralValue.THIS);
}
case lk_true:
return EVAL_TRUE;
case lk_false:
return EVAL_FALSE;
case lk_char_constant:
return new EvalFixed(getCharType(), PRVALUE, createCharValue());
case lk_float_constant:
return new EvalFixed(classifyTypeOfFloatLiteral(), PRVALUE, FloatingPointValue.create(getValue()));
case lk_integer_constant:
return new EvalFixed(classifyTypeOfIntLiteral(), PRVALUE, createIntValue());
case lk_string_literal:
return new EvalFixed(getStringType(), LVALUE, CStringValue.create(getValue()));
case lk_nullptr:
return EVAL_NULL_PTR;
}
return EvalFixed.INCOMPLETE;
return EvalFixed.INCOMPLETE;
}
private ICPPEvaluation createEvaluation() {
ICPPEvaluation literalEval = createLiteralEvaluation();
IBinding udlOperator = getUserDefinedLiteralOperator();
if(udlOperator != null && literalEval != EvalFixed.INCOMPLETE) {
if(udlOperator instanceof ICPPFunction) {
ICPPFunction udlOpFunction = (ICPPFunction)udlOperator;
EvalBinding op = new EvalBinding(udlOpFunction, udlOpFunction.getType(), this);
ICPPEvaluation[] args = null;
ICPPParameter params[] = udlOpFunction.getParameters();
int paramCount = params.length;
if(paramCount == 0) {
// TODO: Support literal operator templates.
args = new ICPPEvaluation[]{op};
} else if(paramCount == 1) {
//this means that we need to fall back to the raw literal operator
if(params[0].getType() instanceof IPointerType) {
char numValue[] = getValue();
int numLen = numValue.length;
char strValue[] = new char[numLen + 2];
strValue[0] = '"';
strValue[numLen + 1] = '"';
System.arraycopy(numValue, 0, strValue, 1, numLen);
IType type = new CPPBasicType(Kind.eChar, 0, this);
type = new CPPQualifierType(type, true, false);
type = new CPPArrayType(type, IntegralValue.create(numLen+1));
EvalFixed strEval = new EvalFixed(type, LVALUE, CStringValue.create(strValue));
args = new ICPPEvaluation[]{op, strEval};
} else {
args = new ICPPEvaluation[]{op, literalEval};
}
} else if(paramCount == 2) {
IValue sizeValue = IntegralValue.create(computeStringLiteralSize() - 1);
EvalFixed literalSizeEval = new EvalFixed(CPPBasicType.INT, PRVALUE, sizeValue);
args = new ICPPEvaluation[]{op, literalEval, literalSizeEval};
}
return new EvalFunctionCall(args, null, this);
}
}
//has a user-defined literal suffix but didn't find a udl operator function => error
if(getSuffix().length > 0 && (getKind() == lk_string_literal || !fIsCompilerSuffix)) {
return EvalFixed.INCOMPLETE;
}
return literalEval;
}
private IValue createCharValue() {
try {
final char[] image= getValue();
if (image.length > 1 && image[0] == 'L')
return Value.create(ExpressionEvaluator.getChar(image, 2));
return Value.create(ExpressionEvaluator.getChar(image, 1));
return IntegralValue.create(ExpressionEvaluator.getChar(image, 2));
return IntegralValue.create(ExpressionEvaluator.getChar(image, 1));
} catch (EvalException e) {
return Value.UNKNOWN;
return IntegralValue.UNKNOWN;
}
}
private IValue createIntValue() {
try {
return Value.create(ExpressionEvaluator.getNumber(getValue()));
return IntegralValue.create(ExpressionEvaluator.getNumber(getValue()));
} catch (EvalException e) {
return Value.UNKNOWN;
return IntegralValue.UNKNOWN;
}
}

View file

@ -18,7 +18,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTNaryTypeIdExpression extends ASTNode implements ICPPASTNaryTypeIdExpression {
public class CPPASTNaryTypeIdExpression extends ASTNode implements ICPPASTNaryTypeIdExpression, ICPPEvaluationOwner {
private Operator fOperator;
private ICPPASTTypeId[] fOperands;

View file

@ -32,7 +32,6 @@ import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
@ -49,7 +48,7 @@ import org.eclipse.core.runtime.Assert;
/**
* Represents a new expression [expr.new].
*/
public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression, IASTAmbiguityParent {
public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression, IASTAmbiguityParent, ICPPEvaluationOwner {
private IASTInitializerClause[] fPlacement;
private IASTTypeId fTypeId;
private IASTInitializer fInitializer;
@ -294,10 +293,10 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression
IASTInitializerClause[] args = ((ICPPASTConstructorInitializer) fInitializer).getArguments();
arguments= new ICPPEvaluation[args.length];
for (int i = 0; i < arguments.length; i++) {
arguments[i] = ((ICPPASTInitializerClause) args[i]).getEvaluation();
arguments[i] = ((ICPPEvaluationOwner) args[i]).getEvaluation();
}
}
fEvaluation = EvalTypeId.createForNewExpression(t, this, arguments);
fEvaluation = EvalTypeId.createForNewExpression(t, this, false, arguments);
}
return fEvaluation;
}

View file

@ -17,7 +17,6 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
@ -26,7 +25,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalParameterPack;
/**
* Implementation of pack expansion expression.
*/
public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPackExpansionExpression, IASTAmbiguityParent {
public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPackExpansionExpression, IASTAmbiguityParent, ICPPEvaluationOwner {
private IASTExpression fPattern;
private ICPPEvaluation fEvaluation;
@ -64,7 +63,7 @@ public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPac
@Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
fEvaluation = new EvalParameterPack(((ICPPASTExpression) fPattern).getEvaluation(), this);
fEvaluation = new EvalParameterPack(((ICPPEvaluationOwner) fPattern).getEvaluation(), this);
}
return fEvaluation;
}

View file

@ -22,7 +22,7 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTProblemExpression, ICPPASTExpression {
public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTProblemExpression, ICPPASTExpression, ICPPEvaluationOwner {
public CPPASTProblemExpression() {
super();

View file

@ -23,20 +23,25 @@ import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTRangeBasedForStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecRangeBasedFor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecSimpleDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
/**
* Range based 'for' loop in C++.
*/
public class CPPASTRangeBasedForStatement extends CPPASTAttributeOwner implements ICPPASTRangeBasedForStatement {
public class CPPASTRangeBasedForStatement extends CPPASTAttributeOwner implements ICPPASTRangeBasedForStatement, ICPPExecutionOwner {
private IScope fScope;
private IASTDeclaration fDeclaration;
private IASTInitializerClause fInitClause;
@ -230,4 +235,23 @@ public class CPPASTRangeBasedForStatement extends CPPASTAttributeOwner implement
}
super.replace(child, other);
}
@Override
public ICPPExecution getExecution() {
ExecSimpleDeclaration declarationExec = (ExecSimpleDeclaration)((ICPPExecutionOwner)fDeclaration).getExecution();
ICPPEvaluation initClauseEval = ((ICPPEvaluationOwner)fInitClause).getEvaluation();
ICPPExecution bodyExec = EvalUtil.getExecutionFromStatement(fBody);
IASTImplicitName[] implicitNames = getImplicitNames();
ICPPFunction begin = null;
ICPPFunction end = null;
if(implicitNames.length == 2) {
IBinding beginBinding = implicitNames[0].resolveBinding();
IBinding endBinding = implicitNames[1].resolveBinding();
if (beginBinding instanceof ICPPFunction && endBinding instanceof ICPPFunction) {
begin = (ICPPFunction)beginBinding;
end = (ICPPFunction)endBinding;
}
}
return new ExecRangeBasedFor(declarationExec, initClauseEval, begin, end, bodyExec);
}
}

View file

@ -17,8 +17,10 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecIncomplete;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecReturn;
public class CPPASTReturnStatement extends CPPASTAttributeOwner implements IASTReturnStatement {
public class CPPASTReturnStatement extends CPPASTAttributeOwner implements IASTReturnStatement, ICPPExecutionOwner {
private IASTInitializerClause retValue;
public CPPASTReturnStatement() {
@ -101,4 +103,13 @@ public class CPPASTReturnStatement extends CPPASTAttributeOwner implements IASTR
}
super.replace(child, other);
}
@Override
public ICPPExecution getExecution() {
if(retValue instanceof ICPPEvaluationOwner) {
ICPPEvaluationOwner evalOwner = (ICPPEvaluationOwner)retValue;
return new ExecReturn(evalOwner.getEvaluation());
}
return ExecIncomplete.INSTANCE;
}
}

View file

@ -18,11 +18,12 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecSimpleDeclaration;
/**
* @author jcamelon
*/
public class CPPASTSimpleDeclaration extends CPPASTAttributeOwner implements IASTSimpleDeclaration {
public class CPPASTSimpleDeclaration extends CPPASTAttributeOwner implements IASTSimpleDeclaration, ICPPExecutionOwner {
private IASTDeclarator[] declarators;
private int declaratorsPos = -1;
private IASTDeclSpecifier declSpecifier;
@ -126,4 +127,13 @@ public class CPPASTSimpleDeclaration extends CPPASTAttributeOwner implements IAS
}
super.replace(child, other);
}
@Override
public ICPPExecution getExecution() {
ICPPExecution[] declaratorExecutions = new ICPPExecution[declarators.length];
for(int i = 0; i < declarators.length; ++i) {
declaratorExecutions[i] = ((ICPPExecutionOwner)declarators[i]).getExecution();
}
return new ExecSimpleDeclaration(declaratorExecutions);
}
}

View file

@ -18,12 +18,10 @@ import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
@ -31,11 +29,12 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalConstructor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
public class CPPASTSimpleTypeConstructorExpression extends ASTNode
implements ICPPASTSimpleTypeConstructorExpression, IASTImplicitNameOwner {
implements ICPPASTSimpleTypeConstructorExpression, IASTImplicitNameOwner, ICPPEvaluationOwner {
private ICPPASTDeclSpecifier fDeclSpec;
private IASTInitializer fInitializer;
private ICPPEvaluation fEvaluation;
@ -97,17 +96,10 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
final IType type = CPPVisitor.createType(fDeclSpec);
ICPPEvaluation[] args= null;
if (fInitializer instanceof ICPPASTConstructorInitializer) {
IASTInitializerClause[] a = ((ICPPASTConstructorInitializer) fInitializer).getArguments();
args= new ICPPEvaluation[a.length];
for (int i = 0; i < a.length; i++) {
args[i]= ((ICPPASTInitializerClause) a[i]).getEvaluation();
}
fEvaluation= new EvalTypeId(type, this, args);
} else if (fInitializer instanceof ICPPASTInitializerList) {
fEvaluation= new EvalTypeId(type, this,
((ICPPASTInitializerList) fInitializer).getEvaluation());
if (fInitializer instanceof ICPPASTConstructorInitializer || fInitializer instanceof ICPPASTInitializerList) {
boolean usesBracedInitList = (fInitializer instanceof ICPPASTInitializerList);
fEvaluation= new EvalTypeId(type, this, usesBracedInitList,
EvalConstructor.extractArguments(fInitializer));
} else {
fEvaluation= EvalFixed.INCOMPLETE;
}
@ -286,7 +278,7 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode
ICPPEvaluation eval = getEvaluation();
if (eval instanceof EvalTypeId) {
ICPPFunction constructor = ((EvalTypeId) eval).getConstructor(this);
if (constructor != null) {
if (constructor != null && constructor != EvalTypeId.AGGREGATE_INITIALIZATION) {
CPPASTImplicitName name = new CPPASTImplicitName(constructor.getNameCharArray(), this);
name.setOffsetAndLength((ASTNode) fDeclSpec);
name.setBinding(constructor);

View file

@ -18,12 +18,16 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSwitchStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecSimpleDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecSwitch;
/**
* Switch statement in C++.
*/
public class CPPASTSwitchStatement extends CPPASTAttributeOwner implements ICPPASTSwitchStatement {
public class CPPASTSwitchStatement extends CPPASTAttributeOwner implements ICPPASTSwitchStatement, ICPPExecutionOwner {
private IScope scope;
private IASTExpression controllerExpression;
private IASTDeclaration controllerDeclaration;
@ -154,4 +158,25 @@ public class CPPASTSwitchStatement extends CPPASTAttributeOwner implements ICPPA
scope = new CPPBlockScope(this);
return scope;
}
@Override
public ICPPExecution getExecution() {
ICPPEvaluationOwner controllerExpr = (ICPPEvaluationOwner)getControllerExpression();
ICPPExecutionOwner controllerDecl = (ICPPExecutionOwner)getControllerDeclaration();
ICPPEvaluation controllerExprEval = controllerExpr != null ? controllerExpr.getEvaluation() : null;
ExecSimpleDeclaration controllerDeclExec = controllerDecl != null ? (ExecSimpleDeclaration)controllerDecl.getExecution() : null;
IASTStatement[] bodyStmts = null;
if(body instanceof ICPPASTCompoundStatement) {
ICPPASTCompoundStatement compoundStmt = (ICPPASTCompoundStatement)body;
bodyStmts = compoundStmt.getStatements();
} else {
bodyStmts = new IASTStatement[]{body};
}
ICPPExecution[] bodyStmtExecutions = new ICPPExecution[bodyStmts.length];
for(int i = 0; i < bodyStmts.length; i++) {
bodyStmtExecutions[i] = EvalUtil.getExecutionFromStatement(bodyStmts[i]);
}
return new ExecSwitch(controllerExprEval, controllerDeclExec, bodyStmtExecutions);
}
}

Some files were not shown because too many files have changed in this diff Show more