Tools.h revision 234353
1228735Smav//===--- Tools.h - Tool Implementations -------------------------*- C++ -*-===//
2228735Smav//
3228735Smav//                     The LLVM Compiler Infrastructure
4228735Smav//
5228735Smav// This file is distributed under the University of Illinois Open Source
6228735Smav// License. See LICENSE.TXT for details.
7228735Smav//
8228735Smav//===----------------------------------------------------------------------===//
9228735Smav
10228735Smav#ifndef CLANG_LIB_DRIVER_TOOLS_H_
11228735Smav#define CLANG_LIB_DRIVER_TOOLS_H_
12228735Smav
13228735Smav#include "clang/Driver/Tool.h"
14228735Smav#include "clang/Driver/Types.h"
15228735Smav#include "clang/Driver/Util.h"
16228735Smav
17228735Smav#include "llvm/ADT/Triple.h"
18228735Smav#include "llvm/Support/Compiler.h"
19228735Smav
20228735Smavnamespace clang {
21228735Smavnamespace driver {
22228735Smav  class Driver;
23228735Smav
24228735Smavnamespace toolchains {
25228735Smav  class Darwin;
26228735Smav}
27228735Smav
28228735Smavnamespace tools {
29228735Smav
30228735Smav  /// \brief Clang compiler tool.
31228735Smav  class LLVM_LIBRARY_VISIBILITY Clang : public Tool {
32228735Smav    void AddPreprocessingOptions(Compilation &C,
33228735Smav                                 const Driver &D,
34228735Smav                                 const ArgList &Args,
35228735Smav                                 ArgStringList &CmdArgs,
36228735Smav                                 const InputInfo &Output,
37228735Smav                                 const InputInfoList &Inputs) const;
38228735Smav
39228735Smav    void AddARMTargetArgs(const ArgList &Args, ArgStringList &CmdArgs,
40228735Smav                          bool KernelOrKext) const;
41228735Smav    void AddMIPSTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
42228735Smav    void AddSparcTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
43228735Smav    void AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
44228735Smav    void AddHexagonTargetArgs (const ArgList &Args, ArgStringList &CmdArgs) const;
45228735Smav
46228735Smav  public:
47228735Smav    Clang(const ToolChain &TC) : Tool("clang", "clang frontend", TC) {}
48228735Smav
49228735Smav    virtual bool hasGoodDiagnostics() const { return true; }
50228735Smav    virtual bool hasIntegratedAssembler() const { return true; }
51228735Smav    virtual bool hasIntegratedCPP() const { return true; }
52228735Smav
53228735Smav    virtual void ConstructJob(Compilation &C, const JobAction &JA,
54228739Smav                              const InputInfo &Output,
55228735Smav                              const InputInfoList &Inputs,
56228735Smav                              const ArgList &TCArgs,
57228739Smav                              const char *LinkingOutput) const;
58228735Smav  };
59228735Smav
60228735Smav  /// \brief Clang integrated assembler tool.
61228735Smav  class LLVM_LIBRARY_VISIBILITY ClangAs : public Tool {
62228735Smav    void AddARMTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
63228735Smav  public:
64229657Suqs    ClangAs(const ToolChain &TC) : Tool("clang::as",
65228735Smav                                        "clang integrated assembler", TC) {}
66228735Smav
67228739Smav    virtual bool hasGoodDiagnostics() const { return true; }
68228735Smav    virtual bool hasIntegratedAssembler() const { return false; }
69228735Smav    virtual bool hasIntegratedCPP() const { return false; }
70228735Smav
71228735Smav    virtual void ConstructJob(Compilation &C, const JobAction &JA,
72228735Smav                              const InputInfo &Output,
73228735Smav                              const InputInfoList &Inputs,
74228735Smav                              const ArgList &TCArgs,
75228735Smav                              const char *LinkingOutput) const;
76228735Smav  };
77228735Smav
78  /// gcc - Generic GCC tool implementations.
79namespace gcc {
80  class LLVM_LIBRARY_VISIBILITY Common : public Tool {
81  public:
82    Common(const char *Name, const char *ShortName,
83           const ToolChain &TC) : Tool(Name, ShortName, TC) {}
84
85    virtual void ConstructJob(Compilation &C, const JobAction &JA,
86                              const InputInfo &Output,
87                              const InputInfoList &Inputs,
88                              const ArgList &TCArgs,
89                              const char *LinkingOutput) const;
90
91    /// RenderExtraToolArgs - Render any arguments necessary to force
92    /// the particular tool mode.
93    virtual void RenderExtraToolArgs(const JobAction &JA,
94                                     ArgStringList &CmdArgs) const = 0;
95  };
96
97
98  class LLVM_LIBRARY_VISIBILITY Preprocess : public Common {
99  public:
100    Preprocess(const ToolChain &TC) : Common("gcc::Preprocess",
101                                             "gcc preprocessor", TC) {}
102
103    virtual bool hasGoodDiagnostics() const { return true; }
104    virtual bool hasIntegratedCPP() const { return false; }
105
106    virtual void RenderExtraToolArgs(const JobAction &JA,
107                                     ArgStringList &CmdArgs) const;
108  };
109
110  class LLVM_LIBRARY_VISIBILITY Precompile : public Common  {
111  public:
112    Precompile(const ToolChain &TC) : Common("gcc::Precompile",
113                                             "gcc precompile", TC) {}
114
115    virtual bool hasGoodDiagnostics() const { return true; }
116    virtual bool hasIntegratedCPP() const { return true; }
117
118    virtual void RenderExtraToolArgs(const JobAction &JA,
119                                     ArgStringList &CmdArgs) const;
120  };
121
122  class LLVM_LIBRARY_VISIBILITY Compile : public Common  {
123  public:
124    Compile(const ToolChain &TC) : Common("gcc::Compile",
125                                          "gcc frontend", TC) {}
126
127    virtual bool hasGoodDiagnostics() const { return true; }
128    virtual bool hasIntegratedCPP() const { return true; }
129
130    virtual void RenderExtraToolArgs(const JobAction &JA,
131                                     ArgStringList &CmdArgs) const;
132  };
133
134  class LLVM_LIBRARY_VISIBILITY Assemble : public Common  {
135  public:
136    Assemble(const ToolChain &TC) : Common("gcc::Assemble",
137                                           "assembler (via gcc)", TC) {}
138
139    virtual bool hasIntegratedCPP() const { return false; }
140
141    virtual void RenderExtraToolArgs(const JobAction &JA,
142                                     ArgStringList &CmdArgs) const;
143  };
144
145  class LLVM_LIBRARY_VISIBILITY Link : public Common  {
146  public:
147    Link(const ToolChain &TC) : Common("gcc::Link",
148                                       "linker (via gcc)", TC) {}
149
150    virtual bool hasIntegratedCPP() const { return false; }
151    virtual bool isLinkJob() const { return true; }
152
153    virtual void RenderExtraToolArgs(const JobAction &JA,
154                                     ArgStringList &CmdArgs) const;
155  };
156} // end namespace gcc
157
158namespace hexagon {
159  // For Hexagon, we do not need to instantiate tools for PreProcess, PreCompile and Compile.
160  // We simply use "clang -cc1" for those actions.
161  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool {
162  public:
163    Assemble(const ToolChain &TC) : Tool("hexagon::Assemble",
164      "hexagon-as", TC) {}
165
166    virtual bool hasIntegratedCPP() const { return false; }
167
168    virtual void RenderExtraToolArgs(const JobAction &JA,
169                                     ArgStringList &CmdArgs) const;
170    virtual void ConstructJob(Compilation &C, const JobAction &JA,
171                              const InputInfo &Output,
172                              const InputInfoList &Inputs,
173                              const ArgList &TCArgs,
174                              const char *LinkingOutput) const;
175  };
176
177  class LLVM_LIBRARY_VISIBILITY Link : public Tool {
178  public:
179    Link(const ToolChain &TC) : Tool("hexagon::Link",
180      "hexagon-ld", TC) {}
181
182    virtual bool hasIntegratedCPP() const { return false; }
183    virtual bool isLinkJob() const { return true; }
184
185    virtual void RenderExtraToolArgs(const JobAction &JA,
186                                     ArgStringList &CmdArgs) const;
187    virtual void ConstructJob(Compilation &C, const JobAction &JA,
188                              const InputInfo &Output,
189                              const InputInfoList &Inputs,
190                              const ArgList &TCArgs,
191                              const char *LinkingOutput) const;
192  };
193} // end namespace hexagon.
194
195
196namespace darwin {
197  class LLVM_LIBRARY_VISIBILITY DarwinTool : public Tool {
198    virtual void anchor();
199  protected:
200    void AddDarwinArch(const ArgList &Args, ArgStringList &CmdArgs) const;
201
202    const toolchains::Darwin &getDarwinToolChain() const {
203      return reinterpret_cast<const toolchains::Darwin&>(getToolChain());
204    }
205
206  public:
207    DarwinTool(const char *Name, const char *ShortName,
208               const ToolChain &TC) : Tool(Name, ShortName, TC) {}
209  };
210
211  class LLVM_LIBRARY_VISIBILITY CC1 : public DarwinTool  {
212    virtual void anchor();
213  public:
214    static const char *getBaseInputName(const ArgList &Args,
215                                 const InputInfoList &Input);
216    static const char *getBaseInputStem(const ArgList &Args,
217                                 const InputInfoList &Input);
218    static const char *getDependencyFileName(const ArgList &Args,
219                                             const InputInfoList &Inputs);
220
221  protected:
222    const char *getCC1Name(types::ID Type) const;
223
224    void AddCC1Args(const ArgList &Args, ArgStringList &CmdArgs) const;
225    void RemoveCC1UnsupportedArgs(ArgStringList &CmdArgs) const;
226    void AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
227                           const InputInfoList &Inputs,
228                           const ArgStringList &OutputArgs) const;
229    void AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
230                           const InputInfoList &Inputs,
231                           const ArgStringList &OutputArgs) const;
232    void AddCPPUniqueOptionsArgs(const ArgList &Args,
233                                 ArgStringList &CmdArgs,
234                                 const InputInfoList &Inputs) const;
235    void AddCPPArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
236
237  public:
238    CC1(const char *Name, const char *ShortName,
239        const ToolChain &TC) : DarwinTool(Name, ShortName, TC) {}
240
241    virtual bool hasGoodDiagnostics() const { return true; }
242    virtual bool hasIntegratedCPP() const { return true; }
243  };
244
245  class LLVM_LIBRARY_VISIBILITY Preprocess : public CC1  {
246  public:
247    Preprocess(const ToolChain &TC) : CC1("darwin::Preprocess",
248                                          "gcc preprocessor", TC) {}
249
250    virtual void ConstructJob(Compilation &C, const JobAction &JA,
251                              const InputInfo &Output,
252                              const InputInfoList &Inputs,
253                              const ArgList &TCArgs,
254                              const char *LinkingOutput) const;
255  };
256
257  class LLVM_LIBRARY_VISIBILITY Compile : public CC1  {
258  public:
259    Compile(const ToolChain &TC) : CC1("darwin::Compile", "gcc frontend", TC) {}
260
261    virtual void ConstructJob(Compilation &C, const JobAction &JA,
262                              const InputInfo &Output,
263                              const InputInfoList &Inputs,
264                              const ArgList &TCArgs,
265                              const char *LinkingOutput) const;
266  };
267
268  class LLVM_LIBRARY_VISIBILITY Assemble : public DarwinTool  {
269  public:
270    Assemble(const ToolChain &TC) : DarwinTool("darwin::Assemble",
271                                               "assembler", TC) {}
272
273    virtual bool hasIntegratedCPP() const { return false; }
274
275    virtual void ConstructJob(Compilation &C, const JobAction &JA,
276                              const InputInfo &Output,
277                              const InputInfoList &Inputs,
278                              const ArgList &TCArgs,
279                              const char *LinkingOutput) const;
280  };
281
282  class LLVM_LIBRARY_VISIBILITY Link : public DarwinTool  {
283    void AddLinkArgs(Compilation &C, const ArgList &Args,
284                     ArgStringList &CmdArgs) const;
285
286  public:
287    Link(const ToolChain &TC) : DarwinTool("darwin::Link", "linker", TC) {}
288
289    virtual bool hasIntegratedCPP() const { return false; }
290    virtual bool isLinkJob() const { return true; }
291
292    virtual void ConstructJob(Compilation &C, const JobAction &JA,
293                              const InputInfo &Output,
294                              const InputInfoList &Inputs,
295                              const ArgList &TCArgs,
296                              const char *LinkingOutput) const;
297  };
298
299  class LLVM_LIBRARY_VISIBILITY Lipo : public DarwinTool  {
300  public:
301    Lipo(const ToolChain &TC) : DarwinTool("darwin::Lipo", "lipo", TC) {}
302
303    virtual bool hasIntegratedCPP() const { return false; }
304
305    virtual void ConstructJob(Compilation &C, const JobAction &JA,
306                              const InputInfo &Output,
307                              const InputInfoList &Inputs,
308                              const ArgList &TCArgs,
309                              const char *LinkingOutput) const;
310  };
311
312  class LLVM_LIBRARY_VISIBILITY Dsymutil : public DarwinTool  {
313  public:
314    Dsymutil(const ToolChain &TC) : DarwinTool("darwin::Dsymutil",
315                                               "dsymutil", TC) {}
316
317    virtual bool hasIntegratedCPP() const { return false; }
318
319    virtual void ConstructJob(Compilation &C, const JobAction &JA,
320                              const InputInfo &Output,
321                              const InputInfoList &Inputs,
322                              const ArgList &TCArgs,
323                              const char *LinkingOutput) const;
324  };
325
326  class LLVM_LIBRARY_VISIBILITY VerifyDebug : public DarwinTool  {
327  public:
328    VerifyDebug(const ToolChain &TC) : DarwinTool("darwin::VerifyDebug",
329						  "dwarfdump", TC) {}
330
331    virtual bool hasIntegratedCPP() const { return false; }
332
333    virtual void ConstructJob(Compilation &C, const JobAction &JA,
334			      const InputInfo &Output,
335			      const InputInfoList &Inputs,
336			      const ArgList &TCArgs,
337			      const char *LinkingOutput) const;
338  };
339
340}
341
342  /// openbsd -- Directly call GNU Binutils assembler and linker
343namespace openbsd {
344  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
345  public:
346    Assemble(const ToolChain &TC) : Tool("openbsd::Assemble", "assembler",
347                                         TC) {}
348
349    virtual bool hasIntegratedCPP() const { return false; }
350
351    virtual void ConstructJob(Compilation &C, const JobAction &JA,
352                              const InputInfo &Output,
353                              const InputInfoList &Inputs,
354                              const ArgList &TCArgs,
355                              const char *LinkingOutput) const;
356  };
357  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
358  public:
359    Link(const ToolChain &TC) : Tool("openbsd::Link", "linker", TC) {}
360
361    virtual bool hasIntegratedCPP() const { return false; }
362    virtual bool isLinkJob() const { return true; }
363
364    virtual void ConstructJob(Compilation &C, const JobAction &JA,
365                              const InputInfo &Output,
366                              const InputInfoList &Inputs,
367                              const ArgList &TCArgs,
368                              const char *LinkingOutput) const;
369  };
370} // end namespace openbsd
371
372  /// freebsd -- Directly call GNU Binutils assembler and linker
373namespace freebsd {
374  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
375  public:
376    Assemble(const ToolChain &TC) : Tool("freebsd::Assemble", "assembler",
377                                         TC) {}
378
379    virtual bool hasIntegratedCPP() const { return false; }
380
381    virtual void ConstructJob(Compilation &C, const JobAction &JA,
382                              const InputInfo &Output,
383                              const InputInfoList &Inputs,
384                              const ArgList &TCArgs,
385                              const char *LinkingOutput) const;
386  };
387  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
388  public:
389    Link(const ToolChain &TC) : Tool("freebsd::Link", "linker", TC) {}
390
391    virtual bool hasIntegratedCPP() const { return false; }
392    virtual bool isLinkJob() const { return true; }
393
394    virtual void ConstructJob(Compilation &C, const JobAction &JA,
395                              const InputInfo &Output,
396                              const InputInfoList &Inputs,
397                              const ArgList &TCArgs,
398                              const char *LinkingOutput) const;
399  };
400} // end namespace freebsd
401
402  /// netbsd -- Directly call GNU Binutils assembler and linker
403namespace netbsd {
404  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
405
406  public:
407    Assemble(const ToolChain &TC)
408      : Tool("netbsd::Assemble", "assembler", TC) {}
409
410    virtual bool hasIntegratedCPP() const { return false; }
411
412    virtual void ConstructJob(Compilation &C, const JobAction &JA,
413                              const InputInfo &Output,
414                              const InputInfoList &Inputs,
415                              const ArgList &TCArgs,
416                              const char *LinkingOutput) const;
417  };
418  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
419
420  public:
421    Link(const ToolChain &TC)
422      : Tool("netbsd::Link", "linker", TC) {}
423
424    virtual bool hasIntegratedCPP() const { return false; }
425    virtual bool isLinkJob() const { return true; }
426
427    virtual void ConstructJob(Compilation &C, const JobAction &JA,
428                              const InputInfo &Output,
429                              const InputInfoList &Inputs,
430                              const ArgList &TCArgs,
431                              const char *LinkingOutput) const;
432  };
433} // end namespace netbsd
434
435  /// linux -- Directly call GNU Binutils assembler and linker
436namespace linuxtools {
437  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
438  public:
439    Assemble(const ToolChain &TC) : Tool("linux::Assemble", "assembler",
440                                         TC) {}
441
442    virtual bool hasIntegratedCPP() const { return false; }
443
444    virtual void ConstructJob(Compilation &C, const JobAction &JA,
445                              const InputInfo &Output,
446                              const InputInfoList &Inputs,
447                              const ArgList &TCArgs,
448                              const char *LinkingOutput) const;
449  };
450  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
451  public:
452    Link(const ToolChain &TC) : Tool("linux::Link", "linker", TC) {}
453
454    virtual bool hasIntegratedCPP() const { return false; }
455    virtual bool isLinkJob() const { return true; }
456
457    virtual void ConstructJob(Compilation &C, const JobAction &JA,
458                              const InputInfo &Output,
459                              const InputInfoList &Inputs,
460                              const ArgList &TCArgs,
461                              const char *LinkingOutput) const;
462  };
463}
464  /// minix -- Directly call GNU Binutils assembler and linker
465namespace minix {
466  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
467  public:
468    Assemble(const ToolChain &TC) : Tool("minix::Assemble", "assembler",
469                                         TC) {}
470
471    virtual bool hasIntegratedCPP() const { return false; }
472
473    virtual void ConstructJob(Compilation &C, const JobAction &JA,
474                              const InputInfo &Output,
475                              const InputInfoList &Inputs,
476                              const ArgList &TCArgs,
477                              const char *LinkingOutput) const;
478  };
479  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
480  public:
481    Link(const ToolChain &TC) : Tool("minix::Link", "linker", TC) {}
482
483    virtual bool hasIntegratedCPP() const { return false; }
484    virtual bool isLinkJob() const { return true; }
485
486    virtual void ConstructJob(Compilation &C, const JobAction &JA,
487                              const InputInfo &Output,
488                              const InputInfoList &Inputs,
489                              const ArgList &TCArgs,
490                              const char *LinkingOutput) const;
491  };
492} // end namespace minix
493
494  /// solaris -- Directly call Solaris assembler and linker
495namespace solaris {
496  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
497  public:
498    Assemble(const ToolChain &TC) : Tool("solaris::Assemble", "assembler",
499                                         TC) {}
500
501    virtual bool hasIntegratedCPP() const { return false; }
502
503    virtual void ConstructJob(Compilation &C, const JobAction &JA,
504                              const InputInfo &Output,
505                              const InputInfoList &Inputs,
506                              const ArgList &TCArgs,
507                              const char *LinkingOutput) const;
508  };
509  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
510  public:
511    Link(const ToolChain &TC) : Tool("solaris::Link", "linker", TC) {}
512
513    virtual bool hasIntegratedCPP() const { return false; }
514    virtual bool isLinkJob() const { return true; }
515
516    virtual void ConstructJob(Compilation &C, const JobAction &JA,
517                              const InputInfo &Output,
518                              const InputInfoList &Inputs,
519                              const ArgList &TCArgs,
520                              const char *LinkingOutput) const;
521  };
522} // end namespace solaris
523
524  /// auroraux -- Directly call GNU Binutils assembler and linker
525namespace auroraux {
526  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
527  public:
528    Assemble(const ToolChain &TC) : Tool("auroraux::Assemble", "assembler",
529                                         TC) {}
530
531    virtual bool hasIntegratedCPP() const { return false; }
532
533    virtual void ConstructJob(Compilation &C, const JobAction &JA,
534                              const InputInfo &Output,
535                              const InputInfoList &Inputs,
536                              const ArgList &TCArgs,
537                              const char *LinkingOutput) const;
538  };
539  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
540  public:
541    Link(const ToolChain &TC) : Tool("auroraux::Link", "linker", TC) {}
542
543    virtual bool hasIntegratedCPP() const { return false; }
544    virtual bool isLinkJob() const { return true; }
545
546    virtual void ConstructJob(Compilation &C, const JobAction &JA,
547                              const InputInfo &Output,
548                              const InputInfoList &Inputs,
549                              const ArgList &TCArgs,
550                              const char *LinkingOutput) const;
551  };
552} // end namespace auroraux
553
554  /// dragonfly -- Directly call GNU Binutils assembler and linker
555namespace dragonfly {
556  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
557  public:
558    Assemble(const ToolChain &TC) : Tool("dragonfly::Assemble", "assembler",
559                                         TC) {}
560
561    virtual bool hasIntegratedCPP() const { return false; }
562
563    virtual void ConstructJob(Compilation &C, const JobAction &JA,
564                              const InputInfo &Output,
565                              const InputInfoList &Inputs,
566                              const ArgList &TCArgs,
567                              const char *LinkingOutput) const;
568  };
569  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
570  public:
571    Link(const ToolChain &TC) : Tool("dragonfly::Link", "linker", TC) {}
572
573    virtual bool hasIntegratedCPP() const { return false; }
574    virtual bool isLinkJob() const { return true; }
575
576    virtual void ConstructJob(Compilation &C, const JobAction &JA,
577                              const InputInfo &Output,
578                              const InputInfoList &Inputs,
579                              const ArgList &TCArgs,
580                              const char *LinkingOutput) const;
581  };
582} // end namespace dragonfly
583
584  /// Visual studio tools.
585namespace visualstudio {
586  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
587  public:
588    Link(const ToolChain &TC) : Tool("visualstudio::Link", "linker", TC) {}
589
590    virtual bool hasIntegratedCPP() const { return false; }
591    virtual bool isLinkJob() const { return true; }
592
593    virtual void ConstructJob(Compilation &C, const JobAction &JA,
594                              const InputInfo &Output,
595                              const InputInfoList &Inputs,
596                              const ArgList &TCArgs,
597                              const char *LinkingOutput) const;
598  };
599} // end namespace visualstudio
600
601} // end namespace toolchains
602} // end namespace driver
603} // end namespace clang
604
605#endif // CLANG_LIB_DRIVER_TOOLS_H_
606