1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-09-01 04:33:36 +02:00

Support for parameter annotations by Sebastian Moss, bug 254520.

This commit is contained in:
Markus Schorn 2008-11-11 12:43:26 +00:00
parent 0700a8fe68
commit edeb6f1af1
9 changed files with 127 additions and 49 deletions

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * IBM Corporation - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.pdom.tests; package org.eclipse.cdt.internal.pdom.tests;
import junit.framework.Test; import junit.framework.Test;
@ -36,12 +35,14 @@ public class CFunctionTests extends PDOMTestBase {
return suite(CFunctionTests.class); return suite(CFunctionTests.class);
} }
@Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
project = createProject("functionTests"); project = createProject("functionTests");
pdom = (PDOM) CCoreInternals.getPDOMManager().getPDOM(project); pdom = (PDOM) CCoreInternals.getPDOMManager().getPDOM(project);
pdom.acquireReadLock(); pdom.acquireReadLock();
} }
@Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
pdom.releaseReadLock(); pdom.releaseReadLock();
if (project != null) { if (project != null) {
@ -84,4 +85,14 @@ public class CFunctionTests extends PDOMTestBase {
assertTrue(params[1].getType() instanceof ICBasicType); assertTrue(params[1].getType() instanceof ICBasicType);
assertTrue(params[2].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());
}
} }

View file

