1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

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>
This commit is contained in:
Hansruedi Patzen 2018-05-29 15:27:30 +02:00 committed by Thomas Corbat
parent 512b73075f
commit cbea1acd85
9 changed files with 145 additions and 31 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -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,14 +2570,39 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return token;
}
protected void __declspec() throws BacktrackException, EndOfFileException {
IToken token = LA(1);
if (token.getType() == IGCCToken.t__declspec) {
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) {
skipBrackets(IToken.tLPAREN, IToken.tRPAREN, 0);
}
consume();
addAttributesOrDeclspecs(result);
final int endOffset = consumeOrEOC(IToken.tRPAREN).getEndOffset();
setRange(result, startOffset, endOffset);
}
return result;
}
/**

View file

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

View file

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

View file

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

View file

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