LLVM 22.0.0git
Twine.h
Go to the documentation of this file.
1//===- Twine.h - Fast Temporary String Concatenation ------------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_ADT_TWINE_H
10#define LLVM_ADT_TWINE_H
11
13#include "llvm/ADT/StringRef.h"
16#include <cassert>
17#include <cstdint>
18#include <string>
19#include <string_view>
20
21namespace llvm {
22
24class raw_ostream;
25
26/// Twine - A lightweight data structure for efficiently representing the
27/// concatenation of temporary values as strings.
28///
29/// A Twine is a kind of rope, it represents a concatenated string using a
30/// binary-tree, where the string is the preorder of the nodes. Since the
31/// Twine can be efficiently rendered into a buffer when its result is used,
32/// it avoids the cost of generating temporary values for intermediate string
33/// results -- particularly in cases when the Twine result is never
34/// required. By explicitly tracking the type of leaf nodes, we can also avoid
35/// the creation of temporary strings for conversions operations (such as
36/// appending an integer to a string).
37///
38/// A Twine is not intended for use directly and should not be stored, its
39/// implementation relies on the ability to store pointers to temporary stack
40/// objects which may be deallocated at the end of a statement. Twines should
41/// only be used as const references in arguments, when an API wishes
42/// to accept possibly-concatenated strings.
43///
44/// Twines support a special 'null' value, which always concatenates to form
45/// itself, and renders as an empty string. This can be returned from APIs to
46/// effectively nullify any concatenations performed on the result.
47///
48/// \b Implementation
49///
50/// Given the nature of a Twine, it is not possible for the Twine's
51/// concatenation method to construct interior nodes; the result must be
52/// represented inside the returned value. For this reason a Twine object
53/// actually holds two values, the left- and right-hand sides of a
54/// concatenation. We also have nullary Twine objects, which are effectively
55/// sentinel values that represent empty strings.
56///
57/// Thus, a Twine can effectively have zero, one, or two children. The \see
58/// isNullary(), \see isUnary(), and \see isBinary() predicates exist for
59/// testing the number of children.
60///
61/// We maintain a number of invariants on Twine objects (FIXME: Why):
62/// - Nullary twines are always represented with their Kind on the left-hand
63/// side, and the Empty kind on the right-hand side.
64/// - Unary twines are always represented with the value on the left-hand
65/// side, and the Empty kind on the right-hand side.
66/// - If a Twine has another Twine as a child, that child should always be
67/// binary (otherwise it could have been folded into the parent).
68///
69/// These invariants are check by \see isValid().
70///
71/// \b Efficiency Considerations
72///
73/// The Twine is designed to yield efficient and small code for common
74/// situations. For this reason, the concat() method is inlined so that
75/// concatenations of leaf nodes can be optimized into stores directly into a
76/// single stack allocated object.
77///
78/// In practice, not all compilers can be trusted to optimize concat() fully,
79/// so we provide two additional methods (and accompanying operator+
80/// overloads) to guarantee that particularly important cases (cstring plus
81/// StringRef) codegen as desired.
82class Twine {
83 /// NodeKind - Represent the type of an argument.
84 enum NodeKind : unsigned char {
85 /// An empty string; the result of concatenating anything with it is also
86 /// empty.
87 NullKind,
88
89 /// The empty string.
90 EmptyKind,
91
92 /// A pointer to a Twine instance.
93 TwineKind,
94
95 /// A pointer to a C string instance.
96 CStringKind,
97
98 /// A pointer to an std::string instance.
99 StdStringKind,
100
101 /// A Pointer and Length representation. Used for std::string_view,
102 /// StringRef, and SmallString. Can't use a StringRef here
103 /// because they are not trivally constructible.
104 PtrAndLengthKind,
105
106 /// A pointer and length representation that's also null-terminated.
107 /// Guaranteed to be constructed from a compile-time string literal.
108 StringLiteralKind,
109
110 /// A pointer to a formatv_object_base instance.
111 FormatvObjectKind,
112
113 /// A char value, to render as a character.
114 CharKind,
115
116 /// An unsigned int value, to render as an unsigned decimal integer.
117 DecUIKind,
118
119 /// An int value, to render as a signed decimal integer.
120 DecIKind,
121
122 /// An unsigned long value, to render as an unsigned decimal integer.
123 DecULKind,
124
125 /// A long value, to render as a signed decimal integer.
126 DecLKind,
127
128 /// An unsigned long long value, to render as an unsigned decimal integer.
129 DecULLKind,
130
131 /// A long long value, to render as a signed decimal integer.
132 DecLLKind,
133
134 /// A uint64_t value, to render as an unsigned hexadecimal integer.
135 UHexKind
136 };
137
138 union Child {
139 const Twine *twine;
140 const char *cString;
141 const std::string *stdString;
142 struct {
143 const char *ptr;
144 size_t length;
145 } ptrAndLength;
146 const formatv_object_base *formatvObject;
147 char character;
148 unsigned int decUI;
149 int decI;
150 unsigned long decUL;
151 long decL;
152 unsigned long long decULL;
153 long long decLL;
154 uint64_t uHex;
155 };
156
157 /// LHS - The prefix in the concatenation, which may be uninitialized for
158 /// Null or Empty kinds.
159 Child LHS;
160
161 /// RHS - The suffix in the concatenation, which may be uninitialized for
162 /// Null or Empty kinds.
163 Child RHS;
164
165 /// LHSKind - The NodeKind of the left hand side, \see getLHSKind().
166 NodeKind LHSKind = EmptyKind;
167
168 /// RHSKind - The NodeKind of the right hand side, \see getRHSKind().
169 NodeKind RHSKind = EmptyKind;
170
171 /// Construct a nullary twine; the kind must be NullKind or EmptyKind.
172 explicit Twine(NodeKind Kind) : LHSKind(Kind) {
173 assert(isNullary() && "Invalid kind!");
174 }
175
176 /// Construct a binary twine.
177 explicit Twine(const Twine &LHS, const Twine &RHS)
178 : LHSKind(TwineKind), RHSKind(TwineKind) {
179 this->LHS.twine = &LHS;
180 this->RHS.twine = &RHS;
181 assert(isValid() && "Invalid twine!");
182 }
183
184 /// Construct a twine from explicit values.
185 explicit Twine(Child LHS, NodeKind LHSKind, Child RHS, NodeKind RHSKind)
186 : LHS(LHS), RHS(RHS), LHSKind(LHSKind), RHSKind(RHSKind) {
187 assert(isValid() && "Invalid twine!");
188 }
189
190 /// Check for the null twine.
191 bool isNull() const { return getLHSKind() == NullKind; }
192
193 /// Check for the empty twine.
194 bool isEmpty() const { return getLHSKind() == EmptyKind; }
195
196 /// Check if this is a nullary twine (null or empty).
197 bool isNullary() const { return isNull() || isEmpty(); }
198
199 /// Check if this is a unary twine.
200 bool isUnary() const { return getRHSKind() == EmptyKind && !isNullary(); }
201
202 /// Check if this is a binary twine.
203 bool isBinary() const {
204 return getLHSKind() != NullKind && getRHSKind() != EmptyKind;
205 }
206
207 /// Check if this is a valid twine (satisfying the invariants on
208 /// order and number of arguments).
209 bool isValid() const {
210 // Nullary twines always have Empty on the RHS.
211 if (isNullary() && getRHSKind() != EmptyKind)
212 return false;
213
214 // Null should never appear on the RHS.
215 if (getRHSKind() == NullKind)
216 return false;
217
218 // The RHS cannot be non-empty if the LHS is empty.
219 if (getRHSKind() != EmptyKind && getLHSKind() == EmptyKind)
220 return false;
221
222 // A twine child should always be binary.
223 if (getLHSKind() == TwineKind && !LHS.twine->isBinary())
224 return false;
225 if (getRHSKind() == TwineKind && !RHS.twine->isBinary())
226 return false;
227
228 return true;
229 }
230
231 /// Get the NodeKind of the left-hand side.
232 NodeKind getLHSKind() const { return LHSKind; }
233
234 /// Get the NodeKind of the right-hand side.
235 NodeKind getRHSKind() const { return RHSKind; }
236
237 /// Print one child from a twine.
238 void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const;
239
240 /// Print the representation of one child from a twine.
241 void printOneChildRepr(raw_ostream &OS, Child Ptr, NodeKind Kind) const;
242
243public:
244 /// @name Constructors
245 /// @{
246
247 /// Construct from an empty string.
248 /*implicit*/ Twine() { assert(isValid() && "Invalid twine!"); }
249
250 Twine(const Twine &) = default;
251
252 /// Construct from a C string.
253 ///
254 /// We take care here to optimize "" into the empty twine -- this will be
255 /// optimized out for string constants. This allows Twine arguments have
256 /// default "" values, without introducing unnecessary string constants.
257 /*implicit*/ Twine(const char *Str) {
258 if (Str[0] != '\0') {
259 LHS.cString = Str;
260 LHSKind = CStringKind;
261 } else {
262 LHSKind = EmptyKind;
263 }
264
265 assert(isValid() && "Invalid twine!");
266 }
267 /// Delete the implicit conversion from nullptr as Twine(const char *)
268 /// cannot take nullptr.
269 /*implicit*/ Twine(std::nullptr_t) = delete;
270
271 /// Construct from an std::string.
272 /*implicit*/ Twine(const std::string &Str) : LHSKind(StdStringKind) {
273 LHS.stdString = &Str;
274 assert(isValid() && "Invalid twine!");
275 }
276
277 /// Construct from an std::string_view by converting it to a pointer and
278 /// length. This handles string_views on a pure API basis, and avoids
279 /// storing one (or a pointer to one) inside a Twine, which avoids problems
280 /// when mixing code compiled under various C++ standards.
281 /*implicit*/ Twine(const std::string_view &Str) : LHSKind(PtrAndLengthKind) {
282 LHS.ptrAndLength.ptr = Str.data();
283 LHS.ptrAndLength.length = Str.length();
284 assert(isValid() && "Invalid twine!");
285 }
286
287 /// Construct from a StringRef.
288 /*implicit*/ Twine(const StringRef &Str) : LHSKind(PtrAndLengthKind) {
289 LHS.ptrAndLength.ptr = Str.data();
290 LHS.ptrAndLength.length = Str.size();
291 assert(isValid() && "Invalid twine!");
292 }
293
294 /// Construct from a StringLiteral.
295 /*implicit*/ Twine(const StringLiteral &Str) : LHSKind(StringLiteralKind) {
296 LHS.ptrAndLength.ptr = Str.data();
297 LHS.ptrAndLength.length = Str.size();
298 assert(isValid() && "Invalid twine!");
299 }
300
301 /// Construct from a SmallString.
302 /*implicit*/ Twine(const SmallVectorImpl<char> &Str)
303 : LHSKind(PtrAndLengthKind) {
304 LHS.ptrAndLength.ptr = Str.data();
305 LHS.ptrAndLength.length = Str.size();
306 assert(isValid() && "Invalid twine!");
307 }
308
309 /// Construct from a formatv_object_base.
310 /*implicit*/ Twine(const formatv_object_base &Fmt)
311 : LHSKind(FormatvObjectKind) {
312 LHS.formatvObject = &Fmt;
313 assert(isValid() && "Invalid twine!");
314 }
315
316 /// Construct from a char.
317 explicit Twine(char Val) : LHSKind(CharKind) { LHS.character = Val; }
318
319 /// Construct from a signed char.
320 explicit Twine(signed char Val) : LHSKind(CharKind) {
321 LHS.character = static_cast<char>(Val);
322 }
323
324 /// Construct from an unsigned char.
325 explicit Twine(unsigned char Val) : LHSKind(CharKind) {
326 LHS.character = static_cast<char>(Val);
327 }
328
329 /// Construct a twine to print \p Val as an unsigned decimal integer.
330 explicit Twine(unsigned Val) : LHSKind(DecUIKind) { LHS.decUI = Val; }
331
332 /// Construct a twine to print \p Val as a signed decimal integer.
333 explicit Twine(int Val) : LHSKind(DecIKind) { LHS.decI = Val; }
334
335 /// Construct a twine to print \p Val as an unsigned decimal integer.
336 explicit Twine(unsigned long Val) : LHSKind(DecULKind) { LHS.decUL = Val; }
337
338 /// Construct a twine to print \p Val as a signed decimal integer.
339 explicit Twine(long Val) : LHSKind(DecLKind) { LHS.decL = Val; }
340
341 /// Construct a twine to print \p Val as an unsigned decimal integer.
342 explicit Twine(unsigned long long Val) : LHSKind(DecULLKind) {
343 LHS.decULL = Val;
344 }
345
346 /// Construct a twine to print \p Val as a signed decimal integer.
347 explicit Twine(long long Val) : LHSKind(DecLLKind) { LHS.decLL = Val; }
348
349 // FIXME: Unfortunately, to make sure this is as efficient as possible we
350 // need extra binary constructors from particular types. We can't rely on
351 // the compiler to be smart enough to fold operator+()/concat() down to the
352 // right thing. Yet.
353
354 /// Construct as the concatenation of a C string and a StringRef.
355 /*implicit*/ Twine(const char *LHS, const StringRef &RHS)
356 : LHSKind(CStringKind), RHSKind(PtrAndLengthKind) {
357 this->LHS.cString = LHS;
358 this->RHS.ptrAndLength.ptr = RHS.data();
359 this->RHS.ptrAndLength.length = RHS.size();
360 assert(isValid() && "Invalid twine!");
361 }
362
363 /// Construct as the concatenation of a StringRef and a C string.
364 /*implicit*/ Twine(const StringRef &LHS, const char *RHS)
365 : LHSKind(PtrAndLengthKind), RHSKind(CStringKind) {
366 this->LHS.ptrAndLength.ptr = LHS.data();
367 this->LHS.ptrAndLength.length = LHS.size();
368 this->RHS.cString = RHS;
369 assert(isValid() && "Invalid twine!");
370 }
371
372 /// Since the intended use of twines is as temporary objects, assignments
373 /// when concatenating might cause undefined behavior or stack corruptions
374 Twine &operator=(const Twine &) = delete;
375
376 /// Create a 'null' string, which is an empty string that always
377 /// concatenates to form another empty string.
378 static Twine createNull() { return Twine(NullKind); }
379
380 /// @}
381 /// @name Numeric Conversions
382 /// @{
383
384 // Construct a twine to print \p Val as an unsigned hexadecimal integer.
385 static Twine utohexstr(uint64_t Val) {
386 Child LHS, RHS;
387 LHS.uHex = Val;
388 RHS.twine = nullptr;
389 return Twine(LHS, UHexKind, RHS, EmptyKind);
390 }
391
392 /// @}
393 /// @name Predicate Operations
394 /// @{
395
396 /// Check if this twine is trivially empty; a false return value does not
397 /// necessarily mean the twine is empty.
398 bool isTriviallyEmpty() const { return isNullary(); }
399
400 /// Check if this twine is guaranteed to refer to single string literal.
402 return isUnary() && getLHSKind() == StringLiteralKind;
403 }
404
405 /// Return true if this twine can be dynamically accessed as a single
406 /// StringRef value with getSingleStringRef().
407 bool isSingleStringRef() const {
408 if (getRHSKind() != EmptyKind)
409 return false;
410
411 switch (getLHSKind()) {
412 case EmptyKind:
413 case CStringKind:
414 case StdStringKind:
415 case PtrAndLengthKind:
416 case StringLiteralKind:
417 return true;
418 default:
419 return false;
420 }
421 }
422
423 /// @}
424 /// @name String Operations
425 /// @{
426
427 Twine concat(const Twine &Suffix) const;
428
429 /// @}
430 /// @name Output & Conversion.
431 /// @{
432
433 /// Return the twine contents as a std::string.
434 LLVM_ABI std::string str() const;
435
436 /// Append the concatenated string into the given SmallString or SmallVector.
437 LLVM_ABI void toVector(SmallVectorImpl<char> &Out) const;
438
439 /// This returns the twine as a single StringRef. This method is only valid
440 /// if isSingleStringRef() is true.
442 assert(isSingleStringRef() && "This cannot be had as a single stringref!");
443 switch (getLHSKind()) {
444 default:
445 llvm_unreachable("Out of sync with isSingleStringRef");
446 case EmptyKind:
447 return StringRef();
448 case CStringKind:
449 return StringRef(LHS.cString);
450 case StdStringKind:
451 return StringRef(*LHS.stdString);
452 case PtrAndLengthKind:
453 case StringLiteralKind:
454 return StringRef(LHS.ptrAndLength.ptr, LHS.ptrAndLength.length);
455 }
456 }
457
458 /// This returns the twine as a single StringRef if it can be
459 /// represented as such. Otherwise the twine is written into the given
460 /// SmallVector and a StringRef to the SmallVector's data is returned.
462 if (isSingleStringRef())
463 return getSingleStringRef();
464 toVector(Out);
465 return StringRef(Out.data(), Out.size());
466 }
467
468 /// This returns the twine as a single null terminated StringRef if it
469 /// can be represented as such. Otherwise the twine is written into the
470 /// given SmallVector and a StringRef to the SmallVector's data is returned.
471 ///
472 /// The returned StringRef's size does not include the null terminator.
475
476 /// Write the concatenated string represented by this twine to the
477 /// stream \p OS.
478 LLVM_ABI void print(raw_ostream &OS) const;
479
480 /// Write the representation of this twine to the stream \p OS.
481 LLVM_ABI void printRepr(raw_ostream &OS) const;
482
483#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
484 /// Dump the concatenated string represented by this twine to stderr.
485 LLVM_DUMP_METHOD void dump() const;
486
487 /// Dump the representation of this twine to stderr.
488 LLVM_DUMP_METHOD void dumpRepr() const;
489#endif
490
491 /// @}
492};
493
494/// @name Twine Inline Implementations
495/// @{
496
497inline Twine Twine::concat(const Twine &Suffix) const {
498 // Concatenation with null is null.
499 if (isNull() || Suffix.isNull())
500 return Twine(NullKind);
501
502 // Concatenation with empty yields the other side.
503 if (isEmpty())
504 return Suffix;
505 if (Suffix.isEmpty())
506 return *this;
507
508 // Otherwise we need to create a new node, taking care to fold in unary
509 // twines.
510 Child NewLHS, NewRHS;
511 NewLHS.twine = this;
512 NewRHS.twine = &Suffix;
513 NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind;
514 if (isUnary()) {
515 NewLHS = LHS;
516 NewLHSKind = getLHSKind();
517 }
518 if (Suffix.isUnary()) {
519 NewRHS = Suffix.LHS;
520 NewRHSKind = Suffix.getLHSKind();
521 }
522
523 return Twine(NewLHS, NewLHSKind, NewRHS, NewRHSKind);
524}
525
526inline Twine operator+(const Twine &LHS, const Twine &RHS) {
527 return LHS.concat(RHS);
528}
529
530/// Additional overload to guarantee simplified codegen; this is equivalent to
531/// concat().
532
533inline Twine operator+(const char *LHS, const StringRef &RHS) {
534 return Twine(LHS, RHS);
535}
536
537/// Additional overload to guarantee simplified codegen; this is equivalent to
538/// concat().
539
540inline Twine operator+(const StringRef &LHS, const char *RHS) {
541 return Twine(LHS, RHS);
542}
543
545 RHS.print(OS);
546 return OS;
547}
548
549/// @}
550
551} // end namespace llvm
552
553#endif // LLVM_ADT_TWINE_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_ABI
Definition Compiler.h:213
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:638
This file defines the SmallVector class.
Value * RHS
Value * LHS
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
pointer data()
Return a pointer to the vector's buffer, even if empty().
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition StringRef.h:862
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
constexpr size_t size() const
size - Get the string size.
Definition StringRef.h:154
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition StringRef.h:148
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
Twine()
Construct from an empty string.
Definition Twine.h:248
Twine(const formatv_object_base &Fmt)
Construct from a formatv_object_base.
Definition Twine.h:310
Twine & operator=(const Twine &)=delete
Since the intended use of twines is as temporary objects, assignments when concatenating might cause ...
bool isSingleStringRef() const
Return true if this twine can be dynamically accessed as a single StringRef value with getSingleStrin...
Definition Twine.h:407
Twine(long Val)
Construct a twine to print Val as a signed decimal integer.
Definition Twine.h:339
Twine(const SmallVectorImpl< char > &Str)
Construct from a SmallString.
Definition Twine.h:302
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
Definition Twine.cpp:17
Twine(unsigned long long Val)
Construct a twine to print Val as an unsigned decimal integer.
Definition Twine.h:342
Twine concat(const Twine &Suffix) const
Definition Twine.h:497
Twine(unsigned Val)
Construct a twine to print Val as an unsigned decimal integer.
Definition Twine.h:330
LLVM_ABI void print(raw_ostream &OS) const
Write the concatenated string represented by this twine to the stream OS.
Definition Twine.cpp:164
LLVM_ABI StringRef toNullTerminatedStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single null terminated StringRef if it can be represented as such.
Definition Twine.cpp:37
Twine(const std::string &Str)
Construct from an std::string.
Definition Twine.h:272
Twine(unsigned char Val)
Construct from an unsigned char.
Definition Twine.h:325
LLVM_DUMP_METHOD void dump() const
Dump the concatenated string represented by this twine to stderr.
Definition Twine.cpp:178
Twine(const char *LHS, const StringRef &RHS)
Construct as the concatenation of a C string and a StringRef.
Definition Twine.h:355
Twine(std::nullptr_t)=delete
Delete the implicit conversion from nullptr as Twine(const char *) cannot take nullptr.
bool isTriviallyEmpty() const
Check if this twine is trivially empty; a false return value does not necessarily mean the twine is e...
Definition Twine.h:398
bool isSingleStringLiteral() const
Check if this twine is guaranteed to refer to single string literal.
Definition Twine.h:401
static Twine createNull()
Create a 'null' string, which is an empty string that always concatenates to form another empty strin...
Definition Twine.h:378
LLVM_ABI void printRepr(raw_ostream &OS) const
Write the representation of this twine to the stream OS.
Definition Twine.cpp:169
Twine(signed char Val)
Construct from a signed char.
Definition Twine.h:320
Twine(const Twine &)=default
Twine(const std::string_view &Str)
Construct from an std::string_view by converting it to a pointer and length.
Definition Twine.h:281
Twine(const StringLiteral &Str)
Construct from a StringLiteral.
Definition Twine.h:295
Twine(long long Val)
Construct a twine to print Val as a signed decimal integer.
Definition Twine.h:347
Twine(const StringRef &LHS, const char *RHS)
Construct as the concatenation of a StringRef and a C string.
Definition Twine.h:364
StringRef toStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single StringRef if it can be represented as such.
Definition Twine.h:461
Twine(int Val)
Construct a twine to print Val as a signed decimal integer.
Definition Twine.h:333
Twine(const StringRef &Str)
Construct from a StringRef.
Definition Twine.h:288
StringRef getSingleStringRef() const
This returns the twine as a single StringRef.
Definition Twine.h:441
static Twine utohexstr(uint64_t Val)
Definition Twine.h:385
Twine(unsigned long Val)
Construct a twine to print Val as an unsigned decimal integer.
Definition Twine.h:336
LLVM_ABI void toVector(SmallVectorImpl< char > &Out) const
Append the concatenated string into the given SmallString or SmallVector.
Definition Twine.cpp:32
Twine(char Val)
Construct from a char.
Definition Twine.h:317
LLVM_DUMP_METHOD void dumpRepr() const
Dump the representation of this twine to stderr.
Definition Twine.cpp:180
Twine(const char *Str)
Construct from a C string.
Definition Twine.h:257
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
APInt operator+(APInt a, const APInt &b)
Definition APInt.h:2193