diff --git a/include/trick/tmm_alloc_args.hh b/include/trick/tmm_alloc_args.hh new file mode 100644 index 00000000..e69de29b diff --git a/test/SIM_tmm_with_args/RUN_test/input.py b/test/SIM_tmm_with_args/RUN_test/input.py new file mode 100644 index 00000000..05331777 --- /dev/null +++ b/test/SIM_tmm_with_args/RUN_test/input.py @@ -0,0 +1,11 @@ +import math +from trick.unit_test import * + +print(f"alloc_test.atwargs = {alloc_test}") + +#TRICK_EXPECT_EQ(alloc_test.atwargs.some_int, 0) +#TRICK_EXPECT_NEAR(alloc_test.atwargs.some_double, 0, 1e-6) + +trick.add_read(4.0, """TRICK_EXPECT_EQ(alloc_test.atwargs.some_int, 0)""") +trick.add_read(4.0, """TRICK_EXPECT_NEAR(alloc_test.atwargs.some_double, 0, 1e-6)""") +trick.stop(5.0) \ No newline at end of file diff --git a/test/SIM_tmm_with_args/S_define b/test/SIM_tmm_with_args/S_define new file mode 100644 index 00000000..0601daa9 --- /dev/null +++ b/test/SIM_tmm_with_args/S_define @@ -0,0 +1,33 @@ +/************************TRICK HEADER************************* +PURPOSE: + (This sim test using tmm_alloc_args template function in a + simulation environment) +*************************************************************/ + +#include "sim_objects/default_trick_sys.sm" + +##include "alloc_with_args.hh" +##include "trick/tmm_alloc_args.hh" + +class AllocTestSimObject : public Trick::SimObject { + + public: + AllocTestWithArguments* atwargs; + + AllocTestSimObject() { + + ("initialization") init_alloc(); + } + + + void init_alloc() + { + std::cout << "Entered init_alloc()\n"; + std::cout << TrickTypeToString::getName() << "\n"; + atwargs = tmm_alloc_args(0, 1.0); + std::cout << "Called tmm_alloc_args: " << atwargs << "\n"; + } +}; + +AllocTestSimObject alloc_test ; + diff --git a/test/SIM_tmm_with_args/S_overrides.mk b/test/SIM_tmm_with_args/S_overrides.mk new file mode 100644 index 00000000..8fb30e4f --- /dev/null +++ b/test/SIM_tmm_with_args/S_overrides.mk @@ -0,0 +1,3 @@ +TRICK_CFLAGS += -I./models -I./build -g +TRICK_CXXFLAGS += -I./models -I./build -std=c++11 -g + diff --git a/test/SIM_tmm_with_args/models/alloc_with_args.hh b/test/SIM_tmm_with_args/models/alloc_with_args.hh new file mode 100644 index 00000000..545cdca2 --- /dev/null +++ b/test/SIM_tmm_with_args/models/alloc_with_args.hh @@ -0,0 +1,39 @@ +/********************************* TRICK HEADER ******************************* +PURPOSE: ( Test tmm_alloc_args in a sim environment ) +LIBRARY DEPENDENCY: +(()) +*******************************************************************************/ + +#include + +class AllocTestWithArguments { + + friend class InputProcessor; + + public: + + AllocTestWithArguments() + : + some_int(0), + some_double(0.0) + { + + } + + AllocTestWithArguments(int in_int, double in_double) + : + some_int(in_int), + some_double(in_double) + { + std::cout << "AllocTestWithArguments constructor with: \n"; + std::cout << "in_int: " << in_int << "\n"; + std::cout << "in_double: " << in_double << "\n"; + } + + ~AllocTestWithArguments() { + std::cout << "AllocTestWithArguments desctruct.\n"; + } + + int some_int; + double some_double; +}; \ No newline at end of file diff --git a/trick_source/codegen/Interface_Code_Gen/ClassValues.cpp b/trick_source/codegen/Interface_Code_Gen/ClassValues.cpp index 105e04c8..921f321c 100644 --- a/trick_source/codegen/Interface_Code_Gen/ClassValues.cpp +++ b/trick_source/codegen/Interface_Code_Gen/ClassValues.cpp @@ -50,6 +50,11 @@ void ClassValues::addFieldDescription(FieldDescription * in_fdes) { field_name_to_info_map[in_fdes->getName()] = in_fdes ; } +void ClassValues::addFunctionDescription(FunctionDescription * in_fdes) +{ + function_descripts.push_back(in_fdes); +} + void ClassValues::addInheritedFieldDescriptions(std::vector in_fdes, unsigned int class_offset, bool virtual_inherited ) { // Make a copy of all of the FieldDescription variables. @@ -179,6 +184,11 @@ void ClassValues::clearFieldDescription() { field_descripts.clear() ; } +void ClassValues::clearFunctionDescription() { + function_descripts.clear() ; +} + + void ClassValues::addInheritedClass(std::string class_name) { inherited_classes.push_back(class_name) ; } diff --git a/trick_source/codegen/Interface_Code_Gen/ClassValues.hh b/trick_source/codegen/Interface_Code_Gen/ClassValues.hh index df113dde..c18ec840 100644 --- a/trick_source/codegen/Interface_Code_Gen/ClassValues.hh +++ b/trick_source/codegen/Interface_Code_Gen/ClassValues.hh @@ -10,7 +10,7 @@ #include "ConstructValues.hh" class FieldDescription ; - +class FunctionDescription ; /** ClassValues holds information describing a class found with ICG. The @@ -33,6 +33,8 @@ class ClassValues : public ConstructValues { /** Appends a single field to field_descripts */ void addFieldDescription(FieldDescription * in_fdes) ; + + void addFunctionDescription(FunctionDescription* in_fdes); /** Appends a vector of fields to field_descripts. A vector comes from adding all inherited fields at once */ @@ -44,8 +46,14 @@ class ClassValues : public ConstructValues { return field_descripts ; } + const std::vector& getFunctionDescriptions() { + return function_descripts ; + } + void clearFieldDescription() ; + void clearFunctionDescription() ; + /** Appends an inherited class name to the list this class inherits from */ void addInheritedClass( std::string class_name ) ; @@ -87,6 +95,8 @@ class ClassValues : public ConstructValues { private: std::vector< FieldDescription * > field_descripts ; + std::vector< FunctionDescription * > function_descripts ; + std::map< std::string , FieldDescription * > field_name_to_info_map ; std::set< std::string > field_names_to_qualify ; diff --git a/trick_source/codegen/Interface_Code_Gen/ClassVisitor.cpp b/trick_source/codegen/Interface_Code_Gen/ClassVisitor.cpp index c5ef77fc..cb887be3 100644 --- a/trick_source/codegen/Interface_Code_Gen/ClassVisitor.cpp +++ b/trick_source/codegen/Interface_Code_Gen/ClassVisitor.cpp @@ -17,6 +17,8 @@ #include "CommentSaver.hh" #include "PrintAttributes.hh" #include "BraceMacro.hh" +#include "FunctionVisitor.hh" + extern llvm::cl::opt< int > debug_level ; @@ -115,6 +117,13 @@ bool CXXRecordVisitor::TraverseDecl(clang::Decl *d) { fvis.TraverseFieldDecl(static_cast(d)) ; cval.addFieldDescription(fvis.get_field_data()) ; } + break; + case clang::Decl::CXXConstructor : { + FunctionVisitor fvis(ci , hsd , cs, pa, cval.getName()) ; + auto* ctor = static_cast(d); + fvis.TraverseDecl(ctor) ; + cval.addFunctionDescription(fvis.get_function_data()) ; + } break ; case clang::Decl::Friend : { ClassValues temp_cv ; diff --git a/trick_source/codegen/Interface_Code_Gen/FunctionDescription.cpp b/trick_source/codegen/Interface_Code_Gen/FunctionDescription.cpp new file mode 100644 index 00000000..4167f395 --- /dev/null +++ b/trick_source/codegen/Interface_Code_Gen/FunctionDescription.cpp @@ -0,0 +1,103 @@ +#include "FunctionDescription.hh" + + +FunctionDescription::FunctionDescription() : + container_class(container_class), + is_inherited(false), + is_virtual_inherited(false), + is_static(false), + is_constructor(false), + is_default_constructor(false) +{ + +} + + + +FunctionDescription::FunctionDescription(std::string& container_class) : + container_class(container_class), + is_inherited(false), + is_virtual_inherited(false), + is_static(false), + is_constructor(false), + is_default_constructor(false) +{ + +} + +FunctionDescription::~FunctionDescription() +{ + +} + + +void FunctionDescription::setContainerClass(std::string& container_class) +{ + this->container_class = container_class; +} + +void FunctionDescription::setInherited(bool inherited) +{ + this->is_inherited = inherited; +} + +void FunctionDescription::setVirtualInherited(bool virtual_inherited) +{ + this->is_virtual_inherited = virtual_inherited; +} + +void FunctionDescription::setStatic(bool is_static) +{ + this->is_static = is_static; +} + +void FunctionDescription::setIsConstructor(bool is_constructor) +{ + this->is_constructor = is_constructor; +} + +void FunctionDescription::setReturnType(std::string return_type_name) +{ + this->return_type_name = return_type_name; +} + +std::string FunctionDescription::getMangledName() +{ + std::string base = this->function_name; + + for(auto& arg : this->function_args) + { + base += "_" + removePointerAndReference(arg.typeName); + } + + return base; +} + +void FunctionDescription::addFunctionArgument(FunctionArgument arg) +{ + function_args.emplace_back(arg); +} + + +bool FunctionDescription::getIsPublic() const +{ + + return this->access == clang::AccessSpecifier::AS_public; + +} + + +std::string FunctionDescription::removePointerAndReference(const std::string& typeStr) +{ + std::string result = typeStr; + // Remove all '*' characters + result.erase(std::remove(result.begin(), result.end(), '*'), result.end()); + + // Remove all '&' characters + result.erase(std::remove(result.begin(), result.end(), '&'), result.end()); + + result.erase(std::remove(result.begin(), result.end(), ' '), result.end()); + + return result; + +} \ No newline at end of file diff --git a/trick_source/codegen/Interface_Code_Gen/FunctionDescription.hh b/trick_source/codegen/Interface_Code_Gen/FunctionDescription.hh new file mode 100644 index 00000000..8443fcc8 --- /dev/null +++ b/trick_source/codegen/Interface_Code_Gen/FunctionDescription.hh @@ -0,0 +1,107 @@ +#ifndef __FUNCTION_DESCRIPTION_HH__ +#define __FUNCTION_DESCRIPTION_HH__ + +#include +#include +#include + +#include "clang/Basic/Specifiers.h" + +struct FunctionArgument +{ + std::string typeName; + std::string argName; + bool isPointer; + bool isReference; + bool isConst; +}; + + +class FunctionDescription +{ + public: + FunctionDescription(); + FunctionDescription(std::string& container_class); + ~FunctionDescription(); + + + void setReturnType(std::string return_type_name); + + void setContainerClass(std::string& container_class); + void setInherited(bool inherited); + void setVirtualInherited(bool virtual_inherited); + void setStatic(bool is_static); + void setIsConstructor(bool is_constructor); + + + std::string getMangledName(); + + void addFunctionArgument(FunctionArgument arg); + + std::string getReturnType() const { return return_type_name; } + + inline std::vector& getFunctionArgs(); + + inline void setFunctionName(std::string in_function_name); + inline void setAccess(clang::AccessSpecifier in_access); + inline void setIsDefaultConstructor(bool is_default); + + inline bool getIsDefaultConstructor() const; + inline std::string getFunctionName() const; + inline std::string getContainerClass() const; + + bool getIsPublic() const; + + private: + /** Line number in current file where field is */ + unsigned int line_no ; + + /** Name of the class this field is in */ + std::string container_class ; + + std::string return_type_name ; + + std::string function_name; + + std::vector function_args; + + + + /** public/protected/private */ + clang::AccessSpecifier access ; + + /** is this function inherited from parent class */ + bool is_inherited ; + + /** is this function virtual inherited from parent class */ + bool is_virtual_inherited ; + + /** is this field declared static */ + bool is_static ; + + bool is_constructor ; + + bool is_default_constructor ; + + + private: + + std::string removePointerAndReference(const std::string& typeStr); +}; + + +inline std::string FunctionDescription::getContainerClass() const {return container_class; } + +inline std::vector& FunctionDescription::getFunctionArgs() { return function_args; } + +inline void FunctionDescription::setFunctionName(std::string in_function_name) { function_name = in_function_name; } + +inline std::string FunctionDescription::getFunctionName() const { return function_name; } + +inline void FunctionDescription::setAccess(clang::AccessSpecifier in_access) { access = in_access;} + +inline bool FunctionDescription::getIsDefaultConstructor() const {return is_default_constructor;} + +inline void FunctionDescription::setIsDefaultConstructor(bool is_default) { is_default_constructor = is_default; } + +#endif // __FUNCTION_DESCRIPTION_HH__ \ No newline at end of file diff --git a/trick_source/codegen/Interface_Code_Gen/FunctionVisitor.cpp b/trick_source/codegen/Interface_Code_Gen/FunctionVisitor.cpp new file mode 100644 index 00000000..efb0aa00 --- /dev/null +++ b/trick_source/codegen/Interface_Code_Gen/FunctionVisitor.cpp @@ -0,0 +1,68 @@ +#include "FunctionVisitor.hh" +#include "FunctionDescription.hh" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/Type.h" +#include "llvm/Support/raw_ostream.h" + +FunctionVisitor::FunctionVisitor(clang::CompilerInstance & in_ci , + HeaderSearchDirs & in_hsd , + CommentSaver & in_cs , + PrintAttributes & in_pa , + std::string container_class ) + : +ci(in_ci) , +hsd(in_hsd) , +cs(in_cs) , +pa(in_pa) +{ + fdes = new FunctionDescription(container_class) ; +} + +bool FunctionVisitor::VisitMethodDecl(clang::CXXMethodDecl* fd) +{ + + + return true; +} + +bool FunctionVisitor::VisitCXXConstructorDecl(clang::CXXConstructorDecl *ctor) +{ + + uint32_t num_params = ctor->getNumParams(); + + //Return type for constuctors is void + fdes->setReturnType(ctor->getReturnType().getAsString()); + + for(uint32_t i = 0; i < num_params; ++i) + { + FunctionArgument funcArg; + + clang::ParmVarDecl *param = ctor->getParamDecl(i); + clang::QualType qt = param->getType(); + std::string paramTypeStr = qt.getAsString(); + + // Get the parameter name + std::string paramName = param->getNameAsString(); + + funcArg.typeName = paramTypeStr; + funcArg.argName = paramName; + funcArg.isPointer = qt->isPointerType(); + funcArg.isReference = qt->isReferenceType(); + funcArg.isConst = qt.isConstQualified(); + + fdes->addFunctionArgument(funcArg); + + } + + fdes->setIsConstructor(true); + + if(ctor->isDefaultConstructor()) + { + fdes->setIsDefaultConstructor(true); + } + + fdes->setAccess(ctor->getAccess()); + fdes->setFunctionName(ctor->getParent()->getQualifiedNameAsString()); + + return true; +} diff --git a/trick_source/codegen/Interface_Code_Gen/FunctionVisitor.hh b/trick_source/codegen/Interface_Code_Gen/FunctionVisitor.hh new file mode 100644 index 00000000..8355b289 --- /dev/null +++ b/trick_source/codegen/Interface_Code_Gen/FunctionVisitor.hh @@ -0,0 +1,47 @@ +#ifndef __FUNCTION_VISITOR_HH__ +#define __FUNCTION_VISITOR_HH__ + +#include "clang/Frontend/CompilerInstance.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/DeclCXX.h" + +#include "PrintAttributes.hh" + +class CommentSaver ; +class HeaderSearchDirs ; +class SourceManager ; +class FunctionDescription ; + +class FunctionVisitor : public clang::RecursiveASTVisitor +{ + public: + FunctionVisitor(clang::CompilerInstance & in_ci , + HeaderSearchDirs & in_hsd , + CommentSaver & cs , + PrintAttributes & in_pa , + std::string container_class ) ; + + bool VisitMethodDecl(clang::CXXMethodDecl* fd) ; + bool VisitCXXConstructorDecl(clang::CXXConstructorDecl *ctor); + + inline FunctionDescription * get_function_data(); + + /** The compiler's source manager. Holds file/line info for everything. */ + clang::CompilerInstance & ci ; + + /** Holds all comments */ + CommentSaver & cs ; + + /** The header search directories */ + HeaderSearchDirs & hsd ; + + /** attributes printer */ + PrintAttributes & pa ; + + /** Holds the field information found, usually returned to caller of this visitor. */ + FunctionDescription * fdes ; +}; + +inline FunctionDescription* FunctionVisitor::get_function_data() { return fdes ;} + +#endif // __FUNCTION_VISITOR_HH__ \ No newline at end of file diff --git a/trick_source/codegen/Interface_Code_Gen/PrintAttributes.cpp b/trick_source/codegen/Interface_Code_Gen/PrintAttributes.cpp index 758a84cd..bd65fbab 100644 --- a/trick_source/codegen/Interface_Code_Gen/PrintAttributes.cpp +++ b/trick_source/codegen/Interface_Code_Gen/PrintAttributes.cpp @@ -16,6 +16,7 @@ #include "PrintFileContentsBase.hh" #include "PrintFileContents10.hh" #include "FieldDescription.hh" +#include "FunctionDescription.hh" #include "HeaderSearchDirs.hh" #include "CommentSaver.hh" #include "ClassValues.hh" @@ -434,7 +435,7 @@ void PrintAttributes::printIOMakefile() { makefile_io_src.open("build/Makefile_io_src") ; makefile_io_src - << "TRICK_IO_CXXFLAGS += -Wno-invalid-offsetof -Wno-old-style-cast -Wno-write-strings -Wno-unused-variable" << std::endl + << "TRICK_IO_CXXFLAGS += -Wno-invalid-offsetof -Wno-old-style-cast -Wno-write-strings -Wno-unused-variable -Ibuild" << std::endl << std::endl << "ifeq ($(IS_CC_CLANG), 0)" << std::endl << " TRICK_IO_CXXFLAGS += -Wno-unused-local-typedefs -Wno-unused-but-set-variable" << std::endl @@ -646,3 +647,149 @@ bool PrintAttributes::isHeaderExcluded(const std::string& header, bool exclude_e void PrintAttributes::markHeaderAsVisited(const std::string& header) { visited_files.insert(header); } + + + +void PrintAttributes::writeTrickTypeToStructHeader() +{ + + + std::set class_names_to_print; + for(auto& pair : processed_classes) + { + bool foundMatch = false; + const std::set& stringSet = pair.second; + for(const std::string& element : stringSet) + { + if(typedef_classes.find(element) != typedef_classes.end()) + { + foundMatch = true; + } + else + { + if(element.find("::") == std::string::npos) + { + class_names_to_print.insert(element); + } + } + + + } + + } + + std::ofstream out_file; + out_file.open("build/trick/trick_type_to_string.hh"); + + out_file << "/********************************* TRICK HEADER *******************************\n"; + out_file << "PURPOSE: ( Map types that trick knows about to strings using tempalte specialization )\n"; + out_file << "LIBRARY DEPENDENCY:\n"; + out_file << "(())\n"; + out_file << "*******************************************************************************/\n"; + + out_file << "\n"; + out_file << "#pragma once"; + out_file << "\n\n"; + out_file << "#include \n"; + out_file << "//Forward declarations\n"; + + for (auto class_name : class_names_to_print) + { + out_file << "class " << class_name << ";\n"; + } + + out_file << "\n\n"; + + + out_file << "template\n"; + out_file << "struct TrickTypeToString { static std::string getName(); };\n"; + out_file << "\n\n"; + + for (auto class_name : class_names_to_print) + { + out_file << "template<>\n"; + out_file << "struct TrickTypeToString<" << class_name << ">\n"; + out_file << "{\n"; + out_file << " static std::string getName() \n"; + out_file << " {\n"; + out_file << " return \"" << class_name << "\";\n"; + out_file << " }\n"; + out_file << "};\n\n"; + //out_file << "const std::string TrickTypeToString<" << class_name << ">::name = \"" << class_name << "\";\n"; + out_file << "\n\n"; + } + + out_file.close(); + +} + +void PrintAttributes::writeTemplateAllocHeader() +{ + std::string build_trick = "build/trick/"; + + _mkdir(build_trick.c_str()); + + std::ofstream out_file; + + out_file.open("build/trick/tmm_alloc_args.hh"); + out_file << "#ifndef SWIG\n"; + out_file << "/********************************* TRICK HEADER *******************************\n"; + out_file << "PURPOSE: ( Simulate balls contacting boundaries. )\n"; + out_file << "LIBRARY DEPENDENCY:\n"; + out_file << "((trick/tmm_alloc_args.o))\n"; + out_file << "*******************************************************************************/\n"; + out_file << "#ifndef __TMM_ALLOC_ARGS_HH__\n"; + out_file << "#define __TMM_ALLOC_ARGS_HH__\n"; + out_file << "\n\n"; + out_file << "#include \n\n"; + out_file << "#include \"trick/trick_type_to_string.hh\"\n"; + out_file << "#include \n\n"; + + out_file << "//trick includes\n"; + out_file << "#include \"trick/MemoryManager.hh\"\n\n"; + + out_file << "template\n"; + out_file << "struct make_void {\n"; + out_file << " typedef void type;\n"; + out_file << "};\n\n"; + + out_file << "template\n"; + out_file << "using void_t = typename make_void::type;\n\n"; + + out_file << "template>\n"; + out_file << "struct has_getname : std::false_type {};\n"; + + out_file << "\n"; + out_file << "template\n"; + out_file << "struct has_getname>().getName())>> : std::true_type {};\n\n"; + + out_file << "template\n"; + out_file << "typename std::enable_if::value, T*>::type\n"; + out_file << "tmm_alloc_args(Args&&... args)\n"; + out_file << "{\n"; + out_file << " void* new_alloc = trick_MM->declare_var(TrickTypeToString::getName().c_str());\n"; + out_file << " return new (new_alloc) T(std::forward(args)...);\n"; + out_file << "}\n\n"; + + out_file << "template\n"; + out_file << "typename std::enable_if::value, T*>::type\n"; + out_file << "tmm_alloc_args(Args&&... args)\n"; + out_file << "{\n"; + out_file << " static_assert(true, \"You've attempted to call tmm_alloc_args using a type(T) that does not have an implemented template specialization.\");\n"; + out_file << " return nullptr;\n"; + out_file << "}\n\n"; + + out_file << "#endif //__TMM_ALLOC_ARGS_HH__\n"; + out_file << "#endif // SWIG\n"; + out_file.close(); + + out_file.open("build/trick/tmm_alloc_args.cc"); + out_file << "#include \"trick/tmm_alloc_args.hh\""; + + out_file.close(); +} + +void PrintAttributes::addTypedefClass(std::string typedef_class) +{ + typedef_classes.insert(typedef_class); +} \ No newline at end of file diff --git a/trick_source/codegen/Interface_Code_Gen/PrintAttributes.hh b/trick_source/codegen/Interface_Code_Gen/PrintAttributes.hh index 9b3a7dec..3d396e2d 100644 --- a/trick_source/codegen/Interface_Code_Gen/PrintAttributes.hh +++ b/trick_source/codegen/Interface_Code_Gen/PrintAttributes.hh @@ -65,8 +65,15 @@ class PrintAttributes { void printSieEnum( EnumValues * ev ) ; bool isHeaderExcluded(const std::string& header, bool exclude_ext_libs = true); + void markHeaderAsVisited(const std::string& header); + void writeTemplateAllocHeader(); + + void writeTrickTypeToStructHeader(); + + void addTypedefClass(std::string typedef_class); + protected: const bool verboseBuild = (getenv("TRICK_VERBOSE_BUILD") || getenv("VERBOSE")); @@ -145,6 +152,8 @@ class PrintAttributes { std::map< std::string , std::set< std::string > > processed_classes ; /** map of processed enums sorted by file */ std::map< std::string , std::set< std::string > > processed_enums ; + + std::set typedef_classes; } ; diff --git a/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.cpp b/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.cpp index 807fca92..76c9e5c4 100644 --- a/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.cpp +++ b/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.cpp @@ -1,8 +1,10 @@ #include #include +#include #include "PrintFileContents10.hh" #include "FieldDescription.hh" +#include "FunctionDescription.hh" #include "ClassValues.hh" #include "EnumValues.hh" #include "Utilities.hh" @@ -37,6 +39,7 @@ void PrintFileContents10::printIOHeader(std::ostream & ostream , std::string hea << "#include \"trick/ClassSizeCheck.hh\"\n" << "#include \"trick/UnitsMap.hh\"\n" << "#include \"trick/checkpoint_stl.hh\"\n" + << "#include \"trick/tmm_alloc_args.hh\"\n" << "#include \"" << header_file_name << "\"\n" << "\n" ; } @@ -354,6 +357,7 @@ void PrintFileContents10::printClass( std::ostream & ostream , ClassValues * cv print_io_src_delete(ostream, cv) ; print_close_extern_c(ostream) ; print_units_map(ostream, cv) ; + printTemplateConstructorWrapper(ostream, cv) ; } void PrintFileContents10::printEnum( std::ostream & ostream , EnumValues * ev ) { @@ -411,3 +415,71 @@ void PrintFileContents10::printStlFunction(const std::string& name, const std::s << " " << call << ";" << std::endl << "}" << std::endl ; } + + +void PrintFileContents10::printTemplateConstructorWrapper(std::ostream & ostream , ClassValues * cv ) { + std::string name = cv->getFullyQualifiedMangledTypeName(); + auto& function_descripts = cv->getFunctionDescriptions(); + + + + for (auto& function_descript : function_descripts) { + if(!function_descript->getIsDefaultConstructor() && function_descript->getIsPublic()) + { + //Create mangled name for this constructor + std::string mangled_name = function_descript->getMangledName(); + + if(mangled_name.find("Trick::") == std::string::npos && mangled_name.find("std::") == std::string::npos && mangled_name.find("er7_utils::") == std::string::npos) + { + + //Since these are constructors, we don't want the return type since it will be void - thanks clang! + ostream << function_descript->getContainerClass() << "* " << mangled_name << "("; + auto arguments = function_descript->getFunctionArgs(); + + std::string arg_base = "arg_"; + + size_t arg_counter = 0; + auto it = arguments.begin(); + auto end = arguments.end(); + + while(it != end) + { + auto argument = *it; + + ostream << argument.typeName; + + ostream << " " << arg_base + std::to_string(arg_counter); + + ++it; + ++arg_counter; + + if (it != end) { + ostream << ", "; + } + } + + ostream << ")\n{\n"; + ostream << " return tmm_alloc_args<" + function_descript->getFunctionName() + ">("; + + for (size_t i = 0; i < arguments.size(); ++i) + { + ostream << "arg_" + std::to_string(i); + + if ( i != arguments.size() - 1) + { + ostream << ", "; + } + } + + ostream << ");\n"; + + ostream << "}\n"; + + } + + ostream << "\n\n"; + + } + } + +} \ No newline at end of file diff --git a/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.hh b/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.hh index 6802f43d..b2ef2382 100644 --- a/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.hh +++ b/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.hh @@ -41,7 +41,7 @@ class PrintFileContents10 : public PrintFileContentsBase { virtual void printClassMapHeader(std::ostream & out, std::string function_name ) ; virtual void printClassMap(std::ostream & outfile , ClassValues * cv) ; virtual void printClassMapFooter(std::ostream & out) ; - + /** Prints all enums for global map */ virtual void printEnumMapHeader(std::ostream & out, std::string function_name ) ; virtual void printEnumMap(std::ostream & out, EnumValues * ev) ; @@ -102,6 +102,8 @@ class PrintFileContents10 : public PrintFileContentsBase { void print_clear_stl(std::ostream & outfile , FieldDescription * fdes , ClassValues * in_class) ; void printStlFunction(const std::string& name, const std::string& parameters, const std::string& call, std::ostream& ostream, FieldDescription& fieldDescription, ClassValues& classValues); + + void printTemplateConstructorWrapper(std::ostream & ostream , ClassValues * cv ) ; } ; #endif diff --git a/trick_source/codegen/Interface_Code_Gen/TypedefVisitor.cpp b/trick_source/codegen/Interface_Code_Gen/TypedefVisitor.cpp index 656b9e52..01910838 100644 --- a/trick_source/codegen/Interface_Code_Gen/TypedefVisitor.cpp +++ b/trick_source/codegen/Interface_Code_Gen/TypedefVisitor.cpp @@ -136,6 +136,8 @@ bool TypedefVisitor::VisitTypedefDecl(clang::TypedefDecl *td) { typedef_location = td->getSourceRange() ; typedef_decl_context = td->getDeclContext() ; + this->pa.addTypedefClass(typedef_name) ; + return true; } diff --git a/trick_source/codegen/Interface_Code_Gen/main.cpp b/trick_source/codegen/Interface_Code_Gen/main.cpp index 84380329..dadbe892 100644 --- a/trick_source/codegen/Interface_Code_Gen/main.cpp +++ b/trick_source/codegen/Interface_Code_Gen/main.cpp @@ -340,6 +340,10 @@ int main(int argc, char * argv[]) { // Print the list of headers that have the ICG:(No) comment printAttributes.printICGNoFiles(); + printAttributes.writeTemplateAllocHeader(); + + printAttributes.writeTrickTypeToStructHeader(); + if (icgDiagConsumer->error_in_user_code) { std::cout << color(ERROR, "Trick build was terminated due to error in user code!") << std::endl; exit(-1);