summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Ridge2013-08-27 02:01:52 (EDT)
committer Sergey Prigogin2013-09-05 23:53:33 (EDT)
commit9d1233f05a4edcfa87c29ab0b88a360f2a7c7e0f (patch)
treef6377476b311795fb77fe9dba912e6fe1176dd29
parentafecac9ccd57dc3e593f282185b5380cc59fa884 (diff)
downloadorg.eclipse.cdt-9d1233f05a4edcfa87c29ab0b88a360f2a7c7e0f.zip
org.eclipse.cdt-9d1233f05a4edcfa87c29ab0b88a360f2a7c7e0f.tar.gz
org.eclipse.cdt-9d1233f05a4edcfa87c29ab0b88a360f2a7c7e0f.tar.bz2
Bug 411196 - Type traits that evaluate to a typerefs/changes/73/15873/4
Change-Id: Ic0772e5b6e27aade06f4100b1ce92f671f6ea4d5 Signed-off-by: Nathan Ridge <zeratul976@hotmail.com> Reviewed-on: https://git.eclipse.org/r/15873 Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com> IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com> Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java38
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java5
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java6
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexGPPBindingResolutionTest.java120
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java1
-rw-r--r--core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/TestScannerInfo.java7
-rw-r--r--core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/TestScannerProvider.java7
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ISemanticProblem.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTTypeTransformationSpecifier.java41
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java6
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPUnaryTypeTransformation.java45
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java6
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java1
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemType.java1
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeTransformationSpecifier.java77
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java11
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnaryTypeTransformation.java73
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java26
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java11
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java19
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java63
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java8
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java3
26 files changed, 576 insertions, 13 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
index 3a24358..029f08a 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
@@ -10358,4 +10358,42 @@ public class AST2CPPTests extends AST2TestBase {
public void testDecltypeInNameQualifier_bug380751() throws Exception {
parseAndCheckBindings();
}
+
+ // template <typename T>
+ // struct underlying_type {
+ // typedef __underlying_type(T) type;
+ // };
+ //
+ // enum class e_fixed_short1 : short;
+ // enum class e_fixed_short2 : short { a = 1, b = 2 };
+ //
+ // enum class e_scoped { a = 1, b = 2 };
+ //
+ // enum e_unsigned { a1 = 1, b1 = 2 };
+ // enum e_int { a2 = -1, b2 = 1 };
+ // enum e_ulong { a3 = 5000000000, b3 };
+ // enum e_long { a4 = -5000000000, b4 = 5000000000 };
+ //
+ // typedef underlying_type<e_fixed_short1>::type short1_type;
+ // typedef underlying_type<e_fixed_short2>::type short2_type;
+ //
+ // typedef underlying_type<e_scoped>::type scoped_type;
+ //
+ // typedef underlying_type<e_unsigned>::type unsigned_type;
+ // typedef underlying_type<e_int>::type int_type;
+ // typedef underlying_type<e_ulong>::type ulong_type;
+ // typedef underlying_type<e_long>::type loong_type;
+ public void testUnderlyingTypeBuiltin_bug411196() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertSameType((ITypedef) helper.assertNonProblem("short1_type"), CPPVisitor.SHORT_TYPE);
+ assertSameType((ITypedef) helper.assertNonProblem("short2_type"), CPPVisitor.SHORT_TYPE);
+
+ assertSameType((ITypedef) helper.assertNonProblem("scoped_type"), CPPVisitor.INT_TYPE);
+
+ assertSameType((ITypedef) helper.assertNonProblem("unsigned_type"), CPPVisitor.UNSIGNED_INT);
+ assertSameType((ITypedef) helper.assertNonProblem("int_type"), CPPVisitor.INT_TYPE);
+ assertSameType((ITypedef) helper.assertNonProblem("ulong_type"), CPPVisitor.UNSIGNED_LONG);
+ assertSameType((ITypedef) helper.assertNonProblem("loong_type"), CPPVisitor.LONG_TYPE);
+ }
}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java
index d8fdbd2..9d88bb2 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java
@@ -62,6 +62,7 @@ import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.c.ICASTTypeIdInitializerExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
+import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
import org.eclipse.cdt.core.dom.parser.IScannerExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.c.ANSICParserExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.c.GCCParserExtensionConfiguration;
@@ -114,8 +115,8 @@ public class AST2TestBase extends BaseTestCase {
private static Map<String, String> getGnuMap() {
Map<String, String> map= new HashMap<String, String>();
- map.put("__GNUC__", "4");
- map.put("__GNUC_MINOR__", "7");
+ map.put("__GNUC__", Integer.toString(GPPLanguage.GNU_LATEST_VERSION_MAJOR));
+ map.put("__GNUC_MINOR__", Integer.toString(GPPLanguage.GNU_LATEST_VERSION_MINOR));
map.put("__SIZEOF_SHORT__", "2");
map.put("__SIZEOF_INT__", "4");
map.put("__SIZEOF_LONG__", "8");
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java
index b006fd6..f8015f5 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java
@@ -767,4 +767,10 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
fail("Artificially failing - see IndexBindingResolutionTestBase.fakeFailForReferenced()");
}
}
+
+ protected static void assertSameType(IType first, IType second){
+ assertNotNull(first);
+ assertNotNull(second);
+ assertTrue("Expected types to be the same, but first was: '" + first.toString() + "' and second was: '" + second + "'", first.isSameType(second));
+ }
} \ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexGPPBindingResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexGPPBindingResolutionTest.java
new file mode 100644
index 0000000..a642cdf
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexGPPBindingResolutionTest.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Nathan Ridge.
+ * 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:
+ * Nathan Ridge - Initial implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.index.tests;
+
+import org.eclipse.cdt.core.dom.ast.ITypedef;
+import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
+import org.eclipse.cdt.core.testplugin.TestScannerProvider;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
+
+import junit.framework.TestSuite;
+
+/**
+ * For testing resolution of bindings in C++ code with GNU extensions.
+ */
+public abstract class IndexGPPBindingResolutionTest extends IndexBindingResolutionTestBase {
+
+ private static void gnuSetUp() {
+ TestScannerProvider.sDefinedSymbols.put("__GNUC__", Integer.toString(GPPLanguage.GNU_LATEST_VERSION_MAJOR));
+ TestScannerProvider.sDefinedSymbols.put("__GNUC_MINOR__", Integer.toString(GPPLanguage.GNU_LATEST_VERSION_MINOR));
+ }
+
+ private static void gnuTearDown() {
+ TestScannerProvider.clear();
+ }
+
+ public class GPPReferencedProject extends ReferencedProject {
+ public GPPReferencedProject() {
+ super(true /* cpp */);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ gnuSetUp();
+ super.setUp();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ gnuTearDown();
+ }
+ }
+
+ public class GPPSinglePDOMTestStrategy extends SinglePDOMTestStrategy {
+ public GPPSinglePDOMTestStrategy() {
+ super(true /* cpp */);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ gnuSetUp();
+ super.setUp();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ gnuTearDown();
+ }
+ }
+
+ public static class SingleProject extends IndexGPPBindingResolutionTest {
+ public SingleProject() { setStrategy(new GPPSinglePDOMTestStrategy()); }
+ public static TestSuite suite() { return suite(SingleProject.class); }
+ }
+
+ public static class ProjectWithDepProj extends IndexGPPBindingResolutionTest {
+ public ProjectWithDepProj() { setStrategy(new GPPReferencedProject()); }
+ public static TestSuite suite() { return suite(ProjectWithDepProj.class); }
+ }
+
+ public static void addTests(TestSuite suite) {
+ suite.addTest(SingleProject.suite());
+ suite.addTest(ProjectWithDepProj.suite());
+ }
+
+ // template <typename T>
+ // struct underlying_type {
+ // typedef __underlying_type(T) type;
+ // };
+ //
+ // enum class e_fixed_short1 : short;
+ // enum class e_fixed_short2 : short { a = 1, b = 2 };
+ //
+ // enum class e_scoped { a = 1, b = 2 };
+ //
+ // enum e_unsigned { a1 = 1, b1 = 2 };
+ // enum e_int { a2 = -1, b2 = 1 };
+ // enum e_ulong { a3 = 5000000000, b3 };
+ // enum e_long { a4 = -5000000000, b4 = 5000000000 };
+
+ // typedef underlying_type<e_fixed_short1>::type short1_type;
+ // typedef underlying_type<e_fixed_short2>::type short2_type;
+ //
+ // typedef underlying_type<e_scoped>::type scoped_type;
+ //
+ // typedef underlying_type<e_unsigned>::type unsigned_type;
+ // typedef underlying_type<e_int>::type int_type;
+ // typedef underlying_type<e_ulong>::type ulong_type;
+ // typedef underlying_type<e_long>::type loong_type;
+ public void testUnderlyingTypeBuiltin_bug411196() throws Exception {
+ assertSameType((ITypedef) getBindingFromASTName("short1_type", 0), CPPVisitor.SHORT_TYPE);
+ assertSameType((ITypedef) getBindingFromASTName("short2_type", 0), CPPVisitor.SHORT_TYPE);
+
+ assertSameType((ITypedef) getBindingFromASTName("scoped_type", 0), CPPVisitor.INT_TYPE);
+
+ assertSameType((ITypedef) getBindingFromASTName("unsigned_type", 0), CPPVisitor.UNSIGNED_INT);
+ assertSameType((ITypedef) getBindingFromASTName("int_type", 0), CPPVisitor.INT_TYPE);
+ assertSameType((ITypedef) getBindingFromASTName("ulong_type", 0), CPPVisitor.UNSIGNED_LONG);
+ assertSameType((ITypedef) getBindingFromASTName("loong_type", 0), CPPVisitor.LONG_TYPE);
+ }
+}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java
index 9ad5894..4bba224 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java
@@ -34,6 +34,7 @@ public class IndexTests extends TestSuite {
IndexCPPBindingResolutionBugs.addTests(suite);
IndexCPPBindingResolutionTest.addTests(suite);
+ IndexGPPBindingResolutionTest.addTests(suite);
IndexCPPTemplateResolutionTest.addTests(suite);
IndexCBindingResolutionBugs.addTests(suite);
IndexCBindingResolutionTest.addTests(suite);
diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/TestScannerInfo.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/TestScannerInfo.java
index 6235fbc..5732bf1 100644
--- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/TestScannerInfo.java
+++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/TestScannerInfo.java
@@ -21,16 +21,19 @@ public class TestScannerInfo extends ExtendedScannerInfo {
private String[] fIncludes;
private String[] fIncludeFiles;
private String[] fMacroFiles;
+ private Map<String, String> fDefinedSymbols;
- public TestScannerInfo(String[] includes, String[] macroFiles, String[] includeFiles) {
+ public TestScannerInfo(String[] includes, String[] macroFiles, String[] includeFiles,
+ Map<String, String> definedSymbols) {
fIncludes= includes;
fIncludeFiles= includeFiles;
fMacroFiles= macroFiles;
+ fDefinedSymbols= definedSymbols;
}
@Override
public Map getDefinedSymbols() {
- return Collections.emptyMap();
+ return fDefinedSymbols == null ? Collections.emptyMap() : fDefinedSymbols;
}
@Override
diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/TestScannerProvider.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/TestScannerProvider.java
index 6fa5de2..bc8f98a 100644
--- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/TestScannerProvider.java
+++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/TestScannerProvider.java
@@ -11,6 +11,9 @@
*******************************************************************************/
package org.eclipse.cdt.core.testplugin;
+import java.util.HashMap;
+import java.util.Map;
+
import org.eclipse.cdt.core.AbstractCExtension;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfoChangeListener;
@@ -21,15 +24,17 @@ public class TestScannerProvider extends AbstractCExtension implements IScannerI
public static String[] sIncludes;
public static String[] sIncludeFiles;
public static String[] sMacroFiles;
+ public static Map<String, String> sDefinedSymbols = new HashMap<String, String>();
public final static String SCANNER_ID = CTestPlugin.PLUGIN_ID + ".TestScanner";
public static void clear() {
sIncludes= sIncludeFiles= sMacroFiles= null;
+ sDefinedSymbols.clear();
}
@Override
public IScannerInfo getScannerInformation(IResource resource) {
- return new TestScannerInfo(sIncludes, sMacroFiles, sIncludeFiles);
+ return new TestScannerInfo(sIncludes, sMacroFiles, sIncludeFiles, sDefinedSymbols);
}
@Override
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ISemanticProblem.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ISemanticProblem.java
index ec7d620..9cb4d08 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ISemanticProblem.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ISemanticProblem.java
@@ -41,6 +41,10 @@ public interface ISemanticProblem {
int TYPE_CANNOT_DEDUCE_AUTO_TYPE = 10003;
int TYPE_UNKNOWN_FOR_EXPRESSION = 10004;
int TYPE_NOT_PERSISTED = 10005;
+ /**
+ * @since 5.6
+ */
+ int TYPE_ENUMERATION_EXPECTED = 10006;
/**
* Returns the ID of the problem.
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTTypeTransformationSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTTypeTransformationSpecifier.java
new file mode 100644
index 0000000..e367938
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTTypeTransformationSpecifier.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Nathan Ridge - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.dom.ast.cpp;
+
+import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation.Operator;
+
+/**
+ * A decl-specifier that represents the application of an intrinsic type
+ * transformation operator like __underlying_type(T). Intrinsic operators
+ * of this form take a type as input, and evaluate to a type.
+ *
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @since 5.6
+ */
+public interface ICPPASTTypeTransformationSpecifier extends ICPPASTDeclSpecifier {
+ /**
+ * <code>OPERAND</code> represents the relationship between an <code>ICPPASTTypeTransformationSpecifier</code> and
+ * its nested <code>IASTTypeId</code>.
+ */
+ public static final ASTNodeProperty OPERAND = new ASTNodeProperty("ICPPASTTypeTransformationSpecifier.OPERAND - type operand for ICPPASTTypeTransformationSpecifier"); //$NON-NLS-1$
+
+ /**
+ * Returns the type transformation operator being applied.
+ */
+ Operator getOperator();
+
+ /**
+ * Returns the type-id to which the type transformation operator is being applied.
+ */
+ ICPPASTTypeId getOperand();
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java
index 49db5b0..769e7aa 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java
@@ -28,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.INodeFactory;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation.Operator;
import org.eclipse.cdt.core.parser.IScanner;
/**
@@ -345,6 +346,11 @@ public interface ICPPNodeFactory extends INodeFactory {
@Deprecated
public ICPPASTTypenameExpression newTypenameExpression(IASTName qualifiedName, IASTExpression expr, boolean isTemplate);
+ /**
+ * @since 5.6
+ */
+ public ICPPASTTypeTransformationSpecifier newTypeTransformationSpecifier(Operator kind, ICPPASTTypeId typeId);
+
@Override
public ICPPASTUnaryExpression newUnaryExpression(int operator, IASTExpression operand);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPUnaryTypeTransformation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPUnaryTypeTransformation.java
new file mode 100644
index 0000000..72804ec
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPUnaryTypeTransformation.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Nathan Ridge - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.dom.ast.cpp;
+
+import org.eclipse.cdt.core.dom.ast.IType;
+
+/**
+ * A type used to represent the result of applying an unary
+ * type transformation operator like __underlying_type(T).
+ *
+ * This representation is only used when T is dependent (and thus
+ * we cannot evaluate the type transformation yet). If T is not
+ * dependent, we simply use the result of evaluating the type
+ * transformation.
+ *
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @since 5.6
+ */
+public interface ICPPUnaryTypeTransformation extends IType {
+ /**
+ * Identifies the type transformation operator being applied.
+ */
+ public enum Operator {
+ underlying_type // the integer type underlying an enumeration type
+ }
+
+ /**
+ * Returns the type transformation operator being applied.
+ */
+ Operator getOperator();
+
+ /**
+ * Returns the type to which the type transformation operator is being applied.
+ */
+ IType getOperand();
+} \ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java
index d4fbe2b..272ce3c 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java
@@ -40,6 +40,12 @@ public class GPPLanguage extends AbstractCLikeLanguage {
protected static final GPPParserExtensionConfiguration CPP_GNU_PARSER_EXTENSION= GPPParserExtensionConfiguration.getInstance();
public static final String ID = CCorePlugin.PLUGIN_ID + ".g++"; //$NON-NLS-1$
+ /**
+ * @since 5.6
+ */
+ public static final int GNU_LATEST_VERSION_MAJOR = 4,
+ GNU_LATEST_VERSION_MINOR = 7;
+
private static final GPPLanguage DEFAULT_INSTANCE = new GPPLanguage();
public static GPPLanguage getDefault() {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java
index 476a245..ee2fcc6 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java
@@ -34,7 +34,7 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu
private static GPPScannerExtensionConfiguration CONFIG_4_3= new GPPScannerExtensionConfiguration(VERSION_4_3);
private static GPPScannerExtensionConfiguration CONFIG_4_6= new GPPScannerExtensionConfiguration(VERSION_4_6);
private static GPPScannerExtensionConfiguration CONFIG_4_7= new GPPScannerExtensionConfiguration(VERSION_4_7);
-
+
public static GPPScannerExtensionConfiguration getInstance() {
return CONFIG;
}
@@ -106,6 +106,8 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu
if (version >= VERSION_4_7) {
addKeyword(GCCKeywords.cp__float128, IGCCToken.t__float128);
addKeyword(GCCKeywords.cp__int128, IGCCToken.t__int128);
+
+ addKeyword(GCCKeywords.cp__underlying_type, IGCCToken.tTT_underlying_type);
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java
index 88a057d..ee06067 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java
@@ -79,4 +79,8 @@ public class GCCKeywords {
cp__is_literal_type= "__is_literal_type".toCharArray(),
cp__is_standard_layout= "__is_standard_layout".toCharArray(),
cp__is_trivial= "__is_trivial".toCharArray();
+
+ /** @since 5.6 */
+ public static final char[]
+ cp__underlying_type= "__underlying_type".toCharArray();
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java
index a8a5d24..d253176 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java
@@ -47,4 +47,6 @@ public interface IGCCToken extends IToken {
/** @since 5.5 */ int t__int128= FIRST_RESERVED_IGCCToken + 25;
/** @since 5.5 */ int t__float128= FIRST_RESERVED_IGCCToken + 26;
+
+ /** @since 5.6 */ int tTT_underlying_type= FIRST_RESERVED_IGCCToken + 27;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java
index 3394c2f..d6f37f3 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java
@@ -38,6 +38,7 @@ public interface ITypeMarshalBuffer {
final static byte UNKNOWN_MEMBER_CLASS_INSTANCE = 0x0D;
final static byte DEFERRED_CLASS_INSTANCE = 0x0E;
final static byte ALIAS_TEMPLATE = 0x0F;
+ final static byte TYPE_TRANSFORMATION = 0x10;
// Can add more types up to 0x1C, after that it will collide with TypeMarshalBuffer.UNSTORABLE_TYPE.
final static byte
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemType.java
index 48d9b49..420d730 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemType.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemType.java
@@ -23,6 +23,7 @@ import org.eclipse.core.runtime.CoreException;
public class ProblemType implements IProblemType, ISerializableType {
public static final IType UNRESOLVED_NAME = new ProblemType(TYPE_UNRESOLVED_NAME);
public static final IType UNKNOWN_FOR_EXPRESSION = new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
+ public static final IType ENUMERATION_EXPECTED = new ProblemType(ISemanticProblem.TYPE_ENUMERATION_EXPECTED);
private final int fID;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeTransformationSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeTransformationSpecifier.java
new file mode 100644
index 0000000..a7b9e4c
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeTransformationSpecifier.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Nathan Ridge - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser.cpp;
+
+import org.eclipse.cdt.core.dom.ast.ASTVisitor;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeTransformationSpecifier;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation.Operator;
+
+/**
+ * Implementation of ICPPASTTypeTransformationSpecifier.
+ */
+public class CPPASTTypeTransformationSpecifier extends CPPASTBaseDeclSpecifier implements ICPPASTTypeTransformationSpecifier {
+ private Operator fOperator;
+ private ICPPASTTypeId fOperand;
+
+ public CPPASTTypeTransformationSpecifier(Operator operator, ICPPASTTypeId operand) {
+ fOperator = operator;
+ fOperand = operand;
+ fOperand.setParent(this);
+ fOperand.setPropertyInParent(OPERAND);
+ }
+
+ @Override
+ public ICPPASTDeclSpecifier copy() {
+ return copy(CopyStyle.withoutLocations);
+ }
+
+ @Override
+ public CPPASTTypeTransformationSpecifier copy(CopyStyle style) {
+ CPPASTTypeTransformationSpecifier copy = new CPPASTTypeTransformationSpecifier(fOperator, fOperand.copy(style));
+ return super.copy(copy, style);
+ }
+
+ @Override
+ public Operator getOperator() {
+ return fOperator;
+ }
+
+ @Override
+ public ICPPASTTypeId getOperand() {
+ return fOperand;
+ }
+
+ @Override
+ public boolean accept(ASTVisitor action) {
+ if (action.shouldVisitDeclSpecifiers) {
+ switch (action.visit(this)) {
+ case ASTVisitor.PROCESS_ABORT: return false;
+ case ASTVisitor.PROCESS_SKIP: return true;
+ default: break;
+ }
+ }
+
+ if (!fOperand.accept(action))
+ return false;
+
+ if (action.shouldVisitDeclSpecifiers) {
+ switch (action.leave(this)) {
+ case ASTVisitor.PROCESS_ABORT: return false;
+ case ASTVisitor.PROCESS_SKIP: return true;
+ default: break;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java
index 26a382a..ad83cf1 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java
@@ -14,7 +14,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTAttribute;
-import org.eclipse.cdt.core.dom.ast.IASTBinaryTypeIdExpression.Operator;
+import org.eclipse.cdt.core.dom.ast.IASTBinaryTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
@@ -108,12 +108,14 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTryBlockStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeIdExpression;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeTransformationSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.internal.core.dom.parser.ASTToken;
@@ -178,7 +180,7 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
}
@Override
- public IASTExpression newBinaryTypeIdExpression(Operator op, IASTTypeId type1, IASTTypeId type2) {
+ public IASTExpression newBinaryTypeIdExpression(IASTBinaryTypeIdExpression.Operator op, IASTTypeId type1, IASTTypeId type2) {
return new CPPASTBinaryTypeIdExpression(op, type1, type2);
}
@@ -722,6 +724,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
}
@Override
+ public ICPPASTTypeTransformationSpecifier newTypeTransformationSpecifier(ICPPUnaryTypeTransformation.Operator operator, ICPPASTTypeId operand) {
+ return new CPPASTTypeTransformationSpecifier(operator, operand);
+ }
+
+ @Override
public ICPPASTUnaryExpression newUnaryExpression(int operator, IASTExpression operand) {
return new CPPASTUnaryExpression(operator, operand);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnaryTypeTransformation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnaryTypeTransformation.java
new file mode 100644
index 0000000..9e4287d
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnaryTypeTransformation.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Nathan Ridge - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser.cpp;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.ast.IType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation;
+import org.eclipse.cdt.internal.core.dom.parser.ISerializableType;
+import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * Implementation of ICPPUnaryTypeTransformation.
+ *
+ */
+public class CPPUnaryTypeTransformation implements ICPPUnaryTypeTransformation, ISerializableType {
+ Operator fOperator;
+ IType fOperand;
+
+ public CPPUnaryTypeTransformation(Operator operator, IType operand) {
+ fOperator = operator;
+ fOperand = operand;
+ }
+
+ @Override
+ public boolean isSameType(IType other) {
+ if (this == other)
+ return false;
+ if (!(other instanceof ICPPUnaryTypeTransformation))
+ return false;
+ ICPPUnaryTypeTransformation otherType = (ICPPUnaryTypeTransformation) other;
+ return getOperator() == otherType.getOperator()
+ && getOperand().isSameType(otherType.getOperand());
+ }
+
+ @Override
+ public Operator getOperator() {
+ return fOperator;
+ }
+
+ @Override
+ public IType getOperand() {
+ return fOperand;
+ }
+
+ @Override
+ public CPPUnaryTypeTransformation clone() {
+ return new CPPUnaryTypeTransformation(fOperator, (IType) fOperand.clone());
+ }
+
+ @Override
+ public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
+ buffer.putShort(ITypeMarshalBuffer.TYPE_TRANSFORMATION);
+ buffer.putByte((byte) getOperator().ordinal());
+ buffer.marshalType(getOperand());
+ }
+
+ public static IType unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException {
+ int operator = buffer.getByte();
+ if (operator >= Operator.values().length)
+ throw new CoreException(CCorePlugin.createStatus(
+ "Cannot unmarshal CPPUnaryTypeTransformation - unrecognized type transformation operator")); //$NON-NLS-1$
+ return new CPPUnaryTypeTransformation(Operator.values()[operator], buffer.unmarshalType());
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
index 694cb93..71d7c47 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
@@ -30,7 +30,6 @@ import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTAttribute;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryTypeIdExpression;
-import org.eclipse.cdt.core.dom.ast.IASTBinaryTypeIdExpression.Operator;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
@@ -123,11 +122,13 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTryBlockStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeIdExpression;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeTransformationSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation;
import org.eclipse.cdt.core.dom.parser.IExtensionToken;
import org.eclipse.cdt.core.dom.parser.cpp.ICPPParserExtensionConfiguration;
import org.eclipse.cdt.core.index.IIndex;
@@ -1382,7 +1383,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return false;
}
- private Operator getBinaryTypeTraitOperator(IToken first) {
+ private IASTBinaryTypeIdExpression.Operator getBinaryTypeTraitOperator(IToken first) {
switch (first.getType()) {
case IGCCToken.tTT_is_base_of:
return IASTBinaryTypeIdExpression.Operator.__is_base_of;
@@ -3037,6 +3038,15 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
encounteredTypename= true;
break;
+
+ case IGCCToken.tTT_underlying_type:
+ if (encounteredRawType || encounteredTypename)
+ throwBacktrack(LA(1));
+
+ result= typeTransformationSpecifier(DeclarationOptions.TYPEID);
+ endOffset= calculateEndOffset(result);
+ encounteredTypename= true;
+ break;
default:
if (lt1 >= IExtensionToken.t__otherDeclSpecModifierFirst && lt1 <= IExtensionToken.t__otherDeclSpecModifierLast) {
@@ -3229,6 +3239,18 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
IASTName name = qualifiedName();
return setRange(nodeFactory.newElaboratedTypeSpecifier(eck, name), offset, calculateEndOffset(name));
}
+
+ /**
+ * Parse a type transformation specifier.
+ */
+ protected ICPPASTTypeTransformationSpecifier typeTransformationSpecifier(DeclarationOptions options)
+ throws BacktrackException, EndOfFileException {
+ final int offset = consume(IGCCToken.tTT_underlying_type).getOffset();
+ consume(IToken.tLPAREN);
+ ICPPASTTypeId operand = typeId(options);
+ final int endOffset = consumeOrEOC(IToken.tRPAREN).getEndOffset();
+ return setRange(nodeFactory.newTypeTransformationSpecifier(ICPPUnaryTypeTransformation.Operator.underlying_type, operand), offset, endOffset);
+ }
@Override
protected IASTDeclarator initDeclarator(IASTDeclSpecifier declspec, DeclarationOptions option)
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
index e5cf9c4..4b40442 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
@@ -97,6 +97,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
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.ICPPUnaryTypeTransformation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
@@ -165,6 +166,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.Context;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMode;
+
/**
* Collection of static methods to perform template instantiation, member specialization and
* type instantiation.
@@ -1355,6 +1357,15 @@ public class CPPTemplates {
return typeContainer;
}
+ if (type instanceof ICPPUnaryTypeTransformation) {
+ ICPPUnaryTypeTransformation typeTransformation = (ICPPUnaryTypeTransformation) type;
+ IType operand = instantiateType(typeTransformation.getOperand(), tpMap, packOffset, within, point);
+ switch (typeTransformation.getOperator()) {
+ case underlying_type: return TypeTraits.underlyingType(operand);
+ default: return null; // shouldn't happen
+ }
+ }
+
return type;
} catch (DOMException e) {
return e.getProblem();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
index ac04f9e..57a2339 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
@@ -137,6 +137,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeTransformationSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
@@ -206,6 +207,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnaryTypeTransformation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedef;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownTypeScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable;
@@ -219,9 +221,17 @@ import org.eclipse.cdt.internal.core.index.IIndexScope;
* Collection of methods to extract information from a C++ translation unit.
*/
public class CPPVisitor extends ASTQueries {
- private static final CPPBasicType INT_TYPE = new CPPBasicType(Kind.eInt, 0);
- private static final CPPBasicType LONG_TYPE = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG);
- private static final CPPBasicType UNSIGNED_LONG = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.IS_UNSIGNED);
+ public static final CPPBasicType SHORT_TYPE = new CPPBasicType(Kind.eInt, IBasicType.IS_SHORT);
+ public static final CPPBasicType INT_TYPE = new CPPBasicType(Kind.eInt, 0);
+ public static final CPPBasicType LONG_TYPE = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG);
+ public static final CPPBasicType LONG_LONG_TYPE = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG_LONG);
+ public static final CPPBasicType INT128_TYPE = new CPPBasicType(Kind.eInt128, 0);
+
+ public static final CPPBasicType UNSIGNED_SHORT = new CPPBasicType(Kind.eInt, IBasicType.IS_SHORT | IBasicType.IS_UNSIGNED);
+ public static final CPPBasicType UNSIGNED_INT = new CPPBasicType(Kind.eInt, IBasicType.IS_UNSIGNED);
+ public static final CPPBasicType UNSIGNED_LONG = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.IS_UNSIGNED);
+ public static final CPPBasicType UNSIGNED_LONG_LONG = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG_LONG | IBasicType.IS_UNSIGNED);
+ public static final CPPBasicType UNSIGNED_INT128 = new CPPBasicType(Kind.eInt128, IBasicType.IS_UNSIGNED);
public static final String BEGIN_STR = "begin"; //$NON-NLS-1$
public static final char[] BEGIN = BEGIN_STR.toCharArray();
@@ -2146,6 +2156,9 @@ public class CPPVisitor extends ASTQueries {
name = ((ICPPASTElaboratedTypeSpecifier) declSpec).getName();
} else if (declSpec instanceof IASTEnumerationSpecifier) {
name = ((IASTEnumerationSpecifier) declSpec).getName();
+ } else if (declSpec instanceof ICPPASTTypeTransformationSpecifier) {
+ ICPPASTTypeTransformationSpecifier spec = (ICPPASTTypeTransformationSpecifier) declSpec;
+ return new CPPUnaryTypeTransformation(spec.getOperator(), createType(spec.getOperand()));
} else if (declSpec instanceof ICPPASTSimpleDeclSpecifier) {
ICPPASTSimpleDeclSpecifier spec = (ICPPASTSimpleDeclSpecifier) declSpec;
// Check for decltype(expr)
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
index d02dfdc..d5493be 100644
--- 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
@@ -15,15 +15,22 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
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.IBasicType;
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.ICPPBasicType;
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.ICPPEnumeration;
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.core.dom.ast.cpp.ICPPUnaryTypeTransformation.Operator;
import org.eclipse.cdt.core.dom.ast.cpp.SemanticQueries;
+import org.eclipse.cdt.internal.core.dom.parser.ArithmeticConversion;
+import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnaryTypeTransformation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper.MethodKind;
@@ -326,4 +333,60 @@ public class TypeTraits {
}
return false;
}
+
+ public static IType underlyingType(IType type) {
+ if (CPPTemplates.isDependentType(type)) {
+ return new CPPUnaryTypeTransformation(Operator.underlying_type, type);
+ } else if (!(type instanceof ICPPEnumeration)) {
+ return ProblemType.ENUMERATION_EXPECTED;
+ } else {
+ ICPPEnumeration enumeration = (ICPPEnumeration) type;
+
+ // [dcl.enum] p5
+ // "The underlying type can be explicitly specified using enum-base;
+ // if not explicitly specified, the underlying type of a scoped
+ // enumeration type is int."
+ IType fixedType = enumeration.getFixedType();
+ if (fixedType != null)
+ return fixedType;
+ if (enumeration.isScoped())
+ return CPPVisitor.INT_TYPE;
+
+ // [dcl.enum] p6
+ // "For an enumeration whose underlying type is not fixed, the
+ // underlying type is an integral type that can represent all
+ // the numerator values defined in the enumeration. ... It is
+ // implementation-defined which integral type is used as the
+ // underlying type except that the underlying type shall not be
+ // larger than int unless the value of an enumerator cannot fit
+ // in an int or unsigned int. If the enumerator-list is empty,
+ // the underlying type is as if the enumeration had a single
+ // enumerator with value 0."
+ if (enumeration.getEnumerators().length == 0)
+ return CPPVisitor.INT_TYPE;
+ if (enumeration.getMinValue() < 0 || enumeration.getMaxValue() < 0) {
+ return smallestFittingType(enumeration,
+ CPPVisitor.INT_TYPE,
+ CPPVisitor.LONG_TYPE,
+ CPPVisitor.LONG_LONG_TYPE,
+ CPPVisitor.INT128_TYPE);
+ } else {
+ return smallestFittingType(enumeration,
+ CPPVisitor.UNSIGNED_INT,
+ CPPVisitor.UNSIGNED_LONG,
+ CPPVisitor.UNSIGNED_LONG_LONG,
+ CPPVisitor.UNSIGNED_INT128);
+ }
+ }
+ }
+
+ private static IBasicType smallestFittingType(ICPPEnumeration enumeration, ICPPBasicType... types) {
+ for (int i = 0; i < types.length - 1; ++i) {
+ if (ArithmeticConversion.fitsIntoType(types[i], enumeration.getMinValue())
+ && ArithmeticConversion.fitsIntoType(types[i], enumeration.getMaxValue())) {
+ return types[i];
+ }
+ }
+ return types[types.length - 1]; // assume it fits into the largest type provided
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java
index 95753c0..67e611b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java
@@ -52,6 +52,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
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.ICPPUnaryTypeTransformation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.core.index.IIndex;
@@ -65,6 +66,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnaryTypeTransformation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
@@ -223,6 +225,12 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
return new TypeOfDependentExpression(e2);
return tde;
}
+ if (rtype instanceof ICPPUnaryTypeTransformation) {
+ ICPPUnaryTypeTransformation ttt= (ICPPUnaryTypeTransformation) rtype;
+ IType operand = ttt.getOperand();
+ IType operand2 = getCompositeType(operand);
+ return new CPPUnaryTypeTransformation(ttt.getOperator(), operand2);
+ }
if (rtype instanceof IBasicType || rtype == null || rtype instanceof ISemanticProblem) {
return rtype;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
index 716725a..b089140 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
@@ -93,6 +93,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnaryTypeTransformation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMember;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
@@ -1197,6 +1198,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
return CPPDeferredClassInstance.unmarshal(getPDOM(), firstBytes, buffer);
case ITypeMarshalBuffer.ALIAS_TEMPLATE:
return CPPAliasTemplateInstance.unmarshal(firstBytes, buffer);
+ case ITypeMarshalBuffer.TYPE_TRANSFORMATION:
+ return CPPUnaryTypeTransformation.unmarshal(firstBytes, buffer);
}
throw new CoreException(CCorePlugin.createStatus("Cannot unmarshal a type, first bytes=" + firstBytes)); //$NON-NLS-1$