mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-10 17:55:39 +02:00
Compound literals for c++, bug 247153.
This commit is contained in:
parent
2f4ab93a0d
commit
728a1a2866
10 changed files with 231 additions and 139 deletions
|
@ -5803,4 +5803,19 @@ public class AST2Tests extends AST2BaseTest {
|
|||
parseAndCheckBindings(code, ParserLanguage.C);
|
||||
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||
}
|
||||
|
||||
// typedef struct {
|
||||
// float a;
|
||||
// int b;
|
||||
// } cs;
|
||||
// void x(void){
|
||||
// cs foo;
|
||||
// foo = ((cs){1.2,1});
|
||||
// }
|
||||
public void testCompoundLiterals_Bug258496() throws Exception {
|
||||
final String code= getAboveComment();
|
||||
parseAndCheckBindings(code, ParserLanguage.C);
|
||||
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2008 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:
|
||||
* John Camelon (IBM Rational Software) - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast;
|
||||
|
||||
|
||||
/**
|
||||
* Compound literal: type-id { initializer }
|
||||
*
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
* @since 5.1
|
||||
*/
|
||||
public interface IASTTypeIdInitializerExpression extends IASTExpression {
|
||||
|
||||
/**
|
||||
* <code>TYPE_ID</code> represents the relationship between an
|
||||
* <code>IASTTypeIdInitializerExpression</code> and
|
||||
* <code>IASTTypeId</code>.
|
||||
*/
|
||||
public static final ASTNodeProperty TYPE_ID = new ASTNodeProperty("IASTTypeIdInitializerExpression.TYPE_ID - IASTTypeId for IASTTypeIdInitializerExpression"); //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* <code>INITIALIZER</code> represents the relationship between an
|
||||
* <code>ICASTTypeIdInitializerExpression</code> and
|
||||
* <code>IASTInitializer</code>.
|
||||
*/
|
||||
public static final ASTNodeProperty INITIALIZER = new ASTNodeProperty(
|
||||
"IASTTypeIdInitializerExpression.INITIALIZER - IASTInitializer for IASTTypeIdInitializerExpression"); //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Returns the type id of the compound literal.
|
||||
*/
|
||||
public IASTTypeId getTypeId();
|
||||
|
||||
/**
|
||||
* Sets the type id of the compound literal, must not be called on frozen ast.
|
||||
*/
|
||||
public void setTypeId(IASTTypeId typeId);
|
||||
|
||||
/**
|
||||
* Returns the initializer for the compound literal.
|
||||
*/
|
||||
public IASTInitializer getInitializer();
|
||||
|
||||
/**
|
||||
* Sets the initializer, must not be called on frozen ast.
|
||||
*/
|
||||
public void setInitializer(IASTInitializer initializer);
|
||||
|
||||
public IASTTypeIdInitializerExpression copy();
|
||||
}
|
|
@ -68,6 +68,8 @@ public interface INodeFactory {
|
|||
|
||||
public IASTConditionalExpression newConditionalExpession(IASTExpression expr1, IASTExpression expr2, IASTExpression expr3);
|
||||
|
||||
public IASTTypeIdInitializerExpression newTypeIdInitializerExpression(IASTTypeId typeId, IASTInitializer initializer);
|
||||
|
||||
public IASTLabelStatement newLabelStatement(IASTName name, IASTStatement nestedStatement);
|
||||
|
||||
public IASTCaseStatement newCaseStatement(IASTExpression expr);
|
||||
|
|
|
@ -1,77 +1,30 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 IBM Corporation and others.
|
||||
* Copyright (c) 2005, 2008 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:
|
||||
* IBM Rational Software - Initial API and implementation
|
||||
* John Camelon (IBM Rational Software) - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast.c;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeIdInitializerExpression;
|
||||
|
||||
/**
|
||||
* C Expression of the format type-id { initializer }
|
||||
*
|
||||
* @author jcamelon
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
* GCC allows compound literals for c++, therefore the interface was moved to the common
|
||||
* ast interfaces ({@link IASTTypeIdInitializerExpression}). For compatibility this interface
|
||||
* is kept.
|
||||
*
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface ICASTTypeIdInitializerExpression extends IASTExpression {
|
||||
|
||||
/**
|
||||
* <code>TYPE_ID</code> represents the relationship between an
|
||||
* <code>ICASTTypeIdInitializerExpression</code> and
|
||||
* <code>IASTTypeId</code>.
|
||||
*/
|
||||
public static final ASTNodeProperty TYPE_ID = new ASTNodeProperty("ICASTTypeIdInitializerExpression.TYPE_ID - IASTTypeId for ICASTTypeIdInitializerExpression"); //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* <code>INITIALIZER</code> represents the relationship between an
|
||||
* <code>ICASTTypeIdInitializerExpression</code> and
|
||||
* <code>IASTInitializer</code>.
|
||||
*/
|
||||
public static final ASTNodeProperty INITIALIZER = new ASTNodeProperty(
|
||||
"ICASTTypeIdInitializerExpression.INITIALIZER - IASTInitializer for ICASTTypeIdInitializerExpression"); //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Get the type-id.
|
||||
*
|
||||
* @return <code>IASTTypeId</code>
|
||||
*/
|
||||
public IASTTypeId getTypeId();
|
||||
|
||||
/**
|
||||
* Set the typeId.
|
||||
*
|
||||
* @param typeId
|
||||
* <code>IASTTypeId</code>
|
||||
*/
|
||||
public void setTypeId(IASTTypeId typeId);
|
||||
|
||||
/**
|
||||
* Get the initializer.
|
||||
*
|
||||
* @return <code>IASTInitializer</code>
|
||||
*/
|
||||
public IASTInitializer getInitializer();
|
||||
|
||||
/**
|
||||
* Set the initializer.
|
||||
*
|
||||
* @param initializer
|
||||
* <code>IASTInitializer</code>
|
||||
*/
|
||||
public void setInitializer(IASTInitializer initializer);
|
||||
|
||||
public interface ICASTTypeIdInitializerExpression extends IASTTypeIdInitializerExpression {
|
||||
/**
|
||||
* @since 5.1
|
||||
*/
|
||||
public ICASTTypeIdInitializerExpression copy();
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2008 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:
|
||||
* John Camelon (IBM Rational Software) - Initial API and implementation
|
||||
* Yuan Zhang / Beth Tibbitts (IBM Research)
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeIdInitializerExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
|
||||
|
||||
/**
|
||||
* Compound literals for c and c++.
|
||||
*/
|
||||
public class ASTTypeIdInitializerExpression extends ASTNode implements IASTTypeIdInitializerExpression {
|
||||
private IASTTypeId typeId;
|
||||
private IASTInitializer initializer;
|
||||
|
||||
public ASTTypeIdInitializerExpression() {
|
||||
}
|
||||
|
||||
public ASTTypeIdInitializerExpression(IASTTypeId t, IASTInitializer i) {
|
||||
setTypeId(t);
|
||||
setInitializer(i);
|
||||
}
|
||||
|
||||
public ASTTypeIdInitializerExpression copy() {
|
||||
ASTTypeIdInitializerExpression copy = new ASTTypeIdInitializerExpression();
|
||||
initializeCopy(copy);
|
||||
return copy;
|
||||
}
|
||||
|
||||
protected void initializeCopy(ASTTypeIdInitializerExpression copy) {
|
||||
copy.setTypeId(typeId == null ? null : typeId.copy());
|
||||
copy.setInitializer(initializer == null ? null : initializer.copy());
|
||||
copy.setOffsetAndLength(this);
|
||||
}
|
||||
|
||||
public IASTTypeId getTypeId() {
|
||||
return typeId;
|
||||
}
|
||||
|
||||
public void setTypeId(IASTTypeId typeId) {
|
||||
assertNotFrozen();
|
||||
this.typeId = typeId;
|
||||
if (typeId != null) {
|
||||
typeId.setParent(this);
|
||||
typeId.setPropertyInParent(TYPE_ID);
|
||||
}
|
||||
}
|
||||
|
||||
public IASTInitializer getInitializer() {
|
||||
return initializer;
|
||||
}
|
||||
|
||||
public void setInitializer(IASTInitializer initializer) {
|
||||
assertNotFrozen();
|
||||
this.initializer = initializer;
|
||||
if (initializer != null) {
|
||||
initializer.setParent(this);
|
||||
initializer.setPropertyInParent(INITIALIZER);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept( ASTVisitor action ){
|
||||
if( action.shouldVisitExpressions ){
|
||||
switch( action.visit( this ) ){
|
||||
case ASTVisitor.PROCESS_ABORT : return false;
|
||||
case ASTVisitor.PROCESS_SKIP : return true;
|
||||
default : break;
|
||||
}
|
||||
}
|
||||
|
||||
if( typeId != null ) if( !typeId.accept( action ) ) return false;
|
||||
if( initializer != null ) if( !initializer.accept( action ) ) return false;
|
||||
|
||||
if( action.shouldVisitExpressions ){
|
||||
switch( action.leave( this ) ){
|
||||
case ASTVisitor.PROCESS_ABORT : return false;
|
||||
case ASTVisitor.PROCESS_SKIP : return true;
|
||||
default : break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public IType getExpressionType() {
|
||||
return CVisitor.getExpressionType(this);
|
||||
}
|
||||
}
|
|
@ -6,94 +6,35 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Rational Software - Initial API and implementation
|
||||
* Yuan Zhang / Beth Tibbitts (IBM Research)
|
||||
* John Camelon (IBM Rational Software) - Initial API and implementation
|
||||
* Yuan Zhang / Beth Tibbitts (IBM Research)
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.c;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.c.ICASTTypeIdInitializerExpression;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTTypeIdInitializerExpression;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
* C-specific implementation adds nothing but the c-specific interface.
|
||||
*/
|
||||
public class CASTTypeIdInitializerExpression extends ASTNode implements
|
||||
public class CASTTypeIdInitializerExpression extends ASTTypeIdInitializerExpression implements
|
||||
ICASTTypeIdInitializerExpression {
|
||||
|
||||
private IASTTypeId typeId;
|
||||
private IASTInitializer initializer;
|
||||
|
||||
|
||||
public CASTTypeIdInitializerExpression() {
|
||||
public CASTTypeIdInitializerExpression() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CASTTypeIdInitializerExpression(IASTTypeId t, IASTInitializer i) {
|
||||
setTypeId(t);
|
||||
setInitializer(i);
|
||||
public CASTTypeIdInitializerExpression(IASTTypeId typeId, IASTInitializer initializer) {
|
||||
super(typeId, initializer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CASTTypeIdInitializerExpression copy() {
|
||||
CASTTypeIdInitializerExpression copy = new CASTTypeIdInitializerExpression();
|
||||
copy.setTypeId(typeId == null ? null : typeId.copy());
|
||||
copy.setInitializer(initializer == null ? null : initializer.copy());
|
||||
copy.setOffsetAndLength(this);
|
||||
initializeCopy(copy);
|
||||
return copy;
|
||||
}
|
||||
|
||||
public IASTTypeId getTypeId() {
|
||||
return typeId;
|
||||
}
|
||||
|
||||
public void setTypeId(IASTTypeId typeId) {
|
||||
assertNotFrozen();
|
||||
this.typeId = typeId;
|
||||
if (typeId != null) {
|
||||
typeId.setParent(this);
|
||||
typeId.setPropertyInParent(TYPE_ID);
|
||||
}
|
||||
}
|
||||
|
||||
public IASTInitializer getInitializer() {
|
||||
return initializer;
|
||||
}
|
||||
|
||||
public void setInitializer(IASTInitializer initializer) {
|
||||
assertNotFrozen();
|
||||
this.initializer = initializer;
|
||||
if (initializer != null) {
|
||||
initializer.setParent(this);
|
||||
initializer.setPropertyInParent(INITIALIZER);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept( ASTVisitor action ){
|
||||
if( action.shouldVisitExpressions ){
|
||||
switch( action.visit( this ) ){
|
||||
case ASTVisitor.PROCESS_ABORT : return false;
|
||||
case ASTVisitor.PROCESS_SKIP : return true;
|
||||
default : break;
|
||||
}
|
||||
}
|
||||
|
||||
if( typeId != null ) if( !typeId.accept( action ) ) return false;
|
||||
if( initializer != null ) if( !initializer.accept( action ) ) return false;
|
||||
|
||||
if( action.shouldVisitExpressions ){
|
||||
switch( action.leave( this ) ){
|
||||
case ASTVisitor.PROCESS_ABORT : return false;
|
||||
case ASTVisitor.PROCESS_SKIP : return true;
|
||||
default : break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public IType getExpressionType() {
|
||||
return CVisitor.getExpressionType(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,6 @@ import org.eclipse.cdt.core.dom.ast.c.ICASTDesignator;
|
|||
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
|
||||
import org.eclipse.cdt.core.dom.ast.c.ICASTPointer;
|
||||
import org.eclipse.cdt.core.dom.ast.c.ICASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.c.ICASTTypeIdInitializerExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.c.ICASTTypedefNameSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.c.ICNodeFactory;
|
||||
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTTypeIdExpression;
|
||||
|
@ -552,10 +551,11 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
int offset = consume().getOffset();
|
||||
IASTTypeId t= typeId(DeclarationOptions.TYPEID);
|
||||
if (t != null) {
|
||||
consume(IToken.tRPAREN).getEndOffset();
|
||||
consume(IToken.tRPAREN);
|
||||
if (LT(1) == IToken.tLBRACE) {
|
||||
IASTInitializer i = cInitializerClause(false);
|
||||
firstExpression = buildTypeIdInitializerExpression(t, i, offset, calculateEndOffset(i));
|
||||
firstExpression= nodeFactory.newTypeIdInitializerExpression(t, i);
|
||||
setRange(firstExpression, offset, calculateEndOffset(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -655,15 +655,6 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
protected ICASTTypeIdInitializerExpression buildTypeIdInitializerExpression(
|
||||
IASTTypeId t, IASTInitializer i, int offset, int lastOffset) {
|
||||
ICASTTypeIdInitializerExpression result = nodeFactory.newTypeIdInitializerExpression(t, i);
|
||||
((ASTNode) result).setOffsetAndLength(offset, lastOffset - offset);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected IASTExpression primaryExpression() throws EndOfFileException, BacktrackException {
|
||||
IToken t = null;
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerList;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
|
||||
|
@ -49,6 +50,7 @@ import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeIdInitializerExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
|
||||
|
@ -101,6 +103,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTExplicitTemplateInstantiation
|
|||
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer;
|
||||
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember;
|
||||
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTTypeIdInitializerExpression;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -190,6 +193,10 @@ public class CPPNodeFactory implements ICPPNodeFactory {
|
|||
public IASTConditionalExpression newConditionalExpession(IASTExpression expr1, IASTExpression expr2, IASTExpression expr3) {
|
||||
return new CPPASTConditionalExpression(expr1, expr2, expr3);
|
||||
}
|
||||
|
||||
public IASTTypeIdInitializerExpression newTypeIdInitializerExpression(IASTTypeId typeId, IASTInitializer initializer) {
|
||||
return new ASTTypeIdInitializerExpression(typeId, initializer);
|
||||
}
|
||||
|
||||
public ICPPASTFieldReference newFieldReference(IASTName name, IASTExpression owner) {
|
||||
return new CPPASTFieldReference(name, owner);
|
||||
|
|
|
@ -974,6 +974,28 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
boolean isTemplate = false;
|
||||
|
||||
switch (LT(1)) {
|
||||
case IToken.tLPAREN:
|
||||
// ( type-name ) { initializer-list }
|
||||
// ( type-name ) { initializer-list , }
|
||||
IToken m = mark();
|
||||
try {
|
||||
int offset = consume().getOffset();
|
||||
IASTTypeId t= typeId(DeclarationOptions.TYPEID);
|
||||
if (t != null) {
|
||||
consume(IToken.tRPAREN);
|
||||
if (LT(1) == IToken.tLBRACE) {
|
||||
IASTInitializer i = initializerClause(false);
|
||||
firstExpression= nodeFactory.newTypeIdInitializerExpression(t, i);
|
||||
setRange(firstExpression, offset, calculateEndOffset(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (BacktrackException bt) {
|
||||
}
|
||||
backup(m);
|
||||
firstExpression= primaryExpression();
|
||||
break;
|
||||
|
||||
case IToken.t_typename:
|
||||
int typenameOffset= consume().getOffset();
|
||||
|
||||
|
|
|
@ -1065,6 +1065,7 @@ public class CPPTemplates {
|
|||
tdecl= outerMostTDecl;
|
||||
while(true) {
|
||||
tdecl.setNestingLevel((short) level++);
|
||||
tdecl.setAssociatedWithLastName(false);
|
||||
node= tdecl.getDeclaration();
|
||||
if (node instanceof ICPPASTInternalTemplateDeclaration) {
|
||||
tdecl= (ICPPASTInternalTemplateDeclaration) node;
|
||||
|
|
Loading…
Add table
Reference in a new issue