clang-metatool
A framework for reusing code in clang tools
meta_tool.h
Go to the documentation of this file.
1 #ifndef INCLUDED_CLANGMETATOOL_META_TOOL_H
2 #define INCLUDED_CLANGMETATOOL_META_TOOL_H
3 
4 #include <assert.h>
5 #include <map>
6 #include <memory>
7 #include <stddef.h>
8 #include <string>
9 
10 #include <clang/AST/ASTConsumer.h>
11 #include <clang/ASTMatchers/ASTMatchFinder.h>
12 #include <clang/Frontend/CompilerInstance.h>
13 #include <clang/Frontend/FrontendAction.h>
14 #include <clang/Tooling/Core/Replacement.h>
15 #include <llvm/ADT/StringRef.h>
16 
17 namespace clangmetatool {
18 namespace {
19 
20 // Code to check if there exists a member T::ArgTypes that was created as a
21 // typedef
22 template <typename... Ts> using void_t = void;
23 
24 template <typename T, typename = void>
25 struct has_typedef_ArgTypes : std::false_type {};
26 
27 template <typename T>
28 struct has_typedef_ArgTypes<T, void_t<typename T::ArgTypes>> : std::true_type {
29 };
30 }
48 template <class WrappedTool> class MetaTool : public clang::ASTFrontendAction {
49 private:
50  static constexpr bool providesArgTypes =
51  has_typedef_ArgTypes<WrappedTool>::value;
52  struct NoArgs {
53  typedef void *ArgTypes;
54  };
55 
56 public:
57  typedef typename std::conditional_t<providesArgTypes, WrappedTool,
59 
60 private:
61  std::map<std::string, clang::tooling::Replacements> &replacementsMap;
62  clang::ast_matchers::MatchFinder f;
63  WrappedTool *tool;
64 
65  ArgTypes &args;
66 
67  template <class A>
68  WrappedTool *create_tool(clang::CompilerInstance &ci, A args) {
69  return new WrappedTool(&ci, &f, args);
70  }
71  WrappedTool *create_tool(clang::CompilerInstance &ci,
72  typename NoArgs::ArgTypes &args) {
73  return new WrappedTool(&ci, &f);
74  }
75 
76 public:
77  MetaTool(std::map<std::string, clang::tooling::Replacements> &replacementsMap,
78  ArgTypes &args)
79  : replacementsMap(replacementsMap), tool(NULL), args(args) {}
80 
81  MetaTool(std::map<std::string, clang::tooling::Replacements> &replacementsMap)
82  : replacementsMap(replacementsMap), tool(NULL) {}
83 
85  if (tool)
86  delete tool;
87  }
88 
89  virtual bool BeginSourceFileAction(clang::CompilerInstance &ci) override {
90  // we don't expect to ever have the metatool be invoked more
91  // than once, it would eventually result in us holding
92  // references to unused compiler instance objects, and
93  // eventually segfaulting, so assert here.
94  assert(tool == NULL);
95  tool = create_tool(ci, args);
96  return true;
97  }
98 
99  virtual void EndSourceFileAction() override {
100  tool->postProcessing(replacementsMap);
101  }
102 
103  virtual std::unique_ptr<clang::ASTConsumer>
104  CreateASTConsumer(clang::CompilerInstance &CI,
105  llvm::StringRef file) override {
106  return f.newASTConsumer();
107  }
108 };
109 }
110 
111 #endif
112 
113 // ----------------------------------------------------------------------------
114 // Copyright 2018 Bloomberg Finance L.P.
115 //
116 // Licensed under the Apache License, Version 2.0 (the "License");
117 // you may not use this file except in compliance with the License.
118 // You may obtain a copy of the License at
119 //
120 // http://www.apache.org/licenses/LICENSE-2.0
121 //
122 // Unless required by applicable law or agreed to in writing, software
123 // distributed under the License is distributed on an "AS IS" BASIS,
124 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
125 // See the License for the specific language governing permissions and
126 // limitations under the License.
127 // ----------------------------- END-OF-FILE ----------------------------------
virtual std::unique_ptr< clang::ASTConsumer > CreateASTConsumer(clang::CompilerInstance &CI, llvm::StringRef file) override
Definition: meta_tool.h:104
std::conditional_t< providesArgTypes, WrappedTool, NoArgs >::ArgTypes ArgTypes
Definition: meta_tool.h:58
MetaTool(std::map< std::string, clang::tooling::Replacements > &replacementsMap, ArgTypes &args)
Definition: meta_tool.h:77
MetaTool(std::map< std::string, clang::tooling::Replacements > &replacementsMap)
Definition: meta_tool.h:81
virtual bool BeginSourceFileAction(clang::CompilerInstance &ci) override
Definition: meta_tool.h:89
virtual void EndSourceFileAction() override
Definition: meta_tool.h:99