Generate overloaded function definitions

This commit is contained in:
2017-05-10 14:21:09 -04:00
parent 192b99f21d
commit 64e1e2b008
7 changed files with 95 additions and 0 deletions

1
.gitignore vendored
View File

@@ -13,6 +13,7 @@ tests*/*cpp
tests*/*run
tests*/*.o
tests_ispcpp/*.h
tests_ispcpp/*.out
tests_ispcpp/*pre*
logs/
notify_log.log

View File

@@ -1977,6 +1977,27 @@ lPrintFunctionDeclarations(FILE *file, const std::vector<Symbol *> &funcs,
// fprintf(file, "#ifdef __cplusplus\n} /* end extern C */\n#endif // __cplusplus\n");
}
static void
lPrintPolyFunctionWrappers(FILE *file, const std::vector<std::string> &funcs) {
fprintf(file, "#if defined(__cplusplus)\n");
for (size_t i=0; i<funcs.size(); i++) {
std::vector<Symbol *> poly = m->symbolTable->LookupPolyFunction(funcs[i].c_str());
for (size_t j=0; j<poly.size(); j++) {
const FunctionType *ftype = CastType<FunctionType>(poly[j]->type);
Assert(ftype);
std::string decl = ftype->GetCDeclaration(funcs[i]);
fprintf(file, " %s {\n", decl.c_str());
std::string call = ftype->GetCCall(poly[j]->name);
fprintf(file, " return %s;\n }\n", call.c_str());
}
}
fprintf(file, "#endif // __cplusplus\n");
}
@@ -2353,8 +2374,10 @@ Module::writeHeader(const char *fn) {
// Collect single linear arrays of the exported and extern "C"
// functions
std::vector<Symbol *> exportedFuncs, externCFuncs;
std::vector<std::string> polyFuncs;
m->symbolTable->GetMatchingFunctions(lIsExported, &exportedFuncs);
m->symbolTable->GetMatchingFunctions(lIsExternC, &externCFuncs);
m->symbolTable->GetPolyFunctions(&polyFuncs);
// Get all of the struct, vector, and enumerant types used as function
// parameters. These vectors may have repeats.
@@ -2391,6 +2414,16 @@ Module::writeHeader(const char *fn) {
fprintf(f, "///////////////////////////////////////////////////////////////////////////\n");
lPrintFunctionDeclarations(f, exportedFuncs);
}
// emit wrappers for polymorphic functions
if (polyFuncs.size() > 0) {
fprintf(f, "\n");
fprintf(f, "///////////////////////////////////////////////////////////////////////////\n");
fprintf(f, "// Polymorphic function wrappers\n");
fprintf(f, "///////////////////////////////////////////////////////////////////////////\n");
lPrintPolyFunctionWrappers(f, polyFuncs);
}
#if 0
if (externCFuncs.size() > 0) {
fprintf(f, "\n");

View File

@@ -206,6 +206,14 @@ SymbolTable::LookupPolyFunction(const char *name) {
return polyFunctions[name];
}
void
SymbolTable::GetPolyFunctions(std::vector<std::string> *funcs) {
FunctionMapType::iterator it = polyFunctions.begin();
for (; it != polyFunctions.end(); it++) {
funcs->push_back(it->first);
}
}
bool
SymbolTable::AddType(const char *name, const Type *type, SourcePos pos) {

2
sym.h
View File

@@ -185,6 +185,8 @@ public:
std::vector<Symbol *>& LookupPolyFunction(const char *name);
void GetPolyFunctions(std::vector<std::string> *funcs);
/** Returns all of the functions in the symbol table that match the given
predicate.

13
tests_ispcpp/Makefile Normal file
View File

@@ -0,0 +1,13 @@
CXX=g++
CXXFLAGS=-std=c++11
ISPC=../ispc
ISPCFLAGS=--target=sse4-x2 -O2 --arch=x86-64
%.out : %.cpp %.o
$(CXX) $(CXXFLAGS) -o $@ $^
$ : $.o
%.o : %.ispc
$(ISPC) $(ISPCFLAGS) -h $*.h -o $*.o $<

View File

@@ -249,6 +249,15 @@ Type::IsVoidType() const {
bool
Type::IsPolymorphicType() const {
const FunctionType *ft = CastType<FunctionType>(this);
if (ft) {
for (int i=0; i<ft->GetNumParameters(); i++) {
if (ft->GetParameterType(i)->IsPolymorphicType())
return true;
}
return false;
}
return (CastType<PolyType>(GetBaseType()) != NULL);
}
@@ -3585,6 +3594,34 @@ FunctionType::GetCDeclaration(const std::string &fname) const {
return ret;
}
std::string
FunctionType::GetCCall(const std::string &fname) const {
std::string ret;
ret += fname;
ret += "(";
for (unsigned int i = 0; i < paramTypes.size(); ++i) {
const Type *type = paramTypes[i];
// Convert pointers to arrays to unsized arrays, which are more clear
// to print out for multidimensional arrays (i.e. "float foo[][4] "
// versus "float (foo *)[4]").
const PointerType *pt = CastType<PointerType>(type);
if (pt != NULL &&
CastType<ArrayType>(pt->GetBaseType()) != NULL) {
type = new ArrayType(pt->GetBaseType(), 0);
}
if (paramNames[i] != "")
ret += paramNames[i];
else
FATAL("Exporting a polymorphic function with incomplete arguments");
if (i != paramTypes.size() - 1)
ret += ", ";
}
ret += ")";
return ret;
}
std::string
FunctionType::GetCDeclarationForDispatch(const std::string &fname) const {

1
type.h
View File

@@ -988,6 +988,7 @@ public:
std::string GetString() const;
std::string Mangle() const;
std::string GetCDeclaration(const std::string &fname) const;
std::string GetCCall(const std::string &fname) const;
std::string GetCDeclarationForDispatch(const std::string &fname) const;
llvm::Type *LLVMType(llvm::LLVMContext *ctx) const;