ICG exclude of class member variables now defines incorrect memory offsets in io_src #311

Added back the code that set the offset of variables with the offsetof function. This
code is running by default.  Any code that includes #ifndef TRICK_ICG in
classes/structures will want this on.

Added a flag to ICG that allows us to turn off writing of these lines.  If the flag
is present, ICG may write out io_src code for private/protected variables that it could
not reach if an offsetof function was required.  Code cannot have any #ifndef TRICK_ICG
present in classes/structures for this to work.
This commit is contained in:
Alex Lin 2016-09-16 08:39:37 -05:00
parent c4a32600cc
commit ae07b26243
8 changed files with 116 additions and 15 deletions

View File

@ -38,7 +38,8 @@ void ClassValues::addFieldDescription(FieldDescription * in_fdes) {
field_name_to_info_map[in_fdes->getName()] = in_fdes ;
}
void ClassValues::addInheritedFieldDescriptions(std::vector<FieldDescription *> in_fdes, unsigned int class_offset ) {
void ClassValues::addInheritedFieldDescriptions(std::vector<FieldDescription *> in_fdes,
unsigned int class_offset, bool virtual_inherited ) {
// Make a copy of all of the FieldDescription variables.
field_descripts.insert(field_descripts.end(), in_fdes.begin() , in_fdes.end()) ;
@ -46,7 +47,9 @@ void ClassValues::addInheritedFieldDescriptions(std::vector<FieldDescription *>
// Loop through the incoming inherited variable names
for ( fdit = in_fdes.begin() ; fdit != in_fdes.end() ; fdit++ ) {
(*fdit)->setBaseClassOffset( class_offset ) ;
(*fdit)->setInherited( true ) ;
(*fdit)->setVirtualInherited( virtual_inherited ) ;
// Adds the class offset to the field offset giving the total offset to the inherited variable
// The offset is stored in bits so multiply class_offset by 8.
(*fdit)->addOffset( class_offset * 8 ) ;

View File

@ -36,7 +36,8 @@ class ClassValues : public ConstructValues {
/** Appends a vector of fields to field_descripts.
A vector comes from adding all inherited fields at once */
void addInheritedFieldDescriptions(std::vector<FieldDescription *>, unsigned int class_offset) ;
void addInheritedFieldDescriptions(std::vector<FieldDescription *>,
unsigned int class_offset, bool virtual_inherited) ;
/** Gets the list of fields in this class */
std::vector<FieldDescription *> getFieldDescription() ;

View File

@ -207,7 +207,7 @@ bool CXXRecordVisitor::VisitCXXRecordDecl( clang::CXXRecordDecl *rec ) {
CXXRecordVisitor inherit_cvis(ci , cs, hsd , pa, false) ;
inherit_cvis.TraverseCXXRecordDecl(static_cast<clang::CXXRecordDecl *>(rd)) ;
cval.addInheritedFieldDescriptions(inherit_cvis.get_class_data()->getFieldDescription(),
inherit_class_offset) ;
inherit_class_offset, false) ;
// 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() ;
@ -257,7 +257,7 @@ 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<clang::CXXRecordDecl *>(rd)) ;
cval.addInheritedFieldDescriptions(inherit_cvis.get_class_data()->getFieldDescription(), inherit_class_offset) ;
cval.addInheritedFieldDescriptions(inherit_cvis.get_class_data()->getFieldDescription(), inherit_class_offset, true) ;
// 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

View File

@ -37,9 +37,11 @@ ut_system * FieldDescription::u_system = get_u_system() ;
FieldDescription::FieldDescription(
std::string in_container_class ) :
container_class(in_container_class) ,
base_class_offset(0) ,
field_offset(0) ,
field_width(0) ,
inherited(false) ,
virtual_inherited(false) ,
units("1") ,
is_dashdash(false) ,
line_no(0) ,
@ -314,6 +316,14 @@ void FieldDescription::setContainerClass(std::string in_name ) {
container_class = in_name ;
}
void FieldDescription::setBaseClassOffset(unsigned int in_offset) {
base_class_offset = in_offset ;
}
unsigned int FieldDescription::getBaseClassOffset() {
return base_class_offset ;
}
void FieldDescription::setFieldOffset(unsigned int in_offset) {
field_offset = in_offset ;
}
@ -393,6 +403,14 @@ bool FieldDescription::isInherited() {
return inherited ;
}
void FieldDescription::setVirtualInherited(bool in_inherited) {
virtual_inherited = in_inherited ;
}
bool FieldDescription::isVirtualInherited() {
return virtual_inherited ;
}
void FieldDescription::setAccess( clang::AccessSpecifier in_val ) {
access = in_val ;
}

View File

@ -39,6 +39,7 @@ class FieldDescription : public ConstructValues {
/* Accessor functions to the data of the class */
std::string getContainerClass() ;
void setContainerClass( std::string in_name ) ;
void setBaseClassOffset( unsigned int in_offset ) ;
unsigned int getBaseClassOffset() ;
void setFieldOffset( unsigned int in_offset ) ;
unsigned int getFieldOffset() ;
@ -80,6 +81,8 @@ class FieldDescription : public ConstructValues {
bool isStatic() ;
void setInherited( bool yes_no ) ;
bool isInherited() ;
void setVirtualInherited( bool yes_no ) ;
bool isVirtualInherited() ;
void setAccess( clang::AccessSpecifier in_val ) ;
clang::AccessSpecifier getAccess() ;
void addOffset( unsigned int offset ) ;
@ -97,6 +100,10 @@ class FieldDescription : public ConstructValues {
/** Name of the class this field is in */
std::string container_class ;
/** This is copied from the current class we are processing. It is the class offset to
be added to field offset */
unsigned int base_class_offset ;
/** The total offset to the current field in bits */
unsigned int field_offset ;
@ -151,6 +158,9 @@ class FieldDescription : public ConstructValues {
/** is this field inherited from parent class */
bool inherited ;
/** is this field virtual inherited from parent class */
bool virtual_inherited ;
/** is an enumeration */
bool is_enum ;

View File

@ -9,6 +9,8 @@
#include "EnumValues.hh"
#include "Utilities.hh"
extern llvm::cl::opt< bool > no_offset_of ;
PrintFileContents10::PrintFileContents10() {}
/** Prints the io_src header information */
@ -157,14 +159,63 @@ void PrintFileContents10::print_field_init_attr_stmts( std::ofstream & outfile ,
ClassValues * cv , unsigned int index ) {
// For static variables replace the offset field with the address of the static variable
if ( fdes->isStatic() ) {
outfile << " attr" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() << "[" << index << "].offset = (long)(void *)&" ;
printNamespaces( outfile, cv , "::" ) ;
printContainerClasses( outfile, cv , "::" ) ;
outfile << cv->getName() << "::" << fdes->getName() << " ;\n" ;
if ( no_offset_of ) {
if ( fdes->isStatic() ) {
outfile << " attr" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() << "[" << index << "].offset = (long)(void *)&" ;
printNamespaces( outfile, cv , "::" ) ;
printContainerClasses( outfile, cv , "::" ) ;
outfile << cv->getName() << "::" << fdes->getName() << " ;\n" ;
}
} else {
if ( fdes->isStatic() ) {
// print a special offsetof statement if this is a static
outfile << " attr" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() << "[" << index << "].offset = (long)(void *)&" ;
printNamespaces( outfile, cv , "::" ) ;
printContainerClasses( outfile, cv , "::" ) ;
outfile << cv->getName() << "::" << fdes->getName() << " ;\n" ;
} else if ( fdes->isBitField() ) {
// else if this is a bitfield
outfile << " attr" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() << "[" << index << "].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() << "[" << index << "].size = sizeof(unsigned int) ;\n" ;
} else if ( fdes->isVirtualInherited() ) {
// else if we have a virtually inherited class.
outfile << " attr" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() << "[" << index << "].offset = " << fdes->getBaseClassOffset() ;
outfile << " + offsetof(" ;
outfile << fdes->getContainerClass() << "," << fdes->getName() << ") ;\n" ;
} else if ( cv->getMangledTypeName() != cv->getName() ) {
// else if we have a template type where mangled_type_name is different then name.
outfile << " attr" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() << "[" << index << "].offset = offsetof(" ;
outfile << cv->getMangledTypeName() << "," << fdes->getName() << ") ;\n" ;
} else {
// else print an offsetof statement if this is not a special case
outfile << " attr" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() << "[" << index << "].offset = offsetof(" ;
printNamespaces( outfile, cv , "::" ) ;
printContainerClasses( outfile, cv , "::" ) ;
outfile << cv->getMangledTypeName() << "," << fdes->getName() << ") ;\n" ;
}
}
if ( fdes->isSTL()) {

View File

@ -6,11 +6,15 @@
#include <string.h>
#include <iomanip>
#include "llvm/Support/CommandLine.h"
#include "PrintFileContentsBase.hh"
#include "FieldDescription.hh"
#include "ClassValues.hh"
#include "EnumValues.hh"
extern llvm::cl::opt< bool > no_offset_of ;
PrintFileContentsBase::PrintFileContentsBase() {}
// provide empty default implementation of these routines.
@ -74,7 +78,19 @@ void PrintFileContentsBase::print_close_extern_c(std::ofstream & outfile) {
*/
bool PrintFileContentsBase::determinePrintAttr( ClassValues * c , FieldDescription * fdes ) {
if ( fdes->getTypeName().compare("void") and fdes->getIO() != 0 and fdes->getEnumString().compare("TRICK_VOID")) {
if ( fdes->isStatic() ) {
if ( no_offset_of ) {
if ( fdes->isStatic() ) {
if ( fdes->isInherited() ) {
return ((c->getHasInitAttrFriend() && fdes->getAccess() == clang::AS_protected)
|| (fdes->getAccess() == clang::AS_public)) ;
} else {
return (c->getHasInitAttrFriend()
|| (fdes->getAccess() == clang::AS_public)) ;
}
} else {
return true ;
}
} else {
if ( fdes->isInherited() ) {
return ((c->getHasInitAttrFriend() && fdes->getAccess() == clang::AS_protected)
|| (fdes->getAccess() == clang::AS_public)) ;
@ -82,8 +98,6 @@ bool PrintFileContentsBase::determinePrintAttr( ClassValues * c , FieldDescripti
return (c->getHasInitAttrFriend()
|| (fdes->getAccess() == clang::AS_public)) ;
}
} else {
return true ;
}
}
return false ;

View File

@ -43,6 +43,10 @@ llvm::cl::list< std::string > input_file_names(llvm::cl::Positional, llvm::cl::d
llvm::cl::list< std::string > sink(llvm::cl::Sink, llvm::cl::ZeroOrMore) ;
llvm::cl::list< std::string > pre_compiled_headers("include", llvm::cl::Prefix, llvm::cl::desc("pre-compiled headers"),
llvm::cl::value_desc("pre_compiled_headers")) ;
llvm::cl::opt< bool > no_offset_of ("n", llvm::cl::desc("Do not print the offsetof calculations in attributes")) ;
llvm::cl::alias no_offset_of_alias ("no-offset-of" , llvm::cl::desc("Alias for -n") , llvm::cl::aliasopt(no_offset_of)) ;
//llvm::cl::opt< bool > show_units ("u", llvm::cl::desc("List recognized units")) ;
void ICG_version() {