11#include " IR.h"
22#include " ../Utils.h"
3+ #include " location/SourceLocation.h"
34
45IR::IR (std::string libName, std::string linkName, std::string objectName,
56 std::string packageName)
@@ -13,48 +14,53 @@ void IR::addFunction(std::string name, std::vector<Parameter *> parameters,
1314}
1415
1516std::shared_ptr<TypeDef> IR::addTypeDef (std::string name,
16- std::shared_ptr<Type> type) {
17- typeDefs.push_back (std::make_shared<TypeDef>(std::move (name), type));
17+ std::shared_ptr<Type> type,
18+ std::shared_ptr<Location> location) {
19+ typeDefs.push_back (
20+ std::make_shared<TypeDef>(std::move (name), type, std::move (location)));
1821 return typeDefs.back ();
1922}
2023
2124std::shared_ptr<Type> IR::addEnum (std::string name, const std::string &type,
22- std::vector<Enumerator> enumerators) {
25+ std::vector<Enumerator> enumerators,
26+ std::shared_ptr<Location> location) {
2327 std::shared_ptr<Enum> e =
2428 std::make_shared<Enum>(std::move (name), type, std::move (enumerators));
2529 enums.push_back (e);
2630 if (!e->isAnonymous ()) {
27- typeDefs.push_back (e->generateTypeDef ());
31+ typeDefs.push_back (e->generateTypeDef (std::move (location) ));
2832 return typeDefs.back ();
2933 }
3034 return nullptr ;
3135}
3236
3337void IR::addStruct (std::string name, std::vector<Field *> fields,
34- uint64_t typeSize) {
38+ uint64_t typeSize, std::shared_ptr<Location> location ) {
3539 std::shared_ptr<Struct> s =
3640 std::make_shared<Struct>(name, std::move (fields), typeSize);
3741 structs.push_back (s);
3842 std::shared_ptr<TypeDef> typeDef = getTypeDefWithName (" struct_" + name);
3943 if (typeDef) {
4044 /* the struct type used to be opaque type, typeDef contains nullptr */
4145 typeDef.get ()->setType (s);
46+ typeDef.get ()->setLocation (location);
4247 } else {
43- typeDefs.push_back (s->generateTypeDef ());
48+ typeDefs.push_back (s->generateTypeDef (std::move (location) ));
4449 }
4550}
4651
4752void IR::addUnion (std::string name, std::vector<Field *> fields,
48- uint64_t maxSize) {
53+ uint64_t maxSize, std::shared_ptr<Location> location ) {
4954 std::shared_ptr<Union> u =
5055 std::make_shared<Union>(name, std::move (fields), maxSize);
5156 unions.push_back (u);
5257 std::shared_ptr<TypeDef> typeDef = getTypeDefWithName (" union_" + name);
5358 if (typeDef) {
5459 /* the union type used to be opaque type, typeDef contains nullptr */
5560 typeDef.get ()->setType (u);
61+ typeDef.get ()->setLocation (location);
5662 } else {
57- typeDefs.push_back (u->generateTypeDef ());
63+ typeDefs.push_back (u->generateTypeDef (std::move (location) ));
5864 }
5965}
6066
@@ -171,6 +177,7 @@ void IR::generate(const std::string &excludePrefix) {
171177 if (!generated) {
172178 setScalaNames ();
173179 filterDeclarations (excludePrefix);
180+ removeUnusedExternalTypes ();
174181 generated = true ;
175182 }
176183}
@@ -230,7 +237,7 @@ void IR::replaceTypeInTypeDefs(std::shared_ptr<Type> oldType,
230237
231238template <typename T>
232239bool IR::isTypeUsed (const std::vector<T> &declarations,
233- std::shared_ptr<Type> type, bool stopOnTypeDefs) {
240+ std::shared_ptr<Type> type, bool stopOnTypeDefs) const {
234241 for (const auto &decl : declarations) {
235242 if (decl->usesType (type, stopOnTypeDefs)) {
236243 return true ;
@@ -239,7 +246,7 @@ bool IR::isTypeUsed(const std::vector<T> &declarations,
239246 return false ;
240247}
241248
242- bool IR::typeIsUsedOnlyInTypeDefs (std::shared_ptr<Type> type) {
249+ bool IR::typeIsUsedOnlyInTypeDefs (const std::shared_ptr<Type> & type) const {
243250 /* varDefines are not checked here because they are simply
244251 * aliases for variables.*/
245252 return !(
@@ -248,6 +255,11 @@ bool IR::typeIsUsedOnlyInTypeDefs(std::shared_ptr<Type> type) {
248255 isTypeUsed (literalDefines, type, true ));
249256}
250257
258+ bool IR::isTypeUsed (const std::shared_ptr<Type> &type) const {
259+ return !(typeIsUsedOnlyInTypeDefs (type) &&
260+ !isTypeUsed (typeDefs, type, false ));
261+ }
262+
251263void IR::setScalaNames () {
252264 /* Renaming according to Scala naming conventions
253265 * should happen here */
@@ -353,3 +365,47 @@ IR::~IR() {
353365 variables.clear ();
354366 varDefines.clear ();
355367}
368+
369+ void IR::removeUnusedExternalTypes () {
370+ for (auto it = typeDefs.begin (); it != typeDefs.end ();) {
371+ std::shared_ptr<TypeDef> typeDef = *it;
372+ std::shared_ptr<Location> location = typeDef->getLocation ();
373+ auto *sourceLocation = dynamic_cast <SourceLocation *>(location.get ());
374+ if (sourceLocation && !sourceLocation->isMainFile ()) {
375+ if (!isTypeUsed (typeDef)) {
376+ removeStructOrUnionOrEnum (typeDef->getType ());
377+ it = typeDefs.erase (it);
378+ } else {
379+ ++it;
380+ }
381+ } else {
382+ ++it;
383+ }
384+ }
385+ }
386+
387+ template <typename T>
388+ void IR::removeDeclaration (std::vector<std::shared_ptr<T>> &declarations,
389+ T *declaration) {
390+ for (auto it = declarations.begin (); it != declarations.end ();) {
391+ T *decl = (*it).get ();
392+ if (decl == declaration) {
393+ it = declarations.erase (it);
394+ } else {
395+ ++it;
396+ }
397+ }
398+ }
399+
400+ void IR::removeStructOrUnionOrEnum (std::shared_ptr<Type> type) {
401+ if (isInstanceOf<Struct>(type.get ())) {
402+ auto *s = dynamic_cast <Struct *>(type.get ());
403+ removeDeclaration (structs, s);
404+ } else if (isInstanceOf<Union>(type.get ())) {
405+ auto *u = dynamic_cast <Union *>(type.get ());
406+ removeDeclaration (unions, u);
407+ } else if (isInstanceOf<Enum>(type.get ())) {
408+ auto *e = dynamic_cast <Enum *>(type.get ());
409+ removeDeclaration (enums, e);
410+ }
411+ }
0 commit comments