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