1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-12 02:35:37 +02:00

Compound literals for c++, bug 247153.

This commit is contained in:
Markus Schorn 2008-12-18 09:11:02 +00:00
parent 2f4ab93a0d
commit 728a1a2866
10 changed files with 231 additions and 139 deletions

View file

@ -5803,4 +5803,19 @@ public class AST2Tests extends AST2BaseTest {
parseAndCheckBindings(code, ParserLanguage.C); parseAndCheckBindings(code, ParserLanguage.C);
parseAndCheckBindings(code, ParserLanguage.CPP); 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);
}
} }

View file

@ -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();
}

View file

@ -68,6 +68,8 @@ public interface INodeFactory {
public IASTConditionalExpression newConditionalExpession(IASTExpression expr1, IASTExpression expr2, IASTExpression expr3); public IASTConditionalExpression newConditionalExpession(IASTExpression expr1, IASTExpression expr2, IASTExpression expr3);
public IASTTypeIdInitializerExpression newTypeIdInitializerExpression(IASTTypeId typeId, IASTInitializer initializer);
public IASTLabelStatement newLabelStatement(IASTName name, IASTStatement nestedStatement); public IASTLabelStatement newLabelStatement(IASTName name, IASTStatement nestedStatement);
public IASTCaseStatement newCaseStatement(IASTExpression expr); public IASTCaseStatement newCaseStatement(IASTExpression expr);

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * 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; package org.eclipse.cdt.core.dom.ast.c;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.IASTTypeIdInitializerExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
/** /**
* C Expression of the format type-id { initializer } * C Expression of the format type-id { initializer }
* *
* @author jcamelon * GCC allows compound literals for c++, therefore the interface was moved to the common
* @noimplement This interface is not intended to be implemented by clients. * 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 { public interface ICASTTypeIdInitializerExpression extends IASTTypeIdInitializerExpression {
/**
* <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);
/** /**
* @since 5.1 * @since 5.1
*/ */
public ICASTTypeIdInitializerExpression copy(); public ICASTTypeIdInitializerExpression copy();
} }

View file

@ -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);
}
}

View file

@ -6,94 +6,35 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Rational Software - Initial API and implementation * John Camelon (IBM Rational Software) - Initial API and implementation
* Yuan Zhang / Beth Tibbitts (IBM Research) * Yuan Zhang / Beth Tibbitts (IBM Research)
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c; 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.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; 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.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 { ICASTTypeIdInitializerExpression {
private IASTTypeId typeId; public CASTTypeIdInitializerExpression() {
private IASTInitializer initializer; super();
public CASTTypeIdInitializerExpression() {
} }
public CASTTypeIdInitializerExpression(IASTTypeId t, IASTInitializer i) { public CASTTypeIdInitializerExpression(IASTTypeId typeId, IASTInitializer initializer) {
setTypeId(t); super(typeId, initializer);
setInitializer(i);
} }
@Override
public CASTTypeIdInitializerExpression copy() { public CASTTypeIdInitializerExpression copy() {
CASTTypeIdInitializerExpression copy = new CASTTypeIdInitializerExpression(); CASTTypeIdInitializerExpression copy = new CASTTypeIdInitializerExpression();
copy.setTypeId(typeId == null ? null : typeId.copy()); initializeCopy(copy);
copy.setInitializer(initializer == null ? null : initializer.copy());
copy.setOffsetAndLength(this);
return 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);
}
} }

View file

@ -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.ICASTFieldDesignator;
import org.eclipse.cdt.core.dom.ast.c.ICASTPointer; 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.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.ICASTTypedefNameSpecifier;
import org.eclipse.cdt.core.dom.ast.c.ICNodeFactory; import org.eclipse.cdt.core.dom.ast.c.ICNodeFactory;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTTypeIdExpression;
@ -552,10 +551,11 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
int offset = consume().getOffset(); int offset = consume().getOffset();
IASTTypeId t= typeId(DeclarationOptions.TYPEID); IASTTypeId t= typeId(DeclarationOptions.TYPEID);
if (t != null) { if (t != null) {
consume(IToken.tRPAREN).getEndOffset(); consume(IToken.tRPAREN);
if (LT(1) == IToken.tLBRACE) { if (LT(1) == IToken.tLBRACE) {
IASTInitializer i = cInitializerClause(false); IASTInitializer i = cInitializerClause(false);
firstExpression = buildTypeIdInitializerExpression(t, i, offset, calculateEndOffset(i)); firstExpression= nodeFactory.newTypeIdInitializerExpression(t, i);
setRange(firstExpression, offset, calculateEndOffset(i));
break; 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 @Override
protected IASTExpression primaryExpression() throws EndOfFileException, BacktrackException { protected IASTExpression primaryExpression() throws EndOfFileException, BacktrackException {
IToken t = null; IToken t = null;

View file

@ -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.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement; import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; 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.IASTInitializerExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerList; import org.eclipse.cdt.core.dom.ast.IASTInitializerList;
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; 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.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; 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.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression; 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.IGPPASTPointer;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTSimpleDeclSpecifier; 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) { public IASTConditionalExpression newConditionalExpession(IASTExpression expr1, IASTExpression expr2, IASTExpression expr3) {
return new CPPASTConditionalExpression(expr1, expr2, 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) { public ICPPASTFieldReference newFieldReference(IASTName name, IASTExpression owner) {
return new CPPASTFieldReference(name, owner); return new CPPASTFieldReference(name, owner);

View file

@ -974,6 +974,28 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
boolean isTemplate = false; boolean isTemplate = false;
switch (LT(1)) { 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: case IToken.t_typename:
int typenameOffset= consume().getOffset(); int typenameOffset= consume().getOffset();

View file

@ -1065,6 +1065,7 @@ public class CPPTemplates {
tdecl= outerMostTDecl; tdecl= outerMostTDecl;
while(true) { while(true) {
tdecl.setNestingLevel((short) level++); tdecl.setNestingLevel((short) level++);
tdecl.setAssociatedWithLastName(false);
node= tdecl.getDeclaration(); node= tdecl.getDeclaration();
if (node instanceof ICPPASTInternalTemplateDeclaration) { if (node instanceof ICPPASTInternalTemplateDeclaration) {
tdecl= (ICPPASTInternalTemplateDeclaration) node; tdecl= (ICPPASTInternalTemplateDeclaration) node;