Skip to main content
summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorHansruedi Patzen2018-05-29 09:27:30 -0400
committerThomas Corbat2018-06-21 04:18:53 -0400
commitcbea1acd8539b5b5bc80b4c9f7c6846e11c537ff (patch)
tree141bb9e5d6485c04c88400b857475e1cb885aade /core
parent512b73075f7f33be51a9fb016a5221662e14f7ce (diff)
downloadorg.eclipse.cdt-cbea1acd8539b5b5bc80b4c9f7c6846e11c537ff.tar.gz
org.eclipse.cdt-cbea1acd8539b5b5bc80b4c9f7c6846e11c537ff.tar.xz
org.eclipse.cdt-cbea1acd8539b5b5bc80b4c9f7c6846e11c537ff.zip
Bug 535257: __declspec lost on AST rewrite
Implemented new IASTMSDeclspec nodes. Change-Id: I2fbc0c2124a8158a457bae0e3cf95aa20ac8ac00 Signed-off-by: Hansruedi Patzen <hansruedi.patzen@hsr.ch> Signed-off-by: Thomas Corbat <tcorbat@hsr.ch>
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterAttributeTestSource.awts14
-rw-r--r--core/org.eclipse.cdt.core/META-INF/MANIFEST.MF1
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/INodeFactory.java6
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ms/IMSASTDeclspecList.java28
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java67
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/MSASTDeclspecList.java29
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/NodeFactory.java6
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/AttributeWriter.java21
9 files changed, 145 insertions, 31 deletions
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 bb6e749a6c..64a636b530 100644
--- a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterAttributeTestSource.awts
+++ b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterAttributeTestSource.awts
@@ -363,3 +363,17 @@ void (__attribute__((__stdcall__))*foo1)(int);
//!Attributed Enumerator
//%CPP
enum E{ value1 [[attr1]], value2 [[attr2]] = 1};
+
+//!MS declspec attribute on class
+//%CPP GNU
+__declspec(dllimport) class X
+{
+} varX;
+
+//!MS declspec attribute on declarator
+//%CPP GNU
+int __declspec(selectany)* pi2 = 0;
+
+//!MS declspec attribute on simple declaration
+//%CPP GNU
+__declspec(thread) int tls_i = 1; \ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF
index b03657253b..4c97838c06 100644
--- a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF
+++ b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF
@@ -17,6 +17,7 @@ Export-Package: org.eclipse.cdt.core,
org.eclipse.cdt.core.dom.ast.gnu,
org.eclipse.cdt.core.dom.ast.gnu.c,
org.eclipse.cdt.core.dom.ast.gnu.cpp,
+ org.eclipse.cdt.core.dom.ast.ms,
org.eclipse.cdt.core.dom.ast.tag,
org.eclipse.cdt.core.dom.parser,
org.eclipse.cdt.core.dom.parser.c,
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 b19af914f6..a9cb2d62c3 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
@@ -17,6 +17,7 @@ package org.eclipse.cdt.core.dom.ast;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.gnu.IGCCASTAttributeList;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
+import org.eclipse.cdt.core.dom.ast.ms.IMSASTDeclspecList;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.internal.core.dom.parser.IASTInactiveCompletionName;
@@ -121,6 +122,11 @@ public interface INodeFactory {
*/
public IGCCASTAttributeList newGCCAttributeList();
+ /**
+ * @since 6.5
+ */
+ public IMSASTDeclspecList newMSDeclspecList();
+
public IGNUASTCompoundStatementExpression newGNUCompoundStatementExpression(IASTCompoundStatement compoundStatement);
public IASTGotoStatement newGotoStatement(IASTName name);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ms/IMSASTDeclspecList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ms/IMSASTDeclspecList.java
new file mode 100644
index 0000000000..768a70366f
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ms/IMSASTDeclspecList.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Institute for Software, HSR Hochschule fuer Technik
+ * Rapperswil, University of applied sciences.
+ * 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:
+ * Hansruedi Patzen (IFS) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.dom.ast.ms;
+
+import org.eclipse.cdt.core.dom.ast.IASTAttributeList;
+import org.eclipse.cdt.core.dom.ast.IASTAttributeSpecifier;
+import org.eclipse.cdt.core.parser.util.InstanceOfPredicate;
+
+/**
+ * Represents a Microsoft attribute specifier, introduced by __declspec.
+ *
+ * @since 6.5
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IMSASTDeclspecList extends IASTAttributeList {
+ public static InstanceOfPredicate<IASTAttributeSpecifier> TYPE_FILTER =
+ new InstanceOfPredicate<>(IMSASTDeclspecList.class);
+}
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 1b5fa01175..4313e5f5af 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
@@ -1572,11 +1572,10 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
final IASTName etorName= identifier();
final IASTEnumerator enumerator= nodeFactory.newEnumerator(etorName, null);
- endOffset= calculateEndOffset(etorName);
List<IASTAttributeSpecifier> attributes = anyAttributes(supportAttributeSpecifiers, supportDeclspecSpecifiers);
addAttributeSpecifiers(attributes, enumerator);
- endOffset = attributesEndOffset(endOffset, attributes);
+ endOffset = attributesEndOffset(calculateEndOffset(etorName), attributes);
setRange(enumerator, problemOffset, endOffset);
result.addEnumerator(enumerator);
@@ -2419,7 +2418,10 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
result.add(__attribute__());
} else if (allowDeclspec && (lt == IGCCToken.t__declspec)) {
- __declspec();
+ if (result == null) {
+ result = new ArrayList<IASTAttributeSpecifier>();
+ }
+ result.add(__declspec());
} else {
break;
}
@@ -2445,21 +2447,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
consume();
consume(IToken.tLPAREN);
- for (;;) {
- final int lt1= LT(1);
- if (lt1 == IToken.tRPAREN || lt1 == IToken.tEOC)
- break;
-
- // Allow empty attribute
- if (lt1 != IToken.tCOMMA) {
- result.addAttribute(singleAttribute());
- }
-
- // Require comma
- if (LT(1) != IToken.tCOMMA)
- break;
- consume();
- }
+ addAttributesOrDeclspecs(result);
consumeOrEOC(IToken.tRPAREN);
endOffset = consumeOrEOC(IToken.tRPAREN).getEndOffset();
@@ -2582,15 +2570,40 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return token;
}
- protected void __declspec() throws BacktrackException, EndOfFileException {
- IToken token = LA(1);
- if (token.getType() == IGCCToken.t__declspec) {
- consume();
- if (LT(1) == IToken.tLPAREN) {
- skipBrackets(IToken.tLPAREN, IToken.tRPAREN, 0);
- }
- }
- }
+ protected void addAttributesOrDeclspecs(IASTAttributeList result) throws EndOfFileException, BacktrackException {
+ int lt1 = LT(1);
+ do {
+ // Allow empty attribute
+ if (lt1 != IToken.tCOMMA) {
+ result.addAttribute(singleAttribute());
+ }
+
+ // Continue on comma
+ if (LT(1) != IToken.tCOMMA) {
+ return;
+ }
+ consume();
+ lt1 = LT(1);
+ } while(lt1 != IToken.tRPAREN && lt1 != IToken.tEOC);
+ }
+
+ /**
+ * Parses an __declspec clause.
+ * @return the list of __declspec attributes
+ * @throws BacktrackException
+ * @throws EndOfFileException
+ */
+ protected IASTAttributeList __declspec() throws BacktrackException, EndOfFileException {
+ IASTAttributeList result = nodeFactory.newMSDeclspecList();
+ final int startOffset = consume(IGCCToken.t__declspec).getOffset();
+ if (LT(1) == IToken.tLPAREN) {
+ consume();
+ addAttributesOrDeclspecs(result);
+ final int endOffset = consumeOrEOC(IToken.tRPAREN).getEndOffset();
+ setRange(result, startOffset, endOffset);
+ }
+ return result;
+ }
/**
* Hook method to support (skip) additional declspec modifiers.
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/MSASTDeclspecList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/MSASTDeclspecList.java
new file mode 100644
index 0000000000..ad757f8c0b
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/MSASTDeclspecList.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Institute for Software, HSR Hochschule fuer Technik
+ * Rapperswil, University of applied sciences.
+ * 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:
+ * Hansruedi Patzen (IFS) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser;
+
+import org.eclipse.cdt.core.dom.ast.ms.IMSASTDeclspecList;
+
+/**
+ * Represents a __declspec list.
+ */
+public class MSASTDeclspecList extends ASTAttributeList implements IMSASTDeclspecList {
+ @Override
+ public MSASTDeclspecList copy(CopyStyle style) {
+ return copy(new MSASTDeclspecList(), style);
+ }
+
+ @Override
+ public MSASTDeclspecList copy() {
+ return copy(CopyStyle.withoutLocations);
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/NodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/NodeFactory.java
index 688893a15f..bba32d8b82 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/NodeFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/NodeFactory.java
@@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.INodeFactory;
import org.eclipse.cdt.core.dom.ast.gnu.IGCCASTAttributeList;
+import org.eclipse.cdt.core.dom.ast.ms.IMSASTDeclspecList;
/**
* Abstract base class for node factories.
@@ -46,4 +47,9 @@ public abstract class NodeFactory implements INodeFactory {
public IGCCASTAttributeList newGCCAttributeList() {
return new GCCASTAttributeList();
}
+
+ @Override
+ public IMSASTDeclspecList newMSDeclspecList() {
+ return new MSASTDeclspecList();
+ }
}
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 77552c119a..c3c193cdea 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
@@ -2594,6 +2594,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
@Override
protected IASTDeclaration declaration(DeclarationOptions option) throws EndOfFileException, BacktrackException {
List<IASTAttributeSpecifier> attributes = attributeSpecifierSeq();
+ attributes = CollectionUtils.merge(attributes, __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers));
+
switch (LT(1)) {
case IToken.t_asm:
return asmDeclaration();
@@ -3466,7 +3468,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
case IGCCToken.t__declspec: // __declspec precedes the identifier
if (identifier != null || !supportDeclspecSpecifiers)
throwBacktrack(LA(1));
- __attribute_decl_seq(false, true);
+ attributes = CollectionUtils.merge(attributes, __attribute_decl_seq(false, true));
break;
case IGCCToken.t_typeof:
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/AttributeWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/AttributeWriter.java
index 2689dd200f..1245f27d1d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/AttributeWriter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/AttributeWriter.java
@@ -13,12 +13,14 @@ package org.eclipse.cdt.internal.core.dom.rewrite.astwriter;
import org.eclipse.cdt.core.dom.ast.IASTAlignmentSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTAttribute;
+import org.eclipse.cdt.core.dom.ast.IASTAttributeList;
import org.eclipse.cdt.core.dom.ast.IASTAttributeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTToken;
import org.eclipse.cdt.core.dom.ast.IASTTokenList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAttribute;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAttributeList;
import org.eclipse.cdt.core.dom.ast.gnu.IGCCASTAttributeList;
+import org.eclipse.cdt.core.dom.ast.ms.IMSASTDeclspecList;
import org.eclipse.cdt.core.parser.GCCKeywords;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
@@ -41,6 +43,8 @@ public class AttributeWriter extends NodeWriter {
writeAttributeSpecifier((ICPPASTAttributeList) attribute);
} else if (attribute instanceof IGCCASTAttributeList) {
writeGCCAttributeSpecifier((IGCCASTAttributeList) attribute);
+ } else if (attribute instanceof IMSASTDeclspecList) {
+ writeMSDeclspecSpecifier((IMSASTDeclspecList) attribute);
} else if (attribute instanceof IASTAlignmentSpecifier) {
writeAlignmentSpecifier((IASTAlignmentSpecifier) attribute);
}
@@ -61,7 +65,20 @@ public class AttributeWriter extends NodeWriter {
scribe.print(GCCKeywords.__ATTRIBUTE__);
scribe.print(OPENING_PARENTHESIS);
scribe.print(OPENING_PARENTHESIS);
- IASTAttribute[] innerAttributes = specifier.getAttributes();
+ writeAttributeOrDeclspec(specifier);
+ scribe.print(CLOSING_PARENTHESIS);
+ scribe.print(CLOSING_PARENTHESIS);
+ }
+
+ private void writeMSDeclspecSpecifier(IMSASTDeclspecList specifier) {
+ scribe.print(GCCKeywords.__DECLSPEC);
+ scribe.print(OPENING_PARENTHESIS);
+ writeAttributeOrDeclspec(specifier);
+ scribe.print(CLOSING_PARENTHESIS);
+ }
+
+ private void writeAttributeOrDeclspec(IASTAttributeList attributeList) {
+ IASTAttribute[] innerAttributes = attributeList.getAttributes();
for (int i = 0; i < innerAttributes.length; i++) {
IASTAttribute innerAttribute = innerAttributes[i];
if (innerAttribute instanceof ICPPASTAttribute) {
@@ -74,8 +91,6 @@ public class AttributeWriter extends NodeWriter {
scribe.printSpace();
}
}
- scribe.print(CLOSING_PARENTHESIS);
- scribe.print(CLOSING_PARENTHESIS);
}
private void writeAttributeSpecifier(ICPPASTAttributeList specifier) {

Back to the top