diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index b2ffeef46a5..8b590545c0c 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -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); + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTypeIdInitializerExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTypeIdInitializerExpression.java new file mode 100644 index 00000000000..635eb5af117 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTypeIdInitializerExpression.java @@ -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 { + + /** + * TYPE_ID represents the relationship between an + * IASTTypeIdInitializerExpression and + * IASTTypeId. + */ + public static final ASTNodeProperty TYPE_ID = new ASTNodeProperty("IASTTypeIdInitializerExpression.TYPE_ID - IASTTypeId for IASTTypeIdInitializerExpression"); //$NON-NLS-1$ + + /** + * INITIALIZER represents the relationship between an + * ICASTTypeIdInitializerExpression and + * IASTInitializer. + */ + 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(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/INodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/INodeFactory.java index 25f9fd4c58a..ac57877da13 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/INodeFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/INodeFactory.java @@ -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); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICASTTypeIdInitializerExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICASTTypeIdInitializerExpression.java index 3bd1c74ff69..5983250152d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICASTTypeIdInitializerExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICASTTypeIdInitializerExpression.java @@ -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 { - - /** - * TYPE_ID represents the relationship between an - * ICASTTypeIdInitializerExpression and - * IASTTypeId. - */ - public static final ASTNodeProperty TYPE_ID = new ASTNodeProperty("ICASTTypeIdInitializerExpression.TYPE_ID - IASTTypeId for ICASTTypeIdInitializerExpression"); //$NON-NLS-1$ - - /** - * INITIALIZER represents the relationship between an - * ICASTTypeIdInitializerExpression and - * IASTInitializer. - */ - public static final ASTNodeProperty INITIALIZER = new ASTNodeProperty( - "ICASTTypeIdInitializerExpression.INITIALIZER - IASTInitializer for ICASTTypeIdInitializerExpression"); //$NON-NLS-1$ - - /** - * Get the type-id. - * - * @return IASTTypeId - */ - public IASTTypeId getTypeId(); - - /** - * Set the typeId. - * - * @param typeId - * IASTTypeId - */ - public void setTypeId(IASTTypeId typeId); - - /** - * Get the initializer. - * - * @return IASTInitializer - */ - public IASTInitializer getInitializer(); - - /** - * Set the initializer. - * - * @param initializer - * IASTInitializer - */ - public void setInitializer(IASTInitializer initializer); - +public interface ICASTTypeIdInitializerExpression extends IASTTypeIdInitializerExpression { /** * @since 5.1 */ public ICASTTypeIdInitializerExpression copy(); - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTypeIdInitializerExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTypeIdInitializerExpression.java new file mode 100644 index 00000000000..a86fdfda9be --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTypeIdInitializerExpression.java @@ -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); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypeIdInitializerExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypeIdInitializerExpression.java index 6ba875e2c85..159e629f128 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypeIdInitializerExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypeIdInitializerExpression.java @@ -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); - } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index 9c6a007d0ff..4c4e09f9143 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java index 8563819cc5b..98b8972bf01 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java @@ -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); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index 5d5c4efaa23..fc9f5b3a293 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -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(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 6ffd8c6e480..bb04b7b771e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -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;