File indexing completed on 2026-05-10 08:43:10
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_ADT_TWINE_H
0010 #define LLVM_ADT_TWINE_H
0011
0012 #include "llvm/ADT/SmallVector.h"
0013 #include "llvm/ADT/StringRef.h"
0014 #include "llvm/Support/ErrorHandling.h"
0015 #include <cassert>
0016 #include <cstdint>
0017 #include <string>
0018 #include <string_view>
0019
0020 namespace llvm {
0021
0022 class formatv_object_base;
0023 class raw_ostream;
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 class Twine {
0082
0083 enum NodeKind : unsigned char {
0084
0085
0086 NullKind,
0087
0088
0089 EmptyKind,
0090
0091
0092 TwineKind,
0093
0094
0095 CStringKind,
0096
0097
0098 StdStringKind,
0099
0100
0101
0102
0103 PtrAndLengthKind,
0104
0105
0106
0107 StringLiteralKind,
0108
0109
0110 FormatvObjectKind,
0111
0112
0113 CharKind,
0114
0115
0116 DecUIKind,
0117
0118
0119 DecIKind,
0120
0121
0122
0123 DecULKind,
0124
0125
0126 DecLKind,
0127
0128
0129
0130 DecULLKind,
0131
0132
0133 DecLLKind,
0134
0135
0136
0137 UHexKind
0138 };
0139
0140 union Child
0141 {
0142 const Twine *twine;
0143 const char *cString;
0144 const std::string *stdString;
0145 struct {
0146 const char *ptr;
0147 size_t length;
0148 } ptrAndLength;
0149 const formatv_object_base *formatvObject;
0150 char character;
0151 unsigned int decUI;
0152 int decI;
0153 const unsigned long *decUL;
0154 const long *decL;
0155 const unsigned long long *decULL;
0156 const long long *decLL;
0157 const uint64_t *uHex;
0158 };
0159
0160
0161
0162 Child LHS;
0163
0164
0165
0166 Child RHS;
0167
0168
0169 NodeKind LHSKind = EmptyKind;
0170
0171
0172 NodeKind RHSKind = EmptyKind;
0173
0174
0175 explicit Twine(NodeKind Kind) : LHSKind(Kind) {
0176 assert(isNullary() && "Invalid kind!");
0177 }
0178
0179
0180 explicit Twine(const Twine &LHS, const Twine &RHS)
0181 : LHSKind(TwineKind), RHSKind(TwineKind) {
0182 this->LHS.twine = &LHS;
0183 this->RHS.twine = &RHS;
0184 assert(isValid() && "Invalid twine!");
0185 }
0186
0187
0188 explicit Twine(Child LHS, NodeKind LHSKind, Child RHS, NodeKind RHSKind)
0189 : LHS(LHS), RHS(RHS), LHSKind(LHSKind), RHSKind(RHSKind) {
0190 assert(isValid() && "Invalid twine!");
0191 }
0192
0193
0194 bool isNull() const {
0195 return getLHSKind() == NullKind;
0196 }
0197
0198
0199 bool isEmpty() const {
0200 return getLHSKind() == EmptyKind;
0201 }
0202
0203
0204 bool isNullary() const {
0205 return isNull() || isEmpty();
0206 }
0207
0208
0209 bool isUnary() const {
0210 return getRHSKind() == EmptyKind && !isNullary();
0211 }
0212
0213
0214 bool isBinary() const {
0215 return getLHSKind() != NullKind && getRHSKind() != EmptyKind;
0216 }
0217
0218
0219
0220 bool isValid() const {
0221
0222 if (isNullary() && getRHSKind() != EmptyKind)
0223 return false;
0224
0225
0226 if (getRHSKind() == NullKind)
0227 return false;
0228
0229
0230 if (getRHSKind() != EmptyKind && getLHSKind() == EmptyKind)
0231 return false;
0232
0233
0234 if (getLHSKind() == TwineKind &&
0235 !LHS.twine->isBinary())
0236 return false;
0237 if (getRHSKind() == TwineKind &&
0238 !RHS.twine->isBinary())
0239 return false;
0240
0241 return true;
0242 }
0243
0244
0245 NodeKind getLHSKind() const { return LHSKind; }
0246
0247
0248 NodeKind getRHSKind() const { return RHSKind; }
0249
0250
0251 void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const;
0252
0253
0254 void printOneChildRepr(raw_ostream &OS, Child Ptr,
0255 NodeKind Kind) const;
0256
0257 public:
0258
0259
0260
0261
0262 Twine() {
0263 assert(isValid() && "Invalid twine!");
0264 }
0265
0266 Twine(const Twine &) = default;
0267
0268
0269
0270
0271
0272
0273 Twine(const char *Str) {
0274 if (Str[0] != '\0') {
0275 LHS.cString = Str;
0276 LHSKind = CStringKind;
0277 } else
0278 LHSKind = EmptyKind;
0279
0280 assert(isValid() && "Invalid twine!");
0281 }
0282
0283
0284 Twine(std::nullptr_t) = delete;
0285
0286
0287 Twine(const std::string &Str) : LHSKind(StdStringKind) {
0288 LHS.stdString = &Str;
0289 assert(isValid() && "Invalid twine!");
0290 }
0291
0292
0293
0294
0295
0296 Twine(const std::string_view &Str)
0297 : LHSKind(PtrAndLengthKind) {
0298 LHS.ptrAndLength.ptr = Str.data();
0299 LHS.ptrAndLength.length = Str.length();
0300 assert(isValid() && "Invalid twine!");
0301 }
0302
0303
0304 Twine(const StringRef &Str) : LHSKind(PtrAndLengthKind) {
0305 LHS.ptrAndLength.ptr = Str.data();
0306 LHS.ptrAndLength.length = Str.size();
0307 assert(isValid() && "Invalid twine!");
0308 }
0309
0310
0311 Twine(const StringLiteral &Str)
0312 : LHSKind(StringLiteralKind) {
0313 LHS.ptrAndLength.ptr = Str.data();
0314 LHS.ptrAndLength.length = Str.size();
0315 assert(isValid() && "Invalid twine!");
0316 }
0317
0318
0319 Twine(const SmallVectorImpl<char> &Str)
0320 : LHSKind(PtrAndLengthKind) {
0321 LHS.ptrAndLength.ptr = Str.data();
0322 LHS.ptrAndLength.length = Str.size();
0323 assert(isValid() && "Invalid twine!");
0324 }
0325
0326
0327 Twine(const formatv_object_base &Fmt)
0328 : LHSKind(FormatvObjectKind) {
0329 LHS.formatvObject = &Fmt;
0330 assert(isValid() && "Invalid twine!");
0331 }
0332
0333
0334 explicit Twine(char Val) : LHSKind(CharKind) {
0335 LHS.character = Val;
0336 }
0337
0338
0339 explicit Twine(signed char Val) : LHSKind(CharKind) {
0340 LHS.character = static_cast<char>(Val);
0341 }
0342
0343
0344 explicit Twine(unsigned char Val) : LHSKind(CharKind) {
0345 LHS.character = static_cast<char>(Val);
0346 }
0347
0348
0349 explicit Twine(unsigned Val) : LHSKind(DecUIKind) {
0350 LHS.decUI = Val;
0351 }
0352
0353
0354 explicit Twine(int Val) : LHSKind(DecIKind) {
0355 LHS.decI = Val;
0356 }
0357
0358
0359 explicit Twine(const unsigned long &Val) : LHSKind(DecULKind) {
0360 LHS.decUL = &Val;
0361 }
0362
0363
0364 explicit Twine(const long &Val) : LHSKind(DecLKind) {
0365 LHS.decL = &Val;
0366 }
0367
0368
0369 explicit Twine(const unsigned long long &Val) : LHSKind(DecULLKind) {
0370 LHS.decULL = &Val;
0371 }
0372
0373
0374 explicit Twine(const long long &Val) : LHSKind(DecLLKind) {
0375 LHS.decLL = &Val;
0376 }
0377
0378
0379
0380
0381
0382
0383
0384 Twine(const char *LHS, const StringRef &RHS)
0385 : LHSKind(CStringKind), RHSKind(PtrAndLengthKind) {
0386 this->LHS.cString = LHS;
0387 this->RHS.ptrAndLength.ptr = RHS.data();
0388 this->RHS.ptrAndLength.length = RHS.size();
0389 assert(isValid() && "Invalid twine!");
0390 }
0391
0392
0393 Twine(const StringRef &LHS, const char *RHS)
0394 : LHSKind(PtrAndLengthKind), RHSKind(CStringKind) {
0395 this->LHS.ptrAndLength.ptr = LHS.data();
0396 this->LHS.ptrAndLength.length = LHS.size();
0397 this->RHS.cString = RHS;
0398 assert(isValid() && "Invalid twine!");
0399 }
0400
0401
0402
0403 Twine &operator=(const Twine &) = delete;
0404
0405
0406
0407 static Twine createNull() {
0408 return Twine(NullKind);
0409 }
0410
0411
0412
0413
0414
0415
0416 static Twine utohexstr(const uint64_t &Val) {
0417 Child LHS, RHS;
0418 LHS.uHex = &Val;
0419 RHS.twine = nullptr;
0420 return Twine(LHS, UHexKind, RHS, EmptyKind);
0421 }
0422
0423
0424
0425
0426
0427
0428
0429 bool isTriviallyEmpty() const {
0430 return isNullary();
0431 }
0432
0433
0434 bool isSingleStringLiteral() const {
0435 return isUnary() && getLHSKind() == StringLiteralKind;
0436 }
0437
0438
0439
0440 bool isSingleStringRef() const {
0441 if (getRHSKind() != EmptyKind) return false;
0442
0443 switch (getLHSKind()) {
0444 case EmptyKind:
0445 case CStringKind:
0446 case StdStringKind:
0447 case PtrAndLengthKind:
0448 case StringLiteralKind:
0449 return true;
0450 default:
0451 return false;
0452 }
0453 }
0454
0455
0456
0457
0458
0459 Twine concat(const Twine &Suffix) const;
0460
0461
0462
0463
0464
0465
0466 std::string str() const;
0467
0468
0469 void toVector(SmallVectorImpl<char> &Out) const;
0470
0471
0472
0473 StringRef getSingleStringRef() const {
0474 assert(isSingleStringRef() &&"This cannot be had as a single stringref!");
0475 switch (getLHSKind()) {
0476 default: llvm_unreachable("Out of sync with isSingleStringRef");
0477 case EmptyKind:
0478 return StringRef();
0479 case CStringKind:
0480 return StringRef(LHS.cString);
0481 case StdStringKind:
0482 return StringRef(*LHS.stdString);
0483 case PtrAndLengthKind:
0484 case StringLiteralKind:
0485 return StringRef(LHS.ptrAndLength.ptr, LHS.ptrAndLength.length);
0486 }
0487 }
0488
0489
0490
0491
0492 StringRef toStringRef(SmallVectorImpl<char> &Out) const {
0493 if (isSingleStringRef())
0494 return getSingleStringRef();
0495 toVector(Out);
0496 return StringRef(Out.data(), Out.size());
0497 }
0498
0499
0500
0501
0502
0503
0504 StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
0505
0506
0507
0508 void print(raw_ostream &OS) const;
0509
0510
0511 void dump() const;
0512
0513
0514 void printRepr(raw_ostream &OS) const;
0515
0516
0517 void dumpRepr() const;
0518
0519
0520 };
0521
0522
0523
0524
0525 inline Twine Twine::concat(const Twine &Suffix) const {
0526
0527 if (isNull() || Suffix.isNull())
0528 return Twine(NullKind);
0529
0530
0531 if (isEmpty())
0532 return Suffix;
0533 if (Suffix.isEmpty())
0534 return *this;
0535
0536
0537
0538 Child NewLHS, NewRHS;
0539 NewLHS.twine = this;
0540 NewRHS.twine = &Suffix;
0541 NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind;
0542 if (isUnary()) {
0543 NewLHS = LHS;
0544 NewLHSKind = getLHSKind();
0545 }
0546 if (Suffix.isUnary()) {
0547 NewRHS = Suffix.LHS;
0548 NewRHSKind = Suffix.getLHSKind();
0549 }
0550
0551 return Twine(NewLHS, NewLHSKind, NewRHS, NewRHSKind);
0552 }
0553
0554 inline Twine operator+(const Twine &LHS, const Twine &RHS) {
0555 return LHS.concat(RHS);
0556 }
0557
0558
0559
0560
0561 inline Twine operator+(const char *LHS, const StringRef &RHS) {
0562 return Twine(LHS, RHS);
0563 }
0564
0565
0566
0567
0568 inline Twine operator+(const StringRef &LHS, const char *RHS) {
0569 return Twine(LHS, RHS);
0570 }
0571
0572 inline raw_ostream &operator<<(raw_ostream &OS, const Twine &RHS) {
0573 RHS.print(OS);
0574 return OS;
0575 }
0576
0577
0578
0579 }
0580
0581 #endif