1 //===- TableGenBackend.cpp - Utilities for TableGen Backends ----*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file provides useful services for TableGen backends...
11 //===----------------------------------------------------------------------===//
13 #include "llvm/TableGen/TableGenBackend.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/Support/CommandLine.h"
16 #include "llvm/Support/ManagedStatic.h"
17 #include "llvm/Support/Path.h"
18 #include "llvm/Support/raw_ostream.h"
24 using namespace TableGen::Emitter
;
26 const size_t MAX_LINE_LEN
= 80U;
28 // CommandLine options of class type are not directly supported with some
29 // specific exceptions like std::string which are safe to copy. In our case,
30 // the `FnT` function_ref object is also safe to copy. So provide a
31 // specialization of `OptionValue` for `FnT` type that stores it as a copy.
32 // This is essentially similar to OptionValue<std::string> specialization for
34 template <> struct cl::OptionValue
<FnT
> final
: cl::OptionValueCopy
<FnT
> {
35 OptionValue() = default;
37 OptionValue(const FnT
&V
) { this->setValue(V
); }
39 OptionValue
<FnT
> &operator=(const FnT
&V
) {
48 return new cl::opt
<FnT
>(cl::desc("Action to perform:"));
53 static ManagedStatic
<cl::opt
<FnT
>, OptCreatorT
> CallbackFunction
;
55 Opt::Opt(StringRef Name
, FnT CB
, StringRef Desc
, bool ByDefault
) {
57 CallbackFunction
->setInitialValue(CB
);
58 CallbackFunction
->getParser().addLiteralOption(Name
, CB
, Desc
);
61 /// Apply callback specified on the command line. Returns true if no callback
63 bool llvm::TableGen::Emitter::ApplyCallback(const RecordKeeper
&Records
,
65 FnT Fn
= CallbackFunction
->getValue();
72 static void printLine(raw_ostream
&OS
, const Twine
&Prefix
, char Fill
,
74 size_t Pos
= (size_t)OS
.tell();
75 assert((Prefix
.str().size() + Suffix
.size() <= MAX_LINE_LEN
) &&
76 "header line exceeds max limit");
78 for (size_t i
= (size_t)OS
.tell() - Pos
, e
= MAX_LINE_LEN
- Suffix
.size();
84 void llvm::emitSourceFileHeader(StringRef Desc
, raw_ostream
&OS
,
85 const RecordKeeper
&Record
) {
86 printLine(OS
, "/*===- TableGen'erated file ", '-', "*- C++ -*-===*\\");
87 StringRef
Prefix("|* ");
88 StringRef
Suffix(" *|");
89 printLine(OS
, Prefix
, ' ', Suffix
);
90 size_t PSLen
= Prefix
.size() + Suffix
.size();
91 assert(PSLen
< MAX_LINE_LEN
);
94 size_t Length
= std::min(Desc
.size() - Pos
, MAX_LINE_LEN
- PSLen
);
95 printLine(OS
, Prefix
+ Desc
.substr(Pos
, Length
), ' ', Suffix
);
97 } while (Pos
< Desc
.size());
98 printLine(OS
, Prefix
, ' ', Suffix
);
99 printLine(OS
, Prefix
+ "Automatically generated file, do not edit!", ' ',
102 // Print the filename of source file.
103 if (!Record
.getInputFilename().empty())
105 OS
, Prefix
+ "From: " + sys::path::filename(Record
.getInputFilename()),
107 printLine(OS
, Prefix
, ' ', Suffix
);
108 printLine(OS
, "\\*===", '-', "===*/");