diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java
index cd0b65a4318..d3d5747fd05 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java
@@ -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;};
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/MethodTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/MethodTests.java
index 0d7f83ea18d..5e3b2c83ffb 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/MethodTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/MethodTests.java
@@ -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));
+ }
}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMTestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMTestBase.java
index eaf2b534567..95380db412c 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMTestBase.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMTestBase.java
@@ -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("::");
diff --git a/core/org.eclipse.cdt.core.tests/resources/pdomtests/methodTests/inheritance.cpp b/core/org.eclipse.cdt.core.tests/resources/pdomtests/methodTests/inheritance.cpp
index 782139217c3..9c218bf5bce 100644
--- a/core/org.eclipse.cdt.core.tests/resources/pdomtests/methodTests/inheritance.cpp
+++ b/core/org.eclipse.cdt.core.tests/resources/pdomtests/methodTests/inheritance.cpp
@@ -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();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunction.java
index b29a06c2502..051b122e908 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunction.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunction.java
@@ -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 null
if there
+ * is no exception specification.
+ * @since 5.1
+ */
+ public IType[] getExceptionSpecification() throws DOMException;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunctionInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunctionInstance.java
index 601ead3f614..3ca58de0d5a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunctionInstance.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunctionInstance.java
@@ -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();
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java
index e2c86302f51..d73826b89f2 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java
@@ -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 inheritedTypeids = new ArrayList();
+ 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;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
index 8121308d8af..e5042106c2d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
@@ -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();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunction.java
index ecbfa9de705..10d658fa418 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunction.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunction.java
@@ -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;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunctionSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunctionSpecialization.java
index de690495369..2274e8a172d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunctionSpecialization.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunctionSpecialization.java
@@ -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);
- }
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
index 98b255c218b..d7760e0e7b2 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
@@ -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);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunction.java
index cb656ef4839..7be137b5af2 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunction.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunction.java
@@ -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;
+ }
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java
index f41ed40f2ce..92bce6424e4 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java
@@ -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());
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java
index 4570406e917..1193e6810b8 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java
@@ -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;
+ }
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethod.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethod.java
index c8dd55afb83..12ac9daa0ef 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethod.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethod.java
@@ -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();
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethodSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethodSpecialization.java
index 8062aef4852..0bbe3d8a0d1 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethodSpecialization.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethodSpecialization.java
@@ -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();
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypeList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypeList.java
new file mode 100644
index 00000000000..b69802b747f
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypeList.java
@@ -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= 0 && len <= (Database.MAX_MALLOC_SIZE-2)/NODE_SIZE);
+ rec+=2;
+ IType[] result= new IType[len];
+ for (int i=0; i= 0 && len <= (Database.MAX_MALLOC_SIZE-2)/NODE_SIZE);
+ int p= record+2;
+ for (int i=0; i