test using ICG to create byteswap attributes for use with external programs

This commit is contained in:
Alex Lin 2024-05-24 10:52:36 -05:00
parent a1d151c4c3
commit 285d6c39b1
7 changed files with 220 additions and 2 deletions

View File

@ -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(".") ) {

View File

@ -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 ;

View File

@ -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) {

View File

@ -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) ;

View File

@ -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 ;

View File

@ -0,0 +1,140 @@
#include <algorithm>
#include <sstream>
#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;
}

View File

@ -0,0 +1,56 @@
#ifndef PRINTFILECONTENTSMIN_HH
#define PRINTFILECONTENTSMIN_HH
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#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