Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix introspection of C array data members #2666

Merged
merged 4 commits into from Feb 27, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion CondCore/ORA/src/ClassUtils.cc
Expand Up @@ -436,7 +436,8 @@ edm::TypeWithDict ora::ClassUtils::containerSubType(const edm::TypeWithDict& typ

edm::TypeWithDict ora::ClassUtils::resolvedType(const edm::TypeWithDict& typ){
if (typ.isTypedef()){
return typ.finalType();
return typ.finalType().toType();
}
return typ;
}

2 changes: 1 addition & 1 deletion CondCore/ORA/src/InlineCArrayStreamer.cc
Expand Up @@ -25,7 +25,7 @@ ora::InlineCArrayStreamerBase::~InlineCArrayStreamerBase(){
bool ora::InlineCArrayStreamerBase::buildDataElement(DataElement& dataElement,
IRelationalData& relationalData,
RelationalBuffer* operationBuffer){
m_arrayType = ClassUtils::resolvedType( m_objectType );
m_arrayType = ClassUtils::resolvedType( m_objectType.toType() );
if ( ! m_arrayType ) {
throwException( "Missing dictionary information for the element of array \"" +
m_objectType.qualifiedName() + "\"",
Expand Down
2 changes: 1 addition & 1 deletion CondCore/ORA/src/ObjectStreamer.cc
Expand Up @@ -42,7 +42,7 @@ void ora::ObjectStreamerBase::buildBaseDataMembers( DataElement& dataElement,

for ( unsigned int i=0;i<ora::helper::BaseSize(objType);i++){
edm::BaseWithDict base = ora::helper::BaseAt(objType, i);
edm::TypeWithDict baseType = ClassUtils::resolvedType( base.typeOf() );
edm::TypeWithDict baseType = ClassUtils::resolvedType( base.typeOf().toType() );
buildBaseDataMembers( dataElement, relationalData, baseType, operationBuffer );
for ( unsigned int j=0;j<baseType.dataMemberSize();j++){
edm::MemberWithDict dataMember = ora::helper::DataMemberAt(baseType, j);
Expand Down
2 changes: 1 addition & 1 deletion CondCore/ORA/src/RelationalMapping.cc
Expand Up @@ -552,7 +552,7 @@ namespace ora {
std::string className = objType.qualifiedName();
for ( size_t i=0; i< ora::helper::BaseSize(objType); i++){
edm::BaseWithDict base = ora::helper::BaseAt(objType, i);
edm::TypeWithDict baseType = ClassUtils::resolvedType( base.typeOf() ); // ?? base.toType() );
edm::TypeWithDict baseType = ClassUtils::resolvedType( base.typeOf().toType() );
if(!baseType){
throwException( "Class for base \""+base.name()+"\" is not in the dictionary.","ObjectMapping::process");
}
Expand Down
1 change: 1 addition & 0 deletions DataFormats/Common/test/DictionaryTools_t.cpp
Expand Up @@ -150,6 +150,7 @@ namespace {
checkIt<edm::Wrapper<T> >();
checkIt<edm::Wrapper<std::vector<T> > >();
checkIt<T>();
checkIt<T[1]>();
}
}

Expand Down
5 changes: 5 additions & 0 deletions DataFormats/TestObjects/interface/ToyProducts.h
Expand Up @@ -28,6 +28,11 @@ namespace edmtest {
struct DummyProduct {
};

struct ArrayProduct {
explicit ArrayProduct(int i = 0) : value{i} {}
int value[1];
};

struct EnumProduct {
enum TheEnumProduct {
TheZero = 0,
Expand Down
3 changes: 3 additions & 0 deletions DataFormats/TestObjects/src/classes_def.xml
Expand Up @@ -9,6 +9,9 @@
<version ClassVersion="10" checksum="3025325436"/>
</class>
<enum name="edmtest::TheEnumProduct"/>
<class name="edmtest::ArrayProduct" ClassVersion="10">
<version ClassVersion="10" checksum="3635152897"/>
</class>
<class name="edmtest::TransientIntProduct" ClassVersion="10">
<version ClassVersion="10" checksum="304339852"/>
</class>
Expand Down
26 changes: 26 additions & 0 deletions DataFormats/TestObjects/test/Enum_t.cpp
Expand Up @@ -16,6 +16,8 @@ class TestDictionaries: public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(TestDictionaries);
CPPUNIT_TEST(enum_is_valid);
CPPUNIT_TEST(enum_by_name_is_valid);
CPPUNIT_TEST(enum_member_is_valid);
CPPUNIT_TEST(array_member_is_valid);
CPPUNIT_TEST(demangling);
CPPUNIT_TEST_SUITE_END();

Expand All @@ -27,6 +29,8 @@ class TestDictionaries: public CppUnit::TestFixture {

void enum_is_valid();
void enum_by_name_is_valid();
void enum_member_is_valid();
void array_member_is_valid();
void demangling();

private:
Expand All @@ -44,6 +48,28 @@ void TestDictionaries::enum_by_name_is_valid() {
CPPUNIT_ASSERT(t);
}

void TestDictionaries::enum_member_is_valid() {
edm::TypeWithDict t = edm::TypeWithDict::byName("edmtest::EnumProduct");
edm::MemberWithDict m = t.dataMemberByName("value");
edm::TypeWithDict t2 = m.typeOf();
edm::TypeWithDict t3 = edm::TypeWithDict::byName("edmtest::EnumProduct::TheEnumProduct");
CPPUNIT_ASSERT(t2);
CPPUNIT_ASSERT(t3);
CPPUNIT_ASSERT(t2 == t3);
}

void TestDictionaries::array_member_is_valid() {
edm::TypeWithDict t = edm::TypeWithDict::byName("edmtest::ArrayProduct");
edm::MemberWithDict m = t.dataMemberByName("value");
CPPUNIT_ASSERT(m.isArray());
edm::TypeWithDict t2 = m.typeOf();
edm::TypeWithDict t3 = edm::TypeWithDict::byName("int[1]");
CPPUNIT_ASSERT(t2);
CPPUNIT_ASSERT(t3);
CPPUNIT_ASSERT(t2.qualifiedName() == "int[1]");
CPPUNIT_ASSERT(t2 == t3);
}

namespace {
template<typename T>
void checkIt() {
Expand Down
1 change: 1 addition & 0 deletions FWCore/Utilities/interface/MemberWithDict.h
Expand Up @@ -25,6 +25,7 @@ class MemberWithDict {
explicit MemberWithDict(TDataMember*);
explicit operator bool() const;
std::string name() const;
bool isArray() const;
bool isConst() const;
bool isPublic() const;
bool isStatic() const;
Expand Down
17 changes: 17 additions & 0 deletions FWCore/Utilities/src/MemberWithDict.cc
Expand Up @@ -2,6 +2,8 @@

#include "FWCore/Utilities/interface/ObjectWithDict.h"
#include "FWCore/Utilities/interface/TypeWithDict.h"
#include <ostream>
#include <sstream>

namespace edm {

Expand All @@ -22,6 +24,16 @@ namespace edm {

TypeWithDict
MemberWithDict::typeOf() const {
if(isArray()) {
std::ostringstream name;
name << dataMember_->GetTypeName();
for(int i = 0; i < dataMember_->GetArrayDim(); ++i) {
name << '[';
name << dataMember_->GetMaxIndex(i);
name << ']';
return TypeWithDict::byName(name.str(), dataMember_->Property());
}
}
return TypeWithDict::byName(dataMember_->GetTypeName(), dataMember_->Property());
}

Expand All @@ -30,6 +42,11 @@ namespace edm {
return TypeWithDict(dataMember_->GetClass(), dataMember_->Property());
}

bool
MemberWithDict::isArray() const {
return dataMember_->Property() & kIsArray;
}

bool
MemberWithDict::isConst() const {
return dataMember_->Property() & kIsConstant;
Expand Down
4 changes: 3 additions & 1 deletion FWCore/Utilities/src/TypeDemangler.cc
Expand Up @@ -118,10 +118,12 @@ namespace edm {
}
std::string demangledName(demangled);
free(demangled);
// We must use the same conventions used by REFLEX.
// We must use the same conventions previously used by REFLEX.
// The order of these is important.
// No space after comma
replaceString(demangledName, ", ", ",");
// No space before opening square bracket
replaceString(demangledName, " [", "[");
// Strip default allocator
std::string const allocator(",std::allocator<");
removeParameter(demangledName, allocator);
Expand Down