mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-06 17:26:01 +02:00
Bug 485713 - Parser support for new type trait intrinsics in GCC 5
Change-Id: I1c0d41c01c921f701c58b2eee342c63de607d1d7 Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
This commit is contained in:
parent
59765dc380
commit
a5348a47ba
18 changed files with 292 additions and 16 deletions
|
@ -10583,6 +10583,19 @@ public class AST2CPPTests extends AST2TestBase {
|
|||
assertTrue(foo.isFinal());
|
||||
}
|
||||
|
||||
// struct S {};
|
||||
// bool b1 = __is_trivially_copyable(S);
|
||||
// bool b2 = __is_trivially_assignable(S, S&);
|
||||
// bool b3 = __is_trivially_constructible(S, int, char*);
|
||||
// // Test that __is_trivially_constructible can take parameter packs
|
||||
// template <typename... Args>
|
||||
// struct U {
|
||||
// static const bool value = __is_trivially_constructible(S, Args...);
|
||||
// };
|
||||
public void testParsingOfGcc5TypeTraitIntrinsics_485713() throws Exception {
|
||||
parseAndCheckBindings(getAboveComment(), CPP, true /* use GNU extensions */);
|
||||
}
|
||||
|
||||
// struct S1 {};
|
||||
// S1 s1;
|
||||
// const int i= 1;
|
||||
|
|
|
@ -66,7 +66,6 @@ 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;
|
||||
|
@ -147,8 +146,8 @@ public class AST2TestBase extends BaseTestCase {
|
|||
|
||||
private static Map<String, String> getGnuMap() {
|
||||
Map<String, String> map= new HashMap<>();
|
||||
map.put("__GNUC__", Integer.toString(GPPLanguage.GNU_LATEST_VERSION_MAJOR));
|
||||
map.put("__GNUC_MINOR__", Integer.toString(GPPLanguage.GNU_LATEST_VERSION_MINOR));
|
||||
map.put("__GNUC__", Integer.toString(GCC_MAJOR_VERSION_FOR_TESTS));
|
||||
map.put("__GNUC_MINOR__", Integer.toString(GCC_MINOR_VERSION_FOR_TESTS));
|
||||
map.put("__SIZEOF_SHORT__", "2");
|
||||
map.put("__SIZEOF_INT__", "4");
|
||||
map.put("__SIZEOF_LONG__", "8");
|
||||
|
|
|
@ -12,7 +12,6 @@ package org.eclipse.cdt.internal.index.tests;
|
|||
|
||||
import org.eclipse.cdt.core.dom.ast.IField;
|
||||
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.CPPBasicType;
|
||||
|
||||
|
@ -24,8 +23,8 @@ import junit.framework.TestSuite;
|
|||
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));
|
||||
TestScannerProvider.sDefinedSymbols.put("__GNUC__", Integer.toString(GCC_MAJOR_VERSION_FOR_TESTS));
|
||||
TestScannerProvider.sDefinedSymbols.put("__GNUC_MINOR__", Integer.toString(GCC_MINOR_VERSION_FOR_TESTS));
|
||||
}
|
||||
|
||||
private static void gnuTearDown() {
|
||||
|
|
|
@ -64,6 +64,13 @@ public class BaseTestCase extends TestCase {
|
|||
Integer.parseInt(System.getProperty(INDEXER_TIMEOUT_PROPERTY, DEFAULT_INDEXER_TIMEOUT_SEC));
|
||||
protected static final int INDEXER_TIMEOUT_MILLISEC= INDEXER_TIMEOUT_SEC * 1000;
|
||||
|
||||
/**
|
||||
* The GCC version to emulate when running tests.
|
||||
* We emulate the latest version whose extensions we support.
|
||||
*/
|
||||
protected static final int GCC_MAJOR_VERSION_FOR_TESTS = 5;
|
||||
protected static final int GCC_MINOR_VERSION_FOR_TESTS = 1;
|
||||
|
||||
private boolean fExpectFailure;
|
||||
private int fBugNumber;
|
||||
private int fExpectedLoggedNonOK;
|
||||
|
|
|
@ -20,9 +20,13 @@ public interface IASTBinaryTypeIdExpression extends IASTExpression {
|
|||
public static final ASTNodeProperty OPERAND2 = new ASTNodeProperty("IASTBinaryTypeIdExpression.OPERAND2 [IASTTypeId]"); //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Built-in type trait of g++.
|
||||
* Built-in type traits of g++.
|
||||
*/
|
||||
public static enum Operator {__is_base_of}
|
||||
public static enum Operator {
|
||||
__is_base_of,
|
||||
/** @since 5.12 */
|
||||
__is_trivially_assignable
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the operator for the expression.
|
||||
|
|
|
@ -158,6 +158,12 @@ public interface IASTTypeIdExpression extends IASTExpression {
|
|||
*/
|
||||
public static final int op_is_final= 23;
|
||||
|
||||
/**
|
||||
* Built-in type trait of g++.
|
||||
* @since 5.12
|
||||
*/
|
||||
public static final int op_is_trivially_copyable = 24;
|
||||
|
||||
/**
|
||||
* @deprecated constants should be declared here, to avoid using the same constant in different
|
||||
* interfaces.
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2016 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 API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||
|
||||
/**
|
||||
* A type-id expression with any number of arguments.
|
||||
* Example: __is_trivially_constructible(MyClass, int, float)
|
||||
*
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
* @since 5.12
|
||||
*/
|
||||
public interface ICPPASTNaryTypeIdExpression extends ICPPASTExpression {
|
||||
public static final ASTNodeProperty OPERAND = new ASTNodeProperty("ICPPASTNaryTypeIdExpression.OPERAND [IASTTypeId]"); //$NON-NLS-1$
|
||||
|
||||
public static enum Operator {
|
||||
__is_trivially_constructible
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the operator of the expression.
|
||||
*/
|
||||
public Operator getOperator();
|
||||
|
||||
/**
|
||||
* Returns the operands of the expression.
|
||||
*/
|
||||
public ICPPASTTypeId[] getOperands();
|
||||
|
||||
@Override
|
||||
public ICPPASTNaryTypeIdExpression copy();
|
||||
|
||||
@Override
|
||||
public ICPPASTNaryTypeIdExpression copy(CopyStyle style);
|
||||
}
|
|
@ -262,6 +262,12 @@ public interface ICPPNodeFactory extends INodeFactory {
|
|||
|
||||
public ICPPASTNamespaceDefinition newNamespaceDefinition(IASTName name);
|
||||
|
||||
/**
|
||||
* @since 5.12
|
||||
*/
|
||||
public ICPPASTNaryTypeIdExpression newNaryTypeIdExpression(ICPPASTNaryTypeIdExpression.Operator operator,
|
||||
ICPPASTTypeId[] operands);
|
||||
|
||||
/**
|
||||
* @deprecated Replaced by {@link #newNewExpression(IASTInitializerClause[], IASTInitializer, IASTTypeId)}
|
||||
*/
|
||||
|
|
|
@ -41,9 +41,17 @@ 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 */
|
||||
/**
|
||||
* @since 5.6
|
||||
* @deprecated This was meant for internal use only.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int GNU_LATEST_VERSION_MAJOR = 4;
|
||||
/** @since 5.6 */
|
||||
/**
|
||||
* @since 5.6
|
||||
* @deprecated This was meant for internal use only.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int GNU_LATEST_VERSION_MINOR = 7;
|
||||
|
||||
private static final GPPLanguage DEFAULT_INSTANCE = new GPPLanguage();
|
||||
|
|
|
@ -32,11 +32,13 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu
|
|||
private static final int VERSION_4_3 = version(4, 3);
|
||||
private static final int VERSION_4_6 = version(4, 6);
|
||||
private static final int VERSION_4_7 = version(4, 7);
|
||||
private static final int VERSION_5_0 = version(5, 0);
|
||||
private static GPPScannerExtensionConfiguration CONFIG= new GPPScannerExtensionConfiguration();
|
||||
private static GPPScannerExtensionConfiguration CONFIG_4_2= new GPPScannerExtensionConfiguration(VERSION_4_2);
|
||||
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);
|
||||
private static GPPScannerExtensionConfiguration CONFIG_5_0= new GPPScannerExtensionConfiguration(VERSION_5_0);
|
||||
|
||||
public static GPPScannerExtensionConfiguration getInstance() {
|
||||
return CONFIG;
|
||||
|
@ -52,6 +54,9 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu
|
|||
int major= Integer.valueOf(definedSymbols.get("__GNUC__")); //$NON-NLS-1$
|
||||
int minor= Integer.valueOf(definedSymbols.get("__GNUC_MINOR__")); //$NON-NLS-1$
|
||||
int version= version(major, minor);
|
||||
if (version >= VERSION_5_0) {
|
||||
return CONFIG_5_0;
|
||||
}
|
||||
if (version >= VERSION_4_7) {
|
||||
return CONFIG_4_7;
|
||||
}
|
||||
|
@ -120,6 +125,11 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu
|
|||
addKeyword(GCCKeywords.cp__is_final, IGCCToken.tTT_is_final);
|
||||
addKeyword(GCCKeywords.cp__underlying_type, IGCCToken.tTT_underlying_type);
|
||||
}
|
||||
if (version >= VERSION_5_0) {
|
||||
addKeyword(GCCKeywords.cp__is_trivially_copyable, IGCCToken.tTT_is_trivially_copyable);
|
||||
addKeyword(GCCKeywords.cp__is_trivially_constructible, IGCCToken.tTT_is_trivially_constructible);
|
||||
addKeyword(GCCKeywords.cp__is_trivially_assignable, IGCCToken.tTT_is_trivially_assignable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -102,4 +102,10 @@ public class GCCKeywords {
|
|||
cp_decimal32= _DECIMAL32.toCharArray(),
|
||||
cp_decimal64= _DECIMAL64.toCharArray(),
|
||||
cp_decimal128= _DECIMAL128.toCharArray();
|
||||
|
||||
/** @since 5.12 */
|
||||
public static final char[]
|
||||
cp__is_trivially_copyable= "__is_trivially_copyable".toCharArray(),
|
||||
cp__is_trivially_constructible= "__is_trivially_constructible".toCharArray(),
|
||||
cp__is_trivially_assignable= "__is_trivially_assignable".toCharArray();
|
||||
}
|
||||
|
|
|
@ -54,4 +54,8 @@ public interface IGCCToken extends IToken {
|
|||
/** @since 5.10 */ int t_decimal32= FIRST_RESERVED_IGCCToken + 29;
|
||||
/** @since 5.10 */ int t_decimal64= FIRST_RESERVED_IGCCToken + 30;
|
||||
/** @since 5.10 */ int t_decimal128= FIRST_RESERVED_IGCCToken + 31;
|
||||
|
||||
/** @since 5.12 */ int tTT_is_trivially_copyable= FIRST_RESERVED_IGCCToken + 32;
|
||||
/** @since 5.12 */ int tTT_is_trivially_constructible= FIRST_RESERVED_IGCCToken + 33;
|
||||
/** @since 5.12 */ int tTT_is_trivially_assignable= FIRST_RESERVED_IGCCToken + 34;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_pod;
|
|||
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_polymorphic;
|
||||
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_standard_layout;
|
||||
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_trivial;
|
||||
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_trivially_copyable;
|
||||
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_union;
|
||||
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_sizeof;
|
||||
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_typeid;
|
||||
|
@ -350,6 +351,8 @@ public class Value implements IValue {
|
|||
case op_is_trivial:
|
||||
return type instanceof ICPPClassType &&
|
||||
TypeTraits.isTrivial((ICPPClassType) type, point) ? 1 : 0;
|
||||
case op_is_trivially_copyable:
|
||||
break; // TODO: Implement
|
||||
case op_is_union:
|
||||
return type instanceof ICompositeType &&
|
||||
((ICompositeType) type).getKey() == ICompositeType.k_union ? 1 : 0;
|
||||
|
@ -371,6 +374,8 @@ public class Value implements IValue {
|
|||
return 1;
|
||||
}
|
||||
return 0;
|
||||
case __is_trivially_assignable:
|
||||
return VALUE_CANNOT_BE_DETERMINED; // TODO: Implement.
|
||||
}
|
||||
return VALUE_CANNOT_BE_DETERMINED;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2016 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 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.IASTImplicitDestructorName;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNaryTypeIdExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
|
||||
|
||||
public class CPPASTNaryTypeIdExpression extends ASTNode implements ICPPASTNaryTypeIdExpression {
|
||||
private Operator fOperator;
|
||||
private ICPPASTTypeId[] fOperands;
|
||||
|
||||
public CPPASTNaryTypeIdExpression(Operator operator, ICPPASTTypeId[] operands) {
|
||||
fOperator = operator;
|
||||
fOperands = operands;
|
||||
for (ICPPASTTypeId operand : fOperands) {
|
||||
operand.setParent(this);
|
||||
operand.setPropertyInParent(OPERAND);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPASTNaryTypeIdExpression copy() {
|
||||
return copy(CopyStyle.withoutLocations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPASTNaryTypeIdExpression copy(CopyStyle style) {
|
||||
ICPPASTTypeId[] operands = new ICPPASTTypeId[fOperands.length];
|
||||
for (int i = 0; i < fOperands.length; ++i) {
|
||||
operands[i] = fOperands[i].copy(style);
|
||||
}
|
||||
CPPASTNaryTypeIdExpression copy = new CPPASTNaryTypeIdExpression(fOperator, operands);
|
||||
return copy(copy, style);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Operator getOperator() {
|
||||
return fOperator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPASTTypeId[] getOperands() {
|
||||
return fOperands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(ASTVisitor action) {
|
||||
if (action.shouldVisitExpressions) {
|
||||
switch (action.visit(this)) {
|
||||
case ASTVisitor.PROCESS_ABORT: return false;
|
||||
case ASTVisitor.PROCESS_SKIP: return true;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
for (ICPPASTTypeId operand : fOperands) {
|
||||
if (!operand.accept(action)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (action.shouldVisitExpressions && action.leave(this) == ASTVisitor.PROCESS_ABORT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPEvaluation getEvaluation() {
|
||||
// TODO: Implement. This will need a new evaluation type, EvalNaryTypeId.
|
||||
return EvalFixed.INCOMPLETE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType getExpressionType() {
|
||||
// TODO: When getEvaluation() is implemented, delegate to getEvaluation().getType().
|
||||
return CPPBasicType.BOOLEAN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLValue() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueCategory getValueCategory() {
|
||||
return ValueCategory.PRVALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
|
||||
// N-ary type-id expressions don't call destructors.
|
||||
return IASTImplicitDestructorName.EMPTY_NAME_ARRAY;
|
||||
}
|
||||
}
|
|
@ -99,6 +99,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNaryTypeIdExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNaryTypeIdExpression.Operator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression;
|
||||
|
@ -570,6 +572,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
|
|||
return new CPPASTNamespaceDefinition(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPASTNaryTypeIdExpression newNaryTypeIdExpression(Operator operator, ICPPASTTypeId[] operands) {
|
||||
return new CPPASTNaryTypeIdExpression(operator, operands);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public ICPPASTNewExpression newNewExpression(IASTExpression placement, IASTExpression initializer, IASTTypeId typeId) {
|
||||
|
|
|
@ -118,6 +118,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNaryTypeIdExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpandable;
|
||||
|
@ -1488,6 +1489,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
case IGCCToken.tTT_is_standard_layout:
|
||||
case IGCCToken.tTT_is_trivial:
|
||||
case IGCCToken.tTT_is_union:
|
||||
case IGCCToken.tTT_is_trivially_copyable:
|
||||
case IGCCToken.tTT_is_trivially_constructible:
|
||||
case IGCCToken.tTT_is_trivially_assignable:
|
||||
return parseTypeTrait();
|
||||
|
||||
default:
|
||||
|
@ -1498,22 +1502,39 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
private IASTExpression parseTypeTrait() throws EndOfFileException, BacktrackException {
|
||||
IToken first= consume();
|
||||
final boolean isBinary= isBinaryTrait(first);
|
||||
final boolean isNary = isNaryTrait(first);
|
||||
|
||||
consume(IToken.tLPAREN);
|
||||
IASTTypeId typeId= typeId(DeclarationOptions.TYPEID);
|
||||
IASTTypeId secondTypeId= null;
|
||||
ICPPASTTypeId[] operands = new ICPPASTTypeId[isBinary ? 2 : 1];
|
||||
operands[0] = typeId(DeclarationOptions.TYPEID);
|
||||
if (isBinary) {
|
||||
consumeOrEOC(IToken.tCOMMA);
|
||||
if (LT(1) != IToken.tEOC) {
|
||||
secondTypeId= typeId(DeclarationOptions.TYPEID);
|
||||
operands[1] = typeId(DeclarationOptions.TYPEID);
|
||||
}
|
||||
} else if (isNary) {
|
||||
while (LTcatchEOF(1) == IToken.tCOMMA) {
|
||||
consume();
|
||||
if (LT(1) != IToken.tEOC) {
|
||||
ICPPASTTypeId operand = typeId(DeclarationOptions.TYPEID);
|
||||
// n-ary type traits can contain pack expansions
|
||||
if (LT(1) == IToken.tELLIPSIS) {
|
||||
addPackExpansion(operand, consume());
|
||||
}
|
||||
operands = ArrayUtil.append(operands, operand);
|
||||
}
|
||||
}
|
||||
operands = ArrayUtil.removeNulls(operands);
|
||||
}
|
||||
int endOffset= consumeOrEOC(IToken.tRPAREN).getEndOffset();
|
||||
IASTExpression result;
|
||||
if (isBinary) {
|
||||
result= getNodeFactory().newBinaryTypeIdExpression(getBinaryTypeTraitOperator(first), typeId, secondTypeId);
|
||||
if (isNary) {
|
||||
result= getNodeFactory().newNaryTypeIdExpression(getNaryTypeTraitOperator(first), operands);
|
||||
} else if (isBinary) {
|
||||
result= getNodeFactory().newBinaryTypeIdExpression(getBinaryTypeTraitOperator(first), operands[0],
|
||||
operands[1]);
|
||||
} else {
|
||||
result= getNodeFactory().newTypeIdExpression(getUnaryTypeTraitOperator(first), typeId);
|
||||
result= getNodeFactory().newTypeIdExpression(getUnaryTypeTraitOperator(first), operands[0]);
|
||||
}
|
||||
return setRange(result, first.getOffset(), endOffset);
|
||||
}
|
||||
|
@ -1521,6 +1542,15 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
private boolean isBinaryTrait(IToken first) {
|
||||
switch (first.getType()) {
|
||||
case IGCCToken.tTT_is_base_of:
|
||||
case IGCCToken.tTT_is_trivially_assignable:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isNaryTrait(IToken operatorToken) {
|
||||
switch (operatorToken.getType()) {
|
||||
case IGCCToken.tTT_is_trivially_constructible:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1530,6 +1560,18 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
switch (first.getType()) {
|
||||
case IGCCToken.tTT_is_base_of:
|
||||
return IASTBinaryTypeIdExpression.Operator.__is_base_of;
|
||||
case IGCCToken.tTT_is_trivially_assignable:
|
||||
return IASTBinaryTypeIdExpression.Operator.__is_trivially_assignable;
|
||||
}
|
||||
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
|
||||
private ICPPASTNaryTypeIdExpression.Operator getNaryTypeTraitOperator(IToken operatorToken) {
|
||||
switch (operatorToken.getType()) {
|
||||
case IGCCToken.tTT_is_trivially_constructible:
|
||||
return ICPPASTNaryTypeIdExpression.Operator.__is_trivially_constructible;
|
||||
}
|
||||
|
||||
assert false;
|
||||
|
@ -1576,6 +1618,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
return IASTTypeIdExpression.op_is_trivial;
|
||||
case IGCCToken.tTT_is_union:
|
||||
return IASTTypeIdExpression.op_is_union;
|
||||
case IGCCToken.tTT_is_trivially_copyable:
|
||||
return IASTTypeIdExpression.op_is_trivially_copyable;
|
||||
}
|
||||
assert false;
|
||||
return 0;
|
||||
|
|
|
@ -76,6 +76,7 @@ public class EvalBinaryTypeId extends CPPDependentEvaluation {
|
|||
public IType getType(IASTNode point) {
|
||||
switch (fOperator) {
|
||||
case __is_base_of:
|
||||
case __is_trivially_assignable:
|
||||
return CPPBasicType.BOOLEAN;
|
||||
}
|
||||
return ProblemType.UNKNOWN_FOR_EXPRESSION;
|
||||
|
|
|
@ -31,6 +31,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_pod;
|
|||
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_polymorphic;
|
||||
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_standard_layout;
|
||||
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_trivial;
|
||||
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_trivially_copyable;
|
||||
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_union;
|
||||
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_sizeof;
|
||||
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_sizeofParameterPack;
|
||||
|
@ -116,6 +117,7 @@ public class EvalUnaryTypeID extends CPPDependentEvaluation {
|
|||
case op_is_polymorphic:
|
||||
case op_is_standard_layout:
|
||||
case op_is_trivial:
|
||||
case op_is_trivially_copyable:
|
||||
case op_is_union:
|
||||
return CPPTemplates.isDependentType(fOrigType);
|
||||
|
||||
|
@ -163,6 +165,7 @@ public class EvalUnaryTypeID extends CPPDependentEvaluation {
|
|||
case op_is_polymorphic:
|
||||
case op_is_standard_layout:
|
||||
case op_is_trivial:
|
||||
case op_is_trivially_copyable:
|
||||
case op_is_union:
|
||||
return CPPBasicType.BOOLEAN;
|
||||
case op_typeof:
|
||||
|
|
Loading…
Add table
Reference in a new issue