mirror of
https://github.com/nasa/trick.git
synced 2025-03-11 06:54:12 +00:00
ICG produces non-compilable io_* code for this weird example #334
When saving the list of namespaces and classes a particular type is contained in we have to save the class name and any template args it includes separately. This allows us to mangle the names easier. And we now search for type names to see if they follow this pattern template_name<template_args>::embedded_class. If we are using a template embedded class we need to create attributes for the embedded class.
This commit is contained in:
parent
8ad462cd1c
commit
d875f837f2
@ -280,14 +280,10 @@ std::ostream & operator << (std::ostream & ostream, ClassValues & cv) {
|
||||
ostream << " mangled_name = " << cv.mangled_type_name << std::endl ;
|
||||
ostream << " file_name = " << cv.file_name << std::endl ;
|
||||
ostream << " namespaces =" ;
|
||||
for (auto& name : cv.getNamespaces()) {
|
||||
ostream << " " << name ;
|
||||
}
|
||||
cv.printNamespaces(ostream) ;
|
||||
ostream << std::endl ;
|
||||
ostream << " parent classes =" ;
|
||||
for (auto& clazz : cv.getContainerClasses()) {
|
||||
ostream << " " << clazz ;
|
||||
}
|
||||
cv.printContainerClasses(ostream) ;
|
||||
ostream << std::endl ;
|
||||
ostream << " has_init_attr_friend = " << cv.has_init_attr_friend << std::endl ;
|
||||
ostream << " is_pod = " << cv.is_pod << std::endl ;
|
||||
|
@ -161,6 +161,11 @@ bool CXXRecordVisitor::VisitCXXRecordDecl( clang::CXXRecordDecl *rec ) {
|
||||
cval.setCompat15(hsd.isPathInCompat15(rp)) ;
|
||||
free(rp) ;
|
||||
|
||||
// If we have trouble determining the containing namespace and classes skip this variable.
|
||||
if ( !cval.getNamespacesAndClasses(rec->getDeclContext())) {
|
||||
return false ;
|
||||
}
|
||||
|
||||
// If this class needs a default constructor, then the complier will generate one and we can call it.
|
||||
if ( rec->needsImplicitDefaultConstructor() ) {
|
||||
cval.setHasDefaultConstructor(true) ;
|
||||
@ -187,10 +192,10 @@ bool CXXRecordVisitor::VisitCXXRecordDecl( clang::CXXRecordDecl *rec ) {
|
||||
|
||||
cval.setSize(rec->getASTContext().getASTRecordLayout(rec).getSize().getQuantity()) ;
|
||||
|
||||
clang::CXXRecordDecl::base_class_iterator bcii ;
|
||||
|
||||
//std::cout << "parsing " << cval.getName() << std::endl ;
|
||||
//std::cout << " [34mprocessing inheritance " << rec->getNumBases() << " " << rec->getNumVBases() << "[00m" << std::endl ;
|
||||
clang::CXXRecordDecl::base_class_iterator bcii ;
|
||||
for ( bcii = rec->bases_begin() ; bcii != rec->bases_end() ; bcii++ ) {
|
||||
if ( !bcii->isVirtual() ) {
|
||||
const clang::Type * temp = bcii->getType().getTypePtr() ;
|
||||
@ -279,8 +284,6 @@ bool CXXRecordVisitor::VisitCXXRecordDecl( clang::CXXRecordDecl *rec ) {
|
||||
}
|
||||
}
|
||||
|
||||
cval.getNamespacesAndClasses(rec->getDeclContext()) ;
|
||||
|
||||
// clears obscured inherited variables caused by diamond inheritance
|
||||
cval.clearAmbiguousVariables() ;
|
||||
|
||||
|
@ -5,6 +5,107 @@
|
||||
|
||||
#include "ConstructValues.hh"
|
||||
|
||||
//====================================================================================
|
||||
|
||||
bool ConstructValues::ContainerClass::extractTemplateArgType(const clang::TemplateArgument& ta) {
|
||||
clang::QualType qt = ta.getAsType() ;
|
||||
const clang::Type * t = qt.getTypePtrOrNull() ;
|
||||
if ( t != NULL ) {
|
||||
ContainerClass inner_cc ;
|
||||
if (t->getTypeClass() == clang::Type::Record and t->getAsCXXRecordDecl()) {
|
||||
clang::CXXRecordDecl * crd = t->getAsCXXRecordDecl() ;
|
||||
if ( clang::isa<clang::ClassTemplateSpecializationDecl>(crd) ) {
|
||||
// template argument is a template specialization
|
||||
if (!inner_cc.extractType(clang::cast<clang::ClassTemplateSpecializationDecl>(crd))) {
|
||||
return false ;
|
||||
}
|
||||
} else {
|
||||
// template argument record type, but not a template specialization
|
||||
inner_cc.name = qt.getAsString() ;
|
||||
}
|
||||
} else {
|
||||
// template argument not a record type.
|
||||
inner_cc.name = qt.getAsString() ;
|
||||
}
|
||||
template_args.push_back(inner_cc) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool ConstructValues::ContainerClass::extractType(const clang::RecordDecl * rd) {
|
||||
if (! rd->getIdentifier()) {
|
||||
return false ;
|
||||
}
|
||||
// Set the name of this type.
|
||||
name = rd->getName().str() ;
|
||||
// If this type is a template specialization we need to save the template argument types.
|
||||
if (const clang::ClassTemplateSpecializationDecl *ctsd = clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(rd)) {
|
||||
for (const clang::TemplateArgument& ta : ctsd->getTemplateArgs().asArray()) {
|
||||
if ( ta.getKind() == clang::TemplateArgument::Type ) {
|
||||
// Class types and intrinsic types
|
||||
if ( !extractTemplateArgType(ta) ) {
|
||||
return false ;
|
||||
}
|
||||
} else if ( ta.getKind() == clang::TemplateArgument::Pack ) {
|
||||
// a Pack is the variables in a variadric template
|
||||
for (const clang::TemplateArgument& pack_ta : ta.getPackAsArray()) {
|
||||
if ( pack_ta.getKind() == clang::TemplateArgument::Type ) {
|
||||
if ( !extractTemplateArgType(pack_ta) ) {
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// This template argument is not a clang::TemplateArgument::Type. We don't currently handle these.
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if we reach the end then we can deal with the class name, return true.
|
||||
return true ;
|
||||
}
|
||||
|
||||
static void mangle_template_param(std::string &work_string, const std::string & delimiter) {
|
||||
if ( !delimiter.compare("__") ) {
|
||||
std::replace( work_string.begin(), work_string.end(), '*', '_') ;
|
||||
std::replace( work_string.begin(), work_string.end(), '[', '_') ;
|
||||
std::replace( work_string.begin(), work_string.end(), ']', '_') ;
|
||||
work_string.erase(std::remove_if(work_string.begin(), work_string.end(),
|
||||
(int(*)(int))std::isspace), work_string.end()) ;
|
||||
}
|
||||
}
|
||||
|
||||
void ConstructValues::ContainerClass::printTemplateList(std::ostream& ostream, const std::string& delimiter) {
|
||||
if ( template_args.size() ) {
|
||||
std::string obracket("<"), comma(","), cbracket(">"), work_string ;
|
||||
if ( !delimiter.compare("__") ) {
|
||||
obracket = comma = cbracket = "_" ;
|
||||
}
|
||||
ostream << obracket ;
|
||||
unsigned int arg_size = template_args.size() - 1 ;
|
||||
for (unsigned int ii = 0 ; ii < arg_size ; ii++ ) {
|
||||
work_string = template_args[ii].name ;
|
||||
mangle_template_param(work_string, delimiter) ;
|
||||
ostream << work_string ;
|
||||
template_args[ii].printTemplateList(ostream, delimiter);
|
||||
ostream << comma ;
|
||||
}
|
||||
work_string = template_args[arg_size].name ;
|
||||
mangle_template_param(work_string, delimiter) ;
|
||||
ostream << work_string ;
|
||||
template_args[arg_size].printTemplateList(ostream, delimiter);
|
||||
ostream << cbracket ;
|
||||
}
|
||||
}
|
||||
|
||||
void ConstructValues::ContainerClass::printContainerClass(std::ostream& ostream, const std::string& delimiter) {
|
||||
ostream << name ;
|
||||
printTemplateList(ostream, delimiter) ;
|
||||
ostream << delimiter ;
|
||||
}
|
||||
|
||||
//====================================================================================
|
||||
|
||||
ConstructValues::ConstructValues() {}
|
||||
|
||||
void ConstructValues::setName(std::string in_name) {
|
||||
@ -28,7 +129,7 @@ void ConstructValues::clearNamespacesAndClasses() {
|
||||
container_classes.clear() ;
|
||||
}
|
||||
|
||||
void ConstructValues::getNamespacesAndClasses( const clang::DeclContext * Ctx ) {
|
||||
bool ConstructValues::getNamespacesAndClasses( const clang::DeclContext * Ctx ) {
|
||||
// Save container namespaces and classes.
|
||||
typedef clang::SmallVector<const clang::DeclContext *, 8> ContextsTy;
|
||||
ContextsTy Contexts;
|
||||
@ -43,40 +144,18 @@ void ConstructValues::getNamespacesAndClasses( const clang::DeclContext * Ctx )
|
||||
//std::cout << "namespace " << nd->getIdentifier()->getName().str() << std::endl ;
|
||||
std::string temp_name = nd->getIdentifier()->getName().str() ;
|
||||
if ( temp_name.compare("std") and temp_name.compare("__1")) {
|
||||
addNamespace(nd->getIdentifier()->getName().str()) ;
|
||||
namespaces.push_back(nd->getIdentifier()->getName().str()) ;
|
||||
}
|
||||
}
|
||||
} else if (const clang::RecordDecl *rd = clang::dyn_cast<clang::RecordDecl>(*I)) {
|
||||
if (rd->getIdentifier()) {
|
||||
//std::cout << "in class " << rd->getName().str() << std::endl ;
|
||||
if (const clang::ClassTemplateSpecializationDecl *td = clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(*I)) {
|
||||
std::string text;
|
||||
llvm::raw_string_ostream stream(text);
|
||||
stream << td->getName().str() << "<";
|
||||
const clang::TemplateArgumentList& arguments = td->getTemplateArgs();
|
||||
unsigned end = arguments.size() - 1;
|
||||
for (unsigned i = 0; i < end; ++i) {
|
||||
arguments[i].print(printingPolicy, stream);
|
||||
stream << ", ";
|
||||
}
|
||||
arguments[end].print(printingPolicy, stream);
|
||||
stream << ">";
|
||||
addContainerClass(stream.str());
|
||||
}
|
||||
else {
|
||||
addContainerClass(rd->getName().str()) ;
|
||||
}
|
||||
ContainerClass cc ;
|
||||
if (!cc.extractType(rd)) {
|
||||
return false ;
|
||||
}
|
||||
container_classes.push_back(cc) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConstructValues::addNamespace( std::string in_name ) {
|
||||
namespaces.push_back(in_name) ;
|
||||
}
|
||||
|
||||
void ConstructValues::addContainerClass( std::string in_name ) {
|
||||
container_classes.push_back(in_name) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
std::string ConstructValues::getFullyQualifiedName(const std::string& delimiter) {
|
||||
@ -106,8 +185,8 @@ void ConstructValues::printNamespaces(std::ostream& ostream, const std::string&
|
||||
}
|
||||
|
||||
void ConstructValues::printContainerClasses(std::ostream& ostream, const std::string& delimiter) {
|
||||
for (auto clazz : container_classes) {
|
||||
ostream << clazz << delimiter;
|
||||
for (auto c : container_classes) {
|
||||
c.printContainerClass(ostream, delimiter);
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,8 +200,10 @@ std::string ConstructValues::getNamespacesAndContainerClasses(const std::string&
|
||||
for (auto name : namespaces) {
|
||||
result += name + delimiter;
|
||||
}
|
||||
for (auto clazz : container_classes) {
|
||||
result += clazz + delimiter;
|
||||
for (auto c : container_classes) {
|
||||
std::stringstream ss ;
|
||||
c.printContainerClass(ss, delimiter);
|
||||
result += ss.str() ;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -21,10 +21,25 @@
|
||||
@date July 2012
|
||||
|
||||
*/
|
||||
|
||||
class ConstructValues {
|
||||
public:
|
||||
|
||||
/*
|
||||
A ContainerClass may be a regular class (zero template_args) or a templated class
|
||||
The same routines are used to extract the names of the classes from the clang::RecordDecl
|
||||
data and the to print the class name with or without template arguments.
|
||||
*/
|
||||
class ContainerClass {
|
||||
public:
|
||||
bool extractType(const clang::RecordDecl * rd) ;
|
||||
void printTemplateList(std::ostream& ostream, const std::string & delimiter) ;
|
||||
void printContainerClass(std::ostream& ostream, const std::string & delimiter) ;
|
||||
private:
|
||||
bool extractTemplateArgType(const clang::TemplateArgument& ta) ;
|
||||
std::string name ;
|
||||
std::vector<ContainerClass> template_args ;
|
||||
} ;
|
||||
|
||||
ConstructValues() ;
|
||||
|
||||
void setName(std::string in_name) ;
|
||||
@ -36,22 +51,15 @@ class ConstructValues {
|
||||
/** Clears current namespaces and classes */
|
||||
void clearNamespacesAndClasses() ;
|
||||
|
||||
/** Gets all of the container namespaces and classes this construct resides in */
|
||||
void getNamespacesAndClasses( const clang::DeclContext * Ctx ) ;
|
||||
|
||||
void addNamespace(std::string in_name) ;
|
||||
/** Gets all of the container namespaces and classes this construct resides in
|
||||
returns true if namespaces and classes were succsssfully retrieved.
|
||||
*/
|
||||
bool getNamespacesAndClasses( const clang::DeclContext * Ctx ) ;
|
||||
|
||||
const std::vector<std::string>& getNamespaces() {
|
||||
return namespaces;
|
||||
}
|
||||
|
||||
|
||||
void addContainerClass(std::string in_name) ;
|
||||
|
||||
const std::vector<std::string>& getContainerClasses() {
|
||||
return container_classes;
|
||||
}
|
||||
|
||||
std::string getFullyQualifiedName(const std::string& delimiter = "::") ;
|
||||
|
||||
void printOpenNamespaceBlocks(std::ostream& ostream);
|
||||
@ -71,7 +79,7 @@ class ConstructValues {
|
||||
std::vector<std::string> namespaces ;
|
||||
|
||||
/** List of container classes this construct is contained within */
|
||||
std::vector<std::string> container_classes ;
|
||||
std::vector<ContainerClass> container_classes ;
|
||||
|
||||
/** File where construct is defined */
|
||||
std::string file_name ;
|
||||
|
@ -22,14 +22,10 @@ std::ostream & operator << (std::ostream & ostream , EnumValues & ev ) {
|
||||
ostream << " name = " << ev.name << std::endl ;
|
||||
ostream << " file_name = " << ev.file_name << std::endl ;
|
||||
ostream << " namespaces =" ;
|
||||
for (auto& name : ev.getNamespaces()) {
|
||||
ostream << " " << name ;
|
||||
}
|
||||
ev.printNamespaces(ostream) ;
|
||||
ostream << std::endl ;
|
||||
ostream << " parent classes =" ;
|
||||
for (auto& clazz : ev.getContainerClasses()) {
|
||||
ostream << " " << clazz ;
|
||||
}
|
||||
ev.printContainerClasses(ostream) ;
|
||||
ostream << std::endl ;
|
||||
|
||||
for (auto& pair : ev.getPairs()) {
|
||||
|
@ -62,27 +62,7 @@ bool EnumVisitor::VisitEnumType(clang::EnumType *et) {
|
||||
//std::cout << "\n[34mReplaced Enum name = " << eval->getName() << "[00m" << std::endl ;
|
||||
}
|
||||
|
||||
const clang::DeclContext * Ctx = td->getDeclContext() ;
|
||||
typedef clang::SmallVector<const clang::DeclContext *, 8> ContextsTy;
|
||||
ContextsTy Contexts;
|
||||
// Collect contexts.
|
||||
while (Ctx && clang::isa<clang::NamedDecl>(Ctx)) {
|
||||
Contexts.push_back(Ctx);
|
||||
Ctx = Ctx->getParent();
|
||||
};
|
||||
for (ContextsTy::reverse_iterator I = Contexts.rbegin(), E = Contexts.rend(); I != E; ++I) {
|
||||
if (const clang::NamespaceDecl *nd = clang::dyn_cast<clang::NamespaceDecl>(*I)) {
|
||||
if (! nd->isAnonymousNamespace()) {
|
||||
//std::cout << "namespace " << nd->getIdentifier()->getName().str() << std::endl ;
|
||||
eval.addNamespace(nd->getIdentifier()->getName().str()) ;
|
||||
}
|
||||
} else if (const clang::RecordDecl *rd = clang::dyn_cast<clang::RecordDecl>(*I)) {
|
||||
if (rd->getIdentifier()) {
|
||||
//std::cout << "in class " << rd->getName().str() << std::endl ;
|
||||
eval.addContainerClass(rd->getName().str()) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
eval.getNamespacesAndClasses(td->getDeclContext()) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
@ -529,14 +529,10 @@ std::ostream & operator << (std::ostream & ostream , FieldDescription & fieldDes
|
||||
ostream << " name = " << fieldDescription.name << std::endl ;
|
||||
ostream << " file_name = " << fieldDescription.file_name << std::endl ;
|
||||
ostream << " namespaces =" ;
|
||||
for (auto& name : fieldDescription.getNamespaces()) {
|
||||
ostream << " " << fieldDescription ;
|
||||
}
|
||||
fieldDescription.printNamespaces(ostream) ;
|
||||
ostream << std::endl ;
|
||||
ostream << " parent classes =" ;
|
||||
for (auto& clazz : fieldDescription.getContainerClasses()) {
|
||||
ostream << " " << clazz ;
|
||||
}
|
||||
fieldDescription.printContainerClasses(ostream) ;
|
||||
ostream << std::endl ;
|
||||
ostream << " line_no = " << fieldDescription.line_no << std::endl ;
|
||||
ostream << " container_class = " << fieldDescription.container_class << std::endl ;
|
||||
|
@ -262,6 +262,9 @@ static std::string mangle_string( std::string in_name ) {
|
||||
std::replace( mangled_name.begin(), mangled_name.end(), ',', '_') ;
|
||||
std::replace( mangled_name.begin(), mangled_name.end(), ':', '_') ;
|
||||
std::replace( mangled_name.begin(), mangled_name.end(), '*', '_') ;
|
||||
std::replace( mangled_name.begin(), mangled_name.end(), ']', '_') ;
|
||||
std::replace( mangled_name.begin(), mangled_name.end(), '[', '_') ;
|
||||
|
||||
return mangled_name ;
|
||||
}
|
||||
|
||||
@ -270,7 +273,11 @@ std::map < std::string , std::string > FieldVisitor::processed_templates ;
|
||||
bool FieldVisitor::ProcessTemplate(std::string in_name , clang::CXXRecordDecl * crd ) {
|
||||
|
||||
// Save container namespaces and classes.
|
||||
fdes->getNamespacesAndClasses(crd->getDeclContext()) ;
|
||||
// If we have trouble getting the namespaces and classes immediately return.
|
||||
if ( !fdes->getNamespacesAndClasses(crd->getDeclContext())) {
|
||||
fdes->setIO(0) ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
size_t pos ;
|
||||
|
||||
@ -481,20 +488,35 @@ bool FieldVisitor::VisitRecordType(clang::RecordType *rt) {
|
||||
will be typed as a record. We test if we have a template specialization type.
|
||||
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)) ) {
|
||||
fdes->setIO(0) ;
|
||||
if ( debug_level >= 3 ) {
|
||||
std::cout << " template using private/protected class as argument, not processing" << std::endl ;
|
||||
if ( rd != NULL ) {
|
||||
if ( clang::ClassTemplateSpecializationDecl::classof(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 ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
return false ;
|
||||
if ( debug_level >= 3 ) {
|
||||
rd->dump() ;
|
||||
std::cout << " tst_string = " << tst_string << std::endl ;
|
||||
std::cout << " is_a_template_specialization" << std::endl ;
|
||||
}
|
||||
return ProcessTemplate(tst_string, clang::cast<clang::CXXRecordDecl>(rd)) ;
|
||||
} else if (tst_string.find(">::") != std::string::npos) {
|
||||
/* Hacky check to see if we are using an embedded class within a template definition.
|
||||
template <class T> class A {
|
||||
public: class B { T t ;} ;
|
||||
};
|
||||
|
||||
class C {
|
||||
public: A<int>::B ab ; // This is the pattern we are looking for.
|
||||
} ;
|
||||
There must be a better way to determine this condition
|
||||
We need to make attributes for th A<int>::B class.
|
||||
*/
|
||||
return ProcessTemplate(tst_string, clang::cast<clang::CXXRecordDecl>(rd)) ;
|
||||
}
|
||||
if ( debug_level >= 3 ) {
|
||||
rd->dump() ;
|
||||
std::cout << " tst_string = " << tst_string << std::endl ;
|
||||
std::cout << " is_a_template_specialization" << std::endl ;
|
||||
}
|
||||
return ProcessTemplate(tst_string, clang::cast<clang::CXXRecordDecl>(rd)) ;
|
||||
}
|
||||
|
||||
/* Test to see if we have an embedded anonymous struct/union. e.g. SB is anonymous below.
|
||||
@ -562,7 +584,7 @@ bool FieldVisitor::VisitVarDecl( clang::VarDecl *v ) {
|
||||
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 ;
|
||||
std::cout << "\033[33mFieldVisitor VisitVarDecl: Processing canonical type " << tst_string << "\033[00m" << std::endl ;
|
||||
ct.dump() ;
|
||||
}
|
||||
TraverseType(ct) ;
|
||||
|
@ -40,38 +40,30 @@ int Trick::MemoryManager::add_attr_info( const std::string & user_type_string ,
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
spos = user_type_name.find("<") ;
|
||||
if ( spos != std::string::npos ) {
|
||||
std::replace( user_type_name.begin(), user_type_name.end(), '*', ' ') ;
|
||||
spos = user_type_name.find("[") ;
|
||||
if ( spos != std::string::npos ) {
|
||||
user_type_name.erase( spos ) ;
|
||||
}
|
||||
user_type_name.erase(std::remove_if(user_type_name.begin(), user_type_name.end(), (int(*)(int))std::isspace), user_type_name.end()) ;
|
||||
mit = template_name_map.find(user_type_name) ;
|
||||
if ( mit != template_name_map.end() ) {
|
||||
user_type_name = template_name_map[user_type_name] ;
|
||||
}
|
||||
}
|
||||
|
||||
std::replace( user_type_name.begin(), user_type_name.end(), ':', '_') ;
|
||||
std::replace( user_type_name.begin(), user_type_name.end(), '<', '_') ;
|
||||
std::replace( user_type_name.begin(), user_type_name.end(), ',', '_') ;
|
||||
std::replace( user_type_name.begin(), user_type_name.end(), '*', ' ') ;
|
||||
// The user type name may start as const Foo<int>::Bar[4]. We need to convert that to Foo_int___Bar
|
||||
// remove const from the typename if it exists
|
||||
spos = user_type_name.find("const ") ;
|
||||
if ( spos != std::string::npos ) {
|
||||
user_type_name.erase( spos , spos + 6) ;
|
||||
}
|
||||
// remove any brackets
|
||||
/*
|
||||
spos = user_type_name.find("[") ;
|
||||
if ( spos != std::string::npos ) {
|
||||
user_type_name.erase( spos ) ;
|
||||
}
|
||||
spos = user_type_name.find(">") ;
|
||||
if ( spos != std::string::npos ) {
|
||||
user_type_name.erase( spos ) ;
|
||||
}
|
||||
*/
|
||||
// replace ":<>,*[]" with '_'
|
||||
std::replace( user_type_name.begin(), user_type_name.end(), ':', '_') ;
|
||||
std::replace( user_type_name.begin(), user_type_name.end(), '<', '_') ;
|
||||
std::replace( user_type_name.begin(), user_type_name.end(), '>', '_') ;
|
||||
std::replace( user_type_name.begin(), user_type_name.end(), ',', '_') ;
|
||||
std::replace( user_type_name.begin(), user_type_name.end(), '*', '_') ;
|
||||
std::replace( user_type_name.begin(), user_type_name.end(), '[', '_') ;
|
||||
std::replace( user_type_name.begin(), user_type_name.end(), ']', '_') ;
|
||||
// remove spaces
|
||||
user_type_name.erase(std::remove_if(user_type_name.begin(), user_type_name.end(), (int(*)(int))std::isspace), user_type_name.end()) ;
|
||||
|
||||
|
||||
// Attempt to find an io_src_sizeof function for the named user type.
|
||||
size_func_name = "io_src_sizeof_" + user_type_name ;
|
||||
for ( ii = 0 ; ii < dlhandles.size() && size_func == NULL ; ii++ ) {
|
||||
@ -83,7 +75,7 @@ int Trick::MemoryManager::add_attr_info( const std::string & user_type_string ,
|
||||
|
||||
if ( size_func == NULL) {
|
||||
std::stringstream message;
|
||||
message << "(" << file_name << ":" << line_num
|
||||
message << "(" << file_name << ":" << line_num
|
||||
<< "): Couldn't find an io_src_sizeof_ function for type "
|
||||
<< user_type_string.c_str() << "[" << size_func_name.c_str() << "()].";
|
||||
emitWarning(message.str());
|
||||
|
Loading…
x
Reference in New Issue
Block a user