mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Support for parameter annotations by Sebastian Moss, bug 254520.
This commit is contained in:
parent
0700a8fe68
commit
edeb6f1af1
9 changed files with 127 additions and 49 deletions
|
@ -1,14 +1,13 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2007 IBM Corporation.
|
||||
* Copyright (c) 2006, 2008 IBM Corporation.
|
||||
* 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:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.pdom.tests;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
@ -36,12 +35,14 @@ public class CFunctionTests extends PDOMTestBase {
|
|||
return suite(CFunctionTests.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
project = createProject("functionTests");
|
||||
pdom = (PDOM) CCoreInternals.getPDOMManager().getPDOM(project);
|
||||
pdom.acquireReadLock();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
pdom.releaseReadLock();
|
||||
if (project != null) {
|
||||
|
@ -84,4 +85,14 @@ public class CFunctionTests extends PDOMTestBase {
|
|||
assertTrue(params[1].getType() instanceof ICBasicType);
|
||||
assertTrue(params[2].getType() instanceof ICBasicType);
|
||||
}
|
||||
|
||||
public void testFunctionWithRegisterParam() throws Exception {
|
||||
IBinding[] bindings = findQualifiedName(pdom, "storageClassCFunction");
|
||||
assertEquals(1, bindings.length);
|
||||
IFunction f= (IFunction) bindings[0];
|
||||
IParameter[] params= f.getParameters();
|
||||
assertEquals(2, params.length);
|
||||
assertEquals(true, params[0].isRegister());
|
||||
assertEquals(false, params[1].isRegister());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,6 +111,16 @@ public class CPPFunctionTests extends PDOMTestBase {
|
|||
assertEquals("p3", parameters[2].getName());
|
||||
}
|
||||
|
||||
public void testStorageClassSpecParameters() throws Exception {
|
||||
IBinding[] bindings = findQualifiedName(pdom, "storageClassCPPFunction");
|
||||
assertEquals(1, bindings.length);
|
||||
ICPPFunction function = (ICPPFunction) bindings[0];
|
||||
IParameter[] parameters = function.getParameters();
|
||||
assertEquals(2, parameters.length);
|
||||
assertEquals(true, parameters[0].isRegister());
|
||||
assertEquals(true, parameters[1].isAuto());
|
||||
}
|
||||
|
||||
public void testExternCPPFunction() throws Exception {
|
||||
IBinding[] bindings = findQualifiedName(pdom, "externCPPFunction");
|
||||
assertEquals(1, bindings.length);
|
||||
|
|
|
@ -5,6 +5,7 @@ inline void inlineCFunction(long p1);
|
|||
void varArgsCFunction(int p1, ...);
|
||||
const void constCFunction();
|
||||
volatile void volatileCFunction();
|
||||
void storageClassCFunction(register int p1, int p2);
|
||||
|
||||
void voidCFunction();
|
||||
int intCFunction();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
double normalCPPFunction(int p1, char p2, float p3);
|
||||
void storageClassCPPFunction(register int p1, auto int p2);
|
||||
static int staticCPPFunction(double p1);
|
||||
extern float externCPPFunction(int p1);
|
||||
inline void inlineCPPFunction(long p1);
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||
|
@ -174,21 +175,25 @@ public class CParameter extends PlatformObject implements IParameter {
|
|||
return hasStorageClass( IASTDeclSpecifier.sc_register );
|
||||
}
|
||||
|
||||
public boolean hasStorageClass( int storage ){
|
||||
if( declarations == null )
|
||||
return false;
|
||||
for( int i = 0; i < declarations.length && declarations[i] != null; i++ ){
|
||||
IASTNode parent = declarations[i].getParent();
|
||||
while( !(parent instanceof IASTDeclaration) )
|
||||
parent = parent.getParent();
|
||||
|
||||
if( parent instanceof IASTSimpleDeclaration ){
|
||||
IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration)parent).getDeclSpecifier();
|
||||
if( declSpec.getStorageClass() == storage )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
public boolean hasStorageClass(int storage) {
|
||||
if (declarations == null)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < declarations.length && declarations[i] != null; i++) {
|
||||
IASTNode parent= declarations[i].getParent();
|
||||
while (!(parent instanceof IASTParameterDeclaration) && !(parent instanceof IASTDeclaration))
|
||||
parent= parent.getParent();
|
||||
|
||||
IASTDeclSpecifier declSpec = null;
|
||||
if (parent instanceof IASTSimpleDeclaration) {
|
||||
declSpec = ((IASTSimpleDeclaration) parent).getDeclSpecifier();
|
||||
} else if (parent instanceof IASTParameterDeclaration) {
|
||||
declSpec = ((IASTParameterDeclaration) parent).getDeclSpecifier();
|
||||
}
|
||||
if (declSpec != null)
|
||||
return declSpec.getStorageClass() == storage;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public ILinkage getLinkage() {
|
||||
|
|
|
@ -20,7 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
|
@ -252,22 +252,19 @@ public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPI
|
|||
}
|
||||
|
||||
public boolean hasStorageClass(int storage) {
|
||||
IASTNode[] ns = getDeclarations();
|
||||
if (ns == null)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < ns.length && ns[i] != null; i++) {
|
||||
IASTNode parent = ns[i].getParent();
|
||||
while (!(parent instanceof IASTDeclaration))
|
||||
parent = parent.getParent();
|
||||
|
||||
if (parent instanceof IASTSimpleDeclaration) {
|
||||
IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration)parent).getDeclSpecifier();
|
||||
if (declSpec.getStorageClass() == storage)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
IASTNode[] ns = getDeclarations();
|
||||
if (ns == null)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < ns.length && ns[i] != null; i++) {
|
||||
IASTNode parent = ns[i].getParent();
|
||||
while (!(parent instanceof IASTParameterDeclaration))
|
||||
parent = parent.getParent();
|
||||
IASTDeclSpecifier declSpec = ((IASTParameterDeclaration) parent).getDeclSpecifier();
|
||||
if (declSpec.getStorageClass() == storage)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public IASTInitializer getDefaultValue() {
|
||||
|
|
|
@ -166,11 +166,12 @@ public class PDOM extends PlatformObject implements IPDOM {
|
|||
* 74.0 - changes for proper template argument support, bug 242668
|
||||
* 75.0 - support for friends, bug 250167
|
||||
* 76.0 - support for exception specification, bug 252697
|
||||
* 77.0 - support for parameter annotations, bug 254520
|
||||
*/
|
||||
private static int version(int major, int minor) {
|
||||
return major << 16 + minor;
|
||||
}
|
||||
public static final int MAJOR_VERSION = 76;
|
||||
public static final int MAJOR_VERSION = 77;
|
||||
public static final int MINOR_VERSION = 0; // minor versions must be compatible
|
||||
|
||||
public static final int CURRENT_VERSION= version(MAJOR_VERSION, MINOR_VERSION);
|
||||
|
|
|
@ -41,9 +41,14 @@ class PDOMCParameter extends PDOMNamedNode implements IParameter, IPDOMBinding {
|
|||
private static final int NEXT_PARAM = PDOMNamedNode.RECORD_SIZE + 0;
|
||||
private static final int TYPE = PDOMNamedNode.RECORD_SIZE + 4;
|
||||
|
||||
protected static final int FLAGS = PDOMNamedNode.RECORD_SIZE + 8;
|
||||
|
||||
@SuppressWarnings("hiding")
|
||||
public static final int RECORD_SIZE = PDOMNamedNode.RECORD_SIZE + 8;
|
||||
|
||||
public static final int RECORD_SIZE = PDOMNamedNode.RECORD_SIZE + 9;
|
||||
static {
|
||||
assert RECORD_SIZE <= 22; // 23 would yield a 32-byte block
|
||||
}
|
||||
|
||||
public PDOMCParameter(PDOM pdom, int record) {
|
||||
super(pdom, record);
|
||||
}
|
||||
|
@ -62,6 +67,8 @@ class PDOMCParameter extends PDOMNamedNode implements IParameter, IPDOMBinding {
|
|||
PDOMNode typeNode = getLinkageImpl().addType(this, type);
|
||||
db.putInt(record + TYPE, typeNode != null ? typeNode.getRecord() : 0);
|
||||
}
|
||||
byte flags = encodeFlags(param);
|
||||
db.putByte(record + FLAGS, flags);
|
||||
}
|
||||
} catch(DOMException e) {
|
||||
throw new CoreException(Util.createStatus(e));
|
||||
|
@ -105,7 +112,8 @@ class PDOMCParameter extends PDOMNamedNode implements IParameter, IPDOMBinding {
|
|||
}
|
||||
|
||||
public boolean isAuto() throws DOMException {
|
||||
throw new PDOMNotImplementedError();
|
||||
byte flag = 1<<PDOMCAnnotation.AUTO_OFFSET;
|
||||
return hasFlag(flag, true);
|
||||
}
|
||||
|
||||
public boolean isExtern() throws DOMException {
|
||||
|
@ -113,7 +121,8 @@ class PDOMCParameter extends PDOMNamedNode implements IParameter, IPDOMBinding {
|
|||
}
|
||||
|
||||
public boolean isRegister() throws DOMException {
|
||||
throw new PDOMNotImplementedError();
|
||||
byte flag = 1<<PDOMCAnnotation.REGISTER_OFFSET;
|
||||
return hasFlag(flag, false);
|
||||
}
|
||||
|
||||
public boolean isStatic() throws DOMException {
|
||||
|
@ -198,4 +207,23 @@ class PDOMCParameter extends PDOMNamedNode implements IParameter, IPDOMBinding {
|
|||
public IValue getInitialValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected byte encodeFlags(IParameter param) throws DOMException {
|
||||
// C99 ISO/IEC 9899: 6.7.5.3.2
|
||||
byte flags= 0;
|
||||
flags |= (param.isAuto() ? 1 : 0) << PDOMCAnnotation.AUTO_OFFSET;
|
||||
flags |= (param.isRegister() ? 1 : 0) << PDOMCAnnotation.REGISTER_OFFSET;
|
||||
return flags;
|
||||
}
|
||||
|
||||
protected boolean hasFlag(byte flag, boolean defValue) {
|
||||
try {
|
||||
byte myflags= pdom.getDB().getByte(record + FLAGS);
|
||||
return (myflags & flag) == flag;
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
return defValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
|
|||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNamedNode;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCAnnotation;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
|
@ -49,18 +50,27 @@ class PDOMCPPParameter extends PDOMNamedNode implements ICPPParameter, IPDOMBind
|
|||
*/
|
||||
private static final int TYPE = PDOMNamedNode.RECORD_SIZE + 4;
|
||||
|
||||
/**
|
||||
* Offset of annotation information (relative to the beginning of the
|
||||
* record).
|
||||
*/
|
||||
private static final int ANNOTATIONS = PDOMNamedNode.RECORD_SIZE + 8;
|
||||
|
||||
/**
|
||||
* Offset of flags
|
||||
* (relative to the beginning of the record).
|
||||
*/
|
||||
private static final int FLAGS = PDOMNamedNode.RECORD_SIZE + 8;
|
||||
private static final int FLAGS = PDOMNamedNode.RECORD_SIZE + 9;
|
||||
|
||||
|
||||
/**
|
||||
* The size in bytes of a PDOMCPPParameter record in the database.
|
||||
*/
|
||||
@SuppressWarnings("hiding")
|
||||
protected static final int RECORD_SIZE = PDOMNamedNode.RECORD_SIZE + 9;
|
||||
protected static final int RECORD_SIZE = PDOMNamedNode.RECORD_SIZE + 10;
|
||||
static {
|
||||
assert RECORD_SIZE <= 22; // 23 would yield a 32-byte block
|
||||
}
|
||||
|
||||
private static final byte FLAG_DEFAULT_VALUE = 0x1;
|
||||
|
||||
|
@ -77,7 +87,7 @@ class PDOMCPPParameter extends PDOMNamedNode implements ICPPParameter, IPDOMBind
|
|||
db.putInt(record + NEXT_PARAM, 0);
|
||||
byte flags= encodeFlags(param);
|
||||
db.putByte(record + FLAGS, flags);
|
||||
|
||||
|
||||
try {
|
||||
if (type == null)
|
||||
type= param.getType();
|
||||
|
@ -85,6 +95,8 @@ class PDOMCPPParameter extends PDOMNamedNode implements ICPPParameter, IPDOMBind
|
|||
PDOMNode typeNode = getLinkageImpl().addType(this, type);
|
||||
db.putInt(record + TYPE, typeNode != null ? typeNode.getRecord() : 0);
|
||||
}
|
||||
byte annotations = PDOMCPPAnnotation.encodeAnnotation(param);
|
||||
db.putByte(record + ANNOTATIONS, annotations);
|
||||
} catch (DOMException e) {
|
||||
throw new CoreException(Util.createStatus(e));
|
||||
}
|
||||
|
@ -101,6 +113,14 @@ class PDOMCPPParameter extends PDOMNamedNode implements ICPPParameter, IPDOMBind
|
|||
db.putByte(record + FLAGS, flags);
|
||||
|
||||
db.putInt(record + TYPE, typeRecord);
|
||||
|
||||
try {
|
||||
byte annotations = PDOMCPPAnnotation.encodeAnnotation(param);
|
||||
db.putByte(record + ANNOTATIONS, annotations);
|
||||
} catch (DOMException e) {
|
||||
throw new CoreException(Util.createStatus(e));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private byte encodeFlags(IParameter param) {
|
||||
|
@ -160,7 +180,9 @@ class PDOMCPPParameter extends PDOMNamedNode implements ICPPParameter, IPDOMBind
|
|||
}
|
||||
|
||||
public boolean isAuto() throws DOMException {
|
||||
throw new PDOMNotImplementedError();
|
||||
// ISO/IEC 14882:2003 7.1.1.2
|
||||
byte flag = 1<<PDOMCAnnotation.AUTO_OFFSET;
|
||||
return hasFlag(flag, true, ANNOTATIONS);
|
||||
}
|
||||
|
||||
public boolean isExtern() throws DOMException {
|
||||
|
@ -173,7 +195,9 @@ class PDOMCPPParameter extends PDOMNamedNode implements ICPPParameter, IPDOMBind
|
|||
}
|
||||
|
||||
public boolean isRegister() throws DOMException {
|
||||
throw new PDOMNotImplementedError();
|
||||
// ISO/IEC 14882:2003 7.1.1.2
|
||||
byte flag = 1<<PDOMCAnnotation.REGISTER_OFFSET;
|
||||
return hasFlag(flag, true, ANNOTATIONS);
|
||||
}
|
||||
|
||||
public boolean isStatic() throws DOMException {
|
||||
|
@ -205,19 +229,19 @@ class PDOMCPPParameter extends PDOMNamedNode implements ICPPParameter, IPDOMBind
|
|||
}
|
||||
|
||||
public boolean hasDefaultValue() {
|
||||
return hasFlag(FLAG_DEFAULT_VALUE, false);
|
||||
return hasFlag(FLAG_DEFAULT_VALUE, false, FLAGS);
|
||||
}
|
||||
|
||||
private boolean hasFlag(byte flag, boolean defValue) {
|
||||
private boolean hasFlag(byte flag, boolean defValue, int offset) {
|
||||
try {
|
||||
byte myflags= pdom.getDB().getByte(record + FLAGS);
|
||||
byte myflags= pdom.getDB().getByte(record + offset);
|
||||
return (myflags & flag) == flag;
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
return defValue;
|
||||
}
|
||||
|
||||
|
||||
public IIndexFragment getFragment() {
|
||||
return pdom;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue