mirror of
https://github.com/nasa/trick.git
synced 2025-02-04 18:13:36 +00:00
Initial pass at adding support for a templated emplacement new function. Added FunctionVisitor class to ICG to handle parsing constructors with arguments.
This commit is contained in:
parent
cca503a6ec
commit
64fabb22ec
0
include/trick/tmm_alloc_args.hh
Normal file
0
include/trick/tmm_alloc_args.hh
Normal file
11
test/SIM_tmm_with_args/RUN_test/input.py
Normal file
11
test/SIM_tmm_with_args/RUN_test/input.py
Normal file
@ -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)
|
33
test/SIM_tmm_with_args/S_define
Normal file
33
test/SIM_tmm_with_args/S_define
Normal file
@ -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<AllocTestWithArguments>::getName() << "\n";
|
||||
atwargs = tmm_alloc_args<AllocTestWithArguments>(0, 1.0);
|
||||
std::cout << "Called tmm_alloc_args: " << atwargs << "\n";
|
||||
}
|
||||
};
|
||||
|
||||
AllocTestSimObject alloc_test ;
|
||||
|
3
test/SIM_tmm_with_args/S_overrides.mk
Normal file
3
test/SIM_tmm_with_args/S_overrides.mk
Normal file
@ -0,0 +1,3 @@
|
||||
TRICK_CFLAGS += -I./models -I./build -g
|
||||
TRICK_CXXFLAGS += -I./models -I./build -std=c++11 -g
|
||||
|
39
test/SIM_tmm_with_args/models/alloc_with_args.hh
Normal file
39
test/SIM_tmm_with_args/models/alloc_with_args.hh
Normal file
@ -0,0 +1,39 @@
|
||||
/********************************* TRICK HEADER *******************************
|
||||
PURPOSE: ( Test tmm_alloc_args in a sim environment )
|
||||
LIBRARY DEPENDENCY:
|
||||
(())
|
||||
*******************************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
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;
|
||||
};
|
@ -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<FieldDescription *> 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) ;
|
||||
}
|
||||
|
@ -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<FunctionDescription*>& 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 ;
|
||||
|
||||
|
@ -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<clang::FieldDecl *>(d)) ;
|
||||
cval.addFieldDescription(fvis.get_field_data()) ;
|
||||
}
|
||||
break;
|
||||
case clang::Decl::CXXConstructor : {
|
||||
FunctionVisitor fvis(ci , hsd , cs, pa, cval.getName()) ;
|
||||
auto* ctor = static_cast<clang::CXXConstructorDecl *>(d);
|
||||
fvis.TraverseDecl(ctor) ;
|
||||
cval.addFunctionDescription(fvis.get_function_data()) ;
|
||||
}
|
||||
break ;
|
||||
case clang::Decl::Friend : {
|
||||
ClassValues temp_cv ;
|
||||
|
103
trick_source/codegen/Interface_Code_Gen/FunctionDescription.cpp
Normal file
103
trick_source/codegen/Interface_Code_Gen/FunctionDescription.cpp
Normal file
@ -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;
|
||||
|
||||
}
|
107
trick_source/codegen/Interface_Code_Gen/FunctionDescription.hh
Normal file
107
trick_source/codegen/Interface_Code_Gen/FunctionDescription.hh
Normal file
@ -0,0 +1,107 @@
|
||||
#ifndef __FUNCTION_DESCRIPTION_HH__
|
||||
#define __FUNCTION_DESCRIPTION_HH__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#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<FunctionArgument>& 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<FunctionArgument> 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<FunctionArgument>& 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__
|
68
trick_source/codegen/Interface_Code_Gen/FunctionVisitor.cpp
Normal file
68
trick_source/codegen/Interface_Code_Gen/FunctionVisitor.cpp
Normal file
@ -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;
|
||||
}
|
47
trick_source/codegen/Interface_Code_Gen/FunctionVisitor.hh
Normal file
47
trick_source/codegen/Interface_Code_Gen/FunctionVisitor.hh
Normal file
@ -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<FunctionVisitor>
|
||||
{
|
||||
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__
|
@ -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<std::string> class_names_to_print;
|
||||
for(auto& pair : processed_classes)
|
||||
{
|
||||
bool foundMatch = false;
|
||||
const std::set<std::string>& 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 <string>\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<typename T>\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 <utility>\n\n";
|
||||
out_file << "#include \"trick/trick_type_to_string.hh\"\n";
|
||||
out_file << "#include <type_traits>\n\n";
|
||||
|
||||
out_file << "//trick includes\n";
|
||||
out_file << "#include \"trick/MemoryManager.hh\"\n\n";
|
||||
|
||||
out_file << "template<typename... Ts>\n";
|
||||
out_file << "struct make_void {\n";
|
||||
out_file << " typedef void type;\n";
|
||||
out_file << "};\n\n";
|
||||
|
||||
out_file << "template<typename... Ts>\n";
|
||||
out_file << "using void_t = typename make_void<Ts...>::type;\n\n";
|
||||
|
||||
out_file << "template<typename T, typename = void_t<>>\n";
|
||||
out_file << "struct has_getname : std::false_type {};\n";
|
||||
|
||||
out_file << "\n";
|
||||
out_file << "template<typename T>\n";
|
||||
out_file << "struct has_getname<T, void_t<decltype(std::declval<TrickTypeToString<T>>().getName())>> : std::true_type {};\n\n";
|
||||
|
||||
out_file << "template<typename T, typename ...Args>\n";
|
||||
out_file << "typename std::enable_if<has_getname<T>::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<T>::getName().c_str());\n";
|
||||
out_file << " return new (new_alloc) T(std::forward<Args>(args)...);\n";
|
||||
out_file << "}\n\n";
|
||||
|
||||
out_file << "template<typename T, typename ...Args>\n";
|
||||
out_file << "typename std::enable_if<!has_getname<T>::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);
|
||||
}
|
@ -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<std::string> typedef_classes;
|
||||
|
||||
} ;
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iterator>
|
||||
|
||||
#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";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user