Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Prigogin2012-08-22 13:18:46 -0400
committerSergey Prigogin2012-08-22 14:44:10 -0400
commitfd7b8220ee5865c8d262dc4872d18d770ed89e9a (patch)
tree269c82dba401096062a997be829ee084813f5370
parent7b3c5d43f30e8f48f42851617815e7f5a3655c4f (diff)
downloadorg.eclipse.cdt-fd7b8220ee5865c8d262dc4872d18d770ed89e9a.tar.gz
org.eclipse.cdt-fd7b8220ee5865c8d262dc4872d18d770ed89e9a.tar.xz
org.eclipse.cdt-fd7b8220ee5865c8d262dc4872d18d770ed89e9a.zip
Bug 367993 - Error due to CDT not recognizing compiler built-ins like
__is_pod.
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java2
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java25
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/ClassTypeHelperTests.java122
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java2
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCCompleteParseExtensionsTest.java2
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/TypeTraitsTests.java239
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/rewrite/TypeHelper.java6
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java15
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java152
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java379
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java10
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVariableReadWriteFlags.java3
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java10
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java5
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java53
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java328
-rw-r--r--lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRGCCCompleteParseExtensionsTest.java2
18 files changed, 865 insertions, 492 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java
index 3cdbabd157..dbebb3faec 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java
@@ -105,7 +105,7 @@ public class AST2BaseTest extends BaseTestCase {
private static Map<String, String> getGnuMap() {
Map<String, String> map= new HashMap<String, String>();
map.put("__GNUC__", "4");
- map.put("__GNUC_MINOR__", "5");
+ map.put("__GNUC_MINOR__", "7");
map.put("__SIZEOF_INT__", "4");
map.put("__SIZEOF_LONG__", "8");
return map;
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
index a35448d8d2..2f54ed2d44 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
@@ -1330,7 +1330,7 @@ public class AST2TemplateTests extends AST2BaseTest {
ICPPClassType sc0= assertInstance(b0.getSpecializedBinding(), ICPPClassType.class);
ICPPClassType sc1= assertInstance(b1.getSpecializedBinding(), ICPPClassType.class);
assertTrue(sc0.isSameType(sc1));
-
+
assertInstance(b0, ICPPSpecialization.class);
assertInstance(b1, ICPPTemplateInstance.class);
@@ -5988,4 +5988,27 @@ public class AST2TemplateTests extends AST2BaseTest {
public void testSFINAE_b() throws Exception {
parseAndCheckBindings();
}
+
+ // template<typename T>
+ // struct is_pod {
+ // static const bool value = __is_pod(T);
+ // };
+ //
+ // template <bool, typename = void>
+ // struct enable_if {};
+ //
+ // template <typename T>
+ // struct enable_if<true, T> {
+ // typedef T type;
+ // };
+ //
+ // template <typename T>
+ // void f(typename enable_if<is_pod<T>::value>::type* = 0);
+ //
+ // void test() {
+ // f<int>();
+ // }
+ public void testIsPOD_367993() throws Exception {
+ parseAndCheckBindings(getAboveComment(), CPP, true);
+ }
}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/ClassTypeHelperTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/ClassTypeHelperTests.java
deleted file mode 100644
index aadfeac567..0000000000
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/ClassTypeHelperTests.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2011 Google, 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:
- * Sergey Prigogin (Google) - initial API and implementation
- *******************************************************************************/
-package org.eclipse.cdt.core.parser.tests.ast2;
-
-import java.io.IOException;
-
-import junit.framework.TestSuite;
-
-import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
-import org.eclipse.cdt.internal.core.parser.ParserException;
-
-/**
- * Tests for ClassTypeHelper class.
- */
-public class ClassTypeHelperTests extends AST2BaseTest {
-
- public ClassTypeHelperTests() {
- }
-
- public ClassTypeHelperTests(String name) {
- super(name);
- }
-
- public static TestSuite suite() {
- return suite(ClassTypeHelperTests.class);
- }
-
- protected BindingAssertionHelper getAssertionHelper() throws ParserException, IOException {
- String code= getAboveComment();
- return new BindingAssertionHelper(code, true);
- }
-
- // struct A {
- // A(const A& a);
- // };
- //
- // class B {
- // public:
- // B();
- // int x;
- // A* y;
- // const A& z;
- // static A s;
- // };
- //
- // class C {
- // public:
- // A a;
- // };
- public void testHasTrivialCopyCtor() throws Exception {
- BindingAssertionHelper helper = getAssertionHelper();
- ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class);
- assertFalse(ClassTypeHelper.hasTrivialCopyCtor(classA, null));
- ICPPClassType classB = helper.assertNonProblem("B {", 1, ICPPClassType.class);
- assertTrue(ClassTypeHelper.hasTrivialCopyCtor(classB, null));
- ICPPClassType classC = helper.assertNonProblem("C {", 1, ICPPClassType.class);
- assertFalse(ClassTypeHelper.hasTrivialCopyCtor(classC, null));
- }
-
- // struct A {
- // ~A();
- // };
- //
- // class B {
- // public:
- // B();
- // B(const B& a);
- // int x;
- // B* y;
- // const B& z;
- // static A s;
- // };
- //
- // class C {
- // public:
- // A a;
- // };
- public void testHasTrivialDestructor() throws Exception {
- BindingAssertionHelper helper = getAssertionHelper();
- ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class);
- assertFalse(ClassTypeHelper.hasTrivialDestructor(classA, null));
- ICPPClassType classB = helper.assertNonProblem("B {", 1, ICPPClassType.class);
- assertTrue(ClassTypeHelper.hasTrivialDestructor(classB, null));
- ICPPClassType classC = helper.assertNonProblem("C {", 1, ICPPClassType.class);
- assertFalse(ClassTypeHelper.hasTrivialDestructor(classC, null));
- }
-
- // struct A {
- // virtual void m();
- // };
- //
- // class B {
- // public:
- // B();
- // B(const B& a);
- // void m();
- // int x;
- // B* y;
- // const B& z;
- // };
- //
- // class C : public A {
- // };
- public void testIsPolymorphic() throws Exception {
- BindingAssertionHelper helper = getAssertionHelper();
- ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class);
- assertTrue(ClassTypeHelper.isPolymorphic(classA));
- ICPPClassType classB = helper.assertNonProblem("B {", 1, ICPPClassType.class);
- assertFalse(ClassTypeHelper.isPolymorphic(classB));
- ICPPClassType classC = helper.assertNonProblem("C", 1, ICPPClassType.class);
- assertTrue(ClassTypeHelper.isPolymorphic(classC));
- }
-}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java
index aff28ece1a..6b46417c96 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java
@@ -30,7 +30,7 @@ public class DOMParserTestSuite extends TestCase {
suite.addTest(ASTCPPSpecDefectTests.suite());
suite.addTest(AST2CPPImplicitNameTests.suite());
suite.addTest(AST2TemplateTests.suite());
- suite.addTest(ClassTypeHelperTests.suite());
+ suite.addTest(TypeTraitsTests.suite());
suite.addTestSuite(QuickParser2Tests.class);
suite.addTest(CompleteParser2Tests.suite());
suite.addTest(DOMLocationTests.suite());
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCCompleteParseExtensionsTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCCompleteParseExtensionsTest.java
index be16c393ab..48f4e1a6c1 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCCompleteParseExtensionsTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCCompleteParseExtensionsTest.java
@@ -426,7 +426,7 @@ public class GCCCompleteParseExtensionsTest extends AST2BaseTest {
// b= __is_polymorphic (int);
// b= __is_union (int);
// }
- public void testTypetraits_Bug342683() throws Exception {
+ public void testTypeTraits_Bug342683() throws Exception {
parseGPP(getAboveComment());
}
}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/TypeTraitsTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/TypeTraitsTests.java
new file mode 100644
index 0000000000..7fff28bb67
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/TypeTraitsTests.java
@@ -0,0 +1,239 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 Google, 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:
+ * Sergey Prigogin (Google) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.parser.tests.ast2;
+
+import java.io.IOException;
+
+import junit.framework.TestSuite;
+
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeTraits;
+import org.eclipse.cdt.internal.core.parser.ParserException;
+
+/**
+ * Tests for ClassTypeHelper class.
+ */
+public class TypeTraitsTests extends AST2BaseTest {
+
+ public TypeTraitsTests() {
+ }
+
+ public TypeTraitsTests(String name) {
+ super(name);
+ }
+
+ public static TestSuite suite() {
+ return suite(TypeTraitsTests.class);
+ }
+
+ protected BindingAssertionHelper getAssertionHelper() throws ParserException, IOException {
+ String code= getAboveComment();
+ return new BindingAssertionHelper(code, true);
+ }
+
+ // struct A {
+ // A(const A& a);
+ // };
+ //
+ // class B {
+ // public:
+ // B();
+ // int x;
+ // A* y;
+ // const A& z;
+ // static A s;
+ // };
+ //
+ // class C {
+ // public:
+ // A a;
+ // };
+ public void testHasTrivialCopyCtor() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+ ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.hasTrivialCopyCtor(classA, null));
+ ICPPClassType classB = helper.assertNonProblem("B {", 1, ICPPClassType.class);
+ assertTrue(TypeTraits.hasTrivialCopyCtor(classB, null));
+ ICPPClassType classC = helper.assertNonProblem("C {", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.hasTrivialCopyCtor(classC, null));
+ }
+
+ // struct A {
+ // ~A();
+ // };
+ //
+ // class B {
+ // public:
+ // B();
+ // B(const B& a);
+ // int x;
+ // B* y;
+ // const B& z;
+ // static A s;
+ // };
+ //
+ // class C {
+ // public:
+ // A a;
+ // };
+ public void testHasTrivialDestructor() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+ ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.hasTrivialDestructor(classA, null));
+ ICPPClassType classB = helper.assertNonProblem("B {", 1, ICPPClassType.class);
+ assertTrue(TypeTraits.hasTrivialDestructor(classB, null));
+ ICPPClassType classC = helper.assertNonProblem("C {", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.hasTrivialDestructor(classC, null));
+ }
+
+ // struct A {
+ // virtual void m();
+ // };
+ //
+ // class B {
+ // public:
+ // B();
+ // B(const B& a);
+ // void m();
+ // int x;
+ // B* y;
+ // const B& z;
+ // };
+ //
+ // class C : public A {
+ // };
+ public void testIsPolymorphic() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+ ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class);
+ assertTrue(TypeTraits.isPolymorphic(classA, null));
+ ICPPClassType classB = helper.assertNonProblem("B {", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.isPolymorphic(classB, null));
+ ICPPClassType classC = helper.assertNonProblem("C", 1, ICPPClassType.class);
+ assertTrue(TypeTraits.isPolymorphic(classC, null));
+ }
+
+ // struct A {
+ // A* a;
+ // int b;
+ // A(A* a, int b);
+ // A(A& a);
+ // ~A();
+ // };
+ //
+ // class B : public A {
+ // static int c;
+ // void m(A* a);
+ // };
+ //
+ // class C : public A {
+ // int c;
+ // };
+ //
+ // struct D {
+ // C c;
+ // };
+ //
+ // struct E : public C {
+ // };
+ //
+ // struct F : public B {
+ // virtual ~F();
+ // };
+ //
+ // struct G {
+ // int a;
+ // private:
+ // int b;
+ // };
+ //
+ // struct H {
+ // int& a;
+ // };
+ public void testIsStandardLayout() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+ ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class);
+ assertTrue(TypeTraits.isStandardLayout(classA, null));
+ ICPPClassType classB = helper.assertNonProblem("B {", 1, ICPPClassType.class);
+ assertTrue(TypeTraits.isStandardLayout(classB, null));
+ ICPPClassType classC = helper.assertNonProblem("C :", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.isStandardLayout(classC, null));
+ ICPPClassType classD = helper.assertNonProblem("D {", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.isStandardLayout(classD, null));
+ ICPPClassType classE = helper.assertNonProblem("E :", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.isStandardLayout(classE, null));
+ ICPPClassType classF = helper.assertNonProblem("F :", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.isStandardLayout(classF, null));
+ ICPPClassType classG = helper.assertNonProblem("G {", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.isStandardLayout(classG, null));
+ ICPPClassType classH = helper.assertNonProblem("H {", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.isStandardLayout(classH, null));
+ }
+
+ // struct A {
+ // A* a;
+ // int b;
+ // A(char* s);
+ // A(const A& a, int b);
+ // A& operator =(const A& a, A* b);
+ // };
+ //
+ // class B : public A {
+ // A a;
+ // };
+ //
+ // struct C {
+ // C(char* s = 0);
+ // };
+ //
+ // struct D {
+ // D(const D& a, int b = 1);
+ // };
+ //
+ // struct E {
+ // E& operator =(const E& a, E* b = nullptr);
+ // };
+ //
+ // struct F {
+ // ~F();
+ // };
+ //
+ // struct G {
+ // C c;
+ // };
+ //
+ // struct H : public C {
+ // };
+ //
+ // struct I {
+ // virtual void m();
+ // };
+ public void testIsTrivial() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+ ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class);
+ assertTrue(TypeTraits.isTrivial(classA, null));
+ ICPPClassType classB = helper.assertNonProblem("B :", 1, ICPPClassType.class);
+ assertTrue(TypeTraits.isTrivial(classB, null));
+ ICPPClassType classC = helper.assertNonProblem("C {", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.isTrivial(classC, null));
+ ICPPClassType classD = helper.assertNonProblem("D {", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.isTrivial(classD, null));
+ ICPPClassType classE = helper.assertNonProblem("E {", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.isTrivial(classE, null));
+ ICPPClassType classF = helper.assertNonProblem("F {", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.isTrivial(classF, null));
+ ICPPClassType classG = helper.assertNonProblem("G {", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.isTrivial(classG, null));
+ ICPPClassType classH = helper.assertNonProblem("H :", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.isTrivial(classH, null));
+ ICPPClassType classI = helper.assertNonProblem("I {", 1, ICPPClassType.class);
+ assertFalse(TypeTraits.isTrivial(classI, null));
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/rewrite/TypeHelper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/rewrite/TypeHelper.java
index 6283e41a76..64d073363f 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/rewrite/TypeHelper.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/rewrite/TypeHelper.java
@@ -20,9 +20,9 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment;
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeTraits;
/**
* A collection of static methods related to types.
@@ -48,8 +48,8 @@ public class TypeHelper {
if (type instanceof ICompositeType) {
if (type instanceof ICPPClassType) {
ICPPClassType classType = ((ICPPClassType) type);
- if (!ClassTypeHelper.hasTrivialCopyCtor(classType, ast) ||
- !ClassTypeHelper.hasTrivialDestructor(classType, ast)) {
+ if (!TypeTraits.hasTrivialCopyCtor(classType, ast) ||
+ !TypeTraits.hasTrivialDestructor(classType, ast)) {
return true;
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java
index cdc024cd70..b8d7de011e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java
@@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.dom.parser;
import java.util.HashMap;
import java.util.Map;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IArrayType;
@@ -74,6 +75,20 @@ public class SizeofCalculator {
private final IASTTranslationUnit ast;
/**
+ * Calculates size and alignment for the given type.
+ *
+ * @param type the type to get size and alignment for.
+ * @param point a node belonging to the AST of the translation unit defining context for
+ * the size calculation.
+ * @return size and alignment, or <code>null</code> if could not be calculated.
+ */
+ public static SizeAndAlignment getSizeAndAlignment(IType type, IASTNode point) {
+ SizeofCalculator calc = point == null ?
+ getDefault() : ((ASTTranslationUnit) point.getTranslationUnit()).getSizeofCalculator();
+ return calc.sizeAndAlignment(type);
+ }
+
+ /**
* Returns the default instance of sizeof calculator. The default instance is not aware
* of the parser configuration and can only calculate sizes that are the same across all
* C/C++ implementations.
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java
index 44e298d51f..a3bc301dad 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java
@@ -11,29 +11,58 @@
*******************************************************************************/
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_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_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 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.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.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
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.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.EvalBinding;
+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.db.TypeMarshalBuffer;
@@ -201,7 +230,7 @@ public class Value implements IValue {
public static IValue evaluateBinaryExpression(final int op, final long v1, final long v2) {
try {
- return create(combineBinary(op, v1, v2));
+ return create(applyBinaryOperator(op, v1, v2));
} catch (UnknownValueException e) {
}
return UNKNOWN;
@@ -209,12 +238,101 @@ public class Value implements IValue {
public static IValue evaluateUnaryExpression(final int unaryOp, final long value) {
try {
- return create(combineUnary(unaryOp, value));
+ return create(applyUnaryOperator(unaryOp, value));
} catch (UnknownValueException e) {
}
return UNKNOWN;
}
+ public static IValue evaluateUnaryTypeIdExpression(int operator, IType type, IASTNode point) {
+ try {
+ return create(applyUnaryTypeIdOperator(operator, type, point));
+ } catch (UnknownValueException e) {
+ }
+ return UNKNOWN;
+ }
+
+ public static IValue evaluateBinaryTypeIdExpression(IASTBinaryTypeIdExpression.Operator operator,
+ IType type1, IType type2, IASTNode point) {
+ try {
+ return create(applyBinaryTypeIdOperator(operator, type1, type2, point));
+ } catch (UnknownValueException e) {
+ }
+ return UNKNOWN;
+ }
+
+ private static long applyUnaryTypeIdOperator(int operator, IType type, IASTNode point) throws UnknownValueException{
+ switch (operator) {
+ case op_sizeof:
+ return getSizeAndAlignment(type, point).size;
+ case op_alignof:
+ return getSizeAndAlignment(type, point).alignment;
+ case op_typeid:
+ break; // TODO(sprigogin): Implement
+ 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:
+ break; // TODO(sprigogin): Implement
+ case op_is_enum:
+ return type instanceof IEnumeration ? 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_union:
+ return type instanceof ICompositeType &&
+ ((ICompositeType) type).getKey() == ICompositeType.k_union ? 1 : 0;
+ case op_typeof:
+ break; // TODO(sprigogin): Implement
+ }
+ throw UNKNOWN_EX;
+ }
+
+ public static long applyBinaryTypeIdOperator(IASTBinaryTypeIdExpression.Operator operator,
+ IType type1, IType type2, IASTNode point) throws UnknownValueException {
+ switch (operator) {
+ case __is_base_of:
+ if (type1 instanceof ICPPClassType && type1 instanceof ICPPClassType) {
+ return ClassTypeHelper.isSubclass((ICPPClassType) type2, (ICPPClassType) type1) ? 1 : 0;
+ }
+ }
+ throw UNKNOWN_EX;
+ }
+
+ private static SizeAndAlignment getSizeAndAlignment(IType type, IASTNode point) throws UnknownValueException {
+ SizeAndAlignment sizeAndAlignment = SizeofCalculator.getSizeAndAlignment(type, point);
+ if (sizeAndAlignment == null)
+ throw UNKNOWN_EX;
+ return sizeAndAlignment;
+ }
+
/**
* Tests whether the value is a template parameter (or a parameter pack).
*
@@ -348,19 +466,15 @@ public class Value implements IValue {
}
}
if (exp instanceof IASTTypeIdExpression) {
- IASTTypeIdExpression typeIdEx = (IASTTypeIdExpression) exp;
- switch (typeIdEx.getOperator()) {
- case IASTTypeIdExpression.op_sizeof:
- ASTTranslationUnit ast = (ASTTranslationUnit) typeIdEx.getTranslationUnit();
- final IType type = ast.createType(typeIdEx.getTypeId());
- if (type instanceof ICPPUnknownType)
- return null;
- SizeofCalculator calculator = ast.getSizeofCalculator();
- SizeAndAlignment info = calculator.sizeAndAlignment(type);
- if (info == null)
- throw UNKNOWN_EX;
- return info.size;
- }
+ ASTTranslationUnit ast = (ASTTranslationUnit) exp.getTranslationUnit();
+ final IType type = ast.createType(((IASTTypeIdExpression) exp).getTypeId());
+ if (type instanceof ICPPUnknownType)
+ return null;
+ return applyUnaryTypeIdOperator(((IASTTypeIdExpression) exp).getOperator(), type, exp);
+ }
+
+ if (exp instanceof IASTBinaryTypeIdExpression) {
+
}
throw UNKNOWN_EX;
}
@@ -422,10 +536,10 @@ public class Value implements IValue {
final Long value= evaluate(exp.getOperand(), maxdepth);
if (value == null)
return null;
- return combineUnary(unaryOp, value);
+ return applyUnaryOperator(unaryOp, value);
}
- private static long combineUnary(final int unaryOp, final long value) throws UnknownValueException {
+ private static long applyUnaryOperator(final int unaryOp, final long value) throws UnknownValueException {
switch (unaryOp) {
case IASTUnaryExpression.op_bracketedPrimary:
case IASTUnaryExpression.op_plus:
@@ -470,10 +584,10 @@ public class Value implements IValue {
if (o2 == null)
return null;
- return combineBinary(op, o1, o2);
+ return applyBinaryOperator(op, o1, o2);
}
- private static long combineBinary(final int op, final long v1, final long v2)
+ private static long applyBinaryOperator(final int op, final long v1, final long v2)
throws UnknownValueException {
switch (op) {
case IASTBinaryExpression.op_multiply:
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java
index 3ddeba3b2f..615bb1a3eb 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java
@@ -15,9 +15,6 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
-import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ARRAY;
-import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
-import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import java.util.ArrayList;
import java.util.Collections;
@@ -39,7 +36,6 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IField;
-import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IQualifierType;
import org.eclipse.cdt.core.dom.ast.IScope;
@@ -60,8 +56,8 @@ 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.ICPPFunctionType;
-import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.core.index.IIndex;
@@ -78,8 +74,8 @@ import org.eclipse.core.runtime.CoreException;
/**
* Holds common implementation of methods for ICPPClassType implementations that have
- * a corresponding textual definition in the source code.
- *
+ * a corresponding textual definition in the source code.
+ *
* @see CPPClassType
* @see CPPClassTemplate
*/
@@ -101,8 +97,9 @@ public class ClassTypeHelper {
ObjectSet<IBinding> resultSet = new ObjectSet<IBinding>(2);
IASTDeclaration[] members = host.getCompositeTypeSpecifier().getMembers();
for (IASTDeclaration decl : members) {
- while (decl instanceof ICPPASTTemplateDeclaration)
+ while (decl instanceof ICPPASTTemplateDeclaration) {
decl = ((ICPPASTTemplateDeclaration) decl).getDeclaration();
+ }
if (decl instanceof IASTSimpleDeclaration) {
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration) decl).getDeclSpecifier();
@@ -115,7 +112,7 @@ public class ClassTypeHelper {
if (dtor == null) break;
dtor= ASTQueries.findInnermostDeclarator(dtor);
resultSet.put(dtor.getName().resolveBinding());
- }
+ }
}
}
} else if (decl instanceof IASTFunctionDefinition) {
@@ -134,7 +131,7 @@ public class ClassTypeHelper {
/**
* Checks if a binding is a friend of a class. Only classes and functions can be friends of a class.
* A class is considered a friend of itself.
- * @param binding a binding.
+ * @param binding a binding.
* @param classType a class.
* @return <code>true</code> if <code>binding</code> is a friend of <code>classType</code>.
*/
@@ -198,7 +195,7 @@ public class ClassTypeHelper {
bindings[i] = new CPPBaseClause(bases[i]);
}
- return bindings;
+ return bindings;
}
public static ICPPField[] getDeclaredFields(ICPPInternalClassTypeMixinHost host) {
@@ -278,7 +275,7 @@ public class ClassTypeHelper {
}
/**
- * Returns all direct and indirect base classes.
+ * Returns all direct and indirect base classes.
* @param classType a class
* @return An array of visible base classes in arbitrary order.
*/
@@ -296,7 +293,7 @@ public class ClassTypeHelper {
IBinding b= base.getBaseClass();
if (b instanceof ICPPClassType) {
final ICPPClassType baseClass = (ICPPClassType) b;
- if (result.add(baseClass)) {
+ if (result.add(baseClass)) {
getAllBases(baseClass, result, point);
}
}
@@ -346,7 +343,7 @@ public class ClassTypeHelper {
/**
* Returns methods either declared by the given class or generated by the compiler. Does not
- * include methods declared in base classes.
+ * include methods declared in base classes.
*/
private static ObjectSet<ICPPMethod> getOwnMethods(ICPPClassType classType, IASTNode point) {
ObjectSet<ICPPMethod> set= new ObjectSet<ICPPMethod>(4);
@@ -460,7 +457,7 @@ public class ClassTypeHelper {
}
if (binding instanceof ICPPClassType)
result = ArrayUtil.append(ICPPClassType.class, result, (ICPPClassType) binding);
- }
+ }
}
return ArrayUtil.trim(ICPPClassType.class, result);
}
@@ -498,7 +495,7 @@ public class ClassTypeHelper {
public static boolean isVirtual(ICPPMethod m) {
if (m instanceof ICPPConstructor)
return false;
- if (m.isVirtual())
+ if (m.isVirtual())
return true;
final char[] mname= m.getNameCharArray();
@@ -528,7 +525,7 @@ public class ClassTypeHelper {
IType[] paramsA = a.getParameterTypes();
IType[] paramsB = b.getParameterTypes();
-
+
if (paramsA.length == 1 && paramsB.length == 0) {
if (!SemanticUtil.isVoidType(paramsA[0]))
return false;
@@ -550,9 +547,9 @@ public class ClassTypeHelper {
* Returns {@code true} if {@code source} overrides {@code target}.
*/
public static boolean isOverrider(ICPPMethod source, ICPPMethod target) {
- if (source instanceof ICPPConstructor || target instanceof ICPPConstructor)
+ if (source instanceof ICPPConstructor || target instanceof ICPPConstructor)
return false;
- if (!isVirtual(target))
+ if (!isVirtual(target))
return false;
if (!functionTypesAllowOverride(source.getType(), target.getType()))
return false;
@@ -580,7 +577,7 @@ public class ClassTypeHelper {
final char[] mname= method.getNameCharArray();
final ICPPClassType mcl= method.getClassOwner();
- if (mcl == null)
+ if (mcl == null)
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
final ArrayList<ICPPMethod> result= new ArrayList<ICPPMethod>();
@@ -646,14 +643,14 @@ public class ClassTypeHelper {
/**
* Returns all methods found in the index, that override the given {@code method}.
- * @throws CoreException
+ * @throws CoreException
*/
public static ICPPMethod[] findOverriders(IIndex index, ICPPMethod method) throws CoreException {
if (!isVirtual(method))
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
final ICPPClassType mcl= method.getClassOwner();
- if (mcl == null)
+ if (mcl == null)
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
ICPPClassType[] subclasses= getSubClasses(index, mcl);
@@ -714,24 +711,76 @@ public class ClassTypeHelper {
}
}
- private static final int KIND_DEFAULT_CTOR= 0;
- private static final int KIND_COPY_CTOR= 1;
- private static final int KIND_ASSIGNMENT_OP= 2;
- private static final int KIND_DTOR= 3;
- private static final int KIND_OTHER= 4;
+ public enum MethodKind {
+ DEFAULT_CTOR,
+ COPY_CTOR,
+ MOVE_CTOR,
+ COPY_ASSIGNMENT_OP,
+ MOVE_ASSIGNMENT_OP,
+ DTOR,
+ OTHER
+ }
+
+ public static MethodKind getMethodKind(ICPPClassType classType, ICPPMethod method) {
+ if (method instanceof ICPPConstructor) {
+ final List<IType> params= getTypesOfRequiredParameters(method);
+ if (params.isEmpty())
+ return MethodKind.DEFAULT_CTOR;
+ if (params.size() == 1) {
+ IType t= SemanticUtil.getNestedType(params.get(0), SemanticUtil.TDEF);
+ if (SemanticUtil.isVoidType(t))
+ return MethodKind.DEFAULT_CTOR;
+
+ ICPPReferenceType refToClass = getRefToClass(classType, t);
+ if (refToClass != null)
+ return refToClass.isRValueReference() ? MethodKind.MOVE_CTOR : MethodKind.COPY_CTOR;
+ }
+ return MethodKind.OTHER;
+ }
+
+ if (method.isDestructor())
+ return MethodKind.DTOR;
+
+ if (CharArrayUtils.equals(method.getNameCharArray(), OverloadableOperator.ASSIGN.toCharArray())) {
+ final List<IType> params= getTypesOfRequiredParameters(method);
+ if (params.size() == 1) {
+ IType t= params.get(0);
+ ICPPReferenceType refToClass = getRefToClass(classType, t);
+ if (refToClass != null)
+ return refToClass.isRValueReference() ? MethodKind.MOVE_ASSIGNMENT_OP : MethodKind.COPY_ASSIGNMENT_OP;
+ }
+ return MethodKind.OTHER;
+ }
+ return MethodKind.OTHER;
+ }
+
+ /**
+ * Returns types of method parameters that don't have defaults.
+ */
+ private static List<IType> getTypesOfRequiredParameters(ICPPMethod method) {
+ ICPPParameter[] parameters = method.getParameters();
+ if (parameters.length == 0)
+ return Collections.emptyList();
+ List<IType> types = new ArrayList<IType>(parameters.length);
+ for (ICPPParameter parameter : parameters) {
+ if (!parameter.hasDefaultValue() && !parameter.isParameterPack())
+ types.add(parameter.getType());
+ }
+ return types;
+ }
/**
- * For implicit methods the exception specification is inherited, search it
+ * For implicit methods the exception specification is inherited, search it.
*/
public static IType[] getInheritedExceptionSpecification(ICPPMethod implicitMethod, IASTNode point) {
// See 15.4.13
ICPPClassType owner= implicitMethod.getClassOwner();
- if (owner == null || ClassTypeHelper.getBases(owner, point).length == 0)
+ if (owner == null || ClassTypeHelper.getBases(owner, point).length == 0)
return null;
- // we use a list as types aren't comparable, and can have duplicates (15.4.6)
- int kind= getImplicitMethodKind(owner, implicitMethod);
- if (kind == KIND_OTHER)
+ // We use a list as types aren't comparable, and can have duplicates (15.4.6)
+ MethodKind kind= getMethodKind(owner, implicitMethod);
+ if (kind == MethodKind.OTHER)
return null;
List<IType> inheritedTypeids = new ArrayList<IType>();
@@ -741,7 +790,7 @@ public class ClassTypeHelper {
ICPPMethod baseMethod= getMethodInClass(base, kind, point);
if (baseMethod != null) {
IType[] baseExceptionSpec= baseMethod.getExceptionSpecification();
- if (baseExceptionSpec == null)
+ if (baseExceptionSpec == null)
return null;
for (IType baseTypeId : baseMethod.getExceptionSpecification()) {
inheritedTypeids.add(baseTypeId);
@@ -752,275 +801,71 @@ public class ClassTypeHelper {
return inheritedTypeids.toArray(new IType[inheritedTypeids.size()]);
}
- private static int getImplicitMethodKind(ICPPClassType ct, ICPPMethod method) {
- if (method instanceof ICPPConstructor) {
- final IFunctionType type= method.getType();
- final IType[] params= type.getParameterTypes();
- if (params.length == 0)
- return KIND_DEFAULT_CTOR;
- if (params.length == 1) {
- IType t= SemanticUtil.getNestedType(params[0], SemanticUtil.TDEF);
- if (SemanticUtil.isVoidType(t))
- return KIND_DEFAULT_CTOR;
-
- if (isRefToConstClass(ct, t))
- return KIND_COPY_CTOR;
- }
- return KIND_OTHER;
+ /**
+ * If {@code type} is a, possibly qualified, reference type referring to {@code classType},
+ * returns that reference type. Otherwise returns {@code null}.
+ */
+ private static ICPPReferenceType getRefToClass(ICPPClassType classType, IType type) {
+ while (type instanceof ITypedef) {
+ type= ((ITypedef) type).getType();
}
- if (method.isDestructor())
- return KIND_DTOR;
-
- if (CharArrayUtils.equals(method.getNameCharArray(), OverloadableOperator.ASSIGN.toCharArray())) {
- final IFunctionType type= method.getType();
- final IType[] params= type.getParameterTypes();
- if (params.length == 1) {
- IType t= params[0];
- if (isRefToConstClass(ct, t))
- return KIND_ASSIGNMENT_OP;
+ if (type instanceof ICPPReferenceType) {
+ ICPPReferenceType refType = (ICPPReferenceType) type;
+ type= refType.getType();
+ while (type instanceof ITypedef) {
+ type= ((ITypedef) type).getType();
}
- return KIND_OTHER;
- }
- return KIND_OTHER;
- }
-
- private static boolean isRefToConstClass(ICPPClassType ct, IType t) {
- while (t instanceof ITypedef)
- t= ((ITypedef) t).getType();
-
- if (t instanceof ICPPReferenceType) {
- t= ((ICPPReferenceType) t).getType();
- while (t instanceof ITypedef)
- t= ((ITypedef) t).getType();
- if (t instanceof IQualifierType) {
- t= ((IQualifierType) t).getType();
- return ct.isSameType(t);
+ if (type instanceof IQualifierType) {
+ type= ((IQualifierType) type).getType();
+ if (classType.isSameType(type))
+ return refType;
}
}
- return false;
+ return null;
}
- private static ICPPMethod getMethodInClass(ICPPClassType ct, int kind, IASTNode point) {
+ private static ICPPMethod getMethodInClass(ICPPClassType ct, MethodKind kind, IASTNode point) {
switch (kind) {
- case KIND_DEFAULT_CTOR:
- case KIND_COPY_CTOR:
+ case DEFAULT_CTOR:
+ case COPY_CTOR:
+ case MOVE_CTOR:
for (ICPPConstructor ctor : getConstructors(ct, point)) {
- if (!ctor.isImplicit() && getImplicitMethodKind(ct, ctor) == kind)
+ if (!ctor.isImplicit() && getMethodKind(ct, ctor) == kind)
return ctor;
}
return null;
- case KIND_ASSIGNMENT_OP:
+ case COPY_ASSIGNMENT_OP:
+ case MOVE_ASSIGNMENT_OP:
for (ICPPMethod method : getDeclaredMethods(ct, point)) {
if (method instanceof ICPPConstructor)
continue;
- if (getImplicitMethodKind(ct, method) == kind)
+ if (getMethodKind(ct, method) == kind)
return method;
}
return null;
- case KIND_DTOR:
+ case DTOR:
for (ICPPMethod method : getDeclaredMethods(ct, point)) {
if (method.isDestructor())
return method;
}
return null;
+ case OTHER:
+ break;
}
return null;
}
/**
- * 8.5.1 Aggregates [dcl.init.aggr]
- * An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1),
- * no private or protected non-static data members (Clause 11),
- * no base classes (Clause 10), and no virtual functions (10.3).
- */
- public static boolean isAggregateClass(ICPPClassType classTarget, IASTNode point) {
- if (ClassTypeHelper.getBases(classTarget, point).length > 0)
- return false;
- ICPPMethod[] methods = ClassTypeHelper.getDeclaredMethods(classTarget, point);
- for (ICPPMethod m : methods) {
- if (m instanceof ICPPConstructor)
- return false;
- if (m.isVirtual()) {
- return false;
- }
- }
- ICPPField[] fields = ClassTypeHelper.getDeclaredFields(classTarget, point);
- for (ICPPField field : fields) {
- if (!(field.getVisibility() == ICPPMember.v_public || field.isStatic())) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Returns <code>true</code> if and only if the given class has a trivial copy constructor.
- * A copy constructor is trivial if:
- * <ul>
- * <li>it is implicitly defined by the compiler, and</li>
- * <li><code>isPolymorphic(classTarget) == false</code>, and</li>
- * <li>the class has no virtual base classes, and</li>
- * <li>every direct base class has trivial copy constructor, and</li>
- * <li>for every nonstatic data member that has class type or array of class type, that type
- * has trivial copy constructor.</li>
- * </ul>
- * Similar to <code>std::tr1::has_trivial_copy</code>.
- *
- * @param classTarget the class to check
- * @return <code>true</code> if the class has a trivial copy constructor
- */
- public static boolean hasTrivialCopyCtor(ICPPClassType classTarget, IASTNode point) {
- if (getImplicitCopyCtor(classTarget) == null)
- return false;
- if (isPolymorphic(classTarget))
- return false;
- for (ICPPBase base : classTarget.getBases()) {
- if (base.isVirtual())
- return false;
- }
- for (ICPPClassType baseClass : getAllBases(classTarget, point)) {
- if (!classTarget.isSameType(baseClass) && !hasTrivialCopyCtor(baseClass, point))
- return false;
- }
- for (ICPPField field : classTarget.getDeclaredFields()) {
- if (!field.isStatic()) {
- IType type = field.getType();
- type = SemanticUtil.getNestedType(type, TDEF | CVTYPE | ARRAY);
- if (type instanceof ICPPClassType && !classTarget.isSameType(type) &&
- !hasTrivialCopyCtor((ICPPClassType) type, point)) {
- return false;
- }
- }
- }
- return true;
- }
-
- /**
- * Returns the compiler-generated copy constructor for the given class, or <code>null</code>
- * if the class doesn't have a compiler-generated copy constructor.
- *
- * @param classTarget the class to get the copy ctor for.
- * @return the compiler-generated copy constructor, or <code>null</code> if the class doesn't
- * have a compiler-generated copy constructor.
- */
- private static ICPPConstructor getImplicitCopyCtor(ICPPClassType classTarget) {
- for (ICPPConstructor ctor : classTarget.getConstructors()) {
- if (ctor.isImplicit() && getImplicitMethodKind(classTarget, ctor) == KIND_COPY_CTOR)
- return ctor;
- }
- return null;
- }
-
- /**
- * Returns <code>true</code> if and only if the given class has a trivial default constructor.
- * A default constructor is trivial if:
- * <ul>
- * <li>it is implicitly defined by the compiler, and</li>
- * <li>every direct base class has trivial default constructor, and</li>
- * <li>for every nonstatic data member that has class type or array of class type, that type
- * has trivial default constructor.</li>
- * </ul>
- * Similar to <code>std::tr1::has_trivial_default_constructor</code>.
- *
- * @param classTarget the class to check
- * @param point
- * @return <code>true</code> if the class has a trivial default constructor
- */
- public static boolean hasTrivialDefaultConstructor(ICPPClassType classTarget, IASTNode point) {
- for (ICPPConstructor ctor : getConstructors(classTarget, point)) {
- if (!ctor.isImplicit() && ctor.getParameters().length == 0)
- return false;
- }
- for (ICPPClassType baseClass : getAllBases(classTarget, null)) {
- if (!classTarget.isSameType(baseClass) && !hasTrivialDefaultConstructor(baseClass, point))
- return false;
- }
- for (ICPPField field : getDeclaredFields(classTarget, point)) {
- if (!field.isStatic()) {
- IType type = field.getType();
- type = SemanticUtil.getNestedType(type, TDEF | CVTYPE | ARRAY);
- if (type instanceof ICPPClassType && !classTarget.isSameType(type) &&
- !hasTrivialDefaultConstructor((ICPPClassType) type, point)) {
- return false;
- }
- }
- }
- return true;
- }
-
- /**
- * Returns <code>true</code> if and only if the given class has a trivial destructor.
- * A destructor is trivial if:
- * <ul>
- * <li>it is implicitly defined by the compiler, and</li>
- * <li>every direct base class has trivial destructor, and</li>
- * <li>for every nonstatic data member that has class type or array of class type, that type
- * has trivial destructor.</li>
- * </ul>
- * Similar to <code>std::tr1::has_trivial_destructor</code>.
- *
- * @param classTarget the class to check
- * @return <code>true</code> if the class has a trivial destructor
- */
- public static boolean hasTrivialDestructor(ICPPClassType classTarget, IASTNode point) {
- for (ICPPMethod method : getDeclaredMethods(classTarget, point)) {
- if (method.isDestructor())
- return false;
- }
- for (ICPPClassType baseClass : getAllBases(classTarget, null)) {
- if (!classTarget.isSameType(baseClass) && !hasTrivialDestructor(baseClass, point))
- return false;
- }
- for (ICPPField field : getDeclaredFields(classTarget, point)) {
- if (!field.isStatic()) {
- IType type = field.getType();
- type = SemanticUtil.getNestedType(type, TDEF | CVTYPE | ARRAY);
- if (type instanceof ICPPClassType && !classTarget.isSameType(type) &&
- !hasTrivialDestructor((ICPPClassType) type, point)) {
- return false;
- }
- }
- }
- return true;
- }
-
- /**
- * Returns <code>true</code> if and only if the given class declares or inherits a virtual
- * function. Similar to <code>std::tr1::is_polymorphic</code>.
- *
- * @param classTarget the class to check
- * @return <code>true</code> if the class declares or inherits a virtual function.
- */
- public static boolean isPolymorphic(ICPPClassType classTarget) {
- if (hasDeclaredVirtualMethod(classTarget))
- return true;
- for (ICPPClassType baseClass : getAllBases(classTarget, null)) {
- if (hasDeclaredVirtualMethod(baseClass))
- return true;
- }
- return false;
- }
-
- private static boolean hasDeclaredVirtualMethod(ICPPClassType classTarget) {
- for (ICPPMethod method : classTarget.getDeclaredMethods()) {
- if (method.isVirtual()) {
- return true;
- }
- }
- return false;
- }
-
- /**
* Checks whether class is abstract, i.e. has pure virtual functions that were
* not implemented in base after declaration.
- *
+ *
* NOTE: The method produces complete results for template instantiations
* but doesn't take into account base classes and methods dependent on unspecified
* template parameters.
*/
public static ICPPMethod[] getPureVirtualMethods(ICPPClassType classType, IASTNode point) {
- Map<String, List<ICPPMethod>> result= collectPureVirtualMethods(classType,
+ Map<String, List<ICPPMethod>> result= collectPureVirtualMethods(classType,
new HashMap<ICPPClassType, Map<String, List<ICPPMethod>>>(), point);
int resultArraySize = 0;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java
index 53b6ff2802..8c2d30ed54 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java
@@ -23,12 +23,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
-import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableType;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
-import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator;
-import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
@@ -250,11 +247,4 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
}
return args;
}
-
- protected static SizeAndAlignment getSizeAndAlignment(IType type, IASTNode point) {
- SizeofCalculator calc = point == null ?
- SizeofCalculator.getDefault() :
- ((ASTTranslationUnit) point.getTranslationUnit()).getSizeofCalculator();
- return calc.sizeAndAlignment(type);
- }
} \ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVariableReadWriteFlags.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVariableReadWriteFlags.java
index 4086f1bd98..5a07c5e916 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVariableReadWriteFlags.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVariableReadWriteFlags.java
@@ -32,7 +32,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.VariableReadWriteFlags;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
/**
@@ -61,7 +60,7 @@ public final class CPPVariableReadWriteFlags extends VariableReadWriteFlags {
IType type = CPPVisitor.createType(parent);
if (type instanceof ICPPUnknownType ||
type instanceof ICPPClassType &&
- !ClassTypeHelper.hasTrivialDefaultConstructor((ICPPClassType) type, parent)) {
+ !TypeTraits.hasTrivialDefaultConstructor((ICPPClassType) type, parent)) {
return WRITE;
}
return super.rwInDeclarator(parent, indirection);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java
index ccf06ec82a..267b5c018d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java
@@ -368,7 +368,7 @@ public class Conversions {
return Cost.NO_CONVERSION;
ICPPClassType classTarget= (ICPPClassType) noCVTarget;
- if (ClassTypeHelper.isAggregateClass(classTarget, point)) {
+ if (TypeTraits.isAggregateClass(classTarget, point)) {
Cost cost= new Cost(arg.getTypeOrFunctionSet(point), target, Rank.IDENTITY);
cost.setUserDefinedConversion(null);
return cost;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java
index 707e19f45e..abdbd08a75 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java
@@ -20,14 +20,12 @@ 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.ICPPClassSpecialization;
-import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
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.CPPBasicType;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.core.runtime.CoreException;
@@ -83,13 +81,7 @@ public class EvalBinaryTypeId extends CPPEvaluation {
if (isValueDependent())
return Value.create(this);
- switch (fOperator) {
- case __is_base_of:
- if (!(fType1 instanceof ICPPClassType) || !(fType1 instanceof ICPPClassType))
- return Value.UNKNOWN;
- return Value.create(ClassTypeHelper.isSubclass((ICPPClassType) fType2, (ICPPClassType) fType1));
- }
- return Value.create(this);
+ return Value.evaluateBinaryTypeIdExpression(fOperator, fType1, fType2, point);
}
@Override
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java
index 7a74dc3404..9763235704 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java
@@ -49,6 +49,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
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.SizeofCalculator.SizeAndAlignment;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArithmeticConversion;
@@ -219,11 +220,11 @@ public class EvalUnary extends CPPEvaluation {
switch (fOperator) {
case op_sizeof: {
- SizeAndAlignment info = getSizeAndAlignment(fArgument.getTypeOrFunctionSet(point), point);
+ SizeAndAlignment info = SizeofCalculator.getSizeAndAlignment(fArgument.getTypeOrFunctionSet(point), point);
return info == null ? Value.UNKNOWN : Value.create(info.size);
}
case op_alignOf: {
- SizeAndAlignment info = getSizeAndAlignment(fArgument.getTypeOrFunctionSet(point), point);
+ SizeAndAlignment info = SizeofCalculator.getSizeAndAlignment(fArgument.getTypeOrFunctionSet(point), point);
return info == null ? Value.UNKNOWN : Value.create(info.alignment);
}
case op_noexcept:
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java
index 241fb626f7..06eb32de63 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java
@@ -37,8 +37,6 @@ import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_typeof;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode;
-import org.eclipse.cdt.core.dom.ast.ICompositeType;
-import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
@@ -46,7 +44,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
-import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
@@ -163,55 +160,7 @@ public class EvalUnaryTypeID extends CPPEvaluation {
if (isValueDependent())
return Value.create(this);
- switch (fOperator) {
- case op_sizeof: {
- SizeAndAlignment info = getSizeAndAlignment(fOrigType, point);
- return info == null ? Value.UNKNOWN : Value.create(info.size);
- }
- case op_alignof: {
- SizeAndAlignment info = getSizeAndAlignment(fOrigType, point);
- return info == null ? Value.UNKNOWN : Value.create(info.alignment);
- }
- case op_typeid:
- return Value.UNKNOWN; // TODO(sprigogin): Implement
- case op_has_nothrow_copy:
- return Value.UNKNOWN; // TODO(sprigogin): Implement
- case op_has_nothrow_constructor:
- return Value.UNKNOWN; // TODO(sprigogin): Implement
- case op_has_trivial_assign:
- return Value.UNKNOWN; // TODO(sprigogin): Implement
- case op_has_trivial_constructor:
- return Value.UNKNOWN; // TODO(sprigogin): Implement
- case op_has_trivial_copy:
- return Value.UNKNOWN; // TODO(sprigogin): Implement
- case op_has_trivial_destructor:
- return Value.UNKNOWN; // TODO(sprigogin): Implement
- case op_has_virtual_destructor:
- return Value.UNKNOWN; // TODO(sprigogin): Implement
- case op_is_abstract:
- return Value.UNKNOWN; // TODO(sprigogin): Implement
- case op_is_class:
- return Value.create(fOrigType instanceof ICompositeType && ((ICompositeType) fOrigType).getKey() != ICompositeType.k_union);
- case op_is_empty:
- return Value.UNKNOWN; // TODO(sprigogin): Implement
- case op_is_enum:
- return Value.create(fOrigType instanceof IEnumeration);
- case op_is_literal_type:
- return Value.UNKNOWN; // TODO(sprigogin): Implement
- case op_is_pod:
- return Value.UNKNOWN; // TODO(sprigogin): Implement
- case op_is_polymorphic:
- return Value.UNKNOWN; // TODO(sprigogin): Implement
- case op_is_standard_layout:
- return Value.UNKNOWN; // TODO(sprigogin): Implement
- case op_is_trivial:
- return Value.UNKNOWN; // TODO(sprigogin): Implement
- case op_is_union:
- return Value.create(fOrigType instanceof ICompositeType && ((ICompositeType) fOrigType).getKey() == ICompositeType.k_union);
- case op_typeof:
- return Value.UNKNOWN; // TODO(sprigogin): Implement
- }
- return Value.create(this);
+ return Value.evaluateUnaryTypeIdExpression(fOperator, fOrigType, point);
}
@Override
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java
new file mode 100644
index 0000000000..71454ab5d6
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java
@@ -0,0 +1,328 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Google, 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:
+ * Sergey Prigogin (Google) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
+
+import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ARRAY;
+import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
+import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
+
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IType;
+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.ICPPConstructor;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper.MethodKind;
+
+/**
+ * A collection of static methods for determining type traits.
+ */
+public class TypeTraits {
+ private TypeTraits() {}
+
+ /**
+ * C++11: 9-6
+ */
+ public static boolean isTrivial(ICPPClassType classType, IASTNode point) {
+ for (ICPPMethod method : ClassTypeHelper.getDeclaredMethods(classType, point)) {
+ if (method.isVirtual())
+ return false;
+ switch (ClassTypeHelper.getMethodKind(classType, method)) {
+ case DEFAULT_CTOR:
+ case COPY_CTOR:
+ case MOVE_CTOR:
+ case COPY_ASSIGNMENT_OP:
+ case MOVE_ASSIGNMENT_OP:
+ case DTOR:
+ return false;
+ default:
+ break;
+ }
+ }
+ ICPPField[] fields = ClassTypeHelper.getDeclaredFields(classType, point);
+ for (ICPPField field : fields) {
+ if (!field.isStatic()) {
+ IType fieldType = SemanticUtil.getNestedType(field.getType(), TDEF);
+ if (fieldType instanceof ICPPClassType && !isTrivial((ICPPClassType) fieldType, point))
+ return false;
+ }
+ }
+ for (ICPPBase base : ClassTypeHelper.getBases(classType, point)) {
+ if (base.isVirtual())
+ return false;
+ }
+ ICPPClassType[] baseClasses = ClassTypeHelper.getAllBases(classType, point);
+ for (ICPPClassType baseClass : baseClasses) {
+ if (!isTrivial(baseClass, point))
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * C++11: 9-7
+ */
+ public static boolean isStandardLayout(IType type, IASTNode point) {
+ type = SemanticUtil.getNestedType(type, ARRAY | CVTYPE | TDEF);
+ if (type instanceof ICPPReferenceType)
+ return false;
+ if (!(type instanceof ICPPClassType))
+ return true;
+ ICPPClassType classType = (ICPPClassType) type;
+ int visibility = 0;
+ ICPPField firstNonStaticField = null;
+ ICPPField[] fields = ClassTypeHelper.getDeclaredFields(classType, point);
+ for (ICPPField field : fields) {
+ if (!field.isStatic()) {
+ if (!isStandardLayout(field.getType(), point))
+ return false;
+ int vis = field.getVisibility();
+ if (visibility == 0) {
+ visibility = vis;
+ } else if (vis != visibility) {
+ return false;
+ }
+ if (firstNonStaticField == null)
+ firstNonStaticField = field;
+ }
+ }
+ if (hasDeclaredVirtualMethod(classType, point))
+ return false;
+ for (ICPPBase base : ClassTypeHelper.getBases(classType, point)) {
+ if (base.isVirtual())
+ return false;
+ }
+ ICPPClassType[] baseClasses = ClassTypeHelper.getAllBases(classType, point);
+ for (ICPPClassType baseClass : baseClasses) {
+ if (!isStandardLayout(baseClass, point))
+ return false;
+ if (firstNonStaticField != null) {
+ if (TypeTraits.hasNonStaticFields(baseClass, point))
+ return false;
+ if (firstNonStaticField.getType().isSameType(baseClass))
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * C++11: 9-10
+ */
+ public static boolean isPOD(IType type, IASTNode point) {
+ if (!isStandardLayout(type, point))
+ return false;
+ type = SemanticUtil.getNestedType(type, ARRAY | CVTYPE | TDEF);
+ if (!(type instanceof ICPPClassType))
+ return true;
+ return isTrivial((ICPPClassType) type, point);
+ }
+
+ /**
+ * 8.5.1 Aggregates [dcl.init.aggr]
+ * An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1),
+ * no private or protected non-static data members (Clause 11),
+ * no base classes (Clause 10), and no virtual functions (10.3).
+ */
+ public static boolean isAggregateClass(ICPPClassType classType, IASTNode point) {
+ if (ClassTypeHelper.getBases(classType, point).length > 0)
+ return false;
+ ICPPMethod[] methods = ClassTypeHelper.getDeclaredMethods(classType, point);
+ for (ICPPMethod m : methods) {
+ if (m instanceof ICPPConstructor)
+ return false;
+ if (m.isVirtual()) {
+ return false;
+ }
+ }
+ ICPPField[] fields = ClassTypeHelper.getDeclaredFields(classType, point);
+ for (ICPPField field : fields) {
+ if (!(field.getVisibility() == ICPPMember.v_public || field.isStatic())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns <code>true</code> if and only if the given class has a trivial copy constructor.
+ * A copy constructor is trivial if:
+ * <ul>
+ * <li>it is implicitly defined by the compiler, and</li>
+ * <li><code>isPolymorphic(classType) is false</code>, and</li>
+ * <li>the class has no virtual base classes, and</li>
+ * <li>every direct base class has trivial copy constructor, and</li>
+ * <li>for every nonstatic data member that has class type or array of class type, that type
+ * has trivial copy constructor.</li>
+ * </ul>
+ * Similar to <code>std::tr1::has_trivial_copy</code>.
+ *
+ * @param classType the class to check
+ * @return <code>true</code> if the class has a trivial copy constructor
+ */
+ public static boolean hasTrivialCopyCtor(ICPPClassType classType, IASTNode point) {
+ if (getImplicitCopyCtor(classType, point) == null)
+ return false;
+ if (isPolymorphic(classType, point))
+ return false;
+ for (ICPPBase base : ClassTypeHelper.getBases(classType, point)) {
+ if (base.isVirtual())
+ return false;
+ }
+ for (ICPPClassType baseClass : ClassTypeHelper.getAllBases(classType, point)) {
+ if (!classType.isSameType(baseClass) && !hasTrivialCopyCtor(baseClass, point))
+ return false;
+ }
+ for (ICPPField field : classType.getDeclaredFields()) {
+ if (!field.isStatic()) {
+ IType type = field.getType();
+ type = SemanticUtil.getNestedType(type, TDEF | CVTYPE | ARRAY);
+ if (type instanceof ICPPClassType && !classType.isSameType(type) &&
+ !hasTrivialCopyCtor((ICPPClassType) type, point)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns <code>true</code> if and only if the given class has a trivial default constructor.
+ * A default constructor is trivial if:
+ * <ul>
+ * <li>it is implicitly defined by the compiler, and</li>
+ * <li>every direct base class has trivial default constructor, and</li>
+ * <li>for every nonstatic data member that has class type or array of class type, that type
+ * has trivial default constructor.</li>
+ * </ul>
+ * Similar to <code>std::tr1::has_trivial_default_constructor</code>.
+ *
+ * @param classType the class to check
+ * @param point
+ * @return <code>true</code> if the class has a trivial default constructor
+ */
+ public static boolean hasTrivialDefaultConstructor(ICPPClassType classType, IASTNode point) {
+ for (ICPPConstructor ctor : ClassTypeHelper.getConstructors(classType, point)) {
+ if (!ctor.isImplicit() && ctor.getParameters().length == 0)
+ return false;
+ }
+ for (ICPPClassType baseClass : ClassTypeHelper.getAllBases(classType, null)) {
+ if (!classType.isSameType(baseClass) && !hasTrivialDefaultConstructor(baseClass, point))
+ return false;
+ }
+ for (ICPPField field : ClassTypeHelper.getDeclaredFields(classType, point)) {
+ if (!field.isStatic()) {
+ IType type = field.getType();
+ type = SemanticUtil.getNestedType(type, TDEF | CVTYPE | ARRAY);
+ if (type instanceof ICPPClassType && !classType.isSameType(type) &&
+ !hasTrivialDefaultConstructor((ICPPClassType) type, point)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns <code>true</code> if and only if the given class has a trivial destructor.
+ * A destructor is trivial if:
+ * <ul>
+ * <li>it is implicitly defined by the compiler, and</li>
+ * <li>every direct base class has trivial destructor, and</li>
+ * <li>for every nonstatic data member that has class type or array of class type, that type
+ * has trivial destructor.</li>
+ * </ul>
+ * Similar to <code>std::tr1::has_trivial_destructor</code>.
+ *
+ * @param classType the class to check
+ * @return <code>true</code> if the class has a trivial destructor
+ */
+ public static boolean hasTrivialDestructor(ICPPClassType classType, IASTNode point) {
+ for (ICPPMethod method : ClassTypeHelper.getDeclaredMethods(classType, point)) {
+ if (method.isDestructor())
+ return false;
+ }
+ for (ICPPClassType baseClass : ClassTypeHelper.getAllBases(classType, null)) {
+ if (!classType.isSameType(baseClass) && !hasTrivialDestructor(baseClass, point))
+ return false;
+ }
+ for (ICPPField field : ClassTypeHelper.getDeclaredFields(classType, point)) {
+ if (!field.isStatic()) {
+ IType type = field.getType();
+ type = SemanticUtil.getNestedType(type, TDEF | CVTYPE | ARRAY);
+ if (type instanceof ICPPClassType && !classType.isSameType(type) &&
+ !hasTrivialDestructor((ICPPClassType) type, point)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns <code>true</code> if and only if the given class declares or inherits a virtual
+ * function. Similar to <code>std::tr1::is_polymorphic</code>.
+ *
+ * @param classType the class to check
+ * @return <code>true</code> if the class declares or inherits a virtual function.
+ */
+ public static boolean isPolymorphic(ICPPClassType classType, IASTNode point) {
+ if (hasDeclaredVirtualMethod(classType, point))
+ return true;
+ for (ICPPClassType baseClass : ClassTypeHelper.getAllBases(classType, point)) {
+ if (hasDeclaredVirtualMethod(baseClass, point))
+ return true;
+ }
+ return false;
+ }
+
+ private static boolean hasNonStaticFields(ICPPClassType classType, IASTNode point) {
+ ICPPField[] fields = ClassTypeHelper.getDeclaredFields(classType, point);
+ for (ICPPField field : fields) {
+ if (!field.isStatic())
+ return true;
+ }
+ return false;
+ }
+
+ public static boolean isAbstract(ICPPClassType classType, IASTNode point) {
+ return ClassTypeHelper.getPureVirtualMethods(classType, point).length != 0;
+ }
+
+ /**
+ * Returns the compiler-generated copy constructor for the given class, or <code>null</code>
+ * if the class doesn't have a compiler-generated copy constructor.
+ *
+ * @param classType the class to get the copy ctor for.
+ * @return the compiler-generated copy constructor, or <code>null</code> if the class doesn't
+ * have a compiler-generated copy constructor.
+ */
+ private static ICPPConstructor getImplicitCopyCtor(ICPPClassType classType, IASTNode point) {
+ for (ICPPConstructor ctor : ClassTypeHelper.getConstructors(classType, point)) {
+ if (ctor.isImplicit() && ClassTypeHelper.getMethodKind(classType, ctor) == MethodKind.COPY_CTOR)
+ return ctor;
+ }
+ return null;
+ }
+
+ private static boolean hasDeclaredVirtualMethod(ICPPClassType classType, IASTNode point) {
+ for (ICPPMethod method : ClassTypeHelper.getDeclaredMethods(classType, point)) {
+ if (method.isVirtual()) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRGCCCompleteParseExtensionsTest.java b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRGCCCompleteParseExtensionsTest.java
index e689324df9..bb6b353501 100644
--- a/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRGCCCompleteParseExtensionsTest.java
+++ b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRGCCCompleteParseExtensionsTest.java
@@ -32,7 +32,7 @@ public class LRGCCCompleteParseExtensionsTest extends GCCCompleteParseExtensions
//override the test failed case for 342683
@Override
- public void testTypetraits_Bug342683() throws Exception {}
+ public void testTypeTraits_Bug342683() throws Exception {}
@Override

Back to the top