Ignore privacy

Moved field offset calculations for inherited classes to when the inherited
classes are processed.  This removes the need to have to remember if fields
were inherited or not, the offset already reflects the correct offset.

refs #218
This commit is contained in:
Alex Lin 2016-04-06 12:06:14 -05:00
parent 7dcc65d0bd
commit 4dad11bf45
11 changed files with 46 additions and 118 deletions

View File

@ -12,8 +12,7 @@ ClassValues::ClassValues(bool in_inherit, bool in_virtual_inherit) :
is_pod(false) ,
is_abstract(false) ,
has_default_constructor(false) ,
has_public_destructor(false) ,
invade_privacy(false)
has_public_destructor(false)
{}
ClassValues::~ClassValues() {
@ -50,18 +49,19 @@ void ClassValues::addFieldDescription(FieldDescription * in_fdes) {
field_name_to_info_map[in_fdes->getName()] = in_fdes ;
}
void ClassValues::addInheritedFieldDescriptions(std::vector<FieldDescription *> in_fdes) {
void ClassValues::addInheritedFieldDescriptions(std::vector<FieldDescription *> in_fdes, unsigned int class_offset ) {
// Make a copy of all of the FieldDescription variables.
field_descripts.insert(field_descripts.end(), in_fdes.begin() , in_fdes.end()) ;
// This section creates code that clang on the Mac cannot compile.
// So, we cannot handle overloaded names on the Mac.
#ifndef __APPLE__
std::vector<FieldDescription *>::iterator fdit ;
// Loop through the incoming inherited variable names
for ( fdit = in_fdes.begin() ; fdit != in_fdes.end() ; fdit++ ) {
std::string in_name = (*fdit)->getName() ;
(*fdit)->addOffset( class_offset ) ;
#ifndef __APPLE__
std::string in_name = (*fdit)->getName() ;
// search existing names for incoming inherited variable name.
std::map< std::string , FieldDescription * >::iterator mit = field_name_to_info_map.find(in_name) ;
// if the variable name already exists we have overloaded variable names.
@ -92,8 +92,8 @@ void ClassValues::addInheritedFieldDescriptions(std::vector<FieldDescription *>
field_name_to_info_map[(*fdit)->getName()] = *fdit ;
}
}
}
#endif
}
}
@ -234,14 +234,6 @@ bool ClassValues::getHasPublicDestructor() {
return has_public_destructor ;
}
void ClassValues::setInvadePrivacy(bool in_val) {
invade_privacy = in_val ;
}
bool ClassValues::getInvadePrivacy() {
return invade_privacy ;
}
void ClassValues::setMangledTypeName( std::string in_val ) {
mangled_type_name = in_val ;
}

View File

@ -36,7 +36,7 @@ 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 *>) ;
void addInheritedFieldDescriptions(std::vector<FieldDescription *>, unsigned int class_offset) ;
/** Gets the list of fields in this class */
std::vector<FieldDescription *> getFieldDescription() ;
@ -119,9 +119,6 @@ class ClassValues : public ConstructValues {
/** Does this class have a public destructor? */
bool has_public_destructor ;
/** Should we invade privacy and write attributes for everything we can? */
bool invade_privacy ;
/** Mangled type name. Templates will have a mangled_type_name. */
std::string mangled_type_name ;
} ;

View File

