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() ) {
case clang::Decl::CXXRecord : {
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 ;
case clang::Decl::Enum : {
@ -54,10 +75,8 @@ bool ClassTemplateVisitor::TraverseDecl(clang::Decl *d) {
}
EnumVisitor evis(ci, hsd) ;
evis.TraverseDecl(ed) ;
//if ( evis.get_enum_data() != NULL ) {
evis.get_enum_data()->setHasDefinition(false) ;
pa.printEnum(evis.get_enum_data()) ;
//}
evis.get_enum_data()->setHasDefinition(false) ;
pa.printEnum(evis.get_enum_data()) ;
}
}

View File

@ -1,6 +1,7 @@
#include <iostream>
#include <sstream>
#include <stack>
#include "llvm/Support/CommandLine.h"
#include "clang/Basic/SourceManager.h"
@ -307,6 +308,10 @@ ClassValues * CXXRecordVisitor::get_class_data() {
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 ) {
size_t pos ;
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 ) {
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 ;
it = private_embedded_classes.find(in_name) ;

View File

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

View File

@ -343,7 +343,7 @@ static std::map<std::string, bool> init_stl_classes() {
return my_map ;
}
static bool checkForPRivateTemplateArgs( clang::ClassTemplateSpecializationDecl * ctsd ) {
static bool checkForPrivateTemplateArgs( clang::ClassTemplateSpecializationDecl * ctsd ) {
unsigned int ii ;
for ( ii = 0 ; ii < ctsd->getTemplateArgs().size() ; ii++ ) {
const clang::TemplateArgument & ta = ctsd->getTemplateArgs().get(ii) ;
@ -362,7 +362,7 @@ static bool checkForPRivateTemplateArgs( clang::ClassTemplateSpecializationDecl
if ( clang::isa<clang::ClassTemplateSpecializationDecl>(crd) ) {
clang::ClassTemplateSpecializationDecl * inner_ctsd ;
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)) {
clang::RecordDecl * rd = rt->getDecl()->getDefinition() ;
clang::ClassTemplateSpecializationDecl * ctsd ;
ctsd = clang::cast<clang::ClassTemplateSpecializationDecl>(rd) ;
if ( rd != NULL and clang::ClassTemplateSpecializationDecl::classof(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.
// Search the template arguments for private embedded classes, if found remove io capabilites.
if ( checkForPRivateTemplateArgs( ctsd )) {
fdes->setIO(0) ;
// 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.
if ( checkForPrivateTemplateArgs( ctsd )) {
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.
@ -446,7 +448,7 @@ bool FieldVisitor::VisitRecordType(clang::RecordType *rt) {
If so process the template type and return */
clang::RecordDecl * rd = rt->getDecl()->getDefinition() ;
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) ;
if ( debug_level >= 3 ) {
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 ) {
fdes->setStatic(v->isStaticDataMember()) ;
/* 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.
@ -501,6 +504,7 @@ bool FieldVisitor::VisitVarDecl( clang::VarDecl *v ) {
v->getType().isConstQualified() and
v->hasInit() ) {
fdes->setIO(0) ;
return false ;
} else if ( v->isStaticDataMember() and
v->getType().isConstQualified() ) {
/* 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 ;
//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 ;
}

View File

@ -167,6 +167,8 @@ void PrintFileContents10::print_field_init_attr_stmts( std::ofstream & outfile ,
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() << "[" << index << "].checkpoint_stl = checkpoint_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ;
outfile << "_" ;
outfile << fdes->getName() ;
@ -176,6 +178,8 @@ void PrintFileContents10::print_field_init_attr_stmts( std::ofstream & outfile ,
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() << "[" << index << "].post_checkpoint_stl = post_checkpoint_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ;
outfile << "_" ;
outfile << fdes->getName() ;
@ -185,6 +189,8 @@ void PrintFileContents10::print_field_init_attr_stmts( std::ofstream & outfile ,
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() << "[" << index << "].restore_stl = restore_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ;
outfile << "_" ;
outfile << fdes->getName() ;
@ -195,6 +201,8 @@ void PrintFileContents10::print_field_init_attr_stmts( std::ofstream & outfile ,
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() << "[" << index << "].clear_stl = clear_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ;
outfile << "_" ;
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++ ) {
if ( (*fit)->isSTL() and determinePrintAttr(cv , *fit) ) {
outfile << "void checkpoint_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ;
outfile << "_" ;
outfile << (*fit)->getName() ;
outfile << "(void * start_address, const char * obj_name , const char * var_name) ;" << std::endl ;
outfile << "void post_checkpoint_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ;
outfile << "_" ;
outfile << (*fit)->getName() ;
outfile << "(void * start_address, const char * obj_name , const char * var_name) ;" << std::endl ;
outfile << "void restore_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ;
outfile << "_" ;
outfile << (*fit)->getName() ;
@ -457,6 +471,8 @@ void PrintFileContents10::print_stl_helper_proto(std::ofstream & outfile , Class
if ((*fit)->hasSTLClear()) {
outfile << "void clear_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ;
outfile << "_" ;
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 ) {
outfile << "void checkpoint_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ;
outfile << "_" ;
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 ) {
outfile << "void post_checkpoint_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ;
outfile << "_" ;
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 ) {
outfile << "void restore_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ;
outfile << "_" ;
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 ) {
outfile << "void clear_stl_" ;
printNamespaces( outfile, cv , "__" ) ;
printContainerClasses( outfile, cv , "__" ) ;
outfile << cv->getMangledTypeName() ;
outfile << "_" ;
outfile << fdes->getName() ;