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:
parent
512b73075f
commit
cbea1acd85
9 changed files with 145 additions and 31 deletions
|
@ -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;
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Reference in a new issue