diff --git a/trick_source/codegen/Interface_Code_Gen/FieldDescription.cpp b/trick_source/codegen/Interface_Code_Gen/FieldDescription.cpp index 08ee6d91..53f24ebf 100644 --- a/trick_source/codegen/Interface_Code_Gen/FieldDescription.cpp +++ b/trick_source/codegen/Interface_Code_Gen/FieldDescription.cpp @@ -37,6 +37,7 @@ FieldDescription::FieldDescription( is_record(0) , is_static(0) , has_type(0) , + has_dims(0) , num_dims(0) , array_sizes() {} ; @@ -385,6 +386,14 @@ bool FieldDescription::hasType() { return has_type ; } +void FieldDescription::setHasDims( bool yes_no ) { + has_dims = yes_no ; +} + +bool FieldDescription::hasDims() { + return has_dims ; +} + unsigned int FieldDescription::getNumDims() { return num_dims ; } diff --git a/trick_source/codegen/Interface_Code_Gen/FieldDescription.hh b/trick_source/codegen/Interface_Code_Gen/FieldDescription.hh index 8024a448..94677359 100644 --- a/trick_source/codegen/Interface_Code_Gen/FieldDescription.hh +++ b/trick_source/codegen/Interface_Code_Gen/FieldDescription.hh @@ -77,6 +77,8 @@ class FieldDescription : public ConstructValues { bool isVirtualInherited() ; void setHasType( bool yes_no ) ; bool hasType() ; + void setHasDims( bool yes_no ) ; + bool hasDims() ; void setAccess( clang::AccessSpecifier in_val ) ; clang::AccessSpecifier getAccess() ; @@ -158,6 +160,9 @@ class FieldDescription : public ConstructValues { /** Have we resolved the type for this parameter? */ bool has_type ; + /** Have we resolved the dimensions for this parameter? */ + bool has_dims ; + /** map of strings to io numbers. One copy for all fields */ static std::map io_map ; diff --git a/trick_source/codegen/Interface_Code_Gen/FieldVisitor.cpp b/trick_source/codegen/Interface_Code_Gen/FieldVisitor.cpp index 5356974c..d710653a 100644 --- a/trick_source/codegen/Interface_Code_Gen/FieldVisitor.cpp +++ b/trick_source/codegen/Interface_Code_Gen/FieldVisitor.cpp @@ -130,7 +130,9 @@ bool FieldVisitor::VisitBuiltinType(clang::BuiltinType *bt) { bool FieldVisitor::VisitConstantArrayType(clang::ConstantArrayType *cat) { //cat->dump() ; std::cout << std::endl ; - fdes->addArrayDim(cat->getSize().getZExtValue()) ; + if ( ! fdes->hasDims() ) { + fdes->addArrayDim(cat->getSize().getZExtValue()) ; + } return true; } @@ -209,16 +211,31 @@ bool FieldVisitor::VisitFieldDecl( clang::FieldDecl *field ) { fdes->setBitFieldStart( 32 - (field_offset_bits % 32) - fdes->getBitFieldWidth()) ; fdes->setBitFieldByteOffset((field_offset_bits / 32) * 4 ) ; } + + clang::QualType qt = field->getType() ; + // If the current type is not canonical because of typedefs, traverse the canonical type + if ( !qt.isCanonical() ) { + clang::QualType ct = qt.getCanonicalType() ; + TraverseType(ct) ; + // Traversing the canonical type will set the has_type flag. Set the has_dims flag too so + // when we continue parsing the AST and the non-canonical type, we don't double add dimensions. + fdes->setHasDims(true) ; + } return true ; } bool FieldVisitor::VisitElaboratedType(clang::ElaboratedType *et) { + if ( debug_level >= 4 ) { + std::cout << "FieldVisitor VisitElaboratedType" << std::endl ; + } //et->dump() ; std::cout << std::endl ; return true ; } bool FieldVisitor::VisitPointerType(clang::PointerType *p) { - fdes->addArrayDim(-1) ; + if ( ! fdes->hasDims() ) { + fdes->addArrayDim(-1) ; + } return true; } @@ -244,8 +261,17 @@ bool FieldVisitor::VisitRecordType(clang::RecordType *rt) { //std::cout << "hasNameForLinkage " << rt->getDecl()->hasNameForLinkage() << std::endl ; if ( rt->getDecl()->hasNameForLinkage() ) { if ( rt->getDecl()->getDeclName() ) { - //std::cout << "getDeclName " << rt->getDecl()->getDeclName().getAsString() << std::endl ; - fdes->setTypeName(rt->getDecl()->getQualifiedNameAsString()) ; + std::string type_name = rt->getDecl()->getQualifiedNameAsString() ; + // Handle the string class differently than regular records. + if ( ! type_name.compare("std::basic_string") || !type_name.compare("std::__1::basic_string")) { + fdes->setEnumString("TRICK_STRING") ; + fdes->setTypeName("std::string") ; + fdes->setHasType(true) ; + return true ; + } else { + //std::cout << "getDeclName " << type_name << std::endl ; + fdes->setTypeName(type_name) ; + } } else { //std::cout << "getTypedefNameForAnonDecl " << rt->getDecl()->getTypedefNameForAnonDecl() << std::endl ; fdes->setTypeName(rt->getDecl()->getTypedefNameForAnonDecl()->getQualifiedNameAsString()) ; @@ -453,6 +479,11 @@ bool FieldVisitor::VisitTypedefType(clang::TypedefType *tt) { fdes->setHasType(true) ; } else if ( tt->isRecordType() ) { + + if ( debug_level >= 4 ) { + std::cout << "FieldVisitor isRecordType" << std::endl ; + } + std::string type_name = tt->desugar().getAsString() ; if ((pos = type_name.find("class ")) != std::string::npos ) { type_name.erase(pos , 6) ;