00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef LLVM_ADT_TWINE_H
00011 #define LLVM_ADT_TWINE_H
00012
00013 #include "llvm/ADT/StringRef.h"
00014 #include "llvm/Support/DataTypes.h"
00015 #include <cassert>
00016 #include <string>
00017 #include <iostream>
00018
00019 namespace llvm {
00020 template <typename T>
00021 class SmallVectorImpl;
00022 class StringRef;
00023
00080 class Twine {
00082 enum NodeKind {
00085 NullKind,
00086
00088 EmptyKind,
00089
00091 TwineKind,
00092
00094 CStringKind,
00095
00097 StdStringKind,
00098
00100 StringRefKind,
00101
00103 CharKind,
00104
00107 DecUIKind,
00108
00111 DecIKind,
00112
00115 DecULKind,
00116
00118 DecLKind,
00119
00122 DecULLKind,
00123
00125 DecLLKind,
00126
00129 UHexKind
00130 };
00131
00132 union Child
00133 {
00134 const Twine *twine;
00135 const char *cString;
00136 const std::string *stdString;
00137 const StringRef *stringRef;
00138 char character;
00139 unsigned int decUI;
00140 int decI;
00141 const unsigned long *decUL;
00142 const long *decL;
00143 const unsigned long long *decULL;
00144 const long long *decLL;
00145 const uint64_t *uHex;
00146 };
00147
00148 private:
00151 Child LHS;
00154 Child RHS;
00155
00156
00158 unsigned char LHSKind;
00160 unsigned char RHSKind;
00161
00162 private:
00164 explicit Twine(NodeKind Kind)
00165 : LHSKind(Kind), RHSKind(EmptyKind) {
00166 assert(isNullary() && "Invalid kind!");
00167 }
00168
00170 explicit Twine(const Twine &_LHS, const Twine &_RHS)
00171 : LHSKind(TwineKind), RHSKind(TwineKind) {
00172 LHS.twine = &_LHS;
00173 RHS.twine = &_RHS;
00174 assert(isValid() && "Invalid twine!");
00175 }
00176
00178 explicit Twine(Child _LHS, NodeKind _LHSKind,
00179 Child _RHS, NodeKind _RHSKind)
00180 : LHS(_LHS), RHS(_RHS), LHSKind(_LHSKind), RHSKind(_RHSKind) {
00181 assert(isValid() && "Invalid twine!");
00182 }
00183
00185 bool isNull() const {
00186 return getLHSKind() == NullKind;
00187 }
00188
00190 bool isEmpty() const {
00191 return getLHSKind() == EmptyKind;
00192 }
00193
00195 bool isNullary() const {
00196 return isNull() || isEmpty();
00197 }
00198
00200 bool isUnary() const {
00201 return getRHSKind() == EmptyKind && !isNullary();
00202 }
00203
00205 bool isBinary() const {
00206 return getLHSKind() != NullKind && getRHSKind() != EmptyKind;
00207 }
00208
00211 bool isValid() const {
00212
00213 if (isNullary() && getRHSKind() != EmptyKind)
00214 return false;
00215
00216
00217 if (getRHSKind() == NullKind)
00218 return false;
00219
00220
00221 if (getRHSKind() != EmptyKind && getLHSKind() == EmptyKind)
00222 return false;
00223
00224
00225 if (getLHSKind() == TwineKind &&
00226 !LHS.twine->isBinary())
00227 return false;
00228 if (getRHSKind() == TwineKind &&
00229 !RHS.twine->isBinary())
00230 return false;
00231
00232 return true;
00233 }
00234
00236 NodeKind getLHSKind() const { return (NodeKind) LHSKind; }
00237
00239 NodeKind getRHSKind() const { return (NodeKind) RHSKind; }
00240
00242 void printOneChild(std::ostream &OS, Child Ptr, NodeKind Kind) const;
00243
00245 void printOneChildRepr(std::ostream &OS, Child Ptr,
00246 NodeKind Kind) const;
00247
00248 public:
00251
00253 Twine() : LHSKind(EmptyKind), RHSKind(EmptyKind) {
00254 assert(isValid() && "Invalid twine!");
00255 }
00256
00262 Twine(const char *Str)
00263 : RHSKind(EmptyKind) {
00264 if (Str[0] != '\0') {
00265 LHS.cString = Str;
00266 LHSKind = CStringKind;
00267 } else
00268 LHSKind = EmptyKind;
00269
00270 assert(isValid() && "Invalid twine!");
00271 }
00272
00274 Twine(const std::string &Str)
00275 : LHSKind(StdStringKind), RHSKind(EmptyKind) {
00276 LHS.stdString = &Str;
00277 assert(isValid() && "Invalid twine!");
00278 }
00279
00281 Twine(const StringRef &Str)
00282 : LHSKind(StringRefKind), RHSKind(EmptyKind) {
00283 LHS.stringRef = &Str;
00284 assert(isValid() && "Invalid twine!");
00285 }
00286
00288 explicit Twine(char Val)
00289 : LHSKind(CharKind), RHSKind(EmptyKind) {
00290 LHS.character = Val;
00291 }
00292
00294 explicit Twine(signed char Val)
00295 : LHSKind(CharKind), RHSKind(EmptyKind) {
00296 LHS.character = static_cast<char>(Val);
00297 }
00298
00300 explicit Twine(unsigned char Val)
00301 : LHSKind(CharKind), RHSKind(EmptyKind) {
00302 LHS.character = static_cast<char>(Val);
00303 }
00304
00306 explicit Twine(unsigned Val)
00307 : LHSKind(DecUIKind), RHSKind(EmptyKind) {
00308 LHS.decUI = Val;
00309 }
00310
00312 explicit Twine(int Val)
00313 : LHSKind(DecIKind), RHSKind(EmptyKind) {
00314 LHS.decI = Val;
00315 }
00316
00318 explicit Twine(const unsigned long &Val)
00319 : LHSKind(DecULKind), RHSKind(EmptyKind) {
00320 LHS.decUL = &Val;
00321 }
00322
00324 explicit Twine(const long &Val)
00325 : LHSKind(DecLKind), RHSKind(EmptyKind) {
00326 LHS.decL = &Val;
00327 }
00328
00330 explicit Twine(const unsigned long long &Val)
00331 : LHSKind(DecULLKind), RHSKind(EmptyKind) {
00332 LHS.decULL = &Val;
00333 }
00334
00336 explicit Twine(const long long &Val)
00337 : LHSKind(DecLLKind), RHSKind(EmptyKind) {
00338 LHS.decLL = &Val;
00339 }
00340
00341
00342
00343
00344
00345
00347 Twine(const char *_LHS, const StringRef &_RHS)
00348 : LHSKind(CStringKind), RHSKind(StringRefKind) {
00349 LHS.cString = _LHS;
00350 RHS.stringRef = &_RHS;
00351 assert(isValid() && "Invalid twine!");
00352 }
00353
00355 Twine(const StringRef &_LHS, const char *_RHS)
00356 : LHSKind(StringRefKind), RHSKind(CStringKind) {
00357 LHS.stringRef = &_LHS;
00358 RHS.cString = _RHS;
00359 assert(isValid() && "Invalid twine!");
00360 }
00361
00364 static Twine createNull() {
00365 return Twine(NullKind);
00366 }
00367
00371
00372
00373 static Twine utohexstr(const uint64_t &Val) {
00374 Child LHS, RHS;
00375 LHS.uHex = &Val;
00376 RHS.twine = 0;
00377 return Twine(LHS, UHexKind, RHS, EmptyKind);
00378 }
00379
00383
00386 bool isTriviallyEmpty() const {
00387 return isNullary();
00388 }
00389
00392 bool isSingleStringRef() const {
00393 if (getRHSKind() != EmptyKind) return false;
00394
00395 switch (getLHSKind()) {
00396 case EmptyKind:
00397 case CStringKind:
00398 case StdStringKind:
00399 case StringRefKind:
00400 return true;
00401 default:
00402 return false;
00403 }
00404 }
00405
00409
00410 Twine concat(const Twine &Suffix) const;
00411
00415
00417 std::string str() const;
00418
00421 void toVector(SmallVectorImpl<char> &Out) const;
00422
00425 StringRef getSingleStringRef() const {
00426 assert(isSingleStringRef() &&"This cannot be had as a single stringref!");
00427 switch (getLHSKind()) {
00428 default: assert(0 && "Out of sync with isSingleStringRef");
00429 case EmptyKind: return StringRef();
00430 case CStringKind: return StringRef(LHS.cString);
00431 case StdStringKind: return StringRef(*LHS.stdString);
00432 case StringRefKind: return *LHS.stringRef;
00433 }
00434 }
00435
00439 StringRef toStringRef(SmallVectorImpl<char> &Out) const;
00440
00447 StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
00448
00451 void print(std::ostream &OS) const;
00452
00454 void dump() const;
00455
00457 void printRepr(std::ostream &OS) const;
00458
00460 void dumpRepr() const;
00461
00463 };
00464
00467
00468 inline Twine Twine::concat(const Twine &Suffix) const {
00469
00470 if (isNull() || Suffix.isNull())
00471 return Twine(NullKind);
00472
00473
00474 if (isEmpty())
00475 return Suffix;
00476 if (Suffix.isEmpty())
00477 return *this;
00478
00479
00480
00481 Child NewLHS, NewRHS;
00482 NewLHS.twine = this;
00483 NewRHS.twine = &Suffix;
00484 NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind;
00485 if (isUnary()) {
00486 NewLHS = LHS;
00487 NewLHSKind = getLHSKind();
00488 }
00489 if (Suffix.isUnary()) {
00490 NewRHS = Suffix.LHS;
00491 NewRHSKind = Suffix.getLHSKind();
00492 }
00493
00494 return Twine(NewLHS, NewLHSKind, NewRHS, NewRHSKind);
00495 }
00496
00497 inline Twine operator+(const Twine &LHS, const Twine &RHS) {
00498 return LHS.concat(RHS);
00499 }
00500
00503
00504 inline Twine operator+(const char *LHS, const StringRef &RHS) {
00505 return Twine(LHS, RHS);
00506 }
00507
00510
00511 inline Twine operator+(const StringRef &LHS, const char *RHS) {
00512 return Twine(LHS, RHS);
00513 }
00514
00515 inline std::ostream &operator<<(std::ostream &OS, const Twine &RHS) {
00516 RHS.print(OS);
00517 return OS;
00518 }
00519
00521 }
00522
00523 #endif