1 //===- AsmParser.cpp - Parser for Assembly Files --------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This class implements the parser for assembly files.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/ADT/APFloat.h"
14 #include "llvm/ADT/APInt.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/None.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringExtras.h"
21 #include "llvm/ADT/StringMap.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/ADT/Twine.h"
24 #include "llvm/BinaryFormat/Dwarf.h"
25 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
26 #include "llvm/MC/MCAsmInfo.h"
27 #include "llvm/MC/MCCodeView.h"
28 #include "llvm/MC/MCContext.h"
29 #include "llvm/MC/MCDirectives.h"
30 #include "llvm/MC/MCDwarf.h"
31 #include "llvm/MC/MCExpr.h"
32 #include "llvm/MC/MCInstPrinter.h"
33 #include "llvm/MC/MCInstrDesc.h"
34 #include "llvm/MC/MCInstrInfo.h"
35 #include "llvm/MC/MCObjectFileInfo.h"
36 #include "llvm/MC/MCParser/AsmCond.h"
37 #include "llvm/MC/MCParser/AsmLexer.h"
38 #include "llvm/MC/MCParser/MCAsmLexer.h"
39 #include "llvm/MC/MCParser/MCAsmParser.h"
40 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
41 #include "llvm/MC/MCParser/MCAsmParserUtils.h"
42 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
43 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
44 #include "llvm/MC/MCRegisterInfo.h"
45 #include "llvm/MC/MCSection.h"
46 #include "llvm/MC/MCStreamer.h"
47 #include "llvm/MC/MCSymbol.h"
48 #include "llvm/MC/MCTargetOptions.h"
49 #include "llvm/MC/MCValue.h"
50 #include "llvm/Support/Casting.h"
51 #include "llvm/Support/CommandLine.h"
52 #include "llvm/Support/ErrorHandling.h"
53 #include "llvm/Support/MD5.h"
54 #include "llvm/Support/MathExtras.h"
55 #include "llvm/Support/MemoryBuffer.h"
56 #include "llvm/Support/SMLoc.h"
57 #include "llvm/Support/SourceMgr.h"
58 #include "llvm/Support/raw_ostream.h"
75 extern cl::opt<unsigned> AsmMacroMaxNestingDepth;
79 /// Helper types for tracking macro definitions.
80 typedef std::vector<AsmToken> MCAsmMacroArgument;
81 typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
83 /// Helper class for storing information about an active macro instantiation.
84 struct MacroInstantiation {
85 /// The location of the instantiation.
86 SMLoc InstantiationLoc;
88 /// The buffer where parsing should resume upon instantiation completion.
91 /// The location where parsing should resume upon instantiation completion.
94 /// The depth of TheCondStack at the start of the instantiation.
95 size_t CondStackDepth;
98 struct ParseStatementInfo {
99 /// The parsed operands from the last parsed statement.
100 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> ParsedOperands;
102 /// The opcode from the last parsed instruction.
103 unsigned Opcode = ~0U;
105 /// Was there an error parsing the inline assembly?
106 bool ParseError = false;
108 SmallVectorImpl<AsmRewrite> *AsmRewrites = nullptr;
110 ParseStatementInfo() = delete;
111 ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites)
112 : AsmRewrites(rewrites) {}
116 FT_INTEGRAL, // Initializer: integer expression, stored as an MCExpr.
117 FT_REAL, // Initializer: real number, stored as an APInt.
118 FT_STRUCT // Initializer: struct initializer, stored recursively.
124 bool IsUnion = false;
125 size_t Alignment = 0;
127 std::vector<FieldInfo> Fields;
128 StringMap<size_t> FieldsByName;
130 FieldInfo &addField(StringRef FieldName, FieldType FT);
132 StructInfo() = default;
134 StructInfo(StringRef StructName, bool Union, unsigned AlignmentValue)
135 : Name(StructName), IsUnion(Union), Alignment(AlignmentValue) {}
138 // FIXME: This should probably use a class hierarchy, raw pointers between the
139 // objects, and dynamic type resolution instead of a union. On the other hand,
140 // ownership then becomes much more complicated; the obvious thing would be to
141 // use BumpPtrAllocator, but the lack of a destructor makes that messy.
143 struct StructInitializer;
144 struct IntFieldInfo {
145 SmallVector<const MCExpr *, 1> Values;
147 IntFieldInfo() = default;
148 IntFieldInfo(const SmallVector<const MCExpr *, 1> &V) { Values = V; }
149 IntFieldInfo(SmallVector<const MCExpr *, 1> &&V) { Values = V; }
151 struct RealFieldInfo {
152 SmallVector<APInt, 1> AsIntValues;
154 RealFieldInfo() = default;
155 RealFieldInfo(const SmallVector<APInt, 1> &V) { AsIntValues = V; }
156 RealFieldInfo(SmallVector<APInt, 1> &&V) { AsIntValues = V; }
158 struct StructFieldInfo {
159 std::vector<StructInitializer> Initializers;
160 StructInfo Structure;
162 StructFieldInfo() = default;
163 StructFieldInfo(const std::vector<StructInitializer> &V, StructInfo S) {
167 StructFieldInfo(std::vector<StructInitializer> &&V, StructInfo S) {
173 class FieldInitializer {
177 IntFieldInfo IntInfo;
178 RealFieldInfo RealInfo;
179 StructFieldInfo StructInfo;
182 ~FieldInitializer() {
185 IntInfo.~IntFieldInfo();
188 RealInfo.~RealFieldInfo();
191 StructInfo.~StructFieldInfo();
196 FieldInitializer(FieldType FT) : FT(FT) {
199 new (&IntInfo) IntFieldInfo();
202 new (&RealInfo) RealFieldInfo();
205 new (&StructInfo) StructFieldInfo();
210 FieldInitializer(SmallVector<const MCExpr *, 1> &&Values) : FT(FT_INTEGRAL) {
211 new (&IntInfo) IntFieldInfo(Values);
214 FieldInitializer(SmallVector<APInt, 1> &&AsIntValues) : FT(FT_REAL) {
215 new (&RealInfo) RealFieldInfo(AsIntValues);
218 FieldInitializer(std::vector<StructInitializer> &&Initializers,
219 struct StructInfo Structure)
221 new (&StructInfo) StructFieldInfo(Initializers, Structure);
224 FieldInitializer(const FieldInitializer &Initializer) : FT(Initializer.FT) {
227 new (&IntInfo) IntFieldInfo(Initializer.IntInfo);
230 new (&RealInfo) RealFieldInfo(Initializer.RealInfo);
233 new (&StructInfo) StructFieldInfo(Initializer.StructInfo);
238 FieldInitializer(FieldInitializer &&Initializer) : FT(Initializer.FT) {
241 new (&IntInfo) IntFieldInfo(Initializer.IntInfo);
244 new (&RealInfo) RealFieldInfo(Initializer.RealInfo);
247 new (&StructInfo) StructFieldInfo(Initializer.StructInfo);
252 FieldInitializer &operator=(const FieldInitializer &Initializer) {
253 if (FT != Initializer.FT) {
256 IntInfo.~IntFieldInfo();
259 RealInfo.~RealFieldInfo();
262 StructInfo.~StructFieldInfo();
269 IntInfo = Initializer.IntInfo;
272 RealInfo = Initializer.RealInfo;
275 StructInfo = Initializer.StructInfo;
281 FieldInitializer &operator=(FieldInitializer &&Initializer) {
282 if (FT != Initializer.FT) {
285 IntInfo.~IntFieldInfo();
288 RealInfo.~RealFieldInfo();
291 StructInfo.~StructFieldInfo();
298 IntInfo = Initializer.IntInfo;
301 RealInfo = Initializer.RealInfo;
304 StructInfo = Initializer.StructInfo;
311 struct StructInitializer {
312 std::vector<FieldInitializer> FieldInitializers;
316 // Offset of the field within the containing STRUCT.
319 // Total size of the field (= LengthOf * Type).
322 // Number of elements in the field (1 if scalar, >1 if an array).
325 // Size of a single entry in this field, in bytes ("type" in MASM standards).
328 FieldInitializer Contents;
330 FieldInfo(FieldType FT) : Contents(FT) {}
333 FieldInfo &StructInfo::addField(StringRef FieldName, FieldType FT) {
334 if (!FieldName.empty())
335 FieldsByName[FieldName] = Fields.size();
336 Fields.emplace_back(FT);
337 FieldInfo &Field = Fields.back();
341 Size = llvm::alignTo(Size, Alignment);
347 /// The concrete assembly parser instance.
348 // Note that this is a full MCAsmParser, not an MCAsmParserExtension!
349 // It's a peer of AsmParser, not of COFFAsmParser, WasmAsmParser, etc.
350 class MasmParser : public MCAsmParser {
355 const MCAsmInfo &MAI;
357 SourceMgr::DiagHandlerTy SavedDiagHandler;
358 void *SavedDiagContext;
359 std::unique_ptr<MCAsmParserExtension> PlatformParser;
361 /// This is the current buffer index we're lexing from as managed by the
362 /// SourceMgr object.
365 AsmCond TheCondState;
366 std::vector<AsmCond> TheCondStack;
368 /// maps directive names to handler methods in parser
369 /// extensions. Extensions register themselves in this map by calling
370 /// addDirectiveHandler.
371 StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap;
373 /// maps assembly-time variable names to variables.
376 bool Redefinable = true;
378 int64_t NumericValue = 0;
379 std::string TextValue;
381 StringMap<Variable> Variables;
383 /// Stack of active struct definitions.
384 SmallVector<StructInfo, 1> StructInProgress;
386 /// Maps struct tags to struct definitions.
387 StringMap<StructInfo> Structs;
389 /// Maps data location names to user-defined types.
390 StringMap<const StructInfo *> KnownType;
392 /// Stack of active macro instantiations.
393 std::vector<MacroInstantiation*> ActiveMacros;
395 /// List of bodies of anonymous macros.
396 std::deque<MCAsmMacro> MacroLikeBodies;
398 /// Keeps track of how many .macro's have been instantiated.
399 unsigned NumOfMacroInstantiations;
401 /// The values from the last parsed cpp hash file line comment if any.
402 struct CppHashInfoTy {
407 CppHashInfoTy() : Filename(), LineNumber(0), Loc(), Buf(0) {}
409 CppHashInfoTy CppHashInfo;
411 /// The filename from the first cpp hash file line comment, if any.
412 StringRef FirstCppHashFilename;
414 /// List of forward directional labels for diagnosis at the end.
415 SmallVector<std::tuple<SMLoc, CppHashInfoTy, MCSymbol *>, 4> DirLabels;
417 /// AssemblerDialect. ~OU means unset value and use value provided by MAI.
418 /// Defaults to 1U, meaning Intel.
419 unsigned AssemblerDialect = 1U;
421 /// is Darwin compatibility enabled?
422 bool IsDarwin = false;
424 /// Are we parsing ms-style inline assembly?
425 bool ParsingMSInlineAsm = false;
427 /// Did we already inform the user about inconsistent MD5 usage?
428 bool ReportedInconsistentMD5 = false;
430 // Is alt macro mode enabled.
431 bool AltMacroMode = false;
433 // Current <...> expression depth.
434 unsigned AngleBracketDepth = 0U;
437 MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
438 const MCAsmInfo &MAI, unsigned CB);
439 MasmParser(const MasmParser &) = delete;
440 MasmParser &operator=(const MasmParser &) = delete;
441 ~MasmParser() override;
443 bool Run(bool NoInitialTextSection, bool NoFinalize = false) override;
445 void addDirectiveHandler(StringRef Directive,
446 ExtensionDirectiveHandler Handler) override {
447 ExtensionDirectiveMap[Directive] = Handler;
448 if (DirectiveKindMap.find(Directive) == DirectiveKindMap.end()) {
449 DirectiveKindMap[Directive] = DK_HANDLER_DIRECTIVE;
453 void addAliasForDirective(StringRef Directive, StringRef Alias) override {
454 DirectiveKindMap[Directive] = DirectiveKindMap[Alias];
457 /// @name MCAsmParser Interface
460 SourceMgr &getSourceManager() override { return SrcMgr; }
461 MCAsmLexer &getLexer() override { return Lexer; }
462 MCContext &getContext() override { return Ctx; }
463 MCStreamer &getStreamer() override { return Out; }
465 CodeViewContext &getCVContext() { return Ctx.getCVContext(); }
467 unsigned getAssemblerDialect() override {
468 if (AssemblerDialect == ~0U)
469 return MAI.getAssemblerDialect();
471 return AssemblerDialect;
473 void setAssemblerDialect(unsigned i) override {
474 AssemblerDialect = i;
477 void Note(SMLoc L, const Twine &Msg, SMRange Range = None) override;
478 bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) override;
479 bool printError(SMLoc L, const Twine &Msg, SMRange Range = None) override;
481 const AsmToken &Lex() override;
483 void setParsingMSInlineAsm(bool V) override {
484 ParsingMSInlineAsm = V;
485 // When parsing MS inline asm, we must lex 0b1101 and 0ABCH as binary and
486 // hex integer literals.
487 Lexer.setLexMasmIntegers(V);
489 bool isParsingMSInlineAsm() override { return ParsingMSInlineAsm; }
491 bool isParsingMasm() const override { return true; }
493 bool lookUpField(StringRef Name, StringRef &Type,
494 unsigned &Offset) const override;
495 bool lookUpField(StringRef Base, StringRef Member, StringRef &Type,
496 unsigned &Offset) const override;
498 bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
499 unsigned &NumOutputs, unsigned &NumInputs,
500 SmallVectorImpl<std::pair<void *,bool>> &OpDecls,
501 SmallVectorImpl<std::string> &Constraints,
502 SmallVectorImpl<std::string> &Clobbers,
503 const MCInstrInfo *MII, const MCInstPrinter *IP,
504 MCAsmParserSemaCallback &SI) override;
506 bool parseExpression(const MCExpr *&Res);
507 bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
508 bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override;
509 bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
510 bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
511 SMLoc &EndLoc) override;
512 bool parseAbsoluteExpression(int64_t &Res) override;
514 /// Parse a floating point expression using the float \p Semantics
515 /// and set \p Res to the value.
516 bool parseRealValue(const fltSemantics &Semantics, APInt &Res);
518 /// Parse an identifier or string (as a quoted identifier)
519 /// and set \p Res to the identifier contents.
520 bool parseIdentifier(StringRef &Res) override;
521 void eatToEndOfStatement() override;
523 bool checkForValidSection() override;
528 bool parseStatement(ParseStatementInfo &Info,
529 MCAsmParserSemaCallback *SI);
530 bool parseCurlyBlockScope(SmallVectorImpl<AsmRewrite>& AsmStrRewrites);
531 bool parseCppHashLineFilenameComment(SMLoc L);
533 void checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body,
534 ArrayRef<MCAsmMacroParameter> Parameters);
535 bool expandMacro(raw_svector_ostream &OS, StringRef Body,
536 ArrayRef<MCAsmMacroParameter> Parameters,
537 ArrayRef<MCAsmMacroArgument> A, bool EnableAtPseudoVariable,
540 /// Are we inside a macro instantiation?
541 bool isInsideMacroInstantiation() {return !ActiveMacros.empty();}
543 /// Handle entry to macro instantiation.
545 /// \param M The macro.
546 /// \param NameLoc Instantiation location.
547 bool handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc);
549 /// Handle exit from macro instantiation.
550 void handleMacroExit();
552 /// Extract AsmTokens for a macro argument.
553 bool parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg);
555 /// Parse all macro arguments for a given macro.
556 bool parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A);
558 void printMacroInstantiations();
559 void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
560 SMRange Range = None) const {
561 ArrayRef<SMRange> Ranges(Range);
562 SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges);
564 static void DiagHandler(const SMDiagnostic &Diag, void *Context);
566 bool lookUpField(const StructInfo &Structure, StringRef Member,
567 StringRef &Type, unsigned &Offset) const;
569 /// Should we emit DWARF describing this assembler source? (Returns false if
570 /// the source has .file directives, which means we don't want to generate
571 /// info describing the assembler source itself.)
572 bool enabledGenDwarfForAssembly();
574 /// Enter the specified file. This returns true on failure.
575 bool enterIncludeFile(const std::string &Filename);
577 /// Reset the current lexer position to that given by \p Loc. The
578 /// current token is not set; clients should ensure Lex() is called
581 /// \param InBuffer If not 0, should be the known buffer id that contains the
583 void jumpToLoc(SMLoc Loc, unsigned InBuffer = 0);
585 /// Parse up to the end of statement and a return the contents from the
586 /// current token until the end of the statement; the current token on exit
587 /// will be either the EndOfStatement or EOF.
588 StringRef parseStringToEndOfStatement() override;
590 bool parseTextItem(std::string &Data);
592 unsigned getBinOpPrecedence(AsmToken::TokenKind K,
593 MCBinaryExpr::Opcode &Kind);
595 bool parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
596 bool parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
597 bool parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);
599 bool parseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
601 bool parseCVFunctionId(int64_t &FunctionId, StringRef DirectiveName);
602 bool parseCVFileId(int64_t &FileId, StringRef DirectiveName);
604 // Generic (target and platform independent) directive parsing.
606 DK_NO_DIRECTIVE, // Placeholder
607 DK_HANDLER_DIRECTIVE,
668 DK_CV_INLINE_SITE_ID,
671 DK_CV_INLINE_LINETABLE,
676 DK_CV_FILECHECKSUM_OFFSET,
682 DK_CFI_DEF_CFA_OFFSET,
683 DK_CFI_ADJUST_CFA_OFFSET,
684 DK_CFI_DEF_CFA_REGISTER,
689 DK_CFI_REMEMBER_STATE,
690 DK_CFI_RESTORE_STATE,
694 DK_CFI_RETURN_COLUMN,
724 /// Maps directive name --> DirectiveKind enum, for directives parsed by this
726 StringMap<DirectiveKind> DirectiveKindMap;
728 // Codeview def_range type parsing.
729 enum CVDefRangeType {
730 CVDR_DEFRANGE = 0, // Placeholder
731 CVDR_DEFRANGE_REGISTER,
732 CVDR_DEFRANGE_FRAMEPOINTER_REL,
733 CVDR_DEFRANGE_SUBFIELD_REGISTER,
734 CVDR_DEFRANGE_REGISTER_REL
737 /// Maps Codeview def_range types --> CVDefRangeType enum, for Codeview
738 /// def_range types parsed by this class.
739 StringMap<CVDefRangeType> CVDefRangeTypeMap;
741 bool parseInitValue(unsigned Size);
743 // ".ascii", ".asciz", ".string"
744 bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
746 // "byte", "word", ...
747 bool emitIntValue(const MCExpr *Value, unsigned Size);
748 bool parseScalarInitializer(unsigned Size,
749 SmallVectorImpl<const MCExpr *> &Values,
750 unsigned StringPadLength = 0);
751 bool parseScalarInstList(
752 unsigned Size, SmallVectorImpl<const MCExpr *> &Values,
753 const AsmToken::TokenKind EndToken = AsmToken::EndOfStatement);
754 bool emitIntegralValues(unsigned Size);
755 bool addIntegralField(StringRef Name, unsigned Size);
756 bool parseDirectiveValue(StringRef IDVal, unsigned Size);
757 bool parseDirectiveNamedValue(StringRef IDVal, unsigned Size, StringRef Name,
761 bool emitRealValues(const fltSemantics &Semantics);
762 bool addRealField(StringRef Name, const fltSemantics &Semantics);
763 bool parseDirectiveRealValue(StringRef IDVal, const fltSemantics &Semantics);
764 bool parseRealInstList(
765 const fltSemantics &Semantics, SmallVectorImpl<APInt> &Values,
766 const AsmToken::TokenKind EndToken = AsmToken::EndOfStatement);
767 bool parseDirectiveNamedRealValue(StringRef IDVal,
768 const fltSemantics &Semantics,
769 StringRef Name, SMLoc NameLoc);
771 bool parseOptionalAngleBracketOpen();
772 bool parseAngleBracketClose(const Twine &Msg = "expected '>'");
774 bool parseFieldInitializer(const FieldInfo &Field,
775 FieldInitializer &Initializer);
776 bool parseFieldInitializer(const FieldInfo &Field,
777 const IntFieldInfo &Contents,
778 FieldInitializer &Initializer);
779 bool parseFieldInitializer(const FieldInfo &Field,
780 const RealFieldInfo &Contents,
781 FieldInitializer &Initializer);
782 bool parseFieldInitializer(const FieldInfo &Field,
783 const StructFieldInfo &Contents,
784 FieldInitializer &Initializer);
786 bool parseStructInitializer(const StructInfo &Structure,
787 StructInitializer &Initializer);
788 bool parseStructInstList(
789 const StructInfo &Structure, std::vector<StructInitializer> &Initializers,
790 const AsmToken::TokenKind EndToken = AsmToken::EndOfStatement);
792 bool emitFieldValue(const FieldInfo &Field);
793 bool emitFieldValue(const FieldInfo &Field, const IntFieldInfo &Contents);
794 bool emitFieldValue(const FieldInfo &Field, const RealFieldInfo &Contents);
795 bool emitFieldValue(const FieldInfo &Field, const StructFieldInfo &Contents);
797 bool emitStructValue(const StructInfo &Structure);
799 bool emitFieldInitializer(const FieldInfo &Field,
800 const FieldInitializer &Initializer);
801 bool emitFieldInitializer(const FieldInfo &Field,
802 const IntFieldInfo &Contents,
803 const IntFieldInfo &Initializer);
804 bool emitFieldInitializer(const FieldInfo &Field,
805 const RealFieldInfo &Contents,
806 const RealFieldInfo &Initializer);
807 bool emitFieldInitializer(const FieldInfo &Field,
808 const StructFieldInfo &Contents,
809 const StructFieldInfo &Initializer);
811 bool emitStructInitializer(const StructInfo &Structure,
812 const StructInitializer &Initializer);
814 // User-defined types (structs, unions):
815 bool emitStructValues(const StructInfo &Structure);
816 bool addStructField(StringRef Name, const StructInfo &Structure);
817 bool parseDirectiveStructValue(const StructInfo &Structure,
818 StringRef Directive, SMLoc DirLoc);
819 bool parseDirectiveNamedStructValue(const StructInfo &Structure,
820 StringRef Directive, SMLoc DirLoc,
823 // "=", "equ", "textequ"
824 bool parseDirectiveEquate(StringRef IDVal, StringRef Name,
825 DirectiveKind DirKind);
827 bool parseDirectiveOrg(); // ".org"
828 bool parseDirectiveAlign(); // "align"
830 // ".file", ".line", ".loc", ".stabs"
831 bool parseDirectiveFile(SMLoc DirectiveLoc);
832 bool parseDirectiveLine();
833 bool parseDirectiveLoc();
834 bool parseDirectiveStabs();
836 // ".cv_file", ".cv_func_id", ".cv_inline_site_id", ".cv_loc", ".cv_linetable",
837 // ".cv_inline_linetable", ".cv_def_range", ".cv_string"
838 bool parseDirectiveCVFile();
839 bool parseDirectiveCVFuncId();
840 bool parseDirectiveCVInlineSiteId();
841 bool parseDirectiveCVLoc();
842 bool parseDirectiveCVLinetable();
843 bool parseDirectiveCVInlineLinetable();
844 bool parseDirectiveCVDefRange();
845 bool parseDirectiveCVString();
846 bool parseDirectiveCVStringTable();
847 bool parseDirectiveCVFileChecksums();
848 bool parseDirectiveCVFileChecksumOffset();
849 bool parseDirectiveCVFPOData();
852 bool parseDirectiveCFIRegister(SMLoc DirectiveLoc);
853 bool parseDirectiveCFIWindowSave();
854 bool parseDirectiveCFISections();
855 bool parseDirectiveCFIStartProc();
856 bool parseDirectiveCFIEndProc();
857 bool parseDirectiveCFIDefCfaOffset();
858 bool parseDirectiveCFIDefCfa(SMLoc DirectiveLoc);
859 bool parseDirectiveCFIAdjustCfaOffset();
860 bool parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc);
861 bool parseDirectiveCFIOffset(SMLoc DirectiveLoc);
862 bool parseDirectiveCFIRelOffset(SMLoc DirectiveLoc);
863 bool parseDirectiveCFIPersonalityOrLsda(bool IsPersonality);
864 bool parseDirectiveCFIRememberState();
865 bool parseDirectiveCFIRestoreState();
866 bool parseDirectiveCFISameValue(SMLoc DirectiveLoc);
867 bool parseDirectiveCFIRestore(SMLoc DirectiveLoc);
868 bool parseDirectiveCFIEscape();
869 bool parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc);
870 bool parseDirectiveCFISignalFrame();
871 bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc);
874 bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
875 bool parseDirectiveExitMacro(StringRef Directive);
876 bool parseDirectiveEndMacro(StringRef Directive);
877 bool parseDirectiveMacro(SMLoc DirectiveLoc);
878 // alternate macro mode directives
879 bool parseDirectiveAltmacro(StringRef Directive);
881 bool parseDirectiveStruct(StringRef Directive, DirectiveKind DirKind,
882 StringRef Name, SMLoc NameLoc);
883 bool parseDirectiveNestedStruct(StringRef Directive, DirectiveKind DirKind);
884 bool parseDirectiveEnds(StringRef Name, SMLoc NameLoc);
885 bool parseDirectiveNestedEnds();
887 /// Parse a directive like ".globl" which accepts a single symbol (which
888 /// should be a label or an external).
889 bool parseDirectiveSymbolAttribute(MCSymbolAttr Attr);
891 bool parseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm"
893 bool parseDirectiveComment(SMLoc DirectiveLoc); // "comment"
895 bool parseDirectiveInclude(); // "include"
898 bool parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind);
899 // "ifb" or "ifnb", depending on ExpectBlank.
900 bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank);
901 // "ifidn", "ifdif", "ifidni", or "ifdifi", depending on ExpectEqual and
903 bool parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
904 bool CaseInsensitive);
905 // "ifdef" or "ifndef", depending on expect_defined
906 bool parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined);
907 // "elseif" or "elseife"
908 bool parseDirectiveElseIf(SMLoc DirectiveLoc, DirectiveKind DirKind);
909 // "elseifb" or "elseifnb", depending on ExpectBlank.
910 bool parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank);
911 // ".elseifdef" or ".elseifndef", depending on expect_defined
912 bool parseDirectiveElseIfdef(SMLoc DirectiveLoc, bool expect_defined);
913 // "elseifidn", "elseifdif", "elseifidni", or "elseifdifi", depending on
914 // ExpectEqual and CaseInsensitive.
915 bool parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
916 bool CaseInsensitive);
917 bool parseDirectiveElse(SMLoc DirectiveLoc); // "else"
918 bool parseDirectiveEndIf(SMLoc DirectiveLoc); // "endif"
919 bool parseEscapedString(std::string &Data) override;
920 bool parseAngleBracketString(std::string &Data) override;
922 // Macro-like directives
923 MCAsmMacro *parseMacroLikeBody(SMLoc DirectiveLoc);
924 void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
925 raw_svector_ostream &OS);
926 bool parseDirectiveRept(SMLoc DirectiveLoc, StringRef Directive);
927 bool parseDirectiveIrp(SMLoc DirectiveLoc); // ".irp"
928 bool parseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc"
929 bool parseDirectiveEndr(SMLoc DirectiveLoc); // ".endr"
931 // "_emit" or "__emit"
932 bool parseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info,
936 bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info);
939 bool parseDirectiveEnd(SMLoc DirectiveLoc);
942 bool parseDirectiveError(SMLoc DirectiveLoc);
943 // ".errb" or ".errnb", depending on ExpectBlank.
944 bool parseDirectiveErrorIfb(SMLoc DirectiveLoc, bool ExpectBlank);
945 // ".errdef" or ".errndef", depending on ExpectBlank.
946 bool parseDirectiveErrorIfdef(SMLoc DirectiveLoc, bool ExpectDefined);
947 // ".erridn", ".errdif", ".erridni", or ".errdifi", depending on ExpectEqual
948 // and CaseInsensitive.
949 bool parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
950 bool CaseInsensitive);
951 // ".erre" or ".errnz", depending on ExpectZero.
952 bool parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero);
955 bool parseDirectiveEcho();
957 void initializeDirectiveKindMap();
958 void initializeCVDefRangeTypeMap();
961 } // end anonymous namespace
965 extern MCAsmParserExtension *createCOFFMasmParser();
967 } // end namespace llvm
969 enum { DEFAULT_ADDRSPACE = 0 };
971 MasmParser::MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
972 const MCAsmInfo &MAI, unsigned CB = 0)
973 : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM),
974 CurBuffer(CB ? CB : SM.getMainFileID()) {
976 // Save the old handler.
977 SavedDiagHandler = SrcMgr.getDiagHandler();
978 SavedDiagContext = SrcMgr.getDiagContext();
979 // Set our own handler which calls the saved handler.
980 SrcMgr.setDiagHandler(DiagHandler, this);
981 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
983 // Initialize the platform / file format parser.
984 switch (Ctx.getObjectFileInfo()->getObjectFileType()) {
985 case MCObjectFileInfo::IsCOFF:
986 PlatformParser.reset(createCOFFMasmParser());
989 report_fatal_error("llvm-ml currently supports only COFF output.");
993 initializeDirectiveKindMap();
994 PlatformParser->Initialize(*this);
995 initializeCVDefRangeTypeMap();
997 NumOfMacroInstantiations = 0;
1000 MasmParser::~MasmParser() {
1001 assert((HadError || ActiveMacros.empty()) &&
1002 "Unexpected active macro instantiation!");
1004 // Restore the saved diagnostics handler and context for use during
1006 SrcMgr.setDiagHandler(SavedDiagHandler, SavedDiagContext);
1009 void MasmParser::printMacroInstantiations() {
1010 // Print the active macro instantiation stack.
1011 for (std::vector<MacroInstantiation *>::const_reverse_iterator
1012 it = ActiveMacros.rbegin(),
1013 ie = ActiveMacros.rend();
1015 printMessage((*it)->InstantiationLoc, SourceMgr::DK_Note,
1016 "while in macro instantiation");
1019 void MasmParser::Note(SMLoc L, const Twine &Msg, SMRange Range) {
1020 printPendingErrors();
1021 printMessage(L, SourceMgr::DK_Note, Msg, Range);
1022 printMacroInstantiations();
1025 bool MasmParser::Warning(SMLoc L, const Twine &Msg, SMRange Range) {
1026 if (getTargetParser().getTargetOptions().MCNoWarn)
1028 if (getTargetParser().getTargetOptions().MCFatalWarnings)
1029 return Error(L, Msg, Range);
1030 printMessage(L, SourceMgr::DK_Warning, Msg, Range);
1031 printMacroInstantiations();
1035 bool MasmParser::printError(SMLoc L, const Twine &Msg, SMRange Range) {
1037 printMessage(L, SourceMgr::DK_Error, Msg, Range);
1038 printMacroInstantiations();
1042 bool MasmParser::enterIncludeFile(const std::string &Filename) {
1043 std::string IncludedFile;
1045 SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
1050 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
1054 void MasmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer) {
1055 CurBuffer = InBuffer ? InBuffer : SrcMgr.FindBufferContainingLoc(Loc);
1056 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(),
1060 const AsmToken &MasmParser::Lex() {
1061 if (Lexer.getTok().is(AsmToken::Error))
1062 Error(Lexer.getErrLoc(), Lexer.getErr());
1064 // if it's a end of statement with a comment in it
1065 if (getTok().is(AsmToken::EndOfStatement)) {
1066 // if this is a line comment output it.
1067 if (!getTok().getString().empty() && getTok().getString().front() != '\n' &&
1068 getTok().getString().front() != '\r' && MAI.preserveAsmComments())
1069 Out.addExplicitComment(Twine(getTok().getString()));
1072 const AsmToken *tok = &Lexer.Lex();
1074 while (tok->is(AsmToken::Identifier)) {
1075 auto it = Variables.find(tok->getIdentifier());
1076 if (it != Variables.end() && it->second.IsText) {
1077 std::unique_ptr<MemoryBuffer> Instantiation =
1078 MemoryBuffer::getMemBufferCopy(it->second.TextValue,
1081 // Jump to the macro instantiation and prime the lexer.
1082 CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation),
1083 getTok().getEndLoc());
1084 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(), nullptr,
1085 /*EndStatementAtEOF=*/false);
1092 // Parse comments here to be deferred until end of next statement.
1093 while (tok->is(AsmToken::Comment)) {
1094 if (MAI.preserveAsmComments())
1095 Out.addExplicitComment(Twine(tok->getString()));
1099 if (tok->is(AsmToken::Eof)) {
1100 // If this is the end of an included file, pop the parent file off the
1102 SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
1103 if (ParentIncludeLoc != SMLoc()) {
1104 jumpToLoc(ParentIncludeLoc);
1112 bool MasmParser::enabledGenDwarfForAssembly() {
1113 // Check whether the user specified -g.
1114 if (!getContext().getGenDwarfForAssembly())
1116 // If we haven't encountered any .file directives (which would imply that
1117 // the assembler source was produced with debug info already) then emit one
1118 // describing the assembler source file itself.
1119 if (getContext().getGenDwarfFileNumber() == 0) {
1120 // Use the first #line directive for this, if any. It's preprocessed, so
1121 // there is no checksum, and of course no source directive.
1122 if (!FirstCppHashFilename.empty())
1123 getContext().setMCLineTableRootFile(/*CUID=*/0,
1124 getContext().getCompilationDir(),
1125 FirstCppHashFilename,
1126 /*Cksum=*/None, /*Source=*/None);
1127 const MCDwarfFile &RootFile =
1128 getContext().getMCDwarfLineTable(/*CUID=*/0).getRootFile();
1129 getContext().setGenDwarfFileNumber(getStreamer().emitDwarfFileDirective(
1130 /*CUID=*/0, getContext().getCompilationDir(), RootFile.Name,
1131 RootFile.Checksum, RootFile.Source));
1136 bool MasmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
1137 // Create the initial section, if requested.
1138 if (!NoInitialTextSection)
1139 Out.InitSections(false);
1145 AsmCond StartingCondState = TheCondState;
1146 SmallVector<AsmRewrite, 4> AsmStrRewrites;
1148 // If we are generating dwarf for assembly source files save the initial text
1149 // section. (Don't use enabledGenDwarfForAssembly() here, as we aren't
1150 // emitting any actual debug info yet and haven't had a chance to parse any
1151 // embedded .file directives.)
1152 if (getContext().getGenDwarfForAssembly()) {
1153 MCSection *Sec = getStreamer().getCurrentSectionOnly();
1154 if (!Sec->getBeginSymbol()) {
1155 MCSymbol *SectionStartSym = getContext().createTempSymbol();
1156 getStreamer().emitLabel(SectionStartSym);
1157 Sec->setBeginSymbol(SectionStartSym);
1159 bool InsertResult = getContext().addGenDwarfSection(Sec);
1160 assert(InsertResult && ".text section should not have debug info yet");
1164 // While we have input, parse each statement.
1165 while (Lexer.isNot(AsmToken::Eof)) {
1166 ParseStatementInfo Info(&AsmStrRewrites);
1167 bool Parsed = parseStatement(Info, nullptr);
1169 // If we have a Lexer Error we are on an Error Token. Load in Lexer Error
1170 // for printing ErrMsg via Lex() only if no (presumably better) parser error
1172 if (Parsed && !hasPendingError() && Lexer.getTok().is(AsmToken::Error)) {
1176 // parseStatement returned true so may need to emit an error.
1177 printPendingErrors();
1179 // Skipping to the next line if needed.
1180 if (Parsed && !getLexer().isAtStartOfStatement())
1181 eatToEndOfStatement();
1184 getTargetParser().onEndOfFile();
1185 printPendingErrors();
1187 // All errors should have been emitted.
1188 assert(!hasPendingError() && "unexpected error from parseStatement");
1190 getTargetParser().flushPendingInstructions(getStreamer());
1192 if (TheCondState.TheCond != StartingCondState.TheCond ||
1193 TheCondState.Ignore != StartingCondState.Ignore)
1194 printError(getTok().getLoc(), "unmatched .ifs or .elses");
1195 // Check to see there are no empty DwarfFile slots.
1196 const auto &LineTables = getContext().getMCDwarfLineTables();
1197 if (!LineTables.empty()) {
1199 for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
1200 if (File.Name.empty() && Index != 0)
1201 printError(getTok().getLoc(), "unassigned file number: " +
1203 " for .file directives");
1208 // Check to see that all assembler local symbols were actually defined.
1209 // Targets that don't do subsections via symbols may not want this, though,
1210 // so conservatively exclude them. Only do this if we're finalizing, though,
1211 // as otherwise we won't necessarilly have seen everything yet.
1213 if (MAI.hasSubsectionsViaSymbols()) {
1214 for (const auto &TableEntry : getContext().getSymbols()) {
1215 MCSymbol *Sym = TableEntry.getValue();
1216 // Variable symbols may not be marked as defined, so check those
1217 // explicitly. If we know it's a variable, we have a definition for
1218 // the purposes of this check.
1219 if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined())
1220 // FIXME: We would really like to refer back to where the symbol was
1221 // first referenced for a source location. We need to add something
1222 // to track that. Currently, we just point to the end of the file.
1223 printError(getTok().getLoc(), "assembler local symbol '" +
1224 Sym->getName() + "' not defined");
1228 // Temporary symbols like the ones for directional jumps don't go in the
1229 // symbol table. They also need to be diagnosed in all (final) cases.
1230 for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
1231 if (std::get<2>(LocSym)->isUndefined()) {
1232 // Reset the state of any "# line file" directives we've seen to the
1233 // context as it was at the diagnostic site.
1234 CppHashInfo = std::get<1>(LocSym);
1235 printError(std::get<0>(LocSym), "directional label undefined");
1240 // Finalize the output stream if there are no errors and if the client wants
1242 if (!HadError && !NoFinalize)
1245 return HadError || getContext().hadError();
1248 bool MasmParser::checkForValidSection() {
1249 if (!ParsingMSInlineAsm && !getStreamer().getCurrentSectionOnly()) {
1250 Out.InitSections(false);
1251 return Error(getTok().getLoc(),
1252 "expected section directive before assembly directive");
1257 /// Throw away the rest of the line for testing purposes.
1258 void MasmParser::eatToEndOfStatement() {
1259 while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
1263 if (Lexer.is(AsmToken::EndOfStatement))
1267 StringRef MasmParser::parseStringToEndOfStatement() {
1268 const char *Start = getTok().getLoc().getPointer();
1270 while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
1273 const char *End = getTok().getLoc().getPointer();
1274 return StringRef(Start, End - Start);
1277 /// Parse a paren expression and return it.
1278 /// NOTE: This assumes the leading '(' has already been consumed.
1280 /// parenexpr ::= expr)
1282 bool MasmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
1283 if (parseExpression(Res))
1285 if (Lexer.isNot(AsmToken::RParen))
1286 return TokError("expected ')' in parentheses expression");
1287 EndLoc = Lexer.getTok().getEndLoc();
1292 /// Parse a bracket expression and return it.
1293 /// NOTE: This assumes the leading '[' has already been consumed.
1295 /// bracketexpr ::= expr]
1297 bool MasmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
1298 if (parseExpression(Res))
1300 EndLoc = getTok().getEndLoc();
1301 if (parseToken(AsmToken::RBrac, "expected ']' in brackets expression"))
1306 /// Parse a primary expression and return it.
1307 /// primaryexpr ::= (parenexpr
1308 /// primaryexpr ::= symbol
1309 /// primaryexpr ::= number
1310 /// primaryexpr ::= '.'
1311 /// primaryexpr ::= ~,+,- primaryexpr
1312 bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
1313 SMLoc FirstTokenLoc = getLexer().getLoc();
1314 AsmToken::TokenKind FirstTokenKind = Lexer.getKind();
1315 switch (FirstTokenKind) {
1317 return TokError("unknown token in expression");
1318 // If we have an error assume that we've already handled it.
1319 case AsmToken::Error:
1321 case AsmToken::Exclaim:
1322 Lex(); // Eat the operator.
1323 if (parsePrimaryExpr(Res, EndLoc))
1325 Res = MCUnaryExpr::createLNot(Res, getContext(), FirstTokenLoc);
1327 case AsmToken::Dollar:
1329 case AsmToken::String:
1330 case AsmToken::Identifier: {
1331 StringRef Identifier;
1332 if (parseIdentifier(Identifier)) {
1333 // We may have failed but $ may be a valid token.
1334 if (getTok().is(AsmToken::Dollar)) {
1335 if (Lexer.getMAI().getDollarIsPC()) {
1337 // This is a '$' reference, which references the current PC. Emit a
1338 // temporary label to the streamer and refer to it.
1339 MCSymbol *Sym = Ctx.createTempSymbol();
1341 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
1343 EndLoc = FirstTokenLoc;
1346 return Error(FirstTokenLoc, "invalid token in expression");
1349 // Parse symbol variant.
1350 std::pair<StringRef, StringRef> Split;
1351 if (!MAI.useParensForSymbolVariant()) {
1352 if (FirstTokenKind == AsmToken::String) {
1353 if (Lexer.is(AsmToken::At)) {
1355 SMLoc AtLoc = getLexer().getLoc();
1357 if (parseIdentifier(VName))
1358 return Error(AtLoc, "expected symbol variant after '@'");
1360 Split = std::make_pair(Identifier, VName);
1363 Split = Identifier.split('@');
1365 } else if (Lexer.is(AsmToken::LParen)) {
1368 parseIdentifier(VName);
1370 if (parseToken(AsmToken::RParen,
1371 "unexpected token in variant, expected ')'"))
1373 Split = std::make_pair(Identifier, VName);
1376 EndLoc = SMLoc::getFromPointer(Identifier.end());
1378 // This is a symbol reference.
1379 StringRef SymbolName = Identifier;
1380 if (SymbolName.empty())
1381 return Error(getLexer().getLoc(), "expected a symbol reference");
1383 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1385 // Look up the symbol variant if used.
1386 if (!Split.second.empty()) {
1387 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
1388 if (Variant != MCSymbolRefExpr::VK_Invalid) {
1389 SymbolName = Split.first;
1390 } else if (MAI.doesAllowAtInName() && !MAI.useParensForSymbolVariant()) {
1391 Variant = MCSymbolRefExpr::VK_None;
1393 return Error(SMLoc::getFromPointer(Split.second.begin()),
1394 "invalid variant '" + Split.second + "'");
1398 // Find the field offset if used.
1400 unsigned Offset = 0;
1401 Split = SymbolName.split('.');
1402 if (!Split.second.empty()) {
1403 SymbolName = Split.first;
1404 if (Structs.count(SymbolName.lower()) &&
1405 !lookUpField(SymbolName, Split.second, Type, Offset)) {
1406 // This is actually a reference to a field offset.
1407 Res = MCConstantExpr::create(Offset, getContext());
1411 auto TypeIt = KnownType.find(SymbolName);
1412 if (TypeIt == KnownType.end() ||
1413 lookUpField(*TypeIt->second, Split.second, Type, Offset)) {
1414 std::pair<StringRef, StringRef> BaseMember = Split.second.split('.');
1415 StringRef Base = BaseMember.first, Member = BaseMember.second;
1416 lookUpField(Base, Member, Type, Offset);
1420 MCSymbol *Sym = getContext().getInlineAsmLabel(SymbolName);
1422 Sym = getContext().getOrCreateSymbol(SymbolName);
1424 // If this is an absolute variable reference, substitute it now to preserve
1425 // semantics in the face of reassignment.
1426 if (Sym->isVariable()) {
1427 auto V = Sym->getVariableValue(/*SetUsed*/ false);
1428 bool DoInline = isa<MCConstantExpr>(V) && !Variant;
1429 if (auto TV = dyn_cast<MCTargetExpr>(V))
1430 DoInline = TV->inlineAssignedExpr();
1433 return Error(EndLoc, "unexpected modifier on variable reference");
1434 Res = Sym->getVariableValue(/*SetUsed*/ false);
1439 // Otherwise create a symbol ref.
1440 const MCExpr *SymRef =
1441 MCSymbolRefExpr::create(Sym, Variant, getContext(), FirstTokenLoc);
1443 Res = MCBinaryExpr::create(MCBinaryExpr::Add, SymRef,
1444 MCConstantExpr::create(Offset, getContext()),
1451 case AsmToken::BigNum:
1452 return TokError("literal value out of range for directive");
1453 case AsmToken::Integer: {
1454 SMLoc Loc = getTok().getLoc();
1455 int64_t IntVal = getTok().getIntVal();
1456 Res = MCConstantExpr::create(IntVal, getContext());
1457 EndLoc = Lexer.getTok().getEndLoc();
1458 Lex(); // Eat token.
1459 // Look for 'b' or 'f' following an Integer as a directional label.
1460 if (Lexer.getKind() == AsmToken::Identifier) {
1461 StringRef IDVal = getTok().getString();
1462 // Look up the symbol variant if used.
1463 std::pair<StringRef, StringRef> Split = IDVal.split('@');
1464 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1465 if (Split.first.size() != IDVal.size()) {
1466 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
1467 if (Variant == MCSymbolRefExpr::VK_Invalid)
1468 return TokError("invalid variant '" + Split.second + "'");
1469 IDVal = Split.first;
1471 if (IDVal == "f" || IDVal == "b") {
1473 Ctx.getDirectionalLocalSymbol(IntVal, IDVal == "b");
1474 Res = MCSymbolRefExpr::create(Sym, Variant, getContext());
1475 if (IDVal == "b" && Sym->isUndefined())
1476 return Error(Loc, "directional label undefined");
1477 DirLabels.push_back(std::make_tuple(Loc, CppHashInfo, Sym));
1478 EndLoc = Lexer.getTok().getEndLoc();
1479 Lex(); // Eat identifier.
1484 case AsmToken::Real: {
1485 APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
1486 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
1487 Res = MCConstantExpr::create(IntVal, getContext());
1488 EndLoc = Lexer.getTok().getEndLoc();
1489 Lex(); // Eat token.
1492 case AsmToken::Dot: {
1493 // This is a '.' reference, which references the current PC. Emit a
1494 // temporary label to the streamer and refer to it.
1495 MCSymbol *Sym = Ctx.createTempSymbol();
1497 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1498 EndLoc = Lexer.getTok().getEndLoc();
1499 Lex(); // Eat identifier.
1502 case AsmToken::LParen:
1503 Lex(); // Eat the '('.
1504 return parseParenExpr(Res, EndLoc);
1505 case AsmToken::LBrac:
1506 if (!PlatformParser->HasBracketExpressions())
1507 return TokError("brackets expression not supported on this target");
1508 Lex(); // Eat the '['.
1509 return parseBracketExpr(Res, EndLoc);
1510 case AsmToken::Minus:
1511 Lex(); // Eat the operator.
1512 if (parsePrimaryExpr(Res, EndLoc))
1514 Res = MCUnaryExpr::createMinus(Res, getContext(), FirstTokenLoc);
1516 case AsmToken::Plus:
1517 Lex(); // Eat the operator.
1518 if (parsePrimaryExpr(Res, EndLoc))
1520 Res = MCUnaryExpr::createPlus(Res, getContext(), FirstTokenLoc);
1522 case AsmToken::Tilde:
1523 Lex(); // Eat the operator.
1524 if (parsePrimaryExpr(Res, EndLoc))
1526 Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc);
1528 // MIPS unary expression operators. The lexer won't generate these tokens if
1529 // MCAsmInfo::HasMipsExpressions is false for the target.
1530 case AsmToken::PercentCall16:
1531 case AsmToken::PercentCall_Hi:
1532 case AsmToken::PercentCall_Lo:
1533 case AsmToken::PercentDtprel_Hi:
1534 case AsmToken::PercentDtprel_Lo:
1535 case AsmToken::PercentGot:
1536 case AsmToken::PercentGot_Disp:
1537 case AsmToken::PercentGot_Hi:
1538 case AsmToken::PercentGot_Lo:
1539 case AsmToken::PercentGot_Ofst:
1540 case AsmToken::PercentGot_Page:
1541 case AsmToken::PercentGottprel:
1542 case AsmToken::PercentGp_Rel:
1543 case AsmToken::PercentHi:
1544 case AsmToken::PercentHigher:
1545 case AsmToken::PercentHighest:
1546 case AsmToken::PercentLo:
1547 case AsmToken::PercentNeg:
1548 case AsmToken::PercentPcrel_Hi:
1549 case AsmToken::PercentPcrel_Lo:
1550 case AsmToken::PercentTlsgd:
1551 case AsmToken::PercentTlsldm:
1552 case AsmToken::PercentTprel_Hi:
1553 case AsmToken::PercentTprel_Lo:
1554 Lex(); // Eat the operator.
1555 if (Lexer.isNot(AsmToken::LParen))
1556 return TokError("expected '(' after operator");
1557 Lex(); // Eat the operator.
1558 if (parseExpression(Res, EndLoc))
1560 if (Lexer.isNot(AsmToken::RParen))
1561 return TokError("expected ')'");
1562 Lex(); // Eat the operator.
1563 Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx);
1568 bool MasmParser::parseExpression(const MCExpr *&Res) {
1570 return parseExpression(Res, EndLoc);
1573 /// This function checks if the next token is <string> type or arithmetic.
1574 /// string that begin with character '<' must end with character '>'.
1575 /// otherwise it is arithmetics.
1576 /// If the function returns a 'true' value,
1577 /// the End argument will be filled with the last location pointed to the '>'
1580 /// There is a gap between the AltMacro's documentation and the single quote
1581 /// implementation. GCC does not fully support this feature and so we will not
1583 /// TODO: Adding single quote as a string.
1584 static bool isAngleBracketString(SMLoc &StrLoc, SMLoc &EndLoc) {
1585 assert((StrLoc.getPointer() != nullptr) &&
1586 "Argument to the function cannot be a NULL value");
1587 const char *CharPtr = StrLoc.getPointer();
1588 while ((*CharPtr != '>') && (*CharPtr != '\n') && (*CharPtr != '\r') &&
1589 (*CharPtr != '\0')) {
1590 if (*CharPtr == '!')
1594 if (*CharPtr == '>') {
1595 EndLoc = StrLoc.getFromPointer(CharPtr + 1);
1601 /// creating a string without the escape characters '!'.
1602 static std::string angleBracketString(StringRef AltMacroStr) {
1604 for (size_t Pos = 0; Pos < AltMacroStr.size(); Pos++) {
1605 if (AltMacroStr[Pos] == '!')
1607 Res += AltMacroStr[Pos];
1612 /// Parse an expression and return it.
1614 /// expr ::= expr &&,|| expr -> lowest.
1615 /// expr ::= expr |,^,&,! expr
1616 /// expr ::= expr ==,!=,<>,<,<=,>,>= expr
1617 /// expr ::= expr <<,>> expr
1618 /// expr ::= expr +,- expr
1619 /// expr ::= expr *,/,% expr -> highest.
1620 /// expr ::= primaryexpr
1622 bool MasmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
1623 // Parse the expression.
1625 if (getTargetParser().parsePrimaryExpr(Res, EndLoc) ||
1626 parseBinOpRHS(1, Res, EndLoc))
1629 // Try to constant fold it up front, if possible. Do not exploit
1632 if (Res->evaluateAsAbsolute(Value))
1633 Res = MCConstantExpr::create(Value, getContext());
1638 bool MasmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
1640 return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
1643 bool MasmParser::parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
1645 if (parseParenExpr(Res, EndLoc))
1648 for (; ParenDepth > 0; --ParenDepth) {
1649 if (parseBinOpRHS(1, Res, EndLoc))
1652 // We don't Lex() the last RParen.
1653 // This is the same behavior as parseParenExpression().
1654 if (ParenDepth - 1 > 0) {
1655 EndLoc = getTok().getEndLoc();
1656 if (parseToken(AsmToken::RParen,
1657 "expected ')' in parentheses expression"))
1664 bool MasmParser::parseAbsoluteExpression(int64_t &Res) {
1667 SMLoc StartLoc = Lexer.getLoc();
1668 if (parseExpression(Expr))
1671 if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1672 return Error(StartLoc, "expected absolute expression");
1677 static unsigned getGNUBinOpPrecedence(AsmToken::TokenKind K,
1678 MCBinaryExpr::Opcode &Kind,
1679 bool ShouldUseLogicalShr,
1680 bool EndExpressionAtGreater) {
1683 return 0; // not a binop.
1685 // Lowest Precedence: &&, ||
1686 case AsmToken::AmpAmp:
1687 Kind = MCBinaryExpr::LAnd;
1689 case AsmToken::PipePipe:
1690 Kind = MCBinaryExpr::LOr;
1693 // Low Precedence: ==, !=, <>, <, <=, >, >=
1694 case AsmToken::EqualEqual:
1695 Kind = MCBinaryExpr::EQ;
1697 case AsmToken::ExclaimEqual:
1698 case AsmToken::LessGreater:
1699 Kind = MCBinaryExpr::NE;
1701 case AsmToken::Less:
1702 Kind = MCBinaryExpr::LT;
1704 case AsmToken::LessEqual:
1705 Kind = MCBinaryExpr::LTE;
1707 case AsmToken::Greater:
1708 if (EndExpressionAtGreater)
1710 Kind = MCBinaryExpr::GT;
1712 case AsmToken::GreaterEqual:
1713 Kind = MCBinaryExpr::GTE;
1716 // Low Intermediate Precedence: +, -
1717 case AsmToken::Plus:
1718 Kind = MCBinaryExpr::Add;
1720 case AsmToken::Minus:
1721 Kind = MCBinaryExpr::Sub;
1724 // High Intermediate Precedence: |, &, ^
1726 // FIXME: gas seems to support '!' as an infix operator?
1727 case AsmToken::Pipe:
1728 Kind = MCBinaryExpr::Or;
1730 case AsmToken::Caret:
1731 Kind = MCBinaryExpr::Xor;
1734 Kind = MCBinaryExpr::And;
1737 // Highest Precedence: *, /, %, <<, >>
1738 case AsmToken::Star:
1739 Kind = MCBinaryExpr::Mul;
1741 case AsmToken::Slash:
1742 Kind = MCBinaryExpr::Div;
1744 case AsmToken::Percent:
1745 Kind = MCBinaryExpr::Mod;
1747 case AsmToken::LessLess:
1748 Kind = MCBinaryExpr::Shl;
1750 case AsmToken::GreaterGreater:
1751 if (EndExpressionAtGreater)
1753 Kind = ShouldUseLogicalShr ? MCBinaryExpr::LShr : MCBinaryExpr::AShr;
1758 unsigned MasmParser::getBinOpPrecedence(AsmToken::TokenKind K,
1759 MCBinaryExpr::Opcode &Kind) {
1760 bool ShouldUseLogicalShr = MAI.shouldUseLogicalShr();
1761 return getGNUBinOpPrecedence(K, Kind, ShouldUseLogicalShr,
1762 AngleBracketDepth > 0);
1765 /// Parse all binary operators with precedence >= 'Precedence'.
1766 /// Res contains the LHS of the expression on input.
1767 bool MasmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
1769 SMLoc StartLoc = Lexer.getLoc();
1771 MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
1772 unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
1774 // If the next token is lower precedence than we are allowed to eat, return
1775 // successfully with what we ate already.
1776 if (TokPrec < Precedence)
1781 // Eat the next primary expression.
1783 if (getTargetParser().parsePrimaryExpr(RHS, EndLoc))
1786 // If BinOp binds less tightly with RHS than the operator after RHS, let
1787 // the pending operator take RHS as its LHS.
1788 MCBinaryExpr::Opcode Dummy;
1789 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
1790 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
1793 // Merge LHS and RHS according to operator.
1794 Res = MCBinaryExpr::create(Kind, Res, RHS, getContext(), StartLoc);
1799 /// ::= EndOfStatement
1800 /// ::= Label* Directive ...Operands... EndOfStatement
1801 /// ::= Label* Identifier OperandList* EndOfStatement
1802 bool MasmParser::parseStatement(ParseStatementInfo &Info,
1803 MCAsmParserSemaCallback *SI) {
1804 assert(!hasPendingError() && "parseStatement started with pending error");
1805 // Eat initial spaces and comments.
1806 while (Lexer.is(AsmToken::Space))
1808 if (Lexer.is(AsmToken::EndOfStatement)) {
1809 // If this is a line comment we can drop it safely.
1810 if (getTok().getString().empty() || getTok().getString().front() == '\r' ||
1811 getTok().getString().front() == '\n')
1816 // Statements always start with an identifier, unless we're dealing with a
1817 // processor directive (.386, .686, etc.) that lexes as a real.
1818 AsmToken ID = getTok();
1819 SMLoc IDLoc = ID.getLoc();
1821 int64_t LocalLabelVal = -1;
1822 if (Lexer.is(AsmToken::HashDirective))
1823 return parseCppHashLineFilenameComment(IDLoc);
1824 // Allow an integer followed by a ':' as a directional local label.
1825 if (Lexer.is(AsmToken::Integer)) {
1826 LocalLabelVal = getTok().getIntVal();
1827 if (LocalLabelVal < 0) {
1828 if (!TheCondState.Ignore) {
1829 Lex(); // always eat a token
1830 return Error(IDLoc, "unexpected token at start of statement");
1834 IDVal = getTok().getString();
1835 Lex(); // Consume the integer token to be used as an identifier token.
1836 if (Lexer.getKind() != AsmToken::Colon) {
1837 if (!TheCondState.Ignore) {
1838 Lex(); // always eat a token
1839 return Error(IDLoc, "unexpected token at start of statement");
1843 } else if (Lexer.is(AsmToken::Dot)) {
1844 // Treat '.' as a valid identifier in this context.
1847 } else if (Lexer.is(AsmToken::LCurly)) {
1848 // Treat '{' as a valid identifier in this context.
1852 } else if (Lexer.is(AsmToken::RCurly)) {
1853 // Treat '}' as a valid identifier in this context.
1856 } else if (Lexer.is(AsmToken::Star) &&
1857 getTargetParser().starIsStartOfStatement()) {
1858 // Accept '*' as a valid start of statement.
1861 } else if (Lexer.is(AsmToken::Real)) {
1862 // Treat ".<number>" as a valid identifier in this context.
1863 IDVal = getTok().getString();
1864 Lex(); // always eat a token
1865 if (!IDVal.startswith("."))
1866 return Error(IDLoc, "unexpected token at start of statement");
1867 } else if (parseIdentifier(IDVal)) {
1868 if (!TheCondState.Ignore) {
1869 Lex(); // always eat a token
1870 return Error(IDLoc, "unexpected token at start of statement");
1875 // Handle conditional assembly here before checking for skipping. We
1876 // have to do this so that .endif isn't skipped in a ".if 0" block for
1878 StringMap<DirectiveKind>::const_iterator DirKindIt =
1879 DirectiveKindMap.find(IDVal.lower());
1880 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
1882 : DirKindIt->getValue();
1888 return parseDirectiveIf(IDLoc, DirKind);
1890 return parseDirectiveIfb(IDLoc, true);
1892 return parseDirectiveIfb(IDLoc, false);
1894 return parseDirectiveIfdef(IDLoc, true);
1896 return parseDirectiveIfdef(IDLoc, false);
1898 return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/false,
1899 /*CaseInsensitive=*/false);
1901 return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/false,
1902 /*CaseInsensitive=*/true);
1904 return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/true,
1905 /*CaseInsensitive=*/false);
1907 return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/true,
1908 /*CaseInsensitive=*/true);
1911 return parseDirectiveElseIf(IDLoc, DirKind);
1913 return parseDirectiveElseIfb(IDLoc, true);
1915 return parseDirectiveElseIfb(IDLoc, false);
1917 return parseDirectiveElseIfdef(IDLoc, true);
1919 return parseDirectiveElseIfdef(IDLoc, false);
1921 return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/false,
1922 /*CaseInsensitive=*/false);
1924 return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/false,
1925 /*CaseInsensitive=*/true);
1927 return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/true,
1928 /*CaseInsensitive=*/false);
1930 return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/true,
1931 /*CaseInsensitive=*/true);
1933 return parseDirectiveElse(IDLoc);
1935 return parseDirectiveEndIf(IDLoc);
1938 // Ignore the statement if in the middle of inactive conditional
1940 if (TheCondState.Ignore) {
1941 eatToEndOfStatement();
1945 // FIXME: Recurse on local labels?
1947 // See what kind of statement we have.
1948 switch (Lexer.getKind()) {
1949 case AsmToken::Colon: {
1950 if (!getTargetParser().isLabel(ID))
1952 if (checkForValidSection())
1955 // identifier ':' -> Label.
1958 // Diagnose attempt to use '.' as a label.
1960 return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label");
1962 // Diagnose attempt to use a variable as a label.
1964 // FIXME: Diagnostics. Note the location of the definition as a label.
1965 // FIXME: This doesn't diagnose assignment to a symbol which has been
1966 // implicitly marked as external.
1968 if (LocalLabelVal == -1) {
1969 if (ParsingMSInlineAsm && SI) {
1970 StringRef RewrittenLabel =
1971 SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true);
1972 assert(!RewrittenLabel.empty() &&
1973 "We should have an internal name here.");
1974 Info.AsmRewrites->emplace_back(AOK_Label, IDLoc, IDVal.size(),
1976 IDVal = RewrittenLabel;
1978 Sym = getContext().getOrCreateSymbol(IDVal);
1980 Sym = Ctx.createDirectionalLocalSymbol(LocalLabelVal);
1981 // End of Labels should be treated as end of line for lexing
1982 // purposes but that information is not available to the Lexer who
1983 // does not understand Labels. This may cause us to see a Hash
1984 // here instead of a preprocessor line comment.
1985 if (getTok().is(AsmToken::Hash)) {
1986 StringRef CommentStr = parseStringToEndOfStatement();
1988 Lexer.UnLex(AsmToken(AsmToken::EndOfStatement, CommentStr));
1991 // Consume any end of statement token, if present, to avoid spurious
1992 // AddBlankLine calls().
1993 if (getTok().is(AsmToken::EndOfStatement)) {
1997 getTargetParser().doBeforeLabelEmit(Sym);
2000 if (!getTargetParser().isParsingMSInlineAsm())
2001 Out.emitLabel(Sym, IDLoc);
2003 // If we are generating dwarf for assembly source files then gather the
2004 // info to make a dwarf label entry for this label if needed.
2005 if (enabledGenDwarfForAssembly())
2006 MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(),
2009 getTargetParser().onLabelParsed(Sym);
2014 default: // Normal instruction or directive.
2018 // If macros are enabled, check to see if this is a macro instantiation.
2019 if (const MCAsmMacro *M = getContext().lookupMacro(IDVal)) {
2020 return handleMacroEntry(M, IDLoc);
2023 // Otherwise, we have a normal instruction or directive.
2025 if (DirKind != DK_NO_DIRECTIVE) {
2026 // There are several entities interested in parsing directives:
2028 // 1. Asm parser extensions. For example, platform-specific parsers
2029 // (like the ELF parser) register themselves as extensions.
2030 // 2. The target-specific assembly parser. Some directives are target
2031 // specific or may potentially behave differently on certain targets.
2032 // 3. The generic directive parser implemented by this class. These are
2033 // all the directives that behave in a target and platform independent
2034 // manner, or at least have a default behavior that's shared between
2035 // all targets and platforms.
2037 getTargetParser().flushPendingInstructions(getStreamer());
2039 // Special-case handling of structure-end directives at higher priority,
2040 // since ENDS is overloaded as a segment-end directive.
2041 if (IDVal.equals_lower("ends") && StructInProgress.size() > 1 &&
2042 getTok().is(AsmToken::EndOfStatement)) {
2043 return parseDirectiveNestedEnds();
2046 // First, check the extension directive map to see if any extension has
2047 // registered itself to parse this directive.
2048 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2049 ExtensionDirectiveMap.lookup(IDVal.lower());
2051 return (*Handler.second)(Handler.first, IDVal, IDLoc);
2053 // Next, let the target-specific assembly parser try.
2054 SMLoc StartTokLoc = getTok().getLoc();
2055 bool TPDirectiveReturn =
2056 ID.is(AsmToken::Identifier) && getTargetParser().ParseDirective(ID);
2058 if (hasPendingError())
2060 // Currently the return value should be true if we are
2061 // uninterested but as this is at odds with the standard parsing
2062 // convention (return true = error) we have instances of a parsed
2063 // directive that fails returning true as an error. Catch these
2064 // cases as best as possible errors here.
2065 if (TPDirectiveReturn && StartTokLoc != getTok().getLoc())
2067 // Return if we did some parsing or believe we succeeded.
2068 if (!TPDirectiveReturn || StartTokLoc != getTok().getLoc())
2071 // Finally, if no one else is interested in this directive, it must be
2072 // generic and familiar to this class.
2077 return parseDirectiveAscii(IDVal, false);
2080 return parseDirectiveAscii(IDVal, true);
2084 return parseDirectiveValue(IDVal, 1);
2088 return parseDirectiveValue(IDVal, 2);
2092 return parseDirectiveValue(IDVal, 4);
2094 return parseDirectiveValue(IDVal, 6);
2098 return parseDirectiveValue(IDVal, 8);
2100 return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle());
2102 return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble());
2105 return parseDirectiveNestedStruct(IDVal, DirKind);
2107 return parseDirectiveNestedEnds();
2109 return parseDirectiveAlign();
2111 return parseDirectiveOrg();
2113 eatToEndOfStatement(); // .extern is the default, ignore it.
2116 return parseDirectiveSymbolAttribute(MCSA_Global);
2118 return parseDirectiveComm(/*IsLocal=*/false);
2120 return parseDirectiveComment(IDLoc);
2122 return parseDirectiveInclude();
2124 return parseDirectiveRept(IDLoc, IDVal);
2126 return parseDirectiveIrp(IDLoc);
2128 return parseDirectiveIrpc(IDLoc);
2130 return parseDirectiveEndr(IDLoc);
2132 return parseDirectiveFile(IDLoc);
2134 return parseDirectiveLine();
2136 return parseDirectiveLoc();
2138 return parseDirectiveStabs();
2140 return parseDirectiveCVFile();
2142 return parseDirectiveCVFuncId();
2143 case DK_CV_INLINE_SITE_ID:
2144 return parseDirectiveCVInlineSiteId();
2146 return parseDirectiveCVLoc();
2147 case DK_CV_LINETABLE:
2148 return parseDirectiveCVLinetable();
2149 case DK_CV_INLINE_LINETABLE:
2150 return parseDirectiveCVInlineLinetable();
2151 case DK_CV_DEF_RANGE:
2152 return parseDirectiveCVDefRange();
2154 return parseDirectiveCVString();
2155 case DK_CV_STRINGTABLE:
2156 return parseDirectiveCVStringTable();
2157 case DK_CV_FILECHECKSUMS:
2158 return parseDirectiveCVFileChecksums();
2159 case DK_CV_FILECHECKSUM_OFFSET:
2160 return parseDirectiveCVFileChecksumOffset();
2161 case DK_CV_FPO_DATA:
2162 return parseDirectiveCVFPOData();
2163 case DK_CFI_SECTIONS:
2164 return parseDirectiveCFISections();
2165 case DK_CFI_STARTPROC:
2166 return parseDirectiveCFIStartProc();
2167 case DK_CFI_ENDPROC:
2168 return parseDirectiveCFIEndProc();
2169 case DK_CFI_DEF_CFA:
2170 return parseDirectiveCFIDefCfa(IDLoc);
2171 case DK_CFI_DEF_CFA_OFFSET:
2172 return parseDirectiveCFIDefCfaOffset();
2173 case DK_CFI_ADJUST_CFA_OFFSET:
2174 return parseDirectiveCFIAdjustCfaOffset();
2175 case DK_CFI_DEF_CFA_REGISTER:
2176 return parseDirectiveCFIDefCfaRegister(IDLoc);
2178 return parseDirectiveCFIOffset(IDLoc);
2179 case DK_CFI_REL_OFFSET:
2180 return parseDirectiveCFIRelOffset(IDLoc);
2181 case DK_CFI_PERSONALITY:
2182 return parseDirectiveCFIPersonalityOrLsda(true);
2184 return parseDirectiveCFIPersonalityOrLsda(false);
2185 case DK_CFI_REMEMBER_STATE:
2186 return parseDirectiveCFIRememberState();
2187 case DK_CFI_RESTORE_STATE:
2188 return parseDirectiveCFIRestoreState();
2189 case DK_CFI_SAME_VALUE:
2190 return parseDirectiveCFISameValue(IDLoc);
2191 case DK_CFI_RESTORE:
2192 return parseDirectiveCFIRestore(IDLoc);
2194 return parseDirectiveCFIEscape();
2195 case DK_CFI_RETURN_COLUMN:
2196 return parseDirectiveCFIReturnColumn(IDLoc);
2197 case DK_CFI_SIGNAL_FRAME:
2198 return parseDirectiveCFISignalFrame();
2199 case DK_CFI_UNDEFINED:
2200 return parseDirectiveCFIUndefined(IDLoc);
2201 case DK_CFI_REGISTER:
2202 return parseDirectiveCFIRegister(IDLoc);
2203 case DK_CFI_WINDOW_SAVE:
2204 return parseDirectiveCFIWindowSave();
2206 return parseDirectiveMacro(IDLoc);
2209 return parseDirectiveAltmacro(IDVal);
2211 return parseDirectiveExitMacro(IDVal);
2213 return parseDirectiveEndMacro(IDVal);
2215 return parseDirectivePurgeMacro(IDLoc);
2217 return parseDirectiveEnd(IDLoc);
2219 return parseDirectiveError(IDLoc);
2221 return parseDirectiveErrorIfb(IDLoc, true);
2223 return parseDirectiveErrorIfb(IDLoc, false);
2225 return parseDirectiveErrorIfdef(IDLoc, true);
2227 return parseDirectiveErrorIfdef(IDLoc, false);
2229 return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/false,
2230 /*CaseInsensitive=*/false);
2232 return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/false,
2233 /*CaseInsensitive=*/true);
2235 return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/true,
2236 /*CaseInsensitive=*/false);
2238 return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/true,
2239 /*CaseInsensitive=*/true);
2241 return parseDirectiveErrorIfe(IDLoc, true);
2243 return parseDirectiveErrorIfe(IDLoc, false);
2245 return parseDirectiveEcho();
2248 return Error(IDLoc, "unknown directive");
2251 // We also check if this is allocating memory with user-defined type.
2252 auto IDIt = Structs.find(IDVal.lower());
2253 if (IDIt != Structs.end())
2254 return parseDirectiveStructValue(/*Structure=*/IDIt->getValue(), IDVal,
2257 // Non-conditional Microsoft directives sometimes follow their first argument.
2258 const AsmToken nextTok = getTok();
2259 const StringRef nextVal = nextTok.getString();
2260 const SMLoc nextLoc = nextTok.getLoc();
2262 // There are several entities interested in parsing infix directives:
2264 // 1. Asm parser extensions. For example, platform-specific parsers
2265 // (like the ELF parser) register themselves as extensions.
2266 // 2. The generic directive parser implemented by this class. These are
2267 // all the directives that behave in a target and platform independent
2268 // manner, or at least have a default behavior that's shared between
2269 // all targets and platforms.
2271 getTargetParser().flushPendingInstructions(getStreamer());
2273 // Special-case handling of structure-end directives at higher priority, since
2274 // ENDS is overloaded as a segment-end directive.
2275 if (nextVal.equals_lower("ends") && StructInProgress.size() == 1) {
2277 return parseDirectiveEnds(IDVal, IDLoc);
2280 // First, check the extension directive map to see if any extension has
2281 // registered itself to parse this directive.
2282 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2283 ExtensionDirectiveMap.lookup(nextVal.lower());
2284 if (Handler.first) {
2287 return (*Handler.second)(Handler.first, nextVal, nextLoc);
2290 // If no one else is interested in this directive, it must be
2291 // generic and familiar to this class.
2292 DirKindIt = DirectiveKindMap.find(nextVal.lower());
2293 DirKind = (DirKindIt == DirectiveKindMap.end())
2295 : DirKindIt->getValue();
2303 return parseDirectiveEquate(nextVal, IDVal, DirKind);
2307 return parseDirectiveNamedValue(nextVal, 1, IDVal, IDLoc);
2311 return parseDirectiveNamedValue(nextVal, 2, IDVal, IDLoc);
2315 return parseDirectiveNamedValue(nextVal, 4, IDVal, IDLoc);
2318 return parseDirectiveNamedValue(nextVal, 6, IDVal, IDLoc);
2322 return parseDirectiveNamedValue(nextVal, 8, IDVal, IDLoc);
2325 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEsingle(), IDVal,
2329 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEdouble(), IDVal,
2334 return parseDirectiveStruct(nextVal, DirKind, IDVal, IDLoc);
2337 return parseDirectiveEnds(IDVal, IDLoc);
2340 // Finally, we check if this is allocating a variable with user-defined type.
2341 auto NextIt = Structs.find(nextVal.lower());
2342 if (NextIt != Structs.end()) {
2344 return parseDirectiveNamedStructValue(/*Structure=*/NextIt->getValue(),
2345 nextVal, nextLoc, IDVal);
2348 // __asm _emit or __asm __emit
2349 if (ParsingMSInlineAsm && (IDVal == "_emit" || IDVal == "__emit" ||
2350 IDVal == "_EMIT" || IDVal == "__EMIT"))
2351 return parseDirectiveMSEmit(IDLoc, Info, IDVal.size());
2354 if (ParsingMSInlineAsm && (IDVal == "align" || IDVal == "ALIGN"))
2355 return parseDirectiveMSAlign(IDLoc, Info);
2357 if (ParsingMSInlineAsm && (IDVal == "even" || IDVal == "EVEN"))
2358 Info.AsmRewrites->emplace_back(AOK_EVEN, IDLoc, 4);
2359 if (checkForValidSection())
2362 // Canonicalize the opcode to lower case.
2363 std::string OpcodeStr = IDVal.lower();
2364 ParseInstructionInfo IInfo(Info.AsmRewrites);
2365 bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID,
2366 Info.ParsedOperands);
2367 Info.ParseError = ParseHadError;
2369 // Dump the parsed representation, if requested.
2370 if (getShowParsedOperands()) {
2371 SmallString<256> Str;
2372 raw_svector_ostream OS(Str);
2373 OS << "parsed instruction: [";
2374 for (unsigned i = 0; i != Info.ParsedOperands.size(); ++i) {
2377 Info.ParsedOperands[i]->print(OS);
2381 printMessage(IDLoc, SourceMgr::DK_Note, OS.str());
2384 // Fail even if ParseInstruction erroneously returns false.
2385 if (hasPendingError() || ParseHadError)
2388 // If we are generating dwarf for the current section then generate a .loc
2389 // directive for the instruction.
2390 if (!ParseHadError && enabledGenDwarfForAssembly() &&
2391 getContext().getGenDwarfSectionSyms().count(
2392 getStreamer().getCurrentSectionOnly())) {
2394 if (ActiveMacros.empty())
2395 Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer);
2397 Line = SrcMgr.FindLineNumber(ActiveMacros.front()->InstantiationLoc,
2398 ActiveMacros.front()->ExitBuffer);
2400 // If we previously parsed a cpp hash file line comment then make sure the
2401 // current Dwarf File is for the CppHashFilename if not then emit the
2402 // Dwarf File table for it and adjust the line number for the .loc.
2403 if (!CppHashInfo.Filename.empty()) {
2404 unsigned FileNumber = getStreamer().emitDwarfFileDirective(
2405 0, StringRef(), CppHashInfo.Filename);
2406 getContext().setGenDwarfFileNumber(FileNumber);
2408 unsigned CppHashLocLineNo =
2409 SrcMgr.FindLineNumber(CppHashInfo.Loc, CppHashInfo.Buf);
2410 Line = CppHashInfo.LineNumber - 1 + (Line - CppHashLocLineNo);
2413 getStreamer().emitDwarfLocDirective(
2414 getContext().getGenDwarfFileNumber(), Line, 0,
2415 DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0, 0, 0,
2419 // If parsing succeeded, match the instruction.
2420 if (!ParseHadError) {
2422 if (getTargetParser().MatchAndEmitInstruction(
2423 IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo,
2424 getTargetParser().isParsingMSInlineAsm()))
2430 // Parse and erase curly braces marking block start/end.
2431 bool MasmParser::parseCurlyBlockScope(
2432 SmallVectorImpl<AsmRewrite> &AsmStrRewrites) {
2433 // Identify curly brace marking block start/end.
2434 if (Lexer.isNot(AsmToken::LCurly) && Lexer.isNot(AsmToken::RCurly))
2437 SMLoc StartLoc = Lexer.getLoc();
2438 Lex(); // Eat the brace.
2439 if (Lexer.is(AsmToken::EndOfStatement))
2440 Lex(); // Eat EndOfStatement following the brace.
2442 // Erase the block start/end brace from the output asm string.
2443 AsmStrRewrites.emplace_back(AOK_Skip, StartLoc, Lexer.getLoc().getPointer() -
2444 StartLoc.getPointer());
2448 /// parseCppHashLineFilenameComment as this:
2449 /// ::= # number "filename"
2450 bool MasmParser::parseCppHashLineFilenameComment(SMLoc L) {
2451 Lex(); // Eat the hash token.
2452 // Lexer only ever emits HashDirective if it fully formed if it's
2453 // done the checking already so this is an internal error.
2454 assert(getTok().is(AsmToken::Integer) &&
2455 "Lexing Cpp line comment: Expected Integer");
2456 int64_t LineNumber = getTok().getIntVal();
2458 assert(getTok().is(AsmToken::String) &&
2459 "Lexing Cpp line comment: Expected String");
2460 StringRef Filename = getTok().getString();
2463 // Get rid of the enclosing quotes.
2464 Filename = Filename.substr(1, Filename.size() - 2);
2466 // Save the SMLoc, Filename and LineNumber for later use by diagnostics
2467 // and possibly DWARF file info.
2468 CppHashInfo.Loc = L;
2469 CppHashInfo.Filename = Filename;
2470 CppHashInfo.LineNumber = LineNumber;
2471 CppHashInfo.Buf = CurBuffer;
2472 if (FirstCppHashFilename.empty())
2473 FirstCppHashFilename = Filename;
2477 /// will use the last parsed cpp hash line filename comment
2478 /// for the Filename and LineNo if any in the diagnostic.
2479 void MasmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
2480 const MasmParser *Parser = static_cast<const MasmParser *>(Context);
2481 raw_ostream &OS = errs();
2483 const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr();
2484 SMLoc DiagLoc = Diag.getLoc();
2485 unsigned DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
2486 unsigned CppHashBuf =
2487 Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
2489 // Like SourceMgr::printMessage() we need to print the include stack if any
2490 // before printing the message.
2491 unsigned DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
2492 if (!Parser->SavedDiagHandler && DiagCurBuffer &&
2493 DiagCurBuffer != DiagSrcMgr.getMainFileID()) {
2494 SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer);
2495 DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS);
2498 // If we have not parsed a cpp hash line filename comment or the source
2499 // manager changed or buffer changed (like in a nested include) then just
2500 // print the normal diagnostic using its Filename and LineNo.
2501 if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
2502 DiagBuf != CppHashBuf) {
2503 if (Parser->SavedDiagHandler)
2504 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2506 Diag.print(nullptr, OS);
2510 // Use the CppHashFilename and calculate a line number based on the
2511 // CppHashInfo.Loc and CppHashInfo.LineNumber relative to this Diag's SMLoc
2512 // for the diagnostic.
2513 const std::string &Filename = std::string(Parser->CppHashInfo.Filename);
2515 int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf);
2516 int CppHashLocLineNo =
2517 Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
2519 Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
2521 SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo,
2522 Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(),
2523 Diag.getLineContents(), Diag.getRanges());
2525 if (Parser->SavedDiagHandler)
2526 Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);
2528 NewDiag.print(nullptr, OS);
2531 // FIXME: This is mostly duplicated from the function in AsmLexer.cpp. The
2532 // difference being that that function accepts '@' as part of identifiers and
2533 // we can't do that. AsmLexer.cpp should probably be changed to handle
2534 // '@' as a special case when needed.
2535 static bool isIdentifierChar(char c) {
2536 return isalnum(static_cast<unsigned char>(c)) || c == '_' || c == '$' ||
2540 bool MasmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
2541 ArrayRef<MCAsmMacroParameter> Parameters,
2542 ArrayRef<MCAsmMacroArgument> A,
2543 bool EnableAtPseudoVariable, SMLoc L) {
2544 unsigned NParameters = Parameters.size();
2545 bool HasVararg = NParameters ? Parameters.back().Vararg : false;
2546 if ((!IsDarwin || NParameters != 0) && NParameters != A.size())
2547 return Error(L, "Wrong number of arguments");
2549 // A macro without parameters is handled differently on Darwin:
2550 // gas accepts no arguments and does no substitutions
2551 while (!Body.empty()) {
2552 // Scan for the next substitution.
2553 std::size_t End = Body.size(), Pos = 0;
2554 for (; Pos != End; ++Pos) {
2555 // Check for a substitution or escape.
2556 if (IsDarwin && !NParameters) {
2557 // This macro has no parameters, look for $0, $1, etc.
2558 if (Body[Pos] != '$' || Pos + 1 == End)
2561 char Next = Body[Pos + 1];
2562 if (Next == '$' || Next == 'n' ||
2563 isdigit(static_cast<unsigned char>(Next)))
2566 // This macro has parameters, look for \foo, \bar, etc.
2567 if (Body[Pos] == '\\' && Pos + 1 != End)
2573 OS << Body.slice(0, Pos);
2575 // Check if we reached the end.
2579 if (IsDarwin && !NParameters) {
2580 switch (Body[Pos + 1]) {
2586 // $n => number of arguments
2591 // $[0-9] => argument
2593 // Missing arguments are ignored.
2594 unsigned Index = Body[Pos + 1] - '0';
2595 if (Index >= A.size())
2598 // Otherwise substitute with the token values, with spaces eliminated.
2599 for (const AsmToken &Token : A[Index])
2600 OS << Token.getString();
2606 unsigned I = Pos + 1;
2608 // Check for the \@ pseudo-variable.
2609 if (EnableAtPseudoVariable && Body[I] == '@' && I + 1 != End)
2612 while (isIdentifierChar(Body[I]) && I + 1 != End)
2615 const char *Begin = Body.data() + Pos + 1;
2616 StringRef Argument(Begin, I - (Pos + 1));
2619 if (Argument == "@") {
2620 OS << NumOfMacroInstantiations;
2623 for (; Index < NParameters; ++Index)
2624 if (Parameters[Index].Name == Argument)
2627 if (Index == NParameters) {
2628 if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
2631 OS << '\\' << Argument;
2635 bool VarargParameter = HasVararg && Index == (NParameters - 1);
2636 for (const AsmToken &Token : A[Index])
2637 // For altmacro mode, you can write '%expr'.
2638 // The prefix '%' evaluates the expression 'expr'
2639 // and uses the result as a string (e.g. replace %(1+2) with the
2641 // Here, we identify the integer token which is the result of the
2642 // absolute expression evaluation and replace it with its string
2644 if (AltMacroMode && Token.getString().front() == '%' &&
2645 Token.is(AsmToken::Integer))
2646 // Emit an integer value to the buffer.
2647 OS << Token.getIntVal();
2648 // Only Token that was validated as a string and begins with '<'
2649 // is considered altMacroString!!!
2650 else if (AltMacroMode && Token.getString().front() == '<' &&
2651 Token.is(AsmToken::String)) {
2652 OS << angleBracketString(Token.getStringContents());
2654 // We expect no quotes around the string's contents when
2655 // parsing for varargs.
2656 else if (Token.isNot(AsmToken::String) || VarargParameter)
2657 OS << Token.getString();
2659 OS << Token.getStringContents();
2661 Pos += 1 + Argument.size();
2665 // Update the scan point.
2666 Body = Body.substr(Pos);
2672 static bool isOperator(AsmToken::TokenKind kind) {
2676 case AsmToken::Plus:
2677 case AsmToken::Minus:
2678 case AsmToken::Tilde:
2679 case AsmToken::Slash:
2680 case AsmToken::Star:
2682 case AsmToken::Equal:
2683 case AsmToken::EqualEqual:
2684 case AsmToken::Pipe:
2685 case AsmToken::PipePipe:
2686 case AsmToken::Caret:
2688 case AsmToken::AmpAmp:
2689 case AsmToken::Exclaim:
2690 case AsmToken::ExclaimEqual:
2691 case AsmToken::Less:
2692 case AsmToken::LessEqual:
2693 case AsmToken::LessLess:
2694 case AsmToken::LessGreater:
2695 case AsmToken::Greater:
2696 case AsmToken::GreaterEqual:
2697 case AsmToken::GreaterGreater:
2704 class AsmLexerSkipSpaceRAII {
2706 AsmLexerSkipSpaceRAII(AsmLexer &Lexer, bool SkipSpace) : Lexer(Lexer) {
2707 Lexer.setSkipSpace(SkipSpace);
2710 ~AsmLexerSkipSpaceRAII() {
2711 Lexer.setSkipSpace(true);
2718 } // end anonymous namespace
2720 bool MasmParser::parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg) {
2723 if (Lexer.isNot(AsmToken::EndOfStatement)) {
2724 StringRef Str = parseStringToEndOfStatement();
2725 MA.emplace_back(AsmToken::String, Str);
2730 unsigned ParenLevel = 0;
2732 // Darwin doesn't use spaces to delmit arguments.
2733 AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
2739 if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal))
2740 return TokError("unexpected token in macro instantiation");
2742 if (ParenLevel == 0) {
2744 if (Lexer.is(AsmToken::Comma))
2747 if (Lexer.is(AsmToken::Space)) {
2749 Lexer.Lex(); // Eat spaces.
2752 // Spaces can delimit parameters, but could also be part an expression.
2753 // If the token after a space is an operator, add the token and the next
2754 // one into this argument
2756 if (isOperator(Lexer.getKind())) {
2757 MA.push_back(getTok());
2760 // Whitespace after an operator can be ignored.
2761 if (Lexer.is(AsmToken::Space))
2771 // handleMacroEntry relies on not advancing the lexer here
2772 // to be able to fill in the remaining default parameter values
2773 if (Lexer.is(AsmToken::EndOfStatement))
2776 // Adjust the current parentheses level.
2777 if (Lexer.is(AsmToken::LParen))
2779 else if (Lexer.is(AsmToken::RParen) && ParenLevel)
2782 // Append the token to the current argument list.
2783 MA.push_back(getTok());
2787 if (ParenLevel != 0)
2788 return TokError("unbalanced parentheses in macro argument");
2792 // Parse the macro instantiation arguments.
2793 bool MasmParser::parseMacroArguments(const MCAsmMacro *M,
2794 MCAsmMacroArguments &A) {
2795 const unsigned NParameters = M ? M->Parameters.size() : 0;
2796 bool NamedParametersFound = false;
2797 SmallVector<SMLoc, 4> FALocs;
2799 A.resize(NParameters);
2800 FALocs.resize(NParameters);
2802 // Parse two kinds of macro invocations:
2803 // - macros defined without any parameters accept an arbitrary number of them
2804 // - macros defined with parameters accept at most that many of them
2805 bool HasVararg = NParameters ? M->Parameters.back().Vararg : false;
2806 for (unsigned Parameter = 0; !NParameters || Parameter < NParameters;
2808 SMLoc IDLoc = Lexer.getLoc();
2809 MCAsmMacroParameter FA;
2811 if (Lexer.is(AsmToken::Identifier) && Lexer.peekTok().is(AsmToken::Equal)) {
2812 if (parseIdentifier(FA.Name))
2813 return Error(IDLoc, "invalid argument identifier for formal argument");
2815 if (Lexer.isNot(AsmToken::Equal))
2816 return TokError("expected '=' after formal parameter identifier");
2820 NamedParametersFound = true;
2822 bool Vararg = HasVararg && Parameter == (NParameters - 1);
2824 if (NamedParametersFound && FA.Name.empty())
2825 return Error(IDLoc, "cannot mix positional and keyword arguments");
2827 SMLoc StrLoc = Lexer.getLoc();
2829 if (AltMacroMode && Lexer.is(AsmToken::Percent)) {
2830 const MCExpr *AbsoluteExp;
2834 if (parseExpression(AbsoluteExp, EndLoc))
2836 if (!AbsoluteExp->evaluateAsAbsolute(Value,
2837 getStreamer().getAssemblerPtr()))
2838 return Error(StrLoc, "expected absolute expression");
2839 const char *StrChar = StrLoc.getPointer();
2840 const char *EndChar = EndLoc.getPointer();
2841 AsmToken newToken(AsmToken::Integer,
2842 StringRef(StrChar, EndChar - StrChar), Value);
2843 FA.Value.push_back(newToken);
2844 } else if (AltMacroMode && Lexer.is(AsmToken::Less) &&
2845 isAngleBracketString(StrLoc, EndLoc)) {
2846 const char *StrChar = StrLoc.getPointer();
2847 const char *EndChar = EndLoc.getPointer();
2848 jumpToLoc(EndLoc, CurBuffer);
2849 /// Eat from '<' to '>'.
2851 AsmToken newToken(AsmToken::String,
2852 StringRef(StrChar, EndChar - StrChar));
2853 FA.Value.push_back(newToken);
2854 } else if(parseMacroArgument(FA.Value, Vararg))
2857 unsigned PI = Parameter;
2858 if (!FA.Name.empty()) {
2860 for (FAI = 0; FAI < NParameters; ++FAI)
2861 if (M->Parameters[FAI].Name == FA.Name)
2864 if (FAI >= NParameters) {
2865 assert(M && "expected macro to be defined");
2866 return Error(IDLoc, "parameter named '" + FA.Name +
2867 "' does not exist for macro '" + M->Name + "'");
2872 if (!FA.Value.empty()) {
2877 if (FALocs.size() <= PI)
2878 FALocs.resize(PI + 1);
2880 FALocs[PI] = Lexer.getLoc();
2883 // At the end of the statement, fill in remaining arguments that have
2884 // default values. If there aren't any, then the next argument is
2885 // required but missing
2886 if (Lexer.is(AsmToken::EndOfStatement)) {
2887 bool Failure = false;
2888 for (unsigned FAI = 0; FAI < NParameters; ++FAI) {
2889 if (A[FAI].empty()) {
2890 if (M->Parameters[FAI].Required) {
2891 Error(FALocs[FAI].isValid() ? FALocs[FAI] : Lexer.getLoc(),
2892 "missing value for required parameter "
2893 "'" + M->Parameters[FAI].Name + "' in macro '" + M->Name + "'");
2897 if (!M->Parameters[FAI].Value.empty())
2898 A[FAI] = M->Parameters[FAI].Value;
2904 if (Lexer.is(AsmToken::Comma))
2908 return TokError("too many positional arguments");
2911 bool MasmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
2912 // Arbitrarily limit macro nesting depth (default matches 'as'). We can
2913 // eliminate this, although we should protect against infinite loops.
2914 unsigned MaxNestingDepth = AsmMacroMaxNestingDepth;
2915 if (ActiveMacros.size() == MaxNestingDepth) {
2916 std::ostringstream MaxNestingDepthError;
2917 MaxNestingDepthError << "macros cannot be nested more than "
2918 << MaxNestingDepth << " levels deep."
2919 << " Use -asm-macro-max-nesting-depth to increase "
2921 return TokError(MaxNestingDepthError.str());
2924 MCAsmMacroArguments A;
2925 if (parseMacroArguments(M, A))
2928 // Macro instantiation is lexical, unfortunately. We construct a new buffer
2929 // to hold the macro body with substitutions.
2930 SmallString<256> Buf;
2931 StringRef Body = M->Body;
2932 raw_svector_ostream OS(Buf);
2934 if (expandMacro(OS, Body, M->Parameters, A, true, getTok().getLoc()))
2937 // We include the .endmacro in the buffer as our cue to exit the macro
2939 OS << ".endmacro\n";
2941 std::unique_ptr<MemoryBuffer> Instantiation =
2942 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
2944 // Create the macro instantiation object and add to the current macro
2945 // instantiation stack.
2946 MacroInstantiation *MI = new MacroInstantiation{
2947 NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
2948 ActiveMacros.push_back(MI);
2950 ++NumOfMacroInstantiations;
2952 // Jump to the macro instantiation and prime the lexer.
2953 CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
2954 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
2960 void MasmParser::handleMacroExit() {
2961 // Jump to the EndOfStatement we should return to, and consume it.
2962 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer);
2965 // Pop the instantiation entry.
2966 delete ActiveMacros.back();
2967 ActiveMacros.pop_back();
2970 /// parseIdentifier:
2973 bool MasmParser::parseIdentifier(StringRef &Res) {
2974 // The assembler has relaxed rules for accepting identifiers, in particular we
2975 // allow things like '.globl $foo' and '.def @feat.00', which would normally
2976 // be separate tokens. At this level, we have already lexed so we cannot
2977 // (currently) handle this as a context dependent token, instead we detect
2978 // adjacent tokens and return the combined identifier.
2979 if (Lexer.is(AsmToken::Dollar) || Lexer.is(AsmToken::At)) {
2980 SMLoc PrefixLoc = getLexer().getLoc();
2982 // Consume the prefix character, and check for a following identifier.
2985 Lexer.peekTokens(Buf, false);
2987 if (Buf[0].isNot(AsmToken::Identifier))
2990 // We have a '$' or '@' followed by an identifier, make sure they are adjacent.
2991 if (PrefixLoc.getPointer() + 1 != Buf[0].getLoc().getPointer())
2995 Lexer.Lex(); // Lexer's Lex guarantees consecutive token.
2996 // Construct the joined identifier and consume the token.
2998 StringRef(PrefixLoc.getPointer(), getTok().getIdentifier().size() + 1);
2999 Lex(); // Parser Lex to maintain invariants.
3003 if (Lexer.isNot(AsmToken::Identifier) && Lexer.isNot(AsmToken::String))
3006 Res = getTok().getIdentifier();
3008 Lex(); // Consume the identifier token.
3013 /// parseDirectiveEquate:
3014 /// ::= name "=" expression
3015 /// | name "equ" expression (not redefinable)
3016 /// | name "equ" text-list
3017 /// | name "textequ" text-list
3018 bool MasmParser::parseDirectiveEquate(StringRef IDVal, StringRef Name,
3019 DirectiveKind DirKind) {
3020 Variable &Var = Variables[Name];
3021 if (Var.Name.empty()) {
3023 } else if (!Var.Redefinable) {
3024 return TokError("invalid variable redefinition");
3026 Var.Redefinable = (DirKind != DK_EQU);
3028 if (DirKind == DK_EQU || DirKind == DK_TEXTEQU) {
3029 // "equ" and "textequ" both allow text expressions.
3031 if (!parseTextItem(Value)) {
3033 Var.TextValue = Value;
3035 // Accept a text-list, not just one text-item.
3036 auto parseItem = [&]() -> bool {
3037 if (parseTextItem(Value))
3039 Var.TextValue += Value;
3042 if (parseOptionalToken(AsmToken::Comma) && parseMany(parseItem))
3043 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3048 if (DirKind == DK_TEXTEQU)
3049 return TokError("expected <text> in '" + Twine(IDVal) + "' directive");
3051 // Parse as expression assignment.
3053 SMLoc EndLoc, StartLoc = Lexer.getLoc();
3054 if (parseExpression(Expr, EndLoc))
3055 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3056 if (Expr->evaluateAsAbsolute(Var.NumericValue,
3057 getStreamer().getAssemblerPtr()))
3060 // Not an absolute expression; define as a text replacement.
3062 Var.TextValue = StringRef(StartLoc.getPointer(),
3063 EndLoc.getPointer() - StartLoc.getPointer()).str();
3067 bool MasmParser::parseEscapedString(std::string &Data) {
3068 if (check(getTok().isNot(AsmToken::String), "expected string"))
3072 StringRef Str = getTok().getStringContents();
3073 for (unsigned i = 0, e = Str.size(); i != e; ++i) {
3074 if (Str[i] != '\\') {
3079 // Recognize escaped characters. Note that this escape semantics currently
3080 // loosely follows Darwin 'as'.
3083 return TokError("unexpected backslash at end of string");
3085 // Recognize hex sequences similarly to GNU 'as'.
3086 if (Str[i] == 'x' || Str[i] == 'X') {
3087 size_t length = Str.size();
3088 if (i + 1 >= length || !isHexDigit(Str[i + 1]))
3089 return TokError("invalid hexadecimal escape sequence");
3091 // Consume hex characters. GNU 'as' reads all hexadecimal characters and
3092 // then truncates to the lower 16 bits. Seems reasonable.
3094 while (i + 1 < length && isHexDigit(Str[i + 1]))
3095 Value = Value * 16 + hexDigitValue(Str[++i]);
3097 Data += (unsigned char)(Value & 0xFF);
3101 // Recognize octal sequences.
3102 if ((unsigned)(Str[i] - '0') <= 7) {
3103 // Consume up to three octal characters.
3104 unsigned Value = Str[i] - '0';
3106 if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) {
3108 Value = Value * 8 + (Str[i] - '0');
3110 if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) {
3112 Value = Value * 8 + (Str[i] - '0');
3117 return TokError("invalid octal escape sequence (out of range)");
3119 Data += (unsigned char)Value;
3123 // Otherwise recognize individual escapes.
3126 // Just reject invalid escape sequences for now.
3127 return TokError("invalid escape sequence (unrecognized character)");
3129 case 'b': Data += '\b'; break;
3130 case 'f': Data += '\f'; break;
3131 case 'n': Data += '\n'; break;
3132 case 'r': Data += '\r'; break;
3133 case 't': Data += '\t'; break;
3134 case '"': Data += '"'; break;
3135 case '\\': Data += '\\'; break;
3143 bool MasmParser::parseAngleBracketString(std::string &Data) {
3144 SMLoc EndLoc, StartLoc = getTok().getLoc();
3145 if (isAngleBracketString(StartLoc, EndLoc)) {
3146 const char *StartChar = StartLoc.getPointer() + 1;
3147 const char *EndChar = EndLoc.getPointer() - 1;
3148 jumpToLoc(EndLoc, CurBuffer);
3149 // Eat from '<' to '>'.
3152 Data = angleBracketString(StringRef(StartChar, EndChar - StartChar));
3158 /// textItem ::= textLiteral | textMacroID | % constExpr
3159 bool MasmParser::parseTextItem(std::string &Data) {
3160 // TODO(epastor): Support textMacroID and % expansion of expressions.
3161 return parseAngleBracketString(Data);
3164 /// parseDirectiveAscii:
3165 /// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ]
3166 bool MasmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
3167 auto parseOp = [&]() -> bool {
3169 if (checkForValidSection() || parseEscapedString(Data))
3171 getStreamer().emitBytes(Data);
3173 getStreamer().emitBytes(StringRef("\0", 1));
3177 if (parseMany(parseOp))
3178 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3182 bool MasmParser::emitIntValue(const MCExpr *Value, unsigned Size) {
3183 // Special case constant expressions to match code generator.
3184 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
3185 assert(Size <= 8 && "Invalid size");
3186 int64_t IntValue = MCE->getValue();
3187 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
3188 return Error(MCE->getLoc(), "out of range literal value");
3189 getStreamer().emitIntValue(IntValue, Size);
3191 const MCSymbolRefExpr *MSE = dyn_cast<MCSymbolRefExpr>(Value);
3192 if (MSE && MSE->getSymbol().getName() == "?") {
3193 // ? initializer; treat as 0.
3194 getStreamer().emitIntValue(0, Size);
3196 getStreamer().emitValue(Value, Size, Value->getLoc());
3202 bool MasmParser::parseScalarInitializer(unsigned Size,
3203 SmallVectorImpl<const MCExpr *> &Values,
3204 unsigned StringPadLength) {
3205 if (getTok().is(AsmToken::String)) {
3206 StringRef Value = getTok().getStringContents();
3208 // Treat each character as an initializer.
3209 for (const char CharVal : Value)
3210 Values.push_back(MCConstantExpr::create(CharVal, getContext()));
3212 // Pad the string with spaces to the specified length.
3213 for (size_t i = Value.size(); i < StringPadLength; ++i)
3214 Values.push_back(MCConstantExpr::create(' ', getContext()));
3216 // Treat the string as an initial value in big-endian representation.
3217 if (Value.size() > Size)
3218 return Error(getTok().getLoc(), "out of range literal value");
3220 uint64_t IntValue = 0;
3221 for (const unsigned char CharVal : Value.bytes())
3222 IntValue = (IntValue << 8) | CharVal;
3223 Values.push_back(MCConstantExpr::create(IntValue, getContext()));
3227 const MCExpr *Value;
3228 if (checkForValidSection() || parseExpression(Value))
3230 if (getTok().is(AsmToken::Identifier) &&
3231 getTok().getString().equals_lower("dup")) {
3232 Lex(); // Eat 'dup'.
3233 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
3235 return Error(Value->getLoc(),
3236 "cannot repeat value a non-constant number of times");
3237 const int64_t Repetitions = MCE->getValue();
3238 if (Repetitions < 0)
3239 return Error(Value->getLoc(),
3240 "cannot repeat value a negative number of times");
3242 SmallVector<const MCExpr *, 1> DuplicatedValues;
3243 if (parseToken(AsmToken::LParen,
3244 "parentheses required for 'dup' contents") ||
3245 parseScalarInstList(Size, DuplicatedValues) ||
3246 parseToken(AsmToken::RParen, "unmatched parentheses"))
3249 for (int i = 0; i < Repetitions; ++i)
3250 Values.append(DuplicatedValues.begin(), DuplicatedValues.end());
3252 Values.push_back(Value);
3258 bool MasmParser::parseScalarInstList(unsigned Size,
3259 SmallVectorImpl<const MCExpr *> &Values,
3260 const AsmToken::TokenKind EndToken) {
3261 while (getTok().isNot(EndToken) &&
3262 (EndToken != AsmToken::Greater ||
3263 getTok().isNot(AsmToken::GreaterGreater))) {
3264 parseScalarInitializer(Size, Values);
3266 // If we see a comma, continue, and allow line continuation.
3267 if (!parseOptionalToken(AsmToken::Comma))
3269 parseOptionalToken(AsmToken::EndOfStatement);
3274 bool MasmParser::emitIntegralValues(unsigned Size) {
3275 SmallVector<const MCExpr *, 1> Values;
3276 if (checkForValidSection() || parseScalarInstList(Size, Values))
3279 for (auto Value : Values) {
3280 emitIntValue(Value, Size);
3285 // Add a field to the current structure.
3286 bool MasmParser::addIntegralField(StringRef Name, unsigned Size) {
3287 StructInfo &Struct = StructInProgress.back();
3288 FieldInfo &Field = Struct.addField(Name, FT_INTEGRAL);
3289 IntFieldInfo &IntInfo = Field.Contents.IntInfo;
3293 if (parseScalarInstList(Size, IntInfo.Values))
3296 Field.SizeOf = Field.Type * IntInfo.Values.size();
3297 Field.LengthOf = IntInfo.Values.size();
3299 Struct.Size = std::max(Struct.Size, Field.SizeOf);
3301 Struct.Size += Field.SizeOf;
3305 /// parseDirectiveValue
3306 /// ::= (byte | word | ... ) [ expression (, expression)* ]
3307 bool MasmParser::parseDirectiveValue(StringRef IDVal, unsigned Size) {
3308 if (StructInProgress.empty()) {
3309 // Initialize data value.
3310 if (emitIntegralValues(Size))
3311 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3312 } else if (addIntegralField("", Size)) {
3313 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3319 /// parseDirectiveNamedValue
3320 /// ::= name (byte | word | ... ) [ expression (, expression)* ]
3321 bool MasmParser::parseDirectiveNamedValue(StringRef IDVal, unsigned Size,
3322 StringRef Name, SMLoc NameLoc) {
3323 if (StructInProgress.empty()) {
3324 // Initialize named data value.
3325 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3326 getStreamer().emitLabel(Sym);
3327 if (emitIntegralValues(Size))
3328 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3329 } else if (addIntegralField(Name, Size)) {
3330 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3336 static bool parseHexOcta(MasmParser &Asm, uint64_t &hi, uint64_t &lo) {
3337 if (Asm.getTok().isNot(AsmToken::Integer) &&
3338 Asm.getTok().isNot(AsmToken::BigNum))
3339 return Asm.TokError("unknown token in expression");
3340 SMLoc ExprLoc = Asm.getTok().getLoc();
3341 APInt IntValue = Asm.getTok().getAPIntVal();
3343 if (!IntValue.isIntN(128))
3344 return Asm.Error(ExprLoc, "out of range literal value");
3345 if (!IntValue.isIntN(64)) {
3346 hi = IntValue.getHiBits(IntValue.getBitWidth() - 64).getZExtValue();
3347 lo = IntValue.getLoBits(64).getZExtValue();
3350 lo = IntValue.getZExtValue();
3355 bool MasmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {
3356 // We don't truly support arithmetic on floating point expressions, so we
3357 // have to manually parse unary prefixes.
3359 if (getLexer().is(AsmToken::Minus)) {
3362 } else if (getLexer().is(AsmToken::Plus)) {
3366 if (Lexer.is(AsmToken::Error))
3367 return TokError(Lexer.getErr());
3368 if (Lexer.isNot(AsmToken::Integer) && Lexer.isNot(AsmToken::Real) &&
3369 Lexer.isNot(AsmToken::Identifier))
3370 return TokError("unexpected token in directive");
3372 // Convert to an APFloat.
3373 APFloat Value(Semantics);
3374 StringRef IDVal = getTok().getString();
3375 if (getLexer().is(AsmToken::Identifier)) {
3376 if (IDVal.equals_lower("infinity") || IDVal.equals_lower("inf"))
3377 Value = APFloat::getInf(Semantics);
3378 else if (IDVal.equals_lower("nan"))
3379 Value = APFloat::getNaN(Semantics, false, ~0);
3380 else if (IDVal.equals_lower("?"))
3381 Value = APFloat::getZero(Semantics);
3383 return TokError("invalid floating point literal");
3384 } else if (errorToBool(
3385 Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven)
3387 return TokError("invalid floating point literal");
3392 // Consume the numeric token.
3395 Res = Value.bitcastToAPInt();
3400 bool MasmParser::parseRealInstList(const fltSemantics &Semantics,
3401 SmallVectorImpl<APInt> &ValuesAsInt,
3402 const AsmToken::TokenKind EndToken) {
3403 while (getTok().isNot(EndToken) ||
3404 (EndToken == AsmToken::Greater &&
3405 getTok().isNot(AsmToken::GreaterGreater))) {
3406 const AsmToken NextTok = Lexer.peekTok();
3407 if (NextTok.is(AsmToken::Identifier) &&
3408 NextTok.getString().equals_lower("dup")) {
3409 const MCExpr *Value;
3410 if (parseExpression(Value) || parseToken(AsmToken::Identifier))
3412 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
3414 return Error(Value->getLoc(),
3415 "cannot repeat value a non-constant number of times");
3416 const int64_t Repetitions = MCE->getValue();
3417 if (Repetitions < 0)
3418 return Error(Value->getLoc(),
3419 "cannot repeat value a negative number of times");
3421 SmallVector<APInt, 1> DuplicatedValues;
3422 if (parseToken(AsmToken::LParen,
3423 "parentheses required for 'dup' contents") ||
3424 parseRealInstList(Semantics, DuplicatedValues) ||
3425 parseToken(AsmToken::RParen, "unmatched parentheses"))
3428 for (int i = 0; i < Repetitions; ++i)
3429 ValuesAsInt.append(DuplicatedValues.begin(), DuplicatedValues.end());
3432 if (parseRealValue(Semantics, AsInt))
3434 ValuesAsInt.push_back(AsInt);
3437 // Continue if we see a comma. (Also, allow line continuation.)
3438 if (!parseOptionalToken(AsmToken::Comma))
3440 parseOptionalToken(AsmToken::EndOfStatement);
3446 // Initialize real data values.
3447 bool MasmParser::emitRealValues(const fltSemantics &Semantics) {
3448 SmallVector<APInt, 1> ValuesAsInt;
3449 if (parseRealInstList(Semantics, ValuesAsInt))
3452 for (const APInt &AsInt : ValuesAsInt) {
3453 getStreamer().emitIntValue(AsInt.getLimitedValue(),
3454 AsInt.getBitWidth() / 8);
3459 // Add a real field to the current struct.
3460 bool MasmParser::addRealField(StringRef Name, const fltSemantics &Semantics) {
3461 StructInfo &Struct = StructInProgress.back();
3462 FieldInfo &Field = Struct.addField(Name, FT_REAL);
3463 RealFieldInfo &RealInfo = Field.Contents.RealInfo;
3467 if (checkForValidSection() ||
3468 parseRealInstList(Semantics, RealInfo.AsIntValues))
3471 Field.Type = RealInfo.AsIntValues.back().getBitWidth() / 8;
3472 Field.LengthOf = RealInfo.AsIntValues.size();
3473 Field.SizeOf = Field.Type * Field.LengthOf;
3475 Struct.Size = std::max(Struct.Size, Field.SizeOf);
3477 Struct.Size += Field.SizeOf;
3481 /// parseDirectiveRealValue
3482 /// ::= (real4 | real8) [ expression (, expression)* ]
3483 bool MasmParser::parseDirectiveRealValue(StringRef IDVal,
3484 const fltSemantics &Semantics) {
3485 if (checkForValidSection())
3488 if (StructInProgress.empty()) {
3489 // Initialize data value.
3490 if (emitRealValues(Semantics))
3491 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3492 } else if (addRealField("", Semantics)) {
3493 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3498 /// parseDirectiveNamedRealValue
3499 /// ::= name (real4 | real8) [ expression (, expression)* ]
3500 bool MasmParser::parseDirectiveNamedRealValue(StringRef IDVal,
3501 const fltSemantics &Semantics,
3502 StringRef Name, SMLoc NameLoc) {
3503 if (checkForValidSection())
3506 if (StructInProgress.empty()) {
3507 // Initialize named data value.
3508 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3509 getStreamer().emitLabel(Sym);
3510 if (emitRealValues(Semantics))
3511 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3512 } else if (addRealField(Name, Semantics)) {
3513 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3518 bool MasmParser::parseOptionalAngleBracketOpen() {
3519 const AsmToken Tok = getTok();
3520 if (parseOptionalToken(AsmToken::LessLess)) {
3521 AngleBracketDepth++;
3522 Lexer.UnLex(AsmToken(AsmToken::Less, Tok.getString().substr(1)));
3524 } else if (parseOptionalToken(AsmToken::LessGreater)) {
3525 AngleBracketDepth++;
3526 Lexer.UnLex(AsmToken(AsmToken::Greater, Tok.getString().substr(1)));
3528 } else if (parseOptionalToken(AsmToken::Less)) {
3529 AngleBracketDepth++;
3536 bool MasmParser::parseAngleBracketClose(const Twine &Msg) {
3537 const AsmToken Tok = getTok();
3538 if (parseOptionalToken(AsmToken::GreaterGreater)) {
3539 Lexer.UnLex(AsmToken(AsmToken::Greater, Tok.getString().substr(1)));
3540 } else if (parseToken(AsmToken::Greater, Msg)) {
3543 AngleBracketDepth--;
3547 bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
3548 const IntFieldInfo &Contents,
3549 FieldInitializer &Initializer) {
3550 SMLoc Loc = getTok().getLoc();
3552 SmallVector<const MCExpr *, 1> Values;
3553 if (parseOptionalToken(AsmToken::LCurly)) {
3554 if (Field.LengthOf == 1 && Field.Type > 1)
3555 return Error(Loc, "Cannot initialize scalar field with array value");
3556 if (parseScalarInstList(Field.Type, Values, AsmToken::RCurly) ||
3557 parseToken(AsmToken::RCurly))
3559 } else if (parseOptionalAngleBracketOpen()) {
3560 if (Field.LengthOf == 1 && Field.Type > 1)
3561 return Error(Loc, "Cannot initialize scalar field with array value");
3562 if (parseScalarInstList(Field.Type, Values, AsmToken::Greater) ||
3563 parseAngleBracketClose())
3565 } else if (Field.LengthOf > 1 && Field.Type > 1) {
3566 return Error(Loc, "Cannot initialize array field with scalar value");
3567 } else if (parseScalarInitializer(Field.Type, Values,
3568 /*StringPadLength=*/Field.LengthOf)) {
3572 if (Values.size() > Field.LengthOf) {
3573 return Error(Loc, "Initializer too long for field; expected at most " +
3574 std::to_string(Field.LengthOf) + " elements, got " +
3575 std::to_string(Values.size()));
3577 // Default-initialize all remaining values.
3578 Values.append(Contents.Values.begin() + Values.size(), Contents.Values.end());
3580 Initializer = FieldInitializer(std::move(Values));
3584 bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
3585 const RealFieldInfo &Contents,
3586 FieldInitializer &Initializer) {
3587 const fltSemantics &Semantics =
3588 (Field.Type == 4) ? APFloat::IEEEsingle() : APFloat::IEEEdouble();
3590 SMLoc Loc = getTok().getLoc();
3592 SmallVector<APInt, 1> AsIntValues;
3593 if (parseOptionalToken(AsmToken::LCurly)) {
3594 if (Field.LengthOf == 1)
3595 return Error(Loc, "Cannot initialize scalar field with array value");
3596 if (parseRealInstList(Semantics, AsIntValues, AsmToken::RCurly) ||
3597 parseToken(AsmToken::RCurly))
3599 } else if (parseOptionalAngleBracketOpen()) {
3600 if (Field.LengthOf == 1)
3601 return Error(Loc, "Cannot initialize scalar field with array value");
3602 if (parseRealInstList(Semantics, AsIntValues, AsmToken::Greater) ||
3603 parseAngleBracketClose())
3605 } else if (Field.LengthOf > 1) {
3606 return Error(Loc, "Cannot initialize array field with scalar value");
3608 AsIntValues.emplace_back();
3609 if (parseRealValue(Semantics, AsIntValues.back()))
3613 if (AsIntValues.size() > Field.LengthOf) {
3614 return Error(Loc, "Initializer too long for field; expected at most " +
3615 std::to_string(Field.LengthOf) + " elements, got " +
3616 std::to_string(AsIntValues.size()));
3618 // Default-initialize all remaining values.
3619 AsIntValues.append(Contents.AsIntValues.begin() + AsIntValues.size(),
3620 Contents.AsIntValues.end());
3622 Initializer = FieldInitializer(std::move(AsIntValues));
3626 bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
3627 const StructFieldInfo &Contents,
3628 FieldInitializer &Initializer) {
3629 SMLoc Loc = getTok().getLoc();
3631 std::vector<StructInitializer> Initializers;
3632 if (Field.LengthOf > 1) {
3633 if (parseOptionalToken(AsmToken::LCurly)) {
3634 if (parseStructInstList(Contents.Structure, Initializers,
3635 AsmToken::RCurly) ||
3636 parseToken(AsmToken::RCurly))
3638 } else if (parseOptionalAngleBracketOpen()) {
3639 if (parseStructInstList(Contents.Structure, Initializers,
3640 AsmToken::Greater) ||
3641 parseAngleBracketClose())
3644 return Error(Loc, "Cannot initialize array field with scalar value");
3647 Initializers.emplace_back();
3648 if (parseStructInitializer(Contents.Structure, Initializers.back()))
3652 if (Initializers.size() > Field.LengthOf) {
3653 return Error(Loc, "Initializer too long for field; expected at most " +
3654 std::to_string(Field.LengthOf) + " elements, got " +
3655 std::to_string(Initializers.size()));
3657 // Default-initialize all remaining values.
3658 Initializers.insert(Initializers.end(),
3659 Contents.Initializers.begin() + Initializers.size(),
3660 Contents.Initializers.end());
3662 Initializer = FieldInitializer(std::move(Initializers), Contents.Structure);
3666 bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
3667 FieldInitializer &Initializer) {
3668 switch (Field.Contents.FT) {
3670 return parseFieldInitializer(Field, Field.Contents.IntInfo, Initializer);
3672 return parseFieldInitializer(Field, Field.Contents.RealInfo, Initializer);
3674 return parseFieldInitializer(Field, Field.Contents.StructInfo, Initializer);
3676 llvm_unreachable("Unhandled FieldType enum");
3679 bool MasmParser::parseStructInitializer(const StructInfo &Structure,
3680 StructInitializer &Initializer) {
3681 const AsmToken FirstToken = getTok();
3683 Optional<AsmToken::TokenKind> EndToken;
3684 if (parseOptionalToken(AsmToken::LCurly)) {
3685 EndToken = AsmToken::RCurly;
3686 } else if (parseOptionalAngleBracketOpen()) {
3687 EndToken = AsmToken::Greater;
3688 AngleBracketDepth++;
3689 } else if (FirstToken.is(AsmToken::Identifier) &&
3690 FirstToken.getString() == "?") {
3691 // ? initializer; leave EndToken uninitialized to treat as empty.
3692 if (parseToken(AsmToken::Identifier))
3695 return Error(FirstToken.getLoc(), "Expected struct initializer");
3698 auto &FieldInitializers = Initializer.FieldInitializers;
3699 size_t FieldIndex = 0;
3700 if (EndToken.hasValue()) {
3701 // Initialize all fields with given initializers.
3702 while (getTok().isNot(EndToken.getValue()) &&
3703 FieldIndex < Structure.Fields.size()) {
3704 const FieldInfo &Field = Structure.Fields[FieldIndex++];
3705 if (parseOptionalToken(AsmToken::Comma)) {
3706 // Empty initializer; use the default and continue. (Also, allow line
3708 FieldInitializers.push_back(Field.Contents);
3709 parseOptionalToken(AsmToken::EndOfStatement);
3712 FieldInitializers.emplace_back(Field.Contents.FT);
3713 if (parseFieldInitializer(Field, FieldInitializers.back()))
3716 // Continue if we see a comma. (Also, allow line continuation.)
3717 SMLoc CommaLoc = getTok().getLoc();
3718 if (!parseOptionalToken(AsmToken::Comma))
3720 if (FieldIndex == Structure.Fields.size())
3721 return Error(CommaLoc, "'" + Structure.Name +
3722 "' initializer initializes too many fields");
3723 parseOptionalToken(AsmToken::EndOfStatement);
3726 // Default-initialize all remaining fields.
3727 for (auto It = Structure.Fields.begin() + FieldIndex;
3728 It != Structure.Fields.end(); ++It) {
3729 const FieldInfo &Field = *It;
3730 FieldInitializers.push_back(Field.Contents);
3733 if (EndToken.hasValue()) {
3734 if (EndToken.getValue() == AsmToken::Greater)
3735 return parseAngleBracketClose();
3737 return parseToken(EndToken.getValue());
3743 bool MasmParser::parseStructInstList(
3744 const StructInfo &Structure, std::vector<StructInitializer> &Initializers,
3745 const AsmToken::TokenKind EndToken) {
3746 while (getTok().isNot(EndToken) ||
3747 (EndToken == AsmToken::Greater &&
3748 getTok().isNot(AsmToken::GreaterGreater))) {
3749 const AsmToken NextTok = Lexer.peekTok();
3750 if (NextTok.is(AsmToken::Identifier) &&
3751 NextTok.getString().equals_lower("dup")) {
3752 const MCExpr *Value;
3753 if (parseExpression(Value) || parseToken(AsmToken::Identifier))
3755 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
3757 return Error(Value->getLoc(),
3758 "cannot repeat value a non-constant number of times");
3759 const int64_t Repetitions = MCE->getValue();
3760 if (Repetitions < 0)
3761 return Error(Value->getLoc(),
3762 "cannot repeat value a negative number of times");
3764 std::vector<StructInitializer> DuplicatedValues;
3765 if (parseToken(AsmToken::LParen,
3766 "parentheses required for 'dup' contents") ||
3767 parseStructInstList(Structure, DuplicatedValues) ||
3768 parseToken(AsmToken::RParen, "unmatched parentheses"))
3771 for (int i = 0; i < Repetitions; ++i)
3772 Initializers.insert(Initializers.end(), DuplicatedValues.begin(),
3773 DuplicatedValues.end());
3775 Initializers.emplace_back();
3776 if (parseStructInitializer(Structure, Initializers.back()))
3780 // Continue if we see a comma. (Also, allow line continuation.)
3781 if (!parseOptionalToken(AsmToken::Comma))
3783 parseOptionalToken(AsmToken::EndOfStatement);
3789 bool MasmParser::emitFieldValue(const FieldInfo &Field,
3790 const IntFieldInfo &Contents) {
3791 // Default-initialize all values.
3792 for (const MCExpr *Value : Contents.Values) {
3793 if (emitIntValue(Value, Field.Type))
3799 bool MasmParser::emitFieldValue(const FieldInfo &Field,
3800 const RealFieldInfo &Contents) {
3801 for (const APInt &AsInt : Contents.AsIntValues) {
3802 getStreamer().emitIntValue(AsInt.getLimitedValue(),
3803 AsInt.getBitWidth() / 8);
3808 bool MasmParser::emitFieldValue(const FieldInfo &Field,
3809 const StructFieldInfo &Contents) {
3810 for (const auto &Initializer : Contents.Initializers) {
3811 size_t Index = 0, Offset = 0;
3812 for (const auto &SubField : Contents.Structure.Fields) {
3813 getStreamer().emitZeros(SubField.Offset - Offset);
3814 Offset = SubField.Offset + SubField.SizeOf;
3815 emitFieldInitializer(SubField, Initializer.FieldInitializers[Index++]);
3821 bool MasmParser::emitFieldValue(const FieldInfo &Field) {
3822 switch (Field.Contents.FT) {
3824 return emitFieldValue(Field, Field.Contents.IntInfo);
3826 return emitFieldValue(Field, Field.Contents.RealInfo);
3828 return emitFieldValue(Field, Field.Contents.StructInfo);
3830 llvm_unreachable("Unhandled FieldType enum");
3833 bool MasmParser::emitStructValue(const StructInfo &Structure) {
3835 for (const auto &Field : Structure.Fields) {
3836 getStreamer().emitZeros(Field.Offset - Offset);
3837 if (emitFieldValue(Field))
3839 Offset = Field.Offset + Field.SizeOf;
3841 // Add final padding.
3842 if (Offset != Structure.Size)
3843 getStreamer().emitZeros(Structure.Size - Offset);
3847 bool MasmParser::emitFieldInitializer(const FieldInfo &Field,
3848 const IntFieldInfo &Contents,
3849 const IntFieldInfo &Initializer) {
3850 for (const auto &Value : Initializer.Values) {
3851 if (emitIntValue(Value, Field.Type))
3854 // Default-initialize all remaining values.
3855 for (auto it = Contents.Values.begin() + Initializer.Values.size();
3856 it != Contents.Values.end(); ++it) {
3857 const auto &Value = *it;
3858 if (emitIntValue(Value, Field.Type))
3864 bool MasmParser::emitFieldInitializer(const FieldInfo &Field,
3865 const RealFieldInfo &Contents,
3866 const RealFieldInfo &Initializer) {
3867 for (const auto &AsInt : Initializer.AsIntValues) {
3868 getStreamer().emitIntValue(AsInt.getLimitedValue(),
3869 AsInt.getBitWidth() / 8);
3871 // Default-initialize all remaining values.
3872 for (auto It = Contents.AsIntValues.begin() + Initializer.AsIntValues.size();
3873 It != Contents.AsIntValues.end(); ++It) {
3874 const auto &AsInt = *It;
3875 getStreamer().emitIntValue(AsInt.getLimitedValue(),
3876 AsInt.getBitWidth() / 8);
3881 bool MasmParser::emitFieldInitializer(const FieldInfo &Field,
3882 const StructFieldInfo &Contents,
3883 const StructFieldInfo &Initializer) {
3884 for (const auto &Init : Initializer.Initializers) {
3885 emitStructInitializer(Contents.Structure, Init);
3887 // Default-initialize all remaining values.
3889 Contents.Initializers.begin() + Initializer.Initializers.size();
3890 It != Contents.Initializers.end(); ++It) {
3891 const auto &Init = *It;
3892 emitStructInitializer(Contents.Structure, Init);
3897 bool MasmParser::emitFieldInitializer(const FieldInfo &Field,
3898 const FieldInitializer &Initializer) {
3899 switch (Field.Contents.FT) {
3901 return emitFieldInitializer(Field, Field.Contents.IntInfo,
3902 Initializer.IntInfo);
3904 return emitFieldInitializer(Field, Field.Contents.RealInfo,
3905 Initializer.RealInfo);
3907 return emitFieldInitializer(Field, Field.Contents.StructInfo,
3908 Initializer.StructInfo);
3910 llvm_unreachable("Unhandled FieldType enum");
3913 bool MasmParser::emitStructInitializer(const StructInfo &Structure,
3914 const StructInitializer &Initializer) {
3915 size_t Index = 0, Offset = 0;
3916 for (const auto &Init : Initializer.FieldInitializers) {
3917 const auto &Field = Structure.Fields[Index++];
3918 getStreamer().emitZeros(Field.Offset - Offset);
3919 Offset = Field.Offset + Field.SizeOf;
3920 if (emitFieldInitializer(Field, Init))
3923 // Default-initialize all remaining fields.
3925 Structure.Fields.begin() + Initializer.FieldInitializers.size();
3926 It != Structure.Fields.end(); ++It) {
3927 const auto &Field = *It;
3928 getStreamer().emitZeros(Field.Offset - Offset);
3929 Offset = Field.Offset + Field.SizeOf;
3930 if (emitFieldValue(Field))
3933 // Add final padding.
3934 if (Offset != Structure.Size)
3935 getStreamer().emitZeros(Structure.Size - Offset);
3939 // Set data values from initializers.
3940 bool MasmParser::emitStructValues(const StructInfo &Structure) {
3941 std::vector<StructInitializer> Initializers;
3942 if (parseStructInstList(Structure, Initializers))
3945 for (const auto &Initializer : Initializers) {
3946 if (emitStructInitializer(Structure, Initializer))
3953 // Declare a field in the current struct.
3954 bool MasmParser::addStructField(StringRef Name, const StructInfo &Structure) {
3955 StructInfo &OwningStruct = StructInProgress.back();
3956 FieldInfo &Field = OwningStruct.addField(Name, FT_STRUCT);
3957 StructFieldInfo &StructInfo = Field.Contents.StructInfo;
3959 StructInfo.Structure = Structure;
3960 Field.Type = Structure.Size;
3962 if (parseStructInstList(Structure, StructInfo.Initializers))
3965 Field.LengthOf = StructInfo.Initializers.size();
3966 Field.SizeOf = Field.Type * Field.LengthOf;
3967 if (OwningStruct.IsUnion)
3968 OwningStruct.Size = std::max(OwningStruct.Size, Field.SizeOf);
3970 OwningStruct.Size += Field.SizeOf;
3975 /// parseDirectiveStructValue
3976 /// ::= struct-id (<struct-initializer> | {struct-initializer})
3977 /// [, (<struct-initializer> | {struct-initializer})]*
3978 bool MasmParser::parseDirectiveStructValue(const StructInfo &Structure,
3979 StringRef Directive, SMLoc DirLoc) {
3980 if (StructInProgress.empty()) {
3981 if (emitStructValues(Structure))
3983 } else if (addStructField("", Structure)) {
3984 return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
3990 /// parseDirectiveNamedValue
3991 /// ::= name (byte | word | ... ) [ expression (, expression)* ]
3992 bool MasmParser::parseDirectiveNamedStructValue(const StructInfo &Structure,
3993 StringRef Directive,
3994 SMLoc DirLoc, StringRef Name) {
3995 if (StructInProgress.empty()) {
3996 // Initialize named data value.
3997 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3998 getStreamer().emitLabel(Sym);
3999 KnownType[Name] = &Structure;
4000 if (emitStructValues(Structure))
4002 } else if (addStructField(Name, Structure)) {
4003 return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
4009 /// parseDirectiveStruct
4010 /// ::= <name> (STRUC | STRUCT | UNION) [fieldAlign] [, NONUNIQUE]
4011 /// (dataDir | generalDir | offsetDir | nestedStruct)+
4013 ////// dataDir = data declaration
4014 ////// offsetDir = EVEN, ORG, ALIGN
4015 bool MasmParser::parseDirectiveStruct(StringRef Directive,
4016 DirectiveKind DirKind, StringRef Name,
4018 // We ignore NONUNIQUE; we do not support OPTION M510 or OPTION OLDSTRUCTS
4019 // anyway, so all field accesses must be qualified.
4020 AsmToken NextTok = getTok();
4021 int64_t AlignmentValue = 1;
4022 if (NextTok.isNot(AsmToken::Comma) &&
4023 NextTok.isNot(AsmToken::EndOfStatement) &&
4024 parseAbsoluteExpression(AlignmentValue)) {
4025 return addErrorSuffix(" in alignment value for '" + Twine(Directive) +
4028 if (!isPowerOf2_64(AlignmentValue)) {
4029 return Error(NextTok.getLoc(), "alignment must be a power of two; was " +
4030 std::to_string(AlignmentValue));
4033 StringRef Qualifier;
4035 if (parseOptionalToken(AsmToken::Comma)) {
4036 QualifierLoc = getTok().getLoc();
4037 if (parseIdentifier(Qualifier))
4038 return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
4039 if (!Qualifier.equals_lower("nonunique"))
4040 return Error(QualifierLoc, "Unrecognized qualifier for '" +
4042 "' directive; expected none or NONUNIQUE");
4045 if (parseToken(AsmToken::EndOfStatement))
4046 return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
4048 StructInProgress.emplace_back(Name, DirKind == DK_UNION, AlignmentValue);
4052 /// parseDirectiveNestedStruct
4053 /// ::= (STRUC | STRUCT | UNION) [name]
4054 /// (dataDir | generalDir | offsetDir | nestedStruct)+
4056 bool MasmParser::parseDirectiveNestedStruct(StringRef Directive,
4057 DirectiveKind DirKind) {
4058 if (StructInProgress.empty())
4059 return TokError("missing name in top-level '" + Twine(Directive) +
4063 if (getTok().is(AsmToken::Identifier)) {
4064 Name = getTok().getIdentifier();
4065 parseToken(AsmToken::Identifier);
4067 if (parseToken(AsmToken::EndOfStatement))
4068 return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
4070 StructInProgress.emplace_back(Name, DirKind == DK_UNION,
4071 StructInProgress.back().Alignment);
4075 bool MasmParser::parseDirectiveEnds(StringRef Name, SMLoc NameLoc) {
4076 if (StructInProgress.empty())
4077 return Error(NameLoc, "ENDS directive without matching STRUC/STRUCT/UNION");
4078 if (StructInProgress.size() > 1)
4079 return Error(NameLoc, "unexpected name in nested ENDS directive");
4080 if (StructInProgress.back().Name.compare_lower(Name))
4081 return Error(NameLoc, "mismatched name in ENDS directive; expected '" +
4082 StructInProgress.back().Name + "'");
4083 StructInfo Structure = StructInProgress.pop_back_val();
4084 // Pad to make the structure's size divisible by its alignment.
4085 Structure.Size = llvm::alignTo(Structure.Size, Structure.Alignment);
4086 Structs[Name.lower()] = Structure;
4088 if (parseToken(AsmToken::EndOfStatement))
4089 return addErrorSuffix(" in ENDS directive");
4094 bool MasmParser::parseDirectiveNestedEnds() {
4095 if (StructInProgress.empty())
4096 return TokError("ENDS directive without matching STRUC/STRUCT/UNION");
4097 if (StructInProgress.size() == 1)
4098 return TokError("missing name in top-level ENDS directive");
4100 if (parseToken(AsmToken::EndOfStatement))
4101 return addErrorSuffix(" in nested ENDS directive");
4103 StructInfo Structure = StructInProgress.pop_back_val();
4104 // Pad to make the structure's size divisible by its alignment.
4105 Structure.Size = llvm::alignTo(Structure.Size, Structure.Alignment);
4107 StructInfo &ParentStruct = StructInProgress.back();
4108 if (Structure.Name.empty()) {
4109 const size_t OldFields = ParentStruct.Fields.size();
4110 ParentStruct.Fields.insert(
4111 ParentStruct.Fields.end(),
4112 std::make_move_iterator(Structure.Fields.begin()),
4113 std::make_move_iterator(Structure.Fields.end()));
4114 for (const auto &FieldByName : Structure.FieldsByName) {
4115 ParentStruct.FieldsByName[FieldByName.getKey()] =
4116 FieldByName.getValue() + OldFields;
4118 if (!ParentStruct.IsUnion) {
4119 for (auto FieldIter = ParentStruct.Fields.begin() + OldFields;
4120 FieldIter != ParentStruct.Fields.end(); ++FieldIter) {
4121 FieldIter->Offset += ParentStruct.Size;
4125 if (ParentStruct.IsUnion)
4126 ParentStruct.Size = std::max(ParentStruct.Size, Structure.Size);
4128 ParentStruct.Size += Structure.Size;
4130 FieldInfo &Field = ParentStruct.addField(Structure.Name, FT_STRUCT);
4131 StructFieldInfo &StructInfo = Field.Contents.StructInfo;
4132 Field.Type = Structure.Size;
4134 Field.SizeOf = Structure.Size;
4136 if (ParentStruct.IsUnion)
4137 ParentStruct.Size = std::max(ParentStruct.Size, Field.SizeOf);
4139 ParentStruct.Size += Field.SizeOf;
4141 StructInfo.Structure = Structure;
4142 StructInfo.Initializers.emplace_back();
4143 auto &FieldInitializers = StructInfo.Initializers.back().FieldInitializers;
4144 for (const auto &SubField : Structure.Fields) {
4145 FieldInitializers.push_back(SubField.Contents);
4152 /// parseDirectiveOrg
4153 /// ::= .org expression [ , expression ]
4154 bool MasmParser::parseDirectiveOrg() {
4155 const MCExpr *Offset;
4156 SMLoc OffsetLoc = Lexer.getLoc();
4157 if (checkForValidSection() || parseExpression(Offset))
4160 // Parse optional fill expression.
4161 int64_t FillExpr = 0;
4162 if (parseOptionalToken(AsmToken::Comma))
4163 if (parseAbsoluteExpression(FillExpr))
4164 return addErrorSuffix(" in '.org' directive");
4165 if (parseToken(AsmToken::EndOfStatement))
4166 return addErrorSuffix(" in '.org' directive");
4168 getStreamer().emitValueToOffset(Offset, FillExpr, OffsetLoc);
4172 /// parseDirectiveAlign
4173 /// ::= align expression
4174 bool MasmParser::parseDirectiveAlign() {
4175 SMLoc AlignmentLoc = getLexer().getLoc();
4178 if (checkForValidSection())
4179 return addErrorSuffix(" in align directive");
4180 // Ignore empty 'align' directives.
4181 if (getTok().is(AsmToken::EndOfStatement)) {
4182 Warning(AlignmentLoc, "align directive with no operand is ignored");
4183 return parseToken(AsmToken::EndOfStatement);
4185 if (parseAbsoluteExpression(Alignment) ||
4186 parseToken(AsmToken::EndOfStatement))
4187 return addErrorSuffix(" in align directive");
4189 // Always emit an alignment here even if we thrown an error.
4190 bool ReturnVal = false;
4192 // Reject alignments that aren't either a power of two or zero, for gas
4193 // compatibility. Alignment of zero is silently rounded up to one.
4196 if (!isPowerOf2_64(Alignment))
4197 ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2");
4199 // Check whether we should use optimal code alignment for this align
4201 const MCSection *Section = getStreamer().getCurrentSectionOnly();
4202 assert(Section && "must have section to emit alignment");
4203 if (Section->UseCodeAlign()) {
4204 getStreamer().emitCodeAlignment(Alignment, /*MaxBytesToEmit=*/0);
4206 // FIXME: Target specific behavior about how the "extra" bytes are filled.
4207 getStreamer().emitValueToAlignment(Alignment, /*Value=*/0, /*ValueSize=*/1,
4208 /*MaxBytesToEmit=*/0);
4214 /// parseDirectiveFile
4215 /// ::= .file filename
4216 /// ::= .file number [directory] filename [md5 checksum] [source source-text]
4217 bool MasmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
4218 // FIXME: I'm not sure what this is.
4219 int64_t FileNumber = -1;
4220 if (getLexer().is(AsmToken::Integer)) {
4221 FileNumber = getTok().getIntVal();
4225 return TokError("negative file number");
4230 // Usually the directory and filename together, otherwise just the directory.
4231 // Allow the strings to have escaped octal character sequence.
4232 if (check(getTok().isNot(AsmToken::String),
4233 "unexpected token in '.file' directive") ||
4234 parseEscapedString(Path))
4237 StringRef Directory;
4239 std::string FilenameData;
4240 if (getLexer().is(AsmToken::String)) {
4241 if (check(FileNumber == -1,
4242 "explicit path specified, but no file number") ||
4243 parseEscapedString(FilenameData))
4245 Filename = FilenameData;
4251 uint64_t MD5Hi, MD5Lo;
4252 bool HasMD5 = false;
4254 Optional<StringRef> Source;
4255 bool HasSource = false;
4256 std::string SourceString;
4258 while (!parseOptionalToken(AsmToken::EndOfStatement)) {
4260 if (check(getTok().isNot(AsmToken::Identifier),
4261 "unexpected token in '.file' directive") ||
4262 parseIdentifier(Keyword))
4264 if (Keyword == "md5") {
4266 if (check(FileNumber == -1,
4267 "MD5 checksum specified, but no file number") ||
4268 parseHexOcta(*this, MD5Hi, MD5Lo))
4270 } else if (Keyword == "source") {
4272 if (check(FileNumber == -1,
4273 "source specified, but no file number") ||
4274 check(getTok().isNot(AsmToken::String),
4275 "unexpected token in '.file' directive") ||
4276 parseEscapedString(SourceString))
4279 return TokError("unexpected token in '.file' directive");
4283 if (FileNumber == -1) {
4284 // Ignore the directive if there is no number and the target doesn't support
4285 // numberless .file directives. This allows some portability of assembler
4286 // between different object file formats.
4287 if (getContext().getAsmInfo()->hasSingleParameterDotFile())
4288 getStreamer().emitFileDirective(Filename);
4290 // In case there is a -g option as well as debug info from directive .file,
4291 // we turn off the -g option, directly use the existing debug info instead.
4292 // Throw away any implicit file table for the assembler source.
4293 if (Ctx.getGenDwarfForAssembly()) {
4294 Ctx.getMCDwarfLineTable(0).resetFileTable();
4295 Ctx.setGenDwarfForAssembly(false);
4298 Optional<MD5::MD5Result> CKMem;
4301 for (unsigned i = 0; i != 8; ++i) {
4302 Sum.Bytes[i] = uint8_t(MD5Hi >> ((7 - i) * 8));
4303 Sum.Bytes[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8));
4308 char *SourceBuf = static_cast<char *>(Ctx.allocate(SourceString.size()));
4309 memcpy(SourceBuf, SourceString.data(), SourceString.size());
4310 Source = StringRef(SourceBuf, SourceString.size());
4312 if (FileNumber == 0) {
4313 if (Ctx.getDwarfVersion() < 5)
4314 return Warning(DirectiveLoc, "file 0 not supported prior to DWARF-5");
4315 getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
4317 Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective(
4318 FileNumber, Directory, Filename, CKMem, Source);
4320 return Error(DirectiveLoc, toString(FileNumOrErr.takeError()));
4322 // Alert the user if there are some .file directives with MD5 and some not.
4323 // But only do that once.
4324 if (!ReportedInconsistentMD5 && !Ctx.isDwarfMD5UsageConsistent(0)) {
4325 ReportedInconsistentMD5 = true;
4326 return Warning(DirectiveLoc, "inconsistent use of MD5 checksums");
4333 /// parseDirectiveLine
4334 /// ::= .line [number]
4335 bool MasmParser::parseDirectiveLine() {
4337 if (getLexer().is(AsmToken::Integer)) {
4338 if (parseIntToken(LineNumber, "unexpected token in '.line' directive"))
4341 // FIXME: Do something with the .line.
4343 if (parseToken(AsmToken::EndOfStatement,
4344 "unexpected token in '.line' directive"))
4350 /// parseDirectiveLoc
4351 /// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end]
4352 /// [epilogue_begin] [is_stmt VALUE] [isa VALUE]
4353 /// The first number is a file number, must have been previously assigned with
4354 /// a .file directive, the second number is the line number and optionally the
4355 /// third number is a column position (zero if not specified). The remaining
4356 /// optional items are .loc sub-directives.
4357 bool MasmParser::parseDirectiveLoc() {
4358 int64_t FileNumber = 0, LineNumber = 0;
4359 SMLoc Loc = getTok().getLoc();
4360 if (parseIntToken(FileNumber, "unexpected token in '.loc' directive") ||
4361 check(FileNumber < 1 && Ctx.getDwarfVersion() < 5, Loc,
4362 "file number less than one in '.loc' directive") ||
4363 check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
4364 "unassigned file number in '.loc' directive"))
4368 if (getLexer().is(AsmToken::Integer)) {
4369 LineNumber = getTok().getIntVal();
4371 return TokError("line number less than zero in '.loc' directive");
4375 int64_t ColumnPos = 0;
4376 if (getLexer().is(AsmToken::Integer)) {
4377 ColumnPos = getTok().getIntVal();
4379 return TokError("column position less than zero in '.loc' directive");
4383 auto PrevFlags = getContext().getCurrentDwarfLoc().getFlags();
4384 unsigned Flags = PrevFlags & DWARF2_FLAG_IS_STMT;
4386 int64_t Discriminator = 0;
4388 auto parseLocOp = [&]() -> bool {
4390 SMLoc Loc = getTok().getLoc();
4391 if (parseIdentifier(Name))
4392 return TokError("unexpected token in '.loc' directive");
4394 if (Name == "basic_block")
4395 Flags |= DWARF2_FLAG_BASIC_BLOCK;
4396 else if (Name == "prologue_end")
4397 Flags |= DWARF2_FLAG_PROLOGUE_END;
4398 else if (Name == "epilogue_begin")
4399 Flags |= DWARF2_FLAG_EPILOGUE_BEGIN;
4400 else if (Name == "is_stmt") {
4401 Loc = getTok().getLoc();
4402 const MCExpr *Value;
4403 if (parseExpression(Value))
4405 // The expression must be the constant 0 or 1.
4406 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
4407 int Value = MCE->getValue();
4409 Flags &= ~DWARF2_FLAG_IS_STMT;
4410 else if (Value == 1)
4411 Flags |= DWARF2_FLAG_IS_STMT;
4413 return Error(Loc, "is_stmt value not 0 or 1");
4415 return Error(Loc, "is_stmt value not the constant value of 0 or 1");
4417 } else if (Name == "isa") {
4418 Loc = getTok().getLoc();
4419 const MCExpr *Value;
4420 if (parseExpression(Value))
4422 // The expression must be a constant greater or equal to 0.
4423 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
4424 int Value = MCE->getValue();
4426 return Error(Loc, "isa number less than zero");
4429 return Error(Loc, "isa number not a constant value");
4431 } else if (Name == "discriminator") {
4432 if (parseAbsoluteExpression(Discriminator))
4435 return Error(Loc, "unknown sub-directive in '.loc' directive");
4440 if (parseMany(parseLocOp, false /*hasComma*/))
4443 getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
4444 Isa, Discriminator, StringRef());
4449 /// parseDirectiveStabs
4450 /// ::= .stabs string, number, number, number
4451 bool MasmParser::parseDirectiveStabs() {
4452 return TokError("unsupported directive '.stabs'");
4455 /// parseDirectiveCVFile
4456 /// ::= .cv_file number filename [checksum] [checksumkind]
4457 bool MasmParser::parseDirectiveCVFile() {
4458 SMLoc FileNumberLoc = getTok().getLoc();
4460 std::string Filename;
4461 std::string Checksum;
4462 int64_t ChecksumKind = 0;
4464 if (parseIntToken(FileNumber,
4465 "expected file number in '.cv_file' directive") ||
4466 check(FileNumber < 1, FileNumberLoc, "file number less than one") ||
4467 check(getTok().isNot(AsmToken::String),
4468 "unexpected token in '.cv_file' directive") ||
4469 parseEscapedString(Filename))
4471 if (!parseOptionalToken(AsmToken::EndOfStatement)) {
4472 if (check(getTok().isNot(AsmToken::String),
4473 "unexpected token in '.cv_file' directive") ||
4474 parseEscapedString(Checksum) ||
4475 parseIntToken(ChecksumKind,
4476 "expected checksum kind in '.cv_file' directive") ||
4477 parseToken(AsmToken::EndOfStatement,
4478 "unexpected token in '.cv_file' directive"))
4482 Checksum = fromHex(Checksum);
4483 void *CKMem = Ctx.allocate(Checksum.size(), 1);
4484 memcpy(CKMem, Checksum.data(), Checksum.size());
4485 ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem),
4488 if (!getStreamer().EmitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
4489 static_cast<uint8_t>(ChecksumKind)))
4490 return Error(FileNumberLoc, "file number already allocated");
4495 bool MasmParser::parseCVFunctionId(int64_t &FunctionId,
4496 StringRef DirectiveName) {
4498 return parseTokenLoc(Loc) ||
4499 parseIntToken(FunctionId, "expected function id in '" + DirectiveName +
4501 check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
4502 "expected function id within range [0, UINT_MAX)");
4505 bool MasmParser::parseCVFileId(int64_t &FileNumber, StringRef DirectiveName) {
4507 return parseTokenLoc(Loc) ||
4508 parseIntToken(FileNumber, "expected integer in '" + DirectiveName +
4510 check(FileNumber < 1, Loc, "file number less than one in '" +
4511 DirectiveName + "' directive") ||
4512 check(!getCVContext().isValidFileNumber(FileNumber), Loc,
4513 "unassigned file number in '" + DirectiveName + "' directive");
4516 /// parseDirectiveCVFuncId
4517 /// ::= .cv_func_id FunctionId
4519 /// Introduces a function ID that can be used with .cv_loc.
4520 bool MasmParser::parseDirectiveCVFuncId() {
4521 SMLoc FunctionIdLoc = getTok().getLoc();
4524 if (parseCVFunctionId(FunctionId, ".cv_func_id") ||
4525 parseToken(AsmToken::EndOfStatement,
4526 "unexpected token in '.cv_func_id' directive"))
4529 if (!getStreamer().EmitCVFuncIdDirective(FunctionId))
4530 return Error(FunctionIdLoc, "function id already allocated");
4535 /// parseDirectiveCVInlineSiteId
4536 /// ::= .cv_inline_site_id FunctionId
4538 /// "inlined_at" IAFile IALine [IACol]
4540 /// Introduces a function ID that can be used with .cv_loc. Includes "inlined
4541 /// at" source location information for use in the line table of the caller,
4542 /// whether the caller is a real function or another inlined call site.
4543 bool MasmParser::parseDirectiveCVInlineSiteId() {
4544 SMLoc FunctionIdLoc = getTok().getLoc();
4552 if (parseCVFunctionId(FunctionId, ".cv_inline_site_id"))
4556 if (check((getLexer().isNot(AsmToken::Identifier) ||
4557 getTok().getIdentifier() != "within"),
4558 "expected 'within' identifier in '.cv_inline_site_id' directive"))
4563 if (parseCVFunctionId(IAFunc, ".cv_inline_site_id"))
4567 if (check((getLexer().isNot(AsmToken::Identifier) ||
4568 getTok().getIdentifier() != "inlined_at"),
4569 "expected 'inlined_at' identifier in '.cv_inline_site_id' "
4575 if (parseCVFileId(IAFile, ".cv_inline_site_id") ||
4576 parseIntToken(IALine, "expected line number after 'inlined_at'"))
4580 if (getLexer().is(AsmToken::Integer)) {
4581 IACol = getTok().getIntVal();
4585 if (parseToken(AsmToken::EndOfStatement,
4586 "unexpected token in '.cv_inline_site_id' directive"))
4589 if (!getStreamer().EmitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
4590 IALine, IACol, FunctionIdLoc))
4591 return Error(FunctionIdLoc, "function id already allocated");
4596 /// parseDirectiveCVLoc
4597 /// ::= .cv_loc FunctionId FileNumber [LineNumber] [ColumnPos] [prologue_end]
4599 /// The first number is a file number, must have been previously assigned with
4600 /// a .file directive, the second number is the line number and optionally the
4601 /// third number is a column position (zero if not specified). The remaining
4602 /// optional items are .loc sub-directives.
4603 bool MasmParser::parseDirectiveCVLoc() {
4604 SMLoc DirectiveLoc = getTok().getLoc();
4605 int64_t FunctionId, FileNumber;
4606 if (parseCVFunctionId(FunctionId, ".cv_loc") ||
4607 parseCVFileId(FileNumber, ".cv_loc"))
4610 int64_t LineNumber = 0;
4611 if (getLexer().is(AsmToken::Integer)) {
4612 LineNumber = getTok().getIntVal();
4614 return TokError("line number less than zero in '.cv_loc' directive");
4618 int64_t ColumnPos = 0;
4619 if (getLexer().is(AsmToken::Integer)) {
4620 ColumnPos = getTok().getIntVal();
4622 return TokError("column position less than zero in '.cv_loc' directive");
4626 bool PrologueEnd = false;
4627 uint64_t IsStmt = 0;
4629 auto parseOp = [&]() -> bool {
4631 SMLoc Loc = getTok().getLoc();
4632 if (parseIdentifier(Name))
4633 return TokError("unexpected token in '.cv_loc' directive");
4634 if (Name == "prologue_end")
4636 else if (Name == "is_stmt") {
4637 Loc = getTok().getLoc();
4638 const MCExpr *Value;
4639 if (parseExpression(Value))
4641 // The expression must be the constant 0 or 1.
4643 if (const auto *MCE = dyn_cast<MCConstantExpr>(Value))
4644 IsStmt = MCE->getValue();
4647 return Error(Loc, "is_stmt value not 0 or 1");
4649 return Error(Loc, "unknown sub-directive in '.cv_loc' directive");
4654 if (parseMany(parseOp, false /*hasComma*/))
4657 getStreamer().emitCVLocDirective(FunctionId, FileNumber, LineNumber,
4658 ColumnPos, PrologueEnd, IsStmt, StringRef(),
4663 /// parseDirectiveCVLinetable
4664 /// ::= .cv_linetable FunctionId, FnStart, FnEnd
4665 bool MasmParser::parseDirectiveCVLinetable() {
4667 StringRef FnStartName, FnEndName;
4668 SMLoc Loc = getTok().getLoc();
4669 if (parseCVFunctionId(FunctionId, ".cv_linetable") ||
4670 parseToken(AsmToken::Comma,
4671 "unexpected token in '.cv_linetable' directive") ||
4672 parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
4673 "expected identifier in directive") ||
4674 parseToken(AsmToken::Comma,
4675 "unexpected token in '.cv_linetable' directive") ||
4676 parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
4677 "expected identifier in directive"))
4680 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
4681 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
4683 getStreamer().emitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym);
4687 /// parseDirectiveCVInlineLinetable
4688 /// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart FnEnd
4689 bool MasmParser::parseDirectiveCVInlineLinetable() {
4690 int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
4691 StringRef FnStartName, FnEndName;
4692 SMLoc Loc = getTok().getLoc();
4693 if (parseCVFunctionId(PrimaryFunctionId, ".cv_inline_linetable") ||
4694 parseTokenLoc(Loc) ||
4697 "expected SourceField in '.cv_inline_linetable' directive") ||
4698 check(SourceFileId <= 0, Loc,
4699 "File id less than zero in '.cv_inline_linetable' directive") ||
4700 parseTokenLoc(Loc) ||
4703 "expected SourceLineNum in '.cv_inline_linetable' directive") ||
4704 check(SourceLineNum < 0, Loc,
4705 "Line number less than zero in '.cv_inline_linetable' directive") ||
4706 parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
4707 "expected identifier in directive") ||
4708 parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
4709 "expected identifier in directive"))
4712 if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
4715 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
4716 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
4717 getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
4718 SourceLineNum, FnStartSym,
4723 void MasmParser::initializeCVDefRangeTypeMap() {
4724 CVDefRangeTypeMap["reg"] = CVDR_DEFRANGE_REGISTER;
4725 CVDefRangeTypeMap["frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
4726 CVDefRangeTypeMap["subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
4727 CVDefRangeTypeMap["reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
4730 /// parseDirectiveCVDefRange
4731 /// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes*
4732 bool MasmParser::parseDirectiveCVDefRange() {
4734 std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;
4735 while (getLexer().is(AsmToken::Identifier)) {
4736 Loc = getLexer().getLoc();
4737 StringRef GapStartName;
4738 if (parseIdentifier(GapStartName))
4739 return Error(Loc, "expected identifier in directive");
4740 MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
4742 Loc = getLexer().getLoc();
4743 StringRef GapEndName;
4744 if (parseIdentifier(GapEndName))
4745 return Error(Loc, "expected identifier in directive");
4746 MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
4748 Ranges.push_back({GapStartSym, GapEndSym});
4751 StringRef CVDefRangeTypeStr;
4754 "expected comma before def_range type in .cv_def_range directive") ||
4755 parseIdentifier(CVDefRangeTypeStr))
4756 return Error(Loc, "expected def_range type in directive");
4758 StringMap<CVDefRangeType>::const_iterator CVTypeIt =
4759 CVDefRangeTypeMap.find(CVDefRangeTypeStr);
4760 CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
4762 : CVTypeIt->getValue();
4764 case CVDR_DEFRANGE_REGISTER: {
4766 if (parseToken(AsmToken::Comma, "expected comma before register number in "
4767 ".cv_def_range directive") ||
4768 parseAbsoluteExpression(DRRegister))
4769 return Error(Loc, "expected register number");
4771 codeview::DefRangeRegisterHeader DRHdr;
4772 DRHdr.Register = DRRegister;
4773 DRHdr.MayHaveNoName = 0;
4774 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4777 case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
4779 if (parseToken(AsmToken::Comma,
4780 "expected comma before offset in .cv_def_range directive") ||
4781 parseAbsoluteExpression(DROffset))
4782 return Error(Loc, "expected offset value");
4784 codeview::DefRangeFramePointerRelHeader DRHdr;
4785 DRHdr.Offset = DROffset;
4786 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4789 case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
4791 int64_t DROffsetInParent;
4792 if (parseToken(AsmToken::Comma, "expected comma before register number in "
4793 ".cv_def_range directive") ||
4794 parseAbsoluteExpression(DRRegister))
4795 return Error(Loc, "expected register number");
4796 if (parseToken(AsmToken::Comma,
4797 "expected comma before offset in .cv_def_range directive") ||
4798 parseAbsoluteExpression(DROffsetInParent))
4799 return Error(Loc, "expected offset value");
4801 codeview::DefRangeSubfieldRegisterHeader DRHdr;
4802 DRHdr.Register = DRRegister;
4803 DRHdr.MayHaveNoName = 0;
4804 DRHdr.OffsetInParent = DROffsetInParent;
4805 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4808 case CVDR_DEFRANGE_REGISTER_REL: {
4811 int64_t DRBasePointerOffset;
4812 if (parseToken(AsmToken::Comma, "expected comma before register number in "
4813 ".cv_def_range directive") ||
4814 parseAbsoluteExpression(DRRegister))
4815 return Error(Loc, "expected register value");
4818 "expected comma before flag value in .cv_def_range directive") ||
4819 parseAbsoluteExpression(DRFlags))
4820 return Error(Loc, "expected flag value");
4821 if (parseToken(AsmToken::Comma, "expected comma before base pointer offset "
4822 "in .cv_def_range directive") ||
4823 parseAbsoluteExpression(DRBasePointerOffset))
4824 return Error(Loc, "expected base pointer offset value");
4826 codeview::DefRangeRegisterRelHeader DRHdr;
4827 DRHdr.Register = DRRegister;
4828 DRHdr.Flags = DRFlags;
4829 DRHdr.BasePointerOffset = DRBasePointerOffset;
4830 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4834 return Error(Loc, "unexpected def_range type in .cv_def_range directive");
4839 /// parseDirectiveCVString
4840 /// ::= .cv_stringtable "string"
4841 bool MasmParser::parseDirectiveCVString() {
4843 if (checkForValidSection() || parseEscapedString(Data))
4844 return addErrorSuffix(" in '.cv_string' directive");
4846 // Put the string in the table and emit the offset.
4847 std::pair<StringRef, unsigned> Insertion =
4848 getCVContext().addToStringTable(Data);
4849 getStreamer().emitIntValue(Insertion.second, 4);
4853 /// parseDirectiveCVStringTable
4854 /// ::= .cv_stringtable
4855 bool MasmParser::parseDirectiveCVStringTable() {
4856 getStreamer().emitCVStringTableDirective();
4860 /// parseDirectiveCVFileChecksums
4861 /// ::= .cv_filechecksums
4862 bool MasmParser::parseDirectiveCVFileChecksums() {
4863 getStreamer().emitCVFileChecksumsDirective();
4867 /// parseDirectiveCVFileChecksumOffset
4868 /// ::= .cv_filechecksumoffset fileno
4869 bool MasmParser::parseDirectiveCVFileChecksumOffset() {
4871 if (parseIntToken(FileNo, "expected identifier in directive"))
4873 if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
4875 getStreamer().emitCVFileChecksumOffsetDirective(FileNo);
4879 /// parseDirectiveCVFPOData
4880 /// ::= .cv_fpo_data procsym
4881 bool MasmParser::parseDirectiveCVFPOData() {
4882 SMLoc DirLoc = getLexer().getLoc();
4884 if (parseIdentifier(ProcName))
4885 return TokError("expected symbol name");
4886 if (parseEOL("unexpected tokens"))
4887 return addErrorSuffix(" in '.cv_fpo_data' directive");
4888 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
4889 getStreamer().EmitCVFPOData(ProcSym, DirLoc);
4893 /// parseDirectiveCFISections
4894 /// ::= .cfi_sections section [, section]
4895 bool MasmParser::parseDirectiveCFISections() {
4900 if (parseIdentifier(Name))
4901 return TokError("Expected an identifier");
4903 if (Name == ".eh_frame")
4905 else if (Name == ".debug_frame")
4908 if (getLexer().is(AsmToken::Comma)) {
4911 if (parseIdentifier(Name))
4912 return TokError("Expected an identifier");
4914 if (Name == ".eh_frame")
4916 else if (Name == ".debug_frame")
4920 getStreamer().emitCFISections(EH, Debug);
4924 /// parseDirectiveCFIStartProc
4925 /// ::= .cfi_startproc [simple]
4926 bool MasmParser::parseDirectiveCFIStartProc() {
4928 if (!parseOptionalToken(AsmToken::EndOfStatement)) {
4929 if (check(parseIdentifier(Simple) || Simple != "simple",
4930 "unexpected token") ||
4931 parseToken(AsmToken::EndOfStatement))
4932 return addErrorSuffix(" in '.cfi_startproc' directive");
4935 // TODO(kristina): Deal with a corner case of incorrect diagnostic context
4936 // being produced if this directive is emitted as part of preprocessor macro
4937 // expansion which can *ONLY* happen if Clang's cc1as is the API consumer.
4938 // Tools like llvm-mc on the other hand are not affected by it, and report
4939 // correct context information.
4940 getStreamer().emitCFIStartProc(!Simple.empty(), Lexer.getLoc());
4944 /// parseDirectiveCFIEndProc
4945 /// ::= .cfi_endproc
4946 bool MasmParser::parseDirectiveCFIEndProc() {
4947 getStreamer().emitCFIEndProc();
4951 /// parse register name or number.
4952 bool MasmParser::parseRegisterOrRegisterNumber(int64_t &Register,
4953 SMLoc DirectiveLoc) {
4956 if (getLexer().isNot(AsmToken::Integer)) {
4957 if (getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc))
4959 Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true);
4961 return parseAbsoluteExpression(Register);
4966 /// parseDirectiveCFIDefCfa
4967 /// ::= .cfi_def_cfa register, offset
4968 bool MasmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
4969 int64_t Register = 0, Offset = 0;
4970 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
4971 parseToken(AsmToken::Comma, "unexpected token in directive") ||
4972 parseAbsoluteExpression(Offset))
4975 getStreamer().emitCFIDefCfa(Register, Offset);
4979 /// parseDirectiveCFIDefCfaOffset
4980 /// ::= .cfi_def_cfa_offset offset
4981 bool MasmParser::parseDirectiveCFIDefCfaOffset() {
4983 if (parseAbsoluteExpression(Offset))
4986 getStreamer().emitCFIDefCfaOffset(Offset);
4990 /// parseDirectiveCFIRegister
4991 /// ::= .cfi_register register, register
4992 bool MasmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
4993 int64_t Register1 = 0, Register2 = 0;
4994 if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) ||
4995 parseToken(AsmToken::Comma, "unexpected token in directive") ||
4996 parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
4999 getStreamer().emitCFIRegister(Register1, Register2);
5003 /// parseDirectiveCFIWindowSave
5004 /// ::= .cfi_window_save
5005 bool MasmParser::parseDirectiveCFIWindowSave() {
5006 getStreamer().emitCFIWindowSave();
5010 /// parseDirectiveCFIAdjustCfaOffset
5011 /// ::= .cfi_adjust_cfa_offset adjustment
5012 bool MasmParser::parseDirectiveCFIAdjustCfaOffset() {
5013 int64_t Adjustment = 0;
5014 if (parseAbsoluteExpression(Adjustment))
5017 getStreamer().emitCFIAdjustCfaOffset(Adjustment);
5021 /// parseDirectiveCFIDefCfaRegister
5022 /// ::= .cfi_def_cfa_register register
5023 bool MasmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) {
5024 int64_t Register = 0;
5025 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5028 getStreamer().emitCFIDefCfaRegister(Register);
5032 /// parseDirectiveCFIOffset
5033 /// ::= .cfi_offset register, offset
5034 bool MasmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
5035 int64_t Register = 0;
5038 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
5039 parseToken(AsmToken::Comma, "unexpected token in directive") ||
5040 parseAbsoluteExpression(Offset))
5043 getStreamer().emitCFIOffset(Register, Offset);
5047 /// parseDirectiveCFIRelOffset
5048 /// ::= .cfi_rel_offset register, offset
5049 bool MasmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
5050 int64_t Register = 0, Offset = 0;
5052 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
5053 parseToken(AsmToken::Comma, "unexpected token in directive") ||
5054 parseAbsoluteExpression(Offset))
5057 getStreamer().emitCFIRelOffset(Register, Offset);
5061 static bool isValidEncoding(int64_t Encoding) {
5062 if (Encoding & ~0xff)
5065 if (Encoding == dwarf::DW_EH_PE_omit)
5068 const unsigned Format = Encoding & 0xf;
5069 if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 &&
5070 Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 &&
5071 Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 &&
5072 Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed)
5075 const unsigned Application = Encoding & 0x70;
5076 if (Application != dwarf::DW_EH_PE_absptr &&
5077 Application != dwarf::DW_EH_PE_pcrel)
5083 /// parseDirectiveCFIPersonalityOrLsda
5084 /// IsPersonality true for cfi_personality, false for cfi_lsda
5085 /// ::= .cfi_personality encoding, [symbol_name]
5086 /// ::= .cfi_lsda encoding, [symbol_name]
5087 bool MasmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
5088 int64_t Encoding = 0;
5089 if (parseAbsoluteExpression(Encoding))
5091 if (Encoding == dwarf::DW_EH_PE_omit)
5095 if (check(!isValidEncoding(Encoding), "unsupported encoding.") ||
5096 parseToken(AsmToken::Comma, "unexpected token in directive") ||
5097 check(parseIdentifier(Name), "expected identifier in directive"))
5100 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5103 getStreamer().emitCFIPersonality(Sym, Encoding);
5105 getStreamer().emitCFILsda(Sym, Encoding);
5109 /// parseDirectiveCFIRememberState
5110 /// ::= .cfi_remember_state
5111 bool MasmParser::parseDirectiveCFIRememberState() {
5112 getStreamer().emitCFIRememberState();
5116 /// parseDirectiveCFIRestoreState
5117 /// ::= .cfi_remember_state
5118 bool MasmParser::parseDirectiveCFIRestoreState() {
5119 getStreamer().emitCFIRestoreState();
5123 /// parseDirectiveCFISameValue
5124 /// ::= .cfi_same_value register
5125 bool MasmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) {
5126 int64_t Register = 0;
5128 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5131 getStreamer().emitCFISameValue(Register);
5135 /// parseDirectiveCFIRestore
5136 /// ::= .cfi_restore register
5137 bool MasmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) {
5138 int64_t Register = 0;
5139 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5142 getStreamer().emitCFIRestore(Register);
5146 /// parseDirectiveCFIEscape
5147 /// ::= .cfi_escape expression[,...]
5148 bool MasmParser::parseDirectiveCFIEscape() {
5151 if (parseAbsoluteExpression(CurrValue))
5154 Values.push_back((uint8_t)CurrValue);
5156 while (getLexer().is(AsmToken::Comma)) {
5159 if (parseAbsoluteExpression(CurrValue))
5162 Values.push_back((uint8_t)CurrValue);
5165 getStreamer().emitCFIEscape(Values);
5169 /// parseDirectiveCFIReturnColumn
5170 /// ::= .cfi_return_column register
5171 bool MasmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) {
5172 int64_t Register = 0;
5173 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5175 getStreamer().emitCFIReturnColumn(Register);
5179 /// parseDirectiveCFISignalFrame
5180 /// ::= .cfi_signal_frame
5181 bool MasmParser::parseDirectiveCFISignalFrame() {
5182 if (parseToken(AsmToken::EndOfStatement,
5183 "unexpected token in '.cfi_signal_frame'"))
5186 getStreamer().emitCFISignalFrame();
5190 /// parseDirectiveCFIUndefined
5191 /// ::= .cfi_undefined register
5192 bool MasmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
5193 int64_t Register = 0;
5195 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5198 getStreamer().emitCFIUndefined(Register);
5202 /// parseDirectiveAltmacro
5205 bool MasmParser::parseDirectiveAltmacro(StringRef Directive) {
5206 if (getLexer().isNot(AsmToken::EndOfStatement))
5207 return TokError("unexpected token in '" + Directive + "' directive");
5208 AltMacroMode = (Directive == ".altmacro");
5212 /// parseDirectiveMacro
5213 /// ::= .macro name[,] [parameters]
5214 bool MasmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
5216 if (parseIdentifier(Name))
5217 return TokError("expected identifier in '.macro' directive");
5219 if (getLexer().is(AsmToken::Comma))
5222 MCAsmMacroParameters Parameters;
5223 while (getLexer().isNot(AsmToken::EndOfStatement)) {
5225 if (!Parameters.empty() && Parameters.back().Vararg)
5226 return Error(Lexer.getLoc(),
5227 "Vararg parameter '" + Parameters.back().Name +
5228 "' should be last one in the list of parameters.");
5230 MCAsmMacroParameter Parameter;
5231 if (parseIdentifier(Parameter.Name))
5232 return TokError("expected identifier in '.macro' directive");
5234 // Emit an error if two (or more) named parameters share the same name.
5235 for (const MCAsmMacroParameter& CurrParam : Parameters)
5236 if (CurrParam.Name.equals(Parameter.Name))
5237 return TokError("macro '" + Name + "' has multiple parameters"
5238 " named '" + Parameter.Name + "'");
5240 if (Lexer.is(AsmToken::Colon)) {
5241 Lex(); // consume ':'
5244 StringRef Qualifier;
5246 QualLoc = Lexer.getLoc();
5247 if (parseIdentifier(Qualifier))
5248 return Error(QualLoc, "missing parameter qualifier for "
5249 "'" + Parameter.Name + "' in macro '" + Name + "'");
5251 if (Qualifier == "req")
5252 Parameter.Required = true;
5253 else if (Qualifier == "vararg")
5254 Parameter.Vararg = true;
5256 return Error(QualLoc, Qualifier + " is not a valid parameter qualifier "
5257 "for '" + Parameter.Name + "' in macro '" + Name + "'");
5260 if (getLexer().is(AsmToken::Equal)) {
5265 ParamLoc = Lexer.getLoc();
5266 if (parseMacroArgument(Parameter.Value, /*Vararg=*/false ))
5269 if (Parameter.Required)
5270 Warning(ParamLoc, "pointless default value for required parameter "
5271 "'" + Parameter.Name + "' in macro '" + Name + "'");
5274 Parameters.push_back(std::move(Parameter));
5276 if (getLexer().is(AsmToken::Comma))
5280 // Eat just the end of statement.
5283 // Consuming deferred text, so use Lexer.Lex to ignore Lexing Errors.
5284 AsmToken EndToken, StartToken = getTok();
5285 unsigned MacroDepth = 0;
5286 // Lex the macro definition.
5288 // Ignore Lexing errors in macros.
5289 while (Lexer.is(AsmToken::Error)) {
5293 // Check whether we have reached the end of the file.
5294 if (getLexer().is(AsmToken::Eof))
5295 return Error(DirectiveLoc, "no matching '.endmacro' in definition");
5297 // Otherwise, check whether we have reach the .endmacro.
5298 if (getLexer().is(AsmToken::Identifier)) {
5299 if (getTok().getIdentifier() == ".endm" ||
5300 getTok().getIdentifier() == ".endmacro") {
5301 if (MacroDepth == 0) { // Outermost macro.
5302 EndToken = getTok();
5304 if (getLexer().isNot(AsmToken::EndOfStatement))
5305 return TokError("unexpected token in '" + EndToken.getIdentifier() +
5309 // Otherwise we just found the end of an inner macro.
5312 } else if (getTok().getIdentifier() == ".macro") {
5313 // We allow nested macros. Those aren't instantiated until the outermost
5314 // macro is expanded so just ignore them for now.
5319 // Otherwise, scan til the end of the statement.
5320 eatToEndOfStatement();
5323 if (getContext().lookupMacro(Name)) {
5324 return Error(DirectiveLoc, "macro '" + Name + "' is already defined");
5327 const char *BodyStart = StartToken.getLoc().getPointer();
5328 const char *BodyEnd = EndToken.getLoc().getPointer();
5329 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
5330 checkForBadMacro(DirectiveLoc, Name, Body, Parameters);
5331 MCAsmMacro Macro(Name, Body, std::move(Parameters));
5332 DEBUG_WITH_TYPE("asm-macros", dbgs() << "Defining new macro:\n";
5334 getContext().defineMacro(Name, std::move(Macro));
5338 /// checkForBadMacro
5340 /// With the support added for named parameters there may be code out there that
5341 /// is transitioning from positional parameters. In versions of gas that did
5342 /// not support named parameters they would be ignored on the macro definition.
5343 /// But to support both styles of parameters this is not possible so if a macro
5344 /// definition has named parameters but does not use them and has what appears
5345 /// to be positional parameters, strings like $1, $2, ... and $n, then issue a
5346 /// warning that the positional parameter found in body which have no effect.
5347 /// Hoping the developer will either remove the named parameters from the macro
5348 /// definition so the positional parameters get used if that was what was
5349 /// intended or change the macro to use the named parameters. It is possible
5350 /// this warning will trigger when the none of the named parameters are used
5351 /// and the strings like $1 are infact to simply to be passed trough unchanged.
5352 void MasmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
5354 ArrayRef<MCAsmMacroParameter> Parameters) {
5355 // If this macro is not defined with named parameters the warning we are
5356 // checking for here doesn't apply.
5357 unsigned NParameters = Parameters.size();
5358 if (NParameters == 0)
5361 bool NamedParametersFound = false;
5362 bool PositionalParametersFound = false;
5364 // Look at the body of the macro for use of both the named parameters and what
5365 // are likely to be positional parameters. This is what expandMacro() is
5366 // doing when it finds the parameters in the body.
5367 while (!Body.empty()) {
5368 // Scan for the next possible parameter.
5369 std::size_t End = Body.size(), Pos = 0;
5370 for (; Pos != End; ++Pos) {
5371 // Check for a substitution or escape.
5372 // This macro is defined with parameters, look for \foo, \bar, etc.
5373 if (Body[Pos] == '\\' && Pos + 1 != End)
5376 // This macro should have parameters, but look for $0, $1, ..., $n too.
5377 if (Body[Pos] != '$' || Pos + 1 == End)
5379 char Next = Body[Pos + 1];
5380 if (Next == '$' || Next == 'n' ||
5381 isdigit(static_cast<unsigned char>(Next)))
5385 // Check if we reached the end.
5389 if (Body[Pos] == '$') {
5390 switch (Body[Pos + 1]) {
5395 // $n => number of arguments
5397 PositionalParametersFound = true;
5400 // $[0-9] => argument
5402 PositionalParametersFound = true;
5408 unsigned I = Pos + 1;
5409 while (isIdentifierChar(Body[I]) && I + 1 != End)
5412 const char *Begin = Body.data() + Pos + 1;
5413 StringRef Argument(Begin, I - (Pos + 1));
5415 for (; Index < NParameters; ++Index)
5416 if (Parameters[Index].Name == Argument)
5419 if (Index == NParameters) {
5420 if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
5426 NamedParametersFound = true;
5427 Pos += 1 + Argument.size();
5430 // Update the scan point.
5431 Body = Body.substr(Pos);
5434 if (!NamedParametersFound && PositionalParametersFound)
5435 Warning(DirectiveLoc, "macro defined with named parameters which are not "
5436 "used in macro body, possible positional parameter "
5437 "found in body which will have no effect");
5440 /// parseDirectiveExitMacro
5442 bool MasmParser::parseDirectiveExitMacro(StringRef Directive) {
5443 if (parseToken(AsmToken::EndOfStatement,
5444 "unexpected token in '" + Directive + "' directive"))
5447 if (!isInsideMacroInstantiation())
5448 return TokError("unexpected '" + Directive + "' in file, "
5449 "no current macro definition");
5451 // Exit all conditionals that are active in the current macro.
5452 while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
5453 TheCondState = TheCondStack.back();
5454 TheCondStack.pop_back();
5461 /// parseDirectiveEndMacro
5464 bool MasmParser::parseDirectiveEndMacro(StringRef Directive) {
5465 if (getLexer().isNot(AsmToken::EndOfStatement))
5466 return TokError("unexpected token in '" + Directive + "' directive");
5468 // If we are inside a macro instantiation, terminate the current
5470 if (isInsideMacroInstantiation()) {
5475 // Otherwise, this .endmacro is a stray entry in the file; well formed
5476 // .endmacro directives are handled during the macro definition parsing.
5477 return TokError("unexpected '" + Directive + "' in file, "
5478 "no current macro definition");
5481 /// parseDirectivePurgeMacro
5483 bool MasmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
5486 if (parseTokenLoc(Loc) ||
5487 check(parseIdentifier(Name), Loc,
5488 "expected identifier in '.purgem' directive") ||
5489 parseToken(AsmToken::EndOfStatement,
5490 "unexpected token in '.purgem' directive"))
5493 if (!getContext().lookupMacro(Name))
5494 return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
5496 getContext().undefineMacro(Name);
5497 DEBUG_WITH_TYPE("asm-macros", dbgs()
5498 << "Un-defining macro: " << Name << "\n");
5502 /// parseDirectiveSymbolAttribute
5503 /// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
5504 bool MasmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
5505 auto parseOp = [&]() -> bool {
5507 SMLoc Loc = getTok().getLoc();
5508 if (parseIdentifier(Name))
5509 return Error(Loc, "expected identifier");
5510 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5512 // Assembler local symbols don't make any sense here. Complain loudly.
5513 if (Sym->isTemporary())
5514 return Error(Loc, "non-local symbol required");
5516 if (!getStreamer().emitSymbolAttribute(Sym, Attr))
5517 return Error(Loc, "unable to emit symbol attribute");
5521 if (parseMany(parseOp))
5522 return addErrorSuffix(" in directive");
5526 /// parseDirectiveComm
5527 /// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
5528 bool MasmParser::parseDirectiveComm(bool IsLocal) {
5529 if (checkForValidSection())
5532 SMLoc IDLoc = getLexer().getLoc();
5534 if (parseIdentifier(Name))
5535 return TokError("expected identifier in directive");
5537 // Handle the identifier as the key symbol.
5538 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5540 if (getLexer().isNot(AsmToken::Comma))
5541 return TokError("unexpected token in directive");
5545 SMLoc SizeLoc = getLexer().getLoc();
5546 if (parseAbsoluteExpression(Size))
5549 int64_t Pow2Alignment = 0;
5550 SMLoc Pow2AlignmentLoc;
5551 if (getLexer().is(AsmToken::Comma)) {
5553 Pow2AlignmentLoc = getLexer().getLoc();
5554 if (parseAbsoluteExpression(Pow2Alignment))
5557 LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType();
5558 if (IsLocal && LCOMM == LCOMM::NoAlignment)
5559 return Error(Pow2AlignmentLoc, "alignment not supported on this target");
5561 // If this target takes alignments in bytes (not log) validate and convert.
5562 if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
5563 (IsLocal && LCOMM == LCOMM::ByteAlignment)) {
5564 if (!isPowerOf2_64(Pow2Alignment))
5565 return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
5566 Pow2Alignment = Log2_64(Pow2Alignment);
5570 if (parseToken(AsmToken::EndOfStatement,
5571 "unexpected token in '.comm' or '.lcomm' directive"))
5574 // NOTE: a size of zero for a .comm should create a undefined symbol
5575 // but a size of .lcomm creates a bss symbol of size zero.
5577 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
5578 "be less than zero");
5580 // NOTE: The alignment in the directive is a power of 2 value, the assembler
5581 // may internally end up wanting an alignment in bytes.
5582 // FIXME: Diagnose overflow.
5583 if (Pow2Alignment < 0)
5584 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
5585 "alignment, can't be less than zero");
5587 Sym->redefineIfPossible();
5588 if (!Sym->isUndefined())
5589 return Error(IDLoc, "invalid symbol redefinition");
5591 // Create the Symbol as a common or local common with Size and Pow2Alignment.
5593 getStreamer().emitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment);
5597 getStreamer().emitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
5601 /// parseDirectiveComment
5602 /// ::= comment delimiter [[text]]
5604 /// [[text]] delimiter [[text]]
5605 bool MasmParser::parseDirectiveComment(SMLoc DirectiveLoc) {
5606 StringRef FirstLine = parseStringToEndOfStatement();
5607 size_t DelimiterEnd = FirstLine.find_first_of("\b\t\v\f\r\x1A ");
5608 StringRef Delimiter = FirstLine.take_front(DelimiterEnd);
5609 if (Delimiter.empty())
5610 return Error(DirectiveLoc, "no delimiter in 'comment' directive");
5612 if (getTok().is(AsmToken::Eof))
5613 return Error(DirectiveLoc, "unmatched delimiter in 'comment' directive");
5614 Lex(); // eat end of statement
5615 } while (!parseStringToEndOfStatement().contains(Delimiter));
5616 return parseToken(AsmToken::EndOfStatement,
5617 "unexpected token in 'comment' directive");
5620 /// parseDirectiveInclude
5621 /// ::= include <filename>
5622 /// | include filename
5623 bool MasmParser::parseDirectiveInclude() {
5624 // Allow the strings to have escaped octal character sequence.
5625 std::string Filename;
5626 SMLoc IncludeLoc = getTok().getLoc();
5628 if (!parseAngleBracketString(Filename))
5629 Filename = parseStringToEndOfStatement().str();
5630 if (check(!Filename.empty(), "missing filename in 'include' directive") ||
5631 check(getTok().isNot(AsmToken::EndOfStatement),
5632 "unexpected token in 'include' directive") ||
5633 // Attempt to switch the lexer to the included file before consuming the
5634 // end of statement to avoid losing it when we switch.
5635 check(enterIncludeFile(Filename), IncludeLoc,
5636 "Could not find include file '" + Filename + "'"))
5642 /// parseDirectiveIf
5643 /// ::= .if{,eq,ge,gt,le,lt,ne} expression
5644 bool MasmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
5645 TheCondStack.push_back(TheCondState);
5646 TheCondState.TheCond = AsmCond::IfCond;
5647 if (TheCondState.Ignore) {
5648 eatToEndOfStatement();
5651 if (parseAbsoluteExpression(ExprValue) ||
5652 parseToken(AsmToken::EndOfStatement,
5653 "unexpected token in '.if' directive"))
5658 llvm_unreachable("unsupported directive");
5662 ExprValue = ExprValue == 0;
5666 TheCondState.CondMet = ExprValue;
5667 TheCondState.Ignore = !TheCondState.CondMet;
5673 /// parseDirectiveIfb
5675 bool MasmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
5676 TheCondStack.push_back(TheCondState);
5677 TheCondState.TheCond = AsmCond::IfCond;
5679 if (TheCondState.Ignore) {
5680 eatToEndOfStatement();
5683 if (parseTextItem(Str))
5684 return TokError("expected string parameter for 'ifb' directive");
5686 if (parseToken(AsmToken::EndOfStatement,
5687 "unexpected token in 'ifb' directive"))
5690 TheCondState.CondMet = ExpectBlank == Str.empty();
5691 TheCondState.Ignore = !TheCondState.CondMet;
5697 /// parseDirectiveIfidn
5698 /// ::= ifidn string1, string2
5699 bool MasmParser::parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual, bool CaseInsensitive) {
5700 std::string String1, String2;
5702 if (parseTextItem(String1)) {
5704 return TokError("expected string parameter for 'ifidn' directive");
5705 return TokError("expected string parameter for 'ifdif' directive");
5708 if (Lexer.isNot(AsmToken::Comma)) {
5711 "expected comma after first string for 'ifidn' directive");
5712 return TokError("expected comma after first string for 'ifdif' directive");
5716 if (parseTextItem(String2)) {
5718 return TokError("expected string parameter for 'ifidn' directive");
5719 return TokError("expected string parameter for 'ifdif' directive");
5722 TheCondStack.push_back(TheCondState);
5723 TheCondState.TheCond = AsmCond::IfCond;
5724 if (CaseInsensitive)
5725 TheCondState.CondMet =
5726 ExpectEqual == (StringRef(String1).equals_lower(String2));
5728 TheCondState.CondMet = ExpectEqual == (String1 == String2);
5729 TheCondState.Ignore = !TheCondState.CondMet;
5734 /// parseDirectiveIfdef
5735 /// ::= ifdef symbol
5736 /// | ifdef variable
5737 bool MasmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
5738 TheCondStack.push_back(TheCondState);
5739 TheCondState.TheCond = AsmCond::IfCond;
5741 if (TheCondState.Ignore) {
5742 eatToEndOfStatement();
5744 bool is_defined = false;
5746 SMLoc StartLoc, EndLoc;
5747 is_defined = (getTargetParser().tryParseRegister(
5748 RegNo, StartLoc, EndLoc) == MatchOperand_Success);
5751 if (check(parseIdentifier(Name), "expected identifier after 'ifdef'") ||
5752 parseToken(AsmToken::EndOfStatement, "unexpected token in 'ifdef'"))
5755 if (Variables.find(Name) != Variables.end()) {
5758 MCSymbol *Sym = getContext().lookupSymbol(Name);
5759 is_defined = (Sym && !Sym->isUndefined(false));
5763 TheCondState.CondMet = (is_defined == expect_defined);
5764 TheCondState.Ignore = !TheCondState.CondMet;
5770 /// parseDirectiveElseIf
5771 /// ::= elseif expression
5772 bool MasmParser::parseDirectiveElseIf(SMLoc DirectiveLoc,
5773 DirectiveKind DirKind) {
5774 if (TheCondState.TheCond != AsmCond::IfCond &&
5775 TheCondState.TheCond != AsmCond::ElseIfCond)
5776 return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an"
5777 " .if or an .elseif");
5778 TheCondState.TheCond = AsmCond::ElseIfCond;
5780 bool LastIgnoreState = false;
5781 if (!TheCondStack.empty())
5782 LastIgnoreState = TheCondStack.back().Ignore;
5783 if (LastIgnoreState || TheCondState.CondMet) {
5784 TheCondState.Ignore = true;
5785 eatToEndOfStatement();
5788 if (parseAbsoluteExpression(ExprValue))
5791 if (parseToken(AsmToken::EndOfStatement,
5792 "unexpected token in '.elseif' directive"))
5797 llvm_unreachable("unsupported directive");
5801 ExprValue = ExprValue == 0;
5805 TheCondState.CondMet = ExprValue;
5806 TheCondState.Ignore = !TheCondState.CondMet;
5812 /// parseDirectiveElseIfb
5813 /// ::= elseifb expression
5814 bool MasmParser::parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
5815 if (TheCondState.TheCond != AsmCond::IfCond &&
5816 TheCondState.TheCond != AsmCond::ElseIfCond)
5817 return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
5818 " if or an elseif");
5819 TheCondState.TheCond = AsmCond::ElseIfCond;
5821 bool LastIgnoreState = false;
5822 if (!TheCondStack.empty())
5823 LastIgnoreState = TheCondStack.back().Ignore;
5824 if (LastIgnoreState || TheCondState.CondMet) {
5825 TheCondState.Ignore = true;
5826 eatToEndOfStatement();
5829 if (parseTextItem(Str))
5830 return TokError("expected string parameter for 'elseifb' directive");
5832 if (parseToken(AsmToken::EndOfStatement,
5833 "unexpected token in 'elseifb' directive"))
5836 TheCondState.CondMet = ExpectBlank == Str.empty();
5837 TheCondState.Ignore = !TheCondState.CondMet;
5843 /// parseDirectiveElseIfdef
5844 /// ::= elseifdef symbol
5845 /// | elseifdef variable
5846 bool MasmParser::parseDirectiveElseIfdef(SMLoc DirectiveLoc,
5847 bool expect_defined) {
5848 if (TheCondState.TheCond != AsmCond::IfCond &&
5849 TheCondState.TheCond != AsmCond::ElseIfCond)
5850 return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
5851 " if or an elseif");
5852 TheCondState.TheCond = AsmCond::ElseIfCond;
5854 bool LastIgnoreState = false;
5855 if (!TheCondStack.empty())
5856 LastIgnoreState = TheCondStack.back().Ignore;
5857 if (LastIgnoreState || TheCondState.CondMet) {
5858 TheCondState.Ignore = true;
5859 eatToEndOfStatement();
5861 bool is_defined = false;
5863 SMLoc StartLoc, EndLoc;
5864 is_defined = (getTargetParser().tryParseRegister(RegNo, StartLoc, EndLoc) ==
5865 MatchOperand_Success);
5868 if (check(parseIdentifier(Name),
5869 "expected identifier after 'elseifdef'") ||
5870 parseToken(AsmToken::EndOfStatement,
5871 "unexpected token in 'elseifdef'"))
5874 if (Variables.find(Name) != Variables.end()) {
5877 MCSymbol *Sym = getContext().lookupSymbol(Name);
5878 is_defined = (Sym && !Sym->isUndefined(false));
5882 TheCondState.CondMet = (is_defined == expect_defined);
5883 TheCondState.Ignore = !TheCondState.CondMet;
5889 /// parseDirectiveElseIfidn
5890 /// ::= elseifidn string1, string2
5891 bool MasmParser::parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
5892 bool CaseInsensitive) {
5893 if (TheCondState.TheCond != AsmCond::IfCond &&
5894 TheCondState.TheCond != AsmCond::ElseIfCond)
5895 return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
5896 " if or an elseif");
5897 TheCondState.TheCond = AsmCond::ElseIfCond;
5899 bool LastIgnoreState = false;
5900 if (!TheCondStack.empty())
5901 LastIgnoreState = TheCondStack.back().Ignore;
5902 if (LastIgnoreState || TheCondState.CondMet) {
5903 TheCondState.Ignore = true;
5904 eatToEndOfStatement();
5906 std::string String1, String2;
5908 if (parseTextItem(String1)) {
5910 return TokError("expected string parameter for 'elseifidn' directive");
5911 return TokError("expected string parameter for 'elseifdif' directive");
5914 if (Lexer.isNot(AsmToken::Comma)) {
5917 "expected comma after first string for 'elseifidn' directive");
5919 "expected comma after first string for 'elseifdif' directive");
5923 if (parseTextItem(String2)) {
5925 return TokError("expected string parameter for 'elseifidn' directive");
5926 return TokError("expected string parameter for 'elseifdif' directive");
5929 if (CaseInsensitive)
5930 TheCondState.CondMet =
5931 ExpectEqual == (StringRef(String1).equals_lower(String2));
5933 TheCondState.CondMet = ExpectEqual == (String1 == String2);
5934 TheCondState.Ignore = !TheCondState.CondMet;
5940 /// parseDirectiveElse
5942 bool MasmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
5943 if (parseToken(AsmToken::EndOfStatement,
5944 "unexpected token in 'else' directive"))
5947 if (TheCondState.TheCond != AsmCond::IfCond &&
5948 TheCondState.TheCond != AsmCond::ElseIfCond)
5949 return Error(DirectiveLoc, "Encountered an else that doesn't follow an if"
5951 TheCondState.TheCond = AsmCond::ElseCond;
5952 bool LastIgnoreState = false;
5953 if (!TheCondStack.empty())
5954 LastIgnoreState = TheCondStack.back().Ignore;
5955 if (LastIgnoreState || TheCondState.CondMet)
5956 TheCondState.Ignore = true;
5958 TheCondState.Ignore = false;
5963 /// parseDirectiveEnd
5965 bool MasmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
5966 if (parseToken(AsmToken::EndOfStatement,
5967 "unexpected token in 'end' directive"))
5970 while (Lexer.isNot(AsmToken::Eof))
5976 /// parseDirectiveError
5977 /// ::= .err [message]
5978 bool MasmParser::parseDirectiveError(SMLoc DirectiveLoc) {
5979 if (!TheCondStack.empty()) {
5980 if (TheCondStack.back().Ignore) {
5981 eatToEndOfStatement();
5986 StringRef Message = ".err directive invoked in source file";
5987 if (Lexer.isNot(AsmToken::EndOfStatement))
5988 Message = parseStringToEndOfStatement();
5991 return Error(DirectiveLoc, Message);
5994 /// parseDirectiveErrorIfb
5995 /// ::= .errb textitem[, message]
5996 bool MasmParser::parseDirectiveErrorIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
5997 if (!TheCondStack.empty()) {
5998 if (TheCondStack.back().Ignore) {
5999 eatToEndOfStatement();
6005 if (parseTextItem(Text))
6006 return Error(getTok().getLoc(), "missing text item in '.errb' directive");
6008 StringRef Message = ".errb directive invoked in source file";
6009 if (Lexer.isNot(AsmToken::EndOfStatement)) {
6010 if (parseToken(AsmToken::Comma))
6011 return addErrorSuffix(" in '.errb' directive");
6012 Message = parseStringToEndOfStatement();
6016 if (Text.empty() == ExpectBlank)
6017 return Error(DirectiveLoc, Message);
6021 /// parseDirectiveErrorIfdef
6022 /// ::= .errdef name[, message]
6023 bool MasmParser::parseDirectiveErrorIfdef(SMLoc DirectiveLoc,
6024 bool ExpectDefined) {
6025 if (!TheCondStack.empty()) {
6026 if (TheCondStack.back().Ignore) {
6027 eatToEndOfStatement();
6032 bool IsDefined = false;
6034 SMLoc StartLoc, EndLoc;
6035 IsDefined = (getTargetParser().tryParseRegister(RegNo, StartLoc, EndLoc) ==
6036 MatchOperand_Success);
6039 if (check(parseIdentifier(Name), "expected identifier after '.errdef'"))
6042 if (Variables.find(Name) != Variables.end()) {
6045 MCSymbol *Sym = getContext().lookupSymbol(Name);
6046 IsDefined = (Sym && !Sym->isUndefined(false));
6050 StringRef Message = ".errdef directive invoked in source file";
6051 if (Lexer.isNot(AsmToken::EndOfStatement)) {
6052 if (parseToken(AsmToken::Comma))
6053 return addErrorSuffix(" in '.errdef' directive");
6054 Message = parseStringToEndOfStatement();
6058 if (IsDefined == ExpectDefined)
6059 return Error(DirectiveLoc, Message);
6063 /// parseDirectiveErrorIfidn
6064 /// ::= .erridn textitem1, textitem2[, message]
6065 bool MasmParser::parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
6066 bool CaseInsensitive) {
6067 if (!TheCondStack.empty()) {
6068 if (TheCondStack.back().Ignore) {
6069 eatToEndOfStatement();
6074 std::string String1, String2;
6076 if (parseTextItem(String1)) {
6078 return TokError("expected string parameter for '.erridn' directive");
6079 return TokError("expected string parameter for '.errdif' directive");
6082 if (Lexer.isNot(AsmToken::Comma)) {
6085 "expected comma after first string for '.erridn' directive");
6087 "expected comma after first string for '.errdif' directive");
6091 if (parseTextItem(String2)) {
6093 return TokError("expected string parameter for '.erridn' directive");
6094 return TokError("expected string parameter for '.errdif' directive");
6099 Message = ".erridn directive invoked in source file";
6101 Message = ".errdif directive invoked in source file";
6102 if (Lexer.isNot(AsmToken::EndOfStatement)) {
6103 if (parseToken(AsmToken::Comma))
6104 return addErrorSuffix(" in '.erridn' directive");
6105 Message = parseStringToEndOfStatement();
6109 if (CaseInsensitive)
6110 TheCondState.CondMet =
6111 ExpectEqual == (StringRef(String1).equals_lower(String2));
6113 TheCondState.CondMet = ExpectEqual == (String1 == String2);
6114 TheCondState.Ignore = !TheCondState.CondMet;
6116 if ((CaseInsensitive &&
6117 ExpectEqual == StringRef(String1).equals_lower(String2)) ||
6118 (ExpectEqual == (String1 == String2)))
6119 return Error(DirectiveLoc, Message);
6123 /// parseDirectiveErrorIfe
6124 /// ::= .erre expression[, message]
6125 bool MasmParser::parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero) {
6126 if (!TheCondStack.empty()) {
6127 if (TheCondStack.back().Ignore) {
6128 eatToEndOfStatement();
6134 if (parseAbsoluteExpression(ExprValue))
6135 return addErrorSuffix(" in '.erre' directive");
6137 StringRef Message = ".erre directive invoked in source file";
6138 if (Lexer.isNot(AsmToken::EndOfStatement)) {
6139 if (parseToken(AsmToken::Comma))
6140 return addErrorSuffix(" in '.erre' directive");
6141 Message = parseStringToEndOfStatement();
6145 if ((ExprValue == 0) == ExpectZero)
6146 return Error(DirectiveLoc, Message);
6150 /// parseDirectiveEndIf
6152 bool MasmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
6153 if (parseToken(AsmToken::EndOfStatement,
6154 "unexpected token in '.endif' directive"))
6157 if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty())
6158 return Error(DirectiveLoc, "Encountered a .endif that doesn't follow "
6160 if (!TheCondStack.empty()) {
6161 TheCondState = TheCondStack.back();
6162 TheCondStack.pop_back();
6168 void MasmParser::initializeDirectiveKindMap() {
6169 DirectiveKindMap["="] = DK_ASSIGN;
6170 DirectiveKindMap["equ"] = DK_EQU;
6171 DirectiveKindMap["textequ"] = DK_TEXTEQU;
6172 // DirectiveKindMap[".ascii"] = DK_ASCII;
6173 // DirectiveKindMap[".asciz"] = DK_ASCIZ;
6174 // DirectiveKindMap[".string"] = DK_STRING;
6175 DirectiveKindMap["byte"] = DK_BYTE;
6176 DirectiveKindMap["sbyte"] = DK_SBYTE;
6177 DirectiveKindMap["word"] = DK_WORD;
6178 DirectiveKindMap["sword"] = DK_SWORD;
6179 DirectiveKindMap["dword"] = DK_DWORD;
6180 DirectiveKindMap["sdword"] = DK_SDWORD;
6181 DirectiveKindMap["fword"] = DK_FWORD;
6182 DirectiveKindMap["qword"] = DK_QWORD;
6183 DirectiveKindMap["sqword"] = DK_SQWORD;
6184 DirectiveKindMap["real4"] = DK_REAL4;
6185 DirectiveKindMap["real8"] = DK_REAL8;
6186 DirectiveKindMap["align"] = DK_ALIGN;
6187 // DirectiveKindMap[".org"] = DK_ORG;
6188 DirectiveKindMap["extern"] = DK_EXTERN;
6189 DirectiveKindMap["public"] = DK_PUBLIC;
6190 // DirectiveKindMap[".comm"] = DK_COMM;
6191 DirectiveKindMap["comment"] = DK_COMMENT;
6192 DirectiveKindMap["include"] = DK_INCLUDE;
6193 // DirectiveKindMap[".rept"] = DK_REPT;
6194 // DirectiveKindMap[".rep"] = DK_REPT;
6195 // DirectiveKindMap[".irp"] = DK_IRP;
6196 // DirectiveKindMap[".irpc"] = DK_IRPC;
6197 // DirectiveKindMap[".endr"] = DK_ENDR;
6198 DirectiveKindMap["if"] = DK_IF;
6199 DirectiveKindMap["ife"] = DK_IFE;
6200 DirectiveKindMap["ifb"] = DK_IFB;
6201 DirectiveKindMap["ifnb"] = DK_IFNB;
6202 DirectiveKindMap["ifdef"] = DK_IFDEF;
6203 DirectiveKindMap["ifndef"] = DK_IFNDEF;
6204 DirectiveKindMap["ifdif"] = DK_IFDIF;
6205 DirectiveKindMap["ifdifi"] = DK_IFDIFI;
6206 DirectiveKindMap["ifidn"] = DK_IFIDN;
6207 DirectiveKindMap["ifidni"] = DK_IFIDNI;
6208 DirectiveKindMap["elseif"] = DK_ELSEIF;
6209 DirectiveKindMap["elseifdef"] = DK_ELSEIFDEF;
6210 DirectiveKindMap["elseifndef"] = DK_ELSEIFNDEF;
6211 DirectiveKindMap["elseifdif"] = DK_ELSEIFDIF;
6212 DirectiveKindMap["elseifidn"] = DK_ELSEIFIDN;
6213 DirectiveKindMap["else"] = DK_ELSE;
6214 DirectiveKindMap["end"] = DK_END;
6215 DirectiveKindMap["endif"] = DK_ENDIF;
6216 // DirectiveKindMap[".file"] = DK_FILE;
6217 // DirectiveKindMap[".line"] = DK_LINE;
6218 // DirectiveKindMap[".loc"] = DK_LOC;
6219 // DirectiveKindMap[".stabs"] = DK_STABS;
6220 // DirectiveKindMap[".cv_file"] = DK_CV_FILE;
6221 // DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID;
6222 // DirectiveKindMap[".cv_loc"] = DK_CV_LOC;
6223 // DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE;
6224 // DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
6225 // DirectiveKindMap[".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID;
6226 // DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;
6227 // DirectiveKindMap[".cv_string"] = DK_CV_STRING;
6228 // DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;
6229 // DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
6230 // DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
6231 // DirectiveKindMap[".cv_fpo_data"] = DK_CV_FPO_DATA;
6232 // DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;
6233 // DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC;
6234 // DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC;
6235 // DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA;
6236 // DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
6237 // DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
6238 // DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
6239 // DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET;
6240 // DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
6241 // DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY;
6242 // DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA;
6243 // DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE;
6244 // DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE;
6245 // DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE;
6246 // DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE;
6247 // DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE;
6248 // DirectiveKindMap[".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
6249 // DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
6250 // DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
6251 // DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
6252 // DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
6253 // DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
6254 // DirectiveKindMap[".macro"] = DK_MACRO;
6255 // DirectiveKindMap[".exitm"] = DK_EXITM;
6256 // DirectiveKindMap[".endm"] = DK_ENDM;
6257 // DirectiveKindMap[".purgem"] = DK_PURGEM;
6258 DirectiveKindMap[".err"] = DK_ERR;
6259 DirectiveKindMap[".errb"] = DK_ERRB;
6260 DirectiveKindMap[".errnb"] = DK_ERRNB;
6261 DirectiveKindMap[".errdef"] = DK_ERRDEF;
6262 DirectiveKindMap[".errndef"] = DK_ERRNDEF;
6263 DirectiveKindMap[".errdif"] = DK_ERRDIF;
6264 DirectiveKindMap[".errdifi"] = DK_ERRDIFI;
6265 DirectiveKindMap[".erridn"] = DK_ERRIDN;
6266 DirectiveKindMap[".erridni"] = DK_ERRIDNI;
6267 DirectiveKindMap[".erre"] = DK_ERRE;
6268 DirectiveKindMap[".errnz"] = DK_ERRNZ;
6269 // DirectiveKindMap[".altmacro"] = DK_ALTMACRO;
6270 // DirectiveKindMap[".noaltmacro"] = DK_NOALTMACRO;
6271 DirectiveKindMap["db"] = DK_DB;
6272 DirectiveKindMap["dd"] = DK_DD;
6273 DirectiveKindMap["dq"] = DK_DQ;
6274 DirectiveKindMap["dw"] = DK_DW;
6275 DirectiveKindMap["echo"] = DK_ECHO;
6276 DirectiveKindMap["struc"] = DK_STRUCT;
6277 DirectiveKindMap["struct"] = DK_STRUCT;
6278 DirectiveKindMap["union"] = DK_UNION;
6279 DirectiveKindMap["ends"] = DK_ENDS;
6282 MCAsmMacro *MasmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
6283 AsmToken EndToken, StartToken = getTok();
6285 unsigned NestLevel = 0;
6287 // Check whether we have reached the end of the file.
6288 if (getLexer().is(AsmToken::Eof)) {
6289 printError(DirectiveLoc, "no matching '.endr' in definition");
6293 if (Lexer.is(AsmToken::Identifier) &&
6294 (getTok().getIdentifier() == ".rep" ||
6295 getTok().getIdentifier() == ".rept" ||
6296 getTok().getIdentifier() == ".irp" ||
6297 getTok().getIdentifier() == ".irpc")) {
6301 // Otherwise, check whether we have reached the .endr.
6302 if (Lexer.is(AsmToken::Identifier) && getTok().getIdentifier() == ".endr") {
6303 if (NestLevel == 0) {
6304 EndToken = getTok();
6306 if (Lexer.isNot(AsmToken::EndOfStatement)) {
6307 printError(getTok().getLoc(),
6308 "unexpected token in '.endr' directive");
6316 // Otherwise, scan till the end of the statement.
6317 eatToEndOfStatement();
6320 const char *BodyStart = StartToken.getLoc().getPointer();
6321 const char *BodyEnd = EndToken.getLoc().getPointer();
6322 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
6324 // We Are Anonymous.
6325 MacroLikeBodies.emplace_back(StringRef(), Body, MCAsmMacroParameters());
6326 return &MacroLikeBodies.back();
6329 void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
6330 raw_svector_ostream &OS) {
6333 std::unique_ptr<MemoryBuffer> Instantiation =
6334 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
6336 // Create the macro instantiation object and add to the current macro
6337 // instantiation stack.
6338 MacroInstantiation *MI = new MacroInstantiation{
6339 DirectiveLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
6340 ActiveMacros.push_back(MI);
6342 // Jump to the macro instantiation and prime the lexer.
6343 CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
6344 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
6348 /// parseDirectiveRept
6349 /// ::= .rep | .rept count
6350 bool MasmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
6351 const MCExpr *CountExpr;
6352 SMLoc CountLoc = getTok().getLoc();
6353 if (parseExpression(CountExpr))
6357 if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {
6358 return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
6361 if (check(Count < 0, CountLoc, "Count is negative") ||
6362 parseToken(AsmToken::EndOfStatement,
6363 "unexpected token in '" + Dir + "' directive"))
6366 // Lex the rept definition.
6367 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
6371 // Macro instantiation is lexical, unfortunately. We construct a new buffer
6372 // to hold the macro body with substitutions.
6373 SmallString<256> Buf;
6374 raw_svector_ostream OS(Buf);
6376 // Note that the AtPseudoVariable is disabled for instantiations of .rep(t).
6377 if (expandMacro(OS, M->Body, None, None, false, getTok().getLoc()))
6380 instantiateMacroLikeBody(M, DirectiveLoc, OS);
6385 /// parseDirectiveIrp
6386 /// ::= .irp symbol,values
6387 bool MasmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
6388 MCAsmMacroParameter Parameter;
6389 MCAsmMacroArguments A;
6390 if (check(parseIdentifier(Parameter.Name),
6391 "expected identifier in '.irp' directive") ||
6392 parseToken(AsmToken::Comma, "expected comma in '.irp' directive") ||
6393 parseMacroArguments(nullptr, A) ||
6394 parseToken(AsmToken::EndOfStatement, "expected End of Statement"))
6397 // Lex the irp definition.
6398 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
6402 // Macro instantiation is lexical, unfortunately. We construct a new buffer
6403 // to hold the macro body with substitutions.
6404 SmallString<256> Buf;
6405 raw_svector_ostream OS(Buf);
6407 for (const MCAsmMacroArgument &Arg : A) {
6408 // Note that the AtPseudoVariable is enabled for instantiations of .irp.
6409 // This is undocumented, but GAS seems to support it.
6410 if (expandMacro(OS, M->Body, Parameter, Arg, true, getTok().getLoc()))
6414 instantiateMacroLikeBody(M, DirectiveLoc, OS);
6419 /// parseDirectiveIrpc
6420 /// ::= .irpc symbol,values
6421 bool MasmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
6422 MCAsmMacroParameter Parameter;
6423 MCAsmMacroArguments A;
6425 if (check(parseIdentifier(Parameter.Name),
6426 "expected identifier in '.irpc' directive") ||
6427 parseToken(AsmToken::Comma, "expected comma in '.irpc' directive") ||
6428 parseMacroArguments(nullptr, A))
6431 if (A.size() != 1 || A.front().size() != 1)
6432 return TokError("unexpected token in '.irpc' directive");
6434 // Eat the end of statement.
6435 if (parseToken(AsmToken::EndOfStatement, "expected end of statement"))
6438 // Lex the irpc definition.
6439 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
6443 // Macro instantiation is lexical, unfortunately. We construct a new buffer
6444 // to hold the macro body with substitutions.
6445 SmallString<256> Buf;
6446 raw_svector_ostream OS(Buf);
6448 StringRef Values = A.front().front().getString();
6449 for (std::size_t I = 0, End = Values.size(); I != End; ++I) {
6450 MCAsmMacroArgument Arg;
6451 Arg.emplace_back(AsmToken::Identifier, Values.slice(I, I + 1));
6453 // Note that the AtPseudoVariable is enabled for instantiations of .irpc.
6454 // This is undocumented, but GAS seems to support it.
6455 if (expandMacro(OS, M->Body, Parameter, Arg, true, getTok().getLoc()))
6459 instantiateMacroLikeBody(M, DirectiveLoc, OS);
6464 bool MasmParser::parseDirectiveEndr(SMLoc DirectiveLoc) {
6465 if (ActiveMacros.empty())
6466 return TokError("unmatched '.endr' directive");
6468 // The only .repl that should get here are the ones created by
6469 // instantiateMacroLikeBody.
6470 assert(getLexer().is(AsmToken::EndOfStatement));
6476 bool MasmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
6478 const MCExpr *Value;
6479 SMLoc ExprLoc = getLexer().getLoc();
6480 if (parseExpression(Value))
6482 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
6484 return Error(ExprLoc, "unexpected expression in _emit");
6485 uint64_t IntValue = MCE->getValue();
6486 if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
6487 return Error(ExprLoc, "literal value out of range for directive");
6489 Info.AsmRewrites->emplace_back(AOK_Emit, IDLoc, Len);
6493 bool MasmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
6494 const MCExpr *Value;
6495 SMLoc ExprLoc = getLexer().getLoc();
6496 if (parseExpression(Value))
6498 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
6500 return Error(ExprLoc, "unexpected expression in align");
6501 uint64_t IntValue = MCE->getValue();
6502 if (!isPowerOf2_64(IntValue))
6503 return Error(ExprLoc, "literal value not a power of two greater then zero");
6505 Info.AsmRewrites->emplace_back(AOK_Align, IDLoc, 5, Log2_64(IntValue));
6509 bool MasmParser::parseDirectiveEcho() {
6510 StringRef Message = parseStringToEndOfStatement();
6511 Lex(); // eat end of statement
6512 llvm::outs() << Message << '\n';
6516 // We are comparing pointers, but the pointers are relative to a single string.
6517 // Thus, this should always be deterministic.
6518 static int rewritesSort(const AsmRewrite *AsmRewriteA,
6519 const AsmRewrite *AsmRewriteB) {
6520 if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer())
6522 if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())
6525 // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output
6526 // rewrite to the same location. Make sure the SizeDirective rewrite is
6527 // performed first, then the Imm/ImmPrefix and finally the Input/Output. This
6528 // ensures the sort algorithm is stable.
6529 if (AsmRewritePrecedence[AsmRewriteA->Kind] >
6530 AsmRewritePrecedence[AsmRewriteB->Kind])
6533 if (AsmRewritePrecedence[AsmRewriteA->Kind] <
6534 AsmRewritePrecedence[AsmRewriteB->Kind])
6536 llvm_unreachable("Unstable rewrite sort.");
6539 bool MasmParser::lookUpField(StringRef Name, StringRef &Type,
6540 unsigned &Offset) const {
6541 const std::pair<StringRef, StringRef> BaseMember = Name.split('.');
6542 const StringRef Base = BaseMember.first, Member = BaseMember.second;
6543 return lookUpField(Base, Member, Type, Offset);
6546 bool MasmParser::lookUpField(StringRef Base, StringRef Member, StringRef &Type,
6547 unsigned &Offset) const {
6551 unsigned BaseOffset = 0;
6552 if (Base.contains('.') && !lookUpField(Base, Type, BaseOffset))
6555 auto TypeIt = KnownType.find(Base);
6556 if (TypeIt != KnownType.end())
6557 return lookUpField(*TypeIt->second, Member, Type, Offset);
6559 auto StructIt = Structs.find(Base.lower());
6560 if (StructIt != Structs.end())
6561 return lookUpField(StructIt->second, Member, Type, Offset);
6566 bool MasmParser::lookUpField(const StructInfo &Structure, StringRef Member,
6567 StringRef &Type, unsigned &Offset) const {
6568 if (Member.empty()) {
6569 Type = Structure.Name;
6573 std::pair<StringRef, StringRef> Split = Member.split('.');
6574 const StringRef FieldName = Split.first, FieldMember = Split.second;
6576 auto StructIt = Structs.find(FieldName.lower());
6577 if (StructIt != Structs.end())
6578 return lookUpField(StructIt->second, FieldMember, Type, Offset);
6580 auto FieldIt = Structure.FieldsByName.find(FieldName.lower());
6581 if (FieldIt == Structure.FieldsByName.end())
6584 const FieldInfo &Field = Structure.Fields[FieldIt->second];
6585 if (FieldMember.empty()) {
6586 Offset += Field.Offset;
6587 if (Field.Contents.FT == FT_STRUCT)
6588 Type = Field.Contents.StructInfo.Structure.Name;
6592 if (Field.Contents.FT != FT_STRUCT)
6594 const StructFieldInfo &StructInfo = Field.Contents.StructInfo;
6596 bool Result = lookUpField(StructInfo.Structure, FieldMember, Type, Offset);
6600 Offset += Field.Offset;
6604 bool MasmParser::parseMSInlineAsm(
6605 void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
6606 unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
6607 SmallVectorImpl<std::string> &Constraints,
6608 SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
6609 const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
6610 SmallVector<void *, 4> InputDecls;
6611 SmallVector<void *, 4> OutputDecls;
6612 SmallVector<bool, 4> InputDeclsAddressOf;
6613 SmallVector<bool, 4> OutputDeclsAddressOf;
6614 SmallVector<std::string, 4> InputConstraints;
6615 SmallVector<std::string, 4> OutputConstraints;
6616 SmallVector<unsigned, 4> ClobberRegs;
6618 SmallVector<AsmRewrite, 4> AsmStrRewrites;
6623 // While we have input, parse each statement.
6624 unsigned InputIdx = 0;
6625 unsigned OutputIdx = 0;
6626 while (getLexer().isNot(AsmToken::Eof)) {
6627 // Parse curly braces marking block start/end.
6628 if (parseCurlyBlockScope(AsmStrRewrites))
6631 ParseStatementInfo Info(&AsmStrRewrites);
6632 bool StatementErr = parseStatement(Info, &SI);
6634 if (StatementErr || Info.ParseError) {
6635 // Emit pending errors if any exist.
6636 printPendingErrors();
6640 // No pending error should exist here.
6641 assert(!hasPendingError() && "unexpected error from parseStatement");
6643 if (Info.Opcode == ~0U)
6646 const MCInstrDesc &Desc = MII->get(Info.Opcode);
6648 // Build the list of clobbers, outputs and inputs.
6649 for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
6650 MCParsedAsmOperand &Operand = *Info.ParsedOperands[i];
6652 // Register operand.
6653 if (Operand.isReg() && !Operand.needAddressOf() &&
6654 !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) {
6655 unsigned NumDefs = Desc.getNumDefs();
6657 if (NumDefs && Operand.getMCOperandNum() < NumDefs)
6658 ClobberRegs.push_back(Operand.getReg());
6662 // Expr/Input or Output.
6663 StringRef SymName = Operand.getSymName();
6664 if (SymName.empty())
6667 void *OpDecl = Operand.getOpDecl();
6671 StringRef Constraint = Operand.getConstraint();
6672 if (Operand.isImm()) {
6673 // Offset as immediate.
6674 if (Operand.isOffsetOfLocal())
6680 bool isOutput = (i == 1) && Desc.mayStore();
6681 SMLoc Start = SMLoc::getFromPointer(SymName.data());
6684 OutputDecls.push_back(OpDecl);
6685 OutputDeclsAddressOf.push_back(Operand.needAddressOf());
6686 OutputConstraints.push_back(("=" + Constraint).str());
6687 AsmStrRewrites.emplace_back(AOK_Output, Start, SymName.size());
6689 InputDecls.push_back(OpDecl);
6690 InputDeclsAddressOf.push_back(Operand.needAddressOf());
6691 InputConstraints.push_back(Constraint.str());
6692 if (Desc.OpInfo[i - 1].isBranchTarget())
6693 AsmStrRewrites.emplace_back(AOK_CallInput, Start, SymName.size());
6695 AsmStrRewrites.emplace_back(AOK_Input, Start, SymName.size());
6699 // Consider implicit defs to be clobbers. Think of cpuid and push.
6700 ArrayRef<MCPhysReg> ImpDefs(Desc.getImplicitDefs(),
6701 Desc.getNumImplicitDefs());
6702 ClobberRegs.insert(ClobberRegs.end(), ImpDefs.begin(), ImpDefs.end());
6705 // Set the number of Outputs and Inputs.
6706 NumOutputs = OutputDecls.size();
6707 NumInputs = InputDecls.size();
6709 // Set the unique clobbers.
6710 array_pod_sort(ClobberRegs.begin(), ClobberRegs.end());
6711 ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()),
6713 Clobbers.assign(ClobberRegs.size(), std::string());
6714 for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) {
6715 raw_string_ostream OS(Clobbers[I]);
6716 IP->printRegName(OS, ClobberRegs[I]);
6719 // Merge the various outputs and inputs. Output are expected first.
6720 if (NumOutputs || NumInputs) {
6721 unsigned NumExprs = NumOutputs + NumInputs;
6722 OpDecls.resize(NumExprs);
6723 Constraints.resize(NumExprs);
6724 for (unsigned i = 0; i < NumOutputs; ++i) {
6725 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
6726 Constraints[i] = OutputConstraints[i];
6728 for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) {
6729 OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
6730 Constraints[j] = InputConstraints[i];
6734 // Build the IR assembly string.
6735 std::string AsmStringIR;
6736 raw_string_ostream OS(AsmStringIR);
6737 StringRef ASMString =
6738 SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer();
6739 const char *AsmStart = ASMString.begin();
6740 const char *AsmEnd = ASMString.end();
6741 array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort);
6742 for (auto it = AsmStrRewrites.begin(); it != AsmStrRewrites.end(); ++it) {
6743 const AsmRewrite &AR = *it;
6744 // Check if this has already been covered by another rewrite...
6747 AsmRewriteKind Kind = AR.Kind;
6749 const char *Loc = AR.Loc.getPointer();
6750 assert(Loc >= AsmStart && "Expected Loc to be at or after Start!");
6752 // Emit everything up to the immediate/expression.
6753 if (unsigned Len = Loc - AsmStart)
6754 OS << StringRef(AsmStart, Len);
6756 // Skip the original expression.
6757 if (Kind == AOK_Skip) {
6758 AsmStart = Loc + AR.Len;
6762 unsigned AdditionalSkip = 0;
6763 // Rewrite expressions in $N notation.
6768 assert(AR.IntelExp.isValid() && "cannot write invalid intel expression");
6769 if (AR.IntelExp.NeedBracs)
6771 if (AR.IntelExp.hasBaseReg())
6772 OS << AR.IntelExp.BaseReg;
6773 if (AR.IntelExp.hasIndexReg())
6774 OS << (AR.IntelExp.hasBaseReg() ? " + " : "")
6775 << AR.IntelExp.IndexReg;
6776 if (AR.IntelExp.Scale > 1)
6777 OS << " * $$" << AR.IntelExp.Scale;
6778 if (AR.IntelExp.hasOffset()) {
6779 if (AR.IntelExp.hasRegs())
6781 // Fuse this rewrite with a rewrite of the offset name, if present.
6782 StringRef OffsetName = AR.IntelExp.OffsetName;
6783 SMLoc OffsetLoc = SMLoc::getFromPointer(AR.IntelExp.OffsetName.data());
6784 size_t OffsetLen = OffsetName.size();
6785 auto rewrite_it = std::find_if(
6786 it, AsmStrRewrites.end(), [&](const AsmRewrite &FusingAR) {
6787 return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen &&
6788 (FusingAR.Kind == AOK_Input ||
6789 FusingAR.Kind == AOK_CallInput);
6791 if (rewrite_it == AsmStrRewrites.end()) {
6792 OS << "offset " << OffsetName;
6793 } else if (rewrite_it->Kind == AOK_CallInput) {
6794 OS << "${" << InputIdx++ << ":P}";
6795 rewrite_it->Done = true;
6797 OS << '$' << InputIdx++;
6798 rewrite_it->Done = true;
6801 if (AR.IntelExp.Imm || AR.IntelExp.emitImm())
6802 OS << (AR.IntelExp.emitImm() ? "$$" : " + $$") << AR.IntelExp.Imm;
6803 if (AR.IntelExp.NeedBracs)
6807 OS << Ctx.getAsmInfo()->getPrivateLabelPrefix() << AR.Label;
6810 OS << '$' << InputIdx++;
6813 OS << "${" << InputIdx++ << ":P}";
6816 OS << '$' << OutputIdx++;
6818 case AOK_SizeDirective:
6821 case 8: OS << "byte ptr "; break;
6822 case 16: OS << "word ptr "; break;
6823 case 32: OS << "dword ptr "; break;
6824 case 64: OS << "qword ptr "; break;
6825 case 80: OS << "xword ptr "; break;
6826 case 128: OS << "xmmword ptr "; break;
6827 case 256: OS << "ymmword ptr "; break;
6834 // MS alignment directives are measured in bytes. If the native assembler
6835 // measures alignment in bytes, we can pass it straight through.
6837 if (getContext().getAsmInfo()->getAlignmentIsInBytes())
6840 // Alignment is in log2 form, so print that instead and skip the original
6842 unsigned Val = AR.Val;
6844 assert(Val < 10 && "Expected alignment less then 2^10.");
6845 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
6851 case AOK_EndOfStatement:
6856 // Skip the original expression.
6857 AsmStart = Loc + AR.Len + AdditionalSkip;
6860 // Emit the remainder of the asm string.
6861 if (AsmStart != AsmEnd)
6862 OS << StringRef(AsmStart, AsmEnd - AsmStart);
6864 AsmString = OS.str();
6868 /// Create an MCAsmParser instance.
6869 MCAsmParser *llvm::createMCMasmParser(SourceMgr &SM, MCContext &C,
6870 MCStreamer &Out, const MCAsmInfo &MAI,
6872 return new MasmParser(SM, C, Out, MAI, CB);