Ignore privacy

Found some of those uncommon cases like inheriting from templates which contain
private embedded classes.

refs #218
This commit is contained in:
Alex Lin 2016-04-13 16:01:59 -05:00
parent 6ea18b425d
commit 54591ec005
5 changed files with 124 additions and 23 deletions

View File

@ -43,6 +43,27 @@ bool ClassTemplateVisitor::TraverseDecl(clang::Decl *d) {
switch ( d->getKind() ) { switch ( d->getKind() ) {
case clang::Decl::CXXRecord : { case clang::Decl::CXXRecord : {
TraverseCXXRecordDecl(static_cast<clang::CXXRecordDecl *>(d)) ; TraverseCXXRecordDecl(static_cast<clang::CXXRecordDecl *>(d)) ;
clang::CXXRecordDecl * crd = static_cast<clang::CXXRecordDecl *>(d) ;
/* The definition of the record must exist before we can process it. The definition is
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 ) {
//d->dump() ;
//std::cout << "access = " << rd->getAccess() << std::endl << std::endl ;
if ( rd->getAccess() == clang::AS_protected || rd->getAccess() == clang::AS_private ) {
// 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()) ;
//std::cout << "marking private " << temp_cv.getFullyQualifiedName() + crd->getNameAsString() << std::endl ;
CXXRecordVisitor::addPrivateEmbeddedClass(temp_cv.getFullyQualifiedName() + crd->getNameAsString()) ;
} else {
TraverseCXXRecordDecl(static_cast<clang::CXXRecordDecl *>(d)) ;
}
}
} }
break ; break ;
case clang::Decl::Enum : { case clang::Decl::Enum : {
@ -54,10 +75,8 @@ bool ClassTemplateVisitor::TraverseDecl(clang::Decl *d) {
} }
EnumVisitor evis(ci, hsd) ; EnumVisitor evis(ci, hsd) ;
evis.TraverseDecl(ed) ; evis.TraverseDecl(ed) ;
//if ( evis.get_enum_data() != NULL ) { evis.get_enum_data()->setHasDefinition(false) ;
evis.get_enum_data()->setHasDefinition(false) ; pa.printEnum(evis.get_enum_data()) ;
pa.printEnum(evis.get_enum_data()) ;
//}
} }
} }

View File

@ -1,6 +1,7 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <stack>
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceManager.h"
@ -307,6 +308,10 @@ ClassValues * CXXRecordVisitor::get_class_data() {
std::set<std::string> CXXRecordVisitor::private_embedded_classes ; std::set<std::string> CXXRecordVisitor::private_embedded_classes ;
void CXXRecordVisitor::addPrivateEmbeddedClass( std::string in_name ) {
private_embedded_classes.insert(in_name) ;
}
bool CXXRecordVisitor::isPrivateEmbeddedClass( std::string in_name ) { bool CXXRecordVisitor::isPrivateEmbeddedClass( std::string in_name ) {
size_t pos ; size_t pos ;
while ((pos = in_name.find("class ")) != std::string::npos ) { while ((pos = in_name.find("class ")) != std::string::npos ) {
@ -315,6 +320,36 @@ bool CXXRecordVisitor::isPrivateEmbeddedClass( std::string in_name ) {
while ((pos = in_name.find("struct ")) != std::string::npos ) { while ((pos = in_name.find("struct ")) != std::string::npos ) {
in_name.erase(pos , 7) ; in_name.erase(pos , 7) ;
} }
while ((pos = in_name.find("const ")) != std::string::npos ) {
in_name.erase(pos , 6) ;
}
// remove any array or pointer dimensions.
if ( in_name.find_first_of("[*") != std::string::npos ) {
in_name.erase(in_name.find_first_of("[*")) ;
}
// remove trailing spaces
in_name.erase(std::find_if(in_name.rbegin(), in_name.rend(),
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), in_name.end());
// remove all template arguments "<text>"
bool template_arg_found ;
do {
template_arg_found = false ;
std::stack<int> bracket_pos ;
for ( int ii = 0 ; ii < in_name.length() ; ii++ ) {
if ( in_name[ii] == '<' ) {
bracket_pos.push(ii) ;
} else if ( in_name[ii] == '>' ) {
int begin = bracket_pos.top() ;
bracket_pos.pop() ;
if ( bracket_pos.empty() ) {
template_arg_found = true ;
in_name.erase(begin, ii - begin + 1) ;
break ;
}
}
}
} while ( template_arg_found == true ) ;
std::set<std::string>::iterator it ; std::set<std::string>::iterator it ;
it = private_embedded_classes.find(in_name) ; it = private_embedded_classes.find(in_name) ;

View File

@ -55,6 +55,7 @@ class CXXRecordVisitor : public clang::RecursiveASTVisitor<CXXRecordVisitor> {
/** Returns the class data */ /** Returns the class data */
ClassValues * get_class_data() ; ClassValues * get_class_data() ;
static void addPrivateEmbeddedClass(std::string in_name) ;
static bool isPrivateEmbeddedClass(std::string in_name) ; static bool isPrivateEmbeddedClass(std::string in_name) ;
private: private:
/** The compiler instance. */ /** The compiler instance. */

View File

@ -343,7 +343,7 @@ static std::map<std::string, bool> init_stl_classes() {
return my_map ; return my_map ;
} }
static bool checkForPRivateTemplateArgs( clang::ClassTemplateSpecializationDecl * ctsd ) { static bool checkForPrivateTemplateArgs( clang::ClassTemplateSpecializationDecl * ctsd ) {
unsigned int ii ; unsigned int ii ;
for ( ii = 0 ; ii < ctsd->getTemplateArgs().size() ; ii++ ) { for ( ii = 0 ; ii < ctsd->getTemplateArgs().size() ; ii++ ) {
const clang::TemplateArgument & ta = ctsd->getTemplateArgs().get(ii) ; const clang::TemplateArgument & ta = ctsd->getTemplateArgs().get(ii) ;
@ -362,7 +362,7 @@ static bool checkForPRivateTemplateArgs( clang::ClassTemplateSpecializationDecl
if ( clang::isa<clang::ClassTemplateSpecializationDecl>(crd) ) { if ( clang::isa<clang::ClassTemplateSpecializationDecl>(crd) ) {
clang::ClassTemplateSpecializationDecl * inner_ctsd ; clang::ClassTemplateSpecializationDecl * inner_ctsd ;
inner_ctsd = clang::cast<clang::ClassTemplateSpecializationDecl>(crd) ; inner_ctsd = clang::cast<clang::ClassTemplateSpecializationDecl>(crd) ;
return checkForPRivateTemplateArgs(inner_ctsd) ; return checkForPrivateTemplateArgs(inner_ctsd) ;
} }
} }
} }
@ -416,24 +416,26 @@ bool FieldVisitor::VisitRecordType(clang::RecordType *rt) {
if (!tst_string.compare( 0 , (*it).first.size() , (*it).first)) { if (!tst_string.compare( 0 , (*it).first.size() , (*it).first)) {
clang::RecordDecl * rd = rt->getDecl()->getDefinition() ; clang::RecordDecl * rd = rt->getDecl()->getDefinition() ;
clang::ClassTemplateSpecializationDecl * ctsd ; if ( rd != NULL and clang::ClassTemplateSpecializationDecl::classof(rd) ) {
ctsd = clang::cast<clang::ClassTemplateSpecializationDecl>(rd) ; clang::ClassTemplateSpecializationDecl * ctsd ;
ctsd = clang::cast<clang::ClassTemplateSpecializationDecl>(rd) ;
// If a private embedded class is in an STL the resulting io_src code will not compile. // 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. // Search the template arguments for private embedded classes, if found remove io capabilites.
if ( checkForPRivateTemplateArgs( ctsd )) { if ( checkForPrivateTemplateArgs( ctsd )) {
fdes->setIO(0) ; fdes->setIO(0) ;
}
fdes->setEnumString("TRICK_STL") ;
fdes->setSTL(true) ;
fdes->setTypeName(tst_string) ;
fdes->setSTLClear((*it).second) ;
// set the type name to the non canonical name, the name the user put in the header file
// The typename is not used by STL variables, and it is nice to see the type that was
// actually inputted by the user
fdes->setMangledTypeName(fdes->getNonCanonicalTypeName()) ;
return false ;
} }
fdes->setEnumString("TRICK_STL") ;
fdes->setSTL(true) ;
fdes->setTypeName(tst_string) ;
fdes->setSTLClear((*it).second) ;
// set the type name to the non canonical name, the name the user put in the header file
// The typename is not used by STL variables, and it is nice to see the type that was
// actually inputted by the user
fdes->setMangledTypeName(fdes->getNonCanonicalTypeName()) ;
return false ;
} }
} }
// If the record type is in std:: but not one we can process, set the I/O spec to zero and return. // If the record type is in std:: but not one we can process, set the I/O spec to zero and return.
@ -446,7 +448,7 @@ bool FieldVisitor::VisitRecordType(clang::RecordType *rt) {
If so process the template type and return */ If so process the template type and return */
clang::RecordDecl * rd = rt->getDecl()->getDefinition() ; clang::RecordDecl * rd = rt->getDecl()->getDefinition() ;
if ( rd != NULL and clang::ClassTemplateSpecializationDecl::classof(rd) ) { if ( rd != NULL and clang::ClassTemplateSpecializationDecl::classof(rd) ) {
if ( checkForPRivateTemplateArgs( clang::cast<clang::ClassTemplateSpecializationDecl>(rd)) ) { if ( checkForPrivateTemplateArgs( clang::cast<clang::ClassTemplateSpecializationDecl>(rd)) ) {
fdes->setIO(0) ; fdes->setIO(0) ;
if ( debug_level >= 3 ) { if ( debug_level >= 3 ) {
std::cout << " template using private/protected class as argument, not processing" << std::endl ; std::cout << " template using private/protected class as argument, not processing" << std::endl ;
@ -492,6 +494,7 @@ bool FieldVisitor::VisitRecordType(clang::RecordType *rt) {
} }
bool FieldVisitor::VisitVarDecl( clang::VarDecl *v ) { bool FieldVisitor::VisitVarDecl( clang::VarDecl *v ) {
fdes->setStatic(v->isStaticDataMember()) ; fdes->setStatic(v->isStaticDataMember()) ;
/* If we have a static const integer type with an initializer value, this variable will /* If we have a static const integer type with an initializer value, this variable will
not be instantiated by the compiler. The compiler substitutes in the value internally. not be instantiated by the compiler. The compiler substitutes in the value internally.
@ -501,6 +504,7 @@ bool FieldVisitor::VisitVarDecl( clang::VarDecl *v ) {
v->getType().isConstQualified() and v->getType().isConstQualified() and
v->hasInit() ) { v->hasInit() ) {
fdes->setIO(0) ; fdes->setIO(0) ;
return false ;
} else if ( v->isStaticDataMember() and } else if ( v->isStaticDataMember() and
v->getType().isConstQualified() ) { v->getType().isConstQualified() ) {
/* Static const members cannot be set through attributes code. Remove input /* Static const members cannot be set through attributes code. Remove input
@ -515,6 +519,24 @@ bool FieldVisitor::VisitVarDecl( clang::VarDecl *v ) {
std::cout << " IO = " << fdes->getIO() << std::endl ; std::cout << " IO = " << fdes->getIO() << std::endl ;
//v->dump() ; std::cout << std::endl ; //v->dump() ; std::cout << std::endl ;
} }
clang::QualType qt = v->getType() ;
// 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() ;
std::string tst_string = ct.getAsString() ;
if ( debug_level >= 3 ) {
std::cout << "\033[33mFieldVisitor VisitVarDecl: Processing canonical type\033[00m" << std::endl ;
ct.dump() ;
}
TraverseType(ct) ;
// We have extracted the canonical type and everything else we need
// return false so we cut off processing of this AST branch
return false ;
}
return true ; return true ;
} }

View File

@ -167,6 +167,8 @@ void PrintFileContents10::print_field_init_attr_stmts( std::ofstream & outfile ,
printNamespaces( outfile, cv , "__" ) ; printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ; printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() << "[" << index << "].checkpoint_stl = checkpoint_stl_" ; outfile << cv->getMangledTypeName() << "[" << index << "].checkpoint_stl = checkpoint_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ; outfile << cv->getMangledTypeName() ;
outfile << "_" ; outfile << "_" ;
outfile << fdes->getName() ; outfile << fdes->getName() ;
@ -176,6 +178,8 @@ void PrintFileContents10::print_field_init_attr_stmts( std::ofstream & outfile ,
printNamespaces( outfile, cv , "__" ) ; printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ; printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() << "[" << index << "].post_checkpoint_stl = post_checkpoint_stl_" ; outfile << cv->getMangledTypeName() << "[" << index << "].post_checkpoint_stl = post_checkpoint_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ; outfile << cv->getMangledTypeName() ;
outfile << "_" ; outfile << "_" ;
outfile << fdes->getName() ; outfile << fdes->getName() ;
@ -185,6 +189,8 @@ void PrintFileContents10::print_field_init_attr_stmts( std::ofstream & outfile ,
printNamespaces( outfile, cv , "__" ) ; printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ; printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() << "[" << index << "].restore_stl = restore_stl_" ; outfile << cv->getMangledTypeName() << "[" << index << "].restore_stl = restore_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ; outfile << cv->getMangledTypeName() ;
outfile << "_" ; outfile << "_" ;
outfile << fdes->getName() ; outfile << fdes->getName() ;
@ -195,6 +201,8 @@ void PrintFileContents10::print_field_init_attr_stmts( std::ofstream & outfile ,
printNamespaces( outfile, cv , "__" ) ; printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ; printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() << "[" << index << "].clear_stl = clear_stl_" ; outfile << cv->getMangledTypeName() << "[" << index << "].clear_stl = clear_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ; outfile << cv->getMangledTypeName() ;
outfile << "_" ; outfile << "_" ;
outfile << fdes->getName() ; outfile << fdes->getName() ;
@ -438,18 +446,24 @@ void PrintFileContents10::print_stl_helper_proto(std::ofstream & outfile , Class
for ( fit = cv->field_begin() ; fit != cv->field_end() ; fit++ ) { for ( fit = cv->field_begin() ; fit != cv->field_end() ; fit++ ) {
if ( (*fit)->isSTL() and determinePrintAttr(cv , *fit) ) { if ( (*fit)->isSTL() and determinePrintAttr(cv , *fit) ) {
outfile << "void checkpoint_stl_" ; outfile << "void checkpoint_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ; outfile << cv->getMangledTypeName() ;
outfile << "_" ; outfile << "_" ;
outfile << (*fit)->getName() ; outfile << (*fit)->getName() ;
outfile << "(void * start_address, const char * obj_name , const char * var_name) ;" << std::endl ; outfile << "(void * start_address, const char * obj_name , const char * var_name) ;" << std::endl ;
outfile << "void post_checkpoint_stl_" ; outfile << "void post_checkpoint_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ; outfile << cv->getMangledTypeName() ;
outfile << "_" ; outfile << "_" ;
outfile << (*fit)->getName() ; outfile << (*fit)->getName() ;
outfile << "(void * start_address, const char * obj_name , const char * var_name) ;" << std::endl ; outfile << "(void * start_address, const char * obj_name , const char * var_name) ;" << std::endl ;
outfile << "void restore_stl_" ; outfile << "void restore_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ; outfile << cv->getMangledTypeName() ;
outfile << "_" ; outfile << "_" ;
outfile << (*fit)->getName() ; outfile << (*fit)->getName() ;
@ -457,6 +471,8 @@ void PrintFileContents10::print_stl_helper_proto(std::ofstream & outfile , Class
if ((*fit)->hasSTLClear()) { if ((*fit)->hasSTLClear()) {
outfile << "void clear_stl_" ; outfile << "void clear_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ; outfile << cv->getMangledTypeName() ;
outfile << "_" ; outfile << "_" ;
outfile << (*fit)->getName() ; outfile << (*fit)->getName() ;
@ -469,6 +485,8 @@ void PrintFileContents10::print_stl_helper_proto(std::ofstream & outfile , Class
void PrintFileContents10::print_checkpoint_stl(std::ofstream & outfile , FieldDescription * fdes , ClassValues * cv ) { void PrintFileContents10::print_checkpoint_stl(std::ofstream & outfile , FieldDescription * fdes , ClassValues * cv ) {
outfile << "void checkpoint_stl_" ; outfile << "void checkpoint_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ; outfile << cv->getMangledTypeName() ;
outfile << "_" ; outfile << "_" ;
outfile << fdes->getName() ; outfile << fdes->getName() ;
@ -482,6 +500,8 @@ void PrintFileContents10::print_checkpoint_stl(std::ofstream & outfile , FieldDe
void PrintFileContents10::print_post_checkpoint_stl(std::ofstream & outfile , FieldDescription * fdes , ClassValues * cv ) { void PrintFileContents10::print_post_checkpoint_stl(std::ofstream & outfile , FieldDescription * fdes , ClassValues * cv ) {
outfile << "void post_checkpoint_stl_" ; outfile << "void post_checkpoint_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ; outfile << cv->getMangledTypeName() ;
outfile << "_" ; outfile << "_" ;
outfile << fdes->getName() ; outfile << fdes->getName() ;
@ -495,6 +515,8 @@ void PrintFileContents10::print_post_checkpoint_stl(std::ofstream & outfile , Fi
void PrintFileContents10::print_restore_stl(std::ofstream & outfile , FieldDescription * fdes , ClassValues * cv ) { void PrintFileContents10::print_restore_stl(std::ofstream & outfile , FieldDescription * fdes , ClassValues * cv ) {
outfile << "void restore_stl_" ; outfile << "void restore_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ; outfile << cv->getMangledTypeName() ;
outfile << "_" ; outfile << "_" ;
outfile << fdes->getName() ; outfile << fdes->getName() ;
@ -508,6 +530,8 @@ void PrintFileContents10::print_restore_stl(std::ofstream & outfile , FieldDescr
void PrintFileContents10::print_clear_stl(std::ofstream & outfile , FieldDescription * fdes , ClassValues * cv ) { void PrintFileContents10::print_clear_stl(std::ofstream & outfile , FieldDescription * fdes , ClassValues * cv ) {
outfile << "void clear_stl_" ; outfile << "void clear_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ; outfile << cv->getMangledTypeName() ;
outfile << "_" ; outfile << "_" ;
outfile << fdes->getName() ; outfile << fdes->getName() ;