From f63f44d8769cbcec5997bc51c7a275657a79d05f Mon Sep 17 00:00:00 2001 From: Alex Lin Date: Tue, 12 Apr 2016 15:53:39 -0500 Subject: [PATCH] Ignore privacy Changed the storage of offsets from bytes to bits to better handle bitfields. Added code to track classes that are defined within other classes and are private/protected. These classes cannot be used in templates because our io_src code declares variables outside of the class that would try and use these private/protected variables. When a template is found to use a private/protected class it is skipped. refs #218 --- include/trick/FrameLog.hh | 4 +- include/trick/ThreadBase.hh | 2 +- .../Interface_Code_Gen/ClassValues.cpp | 3 +- .../Interface_Code_Gen/ClassVisitor.cpp | 55 +++++++++--- .../Interface_Code_Gen/ClassVisitor.hh | 5 +- .../Interface_Code_Gen/FieldDescription.cpp | 12 --- .../Interface_Code_Gen/FieldDescription.hh | 5 +- .../Interface_Code_Gen/FieldVisitor.cpp | 85 ++++++++++++++++--- .../PrintFileContents10.cpp | 75 +++++++--------- .../Interface_Code_Gen/PrintFileContents10.hh | 3 +- 10 files changed, 158 insertions(+), 91 deletions(-) diff --git a/include/trick/FrameLog.hh b/include/trick/FrameLog.hh index 7a443ec1..fd2c3667 100644 --- a/include/trick/FrameLog.hh +++ b/include/trick/FrameLog.hh @@ -153,8 +153,8 @@ namespace Trick { int shutdown() ; private: - std::vector trick_jobs; // -- vector containing all trick job names - std::vector user_jobs; // -- vector containing all user job names + std::vector trick_jobs; // ** vector containing all trick job names + std::vector user_jobs; // ** vector containing all user job names std::string DP_dir; // ** name of DP_Product directory diff --git a/include/trick/ThreadBase.hh b/include/trick/ThreadBase.hh index 8e51990b..085b0b76 100644 --- a/include/trick/ThreadBase.hh +++ b/include/trick/ThreadBase.hh @@ -162,7 +162,7 @@ namespace Trick { unsigned int rt_priority; /**< trick_units(--) */ /** Set of cpus to use with thread */ - unsigned int max_cpu ; + unsigned int max_cpu ; /**< trick_io(**) */ #if __linux #ifndef SWIG diff --git a/trick_source/codegen/Interface_Code_Gen/ClassValues.cpp b/trick_source/codegen/Interface_Code_Gen/ClassValues.cpp index 19ee3e09..6d0e07b0 100644 --- a/trick_source/codegen/Interface_Code_Gen/ClassValues.cpp +++ b/trick_source/codegen/Interface_Code_Gen/ClassValues.cpp @@ -48,7 +48,8 @@ void ClassValues::addInheritedFieldDescriptions(std::vector (*fdit)->setInherited( true ) ; // Adds the class offset to the field offset giving the total offset to the inherited variable - (*fdit)->addOffset( class_offset ) ; + // The offset is stored in bits so multiply class_offset by 8. + (*fdit)->addOffset( class_offset * 8 ) ; std::string in_name = (*fdit)->getName() ; // search existing names for incoming inherited variable name. diff --git a/trick_source/codegen/Interface_Code_Gen/ClassVisitor.cpp b/trick_source/codegen/Interface_Code_Gen/ClassVisitor.cpp index 321f32e4..2b6d94c2 100644 --- a/trick_source/codegen/Interface_Code_Gen/ClassVisitor.cpp +++ b/trick_source/codegen/Interface_Code_Gen/ClassVisitor.cpp @@ -53,11 +53,21 @@ bool CXXRecordVisitor::TraverseDecl(clang::Decl *d) { NULL when this is only a forward declaration of a class. We also only want to process embedded classes that have public access. */ clang::RecordDecl * rd = crd->getDefinition() ; - if ( rd != NULL and rd->getAccess() == clang::AS_public ) { - if ( isInUserCode(ci , crd->getRBraceLoc(), hsd) ) { - CXXRecordVisitor embedded_cvis(ci , cs, hsd , pa, true) ; - embedded_cvis.TraverseCXXRecordDecl(static_cast(d)) ; - pa.printClass(embedded_cvis.get_class_data()) ; + if ( rd != NULL ) { + if ( rd->getAccess() == clang::AS_public ) { + if ( isInUserCode(ci , crd->getRBraceLoc(), hsd) ) { + CXXRecordVisitor embedded_cvis(ci , cs, hsd , pa, true) ; + embedded_cvis.TraverseCXXRecordDecl(static_cast(d)) ; + pa.printClass(embedded_cvis.get_class_data()) ; + } + } else { + // protected and private embedded classes cannot be used outside of their class + // in our auto-generated code. Keep a set of all classes of this type so we can + // test against them. + ClassValues temp_cv ; + temp_cv.getNamespacesAndClasses(crd->getDeclContext()) ; + private_embedded_classes.insert(temp_cv.getFullyQualifiedName() + crd->getNameAsString()) ; + //std::cout << "marking private " << temp_cv.getFullyQualifiedName() + crd->getNameAsString() << std::endl ; } } } @@ -188,17 +198,20 @@ bool CXXRecordVisitor::VisitCXXRecordDecl( clang::CXXRecordDecl *rec ) { //std::cout << " " << getFileName(ci , rd->getRBraceLoc(), hsd) << "" << std::endl ; CXXRecordVisitor inherit_cvis(ci , cs, hsd , pa, false) ; inherit_cvis.TraverseCXXRecordDecl(static_cast(rd)) ; - cval.addInheritedFieldDescriptions(inherit_cvis.get_class_data()->getFieldDescription(), inherit_class_offset) ; - // clear the field list in the inherited class so they are not freed when inherit_cvis goes out of scope. + cval.addInheritedFieldDescriptions(inherit_cvis.get_class_data()->getFieldDescription(), + inherit_class_offset) ; + // clear the field list in the inherited class so they are not freed when inherit_cvis + // goes out of scope. inherit_cvis.get_class_data()->clearFieldDescription() ; // If we are inheriting from a template specialization, don't save the inherited class. This list - // is maintained to call init_attr of the inherited classes. A template specialization does not have - // these attributes. + // is maintained to call init_attr of the inherited classes. A template specialization does not + // havethese attributes. if ( ! isTypeTemplateSpecialization(temp) ) { - // We want to save the inherited class data, but it's going to go out of scope so we need to make - // a copy of it. + // We want to save the inherited class data, but it's going to go out of scope so we need + // to make a copy of it. ClassValues * icv = new ClassValues(*(inherit_cvis.get_class_data())) ; - // The inherited classes of this inherited class are not required in the copy, and they are going out of scope + // The inherited classes of this inherited class are not required in the copy, + // and they are going out of scope cval.saveInheritAncestry(icv) ; icv->clearInheritedClass() ; @@ -292,3 +305,21 @@ ClassValues * CXXRecordVisitor::get_class_data() { return &cval ; } +std::set CXXRecordVisitor::private_embedded_classes ; + +bool CXXRecordVisitor::isPrivateEmbeddedClass( std::string in_name ) { + size_t pos ; + while ((pos = in_name.find("class ")) != std::string::npos ) { + in_name.erase(pos , 6) ; + } + while ((pos = in_name.find("struct ")) != std::string::npos ) { + in_name.erase(pos , 7) ; + } + + std::set::iterator it ; + it = private_embedded_classes.find(in_name) ; + if ( it != private_embedded_classes.end() ) { + return true ; + } + return false ; +} diff --git a/trick_source/codegen/Interface_Code_Gen/ClassVisitor.hh b/trick_source/codegen/Interface_Code_Gen/ClassVisitor.hh index 61f05120..1280ffec 100644 --- a/trick_source/codegen/Interface_Code_Gen/ClassVisitor.hh +++ b/trick_source/codegen/Interface_Code_Gen/ClassVisitor.hh @@ -2,9 +2,8 @@ #ifndef CLASSVISITOR_HH #define CLASSVISITOR_HH +#include #include -#include -#include #include "clang/Frontend/CompilerInstance.h" #include "clang/AST/RecursiveASTVisitor.h" @@ -56,6 +55,7 @@ class CXXRecordVisitor : public clang::RecursiveASTVisitor { /** Returns the class data */ ClassValues * get_class_data() ; + static bool isPrivateEmbeddedClass(std::string in_name) ; private: /** The compiler instance. */ clang::CompilerInstance & ci ; @@ -78,6 +78,7 @@ class CXXRecordVisitor : public clang::RecursiveASTVisitor { /** Flag indicating we have found a public/private/protected keyword */ bool access_spec_found ; + static std::set private_embedded_classes ; } ; #endif diff --git a/trick_source/codegen/Interface_Code_Gen/FieldDescription.cpp b/trick_source/codegen/Interface_Code_Gen/FieldDescription.cpp index a9d03845..e498dd9b 100644 --- a/trick_source/codegen/Interface_Code_Gen/FieldDescription.cpp +++ b/trick_source/codegen/Interface_Code_Gen/FieldDescription.cpp @@ -247,9 +247,6 @@ void FieldDescription::setContainerClass(std::string in_name ) { void FieldDescription::setFieldOffset(unsigned int in_offset) { field_offset = in_offset ; - if ( is_bitfield ) { - calcBitfieldOffset() ; - } } unsigned int FieldDescription::getFieldOffset() { @@ -331,17 +328,8 @@ clang::AccessSpecifier FieldDescription::getAccess() { return access ; } -void FieldDescription::calcBitfieldOffset() { - unsigned int field_offset_bits = field_offset * 8 ; - bitfield_start_bit = 32 - (field_offset_bits % 32) - bitfield_width ; - bitfield_word_offset = (field_offset_bits / 32) * 4 ; -} - void FieldDescription::addOffset( unsigned int offset ) { field_offset += offset ; - if ( is_bitfield ) { - calcBitfieldOffset() ; - } } void FieldDescription::setEnumString(std::string in_str) { diff --git a/trick_source/codegen/Interface_Code_Gen/FieldDescription.hh b/trick_source/codegen/Interface_Code_Gen/FieldDescription.hh index e5d12ca8..754ade40 100644 --- a/trick_source/codegen/Interface_Code_Gen/FieldDescription.hh +++ b/trick_source/codegen/Interface_Code_Gen/FieldDescription.hh @@ -79,7 +79,6 @@ class FieldDescription : public ConstructValues { bool isInherited() ; void setAccess( clang::AccessSpecifier in_val ) ; clang::AccessSpecifier getAccess() ; - void calcBitfieldOffset() ; void addOffset( unsigned int offset ) ; /** Adds an array dimension to the field */ @@ -95,10 +94,10 @@ class FieldDescription : public ConstructValues { /** Name of the class this field is in */ std::string container_class ; - /** The total offset to the current field in bytes */ + /** The total offset to the current field in bits */ unsigned int field_offset ; - /** The size of the current field in bytes */ + /** The size of the current field in bits */ unsigned int field_width ; /** Name of the type. Non-canonical. It's what was actually read in input file */ diff --git a/trick_source/codegen/Interface_Code_Gen/FieldVisitor.cpp b/trick_source/codegen/Interface_Code_Gen/FieldVisitor.cpp index 223cf970..535d0f95 100644 --- a/trick_source/codegen/Interface_Code_Gen/FieldVisitor.cpp +++ b/trick_source/codegen/Interface_Code_Gen/FieldVisitor.cpp @@ -6,6 +6,7 @@ #include "clang/AST/RecordLayout.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Comment.h" +#include "clang/Sema/Sema.h" #include "FieldVisitor.hh" #include "FieldDescription.hh" @@ -138,9 +139,22 @@ bool FieldVisitor::VisitDeclaratorDecl( clang::DeclaratorDecl *dd ) { fdes->setName(dd->getNameAsString()) ; fdes->setAccess(dd->getAccess()) ; + clang::SourceRange dd_range = dd->getSourceRange() ; + clang::PresumedLoc PLoc = ci.getSourceManager().getPresumedLoc(dd_range.getEnd()); + std::string file_name ; + if (!PLoc.isInvalid()) { + char * resolved_path = almostRealPath(PLoc.getFilename()) ; + if ( resolved_path != NULL ) { + file_name = std::string(resolved_path) ; + free(resolved_path) ; + } + } + /* Get the source location of this field. */ +#if 0 clang::SourceRange dd_range = dd->getSourceRange() ; std::string file_name = getFileName(ci, dd_range.getEnd(), hsd) ; +#endif if ( ! file_name.empty() ) { if ( isInUserOrTrickCode( ci , dd_range.getEnd() , hsd ) ) { fdes->setLineNo(ci.getSourceManager().getSpellingLineNumber(dd_range.getEnd())) ; @@ -196,28 +210,27 @@ bool FieldVisitor::VisitEnumType( clang::EnumType *et ) { bool FieldVisitor::VisitFieldDecl( clang::FieldDecl *field ) { - // set the offset to the field - fdes->setFieldOffset(field->getASTContext().getFieldOffset(field) / 8) ; + clang::QualType qt = field->getType() ; - fdes->setBitField(field->isBitField()) ; - if ( fdes->isBitField() ) { + // set the offset and size field + fdes->setFieldOffset(field->getASTContext().getFieldOffset(field)) ; + fdes->setFieldWidth(field->getASTContext().getTypeSize(qt)) ; + + if ( field->isBitField()) { + fdes->setBitField(true) ; fdes->setBitFieldWidth(field->getBitWidthValue(field->getASTContext())) ; - fdes->calcBitfieldOffset() ; } - // If the current type is not canonical because of typedefs or template parameter substitution, - // traverse the canonical type - clang::QualType qt = field->getType() ; if ( debug_level >= 3 ) { std::cout << "FieldVisitor VisitFieldDecl" << std::endl ; std::cout << " is_bitfield = " << fdes->isBitField() << std::endl ; std::cout << " is_canonical = " << qt.isCanonical() << std::endl ; + std::cout << " is_hidden = " << field->isHidden() << std::endl ; //field->dump() ; } - // set the offset to the field - fdes->setFieldWidth(field->getASTContext().getTypeSize(qt) / 8) ; - + // If the current type is not canonical because of typedefs or template parameter substitution, + // traverse the canonical type if ( !qt.isCanonical() ) { fdes->setNonCanonicalTypeName(qt.getAsString()) ; clang::QualType ct = qt.getCanonicalType() ; @@ -334,6 +347,35 @@ static std::map init_stl_classes() { return my_map ; } +static bool checkForPRivateTemplateArgs( clang::ClassTemplateSpecializationDecl * ctsd ) { + unsigned int ii ; + for ( ii = 0 ; ii < ctsd->getTemplateArgs().size() ; ii++ ) { + const clang::TemplateArgument & ta = ctsd->getTemplateArgs().get(ii) ; + if ( ta.getKind() == clang::TemplateArgument::Type ) { + clang::QualType qt = ta.getAsType() ; + //std::cout << qt.getAsString() << std::endl ; + if ( CXXRecordVisitor::isPrivateEmbeddedClass(qt.getAsString()) ) { + //std::cout << " is private embedded class" << std::endl ; + return true ; + } else { + //std::cout << " is public embedded class" << std::endl ; + const clang::Type * t = qt.getTypePtrOrNull() ; + if ( t != NULL ) { + if (t->getTypeClass() == clang::Type::Record ) { + clang::CXXRecordDecl * crd = t->getAsCXXRecordDecl() ; + if ( clang::isa(crd) ) { + clang::ClassTemplateSpecializationDecl * inner_ctsd ; + inner_ctsd = clang::cast(crd) ; + return checkForPRivateTemplateArgs(inner_ctsd) ; + } + } + } + } + } + } + return false ; +} + static std::map stl_classes = init_stl_classes() ; bool FieldVisitor::VisitRecordType(clang::RecordType *rt) { @@ -376,6 +418,17 @@ bool FieldVisitor::VisitRecordType(clang::RecordType *rt) { for ( std::map::iterator it = stl_classes.begin() ; it != stl_classes.end() ; it++ ) { /* Mark STL types that are not strings and exit */ if (!tst_string.compare( 0 , (*it).first.size() , (*it).first)) { + + clang::RecordDecl * rd = rt->getDecl()->getDefinition() ; + clang::ClassTemplateSpecializationDecl * ctsd ; + ctsd = clang::cast(rd) ; + + // If a private embedded class is in an STL the resulting io_src code will not compile. + // Search the template arguments for private embedded classes, if found remove io capabilites. + if ( checkForPRivateTemplateArgs( ctsd )) { + fdes->setIO(0) ; + } + fdes->setEnumString("TRICK_STL") ; fdes->setSTL(true) ; fdes->setTypeName(tst_string) ; @@ -397,11 +450,17 @@ bool FieldVisitor::VisitRecordType(clang::RecordType *rt) { If so process the template type and return */ clang::RecordDecl * rd = rt->getDecl()->getDefinition() ; if ( rd != NULL and clang::ClassTemplateSpecializationDecl::classof(rd) ) { + if ( checkForPRivateTemplateArgs( clang::cast(rd)) ) { + fdes->setIO(0) ; + if ( debug_level >= 3 ) { + std::cout << " template using private/protected class as argument, not processing" << std::endl ; + } + return false ; + } if ( debug_level >= 3 ) { rd->dump() ; std::cout << " tst_string = " << tst_string << std::endl ; - std::cout << " rd is_a_template_specialization = " << - clang::ClassTemplateSpecializationDecl::classof(rd) << std::endl ; + std::cout << " is_a_template_specialization" << std::endl ; } return ProcessTemplate(tst_string, clang::cast(rd)) ; } diff --git a/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.cpp b/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.cpp index 17e1dd87..7cb15ed8 100644 --- a/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.cpp +++ b/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.cpp @@ -80,14 +80,27 @@ void PrintFileContents10::print_field_attr(std::ofstream & outfile , FieldDescr outfile << " \"" << fdes->getDescription() << "\"," << std::endl ; // description outfile << " " << fdes->getIO() ; // io outfile << "," << fdes->getEnumString() ; // type - outfile << "," << fdes->getFieldWidth() << ",0,0,Language_CPP" ; // size, range_min, range_max, language + if ( fdes->isBitField() ) { + outfile << ",4" ; // size, bitfields are handled in 4 byte (32 bit) chunks + } else { + outfile << "," << fdes->getFieldWidth() / 8 ; // size, size is saved in bits, convert to bytes. + } + outfile << ",0,0,Language_CPP" ; // range_min, range_max, language outfile << "," << (fdes->isStatic() << 1 ) << "," << std::endl ; // mods - outfile << " " << fdes->getFieldOffset() << ",NULL" ; // offset, attr + if ( fdes->isBitField() ) { + // For bitfields we need the offset to start on 4 byte boundaries because that is what our + // insert and extract bitfield routines work with. + outfile << " " << (fdes->getFieldOffset() - (fdes->getFieldOffset() % 32)) / 8 ; // offset + } else { + outfile << " " << (fdes->getFieldOffset() / 8) ; // offset + } + outfile << ",NULL" ; // attr outfile << "," << fdes->getNumDims() ; // num_index outfile << ",{" ; if ( fdes->isBitField() ) { - outfile << "{" << fdes->getBitFieldWidth() << "," << fdes->getBitFieldStart() << "}" ; // index 0 + outfile << "{" << fdes->getBitFieldWidth() ; // size of bitfield + outfile << "," << 32 - (fdes->getFieldOffset() % 32) - fdes->getBitFieldWidth() << "}" ; // start bit } else { array_dim = fdes->getArrayDim(0) ; if ( array_dim < 0 ) array_dim = 0 ; @@ -133,53 +146,27 @@ void PrintFileContents10::print_class_attr(std::ofstream & outfile , ClassValues } /** Prints init_attr function for each class */ -void PrintFileContents10::print_field_init_attr_stmts( std::ofstream & outfile , FieldDescription * fdes , ClassValues * cv ) { +void PrintFileContents10::print_field_init_attr_stmts( std::ofstream & outfile , FieldDescription * fdes , + ClassValues * cv , unsigned int index ) { - // Static bitfields do not get to this point, they are filtered out in determinePrintAttr - - // Always print offset as address of the static variable + // For static variables replace the offset field with the address of the static variable if ( fdes->isStatic() ) { - // print a special offsetof statement if this is a static + // NOTE: We would not be able to take the address of a static bitfield. + // Static bitfields do not get to this point, they are filtered out in determinePrintAttr outfile << " attr" ; printNamespaces( outfile, cv , "__" ) ; printContainerClasses( outfile, cv , "__" ) ; - outfile << cv->getMangledTypeName() << "[i].offset = (long)(void *)&" ; + outfile << cv->getMangledTypeName() << "[" << index << "].offset = (long)(void *)&" ; printNamespaces( outfile, cv , "::" ) ; printContainerClasses( outfile, cv , "::" ) ; outfile << cv->getName() << "::" << fdes->getName() << " ;\n" ; } - // if this is a bitfield... - // TODO: may not need to write out offset... - if ( fdes->isBitField() ) { - outfile << " attr" ; - printNamespaces( outfile, cv , "__" ) ; - printContainerClasses( outfile, cv , "__" ) ; - outfile << cv->getMangledTypeName() << "[i].offset = " ; - outfile << fdes->getBitFieldByteOffset() << " ;\n" ; - - // All bitfield offsets are in terms of unsigned ints. - outfile << " attr" ; - printNamespaces( outfile, cv , "__" ) ; - printContainerClasses( outfile, cv , "__" ) ; - outfile << cv->getMangledTypeName() << "[i].size = sizeof(unsigned int) ;\n" ; - } - - if ( !fdes->isRecord() and !fdes->isEnum() and !fdes->isBitField() and !fdes->isSTL()) { - outfile << " attr" ; - printNamespaces( outfile, cv , "__" ) ; - printContainerClasses( outfile, cv , "__" ) ; - outfile << cv->getMangledTypeName() << "[i].size = sizeof(" ; - printNamespaces( outfile, fdes , "::" ) ; - printContainerClasses( outfile, fdes , "::" ) ; - outfile << fdes->getTypeName() << ") ;\n" ; - } - if ( fdes->isSTL()) { outfile << " attr" ; printNamespaces( outfile, cv , "__" ) ; printContainerClasses( outfile, cv , "__" ) ; - outfile << cv->getMangledTypeName() << "[i].checkpoint_stl = checkpoint_stl_" ; + outfile << cv->getMangledTypeName() << "[" << index << "].checkpoint_stl = checkpoint_stl_" ; outfile << cv->getMangledTypeName() ; outfile << "_" ; outfile << fdes->getName() ; @@ -188,7 +175,7 @@ void PrintFileContents10::print_field_init_attr_stmts( std::ofstream & outfile , outfile << " attr" ; printNamespaces( outfile, cv , "__" ) ; printContainerClasses( outfile, cv , "__" ) ; - outfile << cv->getMangledTypeName() << "[i].post_checkpoint_stl = post_checkpoint_stl_" ; + outfile << cv->getMangledTypeName() << "[" << index << "].post_checkpoint_stl = post_checkpoint_stl_" ; outfile << cv->getMangledTypeName() ; outfile << "_" ; outfile << fdes->getName() ; @@ -197,7 +184,7 @@ void PrintFileContents10::print_field_init_attr_stmts( std::ofstream & outfile , outfile << " attr" ; printNamespaces( outfile, cv , "__" ) ; printContainerClasses( outfile, cv , "__" ) ; - outfile << cv->getMangledTypeName() << "[i].restore_stl = restore_stl_" ; + outfile << cv->getMangledTypeName() << "[" << index << "].restore_stl = restore_stl_" ; outfile << cv->getMangledTypeName() ; outfile << "_" ; outfile << fdes->getName() ; @@ -207,7 +194,7 @@ void PrintFileContents10::print_field_init_attr_stmts( std::ofstream & outfile , outfile << " attr" ; printNamespaces( outfile, cv , "__" ) ; printContainerClasses( outfile, cv , "__" ) ; - outfile << cv->getMangledTypeName() << "[i].clear_stl = clear_stl_" ; + outfile << cv->getMangledTypeName() << "[" << index << "].clear_stl = clear_stl_" ; outfile << cv->getMangledTypeName() ; outfile << "_" ; outfile << fdes->getName() ; @@ -219,14 +206,13 @@ void PrintFileContents10::print_field_init_attr_stmts( std::ofstream & outfile , outfile << " next_attr = std::string(attr" ; printNamespaces( outfile, cv , "__" ) ; printContainerClasses( outfile, cv , "__" ) ; - outfile << cv->getMangledTypeName() << "[i].type_name) ;\n" ; + outfile << cv->getMangledTypeName() << "[" << index << "].type_name) ;\n" ; outfile << " mm->add_attr_info(next_attr , &attr" ; printNamespaces( outfile, cv , "__" ) ; printContainerClasses( outfile, cv , "__" ) ; - outfile << cv->getMangledTypeName() << "[i], __FILE__ , __LINE__ ) ;\n" ; + outfile << cv->getMangledTypeName() << "[" << index << "], __FILE__ , __LINE__ ) ;\n" ; } - outfile << " i++ ;\n\n" ; } /** Prints add_attr_info statements for each inherited class */ @@ -252,7 +238,6 @@ void PrintFileContents10::print_init_attr_func( std::ofstream & outfile , ClassV printContainerClasses( outfile, cv , "__" ) ; outfile << cv->getMangledTypeName() ; outfile << "() {\n\n" -" int i __attribute__((unused)) = 0 ;\n" " static int initialized_1337 ;\n" " if ( initialized_1337 ) {\n" " return ;\n" @@ -266,9 +251,11 @@ void PrintFileContents10::print_init_attr_func( std::ofstream & outfile , ClassV outfile << " typedef " << cv->getName() << " " << cv->getMangledTypeName() << " ;\n\n" ; } + unsigned int ii = 0 ; for ( fit = cv->field_begin() ; fit != cv->field_end() ; fit++ ) { if ( determinePrintAttr(cv , *fit) ) { - print_field_init_attr_stmts(outfile, *fit, cv) ; + print_field_init_attr_stmts(outfile, *fit, cv, ii) ; + ii++ ; } } print_inherited_add_attr_info(outfile, cv ) ; diff --git a/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.hh b/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.hh index 53f91047..fad81c1f 100644 --- a/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.hh +++ b/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.hh @@ -58,7 +58,8 @@ class PrintFileContents10 : public PrintFileContentsBase { void print_class_attr(std::ofstream & outfile , ClassValues * in_class) ; /** Prints init_attr function for each class */ - void print_field_init_attr_stmts(std::ofstream & outfile , FieldDescription * fdes , ClassValues * cv ) ; + void print_field_init_attr_stmts(std::ofstream & outfile , FieldDescription * fdes , + ClassValues * cv , unsigned int index ) ; /** Prints add_attr_info statements for each inherited class */ void print_inherited_add_attr_info(std::ofstream & outfile , ClassValues * cv ) ;