mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42:11 +02:00
Bug 411196 - Type traits that evaluate to a type
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>
This commit is contained in:
parent
afecac9ccd
commit
9d1233f05a
26 changed files with 576 additions and 13 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -721,6 +723,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
|
|||
return new CPPASTTypenameExpression(qualifiedName, expr);
|
||||
}
|
||||
|
||||
@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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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$
|
||||
|
|
Loading…
Add table
Reference in a new issue