mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Support for exception specifications by Sebastian Moss, bug 252697
This commit is contained in:
parent
e9f3d2a3a2
commit
c656d4d2ee
23 changed files with 655 additions and 65 deletions
|
@ -873,6 +873,82 @@ public class IndexUpdateTests extends IndexTestBase {
|
|||
checkValue("C::mem", null);
|
||||
checkValue("e0", 0L);
|
||||
}
|
||||
|
||||
// class A {
|
||||
// public: void foo();
|
||||
// };
|
||||
|
||||
// class A {
|
||||
// public: void foo() throw();
|
||||
// };
|
||||
|
||||
// class A {
|
||||
// public: void foo() throw(int, double);
|
||||
// };
|
||||
|
||||
// class A {
|
||||
// public: void foo() throw();
|
||||
// };
|
||||
|
||||
// class A {
|
||||
// public: void foo();
|
||||
// };
|
||||
public void testExceptionSpecification() throws Exception {
|
||||
ICPPMethod method;
|
||||
IType[] exceptionSpec;
|
||||
setupFile(5, true);
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
method = (ICPPMethod) findBinding("A::foo");
|
||||
exceptionSpec = method.getExceptionSpecification();
|
||||
assertNull(exceptionSpec);
|
||||
} finally {
|
||||
fIndex.releaseReadLock();
|
||||
}
|
||||
|
||||
updateFile();
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
method = (ICPPMethod) findBinding("A::foo");
|
||||
exceptionSpec = method.getExceptionSpecification();
|
||||
assertEquals(0, exceptionSpec.length);
|
||||
} finally {
|
||||
fIndex.releaseReadLock();
|
||||
}
|
||||
|
||||
updateFile();
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
method = (ICPPMethod) findBinding("A::foo");
|
||||
exceptionSpec = method.getExceptionSpecification();
|
||||
assertNotNull(exceptionSpec);
|
||||
assertEquals(2, exceptionSpec.length);
|
||||
assertEquals("int", ASTTypeUtil.getType(exceptionSpec[0]));
|
||||
assertEquals("double", ASTTypeUtil.getType(exceptionSpec[1]));
|
||||
} finally {
|
||||
fIndex.releaseReadLock();
|
||||
}
|
||||
|
||||
updateFile();
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
method = (ICPPMethod) findBinding("A::foo");
|
||||
exceptionSpec = method.getExceptionSpecification();
|
||||
assertEquals(0, exceptionSpec.length);
|
||||
} finally {
|
||||
fIndex.releaseReadLock();
|
||||
}
|
||||
|
||||
updateFile();
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
method = (ICPPMethod) findBinding("A::foo");
|
||||
exceptionSpec = method.getExceptionSpecification();
|
||||
assertNull(exceptionSpec);
|
||||
} finally {
|
||||
fIndex.releaseReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
// int global;
|
||||
// struct C {int mem;};
|
||||
|
|
|
@ -15,6 +15,7 @@ import junit.framework.Test;
|
|||
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
|
||||
|
@ -246,5 +247,59 @@ public class MethodTests extends PDOMTestBase {
|
|||
assertFalse(type.isConst());
|
||||
assertFalse(type.isVolatile());
|
||||
}
|
||||
|
||||
public void testNoExceptionSpecification() throws Exception {
|
||||
IBinding[] bindings = findQualifiedName(pdom, "Class1::noExceptionSpecMethod");
|
||||
assertEquals(1, bindings.length);
|
||||
ICPPMethod method = (ICPPMethod) bindings[0];
|
||||
IType[] exceptionSpec = method.getExceptionSpecification();
|
||||
assertNull(exceptionSpec);
|
||||
}
|
||||
|
||||
public void testEmptyExceptionSpecification() throws Exception {
|
||||
IBinding[] bindings = findQualifiedName(pdom, "Class1::emptyExceptionSpecMethod");
|
||||
assertEquals(1, bindings.length);
|
||||
ICPPMethod method = (ICPPMethod) bindings[0];
|
||||
IType[] exceptionSpec = method.getExceptionSpecification();
|
||||
assertEquals(0, exceptionSpec.length);
|
||||
}
|
||||
|
||||
public void testNonEmptyExceptionSpecification() throws Exception {
|
||||
IBinding[] bindings = findQualifiedName(pdom, "Class1::nonEmptyExceptionSpecMethod");
|
||||
assertEquals(1, bindings.length);
|
||||
ICPPMethod method = (ICPPMethod) bindings[0];
|
||||
IType[] exceptionSpec = method.getExceptionSpecification();
|
||||
assertEquals(1, exceptionSpec.length);
|
||||
assertEquals(IBasicType.t_int, ((ICPPBasicType) exceptionSpec[0]).getType());
|
||||
}
|
||||
|
||||
public void testImplicitCtorExceptionSpec() throws Exception {
|
||||
IBinding[] bindings = findQualifiedPossiblyImplicit(pdom, "D::D");
|
||||
// get both default ctor + copy ctor
|
||||
assertEquals(2, bindings.length);
|
||||
ICPPMethod method = (ICPPMethod) bindings[0];
|
||||
IType[] exceptionSpec = method.getExceptionSpecification();
|
||||
assertNull(exceptionSpec);
|
||||
}
|
||||
|
||||
public void testImplicitCopyCtorExceptionSpec() throws Exception {
|
||||
IBinding[] bindings = findQualifiedPossiblyImplicit(pdom, "D::D");
|
||||
// get both default ctor + copy ctor
|
||||
assertEquals(2, bindings.length);
|
||||
ICPPMethod method = (ICPPMethod) bindings[1];
|
||||
IType[] exceptionSpec = method.getExceptionSpecification();
|
||||
assertEquals(0, exceptionSpec.length);
|
||||
}
|
||||
|
||||
public void testImplicitDtorExceptionSpec() throws Exception {
|
||||
IBinding[] bindings = findQualifiedPossiblyImplicit(pdom, "D::~D");
|
||||
assertEquals(1, bindings.length);
|
||||
ICPPMethod method = (ICPPMethod) bindings[0];
|
||||
IType[] exceptionSpec = method.getExceptionSpecification();
|
||||
assertEquals(2, exceptionSpec.length);
|
||||
int t1= ((ICPPBasicType) exceptionSpec[0]).getType();
|
||||
int t2= ((ICPPBasicType) exceptionSpec[1]).getType();
|
||||
assertEquals(IBasicType.t_int, Math.min(t1, t2));
|
||||
assertEquals(IBasicType.t_double, Math.max(t1, t2));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,6 +120,15 @@ public class PDOMTestBase extends BaseTestCase {
|
|||
}
|
||||
return pdom.findBindings(pattern, true, IndexFilter.ALL_DECLARED, PROGRESS);
|
||||
}
|
||||
|
||||
protected IBinding[] findQualifiedPossiblyImplicit(PDOM pdom, String name) throws CoreException {
|
||||
String[] segments = name.split("::");
|
||||
Pattern[] pattern = new Pattern[segments.length];
|
||||
for (int i = 0; i < segments.length; i++) {
|
||||
pattern[i] = Pattern.compile(segments[i]);
|
||||
}
|
||||
return pdom.findBindings(pattern, true, IndexFilter.ALL, PROGRESS);
|
||||
}
|
||||
|
||||
protected IBinding[] findUnqualifiedName(PDOM pdom, String name) throws CoreException {
|
||||
String[] segments = name.split("::");
|
||||
|
|
|
@ -4,30 +4,48 @@ public:
|
|||
virtual void inheritedMethod();
|
||||
virtual void pureVirtualMethod() = 0;
|
||||
virtual void overriddenMethod();
|
||||
|
||||
|
||||
void noExceptionSpecMethod();
|
||||
void emptyExceptionSpecMethod() throw();
|
||||
void nonEmptyExceptionSpecMethod() throw(int);
|
||||
|
||||
inline int inlineMethod();
|
||||
static int staticMethod();
|
||||
int varArgsMethod(...);
|
||||
int constMethod() const;
|
||||
int volatileMethod() volatile;
|
||||
int constVolatileMethod() const volatile;
|
||||
|
||||
|
||||
// Here, const/volatile applies to the return value, not the method
|
||||
const int *notConstMethod();
|
||||
volatile int *notVolatileMethod();
|
||||
const volatile int *notConstVolatileMethod();
|
||||
|
||||
|
||||
Class1();
|
||||
virtual ~Class1() = 0;
|
||||
};
|
||||
|
||||
struct A {
|
||||
A();
|
||||
A(const A&) throw();
|
||||
~A() throw(int);
|
||||
};
|
||||
|
||||
struct B {
|
||||
B() throw();
|
||||
B(const B&) throw();
|
||||
~B() throw(double);
|
||||
};
|
||||
|
||||
struct D : public A, public B {};
|
||||
|
||||
class Class2 : public Class1 {
|
||||
public:
|
||||
void pureVirtualMethod();
|
||||
void overriddenMethod();
|
||||
void overloadedMethod();
|
||||
void overloadedMethod(int p1);
|
||||
|
||||
|
||||
Class2();
|
||||
~Class2();
|
||||
};
|
||||
|
@ -66,7 +84,7 @@ Class2::~Class2() {
|
|||
}
|
||||
|
||||
class Class3 {
|
||||
int defaultMethod();
|
||||
int defaultMethod();
|
||||
private:
|
||||
void privateMethod();
|
||||
protected:
|
||||
|
@ -85,23 +103,23 @@ int main() {
|
|||
|
||||
pc1->pureVirtualMethod();
|
||||
pc1->pureVirtualMethod();
|
||||
|
||||
|
||||
pc1->overriddenMethod();
|
||||
pc1->overriddenMethod();
|
||||
pc1->overriddenMethod();
|
||||
|
||||
c2.inheritedMethod();
|
||||
pc2->inheritedMethod();
|
||||
|
||||
|
||||
c2.pureVirtualMethod();
|
||||
c2.pureVirtualMethod();
|
||||
pc2->pureVirtualMethod();
|
||||
|
||||
|
||||
c2.overriddenMethod();
|
||||
c2.overriddenMethod();
|
||||
c2.overriddenMethod();
|
||||
pc2->overriddenMethod();
|
||||
|
||||
|
||||
c2.overloadedMethod();
|
||||
pc2->overloadedMethod();
|
||||
|
||||
|
|
|
@ -6,24 +6,23 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Andrew Niefer (IBM Corporation) - initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
|
||||
/*
|
||||
* Created on Mar 15, 2005
|
||||
*/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
* Binding for c++ functions.
|
||||
*
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface ICPPFunction extends IFunction, ICPPBinding {
|
||||
|
||||
/**
|
||||
/**
|
||||
* does this function have the mutable storage class specifier
|
||||
* @throws DOMException
|
||||
*/
|
||||
|
@ -39,4 +38,11 @@ public interface ICPPFunction extends IFunction, ICPPBinding {
|
|||
* @since 5.0
|
||||
*/
|
||||
public boolean isExternC() throws DOMException;
|
||||
|
||||
/**
|
||||
* Returns the exception specification for this function or <code>null</code> if there
|
||||
* is no exception specification.
|
||||
* @since 5.1
|
||||
*/
|
||||
public IType[] getExceptionSpecification() throws DOMException;
|
||||
}
|
||||
|
|
|
@ -143,4 +143,8 @@ public class CPPDeferredFunctionInstance extends CPPUnknownBinding implements IC
|
|||
public IBinding resolveParameter(IASTParameterDeclaration param) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public IType[] getExceptionSpecification() throws DOMException {
|
||||
return ((ICPPFunction)getTemplateDefinition()).getExceptionSpecification();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Andrew Niefer (IBM Corporation) - initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
@ -24,11 +24,13 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
|
@ -44,10 +46,10 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
|||
import org.eclipse.core.runtime.PlatformObject;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
* Binding for c++ function
|
||||
*/
|
||||
public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInternalFunction {
|
||||
|
||||
|
||||
public static class CPPFunctionProblem extends ProblemBinding implements ICPPFunction {
|
||||
public CPPFunctionProblem(IASTNode node, int id, char[] arg) {
|
||||
super(node, id, arg);
|
||||
|
@ -97,6 +99,9 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
|
|||
public boolean takesVarArgs() throws DOMException {
|
||||
throw new DOMException(this);
|
||||
}
|
||||
public IType[] getExceptionSpecification() throws DOMException {
|
||||
throw new DOMException(this);
|
||||
}
|
||||
}
|
||||
|
||||
protected ICPPASTFunctionDeclarator[] declarations;
|
||||
|
@ -213,7 +218,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
|
|||
|
||||
|
||||
public IParameter[] getParameters() {
|
||||
IASTStandardFunctionDeclarator dtor = (definition != null) ? definition : declarations[0];
|
||||
IASTStandardFunctionDeclarator dtor = getPreferredDtor();
|
||||
IASTParameterDeclaration[] params = dtor.getParameters();
|
||||
int size = params.length;
|
||||
IParameter[] result = new IParameter[ size ];
|
||||
|
@ -516,15 +521,8 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
|
|||
}
|
||||
|
||||
public boolean takesVarArgs() {
|
||||
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) getDefinition();
|
||||
if (dtor != null) {
|
||||
return dtor.takesVarArgs();
|
||||
}
|
||||
ICPPASTFunctionDeclarator[] ds = (ICPPASTFunctionDeclarator[]) getDeclarations();
|
||||
if (ds != null && ds.length > 0) {
|
||||
return ds[0].takesVarArgs();
|
||||
}
|
||||
return false;
|
||||
ICPPASTFunctionDeclarator dtor= getPreferredDtor();
|
||||
return dtor != null ? dtor.takesVarArgs() : false;
|
||||
}
|
||||
|
||||
public ILinkage getLinkage() {
|
||||
|
@ -543,4 +541,38 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
|
|||
public IBinding getOwner() throws DOMException {
|
||||
return CPPVisitor.findNameOwner(getASTName(), false);
|
||||
}
|
||||
|
||||
public IType[] getExceptionSpecification() throws DOMException {
|
||||
ICPPASTFunctionDeclarator declarator = getPreferredDtor();
|
||||
if (declarator != null) {
|
||||
IASTTypeId[] astTypeIds= declarator.getExceptionSpecification();
|
||||
if (astTypeIds.equals(ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION))
|
||||
return null;
|
||||
|
||||
if (astTypeIds.equals(IASTTypeId.EMPTY_TYPEID_ARRAY))
|
||||
return IType.EMPTY_TYPE_ARRAY;
|
||||
|
||||
IType[] typeIds = new IType[astTypeIds.length];
|
||||
for (int i=0; i<astTypeIds.length; ++i) {
|
||||
typeIds[i] = CPPVisitor.createType(astTypeIds[i]);
|
||||
}
|
||||
return typeIds;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected ICPPASTFunctionDeclarator getPreferredDtor() {
|
||||
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) getDefinition();
|
||||
if (dtor != null)
|
||||
return dtor;
|
||||
|
||||
ICPPASTFunctionDeclarator[] dtors = (ICPPASTFunctionDeclarator[]) getDeclarations();
|
||||
if (dtors != null) {
|
||||
for (ICPPASTFunctionDeclarator declarator : dtors) {
|
||||
if (declarator != null)
|
||||
return declarator;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
|
|||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
|
||||
|
@ -38,6 +39,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
|||
public class CPPFunctionSpecialization extends CPPSpecialization implements ICPPFunction, ICPPInternalFunction {
|
||||
private IFunctionType type = null;
|
||||
private IParameter[] specializedParams = null;
|
||||
private IType[] specializedExceptionSpec = null;
|
||||
|
||||
public CPPFunctionSpecialization(IBinding orig, IBinding owner, ICPPTemplateParameterMap argMap) {
|
||||
super(orig, owner, argMap);
|
||||
|
@ -249,4 +251,17 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
|
|||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public IType[] getExceptionSpecification() throws DOMException {
|
||||
if (specializedExceptionSpec == null) {
|
||||
ICPPFunction function = (ICPPFunction) getSpecializedBinding();
|
||||
IType[] types = function.getExceptionSpecification();
|
||||
if (types != null) {
|
||||
IType[] specializedTypeList = new IType[types.length];
|
||||
for (int i=0; i<types.length; ++i)
|
||||
specializedTypeList[i] = specializeType(types[i]);
|
||||
}
|
||||
}
|
||||
return specializedExceptionSpec;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ 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.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||
|
@ -94,6 +95,9 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
|
|||
public boolean takesVarArgs() throws DOMException {
|
||||
throw new DOMException(this);
|
||||
}
|
||||
public IType[] getExceptionSpecification() throws DOMException {
|
||||
throw new DOMException( this );
|
||||
}
|
||||
}
|
||||
|
||||
protected IFunctionType type = null;
|
||||
|
@ -355,4 +359,24 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
|
|||
result.append(t != null ? ASTTypeUtil.getParameterTypeString(t) : "()"); //$NON-NLS-1$
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public IType[] getExceptionSpecification() throws DOMException {
|
||||
ICPPASTFunctionDeclarator declarator = getDeclaratorByName(getDefinition());
|
||||
if (declarator != null) {
|
||||
IASTTypeId[] astTypeIds = declarator.getExceptionSpecification();
|
||||
if (astTypeIds.equals(ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION)) {
|
||||
return null;
|
||||
}
|
||||
if (astTypeIds.equals(IASTTypeId.EMPTY_TYPEID_ARRAY)) {
|
||||
return IType.EMPTY_TYPE_ARRAY;
|
||||
}
|
||||
|
||||
IType[] typeIds = new IType[astTypeIds.length];
|
||||
for (int i=0; i<astTypeIds.length; ++i) {
|
||||
typeIds[i] = CPPVisitor.createType(astTypeIds[i]);
|
||||
}
|
||||
return typeIds;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Andrew Niefer (IBM Corporation) - initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
@ -20,15 +20,11 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
|||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
* Binding for implicit constructors (default and copy constructor).
|
||||
*/
|
||||
public class CPPImplicitConstructor extends CPPImplicitMethod implements ICPPConstructor {
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @param params
|
||||
*/
|
||||
public CPPImplicitConstructor( ICPPClassScope scope, char [] name, IParameter[] params ) {
|
||||
public CPPImplicitConstructor(ICPPClassScope scope, char[] name, IParameter[] params) {
|
||||
super( scope, name, createFunctionType(scope, params), params );
|
||||
}
|
||||
|
||||
|
@ -37,9 +33,6 @@ public class CPPImplicitConstructor extends CPPImplicitMethod implements ICPPCon
|
|||
return CPPVisitor.createImplicitFunctionType(returnType, params, null);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor#isExplicit()
|
||||
*/
|
||||
public boolean isExplicit() {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Andrew Niefer (IBM Corporation) - initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
@ -35,7 +35,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
|
|||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
* Binding for implicit methods, base class for implicit constructors.
|
||||
*/
|
||||
public class CPPImplicitMethod extends CPPImplicitFunction implements ICPPMethod {
|
||||
|
||||
|
@ -180,4 +180,8 @@ public class CPPImplicitMethod extends CPPImplicitFunction implements ICPPMethod
|
|||
return getClassOwner();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType[] getExceptionSpecification() throws DOMException {
|
||||
return ClassTypeHelper.getInheritedExceptionSpecification(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||
|
@ -75,7 +76,7 @@ public class CPPMethodSpecialization extends CPPFunctionSpecialization
|
|||
}
|
||||
|
||||
public boolean isImplicit() {
|
||||
return false;
|
||||
return ((ICPPMethod) getSpecializedBinding()).isImplicit();
|
||||
}
|
||||
|
||||
public boolean isPureVirtual() throws DOMException {
|
||||
|
@ -86,4 +87,11 @@ public class CPPMethodSpecialization extends CPPFunctionSpecialization
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType[] getExceptionSpecification() throws DOMException {
|
||||
if (isImplicit()) {
|
||||
return ClassTypeHelper.getInheritedExceptionSpecification(this);
|
||||
}
|
||||
return super.getExceptionSpecification();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,10 +29,15 @@ 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.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IField;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IQualifierType;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
||||
|
@ -45,6 +50,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||
import org.eclipse.cdt.core.index.IIndex;
|
||||
|
@ -207,8 +213,10 @@ public class ClassTypeHelper {
|
|||
ICPPClassType[] bases= getAllBases(ct);
|
||||
for (ICPPClassType base : bases) {
|
||||
set.addAll(base.getDeclaredMethods());
|
||||
scope= (ICPPClassScope) base.getCompositeScope();
|
||||
set.addAll(scope.getImplicitMethods());
|
||||
final IScope compositeScope = base.getCompositeScope();
|
||||
if (compositeScope instanceof ICPPClassScope) {
|
||||
set.addAll(((ICPPClassScope) compositeScope).getImplicitMethods());
|
||||
}
|
||||
}
|
||||
return set.keyArray(ICPPMethod.class);
|
||||
}
|
||||
|
@ -547,4 +555,119 @@ public class ClassTypeHelper {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final int KIND_DEFAULT_CTOR= 0;
|
||||
private static final int KIND_COPY_CTOR= 1;
|
||||
private static final int KIND_ASSIGNMENT_OP= 2;
|
||||
private static final int KIND_DTOR= 3;
|
||||
private static final int KIND_OTHER= 4;
|
||||
|
||||
/**
|
||||
* For implicit methods the exception specification is inherited, search it
|
||||
* @throws DOMException
|
||||
*/
|
||||
public static IType[] getInheritedExceptionSpecification(ICPPMethod implicitMethod) throws DOMException {
|
||||
// See 15.4.13
|
||||
ICPPClassType owner= implicitMethod.getClassOwner();
|
||||
if (owner == null || owner.getBases().length == 0)
|
||||
return null;
|
||||
|
||||
// we use a list as types aren't comparable, and can have duplicates (15.4.6)
|
||||
int kind= getImplicitMethodKind(owner, implicitMethod);
|
||||
if (kind == KIND_OTHER)
|
||||
return null;
|
||||
|
||||
List<IType> inheritedTypeids = new ArrayList<IType>();
|
||||
ICPPClassType[] bases= getAllBases(owner);
|
||||
for (ICPPClassType base : bases) {
|
||||
if (!(base instanceof ICPPDeferredClassInstance)) {
|
||||
ICPPMethod baseMethod= getMethodInClass(base, kind);
|
||||
if (baseMethod != null) {
|
||||
IType[] baseExceptionSpec= baseMethod.getExceptionSpecification();
|
||||
if (baseExceptionSpec == null)
|
||||
return null;
|
||||
for (IType baseTypeId : baseMethod.getExceptionSpecification()) {
|
||||
inheritedTypeids.add(baseTypeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return inheritedTypeids.toArray(new IType[inheritedTypeids.size()]);
|
||||
}
|
||||
|
||||
private static int getImplicitMethodKind(ICPPClassType ct, ICPPMethod method) throws DOMException {
|
||||
if (method instanceof ICPPConstructor) {
|
||||
final IFunctionType type= method.getType();
|
||||
final IType[] params= type.getParameterTypes();
|
||||
if (params.length == 0)
|
||||
return KIND_DEFAULT_CTOR;
|
||||
if (params.length == 1) {
|
||||
IType t= params[0];
|
||||
if (t instanceof IBasicType && ((IBasicType) t).getType() == IBasicType.t_void)
|
||||
return KIND_DEFAULT_CTOR;
|
||||
|
||||
if (isRefToConstClass(ct, t))
|
||||
return KIND_COPY_CTOR;
|
||||
}
|
||||
return KIND_OTHER;
|
||||
}
|
||||
|
||||
if (method.isDestructor())
|
||||
return KIND_DTOR;
|
||||
|
||||
if (CharArrayUtils.equals(method.getNameCharArray(), OverloadableOperator.ASSIGN.toCharArray())) {
|
||||
final IFunctionType type= method.getType();
|
||||
final IType[] params= type.getParameterTypes();
|
||||
if (params.length == 1) {
|
||||
IType t= params[0];
|
||||
if (isRefToConstClass(ct, t))
|
||||
return KIND_ASSIGNMENT_OP;
|
||||
}
|
||||
return KIND_OTHER;
|
||||
}
|
||||
return KIND_OTHER;
|
||||
}
|
||||
|
||||
private static boolean isRefToConstClass(ICPPClassType ct, IType t) throws DOMException {
|
||||
while (t instanceof ITypedef)
|
||||
t= ((ITypedef) t).getType();
|
||||
|
||||
if (t instanceof ICPPReferenceType) {
|
||||
t= ((ICPPReferenceType) t).getType();
|
||||
while (t instanceof ITypedef)
|
||||
t= ((ITypedef) t).getType();
|
||||
if (t instanceof IQualifierType) {
|
||||
t= ((IQualifierType) t).getType();
|
||||
return ct.isSameType(t);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static ICPPMethod getMethodInClass(ICPPClassType ct, int kind) throws DOMException {
|
||||
switch(kind) {
|
||||
case KIND_DEFAULT_CTOR:
|
||||
case KIND_COPY_CTOR:
|
||||
for (ICPPConstructor ctor : ct.getConstructors()) {
|
||||
if (!ctor.isImplicit() && getImplicitMethodKind(ct, ctor) == kind)
|
||||
return ctor;
|
||||
}
|
||||
return null;
|
||||
case KIND_ASSIGNMENT_OP:
|
||||
for (ICPPMethod method : ct.getDeclaredMethods()) {
|
||||
if (method instanceof ICPPConstructor)
|
||||
continue;
|
||||
if (getImplicitMethodKind(ct, method) == kind)
|
||||
return method;
|
||||
}
|
||||
return null;
|
||||
case KIND_DTOR:
|
||||
for (ICPPMethod method : ct.getDeclaredMethods()) {
|
||||
if (method.isDestructor())
|
||||
return method;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1617,6 +1617,9 @@ public class CPPVisitor extends ASTQueries {
|
|||
}
|
||||
|
||||
public static IType createType(IASTDeclarator declarator) {
|
||||
if (declarator == null)
|
||||
return null;
|
||||
|
||||
IASTDeclSpecifier declSpec = null;
|
||||
|
||||
IASTNode node = declarator.getParent();
|
||||
|
|
|
@ -92,4 +92,16 @@ class CompositeCPPFunction extends CompositeCPPBinding implements ICPPFunction {
|
|||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public IType[] getExceptionSpecification() throws DOMException {
|
||||
IType[] es= ((ICPPFunction)rbinding).getExceptionSpecification();
|
||||
if (es == null || es.length == 0)
|
||||
return es;
|
||||
|
||||
IType[] result= new IType[es.length];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i]= cf.getCompositeType((IIndexType) es[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,11 +14,13 @@ package org.eclipse.cdt.internal.core.index.composite.cpp;
|
|||
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
||||
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexType;
|
||||
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
|
||||
|
||||
public class CompositeCPPFunctionSpecialization extends CompositeCPPFunction implements ICPPSpecialization {
|
||||
|
@ -53,8 +55,21 @@ public class CompositeCPPFunctionSpecialization extends CompositeCPPFunction imp
|
|||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType[] getExceptionSpecification() throws DOMException {
|
||||
IType[] es= ((ICPPFunction)rbinding).getExceptionSpecification();
|
||||
if (es == null || es.length == 0)
|
||||
return es;
|
||||
|
||||
IType[] result= new IType[es.length];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i]= cf.getCompositeType((IIndexType) result[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public ObjectMap getArgumentMap() {
|
||||
return TemplateInstanceUtil.getArgumentMap(cf, rbinding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -165,11 +165,12 @@ public class PDOM extends PlatformObject implements IPDOM {
|
|||
* 73.0 - add values for variables and enumerations, bug 250788
|
||||
* 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
|
||||
*/
|
||||
private static int version(int major, int minor) {
|
||||
return major << 16 + minor;
|
||||
}
|
||||
public static final int MAJOR_VERSION = 75;
|
||||
public static final int MAJOR_VERSION = 76;
|
||||
public static final int MINOR_VERSION = 0; // minor versions must be compatible
|
||||
|
||||
public static final int CURRENT_VERSION= version(MAJOR_VERSION, MINOR_VERSION);
|
||||
|
|
|
@ -6,24 +6,23 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
* Doug Schaefer (QNX) - Initial API and implementation
|
||||
* IBM Corporation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||
import org.eclipse.cdt.internal.core.Util;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
|
||||
import org.eclipse.cdt.internal.core.index.IndexCPPSignatureUtil;
|
||||
|
@ -38,8 +37,7 @@ import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCAnnotation;
|
|||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
* Binding for c++ functions in the index.
|
||||
*/
|
||||
class PDOMCPPFunction extends PDOMCPPBinding implements ICPPFunction, IPDOMOverloader {
|
||||
|
||||
|
@ -65,18 +63,23 @@ class PDOMCPPFunction extends PDOMCPPBinding implements ICPPFunction, IPDOMOverl
|
|||
* Offset of hash of parameter information to allow fast comparison
|
||||
*/
|
||||
private static final int SIGNATURE_HASH = PDOMCPPBinding.RECORD_SIZE + 12;
|
||||
|
||||
/**
|
||||
* Offset of start of exception specifications
|
||||
*/
|
||||
protected static final int EXCEPTION_SPEC = PDOMCPPBinding.RECORD_SIZE + 16; // int
|
||||
|
||||
/**
|
||||
* Offset of annotation information (relative to the beginning of the
|
||||
* record).
|
||||
*/
|
||||
protected static final int ANNOTATION = PDOMCPPBinding.RECORD_SIZE + 16; // byte
|
||||
|
||||
protected static final int ANNOTATION = PDOMCPPBinding.RECORD_SIZE + 20; // byte
|
||||
|
||||
/**
|
||||
* The size in bytes of a PDOMCPPFunction record in the database.
|
||||
*/
|
||||
@SuppressWarnings("hiding")
|
||||
protected static final int RECORD_SIZE = PDOMCPPBinding.RECORD_SIZE + 17;
|
||||
protected static final int RECORD_SIZE = PDOMCPPBinding.RECORD_SIZE + 21;
|
||||
|
||||
public PDOMCPPFunction(PDOM pdom, PDOMNode parent, ICPPFunction function, boolean setTypes) throws CoreException {
|
||||
super(pdom, parent, function.getNameCharArray());
|
||||
|
@ -89,6 +92,7 @@ class PDOMCPPFunction extends PDOMCPPBinding implements ICPPFunction, IPDOMOverl
|
|||
initData((ICPPFunctionType) function.getType(), function.getParameters());
|
||||
}
|
||||
db.putByte(record + ANNOTATION, PDOMCPPAnnotation.encodeAnnotation(function));
|
||||
storeExceptionSpec(db, function);
|
||||
} catch (DOMException e) {
|
||||
throw new CoreException(Util.createStatus(e));
|
||||
}
|
||||
|
@ -102,7 +106,7 @@ class PDOMCPPFunction extends PDOMCPPBinding implements ICPPFunction, IPDOMOverl
|
|||
@Override
|
||||
public void update(final PDOMLinkage linkage, IBinding newBinding) throws CoreException {
|
||||
if (newBinding instanceof ICPPFunction) {
|
||||
IFunction func= (ICPPFunction) newBinding;
|
||||
ICPPFunction func= (ICPPFunction) newBinding;
|
||||
ICPPFunctionType newType;
|
||||
IParameter[] newParams;
|
||||
byte newAnnotation;
|
||||
|
@ -123,10 +127,31 @@ class PDOMCPPFunction extends PDOMCPPBinding implements ICPPFunction, IPDOMOverl
|
|||
if (oldParams != null) {
|
||||
oldParams.delete(linkage);
|
||||
}
|
||||
pdom.getDB().putByte(record + ANNOTATION, newAnnotation);
|
||||
final Database db = pdom.getDB();
|
||||
db.putByte(record + ANNOTATION, newAnnotation);
|
||||
|
||||
int oldRec = db.getInt(record+EXCEPTION_SPEC);
|
||||
storeExceptionSpec(db, func);
|
||||
if (oldRec != 0) {
|
||||
PDOMCPPTypeList.clearTypes(this, oldRec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void storeExceptionSpec(final Database db, ICPPFunction binding) throws CoreException {
|
||||
int typelist= 0;
|
||||
try {
|
||||
if (binding instanceof ICPPMethod && ((ICPPMethod) binding).isImplicit()) {
|
||||
// don't store the exception specification, computed it on demand.
|
||||
} else {
|
||||
typelist = PDOMCPPTypeList.putTypes(this, binding.getExceptionSpecification());
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
// ignore problems in the exception specification.
|
||||
}
|
||||
db.putInt(record + EXCEPTION_SPEC, typelist);
|
||||
}
|
||||
|
||||
private void setParameters(PDOMCPPFunctionType pft, IParameter[] params) throws CoreException {
|
||||
final Database db= pdom.getDB();
|
||||
db.putInt(record + NUM_PARAMS, params.length);
|
||||
|
@ -282,4 +307,14 @@ class PDOMCPPFunction extends PDOMCPPBinding implements ICPPFunction, IPDOMOverl
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public IType[] getExceptionSpecification() throws DOMException {
|
||||
try {
|
||||
final int rec = getPDOM().getDB().getInt(record+EXCEPTION_SPEC);
|
||||
return PDOMCPPTypeList.getTypes(this, rec);
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
|
|||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
@ -32,8 +33,12 @@ import org.eclipse.core.runtime.CoreException;
|
|||
*/
|
||||
class PDOMCPPFunctionInstance extends PDOMCPPFunctionSpecialization implements ICPPTemplateInstance {
|
||||
private static final int ARGUMENTS = PDOMCPPFunctionSpecialization.RECORD_SIZE + 0;
|
||||
|
||||
@SuppressWarnings("hiding")
|
||||
protected static final int RECORD_SIZE = PDOMCPPFunctionSpecialization.RECORD_SIZE + 4;
|
||||
private static final int EXCEPTION_SPEC = PDOMCPPFunctionSpecialization.RECORD_SIZE + 4;
|
||||
|
||||
@SuppressWarnings("hiding")
|
||||
protected static final int RECORD_SIZE = PDOMCPPFunctionSpecialization.RECORD_SIZE + 8;
|
||||
|
||||
public PDOMCPPFunctionInstance(PDOM pdom, PDOMNode parent, ICPPFunction function, PDOMBinding orig)
|
||||
throws CoreException {
|
||||
|
@ -41,7 +46,15 @@ class PDOMCPPFunctionInstance extends PDOMCPPFunctionSpecialization implements I
|
|||
|
||||
final ICPPTemplateInstance asInstance= (ICPPTemplateInstance) function;
|
||||
final int argListRec= PDOMCPPArgumentList.putArguments(this, asInstance.getTemplateArguments());
|
||||
pdom.getDB().putInt(record+ARGUMENTS, argListRec);
|
||||
final Database db = pdom.getDB();
|
||||
db.putInt(record+ARGUMENTS, argListRec);
|
||||
|
||||
try {
|
||||
int exceptSpecRec = PDOMCPPTypeList.putTypes(this, function.getExceptionSpecification());
|
||||
db.putInt(record+EXCEPTION_SPEC, exceptSpecRec);
|
||||
} catch (DOMException e) {
|
||||
// ignore problems in the exception specification
|
||||
}
|
||||
}
|
||||
|
||||
public PDOMCPPFunctionInstance(PDOM pdom, int bindingRecord) {
|
||||
|
@ -73,6 +86,17 @@ class PDOMCPPFunctionInstance extends PDOMCPPFunctionSpecialization implements I
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType[] getExceptionSpecification() throws DOMException {
|
||||
try {
|
||||
final int rec = getPDOM().getDB().getInt(record+EXCEPTION_SPEC);
|
||||
return PDOMCPPTypeList.getTypes(this, rec);
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public IType[] getArguments() {
|
||||
return CPPTemplates.getArguments(getTemplateArguments());
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 QNX Software Systems and others.
|
||||
* Copyright (c) 2007, 2008 QNX Software Systems and others.
|
||||
* 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:
|
||||
* QNX - Initial API and implementation
|
||||
* Bryan Wilkinson (QNX) - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
|
||||
|
@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.IParameter;
|
|||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
|
||||
import org.eclipse.cdt.internal.core.Util;
|
||||
|
@ -31,8 +32,7 @@ import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCAnnotation;
|
|||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* @author Bryan Wilkinson
|
||||
*
|
||||
* Binding for function specialization in the index.
|
||||
*/
|
||||
class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization implements ICPPFunction {
|
||||
/**
|
||||
|
@ -53,17 +53,22 @@ class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization implements ICP
|
|||
*/
|
||||
private static final int FUNCTION_TYPE = PDOMCPPSpecialization.RECORD_SIZE + 8;
|
||||
|
||||
/**
|
||||
* Offset of start of exception specification
|
||||
*/
|
||||
protected static final int EXCEPTION_SPEC = PDOMCPPSpecialization.RECORD_SIZE + 12; // int
|
||||
|
||||
/**
|
||||
* Offset of annotation information (relative to the beginning of the
|
||||
* record).
|
||||
*/
|
||||
protected static final int ANNOTATION = PDOMCPPSpecialization.RECORD_SIZE + 12; // byte
|
||||
protected static final int ANNOTATION = PDOMCPPSpecialization.RECORD_SIZE + 16; // byte
|
||||
|
||||
/**
|
||||
* The size in bytes of a PDOMCPPFunction record in the database.
|
||||
*/
|
||||
@SuppressWarnings("hiding")
|
||||
protected static final int RECORD_SIZE = PDOMCPPSpecialization.RECORD_SIZE + 13;
|
||||
protected static final int RECORD_SIZE = PDOMCPPSpecialization.RECORD_SIZE + 17;
|
||||
|
||||
public PDOMCPPFunctionSpecialization(PDOM pdom, PDOMNode parent, ICPPFunction function, PDOMBinding specialized) throws CoreException {
|
||||
super(pdom, parent, (ICPPSpecialization) function, specialized);
|
||||
|
@ -95,10 +100,22 @@ class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization implements ICP
|
|||
PDOMCPPParameter sParam = new PDOMCPPParameter(pdom, this, sParams[i], type);
|
||||
setFirstParameter(new PDOMCPPParameterSpecialization(pdom, this, (ICPPParameter) params[i], sParam, typeRecord));
|
||||
}
|
||||
db.putByte(record + ANNOTATION, PDOMCPPAnnotation.encodeAnnotation(function));
|
||||
db.putByte(record + ANNOTATION, PDOMCPPAnnotation.encodeAnnotation(function));
|
||||
} catch (DOMException e) {
|
||||
throw new CoreException(Util.createStatus(e));
|
||||
}
|
||||
try {
|
||||
int typelist= 0;
|
||||
if (function instanceof ICPPMethod && ((ICPPMethod) function).isImplicit()) {
|
||||
// don't store the exception specification, computed it on demand.
|
||||
} else {
|
||||
typelist = PDOMCPPTypeList.putTypes(this, function.getExceptionSpecification());
|
||||
}
|
||||
db.putInt(record + EXCEPTION_SPEC, typelist);
|
||||
} catch (DOMException e) {
|
||||
// ignore problems in the exception specification
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public PDOMCPPFunctionSpecialization(PDOM pdom, int bindingRecord) {
|
||||
|
@ -208,4 +225,14 @@ class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization implements ICP
|
|||
int cmp= super.pdomCompareTo(other);
|
||||
return cmp==0 ? PDOMCPPFunction.compareSignatures(this, other) : cmp;
|
||||
}
|
||||
|
||||
public IType[] getExceptionSpecification() throws DOMException {
|
||||
try {
|
||||
final int rec = getPDOM().getDB().getInt(record+EXCEPTION_SPEC);
|
||||
return PDOMCPPTypeList.getTypes(this, rec);
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||
import org.eclipse.cdt.internal.core.Util;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||
|
@ -198,4 +199,12 @@ class PDOMCPPMethod extends PDOMCPPFunction implements ICPPMethod {
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType[] getExceptionSpecification() throws DOMException {
|
||||
if (isImplicit()) {
|
||||
return ClassTypeHelper.getInheritedExceptionSpecification(this);
|
||||
}
|
||||
return super.getExceptionSpecification();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,10 +12,12 @@
|
|||
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||
import org.eclipse.cdt.internal.core.Util;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||
|
@ -121,4 +123,12 @@ class PDOMCPPMethodSpecialization extends PDOMCPPFunctionSpecialization
|
|||
public boolean isVolatile() {
|
||||
return getBit(getByte(record + ANNOTATION1), PDOMCAnnotation.VOLATILE_OFFSET + CV_OFFSET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType[] getExceptionSpecification() throws DOMException {
|
||||
if (isImplicit()) {
|
||||
return ClassTypeHelper.getInheritedExceptionSpecification(this);
|
||||
}
|
||||
return super.getExceptionSpecification();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
|
||||
import org.eclipse.core.runtime.Assert;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* Stores a typelist
|
||||
* TODO could refactor to have common base shared by {@link PDOMCPPArgumentList} using generics
|
||||
*/
|
||||
class PDOMCPPTypeList {
|
||||
|
||||
protected static final int NODE_SIZE = 4;
|
||||
|
||||
/**
|
||||
* Stores the given types in the database.
|
||||
* @return the record by which the types can be referenced.
|
||||
*/
|
||||
public static int putTypes(PDOMNode parent, IType[] types) throws CoreException {
|
||||
if (types == null)
|
||||
return 0;
|
||||
|
||||
final PDOMLinkage linkage= parent.getLinkage();
|
||||
final Database db= linkage.getPDOM().getDB();
|
||||
final short len = (short)Math.min(types.length, (Database.MAX_MALLOC_SIZE-2)/NODE_SIZE);
|
||||
final int block = db.malloc(2+ NODE_SIZE*len);
|
||||
int p = block;
|
||||
|
||||
db.putShort(p, len); p+=2;
|
||||
for (int i=0; i<len; i++, p+=NODE_SIZE) {
|
||||
final IType type = types[i];
|
||||
if (type != null) {
|
||||
final PDOMNode pdomType = linkage.addType(parent, type);
|
||||
db.putInt(p, pdomType.getRecord());
|
||||
} else {
|
||||
db.putInt(p, 0);
|
||||
}
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
public static IType[] getTypes(PDOMNode parent, int rec) throws CoreException {
|
||||
if (rec == 0)
|
||||
return null;
|
||||
|
||||
final PDOMLinkage linkage= parent.getLinkage();
|
||||
final Database db= linkage.getPDOM().getDB();
|
||||
final short len = db.getShort(rec);
|
||||
|
||||
if (len == 0)
|
||||
return IType.EMPTY_TYPE_ARRAY;
|
||||
|
||||
Assert.isTrue(len >= 0 && len <= (Database.MAX_MALLOC_SIZE-2)/NODE_SIZE);
|
||||
rec+=2;
|
||||
IType[] result= new IType[len];
|
||||
for (int i=0; i<len; i++, rec+=NODE_SIZE) {
|
||||
final int typeRec= db.getInt(rec);
|
||||
if (typeRec != 0)
|
||||
result[i]= (IType)linkage.getNode(typeRec);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores an array of template arguments from the database.
|
||||
*/
|
||||
public static void clearTypes(PDOMNode parent, final int record) throws CoreException {
|
||||
if (record == 0)
|
||||
return;
|
||||
|
||||
final PDOMLinkage linkage= parent.getLinkage();
|
||||
final Database db= linkage.getPDOM().getDB();
|
||||
final short len= db.getShort(record);
|
||||
|
||||
Assert.isTrue(len >= 0 && len <= (Database.MAX_MALLOC_SIZE-2)/NODE_SIZE);
|
||||
int p= record+2;
|
||||
for (int i=0; i<len; i++, p+=NODE_SIZE) {
|
||||
final int typeRec= db.getInt(p);
|
||||
final IType t= (IType) linkage.getNode(typeRec);
|
||||
linkage.deleteType(t, parent.getRecord());
|
||||
}
|
||||
db.free(record);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue