Bug Summary

File:lib/MC/MCParser/AsmParser.cpp
Warning:line 2801, column 7
Branch condition evaluates to a garbage value

Annotated Source Code

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

/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/ADT/Twine.h

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