I'm working on LLVM project and have such code:
if (auto *var = dyn_cast<type_0>(args) {
// code
} else if (auto *var = dyn_cast<type_1>(args) {
// same code as in first `if`
} else if (auto *vat = dyn_cast<type_2>(args) {
//same code as in first `if`
}// and etc.
Is it possible to convert these if/else
statements to something like this?
auto types[] = {type_0, type_1, type_2, ... };
for (auto type : types) {
if (apply(type, args)) {
break;
}
}
bool apply(type, args) {
//code from first `if` statement
}
CodePudding user response:
With some funky fold expression magic it's possible to do this (derived from https://www.foonathan.net/2020/05/fold-tricks/). I've used dynamic_cast
for an easier demo but I presume dyn_cast
works the same way:
#include <string>
#include <iostream>
#include <typeinfo>
class Base
{
public:
virtual ~Base() {};
};
class Sub1 : public Base {};
class Sub2 : public Base {};
class Sub3 : public Base {};
class Sub4 : public Base {};
template<typename T>
bool visitor(const T& t)
{
std::cout << typeid(T).name() << "\n";
return true;
}
template <typename Base, typename ...T>
bool visit(Base& base)
{
return ((dynamic_cast<T*>(&base) ? (visitor(*dynamic_cast<T*>(&base)), false) : true) && ...);
}
int main()
{
Sub2 sub;
Base& base = sub;
visit<Base, Sub1, Sub2, Sub3, Sub4>(base);
}
CodePudding user response:
The simplest LLVM-ish way is to use InstVisitor; this answer contains the typical declaration and you can find several examples if you search for code in LLVM that inherits InstVisitor in that way.
Then you just make an instance of your InstVisitor subclass and tell it to visit() any module, function, basic block or instruction, and it'll call the right visitFoo() for that instruction or for each instruction.