Bug Summary

File:lib/MC/MCParser/AsmParser.cpp
Warning:line 2754, column 7
Branch condition evaluates to 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 AsmParser.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~svn329677/build-llvm/lib/MC/MCParser -I /build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn329677/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~svn329677/build-llvm/lib/MC/MCParser -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-04-11-031539-24776-1 -x c++ /build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp
1//===- AsmParser.cpp - Parser for Assembly Files --------------------------===//
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// This class implements the parser for assembly files.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/ADT/APFloat.h"
15#include "llvm/ADT/APInt.h"
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/None.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/SmallString.h"
20#include "llvm/ADT/SmallVector.h"
21#include "llvm/ADT/StringExtras.h"
22#include "llvm/ADT/StringMap.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/ADT/Twine.h"
25#include "llvm/BinaryFormat/Dwarf.h"
26#include "llvm/MC/MCAsmInfo.h"
27#include "llvm/MC/MCCodeView.h"
28#include "llvm/MC/MCContext.h"
29#include "llvm/MC/MCDirectives.h"
30#include "llvm/MC/MCDwarf.h"
31#include "llvm/MC/MCExpr.h"
32#include "llvm/MC/MCInstPrinter.h"
33#include "llvm/MC/MCInstrDesc.h"
34#include "llvm/MC/MCInstrInfo.h"
35#include "llvm/MC/MCObjectFileInfo.h"
36#include "llvm/MC/MCParser/AsmCond.h"
37#include "llvm/MC/MCParser/AsmLexer.h"
38#include "llvm/MC/MCParser/MCAsmLexer.h"
39#include "llvm/MC/MCParser/MCAsmParser.h"
40#include "llvm/MC/MCParser/MCAsmParserExtension.h"
41#include "llvm/MC/MCParser/MCAsmParserUtils.h"
42#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
43#include "llvm/MC/MCParser/MCTargetAsmParser.h"
44#include "llvm/MC/MCRegisterInfo.h"
45#include "llvm/MC/MCSection.h"
46#include "llvm/MC/MCStreamer.h"
47#include "llvm/MC/MCSymbol.h"
48#include "llvm/MC/MCTargetOptions.h"
49#include "llvm/MC/MCValue.h"
50#include "llvm/Support/Casting.h"
51#include "llvm/Support/CommandLine.h"
52#include "llvm/Support/ErrorHandling.h"
53#include "llvm/Support/MD5.h"
54#include "llvm/Support/MathExtras.h"
55#include "llvm/Support/MemoryBuffer.h"
56#include "llvm/Support/SMLoc.h"
57#include "llvm/Support/SourceMgr.h"
58#include "llvm/Support/raw_ostream.h"
59#include <algorithm>
60#include <cassert>
61#include <cctype>
62#include <climits>
63#include <cstddef>
64#include <cstdint>
65#include <deque>
66#include <memory>
67#include <sstream>
68#include <string>
69#include <tuple>
70#include <utility>
71#include <vector>
72
73using namespace llvm;
74
75MCAsmParserSemaCallback::~MCAsmParserSemaCallback() = default;
76
77static cl::opt<unsigned> AsmMacroMaxNestingDepth(
78 "asm-macro-max-nesting-depth", cl::init(20), cl::Hidden,
79 cl::desc("The maximum nesting depth allowed for assembly macros."));
80
81namespace {
82
83/// \brief Helper types for tracking macro definitions.
84typedef std::vector<AsmToken> MCAsmMacroArgument;
85typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
86
87/// \brief Helper class for storing information about an active macro
88/// instantiation.
89struct MacroInstantiation {
90 /// The location of the instantiation.
91 SMLoc InstantiationLoc;
92
93 /// The buffer where parsing should resume upon instantiation completion.
94 int ExitBuffer;
95
96 /// The location where parsing should resume upon instantiation completion.
97 SMLoc ExitLoc;
98
99 /// The depth of TheCondStack at the start of the instantiation.
100 size_t CondStackDepth;
101
102public:
103 MacroInstantiation(SMLoc IL, int EB, SMLoc EL, size_t CondStackDepth);
104};
105
106struct ParseStatementInfo {
107 /// \brief The parsed operands from the last parsed statement.
108 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> ParsedOperands;
109
110 /// \brief The opcode from the last parsed instruction.
111 unsigned Opcode = ~0U;
112
113 /// \brief Was there an error parsing the inline assembly?
114 bool ParseError = false;
115
116 SmallVectorImpl<AsmRewrite> *AsmRewrites = nullptr;
117
118 ParseStatementInfo() = delete;
119 ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites)
120 : AsmRewrites(rewrites) {}
121};
122
123/// \brief The concrete assembly parser instance.
124class AsmParser : public MCAsmParser {
125private:
126 AsmLexer Lexer;
127 MCContext &Ctx;
128 MCStreamer &Out;
129 const MCAsmInfo &MAI;
130 SourceMgr &SrcMgr;
131 SourceMgr::DiagHandlerTy SavedDiagHandler;
132 void *SavedDiagContext;
133 std::unique_ptr<MCAsmParserExtension> PlatformParser;
134
135 /// This is the current buffer index we're lexing from as managed by the
136 /// SourceMgr object.
137 unsigned CurBuffer;
138
139 AsmCond TheCondState;
140 std::vector<AsmCond> TheCondStack;
141
142 /// \brief maps directive names to handler methods in parser
143 /// extensions. Extensions register themselves in this map by calling
144 /// addDirectiveHandler.
145 StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap;
146
147 /// \brief Stack of active macro instantiations.
148 std::vector<MacroInstantiation*> ActiveMacros;
149
150 /// \brief List of bodies of anonymous macros.
151 std::deque<MCAsmMacro> MacroLikeBodies;
152
153 /// Boolean tracking whether macro substitution is enabled.
154 unsigned MacrosEnabledFlag : 1;
155
156 /// \brief Keeps track of how many .macro's have been instantiated.
157 unsigned NumOfMacroInstantiations;
158
159 /// The values from the last parsed cpp hash file line comment if any.
160 struct CppHashInfoTy {
161 StringRef Filename;
162 int64_t LineNumber = 0;
163 SMLoc Loc;
164 unsigned Buf = 0;
165 };
166 CppHashInfoTy CppHashInfo;
167
168 /// \brief List of forward directional labels for diagnosis at the end.
169 SmallVector<std::tuple<SMLoc, CppHashInfoTy, MCSymbol *>, 4> DirLabels;
170
171 /// AssemblerDialect. ~OU means unset value and use value provided by MAI.
172 unsigned AssemblerDialect = ~0U;
173
174 /// \brief is Darwin compatibility enabled?
175 bool IsDarwin = false;
176
177 /// \brief Are we parsing ms-style inline assembly?
178 bool ParsingInlineAsm = false;
179
180public:
181 AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
182 const MCAsmInfo &MAI, unsigned CB);
183 AsmParser(const AsmParser &) = delete;
184 AsmParser &operator=(const AsmParser &) = delete;
185 ~AsmParser() override;
186
187 bool Run(bool NoInitialTextSection, bool NoFinalize = false) override;
188
189 void addDirectiveHandler(StringRef Directive,
190 ExtensionDirectiveHandler Handler) override {
191 ExtensionDirectiveMap[Directive] = Handler;
192 }
193
194 void addAliasForDirective(StringRef Directive, StringRef Alias) override {
195 DirectiveKindMap[Directive] = DirectiveKindMap[Alias];
196 }
197
198 /// @name MCAsmParser Interface
199 /// {
200
201 SourceMgr &getSourceManager() override { return SrcMgr; }
202 MCAsmLexer &getLexer() override { return Lexer; }
203 MCContext &getContext() override { return Ctx; }
204 MCStreamer &getStreamer() override { return Out; }
205
206 CodeViewContext &getCVContext() { return Ctx.getCVContext(); }
207
208 unsigned getAssemblerDialect() override {
209 if (AssemblerDialect == ~0U)
210 return MAI.getAssemblerDialect();
211 else
212 return AssemblerDialect;
213 }
214 void setAssemblerDialect(unsigned i) override {
215 AssemblerDialect = i;
216 }
217
218 void Note(SMLoc L, const Twine &Msg, SMRange Range = None) override;
219 bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) override;
220 bool printError(SMLoc L, const Twine &Msg, SMRange Range = None) override;
221
222 const AsmToken &Lex() override;
223
224 void setParsingInlineAsm(bool V) override {
225 ParsingInlineAsm = V;
226 Lexer.setParsingMSInlineAsm(V);
227 }
228 bool isParsingInlineAsm() override { return ParsingInlineAsm; }
229
230 bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
231 unsigned &NumOutputs, unsigned &NumInputs,
232 SmallVectorImpl<std::pair<void *,bool>> &OpDecls,
233 SmallVectorImpl<std::string> &Constraints,
234 SmallVectorImpl<std::string> &Clobbers,
235 const MCInstrInfo *MII, const MCInstPrinter *IP,
236 MCAsmParserSemaCallback &SI) override;
237
238 bool parseExpression(const MCExpr *&Res);
239 bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
240 bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override;
241 bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
242 bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
243 SMLoc &EndLoc) override;
244 bool parseAbsoluteExpression(int64_t &Res) override;
245
246 /// \brief Parse a floating point expression using the float \p Semantics
247 /// and set \p Res to the value.
248 bool parseRealValue(const fltSemantics &Semantics, APInt &Res);
249
250 /// \brief Parse an identifier or string (as a quoted identifier)
251 /// and set \p Res to the identifier contents.
252 bool parseIdentifier(StringRef &Res) override;
253 void eatToEndOfStatement() override;
254
255 bool checkForValidSection() override;
256
257 /// }
258
259private:
260 bool isAltmacroString(SMLoc &StrLoc, SMLoc &EndLoc);
261 void altMacroString(StringRef AltMacroStr, std::string &Res);
262 bool parseStatement(ParseStatementInfo &Info,
263 MCAsmParserSemaCallback *SI);
264 bool parseCurlyBlockScope(SmallVectorImpl<AsmRewrite>& AsmStrRewrites);
265 bool parseCppHashLineFilenameComment(SMLoc L);
266
267 void checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body,
268 ArrayRef<MCAsmMacroParameter> Parameters);
269 bool expandMacro(raw_svector_ostream &OS, StringRef Body,
270 ArrayRef<MCAsmMacroParameter> Parameters,
271 ArrayRef<MCAsmMacroArgument> A, bool EnableAtPseudoVariable,
272 SMLoc L);
273
274 /// \brief Are macros enabled in the parser?
275 bool areMacrosEnabled() {return MacrosEnabledFlag;}
276
277 /// \brief Control a flag in the parser that enables or disables macros.
278 void setMacrosEnabled(bool Flag) {MacrosEnabledFlag = Flag;}
279
280 /// \brief Are we inside a macro instantiation?
281 bool isInsideMacroInstantiation() {return !ActiveMacros.empty();}
282
283 /// \brief Handle entry to macro instantiation.
284 ///
285 /// \param M The macro.
286 /// \param NameLoc Instantiation location.
287 bool handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc);
288
289 /// \brief Handle exit from macro instantiation.
290 void handleMacroExit();
291
292 /// \brief Extract AsmTokens for a macro argument.
293 bool parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg);
294
295 /// \brief Parse all macro arguments for a given macro.
296 bool parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A);
297
298 void printMacroInstantiations();
299 void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
300 SMRange Range = None) const {
301 ArrayRef<SMRange> Ranges(Range);
302 SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges);
303 }
304 static void DiagHandler(const SMDiagnostic &Diag, void *Context);
305
306 /// Should we emit DWARF describing this assembler source? (Returns false if
307 /// the source has .file directives, which means we don't want to generate
308 /// info describing the assembler source itself.)
309 bool enabledGenDwarfForAssembly();
310
311 /// \brief Enter the specified file. This returns true on failure.
312 bool enterIncludeFile(const std::string &Filename);
313
314 /// \brief Process the specified file for the .incbin directive.
315 /// This returns true on failure.
316 bool processIncbinFile(const std::string &Filename, int64_t Skip = 0,
317 const MCExpr *Count = nullptr, SMLoc Loc = SMLoc());
318
319 /// \brief Reset the current lexer position to that given by \p Loc. The
320 /// current token is not set; clients should ensure Lex() is called
321 /// subsequently.
322 ///
323 /// \param InBuffer If not 0, should be the known buffer id that contains the
324 /// location.
325 void jumpToLoc(SMLoc Loc, unsigned InBuffer = 0);
326
327 /// \brief Parse up to the end of statement and a return the contents from the
328 /// current token until the end of the statement; the current token on exit
329 /// will be either the EndOfStatement or EOF.
330 StringRef parseStringToEndOfStatement() override;
331
332 /// \brief Parse until the end of a statement or a comma is encountered,
333 /// return the contents from the current token up to the end or comma.
334 StringRef parseStringToComma();
335
336 bool parseAssignment(StringRef Name, bool allow_redef,
337 bool NoDeadStrip = false);
338
339 unsigned getBinOpPrecedence(AsmToken::TokenKind K,
340 MCBinaryExpr::Opcode &Kind);
341
342 bool parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
343 bool parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
344 bool parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);
345
346 bool parseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
347
348 bool parseCVFunctionId(int64_t &FunctionId, StringRef DirectiveName);
349 bool parseCVFileId(int64_t &FileId, StringRef DirectiveName);
350
351 // Generic (target and platform independent) directive parsing.
352 enum DirectiveKind {
353 DK_NO_DIRECTIVE, // Placeholder
354 DK_SET,
355 DK_EQU,
356 DK_EQUIV,
357 DK_ASCII,
358 DK_ASCIZ,
359 DK_STRING,
360 DK_BYTE,
361 DK_SHORT,
362 DK_RELOC,
363 DK_VALUE,
364 DK_2BYTE,
365 DK_LONG,
366 DK_INT,
367 DK_4BYTE,
368 DK_QUAD,
369 DK_8BYTE,
370 DK_OCTA,
371 DK_DC,
372 DK_DC_A,
373 DK_DC_B,
374 DK_DC_D,
375 DK_DC_L,
376 DK_DC_S,
377 DK_DC_W,
378 DK_DC_X,
379 DK_DCB,
380 DK_DCB_B,
381 DK_DCB_D,
382 DK_DCB_L,
383 DK_DCB_S,
384 DK_DCB_W,
385 DK_DCB_X,
386 DK_DS,
387 DK_DS_B,
388 DK_DS_D,
389 DK_DS_L,
390 DK_DS_P,
391 DK_DS_S,
392 DK_DS_W,
393 DK_DS_X,
394 DK_SINGLE,
395 DK_FLOAT,
396 DK_DOUBLE,
397 DK_ALIGN,
398 DK_ALIGN32,
399 DK_BALIGN,
400 DK_BALIGNW,
401 DK_BALIGNL,
402 DK_P2ALIGN,
403 DK_P2ALIGNW,
404 DK_P2ALIGNL,
405 DK_ORG,
406 DK_FILL,
407 DK_ENDR,
408 DK_BUNDLE_ALIGN_MODE,
409 DK_BUNDLE_LOCK,
410 DK_BUNDLE_UNLOCK,
411 DK_ZERO,
412 DK_EXTERN,
413 DK_GLOBL,
414 DK_GLOBAL,
415 DK_LAZY_REFERENCE,
416 DK_NO_DEAD_STRIP,
417 DK_SYMBOL_RESOLVER,
418 DK_PRIVATE_EXTERN,
419 DK_REFERENCE,
420 DK_WEAK_DEFINITION,
421 DK_WEAK_REFERENCE,
422 DK_WEAK_DEF_CAN_BE_HIDDEN,
423 DK_COMM,
424 DK_COMMON,
425 DK_LCOMM,
426 DK_ABORT,
427 DK_INCLUDE,
428 DK_INCBIN,
429 DK_CODE16,
430 DK_CODE16GCC,
431 DK_REPT,
432 DK_IRP,
433 DK_IRPC,
434 DK_IF,
435 DK_IFEQ,
436 DK_IFGE,
437 DK_IFGT,
438 DK_IFLE,
439 DK_IFLT,
440 DK_IFNE,
441 DK_IFB,
442 DK_IFNB,
443 DK_IFC,
444 DK_IFEQS,
445 DK_IFNC,
446 DK_IFNES,
447 DK_IFDEF,
448 DK_IFNDEF,
449 DK_IFNOTDEF,
450 DK_ELSEIF,
451 DK_ELSE,
452 DK_ENDIF,
453 DK_SPACE,
454 DK_SKIP,
455 DK_FILE,
456 DK_LINE,
457 DK_LOC,
458 DK_STABS,
459 DK_CV_FILE,
460 DK_CV_FUNC_ID,
461 DK_CV_INLINE_SITE_ID,
462 DK_CV_LOC,
463 DK_CV_LINETABLE,
464 DK_CV_INLINE_LINETABLE,
465 DK_CV_DEF_RANGE,
466 DK_CV_STRINGTABLE,
467 DK_CV_FILECHECKSUMS,
468 DK_CV_FILECHECKSUM_OFFSET,
469 DK_CV_FPO_DATA,
470 DK_CFI_SECTIONS,
471 DK_CFI_STARTPROC,
472 DK_CFI_ENDPROC,
473 DK_CFI_DEF_CFA,
474 DK_CFI_DEF_CFA_OFFSET,
475 DK_CFI_ADJUST_CFA_OFFSET,
476 DK_CFI_DEF_CFA_REGISTER,
477 DK_CFI_OFFSET,
478 DK_CFI_REL_OFFSET,
479 DK_CFI_PERSONALITY,
480 DK_CFI_LSDA,
481 DK_CFI_REMEMBER_STATE,
482 DK_CFI_RESTORE_STATE,
483 DK_CFI_SAME_VALUE,
484 DK_CFI_RESTORE,
485 DK_CFI_ESCAPE,
486 DK_CFI_RETURN_COLUMN,
487 DK_CFI_SIGNAL_FRAME,
488 DK_CFI_UNDEFINED,
489 DK_CFI_REGISTER,
490 DK_CFI_WINDOW_SAVE,
491 DK_MACROS_ON,
492 DK_MACROS_OFF,
493 DK_ALTMACRO,
494 DK_NOALTMACRO,
495 DK_MACRO,
496 DK_EXITM,
497 DK_ENDM,
498 DK_ENDMACRO,
499 DK_PURGEM,
500 DK_SLEB128,
501 DK_ULEB128,
502 DK_ERR,
503 DK_ERROR,
504 DK_WARNING,
505 DK_PRINT,
506 DK_END
507 };
508
509 /// \brief Maps directive name --> DirectiveKind enum, for
510 /// directives parsed by this class.
511 StringMap<DirectiveKind> DirectiveKindMap;
512
513 // ".ascii", ".asciz", ".string"
514 bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
515 bool parseDirectiveReloc(SMLoc DirectiveLoc); // ".reloc"
516 bool parseDirectiveValue(StringRef IDVal,
517 unsigned Size); // ".byte", ".long", ...
518 bool parseDirectiveOctaValue(StringRef IDVal); // ".octa", ...
519 bool parseDirectiveRealValue(StringRef IDVal,
520 const fltSemantics &); // ".single", ...
521 bool parseDirectiveFill(); // ".fill"
522 bool parseDirectiveZero(); // ".zero"
523 // ".set", ".equ", ".equiv"
524 bool parseDirectiveSet(StringRef IDVal, bool allow_redef);
525 bool parseDirectiveOrg(); // ".org"
526 // ".align{,32}", ".p2align{,w,l}"
527 bool parseDirectiveAlign(bool IsPow2, unsigned ValueSize);
528
529 // ".file", ".line", ".loc", ".stabs"
530 bool parseDirectiveFile(SMLoc DirectiveLoc);
531 bool parseDirectiveLine();
532 bool parseDirectiveLoc();
533 bool parseDirectiveStabs();
534
535 // ".cv_file", ".cv_func_id", ".cv_inline_site_id", ".cv_loc", ".cv_linetable",
536 // ".cv_inline_linetable", ".cv_def_range"
537 bool parseDirectiveCVFile();
538 bool parseDirectiveCVFuncId();
539 bool parseDirectiveCVInlineSiteId();
540 bool parseDirectiveCVLoc();
541 bool parseDirectiveCVLinetable();
542 bool parseDirectiveCVInlineLinetable();
543 bool parseDirectiveCVDefRange();
544 bool parseDirectiveCVStringTable();
545 bool parseDirectiveCVFileChecksums();
546 bool parseDirectiveCVFileChecksumOffset();
547 bool parseDirectiveCVFPOData();
548
549 // .cfi directives
550 bool parseDirectiveCFIRegister(SMLoc DirectiveLoc);
551 bool parseDirectiveCFIWindowSave();
552 bool parseDirectiveCFISections();
553 bool parseDirectiveCFIStartProc();
554 bool parseDirectiveCFIEndProc();
555 bool parseDirectiveCFIDefCfaOffset();
556 bool parseDirectiveCFIDefCfa(SMLoc DirectiveLoc);
557 bool parseDirectiveCFIAdjustCfaOffset();
558 bool parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc);
559 bool parseDirectiveCFIOffset(SMLoc DirectiveLoc);
560 bool parseDirectiveCFIRelOffset(SMLoc DirectiveLoc);
561 bool parseDirectiveCFIPersonalityOrLsda(bool IsPersonality);
562 bool parseDirectiveCFIRememberState();
563 bool parseDirectiveCFIRestoreState();
564 bool parseDirectiveCFISameValue(SMLoc DirectiveLoc);
565 bool parseDirectiveCFIRestore(SMLoc DirectiveLoc);
566 bool parseDirectiveCFIEscape();
567 bool parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc);
568 bool parseDirectiveCFISignalFrame();
569 bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc);
570
571 // macro directives
572 bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
573 bool parseDirectiveExitMacro(StringRef Directive);
574 bool parseDirectiveEndMacro(StringRef Directive);
575 bool parseDirectiveMacro(SMLoc DirectiveLoc);
576 bool parseDirectiveMacrosOnOff(StringRef Directive);
577 // alternate macro mode directives
578 bool parseDirectiveAltmacro(StringRef Directive);
579 // ".bundle_align_mode"
580 bool parseDirectiveBundleAlignMode();
581 // ".bundle_lock"
582 bool parseDirectiveBundleLock();
583 // ".bundle_unlock"
584 bool parseDirectiveBundleUnlock();
585
586 // ".space", ".skip"
587 bool parseDirectiveSpace(StringRef IDVal);
588
589 // ".dcb"
590 bool parseDirectiveDCB(StringRef IDVal, unsigned Size);
591 bool parseDirectiveRealDCB(StringRef IDVal, const fltSemantics &);
592 // ".ds"
593 bool parseDirectiveDS(StringRef IDVal, unsigned Size);
594
595 // .sleb128 (Signed=true) and .uleb128 (Signed=false)
596 bool parseDirectiveLEB128(bool Signed);
597
598 /// \brief Parse a directive like ".globl" which
599 /// accepts a single symbol (which should be a label or an external).
600 bool parseDirectiveSymbolAttribute(MCSymbolAttr Attr);
601
602 bool parseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm"
603
604 bool parseDirectiveAbort(); // ".abort"
605 bool parseDirectiveInclude(); // ".include"
606 bool parseDirectiveIncbin(); // ".incbin"
607
608 // ".if", ".ifeq", ".ifge", ".ifgt" , ".ifle", ".iflt" or ".ifne"
609 bool parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind);
610 // ".ifb" or ".ifnb", depending on ExpectBlank.
611 bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank);
612 // ".ifc" or ".ifnc", depending on ExpectEqual.
613 bool parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual);
614 // ".ifeqs" or ".ifnes", depending on ExpectEqual.
615 bool parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual);
616 // ".ifdef" or ".ifndef", depending on expect_defined
617 bool parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined);
618 bool parseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif"
619 bool parseDirectiveElse(SMLoc DirectiveLoc); // ".else"
620 bool parseDirectiveEndIf(SMLoc DirectiveLoc); // .endif
621 bool parseEscapedString(std::string &Data) override;
622
623 const MCExpr *applyModifierToExpr(const MCExpr *E,
624 MCSymbolRefExpr::VariantKind Variant);
625
626 // Macro-like directives
627 MCAsmMacro *parseMacroLikeBody(SMLoc DirectiveLoc);
628 void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
629 raw_svector_ostream &OS);
630 bool parseDirectiveRept(SMLoc DirectiveLoc, StringRef Directive);
631 bool parseDirectiveIrp(SMLoc DirectiveLoc); // ".irp"
632 bool parseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc"
633 bool parseDirectiveEndr(SMLoc DirectiveLoc); // ".endr"
634
635 // "_emit" or "__emit"
636 bool parseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info,
637 size_t Len);
638
639 // "align"
640 bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info);
641
642 // "end"
643 bool parseDirectiveEnd(SMLoc DirectiveLoc);
644
645 // ".err" or ".error"
646 bool parseDirectiveError(SMLoc DirectiveLoc, bool WithMessage);
647
648 // ".warning"
649 bool parseDirectiveWarning(SMLoc DirectiveLoc);
650
651 // .print <double-quotes-string>
652 bool parseDirectivePrint(SMLoc DirectiveLoc);
653
654 void initializeDirectiveKindMap();
655};
656
657} // end anonymous namespace
658
659namespace llvm {
660
661extern MCAsmParserExtension *createDarwinAsmParser();
662extern MCAsmParserExtension *createELFAsmParser();
663extern MCAsmParserExtension *createCOFFAsmParser();
664
665} // end namespace llvm
666
667enum { DEFAULT_ADDRSPACE = 0 };
668
669AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
670 const MCAsmInfo &MAI, unsigned CB = 0)
671 : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM),
672 CurBuffer(CB ? CB : SM.getMainFileID()), MacrosEnabledFlag(true) {
673 HadError = false;
674 // Save the old handler.
675 SavedDiagHandler = SrcMgr.getDiagHandler();
676 SavedDiagContext = SrcMgr.getDiagContext();
677 // Set our own handler which calls the saved handler.
678 SrcMgr.setDiagHandler(DiagHandler, this);
679 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
680
681 // Initialize the platform / file format parser.
682 switch (Ctx.getObjectFileInfo()->getObjectFileType()) {
683 case MCObjectFileInfo::IsCOFF:
684 PlatformParser.reset(createCOFFAsmParser());
685 break;
686 case MCObjectFileInfo::IsMachO:
687 PlatformParser.reset(createDarwinAsmParser());
688 IsDarwin = true;
689 break;
690 case MCObjectFileInfo::IsELF:
691 PlatformParser.reset(createELFAsmParser());
692 break;
693 case MCObjectFileInfo::IsWasm:
694 llvm_unreachable("Wasm parsing not supported yet")::llvm::llvm_unreachable_internal("Wasm parsing not supported yet"
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 694)
;
695 break;
696 }
697
698 PlatformParser->Initialize(*this);
699 initializeDirectiveKindMap();
700
701 NumOfMacroInstantiations = 0;
702}
703
704AsmParser::~AsmParser() {
705 assert((HadError || ActiveMacros.empty()) &&(static_cast <bool> ((HadError || ActiveMacros.empty())
&& "Unexpected active macro instantiation!") ? void (
0) : __assert_fail ("(HadError || ActiveMacros.empty()) && \"Unexpected active macro instantiation!\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 706, __extension__ __PRETTY_FUNCTION__))
706 "Unexpected active macro instantiation!")(static_cast <bool> ((HadError || ActiveMacros.empty())
&& "Unexpected active macro instantiation!") ? void (
0) : __assert_fail ("(HadError || ActiveMacros.empty()) && \"Unexpected active macro instantiation!\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 706, __extension__ __PRETTY_FUNCTION__))
;
707
708 // Restore the saved diagnostics handler and context for use during
709 // finalization.
710 SrcMgr.setDiagHandler(SavedDiagHandler, SavedDiagContext);
711}
712
713void AsmParser::printMacroInstantiations() {
714 // Print the active macro instantiation stack.
715 for (std::vector<MacroInstantiation *>::const_reverse_iterator
716 it = ActiveMacros.rbegin(),
717 ie = ActiveMacros.rend();
718 it != ie; ++it)
719 printMessage((*it)->InstantiationLoc, SourceMgr::DK_Note,
720 "while in macro instantiation");
721}
722
723void AsmParser::Note(SMLoc L, const Twine &Msg, SMRange Range) {
724 printPendingErrors();
725 printMessage(L, SourceMgr::DK_Note, Msg, Range);
726 printMacroInstantiations();
727}
728
729bool AsmParser::Warning(SMLoc L, const Twine &Msg, SMRange Range) {
730 if(getTargetParser().getTargetOptions().MCNoWarn)
731 return false;
732 if (getTargetParser().getTargetOptions().MCFatalWarnings)
733 return Error(L, Msg, Range);
734 printMessage(L, SourceMgr::DK_Warning, Msg, Range);
735 printMacroInstantiations();
736 return false;
737}
738
739bool AsmParser::printError(SMLoc L, const Twine &Msg, SMRange Range) {
740 HadError = true;
741 printMessage(L, SourceMgr::DK_Error, Msg, Range);
742 printMacroInstantiations();
743 return true;
744}
745
746bool AsmParser::enterIncludeFile(const std::string &Filename) {
747 std::string IncludedFile;
748 unsigned NewBuf =
749 SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
750 if (!NewBuf)
751 return true;
752
753 CurBuffer = NewBuf;
754 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
755 return false;
756}
757
758/// Process the specified .incbin file by searching for it in the include paths
759/// then just emitting the byte contents of the file to the streamer. This
760/// returns true on failure.
761bool AsmParser::processIncbinFile(const std::string &Filename, int64_t Skip,
762 const MCExpr *Count, SMLoc Loc) {
763 std::string IncludedFile;
764 unsigned NewBuf =
765 SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
766 if (!NewBuf)
767 return true;
768
769 // Pick up the bytes from the file and emit them.
770 StringRef Bytes = SrcMgr.getMemoryBuffer(NewBuf)->getBuffer();
771 Bytes = Bytes.drop_front(Skip);
772 if (Count) {
773 int64_t Res;
774 if (!Count->evaluateAsAbsolute(Res))
775 return Error(Loc, "expected absolute expression");
776 if (Res < 0)
777 return Warning(Loc, "negative count has no effect");
778 Bytes = Bytes.take_front(Res);
779 }
780 getStreamer().EmitBytes(Bytes);
781 return false;
782}
783
784void AsmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer) {
785 CurBuffer = InBuffer ? InBuffer : SrcMgr.FindBufferContainingLoc(Loc);
786 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(),
787 Loc.getPointer());
788}
789
790const AsmToken &AsmParser::Lex() {
791 if (Lexer.getTok().is(AsmToken::Error))
792 Error(Lexer.getErrLoc(), Lexer.getErr());
793
794 // if it's a end of statement with a comment in it
795 if (getTok().is(AsmToken::EndOfStatement)) {
796 // if this is a line comment output it.
797 if (!getTok().getString().empty() && getTok().getString().front() != '\n' &&
798 getTok().getString().front() != '\r' && MAI.preserveAsmComments())
799 Out.addExplicitComment(Twine(getTok().getString()));
800 }
801
802 const AsmToken *tok = &Lexer.Lex();
803
804 // Parse comments here to be deferred until end of next statement.
805 while (tok->is(AsmToken::Comment)) {
806 if (MAI.preserveAsmComments())
807 Out.addExplicitComment(Twine(tok->getString()));
808 tok = &Lexer.Lex();
809 }
810
811 if (tok->is(AsmToken::Eof)) {
812 // If this is the end of an included file, pop the parent file off the
813 // include stack.
814 SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
815 if (ParentIncludeLoc != SMLoc()) {
816 jumpToLoc(ParentIncludeLoc);
817 return Lex();
818 }
819 }
820
821 return *tok;
822}
823
824bool AsmParser::enabledGenDwarfForAssembly() {
825 // Check whether the user specified -g.
826 if (!getContext().getGenDwarfForAssembly())
827 return false;
828 // If we haven't encountered any .file directives (which would imply that
829 // the assembler source was produced with debug info already) then emit one
830 // describing the assembler source file itself.
831 if (getContext().getGenDwarfFileNumber() == 0)
832 getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective(
833 0, StringRef(), getContext().getMainFileName()));
834 return true;
835}
836
837bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
838 // Create the initial section, if requested.
839 if (!NoInitialTextSection)
840 Out.InitSections(false);
841
842 // Prime the lexer.
843 Lex();
844
845 HadError = false;
846 AsmCond StartingCondState = TheCondState;
847 SmallVector<AsmRewrite, 4> AsmStrRewrites;
848
849 // If we are generating dwarf for assembly source files save the initial text
850 // section. (Don't use enabledGenDwarfForAssembly() here, as we aren't
851 // emitting any actual debug info yet and haven't had a chance to parse any
852 // embedded .file directives.)
853 if (getContext().getGenDwarfForAssembly()) {
854 MCSection *Sec = getStreamer().getCurrentSectionOnly();
855 if (!Sec->getBeginSymbol()) {
856 MCSymbol *SectionStartSym = getContext().createTempSymbol();
857 getStreamer().EmitLabel(SectionStartSym);
858 Sec->setBeginSymbol(SectionStartSym);
859 }
860 bool InsertResult = getContext().addGenDwarfSection(Sec);
861 assert(InsertResult && ".text section should not have debug info yet")(static_cast <bool> (InsertResult && ".text section should not have debug info yet"
) ? void (0) : __assert_fail ("InsertResult && \".text section should not have debug info yet\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 861, __extension__ __PRETTY_FUNCTION__))
;
862 (void)InsertResult;
863 }
864
865 // While we have input, parse each statement.
866 while (Lexer.isNot(AsmToken::Eof)) {
867 ParseStatementInfo Info(&AsmStrRewrites);
868 if (!parseStatement(Info, nullptr))
869 continue;
870
871 // If we have a Lexer Error we are on an Error Token. Load in Lexer Error
872 // for printing ErrMsg via Lex() only if no (presumably better) parser error
873 // exists.
874 if (!hasPendingError() && Lexer.getTok().is(AsmToken::Error)) {
875 Lex();
876 }
877
878 // parseStatement returned true so may need to emit an error.
879 printPendingErrors();
880
881 // Skipping to the next line if needed.
882 if (!getLexer().isAtStartOfStatement())
883 eatToEndOfStatement();
884 }
885
886 // All errors should have been emitted.
887 assert(!hasPendingError() && "unexpected error from parseStatement")(static_cast <bool> (!hasPendingError() && "unexpected error from parseStatement"
) ? void (0) : __assert_fail ("!hasPendingError() && \"unexpected error from parseStatement\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 887, __extension__ __PRETTY_FUNCTION__))
;
888
889 getTargetParser().flushPendingInstructions(getStreamer());
890
891 if (TheCondState.TheCond != StartingCondState.TheCond ||
892 TheCondState.Ignore != StartingCondState.Ignore)
893 printError(getTok().getLoc(), "unmatched .ifs or .elses");
894 // Check to see there are no empty DwarfFile slots.
895 const auto &LineTables = getContext().getMCDwarfLineTables();
896 if (!LineTables.empty()) {
897 unsigned Index = 0;
898 for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
899 if (File.Name.empty() && Index != 0)
900 printError(getTok().getLoc(), "unassigned file number: " +
901 Twine(Index) +
902 " for .file directives");
903 ++Index;
904 }
905 }
906
907 // Check to see that all assembler local symbols were actually defined.
908 // Targets that don't do subsections via symbols may not want this, though,
909 // so conservatively exclude them. Only do this if we're finalizing, though,
910 // as otherwise we won't necessarilly have seen everything yet.
911 if (!NoFinalize) {
912 if (MAI.hasSubsectionsViaSymbols()) {
913 for (const auto &TableEntry : getContext().getSymbols()) {
914 MCSymbol *Sym = TableEntry.getValue();
915 // Variable symbols may not be marked as defined, so check those
916 // explicitly. If we know it's a variable, we have a definition for
917 // the purposes of this check.
918 if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined())
919 // FIXME: We would really like to refer back to where the symbol was
920 // first referenced for a source location. We need to add something
921 // to track that. Currently, we just point to the end of the file.
922 printError(getTok().getLoc(), "assembler local symbol '" +
923 Sym->getName() + "' not defined");
924 }
925 }
926
927 // Temporary symbols like the ones for directional jumps don't go in the
928 // symbol table. They also need to be diagnosed in all (final) cases.
929 for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
930 if (std::get<2>(LocSym)->isUndefined()) {
931 // Reset the state of any "# line file" directives we've seen to the
932 // context as it was at the diagnostic site.
933 CppHashInfo = std::get<1>(LocSym);
934 printError(std::get<0>(LocSym), "directional label undefined");
935 }
936 }
937 }
938
939 // Finalize the output stream if there are no errors and if the client wants
940 // us to.
941 if (!HadError && !NoFinalize)
942 Out.Finish();
943
944 return HadError || getContext().hadError();
945}
946
947bool AsmParser::checkForValidSection() {
948 if (!ParsingInlineAsm && !getStreamer().getCurrentSectionOnly()) {
949 Out.InitSections(false);
950 return Error(getTok().getLoc(),
951 "expected section directive before assembly directive");
952 }
953 return false;
954}
955
956/// \brief Throw away the rest of the line for testing purposes.
957void AsmParser::eatToEndOfStatement() {
958 while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
959 Lexer.Lex();
960
961 // Eat EOL.
962 if (Lexer.is(AsmToken::EndOfStatement))
963 Lexer.Lex();
964}
965
966StringRef AsmParser::parseStringToEndOfStatement() {
967 const char *Start = getTok().getLoc().getPointer();
968
969 while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
970 Lexer.Lex();
971
972 const char *End = getTok().getLoc().getPointer();
973 return StringRef(Start, End - Start);
974}
975
976StringRef AsmParser::parseStringToComma() {
977 const char *Start = getTok().getLoc().getPointer();
978
979 while (Lexer.isNot(AsmToken::EndOfStatement) &&
980 Lexer.isNot(AsmToken::Comma) && Lexer.isNot(AsmToken::Eof))
981 Lexer.Lex();
982
983 const char *End = getTok().getLoc().getPointer();
984 return StringRef(Start, End - Start);
985}
986
987/// \brief Parse a paren expression and return it.
988/// NOTE: This assumes the leading '(' has already been consumed.
989///
990/// parenexpr ::= expr)
991///
992bool AsmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
993 if (parseExpression(Res))
994 return true;
995 if (Lexer.isNot(AsmToken::RParen))
996 return TokError("expected ')' in parentheses expression");
997 EndLoc = Lexer.getTok().getEndLoc();
998 Lex();
999 return false;
1000}
1001
1002/// \brief Parse a bracket expression and return it.
1003/// NOTE: This assumes the leading '[' has already been consumed.
1004///
1005/// bracketexpr ::= expr]
1006///
1007bool AsmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
1008 if (parseExpression(Res))
1009 return true;
1010 EndLoc = getTok().getEndLoc();
1011 if (parseToken(AsmToken::RBrac, "expected ']' in brackets expression"))
1012 return true;
1013 return false;
1014}
1015
1016/// \brief Parse a primary expression and return it.
1017/// primaryexpr ::= (parenexpr
1018/// primaryexpr ::= symbol
1019/// primaryexpr ::= number
1020/// primaryexpr ::= '.'
1021/// primaryexpr ::= ~,+,- primaryexpr
1022bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
1023 SMLoc FirstTokenLoc = getLexer().getLoc();
1024 AsmToken::TokenKind FirstTokenKind = Lexer.getKind();
1025 switch (FirstTokenKind) {
1026 default:
1027 return TokError("unknown token in expression");
1028 // If we have an error assume that we've already handled it.
1029 case AsmToken::Error:
1030 return true;
1031 case AsmToken::Exclaim:
1032 Lex(); // Eat the operator.
1033 if (parsePrimaryExpr(Res, EndLoc))
1034 return true;
1035 Res = MCUnaryExpr::createLNot(Res, getContext(), FirstTokenLoc);
1036 return false;
1037 case AsmToken::Dollar:
1038 case AsmToken::At:
1039 case AsmToken::String:
1040 case AsmToken::Identifier: {
1041 StringRef Identifier;
1042 if (parseIdentifier(Identifier)) {
1043 // We may have failed but $ may be a valid token.
1044 if (getTok().is(AsmToken::Dollar)) {
1045 if (Lexer.getMAI().getDollarIsPC()) {
1046 Lex();
1047 // This is a '$' reference, which references the current PC. Emit a
1048 // temporary label to the streamer and refer to it.
1049 MCSymbol *Sym = Ctx.createTempSymbol();
1050 Out.EmitLabel(Sym);
1051 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
1052 getContext());
1053 EndLoc = FirstTokenLoc;
1054 return false;
1055 }
1056 return Error(FirstTokenLoc, "invalid token in expression");
1057 }
1058 }
1059 // Parse symbol variant
1060 std::pair<StringRef, StringRef> Split;
1061 if (!MAI.useParensForSymbolVariant()) {
1062 if (FirstTokenKind == AsmToken::String) {
1063 if (Lexer.is(AsmToken::At)) {
1064 Lex(); // eat @
1065 SMLoc AtLoc = getLexer().getLoc();
1066 StringRef VName;
1067 if (parseIdentifier(VName))
1068 return Error(AtLoc, "expected symbol variant after '@'");
1069
1070 Split = std::make_pair(Identifier, VName);
1071 }
1072 } else {
1073 Split = Identifier.split('@');
1074 }
1075 } else if (Lexer.is(AsmToken::LParen)) {
1076 Lex(); // eat '('.
1077 StringRef VName;
1078 parseIdentifier(VName);
1079 // eat ')'.
1080 if (parseToken(AsmToken::RParen,
1081 "unexpected token in variant, expected ')'"))
1082 return true;
1083 Split = std::make_pair(Identifier, VName);
1084 }
1085
1086 EndLoc = SMLoc::getFromPointer(Identifier.end());
1087
1088 // This is a symbol reference.
1089 StringRef SymbolName = Identifier;
1090 if (SymbolName.empty())
1091 return true;
1092
1093 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1094
1095 // Lookup the symbol variant if used.
1096 if (!Split.second.empty()) {
1097 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
1098 if (Variant != MCSymbolRefExpr::VK_Invalid) {
1099 SymbolName = Split.first;
1100 } else if (MAI.doesAllowAtInName() && !MAI.useParensForSymbolVariant()) {
1101 Variant = MCSymbolRefExpr::VK_None;
1102 } else {
1103 return Error(SMLoc::getFromPointer(Split.second.begin()),
1104 "invalid variant '" + Split.second + "'");
1105 }
1106 }
1107
1108 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
1109
1110 // If this is an absolute variable reference, substitute it now to preserve
1111 // semantics in the face of reassignment.
1112 if (Sym->isVariable() &&
1113 isa<MCConstantExpr>(Sym->getVariableValue(/*SetUsed*/ false))) {
1114 if (Variant)
1115 return Error(EndLoc, "unexpected modifier on variable reference");
1116
1117 Res = Sym->getVariableValue(/*SetUsed*/ false);
1118 return false;
1119 }
1120
1121 // Otherwise create a symbol ref.
1122 Res = MCSymbolRefExpr::create(Sym, Variant, getContext(), FirstTokenLoc);
1123 return false;
1124 }
1125 case AsmToken::BigNum:
1126 return TokError("literal value out of range for directive");
1127 case AsmToken::Integer: {
1128 SMLoc Loc = getTok().getLoc();
1129 int64_t IntVal = getTok().getIntVal();
1130 Res = MCConstantExpr::create(IntVal, getContext());
1131 EndLoc = Lexer.getTok().getEndLoc();
1132 Lex(); // Eat token.
1133 // Look for 'b' or 'f' following an Integer as a directional label
1134 if (Lexer.getKind() == AsmToken::Identifier) {
1135 StringRef IDVal = getTok().getString();
1136 // Lookup the symbol variant if used.
1137 std::pair<StringRef, StringRef> Split = IDVal.split('@');
1138 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1139 if (Split.first.size() != IDVal.size()) {
1140 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
1141 if (Variant == MCSymbolRefExpr::VK_Invalid)
1142 return TokError("invalid variant '" + Split.second + "'");
1143 IDVal = Split.first;
1144 }
1145 if (IDVal == "f" || IDVal == "b") {
1146 MCSymbol *Sym =
1147 Ctx.getDirectionalLocalSymbol(IntVal, IDVal == "b");
1148 Res = MCSymbolRefExpr::create(Sym, Variant, getContext());
1149 if (IDVal == "b" && Sym->isUndefined())
1150 return Error(Loc, "directional label undefined");
1151 DirLabels.push_back(std::make_tuple(Loc, CppHashInfo, Sym));
1152 EndLoc = Lexer.getTok().getEndLoc();
1153 Lex(); // Eat identifier.
1154 }
1155 }
1156 return false;
1157 }
1158 case AsmToken::Real: {
1159 APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
1160 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
1161 Res = MCConstantExpr::create(IntVal, getContext());
1162 EndLoc = Lexer.getTok().getEndLoc();
1163 Lex(); // Eat token.
1164 return false;
1165 }
1166 case AsmToken::Dot: {
1167 // This is a '.' reference, which references the current PC. Emit a
1168 // temporary label to the streamer and refer to it.
1169 MCSymbol *Sym = Ctx.createTempSymbol();
1170 Out.EmitLabel(Sym);
1171 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1172 EndLoc = Lexer.getTok().getEndLoc();
1173 Lex(); // Eat identifier.
1174 return false;
1175 }
1176 case AsmToken::LParen:
1177 Lex(); // Eat the '('.
1178 return parseParenExpr(Res, EndLoc);
1179 case AsmToken::LBrac:
1180 if (!PlatformParser->HasBracketExpressions())
1181 return TokError("brackets expression not supported on this target");
1182 Lex(); // Eat the '['.
1183 return parseBracketExpr(Res, EndLoc);
1184 case AsmToken::Minus:
1185 Lex(); // Eat the operator.
1186 if (parsePrimaryExpr(Res, EndLoc))
1187 return true;
1188 Res = MCUnaryExpr::createMinus(Res, getContext(), FirstTokenLoc);
1189 return false;
1190 case AsmToken::Plus:
1191 Lex(); // Eat the operator.
1192 if (parsePrimaryExpr(Res, EndLoc))
1193 return true;
1194 Res = MCUnaryExpr::createPlus(Res, getContext(), FirstTokenLoc);
1195 return false;
1196 case AsmToken::Tilde:
1197 Lex(); // Eat the operator.
1198 if (parsePrimaryExpr(Res, EndLoc))
1199 return true;
1200 Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc);
1201 return false;
1202 // MIPS unary expression operators. The lexer won't generate these tokens if
1203 // MCAsmInfo::HasMipsExpressions is false for the target.
1204 case AsmToken::PercentCall16:
1205 case AsmToken::PercentCall_Hi:
1206 case AsmToken::PercentCall_Lo:
1207 case AsmToken::PercentDtprel_Hi:
1208 case AsmToken::PercentDtprel_Lo:
1209 case AsmToken::PercentGot:
1210 case AsmToken::PercentGot_Disp:
1211 case AsmToken::PercentGot_Hi:
1212 case AsmToken::PercentGot_Lo:
1213 case AsmToken::PercentGot_Ofst:
1214 case AsmToken::PercentGot_Page:
1215 case AsmToken::PercentGottprel:
1216 case AsmToken::PercentGp_Rel:
1217 case AsmToken::PercentHi:
1218 case AsmToken::PercentHigher:
1219 case AsmToken::PercentHighest:
1220 case AsmToken::PercentLo:
1221 case AsmToken::PercentNeg:
1222 case AsmToken::PercentPcrel_Hi:
1223 case AsmToken::PercentPcrel_Lo:
1224 case AsmToken::PercentTlsgd:
1225 case AsmToken::PercentTlsldm:
1226 case AsmToken::PercentTprel_Hi:
1227 case AsmToken::PercentTprel_Lo:
1228 Lex(); // Eat the operator.
1229 if (Lexer.isNot(AsmToken::LParen))
1230 return TokError("expected '(' after operator");
1231 Lex(); // Eat the operator.
1232 if (parseExpression(Res, EndLoc))
1233 return true;
1234 if (Lexer.isNot(AsmToken::RParen))
1235 return TokError("expected ')'");
1236 Lex(); // Eat the operator.
1237 Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx);
1238 return !Res;
1239 }
1240}
1241
1242bool AsmParser::parseExpression(const MCExpr *&Res) {
1243 SMLoc EndLoc;
1244 return parseExpression(Res, EndLoc);
1245}
1246
1247const MCExpr *
1248AsmParser::applyModifierToExpr(const MCExpr *E,
1249 MCSymbolRefExpr::VariantKind Variant) {
1250 // Ask the target implementation about this expression first.
1251 const MCExpr *NewE = getTargetParser().applyModifierToExpr(E, Variant, Ctx);
1252 if (NewE)
1253 return NewE;
1254 // Recurse over the given expression, rebuilding it to apply the given variant
1255 // if there is exactly one symbol.
1256 switch (E->getKind()) {
1257 case MCExpr::Target:
1258 case MCExpr::Constant:
1259 return nullptr;
1260
1261 case MCExpr::SymbolRef: {
1262 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
1263
1264 if (SRE->getKind() != MCSymbolRefExpr::VK_None) {
1265 TokError("invalid variant on expression '" + getTok().getIdentifier() +
1266 "' (already modified)");
1267 return E;
1268 }
1269
1270 return MCSymbolRefExpr::create(&SRE->getSymbol(), Variant, getContext());
1271 }
1272
1273 case MCExpr::Unary: {
1274 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
1275 const MCExpr *Sub = applyModifierToExpr(UE->getSubExpr(), Variant);
1276 if (!Sub)
1277 return nullptr;
1278 return MCUnaryExpr::create(UE->getOpcode(), Sub, getContext());
1279 }
1280
1281 case MCExpr::Binary: {
1282 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
1283 const MCExpr *LHS = applyModifierToExpr(BE->getLHS(), Variant);
1284 const MCExpr *RHS = applyModifierToExpr(BE->getRHS(), Variant);
1285
1286 if (!LHS && !RHS)
1287 return nullptr;
1288
1289 if (!LHS)
1290 LHS = BE->getLHS();
1291 if (!RHS)
1292 RHS = BE->getRHS();
1293
1294 return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, getContext());
1295 }
1296 }
1297
1298 llvm_unreachable("Invalid expression kind!")::llvm::llvm_unreachable_internal("Invalid expression kind!",
"/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 1298)
;
1299}
1300
1301/// This function checks if the next token is <string> type or arithmetic.
1302/// string that begin with character '<' must end with character '>'.
1303/// otherwise it is arithmetics.
1304/// If the function returns a 'true' value,
1305/// the End argument will be filled with the last location pointed to the '>'
1306/// character.
1307
1308/// There is a gap between the AltMacro's documentation and the single quote implementation.
1309/// GCC does not fully support this feature and so we will not support it.
1310/// TODO: Adding single quote as a string.
1311bool AsmParser::isAltmacroString(SMLoc &StrLoc, SMLoc &EndLoc) {
1312 assert((StrLoc.getPointer() != NULL) &&(static_cast <bool> ((StrLoc.getPointer() != __null) &&
"Argument to the function cannot be a NULL value") ? void (0
) : __assert_fail ("(StrLoc.getPointer() != NULL) && \"Argument to the function cannot be a NULL value\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 1313, __extension__ __PRETTY_FUNCTION__))
1313 "Argument to the function cannot be a NULL value")(static_cast <bool> ((StrLoc.getPointer() != __null) &&
"Argument to the function cannot be a NULL value") ? void (0
) : __assert_fail ("(StrLoc.getPointer() != NULL) && \"Argument to the function cannot be a NULL value\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 1313, __extension__ __PRETTY_FUNCTION__))
;
1314 const char *CharPtr = StrLoc.getPointer();
1315 while ((*CharPtr != '>') && (*CharPtr != '\n') && (*CharPtr != '\r') &&
1316 (*CharPtr != '\0')) {
1317 if (*CharPtr == '!')
1318 CharPtr++;
1319 CharPtr++;
1320 }
1321 if (*CharPtr == '>') {
1322 EndLoc = StrLoc.getFromPointer(CharPtr + 1);
1323 return true;
1324 }
1325 return false;
1326}
1327
1328/// \brief creating a string without the escape characters '!'.
1329void AsmParser::altMacroString(StringRef AltMacroStr,std::string &Res) {
1330 for (size_t Pos = 0; Pos < AltMacroStr.size(); Pos++) {
1331 if (AltMacroStr[Pos] == '!')
1332 Pos++;
1333 Res += AltMacroStr[Pos];
1334 }
1335}
1336
1337/// \brief Parse an expression and return it.
1338///
1339/// expr ::= expr &&,|| expr -> lowest.
1340/// expr ::= expr |,^,&,! expr
1341/// expr ::= expr ==,!=,<>,<,<=,>,>= expr
1342/// expr ::= expr <<,>> expr
1343/// expr ::= expr +,- expr
1344/// expr ::= expr *,/,% expr -> highest.
1345/// expr ::= primaryexpr
1346///
1347bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
1348 // Parse the expression.
1349 Res = nullptr;
1350 if (parsePrimaryExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc))
1351 return true;
1352
1353 // As a special case, we support 'a op b @ modifier' by rewriting the
1354 // expression to include the modifier. This is inefficient, but in general we
1355 // expect users to use 'a@modifier op b'.
1356 if (Lexer.getKind() == AsmToken::At) {
1357 Lex();
1358
1359 if (Lexer.isNot(AsmToken::Identifier))
1360 return TokError("unexpected symbol modifier following '@'");
1361
1362 MCSymbolRefExpr::VariantKind Variant =
1363 MCSymbolRefExpr::getVariantKindForName(getTok().getIdentifier());
1364 if (Variant == MCSymbolRefExpr::VK_Invalid)
1365 return TokError("invalid variant '" + getTok().getIdentifier() + "'");
1366
1367 const MCExpr *ModifiedRes = applyModifierToExpr(Res, Variant);
1368 if (!ModifiedRes) {
1369 return TokError("invalid modifier '" + getTok().getIdentifier() +
1370 "' (no symbols present)");
1371 }
1372
1373 Res = ModifiedRes;
1374 Lex();
1375 }
1376
1377 // Try to constant fold it up front, if possible.
1378 int64_t Value;
1379 if (Res->evaluateAsAbsolute(Value))
1380 Res = MCConstantExpr::create(Value, getContext());
1381
1382 return false;
1383}
1384
1385bool AsmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
1386 Res = nullptr;
1387 return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
1388}
1389
1390bool AsmParser::parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
1391 SMLoc &EndLoc) {
1392 if (parseParenExpr(Res, EndLoc))
1393 return true;
1394
1395 for (; ParenDepth > 0; --ParenDepth) {
1396 if (parseBinOpRHS(1, Res, EndLoc))
1397 return true;
1398
1399 // We don't Lex() the last RParen.
1400 // This is the same behavior as parseParenExpression().
1401 if (ParenDepth - 1 > 0) {
1402 EndLoc = getTok().getEndLoc();
1403 if (parseToken(AsmToken::RParen,
1404 "expected ')' in parentheses expression"))
1405 return true;
1406 }
1407 }
1408 return false;
1409}
1410
1411bool AsmParser::parseAbsoluteExpression(int64_t &Res) {
1412 const MCExpr *Expr;
1413
1414 SMLoc StartLoc = Lexer.getLoc();
1415 if (parseExpression(Expr))
1416 return true;
1417
1418 if (!Expr->evaluateAsAbsolute(Res))
1419 return Error(StartLoc, "expected absolute expression");
1420
1421 return false;
1422}
1423
1424static unsigned getDarwinBinOpPrecedence(AsmToken::TokenKind K,
1425 MCBinaryExpr::Opcode &Kind,
1426 bool ShouldUseLogicalShr) {
1427 switch (K) {
1428 default:
1429 return 0; // not a binop.
1430
1431 // Lowest Precedence: &&, ||
1432 case AsmToken::AmpAmp:
1433 Kind = MCBinaryExpr::LAnd;
1434 return 1;
1435 case AsmToken::PipePipe:
1436 Kind = MCBinaryExpr::LOr;
1437 return 1;
1438
1439 // Low Precedence: |, &, ^
1440 //
1441 // FIXME: gas seems to support '!' as an infix operator?
1442 case AsmToken::Pipe:
1443 Kind = MCBinaryExpr::Or;
1444 return 2;
1445 case AsmToken::Caret:
1446 Kind = MCBinaryExpr::Xor;
1447 return 2;
1448 case AsmToken::Amp:
1449 Kind = MCBinaryExpr::And;
1450 return 2;
1451
1452 // Low Intermediate Precedence: ==, !=, <>, <, <=, >, >=
1453 case AsmToken::EqualEqual:
1454 Kind = MCBinaryExpr::EQ;
1455 return 3;
1456 case AsmToken::ExclaimEqual:
1457 case AsmToken::LessGreater:
1458 Kind = MCBinaryExpr::NE;
1459 return 3;
1460 case AsmToken::Less:
1461 Kind = MCBinaryExpr::LT;
1462 return 3;
1463 case AsmToken::LessEqual:
1464 Kind = MCBinaryExpr::LTE;
1465 return 3;
1466 case AsmToken::Greater:
1467 Kind = MCBinaryExpr::GT;
1468 return 3;
1469 case AsmToken::GreaterEqual:
1470 Kind = MCBinaryExpr::GTE;
1471 return 3;
1472
1473 // Intermediate Precedence: <<, >>
1474 case AsmToken::LessLess:
1475 Kind = MCBinaryExpr::Shl;
1476 return 4;
1477 case AsmToken::GreaterGreater:
1478 Kind = ShouldUseLogicalShr ? MCBinaryExpr::LShr : MCBinaryExpr::AShr;
1479 return 4;
1480
1481 // High Intermediate Precedence: +, -
1482 case AsmToken::Plus:
1483 Kind = MCBinaryExpr::Add;
1484 return 5;
1485 case AsmToken::Minus:
1486 Kind = MCBinaryExpr::Sub;
1487 return 5;
1488
1489 // Highest Precedence: *, /, %
1490 case AsmToken::Star:
1491 Kind = MCBinaryExpr::Mul;
1492 return 6;
1493 case AsmToken::Slash:
1494 Kind = MCBinaryExpr::Div;
1495 return 6;
1496 case AsmToken::Percent:
1497 Kind = MCBinaryExpr::Mod;
1498 return 6;
1499 }
1500}
1501
1502static unsigned getGNUBinOpPrecedence(AsmToken::TokenKind K,
1503 MCBinaryExpr::Opcode &Kind,
1504 bool ShouldUseLogicalShr) {
1505 switch (K) {
1506 default:
1507 return 0; // not a binop.
1508
1509 // Lowest Precedence: &&, ||
1510 case AsmToken::AmpAmp:
1511 Kind = MCBinaryExpr::LAnd;
1512 return 2;
1513 case AsmToken::PipePipe:
1514 Kind = MCBinaryExpr::LOr;
1515 return 1;
1516
1517 // Low Precedence: ==, !=, <>, <, <=, >, >=
1518 case AsmToken::EqualEqual:
1519 Kind = MCBinaryExpr::EQ;
1520 return 3;
1521 case AsmToken::ExclaimEqual:
1522 case AsmToken::LessGreater:
1523 Kind = MCBinaryExpr::NE;
1524 return 3;
1525 case AsmToken::Less:
1526 Kind = MCBinaryExpr::LT;
1527 return 3;
1528 case AsmToken::LessEqual:
1529 Kind = MCBinaryExpr::LTE;
1530 return 3;
1531 case AsmToken::Greater:
1532 Kind = MCBinaryExpr::GT;
1533 return 3;
1534 case AsmToken::GreaterEqual:
1535 Kind = MCBinaryExpr::GTE;
1536 return 3;
1537
1538 // Low Intermediate Precedence: +, -
1539 case AsmToken::Plus:
1540 Kind = MCBinaryExpr::Add;
1541 return 4;
1542 case AsmToken::Minus:
1543 Kind = MCBinaryExpr::Sub;
1544 return 4;
1545
1546 // High Intermediate Precedence: |, &, ^
1547 //
1548 // FIXME: gas seems to support '!' as an infix operator?
1549 case AsmToken::Pipe:
1550 Kind = MCBinaryExpr::Or;
1551 return 5;
1552 case AsmToken::Caret:
1553 Kind = MCBinaryExpr::Xor;
1554 return 5;
1555 case AsmToken::Amp:
1556 Kind = MCBinaryExpr::And;
1557 return 5;
1558
1559 // Highest Precedence: *, /, %, <<, >>
1560 case AsmToken::Star:
1561 Kind = MCBinaryExpr::Mul;
1562 return 6;
1563 case AsmToken::Slash:
1564 Kind = MCBinaryExpr::Div;
1565 return 6;
1566 case AsmToken::Percent:
1567 Kind = MCBinaryExpr::Mod;
1568 return 6;
1569 case AsmToken::LessLess:
1570 Kind = MCBinaryExpr::Shl;
1571 return 6;
1572 case AsmToken::GreaterGreater:
1573 Kind = ShouldUseLogicalShr ? MCBinaryExpr::LShr : MCBinaryExpr::AShr;
1574 return 6;
1575 }
1576}
1577
1578unsigned AsmParser::getBinOpPrecedence(AsmToken::TokenKind K,
1579 MCBinaryExpr::Opcode &Kind) {
1580 bool ShouldUseLogicalShr = MAI.shouldUseLogicalShr();
1581 return IsDarwin ? getDarwinBinOpPrecedence(K, Kind, ShouldUseLogicalShr)
1582 : getGNUBinOpPrecedence(K, Kind, ShouldUseLogicalShr);
1583}
1584
1585/// \brief Parse all binary operators with precedence >= 'Precedence'.
1586/// Res contains the LHS of the expression on input.
1587bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
1588 SMLoc &EndLoc) {
1589 SMLoc StartLoc = Lexer.getLoc();
1590 while (true) {
1591 MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
1592 unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
1593
1594 // If the next token is lower precedence than we are allowed to eat, return
1595 // successfully with what we ate already.
1596 if (TokPrec < Precedence)
1597 return false;
1598
1599 Lex();
1600
1601 // Eat the next primary expression.
1602 const MCExpr *RHS;
1603 if (parsePrimaryExpr(RHS, EndLoc))
1604 return true;
1605
1606 // If BinOp binds less tightly with RHS than the operator after RHS, let
1607 // the pending operator take RHS as its LHS.
1608 MCBinaryExpr::Opcode Dummy;
1609 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
1610 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
1611 return true;
1612
1613 // Merge LHS and RHS according to operator.
1614 Res = MCBinaryExpr::create(Kind, Res, RHS, getContext(), StartLoc);
1615 }
1616}
1617
1618/// ParseStatement:
1619/// ::= EndOfStatement
1620/// ::= Label* Directive ...Operands... EndOfStatement
1621/// ::= Label* Identifier OperandList* EndOfStatement
1622bool AsmParser::parseStatement(ParseStatementInfo &Info,
1623 MCAsmParserSemaCallback *SI) {
1624 assert(!hasPendingError() && "parseStatement started with pending error")(static_cast <bool> (!hasPendingError() && "parseStatement started with pending error"
) ? void (0) : __assert_fail ("!hasPendingError() && \"parseStatement started with pending error\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 1624, __extension__ __PRETTY_FUNCTION__))
;
1625 // Eat initial spaces and comments
1626 while (Lexer.is(AsmToken::Space))
1
Loop condition is false. Execution continues on line 1628
1627 Lex();
1628 if (Lexer.is(AsmToken::EndOfStatement)) {
2
Taking false branch
1629 // if this is a line comment we can drop it safely
1630 if (getTok().getString().empty() || getTok().getString().front() == '\r' ||
1631 getTok().getString().front() == '\n')
1632 Out.AddBlankLine();
1633 Lex();
1634 return false;
1635 }
1636 // Statements always start with an identifier.
1637 AsmToken ID = getTok();
1638 SMLoc IDLoc = ID.getLoc();
1639 StringRef IDVal;
1640 int64_t LocalLabelVal = -1;
1641 if (Lexer.is(AsmToken::HashDirective))
3
Taking false branch
1642 return parseCppHashLineFilenameComment(IDLoc);
1643 // Allow an integer followed by a ':' as a directional local label.
1644 if (Lexer.is(AsmToken::Integer)) {
4
Taking false branch
1645 LocalLabelVal = getTok().getIntVal();
1646 if (LocalLabelVal < 0) {
1647 if (!TheCondState.Ignore) {
1648 Lex(); // always eat a token
1649 return Error(IDLoc, "unexpected token at start of statement");
1650 }
1651 IDVal = "";
1652 } else {
1653 IDVal = getTok().getString();
1654 Lex(); // Consume the integer token to be used as an identifier token.
1655 if (Lexer.getKind() != AsmToken::Colon) {
1656 if (!TheCondState.Ignore) {
1657 Lex(); // always eat a token
1658 return Error(IDLoc, "unexpected token at start of statement");
1659 }
1660 }
1661 }
1662 } else if (Lexer.is(AsmToken::Dot)) {
5
Taking false branch
1663 // Treat '.' as a valid identifier in this context.
1664 Lex();
1665 IDVal = ".";
1666 } else if (Lexer.is(AsmToken::LCurly)) {
6
Taking false branch
1667 // Treat '{' as a valid identifier in this context.
1668 Lex();
1669 IDVal = "{";
1670
1671 } else if (Lexer.is(AsmToken::RCurly)) {
7
Taking false branch
1672 // Treat '}' as a valid identifier in this context.
1673 Lex();
1674 IDVal = "}";
1675 } else if (Lexer.is(AsmToken::Star) &&
1676 getTargetParser().starIsStartOfStatement()) {
1677 // Accept '*' as a valid start of statement.
1678 Lex();
1679 IDVal = "*";
1680 } else if (parseIdentifier(IDVal)) {
8
Assuming the condition is false
9
Taking false branch
1681 if (!TheCondState.Ignore) {
1682 Lex(); // always eat a token
1683 return Error(IDLoc, "unexpected token at start of statement");
1684 }
1685 IDVal = "";
1686 }
1687
1688 // Handle conditional assembly here before checking for skipping. We
1689 // have to do this so that .endif isn't skipped in a ".if 0" block for
1690 // example.
1691 StringMap<DirectiveKind>::const_iterator DirKindIt =
1692 DirectiveKindMap.find(IDVal);
1693 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
10
Assuming the condition is true
11
'?' condition is true
1694 ? DK_NO_DIRECTIVE
1695 : DirKindIt->getValue();
1696 switch (DirKind) {
12
Control jumps to the 'default' case at line 1697
1697 default:
1698 break;
13
Execution continues on line 1734
1699 case DK_IF:
1700 case DK_IFEQ:
1701 case DK_IFGE:
1702 case DK_IFGT:
1703 case DK_IFLE:
1704 case DK_IFLT:
1705 case DK_IFNE:
1706 return parseDirectiveIf(IDLoc, DirKind);
1707 case DK_IFB:
1708 return parseDirectiveIfb(IDLoc, true);
1709 case DK_IFNB:
1710 return parseDirectiveIfb(IDLoc, false);
1711 case DK_IFC:
1712 return parseDirectiveIfc(IDLoc, true);
1713 case DK_IFEQS:
1714 return parseDirectiveIfeqs(IDLoc, true);
1715 case DK_IFNC:
1716 return parseDirectiveIfc(IDLoc, false);
1717 case DK_IFNES:
1718 return parseDirectiveIfeqs(IDLoc, false);
1719 case DK_IFDEF:
1720 return parseDirectiveIfdef(IDLoc, true);
1721 case DK_IFNDEF:
1722 case DK_IFNOTDEF:
1723 return parseDirectiveIfdef(IDLoc, false);
1724 case DK_ELSEIF:
1725 return parseDirectiveElseIf(IDLoc);
1726 case DK_ELSE:
1727 return parseDirectiveElse(IDLoc);
1728 case DK_ENDIF:
1729 return parseDirectiveEndIf(IDLoc);
1730 }
1731
1732 // Ignore the statement if in the middle of inactive conditional
1733 // (e.g. ".if 0").
1734 if (TheCondState.Ignore) {
14
Assuming the condition is false
15
Taking false branch
1735 eatToEndOfStatement();
1736 return false;
1737 }
1738
1739 // FIXME: Recurse on local labels?
1740
1741 // See what kind of statement we have.
1742 switch (Lexer.getKind()) {
16
Control jumps to 'case Equal:' at line 1806
1743 case AsmToken::Colon: {
1744 if (!getTargetParser().isLabel(ID))
1745 break;
1746 if (checkForValidSection())
1747 return true;
1748
1749 // identifier ':' -> Label.
1750 Lex();
1751
1752 // Diagnose attempt to use '.' as a label.
1753 if (IDVal == ".")
1754 return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label");
1755
1756 // Diagnose attempt to use a variable as a label.
1757 //
1758 // FIXME: Diagnostics. Note the location of the definition as a label.
1759 // FIXME: This doesn't diagnose assignment to a symbol which has been
1760 // implicitly marked as external.
1761 MCSymbol *Sym;
1762 if (LocalLabelVal == -1) {
1763 if (ParsingInlineAsm && SI) {
1764 StringRef RewrittenLabel =
1765 SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true);
1766 assert(!RewrittenLabel.empty() &&(static_cast <bool> (!RewrittenLabel.empty() &&
"We should have an internal name here.") ? void (0) : __assert_fail
("!RewrittenLabel.empty() && \"We should have an internal name here.\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 1767, __extension__ __PRETTY_FUNCTION__))
1767 "We should have an internal name here.")(static_cast <bool> (!RewrittenLabel.empty() &&
"We should have an internal name here.") ? void (0) : __assert_fail
("!RewrittenLabel.empty() && \"We should have an internal name here.\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 1767, __extension__ __PRETTY_FUNCTION__))
;
1768 Info.AsmRewrites->emplace_back(AOK_Label, IDLoc, IDVal.size(),
1769 RewrittenLabel);
1770 IDVal = RewrittenLabel;
1771 }
1772 Sym = getContext().getOrCreateSymbol(IDVal);
1773 } else
1774 Sym = Ctx.createDirectionalLocalSymbol(LocalLabelVal);
1775 // End of Labels should be treated as end of line for lexing
1776 // purposes but that information is not available to the Lexer who
1777 // does not understand Labels. This may cause us to see a Hash
1778 // here instead of a preprocessor line comment.
1779 if (getTok().is(AsmToken::Hash)) {
1780 StringRef CommentStr = parseStringToEndOfStatement();
1781 Lexer.Lex();
1782 Lexer.UnLex(AsmToken(AsmToken::EndOfStatement, CommentStr));
1783 }
1784
1785 // Consume any end of statement token, if present, to avoid spurious
1786 // AddBlankLine calls().
1787 if (getTok().is(AsmToken::EndOfStatement)) {
1788 Lex();
1789 }
1790
1791 // Emit the label.
1792 if (!getTargetParser().isParsingInlineAsm())
1793 Out.EmitLabel(Sym, IDLoc);
1794
1795 // If we are generating dwarf for assembly source files then gather the
1796 // info to make a dwarf label entry for this label if needed.
1797 if (enabledGenDwarfForAssembly())
1798 MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(),
1799 IDLoc);
1800
1801 getTargetParser().onLabelParsed(Sym);
1802
1803 return false;
1804 }
1805
1806 case AsmToken::Equal:
1807 if (!getTargetParser().equalIsAsmAssignment())
17
Assuming the condition is false
18
Taking false branch
1808 break;
1809 // identifier '=' ... -> assignment statement
1810 Lex();
1811
1812 return parseAssignment(IDVal, true);
19
Calling 'AsmParser::parseAssignment'
1813
1814 default: // Normal instruction or directive.
1815 break;
1816 }
1817
1818 // If macros are enabled, check to see if this is a macro instantiation.
1819 if (areMacrosEnabled())
1820 if (const MCAsmMacro *M = getContext().lookupMacro(IDVal)) {
1821 return handleMacroEntry(M, IDLoc);
1822 }
1823
1824 // Otherwise, we have a normal instruction or directive.
1825
1826 // Directives start with "."
1827 if (IDVal[0] == '.' && IDVal != ".") {
1828 // There are several entities interested in parsing directives:
1829 //
1830 // 1. The target-specific assembly parser. Some directives are target
1831 // specific or may potentially behave differently on certain targets.
1832 // 2. Asm parser extensions. For example, platform-specific parsers
1833 // (like the ELF parser) register themselves as extensions.
1834 // 3. The generic directive parser implemented by this class. These are
1835 // all the directives that behave in a target and platform independent
1836 // manner, or at least have a default behavior that's shared between
1837 // all targets and platforms.
1838
1839 getTargetParser().flushPendingInstructions(getStreamer());
1840
1841 SMLoc StartTokLoc = getTok().getLoc();
1842 bool TPDirectiveReturn = getTargetParser().ParseDirective(ID);
1843
1844 if (hasPendingError())
1845 return true;
1846 // Currently the return value should be true if we are
1847 // uninterested but as this is at odds with the standard parsing
1848 // convention (return true = error) we have instances of a parsed
1849 // directive that fails returning true as an error. Catch these
1850 // cases as best as possible errors here.
1851 if (TPDirectiveReturn && StartTokLoc != getTok().getLoc())
1852 return true;
1853 // Return if we did some parsing or believe we succeeded.
1854 if (!TPDirectiveReturn || StartTokLoc != getTok().getLoc())
1855 return false;
1856
1857 // Next, check the extension directive map to see if any extension has
1858 // registered itself to parse this directive.
1859 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
1860 ExtensionDirectiveMap.lookup(IDVal);
1861 if (Handler.first)
1862 return (*Handler.second)(Handler.first, IDVal, IDLoc);
1863
1864 // Finally, if no one else is interested in this directive, it must be
1865 // generic and familiar to this class.
1866 switch (DirKind) {
1867 default:
1868 break;
1869 case DK_SET:
1870 case DK_EQU:
1871 return parseDirectiveSet(IDVal, true);
1872 case DK_EQUIV:
1873 return parseDirectiveSet(IDVal, false);
1874 case DK_ASCII:
1875 return parseDirectiveAscii(IDVal, false);
1876 case DK_ASCIZ:
1877 case DK_STRING:
1878 return parseDirectiveAscii(IDVal, true);
1879 case DK_BYTE:
1880 case DK_DC_B:
1881 return parseDirectiveValue(IDVal, 1);
1882 case DK_DC:
1883 case DK_DC_W:
1884 case DK_SHORT:
1885 case DK_VALUE:
1886 case DK_2BYTE:
1887 return parseDirectiveValue(IDVal, 2);
1888 case DK_LONG:
1889 case DK_INT:
1890 case DK_4BYTE:
1891 case DK_DC_L:
1892 return parseDirectiveValue(IDVal, 4);
1893 case DK_QUAD:
1894 case DK_8BYTE:
1895 return parseDirectiveValue(IDVal, 8);
1896 case DK_DC_A:
1897 return parseDirectiveValue(
1898 IDVal, getContext().getAsmInfo()->getCodePointerSize());
1899 case DK_OCTA:
1900 return parseDirectiveOctaValue(IDVal);
1901 case DK_SINGLE:
1902 case DK_FLOAT:
1903 case DK_DC_S:
1904 return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle());
1905 case DK_DOUBLE:
1906 case DK_DC_D:
1907 return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble());
1908 case DK_ALIGN: {
1909 bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes();
1910 return parseDirectiveAlign(IsPow2, /*ExprSize=*/1);
1911 }
1912 case DK_ALIGN32: {
1913 bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes();
1914 return parseDirectiveAlign(IsPow2, /*ExprSize=*/4);
1915 }
1916 case DK_BALIGN:
1917 return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
1918 case DK_BALIGNW:
1919 return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
1920 case DK_BALIGNL:
1921 return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
1922 case DK_P2ALIGN:
1923 return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
1924 case DK_P2ALIGNW:
1925 return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
1926 case DK_P2ALIGNL:
1927 return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
1928 case DK_ORG:
1929 return parseDirectiveOrg();
1930 case DK_FILL:
1931 return parseDirectiveFill();
1932 case DK_ZERO:
1933 return parseDirectiveZero();
1934 case DK_EXTERN:
1935 eatToEndOfStatement(); // .extern is the default, ignore it.
1936 return false;
1937 case DK_GLOBL:
1938 case DK_GLOBAL:
1939 return parseDirectiveSymbolAttribute(MCSA_Global);
1940 case DK_LAZY_REFERENCE:
1941 return parseDirectiveSymbolAttribute(MCSA_LazyReference);
1942 case DK_NO_DEAD_STRIP:
1943 return parseDirectiveSymbolAttribute(MCSA_NoDeadStrip);
1944 case DK_SYMBOL_RESOLVER:
1945 return parseDirectiveSymbolAttribute(MCSA_SymbolResolver);
1946 case DK_PRIVATE_EXTERN:
1947 return parseDirectiveSymbolAttribute(MCSA_PrivateExtern);
1948 case DK_REFERENCE:
1949 return parseDirectiveSymbolAttribute(MCSA_Reference);
1950 case DK_WEAK_DEFINITION:
1951 return parseDirectiveSymbolAttribute(MCSA_WeakDefinition);
1952 case DK_WEAK_REFERENCE:
1953 return parseDirectiveSymbolAttribute(MCSA_WeakReference);
1954 case DK_WEAK_DEF_CAN_BE_HIDDEN:
1955 return parseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate);
1956 case DK_COMM:
1957 case DK_COMMON:
1958 return parseDirectiveComm(/*IsLocal=*/false);
1959 case DK_LCOMM:
1960 return parseDirectiveComm(/*IsLocal=*/true);
1961 case DK_ABORT:
1962 return parseDirectiveAbort();
1963 case DK_INCLUDE:
1964 return parseDirectiveInclude();
1965 case DK_INCBIN:
1966 return parseDirectiveIncbin();
1967 case DK_CODE16:
1968 case DK_CODE16GCC:
1969 return TokError(Twine(IDVal) +
1970 " not currently supported for this target");
1971 case DK_REPT:
1972 return parseDirectiveRept(IDLoc, IDVal);
1973 case DK_IRP:
1974 return parseDirectiveIrp(IDLoc);
1975 case DK_IRPC:
1976 return parseDirectiveIrpc(IDLoc);
1977 case DK_ENDR:
1978 return parseDirectiveEndr(IDLoc);
1979 case DK_BUNDLE_ALIGN_MODE:
1980 return parseDirectiveBundleAlignMode();
1981 case DK_BUNDLE_LOCK:
1982 return parseDirectiveBundleLock();
1983 case DK_BUNDLE_UNLOCK:
1984 return parseDirectiveBundleUnlock();
1985 case DK_SLEB128:
1986 return parseDirectiveLEB128(true);
1987 case DK_ULEB128:
1988 return parseDirectiveLEB128(false);
1989 case DK_SPACE:
1990 case DK_SKIP:
1991 return parseDirectiveSpace(IDVal);
1992 case DK_FILE:
1993 return parseDirectiveFile(IDLoc);
1994 case DK_LINE:
1995 return parseDirectiveLine();
1996 case DK_LOC:
1997 return parseDirectiveLoc();
1998 case DK_STABS:
1999 return parseDirectiveStabs();
2000 case DK_CV_FILE:
2001 return parseDirectiveCVFile();
2002 case DK_CV_FUNC_ID:
2003 return parseDirectiveCVFuncId();
2004 case DK_CV_INLINE_SITE_ID:
2005 return parseDirectiveCVInlineSiteId();
2006 case DK_CV_LOC:
2007 return parseDirectiveCVLoc();
2008 case DK_CV_LINETABLE:
2009 return parseDirectiveCVLinetable();
2010 case DK_CV_INLINE_LINETABLE:
2011 return parseDirectiveCVInlineLinetable();
2012 case DK_CV_DEF_RANGE:
2013 return parseDirectiveCVDefRange();
2014 case DK_CV_STRINGTABLE:
2015 return parseDirectiveCVStringTable();
2016 case DK_CV_FILECHECKSUMS:
2017 return parseDirectiveCVFileChecksums();
2018 case DK_CV_FILECHECKSUM_OFFSET:
2019 return parseDirectiveCVFileChecksumOffset();
2020 case DK_CV_FPO_DATA:
2021 return parseDirectiveCVFPOData();
2022 case DK_CFI_SECTIONS:
2023 return parseDirectiveCFISections();
2024 case DK_CFI_STARTPROC:
2025 return parseDirectiveCFIStartProc();
2026 case DK_CFI_ENDPROC:
2027 return parseDirectiveCFIEndProc();
2028 case DK_CFI_DEF_CFA:
2029 return parseDirectiveCFIDefCfa(IDLoc);
2030 case DK_CFI_DEF_CFA_OFFSET:
2031 return parseDirectiveCFIDefCfaOffset();
2032 case DK_CFI_ADJUST_CFA_OFFSET:
2033 return parseDirectiveCFIAdjustCfaOffset();
2034 case DK_CFI_DEF_CFA_REGISTER:
2035 return parseDirectiveCFIDefCfaRegister(IDLoc);
2036 case DK_CFI_OFFSET:
2037 return parseDirectiveCFIOffset(IDLoc);
2038 case DK_CFI_REL_OFFSET:
2039 return parseDirectiveCFIRelOffset(IDLoc);
2040 case DK_CFI_PERSONALITY:
2041 return parseDirectiveCFIPersonalityOrLsda(true);
2042 case DK_CFI_LSDA:
2043 return parseDirectiveCFIPersonalityOrLsda(false);
2044 case DK_CFI_REMEMBER_STATE:
2045 return parseDirectiveCFIRememberState();
2046 case DK_CFI_RESTORE_STATE:
2047 return parseDirectiveCFIRestoreState();
2048 case DK_CFI_SAME_VALUE:
2049 return parseDirectiveCFISameValue(IDLoc);
2050 case DK_CFI_RESTORE:
2051 return parseDirectiveCFIRestore(IDLoc);
2052 case DK_CFI_ESCAPE:
2053 return parseDirectiveCFIEscape();
2054 case DK_CFI_RETURN_COLUMN:
2055 return parseDirectiveCFIReturnColumn(IDLoc);
2056 case DK_CFI_SIGNAL_FRAME:
2057 return parseDirectiveCFISignalFrame();
2058 case DK_CFI_UNDEFINED:
2059 return parseDirectiveCFIUndefined(IDLoc);
2060 case DK_CFI_REGISTER:
2061 return parseDirectiveCFIRegister(IDLoc);
2062 case DK_CFI_WINDOW_SAVE:
2063 return parseDirectiveCFIWindowSave();
2064 case DK_MACROS_ON:
2065 case DK_MACROS_OFF:
2066 return parseDirectiveMacrosOnOff(IDVal);
2067 case DK_MACRO:
2068 return parseDirectiveMacro(IDLoc);
2069 case DK_ALTMACRO:
2070 case DK_NOALTMACRO:
2071 return parseDirectiveAltmacro(IDVal);
2072 case DK_EXITM:
2073 return parseDirectiveExitMacro(IDVal);
2074 case DK_ENDM:
2075 case DK_ENDMACRO:
2076 return parseDirectiveEndMacro(IDVal);
2077 case DK_PURGEM:
2078 return parseDirectivePurgeMacro(IDLoc);
2079 case DK_END:
2080 return parseDirectiveEnd(IDLoc);
2081 case DK_ERR:
2082 return parseDirectiveError(IDLoc, false);
2083 case DK_ERROR:
2084 return parseDirectiveError(IDLoc, true);
2085 case DK_WARNING:
2086 return parseDirectiveWarning(IDLoc);
2087 case DK_RELOC:
2088 return parseDirectiveReloc(IDLoc);
2089 case DK_DCB:
2090 case DK_DCB_W:
2091 return parseDirectiveDCB(IDVal, 2);
2092 case DK_DCB_B:
2093 return parseDirectiveDCB(IDVal, 1);
2094 case DK_DCB_D:
2095 return parseDirectiveRealDCB(IDVal, APFloat::IEEEdouble());
2096 case DK_DCB_L:
2097 return parseDirectiveDCB(IDVal, 4);
2098 case DK_DCB_S:
2099 return parseDirectiveRealDCB(IDVal, APFloat::IEEEsingle());
2100 case DK_DC_X:
2101 case DK_DCB_X:
2102 return TokError(Twine(IDVal) +
2103 " not currently supported for this target");
2104 case DK_DS:
2105 case DK_DS_W:
2106 return parseDirectiveDS(IDVal, 2);
2107 case DK_DS_B:
2108 return parseDirectiveDS(IDVal, 1);
2109 case DK_DS_D:
2110 return parseDirectiveDS(IDVal, 8);
2111 case DK_DS_L:
2112 case DK_DS_S:
2113 return parseDirectiveDS(IDVal, 4);
2114 case DK_DS_P:
2115 case DK_DS_X:
2116 return parseDirectiveDS(IDVal, 12);
2117 case DK_PRINT:
2118 return parseDirectivePrint(IDLoc);
2119 }
2120
2121 return Error(IDLoc, "unknown directive");
2122 }
2123
2124 // __asm _emit or __asm __emit
2125 if (ParsingInlineAsm && (IDVal == "_emit" || IDVal == "__emit" ||
2126 IDVal == "_EMIT" || IDVal == "__EMIT"))
2127 return parseDirectiveMSEmit(IDLoc, Info, IDVal.size());
2128
2129 // __asm align
2130 if (ParsingInlineAsm && (IDVal == "align" || IDVal == "ALIGN"))
2131 return parseDirectiveMSAlign(IDLoc, Info);
2132
2133 if (ParsingInlineAsm && (IDVal == "even" || IDVal == "EVEN"))
2134 Info.AsmRewrites->emplace_back(AOK_EVEN, IDLoc, 4);
2135 if (checkForValidSection())
2136 return true;
2137
2138 // Canonicalize the opcode to lower case.
2139 std::string OpcodeStr = IDVal.lower();
2140 ParseInstructionInfo IInfo(Info.AsmRewrites);
2141 bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID,
2142 Info.ParsedOperands);
2143 Info.ParseError = ParseHadError;
2144
2145 // Dump the parsed representation, if requested.
2146 if (getShowParsedOperands()) {
2147 SmallString<256> Str;
2148 raw_svector_ostream OS(Str);
2149 OS << "parsed instruction: [";
2150 for (unsigned i = 0; i != Info.ParsedOperands.size(); ++i) {
2151 if (i != 0)
2152 OS << ", ";
2153 Info.ParsedOperands[i]->print(OS);
2154 }
2155 OS << "]";
2156
2157 printMessage(IDLoc, SourceMgr::DK_Note, OS.str());
2158 }
2159
2160 // Fail even if ParseInstruction erroneously returns false.
2161 if (hasPendingError() || ParseHadError)
2162 return true;
2163
2164 // If we are generating dwarf for the current section then generate a .loc
2165 // directive for the instruction.
2166 if (!ParseHadError && enabledGenDwarfForAssembly() &&
2167 getContext().getGenDwarfSectionSyms().count(
2168 getStreamer().getCurrentSectionOnly())) {
2169 unsigned Line;
2170 if (ActiveMacros.empty())
2171 Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer);
2172 else
2173 Line = SrcMgr.FindLineNumber(ActiveMacros.front()->InstantiationLoc,
2174 ActiveMacros.front()->ExitBuffer);
2175
2176 // If we previously parsed a cpp hash file line comment then make sure the
2177 // current Dwarf File is for the CppHashFilename if not then emit the
2178 // Dwarf File table for it and adjust the line number for the .loc.
2179 if (!CppHashInfo.Filename.empty()) {
2180 unsigned FileNumber = getStreamer().EmitDwarfFileDirective(
2181 0, StringRef(), CppHashInfo.Filename);
2182 getContext().setGenDwarfFileNumber(FileNumber);
2183
2184 unsigned CppHashLocLineNo =
2185 SrcMgr.FindLineNumber(CppHashInfo.Loc, CppHashInfo.Buf);
2186 Line = CppHashInfo.LineNumber - 1 + (Line - CppHashLocLineNo);
2187 }
2188
2189 getStreamer().EmitDwarfLocDirective(
2190 getContext().getGenDwarfFileNumber(), Line, 0,
2191 DWARF2_LINE_DEFAULT_IS_STMT1 ? DWARF2_FLAG_IS_STMT(1 << 0) : 0, 0, 0,
2192 StringRef());
2193 }
2194
2195 // If parsing succeeded, match the instruction.
2196 if (!ParseHadError) {
2197 uint64_t ErrorInfo;
2198 if (getTargetParser().MatchAndEmitInstruction(
2199 IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo,
2200 getTargetParser().isParsingInlineAsm()))
2201 return true;
2202 }
2203 return false;
2204}
2205
2206// Parse and erase curly braces marking block start/end
2207bool
2208AsmParser::parseCurlyBlockScope(SmallVectorImpl<AsmRewrite> &AsmStrRewrites) {
2209 // Identify curly brace marking block start/end
2210 if (Lexer.isNot(AsmToken::LCurly) && Lexer.isNot(AsmToken::RCurly))
2211 return false;
2212
2213 SMLoc StartLoc = Lexer.getLoc();
2214 Lex(); // Eat the brace
2215 if (Lexer.is(AsmToken::EndOfStatement))
2216 Lex(); // Eat EndOfStatement following the brace
2217
2218 // Erase the block start/end brace from the output asm string
2219 AsmStrRewrites.emplace_back(AOK_Skip, StartLoc, Lexer.getLoc().getPointer() -
2220 StartLoc.getPointer());
2221 return true;
2222}
2223
2224/// parseCppHashLineFilenameComment as this:
2225/// ::= # number "filename"
2226bool AsmParser::parseCppHashLineFilenameComment(SMLoc L) {
2227 Lex(); // Eat the hash token.
2228 // Lexer only ever emits HashDirective if it fully formed if it's
2229 // done the checking already so this is an internal error.
2230 assert(getTok().is(AsmToken::Integer) &&(static_cast <bool> (getTok().is(AsmToken::Integer) &&
"Lexing Cpp line comment: Expected Integer") ? void (0) : __assert_fail
("getTok().is(AsmToken::Integer) && \"Lexing Cpp line comment: Expected Integer\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 2231, __extension__ __PRETTY_FUNCTION__))
2231 "Lexing Cpp line comment: Expected Integer")(static_cast <bool> (getTok().is(AsmToken::Integer) &&
"Lexing Cpp line comment: Expected Integer") ? void (0) : __assert_fail
("getTok().is(AsmToken::Integer) && \"Lexing Cpp line comment: Expected Integer\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 2231, __extension__ __PRETTY_FUNCTION__))
;
2232 int64_t LineNumber = getTok().getIntVal();
2233 Lex();
2234 assert(getTok().is(AsmToken::String) &&(static_cast <bool> (getTok().is(AsmToken::String) &&
"Lexing Cpp line comment: Expected String") ? void (0) : __assert_fail
("getTok().is(AsmToken::String) && \"Lexing Cpp line comment: Expected String\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 2235, __extension__ __PRETTY_FUNCTION__))
2235 "Lexing Cpp line comment: Expected String")(static_cast <bool> (getTok().is(AsmToken::String) &&
"Lexing Cpp line comment: Expected String") ? void (0) : __assert_fail
("getTok().is(AsmToken::String) && \"Lexing Cpp line comment: Expected String\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 2235, __extension__ __PRETTY_FUNCTION__))
;
2236 StringRef Filename = getTok().getString();
2237 Lex();
2238
2239 // Get rid of the enclosing quotes.
2240 Filename = Filename.substr(1, Filename.size() - 2);
2241
2242 // Save the SMLoc, Filename and LineNumber for later use by diagnostics.
2243 CppHashInfo.Loc = L;
2244 CppHashInfo.Filename = Filename;
2245 CppHashInfo.LineNumber = LineNumber;
2246 CppHashInfo.Buf = CurBuffer;
2247 return false;
2248}
2249
2250/// \brief will use the last parsed cpp hash line filename comment
2251/// for the Filename and LineNo if any in the diagnostic.
2252void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
2253 const AsmParser *Parser = static_cast<const AsmParser *>(Context);
2254 raw_ostream &OS = errs();
2255
2256 const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr();
2257 SMLoc DiagLoc = Diag.getLoc();
2258 unsigned DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
2259 unsigned CppHashBuf =
2260 Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
2261
2262 // Like SourceMgr::printMessage() we need to print the include stack if any
2263 // before printing the message.
2264 unsigned DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
2265 if (!Parser->SavedDiagHandler && DiagCurBuffer &&
2266 DiagCurBuffer != DiagSrcMgr.getMainFileID()) {
2267 SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer);
2268 DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS);
2269 }
2270
2271 // If we have not parsed a cpp hash line filename comment or the source
2272 // manager changed or buffer changed (like in a nested include) then just
2273 // print the normal diagnostic using its Filename and LineNo.
2274 if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
2275 DiagBuf != CppHashBuf) {
2276 if (Parser->SavedDiagHandler)
2277 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2278 else
2279 Diag.print(nullptr, OS);
2280 return;
2281 }
2282
2283 // Use the CppHashFilename and calculate a line number based on the
2284 // CppHashInfo.Loc and CppHashInfo.LineNumber relative to this Diag's SMLoc
2285 // for the diagnostic.
2286 const std::string &Filename = Parser->CppHashInfo.Filename;
2287
2288 int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf);
2289 int CppHashLocLineNo =
2290 Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
2291 int LineNo =
2292 Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
2293
2294 SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo,
2295 Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(),
2296 Diag.getLineContents(), Diag.getRanges());
2297
2298 if (Parser->SavedDiagHandler)
2299 Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);
2300 else
2301 NewDiag.print(nullptr, OS);
2302}
2303
2304// FIXME: This is mostly duplicated from the function in AsmLexer.cpp. The
2305// difference being that that function accepts '@' as part of identifiers and
2306// we can't do that. AsmLexer.cpp should probably be changed to handle
2307// '@' as a special case when needed.
2308static bool isIdentifierChar(char c) {
2309 return isalnum(static_cast<unsigned char>(c)) || c == '_' || c == '$' ||
2310 c == '.';
2311}
2312
2313bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
2314 ArrayRef<MCAsmMacroParameter> Parameters,
2315 ArrayRef<MCAsmMacroArgument> A,
2316 bool EnableAtPseudoVariable, SMLoc L) {
2317 unsigned NParameters = Parameters.size();
2318 bool HasVararg = NParameters ? Parameters.back().Vararg : false;
2319 if ((!IsDarwin || NParameters != 0) && NParameters != A.size())
2320 return Error(L, "Wrong number of arguments");
2321
2322 // A macro without parameters is handled differently on Darwin:
2323 // gas accepts no arguments and does no substitutions
2324 while (!Body.empty()) {
2325 // Scan for the next substitution.
2326 std::size_t End = Body.size(), Pos = 0;
2327 for (; Pos != End; ++Pos) {
2328 // Check for a substitution or escape.
2329 if (IsDarwin && !NParameters) {
2330 // This macro has no parameters, look for $0, $1, etc.
2331 if (Body[Pos] != '$' || Pos + 1 == End)
2332 continue;
2333
2334 char Next = Body[Pos + 1];
2335 if (Next == '$' || Next == 'n' ||
2336 isdigit(static_cast<unsigned char>(Next)))
2337 break;
2338 } else {
2339 // This macro has parameters, look for \foo, \bar, etc.
2340 if (Body[Pos] == '\\' && Pos + 1 != End)
2341 break;
2342 }
2343 }
2344
2345 // Add the prefix.
2346 OS << Body.slice(0, Pos);
2347
2348 // Check if we reached the end.
2349 if (Pos == End)
2350 break;
2351
2352 if (IsDarwin && !NParameters) {
2353 switch (Body[Pos + 1]) {
2354 // $$ => $
2355 case '$':
2356 OS << '$';
2357 break;
2358
2359 // $n => number of arguments
2360 case 'n':
2361 OS << A.size();
2362 break;
2363
2364 // $[0-9] => argument
2365 default: {
2366 // Missing arguments are ignored.
2367 unsigned Index = Body[Pos + 1] - '0';
2368 if (Index >= A.size())
2369 break;
2370
2371 // Otherwise substitute with the token values, with spaces eliminated.
2372 for (const AsmToken &Token : A[Index])
2373 OS << Token.getString();
2374 break;
2375 }
2376 }
2377 Pos += 2;
2378 } else {
2379 unsigned I = Pos + 1;
2380
2381 // Check for the \@ pseudo-variable.
2382 if (EnableAtPseudoVariable && Body[I] == '@' && I + 1 != End)
2383 ++I;
2384 else
2385 while (isIdentifierChar(Body[I]) && I + 1 != End)
2386 ++I;
2387
2388 const char *Begin = Body.data() + Pos + 1;
2389 StringRef Argument(Begin, I - (Pos + 1));
2390 unsigned Index = 0;
2391
2392 if (Argument == "@") {
2393 OS << NumOfMacroInstantiations;
2394 Pos += 2;
2395 } else {
2396 for (; Index < NParameters; ++Index)
2397 if (Parameters[Index].Name == Argument)
2398 break;
2399
2400 if (Index == NParameters) {
2401 if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
2402 Pos += 3;
2403 else {
2404 OS << '\\' << Argument;
2405 Pos = I;
2406 }
2407 } else {
2408 bool VarargParameter = HasVararg && Index == (NParameters - 1);
2409 for (const AsmToken &Token : A[Index])
2410 // For altmacro mode, you can write '%expr'.
2411 // The prefix '%' evaluates the expression 'expr'
2412 // and uses the result as a string (e.g. replace %(1+2) with the string "3").
2413 // Here, we identify the integer token which is the result of the
2414 // absolute expression evaluation and replace it with its string representation.
2415 if ((Lexer.IsaAltMacroMode()) &&
2416 (*(Token.getString().begin()) == '%') && Token.is(AsmToken::Integer))
2417 // Emit an integer value to the buffer.
2418 OS << Token.getIntVal();
2419 // Only Token that was validated as a string and begins with '<'
2420 // is considered altMacroString!!!
2421 else if ((Lexer.IsaAltMacroMode()) &&
2422 (*(Token.getString().begin()) == '<') &&
2423 Token.is(AsmToken::String)) {
2424 std::string Res;
2425 altMacroString(Token.getStringContents(), Res);
2426 OS << Res;
2427 }
2428 // We expect no quotes around the string's contents when
2429 // parsing for varargs.
2430 else if (Token.isNot(AsmToken::String) || VarargParameter)
2431 OS << Token.getString();
2432 else
2433 OS << Token.getStringContents();
2434
2435 Pos += 1 + Argument.size();
2436 }
2437 }
2438 }
2439 // Update the scan point.
2440 Body = Body.substr(Pos);
2441 }
2442
2443 return false;
2444}
2445
2446MacroInstantiation::MacroInstantiation(SMLoc IL, int EB, SMLoc EL,
2447 size_t CondStackDepth)
2448 : InstantiationLoc(IL), ExitBuffer(EB), ExitLoc(EL),
2449 CondStackDepth(CondStackDepth) {}
2450
2451static bool isOperator(AsmToken::TokenKind kind) {
2452 switch (kind) {
2453 default:
2454 return false;
2455 case AsmToken::Plus:
2456 case AsmToken::Minus:
2457 case AsmToken::Tilde:
2458 case AsmToken::Slash:
2459 case AsmToken::Star:
2460 case AsmToken::Dot:
2461 case AsmToken::Equal:
2462 case AsmToken::EqualEqual:
2463 case AsmToken::Pipe:
2464 case AsmToken::PipePipe:
2465 case AsmToken::Caret:
2466 case AsmToken::Amp:
2467 case AsmToken::AmpAmp:
2468 case AsmToken::Exclaim:
2469 case AsmToken::ExclaimEqual:
2470 case AsmToken::Less:
2471 case AsmToken::LessEqual:
2472 case AsmToken::LessLess:
2473 case AsmToken::LessGreater:
2474 case AsmToken::Greater:
2475 case AsmToken::GreaterEqual:
2476 case AsmToken::GreaterGreater:
2477 return true;
2478 }
2479}
2480
2481namespace {
2482
2483class AsmLexerSkipSpaceRAII {
2484public:
2485 AsmLexerSkipSpaceRAII(AsmLexer &Lexer, bool SkipSpace) : Lexer(Lexer) {
2486 Lexer.setSkipSpace(SkipSpace);
2487 }
2488
2489 ~AsmLexerSkipSpaceRAII() {
2490 Lexer.setSkipSpace(true);
2491 }
2492
2493private:
2494 AsmLexer &Lexer;
2495};
2496
2497} // end anonymous namespace
2498
2499bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg) {
2500
2501 if (Vararg) {
2502 if (Lexer.isNot(AsmToken::EndOfStatement)) {
2503 StringRef Str = parseStringToEndOfStatement();
2504 MA.emplace_back(AsmToken::String, Str);
2505 }
2506 return false;
2507 }
2508
2509 unsigned ParenLevel = 0;
2510
2511 // Darwin doesn't use spaces to delmit arguments.
2512 AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
2513
2514 bool SpaceEaten;
2515
2516 while (true) {
2517 SpaceEaten = false;
2518 if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal))
2519 return TokError("unexpected token in macro instantiation");
2520
2521 if (ParenLevel == 0) {
2522
2523 if (Lexer.is(AsmToken::Comma))
2524 break;
2525
2526 if (Lexer.is(AsmToken::Space)) {
2527 SpaceEaten = true;
2528 Lexer.Lex(); // Eat spaces
2529 }
2530
2531 // Spaces can delimit parameters, but could also be part an expression.
2532 // If the token after a space is an operator, add the token and the next
2533 // one into this argument
2534 if (!IsDarwin) {
2535 if (isOperator(Lexer.getKind())) {
2536 MA.push_back(getTok());
2537 Lexer.Lex();
2538
2539 // Whitespace after an operator can be ignored.
2540 if (Lexer.is(AsmToken::Space))
2541 Lexer.Lex();
2542
2543 continue;
2544 }
2545 }
2546 if (SpaceEaten)
2547 break;
2548 }
2549
2550 // handleMacroEntry relies on not advancing the lexer here
2551 // to be able to fill in the remaining default parameter values
2552 if (Lexer.is(AsmToken::EndOfStatement))
2553 break;
2554
2555 // Adjust the current parentheses level.
2556 if (Lexer.is(AsmToken::LParen))
2557 ++ParenLevel;
2558 else if (Lexer.is(AsmToken::RParen) && ParenLevel)
2559 --ParenLevel;
2560
2561 // Append the token to the current argument list.
2562 MA.push_back(getTok());
2563 Lexer.Lex();
2564 }
2565
2566 if (ParenLevel != 0)
2567 return TokError("unbalanced parentheses in macro argument");
2568 return false;
2569}
2570
2571// Parse the macro instantiation arguments.
2572bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
2573 MCAsmMacroArguments &A) {
2574 const unsigned NParameters = M ? M->Parameters.size() : 0;
2575 bool NamedParametersFound = false;
2576 SmallVector<SMLoc, 4> FALocs;
2577
2578 A.resize(NParameters);
2579 FALocs.resize(NParameters);
2580
2581 // Parse two kinds of macro invocations:
2582 // - macros defined without any parameters accept an arbitrary number of them
2583 // - macros defined with parameters accept at most that many of them
2584 bool HasVararg = NParameters ? M->Parameters.back().Vararg : false;
2585 for (unsigned Parameter = 0; !NParameters || Parameter < NParameters;
2586 ++Parameter) {
2587 SMLoc IDLoc = Lexer.getLoc();
2588 MCAsmMacroParameter FA;
2589
2590 if (Lexer.is(AsmToken::Identifier) && Lexer.peekTok().is(AsmToken::Equal)) {
2591 if (parseIdentifier(FA.Name))
2592 return Error(IDLoc, "invalid argument identifier for formal argument");
2593
2594 if (Lexer.isNot(AsmToken::Equal))
2595 return TokError("expected '=' after formal parameter identifier");
2596
2597 Lex();
2598
2599 NamedParametersFound = true;
2600 }
2601 bool Vararg = HasVararg && Parameter == (NParameters - 1);
2602
2603 if (NamedParametersFound && FA.Name.empty())
2604 return Error(IDLoc, "cannot mix positional and keyword arguments");
2605
2606 SMLoc StrLoc = Lexer.getLoc();
2607 SMLoc EndLoc;
2608 if (Lexer.IsaAltMacroMode() && Lexer.is(AsmToken::Percent)) {
2609 const MCExpr *AbsoluteExp;
2610 int64_t Value;
2611 /// Eat '%'
2612 Lex();
2613 if (parseExpression(AbsoluteExp, EndLoc))
2614 return false;
2615 if (!AbsoluteExp->evaluateAsAbsolute(Value))
2616 return Error(StrLoc, "expected absolute expression");
2617 const char *StrChar = StrLoc.getPointer();
2618 const char *EndChar = EndLoc.getPointer();
2619 AsmToken newToken(AsmToken::Integer, StringRef(StrChar , EndChar - StrChar), Value);
2620 FA.Value.push_back(newToken);
2621 } else if (Lexer.IsaAltMacroMode() && Lexer.is(AsmToken::Less) &&
2622 isAltmacroString(StrLoc, EndLoc)) {
2623 const char *StrChar = StrLoc.getPointer();
2624 const char *EndChar = EndLoc.getPointer();
2625 jumpToLoc(EndLoc, CurBuffer);
2626 /// Eat from '<' to '>'
2627 Lex();
2628 AsmToken newToken(AsmToken::String, StringRef(StrChar, EndChar - StrChar));
2629 FA.Value.push_back(newToken);
2630 } else if(parseMacroArgument(FA.Value, Vararg))
2631 return true;
2632
2633 unsigned PI = Parameter;
2634 if (!FA.Name.empty()) {
2635 unsigned FAI = 0;
2636 for (FAI = 0; FAI < NParameters; ++FAI)
2637 if (M->Parameters[FAI].Name == FA.Name)
2638 break;
2639
2640 if (FAI >= NParameters) {
2641 assert(M && "expected macro to be defined")(static_cast <bool> (M && "expected macro to be defined"
) ? void (0) : __assert_fail ("M && \"expected macro to be defined\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 2641, __extension__ __PRETTY_FUNCTION__))
;
2642 return Error(IDLoc, "parameter named '" + FA.Name +
2643 "' does not exist for macro '" + M->Name + "'");
2644 }
2645 PI = FAI;
2646 }
2647
2648 if (!FA.Value.empty()) {
2649 if (A.size() <= PI)
2650 A.resize(PI + 1);
2651 A[PI] = FA.Value;
2652
2653 if (FALocs.size() <= PI)
2654 FALocs.resize(PI + 1);
2655
2656 FALocs[PI] = Lexer.getLoc();
2657 }
2658
2659 // At the end of the statement, fill in remaining arguments that have
2660 // default values. If there aren't any, then the next argument is
2661 // required but missing
2662 if (Lexer.is(AsmToken::EndOfStatement)) {
2663 bool Failure = false;
2664 for (unsigned FAI = 0; FAI < NParameters; ++FAI) {
2665 if (A[FAI].empty()) {
2666 if (M->Parameters[FAI].Required) {
2667 Error(FALocs[FAI].isValid() ? FALocs[FAI] : Lexer.getLoc(),
2668 "missing value for required parameter "
2669 "'" + M->Parameters[FAI].Name + "' in macro '" + M->Name + "'");
2670 Failure = true;
2671 }
2672
2673 if (!M->Parameters[FAI].Value.empty())
2674 A[FAI] = M->Parameters[FAI].Value;
2675 }
2676 }
2677 return Failure;
2678 }
2679
2680 if (Lexer.is(AsmToken::Comma))
2681 Lex();
2682 }
2683
2684 return TokError("too many positional arguments");
2685}
2686
2687bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
2688 // Arbitrarily limit macro nesting depth (default matches 'as'). We can
2689 // eliminate this, although we should protect against infinite loops.
2690 unsigned MaxNestingDepth = AsmMacroMaxNestingDepth;
2691 if (ActiveMacros.size() == MaxNestingDepth) {
2692 std::ostringstream MaxNestingDepthError;
2693 MaxNestingDepthError << "macros cannot be nested more than "
2694 << MaxNestingDepth << " levels deep."
2695 << " Use -asm-macro-max-nesting-depth to increase "
2696 "this limit.";
2697 return TokError(MaxNestingDepthError.str());
2698 }
2699
2700 MCAsmMacroArguments A;
2701 if (parseMacroArguments(M, A))
2702 return true;
2703
2704 // Macro instantiation is lexical, unfortunately. We construct a new buffer
2705 // to hold the macro body with substitutions.
2706 SmallString<256> Buf;
2707 StringRef Body = M->Body;
2708 raw_svector_ostream OS(Buf);
2709
2710 if (expandMacro(OS, Body, M->Parameters, A, true, getTok().getLoc()))
2711 return true;
2712
2713 // We include the .endmacro in the buffer as our cue to exit the macro
2714 // instantiation.
2715 OS << ".endmacro\n";
2716
2717 std::unique_ptr<MemoryBuffer> Instantiation =
2718 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
2719
2720 // Create the macro instantiation object and add to the current macro
2721 // instantiation stack.
2722 MacroInstantiation *MI = new MacroInstantiation(
2723 NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size());
2724 ActiveMacros.push_back(MI);
2725
2726 ++NumOfMacroInstantiations;
2727
2728 // Jump to the macro instantiation and prime the lexer.
2729 CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
2730 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
2731 Lex();
2732
2733 return false;
2734}
2735
2736void AsmParser::handleMacroExit() {
2737 // Jump to the EndOfStatement we should return to, and consume it.
2738 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer);
2739 Lex();
2740
2741 // Pop the instantiation entry.
2742 delete ActiveMacros.back();
2743 ActiveMacros.pop_back();
2744}
2745
2746bool AsmParser::parseAssignment(StringRef Name, bool allow_redef,
2747 bool NoDeadStrip) {
2748 MCSymbol *Sym;
20
'Sym' declared without an initial value
2749 const MCExpr *Value;
2750 if (MCParserUtils::parseAssignmentExpression(Name, allow_redef, *this, Sym,
21
Calling 'parseAssignmentExpression'
25
Returning from 'parseAssignmentExpression'
26
Assuming the condition is false
27
Taking false branch
2751 Value))
2752 return true;
2753
2754 if (!Sym) {
28
Branch condition evaluates to a garbage value
2755 // In the case where we parse an expression starting with a '.', we will
2756 // not generate an error, nor will we create a symbol. In this case we
2757 // should just return out.
2758 return false;
2759 }
2760
2761 // Do the assignment.
2762 Out.EmitAssignment(Sym, Value);
2763 if (NoDeadStrip)
2764 Out.EmitSymbolAttribute(Sym, MCSA_NoDeadStrip);
2765
2766 return false;
2767}
2768
2769/// parseIdentifier:
2770/// ::= identifier
2771/// ::= string
2772bool AsmParser::parseIdentifier(StringRef &Res) {
2773 // The assembler has relaxed rules for accepting identifiers, in particular we
2774 // allow things like '.globl $foo' and '.def @feat.00', which would normally be
2775 // separate tokens. At this level, we have already lexed so we cannot (currently)
2776 // handle this as a context dependent token, instead we detect adjacent tokens
2777 // and return the combined identifier.
2778 if (Lexer.is(AsmToken::Dollar) || Lexer.is(AsmToken::At)) {
2779 SMLoc PrefixLoc = getLexer().getLoc();
2780
2781 // Consume the prefix character, and check for a following identifier.
2782
2783 AsmToken Buf[1];
2784 Lexer.peekTokens(Buf, false);
2785
2786 if (Buf[0].isNot(AsmToken::Identifier))
2787 return true;
2788
2789 // We have a '$' or '@' followed by an identifier, make sure they are adjacent.
2790 if (PrefixLoc.getPointer() + 1 != Buf[0].getLoc().getPointer())
2791 return true;
2792
2793 // eat $ or @
2794 Lexer.Lex(); // Lexer's Lex guarantees consecutive token.
2795 // Construct the joined identifier and consume the token.
2796 Res =
2797 StringRef(PrefixLoc.getPointer(), getTok().getIdentifier().size() + 1);
2798 Lex(); // Parser Lex to maintain invariants.
2799 return false;
2800 }
2801
2802 if (Lexer.isNot(AsmToken::Identifier) && Lexer.isNot(AsmToken::String))
2803 return true;
2804
2805 Res = getTok().getIdentifier();
2806
2807 Lex(); // Consume the identifier token.
2808
2809 return false;
2810}
2811
2812/// parseDirectiveSet:
2813/// ::= .equ identifier ',' expression
2814/// ::= .equiv identifier ',' expression
2815/// ::= .set identifier ',' expression
2816bool AsmParser::parseDirectiveSet(StringRef IDVal, bool allow_redef) {
2817 StringRef Name;
2818 if (check(parseIdentifier(Name), "expected identifier") ||
2819 parseToken(AsmToken::Comma) || parseAssignment(Name, allow_redef, true))
2820 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
2821 return false;
2822}
2823
2824bool AsmParser::parseEscapedString(std::string &Data) {
2825 if (check(getTok().isNot(AsmToken::String), "expected string"))
2826 return true;
2827
2828 Data = "";
2829 StringRef Str = getTok().getStringContents();
2830 for (unsigned i = 0, e = Str.size(); i != e; ++i) {
2831 if (Str[i] != '\\') {
2832 Data += Str[i];
2833 continue;
2834 }
2835
2836 // Recognize escaped characters. Note that this escape semantics currently
2837 // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes.
2838 ++i;
2839 if (i == e)
2840 return TokError("unexpected backslash at end of string");
2841
2842 // Recognize octal sequences.
2843 if ((unsigned)(Str[i] - '0') <= 7) {
2844 // Consume up to three octal characters.
2845 unsigned Value = Str[i] - '0';
2846
2847 if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) {
2848 ++i;
2849 Value = Value * 8 + (Str[i] - '0');
2850
2851 if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) {
2852 ++i;
2853 Value = Value * 8 + (Str[i] - '0');
2854 }
2855 }
2856
2857 if (Value > 255)
2858 return TokError("invalid octal escape sequence (out of range)");
2859
2860 Data += (unsigned char)Value;
2861 continue;
2862 }
2863
2864 // Otherwise recognize individual escapes.
2865 switch (Str[i]) {
2866 default:
2867 // Just reject invalid escape sequences for now.
2868 return TokError("invalid escape sequence (unrecognized character)");
2869
2870 case 'b': Data += '\b'; break;
2871 case 'f': Data += '\f'; break;
2872 case 'n': Data += '\n'; break;
2873 case 'r': Data += '\r'; break;
2874 case 't': Data += '\t'; break;
2875 case '"': Data += '"'; break;
2876 case '\\': Data += '\\'; break;
2877 }
2878 }
2879
2880 Lex();
2881 return false;
2882}
2883
2884/// parseDirectiveAscii:
2885/// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ]
2886bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
2887 auto parseOp = [&]() -> bool {
2888 std::string Data;
2889 if (checkForValidSection() || parseEscapedString(Data))
2890 return true;
2891 getStreamer().EmitBytes(Data);
2892 if (ZeroTerminated)
2893 getStreamer().EmitBytes(StringRef("\0", 1));
2894 return false;
2895 };
2896
2897 if (parseMany(parseOp))
2898 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
2899 return false;
2900}
2901
2902/// parseDirectiveReloc
2903/// ::= .reloc expression , identifier [ , expression ]
2904bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) {
2905 const MCExpr *Offset;
2906 const MCExpr *Expr = nullptr;
2907
2908 SMLoc OffsetLoc = Lexer.getTok().getLoc();
2909 int64_t OffsetValue;
2910 // We can only deal with constant expressions at the moment.
2911
2912 if (parseExpression(Offset))
2913 return true;
2914
2915 if (check(!Offset->evaluateAsAbsolute(OffsetValue), OffsetLoc,
2916 "expression is not a constant value") ||
2917 check(OffsetValue < 0, OffsetLoc, "expression is negative") ||
2918 parseToken(AsmToken::Comma, "expected comma") ||
2919 check(getTok().isNot(AsmToken::Identifier), "expected relocation name"))
2920 return true;
2921
2922 SMLoc NameLoc = Lexer.getTok().getLoc();
2923 StringRef Name = Lexer.getTok().getIdentifier();
2924 Lex();
2925
2926 if (Lexer.is(AsmToken::Comma)) {
2927 Lex();
2928 SMLoc ExprLoc = Lexer.getLoc();
2929 if (parseExpression(Expr))
2930 return true;
2931
2932 MCValue Value;
2933 if (!Expr->evaluateAsRelocatable(Value, nullptr, nullptr))
2934 return Error(ExprLoc, "expression must be relocatable");
2935 }
2936
2937 if (parseToken(AsmToken::EndOfStatement,
2938 "unexpected token in .reloc directive"))
2939 return true;
2940
2941 if (getStreamer().EmitRelocDirective(*Offset, Name, Expr, DirectiveLoc))
2942 return Error(NameLoc, "unknown relocation name");
2943
2944 return false;
2945}
2946
2947/// parseDirectiveValue
2948/// ::= (.byte | .short | ... ) [ expression (, expression)* ]
2949bool AsmParser::parseDirectiveValue(StringRef IDVal, unsigned Size) {
2950 auto parseOp = [&]() -> bool {
2951 const MCExpr *Value;
2952 SMLoc ExprLoc = getLexer().getLoc();
2953 if (checkForValidSection() || parseExpression(Value))
2954 return true;
2955 // Special case constant expressions to match code generator.
2956 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
2957 assert(Size <= 8 && "Invalid size")(static_cast <bool> (Size <= 8 && "Invalid size"
) ? void (0) : __assert_fail ("Size <= 8 && \"Invalid size\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 2957, __extension__ __PRETTY_FUNCTION__))
;
2958 uint64_t IntValue = MCE->getValue();
2959 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
2960 return Error(ExprLoc, "out of range literal value");
2961 getStreamer().EmitIntValue(IntValue, Size);
2962 } else
2963 getStreamer().EmitValue(Value, Size, ExprLoc);
2964 return false;
2965 };
2966
2967 if (parseMany(parseOp))
2968 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
2969 return false;
2970}
2971
2972/// ParseDirectiveOctaValue
2973/// ::= .octa [ hexconstant (, hexconstant)* ]
2974
2975bool AsmParser::parseDirectiveOctaValue(StringRef IDVal) {
2976 auto parseOp = [&]() -> bool {
2977 if (checkForValidSection())
2978 return true;
2979 if (getTok().isNot(AsmToken::Integer) && getTok().isNot(AsmToken::BigNum))
2980 return TokError("unknown token in expression");
2981 SMLoc ExprLoc = getTok().getLoc();
2982 APInt IntValue = getTok().getAPIntVal();
2983 uint64_t hi, lo;
2984 Lex();
2985 if (!IntValue.isIntN(128))
2986 return Error(ExprLoc, "out of range literal value");
2987 if (!IntValue.isIntN(64)) {
2988 hi = IntValue.getHiBits(IntValue.getBitWidth() - 64).getZExtValue();
2989 lo = IntValue.getLoBits(64).getZExtValue();
2990 } else {
2991 hi = 0;
2992 lo = IntValue.getZExtValue();
2993 }
2994 if (MAI.isLittleEndian()) {
2995 getStreamer().EmitIntValue(lo, 8);
2996 getStreamer().EmitIntValue(hi, 8);
2997 } else {
2998 getStreamer().EmitIntValue(hi, 8);
2999 getStreamer().EmitIntValue(lo, 8);
3000 }
3001 return false;
3002 };
3003
3004 if (parseMany(parseOp))
3005 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3006 return false;
3007}
3008
3009bool AsmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {
3010 // We don't truly support arithmetic on floating point expressions, so we
3011 // have to manually parse unary prefixes.
3012 bool IsNeg = false;
3013 if (getLexer().is(AsmToken::Minus)) {
3014 Lexer.Lex();
3015 IsNeg = true;
3016 } else if (getLexer().is(AsmToken::Plus))
3017 Lexer.Lex();
3018
3019 if (Lexer.is(AsmToken::Error))
3020 return TokError(Lexer.getErr());
3021 if (Lexer.isNot(AsmToken::Integer) && Lexer.isNot(AsmToken::Real) &&
3022 Lexer.isNot(AsmToken::Identifier))
3023 return TokError("unexpected token in directive");
3024
3025 // Convert to an APFloat.
3026 APFloat Value(Semantics);
3027 StringRef IDVal = getTok().getString();
3028 if (getLexer().is(AsmToken::Identifier)) {
3029 if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf"))
3030 Value = APFloat::getInf(Semantics);
3031 else if (!IDVal.compare_lower("nan"))
3032 Value = APFloat::getNaN(Semantics, false, ~0);
3033 else
3034 return TokError("invalid floating point literal");
3035 } else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) ==
3036 APFloat::opInvalidOp)
3037 return TokError("invalid floating point literal");
3038 if (IsNeg)
3039 Value.changeSign();
3040
3041 // Consume the numeric token.
3042 Lex();
3043
3044 Res = Value.bitcastToAPInt();
3045
3046 return false;
3047}
3048
3049/// parseDirectiveRealValue
3050/// ::= (.single | .double) [ expression (, expression)* ]
3051bool AsmParser::parseDirectiveRealValue(StringRef IDVal,
3052 const fltSemantics &Semantics) {
3053 auto parseOp = [&]() -> bool {
3054 APInt AsInt;
3055 if (checkForValidSection() || parseRealValue(Semantics, AsInt))
3056 return true;
3057 getStreamer().EmitIntValue(AsInt.getLimitedValue(),
3058 AsInt.getBitWidth() / 8);
3059 return false;
3060 };
3061
3062 if (parseMany(parseOp))
3063 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3064 return false;
3065}
3066
3067/// parseDirectiveZero
3068/// ::= .zero expression
3069bool AsmParser::parseDirectiveZero() {
3070 SMLoc NumBytesLoc = Lexer.getLoc();
3071 const MCExpr *NumBytes;
3072 if (checkForValidSection() || parseExpression(NumBytes))
3073 return true;
3074
3075 int64_t Val = 0;
3076 if (getLexer().is(AsmToken::Comma)) {
3077 Lex();
3078 if (parseAbsoluteExpression(Val))
3079 return true;
3080 }
3081
3082 if (parseToken(AsmToken::EndOfStatement,
3083 "unexpected token in '.zero' directive"))
3084 return true;
3085 getStreamer().emitFill(*NumBytes, Val, NumBytesLoc);
3086
3087 return false;
3088}
3089
3090/// parseDirectiveFill
3091/// ::= .fill expression [ , expression [ , expression ] ]
3092bool AsmParser::parseDirectiveFill() {
3093 SMLoc NumValuesLoc = Lexer.getLoc();
3094 const MCExpr *NumValues;
3095 if (checkForValidSection() || parseExpression(NumValues))
3096 return true;
3097
3098 int64_t FillSize = 1;
3099 int64_t FillExpr = 0;
3100
3101 SMLoc SizeLoc, ExprLoc;
3102
3103 if (parseOptionalToken(AsmToken::Comma)) {
3104 SizeLoc = getTok().getLoc();
3105 if (parseAbsoluteExpression(FillSize))
3106 return true;
3107 if (parseOptionalToken(AsmToken::Comma)) {
3108 ExprLoc = getTok().getLoc();
3109 if (parseAbsoluteExpression(FillExpr))
3110 return true;
3111 }
3112 }
3113 if (parseToken(AsmToken::EndOfStatement,
3114 "unexpected token in '.fill' directive"))
3115 return true;
3116
3117 if (FillSize < 0) {
3118 Warning(SizeLoc, "'.fill' directive with negative size has no effect");
3119 return false;
3120 }
3121 if (FillSize > 8) {
3122 Warning(SizeLoc, "'.fill' directive with size greater than 8 has been truncated to 8");
3123 FillSize = 8;
3124 }
3125
3126 if (!isUInt<32>(FillExpr) && FillSize > 4)
3127 Warning(ExprLoc, "'.fill' directive pattern has been truncated to 32-bits");
3128
3129 getStreamer().emitFill(*NumValues, FillSize, FillExpr, NumValuesLoc);
3130
3131 return false;
3132}
3133
3134/// parseDirectiveOrg
3135/// ::= .org expression [ , expression ]
3136bool AsmParser::parseDirectiveOrg() {
3137 const MCExpr *Offset;
3138 SMLoc OffsetLoc = Lexer.getLoc();
3139 if (checkForValidSection() || parseExpression(Offset))
3140 return true;
3141
3142 // Parse optional fill expression.
3143 int64_t FillExpr = 0;
3144 if (parseOptionalToken(AsmToken::Comma))
3145 if (parseAbsoluteExpression(FillExpr))
3146 return addErrorSuffix(" in '.org' directive");
3147 if (parseToken(AsmToken::EndOfStatement))
3148 return addErrorSuffix(" in '.org' directive");
3149
3150 getStreamer().emitValueToOffset(Offset, FillExpr, OffsetLoc);
3151 return false;
3152}
3153
3154/// parseDirectiveAlign
3155/// ::= {.align, ...} expression [ , expression [ , expression ]]
3156bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
3157 SMLoc AlignmentLoc = getLexer().getLoc();
3158 int64_t Alignment;
3159 SMLoc MaxBytesLoc;
3160 bool HasFillExpr = false;
3161 int64_t FillExpr = 0;
3162 int64_t MaxBytesToFill = 0;
3163
3164 auto parseAlign = [&]() -> bool {
3165 if (parseAbsoluteExpression(Alignment))
3166 return true;
3167 if (parseOptionalToken(AsmToken::Comma)) {
3168 // The fill expression can be omitted while specifying a maximum number of
3169 // alignment bytes, e.g:
3170 // .align 3,,4
3171 if (getTok().isNot(AsmToken::Comma)) {
3172 HasFillExpr = true;
3173 if (parseAbsoluteExpression(FillExpr))
3174 return true;
3175 }
3176 if (parseOptionalToken(AsmToken::Comma))
3177 if (parseTokenLoc(MaxBytesLoc) ||
3178 parseAbsoluteExpression(MaxBytesToFill))
3179 return true;
3180 }
3181 return parseToken(AsmToken::EndOfStatement);
3182 };
3183
3184 if (checkForValidSection())
3185 return addErrorSuffix(" in directive");
3186 // Ignore empty '.p2align' directives for GNU-as compatibility
3187 if (IsPow2 && (ValueSize == 1) && getTok().is(AsmToken::EndOfStatement)) {
3188 Warning(AlignmentLoc, "p2align directive with no operand(s) is ignored");
3189 return parseToken(AsmToken::EndOfStatement);
3190 }
3191 if (parseAlign())
3192 return addErrorSuffix(" in directive");
3193
3194 // Always emit an alignment here even if we thrown an error.
3195 bool ReturnVal = false;
3196
3197 // Compute alignment in bytes.
3198 if (IsPow2) {
3199 // FIXME: Diagnose overflow.
3200 if (Alignment >= 32) {
3201 ReturnVal |= Error(AlignmentLoc, "invalid alignment value");
3202 Alignment = 31;
3203 }
3204
3205 Alignment = 1ULL << Alignment;
3206 } else {
3207 // Reject alignments that aren't either a power of two or zero,
3208 // for gas compatibility. Alignment of zero is silently rounded
3209 // up to one.
3210 if (Alignment == 0)
3211 Alignment = 1;
3212 if (!isPowerOf2_64(Alignment))
3213 ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2");
3214 }
3215
3216 // Diagnose non-sensical max bytes to align.
3217 if (MaxBytesLoc.isValid()) {
3218 if (MaxBytesToFill < 1) {
3219 ReturnVal |= Error(MaxBytesLoc,
3220 "alignment directive can never be satisfied in this "
3221 "many bytes, ignoring maximum bytes expression");
3222 MaxBytesToFill = 0;
3223 }
3224
3225 if (MaxBytesToFill >= Alignment) {
3226 Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and "
3227 "has no effect");
3228 MaxBytesToFill = 0;
3229 }
3230 }
3231
3232 // Check whether we should use optimal code alignment for this .align
3233 // directive.
3234 const MCSection *Section = getStreamer().getCurrentSectionOnly();
3235 assert(Section && "must have section to emit alignment")(static_cast <bool> (Section && "must have section to emit alignment"
) ? void (0) : __assert_fail ("Section && \"must have section to emit alignment\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 3235, __extension__ __PRETTY_FUNCTION__))
;
3236 bool UseCodeAlign = Section->UseCodeAlign();
3237 if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
3238 ValueSize == 1 && UseCodeAlign) {
3239 getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill);
3240 } else {
3241 // FIXME: Target specific behavior about how the "extra" bytes are filled.
3242 getStreamer().EmitValueToAlignment(Alignment, FillExpr, ValueSize,
3243 MaxBytesToFill);
3244 }
3245
3246 return ReturnVal;
3247}
3248
3249/// parseDirectiveFile
3250/// ::= .file filename
3251/// ::= .file number [directory] filename [md5 checksum] [source source-text]
3252bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
3253 // FIXME: I'm not sure what this is.
3254 int64_t FileNumber = -1;
3255 if (getLexer().is(AsmToken::Integer)) {
3256 FileNumber = getTok().getIntVal();
3257 Lex();
3258
3259 if (FileNumber < 0)
3260 return TokError("negative file number");
3261 }
3262
3263 std::string Path = getTok().getString();
3264
3265 // Usually the directory and filename together, otherwise just the directory.
3266 // Allow the strings to have escaped octal character sequence.
3267 if (check(getTok().isNot(AsmToken::String),
3268 "unexpected token in '.file' directive") ||
3269 parseEscapedString(Path))
3270 return true;
3271
3272 StringRef Directory;
3273 StringRef Filename;
3274 std::string FilenameData;
3275 if (getLexer().is(AsmToken::String)) {
3276 if (check(FileNumber == -1,
3277 "explicit path specified, but no file number") ||
3278 parseEscapedString(FilenameData))
3279 return true;
3280 Filename = FilenameData;
3281 Directory = Path;
3282 } else {
3283 Filename = Path;
3284 }
3285
3286 std::string Checksum;
3287
3288 Optional<StringRef> Source;
3289 bool HasSource = false;
3290 std::string SourceString;
3291
3292 while (!parseOptionalToken(AsmToken::EndOfStatement)) {
3293 StringRef Keyword;
3294 if (check(getTok().isNot(AsmToken::Identifier),
3295 "unexpected token in '.file' directive") ||
3296 parseIdentifier(Keyword))
3297 return true;
3298 if (Keyword == "md5") {
3299 if (check(FileNumber == -1,
3300 "MD5 checksum specified, but no file number") ||
3301 check(getTok().isNot(AsmToken::String),
3302 "unexpected token in '.file' directive") ||
3303 parseEscapedString(Checksum) ||
3304 check(Checksum.size() != 32, "invalid MD5 checksum specified"))
3305 return true;
3306 } else if (Keyword == "source") {
3307 HasSource = true;
3308 if (check(FileNumber == -1,
3309 "source specified, but no file number") ||
3310 check(getTok().isNot(AsmToken::String),
3311 "unexpected token in '.file' directive") ||
3312 parseEscapedString(SourceString))
3313 return true;
3314 } else {
3315 return TokError("unexpected token in '.file' directive");
3316 }
3317 }
3318
3319 // In case there is a -g option as well as debug info from directive .file,
3320 // we turn off the -g option, directly use the existing debug info instead.
3321 getContext().setGenDwarfForAssembly(false);
3322
3323 if (FileNumber == -1)
3324 getStreamer().EmitFileDirective(Filename);
3325 else {
3326 MD5::MD5Result *CKMem = nullptr;
3327 if (!Checksum.empty()) {
3328 Checksum = fromHex(Checksum);
3329 if (check(Checksum.size() != 16, "invalid MD5 checksum specified"))
3330 return true;
3331 CKMem = (MD5::MD5Result *)Ctx.allocate(sizeof(MD5::MD5Result), 1);
3332 memcpy(&CKMem->Bytes, Checksum.data(), 16);
3333 }
3334 if (HasSource) {
3335 char *SourceBuf = static_cast<char *>(Ctx.allocate(SourceString.size()));
3336 memcpy(SourceBuf, SourceString.data(), SourceString.size());
3337 Source = StringRef(SourceBuf, SourceString.size());
3338 }
3339 if (FileNumber == 0)
3340 getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
3341 else {
3342 Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective(
3343 FileNumber, Directory, Filename, CKMem, Source);
3344 if (!FileNumOrErr)
3345 return Error(DirectiveLoc, toString(FileNumOrErr.takeError()));
3346 FileNumber = FileNumOrErr.get();
3347 }
3348 }
3349
3350 return false;
3351}
3352
3353/// parseDirectiveLine
3354/// ::= .line [number]
3355bool AsmParser::parseDirectiveLine() {
3356 int64_t LineNumber;
3357 if (getLexer().is(AsmToken::Integer)) {
3358 if (parseIntToken(LineNumber, "unexpected token in '.line' directive"))
3359 return true;
3360 (void)LineNumber;
3361 // FIXME: Do something with the .line.
3362 }
3363 if (parseToken(AsmToken::EndOfStatement,
3364 "unexpected token in '.line' directive"))
3365 return true;
3366
3367 return false;
3368}
3369
3370/// parseDirectiveLoc
3371/// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end]
3372/// [epilogue_begin] [is_stmt VALUE] [isa VALUE]
3373/// The first number is a file number, must have been previously assigned with
3374/// a .file directive, the second number is the line number and optionally the
3375/// third number is a column position (zero if not specified). The remaining
3376/// optional items are .loc sub-directives.
3377bool AsmParser::parseDirectiveLoc() {
3378 int64_t FileNumber = 0, LineNumber = 0;
3379 SMLoc Loc = getTok().getLoc();
3380 if (parseIntToken(FileNumber, "unexpected token in '.loc' directive") ||
3381 check(FileNumber < 1, Loc,
3382 "file number less than one in '.loc' directive") ||
3383 check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
3384 "unassigned file number in '.loc' directive"))
3385 return true;
3386
3387 // optional
3388 if (getLexer().is(AsmToken::Integer)) {
3389 LineNumber = getTok().getIntVal();
3390 if (LineNumber < 0)
3391 return TokError("line number less than zero in '.loc' directive");
3392 Lex();
3393 }
3394
3395 int64_t ColumnPos = 0;
3396 if (getLexer().is(AsmToken::Integer)) {
3397 ColumnPos = getTok().getIntVal();
3398 if (ColumnPos < 0)
3399 return TokError("column position less than zero in '.loc' directive");
3400 Lex();
3401 }
3402
3403 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT1 ? DWARF2_FLAG_IS_STMT(1 << 0) : 0;
3404 unsigned Isa = 0;
3405 int64_t Discriminator = 0;
3406
3407 auto parseLocOp = [&]() -> bool {
3408 StringRef Name;
3409 SMLoc Loc = getTok().getLoc();
3410 if (parseIdentifier(Name))
3411 return TokError("unexpected token in '.loc' directive");
3412
3413 if (Name == "basic_block")
3414 Flags |= DWARF2_FLAG_BASIC_BLOCK(1 << 1);
3415 else if (Name == "prologue_end")
3416 Flags |= DWARF2_FLAG_PROLOGUE_END(1 << 2);
3417 else if (Name == "epilogue_begin")
3418 Flags |= DWARF2_FLAG_EPILOGUE_BEGIN(1 << 3);
3419 else if (Name == "is_stmt") {
3420 Loc = getTok().getLoc();
3421 const MCExpr *Value;
3422 if (parseExpression(Value))
3423 return true;
3424 // The expression must be the constant 0 or 1.
3425 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
3426 int Value = MCE->getValue();
3427 if (Value == 0)
3428 Flags &= ~DWARF2_FLAG_IS_STMT(1 << 0);
3429 else if (Value == 1)
3430 Flags |= DWARF2_FLAG_IS_STMT(1 << 0);
3431 else
3432 return Error(Loc, "is_stmt value not 0 or 1");
3433 } else {
3434 return Error(Loc, "is_stmt value not the constant value of 0 or 1");
3435 }
3436 } else if (Name == "isa") {
3437 Loc = getTok().getLoc();
3438 const MCExpr *Value;
3439 if (parseExpression(Value))
3440 return true;
3441 // The expression must be a constant greater or equal to 0.
3442 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
3443 int Value = MCE->getValue();
3444 if (Value < 0)
3445 return Error(Loc, "isa number less than zero");
3446 Isa = Value;
3447 } else {
3448 return Error(Loc, "isa number not a constant value");
3449 }
3450 } else if (Name == "discriminator") {
3451 if (parseAbsoluteExpression(Discriminator))
3452 return true;
3453 } else {
3454 return Error(Loc, "unknown sub-directive in '.loc' directive");
3455 }
3456 return false;
3457 };
3458
3459 if (parseMany(parseLocOp, false /*hasComma*/))
3460 return true;
3461
3462 getStreamer().EmitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
3463 Isa, Discriminator, StringRef());
3464
3465 return false;
3466}
3467
3468/// parseDirectiveStabs
3469/// ::= .stabs string, number, number, number
3470bool AsmParser::parseDirectiveStabs() {
3471 return TokError("unsupported directive '.stabs'");
3472}
3473
3474/// parseDirectiveCVFile
3475/// ::= .cv_file number filename [checksum] [checksumkind]
3476bool AsmParser::parseDirectiveCVFile() {
3477 SMLoc FileNumberLoc = getTok().getLoc();
3478 int64_t FileNumber;
3479 std::string Filename;
3480 std::string Checksum;
3481 int64_t ChecksumKind = 0;
3482
3483 if (parseIntToken(FileNumber,
3484 "expected file number in '.cv_file' directive") ||
3485 check(FileNumber < 1, FileNumberLoc, "file number less than one") ||
3486 check(getTok().isNot(AsmToken::String),
3487 "unexpected token in '.cv_file' directive") ||
3488 parseEscapedString(Filename))
3489 return true;
3490 if (!parseOptionalToken(AsmToken::EndOfStatement)) {
3491 if (check(getTok().isNot(AsmToken::String),
3492 "unexpected token in '.cv_file' directive") ||
3493 parseEscapedString(Checksum) ||
3494 parseIntToken(ChecksumKind,
3495 "expected checksum kind in '.cv_file' directive") ||
3496 parseToken(AsmToken::EndOfStatement,
3497 "unexpected token in '.cv_file' directive"))
3498 return true;
3499 }
3500
3501 Checksum = fromHex(Checksum);
3502 void *CKMem = Ctx.allocate(Checksum.size(), 1);
3503 memcpy(CKMem, Checksum.data(), Checksum.size());
3504 ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem),
3505 Checksum.size());
3506
3507 if (!getStreamer().EmitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
3508 static_cast<uint8_t>(ChecksumKind)))
3509 return Error(FileNumberLoc, "file number already allocated");
3510
3511 return false;
3512}
3513
3514bool AsmParser::parseCVFunctionId(int64_t &FunctionId,
3515 StringRef DirectiveName) {
3516 SMLoc Loc;
3517 return parseTokenLoc(Loc) ||
3518 parseIntToken(FunctionId, "expected function id in '" + DirectiveName +
3519 "' directive") ||
3520 check(FunctionId < 0 || FunctionId >= UINT_MAX(2147483647 *2U +1U), Loc,
3521 "expected function id within range [0, UINT_MAX)");
3522}
3523
3524bool AsmParser::parseCVFileId(int64_t &FileNumber, StringRef DirectiveName) {
3525 SMLoc Loc;
3526 return parseTokenLoc(Loc) ||
3527 parseIntToken(FileNumber, "expected integer in '" + DirectiveName +
3528 "' directive") ||
3529 check(FileNumber < 1, Loc, "file number less than one in '" +
3530 DirectiveName + "' directive") ||
3531 check(!getCVContext().isValidFileNumber(FileNumber), Loc,
3532 "unassigned file number in '" + DirectiveName + "' directive");
3533}
3534
3535/// parseDirectiveCVFuncId
3536/// ::= .cv_func_id FunctionId
3537///
3538/// Introduces a function ID that can be used with .cv_loc.
3539bool AsmParser::parseDirectiveCVFuncId() {
3540 SMLoc FunctionIdLoc = getTok().getLoc();
3541 int64_t FunctionId;
3542
3543 if (parseCVFunctionId(FunctionId, ".cv_func_id") ||
3544 parseToken(AsmToken::EndOfStatement,
3545 "unexpected token in '.cv_func_id' directive"))
3546 return true;
3547
3548 if (!getStreamer().EmitCVFuncIdDirective(FunctionId))
3549 return Error(FunctionIdLoc, "function id already allocated");
3550
3551 return false;
3552}
3553
3554/// parseDirectiveCVInlineSiteId
3555/// ::= .cv_inline_site_id FunctionId
3556/// "within" IAFunc
3557/// "inlined_at" IAFile IALine [IACol]
3558///
3559/// Introduces a function ID that can be used with .cv_loc. Includes "inlined
3560/// at" source location information for use in the line table of the caller,
3561/// whether the caller is a real function or another inlined call site.
3562bool AsmParser::parseDirectiveCVInlineSiteId() {
3563 SMLoc FunctionIdLoc = getTok().getLoc();
3564 int64_t FunctionId;
3565 int64_t IAFunc;
3566 int64_t IAFile;
3567 int64_t IALine;
3568 int64_t IACol = 0;
3569
3570 // FunctionId
3571 if (parseCVFunctionId(FunctionId, ".cv_inline_site_id"))
3572 return true;
3573
3574 // "within"
3575 if (check((getLexer().isNot(AsmToken::Identifier) ||
3576 getTok().getIdentifier() != "within"),
3577 "expected 'within' identifier in '.cv_inline_site_id' directive"))
3578 return true;
3579 Lex();
3580
3581 // IAFunc
3582 if (parseCVFunctionId(IAFunc, ".cv_inline_site_id"))
3583 return true;
3584
3585 // "inlined_at"
3586 if (check((getLexer().isNot(AsmToken::Identifier) ||
3587 getTok().getIdentifier() != "inlined_at"),
3588 "expected 'inlined_at' identifier in '.cv_inline_site_id' "
3589 "directive") )
3590 return true;
3591 Lex();
3592
3593 // IAFile IALine
3594 if (parseCVFileId(IAFile, ".cv_inline_site_id") ||
3595 parseIntToken(IALine, "expected line number after 'inlined_at'"))
3596 return true;
3597
3598 // [IACol]
3599 if (getLexer().is(AsmToken::Integer)) {
3600 IACol = getTok().getIntVal();
3601 Lex();
3602 }
3603
3604 if (parseToken(AsmToken::EndOfStatement,
3605 "unexpected token in '.cv_inline_site_id' directive"))
3606 return true;
3607
3608 if (!getStreamer().EmitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
3609 IALine, IACol, FunctionIdLoc))
3610 return Error(FunctionIdLoc, "function id already allocated");
3611
3612 return false;
3613}
3614
3615/// parseDirectiveCVLoc
3616/// ::= .cv_loc FunctionId FileNumber [LineNumber] [ColumnPos] [prologue_end]
3617/// [is_stmt VALUE]
3618/// The first number is a file number, must have been previously assigned with
3619/// a .file directive, the second number is the line number and optionally the
3620/// third number is a column position (zero if not specified). The remaining
3621/// optional items are .loc sub-directives.
3622bool AsmParser::parseDirectiveCVLoc() {
3623 SMLoc DirectiveLoc = getTok().getLoc();
3624 int64_t FunctionId, FileNumber;
3625 if (parseCVFunctionId(FunctionId, ".cv_loc") ||
3626 parseCVFileId(FileNumber, ".cv_loc"))
3627 return true;
3628
3629 int64_t LineNumber = 0;
3630 if (getLexer().is(AsmToken::Integer)) {
3631 LineNumber = getTok().getIntVal();
3632 if (LineNumber < 0)
3633 return TokError("line number less than zero in '.cv_loc' directive");
3634 Lex();
3635 }
3636
3637 int64_t ColumnPos = 0;
3638 if (getLexer().is(AsmToken::Integer)) {
3639 ColumnPos = getTok().getIntVal();
3640 if (ColumnPos < 0)
3641 return TokError("column position less than zero in '.cv_loc' directive");
3642 Lex();
3643 }
3644
3645 bool PrologueEnd = false;
3646 uint64_t IsStmt = 0;
3647
3648 auto parseOp = [&]() -> bool {
3649 StringRef Name;
3650 SMLoc Loc = getTok().getLoc();
3651 if (parseIdentifier(Name))
3652 return TokError("unexpected token in '.cv_loc' directive");
3653 if (Name == "prologue_end")
3654 PrologueEnd = true;
3655 else if (Name == "is_stmt") {
3656 Loc = getTok().getLoc();
3657 const MCExpr *Value;
3658 if (parseExpression(Value))
3659 return true;
3660 // The expression must be the constant 0 or 1.
3661 IsStmt = ~0ULL;
3662 if (const auto *MCE = dyn_cast<MCConstantExpr>(Value))
3663 IsStmt = MCE->getValue();
3664
3665 if (IsStmt > 1)
3666 return Error(Loc, "is_stmt value not 0 or 1");
3667 } else {
3668 return Error(Loc, "unknown sub-directive in '.cv_loc' directive");
3669 }
3670 return false;
3671 };
3672
3673 if (parseMany(parseOp, false /*hasComma*/))
3674 return true;
3675
3676 getStreamer().EmitCVLocDirective(FunctionId, FileNumber, LineNumber,
3677 ColumnPos, PrologueEnd, IsStmt, StringRef(),
3678 DirectiveLoc);
3679 return false;
3680}
3681
3682/// parseDirectiveCVLinetable
3683/// ::= .cv_linetable FunctionId, FnStart, FnEnd
3684bool AsmParser::parseDirectiveCVLinetable() {
3685 int64_t FunctionId;
3686 StringRef FnStartName, FnEndName;
3687 SMLoc Loc = getTok().getLoc();
3688 if (parseCVFunctionId(FunctionId, ".cv_linetable") ||
3689 parseToken(AsmToken::Comma,
3690 "unexpected token in '.cv_linetable' directive") ||
3691 parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
3692 "expected identifier in directive") ||
3693 parseToken(AsmToken::Comma,
3694 "unexpected token in '.cv_linetable' directive") ||
3695 parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
3696 "expected identifier in directive"))
3697 return true;
3698
3699 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
3700 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
3701
3702 getStreamer().EmitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym);
3703 return false;
3704}
3705
3706/// parseDirectiveCVInlineLinetable
3707/// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart FnEnd
3708bool AsmParser::parseDirectiveCVInlineLinetable() {
3709 int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
3710 StringRef FnStartName, FnEndName;
3711 SMLoc Loc = getTok().getLoc();
3712 if (parseCVFunctionId(PrimaryFunctionId, ".cv_inline_linetable") ||
3713 parseTokenLoc(Loc) ||
3714 parseIntToken(
3715 SourceFileId,
3716 "expected SourceField in '.cv_inline_linetable' directive") ||
3717 check(SourceFileId <= 0, Loc,
3718 "File id less than zero in '.cv_inline_linetable' directive") ||
3719 parseTokenLoc(Loc) ||
3720 parseIntToken(
3721 SourceLineNum,
3722 "expected SourceLineNum in '.cv_inline_linetable' directive") ||
3723 check(SourceLineNum < 0, Loc,
3724 "Line number less than zero in '.cv_inline_linetable' directive") ||
3725 parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
3726 "expected identifier in directive") ||
3727 parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
3728 "expected identifier in directive"))
3729 return true;
3730
3731 if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
3732 return true;
3733
3734 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
3735 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
3736 getStreamer().EmitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
3737 SourceLineNum, FnStartSym,
3738 FnEndSym);
3739 return false;
3740}
3741
3742/// parseDirectiveCVDefRange
3743/// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes*
3744bool AsmParser::parseDirectiveCVDefRange() {
3745 SMLoc Loc;
3746 std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;
3747 while (getLexer().is(AsmToken::Identifier)) {
3748 Loc = getLexer().getLoc();
3749 StringRef GapStartName;
3750 if (parseIdentifier(GapStartName))
3751 return Error(Loc, "expected identifier in directive");
3752 MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
3753
3754 Loc = getLexer().getLoc();
3755 StringRef GapEndName;
3756 if (parseIdentifier(GapEndName))
3757 return Error(Loc, "expected identifier in directive");
3758 MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
3759
3760 Ranges.push_back({GapStartSym, GapEndSym});
3761 }
3762
3763 std::string FixedSizePortion;
3764 if (parseToken(AsmToken::Comma, "unexpected token in directive") ||
3765 parseEscapedString(FixedSizePortion))
3766 return true;
3767
3768 getStreamer().EmitCVDefRangeDirective(Ranges, FixedSizePortion);
3769 return false;
3770}
3771
3772/// parseDirectiveCVStringTable
3773/// ::= .cv_stringtable
3774bool AsmParser::parseDirectiveCVStringTable() {
3775 getStreamer().EmitCVStringTableDirective();
3776 return false;
3777}
3778
3779/// parseDirectiveCVFileChecksums
3780/// ::= .cv_filechecksums
3781bool AsmParser::parseDirectiveCVFileChecksums() {
3782 getStreamer().EmitCVFileChecksumsDirective();
3783 return false;
3784}
3785
3786/// parseDirectiveCVFileChecksumOffset
3787/// ::= .cv_filechecksumoffset fileno
3788bool AsmParser::parseDirectiveCVFileChecksumOffset() {
3789 int64_t FileNo;
3790 if (parseIntToken(FileNo, "expected identifier in directive"))
3791 return true;
3792 if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
3793 return true;
3794 getStreamer().EmitCVFileChecksumOffsetDirective(FileNo);
3795 return false;
3796}
3797
3798/// parseDirectiveCVFPOData
3799/// ::= .cv_fpo_data procsym
3800bool AsmParser::parseDirectiveCVFPOData() {
3801 SMLoc DirLoc = getLexer().getLoc();
3802 StringRef ProcName;
3803 if (parseIdentifier(ProcName))
3804 return TokError("expected symbol name");
3805 if (parseEOL("unexpected tokens"))
3806 return addErrorSuffix(" in '.cv_fpo_data' directive");
3807 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
3808 getStreamer().EmitCVFPOData(ProcSym, DirLoc);
3809 return false;
3810}
3811
3812/// parseDirectiveCFISections
3813/// ::= .cfi_sections section [, section]
3814bool AsmParser::parseDirectiveCFISections() {
3815 StringRef Name;
3816 bool EH = false;
3817 bool Debug = false;
3818
3819 if (parseIdentifier(Name))
3820 return TokError("Expected an identifier");
3821
3822 if (Name == ".eh_frame")
3823 EH = true;
3824 else if (Name == ".debug_frame")
3825 Debug = true;
3826
3827 if (getLexer().is(AsmToken::Comma)) {
3828 Lex();
3829
3830 if (parseIdentifier(Name))
3831 return TokError("Expected an identifier");
3832
3833 if (Name == ".eh_frame")
3834 EH = true;
3835 else if (Name == ".debug_frame")
3836 Debug = true;
3837 }
3838
3839 getStreamer().EmitCFISections(EH, Debug);
3840 return false;
3841}
3842
3843/// parseDirectiveCFIStartProc
3844/// ::= .cfi_startproc [simple]
3845bool AsmParser::parseDirectiveCFIStartProc() {
3846 StringRef Simple;
3847 if (!parseOptionalToken(AsmToken::EndOfStatement)) {
3848 if (check(parseIdentifier(Simple) || Simple != "simple",
3849 "unexpected token") ||
3850 parseToken(AsmToken::EndOfStatement))
3851 return addErrorSuffix(" in '.cfi_startproc' directive");
3852 }
3853
3854 getStreamer().EmitCFIStartProc(!Simple.empty());
3855 return false;
3856}
3857
3858/// parseDirectiveCFIEndProc
3859/// ::= .cfi_endproc
3860bool AsmParser::parseDirectiveCFIEndProc() {
3861 getStreamer().EmitCFIEndProc();
3862 return false;
3863}
3864
3865/// \brief parse register name or number.
3866bool AsmParser::parseRegisterOrRegisterNumber(int64_t &Register,
3867 SMLoc DirectiveLoc) {
3868 unsigned RegNo;
3869
3870 if (getLexer().isNot(AsmToken::Integer)) {
3871 if (getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc))
3872 return true;
3873 Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true);
3874 } else
3875 return parseAbsoluteExpression(Register);
3876
3877 return false;
3878}
3879
3880/// parseDirectiveCFIDefCfa
3881/// ::= .cfi_def_cfa register, offset
3882bool AsmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
3883 int64_t Register = 0, Offset = 0;
3884 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
3885 parseToken(AsmToken::Comma, "unexpected token in directive") ||
3886 parseAbsoluteExpression(Offset))
3887 return true;
3888
3889 getStreamer().EmitCFIDefCfa(Register, Offset);
3890 return false;
3891}
3892
3893/// parseDirectiveCFIDefCfaOffset
3894/// ::= .cfi_def_cfa_offset offset
3895bool AsmParser::parseDirectiveCFIDefCfaOffset() {
3896 int64_t Offset = 0;
3897 if (parseAbsoluteExpression(Offset))
3898 return true;
3899
3900 getStreamer().EmitCFIDefCfaOffset(Offset);
3901 return false;
3902}
3903
3904/// parseDirectiveCFIRegister
3905/// ::= .cfi_register register, register
3906bool AsmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
3907 int64_t Register1 = 0, Register2 = 0;
3908 if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) ||
3909 parseToken(AsmToken::Comma, "unexpected token in directive") ||
3910 parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
3911 return true;
3912
3913 getStreamer().EmitCFIRegister(Register1, Register2);
3914 return false;
3915}
3916
3917/// parseDirectiveCFIWindowSave
3918/// ::= .cfi_window_save
3919bool AsmParser::parseDirectiveCFIWindowSave() {
3920 getStreamer().EmitCFIWindowSave();
3921 return false;
3922}
3923
3924/// parseDirectiveCFIAdjustCfaOffset
3925/// ::= .cfi_adjust_cfa_offset adjustment
3926bool AsmParser::parseDirectiveCFIAdjustCfaOffset() {
3927 int64_t Adjustment = 0;
3928 if (parseAbsoluteExpression(Adjustment))
3929 return true;
3930
3931 getStreamer().EmitCFIAdjustCfaOffset(Adjustment);
3932 return false;
3933}
3934
3935/// parseDirectiveCFIDefCfaRegister
3936/// ::= .cfi_def_cfa_register register
3937bool AsmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) {
3938 int64_t Register = 0;
3939 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
3940 return true;
3941
3942 getStreamer().EmitCFIDefCfaRegister(Register);
3943 return false;
3944}
3945
3946/// parseDirectiveCFIOffset
3947/// ::= .cfi_offset register, offset
3948bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
3949 int64_t Register = 0;
3950 int64_t Offset = 0;
3951
3952 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
3953 parseToken(AsmToken::Comma, "unexpected token in directive") ||
3954 parseAbsoluteExpression(Offset))
3955 return true;
3956
3957 getStreamer().EmitCFIOffset(Register, Offset);
3958 return false;
3959}
3960
3961/// parseDirectiveCFIRelOffset
3962/// ::= .cfi_rel_offset register, offset
3963bool AsmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
3964 int64_t Register = 0, Offset = 0;
3965
3966 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
3967 parseToken(AsmToken::Comma, "unexpected token in directive") ||
3968 parseAbsoluteExpression(Offset))
3969 return true;
3970
3971 getStreamer().EmitCFIRelOffset(Register, Offset);
3972 return false;
3973}
3974
3975static bool isValidEncoding(int64_t Encoding) {
3976 if (Encoding & ~0xff)
3977 return false;
3978
3979 if (Encoding == dwarf::DW_EH_PE_omit)
3980 return true;
3981
3982 const unsigned Format = Encoding & 0xf;
3983 if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 &&
3984 Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 &&
3985 Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 &&
3986 Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed)
3987 return false;
3988
3989 const unsigned Application = Encoding & 0x70;
3990 if (Application != dwarf::DW_EH_PE_absptr &&
3991 Application != dwarf::DW_EH_PE_pcrel)
3992 return false;
3993
3994 return true;
3995}
3996
3997/// parseDirectiveCFIPersonalityOrLsda
3998/// IsPersonality true for cfi_personality, false for cfi_lsda
3999/// ::= .cfi_personality encoding, [symbol_name]
4000/// ::= .cfi_lsda encoding, [symbol_name]
4001bool AsmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
4002 int64_t Encoding = 0;
4003 if (parseAbsoluteExpression(Encoding))
4004 return true;
4005 if (Encoding == dwarf::DW_EH_PE_omit)
4006 return false;
4007
4008 StringRef Name;
4009 if (check(!isValidEncoding(Encoding), "unsupported encoding.") ||
4010 parseToken(AsmToken::Comma, "unexpected token in directive") ||
4011 check(parseIdentifier(Name), "expected identifier in directive"))
4012 return true;
4013
4014 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4015
4016 if (IsPersonality)
4017 getStreamer().EmitCFIPersonality(Sym, Encoding);
4018 else
4019 getStreamer().EmitCFILsda(Sym, Encoding);
4020 return false;
4021}
4022
4023/// parseDirectiveCFIRememberState
4024/// ::= .cfi_remember_state
4025bool AsmParser::parseDirectiveCFIRememberState() {
4026 getStreamer().EmitCFIRememberState();
4027 return false;
4028}
4029
4030/// parseDirectiveCFIRestoreState
4031/// ::= .cfi_remember_state
4032bool AsmParser::parseDirectiveCFIRestoreState() {
4033 getStreamer().EmitCFIRestoreState();
4034 return false;
4035}
4036
4037/// parseDirectiveCFISameValue
4038/// ::= .cfi_same_value register
4039bool AsmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) {
4040 int64_t Register = 0;
4041
4042 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
4043 return true;
4044
4045 getStreamer().EmitCFISameValue(Register);
4046 return false;
4047}
4048
4049/// parseDirectiveCFIRestore
4050/// ::= .cfi_restore register
4051bool AsmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) {
4052 int64_t Register = 0;
4053 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
4054 return true;
4055
4056 getStreamer().EmitCFIRestore(Register);
4057 return false;
4058}
4059
4060/// parseDirectiveCFIEscape
4061/// ::= .cfi_escape expression[,...]
4062bool AsmParser::parseDirectiveCFIEscape() {
4063 std::string Values;
4064 int64_t CurrValue;
4065 if (parseAbsoluteExpression(CurrValue))
4066 return true;
4067
4068 Values.push_back((uint8_t)CurrValue);
4069
4070 while (getLexer().is(AsmToken::Comma)) {
4071 Lex();
4072
4073 if (parseAbsoluteExpression(CurrValue))
4074 return true;
4075
4076 Values.push_back((uint8_t)CurrValue);
4077 }
4078
4079 getStreamer().EmitCFIEscape(Values);
4080 return false;
4081}
4082
4083/// parseDirectiveCFIReturnColumn
4084/// ::= .cfi_return_column register
4085bool AsmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) {
4086 int64_t Register = 0;
4087 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
4088 return true;
4089 getStreamer().EmitCFIReturnColumn(Register);
4090 return false;
4091}
4092
4093/// parseDirectiveCFISignalFrame
4094/// ::= .cfi_signal_frame
4095bool AsmParser::parseDirectiveCFISignalFrame() {
4096 if (parseToken(AsmToken::EndOfStatement,
4097 "unexpected token in '.cfi_signal_frame'"))
4098 return true;
4099
4100 getStreamer().EmitCFISignalFrame();
4101 return false;
4102}
4103
4104/// parseDirectiveCFIUndefined
4105/// ::= .cfi_undefined register
4106bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
4107 int64_t Register = 0;
4108
4109 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
4110 return true;
4111
4112 getStreamer().EmitCFIUndefined(Register);
4113 return false;
4114}
4115
4116/// parseDirectiveAltmacro
4117/// ::= .altmacro
4118/// ::= .noaltmacro
4119bool AsmParser::parseDirectiveAltmacro(StringRef Directive) {
4120 if (getLexer().isNot(AsmToken::EndOfStatement))
4121 return TokError("unexpected token in '" + Directive + "' directive");
4122 if (Directive == ".altmacro")
4123 getLexer().SetAltMacroMode(true);
4124 else
4125 getLexer().SetAltMacroMode(false);
4126 return false;
4127}
4128
4129/// parseDirectiveMacrosOnOff
4130/// ::= .macros_on
4131/// ::= .macros_off
4132bool AsmParser::parseDirectiveMacrosOnOff(StringRef Directive) {
4133 if (parseToken(AsmToken::EndOfStatement,
4134 "unexpected token in '" + Directive + "' directive"))
4135 return true;
4136
4137 setMacrosEnabled(Directive == ".macros_on");
4138 return false;
4139}
4140
4141/// parseDirectiveMacro
4142/// ::= .macro name[,] [parameters]
4143bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
4144 StringRef Name;
4145 if (parseIdentifier(Name))
4146 return TokError("expected identifier in '.macro' directive");
4147
4148 if (getLexer().is(AsmToken::Comma))
4149 Lex();
4150
4151 MCAsmMacroParameters Parameters;
4152 while (getLexer().isNot(AsmToken::EndOfStatement)) {
4153
4154 if (!Parameters.empty() && Parameters.back().Vararg)
4155 return Error(Lexer.getLoc(),
4156 "Vararg parameter '" + Parameters.back().Name +
4157 "' should be last one in the list of parameters.");
4158
4159 MCAsmMacroParameter Parameter;
4160 if (parseIdentifier(Parameter.Name))
4161 return TokError("expected identifier in '.macro' directive");
4162
4163 // Emit an error if two (or more) named parameters share the same name
4164 for (const MCAsmMacroParameter& CurrParam : Parameters)
4165 if (CurrParam.Name.equals(Parameter.Name))
4166 return TokError("macro '" + Name + "' has multiple parameters"
4167 " named '" + Parameter.Name + "'");
4168
4169 if (Lexer.is(AsmToken::Colon)) {
4170 Lex(); // consume ':'
4171
4172 SMLoc QualLoc;
4173 StringRef Qualifier;
4174
4175 QualLoc = Lexer.getLoc();
4176 if (parseIdentifier(Qualifier))
4177 return Error(QualLoc, "missing parameter qualifier for "
4178 "'" + Parameter.Name + "' in macro '" + Name + "'");
4179
4180 if (Qualifier == "req")
4181 Parameter.Required = true;
4182 else if (Qualifier == "vararg")
4183 Parameter.Vararg = true;
4184 else
4185 return Error(QualLoc, Qualifier + " is not a valid parameter qualifier "
4186 "for '" + Parameter.Name + "' in macro '" + Name + "'");
4187 }
4188
4189 if (getLexer().is(AsmToken::Equal)) {
4190 Lex();
4191
4192 SMLoc ParamLoc;
4193
4194 ParamLoc = Lexer.getLoc();
4195 if (parseMacroArgument(Parameter.Value, /*Vararg=*/false ))
4196 return true;
4197
4198 if (Parameter.Required)
4199 Warning(ParamLoc, "pointless default value for required parameter "
4200 "'" + Parameter.Name + "' in macro '" + Name + "'");
4201 }
4202
4203 Parameters.push_back(std::move(Parameter));
4204
4205 if (getLexer().is(AsmToken::Comma))
4206 Lex();
4207 }
4208
4209 // Eat just the end of statement.
4210 Lexer.Lex();
4211
4212 // Consuming deferred text, so use Lexer.Lex to ignore Lexing Errors
4213 AsmToken EndToken, StartToken = getTok();
4214 unsigned MacroDepth = 0;
4215 // Lex the macro definition.
4216 while (true) {
4217 // Ignore Lexing errors in macros.
4218 while (Lexer.is(AsmToken::Error)) {
4219 Lexer.Lex();
4220 }
4221
4222 // Check whether we have reached the end of the file.
4223 if (getLexer().is(AsmToken::Eof))
4224 return Error(DirectiveLoc, "no matching '.endmacro' in definition");
4225
4226 // Otherwise, check whether we have reach the .endmacro.
4227 if (getLexer().is(AsmToken::Identifier)) {
4228 if (getTok().getIdentifier() == ".endm" ||
4229 getTok().getIdentifier() == ".endmacro") {
4230 if (MacroDepth == 0) { // Outermost macro.
4231 EndToken = getTok();
4232 Lexer.Lex();
4233 if (getLexer().isNot(AsmToken::EndOfStatement))
4234 return TokError("unexpected token in '" + EndToken.getIdentifier() +
4235 "' directive");
4236 break;
4237 } else {
4238 // Otherwise we just found the end of an inner macro.
4239 --MacroDepth;
4240 }
4241 } else if (getTok().getIdentifier() == ".macro") {
4242 // We allow nested macros. Those aren't instantiated until the outermost
4243 // macro is expanded so just ignore them for now.
4244 ++MacroDepth;
4245 }
4246 }
4247
4248 // Otherwise, scan til the end of the statement.
4249 eatToEndOfStatement();
4250 }
4251
4252 if (getContext().lookupMacro(Name)) {
4253 return Error(DirectiveLoc, "macro '" + Name + "' is already defined");
4254 }
4255
4256 const char *BodyStart = StartToken.getLoc().getPointer();
4257 const char *BodyEnd = EndToken.getLoc().getPointer();
4258 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
4259 checkForBadMacro(DirectiveLoc, Name, Body, Parameters);
4260 MCAsmMacro Macro(Name, Body, std::move(Parameters));
4261 DEBUG_WITH_TYPE("asm-macros", dbgs() << "Defining new macro:\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("asm-macros")) { dbgs() << "Defining new macro:\n"; Macro
.dump(); } } while (false)
4262 Macro.dump())do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("asm-macros")) { dbgs() << "Defining new macro:\n"; Macro
.dump(); } } while (false)
;
4263 getContext().defineMacro(Name, std::move(Macro));
4264 return false;
4265}
4266
4267/// checkForBadMacro
4268///
4269/// With the support added for named parameters there may be code out there that
4270/// is transitioning from positional parameters. In versions of gas that did
4271/// not support named parameters they would be ignored on the macro definition.
4272/// But to support both styles of parameters this is not possible so if a macro
4273/// definition has named parameters but does not use them and has what appears
4274/// to be positional parameters, strings like $1, $2, ... and $n, then issue a
4275/// warning that the positional parameter found in body which have no effect.
4276/// Hoping the developer will either remove the named parameters from the macro
4277/// definition so the positional parameters get used if that was what was
4278/// intended or change the macro to use the named parameters. It is possible
4279/// this warning will trigger when the none of the named parameters are used
4280/// and the strings like $1 are infact to simply to be passed trough unchanged.
4281void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
4282 StringRef Body,
4283 ArrayRef<MCAsmMacroParameter> Parameters) {
4284 // If this macro is not defined with named parameters the warning we are
4285 // checking for here doesn't apply.
4286 unsigned NParameters = Parameters.size();
4287 if (NParameters == 0)
4288 return;
4289
4290 bool NamedParametersFound = false;
4291 bool PositionalParametersFound = false;
4292
4293 // Look at the body of the macro for use of both the named parameters and what
4294 // are likely to be positional parameters. This is what expandMacro() is
4295 // doing when it finds the parameters in the body.
4296 while (!Body.empty()) {
4297 // Scan for the next possible parameter.
4298 std::size_t End = Body.size(), Pos = 0;
4299 for (; Pos != End; ++Pos) {
4300 // Check for a substitution or escape.
4301 // This macro is defined with parameters, look for \foo, \bar, etc.
4302 if (Body[Pos] == '\\' && Pos + 1 != End)
4303 break;
4304
4305 // This macro should have parameters, but look for $0, $1, ..., $n too.
4306 if (Body[Pos] != '$' || Pos + 1 == End)
4307 continue;
4308 char Next = Body[Pos + 1];
4309 if (Next == '$' || Next == 'n' ||
4310 isdigit(static_cast<unsigned char>(Next)))
4311 break;
4312 }
4313
4314 // Check if we reached the end.
4315 if (Pos == End)
4316 break;
4317
4318 if (Body[Pos] == '$') {
4319 switch (Body[Pos + 1]) {
4320 // $$ => $
4321 case '$':
4322 break;
4323
4324 // $n => number of arguments
4325 case 'n':
4326 PositionalParametersFound = true;
4327 break;
4328
4329 // $[0-9] => argument
4330 default: {
4331 PositionalParametersFound = true;
4332 break;
4333 }
4334 }
4335 Pos += 2;
4336 } else {
4337 unsigned I = Pos + 1;
4338 while (isIdentifierChar(Body[I]) && I + 1 != End)
4339 ++I;
4340
4341 const char *Begin = Body.data() + Pos + 1;
4342 StringRef Argument(Begin, I - (Pos + 1));
4343 unsigned Index = 0;
4344 for (; Index < NParameters; ++Index)
4345 if (Parameters[Index].Name == Argument)
4346 break;
4347
4348 if (Index == NParameters) {
4349 if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
4350 Pos += 3;
4351 else {
4352 Pos = I;
4353 }
4354 } else {
4355 NamedParametersFound = true;
4356 Pos += 1 + Argument.size();
4357 }
4358 }
4359 // Update the scan point.
4360 Body = Body.substr(Pos);
4361 }
4362
4363 if (!NamedParametersFound && PositionalParametersFound)
4364 Warning(DirectiveLoc, "macro defined with named parameters which are not "
4365 "used in macro body, possible positional parameter "
4366 "found in body which will have no effect");
4367}
4368
4369/// parseDirectiveExitMacro
4370/// ::= .exitm
4371bool AsmParser::parseDirectiveExitMacro(StringRef Directive) {
4372 if (parseToken(AsmToken::EndOfStatement,
4373 "unexpected token in '" + Directive + "' directive"))
4374 return true;
4375
4376 if (!isInsideMacroInstantiation())
4377 return TokError("unexpected '" + Directive + "' in file, "
4378 "no current macro definition");
4379
4380 // Exit all conditionals that are active in the current macro.
4381 while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
4382 TheCondState = TheCondStack.back();
4383 TheCondStack.pop_back();
4384 }
4385
4386 handleMacroExit();
4387 return false;
4388}
4389
4390/// parseDirectiveEndMacro
4391/// ::= .endm
4392/// ::= .endmacro
4393bool AsmParser::parseDirectiveEndMacro(StringRef Directive) {
4394 if (getLexer().isNot(AsmToken::EndOfStatement))
4395 return TokError("unexpected token in '" + Directive + "' directive");
4396
4397 // If we are inside a macro instantiation, terminate the current
4398 // instantiation.
4399 if (isInsideMacroInstantiation()) {
4400 handleMacroExit();
4401 return false;
4402 }
4403
4404 // Otherwise, this .endmacro is a stray entry in the file; well formed
4405 // .endmacro directives are handled during the macro definition parsing.
4406 return TokError("unexpected '" + Directive + "' in file, "
4407 "no current macro definition");
4408}
4409
4410/// parseDirectivePurgeMacro
4411/// ::= .purgem
4412bool AsmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
4413 StringRef Name;
4414 SMLoc Loc;
4415 if (parseTokenLoc(Loc) ||
4416 check(parseIdentifier(Name), Loc,
4417 "expected identifier in '.purgem' directive") ||
4418 parseToken(AsmToken::EndOfStatement,
4419 "unexpected token in '.purgem' directive"))
4420 return true;
4421
4422 if (!getContext().lookupMacro(Name))
4423 return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
4424
4425 getContext().undefineMacro(Name);
4426 DEBUG_WITH_TYPE("asm-macros", dbgs()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("asm-macros")) { dbgs() << "Un-defining macro: " <<
Name << "\n"; } } while (false)
4427 << "Un-defining macro: " << Name << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("asm-macros")) { dbgs() << "Un-defining macro: " <<
Name << "\n"; } } while (false)
;
4428 return false;
4429}
4430
4431/// parseDirectiveBundleAlignMode
4432/// ::= {.bundle_align_mode} expression
4433bool AsmParser::parseDirectiveBundleAlignMode() {
4434 // Expect a single argument: an expression that evaluates to a constant
4435 // in the inclusive range 0-30.
4436 SMLoc ExprLoc = getLexer().getLoc();
4437 int64_t AlignSizePow2;
4438 if (checkForValidSection() || parseAbsoluteExpression(AlignSizePow2) ||
4439 parseToken(AsmToken::EndOfStatement, "unexpected token after expression "
4440 "in '.bundle_align_mode' "
4441 "directive") ||
4442 check(AlignSizePow2 < 0 || AlignSizePow2 > 30, ExprLoc,
4443 "invalid bundle alignment size (expected between 0 and 30)"))
4444 return true;
4445
4446 // Because of AlignSizePow2's verified range we can safely truncate it to
4447 // unsigned.
4448 getStreamer().EmitBundleAlignMode(static_cast<unsigned>(AlignSizePow2));
4449 return false;
4450}
4451
4452/// parseDirectiveBundleLock
4453/// ::= {.bundle_lock} [align_to_end]
4454bool AsmParser::parseDirectiveBundleLock() {
4455 if (checkForValidSection())
4456 return true;
4457 bool AlignToEnd = false;
4458
4459 StringRef Option;
4460 SMLoc Loc = getTok().getLoc();
4461 const char *kInvalidOptionError =
4462 "invalid option for '.bundle_lock' directive";
4463
4464 if (!parseOptionalToken(AsmToken::EndOfStatement)) {
4465 if (check(parseIdentifier(Option), Loc, kInvalidOptionError) ||
4466 check(Option != "align_to_end", Loc, kInvalidOptionError) ||
4467 parseToken(AsmToken::EndOfStatement,
4468 "unexpected token after '.bundle_lock' directive option"))
4469 return true;
4470 AlignToEnd = true;
4471 }
4472
4473 getStreamer().EmitBundleLock(AlignToEnd);
4474 return false;
4475}
4476
4477/// parseDirectiveBundleLock
4478/// ::= {.bundle_lock}
4479bool AsmParser::parseDirectiveBundleUnlock() {
4480 if (checkForValidSection() ||
4481 parseToken(AsmToken::EndOfStatement,
4482 "unexpected token in '.bundle_unlock' directive"))
4483 return true;
4484
4485 getStreamer().EmitBundleUnlock();
4486 return false;
4487}
4488
4489/// parseDirectiveSpace
4490/// ::= (.skip | .space) expression [ , expression ]
4491bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
4492 SMLoc NumBytesLoc = Lexer.getLoc();
4493 const MCExpr *NumBytes;
4494 if (checkForValidSection() || parseExpression(NumBytes))
4495 return true;
4496
4497 int64_t FillExpr = 0;
4498 if (parseOptionalToken(AsmToken::Comma))
4499 if (parseAbsoluteExpression(FillExpr))
4500 return addErrorSuffix("in '" + Twine(IDVal) + "' directive");
4501 if (parseToken(AsmToken::EndOfStatement))
4502 return addErrorSuffix("in '" + Twine(IDVal) + "' directive");
4503
4504 // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
4505 getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
4506
4507 return false;
4508}
4509
4510/// parseDirectiveDCB
4511/// ::= .dcb.{b, l, w} expression, expression
4512bool AsmParser::parseDirectiveDCB(StringRef IDVal, unsigned Size) {
4513 SMLoc NumValuesLoc = Lexer.getLoc();
4514 int64_t NumValues;
4515 if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4516 return true;
4517
4518 if (NumValues < 0) {
4519 Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
4520 return false;
4521 }
4522
4523 if (parseToken(AsmToken::Comma,
4524 "unexpected token in '" + Twine(IDVal) + "' directive"))
4525 return true;
4526
4527 const MCExpr *Value;
4528 SMLoc ExprLoc = getLexer().getLoc();
4529 if (parseExpression(Value))
4530 return true;
4531
4532 // Special case constant expressions to match code generator.
4533 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
4534 assert(Size <= 8 && "Invalid size")(static_cast <bool> (Size <= 8 && "Invalid size"
) ? void (0) : __assert_fail ("Size <= 8 && \"Invalid size\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 4534, __extension__ __PRETTY_FUNCTION__))
;
4535 uint64_t IntValue = MCE->getValue();
4536 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
4537 return Error(ExprLoc, "literal value out of range for directive");
4538 for (uint64_t i = 0, e = NumValues; i != e; ++i)
4539 getStreamer().EmitIntValue(IntValue, Size);
4540 } else {
4541 for (uint64_t i = 0, e = NumValues; i != e; ++i)
4542 getStreamer().EmitValue(Value, Size, ExprLoc);
4543 }
4544
4545 if (parseToken(AsmToken::EndOfStatement,
4546 "unexpected token in '" + Twine(IDVal) + "' directive"))
4547 return true;
4548
4549 return false;
4550}
4551
4552/// parseDirectiveRealDCB
4553/// ::= .dcb.{d, s} expression, expression
4554bool AsmParser::parseDirectiveRealDCB(StringRef IDVal, const fltSemantics &Semantics) {
4555 SMLoc NumValuesLoc = Lexer.getLoc();
4556 int64_t NumValues;
4557 if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4558 return true;
4559
4560 if (NumValues < 0) {
4561 Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
4562 return false;
4563 }
4564
4565 if (parseToken(AsmToken::Comma,
4566 "unexpected token in '" + Twine(IDVal) + "' directive"))
4567 return true;
4568
4569 APInt AsInt;
4570 if (parseRealValue(Semantics, AsInt))
4571 return true;
4572
4573 if (parseToken(AsmToken::EndOfStatement,
4574 "unexpected token in '" + Twine(IDVal) + "' directive"))
4575 return true;
4576
4577 for (uint64_t i = 0, e = NumValues; i != e; ++i)
4578 getStreamer().EmitIntValue(AsInt.getLimitedValue(),
4579 AsInt.getBitWidth() / 8);
4580
4581 return false;
4582}
4583
4584/// parseDirectiveDS
4585/// ::= .ds.{b, d, l, p, s, w, x} expression
4586bool AsmParser::parseDirectiveDS(StringRef IDVal, unsigned Size) {
4587 SMLoc NumValuesLoc = Lexer.getLoc();
4588 int64_t NumValues;
4589 if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4590 return true;
4591
4592 if (NumValues < 0) {
4593 Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
4594 return false;
4595 }
4596
4597 if (parseToken(AsmToken::EndOfStatement,
4598 "unexpected token in '" + Twine(IDVal) + "' directive"))
4599 return true;
4600
4601 for (uint64_t i = 0, e = NumValues; i != e; ++i)
4602 getStreamer().emitFill(Size, 0);
4603
4604 return false;
4605}
4606
4607/// parseDirectiveLEB128
4608/// ::= (.sleb128 | .uleb128) [ expression (, expression)* ]
4609bool AsmParser::parseDirectiveLEB128(bool Signed) {
4610 if (checkForValidSection())
4611 return true;
4612
4613 auto parseOp = [&]() -> bool {
4614 const MCExpr *Value;
4615 if (parseExpression(Value))
4616 return true;
4617 if (Signed)
4618 getStreamer().EmitSLEB128Value(Value);
4619 else
4620 getStreamer().EmitULEB128Value(Value);
4621 return false;
4622 };
4623
4624 if (parseMany(parseOp))
4625 return addErrorSuffix(" in directive");
4626
4627 return false;
4628}
4629
4630/// parseDirectiveSymbolAttribute
4631/// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
4632bool AsmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
4633 auto parseOp = [&]() -> bool {
4634 StringRef Name;
4635 SMLoc Loc = getTok().getLoc();
4636 if (parseIdentifier(Name))
4637 return Error(Loc, "expected identifier");
4638 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4639
4640 // Assembler local symbols don't make any sense here. Complain loudly.
4641 if (Sym->isTemporary())
4642 return Error(Loc, "non-local symbol required");
4643
4644 if (!getStreamer().EmitSymbolAttribute(Sym, Attr))
4645 return Error(Loc, "unable to emit symbol attribute");
4646 return false;
4647 };
4648
4649 if (parseMany(parseOp))
4650 return addErrorSuffix(" in directive");
4651 return false;
4652}
4653
4654/// parseDirectiveComm
4655/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
4656bool AsmParser::parseDirectiveComm(bool IsLocal) {
4657 if (checkForValidSection())
4658 return true;
4659
4660 SMLoc IDLoc = getLexer().getLoc();
4661 StringRef Name;
4662 if (parseIdentifier(Name))
4663 return TokError("expected identifier in directive");
4664
4665 // Handle the identifier as the key symbol.
4666 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4667
4668 if (getLexer().isNot(AsmToken::Comma))
4669 return TokError("unexpected token in directive");
4670 Lex();
4671
4672 int64_t Size;
4673 SMLoc SizeLoc = getLexer().getLoc();
4674 if (parseAbsoluteExpression(Size))
4675 return true;
4676
4677 int64_t Pow2Alignment = 0;
4678 SMLoc Pow2AlignmentLoc;
4679 if (getLexer().is(AsmToken::Comma)) {
4680 Lex();
4681 Pow2AlignmentLoc = getLexer().getLoc();
4682 if (parseAbsoluteExpression(Pow2Alignment))
4683 return true;
4684
4685 LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType();
4686 if (IsLocal && LCOMM == LCOMM::NoAlignment)
4687 return Error(Pow2AlignmentLoc, "alignment not supported on this target");
4688
4689 // If this target takes alignments in bytes (not log) validate and convert.
4690 if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
4691 (IsLocal && LCOMM == LCOMM::ByteAlignment)) {
4692 if (!isPowerOf2_64(Pow2Alignment))
4693 return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
4694 Pow2Alignment = Log2_64(Pow2Alignment);
4695 }
4696 }
4697
4698 if (parseToken(AsmToken::EndOfStatement,
4699 "unexpected token in '.comm' or '.lcomm' directive"))
4700 return true;
4701
4702 // NOTE: a size of zero for a .comm should create a undefined symbol
4703 // but a size of .lcomm creates a bss symbol of size zero.
4704 if (Size < 0)
4705 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
4706 "be less than zero");
4707
4708 // NOTE: The alignment in the directive is a power of 2 value, the assembler
4709 // may internally end up wanting an alignment in bytes.
4710 // FIXME: Diagnose overflow.
4711 if (Pow2Alignment < 0)
4712 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
4713 "alignment, can't be less than zero");
4714
4715 Sym->redefineIfPossible();
4716 if (!Sym->isUndefined())
4717 return Error(IDLoc, "invalid symbol redefinition");
4718
4719 // Create the Symbol as a common or local common with Size and Pow2Alignment
4720 if (IsLocal) {
4721 getStreamer().EmitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment);
4722 return false;
4723 }
4724
4725 getStreamer().EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
4726 return false;
4727}
4728
4729/// parseDirectiveAbort
4730/// ::= .abort [... message ...]
4731bool AsmParser::parseDirectiveAbort() {
4732 // FIXME: Use loc from directive.
4733 SMLoc Loc = getLexer().getLoc();
4734
4735 StringRef Str = parseStringToEndOfStatement();
4736 if (parseToken(AsmToken::EndOfStatement,
4737 "unexpected token in '.abort' directive"))
4738 return true;
4739
4740 if (Str.empty())
4741 return Error(Loc, ".abort detected. Assembly stopping.");
4742 else
4743 return Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
4744 // FIXME: Actually abort assembly here.
4745
4746 return false;
4747}
4748
4749/// parseDirectiveInclude
4750/// ::= .include "filename"
4751bool AsmParser::parseDirectiveInclude() {
4752 // Allow the strings to have escaped octal character sequence.
4753 std::string Filename;
4754 SMLoc IncludeLoc = getTok().getLoc();
4755
4756 if (check(getTok().isNot(AsmToken::String),
4757 "expected string in '.include' directive") ||
4758 parseEscapedString(Filename) ||
4759 check(getTok().isNot(AsmToken::EndOfStatement),
4760 "unexpected token in '.include' directive") ||
4761 // Attempt to switch the lexer to the included file before consuming the
4762 // end of statement to avoid losing it when we switch.
4763 check(enterIncludeFile(Filename), IncludeLoc,
4764 "Could not find include file '" + Filename + "'"))
4765 return true;
4766
4767 return false;
4768}
4769
4770/// parseDirectiveIncbin
4771/// ::= .incbin "filename" [ , skip [ , count ] ]
4772bool AsmParser::parseDirectiveIncbin() {
4773 // Allow the strings to have escaped octal character sequence.
4774 std::string Filename;
4775 SMLoc IncbinLoc = getTok().getLoc();
4776 if (check(getTok().isNot(AsmToken::String),
4777 "expected string in '.incbin' directive") ||
4778 parseEscapedString(Filename))
4779 return true;
4780
4781 int64_t Skip = 0;
4782 const MCExpr *Count = nullptr;
4783 SMLoc SkipLoc, CountLoc;
4784 if (parseOptionalToken(AsmToken::Comma)) {
4785 // The skip expression can be omitted while specifying the count, e.g:
4786 // .incbin "filename",,4
4787 if (getTok().isNot(AsmToken::Comma)) {
4788 if (parseTokenLoc(SkipLoc) || parseAbsoluteExpression(Skip))
4789 return true;
4790 }
4791 if (parseOptionalToken(AsmToken::Comma)) {
4792 CountLoc = getTok().getLoc();
4793 if (parseExpression(Count))
4794 return true;
4795 }
4796 }
4797
4798 if (parseToken(AsmToken::EndOfStatement,
4799 "unexpected token in '.incbin' directive"))
4800 return true;
4801
4802 if (check(Skip < 0, SkipLoc, "skip is negative"))
4803 return true;
4804
4805 // Attempt to process the included file.
4806 if (processIncbinFile(Filename, Skip, Count, CountLoc))
4807 return Error(IncbinLoc, "Could not find incbin file '" + Filename + "'");
4808 return false;
4809}
4810
4811/// parseDirectiveIf
4812/// ::= .if{,eq,ge,gt,le,lt,ne} expression
4813bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
4814 TheCondStack.push_back(TheCondState);
4815 TheCondState.TheCond = AsmCond::IfCond;
4816 if (TheCondState.Ignore) {
4817 eatToEndOfStatement();
4818 } else {
4819 int64_t ExprValue;
4820 if (parseAbsoluteExpression(ExprValue) ||
4821 parseToken(AsmToken::EndOfStatement,
4822 "unexpected token in '.if' directive"))
4823 return true;
4824
4825 switch (DirKind) {
4826 default:
4827 llvm_unreachable("unsupported directive")::llvm::llvm_unreachable_internal("unsupported directive", "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 4827)
;
4828 case DK_IF:
4829 case DK_IFNE:
4830 break;
4831 case DK_IFEQ:
4832 ExprValue = ExprValue == 0;
4833 break;
4834 case DK_IFGE:
4835 ExprValue = ExprValue >= 0;
4836 break;
4837 case DK_IFGT:
4838 ExprValue = ExprValue > 0;
4839 break;
4840 case DK_IFLE:
4841 ExprValue = ExprValue <= 0;
4842 break;
4843 case DK_IFLT:
4844 ExprValue = ExprValue < 0;
4845 break;
4846 }
4847
4848 TheCondState.CondMet = ExprValue;
4849 TheCondState.Ignore = !TheCondState.CondMet;
4850 }
4851
4852 return false;
4853}
4854
4855/// parseDirectiveIfb
4856/// ::= .ifb string
4857bool AsmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
4858 TheCondStack.push_back(TheCondState);
4859 TheCondState.TheCond = AsmCond::IfCond;
4860
4861 if (TheCondState.Ignore) {
4862 eatToEndOfStatement();
4863 } else {
4864 StringRef Str = parseStringToEndOfStatement();
4865
4866 if (parseToken(AsmToken::EndOfStatement,
4867 "unexpected token in '.ifb' directive"))
4868 return true;
4869
4870 TheCondState.CondMet = ExpectBlank == Str.empty();
4871 TheCondState.Ignore = !TheCondState.CondMet;
4872 }
4873
4874 return false;
4875}
4876
4877/// parseDirectiveIfc
4878/// ::= .ifc string1, string2
4879/// ::= .ifnc string1, string2
4880bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
4881 TheCondStack.push_back(TheCondState);
4882 TheCondState.TheCond = AsmCond::IfCond;
4883
4884 if (TheCondState.Ignore) {
4885 eatToEndOfStatement();
4886 } else {
4887 StringRef Str1 = parseStringToComma();
4888
4889 if (parseToken(AsmToken::Comma, "unexpected token in '.ifc' directive"))
4890 return true;
4891
4892 StringRef Str2 = parseStringToEndOfStatement();
4893
4894 if (parseToken(AsmToken::EndOfStatement,
4895 "unexpected token in '.ifc' directive"))
4896 return true;
4897
4898 TheCondState.CondMet = ExpectEqual == (Str1.trim() == Str2.trim());
4899 TheCondState.Ignore = !TheCondState.CondMet;
4900 }
4901
4902 return false;
4903}
4904
4905/// parseDirectiveIfeqs
4906/// ::= .ifeqs string1, string2
4907bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual) {
4908 if (Lexer.isNot(AsmToken::String)) {
4909 if (ExpectEqual)
4910 return TokError("expected string parameter for '.ifeqs' directive");
4911 return TokError("expected string parameter for '.ifnes' directive");
4912 }
4913
4914 StringRef String1 = getTok().getStringContents();
4915 Lex();
4916
4917 if (Lexer.isNot(AsmToken::Comma)) {
4918 if (ExpectEqual)
4919 return TokError(
4920 "expected comma after first string for '.ifeqs' directive");
4921 return TokError("expected comma after first string for '.ifnes' directive");
4922 }
4923
4924 Lex();
4925
4926 if (Lexer.isNot(AsmToken::String)) {
4927 if (ExpectEqual)
4928 return TokError("expected string parameter for '.ifeqs' directive");
4929 return TokError("expected string parameter for '.ifnes' directive");
4930 }
4931
4932 StringRef String2 = getTok().getStringContents();
4933 Lex();
4934
4935 TheCondStack.push_back(TheCondState);
4936 TheCondState.TheCond = AsmCond::IfCond;
4937 TheCondState.CondMet = ExpectEqual == (String1 == String2);
4938 TheCondState.Ignore = !TheCondState.CondMet;
4939
4940 return false;
4941}
4942
4943/// parseDirectiveIfdef
4944/// ::= .ifdef symbol
4945bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
4946 StringRef Name;
4947 TheCondStack.push_back(TheCondState);
4948 TheCondState.TheCond = AsmCond::IfCond;
4949
4950 if (TheCondState.Ignore) {
4951 eatToEndOfStatement();
4952 } else {
4953 if (check(parseIdentifier(Name), "expected identifier after '.ifdef'") ||
4954 parseToken(AsmToken::EndOfStatement, "unexpected token in '.ifdef'"))
4955 return true;
4956
4957 MCSymbol *Sym = getContext().lookupSymbol(Name);
4958
4959 if (expect_defined)
4960 TheCondState.CondMet = (Sym && !Sym->isUndefined());
4961 else
4962 TheCondState.CondMet = (!Sym || Sym->isUndefined());
4963 TheCondState.Ignore = !TheCondState.CondMet;
4964 }
4965
4966 return false;
4967}
4968
4969/// parseDirectiveElseIf
4970/// ::= .elseif expression
4971bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) {
4972 if (TheCondState.TheCond != AsmCond::IfCond &&
4973 TheCondState.TheCond != AsmCond::ElseIfCond)
4974 return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an"
4975 " .if or an .elseif");
4976 TheCondState.TheCond = AsmCond::ElseIfCond;
4977
4978 bool LastIgnoreState = false;
4979 if (!TheCondStack.empty())
4980 LastIgnoreState = TheCondStack.back().Ignore;
4981 if (LastIgnoreState || TheCondState.CondMet) {
4982 TheCondState.Ignore = true;
4983 eatToEndOfStatement();
4984 } else {
4985 int64_t ExprValue;
4986 if (parseAbsoluteExpression(ExprValue))
4987 return true;
4988
4989 if (parseToken(AsmToken::EndOfStatement,
4990 "unexpected token in '.elseif' directive"))
4991 return true;
4992
4993 TheCondState.CondMet = ExprValue;
4994 TheCondState.Ignore = !TheCondState.CondMet;
4995 }
4996
4997 return false;
4998}
4999
5000/// parseDirectiveElse
5001/// ::= .else
5002bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
5003 if (parseToken(AsmToken::EndOfStatement,
5004 "unexpected token in '.else' directive"))
5005 return true;
5006
5007 if (TheCondState.TheCond != AsmCond::IfCond &&
5008 TheCondState.TheCond != AsmCond::ElseIfCond)
5009 return Error(DirectiveLoc, "Encountered a .else that doesn't follow "
5010 " an .if or an .elseif");
5011 TheCondState.TheCond = AsmCond::ElseCond;
5012 bool LastIgnoreState = false;
5013 if (!TheCondStack.empty())
5014 LastIgnoreState = TheCondStack.back().Ignore;
5015 if (LastIgnoreState || TheCondState.CondMet)
5016 TheCondState.Ignore = true;
5017 else
5018 TheCondState.Ignore = false;
5019
5020 return false;
5021}
5022
5023/// parseDirectiveEnd
5024/// ::= .end
5025bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
5026 if (parseToken(AsmToken::EndOfStatement,
5027 "unexpected token in '.end' directive"))
5028 return true;
5029
5030 while (Lexer.isNot(AsmToken::Eof))
5031 Lexer.Lex();
5032
5033 return false;
5034}
5035
5036/// parseDirectiveError
5037/// ::= .err
5038/// ::= .error [string]
5039bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) {
5040 if (!TheCondStack.empty()) {
5041 if (TheCondStack.back().Ignore) {
5042 eatToEndOfStatement();
5043 return false;
5044 }
5045 }
5046
5047 if (!WithMessage)
5048 return Error(L, ".err encountered");
5049
5050 StringRef Message = ".error directive invoked in source file";
5051 if (Lexer.isNot(AsmToken::EndOfStatement)) {
5052 if (Lexer.isNot(AsmToken::String))
5053 return TokError(".error argument must be a string");
5054
5055 Message = getTok().getStringContents();
5056 Lex();
5057 }
5058
5059 return Error(L, Message);
5060}
5061
5062/// parseDirectiveWarning
5063/// ::= .warning [string]
5064bool AsmParser::parseDirectiveWarning(SMLoc L) {
5065 if (!TheCondStack.empty()) {
5066 if (TheCondStack.back().Ignore) {
5067 eatToEndOfStatement();
5068 return false;
5069 }
5070 }
5071
5072 StringRef Message = ".warning directive invoked in source file";
5073
5074 if (!parseOptionalToken(AsmToken::EndOfStatement)) {
5075 if (Lexer.isNot(AsmToken::String))
5076 return TokError(".warning argument must be a string");
5077
5078 Message = getTok().getStringContents();
5079 Lex();
5080 if (parseToken(AsmToken::EndOfStatement,
5081 "expected end of statement in '.warning' directive"))
5082 return true;
5083 }
5084
5085 return Warning(L, Message);
5086}
5087
5088/// parseDirectiveEndIf
5089/// ::= .endif
5090bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
5091 if (parseToken(AsmToken::EndOfStatement,
5092 "unexpected token in '.endif' directive"))
5093 return true;
5094
5095 if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty())
5096 return Error(DirectiveLoc, "Encountered a .endif that doesn't follow "
5097 "an .if or .else");
5098 if (!TheCondStack.empty()) {
5099 TheCondState = TheCondStack.back();
5100 TheCondStack.pop_back();
5101 }
5102
5103 return false;
5104}
5105
5106void AsmParser::initializeDirectiveKindMap() {
5107 DirectiveKindMap[".set"] = DK_SET;
5108 DirectiveKindMap[".equ"] = DK_EQU;
5109 DirectiveKindMap[".equiv"] = DK_EQUIV;
5110 DirectiveKindMap[".ascii"] = DK_ASCII;
5111 DirectiveKindMap[".asciz"] = DK_ASCIZ;
5112 DirectiveKindMap[".string"] = DK_STRING;
5113 DirectiveKindMap[".byte"] = DK_BYTE;
5114 DirectiveKindMap[".short"] = DK_SHORT;
5115 DirectiveKindMap[".value"] = DK_VALUE;
5116 DirectiveKindMap[".2byte"] = DK_2BYTE;
5117 DirectiveKindMap[".long"] = DK_LONG;
5118 DirectiveKindMap[".int"] = DK_INT;
5119 DirectiveKindMap[".4byte"] = DK_4BYTE;
5120 DirectiveKindMap[".quad"] = DK_QUAD;
5121 DirectiveKindMap[".8byte"] = DK_8BYTE;
5122 DirectiveKindMap[".octa"] = DK_OCTA;
5123 DirectiveKindMap[".single"] = DK_SINGLE;
5124 DirectiveKindMap[".float"] = DK_FLOAT;
5125 DirectiveKindMap[".double"] = DK_DOUBLE;
5126 DirectiveKindMap[".align"] = DK_ALIGN;
5127 DirectiveKindMap[".align32"] = DK_ALIGN32;
5128 DirectiveKindMap[".balign"] = DK_BALIGN;
5129 DirectiveKindMap[".balignw"] = DK_BALIGNW;
5130 DirectiveKindMap[".balignl"] = DK_BALIGNL;
5131 DirectiveKindMap[".p2align"] = DK_P2ALIGN;
5132 DirectiveKindMap[".p2alignw"] = DK_P2ALIGNW;
5133 DirectiveKindMap[".p2alignl"] = DK_P2ALIGNL;
5134 DirectiveKindMap[".org"] = DK_ORG;
5135 DirectiveKindMap[".fill"] = DK_FILL;
5136 DirectiveKindMap[".zero"] = DK_ZERO;
5137 DirectiveKindMap[".extern"] = DK_EXTERN;
5138 DirectiveKindMap[".globl"] = DK_GLOBL;
5139 DirectiveKindMap[".global"] = DK_GLOBAL;
5140 DirectiveKindMap[".lazy_reference"] = DK_LAZY_REFERENCE;
5141 DirectiveKindMap[".no_dead_strip"] = DK_NO_DEAD_STRIP;
5142 DirectiveKindMap[".symbol_resolver"] = DK_SYMBOL_RESOLVER;
5143 DirectiveKindMap[".private_extern"] = DK_PRIVATE_EXTERN;
5144 DirectiveKindMap[".reference"] = DK_REFERENCE;
5145 DirectiveKindMap[".weak_definition"] = DK_WEAK_DEFINITION;
5146 DirectiveKindMap[".weak_reference"] = DK_WEAK_REFERENCE;
5147 DirectiveKindMap[".weak_def_can_be_hidden"] = DK_WEAK_DEF_CAN_BE_HIDDEN;
5148 DirectiveKindMap[".comm"] = DK_COMM;
5149 DirectiveKindMap[".common"] = DK_COMMON;
5150 DirectiveKindMap[".lcomm"] = DK_LCOMM;
5151 DirectiveKindMap[".abort"] = DK_ABORT;
5152 DirectiveKindMap[".include"] = DK_INCLUDE;
5153 DirectiveKindMap[".incbin"] = DK_INCBIN;
5154 DirectiveKindMap[".code16"] = DK_CODE16;
5155 DirectiveKindMap[".code16gcc"] = DK_CODE16GCC;
5156 DirectiveKindMap[".rept"] = DK_REPT;
5157 DirectiveKindMap[".rep"] = DK_REPT;
5158 DirectiveKindMap[".irp"] = DK_IRP;
5159 DirectiveKindMap[".irpc"] = DK_IRPC;
5160 DirectiveKindMap[".endr"] = DK_ENDR;
5161 DirectiveKindMap[".bundle_align_mode"] = DK_BUNDLE_ALIGN_MODE;
5162 DirectiveKindMap[".bundle_lock"] = DK_BUNDLE_LOCK;
5163 DirectiveKindMap[".bundle_unlock"] = DK_BUNDLE_UNLOCK;
5164 DirectiveKindMap[".if"] = DK_IF;
5165 DirectiveKindMap[".ifeq"] = DK_IFEQ;
5166 DirectiveKindMap[".ifge"] = DK_IFGE;
5167 DirectiveKindMap[".ifgt"] = DK_IFGT;
5168 DirectiveKindMap[".ifle"] = DK_IFLE;
5169 DirectiveKindMap[".iflt"] = DK_IFLT;
5170 DirectiveKindMap[".ifne"] = DK_IFNE;
5171 DirectiveKindMap[".ifb"] = DK_IFB;
5172 DirectiveKindMap[".ifnb"] = DK_IFNB;
5173 DirectiveKindMap[".ifc"] = DK_IFC;
5174 DirectiveKindMap[".ifeqs"] = DK_IFEQS;
5175 DirectiveKindMap[".ifnc"] = DK_IFNC;
5176 DirectiveKindMap[".ifnes"] = DK_IFNES;
5177 DirectiveKindMap[".ifdef"] = DK_IFDEF;
5178 DirectiveKindMap[".ifndef"] = DK_IFNDEF;
5179 DirectiveKindMap[".ifnotdef"] = DK_IFNOTDEF;
5180 DirectiveKindMap[".elseif"] = DK_ELSEIF;
5181 DirectiveKindMap[".else"] = DK_ELSE;
5182 DirectiveKindMap[".end"] = DK_END;
5183 DirectiveKindMap[".endif"] = DK_ENDIF;
5184 DirectiveKindMap[".skip"] = DK_SKIP;
5185 DirectiveKindMap[".space"] = DK_SPACE;
5186 DirectiveKindMap[".file"] = DK_FILE;
5187 DirectiveKindMap[".line"] = DK_LINE;
5188 DirectiveKindMap[".loc"] = DK_LOC;
5189 DirectiveKindMap[".stabs"] = DK_STABS;
5190 DirectiveKindMap[".cv_file"] = DK_CV_FILE;
5191 DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID;
5192 DirectiveKindMap[".cv_loc"] = DK_CV_LOC;
5193 DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE;
5194 DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
5195 DirectiveKindMap[".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID;
5196 DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;
5197 DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;
5198 DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
5199 DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
5200 DirectiveKindMap[".cv_fpo_data"] = DK_CV_FPO_DATA;
5201 DirectiveKindMap[".sleb128"] = DK_SLEB128;
5202 DirectiveKindMap[".uleb128"] = DK_ULEB128;
5203 DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;
5204 DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC;
5205 DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC;
5206 DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA;
5207 DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
5208 DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
5209 DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
5210 DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET;
5211 DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
5212 DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY;
5213 DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA;
5214 DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE;
5215 DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE;
5216 DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE;
5217 DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE;
5218 DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE;
5219 DirectiveKindMap[".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
5220 DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
5221 DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
5222 DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
5223 DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
5224 DirectiveKindMap[".macros_on"] = DK_MACROS_ON;
5225 DirectiveKindMap[".macros_off"] = DK_MACROS_OFF;
5226 DirectiveKindMap[".macro"] = DK_MACRO;
5227 DirectiveKindMap[".exitm"] = DK_EXITM;
5228 DirectiveKindMap[".endm"] = DK_ENDM;
5229 DirectiveKindMap[".endmacro"] = DK_ENDMACRO;
5230 DirectiveKindMap[".purgem"] = DK_PURGEM;
5231 DirectiveKindMap[".err"] = DK_ERR;
5232 DirectiveKindMap[".error"] = DK_ERROR;
5233 DirectiveKindMap[".warning"] = DK_WARNING;
5234 DirectiveKindMap[".altmacro"] = DK_ALTMACRO;
5235 DirectiveKindMap[".noaltmacro"] = DK_NOALTMACRO;
5236 DirectiveKindMap[".reloc"] = DK_RELOC;
5237 DirectiveKindMap[".dc"] = DK_DC;
5238 DirectiveKindMap[".dc.a"] = DK_DC_A;
5239 DirectiveKindMap[".dc.b"] = DK_DC_B;
5240 DirectiveKindMap[".dc.d"] = DK_DC_D;
5241 DirectiveKindMap[".dc.l"] = DK_DC_L;
5242 DirectiveKindMap[".dc.s"] = DK_DC_S;
5243 DirectiveKindMap[".dc.w"] = DK_DC_W;
5244 DirectiveKindMap[".dc.x"] = DK_DC_X;
5245 DirectiveKindMap[".dcb"] = DK_DCB;
5246 DirectiveKindMap[".dcb.b"] = DK_DCB_B;
5247 DirectiveKindMap[".dcb.d"] = DK_DCB_D;
5248 DirectiveKindMap[".dcb.l"] = DK_DCB_L;
5249 DirectiveKindMap[".dcb.s"] = DK_DCB_S;
5250 DirectiveKindMap[".dcb.w"] = DK_DCB_W;
5251 DirectiveKindMap[".dcb.x"] = DK_DCB_X;
5252 DirectiveKindMap[".ds"] = DK_DS;
5253 DirectiveKindMap[".ds.b"] = DK_DS_B;
5254 DirectiveKindMap[".ds.d"] = DK_DS_D;
5255 DirectiveKindMap[".ds.l"] = DK_DS_L;
5256 DirectiveKindMap[".ds.p"] = DK_DS_P;
5257 DirectiveKindMap[".ds.s"] = DK_DS_S;
5258 DirectiveKindMap[".ds.w"] = DK_DS_W;
5259 DirectiveKindMap[".ds.x"] = DK_DS_X;
5260 DirectiveKindMap[".print"] = DK_PRINT;
5261}
5262
5263MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
5264 AsmToken EndToken, StartToken = getTok();
5265
5266 unsigned NestLevel = 0;
5267 while (true) {
5268 // Check whether we have reached the end of the file.
5269 if (getLexer().is(AsmToken::Eof)) {
5270 printError(DirectiveLoc, "no matching '.endr' in definition");
5271 return nullptr;
5272 }
5273
5274 if (Lexer.is(AsmToken::Identifier) &&
5275 (getTok().getIdentifier() == ".rept" ||
5276 getTok().getIdentifier() == ".irp" ||
5277 getTok().getIdentifier() == ".irpc")) {
5278 ++NestLevel;
5279 }
5280
5281 // Otherwise, check whether we have reached the .endr.
5282 if (Lexer.is(AsmToken::Identifier) && getTok().getIdentifier() == ".endr") {
5283 if (NestLevel == 0) {
5284 EndToken = getTok();
5285 Lex();
5286 if (Lexer.isNot(AsmToken::EndOfStatement)) {
5287 printError(getTok().getLoc(),
5288 "unexpected token in '.endr' directive");
5289 return nullptr;
5290 }
5291 break;
5292 }
5293 --NestLevel;
5294 }
5295
5296 // Otherwise, scan till the end of the statement.
5297 eatToEndOfStatement();
5298 }
5299
5300 const char *BodyStart = StartToken.getLoc().getPointer();
5301 const char *BodyEnd = EndToken.getLoc().getPointer();
5302 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
5303
5304 // We Are Anonymous.
5305 MacroLikeBodies.emplace_back(StringRef(), Body, MCAsmMacroParameters());
5306 return &MacroLikeBodies.back();
5307}
5308
5309void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
5310 raw_svector_ostream &OS) {
5311 OS << ".endr\n";
5312
5313 std::unique_ptr<MemoryBuffer> Instantiation =
5314 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
5315
5316 // Create the macro instantiation object and add to the current macro
5317 // instantiation stack.
5318 MacroInstantiation *MI = new MacroInstantiation(
5319 DirectiveLoc, CurBuffer, getTok().getLoc(), TheCondStack.size());
5320 ActiveMacros.push_back(MI);
5321
5322 // Jump to the macro instantiation and prime the lexer.
5323 CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
5324 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
5325 Lex();
5326}
5327
5328/// parseDirectiveRept
5329/// ::= .rep | .rept count
5330bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
5331 const MCExpr *CountExpr;
5332 SMLoc CountLoc = getTok().getLoc();
5333 if (parseExpression(CountExpr))
5334 return true;
5335
5336 int64_t Count;
5337 if (!CountExpr->evaluateAsAbsolute(Count)) {
5338 return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
5339 }
5340
5341 if (check(Count < 0, CountLoc, "Count is negative") ||
5342 parseToken(AsmToken::EndOfStatement,
5343 "unexpected token in '" + Dir + "' directive"))
5344 return true;
5345
5346 // Lex the rept definition.
5347 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5348 if (!M)
5349 return true;
5350
5351 // Macro instantiation is lexical, unfortunately. We construct a new buffer
5352 // to hold the macro body with substitutions.
5353 SmallString<256> Buf;
5354 raw_svector_ostream OS(Buf);
5355 while (Count--) {
5356 // Note that the AtPseudoVariable is disabled for instantiations of .rep(t).
5357 if (expandMacro(OS, M->Body, None, None, false, getTok().getLoc()))
5358 return true;
5359 }
5360 instantiateMacroLikeBody(M, DirectiveLoc, OS);
5361
5362 return false;
5363}
5364
5365/// parseDirectiveIrp
5366/// ::= .irp symbol,values
5367bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
5368 MCAsmMacroParameter Parameter;
5369 MCAsmMacroArguments A;
5370 if (check(parseIdentifier(Parameter.Name),
5371 "expected identifier in '.irp' directive") ||
5372 parseToken(AsmToken::Comma, "expected comma in '.irp' directive") ||
5373 parseMacroArguments(nullptr, A) ||
5374 parseToken(AsmToken::EndOfStatement, "expected End of Statement"))
5375 return true;
5376
5377 // Lex the irp definition.
5378 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5379 if (!M)
5380 return true;
5381
5382 // Macro instantiation is lexical, unfortunately. We construct a new buffer
5383 // to hold the macro body with substitutions.
5384 SmallString<256> Buf;
5385 raw_svector_ostream OS(Buf);
5386
5387 for (const MCAsmMacroArgument &Arg : A) {
5388 // Note that the AtPseudoVariable is enabled for instantiations of .irp.
5389 // This is undocumented, but GAS seems to support it.
5390 if (expandMacro(OS, M->Body, Parameter, Arg, true, getTok().getLoc()))
5391 return true;
5392 }
5393
5394 instantiateMacroLikeBody(M, DirectiveLoc, OS);
5395
5396 return false;
5397}
5398
5399/// parseDirectiveIrpc
5400/// ::= .irpc symbol,values
5401bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
5402 MCAsmMacroParameter Parameter;
5403 MCAsmMacroArguments A;
5404
5405 if (check(parseIdentifier(Parameter.Name),
5406 "expected identifier in '.irpc' directive") ||
5407 parseToken(AsmToken::Comma, "expected comma in '.irpc' directive") ||
5408 parseMacroArguments(nullptr, A))
5409 return true;
5410
5411 if (A.size() != 1 || A.front().size() != 1)
5412 return TokError("unexpected token in '.irpc' directive");
5413
5414 // Eat the end of statement.
5415 if (parseToken(AsmToken::EndOfStatement, "expected end of statement"))
5416 return true;
5417
5418 // Lex the irpc definition.
5419 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5420 if (!M)
5421 return true;
5422
5423 // Macro instantiation is lexical, unfortunately. We construct a new buffer
5424 // to hold the macro body with substitutions.
5425 SmallString<256> Buf;
5426 raw_svector_ostream OS(Buf);
5427
5428 StringRef Values = A.front().front().getString();
5429 for (std::size_t I = 0, End = Values.size(); I != End; ++I) {
5430 MCAsmMacroArgument Arg;
5431 Arg.emplace_back(AsmToken::Identifier, Values.slice(I, I + 1));
5432
5433 // Note that the AtPseudoVariable is enabled for instantiations of .irpc.
5434 // This is undocumented, but GAS seems to support it.
5435 if (expandMacro(OS, M->Body, Parameter, Arg, true, getTok().getLoc()))
5436 return true;
5437 }
5438
5439 instantiateMacroLikeBody(M, DirectiveLoc, OS);
5440
5441 return false;
5442}
5443
5444bool AsmParser::parseDirectiveEndr(SMLoc DirectiveLoc) {
5445 if (ActiveMacros.empty())
5446 return TokError("unmatched '.endr' directive");
5447
5448 // The only .repl that should get here are the ones created by
5449 // instantiateMacroLikeBody.
5450 assert(getLexer().is(AsmToken::EndOfStatement))(static_cast <bool> (getLexer().is(AsmToken::EndOfStatement
)) ? void (0) : __assert_fail ("getLexer().is(AsmToken::EndOfStatement)"
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 5450, __extension__ __PRETTY_FUNCTION__))
;
5451
5452 handleMacroExit();
5453 return false;
5454}
5455
5456bool AsmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
5457 size_t Len) {
5458 const MCExpr *Value;
5459 SMLoc ExprLoc = getLexer().getLoc();
5460 if (parseExpression(Value))
5461 return true;
5462 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
5463 if (!MCE)
5464 return Error(ExprLoc, "unexpected expression in _emit");
5465 uint64_t IntValue = MCE->getValue();
5466 if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
5467 return Error(ExprLoc, "literal value out of range for directive");
5468
5469 Info.AsmRewrites->emplace_back(AOK_Emit, IDLoc, Len);
5470 return false;
5471}
5472
5473bool AsmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
5474 const MCExpr *Value;
5475 SMLoc ExprLoc = getLexer().getLoc();
5476 if (parseExpression(Value))
5477 return true;
5478 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
5479 if (!MCE)
5480 return Error(ExprLoc, "unexpected expression in align");
5481 uint64_t IntValue = MCE->getValue();
5482 if (!isPowerOf2_64(IntValue))
5483 return Error(ExprLoc, "literal value not a power of two greater then zero");
5484
5485 Info.AsmRewrites->emplace_back(AOK_Align, IDLoc, 5, Log2_64(IntValue));
5486 return false;
5487}
5488
5489bool AsmParser::parseDirectivePrint(SMLoc DirectiveLoc) {
5490 const AsmToken StrTok = getTok();
5491 Lex();
5492 if (StrTok.isNot(AsmToken::String) || StrTok.getString().front() != '"')
5493 return Error(DirectiveLoc, "expected double quoted string after .print");
5494 if (parseToken(AsmToken::EndOfStatement, "expected end of statement"))
5495 return true;
5496 llvm::outs() << StrTok.getStringContents() << '\n';
5497 return false;
5498}
5499
5500// We are comparing pointers, but the pointers are relative to a single string.
5501// Thus, this should always be deterministic.
5502static int rewritesSort(const AsmRewrite *AsmRewriteA,
5503 const AsmRewrite *AsmRewriteB) {
5504 if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer())
5505 return -1;
5506 if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())
5507 return 1;
5508
5509 // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output
5510 // rewrite to the same location. Make sure the SizeDirective rewrite is
5511 // performed first, then the Imm/ImmPrefix and finally the Input/Output. This
5512 // ensures the sort algorithm is stable.
5513 if (AsmRewritePrecedence[AsmRewriteA->Kind] >
5514 AsmRewritePrecedence[AsmRewriteB->Kind])
5515 return -1;
5516
5517 if (AsmRewritePrecedence[AsmRewriteA->Kind] <
5518 AsmRewritePrecedence[AsmRewriteB->Kind])
5519 return 1;
5520 llvm_unreachable("Unstable rewrite sort.")::llvm::llvm_unreachable_internal("Unstable rewrite sort.", "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 5520)
;
5521}
5522
5523bool AsmParser::parseMSInlineAsm(
5524 void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
5525 unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
5526 SmallVectorImpl<std::string> &Constraints,
5527 SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
5528 const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
5529 SmallVector<void *, 4> InputDecls;
5530 SmallVector<void *, 4> OutputDecls;
5531 SmallVector<bool, 4> InputDeclsAddressOf;
5532 SmallVector<bool, 4> OutputDeclsAddressOf;
5533 SmallVector<std::string, 4> InputConstraints;
5534 SmallVector<std::string, 4> OutputConstraints;
5535 SmallVector<unsigned, 4> ClobberRegs;
5536
5537 SmallVector<AsmRewrite, 4> AsmStrRewrites;
5538
5539 // Prime the lexer.
5540 Lex();
5541
5542 // While we have input, parse each statement.
5543 unsigned InputIdx = 0;
5544 unsigned OutputIdx = 0;
5545 while (getLexer().isNot(AsmToken::Eof)) {
5546 // Parse curly braces marking block start/end
5547 if (parseCurlyBlockScope(AsmStrRewrites))
5548 continue;
5549
5550 ParseStatementInfo Info(&AsmStrRewrites);
5551 bool StatementErr = parseStatement(Info, &SI);
5552
5553 if (StatementErr || Info.ParseError) {
5554 // Emit pending errors if any exist.
5555 printPendingErrors();
5556 return true;
5557 }
5558
5559 // No pending error should exist here.
5560 assert(!hasPendingError() && "unexpected error from parseStatement")(static_cast <bool> (!hasPendingError() && "unexpected error from parseStatement"
) ? void (0) : __assert_fail ("!hasPendingError() && \"unexpected error from parseStatement\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 5560, __extension__ __PRETTY_FUNCTION__))
;
5561
5562 if (Info.Opcode == ~0U)
5563 continue;
5564
5565 const MCInstrDesc &Desc = MII->get(Info.Opcode);
5566
5567 // Build the list of clobbers, outputs and inputs.
5568 for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
5569 MCParsedAsmOperand &Operand = *Info.ParsedOperands[i];
5570
5571 // Immediate.
5572 if (Operand.isImm())
5573 continue;
5574
5575 // Register operand.
5576 if (Operand.isReg() && !Operand.needAddressOf() &&
5577 !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) {
5578 unsigned NumDefs = Desc.getNumDefs();
5579 // Clobber.
5580 if (NumDefs && Operand.getMCOperandNum() < NumDefs)
5581 ClobberRegs.push_back(Operand.getReg());
5582 continue;
5583 }
5584
5585 // Expr/Input or Output.
5586 StringRef SymName = Operand.getSymName();
5587 if (SymName.empty())
5588 continue;
5589
5590 void *OpDecl = Operand.getOpDecl();
5591 if (!OpDecl)
5592 continue;
5593
5594 bool isOutput = (i == 1) && Desc.mayStore();
5595 SMLoc Start = SMLoc::getFromPointer(SymName.data());
5596 if (isOutput) {
5597 ++InputIdx;
5598 OutputDecls.push_back(OpDecl);
5599 OutputDeclsAddressOf.push_back(Operand.needAddressOf());
5600 OutputConstraints.push_back(("=" + Operand.getConstraint()).str());
5601 AsmStrRewrites.emplace_back(AOK_Output, Start, SymName.size());
5602 } else {
5603 InputDecls.push_back(OpDecl);
5604 InputDeclsAddressOf.push_back(Operand.needAddressOf());
5605 InputConstraints.push_back(Operand.getConstraint().str());
5606 AsmStrRewrites.emplace_back(AOK_Input, Start, SymName.size());
5607 }
5608 }
5609
5610 // Consider implicit defs to be clobbers. Think of cpuid and push.
5611 ArrayRef<MCPhysReg> ImpDefs(Desc.getImplicitDefs(),
5612 Desc.getNumImplicitDefs());
5613 ClobberRegs.insert(ClobberRegs.end(), ImpDefs.begin(), ImpDefs.end());
5614 }
5615
5616 // Set the number of Outputs and Inputs.
5617 NumOutputs = OutputDecls.size();
5618 NumInputs = InputDecls.size();
5619
5620 // Set the unique clobbers.
5621 array_pod_sort(ClobberRegs.begin(), ClobberRegs.end());
5622 ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()),
5623 ClobberRegs.end());
5624 Clobbers.assign(ClobberRegs.size(), std::string());
5625 for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) {
5626 raw_string_ostream OS(Clobbers[I]);
5627 IP->printRegName(OS, ClobberRegs[I]);
5628 }
5629
5630 // Merge the various outputs and inputs. Output are expected first.
5631 if (NumOutputs || NumInputs) {
5632 unsigned NumExprs = NumOutputs + NumInputs;
5633 OpDecls.resize(NumExprs);
5634 Constraints.resize(NumExprs);
5635 for (unsigned i = 0; i < NumOutputs; ++i) {
5636 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
5637 Constraints[i] = OutputConstraints[i];
5638 }
5639 for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) {
5640 OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
5641 Constraints[j] = InputConstraints[i];
5642 }
5643 }
5644
5645 // Build the IR assembly string.
5646 std::string AsmStringIR;
5647 raw_string_ostream OS(AsmStringIR);
5648 StringRef ASMString =
5649 SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer();
5650 const char *AsmStart = ASMString.begin();
5651 const char *AsmEnd = ASMString.end();
5652 array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort);
5653 for (const AsmRewrite &AR : AsmStrRewrites) {
5654 AsmRewriteKind Kind = AR.Kind;
5655
5656 const char *Loc = AR.Loc.getPointer();
5657 assert(Loc >= AsmStart && "Expected Loc to be at or after Start!")(static_cast <bool> (Loc >= AsmStart && "Expected Loc to be at or after Start!"
) ? void (0) : __assert_fail ("Loc >= AsmStart && \"Expected Loc to be at or after Start!\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 5657, __extension__ __PRETTY_FUNCTION__))
;
5658
5659 // Emit everything up to the immediate/expression.
5660 if (unsigned Len = Loc - AsmStart)
5661 OS << StringRef(AsmStart, Len);
5662
5663 // Skip the original expression.
5664 if (Kind == AOK_Skip) {
5665 AsmStart = Loc + AR.Len;
5666 continue;
5667 }
5668
5669 unsigned AdditionalSkip = 0;
5670 // Rewrite expressions in $N notation.
5671 switch (Kind) {
5672 default:
5673 break;
5674 case AOK_IntelExpr:
5675 assert(AR.IntelExp.isValid() && "cannot write invalid intel expression")(static_cast <bool> (AR.IntelExp.isValid() && "cannot write invalid intel expression"
) ? void (0) : __assert_fail ("AR.IntelExp.isValid() && \"cannot write invalid intel expression\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 5675, __extension__ __PRETTY_FUNCTION__))
;
5676 if (AR.IntelExp.NeedBracs)
5677 OS << "[";
5678 if (AR.IntelExp.hasBaseReg())
5679 OS << AR.IntelExp.BaseReg;
5680 if (AR.IntelExp.hasIndexReg())
5681 OS << (AR.IntelExp.hasBaseReg() ? " + " : "")
5682 << AR.IntelExp.IndexReg;
5683 if (AR.IntelExp.Scale > 1)
5684 OS << " * $$" << AR.IntelExp.Scale;
5685 if (AR.IntelExp.Imm || !AR.IntelExp.hasRegs())
5686 OS << (AR.IntelExp.hasRegs() ? " + $$" : "$$") << AR.IntelExp.Imm;
5687 if (AR.IntelExp.NeedBracs)
5688 OS << "]";
5689 break;
5690 case AOK_Label:
5691 OS << Ctx.getAsmInfo()->getPrivateLabelPrefix() << AR.Label;
5692 break;
5693 case AOK_Input:
5694 OS << '$' << InputIdx++;
5695 break;
5696 case AOK_Output:
5697 OS << '$' << OutputIdx++;
5698 break;
5699 case AOK_SizeDirective:
5700 switch (AR.Val) {
5701 default: break;
5702 case 8: OS << "byte ptr "; break;
5703 case 16: OS << "word ptr "; break;
5704 case 32: OS << "dword ptr "; break;
5705 case 64: OS << "qword ptr "; break;
5706 case 80: OS << "xword ptr "; break;
5707 case 128: OS << "xmmword ptr "; break;
5708 case 256: OS << "ymmword ptr "; break;
5709 }
5710 break;
5711 case AOK_Emit:
5712 OS << ".byte";
5713 break;
5714 case AOK_Align: {
5715 // MS alignment directives are measured in bytes. If the native assembler
5716 // measures alignment in bytes, we can pass it straight through.
5717 OS << ".align";
5718 if (getContext().getAsmInfo()->getAlignmentIsInBytes())
5719 break;
5720
5721 // Alignment is in log2 form, so print that instead and skip the original
5722 // immediate.
5723 unsigned Val = AR.Val;
5724 OS << ' ' << Val;
5725 assert(Val < 10 && "Expected alignment less then 2^10.")(static_cast <bool> (Val < 10 && "Expected alignment less then 2^10."
) ? void (0) : __assert_fail ("Val < 10 && \"Expected alignment less then 2^10.\""
, "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 5725, __extension__ __PRETTY_FUNCTION__))
;
5726 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
5727 break;
5728 }
5729 case AOK_EVEN:
5730 OS << ".even";
5731 break;
5732 case AOK_EndOfStatement:
5733 OS << "\n\t";
5734 break;
5735 }
5736
5737 // Skip the original expression.
5738 AsmStart = Loc + AR.Len + AdditionalSkip;
5739 }
5740
5741 // Emit the remainder of the asm string.
5742 if (AsmStart != AsmEnd)
5743 OS << StringRef(AsmStart, AsmEnd - AsmStart);
5744
5745 AsmString = OS.str();
5746 return false;
5747}
5748
5749namespace llvm {
5750namespace MCParserUtils {
5751
5752/// Returns whether the given symbol is used anywhere in the given expression,
5753/// or subexpressions.
5754static bool isSymbolUsedInExpression(const MCSymbol *Sym, const MCExpr *Value) {
5755 switch (Value->getKind()) {
5756 case MCExpr::Binary: {
5757 const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(Value);
5758 return isSymbolUsedInExpression(Sym, BE->getLHS()) ||
5759 isSymbolUsedInExpression(Sym, BE->getRHS());
5760 }
5761 case MCExpr::Target:
5762 case MCExpr::Constant:
5763 return false;
5764 case MCExpr::SymbolRef: {
5765 const MCSymbol &S =
5766 static_cast<const MCSymbolRefExpr *>(Value)->getSymbol();
5767 if (S.isVariable())
5768 return isSymbolUsedInExpression(Sym, S.getVariableValue());
5769 return &S == Sym;
5770 }
5771 case MCExpr::Unary:
5772 return isSymbolUsedInExpression(
5773 Sym, static_cast<const MCUnaryExpr *>(Value)->getSubExpr());
5774 }
5775
5776 llvm_unreachable("Unknown expr kind!")::llvm::llvm_unreachable_internal("Unknown expr kind!", "/build/llvm-toolchain-snapshot-7~svn329677/lib/MC/MCParser/AsmParser.cpp"
, 5776)
;
5777}
5778
5779bool parseAssignmentExpression(StringRef Name, bool allow_redef,
5780 MCAsmParser &Parser, MCSymbol *&Sym,
5781 const MCExpr *&Value) {
5782
5783 // FIXME: Use better location, we should use proper tokens.
5784 SMLoc EqualLoc = Parser.getTok().getLoc();
5785
5786 if (Parser.parseExpression(Value)) {
22
Assuming the condition is true
23
Taking true branch
5787 return Parser.TokError("missing expression");
24
Returning without writing to 'Sym'
5788 }
5789
5790 // Note: we don't count b as used in "a = b". This is to allow
5791 // a = b
5792 // b = c
5793
5794 if (Parser.parseToken(AsmToken::EndOfStatement))
5795 return true;
5796
5797 // Validate that the LHS is allowed to be a variable (either it has not been
5798 // used as a symbol, or it is an absolute symbol).
5799 Sym = Parser.getContext().lookupSymbol(Name);
5800 if (Sym) {
5801 // Diagnose assignment to a label.
5802 //
5803 // FIXME: Diagnostics. Note the location of the definition as a label.
5804 // FIXME: Diagnose assignment to protected identifier (e.g., register name).
5805 if (isSymbolUsedInExpression(Sym, Value))
5806 return Parser.Error(EqualLoc, "Recursive use of '" + Name + "'");
5807 else if (Sym->isUndefined(/*SetUsed*/ false) && !Sym->isUsed() &&
5808 !Sym->isVariable())
5809 ; // Allow redefinitions of undefined symbols only used in directives.
5810 else if (Sym->isVariable() && !Sym->isUsed() && allow_redef)
5811 ; // Allow redefinitions of variables that haven't yet been used.
5812 else if (!Sym->isUndefined() && (!Sym->isVariable() || !allow_redef))
5813 return Parser.Error(EqualLoc, "redefinition of '" + Name + "'");
5814 else if (!Sym->isVariable())
5815 return Parser.Error(EqualLoc, "invalid assignment to '" + Name + "'");
5816 else if (!isa<MCConstantExpr>(Sym->getVariableValue()))
5817 return Parser.Error(EqualLoc,
5818 "invalid reassignment of non-absolute variable '" +
5819 Name + "'");
5820 } else if (Name == ".") {
5821 Parser.getStreamer().emitValueToOffset(Value, 0, EqualLoc);
5822 return false;
5823 } else
5824 Sym = Parser.getContext().getOrCreateSymbol(Name);
5825
5826 Sym->setRedefinable(allow_redef);
5827
5828 return false;
5829}
5830
5831} // end namespace MCParserUtils
5832} // end namespace llvm
5833
5834/// \brief Create an MCAsmParser instance.
5835MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM, MCContext &C,
5836 MCStreamer &Out, const MCAsmInfo &MAI,
5837 unsigned CB) {
5838 return new AsmParser(SM, C, Out, MAI, CB);
5839}