1
0
Fork 0
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:
Markus Schorn 2008-11-10 15:46:54 +00:00
parent e9f3d2a3a2
commit c656d4d2ee
23 changed files with 655 additions and 65 deletions

View file

@ -873,6 +873,82 @@ public class IndexUpdateTests extends IndexTestBase {
checkValue("C::mem", null); checkValue("C::mem", null);
checkValue("e0", 0L); 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; // int global;
// struct C {int mem;}; // struct C {int mem;};

View file

@ -15,6 +15,7 @@ import junit.framework.Test;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
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;
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.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; 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.ICPPFunctionType;
@ -246,5 +247,59 @@ public class MethodTests extends PDOMTestBase {
assertFalse(type.isConst()); assertFalse(type.isConst());
assertFalse(type.isVolatile()); 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));
}
} }

View file

@ -120,6 +120,15 @@ public class PDOMTestBase extends BaseTestCase {
} }
return pdom.findBindings(pattern, true, IndexFilter.ALL_DECLARED, PROGRESS); 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 { protected IBinding[] findUnqualifiedName(PDOM pdom, String name) throws CoreException {
String[] segments = name.split("::"); String[] segments = name.split("::");

View file

@ -4,30 +4,48 @@ public:
virtual void inheritedMethod(); virtual void inheritedMethod();
virtual void pureVirtualMethod() = 0; virtual void pureVirtualMethod() = 0;
virtual void overriddenMethod(); virtual void overriddenMethod();
void noExceptionSpecMethod();
void emptyExceptionSpecMethod() throw();
void nonEmptyExceptionSpecMethod() throw(int);
inline int inlineMethod(); inline int inlineMethod();
static int staticMethod(); static int staticMethod();
int varArgsMethod(...); int varArgsMethod(...);
int constMethod() const; int constMethod() const;
int volatileMethod() volatile; int volatileMethod() volatile;
int constVolatileMethod() const volatile; int constVolatileMethod() const volatile;
// Here, const/volatile applies to the return value, not the method // Here, const/volatile applies to the return value, not the method
const int *notConstMethod(); const int *notConstMethod();
volatile int *notVolatileMethod(); volatile int *notVolatileMethod();
const volatile int *notConstVolatileMethod(); const volatile int *notConstVolatileMethod();
Class1(); Class1();
virtual ~Class1() = 0; 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 { class Class2 : public Class1 {
public: public:
void pureVirtualMethod(); void pureVirtualMethod();
void overriddenMethod(); void overriddenMethod();
void overloadedMethod(); void overloadedMethod();
void overloadedMethod(int p1); void overloadedMethod(int p1);
Class2(); Class2();
~Class2(); ~Class2();
}; };
@ -66,7 +84,7 @@ Class2::~Class2() {
} }
class Class3 { class Class3 {
int defaultMethod(); int defaultMethod();
private: private:
void privateMethod(); void privateMethod();
protected: protected:
@ -85,23 +103,23 @@ int main() {
pc1->pureVirtualMethod(); pc1->pureVirtualMethod();
pc1->pureVirtualMethod(); pc1->pureVirtualMethod();
pc1->overriddenMethod(); pc1->overriddenMethod();
pc1->overriddenMethod(); pc1->overriddenMethod();
pc1->overriddenMethod(); pc1->overriddenMethod();
c2.inheritedMethod(); c2.inheritedMethod();
pc2->inheritedMethod(); pc2->inheritedMethod();
c2.pureVirtualMethod(); c2.pureVirtualMethod();
c2.pureVirtualMethod(); c2.pureVirtualMethod();
pc2->pureVirtualMethod(); pc2->pureVirtualMethod();
c2.overriddenMethod(); c2.overriddenMethod();
c2.overriddenMethod(); c2.overriddenMethod();
c2.overriddenMethod(); c2.overriddenMethod();
pc2->overriddenMethod(); pc2->overriddenMethod();
c2.overloadedMethod(); c2.overloadedMethod();
pc2->overloadedMethod(); pc2->overloadedMethod();

View file

@ -6,24 +6,23 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
/*
* Created on Mar 15, 2005
*/
package org.eclipse.cdt.core.dom.ast.cpp; package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IFunction; 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 { public interface ICPPFunction extends IFunction, ICPPBinding {
/** /**
* does this function have the mutable storage class specifier * does this function have the mutable storage class specifier
* @throws DOMException * @throws DOMException
*/ */
@ -39,4 +38,11 @@ public interface ICPPFunction extends IFunction, ICPPBinding {
* @since 5.0 * @since 5.0
*/ */
public boolean isExternC() throws DOMException; 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;
} }

View file

@ -143,4 +143,8 @@ public class CPPDeferredFunctionInstance extends CPPUnknownBinding implements IC
public IBinding resolveParameter(IASTParameterDeclaration param) { public IBinding resolveParameter(IASTParameterDeclaration param) {
return null; return null;
} }
public IType[] getExceptionSpecification() throws DOMException {
return ((ICPPFunction)getTemplateDefinition()).getExceptionSpecification();
}
} }

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; 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.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; 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.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
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.cpp.ICPPASTDeclSpecifier; 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.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; 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; import org.eclipse.core.runtime.PlatformObject;
/** /**
* @author aniefer * Binding for c++ function
*/ */
public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInternalFunction { public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInternalFunction {
public static class CPPFunctionProblem extends ProblemBinding implements ICPPFunction { public static class CPPFunctionProblem extends ProblemBinding implements ICPPFunction {
public CPPFunctionProblem(IASTNode node, int id, char[] arg) { public CPPFunctionProblem(IASTNode node, int id, char[] arg) {
super(node, id, arg); super(node, id, arg);
@ -97,6 +99,9 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
public boolean takesVarArgs() throws DOMException { public boolean takesVarArgs() throws DOMException {
throw new DOMException(this); throw new DOMException(this);
} }
public IType[] getExceptionSpecification() throws DOMException {
throw new DOMException(this);
}
} }
protected ICPPASTFunctionDeclarator[] declarations; protected ICPPASTFunctionDeclarator[] declarations;
@ -213,7 +218,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
public IParameter[] getParameters() { public IParameter[] getParameters() {
IASTStandardFunctionDeclarator dtor = (definition != null) ? definition : declarations[0]; IASTStandardFunctionDeclarator dtor = getPreferredDtor();
IASTParameterDeclaration[] params = dtor.getParameters(); IASTParameterDeclaration[] params = dtor.getParameters();
int size = params.length; int size = params.length;
IParameter[] result = new IParameter[ size ]; IParameter[] result = new IParameter[ size ];
@ -516,15 +521,8 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
} }
public boolean takesVarArgs() { public boolean takesVarArgs() {
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) getDefinition(); ICPPASTFunctionDeclarator dtor= getPreferredDtor();
if (dtor != null) { return dtor != null ? dtor.takesVarArgs() : false;
return dtor.takesVarArgs();
}
ICPPASTFunctionDeclarator[] ds = (ICPPASTFunctionDeclarator[]) getDeclarations();
if (ds != null && ds.length > 0) {
return ds[0].takesVarArgs();
}
return false;
} }
public ILinkage getLinkage() { public ILinkage getLinkage() {
@ -543,4 +541,38 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
public IBinding getOwner() throws DOMException { public IBinding getOwner() throws DOMException {
return CPPVisitor.findNameOwner(getASTName(), false); 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;
}
} }

View file

@ -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.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IParameter;
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.cpp.ICPPASTFunctionDeclarator; 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.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; 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 { public class CPPFunctionSpecialization extends CPPSpecialization implements ICPPFunction, ICPPInternalFunction {
private IFunctionType type = null; private IFunctionType type = null;
private IParameter[] specializedParams = null; private IParameter[] specializedParams = null;
private IType[] specializedExceptionSpec = null;
public CPPFunctionSpecialization(IBinding orig, IBinding owner, ICPPTemplateParameterMap argMap) { public CPPFunctionSpecialization(IBinding orig, IBinding owner, ICPPTemplateParameterMap argMap) {
super(orig, owner, argMap); super(orig, owner, argMap);
@ -249,4 +251,17 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
} }
return result.toString(); 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;
}
} }

View file

@ -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.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; 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.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IParameter;
@ -94,6 +95,9 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
public boolean takesVarArgs() throws DOMException { public boolean takesVarArgs() throws DOMException {
throw new DOMException(this); throw new DOMException(this);
} }
public IType[] getExceptionSpecification() throws DOMException {
throw new DOMException( this );
}
} }
protected IFunctionType type = null; protected IFunctionType type = null;
@ -355,4 +359,24 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
result.append(t != null ? ASTTypeUtil.getParameterTypeString(t) : "()"); //$NON-NLS-1$ result.append(t != null ? ASTTypeUtil.getParameterTypeString(t) : "()"); //$NON-NLS-1$
return result.toString(); 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;
}
} }

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; 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; 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 { public class CPPImplicitConstructor extends CPPImplicitMethod implements ICPPConstructor {
/** public CPPImplicitConstructor(ICPPClassScope scope, char[] name, IParameter[] params) {
* @param name
* @param params
*/
public CPPImplicitConstructor( ICPPClassScope scope, char [] name, IParameter[] params ) {
super( scope, name, createFunctionType(scope, params), 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); return CPPVisitor.createImplicitFunctionType(returnType, params, null);
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor#isExplicit()
*/
public boolean isExplicit() { public boolean isExplicit() {
return false; return false;
} }

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; 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; 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 { public class CPPImplicitMethod extends CPPImplicitFunction implements ICPPMethod {
@ -180,4 +180,8 @@ public class CPPImplicitMethod extends CPPImplicitFunction implements ICPPMethod
return getClassOwner(); return getClassOwner();
} }
@Override
public IType[] getExceptionSpecification() throws DOMException {
return ClassTypeHelper.getInheritedExceptionSpecification(this);
}
} }

View file

@ -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.IASTNode;
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.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; 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.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
@ -75,7 +76,7 @@ public class CPPMethodSpecialization extends CPPFunctionSpecialization
} }
public boolean isImplicit() { public boolean isImplicit() {
return false; return ((ICPPMethod) getSpecializedBinding()).isImplicit();
} }
public boolean isPureVirtual() throws DOMException { public boolean isPureVirtual() throws DOMException {
@ -86,4 +87,11 @@ public class CPPMethodSpecialization extends CPPFunctionSpecialization
return false; return false;
} }
@Override
public IType[] getExceptionSpecification() throws DOMException {
if (isImplicit()) {
return ClassTypeHelper.getInheritedExceptionSpecification(this);
}
return super.getExceptionSpecification();
}
} }

