1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-22 14:12:10 +02:00

Bug 535269: Allow attributes on enumerators

C++17 feature.
Implementation and tests.

Change-Id: Idafe4ca41058e8387aeae9a27f028677c62245c0
Signed-off-by: Hansruedi Patzen <hansruedi.patzen@hsr.ch>
Signed-off-by: Thomas Corbat <tcorbat@hsr.ch>
This commit is contained in:
Hansruedi Patzen 2018-05-29 14:09:53 +02:00 committed by Thomas Corbat
parent 66df5ff428
commit c0d54f4f19
6 changed files with 40 additions and 23 deletions

View file

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

View file

@ -358,4 +358,8 @@ char*__attribute__((aligned(8)))* f;
//!GCC Attributed Declarator
//%CPP GNU
void __attribute__((noreturn)) foo();
void (__attribute__((__stdcall__))*foo1)(int);
void (__attribute__((__stdcall__))*foo1)(int);
//!Attributed Enumerator
//%CPP
enum E{ value1 [[attr1]], value2 [[attr2]] = 1};

View file

@ -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)) {

View file

@ -1574,11 +1574,11 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
final IASTEnumerator enumerator= nodeFactory.newEnumerator(etorName, null);
endOffset= calculateEndOffset(etorName);
List<IASTAttributeSpecifier> attributes = __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
List<IASTAttributeSpecifier> 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<IASTAttributeSpecifier> anyAttributes(boolean allowAttrib, boolean allowDeclspec) throws BacktrackException, EndOfFileException {
return __attribute_decl_seq(allowAttrib, allowDeclspec);
}
/**
* Accepts a sequence of __attribute__ or __declspec.
*

View file

@ -2753,6 +2753,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return null;
}
@Override
protected List<IASTAttributeSpecifier> anyAttributes(boolean allowAttrib, boolean allowDeclspec)
throws BacktrackException, EndOfFileException {
List<IASTAttributeSpecifier> attributes = super.anyAttributes(allowAttrib, allowDeclspec);
attributes = CollectionUtils.merge(attributes, attributeSpecifierSeq());
return attributes;
}
protected List<IASTAttributeSpecifier> attributeSpecifierSeq() throws EndOfFileException,
BacktrackException {
List<IASTAttributeSpecifier> 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<IASTAttributeSpecifier> attributes = __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
attributes = CollectionUtils.merge(attributes, attributeSpecifierSeq());
List<IASTAttributeSpecifier> 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<IASTAttributeSpecifier> attributes = __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
attributes = CollectionUtils.merge(attributes, attributeSpecifierSeq());
List<IASTAttributeSpecifier> attributes = anyAttributes(supportAttributeSpecifiers, supportDeclspecSpecifiers);
// class name
IASTName name = null;

View file

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