Search code examples
c++llvm-clanglibtooling

How to pass arguments to ASTFrontendAction


Is there a way I can pass constructor arguments to classes inheriting from clang::ASTFrontendAction in programs based on libtooling? All examples I have found online look something like this:

int main() {
    ClangTool Tool(...);

    return Tool.run(newFrontendActionFactory<SomeFrontendAction>().get());
}

But what if SomeFrontendAction needs to be aware of, i.e. options passed in by the tools user? How can I pass those on to the constructor of SomeFrontendAction?


Solution

  • I found this answer while looking for an answer to this question. You should create your own version of newFrontEndActionFactory. The original code for newFrontEndActionFactory is:

    template <typename T>
    std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
      class SimpleFrontendActionFactory : public FrontendActionFactory {
       public:
        std::unique_ptr<FrontendAction> create() override {
          return std::make_unique<T>();
        }
      };
     
      return std::unique_ptr<FrontendActionFactory>(
          new SimpleFrontendActionFactory);
    }
    

    I replaced T with SomeFrontendAction, added a constructor to class SimpleFrontendActionFactory and then pass the options to SomeFrontendAction. The resulting function looks something like this:

    std::unique_ptr<FrontendActionFactory> myNewFrontendActionFactory(string options) {
      class SimpleFrontendActionFactory : public FrontendActionFactory {
       public:
        SimpleFrontendActionFactory(string options) : mOptions(options) {}
    
        std::unique_ptr<FrontendAction> create() override {
          return std::make_unique<SomeFrontendAction>(options);
        }
    
       private:
        string mOptions;
      };
     
      return std::unique_ptr<FrontendActionFactory>(
          new SimpleFrontendActionFactory(options));
    }
    
    int main() {
      ClangTool Tool(...);
    
      return Tool.run(myNewFrontendActionFactory(options).get());
    }