@ -111,6 +111,16 @@ public class CPPFunctionTests extends PDOMTestBase {
assertEquals("p3", parameters[2].getName()); 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 { public void testExternCPPFunction() throws Exception {
IBinding[] bindings = findQualifiedName(pdom, "externCPPFunction"); IBinding[] bindings = findQualifiedName(pdom, "externCPPFunction");
assertEquals(1, bindings.length); assertEquals(1, bindings.length);

View file

@ -5,6 +5,7 @@ inline void inlineCFunction(long p1);
void varArgsCFunction(int p1, ...); void varArgsCFunction(int p1, ...);
const void constCFunction(); const void constCFunction();
volatile void volatileCFunction(); volatile void volatileCFunction();
void storageClassCFunction(register int p1, int p2);
void voidCFunction(); void voidCFunction();
int intCFunction(); int intCFunction();

View file

@ -1,4 +1,5 @@
double normalCPPFunction(int p1, char p2, float p3); double normalCPPFunction(int p1, char p2, float p3);
void storageClassCPPFunction(register int p1, auto int p2);
static int staticCPPFunction(double p1); static int staticCPPFunction(double p1);
extern float externCPPFunction(int p1); extern float externCPPFunction(int p1);
inline void inlineCPPFunction(long p1); inline void inlineCPPFunction(long p1);

View file

@ -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.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; 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.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IParameter;
@ -174,21 +175,25 @@ public class CParameter extends PlatformObject implements IParameter {
return hasStorageClass( IASTDeclSpecifier.sc_register ); return hasStorageClass( IASTDeclSpecifier.sc_register );
} }
public boolean hasStorageClass( int storage ){ public boolean hasStorageClass(int storage) {
if( declarations == null ) if (declarations == null)
return false; return false;
for( int i = 0; i < declarations.length && declarations[i] != null; i++ ){
IASTNode parent = declarations[i].getParent(); for (int i = 0; i < declarations.length && declarations[i] != null; i++) {
while( !(parent instanceof IASTDeclaration) ) IASTNode parent= declarations[i].getParent();
parent = parent.getParent(); while (!(parent instanceof IASTParameterDeclaration) && !(parent instanceof IASTDeclaration))
parent= parent.getParent();
if( parent instanceof IASTSimpleDeclaration ){
IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration)parent).getDeclSpecifier(); IASTDeclSpecifier declSpec = null;
if( declSpec.getStorageClass() == storage ) if (parent instanceof IASTSimpleDeclaration) {
return true; declSpec = ((IASTSimpleDeclaration) parent).getDeclSpecifier();
} } else if (parent instanceof IASTParameterDeclaration) {
} declSpec = ((IASTParameterDeclaration) parent).getDeclSpecifier();
return false; }
if (declSpec != null)
return declSpec.getStorageClass() == storage;
}
return false;
} }
public ILinkage getLinkage() { public ILinkage getLinkage() {

View file

@ -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.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; 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.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; 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) { public boolean hasStorageClass(int storage) {
IASTNode[] ns = getDeclarations(); IASTNode[] ns = getDeclarations();
if (ns == null) if (ns == null)
return false; return false;
for (int i = 0; i < ns.length && ns[i] != null; i++) { for (int i = 0; i < ns.length && ns[i] != null; i++) {
IASTNode parent = ns[i].getParent(); IASTNode parent = ns[i].getParent();
while (!(parent instanceof IASTDeclaration)) while (!(parent instanceof IASTParameterDeclaration))
parent = parent.getParent(); parent = parent.getParent();
IASTDeclSpecifier declSpec = ((IASTParameterDeclaration) parent).getDeclSpecifier();
if (parent instanceof IASTSimpleDeclaration) { if (declSpec.getStorageClass() == storage)
IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration)parent).getDeclSpecifier(); return true;
if (declSpec.getStorageClass() == storage) }
return true; return false;
}
}
return false;
} }
public IASTInitializer getDefaultValue() { public IASTInitializer getDefaultValue() {

View file

@ -166,11 +166,12 @@ public class PDOM extends PlatformObject implements IPDOM {
* 74.0 - changes for proper template argument support, bug 242668 * 74.0 - changes for proper template argument support, bug 242668
* 75.0 - support for friends, bug 250167 * 75.0 - support for friends, bug 250167
* 76.0 - support for exception specification, bug 252697 * 76.0 - support for exception specification, bug 252697
* 77.0 - support for parameter annotations, bug 254520
*/ */
private static int version(int major, int minor) { private static int version(int major, int minor) {
return major << 16 + 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 MINOR_VERSION = 0; // minor versions must be compatible
public static final int CURRENT_VERSION= version(MAJOR_VERSION, MINOR_VERSION); public static final int CURRENT_VERSION= version(MAJOR_VERSION, MINOR_VERSION);

View file

@ -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 NEXT_PARAM = PDOMNamedNode.RECORD_SIZE + 0;
private static final int TYPE = PDOMNamedNode.RECORD_SIZE + 4; private static final int TYPE = PDOMNamedNode.RECORD_SIZE + 4;
protected static final int FLAGS = PDOMNamedNode.RECORD_SIZE + 8;
@SuppressWarnings("hiding") @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) { public PDOMCParameter(PDOM pdom, int record) {
super(pdom, record); super(pdom, record);
} }
@ -62,6 +67,8 @@ class PDOMCParameter extends PDOMNamedNode implements IParameter, IPDOMBinding {
PDOMNode typeNode = getLinkageImpl().addType(this, type); PDOMNode typeNode = getLinkageImpl().addType(this, type);
db.putInt(record + TYPE, typeNode != null ? typeNode.getRecord() : 0); db.putInt(record + TYPE, typeNode != null ? typeNode.getRecord() : 0);
} }
byte flags = encodeFlags(param);
db.putByte(record + FLAGS, flags);
} }
} catch(DOMException e) { } catch(DOMException e) {
throw new CoreException(Util.createStatus(e)); throw new CoreException(Util.createStatus(e));
@ -105,7 +112,8 @@ class PDOMCParameter extends PDOMNamedNode implements IParameter, IPDOMBinding {
} }
public boolean isAuto() throws DOMException { public boolean isAuto() throws DOMException {
throw new PDOMNotImplementedError(); byte flag = 1<<PDOMCAnnotation.AUTO_OFFSET;
return hasFlag(flag, true);
} }
public boolean isExtern() throws DOMException { public boolean isExtern() throws DOMException {
@ -113,7 +121,8 @@ class PDOMCParameter extends PDOMNamedNode implements IParameter, IPDOMBinding {
} }
public boolean isRegister() throws DOMException { public boolean isRegister() throws DOMException {
throw new PDOMNotImplementedError(); byte flag = 1<<PDOMCAnnotation.REGISTER_OFFSET;
return hasFlag(flag, false);
} }
public boolean isStatic() throws DOMException { public boolean isStatic() throws DOMException {
@ -198,4 +207,23 @@ class PDOMCParameter extends PDOMNamedNode implements IParameter, IPDOMBinding {
public IValue getInitialValue() { public IValue getInitialValue() {
return null; 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;
}
} }

View file

@ -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.PDOMNamedNode;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; 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.PDOMNotImplementedError;
import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCAnnotation;
import org.eclipse.core.runtime.CoreException; 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; 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 * Offset of flags
* (relative to the beginning of the record). * (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. * The size in bytes of a PDOMCPPParameter record in the database.
*/ */
@SuppressWarnings("hiding") @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; 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); db.putInt(record + NEXT_PARAM, 0);
byte flags= encodeFlags(param); byte flags= encodeFlags(param);
db.putByte(record + FLAGS, flags); db.putByte(record + FLAGS, flags);
try { try {
if (type == null) if (type == null)
type= param.getType(); type= param.getType();
@ -85,6 +95,8 @@ class PDOMCPPParameter extends PDOMNamedNode implements ICPPParameter, IPDOMBind
PDOMNode typeNode = getLinkageImpl().addType(this, type); PDOMNode typeNode = getLinkageImpl().addType(this, type);
db.putInt(record + TYPE, typeNode != null ? typeNode.getRecord() : 0); db.putInt(record + TYPE, typeNode != null ? typeNode.getRecord() : 0);
} }
byte annotations = PDOMCPPAnnotation.encodeAnnotation(param);
db.putByte(record + ANNOTATIONS, annotations);
} catch (DOMException e) { } catch (DOMException e) {
throw new CoreException(Util.createStatus(e)); throw new CoreException(Util.createStatus(e));
} }
@ -101,6 +113,14 @@ class PDOMCPPParameter extends PDOMNamedNode implements ICPPParameter, IPDOMBind
db.putByte(record + FLAGS, flags); db.putByte(record + FLAGS, flags);
db.putInt(record + TYPE, typeRecord); 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) { private byte encodeFlags(IParameter param) {
@ -160,7 +180,9 @@ class PDOMCPPParameter extends PDOMNamedNode implements ICPPParameter, IPDOMBind
} }
public boolean isAuto() throws DOMException { 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 { public boolean isExtern() throws DOMException {
@ -173,7 +195,9 @@ class PDOMCPPParameter extends PDOMNamedNode implements ICPPParameter, IPDOMBind
} }
public boolean isRegister() throws DOMException { 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 { public boolean isStatic() throws DOMException {
@ -205,19 +229,19 @@ class PDOMCPPParameter extends PDOMNamedNode implements ICPPParameter, IPDOMBind
} }
public boolean hasDefaultValue() { 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 { try {
byte myflags= pdom.getDB().getByte(record + FLAGS); byte myflags= pdom.getDB().getByte(record + offset);
return (myflags & flag) == flag; return (myflags & flag) == flag;
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
} }
return defValue; return defValue;
} }
public IIndexFragment getFragment() { public IIndexFragment getFragment() {
return pdom; return pdom;
} }