View file

@ -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.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.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; 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.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; 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.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; 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.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.ICPPUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
@ -207,8 +213,10 @@ public class ClassTypeHelper {
ICPPClassType[] bases= getAllBases(ct); ICPPClassType[] bases= getAllBases(ct);
for (ICPPClassType base : bases) { for (ICPPClassType base : bases) {
set.addAll(base.getDeclaredMethods()); set.addAll(base.getDeclaredMethods());
scope= (ICPPClassScope) base.getCompositeScope(); final IScope compositeScope = base.getCompositeScope();
set.addAll(scope.getImplicitMethods()); if (compositeScope instanceof ICPPClassScope) {
set.addAll(((ICPPClassScope) compositeScope).getImplicitMethods());
}
} }
return set.keyArray(ICPPMethod.class); 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;
}
} }

View file

@ -1617,6 +1617,9 @@ public class CPPVisitor extends ASTQueries {
} }
public static IType createType(IASTDeclarator declarator) { public static IType createType(IASTDeclarator declarator) {
if (declarator == null)
return null;
IASTDeclSpecifier declSpec = null; IASTDeclSpecifier declSpec = null;
IASTNode node = declarator.getParent(); IASTNode node = declarator.getParent();

View file

@ -92,4 +92,16 @@ class CompositeCPPFunction extends CompositeCPPBinding implements ICPPFunction {
} }
return result.toString(); 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;
}
} }

