4 #include "typeInfo.h"
\r
7 // add a generic instantiation if its not in the vector already
\r
8 void addGenericInstantiation(
\r
9 std::vector<std::vector<Type>> & insts,
\r
10 const std::vector<Type> & newInst)
\r
14 insts.push_back(newInst);
\r
17 for (auto inst : insts)
\r
19 for (int i = 0; i < inst.size(); i++)
\r
21 if (inst[i] != newInst[i])
\r
23 insts.push_back(newInst);
\r
30 Program instantiateGenerics(const Program & p)
\r
34 // Find generic instantiations
\r
36 // visit expressions (only function calls are considered) and types,
\r
37 // find the function/struct by pointer and add an instantiation
\r
38 Visitor findGenericInstantiations;
\r
39 findGenericInstantiations.onExpr =
\r
40 [&](const Expr & e, const std::shared_ptr<Context> ctx)
\r
42 if (e.type == ExprType::Func && !e._func.genericInstantiation.empty())
\r
44 auto f = findFunctionPtr(e._func.functionName, e._func.namespacePrefixes, ctx);
\r
47 if (std::get<0>(*f)->genericTypeNames.empty())
\r
48 throw "Trying to instantiate non-generic function";
\r
49 if (e._func.genericInstantiation.size() != std::get<0>(*f)->genericTypeNames.size())
\r
50 throw "Trying to instantiate function with wrong number of types";
\r
51 addGenericInstantiation(std::get<0>(*f)->genericInstantiations, e._func.genericInstantiation);
\r
55 findGenericInstantiations.onType =
\r
56 [&](const Type & t, const std::shared_ptr<Context> ctx)
\r
58 if (!t.genericInstantiation.empty())
\r
60 auto s = findStructPtr(t.name, t.namespacePrefixes, ctx);
\r
63 if (std::get<0>(*s)->genericTypeNames.empty())
\r
64 throw "Trying to instantiate non-generic struct";
\r
65 if (t.genericInstantiation.size() != std::get<0>(*s)->genericTypeNames.size())
\r
66 throw "Trying to instantiate struct with wrong number of types";
\r
67 addGenericInstantiation(std::get<0>(*s)->genericInstantiations, t.genericInstantiation);
\r
71 Visit v(findGenericInstantiations);
\r
77 // generate the appendix for C struct/function names
\r
78 // including array/pointer indicators because
\r
79 // there might be distinct instantiations
\r
80 // for int and int* for example
\r
81 std::string genericAppendix(const std::vector<Type> & ts)
\r
83 std::stringstream sstr;
\r
88 for (auto m : t.modifiers)
\r
90 if (m.type == TypeModifierType::Array)
\r
94 sstr << m._arraySize;
\r
96 else if (m.type == TypeModifierType::Pointer)
\r
101 if (!t.genericInstantiation.empty())
\r
103 sstr << genericAppendix(t.genericInstantiation);
\r