From 285d6c39b1880fb6f54c0dea7d9e3c6a3bbdc92c Mon Sep 17 00:00:00 2001 From: Alex Lin Date: Fri, 24 May 2024 10:52:36 -0500 Subject: [PATCH] test using ICG to create byteswap attributes for use with external programs --- .../Interface_Code_Gen/PrintAttributes.cpp | 13 +- .../Interface_Code_Gen/PrintAttributes.hh | 3 + .../PrintFileContents10.cpp | 4 + .../Interface_Code_Gen/PrintFileContents10.hh | 3 + .../PrintFileContentsBase.hh | 3 + .../PrintFileContentsMin.cpp | 140 ++++++++++++++++++ .../PrintFileContentsMin.hh | 56 +++++++ 7 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 trick_source/codegen/Interface_Code_Gen/PrintFileContentsMin.cpp create mode 100644 trick_source/codegen/Interface_Code_Gen/PrintFileContentsMin.hh diff --git a/trick_source/codegen/Interface_Code_Gen/PrintAttributes.cpp b/trick_source/codegen/Interface_Code_Gen/PrintAttributes.cpp index 758a84cd..71f18614 100644 --- a/trick_source/codegen/Interface_Code_Gen/PrintAttributes.cpp +++ b/trick_source/codegen/Interface_Code_Gen/PrintAttributes.cpp @@ -15,6 +15,7 @@ #include "PrintAttributes.hh" #include "PrintFileContentsBase.hh" #include "PrintFileContents10.hh" +#include "PrintFileContentsMin.hh" #include "FieldDescription.hh" #include "HeaderSearchDirs.hh" #include "CommentSaver.hh" @@ -28,11 +29,16 @@ PrintAttributes::PrintAttributes(int in_attr_version , HeaderSearchDirs & in_hsd hsd(in_hsd) , cs(in_cs) , ci(in_ci) , + attr_version(in_attr_version) , force(in_force) , sim_services_flag( in_sim_services_flag ) , output_dir( in_output_dir ) { - printer = new PrintFileContents10() ; + if ( in_attr_version == 0 ) { + printer = new PrintFileContentsMin() ; + } else { + printer = new PrintFileContents10() ; + } } void PrintAttributes::addIgnoreTypes() { @@ -177,7 +183,10 @@ std::string PrintAttributes::createIOFileName(std::string header_file_name) { base_name = std::string(basename(temp_str)) ; found = base_name.find_last_of(".") ; - base_name = std::string("io_") + base_name.substr(0,found) + std::string(".cpp") ; + base_name = printer->createIOSrcFileName(base_name.substr(0,found)); + if (attr_version == 0) { + return base_name; + } dir_name = std::string(dirname(temp_str)) ; if ( ! dir_name.compare(".") ) { diff --git a/trick_source/codegen/Interface_Code_Gen/PrintAttributes.hh b/trick_source/codegen/Interface_Code_Gen/PrintAttributes.hh index 9b3a7dec..35374973 100644 --- a/trick_source/codegen/Interface_Code_Gen/PrintAttributes.hh +++ b/trick_source/codegen/Interface_Code_Gen/PrintAttributes.hh @@ -93,6 +93,9 @@ class PrintAttributes { /** Compiler instance */ clang::CompilerInstance & ci ; + /** version of attributes requested by user */ + int attr_version; + /** Version specific attributes printer */ PrintFileContentsBase * printer ; diff --git a/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.cpp b/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.cpp index 807fca92..6e0e76fc 100644 --- a/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.cpp +++ b/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.cpp @@ -11,6 +11,10 @@ extern llvm::cl::opt< bool > global_compat15 ; PrintFileContents10::PrintFileContents10() {} +std::string PrintFileContents10::createIOSrcFileName(std::string base_file_name) { + return std::string("io_") + base_file_name + std::string(".cpp") ; +} + /** Prints the io_src header information */ void PrintFileContents10::printIOHeader(std::ostream & ostream , std::string header_file_name) { diff --git a/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.hh b/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.hh index 6802f43d..b3ab068a 100644 --- a/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.hh +++ b/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.hh @@ -28,6 +28,9 @@ class PrintFileContents10 : public PrintFileContentsBase { PrintFileContents10() ; + /** create io_src file name */ + virtual std::string createIOSrcFileName(std::string base_file_name) ; + /** Prints the io_src header information */ virtual void printIOHeader(std::ostream & outfile , std::string header_file_name) ; diff --git a/trick_source/codegen/Interface_Code_Gen/PrintFileContentsBase.hh b/trick_source/codegen/Interface_Code_Gen/PrintFileContentsBase.hh index a157a533..6562d4e1 100644 --- a/trick_source/codegen/Interface_Code_Gen/PrintFileContentsBase.hh +++ b/trick_source/codegen/Interface_Code_Gen/PrintFileContentsBase.hh @@ -29,6 +29,9 @@ class PrintFileContentsBase { public: PrintFileContentsBase() ; + /** create io_src file name */ + virtual std::string createIOSrcFileName(std::string base_file_name) = 0 ; + virtual void printIOHeader(std::ostream & ostream, std::string header_file_name) = 0 ; virtual void printClass(std::ostream & ostream, ClassValues * cv) = 0 ; virtual void printEnum(std::ostream & ostream, EnumValues * ev) = 0 ; diff --git a/trick_source/codegen/Interface_Code_Gen/PrintFileContentsMin.cpp b/trick_source/codegen/Interface_Code_Gen/PrintFileContentsMin.cpp new file mode 100644 index 00000000..72ba2d1d --- /dev/null +++ b/trick_source/codegen/Interface_Code_Gen/PrintFileContentsMin.cpp @@ -0,0 +1,140 @@ +#include +#include + +#include "PrintFileContentsMin.hh" +#include "FieldDescription.hh" +#include "ClassValues.hh" +#include "EnumValues.hh" +#include "Utilities.hh" + +extern llvm::cl::opt< bool > global_compat15 ; + +PrintFileContentsMin::PrintFileContentsMin() {} + +std::string PrintFileContentsMin::createIOSrcFileName(std::string base_file_name) { + return std::string("io_") + base_file_name + std::string(".c") ; +} + +/** Prints the io_src header information */ +void PrintFileContentsMin::printIOHeader(std::ostream & ostream , std::string header_file_name) { + + if ( ! header_file_name.compare("S_source.hh") ) { + header_file_name = "../S_source.hh" ; + } else { + header_file_name = almostRealPath(header_file_name.c_str()) ; + } + ostream << "/**\n" + << " * This file was automatically generated by the ICG based on the file:\n" + << " * " << header_file_name << "\n" + << " * This file contains database parameter declarations specific to the\n" + << " * data structures and enumerated types declared in the above file.\n" + << " * These database parameters are used by the Trick input and\n" + << " * data recording processors to gain access to important simulation\n" + << " * variable information.\n" + << " */\n" + << "\n" + << "#define TRICK_IN_IOSRC\n" + << "#include \"trick/attributes.h\"\n" + << "#include \"trick/parameter_types.h\"\n" + << "#include \"io_src.h\"\n" + << "#include \"" << header_file_name << "\"\n" + << "\n"; +} + +/** Prints enumeration attributes */ +void PrintFileContentsMin::print_enum_attr(std::ostream & ostream , EnumValues * e ) { + ostream << "ENUM_ATTR enum" << e->getFullyQualifiedTypeName("__") << "[] = {\n" ; + std::string name = e->getNamespacesAndContainerClasses(); + for (auto& pair : e->getPairs()) { + ostream << "{\"" << name << pair.first << "\", " << pair.second << ", 0x0},\n" ; + } + ostream << "{\"\", 0, 0x0}\n};\n" ; +} + +/** Prints attributes for a field */ +void PrintFileContentsMin::print_field_attr(std::ostream & ostream , FieldDescription & fdes ) { + int array_dim ; + + ostream << " {\"" << fdes.getName() << "\"" // name + << ", \"" << fdes.getFullyQualifiedMangledTypeName("__") << "\"" // type_name + << ", \"" << fdes.getUnits() << "\"" // units + << ", \"\", \"\"," << std::endl // alias, user_defined + << " \"" << fdes.getDescription() << "\"," << std::endl // description + << " " << fdes.getIO() // io + << "," << fdes.getEnumString() ; // type + // There are several cases when printing the size of a variable. + if ( fdes.isBitField() ) { + // bitfields are handled in 4 byte (32 bit) chunks + ostream << ", 4" ; + } else if ( fdes.isRecord() or fdes.isEnum() ) { + // records enums use io_src_get_size. The sentinel has no typename + //ostream << ", 0" ; + ostream << ", sizeof(" << fdes.getNonCanonicalTypeName() << ")" ; + } else if ( fdes.getTypeName().empty() ) { + ostream << ", 0" ; + } else { + // print size of the underlying type + ostream << ", sizeof(" << fdes.getTypeName() << ")" ; + } + ostream << ", 0, 0, Language_C" ; // range_min, range_max, language + // mods (see attributes.h for descriptions) + ostream << ", 0,\n"; // mods + 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. + ostream << " " << (fdes.getFieldOffset() - (fdes.getFieldOffset() % 32)) / 8 ; // offset + } else { + ostream << " " << (fdes.getFieldOffset() / 8) ; // offset + } + if ( fdes.isRecord() ) { + ostream << ", attr" << fdes.getFullyQualifiedMangledTypeName("__"); + } else { + ostream << ", NULL" ; // attr + } + ostream << ", " << fdes.getNumDims() ; // num_index + + ostream << ", {" ; + if ( fdes.isBitField() ) { + ostream << "{" << fdes.getBitFieldWidth() ; // size of bitfield + ostream << ", " << 32 - (fdes.getFieldOffset() % 32) - fdes.getBitFieldWidth() << "}" ; // start bit + } else { + array_dim = fdes.getArrayDim(0) ; + if ( array_dim < 0 ) array_dim = 0 ; + ostream << "{" << array_dim << ", 0}" ; // index 0 + } + unsigned int ii ; + for ( ii = 1 ; ii < 8 ; ii++ ) { + array_dim = fdes.getArrayDim(ii) ; + if ( array_dim < 0 ) array_dim = 0 ; + ostream << ", {" << array_dim << ", 0}" ; // indexes 1 through 7 + } + ostream << "}," << std::endl ; + ostream << " NULL, NULL, NULL, NULL" ; + ostream << "}" ; +} + +/** Prints class attributes */ +void PrintFileContentsMin::print_class_attr(std::ostream & ostream , ClassValues * c ) { + + ostream << "ATTRIBUTES attr" << c->getFullyQualifiedMangledTypeName("__") << "[] = {" << std::endl ; + + for (FieldDescription* fieldDescription : getPrintableFields(*c)) { + print_field_attr(ostream, *fieldDescription) ; + ostream << "," << std::endl ; + } + // Print an empty sentinel attribute at the end of the class. + FieldDescription new_fdes(std::string("")) ; + print_field_attr(ostream, new_fdes) ; + ostream << "\n};" << std::endl ; +} + +void PrintFileContentsMin::printClass( std::ostream & ostream , ClassValues * cv ) { + print_class_attr(ostream, cv) ; + ostream << std::endl; +} + +void PrintFileContentsMin::printEnum( std::ostream & ostream , EnumValues * ev ) { + print_enum_attr(ostream, ev) ; + ostream << std::endl; +} + diff --git a/trick_source/codegen/Interface_Code_Gen/PrintFileContentsMin.hh b/trick_source/codegen/Interface_Code_Gen/PrintFileContentsMin.hh new file mode 100644 index 00000000..39801df7 --- /dev/null +++ b/trick_source/codegen/Interface_Code_Gen/PrintFileContentsMin.hh @@ -0,0 +1,56 @@ + +#ifndef PRINTFILECONTENTSMIN_HH +#define PRINTFILECONTENTSMIN_HH + +#include +#include +#include +#include +#include + +#include "PrintFileContentsBase.hh" + +/** + + This class prints Trick 10 style io_src code. The print command is called when + the container class has added all of the classes and enumerations to this class + to print. + + @author Alexander S. Lin + + @date July 2012 + + */ + +class PrintFileContentsMin : public PrintFileContentsBase { + + public: + + PrintFileContentsMin() ; + + /** create io_src file name */ + virtual std::string createIOSrcFileName(std::string base_file_name) ; + + /** Prints the io_src header information */ + virtual void printIOHeader(std::ostream & outfile , std::string header_file_name) ; + + /** Prints all io_src code for incoming class */ + virtual void printClass(std::ostream & outfile , ClassValues * cv) ; + + /** Prints all io_src code for incoming enum */ + virtual void printEnum(std::ostream & outfile , EnumValues * ev) ; + + private: + + /** Prints enumeration attributes */ + void print_enum_attr(std::ostream & outfile , EnumValues * in_enum) ; + + /** Prints attributes for a field */ + void print_field_attr(std::ostream & outfile , FieldDescription & fdes ) ; + + /** Prints class attributes */ + void print_class_attr(std::ostream & outfile , ClassValues * in_class) ; + +} ; + +#endif