diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPAttributeTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPAttributeTests.java index 1e27f21c3bc..741bdd3de0c 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPAttributeTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPAttributeTests.java @@ -15,8 +15,6 @@ package org.eclipse.cdt.core.parser.tests.ast2; import java.util.ArrayList; import java.util.List; -import junit.framework.TestSuite; - import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; import org.eclipse.cdt.core.dom.ast.IASTAttribute; @@ -26,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IASTCaseStatement; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement; +import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; @@ -55,6 +54,8 @@ import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTTokenList; +import junit.framework.TestSuite; + public class AST2CPPAttributeTests extends AST2TestBase { public AST2CPPAttributeTests() { @@ -519,4 +520,13 @@ public class AST2CPPAttributeTests extends AST2TestBase { IASTTranslationUnit tu = parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP, true); checkAttributeRelations(getAttributeSpecifiers(tu), ICPPASTFunctionDeclarator.class); } + + + // enum E { + // value1 [[attr1]], value2 [[attr2]] = 1 + // }; + public void testAttributedEnumerator_Bug535269() throws Exception { + IASTTranslationUnit tu = parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP, true); + checkAttributeRelations(getAttributeSpecifiers(tu), IASTEnumerator.class, IASTEnumerator.class); + } } diff --git a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterAttributeTestSource.awts b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterAttributeTestSource.awts index d23f8a3891e..bb6e749a6c7 100644 --- a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterAttributeTestSource.awts +++ b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterAttributeTestSource.awts @@ -358,4 +358,8 @@ char*__attribute__((aligned(8)))* f; //!GCC Attributed Declarator //%CPP GNU void __attribute__((noreturn)) foo(); -void (__attribute__((__stdcall__))*foo1)(int); \ No newline at end of file +void (__attribute__((__stdcall__))*foo1)(int); + +//!Attributed Enumerator +//%CPP +enum E{ value1 [[attr1]], value2 [[attr2]] = 1}; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTEnumerator.java index 42ceb897792..56ed8f40f96 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTEnumerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTEnumerator.java @@ -89,6 +89,7 @@ public abstract class ASTEnumerator extends ASTAttributeOwner implements IASTEnu } } if (name != null && !name.accept(action)) return false; + if (!acceptByAttributeSpecifiers(action)) return false; if (value != null && !value.accept(action)) return false; if (action.shouldVisitEnumerators) { switch (action.leave(this)) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java index 3aa419d89e2..b5159d86f0b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java @@ -1574,11 +1574,11 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { final IASTEnumerator enumerator= nodeFactory.newEnumerator(etorName, null); endOffset= calculateEndOffset(etorName); - List attributes = __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); + List attributes = anyAttributes(supportAttributeSpecifiers, supportDeclspecSpecifiers); addAttributeSpecifiers(attributes, enumerator); endOffset = attributesEndOffset(endOffset, attributes); setRange(enumerator, problemOffset, endOffset); - + result.addEnumerator(enumerator); if (LTcatchEOF(1) == IToken.tASSIGN) { problemOffset= consume().getOffset(); @@ -2395,6 +2395,10 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { } } + protected List anyAttributes(boolean allowAttrib, boolean allowDeclspec) throws BacktrackException, EndOfFileException { + return __attribute_decl_seq(allowAttrib, allowDeclspec); + } + /** * Accepts a sequence of __attribute__ or __declspec. * 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 4337d5f9f30..59bb8e30dbc 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 @@ -2753,6 +2753,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return null; } + @Override + protected List anyAttributes(boolean allowAttrib, boolean allowDeclspec) + throws BacktrackException, EndOfFileException { + List attributes = super.anyAttributes(allowAttrib, allowDeclspec); + attributes = CollectionUtils.merge(attributes, attributeSpecifierSeq()); + return attributes; + } + protected List attributeSpecifierSeq() throws EndOfFileException, BacktrackException { List specifiers = null; @@ -3630,8 +3638,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { consume(); } // if __attribute__ or __declspec occurs after struct/union/class and before the identifier - attributes = __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); - attributes = CollectionUtils.merge(attributes, attributeSpecifierSeq()); + attributes = anyAttributes(supportAttributeSpecifiers, supportDeclspecSpecifiers); if (isScoped || LT(1) == IToken.tIDENTIFIER) { // A qualified-name can appear here if an enumeration declared at class scope is @@ -3709,8 +3716,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { final int offset= consume().getOffset(); // if __attribute__ or __declspec occurs after struct/union/class and before the identifier - List attributes = __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); - attributes = CollectionUtils.merge(attributes, attributeSpecifierSeq()); + List attributes = anyAttributes(supportAttributeSpecifiers, supportDeclspecSpecifiers); IASTName name = qualifiedName(); ICPPASTElaboratedTypeSpecifier elaboratedTypeSpecifier = getNodeFactory().newElaboratedTypeSpecifier(eck, name); @@ -4838,8 +4844,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } // if __attribute__ or __declspec occurs after struct/union/class and before the identifier - List attributes = __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); - attributes = CollectionUtils.merge(attributes, attributeSpecifierSeq()); + List attributes = anyAttributes(supportAttributeSpecifiers, supportDeclspecSpecifiers); // class name IASTName name = null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclSpecWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclSpecWriter.java index a369a22f8d9..d6fbf974f06 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclSpecWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclSpecWriter.java @@ -15,7 +15,6 @@ package org.eclipse.cdt.internal.core.dom.rewrite.astwriter; import java.util.EnumSet; -import org.eclipse.cdt.core.dom.ast.IASTAttributeOwner; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; @@ -171,9 +170,7 @@ public class DeclSpecWriter extends NodeWriter { private void writeElaboratedTypeSec(IASTElaboratedTypeSpecifier elabType) { scribe.printStringSpace(getElabTypeString(elabType.getKind())); - if (elabType instanceof IASTAttributeOwner) { - writeAttributes((IASTAttributeOwner) elabType, EnumSet.of(SpaceLocation.AFTER)); - } + writeAttributes(elabType, EnumSet.of(SpaceLocation.AFTER)); elabType.getName().accept(visitor); } @@ -228,9 +225,7 @@ public class DeclSpecWriter extends NodeWriter { private void writeEnumSpec(IASTEnumerationSpecifier enumSpec) { scribe.printStringSpace(Keywords.ENUM); - if (enumSpec instanceof IASTAttributeOwner) { - writeAttributes((IASTAttributeOwner) enumSpec, EnumSet.of(SpaceLocation.AFTER)); - } + writeAttributes(enumSpec, EnumSet.of(SpaceLocation.AFTER)); enumSpec.getName().accept(visitor); scribe.print('{'); scribe.printSpace(); @@ -246,20 +241,18 @@ public class DeclSpecWriter extends NodeWriter { private void writeEnumerator(IASTEnumerator enumerator) { enumerator.getName().accept(visitor); - + writeAttributes(enumerator, EnumSet.of(SpaceLocation.BEFORE)); IASTExpression value = enumerator.getValue(); if (value != null) { scribe.print(EQUALS); value.accept(visitor); - } + } } private void writeCompositeTypeSpecifier(IASTCompositeTypeSpecifier compDeclSpec) { boolean hasTrailingComments = hasTrailingComments(compDeclSpec.getName()); scribe.printStringSpace(getCPPCompositeTypeString(compDeclSpec.getKey())); - if (compDeclSpec instanceof IASTAttributeOwner) { - writeAttributes((IASTAttributeOwner) compDeclSpec, EnumSet.of(SpaceLocation.AFTER)); - } + writeAttributes(compDeclSpec, EnumSet.of(SpaceLocation.AFTER)); compDeclSpec.getName().accept(visitor); if (compDeclSpec instanceof ICPPASTCompositeTypeSpecifier) { ICPPASTCompositeTypeSpecifier cppComp = (ICPPASTCompositeTypeSpecifier) compDeclSpec;