llvm.org GIT mirror llvm / 3f25ee0
Add Twine support for characters, and switch twine to use a union internally to eliminate some casting. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135888 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 9 years ago
3 changed file(s) with 123 addition(s) and 55 deletion(s). Raw diff Collapse all Expand all
9898 /// A pointer to a StringRef instance.
9999 StringRefKind,
100100
101 /// A char value reinterpreted as a pointer, to render as a character.
102 CharKind,
103
101104 /// An unsigned int value reinterpreted as a pointer, to render as an
102105 /// unsigned decimal integer.
103106 DecUIKind,
125128 UHexKind
126129 };
127130
131 union Child
132 {
133 const Twine *twine;
134 const char *cString;
135 const std::string *stdString;
136 const StringRef *stringRef;
137 char character;
138 unsigned int decUI;
139 int decI;
140 const unsigned long *decUL;
141 const long *decL;
142 const unsigned long long *decULL;
143 const long long *decLL;
144 const uint64_t *uHex;
145 };
146
128147 private:
129148 /// LHS - The prefix in the concatenation, which may be uninitialized for
130149 /// Null or Empty kinds.
131 const void *LHS;
150 Child LHS;
132151 /// RHS - The suffix in the concatenation, which may be uninitialized for
133152 /// Null or Empty kinds.
134 const void *RHS;
153 Child RHS;
154 // enums stored as unsigned chars to save on space while some compilers
155 // don't support specifying the backing type for an enum
135156 /// LHSKind - The NodeKind of the left hand side, \see getLHSKind().
136157 unsigned char LHSKind;
137158 /// RHSKind - The NodeKind of the left hand side, \see getLHSKind().
146167
147168 /// Construct a binary twine.
148169 explicit Twine(const Twine &_LHS, const Twine &_RHS)
149 : LHS(&_LHS), RHS(&_RHS), LHSKind(TwineKind), RHSKind(TwineKind) {
170 : LHSKind(TwineKind), RHSKind(TwineKind) {
171 LHS.twine = &_LHS;
172 RHS.twine = &_RHS;
150173 assert(isValid() && "Invalid twine!");
151174 }
152175
153176 /// Construct a twine from explicit values.
154 explicit Twine(const void *_LHS, NodeKind _LHSKind,
155 const void *_RHS, NodeKind _RHSKind)
177 explicit Twine(Child _LHS, NodeKind _LHSKind,
178 Child _RHS, NodeKind _RHSKind)
156179 : LHS(_LHS), RHS(_RHS), LHSKind(_LHSKind), RHSKind(_RHSKind) {
157180 assert(isValid() && "Invalid twine!");
158181 }
199222
200223 // A twine child should always be binary.
201224 if (getLHSKind() == TwineKind &&
202 !static_cast(LHS)->isBinary())
225 !LHS.twine->isBinary())
203226 return false;
204227 if (getRHSKind() == TwineKind &&
205 !static_cast(RHS)->isBinary())
228 !RHS.twine->isBinary())
206229 return false;
207230
208231 return true;
215238 NodeKind getRHSKind() const { return (NodeKind) RHSKind; }
216239
217240 /// printOneChild - Print one child from a twine.
218 void printOneChild(raw_ostream &OS, const void *Ptr, NodeKind Kind) const;
241 void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const;
219242
220243 /// printOneChildRepr - Print the representation of one child from a twine.
221 void printOneChildRepr(raw_ostream &OS, const void *Ptr,
244 void printOneChildRepr(raw_ostream &OS, Child Ptr,
222245 NodeKind Kind) const;
223246
224247 public:
238261 /*implicit*/ Twine(const char *Str)
239262 : RHSKind(EmptyKind) {
240263 if (Str[0] != '\0') {
241 LHS = Str;
264 LHS.cString = Str;
242265 LHSKind = CStringKind;
243266 } else
244267 LHSKind = EmptyKind;
248271
249272 /// Construct from an std::string.
250273 /*implicit*/ Twine(const std::string &Str)
251 : LHS(&Str), LHSKind(StdStringKind), RHSKind(EmptyKind) {
274 : LHSKind(StdStringKind), RHSKind(EmptyKind) {
275 LHS.stdString = &Str;
252276 assert(isValid() && "Invalid twine!");
253277 }
254278
255279 /// Construct from a StringRef.
256280 /*implicit*/ Twine(const StringRef &Str)
257 : LHS(&Str), LHSKind(StringRefKind), RHSKind(EmptyKind) {
258 assert(isValid() && "Invalid twine!");
281 : LHSKind(StringRefKind), RHSKind(EmptyKind) {
282 LHS.stringRef = &Str;
283 assert(isValid() && "Invalid twine!");
284 }
285
286 /// Construct from a char.
287 explicit Twine(char Val)
288 : LHSKind(CharKind), RHSKind(EmptyKind) {
289 LHS.character = Val;
290 }
291
292 /// Construct from a signed char.
293 explicit Twine(signed char Val)
294 : LHSKind(CharKind), RHSKind(EmptyKind) {
295 LHS.character = static_cast(Val);
296 }
297
298 /// Construct from an unsigned char.
299 explicit Twine(unsigned char Val)
300 : LHSKind(CharKind), RHSKind(EmptyKind) {
301 LHS.character = static_cast(Val);
259302 }
260303
261304 /// Construct a twine to print \arg Val as an unsigned decimal integer.
262305 explicit Twine(unsigned Val)
263 : LHS((void*)(intptr_t)Val), LHSKind(DecUIKind), RHSKind(EmptyKind) {
306 : LHSKind(DecUIKind), RHSKind(EmptyKind) {
307 LHS.decUI = Val;
264308 }
265309
266310 /// Construct a twine to print \arg Val as a signed decimal integer.
267311 explicit Twine(int Val)
268 : LHS((void*)(intptr_t)Val), LHSKind(DecIKind), RHSKind(EmptyKind) {
312 : LHSKind(DecIKind), RHSKind(EmptyKind) {
313 LHS.decI = Val;
269314 }
270315
271316 /// Construct a twine to print \arg Val as an unsigned decimal integer.
272317 explicit Twine(const unsigned long &Val)
273 : LHS(&Val), LHSKind(DecULKind), RHSKind(EmptyKind) {
318 : LHSKind(DecULKind), RHSKind(EmptyKind) {
319 LHS.decUL = &Val;
274320 }
275321
276322 /// Construct a twine to print \arg Val as a signed decimal integer.
277323 explicit Twine(const long &Val)
278 : LHS(&Val), LHSKind(DecLKind), RHSKind(EmptyKind) {
324 : LHSKind(DecLKind), RHSKind(EmptyKind) {
325 LHS.decL = &Val;
279326 }
280327
281328 /// Construct a twine to print \arg Val as an unsigned decimal integer.
282329 explicit Twine(const unsigned long long &Val)
283 : LHS(&Val), LHSKind(DecULLKind), RHSKind(EmptyKind) {
330 : LHSKind(DecULLKind), RHSKind(EmptyKind) {
331 LHS.decULL = &Val;
284332 }
285333
286334 /// Construct a twine to print \arg Val as a signed decimal integer.
287335 explicit Twine(const long long &Val)
288 : LHS(&Val), LHSKind(DecLLKind), RHSKind(EmptyKind) {
336 : LHSKind(DecLLKind), RHSKind(EmptyKind) {
337 LHS.decLL = &Val;
289338 }
290339
291340 // FIXME: Unfortunately, to make sure this is as efficient as possible we
295344
296345 /// Construct as the concatenation of a C string and a StringRef.
297346 /*implicit*/ Twine(const char *_LHS, const StringRef &_RHS)
298 : LHS(_LHS), RHS(&_RHS), LHSKind(CStringKind), RHSKind(StringRefKind) {
347 : LHSKind(CStringKind), RHSKind(StringRefKind) {
348 LHS.cString = _LHS;
349 RHS.stringRef = &_RHS;
299350 assert(isValid() && "Invalid twine!");
300351 }
301352
302353 /// Construct as the concatenation of a StringRef and a C string.
303354 /*implicit*/ Twine(const StringRef &_LHS, const char *_RHS)
304 : LHS(&_LHS), RHS(_RHS), LHSKind(StringRefKind), RHSKind(CStringKind) {
355 : LHSKind(StringRefKind), RHSKind(CStringKind) {
356 LHS.stringRef = &_LHS;
357 RHS.cString = _RHS;
305358 assert(isValid() && "Invalid twine!");
306359 }
307360
317370
318371 // Construct a twine to print \arg Val as an unsigned hexadecimal integer.
319372 static Twine utohexstr(const uint64_t &Val) {
320 return Twine(&Val, UHexKind, 0, EmptyKind);
373 Child LHS, RHS;
374 LHS.uHex = &Val;
375 RHS.twine = 0;
376 return Twine(LHS, UHexKind, RHS, EmptyKind);
321377 }
322378
323379 /// @}
370426 switch (getLHSKind()) {
371427 default: assert(0 && "Out of sync with isSingleStringRef");
372428 case EmptyKind: return StringRef();
373 case CStringKind: return StringRef((const char*)LHS);
374 case StdStringKind: return StringRef(*(const std::string*)LHS);
375 case StringRefKind: return *(const StringRef*)LHS;
429 case CStringKind: return StringRef(LHS.cString);
430 case StdStringKind: return StringRef(*LHS.stdString);
431 case StringRefKind: return *LHS.stringRef;
376432 }
377433 }
378434
421477
422478 // Otherwise we need to create a new node, taking care to fold in unary
423479 // twines.
424 const void *NewLHS = this, *NewRHS = &Suffix;
480 Child NewLHS, NewRHS;
481 NewLHS.twine = this;
482 NewRHS.twine = &Suffix;
425483 NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind;
426484 if (isUnary()) {
427485 NewLHS = LHS;
1515 std::string Twine::str() const {
1616 // If we're storing only a std::string, just return it.
1717 if (LHSKind == StdStringKind && RHSKind == EmptyKind)
18 return *static_cast(LHS);
18 return *LHS.stdString;
1919
2020 // Otherwise, flatten and copy the contents first.
2121 SmallString<256> Vec;
3939 switch (getLHSKind()) {
4040 case CStringKind:
4141 // Already null terminated, yay!
42 return StringRef(static_cast(LHS));
42 return StringRef(LHS.cString);
4343 case StdStringKind: {
44 const std::string *str = static_cast(LHS);
44 const std::string *str = LHS.stdString;
4545 return StringRef(str->c_str(), str->size());
4646 }
4747 default:
5454 return StringRef(Out.data(), Out.size());
5555 }
5656
57 void Twine::printOneChild(raw_ostream &OS, const void *Ptr,
57 void Twine::printOneChild(raw_ostream &OS, Child Ptr,
5858 NodeKind Kind) const {
5959 switch (Kind) {
6060 case Twine::NullKind: break;
6161 case Twine::EmptyKind: break;
6262 case Twine::TwineKind:
63 static_cast(Ptr)->print(OS);
63 Ptr.twine->print(OS);
6464 break;
6565 case Twine::CStringKind:
66 OS << static_cast(Ptr);
66 OS << Ptr.cString;
6767 break;
6868 case Twine::StdStringKind:
69 OS << *static_cast(Ptr);
69 OS << *Ptr.stdString;
7070 break;
7171 case Twine::StringRefKind:
72 OS << *static_cast(Ptr);
72 OS << *Ptr.stringRef;
73 break;
74 case Twine::CharKind:
75 OS << Ptr.character;
7376 break;
7477 case Twine::DecUIKind:
75 OS << (unsigned)(uintptr_t)Ptr;
78 OS << Ptr.decUI;
7679 break;
7780 case Twine::DecIKind:
78 OS << (int)(intptr_t)Ptr;
81 OS << Ptr.decI;
7982 break;
8083 case Twine::DecULKind:
81 OS << *static_cast(Ptr);
84 OS << *Ptr.decUL;
8285 break;
8386 case Twine::DecLKind:
84 OS << *static_cast(Ptr);
87 OS << *Ptr.decL;
8588 break;
8689 case Twine::DecULLKind:
87 OS << *static_cast(Ptr);
90 OS << *Ptr.decULL;
8891 break;
8992 case Twine::DecLLKind:
90 OS << *static_cast(Ptr);
93 OS << *Ptr.decLL;
9194 break;
9295 case Twine::UHexKind:
93 OS.write_hex(*static_cast(Ptr));
96 OS.write_hex(*Ptr.uHex);
9497 break;
9598 }
9699 }
97100
98 void Twine::printOneChildRepr(raw_ostream &OS, const void *Ptr,
101 void Twine::printOneChildRepr(raw_ostream &OS, Child Ptr,
99102 NodeKind Kind) const {
100103 switch (Kind) {
101104 case Twine::NullKind:
104107 OS << "empty"; break;
105108 case Twine::TwineKind:
106109 OS << "rope:";
107 static_cast(Ptr)->printRepr(OS);
110 Ptr.twine->printRepr(OS);
108111 break;
109112 case Twine::CStringKind:
110113 OS << "cstring:\""
111 << static_cast(Ptr) << "\"";
114 << Ptr.cString << "\"";
112115 break;
113116 case Twine::StdStringKind:
114117 OS << "std::string:\""
115 << static_cast(Ptr) << "\"";
118 << Ptr.stdString << "\"";
116119 break;
117120 case Twine::StringRefKind:
118121 OS << "stringref:\""
119 << static_cast(Ptr) << "\"";
122 << Ptr.stringRef << "\"";
123 break;
124 case Twine::CharKind:
125 OS << "char:\"" << Ptr.character << "\"";
120126 break;
121127 case Twine::DecUIKind:
122 OS << "decUI:\"" << (unsigned)(uintptr_t)Ptr << "\"";
128 OS << "decUI:\"" << Ptr.decUI << "\"";
123129 break;
124130 case Twine::DecIKind:
125 OS << "decI:\"" << (int)(intptr_t)Ptr << "\"";
131 OS << "decI:\"" << Ptr.decI << "\"";
126132 break;
127133 case Twine::DecULKind:
128 OS << "decUL:\"" << *static_cast(Ptr) << "\"";
134 OS << "decUL:\"" << *Ptr.decUL << "\"";
129135 break;
130136 case Twine::DecLKind:
131 OS << "decL:\"" << *static_cast(Ptr) << "\"";
137 OS << "decL:\"" << *Ptr.decL << "\"";
132138 break;
133139 case Twine::DecULLKind:
134 OS << "decULL:\"" << *static_cast(Ptr) << "\"";
140 OS << "decULL:\"" << *Ptr.decULL << "\"";
135141 break;
136142 case Twine::DecLLKind:
137 OS << "decLL:\"" << *static_cast(Ptr) << "\"";
143 OS << "decLL:\"" << *Ptr.decLL << "\"";
138144 break;
139145 case Twine::UHexKind:
140 OS << "uhex:\"" << static_cast(Ptr) << "\"";
146 OS << "uhex:\"" << Ptr.uHex << "\"";
141147 break;
142148 }
143149 }
3636 EXPECT_EQ("-123", Twine(-123).str());
3737 EXPECT_EQ("123", Twine(123).str());
3838 EXPECT_EQ("-123", Twine(-123).str());
39 EXPECT_EQ("123", Twine((char) 123).str());
40 EXPECT_EQ("-123", Twine((signed char) -123).str());
4139
4240 EXPECT_EQ("7b", Twine::utohexstr(123).str());
41 }
42
43 TEST(TwineTest, Characters) {
44 EXPECT_EQ("x", Twine('x').str());
45 EXPECT_EQ("x", Twine(static_cast('x')).str());
46 EXPECT_EQ("x", Twine(static_cast('x')).str());
4347 }
4448
4549 TEST(TwineTest, Concat) {