Tools.h revision f395528158379e7ea9f6ff4bbb791abadca15aab
14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)//===--- Tools.h - Tool Implementations -------------------------*- C++ -*-===//
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)//
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)//                     The LLVM Compiler Infrastructure
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)//
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// This file is distributed under the University of Illinois Open Source
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// License. See LICENSE.TXT for details.
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)//
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)//===----------------------------------------------------------------------===//
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifndef CLANG_LIB_DRIVER_TOOLS_H_
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#define CLANG_LIB_DRIVER_TOOLS_H_
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "clang/Driver/Tool.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "clang/Driver/Types.h"
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "clang/Driver/Util.h"
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "llvm/Support/Compiler.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace clang {
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace driver {
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  class Driver;
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace toolchains {
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  class Darwin;
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace tools {
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  class VISIBILITY_HIDDEN Clang : public Tool {
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    void AddPreprocessingOptions(const Driver &D,
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 const ArgList &Args,
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 ArgStringList &CmdArgs,
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 const InputInfo &Output,
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 const InputInfoList &Inputs) const;
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  public:
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    Clang(const ToolChain &TC) : Tool("clang", TC) {}
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual bool acceptsPipedInput() const { return true; }
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual bool canPipeOutput() const { return true; }
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual bool hasIntegratedCPP() const { return true; }
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual void ConstructJob(Compilation &C, const JobAction &JA,
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              Job &Dest,
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              const InputInfo &Output,
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              const InputInfoList &Inputs,
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              const ArgList &TCArgs,
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              const char *LinkingOutput) const;
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  /// gcc - Generic GCC tool implementations.
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace gcc {
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  class VISIBILITY_HIDDEN Common : public Tool {
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  public:
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    Common(const char *Name, const ToolChain &TC) : Tool(Name, TC) {}
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual void ConstructJob(Compilation &C, const JobAction &JA,
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              Job &Dest,
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              const InputInfo &Output,
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              const InputInfoList &Inputs,
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              const ArgList &TCArgs,
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              const char *LinkingOutput) const;
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    /// RenderExtraToolArgs - Render any arguments necessary to force
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    /// the particular tool mode.
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual void RenderExtraToolArgs(ArgStringList &CmdArgs) const = 0;
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  class VISIBILITY_HIDDEN Preprocess : public Common {
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  public:
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    Preprocess(const ToolChain &TC) : Common("gcc::Preprocess", TC) {}
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual bool acceptsPipedInput() const { return true; }
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual bool canPipeOutput() const { return true; }
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual bool hasIntegratedCPP() const { return false; }
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual void RenderExtraToolArgs(ArgStringList &CmdArgs) const;
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  class VISIBILITY_HIDDEN Precompile : public Common  {
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  public:
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    Precompile(const ToolChain &TC) : Common("gcc::Precompile", TC) {}
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual bool acceptsPipedInput() const { return true; }
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual bool canPipeOutput() const { return false; }
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual bool hasIntegratedCPP() const { return true; }
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual void RenderExtraToolArgs(ArgStringList &CmdArgs) const;
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  class VISIBILITY_HIDDEN Compile : public Common  {
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  public:
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    Compile(const ToolChain &TC) : Common("gcc::Compile", TC) {}
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual bool acceptsPipedInput() const { return true; }
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual bool canPipeOutput() const { return true; }
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual bool hasIntegratedCPP() const { return true; }
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual void RenderExtraToolArgs(ArgStringList &CmdArgs) const;
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  class VISIBILITY_HIDDEN Assemble : public Common  {
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  public:
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    Assemble(const ToolChain &TC) : Common("gcc::Assemble", TC) {}
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual bool acceptsPipedInput() const { return true; }
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual bool canPipeOutput() const { return false; }
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual bool hasIntegratedCPP() const { return false; }
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
111    virtual void RenderExtraToolArgs(ArgStringList &CmdArgs) const;
112  };
113
114  class VISIBILITY_HIDDEN Link : public Common  {
115  public:
116    Link(const ToolChain &TC) : Common("gcc::Link", TC) {}
117
118    virtual bool acceptsPipedInput() const { return false; }
119    virtual bool canPipeOutput() const { return false; }
120    virtual bool hasIntegratedCPP() const { return false; }
121
122    virtual void RenderExtraToolArgs(ArgStringList &CmdArgs) const;
123  };
124} // end namespace gcc
125
126namespace darwin {
127  class VISIBILITY_HIDDEN CC1 : public Tool  {
128  public:
129    static const char *getBaseInputName(const ArgList &Args,
130                                 const InputInfoList &Input);
131    static const char *getBaseInputStem(const ArgList &Args,
132                                 const InputInfoList &Input);
133    static const char *getDependencyFileName(const ArgList &Args,
134                                             const InputInfoList &Inputs);
135
136  protected:
137    const char *getCC1Name(types::ID Type) const;
138
139    void AddCC1Args(const ArgList &Args, ArgStringList &CmdArgs) const;
140    void AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
141                           const InputInfoList &Inputs,
142                           const ArgStringList &OutputArgs) const;
143    void AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
144                           const InputInfoList &Inputs,
145                           const ArgStringList &OutputArgs) const;
146    void AddCPPUniqueOptionsArgs(const ArgList &Args,
147                                 ArgStringList &CmdArgs,
148                                 const InputInfoList &Inputs) const;
149    void AddCPPArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
150
151  public:
152    CC1(const char *Name, const ToolChain &TC) : Tool(Name, TC) {}
153
154    virtual bool acceptsPipedInput() const { return true; }
155    virtual bool canPipeOutput() const { return true; }
156    virtual bool hasIntegratedCPP() const { return true; }
157  };
158
159  class VISIBILITY_HIDDEN Preprocess : public CC1  {
160  public:
161    Preprocess(const ToolChain &TC) : CC1("darwin::Preprocess", TC) {}
162
163    virtual void ConstructJob(Compilation &C, const JobAction &JA,
164                              Job &Dest,
165                              const InputInfo &Output,
166                              const InputInfoList &Inputs,
167                              const ArgList &TCArgs,
168                              const char *LinkingOutput) const;
169  };
170
171  class VISIBILITY_HIDDEN Compile : public CC1  {
172  public:
173    Compile(const ToolChain &TC) : CC1("darwin::Compile", TC) {}
174
175    virtual void ConstructJob(Compilation &C, const JobAction &JA,
176                              Job &Dest,
177                              const InputInfo &Output,
178                              const InputInfoList &Inputs,
179                              const ArgList &TCArgs,
180                              const char *LinkingOutput) const;
181  };
182
183  class VISIBILITY_HIDDEN Assemble : public Tool  {
184  public:
185    Assemble(const ToolChain &TC) : Tool("darwin::Assemble", TC) {}
186
187    virtual bool acceptsPipedInput() const { return true; }
188    virtual bool canPipeOutput() const { return false; }
189    virtual bool hasIntegratedCPP() const { return false; }
190
191    virtual void ConstructJob(Compilation &C, const JobAction &JA,
192                              Job &Dest,
193                              const InputInfo &Output,
194                              const InputInfoList &Inputs,
195                              const ArgList &TCArgs,
196                              const char *LinkingOutput) const;
197  };
198
199  class VISIBILITY_HIDDEN Link : public Tool  {
200    void AddDarwinArch(const ArgList &Args, ArgStringList &CmdArgs) const;
201    void AddDarwinSubArch(const ArgList &Args, ArgStringList &CmdArgs) const;
202    void AddLinkArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
203
204    const toolchains::Darwin &getDarwinToolChain() const {
205      return reinterpret_cast<const toolchains::Darwin&>(getToolChain());
206    }
207
208  public:
209    Link(const ToolChain &TC)
210      : Tool("darwin::Link", TC) {
211    }
212
213    virtual bool acceptsPipedInput() const { return false; }
214    virtual bool canPipeOutput() const { return false; }
215    virtual bool hasIntegratedCPP() const { return false; }
216
217    virtual void ConstructJob(Compilation &C, const JobAction &JA,
218                              Job &Dest,
219                              const InputInfo &Output,
220                              const InputInfoList &Inputs,
221                              const ArgList &TCArgs,
222                              const char *LinkingOutput) const;
223  };
224
225  class VISIBILITY_HIDDEN Lipo : public Tool  {
226  public:
227    Lipo(const ToolChain &TC) : Tool("darwin::Lipo", TC) {}
228
229    virtual bool acceptsPipedInput() const { return false; }
230    virtual bool canPipeOutput() const { return false; }
231    virtual bool hasIntegratedCPP() const { return false; }
232
233    virtual void ConstructJob(Compilation &C, const JobAction &JA,
234                              Job &Dest,
235                              const InputInfo &Output,
236                              const InputInfoList &Inputs,
237                              const ArgList &TCArgs,
238                              const char *LinkingOutput) const;
239  };
240}
241
242  /// openbsd -- Directly call GNU Binutils assembler and linker
243namespace openbsd {
244  class VISIBILITY_HIDDEN Assemble : public Tool  {
245  public:
246    Assemble(const ToolChain &TC) : Tool("openbsd::Assemble", TC) {}
247
248    virtual bool acceptsPipedInput() const { return true; }
249    virtual bool canPipeOutput() const { return true; }
250    virtual bool hasIntegratedCPP() const { return false; }
251
252    virtual void ConstructJob(Compilation &C, const JobAction &JA,
253                              Job &Dest,
254                              const InputInfo &Output,
255                              const InputInfoList &Inputs,
256                              const ArgList &TCArgs,
257                              const char *LinkingOutput) const;
258  };
259  class VISIBILITY_HIDDEN Link : public Tool  {
260  public:
261    Link(const ToolChain &TC) : Tool("openbsd::Link", TC) {}
262
263    virtual bool acceptsPipedInput() const { return true; }
264    virtual bool canPipeOutput() const { return true; }
265    virtual bool hasIntegratedCPP() const { return false; }
266
267    virtual void ConstructJob(Compilation &C, const JobAction &JA,
268                              Job &Dest,
269                              const InputInfo &Output,
270                              const InputInfoList &Inputs,
271                              const ArgList &TCArgs,
272                              const char *LinkingOutput) const;
273  };
274} // end namespace openbsd
275
276  /// freebsd -- Directly call GNU Binutils assembler and linker
277namespace freebsd {
278  class VISIBILITY_HIDDEN Assemble : public Tool  {
279  public:
280    Assemble(const ToolChain &TC) : Tool("freebsd::Assemble", TC) {}
281
282    virtual bool acceptsPipedInput() const { return true; }
283    virtual bool canPipeOutput() const { return true; }
284    virtual bool hasIntegratedCPP() const { return false; }
285
286    virtual void ConstructJob(Compilation &C, const JobAction &JA,
287                              Job &Dest,
288                              const InputInfo &Output,
289                              const InputInfoList &Inputs,
290                              const ArgList &TCArgs,
291                              const char *LinkingOutput) const;
292  };
293  class VISIBILITY_HIDDEN Link : public Tool  {
294  public:
295    Link(const ToolChain &TC) : Tool("freebsd::Link", TC) {}
296
297    virtual bool acceptsPipedInput() const { return true; }
298    virtual bool canPipeOutput() const { return true; }
299    virtual bool hasIntegratedCPP() const { return false; }
300
301    virtual void ConstructJob(Compilation &C, const JobAction &JA,
302                              Job &Dest,
303                              const InputInfo &Output,
304                              const InputInfoList &Inputs,
305                              const ArgList &TCArgs,
306                              const char *LinkingOutput) const;
307  };
308} // end namespace freebsd
309
310  /// auroraux -- Directly call GNU Binutils assembler and linker
311namespace auroraux {
312  class VISIBILITY_HIDDEN Assemble : public Tool  {
313  public:
314    Assemble(const ToolChain &TC) : Tool("auroraux::Assemble", TC) {}
315
316    virtual bool acceptsPipedInput() const { return true; }
317    virtual bool canPipeOutput() const { return true; }
318    virtual bool hasIntegratedCPP() const { return false; }
319
320    virtual void ConstructJob(Compilation &C, const JobAction &JA,
321                              Job &Dest,
322                              const InputInfo &Output,
323                              const InputInfoList &Inputs,
324                              const ArgList &TCArgs,
325                              const char *LinkingOutput) const;
326  };
327  class VISIBILITY_HIDDEN Link : public Tool  {
328  public:
329    Link(const ToolChain &TC) : Tool("auroraux::Link", TC) {}
330
331    virtual bool acceptsPipedInput() const { return true; }
332    virtual bool canPipeOutput() const { return true; }
333    virtual bool hasIntegratedCPP() const { return false; }
334
335    virtual void ConstructJob(Compilation &C, const JobAction &JA,
336                              Job &Dest,
337                              const InputInfo &Output,
338                              const InputInfoList &Inputs,
339                              const ArgList &TCArgs,
340                              const char *LinkingOutput) const;
341  };
342} // end namespace auroraux
343
344  /// dragonfly -- Directly call GNU Binutils assembler and linker
345namespace dragonfly {
346  class VISIBILITY_HIDDEN Assemble : public Tool  {
347  public:
348    Assemble(const ToolChain &TC) : Tool("dragonfly::Assemble", TC) {}
349
350    virtual bool acceptsPipedInput() const { return true; }
351    virtual bool canPipeOutput() const { return true; }
352    virtual bool hasIntegratedCPP() const { return false; }
353
354    virtual void ConstructJob(Compilation &C, const JobAction &JA,
355                              Job &Dest,
356                              const InputInfo &Output,
357                              const InputInfoList &Inputs,
358                              const ArgList &TCArgs,
359                              const char *LinkingOutput) const;
360  };
361  class VISIBILITY_HIDDEN Link : public Tool  {
362  public:
363    Link(const ToolChain &TC) : Tool("dragonfly::Link", TC) {}
364
365    virtual bool acceptsPipedInput() const { return true; }
366    virtual bool canPipeOutput() const { return true; }
367    virtual bool hasIntegratedCPP() const { return false; }
368
369    virtual void ConstructJob(Compilation &C, const JobAction &JA,
370                              Job &Dest,
371                              const InputInfo &Output,
372                              const InputInfoList &Inputs,
373                              const ArgList &TCArgs,
374                              const char *LinkingOutput) const;
375  };
376} // end namespace dragonfly
377
378} // end namespace toolchains
379} // end namespace driver
380} // end namespace clang
381
382#endif // CLANG_LIB_DRIVER_TOOLS_H_
383