@ -24,18 +24,13 @@ CXXRecordVisitor::CXXRecordVisitor(
PrintAttributes & in_pa ,
bool in_inherited ,
bool in_virtual_inherited ,
bool in_include_virtual_base ,
unsigned int in_base_class_offset) :
bool in_include_virtual_base ) :
ci(in_ci) ,
cs(in_cs) ,
hsd(in_hsd) ,
pa(in_pa) ,
cval(in_inherited , in_virtual_inherited) ,
include_virtual_base(in_include_virtual_base) ,
base_class_offset(in_base_class_offset)
{
//cval = new ClassValues(in_inherited , in_virtual_inherited) ;
}
include_virtual_base(in_include_virtual_base) {}
CXXRecordVisitor::~CXXRecordVisitor() {
}
@ -81,7 +76,7 @@ bool CXXRecordVisitor::TraverseDecl(clang::Decl *d) {
}
break ;
case clang::Decl::Field : {
FieldVisitor fvis(ci , hsd , cs, pa, cval.getName() , cval.isInherited(), cval.isVirtualInherited(), base_class_offset) ;
FieldVisitor fvis(ci , hsd , cs, pa, cval.getName() , cval.isInherited() ) ;
fvis.TraverseFieldDecl(static_cast<clang::FieldDecl *>(d)) ;
cval.addFieldDescription(fvis.get_field_data()) ;
}
@ -92,7 +87,7 @@ bool CXXRecordVisitor::TraverseDecl(clang::Decl *d) {
break ;
case clang::Decl::Var : {
/* Static fields appear as vars. Treat it as a field. */
FieldVisitor fvis(ci , hsd , cs, pa, cval.getName() , cval.isInherited(), cval.isVirtualInherited(), base_class_offset) ;
FieldVisitor fvis(ci , hsd , cs, pa, cval.getName() , cval.isInherited() ) ;
fvis.TraverseVarDecl(static_cast<clang::VarDecl *>(d)) ;
cval.addFieldDescription(fvis.get_field_data()) ;
}
@ -182,9 +177,9 @@ bool CXXRecordVisitor::VisitCXXRecordDecl( clang::CXXRecordDecl *rec ) {
inherit_class_offset = record_layout.getBaseClassOffset(llvm::cast<clang::CXXRecordDecl>(rd)).getQuantity() ;
//std::cout << " inherit_class_offset = " << inherit_class_offset << "" << std::endl ;
//std::cout << " " << getFileName(ci , rd->getRBraceLoc(), hsd) << "" << std::endl ;
CXXRecordVisitor inherit_cvis(ci , cs, hsd , pa, true, bcii->isVirtual(), false, inherit_class_offset) ;
CXXRecordVisitor inherit_cvis(ci , cs, hsd , pa, true, bcii->isVirtual(), false) ;
inherit_cvis.TraverseCXXRecordDecl(static_cast<clang::CXXRecordDecl *>(rd)) ;
cval.addInheritedFieldDescriptions(inherit_cvis.get_class_data()->getFieldDescription()) ;
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
@ -227,9 +222,9 @@ bool CXXRecordVisitor::VisitCXXRecordDecl( clang::CXXRecordDecl *rec ) {
//std::cout << " inherit_class_offset = " << inherit_class_offset << "" << std::endl ;
//std::cout << " " << getFileName(ci , rd->getRBraceLoc(), hsd) << "" << std::endl ;
CXXRecordVisitor inherit_cvis(ci , cs, hsd , pa, true, bcii->isVirtual(), false, inherit_class_offset) ;
CXXRecordVisitor inherit_cvis(ci , cs, hsd , pa, true, bcii->isVirtual(), false) ;
inherit_cvis.TraverseCXXRecordDecl(static_cast<clang::CXXRecordDecl *>(rd)) ;
cval.addInheritedFieldDescriptions(inherit_cvis.get_class_data()->getFieldDescription()) ;
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

View File

@ -40,8 +40,7 @@ class CXXRecordVisitor : public clang::RecursiveASTVisitor<CXXRecordVisitor> {
PrintAttributes & in_pa ,
bool in_inherited ,
bool in_virtual_inherited ,
bool in_include_virtual_base ,
unsigned int in_base_class_offset = 0 ) ;
bool in_include_virtual_base ) ;
~CXXRecordVisitor() ;
@ -75,9 +74,6 @@ class CXXRecordVisitor : public clang::RecursiveASTVisitor<CXXRecordVisitor> {
/** Holds the class information found, usually returned to caller of this visitor. */
ClassValues cval ;
/** For inherited classes this is how many bytes into the derived class we are offset */
unsigned int base_class_offset ;
/** Flag to specify if we should process virtual base classes. */
bool include_virtual_base ;

View File

@ -84,7 +84,6 @@ void CommentSaver::getICGField( std::string file_name ) {
/* default the icg_no flags to false */
icg_no_found[file_name] = false ;
icg_no_comment_found[file_name] = false ;
invade_privacy[file_name] = false ;
std::string th_str = getTrickHeaderComment(file_name) ;
if ( ! th_str.empty() ) {
@ -114,10 +113,6 @@ void CommentSaver::getICGField( std::string file_name ) {
exit(-1) ;
}
}
size_t trick_parse_invade_privacy = th_str.find("trick_invade_privacy") ;
if ( trick_parse_invade_privacy != std::string::npos ) {
invade_privacy[file_name] = true ;
}
} else {
std::transform(th_str.begin(), th_str.end(), th_str.begin(), ::toupper) ;
@ -126,14 +121,6 @@ void CommentSaver::getICGField( std::string file_name ) {
regmatch_t pmatch[10] ;
memset(pmatch , 0 , sizeof(pmatch)) ;
ret = regcomp( &reg_expr , "(INVADE[ _]PRIVACY:)" , REG_EXTENDED | REG_ICASE ) ;
ret = regexec( &reg_expr , th_str.c_str() , 10 , pmatch , 0 ) ;
regfree(&reg_expr) ;
if ( ret == 0 ) {
invade_privacy[file_name] = true ;
}
/* POSIX regular expressions are always greedy, making our job harder.
We have to use several regular expressions to get the types. This was
so much easier in perl! */
@ -206,15 +193,6 @@ bool CommentSaver::hasICGNoComment( std::string file_name ) {
return icg_no_comment_found[file_name] ;
}
bool CommentSaver::hasInvadePrivacy( std::string file_name ) {
if ( invade_privacy.find(file_name) == invade_privacy.end() ) {
getICGField(file_name) ;
}
return invade_privacy[file_name] ;
}
std::set< std::string > CommentSaver::getIgnoreTypes( std::string file_name ) {
std::set< std::string > ignore_types ;
std::string th_str = getTrickHeaderComment(file_name) ;

View File

@ -77,12 +77,6 @@ class CommentSaver : public clang::CommentHandler {
*/
bool hasICGNoComment( std::string file_name ) ;
/** Searches the Trick header comment for the Invade_Privacy:() entry.
@param file_name = File name to search
@return true = ICG:(NoComment) was found.
*/
bool hasInvadePrivacy( std::string file_name ) ;
/** Searches the Trick header comment for the ICG_EXCLUDE_TYPES field
@param file_name = File name to search
@return set of strings that list the type names to ignore.
@ -101,9 +95,6 @@ class CommentSaver : public clang::CommentHandler {
/** Map of file name to ICG: (NoComment) found */
std::map < std::string , bool > icg_no_comment_found ;
/** Map of file name to ICG: (NoComment) found */
std::map < std::string , bool > invade_privacy ;
/** All comments source locations indexed by file name then line number */
std::map < std::string , std::map < unsigned int , clang::SourceRange > > comment_map ;

View File

@ -16,15 +16,11 @@
FieldDescription::FieldDescription(
std::string in_container_class ,
bool in_inherited ,
bool in_virtual_inherited ,
unsigned int in_base_class_offset) :
bool in_inherited ) :
container_class(in_container_class) ,
base_class_offset(in_base_class_offset) ,
field_offset(0) ,
field_width(0) ,
inherited(in_inherited) ,
virtual_inherited(in_virtual_inherited) ,
units("--") ,
line_no(0) ,
io(3) ,
@ -247,12 +243,11 @@ void FieldDescription::setContainerClass(std::string in_name ) {
container_class = in_name ;
}
unsigned int FieldDescription::getBaseClassOffset() {
return base_class_offset ;
}
void FieldDescription::setFieldOffset(unsigned int in_offset) {
field_offset = in_offset ;
if ( is_bitfield ) {
calcBitfieldOffset() ;
}
}
unsigned int FieldDescription::getFieldOffset() {
@ -322,10 +317,6 @@ bool FieldDescription::isInherited() {
return inherited ;
}
bool FieldDescription::isVirtualInherited() {
return virtual_inherited ;
}
void FieldDescription::setAccess( clang::AccessSpecifier in_val ) {
access = in_val ;
}
@ -334,6 +325,19 @@ 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) {
type_enum_string = in_str ;
}
@ -354,14 +358,6 @@ void FieldDescription::setBitFieldWidth(unsigned int len) {
bitfield_width = len ;
}
void FieldDescription::setBitFieldStart(unsigned int sb) {
bitfield_start_bit = sb ;
}
void FieldDescription::setBitFieldByteOffset(unsigned int wo) {
bitfield_word_offset = wo ;
}
unsigned int FieldDescription::getBitFieldWidth() {
return bitfield_width ;
}

View File

@ -29,11 +29,7 @@ class FieldDescription : public ConstructValues {
public:
/* Default the inheritance to false */
FieldDescription(
std::string in_container_class ,
bool inherited ,
bool virtual_inherited ,
unsigned int base_class_offset ) ;
FieldDescription( std::string in_container_class , bool inherited ) ;
/* Extracts units and io code from a comment */
void parseComment(std::string) ;
@ -62,8 +58,6 @@ class FieldDescription : public ConstructValues {
std::string getEnumString() ;
void setBitField( bool yes_no ) ;
void setBitFieldWidth( unsigned int len ) ;
void setBitFieldStart( unsigned int len ) ;
void setBitFieldByteOffset( unsigned int len ) ;
unsigned int getBitFieldWidth() ;
unsigned int getBitFieldStart() ;
unsigned int getBitFieldByteOffset() ;
@ -82,9 +76,10 @@ class FieldDescription : public ConstructValues {
void setStatic( bool yes_no ) ;
bool isStatic() ;
bool isInherited() ;
bool isVirtualInherited() ;
void setAccess( clang::AccessSpecifier in_val ) ;
clang::AccessSpecifier getAccess() ;
void calcBitfieldOffset() ;
void addOffset( unsigned int offset ) ;
/** Adds an array dimension to the field */
void addArrayDim( int in_dim ) ;
@ -99,10 +94,6 @@ 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 bytes */
unsigned int field_offset ;
@ -118,7 +109,6 @@ class FieldDescription : public ConstructValues {
/** Name of the type */
std::string mangled_type_name ;
/** String representing the type enumeration */
std::string type_enum_string ;
@ -155,9 +145,6 @@ 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

@ -22,14 +22,12 @@ FieldVisitor::FieldVisitor(clang::CompilerInstance & in_ci ,
CommentSaver & in_cs ,
PrintAttributes & in_pa ,
std::string container_class ,
bool in_inherited ,
bool in_virtual_inherited ,
unsigned int in_base_class_offset ) :
bool in_inherited ) :
ci(in_ci) ,
hsd(in_hsd) ,
cs(in_cs) ,
pa(in_pa) {
fdes = new FieldDescription(container_class, in_inherited, in_virtual_inherited, in_base_class_offset) ;
fdes = new FieldDescription(container_class, in_inherited ) ;
}
bool FieldVisitor::VisitDecl(clang::Decl *d) {
@ -198,15 +196,15 @@ 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) ;
fdes->setBitField(field->isBitField()) ;
if ( fdes->isBitField() ) {
fdes->setBitFieldWidth(field->getBitWidthValue(field->getASTContext())) ;
unsigned int field_offset_bits = field->getASTContext().getFieldOffset(field) + fdes->getBaseClassOffset() * 8 ;
fdes->setBitFieldStart( 32 - (field_offset_bits % 32) - fdes->getBitFieldWidth()) ;
fdes->setBitFieldByteOffset((field_offset_bits / 32) * 4 ) ;
fdes->calcBitfieldOffset() ;
}
// set the offset to the field
fdes->setFieldOffset(field->getASTContext().getFieldOffset(field) / 8 + fdes->getBaseClassOffset()) ;
// If the current type is not canonical because of typedefs or template parameter substitution,
// traverse the canonical type
@ -373,7 +371,7 @@ bool FieldVisitor::VisitRecordType(clang::RecordType *rt) {
}
// NOTE: clang also changes FILE * to struct _SFILE *. We may need to change that too.
// Test if we have some type from std.
// Test if we have some type from STL.
if (!tst_string.compare( 0 , 5 , "std::")) {
// If we have some type from std, figure out if it is one we support.
for ( std::map<std::string, bool>::iterator it = stl_classes.begin() ; it != stl_classes.end() ; it++ ) {

View File

@ -32,9 +32,7 @@ class FieldVisitor : public clang::RecursiveASTVisitor<FieldVisitor> {
CommentSaver & cs ,
PrintAttributes & in_pa ,
std::string container_class ,
bool inherited ,
bool virtual_inherited ,
unsigned int base_class_offset ) ;
bool inherited ) ;
/* VisitDecl and VisitType are here for debug printing. */
bool VisitDecl(clang::Decl *d) ;

View File

@ -129,7 +129,7 @@ void PrintFileContents10::print_class_attr(std::ofstream & outfile , ClassValues
}
}
// Print an empty sentinel attribute at the end of the class.
FieldDescription * new_fdes = new FieldDescription(std::string(""), false, false, 0) ;
FieldDescription * new_fdes = new FieldDescription(std::string(""), false) ;
print_field_attr(outfile, new_fdes) ;
outfile << " };" << std::endl ;
delete new_fdes ;