View file

@ -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.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding; 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.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; 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; import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
public class CompositeCPPFunctionSpecialization extends CompositeCPPFunction implements ICPPSpecialization { public class CompositeCPPFunctionSpecialization extends CompositeCPPFunction implements ICPPSpecialization {
@ -53,8 +55,21 @@ public class CompositeCPPFunctionSpecialization extends CompositeCPPFunction imp
return result.toString(); 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 @Deprecated
public ObjectMap getArgumentMap() { public ObjectMap getArgumentMap() {
return TemplateInstanceUtil.getArgumentMap(cf, rbinding); return TemplateInstanceUtil.getArgumentMap(cf, rbinding);
} }
} }

View file

@ -165,11 +165,12 @@ public class PDOM extends PlatformObject implements IPDOM {
* 73.0 - add values for variables and enumerations, bug 250788 * 73.0 - add values for variables and enumerations, bug 250788
* 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
*/ */
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 = 75; public static final int MAJOR_VERSION = 76;
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

@ -6,24 +6,23 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* QNX - Initial API and implementation * Doug Schaefer (QNX) - Initial API and implementation
* IBM Corporation * IBM Corporation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp; package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding; 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.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IParameter;
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;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; 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.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.Util;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.index.IndexCPPSignatureUtil; 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; import org.eclipse.core.runtime.CoreException;
/** /**
* @author Doug Schaefer * Binding for c++ functions in the index.
*
*/ */
class PDOMCPPFunction extends PDOMCPPBinding implements ICPPFunction, IPDOMOverloader { 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 * Offset of hash of parameter information to allow fast comparison
*/ */
private static final int SIGNATURE_HASH = PDOMCPPBinding.RECORD_SIZE + 12; 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 * Offset of annotation information (relative to the beginning of the
* record). * 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. * The size in bytes of a PDOMCPPFunction record in the database.
*/ */
@SuppressWarnings("hiding") @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 { public PDOMCPPFunction(PDOM pdom, PDOMNode parent, ICPPFunction function, boolean setTypes) throws CoreException {
super(pdom, parent, function.getNameCharArray()); super(pdom, parent, function.getNameCharArray());
@ -89,6 +92,7 @@ class PDOMCPPFunction extends PDOMCPPBinding implements ICPPFunction, IPDOMOverl
initData((ICPPFunctionType) function.getType(), function.getParameters()); initData((ICPPFunctionType) function.getType(), function.getParameters());
} }
db.putByte(record + ANNOTATION, PDOMCPPAnnotation.encodeAnnotation(function)); db.putByte(record + ANNOTATION, PDOMCPPAnnotation.encodeAnnotation(function));
storeExceptionSpec(db, function);
} catch (DOMException e) { } catch (DOMException e) {
throw new CoreException(Util.createStatus(e)); throw new CoreException(Util.createStatus(e));
} }
@ -102,7 +106,7 @@ class PDOMCPPFunction extends PDOMCPPBinding implements ICPPFunction, IPDOMOverl
@Override @Override
public void update(final PDOMLinkage linkage, IBinding newBinding) throws CoreException { public void update(final PDOMLinkage linkage, IBinding newBinding) throws CoreException {
if (newBinding instanceof ICPPFunction) { if (newBinding instanceof ICPPFunction) {
IFunction func= (ICPPFunction) newBinding; ICPPFunction func= (ICPPFunction) newBinding;
ICPPFunctionType newType; ICPPFunctionType newType;
IParameter[] newParams; IParameter[] newParams;
byte newAnnotation; byte newAnnotation;
@ -123,10 +127,31 @@ class PDOMCPPFunction extends PDOMCPPBinding implements ICPPFunction, IPDOMOverl
if (oldParams != null) { if (oldParams != null) {
oldParams.delete(linkage); 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 { private void setParameters(PDOMCPPFunctionType pft, IParameter[] params) throws CoreException {
final Database db= pdom.getDB(); final Database db= pdom.getDB();
db.putInt(record + NUM_PARAMS, params.length); db.putInt(record + NUM_PARAMS, params.length);
@ -282,4 +307,14 @@ class PDOMCPPFunction extends PDOMCPPBinding implements ICPPFunction, IPDOMOverl
} }
return 0; 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;
}
}
} }

View file

@ -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.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.PDOM; 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.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -32,8 +33,12 @@ import org.eclipse.core.runtime.CoreException;
*/ */
class PDOMCPPFunctionInstance extends PDOMCPPFunctionSpecialization implements ICPPTemplateInstance { class PDOMCPPFunctionInstance extends PDOMCPPFunctionSpecialization implements ICPPTemplateInstance {
private static final int ARGUMENTS = PDOMCPPFunctionSpecialization.RECORD_SIZE + 0; private static final int ARGUMENTS = PDOMCPPFunctionSpecialization.RECORD_SIZE + 0;
@SuppressWarnings("hiding") @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) public PDOMCPPFunctionInstance(PDOM pdom, PDOMNode parent, ICPPFunction function, PDOMBinding orig)
throws CoreException { throws CoreException {
@ -41,7 +46,15 @@ class PDOMCPPFunctionInstance extends PDOMCPPFunctionSpecialization implements I
final ICPPTemplateInstance asInstance= (ICPPTemplateInstance) function; final ICPPTemplateInstance asInstance= (ICPPTemplateInstance) function;
final int argListRec= PDOMCPPArgumentList.putArguments(this, asInstance.getTemplateArguments()); 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) { 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 @Deprecated
public IType[] getArguments() { public IType[] getArguments() {
return CPPTemplates.getArguments(getTemplateArguments()); return CPPTemplates.getArguments(getTemplateArguments());

View file

@ -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 * 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:
* QNX - Initial API and implementation * Bryan Wilkinson (QNX) - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp; 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.IScope;
import org.eclipse.cdt.core.dom.ast.IType; 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.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.ICPPParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.internal.core.Util; 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; import org.eclipse.core.runtime.CoreException;
/** /**
* @author Bryan Wilkinson * Binding for function specialization in the index.
*
*/ */
class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization implements ICPPFunction { 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; 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 * Offset of annotation information (relative to the beginning of the
* record). * 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. * The size in bytes of a PDOMCPPFunction record in the database.
*/ */
@SuppressWarnings("hiding") @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 { public PDOMCPPFunctionSpecialization(PDOM pdom, PDOMNode parent, ICPPFunction function, PDOMBinding specialized) throws CoreException {
super(pdom, parent, (ICPPSpecialization) function, specialized); 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); PDOMCPPParameter sParam = new PDOMCPPParameter(pdom, this, sParams[i], type);
setFirstParameter(new PDOMCPPParameterSpecialization(pdom, this, (ICPPParameter) params[i], sParam, typeRecord)); 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) { } catch (DOMException e) {
throw new CoreException(Util.createStatus(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) { public PDOMCPPFunctionSpecialization(PDOM pdom, int bindingRecord) {
@ -208,4 +225,14 @@ class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization implements ICP
int cmp= super.pdomCompareTo(other); int cmp= super.pdomCompareTo(other);
return cmp==0 ? PDOMCPPFunction.compareSignatures(this, other) : cmp; 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;
}
}
} }

View file

@ -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.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.internal.core.Util; 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.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.db.Database;
@ -198,4 +199,12 @@ class PDOMCPPMethod extends PDOMCPPFunction implements ICPPMethod {
} }
return 0; return 0;
} }
@Override
public IType[] getExceptionSpecification() throws DOMException {
if (isImplicit()) {
return ClassTypeHelper.getInheritedExceptionSpecification(this);
}
return super.getExceptionSpecification();
}
} }

View file

@ -12,10 +12,12 @@
package org.eclipse.cdt.internal.core.pdom.dom.cpp; package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException; 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.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.internal.core.Util; 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.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.db.Database;
@ -121,4 +123,12 @@ class PDOMCPPMethodSpecialization extends PDOMCPPFunctionSpecialization
public boolean isVolatile() { public boolean isVolatile() {
return getBit(getByte(record + ANNOTATION1), PDOMCAnnotation.VOLATILE_OFFSET + CV_OFFSET); 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();
}
} }

View file

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