Bug Summary

File:lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
Warning:line 1157, column 30
The left operand of '!=' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SystemZAsmParser.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn326246/build-llvm/lib/Target/SystemZ/AsmParser -I /build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser -I /build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ -I /build/llvm-toolchain-snapshot-7~svn326246/build-llvm/lib/Target/SystemZ -I /build/llvm-toolchain-snapshot-7~svn326246/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn326246/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn326246/build-llvm/lib/Target/SystemZ/AsmParser -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-02-28-041547-14988-1 -x c++ /build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp

/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp

1//===-- SystemZAsmParser.cpp - Parse SystemZ assembly instructions --------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "MCTargetDesc/SystemZMCTargetDesc.h"
11#include "llvm/ADT/STLExtras.h"
12#include "llvm/ADT/SmallVector.h"
13#include "llvm/ADT/StringRef.h"
14#include "llvm/MC/MCContext.h"
15#include "llvm/MC/MCExpr.h"
16#include "llvm/MC/MCInst.h"
17#include "llvm/MC/MCInstBuilder.h"
18#include "llvm/MC/MCParser/MCAsmLexer.h"
19#include "llvm/MC/MCParser/MCAsmParser.h"
20#include "llvm/MC/MCParser/MCAsmParserExtension.h"
21#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
22#include "llvm/MC/MCParser/MCTargetAsmParser.h"
23#include "llvm/MC/MCStreamer.h"
24#include "llvm/MC/MCSubtargetInfo.h"
25#include "llvm/Support/Casting.h"
26#include "llvm/Support/ErrorHandling.h"
27#include "llvm/Support/SMLoc.h"
28#include "llvm/Support/TargetRegistry.h"
29#include <algorithm>
30#include <cassert>
31#include <cstddef>
32#include <cstdint>
33#include <iterator>
34#include <memory>
35#include <string>
36
37using namespace llvm;
38
39// Return true if Expr is in the range [MinValue, MaxValue].
40static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue) {
41 if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
42 int64_t Value = CE->getValue();
43 return Value >= MinValue && Value <= MaxValue;
44 }
45 return false;
46}
47
48namespace {
49
50enum RegisterKind {
51 GR32Reg,
52 GRH32Reg,
53 GR64Reg,
54 GR128Reg,
55 ADDR32Reg,
56 ADDR64Reg,
57 FP32Reg,
58 FP64Reg,
59 FP128Reg,
60 VR32Reg,
61 VR64Reg,
62 VR128Reg,
63 AR32Reg,
64 CR64Reg,
65};
66
67enum MemoryKind {
68 BDMem,
69 BDXMem,
70 BDLMem,
71 BDRMem,
72 BDVMem
73};
74
75class SystemZOperand : public MCParsedAsmOperand {
76private:
77 enum OperandKind {
78 KindInvalid,
79 KindToken,
80 KindReg,
81 KindImm,
82 KindImmTLS,
83 KindMem
84 };
85
86 OperandKind Kind;
87 SMLoc StartLoc, EndLoc;
88
89 // A string of length Length, starting at Data.
90 struct TokenOp {
91 const char *Data;
92 unsigned Length;
93 };
94
95 // LLVM register Num, which has kind Kind. In some ways it might be
96 // easier for this class to have a register bank (general, floating-point
97 // or access) and a raw register number (0-15). This would postpone the
98 // interpretation of the operand to the add*() methods and avoid the need
99 // for context-dependent parsing. However, we do things the current way
100 // because of the virtual getReg() method, which needs to distinguish
101 // between (say) %r0 used as a single register and %r0 used as a pair.
102 // Context-dependent parsing can also give us slightly better error
103 // messages when invalid pairs like %r1 are used.
104 struct RegOp {
105 RegisterKind Kind;
106 unsigned Num;
107 };
108
109 // Base + Disp + Index, where Base and Index are LLVM registers or 0.
110 // MemKind says what type of memory this is and RegKind says what type
111 // the base register has (ADDR32Reg or ADDR64Reg). Length is the operand
112 // length for D(L,B)-style operands, otherwise it is null.
113 struct MemOp {
114 unsigned Base : 12;
115 unsigned Index : 12;
116 unsigned MemKind : 4;
117 unsigned RegKind : 4;
118 const MCExpr *Disp;
119 union {
120 const MCExpr *Imm;
121 unsigned Reg;
122 } Length;
123 };
124
125 // Imm is an immediate operand, and Sym is an optional TLS symbol
126 // for use with a __tls_get_offset marker relocation.
127 struct ImmTLSOp {
128 const MCExpr *Imm;
129 const MCExpr *Sym;
130 };
131
132 union {
133 TokenOp Token;
134 RegOp Reg;
135 const MCExpr *Imm;
136 ImmTLSOp ImmTLS;
137 MemOp Mem;
138 };
139
140 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
141 // Add as immediates when possible. Null MCExpr = 0.
142 if (!Expr)
143 Inst.addOperand(MCOperand::createImm(0));
144 else if (auto *CE = dyn_cast<MCConstantExpr>(Expr))
145 Inst.addOperand(MCOperand::createImm(CE->getValue()));
146 else
147 Inst.addOperand(MCOperand::createExpr(Expr));
148 }
149
150public:
151 SystemZOperand(OperandKind kind, SMLoc startLoc, SMLoc endLoc)
152 : Kind(kind), StartLoc(startLoc), EndLoc(endLoc) {}
153
154 // Create particular kinds of operand.
155 static std::unique_ptr<SystemZOperand> createInvalid(SMLoc StartLoc,
156 SMLoc EndLoc) {
157 return make_unique<SystemZOperand>(KindInvalid, StartLoc, EndLoc);
158 }
159
160 static std::unique_ptr<SystemZOperand> createToken(StringRef Str, SMLoc Loc) {
161 auto Op = make_unique<SystemZOperand>(KindToken, Loc, Loc);
162 Op->Token.Data = Str.data();
163 Op->Token.Length = Str.size();
164 return Op;
165 }
166
167 static std::unique_ptr<SystemZOperand>
168 createReg(RegisterKind Kind, unsigned Num, SMLoc StartLoc, SMLoc EndLoc) {
169 auto Op = make_unique<SystemZOperand>(KindReg, StartLoc, EndLoc);
170 Op->Reg.Kind = Kind;
171 Op->Reg.Num = Num;
172 return Op;
173 }
174
175 static std::unique_ptr<SystemZOperand>
176 createImm(const MCExpr *Expr, SMLoc StartLoc, SMLoc EndLoc) {
177 auto Op = make_unique<SystemZOperand>(KindImm, StartLoc, EndLoc);
178 Op->Imm = Expr;
179 return Op;
180 }
181
182 static std::unique_ptr<SystemZOperand>
183 createMem(MemoryKind MemKind, RegisterKind RegKind, unsigned Base,
184 const MCExpr *Disp, unsigned Index, const MCExpr *LengthImm,
185 unsigned LengthReg, SMLoc StartLoc, SMLoc EndLoc) {
186 auto Op = make_unique<SystemZOperand>(KindMem, StartLoc, EndLoc);
187 Op->Mem.MemKind = MemKind;
188 Op->Mem.RegKind = RegKind;
189 Op->Mem.Base = Base;
190 Op->Mem.Index = Index;
191 Op->Mem.Disp = Disp;
192 if (MemKind == BDLMem)
193 Op->Mem.Length.Imm = LengthImm;
194 if (MemKind == BDRMem)
195 Op->Mem.Length.Reg = LengthReg;
196 return Op;
197 }
198
199 static std::unique_ptr<SystemZOperand>
200 createImmTLS(const MCExpr *Imm, const MCExpr *Sym,
201 SMLoc StartLoc, SMLoc EndLoc) {
202 auto Op = make_unique<SystemZOperand>(KindImmTLS, StartLoc, EndLoc);
203 Op->ImmTLS.Imm = Imm;
204 Op->ImmTLS.Sym = Sym;
205 return Op;
206 }
207
208 // Token operands
209 bool isToken() const override {
210 return Kind == KindToken;
211 }
212 StringRef getToken() const {
213 assert(Kind == KindToken && "Not a token")(static_cast <bool> (Kind == KindToken && "Not a token"
) ? void (0) : __assert_fail ("Kind == KindToken && \"Not a token\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 213, __extension__ __PRETTY_FUNCTION__))
;
214 return StringRef(Token.Data, Token.Length);
215 }
216
217 // Register operands.
218 bool isReg() const override {
219 return Kind == KindReg;
220 }
221 bool isReg(RegisterKind RegKind) const {
222 return Kind == KindReg && Reg.Kind == RegKind;
223 }
224 unsigned getReg() const override {
225 assert(Kind == KindReg && "Not a register")(static_cast <bool> (Kind == KindReg && "Not a register"
) ? void (0) : __assert_fail ("Kind == KindReg && \"Not a register\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 225, __extension__ __PRETTY_FUNCTION__))
;
226 return Reg.Num;
227 }
228
229 // Immediate operands.
230 bool isImm() const override {
231 return Kind == KindImm;
232 }
233 bool isImm(int64_t MinValue, int64_t MaxValue) const {
234 return Kind == KindImm && inRange(Imm, MinValue, MaxValue);
235 }
236 const MCExpr *getImm() const {
237 assert(Kind == KindImm && "Not an immediate")(static_cast <bool> (Kind == KindImm && "Not an immediate"
) ? void (0) : __assert_fail ("Kind == KindImm && \"Not an immediate\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 237, __extension__ __PRETTY_FUNCTION__))
;
238 return Imm;
239 }
240
241 // Immediate operands with optional TLS symbol.
242 bool isImmTLS() const {
243 return Kind == KindImmTLS;
244 }
245
246 // Memory operands.
247 bool isMem() const override {
248 return Kind == KindMem;
249 }
250 bool isMem(MemoryKind MemKind) const {
251 return (Kind == KindMem &&
252 (Mem.MemKind == MemKind ||
253 // A BDMem can be treated as a BDXMem in which the index
254 // register field is 0.
255 (Mem.MemKind == BDMem && MemKind == BDXMem)));
256 }
257 bool isMem(MemoryKind MemKind, RegisterKind RegKind) const {
258 return isMem(MemKind) && Mem.RegKind == RegKind;
259 }
260 bool isMemDisp12(MemoryKind MemKind, RegisterKind RegKind) const {
261 return isMem(MemKind, RegKind) && inRange(Mem.Disp, 0, 0xfff);
262 }
263 bool isMemDisp20(MemoryKind MemKind, RegisterKind RegKind) const {
264 return isMem(MemKind, RegKind) && inRange(Mem.Disp, -524288, 524287);
265 }
266 bool isMemDisp12Len4(RegisterKind RegKind) const {
267 return isMemDisp12(BDLMem, RegKind) && inRange(Mem.Length.Imm, 1, 0x10);
268 }
269 bool isMemDisp12Len8(RegisterKind RegKind) const {
270 return isMemDisp12(BDLMem, RegKind) && inRange(Mem.Length.Imm, 1, 0x100);
271 }
272
273 // Override MCParsedAsmOperand.
274 SMLoc getStartLoc() const override { return StartLoc; }
275 SMLoc getEndLoc() const override { return EndLoc; }
276 void print(raw_ostream &OS) const override;
277
278 /// getLocRange - Get the range between the first and last token of this
279 /// operand.
280 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
281
282 // Used by the TableGen code to add particular types of operand
283 // to an instruction.
284 void addRegOperands(MCInst &Inst, unsigned N) const {
285 assert(N == 1 && "Invalid number of operands")(static_cast <bool> (N == 1 && "Invalid number of operands"
) ? void (0) : __assert_fail ("N == 1 && \"Invalid number of operands\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 285, __extension__ __PRETTY_FUNCTION__))
;
286 Inst.addOperand(MCOperand::createReg(getReg()));
287 }
288 void addImmOperands(MCInst &Inst, unsigned N) const {
289 assert(N == 1 && "Invalid number of operands")(static_cast <bool> (N == 1 && "Invalid number of operands"
) ? void (0) : __assert_fail ("N == 1 && \"Invalid number of operands\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 289, __extension__ __PRETTY_FUNCTION__))
;
290 addExpr(Inst, getImm());
291 }
292 void addBDAddrOperands(MCInst &Inst, unsigned N) const {
293 assert(N == 2 && "Invalid number of operands")(static_cast <bool> (N == 2 && "Invalid number of operands"
) ? void (0) : __assert_fail ("N == 2 && \"Invalid number of operands\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 293, __extension__ __PRETTY_FUNCTION__))
;
294 assert(isMem(BDMem) && "Invalid operand type")(static_cast <bool> (isMem(BDMem) && "Invalid operand type"
) ? void (0) : __assert_fail ("isMem(BDMem) && \"Invalid operand type\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 294, __extension__ __PRETTY_FUNCTION__))
;
295 Inst.addOperand(MCOperand::createReg(Mem.Base));
296 addExpr(Inst, Mem.Disp);
297 }
298 void addBDXAddrOperands(MCInst &Inst, unsigned N) const {
299 assert(N == 3 && "Invalid number of operands")(static_cast <bool> (N == 3 && "Invalid number of operands"
) ? void (0) : __assert_fail ("N == 3 && \"Invalid number of operands\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 299, __extension__ __PRETTY_FUNCTION__))
;
300 assert(isMem(BDXMem) && "Invalid operand type")(static_cast <bool> (isMem(BDXMem) && "Invalid operand type"
) ? void (0) : __assert_fail ("isMem(BDXMem) && \"Invalid operand type\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 300, __extension__ __PRETTY_FUNCTION__))
;
301 Inst.addOperand(MCOperand::createReg(Mem.Base));
302 addExpr(Inst, Mem.Disp);
303 Inst.addOperand(MCOperand::createReg(Mem.Index));
304 }
305 void addBDLAddrOperands(MCInst &Inst, unsigned N) const {
306 assert(N == 3 && "Invalid number of operands")(static_cast <bool> (N == 3 && "Invalid number of operands"
) ? void (0) : __assert_fail ("N == 3 && \"Invalid number of operands\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 306, __extension__ __PRETTY_FUNCTION__))
;
307 assert(isMem(BDLMem) && "Invalid operand type")(static_cast <bool> (isMem(BDLMem) && "Invalid operand type"
) ? void (0) : __assert_fail ("isMem(BDLMem) && \"Invalid operand type\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 307, __extension__ __PRETTY_FUNCTION__))
;
308 Inst.addOperand(MCOperand::createReg(Mem.Base));
309 addExpr(Inst, Mem.Disp);
310 addExpr(Inst, Mem.Length.Imm);
311 }
312 void addBDRAddrOperands(MCInst &Inst, unsigned N) const {
313 assert(N == 3 && "Invalid number of operands")(static_cast <bool> (N == 3 && "Invalid number of operands"
) ? void (0) : __assert_fail ("N == 3 && \"Invalid number of operands\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 313, __extension__ __PRETTY_FUNCTION__))
;
314 assert(isMem(BDRMem) && "Invalid operand type")(static_cast <bool> (isMem(BDRMem) && "Invalid operand type"
) ? void (0) : __assert_fail ("isMem(BDRMem) && \"Invalid operand type\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 314, __extension__ __PRETTY_FUNCTION__))
;
315 Inst.addOperand(MCOperand::createReg(Mem.Base));
316 addExpr(Inst, Mem.Disp);
317 Inst.addOperand(MCOperand::createReg(Mem.Length.Reg));
318 }
319 void addBDVAddrOperands(MCInst &Inst, unsigned N) const {
320 assert(N == 3 && "Invalid number of operands")(static_cast <bool> (N == 3 && "Invalid number of operands"
) ? void (0) : __assert_fail ("N == 3 && \"Invalid number of operands\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 320, __extension__ __PRETTY_FUNCTION__))
;
321 assert(isMem(BDVMem) && "Invalid operand type")(static_cast <bool> (isMem(BDVMem) && "Invalid operand type"
) ? void (0) : __assert_fail ("isMem(BDVMem) && \"Invalid operand type\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 321, __extension__ __PRETTY_FUNCTION__))
;
322 Inst.addOperand(MCOperand::createReg(Mem.Base));
323 addExpr(Inst, Mem.Disp);
324 Inst.addOperand(MCOperand::createReg(Mem.Index));
325 }
326 void addImmTLSOperands(MCInst &Inst, unsigned N) const {
327 assert(N == 2 && "Invalid number of operands")(static_cast <bool> (N == 2 && "Invalid number of operands"
) ? void (0) : __assert_fail ("N == 2 && \"Invalid number of operands\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 327, __extension__ __PRETTY_FUNCTION__))
;
328 assert(Kind == KindImmTLS && "Invalid operand type")(static_cast <bool> (Kind == KindImmTLS && "Invalid operand type"
) ? void (0) : __assert_fail ("Kind == KindImmTLS && \"Invalid operand type\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 328, __extension__ __PRETTY_FUNCTION__))
;
329 addExpr(Inst, ImmTLS.Imm);
330 if (ImmTLS.Sym)
331 addExpr(Inst, ImmTLS.Sym);
332 }
333
334 // Used by the TableGen code to check for particular operand types.
335 bool isGR32() const { return isReg(GR32Reg); }
336 bool isGRH32() const { return isReg(GRH32Reg); }
337 bool isGRX32() const { return false; }
338 bool isGR64() const { return isReg(GR64Reg); }
339 bool isGR128() const { return isReg(GR128Reg); }
340 bool isADDR32() const { return isReg(ADDR32Reg); }
341 bool isADDR64() const { return isReg(ADDR64Reg); }
342 bool isADDR128() const { return false; }
343 bool isFP32() const { return isReg(FP32Reg); }
344 bool isFP64() const { return isReg(FP64Reg); }
345 bool isFP128() const { return isReg(FP128Reg); }
346 bool isVR32() const { return isReg(VR32Reg); }
347 bool isVR64() const { return isReg(VR64Reg); }
348 bool isVF128() const { return false; }
349 bool isVR128() const { return isReg(VR128Reg); }
350 bool isAR32() const { return isReg(AR32Reg); }
351 bool isCR64() const { return isReg(CR64Reg); }
352 bool isAnyReg() const { return (isReg() || isImm(0, 15)); }
353 bool isBDAddr32Disp12() const { return isMemDisp12(BDMem, ADDR32Reg); }
354 bool isBDAddr32Disp20() const { return isMemDisp20(BDMem, ADDR32Reg); }
355 bool isBDAddr64Disp12() const { return isMemDisp12(BDMem, ADDR64Reg); }
356 bool isBDAddr64Disp20() const { return isMemDisp20(BDMem, ADDR64Reg); }
357 bool isBDXAddr64Disp12() const { return isMemDisp12(BDXMem, ADDR64Reg); }
358 bool isBDXAddr64Disp20() const { return isMemDisp20(BDXMem, ADDR64Reg); }
359 bool isBDLAddr64Disp12Len4() const { return isMemDisp12Len4(ADDR64Reg); }
360 bool isBDLAddr64Disp12Len8() const { return isMemDisp12Len8(ADDR64Reg); }
361 bool isBDRAddr64Disp12() const { return isMemDisp12(BDRMem, ADDR64Reg); }
362 bool isBDVAddr64Disp12() const { return isMemDisp12(BDVMem, ADDR64Reg); }
363 bool isU1Imm() const { return isImm(0, 1); }
364 bool isU2Imm() const { return isImm(0, 3); }
365 bool isU3Imm() const { return isImm(0, 7); }
366 bool isU4Imm() const { return isImm(0, 15); }
367 bool isU6Imm() const { return isImm(0, 63); }
368 bool isU8Imm() const { return isImm(0, 255); }
369 bool isS8Imm() const { return isImm(-128, 127); }
370 bool isU12Imm() const { return isImm(0, 4095); }
371 bool isU16Imm() const { return isImm(0, 65535); }
372 bool isS16Imm() const { return isImm(-32768, 32767); }
373 bool isU32Imm() const { return isImm(0, (1LL << 32) - 1); }
374 bool isS32Imm() const { return isImm(-(1LL << 31), (1LL << 31) - 1); }
375 bool isU48Imm() const { return isImm(0, (1LL << 48) - 1); }
376};
377
378class SystemZAsmParser : public MCTargetAsmParser {
379#define GET_ASSEMBLER_HEADER
380#include "SystemZGenAsmMatcher.inc"
381
382private:
383 MCAsmParser &Parser;
384 enum RegisterGroup {
385 RegGR,
386 RegFP,
387 RegV,
388 RegAR,
389 RegCR
390 };
391 struct Register {
392 RegisterGroup Group;
393 unsigned Num;
394 SMLoc StartLoc, EndLoc;
395 };
396
397 bool parseRegister(Register &Reg);
398
399 bool parseRegister(Register &Reg, RegisterGroup Group, const unsigned *Regs,
400 bool IsAddress = false);
401
402 OperandMatchResultTy parseRegister(OperandVector &Operands,
403 RegisterGroup Group, const unsigned *Regs,
404 RegisterKind Kind);
405
406 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
407
408 bool parseAddress(bool &HaveReg1, Register &Reg1,
409 bool &HaveReg2, Register &Reg2,
410 const MCExpr *&Disp, const MCExpr *&Length);
411 bool parseAddressRegister(Register &Reg);
412
413 bool ParseDirectiveInsn(SMLoc L);
414
415 OperandMatchResultTy parseAddress(OperandVector &Operands,
416 MemoryKind MemKind, const unsigned *Regs,
417 RegisterKind RegKind);
418
419 OperandMatchResultTy parsePCRel(OperandVector &Operands, int64_t MinVal,
420 int64_t MaxVal, bool AllowTLS);
421
422 bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
423
424public:
425 SystemZAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
426 const MCInstrInfo &MII,
427 const MCTargetOptions &Options)
428 : MCTargetAsmParser(Options, sti, MII), Parser(parser) {
429 MCAsmParserExtension::Initialize(Parser);
430
431 // Alias the .word directive to .short.
432 parser.addAliasForDirective(".word", ".short");
433
434 // Initialize the set of available features.
435 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
436 }
437
438 // Override MCTargetAsmParser.
439 bool ParseDirective(AsmToken DirectiveID) override;
440 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
441 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
442 SMLoc NameLoc, OperandVector &Operands) override;
443 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
444 OperandVector &Operands, MCStreamer &Out,
445 uint64_t &ErrorInfo,
446 bool MatchingInlineAsm) override;
447
448 // Used by the TableGen code to parse particular operand types.
449 OperandMatchResultTy parseGR32(OperandVector &Operands) {
450 return parseRegister(Operands, RegGR, SystemZMC::GR32Regs, GR32Reg);
451 }
452 OperandMatchResultTy parseGRH32(OperandVector &Operands) {
453 return parseRegister(Operands, RegGR, SystemZMC::GRH32Regs, GRH32Reg);
454 }
455 OperandMatchResultTy parseGRX32(OperandVector &Operands) {
456 llvm_unreachable("GRX32 should only be used for pseudo instructions")::llvm::llvm_unreachable_internal("GRX32 should only be used for pseudo instructions"
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 456)
;
457 }
458 OperandMatchResultTy parseGR64(OperandVector &Operands) {
459 return parseRegister(Operands, RegGR, SystemZMC::GR64Regs, GR64Reg);
460 }
461 OperandMatchResultTy parseGR128(OperandVector &Operands) {
462 return parseRegister(Operands, RegGR, SystemZMC::GR128Regs, GR128Reg);
463 }
464 OperandMatchResultTy parseADDR32(OperandVector &Operands) {
465 return parseRegister(Operands, RegGR, SystemZMC::GR32Regs, ADDR32Reg);
466 }
467 OperandMatchResultTy parseADDR64(OperandVector &Operands) {
468 return parseRegister(Operands, RegGR, SystemZMC::GR64Regs, ADDR64Reg);
469 }
470 OperandMatchResultTy parseADDR128(OperandVector &Operands) {
471 llvm_unreachable("Shouldn't be used as an operand")::llvm::llvm_unreachable_internal("Shouldn't be used as an operand"
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 471)
;
472 }
473 OperandMatchResultTy parseFP32(OperandVector &Operands) {
474 return parseRegister(Operands, RegFP, SystemZMC::FP32Regs, FP32Reg);
475 }
476 OperandMatchResultTy parseFP64(OperandVector &Operands) {
477 return parseRegister(Operands, RegFP, SystemZMC::FP64Regs, FP64Reg);
478 }
479 OperandMatchResultTy parseFP128(OperandVector &Operands) {
480 return parseRegister(Operands, RegFP, SystemZMC::FP128Regs, FP128Reg);
481 }
482 OperandMatchResultTy parseVR32(OperandVector &Operands) {
483 return parseRegister(Operands, RegV, SystemZMC::VR32Regs, VR32Reg);
484 }
485 OperandMatchResultTy parseVR64(OperandVector &Operands) {
486 return parseRegister(Operands, RegV, SystemZMC::VR64Regs, VR64Reg);
487 }
488 OperandMatchResultTy parseVF128(OperandVector &Operands) {
489 llvm_unreachable("Shouldn't be used as an operand")::llvm::llvm_unreachable_internal("Shouldn't be used as an operand"
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 489)
;
490 }
491 OperandMatchResultTy parseVR128(OperandVector &Operands) {
492 return parseRegister(Operands, RegV, SystemZMC::VR128Regs, VR128Reg);
493 }
494 OperandMatchResultTy parseAR32(OperandVector &Operands) {
495 return parseRegister(Operands, RegAR, SystemZMC::AR32Regs, AR32Reg);
496 }
497 OperandMatchResultTy parseCR64(OperandVector &Operands) {
498 return parseRegister(Operands, RegCR, SystemZMC::CR64Regs, CR64Reg);
499 }
500 OperandMatchResultTy parseAnyReg(OperandVector &Operands) {
501 return parseAnyRegister(Operands);
502 }
503 OperandMatchResultTy parseBDAddr32(OperandVector &Operands) {
504 return parseAddress(Operands, BDMem, SystemZMC::GR32Regs, ADDR32Reg);
505 }
506 OperandMatchResultTy parseBDAddr64(OperandVector &Operands) {
507 return parseAddress(Operands, BDMem, SystemZMC::GR64Regs, ADDR64Reg);
508 }
509 OperandMatchResultTy parseBDXAddr64(OperandVector &Operands) {
510 return parseAddress(Operands, BDXMem, SystemZMC::GR64Regs, ADDR64Reg);
511 }
512 OperandMatchResultTy parseBDLAddr64(OperandVector &Operands) {
513 return parseAddress(Operands, BDLMem, SystemZMC::GR64Regs, ADDR64Reg);
514 }
515 OperandMatchResultTy parseBDRAddr64(OperandVector &Operands) {
516 return parseAddress(Operands, BDRMem, SystemZMC::GR64Regs, ADDR64Reg);
517 }
518 OperandMatchResultTy parseBDVAddr64(OperandVector &Operands) {
519 return parseAddress(Operands, BDVMem, SystemZMC::GR64Regs, ADDR64Reg);
520 }
521 OperandMatchResultTy parsePCRel12(OperandVector &Operands) {
522 return parsePCRel(Operands, -(1LL << 12), (1LL << 12) - 1, false);
523 }
524 OperandMatchResultTy parsePCRel16(OperandVector &Operands) {
525 return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, false);
526 }
527 OperandMatchResultTy parsePCRel24(OperandVector &Operands) {
528 return parsePCRel(Operands, -(1LL << 24), (1LL << 24) - 1, false);
529 }
530 OperandMatchResultTy parsePCRel32(OperandVector &Operands) {
531 return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1, false);
532 }
533 OperandMatchResultTy parsePCRelTLS16(OperandVector &Operands) {
534 return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, true);
535 }
536 OperandMatchResultTy parsePCRelTLS32(OperandVector &Operands) {
537 return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1, true);
538 }
539};
540
541} // end anonymous namespace
542
543#define GET_REGISTER_MATCHER
544#define GET_SUBTARGET_FEATURE_NAME
545#define GET_MATCHER_IMPLEMENTATION
546#define GET_MNEMONIC_SPELL_CHECKER
547#include "SystemZGenAsmMatcher.inc"
548
549// Used for the .insn directives; contains information needed to parse the
550// operands in the directive.
551struct InsnMatchEntry {
552 StringRef Format;
553 uint64_t Opcode;
554 int32_t NumOperands;
555 MatchClassKind OperandKinds[5];
556};
557
558// For equal_range comparison.
559struct CompareInsn {
560 bool operator() (const InsnMatchEntry &LHS, StringRef RHS) {
561 return LHS.Format < RHS;
562 }
563 bool operator() (StringRef LHS, const InsnMatchEntry &RHS) {
564 return LHS < RHS.Format;
565 }
566 bool operator() (const InsnMatchEntry &LHS, const InsnMatchEntry &RHS) {
567 return LHS.Format < RHS.Format;
568 }
569};
570
571// Table initializing information for parsing the .insn directive.
572static struct InsnMatchEntry InsnMatchTable[] = {
573 /* Format, Opcode, NumOperands, OperandKinds */
574 { "e", SystemZ::InsnE, 1,
575 { MCK_U16Imm } },
576 { "ri", SystemZ::InsnRI, 3,
577 { MCK_U32Imm, MCK_AnyReg, MCK_S16Imm } },
578 { "rie", SystemZ::InsnRIE, 4,
579 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
580 { "ril", SystemZ::InsnRIL, 3,
581 { MCK_U48Imm, MCK_AnyReg, MCK_PCRel32 } },
582 { "rilu", SystemZ::InsnRILU, 3,
583 { MCK_U48Imm, MCK_AnyReg, MCK_U32Imm } },
584 { "ris", SystemZ::InsnRIS, 5,
585 { MCK_U48Imm, MCK_AnyReg, MCK_S8Imm, MCK_U4Imm, MCK_BDAddr64Disp12 } },
586 { "rr", SystemZ::InsnRR, 3,
587 { MCK_U16Imm, MCK_AnyReg, MCK_AnyReg } },
588 { "rre", SystemZ::InsnRRE, 3,
589 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg } },
590 { "rrf", SystemZ::InsnRRF, 5,
591 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm } },
592 { "rrs", SystemZ::InsnRRS, 5,
593 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm, MCK_BDAddr64Disp12 } },
594 { "rs", SystemZ::InsnRS, 4,
595 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
596 { "rse", SystemZ::InsnRSE, 4,
597 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
598 { "rsi", SystemZ::InsnRSI, 4,
599 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
600 { "rsy", SystemZ::InsnRSY, 4,
601 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp20 } },
602 { "rx", SystemZ::InsnRX, 3,
603 { MCK_U32Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
604 { "rxe", SystemZ::InsnRXE, 3,
605 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
606 { "rxf", SystemZ::InsnRXF, 4,
607 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
608 { "rxy", SystemZ::InsnRXY, 3,
609 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp20 } },
610 { "s", SystemZ::InsnS, 2,
611 { MCK_U32Imm, MCK_BDAddr64Disp12 } },
612 { "si", SystemZ::InsnSI, 3,
613 { MCK_U32Imm, MCK_BDAddr64Disp12, MCK_S8Imm } },
614 { "sil", SystemZ::InsnSIL, 3,
615 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_U16Imm } },
616 { "siy", SystemZ::InsnSIY, 3,
617 { MCK_U48Imm, MCK_BDAddr64Disp20, MCK_U8Imm } },
618 { "ss", SystemZ::InsnSS, 4,
619 { MCK_U48Imm, MCK_BDXAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
620 { "sse", SystemZ::InsnSSE, 3,
621 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12 } },
622 { "ssf", SystemZ::InsnSSF, 4,
623 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } }
624};
625
626void SystemZOperand::print(raw_ostream &OS) const {
627 llvm_unreachable("Not implemented")::llvm::llvm_unreachable_internal("Not implemented", "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 627)
;
628}
629
630// Parse one register of the form %<prefix><number>.
631bool SystemZAsmParser::parseRegister(Register &Reg) {
632 Reg.StartLoc = Parser.getTok().getLoc();
633
634 // Eat the % prefix.
635 if (Parser.getTok().isNot(AsmToken::Percent))
126
Calling 'AsmToken::isNot'
128
Returning from 'AsmToken::isNot'
129
Taking true branch
636 return Error(Parser.getTok().getLoc(), "register expected");
130
Calling constructor for 'Twine'
137
Returning from constructor for 'Twine'
138
Calling 'MCAsmParserExtension::Error'
141
Returning from 'MCAsmParserExtension::Error'
142
Returning without writing to 'Reg.Group'
637 Parser.Lex();
638
639 // Expect a register name.
640 if (Parser.getTok().isNot(AsmToken::Identifier))
641 return Error(Reg.StartLoc, "invalid register");
642
643 // Check that there's a prefix.
644 StringRef Name = Parser.getTok().getString();
645 if (Name.size() < 2)
646 return Error(Reg.StartLoc, "invalid register");
647 char Prefix = Name[0];
648
649 // Treat the rest of the register name as a register number.
650 if (Name.substr(1).getAsInteger(10, Reg.Num))
651 return Error(Reg.StartLoc, "invalid register");
652
653 // Look for valid combinations of prefix and number.
654 if (Prefix == 'r' && Reg.Num < 16)
655 Reg.Group = RegGR;
656 else if (Prefix == 'f' && Reg.Num < 16)
657 Reg.Group = RegFP;
658 else if (Prefix == 'v' && Reg.Num < 32)
659 Reg.Group = RegV;
660 else if (Prefix == 'a' && Reg.Num < 16)
661 Reg.Group = RegAR;
662 else if (Prefix == 'c' && Reg.Num < 16)
663 Reg.Group = RegCR;
664 else
665 return Error(Reg.StartLoc, "invalid register");
666
667 Reg.EndLoc = Parser.getTok().getLoc();
668 Parser.Lex();
669 return false;
670}
671
672// Parse a register of group Group. If Regs is nonnull, use it to map
673// the raw register number to LLVM numbering, with zero entries
674// indicating an invalid register. IsAddress says whether the
675// register appears in an address context. Allow FP Group if expecting
676// RegV Group, since the f-prefix yields the FP group even while used
677// with vector instructions.
678bool SystemZAsmParser::parseRegister(Register &Reg, RegisterGroup Group,
679 const unsigned *Regs, bool IsAddress) {
680 if (parseRegister(Reg))
681 return true;
682 if (Reg.Group != Group && !(Reg.Group == RegFP && Group == RegV))
683 return Error(Reg.StartLoc, "invalid operand for instruction");
684 if (Regs && Regs[Reg.Num] == 0)
685 return Error(Reg.StartLoc, "invalid register pair");
686 if (Reg.Num == 0 && IsAddress)
687 return Error(Reg.StartLoc, "%r0 used in an address");
688 if (Regs)
689 Reg.Num = Regs[Reg.Num];
690 return false;
691}
692
693// Parse a register and add it to Operands. The other arguments are as above.
694OperandMatchResultTy
695SystemZAsmParser::parseRegister(OperandVector &Operands, RegisterGroup Group,
696 const unsigned *Regs, RegisterKind Kind) {
697 if (Parser.getTok().isNot(AsmToken::Percent))
698 return MatchOperand_NoMatch;
699
700 Register Reg;
701 bool IsAddress = (Kind == ADDR32Reg || Kind == ADDR64Reg);
702 if (parseRegister(Reg, Group, Regs, IsAddress))
703 return MatchOperand_ParseFail;
704
705 Operands.push_back(SystemZOperand::createReg(Kind, Reg.Num,
706 Reg.StartLoc, Reg.EndLoc));
707 return MatchOperand_Success;
708}
709
710// Parse any type of register (including integers) and add it to Operands.
711OperandMatchResultTy
712SystemZAsmParser::parseAnyRegister(OperandVector &Operands) {
713 // Handle integer values.
714 if (Parser.getTok().is(AsmToken::Integer)) {
715 const MCExpr *Register;
716 SMLoc StartLoc = Parser.getTok().getLoc();
717 if (Parser.parseExpression(Register))
718 return MatchOperand_ParseFail;
719
720 if (auto *CE = dyn_cast<MCConstantExpr>(Register)) {
721 int64_t Value = CE->getValue();
722 if (Value < 0 || Value > 15) {
723 Error(StartLoc, "invalid register");
724 return MatchOperand_ParseFail;
725 }
726 }
727
728 SMLoc EndLoc =
729 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
730
731 Operands.push_back(SystemZOperand::createImm(Register, StartLoc, EndLoc));
732 }
733 else {
734 Register Reg;
735 if (parseRegister(Reg))
736 return MatchOperand_ParseFail;
737
738 // Map to the correct register kind.
739 RegisterKind Kind;
740 unsigned RegNo;
741 if (Reg.Group == RegGR) {
742 Kind = GR64Reg;
743 RegNo = SystemZMC::GR64Regs[Reg.Num];
744 }
745 else if (Reg.Group == RegFP) {
746 Kind = FP64Reg;
747 RegNo = SystemZMC::FP64Regs[Reg.Num];
748 }
749 else if (Reg.Group == RegV) {
750 Kind = VR128Reg;
751 RegNo = SystemZMC::VR128Regs[Reg.Num];
752 }
753 else if (Reg.Group == RegAR) {
754 Kind = AR32Reg;
755 RegNo = SystemZMC::AR32Regs[Reg.Num];
756 }
757 else if (Reg.Group == RegCR) {
758 Kind = CR64Reg;
759 RegNo = SystemZMC::CR64Regs[Reg.Num];
760 }
761 else {
762 return MatchOperand_ParseFail;
763 }
764
765 Operands.push_back(SystemZOperand::createReg(Kind, RegNo,
766 Reg.StartLoc, Reg.EndLoc));
767 }
768 return MatchOperand_Success;
769}
770
771// Parse a memory operand into Reg1, Reg2, Disp, and Length.
772bool SystemZAsmParser::parseAddress(bool &HaveReg1, Register &Reg1,
773 bool &HaveReg2, Register &Reg2,
774 const MCExpr *&Disp,
775 const MCExpr *&Length) {
776 // Parse the displacement, which must always be present.
777 if (getParser().parseExpression(Disp))
9
Calling 'MCAsmParserExtension::getParser'
10
Returning from 'MCAsmParserExtension::getParser'
11
Assuming the condition is false
12
Taking false branch
37
Calling 'MCAsmParserExtension::getParser'
38
Returning from 'MCAsmParserExtension::getParser'
39
Assuming the condition is false
40
Taking false branch
67
Calling 'MCAsmParserExtension::getParser'
68
Returning from 'MCAsmParserExtension::getParser'
69
Assuming the condition is false
70
Taking false branch
97
Calling 'MCAsmParserExtension::getParser'
98
Returning from 'MCAsmParserExtension::getParser'
99
Assuming the condition is false
100
Taking false branch
778 return true;
779
780 // Parse the optional base and index.
781 HaveReg1 = false;
782 HaveReg2 = false;
783 Length = nullptr;
784 if (getLexer().is(AsmToken::LParen)) {
13
Calling 'MCAsmParserExtension::getLexer'
16
Returning from 'MCAsmParserExtension::getLexer'
17
Calling 'MCAsmLexer::is'
23
Returning from 'MCAsmLexer::is'
24
Taking false branch
41
Calling 'MCAsmParserExtension::getLexer'
44
Returning from 'MCAsmParserExtension::getLexer'
45
Calling 'MCAsmLexer::is'
51
Returning from 'MCAsmLexer::is'
52
Taking false branch
71
Calling 'MCAsmParserExtension::getLexer'
74
Returning from 'MCAsmParserExtension::getLexer'
75
Calling 'MCAsmLexer::is'
81
Returning from 'MCAsmLexer::is'
82
Taking false branch
101
Calling 'MCAsmParserExtension::getLexer'
104
Returning from 'MCAsmParserExtension::getLexer'
105
Calling 'MCAsmLexer::is'
111
Returning from 'MCAsmLexer::is'
112
Taking true branch
785 Parser.Lex();
786
787 if (getLexer().is(AsmToken::Percent)) {
113
Calling 'MCAsmParserExtension::getLexer'
116
Returning from 'MCAsmParserExtension::getLexer'
117
Calling 'MCAsmLexer::is'
123
Returning from 'MCAsmLexer::is'
124
Taking true branch
788 // Parse the first register.
789 HaveReg1 = true;
790 if (parseRegister(Reg1))
125
Calling 'SystemZAsmParser::parseRegister'
143
Returning from 'SystemZAsmParser::parseRegister'
144
Assuming the condition is false
145
Taking false branch
791 return true;
792 } else {
793 // Parse the length.
794 if (getParser().parseExpression(Length))
795 return true;
796 }
797
798 // Check whether there's a second register.
799 if (getLexer().is(AsmToken::Comma)) {
146
Calling 'MCAsmParserExtension::getLexer'
149
Returning from 'MCAsmParserExtension::getLexer'
150
Calling 'MCAsmLexer::is'
156
Returning from 'MCAsmLexer::is'
157
Taking false branch
800 Parser.Lex();
801 HaveReg2 = true;
802 if (parseRegister(Reg2))
803 return true;
804 }
805
806 // Consume the closing bracket.
807 if (getLexer().isNot(AsmToken::RParen))
158
Calling 'MCAsmParserExtension::getLexer'
161
Returning from 'MCAsmParserExtension::getLexer'
162
Calling 'MCAsmLexer::isNot'
168
Returning from 'MCAsmLexer::isNot'
169
Taking false branch
808 return Error(Parser.getTok().getLoc(), "unexpected token in address");
809 Parser.Lex();
810 }
811 return false;
25
Returning without writing to 'Reg1.Group'
53
Returning without writing to 'Reg1.Group'
83
Returning without writing to 'Reg1.Group'
170
Returning without writing to 'Reg1.Group'
812}
813
814// Verify that Reg is a valid address register (base or index).
815bool
816SystemZAsmParser::parseAddressRegister(Register &Reg) {
817 if (Reg.Group == RegV) {
818 Error(Reg.StartLoc, "invalid use of vector addressing");
819 return true;
820 } else if (Reg.Group != RegGR) {
821 Error(Reg.StartLoc, "invalid address register");
822 return true;
823 } else if (Reg.Num == 0) {
824 Error(Reg.StartLoc, "%r0 used in an address");
825 return true;
826 }
827 return false;
828}
829
830// Parse a memory operand and add it to Operands. The other arguments
831// are as above.
832OperandMatchResultTy
833SystemZAsmParser::parseAddress(OperandVector &Operands, MemoryKind MemKind,
834 const unsigned *Regs, RegisterKind RegKind) {
835 SMLoc StartLoc = Parser.getTok().getLoc();
836 unsigned Base = 0, Index = 0, LengthReg = 0;
837 Register Reg1, Reg2;
838 bool HaveReg1, HaveReg2;
839 const MCExpr *Disp;
840 const MCExpr *Length;
841 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Disp, Length))
842 return MatchOperand_ParseFail;
843
844 switch (MemKind) {
845 case BDMem:
846 // If we have Reg1, it must be an address register.
847 if (HaveReg1) {
848 if (parseAddressRegister(Reg1))
849 return MatchOperand_ParseFail;
850 Base = Regs[Reg1.Num];
851 }
852 // There must be no Reg2 or length.
853 if (Length) {
854 Error(StartLoc, "invalid use of length addressing");
855 return MatchOperand_ParseFail;
856 }
857 if (HaveReg2) {
858 Error(StartLoc, "invalid use of indexed addressing");
859 return MatchOperand_ParseFail;
860 }
861 break;
862 case BDXMem:
863 // If we have Reg1, it must be an address register.
864 if (HaveReg1) {
865 if (parseAddressRegister(Reg1))
866 return MatchOperand_ParseFail;
867 // If the are two registers, the first one is the index and the
868 // second is the base.
869 if (HaveReg2)
870 Index = Regs[Reg1.Num];
871 else
872 Base = Regs[Reg1.Num];
873 }
874 // If we have Reg2, it must be an address register.
875 if (HaveReg2) {
876 if (parseAddressRegister(Reg2))
877 return MatchOperand_ParseFail;
878 Base = Regs[Reg2.Num];
879 }
880 // There must be no length.
881 if (Length) {
882 Error(StartLoc, "invalid use of length addressing");
883 return MatchOperand_ParseFail;
884 }
885 break;
886 case BDLMem:
887 // If we have Reg2, it must be an address register.
888 if (HaveReg2) {
889 if (parseAddressRegister(Reg2))
890 return MatchOperand_ParseFail;
891 Base = Regs[Reg2.Num];
892 }
893 // We cannot support base+index addressing.
894 if (HaveReg1 && HaveReg2) {
895 Error(StartLoc, "invalid use of indexed addressing");
896 return MatchOperand_ParseFail;
897 }
898 // We must have a length.
899 if (!Length) {
900 Error(StartLoc, "missing length in address");
901 return MatchOperand_ParseFail;
902 }
903 break;
904 case BDRMem:
905 // We must have Reg1, and it must be a GPR.
906 if (!HaveReg1 || Reg1.Group != RegGR) {
907 Error(StartLoc, "invalid operand for instruction");
908 return MatchOperand_ParseFail;
909 }
910 LengthReg = SystemZMC::GR64Regs[Reg1.Num];
911 // If we have Reg2, it must be an address register.
912 if (HaveReg2) {
913 if (parseAddressRegister(Reg2))
914 return MatchOperand_ParseFail;
915 Base = Regs[Reg2.Num];
916 }
917 // There must be no length.
918 if (Length) {
919 Error(StartLoc, "invalid use of length addressing");
920 return MatchOperand_ParseFail;
921 }
922 break;
923 case BDVMem:
924 // We must have Reg1, and it must be a vector register.
925 if (!HaveReg1 || Reg1.Group != RegV) {
926 Error(StartLoc, "vector index required in address");
927 return MatchOperand_ParseFail;
928 }
929 Index = SystemZMC::VR128Regs[Reg1.Num];
930 // If we have Reg2, it must be an address register.
931 if (HaveReg2) {
932 if (parseAddressRegister(Reg2))
933 return MatchOperand_ParseFail;
934 Base = Regs[Reg2.Num];
935 }
936 // There must be no length.
937 if (Length) {
938 Error(StartLoc, "invalid use of length addressing");
939 return MatchOperand_ParseFail;
940 }
941 break;
942 }
943
944 SMLoc EndLoc =
945 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
946 Operands.push_back(SystemZOperand::createMem(MemKind, RegKind, Base, Disp,
947 Index, Length, LengthReg,
948 StartLoc, EndLoc));
949 return MatchOperand_Success;
950}
951
952bool SystemZAsmParser::ParseDirective(AsmToken DirectiveID) {
953 StringRef IDVal = DirectiveID.getIdentifier();
954
955 if (IDVal == ".insn")
956 return ParseDirectiveInsn(DirectiveID.getLoc());
957
958 return true;
959}
960
961/// ParseDirectiveInsn
962/// ::= .insn [ format, encoding, (operands (, operands)*) ]
963bool SystemZAsmParser::ParseDirectiveInsn(SMLoc L) {
964 MCAsmParser &Parser = getParser();
965
966 // Expect instruction format as identifier.
967 StringRef Format;
968 SMLoc ErrorLoc = Parser.getTok().getLoc();
969 if (Parser.parseIdentifier(Format))
970 return Error(ErrorLoc, "expected instruction format");
971
972 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> Operands;
973
974 // Find entry for this format in InsnMatchTable.
975 auto EntryRange =
976 std::equal_range(std::begin(InsnMatchTable), std::end(InsnMatchTable),
977 Format, CompareInsn());
978
979 // If first == second, couldn't find a match in the table.
980 if (EntryRange.first == EntryRange.second)
981 return Error(ErrorLoc, "unrecognized format");
982
983 struct InsnMatchEntry *Entry = EntryRange.first;
984
985 // Format should match from equal_range.
986 assert(Entry->Format == Format)(static_cast <bool> (Entry->Format == Format) ? void
(0) : __assert_fail ("Entry->Format == Format", "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 986, __extension__ __PRETTY_FUNCTION__))
;
987
988 // Parse the following operands using the table's information.
989 for (int i = 0; i < Entry->NumOperands; i++) {
990 MatchClassKind Kind = Entry->OperandKinds[i];
991
992 SMLoc StartLoc = Parser.getTok().getLoc();
993
994 // Always expect commas as separators for operands.
995 if (getLexer().isNot(AsmToken::Comma))
996 return Error(StartLoc, "unexpected token in directive");
997 Lex();
998
999 // Parse operands.
1000 OperandMatchResultTy ResTy;
1001 if (Kind == MCK_AnyReg)
1002 ResTy = parseAnyReg(Operands);
1003 else if (Kind == MCK_BDXAddr64Disp12 || Kind == MCK_BDXAddr64Disp20)
1004 ResTy = parseBDXAddr64(Operands);
1005 else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20)
1006 ResTy = parseBDAddr64(Operands);
1007 else if (Kind == MCK_PCRel32)
1008 ResTy = parsePCRel32(Operands);
1009 else if (Kind == MCK_PCRel16)
1010 ResTy = parsePCRel16(Operands);
1011 else {
1012 // Only remaining operand kind is an immediate.
1013 const MCExpr *Expr;
1014 SMLoc StartLoc = Parser.getTok().getLoc();
1015
1016 // Expect immediate expression.
1017 if (Parser.parseExpression(Expr))
1018 return Error(StartLoc, "unexpected token in directive");
1019
1020 SMLoc EndLoc =
1021 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1022
1023 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1024 ResTy = MatchOperand_Success;
1025 }
1026
1027 if (ResTy != MatchOperand_Success)
1028 return true;
1029 }
1030
1031 // Build the instruction with the parsed operands.
1032 MCInst Inst = MCInstBuilder(Entry->Opcode);
1033
1034 for (size_t i = 0; i < Operands.size(); i++) {
1035 MCParsedAsmOperand &Operand = *Operands[i];
1036 MatchClassKind Kind = Entry->OperandKinds[i];
1037
1038 // Verify operand.
1039 unsigned Res = validateOperandClass(Operand, Kind);
1040 if (Res != Match_Success)
1041 return Error(Operand.getStartLoc(), "unexpected operand type");
1042
1043 // Add operands to instruction.
1044 SystemZOperand &ZOperand = static_cast<SystemZOperand &>(Operand);
1045 if (ZOperand.isReg())
1046 ZOperand.addRegOperands(Inst, 1);
1047 else if (ZOperand.isMem(BDMem))
1048 ZOperand.addBDAddrOperands(Inst, 2);
1049 else if (ZOperand.isMem(BDXMem))
1050 ZOperand.addBDXAddrOperands(Inst, 3);
1051 else if (ZOperand.isImm())
1052 ZOperand.addImmOperands(Inst, 1);
1053 else
1054 llvm_unreachable("unexpected operand type")::llvm::llvm_unreachable_internal("unexpected operand type", "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 1054)
;
1055 }
1056
1057 // Emit as a regular instruction.
1058 Parser.getStreamer().EmitInstruction(Inst, getSTI());
1059
1060 return false;
1061}
1062
1063bool SystemZAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1064 SMLoc &EndLoc) {
1065 Register Reg;
1066 if (parseRegister(Reg))
1067 return true;
1068 if (Reg.Group == RegGR)
1069 RegNo = SystemZMC::GR64Regs[Reg.Num];
1070 else if (Reg.Group == RegFP)
1071 RegNo = SystemZMC::FP64Regs[Reg.Num];
1072 else if (Reg.Group == RegV)
1073 RegNo = SystemZMC::VR128Regs[Reg.Num];
1074 else if (Reg.Group == RegAR)
1075 RegNo = SystemZMC::AR32Regs[Reg.Num];
1076 else if (Reg.Group == RegCR)
1077 RegNo = SystemZMC::CR64Regs[Reg.Num];
1078 StartLoc = Reg.StartLoc;
1079 EndLoc = Reg.EndLoc;
1080 return false;
1081}
1082
1083bool SystemZAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1084 StringRef Name, SMLoc NameLoc,
1085 OperandVector &Operands) {
1086 Operands.push_back(SystemZOperand::createToken(Name, NameLoc));
1087
1088 // Read the remaining operands.
1089 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1
Taking true branch
1090 // Read the first operand.
1091 if (parseOperand(Operands, Name)) {
2
Taking false branch
1092 return true;
1093 }
1094
1095 // Read any subsequent operands.
1096 while (getLexer().is(AsmToken::Comma)) {
3
Loop condition is true. Entering loop body
31
Loop condition is true. Entering loop body
59
Loop condition is true. Entering loop body
89
Loop condition is true. Entering loop body
1097 Parser.Lex();
1098 if (parseOperand(Operands, Name)) {
4
Calling 'SystemZAsmParser::parseOperand'
29
Returning from 'SystemZAsmParser::parseOperand'
30
Taking false branch
32
Calling 'SystemZAsmParser::parseOperand'
57
Returning from 'SystemZAsmParser::parseOperand'
58
Taking false branch
60
Calling 'SystemZAsmParser::parseOperand'
87
Returning from 'SystemZAsmParser::parseOperand'
88
Taking false branch
90
Calling 'SystemZAsmParser::parseOperand'
1099 return true;
1100 }
1101 }
1102 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1103 SMLoc Loc = getLexer().getLoc();
1104 return Error(Loc, "unexpected token in argument list");
1105 }
1106 }
1107
1108 // Consume the EndOfStatement.
1109 Parser.Lex();
1110 return false;
1111}
1112
1113bool SystemZAsmParser::parseOperand(OperandVector &Operands,
1114 StringRef Mnemonic) {
1115 // Check if the current operand has a custom associated parser, if so, try to
1116 // custom parse the operand, or fallback to the general approach. Force all
1117 // features to be available during the operand check, or else we will fail to
1118 // find the custom parser, and then we will later get an InvalidOperand error
1119 // instead of a MissingFeature errror.
1120 uint64_t AvailableFeatures = getAvailableFeatures();
1121 setAvailableFeatures(~(uint64_t)0);
1122 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1123 setAvailableFeatures(AvailableFeatures);
1124 if (ResTy == MatchOperand_Success)
5
Taking false branch
33
Taking false branch
61
Assuming 'ResTy' is not equal to MatchOperand_Success
62
Taking false branch
91
Assuming 'ResTy' is not equal to MatchOperand_Success
92
Taking false branch
1125 return false;
1126
1127 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1128 // there was a match, but an error occurred, in which case, just return that
1129 // the operand parsing failed.
1130 if (ResTy == MatchOperand_ParseFail)
6
Taking false branch
34
Taking false branch
63
Assuming 'ResTy' is not equal to MatchOperand_ParseFail
64
Taking false branch
93
Assuming 'ResTy' is not equal to MatchOperand_ParseFail
94
Taking false branch
1131 return true;
1132
1133 // Check for a register. All real register operands should have used
1134 // a context-dependent parse routine, which gives the required register
1135 // class. The code is here to mop up other cases, like those where
1136 // the instruction isn't recognized.
1137 if (Parser.getTok().is(AsmToken::Percent)) {
7
Taking false branch
35
Taking false branch
65
Taking false branch
95
Taking false branch
1138 Register Reg;
1139 if (parseRegister(Reg))
1140 return true;
1141 Operands.push_back(SystemZOperand::createInvalid(Reg.StartLoc, Reg.EndLoc));
1142 return false;
1143 }
1144
1145 // The only other type of operand is an immediate or address. As above,
1146 // real address operands should have used a context-dependent parse routine,
1147 // so we treat any plain expression as an immediate.
1148 SMLoc StartLoc = Parser.getTok().getLoc();
1149 Register Reg1, Reg2;
1150 bool HaveReg1, HaveReg2;
1151 const MCExpr *Expr;
1152 const MCExpr *Length;
1153 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Expr, Length))
8
Calling 'SystemZAsmParser::parseAddress'
26
Returning from 'SystemZAsmParser::parseAddress'
27
Taking false branch
36
Calling 'SystemZAsmParser::parseAddress'
54
Returning from 'SystemZAsmParser::parseAddress'
55
Taking false branch
66
Calling 'SystemZAsmParser::parseAddress'
84
Returning from 'SystemZAsmParser::parseAddress'
85
Taking false branch
96
Calling 'SystemZAsmParser::parseAddress'
171
Returning from 'SystemZAsmParser::parseAddress'
172
Taking false branch
1154 return true;
1155 // If the register combination is not valid for any instruction, reject it.
1156 // Otherwise, fall back to reporting an unrecognized instruction.
1157 if (HaveReg1 && Reg1.Group != RegGR && Reg1.Group != RegV
173
The left operand of '!=' is a garbage value
1158 && parseAddressRegister(Reg1))
1159 return true;
1160 if (HaveReg2 && parseAddressRegister(Reg2))
1161 return true;
1162
1163 SMLoc EndLoc =
1164 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1165 if (HaveReg1 || HaveReg2 || Length)
28
Taking false branch
56
Taking false branch
86
Taking false branch
1166 Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));
1167 else
1168 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1169 return false;
1170}
1171
1172static std::string SystemZMnemonicSpellCheck(StringRef S, uint64_t FBS,
1173 unsigned VariantID = 0);
1174
1175bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1176 OperandVector &Operands,
1177 MCStreamer &Out,
1178 uint64_t &ErrorInfo,
1179 bool MatchingInlineAsm) {
1180 MCInst Inst;
1181 unsigned MatchResult;
1182
1183 MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
1184 MatchingInlineAsm);
1185 switch (MatchResult) {
1186 case Match_Success:
1187 Inst.setLoc(IDLoc);
1188 Out.EmitInstruction(Inst, getSTI());
1189 return false;
1190
1191 case Match_MissingFeature: {
1192 assert(ErrorInfo && "Unknown missing feature!")(static_cast <bool> (ErrorInfo && "Unknown missing feature!"
) ? void (0) : __assert_fail ("ErrorInfo && \"Unknown missing feature!\""
, "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 1192, __extension__ __PRETTY_FUNCTION__))
;
1193 // Special case the error message for the very common case where only
1194 // a single subtarget feature is missing
1195 std::string Msg = "instruction requires:";
1196 uint64_t Mask = 1;
1197 for (unsigned I = 0; I < sizeof(ErrorInfo) * 8 - 1; ++I) {
1198 if (ErrorInfo & Mask) {
1199 Msg += " ";
1200 Msg += getSubtargetFeatureName(ErrorInfo & Mask);
1201 }
1202 Mask <<= 1;
1203 }
1204 return Error(IDLoc, Msg);
1205 }
1206
1207 case Match_InvalidOperand: {
1208 SMLoc ErrorLoc = IDLoc;
1209 if (ErrorInfo != ~0ULL) {
1210 if (ErrorInfo >= Operands.size())
1211 return Error(IDLoc, "too few operands for instruction");
1212
1213 ErrorLoc = ((SystemZOperand &)*Operands[ErrorInfo]).getStartLoc();
1214 if (ErrorLoc == SMLoc())
1215 ErrorLoc = IDLoc;
1216 }
1217 return Error(ErrorLoc, "invalid operand for instruction");
1218 }
1219
1220 case Match_MnemonicFail: {
1221 uint64_t FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1222 std::string Suggestion = SystemZMnemonicSpellCheck(
1223 ((SystemZOperand &)*Operands[0]).getToken(), FBS);
1224 return Error(IDLoc, "invalid instruction" + Suggestion,
1225 ((SystemZOperand &)*Operands[0]).getLocRange());
1226 }
1227 }
1228
1229 llvm_unreachable("Unexpected match type")::llvm::llvm_unreachable_internal("Unexpected match type", "/build/llvm-toolchain-snapshot-7~svn326246/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp"
, 1229)
;
1230}
1231
1232OperandMatchResultTy
1233SystemZAsmParser::parsePCRel(OperandVector &Operands, int64_t MinVal,
1234 int64_t MaxVal, bool AllowTLS) {
1235 MCContext &Ctx = getContext();
1236 MCStreamer &Out = getStreamer();
1237 const MCExpr *Expr;
1238 SMLoc StartLoc = Parser.getTok().getLoc();
1239 if (getParser().parseExpression(Expr))
1240 return MatchOperand_NoMatch;
1241
1242 // For consistency with the GNU assembler, treat immediates as offsets
1243 // from ".".
1244 if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
1245 int64_t Value = CE->getValue();
1246 if ((Value & 1) || Value < MinVal || Value > MaxVal) {
1247 Error(StartLoc, "offset out of range");
1248 return MatchOperand_ParseFail;
1249 }
1250 MCSymbol *Sym = Ctx.createTempSymbol();
1251 Out.EmitLabel(Sym);
1252 const MCExpr *Base = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
1253 Ctx);
1254 Expr = Value == 0 ? Base : MCBinaryExpr::createAdd(Base, Expr, Ctx);
1255 }
1256
1257 // Optionally match :tls_gdcall: or :tls_ldcall: followed by a TLS symbol.
1258 const MCExpr *Sym = nullptr;
1259 if (AllowTLS && getLexer().is(AsmToken::Colon)) {
1260 Parser.Lex();
1261
1262 if (Parser.getTok().isNot(AsmToken::Identifier)) {
1263 Error(Parser.getTok().getLoc(), "unexpected token");
1264 return MatchOperand_ParseFail;
1265 }
1266
1267 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
1268 StringRef Name = Parser.getTok().getString();
1269 if (Name == "tls_gdcall")
1270 Kind = MCSymbolRefExpr::VK_TLSGD;
1271 else if (Name == "tls_ldcall")
1272 Kind = MCSymbolRefExpr::VK_TLSLDM;
1273 else {
1274 Error(Parser.getTok().getLoc(), "unknown TLS tag");
1275 return MatchOperand_ParseFail;
1276 }
1277 Parser.Lex();
1278
1279 if (Parser.getTok().isNot(AsmToken::Colon)) {
1280 Error(Parser.getTok().getLoc(), "unexpected token");
1281 return MatchOperand_ParseFail;
1282 }
1283 Parser.Lex();
1284
1285 if (Parser.getTok().isNot(AsmToken::Identifier)) {
1286 Error(Parser.getTok().getLoc(), "unexpected token");
1287 return MatchOperand_ParseFail;
1288 }
1289
1290 StringRef Identifier = Parser.getTok().getString();
1291 Sym = MCSymbolRefExpr::create(Ctx.getOrCreateSymbol(Identifier),
1292 Kind, Ctx);
1293 Parser.Lex();
1294 }
1295
1296 SMLoc EndLoc =
1297 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1298
1299 if (AllowTLS)
1300 Operands.push_back(SystemZOperand::createImmTLS(Expr, Sym,
1301 StartLoc, EndLoc));
1302 else
1303 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1304
1305 return MatchOperand_Success;
1306}
1307
1308// Force static initialization.
1309extern "C" void LLVMInitializeSystemZAsmParser() {
1310 RegisterMCAsmParser<SystemZAsmParser> X(getTheSystemZTarget());
1311}

/build/llvm-toolchain-snapshot-7~svn326246/include/llvm/MC/MCParser/MCAsmParserExtension.h

1//===- llvm/MC/MCAsmParserExtension.h - Asm Parser Hooks --------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
11#define LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
12
13#include "llvm/ADT/STLExtras.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/MC/MCParser/MCAsmLexer.h"
16#include "llvm/MC/MCParser/MCAsmParser.h"
17#include "llvm/Support/SMLoc.h"
18
19namespace llvm {
20
21class Twine;
22
23/// \brief Generic interface for extending the MCAsmParser,
24/// which is implemented by target and object file assembly parser
25/// implementations.
26class MCAsmParserExtension {
27 MCAsmParser *Parser;
28
29protected:
30 MCAsmParserExtension();
31
32 // Helper template for implementing static dispatch functions.
33 template<typename T, bool (T::*Handler)(StringRef, SMLoc)>
34 static bool HandleDirective(MCAsmParserExtension *Target,
35 StringRef Directive,
36 SMLoc DirectiveLoc) {
37 T *Obj = static_cast<T*>(Target);
38 return (Obj->*Handler)(Directive, DirectiveLoc);
39 }
40
41 bool BracketExpressionsSupported = false;
42
43public:
44 MCAsmParserExtension(const MCAsmParserExtension &) = delete;
45 MCAsmParserExtension &operator=(const MCAsmParserExtension &) = delete;
46 virtual ~MCAsmParserExtension();
47
48 /// \brief Initialize the extension for parsing using the given \p Parser.
49 /// The extension should use the AsmParser interfaces to register its
50 /// parsing routines.
51 virtual void Initialize(MCAsmParser &Parser);
52
53 /// \name MCAsmParser Proxy Interfaces
54 /// @{
55
56 MCContext &getContext() { return getParser().getContext(); }
57
58 MCAsmLexer &getLexer() { return getParser().getLexer(); }
14
Calling 'MCAsmParserExtension::getParser'
15
Returning from 'MCAsmParserExtension::getParser'
42
Calling 'MCAsmParserExtension::getParser'
43
Returning from 'MCAsmParserExtension::getParser'
72
Calling 'MCAsmParserExtension::getParser'
73
Returning from 'MCAsmParserExtension::getParser'
102
Calling 'MCAsmParserExtension::getParser'
103
Returning from 'MCAsmParserExtension::getParser'
114
Calling 'MCAsmParserExtension::getParser'
115
Returning from 'MCAsmParserExtension::getParser'
147
Calling 'MCAsmParserExtension::getParser'
148
Returning from 'MCAsmParserExtension::getParser'
159
Calling 'MCAsmParserExtension::getParser'
160
Returning from 'MCAsmParserExtension::getParser'
59 const MCAsmLexer &getLexer() const {
60 return const_cast<MCAsmParserExtension *>(this)->getLexer();
61 }
62
63 MCAsmParser &getParser() { return *Parser; }
64 const MCAsmParser &getParser() const {
65 return const_cast<MCAsmParserExtension*>(this)->getParser();
66 }
67
68 SourceMgr &getSourceManager() { return getParser().getSourceManager(); }
69 MCStreamer &getStreamer() { return getParser().getStreamer(); }
70
71 bool Warning(SMLoc L, const Twine &Msg) {
72 return getParser().Warning(L, Msg);
73 }
74
75 bool Error(SMLoc L, const Twine &Msg, SMRange Range = SMRange()) {
76 return getParser().Error(L, Msg, Range);
139
Calling 'MCAsmParserExtension::getParser'
140
Returning from 'MCAsmParserExtension::getParser'
77 }
78
79 void Note(SMLoc L, const Twine &Msg) {
80 getParser().Note(L, Msg);
81 }
82
83 bool TokError(const Twine &Msg) {
84 return getParser().TokError(Msg);
85 }
86
87 const AsmToken &Lex() { return getParser().Lex(); }
88 const AsmToken &getTok() { return getParser().getTok(); }
89 bool parseToken(AsmToken::TokenKind T,
90 const Twine &Msg = "unexpected token") {
91 return getParser().parseToken(T, Msg);
92 }
93
94 bool parseMany(function_ref<bool()> parseOne, bool hasComma = true) {
95 return getParser().parseMany(parseOne, hasComma);
96 }
97
98 bool parseOptionalToken(AsmToken::TokenKind T) {
99 return getParser().parseOptionalToken(T);
100 }
101
102 bool check(bool P, const Twine &Msg) {
103 return getParser().check(P, Msg);
104 }
105
106 bool check(bool P, SMLoc Loc, const Twine &Msg) {
107 return getParser().check(P, Loc, Msg);
108 }
109
110 bool addErrorSuffix(const Twine &Suffix) {
111 return getParser().addErrorSuffix(Suffix);
112 }
113
114 bool HasBracketExpressions() const { return BracketExpressionsSupported; }
115
116 /// @}
117};
118
119} // end namespace llvm
120
121#endif // LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H

/build/llvm-toolchain-snapshot-7~svn326246/include/llvm/MC/MCParser/MCAsmLexer.h

1//===- llvm/MC/MCAsmLexer.h - Abstract Asm Lexer Interface ------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLVM_MC_MCPARSER_MCASMLEXER_H
11#define LLVM_MC_MCPARSER_MCASMLEXER_H
12
13#include "llvm/ADT/APInt.h"
14#include "llvm/ADT/ArrayRef.h"
15#include "llvm/ADT/SmallVector.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/Support/SMLoc.h"
18#include <algorithm>
19#include <cassert>
20#include <cstddef>
21#include <cstdint>
22#include <string>
23
24namespace llvm {
25
26/// Target independent representation for an assembler token.
27class AsmToken {
28public:
29 enum TokenKind {
30 // Markers
31 Eof, Error,
32
33 // String values.
34 Identifier,
35 String,
36
37 // Integer values.
38 Integer,
39 BigNum, // larger than 64 bits
40
41 // Real values.
42 Real,
43
44 // Comments
45 Comment,
46 HashDirective,
47 // No-value.
48 EndOfStatement,
49 Colon,
50 Space,
51 Plus, Minus, Tilde,
52 Slash, // '/'
53 BackSlash, // '\'
54 LParen, RParen, LBrac, RBrac, LCurly, RCurly,
55 Star, Dot, Comma, Dollar, Equal, EqualEqual,
56
57 Pipe, PipePipe, Caret,
58 Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash,
59 Less, LessEqual, LessLess, LessGreater,
60 Greater, GreaterEqual, GreaterGreater, At,
61
62 // MIPS unary expression operators such as %neg.
63 PercentCall16, PercentCall_Hi, PercentCall_Lo, PercentDtprel_Hi,
64 PercentDtprel_Lo, PercentGot, PercentGot_Disp, PercentGot_Hi, PercentGot_Lo,
65 PercentGot_Ofst, PercentGot_Page, PercentGottprel, PercentGp_Rel, PercentHi,
66 PercentHigher, PercentHighest, PercentLo, PercentNeg, PercentPcrel_Hi,
67 PercentPcrel_Lo, PercentTlsgd, PercentTlsldm, PercentTprel_Hi,
68 PercentTprel_Lo
69 };
70
71private:
72 TokenKind Kind;
73
74 /// A reference to the entire token contents; this is always a pointer into
75 /// a memory buffer owned by the source manager.
76 StringRef Str;
77
78 APInt IntVal;
79
80public:
81 AsmToken() = default;
82 AsmToken(TokenKind Kind, StringRef Str, APInt IntVal)
83 : Kind(Kind), Str(Str), IntVal(std::move(IntVal)) {}
84 AsmToken(TokenKind Kind, StringRef Str, int64_t IntVal = 0)
85 : Kind(Kind), Str(Str), IntVal(64, IntVal, true) {}
86
87 TokenKind getKind() const { return Kind; }
88 bool is(TokenKind K) const { return Kind == K; }
21
Assuming the condition is false
49
Assuming the condition is false
79
Assuming the condition is false
109
Assuming the condition is true
121
Assuming the condition is true
154
Assuming the condition is false
89 bool isNot(TokenKind K) const { return Kind != K; }
127
Assuming the condition is true
166
Assuming the condition is false
90
91 SMLoc getLoc() const;
92 SMLoc getEndLoc() const;
93 SMRange getLocRange() const;
94
95 /// Get the contents of a string token (without quotes).
96 StringRef getStringContents() const {
97 assert(Kind == String && "This token isn't a string!")(static_cast <bool> (Kind == String && "This token isn't a string!"
) ? void (0) : __assert_fail ("Kind == String && \"This token isn't a string!\""
, "/build/llvm-toolchain-snapshot-7~svn326246/include/llvm/MC/MCParser/MCAsmLexer.h"
, 97, __extension__ __PRETTY_FUNCTION__))
;
98 return Str.slice(1, Str.size() - 1);
99 }
100
101 /// Get the identifier string for the current token, which should be an
102 /// identifier or a string. This gets the portion of the string which should
103 /// be used as the identifier, e.g., it does not include the quotes on
104 /// strings.
105 StringRef getIdentifier() const {
106 if (Kind == Identifier)
107 return getString();
108 return getStringContents();
109 }
110
111 /// Get the string for the current token, this includes all characters (for
112 /// example, the quotes on strings) in the token.
113 ///
114 /// The returned StringRef points into the source manager's memory buffer, and
115 /// is safe to store across calls to Lex().
116 StringRef getString() const { return Str; }
117
118 // FIXME: Don't compute this in advance, it makes every token larger, and is
119 // also not generally what we want (it is nicer for recovery etc. to lex 123br
120 // as a single token, then diagnose as an invalid number).
121 int64_t getIntVal() const {
122 assert(Kind == Integer && "This token isn't an integer!")(static_cast <bool> (Kind == Integer && "This token isn't an integer!"
) ? void (0) : __assert_fail ("Kind == Integer && \"This token isn't an integer!\""
, "/build/llvm-toolchain-snapshot-7~svn326246/include/llvm/MC/MCParser/MCAsmLexer.h"
, 122, __extension__ __PRETTY_FUNCTION__))
;
123 return IntVal.getZExtValue();
124 }
125
126 APInt getAPIntVal() const {
127 assert((Kind == Integer || Kind == BigNum) &&(static_cast <bool> ((Kind == Integer || Kind == BigNum
) && "This token isn't an integer!") ? void (0) : __assert_fail
("(Kind == Integer || Kind == BigNum) && \"This token isn't an integer!\""
, "/build/llvm-toolchain-snapshot-7~svn326246/include/llvm/MC/MCParser/MCAsmLexer.h"
, 128, __extension__ __PRETTY_FUNCTION__))
128 "This token isn't an integer!")(static_cast <bool> ((Kind == Integer || Kind == BigNum
) && "This token isn't an integer!") ? void (0) : __assert_fail
("(Kind == Integer || Kind == BigNum) && \"This token isn't an integer!\""
, "/build/llvm-toolchain-snapshot-7~svn326246/include/llvm/MC/MCParser/MCAsmLexer.h"
, 128, __extension__ __PRETTY_FUNCTION__))
;
129 return IntVal;
130 }
131};
132
133/// A callback class which is notified of each comment in an assembly file as
134/// it is lexed.
135class AsmCommentConsumer {
136public:
137 virtual ~AsmCommentConsumer() = default;
138
139 /// Callback function for when a comment is lexed. Loc is the start of the
140 /// comment text (excluding the comment-start marker). CommentText is the text
141 /// of the comment, excluding the comment start and end markers, and the
142 /// newline for single-line comments.
143 virtual void HandleComment(SMLoc Loc, StringRef CommentText) = 0;
144};
145
146
147/// Generic assembler lexer interface, for use by target specific assembly
148/// lexers.
149class MCAsmLexer {
150 /// The current token, stored in the base class for faster access.
151 SmallVector<AsmToken, 1> CurTok;
152
153 /// The location and description of the current error
154 SMLoc ErrLoc;
155 std::string Err;
156
157protected: // Can only create subclasses.
158 const char *TokStart = nullptr;
159 bool SkipSpace = true;
160 bool AllowAtInIdentifier;
161 bool IsAtStartOfStatement = true;
162 AsmCommentConsumer *CommentConsumer = nullptr;
163
164 bool AltMacroMode;
165 MCAsmLexer();
166
167 virtual AsmToken LexToken() = 0;
168
169 void SetError(SMLoc errLoc, const std::string &err) {
170 ErrLoc = errLoc;
171 Err = err;
172 }
173
174public:
175 MCAsmLexer(const MCAsmLexer &) = delete;
176 MCAsmLexer &operator=(const MCAsmLexer &) = delete;
177 virtual ~MCAsmLexer();
178
179 bool IsaAltMacroMode() {
180 return AltMacroMode;
181 }
182
183 void SetAltMacroMode(bool AltMacroSet) {
184 AltMacroMode = AltMacroSet;
185 }
186
187 /// Consume the next token from the input stream and return it.
188 ///
189 /// The lexer will continuosly return the end-of-file token once the end of
190 /// the main input file has been reached.
191 const AsmToken &Lex() {
192 assert(!CurTok.empty())(static_cast <bool> (!CurTok.empty()) ? void (0) : __assert_fail
("!CurTok.empty()", "/build/llvm-toolchain-snapshot-7~svn326246/include/llvm/MC/MCParser/MCAsmLexer.h"
, 192, __extension__ __PRETTY_FUNCTION__))
;
193 // Mark if we parsing out a EndOfStatement.
194 IsAtStartOfStatement = CurTok.front().getKind() == AsmToken::EndOfStatement;
195 CurTok.erase(CurTok.begin());
196 // LexToken may generate multiple tokens via UnLex but will always return
197 // the first one. Place returned value at head of CurTok vector.
198 if (CurTok.empty()) {
199 AsmToken T = LexToken();
200 CurTok.insert(CurTok.begin(), T);
201 }
202 return CurTok.front();
203 }
204
205 void UnLex(AsmToken const &Token) {
206 IsAtStartOfStatement = false;
207 CurTok.insert(CurTok.begin(), Token);
208 }
209
210 bool isAtStartOfStatement() { return IsAtStartOfStatement; }
211
212 virtual StringRef LexUntilEndOfStatement() = 0;
213
214 /// Get the current source location.
215 SMLoc getLoc() const;
216
217 /// Get the current (last) lexed token.
218 const AsmToken &getTok() const {
219 return CurTok[0];
220 }
221
222 /// Look ahead at the next token to be lexed.
223 const AsmToken peekTok(bool ShouldSkipSpace = true) {
224 AsmToken Tok;
225
226 MutableArrayRef<AsmToken> Buf(Tok);
227 size_t ReadCount = peekTokens(Buf, ShouldSkipSpace);
228
229 assert(ReadCount == 1)(static_cast <bool> (ReadCount == 1) ? void (0) : __assert_fail
("ReadCount == 1", "/build/llvm-toolchain-snapshot-7~svn326246/include/llvm/MC/MCParser/MCAsmLexer.h"
, 229, __extension__ __PRETTY_FUNCTION__))
;
230 (void)ReadCount;
231
232 return Tok;
233 }
234
235 /// Look ahead an arbitrary number of tokens.
236 virtual size_t peekTokens(MutableArrayRef<AsmToken> Buf,
237 bool ShouldSkipSpace = true) = 0;
238
239 /// Get the current error location
240 SMLoc getErrLoc() {
241 return ErrLoc;
242 }
243
244 /// Get the current error string
245 const std::string &getErr() {
246 return Err;
247 }
248
249 /// Get the kind of current token.
250 AsmToken::TokenKind getKind() const { return getTok().getKind(); }
251
252 /// Check if the current token has kind \p K.
253 bool is(AsmToken::TokenKind K) const { return getTok().is(K); }
18
Calling 'MCAsmLexer::getTok'
19
Returning from 'MCAsmLexer::getTok'
20
Calling 'AsmToken::is'
22
Returning from 'AsmToken::is'
46
Calling 'MCAsmLexer::getTok'
47
Returning from 'MCAsmLexer::getTok'
48
Calling 'AsmToken::is'
50
Returning from 'AsmToken::is'
76
Calling 'MCAsmLexer::getTok'
77
Returning from 'MCAsmLexer::getTok'
78
Calling 'AsmToken::is'
80
Returning from 'AsmToken::is'
106
Calling 'MCAsmLexer::getTok'
107
Returning from 'MCAsmLexer::getTok'
108
Calling 'AsmToken::is'
110
Returning from 'AsmToken::is'
118
Calling 'MCAsmLexer::getTok'
119
Returning from 'MCAsmLexer::getTok'
120
Calling 'AsmToken::is'
122
Returning from 'AsmToken::is'
151
Calling 'MCAsmLexer::getTok'
152
Returning from 'MCAsmLexer::getTok'
153
Calling 'AsmToken::is'
155
Returning from 'AsmToken::is'
254
255 /// Check if the current token has kind \p K.
256 bool isNot(AsmToken::TokenKind K) const { return getTok().isNot(K); }
163
Calling 'MCAsmLexer::getTok'
164
Returning from 'MCAsmLexer::getTok'
165
Calling 'AsmToken::isNot'
167
Returning from 'AsmToken::isNot'
257
258 /// Set whether spaces should be ignored by the lexer
259 void setSkipSpace(bool val) { SkipSpace = val; }
260
261 bool getAllowAtInIdentifier() { return AllowAtInIdentifier; }
262 void setAllowAtInIdentifier(bool v) { AllowAtInIdentifier = v; }
263
264 void setCommentConsumer(AsmCommentConsumer *CommentConsumer) {
265 this->CommentConsumer = CommentConsumer;
266 }
267};
268
269} // end namespace llvm
270
271#endif // LLVM_MC_MCPARSER_MCASMLEXER_H

/build/llvm-toolchain-snapshot-7~svn326246/include/llvm/ADT/Twine.h

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