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 741bdd3de0c..a1133c83558 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 @@ -44,6 +44,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTryBlockStatement; @@ -529,4 +530,11 @@ public class AST2CPPAttributeTests extends AST2TestBase { IASTTranslationUnit tu = parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP, true); checkAttributeRelations(getAttributeSpecifiers(tu), IASTEnumerator.class, IASTEnumerator.class); } + + //void f([[attr1]] int [[attr2]] p) { + //} + public void testAttributedFunctionParameter_Bug535275() throws Exception { + IASTTranslationUnit tu = parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP, true); + checkAttributeRelations(getAttributeSpecifiers(tu), ICPPASTParameterDeclaration.class, ICPPASTSimpleDeclSpecifier.class); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/ReplaceTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/ReplaceTests.java index 5a6514c17b3..2b11860d4b7 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/ReplaceTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/ReplaceTests.java @@ -1219,4 +1219,10 @@ public class ReplaceTests extends ChangeGeneratorTest { } }); } + + //void f([[attr1]] int p1, int [[attr2]] p2, [[attr3]] int p3) { + //} + public void testCopyReplaceAttribute_Bug535275() throws Exception { + compareCopyResult(new CopyReplaceVisitor(this, ICPPASTFunctionDeclarator.class::isInstance)); + } } diff --git a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterDeclarationTestSource.awts b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterDeclarationTestSource.awts index f57045592bd..4edde1b12d0 100644 --- a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterDeclarationTestSource.awts +++ b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterDeclarationTestSource.awts @@ -172,3 +172,9 @@ inline namespace InlnNS } + +//!Function definition with attributed parameters +//%CPP +void f([[attr1]] int p1, int [[attr2]] p2, [[attr3]] int p3) +{ +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTParameterDeclaration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTParameterDeclaration.java index b08da127cb6..2c0ff4d457c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTParameterDeclaration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTParameterDeclaration.java @@ -11,13 +11,14 @@ *******************************************************************************/ package org.eclipse.cdt.core.dom.ast.cpp; +import org.eclipse.cdt.core.dom.ast.IASTAttributeOwner; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; /** * @noextend This interface is not intended to be extended by clients. * @noimplement This interface is not intended to be implemented by clients. */ -public interface ICPPASTParameterDeclaration extends ICPPASTTemplateParameter, IASTParameterDeclaration { +public interface ICPPASTParameterDeclaration extends ICPPASTTemplateParameter, IASTParameterDeclaration, IASTAttributeOwner { /** * @since 5.2 */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousParameterDeclaration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousParameterDeclaration.java index f94931e64be..cae07b2b9b2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousParameterDeclaration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousParameterDeclaration.java @@ -11,6 +11,8 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTAttribute; +import org.eclipse.cdt.core.dom.ast.IASTAttributeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTNode; @@ -125,4 +127,25 @@ public class CPPASTAmbiguousParameterDeclaration extends ASTAmbiguousNode Assert.isLegal(false); return true; } + + @Override + public IASTAttributeSpecifier[] getAttributeSpecifiers() { + return fParameterDecl.getAttributeSpecifiers(); + } + + @Override + public void addAttributeSpecifier(IASTAttributeSpecifier attributeSpecifier) { + fParameterDecl.addAttributeSpecifier(attributeSpecifier); + } + + @Override + public IASTAttribute[] getAttributes() { + return fParameterDecl.getAttributes(); + } + + @Override + @Deprecated + public void addAttribute(IASTAttribute attribute) { + fParameterDecl.addAttribute(attribute); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTParameterDeclaration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTParameterDeclaration.java index 9f66bbc9951..3be016bab68 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTParameterDeclaration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTParameterDeclaration.java @@ -18,14 +18,12 @@ import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; -import org.eclipse.cdt.internal.core.dom.parser.ASTNode; -import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; /** * Function parameter or non-type template parameter declaration. */ -public class CPPASTParameterDeclaration extends ASTNode implements ICPPASTParameterDeclaration, IASTAmbiguityParent { +public class CPPASTParameterDeclaration extends CPPASTAttributeOwner implements ICPPASTParameterDeclaration { private IASTDeclSpecifier fDeclSpec; private ICPPASTDeclarator fDeclarator; @@ -97,6 +95,8 @@ public class CPPASTParameterDeclaration extends ASTNode implements ICPPASTParame } } + if (!acceptByAttributeSpecifiers(action)) + return false; if (fDeclSpec != null && !fDeclSpec.accept(action)) return false; if (fDeclarator != null && !fDeclarator.accept(action)) 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 59bb8e30dbc..4cde7a50c3e 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 @@ -3111,12 +3111,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { declSpec= lie.fDeclSpec; declarator= addInitializer(lie, DeclarationOptions.PARAMETER); } - - addAttributeSpecifiers(attributes, declSpec); final ICPPASTParameterDeclaration parm = getNodeFactory().newParameterDeclaration(declSpec, declarator); final int endOffset = figureEndOffset(declSpec, declarator); setRange(parm, startOffset, endOffset); + addAttributeSpecifiers(attributes, parm); return parm; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java index f832ae4ec45..ae880c4baf4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java @@ -14,6 +14,7 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.rewrite.astwriter; +import java.util.EnumSet; import java.util.List; import org.eclipse.cdt.core.dom.ast.ASTVisitor; @@ -36,12 +37,14 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDecltypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId; import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.internal.core.dom.rewrite.ASTLiteralNode; +import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.NodeWriter.SpaceLocation; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; /** @@ -273,6 +276,9 @@ public class ASTWriterVisitor extends ASTVisitor { @Override public int visit(IASTParameterDeclaration parameterDeclaration) { writeLeadingComments(parameterDeclaration); + if (parameterDeclaration instanceof ICPPASTParameterDeclaration) { + attributeWriter.writeAttributes((ICPPASTParameterDeclaration) parameterDeclaration, EnumSet.of(SpaceLocation.AFTER)); + } if (!macroHandler.checkisMacroExpansionNode(parameterDeclaration)) { parameterDeclaration.getDeclSpecifier().accept(this); IASTDeclarator declarator = getParameterDeclarator(parameterDeclaration);