summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2012-12-02 20:13:47 +0100
committerMichael Stahl <mstahl@redhat.com>2012-12-02 20:58:32 +0100
commiteb0cfb3bf220892e4885945452930790f5e22000 (patch)
treebac2d6b6ae99a3732431d3d04d85ae756d086faa
parent1658e4efac5fc851b322103ed40545fa263ae280 (diff)
cppumaker: do write exception specifications on --enable-dbgutil
Exception specifications are useless for production code, but make for useful assertions in dbgutil builds (on platforms where they are enforced at runtime). Because we do not have API tests that exhaustively trigger all documented error conditions, much less the undocumented or wrongly handled error conditions that would cause the implementation to violate its API specification, there is likely some benefit in having these runtime-checked specifications in debug builds, in the hope that our various tests which may incidentally call various API methods, or general soffice usage, uncovers these bugs. Also, there may be some benefit to making API implementers more aware of the exception specifications, to quote Stephan's mail: To be able to programmatically react to an exception raised by a UNO method (which is the raison d'ĂȘtre of non-runtime UNO exceptions), the specification of that method must document the method's behavior with respect to raising that exception, and any implementation of the method must adhere to that specification. However, with that part of a UNO method's interface moved out of sight of a programmer writing a C++ implementation of that method, I fear that adherence to specification will degrade in practice. And that negatively affects an area where we do not shine anyway: reaction to errors. This partially reverts commits: 0295bd6b3f21dd648af6145ca23d90467f3cec73 155cd09b5eebe0c1eab0610a7f1f04f09de4b217 Change-Id: I9c7664c9f1b238f4f9501aacb065981236949440
-rw-r--r--codemaker/source/cppumaker/cpputype.cxx65
-rw-r--r--codemaker/source/cppumaker/cpputype.hxx6
2 files changed, 71 insertions, 0 deletions
diff --git a/codemaker/source/cppumaker/cpputype.cxx b/codemaker/source/cppumaker/cpputype.cxx
index 3aba0234f9fd..5b9721bad7d5 100644
--- a/codemaker/source/cppumaker/cpputype.cxx
+++ b/codemaker/source/cppumaker/cpputype.cxx
@@ -1483,6 +1483,7 @@ void InterfaceType::dumpAttributes(FileStream& o)
o << "virtual ";
dumpType(o, fieldType);
o << " SAL_CALL get" << fieldName << "()";
+ dumpAttributeExceptionSpecification(o, name, RT_MODE_ATTRIBUTE_GET);
o << " = 0;\n";
if ((access & RT_ACCESS_READONLY) == 0)
@@ -1493,6 +1494,7 @@ void InterfaceType::dumpAttributes(FileStream& o)
o << "virtual void SAL_CALL set" << fieldName << "( ";
dumpType(o, fieldType, byRef, byRef);
o << " _" << fieldName.toAsciiLowerCase() << " )";
+ dumpAttributeExceptionSpecification(o, name, RT_MODE_ATTRIBUTE_SET);
o << " = 0;\n";
}
}
@@ -1510,6 +1512,7 @@ void InterfaceType::dumpMethods(FileStream& o)
sal_Bool bRef = sal_False;
sal_Bool bConst = sal_False;
+ sal_Bool bWithRunTimeExcp = sal_True;
for (sal_uInt16 i=0; i < methodCount; i++)
{
@@ -1526,6 +1529,11 @@ void InterfaceType::dumpMethods(FileStream& o)
m_reader.getMethodReturnTypeName(i), RTL_TEXTENCODING_UTF8);
paramCount = m_reader.getMethodParameterCount(i);
+ if ( methodName.equals("acquire") || methodName.equals("release") )
+ {
+ bWithRunTimeExcp = sal_False;
+ }
+
if (first)
{
first = sal_False;
@@ -1578,6 +1586,7 @@ void InterfaceType::dumpMethods(FileStream& o)
}
o << " )";
}
+ dumpExceptionSpecification(o, i, bWithRunTimeExcp);
o << " = 0;\n";
}
}
@@ -2207,6 +2216,62 @@ void InterfaceType::dumpMethodsCppuDecl(FileStream& o, StringSet* pFinishedTypes
}
}
+void InterfaceType::dumpExceptionSpecification(
+ FileStream & out, sal_uInt32 methodIndex, bool runtimeException)
+{
+ // exception specifications are undesirable in production code, but make
+ // for useful assertions in debug builds (on platforms where they are
+ // enforced at runtime)
+#ifndef DBG_UTIL
+ (void) out;
+ (void) methodIndex;
+ (void) runtimeException;
+#else
+ out << " throw (";
+ bool first = true;
+ if (methodIndex <= SAL_MAX_UINT16) {
+ sal_uInt16 count = m_reader.getMethodExceptionCount(
+ static_cast< sal_uInt16 >(methodIndex));
+ for (sal_uInt16 i = 0; i < count; ++i) {
+ rtl::OUString name(
+ m_reader.getMethodExceptionTypeName(
+ static_cast< sal_uInt16 >(methodIndex), i));
+ if ( name != "com/sun/star/uno/RuntimeException" )
+ {
+ if (!first) {
+ out << ", ";
+ }
+ first = false;
+ out << scopedCppName(
+ rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8));
+ }
+ }
+ }
+ if (runtimeException) {
+ if (!first) {
+ out << ", ";
+ }
+ out << "::com::sun::star::uno::RuntimeException";
+ }
+ out << ")";
+#endif
+}
+
+void InterfaceType::dumpAttributeExceptionSpecification(
+ FileStream & out, rtl::OUString const & name, RTMethodMode sort)
+{
+ sal_uInt16 methodCount = m_reader.getMethodCount();
+ for (sal_uInt16 i = 0; i < methodCount; ++i) {
+ if (m_reader.getMethodFlags(i) == sort
+ && m_reader.getMethodName(i) == name)
+ {
+ dumpExceptionSpecification(out, i, true);
+ return;
+ }
+ }
+ dumpExceptionSpecification(out, 0xFFFFFFFF, true);
+}
+
void InterfaceType::dumpExceptionTypeName(
FileStream & out, char const * prefix, sal_uInt32 index, rtl::OUString name)
{
diff --git a/codemaker/source/cppumaker/cpputype.hxx b/codemaker/source/cppumaker/cpputype.hxx
index 32728f6f8e70..b80b3d822e60 100644
--- a/codemaker/source/cppumaker/cpputype.hxx
+++ b/codemaker/source/cppumaker/cpputype.hxx
@@ -194,6 +194,12 @@ protected:
bool m_isDeprecated;
private:
+ void dumpExceptionSpecification(
+ FileStream & out, sal_uInt32 methodIndex, bool runtimeException);
+
+ void dumpAttributeExceptionSpecification(
+ FileStream & out, rtl::OUString const & name, RTMethodMode sort);
+
void dumpExceptionTypeName(
FileStream & out, char const * prefix, sal_uInt32 index,
rtl::OUString name);