1 //===- AsmParser.cpp - Parser for Assembly Files --------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This class implements the parser for assembly files. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/ADT/APFloat.h" 14 #include "llvm/ADT/APInt.h" 15 #include "llvm/ADT/ArrayRef.h" 16 #include "llvm/ADT/None.h" 17 #include "llvm/ADT/Optional.h" 18 #include "llvm/ADT/STLExtras.h" 19 #include "llvm/ADT/SmallString.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/ADT/StringExtras.h" 22 #include "llvm/ADT/StringMap.h" 23 #include "llvm/ADT/StringRef.h" 24 #include "llvm/ADT/StringSwitch.h" 25 #include "llvm/ADT/Twine.h" 26 #include "llvm/BinaryFormat/Dwarf.h" 27 #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 28 #include "llvm/MC/MCAsmInfo.h" 29 #include "llvm/MC/MCCodeView.h" 30 #include "llvm/MC/MCContext.h" 31 #include "llvm/MC/MCDirectives.h" 32 #include "llvm/MC/MCDwarf.h" 33 #include "llvm/MC/MCExpr.h" 34 #include "llvm/MC/MCInstPrinter.h" 35 #include "llvm/MC/MCInstrDesc.h" 36 #include "llvm/MC/MCInstrInfo.h" 37 #include "llvm/MC/MCObjectFileInfo.h" 38 #include "llvm/MC/MCParser/AsmCond.h" 39 #include "llvm/MC/MCParser/AsmLexer.h" 40 #include "llvm/MC/MCParser/MCAsmLexer.h" 41 #include "llvm/MC/MCParser/MCAsmParser.h" 42 #include "llvm/MC/MCParser/MCAsmParserExtension.h" 43 #include "llvm/MC/MCParser/MCAsmParserUtils.h" 44 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 45 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 46 #include "llvm/MC/MCRegisterInfo.h" 47 #include "llvm/MC/MCSection.h" 48 #include "llvm/MC/MCStreamer.h" 49 #include "llvm/MC/MCSymbol.h" 50 #include "llvm/MC/MCTargetOptions.h" 51 #include "llvm/MC/MCValue.h" 52 #include "llvm/Support/Casting.h" 53 #include "llvm/Support/CommandLine.h" 54 #include "llvm/Support/ErrorHandling.h" 55 #include "llvm/Support/Format.h" 56 #include "llvm/Support/MD5.h" 57 #include "llvm/Support/MathExtras.h" 58 #include "llvm/Support/MemoryBuffer.h" 59 #include "llvm/Support/SMLoc.h" 60 #include "llvm/Support/SourceMgr.h" 61 #include "llvm/Support/raw_ostream.h" 62 #include <algorithm> 63 #include <cassert> 64 #include <cctype> 65 #include <climits> 66 #include <cstddef> 67 #include <cstdint> 68 #include <deque> 69 #include <memory> 70 #include <sstream> 71 #include <string> 72 #include <tuple> 73 #include <utility> 74 #include <vector> 75 76 using namespace llvm; 77 78 extern cl::opt<unsigned> AsmMacroMaxNestingDepth; 79 80 namespace { 81 82 /// Helper types for tracking macro definitions. 83 typedef std::vector<AsmToken> MCAsmMacroArgument; 84 typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments; 85 86 /// Helper class for storing information about an active macro instantiation. 87 struct MacroInstantiation { 88 /// The location of the instantiation. 89 SMLoc InstantiationLoc; 90 91 /// The buffer where parsing should resume upon instantiation completion. 92 unsigned ExitBuffer; 93 94 /// The location where parsing should resume upon instantiation completion. 95 SMLoc ExitLoc; 96 97 /// The depth of TheCondStack at the start of the instantiation. 98 size_t CondStackDepth; 99 }; 100 101 struct ParseStatementInfo { 102 /// The parsed operands from the last parsed statement. 103 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> ParsedOperands; 104 105 /// The opcode from the last parsed instruction. 106 unsigned Opcode = ~0U; 107 108 /// Was there an error parsing the inline assembly? 109 bool ParseError = false; 110 111 /// The value associated with a macro exit. 112 Optional<std::string> ExitValue; 113 114 SmallVectorImpl<AsmRewrite> *AsmRewrites = nullptr; 115 116 ParseStatementInfo() = delete; 117 ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites) 118 : AsmRewrites(rewrites) {} 119 }; 120 121 enum FieldType { 122 FT_INTEGRAL, // Initializer: integer expression, stored as an MCExpr. 123 FT_REAL, // Initializer: real number, stored as an APInt. 124 FT_STRUCT // Initializer: struct initializer, stored recursively. 125 }; 126 127 struct FieldInfo; 128 struct StructInfo { 129 StringRef Name; 130 bool IsUnion = false; 131 bool Initializable = true; 132 unsigned Alignment = 0; 133 unsigned AlignmentSize = 0; 134 unsigned NextOffset = 0; 135 unsigned Size = 0; 136 std::vector<FieldInfo> Fields; 137 StringMap<size_t> FieldsByName; 138 139 FieldInfo &addField(StringRef FieldName, FieldType FT, 140 unsigned FieldAlignmentSize); 141 142 StructInfo() = default; 143 144 StructInfo(StringRef StructName, bool Union, unsigned AlignmentValue) 145 : Name(StructName), IsUnion(Union), Alignment(AlignmentValue) {} 146 }; 147 148 // FIXME: This should probably use a class hierarchy, raw pointers between the 149 // objects, and dynamic type resolution instead of a union. On the other hand, 150 // ownership then becomes much more complicated; the obvious thing would be to 151 // use BumpPtrAllocator, but the lack of a destructor makes that messy. 152 153 struct StructInitializer; 154 struct IntFieldInfo { 155 SmallVector<const MCExpr *, 1> Values; 156 157 IntFieldInfo() = default; 158 IntFieldInfo(const SmallVector<const MCExpr *, 1> &V) { Values = V; } 159 IntFieldInfo(SmallVector<const MCExpr *, 1> &&V) { Values = V; } 160 }; 161 struct RealFieldInfo { 162 SmallVector<APInt, 1> AsIntValues; 163 164 RealFieldInfo() = default; 165 RealFieldInfo(const SmallVector<APInt, 1> &V) { AsIntValues = V; } 166 RealFieldInfo(SmallVector<APInt, 1> &&V) { AsIntValues = V; } 167 }; 168 struct StructFieldInfo { 169 std::vector<StructInitializer> Initializers; 170 StructInfo Structure; 171 172 StructFieldInfo() = default; 173 StructFieldInfo(const std::vector<StructInitializer> &V, StructInfo S) { 174 Initializers = V; 175 Structure = S; 176 } 177 StructFieldInfo(std::vector<StructInitializer> &&V, StructInfo S) { 178 Initializers = V; 179 Structure = S; 180 } 181 }; 182 183 class FieldInitializer { 184 public: 185 FieldType FT; 186 union { 187 IntFieldInfo IntInfo; 188 RealFieldInfo RealInfo; 189 StructFieldInfo StructInfo; 190 }; 191 192 ~FieldInitializer() { 193 switch (FT) { 194 case FT_INTEGRAL: 195 IntInfo.~IntFieldInfo(); 196 break; 197 case FT_REAL: 198 RealInfo.~RealFieldInfo(); 199 break; 200 case FT_STRUCT: 201 StructInfo.~StructFieldInfo(); 202 break; 203 } 204 } 205 206 FieldInitializer(FieldType FT) : FT(FT) { 207 switch (FT) { 208 case FT_INTEGRAL: 209 new (&IntInfo) IntFieldInfo(); 210 break; 211 case FT_REAL: 212 new (&RealInfo) RealFieldInfo(); 213 break; 214 case FT_STRUCT: 215 new (&StructInfo) StructFieldInfo(); 216 break; 217 } 218 } 219 220 FieldInitializer(SmallVector<const MCExpr *, 1> &&Values) : FT(FT_INTEGRAL) { 221 new (&IntInfo) IntFieldInfo(Values); 222 } 223 224 FieldInitializer(SmallVector<APInt, 1> &&AsIntValues) : FT(FT_REAL) { 225 new (&RealInfo) RealFieldInfo(AsIntValues); 226 } 227 228 FieldInitializer(std::vector<StructInitializer> &&Initializers, 229 struct StructInfo Structure) 230 : FT(FT_STRUCT) { 231 new (&StructInfo) StructFieldInfo(Initializers, Structure); 232 } 233 234 FieldInitializer(const FieldInitializer &Initializer) : FT(Initializer.FT) { 235 switch (FT) { 236 case FT_INTEGRAL: 237 new (&IntInfo) IntFieldInfo(Initializer.IntInfo); 238 break; 239 case FT_REAL: 240 new (&RealInfo) RealFieldInfo(Initializer.RealInfo); 241 break; 242 case FT_STRUCT: 243 new (&StructInfo) StructFieldInfo(Initializer.StructInfo); 244 break; 245 } 246 } 247 248 FieldInitializer(FieldInitializer &&Initializer) : FT(Initializer.FT) { 249 switch (FT) { 250 case FT_INTEGRAL: 251 new (&IntInfo) IntFieldInfo(Initializer.IntInfo); 252 break; 253 case FT_REAL: 254 new (&RealInfo) RealFieldInfo(Initializer.RealInfo); 255 break; 256 case FT_STRUCT: 257 new (&StructInfo) StructFieldInfo(Initializer.StructInfo); 258 break; 259 } 260 } 261 262 FieldInitializer &operator=(const FieldInitializer &Initializer) { 263 if (FT != Initializer.FT) { 264 switch (FT) { 265 case FT_INTEGRAL: 266 IntInfo.~IntFieldInfo(); 267 break; 268 case FT_REAL: 269 RealInfo.~RealFieldInfo(); 270 break; 271 case FT_STRUCT: 272 StructInfo.~StructFieldInfo(); 273 break; 274 } 275 } 276 FT = Initializer.FT; 277 switch (FT) { 278 case FT_INTEGRAL: 279 IntInfo = Initializer.IntInfo; 280 break; 281 case FT_REAL: 282 RealInfo = Initializer.RealInfo; 283 break; 284 case FT_STRUCT: 285 StructInfo = Initializer.StructInfo; 286 break; 287 } 288 return *this; 289 } 290 291 FieldInitializer &operator=(FieldInitializer &&Initializer) { 292 if (FT != Initializer.FT) { 293 switch (FT) { 294 case FT_INTEGRAL: 295 IntInfo.~IntFieldInfo(); 296 break; 297 case FT_REAL: 298 RealInfo.~RealFieldInfo(); 299 break; 300 case FT_STRUCT: 301 StructInfo.~StructFieldInfo(); 302 break; 303 } 304 } 305 FT = Initializer.FT; 306 switch (FT) { 307 case FT_INTEGRAL: 308 IntInfo = Initializer.IntInfo; 309 break; 310 case FT_REAL: 311 RealInfo = Initializer.RealInfo; 312 break; 313 case FT_STRUCT: 314 StructInfo = Initializer.StructInfo; 315 break; 316 } 317 return *this; 318 } 319 }; 320 321 struct StructInitializer { 322 std::vector<FieldInitializer> FieldInitializers; 323 }; 324 325 struct FieldInfo { 326 // Offset of the field within the containing STRUCT. 327 unsigned Offset = 0; 328 329 // Total size of the field (= LengthOf * Type). 330 unsigned SizeOf = 0; 331 332 // Number of elements in the field (1 if scalar, >1 if an array). 333 unsigned LengthOf = 0; 334 335 // Size of a single entry in this field, in bytes ("type" in MASM standards). 336 unsigned Type = 0; 337 338 FieldInitializer Contents; 339 340 FieldInfo(FieldType FT) : Contents(FT) {} 341 }; 342 343 FieldInfo &StructInfo::addField(StringRef FieldName, FieldType FT, 344 unsigned FieldAlignmentSize) { 345 if (!FieldName.empty()) 346 FieldsByName[FieldName.lower()] = Fields.size(); 347 Fields.emplace_back(FT); 348 FieldInfo &Field = Fields.back(); 349 Field.Offset = 350 llvm::alignTo(NextOffset, std::min(Alignment, FieldAlignmentSize)); 351 if (!IsUnion) { 352 NextOffset = std::max(NextOffset, Field.Offset); 353 } 354 AlignmentSize = std::max(AlignmentSize, FieldAlignmentSize); 355 return Field; 356 } 357 358 /// The concrete assembly parser instance. 359 // Note that this is a full MCAsmParser, not an MCAsmParserExtension! 360 // It's a peer of AsmParser, not of COFFAsmParser, WasmAsmParser, etc. 361 class MasmParser : public MCAsmParser { 362 private: 363 AsmLexer Lexer; 364 MCContext &Ctx; 365 MCStreamer &Out; 366 const MCAsmInfo &MAI; 367 SourceMgr &SrcMgr; 368 SourceMgr::DiagHandlerTy SavedDiagHandler; 369 void *SavedDiagContext; 370 std::unique_ptr<MCAsmParserExtension> PlatformParser; 371 372 /// This is the current buffer index we're lexing from as managed by the 373 /// SourceMgr object. 374 unsigned CurBuffer; 375 std::vector<bool> EndStatementAtEOFStack; 376 377 AsmCond TheCondState; 378 std::vector<AsmCond> TheCondStack; 379 380 /// maps directive names to handler methods in parser 381 /// extensions. Extensions register themselves in this map by calling 382 /// addDirectiveHandler. 383 StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap; 384 385 /// maps assembly-time variable names to variables. 386 struct Variable { 387 enum RedefinableKind { NOT_REDEFINABLE, WARN_ON_REDEFINITION, REDEFINABLE }; 388 389 StringRef Name; 390 RedefinableKind Redefinable = REDEFINABLE; 391 bool IsText = false; 392 int64_t NumericValue = 0; 393 std::string TextValue; 394 }; 395 StringMap<Variable> Variables; 396 397 /// Stack of active struct definitions. 398 SmallVector<StructInfo, 1> StructInProgress; 399 400 /// Maps struct tags to struct definitions. 401 StringMap<StructInfo> Structs; 402 403 /// Maps data location names to types. 404 StringMap<AsmTypeInfo> KnownType; 405 406 /// Stack of active macro instantiations. 407 std::vector<MacroInstantiation*> ActiveMacros; 408 409 /// List of bodies of anonymous macros. 410 std::deque<MCAsmMacro> MacroLikeBodies; 411 412 /// Keeps track of how many .macro's have been instantiated. 413 unsigned NumOfMacroInstantiations; 414 415 /// The values from the last parsed cpp hash file line comment if any. 416 struct CppHashInfoTy { 417 StringRef Filename; 418 int64_t LineNumber; 419 SMLoc Loc; 420 unsigned Buf; 421 CppHashInfoTy() : Filename(), LineNumber(0), Loc(), Buf(0) {} 422 }; 423 CppHashInfoTy CppHashInfo; 424 425 /// The filename from the first cpp hash file line comment, if any. 426 StringRef FirstCppHashFilename; 427 428 /// List of forward directional labels for diagnosis at the end. 429 SmallVector<std::tuple<SMLoc, CppHashInfoTy, MCSymbol *>, 4> DirLabels; 430 431 /// AssemblerDialect. ~OU means unset value and use value provided by MAI. 432 /// Defaults to 1U, meaning Intel. 433 unsigned AssemblerDialect = 1U; 434 435 /// is Darwin compatibility enabled? 436 bool IsDarwin = false; 437 438 /// Are we parsing ms-style inline assembly? 439 bool ParsingMSInlineAsm = false; 440 441 /// Did we already inform the user about inconsistent MD5 usage? 442 bool ReportedInconsistentMD5 = false; 443 444 // Current <...> expression depth. 445 unsigned AngleBracketDepth = 0U; 446 447 // Number of locals defined. 448 uint16_t LocalCounter = 0; 449 450 public: 451 MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, 452 const MCAsmInfo &MAI, unsigned CB); 453 MasmParser(const MasmParser &) = delete; 454 MasmParser &operator=(const MasmParser &) = delete; 455 ~MasmParser() override; 456 457 bool Run(bool NoInitialTextSection, bool NoFinalize = false) override; 458 459 void addDirectiveHandler(StringRef Directive, 460 ExtensionDirectiveHandler Handler) override { 461 ExtensionDirectiveMap[Directive] = Handler; 462 if (DirectiveKindMap.find(Directive) == DirectiveKindMap.end()) { 463 DirectiveKindMap[Directive] = DK_HANDLER_DIRECTIVE; 464 } 465 } 466 467 void addAliasForDirective(StringRef Directive, StringRef Alias) override { 468 DirectiveKindMap[Directive] = DirectiveKindMap[Alias]; 469 } 470 471 /// @name MCAsmParser Interface 472 /// { 473 474 SourceMgr &getSourceManager() override { return SrcMgr; } 475 MCAsmLexer &getLexer() override { return Lexer; } 476 MCContext &getContext() override { return Ctx; } 477 MCStreamer &getStreamer() override { return Out; } 478 479 CodeViewContext &getCVContext() { return Ctx.getCVContext(); } 480 481 unsigned getAssemblerDialect() override { 482 if (AssemblerDialect == ~0U) 483 return MAI.getAssemblerDialect(); 484 else 485 return AssemblerDialect; 486 } 487 void setAssemblerDialect(unsigned i) override { 488 AssemblerDialect = i; 489 } 490 491 void Note(SMLoc L, const Twine &Msg, SMRange Range = None) override; 492 bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) override; 493 bool printError(SMLoc L, const Twine &Msg, SMRange Range = None) override; 494 495 const AsmToken &Lex() override; 496 497 void setParsingMSInlineAsm(bool V) override { 498 ParsingMSInlineAsm = V; 499 // When parsing MS inline asm, we must lex 0b1101 and 0ABCH as binary and 500 // hex integer literals. 501 Lexer.setLexMasmIntegers(V); 502 } 503 bool isParsingMSInlineAsm() override { return ParsingMSInlineAsm; } 504 505 bool isParsingMasm() const override { return true; } 506 507 bool defineMacro(StringRef Name, StringRef Value) override; 508 509 bool lookUpField(StringRef Name, AsmFieldInfo &Info) const override; 510 bool lookUpField(StringRef Base, StringRef Member, 511 AsmFieldInfo &Info) const override; 512 513 bool lookUpType(StringRef Name, AsmTypeInfo &Info) const override; 514 515 bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString, 516 unsigned &NumOutputs, unsigned &NumInputs, 517 SmallVectorImpl<std::pair<void *,bool>> &OpDecls, 518 SmallVectorImpl<std::string> &Constraints, 519 SmallVectorImpl<std::string> &Clobbers, 520 const MCInstrInfo *MII, const MCInstPrinter *IP, 521 MCAsmParserSemaCallback &SI) override; 522 523 bool parseExpression(const MCExpr *&Res); 524 bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) override; 525 bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc, 526 AsmTypeInfo *TypeInfo) override; 527 bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) override; 528 bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res, 529 SMLoc &EndLoc) override; 530 bool parseAbsoluteExpression(int64_t &Res) override; 531 532 /// Parse a floating point expression using the float \p Semantics 533 /// and set \p Res to the value. 534 bool parseRealValue(const fltSemantics &Semantics, APInt &Res); 535 536 /// Parse an identifier or string (as a quoted identifier) 537 /// and set \p Res to the identifier contents. 538 bool parseIdentifier(StringRef &Res) override; 539 void eatToEndOfStatement() override; 540 541 bool checkForValidSection() override; 542 543 /// } 544 545 private: 546 const AsmToken peekTok(bool ShouldSkipSpace = true); 547 548 bool parseStatement(ParseStatementInfo &Info, 549 MCAsmParserSemaCallback *SI); 550 bool parseCurlyBlockScope(SmallVectorImpl<AsmRewrite>& AsmStrRewrites); 551 bool parseCppHashLineFilenameComment(SMLoc L); 552 553 bool expandMacro(raw_svector_ostream &OS, StringRef Body, 554 ArrayRef<MCAsmMacroParameter> Parameters, 555 ArrayRef<MCAsmMacroArgument> A, 556 const std::vector<std::string> &Locals, SMLoc L); 557 558 /// Are we inside a macro instantiation? 559 bool isInsideMacroInstantiation() {return !ActiveMacros.empty();} 560 561 /// Handle entry to macro instantiation. 562 /// 563 /// \param M The macro. 564 /// \param NameLoc Instantiation location. 565 bool handleMacroEntry( 566 const MCAsmMacro *M, SMLoc NameLoc, 567 AsmToken::TokenKind ArgumentEndTok = AsmToken::EndOfStatement); 568 569 /// Handle invocation of macro function. 570 /// 571 /// \param M The macro. 572 /// \param NameLoc Invocation location. 573 bool handleMacroInvocation(const MCAsmMacro *M, SMLoc NameLoc); 574 575 /// Handle exit from macro instantiation. 576 void handleMacroExit(); 577 578 /// Extract AsmTokens for a macro argument. 579 bool 580 parseMacroArgument(const MCAsmMacroParameter *MP, MCAsmMacroArgument &MA, 581 AsmToken::TokenKind EndTok = AsmToken::EndOfStatement); 582 583 /// Parse all macro arguments for a given macro. 584 bool 585 parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A, 586 AsmToken::TokenKind EndTok = AsmToken::EndOfStatement); 587 588 void printMacroInstantiations(); 589 590 bool expandStatement(SMLoc Loc); 591 592 void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg, 593 SMRange Range = None) const { 594 ArrayRef<SMRange> Ranges(Range); 595 SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges); 596 } 597 static void DiagHandler(const SMDiagnostic &Diag, void *Context); 598 599 bool lookUpField(const StructInfo &Structure, StringRef Member, 600 AsmFieldInfo &Info) const; 601 602 /// Should we emit DWARF describing this assembler source? (Returns false if 603 /// the source has .file directives, which means we don't want to generate 604 /// info describing the assembler source itself.) 605 bool enabledGenDwarfForAssembly(); 606 607 /// Enter the specified file. This returns true on failure. 608 bool enterIncludeFile(const std::string &Filename); 609 610 /// Reset the current lexer position to that given by \p Loc. The 611 /// current token is not set; clients should ensure Lex() is called 612 /// subsequently. 613 /// 614 /// \param InBuffer If not 0, should be the known buffer id that contains the 615 /// location. 616 void jumpToLoc(SMLoc Loc, unsigned InBuffer = 0, 617 bool EndStatementAtEOF = true); 618 619 /// Parse up to a token of kind \p EndTok and return the contents from the 620 /// current token up to (but not including) this token; the current token on 621 /// exit will be either this kind or EOF. Reads through instantiated macro 622 /// functions and text macros. 623 SmallVector<StringRef, 1> parseStringRefsTo(AsmToken::TokenKind EndTok); 624 std::string parseStringTo(AsmToken::TokenKind EndTok); 625 626 /// Parse up to the end of statement and return the contents from the current 627 /// token until the end of the statement; the current token on exit will be 628 /// either the EndOfStatement or EOF. 629 StringRef parseStringToEndOfStatement() override; 630 631 bool parseTextItem(std::string &Data); 632 633 unsigned getBinOpPrecedence(AsmToken::TokenKind K, 634 MCBinaryExpr::Opcode &Kind); 635 636 bool parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc); 637 bool parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc); 638 bool parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc); 639 640 bool parseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc); 641 642 bool parseCVFunctionId(int64_t &FunctionId, StringRef DirectiveName); 643 bool parseCVFileId(int64_t &FileId, StringRef DirectiveName); 644 645 // Generic (target and platform independent) directive parsing. 646 enum DirectiveKind { 647 DK_NO_DIRECTIVE, // Placeholder 648 DK_HANDLER_DIRECTIVE, 649 DK_ASSIGN, 650 DK_EQU, 651 DK_TEXTEQU, 652 DK_ASCII, 653 DK_ASCIZ, 654 DK_STRING, 655 DK_BYTE, 656 DK_SBYTE, 657 DK_WORD, 658 DK_SWORD, 659 DK_DWORD, 660 DK_SDWORD, 661 DK_FWORD, 662 DK_QWORD, 663 DK_SQWORD, 664 DK_DB, 665 DK_DD, 666 DK_DF, 667 DK_DQ, 668 DK_DW, 669 DK_REAL4, 670 DK_REAL8, 671 DK_REAL10, 672 DK_ALIGN, 673 DK_EVEN, 674 DK_ORG, 675 DK_ENDR, 676 DK_EXTERN, 677 DK_PUBLIC, 678 DK_COMM, 679 DK_COMMENT, 680 DK_INCLUDE, 681 DK_REPEAT, 682 DK_WHILE, 683 DK_FOR, 684 DK_FORC, 685 DK_IF, 686 DK_IFE, 687 DK_IFB, 688 DK_IFNB, 689 DK_IFDEF, 690 DK_IFNDEF, 691 DK_IFDIF, 692 DK_IFDIFI, 693 DK_IFIDN, 694 DK_IFIDNI, 695 DK_ELSEIF, 696 DK_ELSEIFE, 697 DK_ELSEIFB, 698 DK_ELSEIFNB, 699 DK_ELSEIFDEF, 700 DK_ELSEIFNDEF, 701 DK_ELSEIFDIF, 702 DK_ELSEIFDIFI, 703 DK_ELSEIFIDN, 704 DK_ELSEIFIDNI, 705 DK_ELSE, 706 DK_ENDIF, 707 DK_FILE, 708 DK_LINE, 709 DK_LOC, 710 DK_STABS, 711 DK_CV_FILE, 712 DK_CV_FUNC_ID, 713 DK_CV_INLINE_SITE_ID, 714 DK_CV_LOC, 715 DK_CV_LINETABLE, 716 DK_CV_INLINE_LINETABLE, 717 DK_CV_DEF_RANGE, 718 DK_CV_STRINGTABLE, 719 DK_CV_STRING, 720 DK_CV_FILECHECKSUMS, 721 DK_CV_FILECHECKSUM_OFFSET, 722 DK_CV_FPO_DATA, 723 DK_CFI_SECTIONS, 724 DK_CFI_STARTPROC, 725 DK_CFI_ENDPROC, 726 DK_CFI_DEF_CFA, 727 DK_CFI_DEF_CFA_OFFSET, 728 DK_CFI_ADJUST_CFA_OFFSET, 729 DK_CFI_DEF_CFA_REGISTER, 730 DK_CFI_OFFSET, 731 DK_CFI_REL_OFFSET, 732 DK_CFI_PERSONALITY, 733 DK_CFI_LSDA, 734 DK_CFI_REMEMBER_STATE, 735 DK_CFI_RESTORE_STATE, 736 DK_CFI_SAME_VALUE, 737 DK_CFI_RESTORE, 738 DK_CFI_ESCAPE, 739 DK_CFI_RETURN_COLUMN, 740 DK_CFI_SIGNAL_FRAME, 741 DK_CFI_UNDEFINED, 742 DK_CFI_REGISTER, 743 DK_CFI_WINDOW_SAVE, 744 DK_CFI_B_KEY_FRAME, 745 DK_MACRO, 746 DK_EXITM, 747 DK_ENDM, 748 DK_PURGE, 749 DK_ERR, 750 DK_ERRB, 751 DK_ERRNB, 752 DK_ERRDEF, 753 DK_ERRNDEF, 754 DK_ERRDIF, 755 DK_ERRDIFI, 756 DK_ERRIDN, 757 DK_ERRIDNI, 758 DK_ERRE, 759 DK_ERRNZ, 760 DK_ECHO, 761 DK_STRUCT, 762 DK_UNION, 763 DK_ENDS, 764 DK_END, 765 DK_PUSHFRAME, 766 DK_PUSHREG, 767 DK_SAVEREG, 768 DK_SAVEXMM128, 769 DK_SETFRAME, 770 DK_RADIX, 771 }; 772 773 /// Maps directive name --> DirectiveKind enum, for directives parsed by this 774 /// class. 775 StringMap<DirectiveKind> DirectiveKindMap; 776 777 bool isMacroLikeDirective(); 778 779 // Codeview def_range type parsing. 780 enum CVDefRangeType { 781 CVDR_DEFRANGE = 0, // Placeholder 782 CVDR_DEFRANGE_REGISTER, 783 CVDR_DEFRANGE_FRAMEPOINTER_REL, 784 CVDR_DEFRANGE_SUBFIELD_REGISTER, 785 CVDR_DEFRANGE_REGISTER_REL 786 }; 787 788 /// Maps Codeview def_range types --> CVDefRangeType enum, for Codeview 789 /// def_range types parsed by this class. 790 StringMap<CVDefRangeType> CVDefRangeTypeMap; 791 792 // ".ascii", ".asciz", ".string" 793 bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated); 794 795 // "byte", "word", ... 796 bool emitIntValue(const MCExpr *Value, unsigned Size); 797 bool parseScalarInitializer(unsigned Size, 798 SmallVectorImpl<const MCExpr *> &Values, 799 unsigned StringPadLength = 0); 800 bool parseScalarInstList( 801 unsigned Size, SmallVectorImpl<const MCExpr *> &Values, 802 const AsmToken::TokenKind EndToken = AsmToken::EndOfStatement); 803 bool emitIntegralValues(unsigned Size, unsigned *Count = nullptr); 804 bool addIntegralField(StringRef Name, unsigned Size); 805 bool parseDirectiveValue(StringRef IDVal, unsigned Size); 806 bool parseDirectiveNamedValue(StringRef TypeName, unsigned Size, 807 StringRef Name, SMLoc NameLoc); 808 809 // "real4", "real8", "real10" 810 bool emitRealValues(const fltSemantics &Semantics, unsigned *Count = nullptr); 811 bool addRealField(StringRef Name, const fltSemantics &Semantics, size_t Size); 812 bool parseDirectiveRealValue(StringRef IDVal, const fltSemantics &Semantics, 813 size_t Size); 814 bool parseRealInstList( 815 const fltSemantics &Semantics, SmallVectorImpl<APInt> &Values, 816 const AsmToken::TokenKind EndToken = AsmToken::EndOfStatement); 817 bool parseDirectiveNamedRealValue(StringRef TypeName, 818 const fltSemantics &Semantics, 819 unsigned Size, StringRef Name, 820 SMLoc NameLoc); 821 822 bool parseOptionalAngleBracketOpen(); 823 bool parseAngleBracketClose(const Twine &Msg = "expected '>'"); 824 825 bool parseFieldInitializer(const FieldInfo &Field, 826 FieldInitializer &Initializer); 827 bool parseFieldInitializer(const FieldInfo &Field, 828 const IntFieldInfo &Contents, 829 FieldInitializer &Initializer); 830 bool parseFieldInitializer(const FieldInfo &Field, 831 const RealFieldInfo &Contents, 832 FieldInitializer &Initializer); 833 bool parseFieldInitializer(const FieldInfo &Field, 834 const StructFieldInfo &Contents, 835 FieldInitializer &Initializer); 836 837 bool parseStructInitializer(const StructInfo &Structure, 838 StructInitializer &Initializer); 839 bool parseStructInstList( 840 const StructInfo &Structure, std::vector<StructInitializer> &Initializers, 841 const AsmToken::TokenKind EndToken = AsmToken::EndOfStatement); 842 843 bool emitFieldValue(const FieldInfo &Field); 844 bool emitFieldValue(const FieldInfo &Field, const IntFieldInfo &Contents); 845 bool emitFieldValue(const FieldInfo &Field, const RealFieldInfo &Contents); 846 bool emitFieldValue(const FieldInfo &Field, const StructFieldInfo &Contents); 847 848 bool emitFieldInitializer(const FieldInfo &Field, 849 const FieldInitializer &Initializer); 850 bool emitFieldInitializer(const FieldInfo &Field, 851 const IntFieldInfo &Contents, 852 const IntFieldInfo &Initializer); 853 bool emitFieldInitializer(const FieldInfo &Field, 854 const RealFieldInfo &Contents, 855 const RealFieldInfo &Initializer); 856 bool emitFieldInitializer(const FieldInfo &Field, 857 const StructFieldInfo &Contents, 858 const StructFieldInfo &Initializer); 859 860 bool emitStructInitializer(const StructInfo &Structure, 861 const StructInitializer &Initializer); 862 863 // User-defined types (structs, unions): 864 bool emitStructValues(const StructInfo &Structure, unsigned *Count = nullptr); 865 bool addStructField(StringRef Name, const StructInfo &Structure); 866 bool parseDirectiveStructValue(const StructInfo &Structure, 867 StringRef Directive, SMLoc DirLoc); 868 bool parseDirectiveNamedStructValue(const StructInfo &Structure, 869 StringRef Directive, SMLoc DirLoc, 870 StringRef Name); 871 872 // "=", "equ", "textequ" 873 bool parseDirectiveEquate(StringRef IDVal, StringRef Name, 874 DirectiveKind DirKind, SMLoc NameLoc); 875 876 bool parseDirectiveOrg(); // "org" 877 878 bool emitAlignTo(int64_t Alignment); 879 bool parseDirectiveAlign(); // "align" 880 bool parseDirectiveEven(); // "even" 881 882 // ".file", ".line", ".loc", ".stabs" 883 bool parseDirectiveFile(SMLoc DirectiveLoc); 884 bool parseDirectiveLine(); 885 bool parseDirectiveLoc(); 886 bool parseDirectiveStabs(); 887 888 // ".cv_file", ".cv_func_id", ".cv_inline_site_id", ".cv_loc", ".cv_linetable", 889 // ".cv_inline_linetable", ".cv_def_range", ".cv_string" 890 bool parseDirectiveCVFile(); 891 bool parseDirectiveCVFuncId(); 892 bool parseDirectiveCVInlineSiteId(); 893 bool parseDirectiveCVLoc(); 894 bool parseDirectiveCVLinetable(); 895 bool parseDirectiveCVInlineLinetable(); 896 bool parseDirectiveCVDefRange(); 897 bool parseDirectiveCVString(); 898 bool parseDirectiveCVStringTable(); 899 bool parseDirectiveCVFileChecksums(); 900 bool parseDirectiveCVFileChecksumOffset(); 901 bool parseDirectiveCVFPOData(); 902 903 // .cfi directives 904 bool parseDirectiveCFIRegister(SMLoc DirectiveLoc); 905 bool parseDirectiveCFIWindowSave(); 906 bool parseDirectiveCFISections(); 907 bool parseDirectiveCFIStartProc(); 908 bool parseDirectiveCFIEndProc(); 909 bool parseDirectiveCFIDefCfaOffset(); 910 bool parseDirectiveCFIDefCfa(SMLoc DirectiveLoc); 911 bool parseDirectiveCFIAdjustCfaOffset(); 912 bool parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc); 913 bool parseDirectiveCFIOffset(SMLoc DirectiveLoc); 914 bool parseDirectiveCFIRelOffset(SMLoc DirectiveLoc); 915 bool parseDirectiveCFIPersonalityOrLsda(bool IsPersonality); 916 bool parseDirectiveCFIRememberState(); 917 bool parseDirectiveCFIRestoreState(); 918 bool parseDirectiveCFISameValue(SMLoc DirectiveLoc); 919 bool parseDirectiveCFIRestore(SMLoc DirectiveLoc); 920 bool parseDirectiveCFIEscape(); 921 bool parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc); 922 bool parseDirectiveCFISignalFrame(); 923 bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc); 924 925 // macro directives 926 bool parseDirectivePurgeMacro(SMLoc DirectiveLoc); 927 bool parseDirectiveExitMacro(SMLoc DirectiveLoc, StringRef Directive, 928 std::string &Value); 929 bool parseDirectiveEndMacro(StringRef Directive); 930 bool parseDirectiveMacro(StringRef Name, SMLoc NameLoc); 931 932 bool parseDirectiveStruct(StringRef Directive, DirectiveKind DirKind, 933 StringRef Name, SMLoc NameLoc); 934 bool parseDirectiveNestedStruct(StringRef Directive, DirectiveKind DirKind); 935 bool parseDirectiveEnds(StringRef Name, SMLoc NameLoc); 936 bool parseDirectiveNestedEnds(); 937 938 /// Parse a directive like ".globl" which accepts a single symbol (which 939 /// should be a label or an external). 940 bool parseDirectiveSymbolAttribute(MCSymbolAttr Attr); 941 942 bool parseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm" 943 944 bool parseDirectiveComment(SMLoc DirectiveLoc); // "comment" 945 946 bool parseDirectiveInclude(); // "include" 947 948 // "if" or "ife" 949 bool parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind); 950 // "ifb" or "ifnb", depending on ExpectBlank. 951 bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank); 952 // "ifidn", "ifdif", "ifidni", or "ifdifi", depending on ExpectEqual and 953 // CaseInsensitive. 954 bool parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual, 955 bool CaseInsensitive); 956 // "ifdef" or "ifndef", depending on expect_defined 957 bool parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined); 958 // "elseif" or "elseife" 959 bool parseDirectiveElseIf(SMLoc DirectiveLoc, DirectiveKind DirKind); 960 // "elseifb" or "elseifnb", depending on ExpectBlank. 961 bool parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank); 962 // ".elseifdef" or ".elseifndef", depending on expect_defined 963 bool parseDirectiveElseIfdef(SMLoc DirectiveLoc, bool expect_defined); 964 // "elseifidn", "elseifdif", "elseifidni", or "elseifdifi", depending on 965 // ExpectEqual and CaseInsensitive. 966 bool parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual, 967 bool CaseInsensitive); 968 bool parseDirectiveElse(SMLoc DirectiveLoc); // "else" 969 bool parseDirectiveEndIf(SMLoc DirectiveLoc); // "endif" 970 bool parseEscapedString(std::string &Data) override; 971 bool parseAngleBracketString(std::string &Data) override; 972 973 // Macro-like directives 974 MCAsmMacro *parseMacroLikeBody(SMLoc DirectiveLoc); 975 void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, 976 raw_svector_ostream &OS); 977 void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, 978 SMLoc ExitLoc, raw_svector_ostream &OS); 979 bool parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Directive); 980 bool parseDirectiveFor(SMLoc DirectiveLoc, StringRef Directive); 981 bool parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive); 982 bool parseDirectiveWhile(SMLoc DirectiveLoc); 983 984 // "_emit" or "__emit" 985 bool parseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info, 986 size_t Len); 987 988 // "align" 989 bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info); 990 991 // "end" 992 bool parseDirectiveEnd(SMLoc DirectiveLoc); 993 994 // ".err" 995 bool parseDirectiveError(SMLoc DirectiveLoc); 996 // ".errb" or ".errnb", depending on ExpectBlank. 997 bool parseDirectiveErrorIfb(SMLoc DirectiveLoc, bool ExpectBlank); 998 // ".errdef" or ".errndef", depending on ExpectBlank. 999 bool parseDirectiveErrorIfdef(SMLoc DirectiveLoc, bool ExpectDefined); 1000 // ".erridn", ".errdif", ".erridni", or ".errdifi", depending on ExpectEqual 1001 // and CaseInsensitive. 1002 bool parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual, 1003 bool CaseInsensitive); 1004 // ".erre" or ".errnz", depending on ExpectZero. 1005 bool parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero); 1006 1007 // ".radix" 1008 bool parseDirectiveRadix(SMLoc DirectiveLoc); 1009 1010 // "echo" 1011 bool parseDirectiveEcho(); 1012 1013 void initializeDirectiveKindMap(); 1014 void initializeCVDefRangeTypeMap(); 1015 }; 1016 1017 } // end anonymous namespace 1018 1019 namespace llvm { 1020 1021 extern MCAsmParserExtension *createCOFFMasmParser(); 1022 1023 } // end namespace llvm 1024 1025 enum { DEFAULT_ADDRSPACE = 0 }; 1026 1027 MasmParser::MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, 1028 const MCAsmInfo &MAI, unsigned CB = 0) 1029 : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM), 1030 CurBuffer(CB ? CB : SM.getMainFileID()) { 1031 HadError = false; 1032 // Save the old handler. 1033 SavedDiagHandler = SrcMgr.getDiagHandler(); 1034 SavedDiagContext = SrcMgr.getDiagContext(); 1035 // Set our own handler which calls the saved handler. 1036 SrcMgr.setDiagHandler(DiagHandler, this); 1037 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); 1038 EndStatementAtEOFStack.push_back(true); 1039 1040 // Initialize the platform / file format parser. 1041 switch (Ctx.getObjectFileType()) { 1042 case MCContext::IsCOFF: 1043 PlatformParser.reset(createCOFFMasmParser()); 1044 break; 1045 default: 1046 report_fatal_error("llvm-ml currently supports only COFF output."); 1047 break; 1048 } 1049 1050 initializeDirectiveKindMap(); 1051 PlatformParser->Initialize(*this); 1052 initializeCVDefRangeTypeMap(); 1053 1054 NumOfMacroInstantiations = 0; 1055 } 1056 1057 MasmParser::~MasmParser() { 1058 assert((HadError || ActiveMacros.empty()) && 1059 "Unexpected active macro instantiation!"); 1060 1061 // Restore the saved diagnostics handler and context for use during 1062 // finalization. 1063 SrcMgr.setDiagHandler(SavedDiagHandler, SavedDiagContext); 1064 } 1065 1066 void MasmParser::printMacroInstantiations() { 1067 // Print the active macro instantiation stack. 1068 for (std::vector<MacroInstantiation *>::const_reverse_iterator 1069 it = ActiveMacros.rbegin(), 1070 ie = ActiveMacros.rend(); 1071 it != ie; ++it) 1072 printMessage((*it)->InstantiationLoc, SourceMgr::DK_Note, 1073 "while in macro instantiation"); 1074 } 1075 1076 void MasmParser::Note(SMLoc L, const Twine &Msg, SMRange Range) { 1077 printPendingErrors(); 1078 printMessage(L, SourceMgr::DK_Note, Msg, Range); 1079 printMacroInstantiations(); 1080 } 1081 1082 bool MasmParser::Warning(SMLoc L, const Twine &Msg, SMRange Range) { 1083 if (getTargetParser().getTargetOptions().MCNoWarn) 1084 return false; 1085 if (getTargetParser().getTargetOptions().MCFatalWarnings) 1086 return Error(L, Msg, Range); 1087 printMessage(L, SourceMgr::DK_Warning, Msg, Range); 1088 printMacroInstantiations(); 1089 return false; 1090 } 1091 1092 bool MasmParser::printError(SMLoc L, const Twine &Msg, SMRange Range) { 1093 HadError = true; 1094 printMessage(L, SourceMgr::DK_Error, Msg, Range); 1095 printMacroInstantiations(); 1096 return true; 1097 } 1098 1099 bool MasmParser::enterIncludeFile(const std::string &Filename) { 1100 std::string IncludedFile; 1101 unsigned NewBuf = 1102 SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); 1103 if (!NewBuf) 1104 return true; 1105 1106 CurBuffer = NewBuf; 1107 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); 1108 EndStatementAtEOFStack.push_back(true); 1109 return false; 1110 } 1111 1112 void MasmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer, 1113 bool EndStatementAtEOF) { 1114 CurBuffer = InBuffer ? InBuffer : SrcMgr.FindBufferContainingLoc(Loc); 1115 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(), 1116 Loc.getPointer(), EndStatementAtEOF); 1117 } 1118 1119 const AsmToken &MasmParser::Lex() { 1120 if (Lexer.getTok().is(AsmToken::Error)) 1121 Error(Lexer.getErrLoc(), Lexer.getErr()); 1122 1123 // if it's a end of statement with a comment in it 1124 if (getTok().is(AsmToken::EndOfStatement)) { 1125 // if this is a line comment output it. 1126 if (!getTok().getString().empty() && getTok().getString().front() != '\n' && 1127 getTok().getString().front() != '\r' && MAI.preserveAsmComments()) 1128 Out.addExplicitComment(Twine(getTok().getString())); 1129 } 1130 1131 const AsmToken *tok = &Lexer.Lex(); 1132 bool StartOfStatement = Lexer.isAtStartOfStatement(); 1133 1134 while (tok->is(AsmToken::Identifier)) { 1135 if (StartOfStatement) { 1136 AsmToken NextTok; 1137 1138 MutableArrayRef<AsmToken> Buf(NextTok); 1139 size_t ReadCount = Lexer.peekTokens(Buf); 1140 if (ReadCount && NextTok.is(AsmToken::Identifier) && 1141 (NextTok.getString().equals_insensitive("equ") || 1142 NextTok.getString().equals_insensitive("textequ"))) { 1143 // This looks like an EQU or TEXTEQU directive; don't expand the 1144 // identifier, allowing for redefinitions. 1145 break; 1146 } 1147 } 1148 auto it = Variables.find(tok->getIdentifier().lower()); 1149 const llvm::MCAsmMacro *M = 1150 getContext().lookupMacro(tok->getIdentifier().lower()); 1151 if (it != Variables.end() && it->second.IsText) { 1152 // This is a textmacro; expand it in place. 1153 std::unique_ptr<MemoryBuffer> Instantiation = 1154 MemoryBuffer::getMemBufferCopy(it->second.TextValue, 1155 "<instantiation>"); 1156 1157 // Jump to the macro instantiation and prime the lexer. 1158 CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), 1159 getTok().getEndLoc()); 1160 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(), nullptr, 1161 /*EndStatementAtEOF=*/false); 1162 EndStatementAtEOFStack.push_back(false); 1163 tok = &Lexer.Lex(); 1164 } else if (M && M->IsFunction && peekTok().is(AsmToken::LParen)) { 1165 // This is a macro function invocation; expand it in place. 1166 const AsmToken MacroTok = *tok; 1167 tok = &Lexer.Lex(); 1168 if (handleMacroInvocation(M, MacroTok.getLoc())) { 1169 Lexer.UnLex(AsmToken(AsmToken::Error, MacroTok.getIdentifier())); 1170 tok = &Lexer.Lex(); 1171 } 1172 continue; 1173 } else { 1174 break; 1175 } 1176 } 1177 1178 // Parse comments here to be deferred until end of next statement. 1179 while (tok->is(AsmToken::Comment)) { 1180 if (MAI.preserveAsmComments()) 1181 Out.addExplicitComment(Twine(tok->getString())); 1182 tok = &Lexer.Lex(); 1183 } 1184 1185 // Recognize and bypass line continuations. 1186 while (tok->is(AsmToken::BackSlash) && 1187 peekTok().is(AsmToken::EndOfStatement)) { 1188 // Eat both the backslash and the end of statement. 1189 Lexer.Lex(); 1190 tok = &Lexer.Lex(); 1191 } 1192 1193 if (tok->is(AsmToken::Eof)) { 1194 // If this is the end of an included file, pop the parent file off the 1195 // include stack. 1196 SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer); 1197 if (ParentIncludeLoc != SMLoc()) { 1198 EndStatementAtEOFStack.pop_back(); 1199 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back()); 1200 return Lex(); 1201 } 1202 EndStatementAtEOFStack.pop_back(); 1203 assert(EndStatementAtEOFStack.empty()); 1204 } 1205 1206 return *tok; 1207 } 1208 1209 const AsmToken MasmParser::peekTok(bool ShouldSkipSpace) { 1210 AsmToken Tok; 1211 1212 MutableArrayRef<AsmToken> Buf(Tok); 1213 size_t ReadCount = Lexer.peekTokens(Buf, ShouldSkipSpace); 1214 1215 if (ReadCount == 0) { 1216 // If this is the end of an included file, pop the parent file off the 1217 // include stack. 1218 SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer); 1219 if (ParentIncludeLoc != SMLoc()) { 1220 EndStatementAtEOFStack.pop_back(); 1221 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back()); 1222 return peekTok(ShouldSkipSpace); 1223 } 1224 EndStatementAtEOFStack.pop_back(); 1225 assert(EndStatementAtEOFStack.empty()); 1226 } 1227 1228 assert(ReadCount == 1); 1229 return Tok; 1230 } 1231 1232 bool MasmParser::enabledGenDwarfForAssembly() { 1233 // Check whether the user specified -g. 1234 if (!getContext().getGenDwarfForAssembly()) 1235 return false; 1236 // If we haven't encountered any .file directives (which would imply that 1237 // the assembler source was produced with debug info already) then emit one 1238 // describing the assembler source file itself. 1239 if (getContext().getGenDwarfFileNumber() == 0) { 1240 // Use the first #line directive for this, if any. It's preprocessed, so 1241 // there is no checksum, and of course no source directive. 1242 if (!FirstCppHashFilename.empty()) 1243 getContext().setMCLineTableRootFile(/*CUID=*/0, 1244 getContext().getCompilationDir(), 1245 FirstCppHashFilename, 1246 /*Cksum=*/None, /*Source=*/None); 1247 const MCDwarfFile &RootFile = 1248 getContext().getMCDwarfLineTable(/*CUID=*/0).getRootFile(); 1249 getContext().setGenDwarfFileNumber(getStreamer().emitDwarfFileDirective( 1250 /*CUID=*/0, getContext().getCompilationDir(), RootFile.Name, 1251 RootFile.Checksum, RootFile.Source)); 1252 } 1253 return true; 1254 } 1255 1256 bool MasmParser::Run(bool NoInitialTextSection, bool NoFinalize) { 1257 // Create the initial section, if requested. 1258 if (!NoInitialTextSection) 1259 Out.InitSections(false); 1260 1261 // Prime the lexer. 1262 Lex(); 1263 1264 HadError = false; 1265 AsmCond StartingCondState = TheCondState; 1266 SmallVector<AsmRewrite, 4> AsmStrRewrites; 1267 1268 // If we are generating dwarf for assembly source files save the initial text 1269 // section. (Don't use enabledGenDwarfForAssembly() here, as we aren't 1270 // emitting any actual debug info yet and haven't had a chance to parse any 1271 // embedded .file directives.) 1272 if (getContext().getGenDwarfForAssembly()) { 1273 MCSection *Sec = getStreamer().getCurrentSectionOnly(); 1274 if (!Sec->getBeginSymbol()) { 1275 MCSymbol *SectionStartSym = getContext().createTempSymbol(); 1276 getStreamer().emitLabel(SectionStartSym); 1277 Sec->setBeginSymbol(SectionStartSym); 1278 } 1279 bool InsertResult = getContext().addGenDwarfSection(Sec); 1280 assert(InsertResult && ".text section should not have debug info yet"); 1281 (void)InsertResult; 1282 } 1283 1284 getTargetParser().onBeginOfFile(); 1285 1286 // While we have input, parse each statement. 1287 while (Lexer.isNot(AsmToken::Eof) || 1288 SrcMgr.getParentIncludeLoc(CurBuffer) != SMLoc()) { 1289 // Skip through the EOF at the end of an inclusion. 1290 if (Lexer.is(AsmToken::Eof)) 1291 Lex(); 1292 1293 ParseStatementInfo Info(&AsmStrRewrites); 1294 bool Parsed = parseStatement(Info, nullptr); 1295 1296 // If we have a Lexer Error we are on an Error Token. Load in Lexer Error 1297 // for printing ErrMsg via Lex() only if no (presumably better) parser error 1298 // exists. 1299 if (Parsed && !hasPendingError() && Lexer.getTok().is(AsmToken::Error)) { 1300 Lex(); 1301 } 1302 1303 // parseStatement returned true so may need to emit an error. 1304 printPendingErrors(); 1305 1306 // Skipping to the next line if needed. 1307 if (Parsed && !getLexer().isAtStartOfStatement()) 1308 eatToEndOfStatement(); 1309 } 1310 1311 getTargetParser().onEndOfFile(); 1312 printPendingErrors(); 1313 1314 // All errors should have been emitted. 1315 assert(!hasPendingError() && "unexpected error from parseStatement"); 1316 1317 getTargetParser().flushPendingInstructions(getStreamer()); 1318 1319 if (TheCondState.TheCond != StartingCondState.TheCond || 1320 TheCondState.Ignore != StartingCondState.Ignore) 1321 printError(getTok().getLoc(), "unmatched .ifs or .elses"); 1322 // Check to see there are no empty DwarfFile slots. 1323 const auto &LineTables = getContext().getMCDwarfLineTables(); 1324 if (!LineTables.empty()) { 1325 unsigned Index = 0; 1326 for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) { 1327 if (File.Name.empty() && Index != 0) 1328 printError(getTok().getLoc(), "unassigned file number: " + 1329 Twine(Index) + 1330 " for .file directives"); 1331 ++Index; 1332 } 1333 } 1334 1335 // Check to see that all assembler local symbols were actually defined. 1336 // Targets that don't do subsections via symbols may not want this, though, 1337 // so conservatively exclude them. Only do this if we're finalizing, though, 1338 // as otherwise we won't necessarilly have seen everything yet. 1339 if (!NoFinalize) { 1340 if (MAI.hasSubsectionsViaSymbols()) { 1341 for (const auto &TableEntry : getContext().getSymbols()) { 1342 MCSymbol *Sym = TableEntry.getValue(); 1343 // Variable symbols may not be marked as defined, so check those 1344 // explicitly. If we know it's a variable, we have a definition for 1345 // the purposes of this check. 1346 if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined()) 1347 // FIXME: We would really like to refer back to where the symbol was 1348 // first referenced for a source location. We need to add something 1349 // to track that. Currently, we just point to the end of the file. 1350 printError(getTok().getLoc(), "assembler local symbol '" + 1351 Sym->getName() + "' not defined"); 1352 } 1353 } 1354 1355 // Temporary symbols like the ones for directional jumps don't go in the 1356 // symbol table. They also need to be diagnosed in all (final) cases. 1357 for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) { 1358 if (std::get<2>(LocSym)->isUndefined()) { 1359 // Reset the state of any "# line file" directives we've seen to the 1360 // context as it was at the diagnostic site. 1361 CppHashInfo = std::get<1>(LocSym); 1362 printError(std::get<0>(LocSym), "directional label undefined"); 1363 } 1364 } 1365 } 1366 1367 // Finalize the output stream if there are no errors and if the client wants 1368 // us to. 1369 if (!HadError && !NoFinalize) 1370 Out.Finish(Lexer.getLoc()); 1371 1372 return HadError || getContext().hadError(); 1373 } 1374 1375 bool MasmParser::checkForValidSection() { 1376 if (!ParsingMSInlineAsm && !getStreamer().getCurrentSectionOnly()) { 1377 Out.InitSections(false); 1378 return Error(getTok().getLoc(), 1379 "expected section directive before assembly directive"); 1380 } 1381 return false; 1382 } 1383 1384 /// Throw away the rest of the line for testing purposes. 1385 void MasmParser::eatToEndOfStatement() { 1386 while (Lexer.isNot(AsmToken::EndOfStatement)) { 1387 if (Lexer.is(AsmToken::Eof)) { 1388 SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer); 1389 if (ParentIncludeLoc == SMLoc()) { 1390 break; 1391 } 1392 1393 EndStatementAtEOFStack.pop_back(); 1394 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back()); 1395 } 1396 1397 Lexer.Lex(); 1398 } 1399 1400 // Eat EOL. 1401 if (Lexer.is(AsmToken::EndOfStatement)) 1402 Lexer.Lex(); 1403 } 1404 1405 SmallVector<StringRef, 1> 1406 MasmParser::parseStringRefsTo(AsmToken::TokenKind EndTok) { 1407 SmallVector<StringRef, 1> Refs; 1408 const char *Start = getTok().getLoc().getPointer(); 1409 while (Lexer.isNot(EndTok)) { 1410 if (Lexer.is(AsmToken::Eof)) { 1411 SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer); 1412 if (ParentIncludeLoc == SMLoc()) { 1413 break; 1414 } 1415 Refs.emplace_back(Start, getTok().getLoc().getPointer() - Start); 1416 1417 EndStatementAtEOFStack.pop_back(); 1418 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back()); 1419 Lexer.Lex(); 1420 Start = getTok().getLoc().getPointer(); 1421 } else { 1422 Lexer.Lex(); 1423 } 1424 } 1425 Refs.emplace_back(Start, getTok().getLoc().getPointer() - Start); 1426 return Refs; 1427 } 1428 1429 std::string MasmParser::parseStringTo(AsmToken::TokenKind EndTok) { 1430 SmallVector<StringRef, 1> Refs = parseStringRefsTo(EndTok); 1431 std::string Str; 1432 for (StringRef S : Refs) { 1433 Str.append(S.str()); 1434 } 1435 return Str; 1436 } 1437 1438 StringRef MasmParser::parseStringToEndOfStatement() { 1439 const char *Start = getTok().getLoc().getPointer(); 1440 1441 while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof)) 1442 Lexer.Lex(); 1443 1444 const char *End = getTok().getLoc().getPointer(); 1445 return StringRef(Start, End - Start); 1446 } 1447 1448 /// Parse a paren expression and return it. 1449 /// NOTE: This assumes the leading '(' has already been consumed. 1450 /// 1451 /// parenexpr ::= expr) 1452 /// 1453 bool MasmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) { 1454 if (parseExpression(Res)) 1455 return true; 1456 if (Lexer.isNot(AsmToken::RParen)) 1457 return TokError("expected ')' in parentheses expression"); 1458 EndLoc = Lexer.getTok().getEndLoc(); 1459 Lex(); 1460 return false; 1461 } 1462 1463 /// Parse a bracket expression and return it. 1464 /// NOTE: This assumes the leading '[' has already been consumed. 1465 /// 1466 /// bracketexpr ::= expr] 1467 /// 1468 bool MasmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) { 1469 if (parseExpression(Res)) 1470 return true; 1471 EndLoc = getTok().getEndLoc(); 1472 if (parseToken(AsmToken::RBrac, "expected ']' in brackets expression")) 1473 return true; 1474 return false; 1475 } 1476 1477 /// Parse a primary expression and return it. 1478 /// primaryexpr ::= (parenexpr 1479 /// primaryexpr ::= symbol 1480 /// primaryexpr ::= number 1481 /// primaryexpr ::= '.' 1482 /// primaryexpr ::= ~,+,-,'not' primaryexpr 1483 /// primaryexpr ::= string 1484 /// (a string is interpreted as a 64-bit number in big-endian base-256) 1485 bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc, 1486 AsmTypeInfo *TypeInfo) { 1487 SMLoc FirstTokenLoc = getLexer().getLoc(); 1488 AsmToken::TokenKind FirstTokenKind = Lexer.getKind(); 1489 switch (FirstTokenKind) { 1490 default: 1491 return TokError("unknown token in expression"); 1492 // If we have an error assume that we've already handled it. 1493 case AsmToken::Error: 1494 return true; 1495 case AsmToken::Exclaim: 1496 Lex(); // Eat the operator. 1497 if (parsePrimaryExpr(Res, EndLoc, nullptr)) 1498 return true; 1499 Res = MCUnaryExpr::createLNot(Res, getContext(), FirstTokenLoc); 1500 return false; 1501 case AsmToken::Dollar: 1502 case AsmToken::At: 1503 case AsmToken::Identifier: { 1504 StringRef Identifier; 1505 if (parseIdentifier(Identifier)) { 1506 // We may have failed but $ may be a valid token. 1507 if (getTok().is(AsmToken::Dollar)) { 1508 if (Lexer.getMAI().getDollarIsPC()) { 1509 Lex(); 1510 // This is a '$' reference, which references the current PC. Emit a 1511 // temporary label to the streamer and refer to it. 1512 MCSymbol *Sym = Ctx.createTempSymbol(); 1513 Out.emitLabel(Sym); 1514 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, 1515 getContext()); 1516 EndLoc = FirstTokenLoc; 1517 return false; 1518 } 1519 return Error(FirstTokenLoc, "invalid token in expression"); 1520 } 1521 } 1522 // Parse named bitwise negation. 1523 if (Identifier.equals_insensitive("not")) { 1524 if (parsePrimaryExpr(Res, EndLoc, nullptr)) 1525 return true; 1526 Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc); 1527 return false; 1528 } 1529 // Parse symbol variant. 1530 std::pair<StringRef, StringRef> Split; 1531 if (!MAI.useParensForSymbolVariant()) { 1532 if (FirstTokenKind == AsmToken::String) { 1533 if (Lexer.is(AsmToken::At)) { 1534 Lex(); // eat @ 1535 SMLoc AtLoc = getLexer().getLoc(); 1536 StringRef VName; 1537 if (parseIdentifier(VName)) 1538 return Error(AtLoc, "expected symbol variant after '@'"); 1539 1540 Split = std::make_pair(Identifier, VName); 1541 } 1542 } else { 1543 Split = Identifier.split('@'); 1544 } 1545 } else if (Lexer.is(AsmToken::LParen)) { 1546 Lex(); // eat '('. 1547 StringRef VName; 1548 parseIdentifier(VName); 1549 // eat ')'. 1550 if (parseToken(AsmToken::RParen, 1551 "unexpected token in variant, expected ')'")) 1552 return true; 1553 Split = std::make_pair(Identifier, VName); 1554 } 1555 1556 EndLoc = SMLoc::getFromPointer(Identifier.end()); 1557 1558 // This is a symbol reference. 1559 StringRef SymbolName = Identifier; 1560 if (SymbolName.empty()) 1561 return Error(getLexer().getLoc(), "expected a symbol reference"); 1562 1563 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 1564 1565 // Look up the symbol variant if used. 1566 if (!Split.second.empty()) { 1567 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second); 1568 if (Variant != MCSymbolRefExpr::VK_Invalid) { 1569 SymbolName = Split.first; 1570 } else if (MAI.doesAllowAtInName() && !MAI.useParensForSymbolVariant()) { 1571 Variant = MCSymbolRefExpr::VK_None; 1572 } else { 1573 return Error(SMLoc::getFromPointer(Split.second.begin()), 1574 "invalid variant '" + Split.second + "'"); 1575 } 1576 } 1577 1578 // Find the field offset if used. 1579 AsmFieldInfo Info; 1580 Split = SymbolName.split('.'); 1581 if (Split.second.empty()) { 1582 } else { 1583 SymbolName = Split.first; 1584 if (lookUpField(SymbolName, Split.second, Info)) { 1585 std::pair<StringRef, StringRef> BaseMember = Split.second.split('.'); 1586 StringRef Base = BaseMember.first, Member = BaseMember.second; 1587 lookUpField(Base, Member, Info); 1588 } else if (Structs.count(SymbolName.lower())) { 1589 // This is actually a reference to a field offset. 1590 Res = MCConstantExpr::create(Info.Offset, getContext()); 1591 return false; 1592 } 1593 } 1594 1595 MCSymbol *Sym = getContext().getInlineAsmLabel(SymbolName); 1596 if (!Sym) { 1597 // Variables use case-insensitive symbol names; if this is a variable, we 1598 // find the symbol using its canonical name. 1599 auto VarIt = Variables.find(SymbolName.lower()); 1600 if (VarIt != Variables.end()) 1601 SymbolName = VarIt->second.Name; 1602 Sym = getContext().getOrCreateSymbol(SymbolName); 1603 } 1604 1605 // If this is an absolute variable reference, substitute it now to preserve 1606 // semantics in the face of reassignment. 1607 if (Sym->isVariable()) { 1608 auto V = Sym->getVariableValue(/*SetUsed*/ false); 1609 bool DoInline = isa<MCConstantExpr>(V) && !Variant; 1610 if (auto TV = dyn_cast<MCTargetExpr>(V)) 1611 DoInline = TV->inlineAssignedExpr(); 1612 if (DoInline) { 1613 if (Variant) 1614 return Error(EndLoc, "unexpected modifier on variable reference"); 1615 Res = Sym->getVariableValue(/*SetUsed*/ false); 1616 return false; 1617 } 1618 } 1619 1620 // Otherwise create a symbol ref. 1621 const MCExpr *SymRef = 1622 MCSymbolRefExpr::create(Sym, Variant, getContext(), FirstTokenLoc); 1623 if (Info.Offset) { 1624 Res = MCBinaryExpr::create( 1625 MCBinaryExpr::Add, SymRef, 1626 MCConstantExpr::create(Info.Offset, getContext()), getContext()); 1627 } else { 1628 Res = SymRef; 1629 } 1630 if (TypeInfo) { 1631 if (Info.Type.Name.empty()) { 1632 auto TypeIt = KnownType.find(Identifier.lower()); 1633 if (TypeIt != KnownType.end()) { 1634 Info.Type = TypeIt->second; 1635 } 1636 } 1637 1638 *TypeInfo = Info.Type; 1639 } 1640 return false; 1641 } 1642 case AsmToken::BigNum: 1643 return TokError("literal value out of range for directive"); 1644 case AsmToken::Integer: { 1645 SMLoc Loc = getTok().getLoc(); 1646 int64_t IntVal = getTok().getIntVal(); 1647 Res = MCConstantExpr::create(IntVal, getContext()); 1648 EndLoc = Lexer.getTok().getEndLoc(); 1649 Lex(); // Eat token. 1650 // Look for 'b' or 'f' following an Integer as a directional label. 1651 if (Lexer.getKind() == AsmToken::Identifier) { 1652 StringRef IDVal = getTok().getString(); 1653 // Look up the symbol variant if used. 1654 std::pair<StringRef, StringRef> Split = IDVal.split('@'); 1655 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 1656 if (Split.first.size() != IDVal.size()) { 1657 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second); 1658 if (Variant == MCSymbolRefExpr::VK_Invalid) 1659 return TokError("invalid variant '" + Split.second + "'"); 1660 IDVal = Split.first; 1661 } 1662 if (IDVal == "f" || IDVal == "b") { 1663 MCSymbol *Sym = 1664 Ctx.getDirectionalLocalSymbol(IntVal, IDVal == "b"); 1665 Res = MCSymbolRefExpr::create(Sym, Variant, getContext()); 1666 if (IDVal == "b" && Sym->isUndefined()) 1667 return Error(Loc, "directional label undefined"); 1668 DirLabels.push_back(std::make_tuple(Loc, CppHashInfo, Sym)); 1669 EndLoc = Lexer.getTok().getEndLoc(); 1670 Lex(); // Eat identifier. 1671 } 1672 } 1673 return false; 1674 } 1675 case AsmToken::String: { 1676 // MASM strings (used as constants) are interpreted as big-endian base-256. 1677 SMLoc ValueLoc = getTok().getLoc(); 1678 std::string Value; 1679 if (parseEscapedString(Value)) 1680 return true; 1681 if (Value.size() > 8) 1682 return Error(ValueLoc, "literal value out of range"); 1683 uint64_t IntValue = 0; 1684 for (const unsigned char CharVal : Value) 1685 IntValue = (IntValue << 8) | CharVal; 1686 Res = MCConstantExpr::create(IntValue, getContext()); 1687 return false; 1688 } 1689 case AsmToken::Real: { 1690 APFloat RealVal(APFloat::IEEEdouble(), getTok().getString()); 1691 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 1692 Res = MCConstantExpr::create(IntVal, getContext()); 1693 EndLoc = Lexer.getTok().getEndLoc(); 1694 Lex(); // Eat token. 1695 return false; 1696 } 1697 case AsmToken::Dot: { 1698 // This is a '.' reference, which references the current PC. Emit a 1699 // temporary label to the streamer and refer to it. 1700 MCSymbol *Sym = Ctx.createTempSymbol(); 1701 Out.emitLabel(Sym); 1702 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1703 EndLoc = Lexer.getTok().getEndLoc(); 1704 Lex(); // Eat identifier. 1705 return false; 1706 } 1707 case AsmToken::LParen: 1708 Lex(); // Eat the '('. 1709 return parseParenExpr(Res, EndLoc); 1710 case AsmToken::LBrac: 1711 if (!PlatformParser->HasBracketExpressions()) 1712 return TokError("brackets expression not supported on this target"); 1713 Lex(); // Eat the '['. 1714 return parseBracketExpr(Res, EndLoc); 1715 case AsmToken::Minus: 1716 Lex(); // Eat the operator. 1717 if (parsePrimaryExpr(Res, EndLoc, nullptr)) 1718 return true; 1719 Res = MCUnaryExpr::createMinus(Res, getContext(), FirstTokenLoc); 1720 return false; 1721 case AsmToken::Plus: 1722 Lex(); // Eat the operator. 1723 if (parsePrimaryExpr(Res, EndLoc, nullptr)) 1724 return true; 1725 Res = MCUnaryExpr::createPlus(Res, getContext(), FirstTokenLoc); 1726 return false; 1727 case AsmToken::Tilde: 1728 Lex(); // Eat the operator. 1729 if (parsePrimaryExpr(Res, EndLoc, nullptr)) 1730 return true; 1731 Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc); 1732 return false; 1733 // MIPS unary expression operators. The lexer won't generate these tokens if 1734 // MCAsmInfo::HasMipsExpressions is false for the target. 1735 case AsmToken::PercentCall16: 1736 case AsmToken::PercentCall_Hi: 1737 case AsmToken::PercentCall_Lo: 1738 case AsmToken::PercentDtprel_Hi: 1739 case AsmToken::PercentDtprel_Lo: 1740 case AsmToken::PercentGot: 1741 case AsmToken::PercentGot_Disp: 1742 case AsmToken::PercentGot_Hi: 1743 case AsmToken::PercentGot_Lo: 1744 case AsmToken::PercentGot_Ofst: 1745 case AsmToken::PercentGot_Page: 1746 case AsmToken::PercentGottprel: 1747 case AsmToken::PercentGp_Rel: 1748 case AsmToken::PercentHi: 1749 case AsmToken::PercentHigher: 1750 case AsmToken::PercentHighest: 1751 case AsmToken::PercentLo: 1752 case AsmToken::PercentNeg: 1753 case AsmToken::PercentPcrel_Hi: 1754 case AsmToken::PercentPcrel_Lo: 1755 case AsmToken::PercentTlsgd: 1756 case AsmToken::PercentTlsldm: 1757 case AsmToken::PercentTprel_Hi: 1758 case AsmToken::PercentTprel_Lo: 1759 Lex(); // Eat the operator. 1760 if (Lexer.isNot(AsmToken::LParen)) 1761 return TokError("expected '(' after operator"); 1762 Lex(); // Eat the operator. 1763 if (parseExpression(Res, EndLoc)) 1764 return true; 1765 if (Lexer.isNot(AsmToken::RParen)) 1766 return TokError("expected ')'"); 1767 Lex(); // Eat the operator. 1768 Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx); 1769 return !Res; 1770 } 1771 } 1772 1773 bool MasmParser::parseExpression(const MCExpr *&Res) { 1774 SMLoc EndLoc; 1775 return parseExpression(Res, EndLoc); 1776 } 1777 1778 /// This function checks if the next token is <string> type or arithmetic. 1779 /// string that begin with character '<' must end with character '>'. 1780 /// otherwise it is arithmetics. 1781 /// If the function returns a 'true' value, 1782 /// the End argument will be filled with the last location pointed to the '>' 1783 /// character. 1784 static bool isAngleBracketString(SMLoc &StrLoc, SMLoc &EndLoc) { 1785 assert((StrLoc.getPointer() != nullptr) && 1786 "Argument to the function cannot be a NULL value"); 1787 const char *CharPtr = StrLoc.getPointer(); 1788 while ((*CharPtr != '>') && (*CharPtr != '\n') && (*CharPtr != '\r') && 1789 (*CharPtr != '\0')) { 1790 if (*CharPtr == '!') 1791 CharPtr++; 1792 CharPtr++; 1793 } 1794 if (*CharPtr == '>') { 1795 EndLoc = StrLoc.getFromPointer(CharPtr + 1); 1796 return true; 1797 } 1798 return false; 1799 } 1800 1801 /// creating a string without the escape characters '!'. 1802 static std::string angleBracketString(StringRef BracketContents) { 1803 std::string Res; 1804 for (size_t Pos = 0; Pos < BracketContents.size(); Pos++) { 1805 if (BracketContents[Pos] == '!') 1806 Pos++; 1807 Res += BracketContents[Pos]; 1808 } 1809 return Res; 1810 } 1811 1812 /// Parse an expression and return it. 1813 /// 1814 /// expr ::= expr &&,|| expr -> lowest. 1815 /// expr ::= expr |,^,&,! expr 1816 /// expr ::= expr ==,!=,<>,<,<=,>,>= expr 1817 /// expr ::= expr <<,>> expr 1818 /// expr ::= expr +,- expr 1819 /// expr ::= expr *,/,% expr -> highest. 1820 /// expr ::= primaryexpr 1821 /// 1822 bool MasmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) { 1823 // Parse the expression. 1824 Res = nullptr; 1825 if (getTargetParser().parsePrimaryExpr(Res, EndLoc) || 1826 parseBinOpRHS(1, Res, EndLoc)) 1827 return true; 1828 1829 // Try to constant fold it up front, if possible. Do not exploit 1830 // assembler here. 1831 int64_t Value; 1832 if (Res->evaluateAsAbsolute(Value)) 1833 Res = MCConstantExpr::create(Value, getContext()); 1834 1835 return false; 1836 } 1837 1838 bool MasmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) { 1839 Res = nullptr; 1840 return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc); 1841 } 1842 1843 bool MasmParser::parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res, 1844 SMLoc &EndLoc) { 1845 if (parseParenExpr(Res, EndLoc)) 1846 return true; 1847 1848 for (; ParenDepth > 0; --ParenDepth) { 1849 if (parseBinOpRHS(1, Res, EndLoc)) 1850 return true; 1851 1852 // We don't Lex() the last RParen. 1853 // This is the same behavior as parseParenExpression(). 1854 if (ParenDepth - 1 > 0) { 1855 EndLoc = getTok().getEndLoc(); 1856 if (parseToken(AsmToken::RParen, 1857 "expected ')' in parentheses expression")) 1858 return true; 1859 } 1860 } 1861 return false; 1862 } 1863 1864 bool MasmParser::parseAbsoluteExpression(int64_t &Res) { 1865 const MCExpr *Expr; 1866 1867 SMLoc StartLoc = Lexer.getLoc(); 1868 if (parseExpression(Expr)) 1869 return true; 1870 1871 if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr())) 1872 return Error(StartLoc, "expected absolute expression"); 1873 1874 return false; 1875 } 1876 1877 static unsigned getGNUBinOpPrecedence(AsmToken::TokenKind K, 1878 MCBinaryExpr::Opcode &Kind, 1879 bool ShouldUseLogicalShr, 1880 bool EndExpressionAtGreater) { 1881 switch (K) { 1882 default: 1883 return 0; // not a binop. 1884 1885 // Lowest Precedence: &&, || 1886 case AsmToken::AmpAmp: 1887 Kind = MCBinaryExpr::LAnd; 1888 return 2; 1889 case AsmToken::PipePipe: 1890 Kind = MCBinaryExpr::LOr; 1891 return 1; 1892 1893 // Low Precedence: ==, !=, <>, <, <=, >, >= 1894 case AsmToken::EqualEqual: 1895 Kind = MCBinaryExpr::EQ; 1896 return 3; 1897 case AsmToken::ExclaimEqual: 1898 case AsmToken::LessGreater: 1899 Kind = MCBinaryExpr::NE; 1900 return 3; 1901 case AsmToken::Less: 1902 Kind = MCBinaryExpr::LT; 1903 return 3; 1904 case AsmToken::LessEqual: 1905 Kind = MCBinaryExpr::LTE; 1906 return 3; 1907 case AsmToken::Greater: 1908 if (EndExpressionAtGreater) 1909 return 0; 1910 Kind = MCBinaryExpr::GT; 1911 return 3; 1912 case AsmToken::GreaterEqual: 1913 Kind = MCBinaryExpr::GTE; 1914 return 3; 1915 1916 // Low Intermediate Precedence: +, - 1917 case AsmToken::Plus: 1918 Kind = MCBinaryExpr::Add; 1919 return 4; 1920 case AsmToken::Minus: 1921 Kind = MCBinaryExpr::Sub; 1922 return 4; 1923 1924 // High Intermediate Precedence: |, &, ^ 1925 case AsmToken::Pipe: 1926 Kind = MCBinaryExpr::Or; 1927 return 5; 1928 case AsmToken::Caret: 1929 Kind = MCBinaryExpr::Xor; 1930 return 5; 1931 case AsmToken::Amp: 1932 Kind = MCBinaryExpr::And; 1933 return 5; 1934 1935 // Highest Precedence: *, /, %, <<, >> 1936 case AsmToken::Star: 1937 Kind = MCBinaryExpr::Mul; 1938 return 6; 1939 case AsmToken::Slash: 1940 Kind = MCBinaryExpr::Div; 1941 return 6; 1942 case AsmToken::Percent: 1943 Kind = MCBinaryExpr::Mod; 1944 return 6; 1945 case AsmToken::LessLess: 1946 Kind = MCBinaryExpr::Shl; 1947 return 6; 1948 case AsmToken::GreaterGreater: 1949 if (EndExpressionAtGreater) 1950 return 0; 1951 Kind = ShouldUseLogicalShr ? MCBinaryExpr::LShr : MCBinaryExpr::AShr; 1952 return 6; 1953 } 1954 } 1955 1956 unsigned MasmParser::getBinOpPrecedence(AsmToken::TokenKind K, 1957 MCBinaryExpr::Opcode &Kind) { 1958 bool ShouldUseLogicalShr = MAI.shouldUseLogicalShr(); 1959 return getGNUBinOpPrecedence(K, Kind, ShouldUseLogicalShr, 1960 AngleBracketDepth > 0); 1961 } 1962 1963 /// Parse all binary operators with precedence >= 'Precedence'. 1964 /// Res contains the LHS of the expression on input. 1965 bool MasmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, 1966 SMLoc &EndLoc) { 1967 SMLoc StartLoc = Lexer.getLoc(); 1968 while (true) { 1969 AsmToken::TokenKind TokKind = Lexer.getKind(); 1970 if (Lexer.getKind() == AsmToken::Identifier) { 1971 TokKind = StringSwitch<AsmToken::TokenKind>(Lexer.getTok().getString()) 1972 .CaseLower("and", AsmToken::Amp) 1973 .CaseLower("not", AsmToken::Exclaim) 1974 .CaseLower("or", AsmToken::Pipe) 1975 .CaseLower("eq", AsmToken::EqualEqual) 1976 .CaseLower("ne", AsmToken::ExclaimEqual) 1977 .CaseLower("lt", AsmToken::Less) 1978 .CaseLower("le", AsmToken::LessEqual) 1979 .CaseLower("gt", AsmToken::Greater) 1980 .CaseLower("ge", AsmToken::GreaterEqual) 1981 .Default(TokKind); 1982 } 1983 MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add; 1984 unsigned TokPrec = getBinOpPrecedence(TokKind, Kind); 1985 1986 // If the next token is lower precedence than we are allowed to eat, return 1987 // successfully with what we ate already. 1988 if (TokPrec < Precedence) 1989 return false; 1990 1991 Lex(); 1992 1993 // Eat the next primary expression. 1994 const MCExpr *RHS; 1995 if (getTargetParser().parsePrimaryExpr(RHS, EndLoc)) 1996 return true; 1997 1998 // If BinOp binds less tightly with RHS than the operator after RHS, let 1999 // the pending operator take RHS as its LHS. 2000 MCBinaryExpr::Opcode Dummy; 2001 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy); 2002 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc)) 2003 return true; 2004 2005 // Merge LHS and RHS according to operator. 2006 Res = MCBinaryExpr::create(Kind, Res, RHS, getContext(), StartLoc); 2007 } 2008 } 2009 2010 /// ParseStatement: 2011 /// ::= % statement 2012 /// ::= EndOfStatement 2013 /// ::= Label* Directive ...Operands... EndOfStatement 2014 /// ::= Label* Identifier OperandList* EndOfStatement 2015 bool MasmParser::parseStatement(ParseStatementInfo &Info, 2016 MCAsmParserSemaCallback *SI) { 2017 assert(!hasPendingError() && "parseStatement started with pending error"); 2018 // Eat initial spaces and comments. 2019 while (Lexer.is(AsmToken::Space)) 2020 Lex(); 2021 if (Lexer.is(AsmToken::EndOfStatement)) { 2022 // If this is a line comment we can drop it safely. 2023 if (getTok().getString().empty() || getTok().getString().front() == '\r' || 2024 getTok().getString().front() == '\n') 2025 Out.AddBlankLine(); 2026 Lex(); 2027 return false; 2028 } 2029 2030 // If preceded by an expansion operator, first expand all text macros and 2031 // macro functions. 2032 if (getTok().is(AsmToken::Percent)) { 2033 SMLoc ExpansionLoc = getTok().getLoc(); 2034 if (parseToken(AsmToken::Percent) || expandStatement(ExpansionLoc)) 2035 return true; 2036 } 2037 2038 // Statements always start with an identifier, unless we're dealing with a 2039 // processor directive (.386, .686, etc.) that lexes as a real. 2040 AsmToken ID = getTok(); 2041 SMLoc IDLoc = ID.getLoc(); 2042 StringRef IDVal; 2043 int64_t LocalLabelVal = -1; 2044 if (Lexer.is(AsmToken::HashDirective)) 2045 return parseCppHashLineFilenameComment(IDLoc); 2046 // Allow an integer followed by a ':' as a directional local label. 2047 if (Lexer.is(AsmToken::Integer)) { 2048 LocalLabelVal = getTok().getIntVal(); 2049 if (LocalLabelVal < 0) { 2050 if (!TheCondState.Ignore) { 2051 Lex(); // always eat a token 2052 return Error(IDLoc, "unexpected token at start of statement"); 2053 } 2054 IDVal = ""; 2055 } else { 2056 IDVal = getTok().getString(); 2057 Lex(); // Consume the integer token to be used as an identifier token. 2058 if (Lexer.getKind() != AsmToken::Colon) { 2059 if (!TheCondState.Ignore) { 2060 Lex(); // always eat a token 2061 return Error(IDLoc, "unexpected token at start of statement"); 2062 } 2063 } 2064 } 2065 } else if (Lexer.is(AsmToken::Dot)) { 2066 // Treat '.' as a valid identifier in this context. 2067 Lex(); 2068 IDVal = "."; 2069 } else if (Lexer.is(AsmToken::LCurly)) { 2070 // Treat '{' as a valid identifier in this context. 2071 Lex(); 2072 IDVal = "{"; 2073 2074 } else if (Lexer.is(AsmToken::RCurly)) { 2075 // Treat '}' as a valid identifier in this context. 2076 Lex(); 2077 IDVal = "}"; 2078 } else if (Lexer.is(AsmToken::Star) && 2079 getTargetParser().starIsStartOfStatement()) { 2080 // Accept '*' as a valid start of statement. 2081 Lex(); 2082 IDVal = "*"; 2083 } else if (Lexer.is(AsmToken::Real)) { 2084 // Treat ".<number>" as a valid identifier in this context. 2085 IDVal = getTok().getString(); 2086 Lex(); // always eat a token 2087 if (!IDVal.startswith(".")) 2088 return Error(IDLoc, "unexpected token at start of statement"); 2089 } else if (Lexer.is(AsmToken::Identifier) && 2090 getTok().getString().equals_insensitive("echo")) { 2091 // Intercept echo early to avoid lexical substitution in its message, and 2092 // delegate all handling to the appropriate function. 2093 return parseDirectiveEcho(); 2094 } else if (parseIdentifier(IDVal)) { 2095 if (!TheCondState.Ignore) { 2096 Lex(); // always eat a token 2097 return Error(IDLoc, "unexpected token at start of statement"); 2098 } 2099 IDVal = ""; 2100 } 2101 2102 // Handle conditional assembly here before checking for skipping. We 2103 // have to do this so that .endif isn't skipped in a ".if 0" block for 2104 // example. 2105 StringMap<DirectiveKind>::const_iterator DirKindIt = 2106 DirectiveKindMap.find(IDVal.lower()); 2107 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end()) 2108 ? DK_NO_DIRECTIVE 2109 : DirKindIt->getValue(); 2110 switch (DirKind) { 2111 default: 2112 break; 2113 case DK_IF: 2114 case DK_IFE: 2115 return parseDirectiveIf(IDLoc, DirKind); 2116 case DK_IFB: 2117 return parseDirectiveIfb(IDLoc, true); 2118 case DK_IFNB: 2119 return parseDirectiveIfb(IDLoc, false); 2120 case DK_IFDEF: 2121 return parseDirectiveIfdef(IDLoc, true); 2122 case DK_IFNDEF: 2123 return parseDirectiveIfdef(IDLoc, false); 2124 case DK_IFDIF: 2125 return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/false, 2126 /*CaseInsensitive=*/false); 2127 case DK_IFDIFI: 2128 return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/false, 2129 /*CaseInsensitive=*/true); 2130 case DK_IFIDN: 2131 return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/true, 2132 /*CaseInsensitive=*/false); 2133 case DK_IFIDNI: 2134 return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/true, 2135 /*CaseInsensitive=*/true); 2136 case DK_ELSEIF: 2137 case DK_ELSEIFE: 2138 return parseDirectiveElseIf(IDLoc, DirKind); 2139 case DK_ELSEIFB: 2140 return parseDirectiveElseIfb(IDLoc, true); 2141 case DK_ELSEIFNB: 2142 return parseDirectiveElseIfb(IDLoc, false); 2143 case DK_ELSEIFDEF: 2144 return parseDirectiveElseIfdef(IDLoc, true); 2145 case DK_ELSEIFNDEF: 2146 return parseDirectiveElseIfdef(IDLoc, false); 2147 case DK_ELSEIFDIF: 2148 return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/false, 2149 /*CaseInsensitive=*/false); 2150 case DK_ELSEIFDIFI: 2151 return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/false, 2152 /*CaseInsensitive=*/true); 2153 case DK_ELSEIFIDN: 2154 return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/true, 2155 /*CaseInsensitive=*/false); 2156 case DK_ELSEIFIDNI: 2157 return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/true, 2158 /*CaseInsensitive=*/true); 2159 case DK_ELSE: 2160 return parseDirectiveElse(IDLoc); 2161 case DK_ENDIF: 2162 return parseDirectiveEndIf(IDLoc); 2163 } 2164 2165 // Ignore the statement if in the middle of inactive conditional 2166 // (e.g. ".if 0"). 2167 if (TheCondState.Ignore) { 2168 eatToEndOfStatement(); 2169 return false; 2170 } 2171 2172 // FIXME: Recurse on local labels? 2173 2174 // See what kind of statement we have. 2175 switch (Lexer.getKind()) { 2176 case AsmToken::Colon: { 2177 if (!getTargetParser().isLabel(ID)) 2178 break; 2179 if (checkForValidSection()) 2180 return true; 2181 2182 // identifier ':' -> Label. 2183 Lex(); 2184 2185 // Diagnose attempt to use '.' as a label. 2186 if (IDVal == ".") 2187 return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label"); 2188 2189 // Diagnose attempt to use a variable as a label. 2190 // 2191 // FIXME: Diagnostics. Note the location of the definition as a label. 2192 // FIXME: This doesn't diagnose assignment to a symbol which has been 2193 // implicitly marked as external. 2194 MCSymbol *Sym; 2195 if (LocalLabelVal == -1) { 2196 if (ParsingMSInlineAsm && SI) { 2197 StringRef RewrittenLabel = 2198 SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true); 2199 assert(!RewrittenLabel.empty() && 2200 "We should have an internal name here."); 2201 Info.AsmRewrites->emplace_back(AOK_Label, IDLoc, IDVal.size(), 2202 RewrittenLabel); 2203 IDVal = RewrittenLabel; 2204 } 2205 Sym = getContext().getOrCreateSymbol(IDVal); 2206 } else 2207 Sym = Ctx.createDirectionalLocalSymbol(LocalLabelVal); 2208 // End of Labels should be treated as end of line for lexing 2209 // purposes but that information is not available to the Lexer who 2210 // does not understand Labels. This may cause us to see a Hash 2211 // here instead of a preprocessor line comment. 2212 if (getTok().is(AsmToken::Hash)) { 2213 std::string CommentStr = parseStringTo(AsmToken::EndOfStatement); 2214 Lexer.Lex(); 2215 Lexer.UnLex(AsmToken(AsmToken::EndOfStatement, CommentStr)); 2216 } 2217 2218 // Consume any end of statement token, if present, to avoid spurious 2219 // AddBlankLine calls(). 2220 if (getTok().is(AsmToken::EndOfStatement)) { 2221 Lex(); 2222 } 2223 2224 getTargetParser().doBeforeLabelEmit(Sym); 2225 2226 // Emit the label. 2227 if (!getTargetParser().isParsingMSInlineAsm()) 2228 Out.emitLabel(Sym, IDLoc); 2229 2230 // If we are generating dwarf for assembly source files then gather the 2231 // info to make a dwarf label entry for this label if needed. 2232 if (enabledGenDwarfForAssembly()) 2233 MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(), 2234 IDLoc); 2235 2236 getTargetParser().onLabelParsed(Sym); 2237 2238 return false; 2239 } 2240 2241 default: // Normal instruction or directive. 2242 break; 2243 } 2244 2245 // If macros are enabled, check to see if this is a macro instantiation. 2246 if (const MCAsmMacro *M = getContext().lookupMacro(IDVal.lower())) { 2247 return handleMacroEntry(M, IDLoc); 2248 } 2249 2250 // Otherwise, we have a normal instruction or directive. 2251 2252 if (DirKind != DK_NO_DIRECTIVE) { 2253 // There are several entities interested in parsing directives: 2254 // 2255 // 1. Asm parser extensions. For example, platform-specific parsers 2256 // (like the ELF parser) register themselves as extensions. 2257 // 2. The target-specific assembly parser. Some directives are target 2258 // specific or may potentially behave differently on certain targets. 2259 // 3. The generic directive parser implemented by this class. These are 2260 // all the directives that behave in a target and platform independent 2261 // manner, or at least have a default behavior that's shared between 2262 // all targets and platforms. 2263 2264 getTargetParser().flushPendingInstructions(getStreamer()); 2265 2266 // Special-case handling of structure-end directives at higher priority, 2267 // since ENDS is overloaded as a segment-end directive. 2268 if (IDVal.equals_insensitive("ends") && StructInProgress.size() > 1 && 2269 getTok().is(AsmToken::EndOfStatement)) { 2270 return parseDirectiveNestedEnds(); 2271 } 2272 2273 // First, check the extension directive map to see if any extension has 2274 // registered itself to parse this directive. 2275 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler = 2276 ExtensionDirectiveMap.lookup(IDVal.lower()); 2277 if (Handler.first) 2278 return (*Handler.second)(Handler.first, IDVal, IDLoc); 2279 2280 // Next, let the target-specific assembly parser try. 2281 SMLoc StartTokLoc = getTok().getLoc(); 2282 bool TPDirectiveReturn = 2283 ID.is(AsmToken::Identifier) && getTargetParser().ParseDirective(ID); 2284 2285 if (hasPendingError()) 2286 return true; 2287 // Currently the return value should be true if we are 2288 // uninterested but as this is at odds with the standard parsing 2289 // convention (return true = error) we have instances of a parsed 2290 // directive that fails returning true as an error. Catch these 2291 // cases as best as possible errors here. 2292 if (TPDirectiveReturn && StartTokLoc != getTok().getLoc()) 2293 return true; 2294 // Return if we did some parsing or believe we succeeded. 2295 if (!TPDirectiveReturn || StartTokLoc != getTok().getLoc()) 2296 return false; 2297 2298 // Finally, if no one else is interested in this directive, it must be 2299 // generic and familiar to this class. 2300 switch (DirKind) { 2301 default: 2302 break; 2303 case DK_ASCII: 2304 return parseDirectiveAscii(IDVal, false); 2305 case DK_ASCIZ: 2306 case DK_STRING: 2307 return parseDirectiveAscii(IDVal, true); 2308 case DK_BYTE: 2309 case DK_SBYTE: 2310 case DK_DB: 2311 return parseDirectiveValue(IDVal, 1); 2312 case DK_WORD: 2313 case DK_SWORD: 2314 case DK_DW: 2315 return parseDirectiveValue(IDVal, 2); 2316 case DK_DWORD: 2317 case DK_SDWORD: 2318 case DK_DD: 2319 return parseDirectiveValue(IDVal, 4); 2320 case DK_FWORD: 2321 case DK_DF: 2322 return parseDirectiveValue(IDVal, 6); 2323 case DK_QWORD: 2324 case DK_SQWORD: 2325 case DK_DQ: 2326 return parseDirectiveValue(IDVal, 8); 2327 case DK_REAL4: 2328 return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle(), 4); 2329 case DK_REAL8: 2330 return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble(), 8); 2331 case DK_REAL10: 2332 return parseDirectiveRealValue(IDVal, APFloat::x87DoubleExtended(), 10); 2333 case DK_STRUCT: 2334 case DK_UNION: 2335 return parseDirectiveNestedStruct(IDVal, DirKind); 2336 case DK_ENDS: 2337 return parseDirectiveNestedEnds(); 2338 case DK_ALIGN: 2339 return parseDirectiveAlign(); 2340 case DK_EVEN: 2341 return parseDirectiveEven(); 2342 case DK_ORG: 2343 return parseDirectiveOrg(); 2344 case DK_EXTERN: 2345 eatToEndOfStatement(); // .extern is the default, ignore it. 2346 return false; 2347 case DK_PUBLIC: 2348 return parseDirectiveSymbolAttribute(MCSA_Global); 2349 case DK_COMM: 2350 return parseDirectiveComm(/*IsLocal=*/false); 2351 case DK_COMMENT: 2352 return parseDirectiveComment(IDLoc); 2353 case DK_INCLUDE: 2354 return parseDirectiveInclude(); 2355 case DK_REPEAT: 2356 return parseDirectiveRepeat(IDLoc, IDVal); 2357 case DK_WHILE: 2358 return parseDirectiveWhile(IDLoc); 2359 case DK_FOR: 2360 return parseDirectiveFor(IDLoc, IDVal); 2361 case DK_FORC: 2362 return parseDirectiveForc(IDLoc, IDVal); 2363 case DK_FILE: 2364 return parseDirectiveFile(IDLoc); 2365 case DK_LINE: 2366 return parseDirectiveLine(); 2367 case DK_LOC: 2368 return parseDirectiveLoc(); 2369 case DK_STABS: 2370 return parseDirectiveStabs(); 2371 case DK_CV_FILE: 2372 return parseDirectiveCVFile(); 2373 case DK_CV_FUNC_ID: 2374 return parseDirectiveCVFuncId(); 2375 case DK_CV_INLINE_SITE_ID: 2376 return parseDirectiveCVInlineSiteId(); 2377 case DK_CV_LOC: 2378 return parseDirectiveCVLoc(); 2379 case DK_CV_LINETABLE: 2380 return parseDirectiveCVLinetable(); 2381 case DK_CV_INLINE_LINETABLE: 2382 return parseDirectiveCVInlineLinetable(); 2383 case DK_CV_DEF_RANGE: 2384 return parseDirectiveCVDefRange(); 2385 case DK_CV_STRING: 2386 return parseDirectiveCVString(); 2387 case DK_CV_STRINGTABLE: 2388 return parseDirectiveCVStringTable(); 2389 case DK_CV_FILECHECKSUMS: 2390 return parseDirectiveCVFileChecksums(); 2391 case DK_CV_FILECHECKSUM_OFFSET: 2392 return parseDirectiveCVFileChecksumOffset(); 2393 case DK_CV_FPO_DATA: 2394 return parseDirectiveCVFPOData(); 2395 case DK_CFI_SECTIONS: 2396 return parseDirectiveCFISections(); 2397 case DK_CFI_STARTPROC: 2398 return parseDirectiveCFIStartProc(); 2399 case DK_CFI_ENDPROC: 2400 return parseDirectiveCFIEndProc(); 2401 case DK_CFI_DEF_CFA: 2402 return parseDirectiveCFIDefCfa(IDLoc); 2403 case DK_CFI_DEF_CFA_OFFSET: 2404 return parseDirectiveCFIDefCfaOffset(); 2405 case DK_CFI_ADJUST_CFA_OFFSET: 2406 return parseDirectiveCFIAdjustCfaOffset(); 2407 case DK_CFI_DEF_CFA_REGISTER: 2408 return parseDirectiveCFIDefCfaRegister(IDLoc); 2409 case DK_CFI_OFFSET: 2410 return parseDirectiveCFIOffset(IDLoc); 2411 case DK_CFI_REL_OFFSET: 2412 return parseDirectiveCFIRelOffset(IDLoc); 2413 case DK_CFI_PERSONALITY: 2414 return parseDirectiveCFIPersonalityOrLsda(true); 2415 case DK_CFI_LSDA: 2416 return parseDirectiveCFIPersonalityOrLsda(false); 2417 case DK_CFI_REMEMBER_STATE: 2418 return parseDirectiveCFIRememberState(); 2419 case DK_CFI_RESTORE_STATE: 2420 return parseDirectiveCFIRestoreState(); 2421 case DK_CFI_SAME_VALUE: 2422 return parseDirectiveCFISameValue(IDLoc); 2423 case DK_CFI_RESTORE: 2424 return parseDirectiveCFIRestore(IDLoc); 2425 case DK_CFI_ESCAPE: 2426 return parseDirectiveCFIEscape(); 2427 case DK_CFI_RETURN_COLUMN: 2428 return parseDirectiveCFIReturnColumn(IDLoc); 2429 case DK_CFI_SIGNAL_FRAME: 2430 return parseDirectiveCFISignalFrame(); 2431 case DK_CFI_UNDEFINED: 2432 return parseDirectiveCFIUndefined(IDLoc); 2433 case DK_CFI_REGISTER: 2434 return parseDirectiveCFIRegister(IDLoc); 2435 case DK_CFI_WINDOW_SAVE: 2436 return parseDirectiveCFIWindowSave(); 2437 case DK_EXITM: 2438 Info.ExitValue = ""; 2439 return parseDirectiveExitMacro(IDLoc, IDVal, *Info.ExitValue); 2440 case DK_ENDM: 2441 Info.ExitValue = ""; 2442 return parseDirectiveEndMacro(IDVal); 2443 case DK_PURGE: 2444 return parseDirectivePurgeMacro(IDLoc); 2445 case DK_END: 2446 return parseDirectiveEnd(IDLoc); 2447 case DK_ERR: 2448 return parseDirectiveError(IDLoc); 2449 case DK_ERRB: 2450 return parseDirectiveErrorIfb(IDLoc, true); 2451 case DK_ERRNB: 2452 return parseDirectiveErrorIfb(IDLoc, false); 2453 case DK_ERRDEF: 2454 return parseDirectiveErrorIfdef(IDLoc, true); 2455 case DK_ERRNDEF: 2456 return parseDirectiveErrorIfdef(IDLoc, false); 2457 case DK_ERRDIF: 2458 return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/false, 2459 /*CaseInsensitive=*/false); 2460 case DK_ERRDIFI: 2461 return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/false, 2462 /*CaseInsensitive=*/true); 2463 case DK_ERRIDN: 2464 return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/true, 2465 /*CaseInsensitive=*/false); 2466 case DK_ERRIDNI: 2467 return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/true, 2468 /*CaseInsensitive=*/true); 2469 case DK_ERRE: 2470 return parseDirectiveErrorIfe(IDLoc, true); 2471 case DK_ERRNZ: 2472 return parseDirectiveErrorIfe(IDLoc, false); 2473 case DK_RADIX: 2474 return parseDirectiveRadix(IDLoc); 2475 } 2476 2477 return Error(IDLoc, "unknown directive"); 2478 } 2479 2480 // We also check if this is allocating memory with user-defined type. 2481 auto IDIt = Structs.find(IDVal.lower()); 2482 if (IDIt != Structs.end()) 2483 return parseDirectiveStructValue(/*Structure=*/IDIt->getValue(), IDVal, 2484 IDLoc); 2485 2486 // Non-conditional Microsoft directives sometimes follow their first argument. 2487 const AsmToken nextTok = getTok(); 2488 const StringRef nextVal = nextTok.getString(); 2489 const SMLoc nextLoc = nextTok.getLoc(); 2490 2491 const AsmToken afterNextTok = peekTok(); 2492 2493 // There are several entities interested in parsing infix directives: 2494 // 2495 // 1. Asm parser extensions. For example, platform-specific parsers 2496 // (like the ELF parser) register themselves as extensions. 2497 // 2. The generic directive parser implemented by this class. These are 2498 // all the directives that behave in a target and platform independent 2499 // manner, or at least have a default behavior that's shared between 2500 // all targets and platforms. 2501 2502 getTargetParser().flushPendingInstructions(getStreamer()); 2503 2504 // Special-case handling of structure-end directives at higher priority, since 2505 // ENDS is overloaded as a segment-end directive. 2506 if (nextVal.equals_insensitive("ends") && StructInProgress.size() == 1) { 2507 Lex(); 2508 return parseDirectiveEnds(IDVal, IDLoc); 2509 } 2510 2511 // First, check the extension directive map to see if any extension has 2512 // registered itself to parse this directive. 2513 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler = 2514 ExtensionDirectiveMap.lookup(nextVal.lower()); 2515 if (Handler.first) { 2516 Lex(); 2517 Lexer.UnLex(ID); 2518 return (*Handler.second)(Handler.first, nextVal, nextLoc); 2519 } 2520 2521 // If no one else is interested in this directive, it must be 2522 // generic and familiar to this class. 2523 DirKindIt = DirectiveKindMap.find(nextVal.lower()); 2524 DirKind = (DirKindIt == DirectiveKindMap.end()) 2525 ? DK_NO_DIRECTIVE 2526 : DirKindIt->getValue(); 2527 switch (DirKind) { 2528 default: 2529 break; 2530 case DK_ASSIGN: 2531 case DK_EQU: 2532 case DK_TEXTEQU: 2533 Lex(); 2534 return parseDirectiveEquate(nextVal, IDVal, DirKind, IDLoc); 2535 case DK_BYTE: 2536 if (afterNextTok.is(AsmToken::Identifier) && 2537 afterNextTok.getString().equals_insensitive("ptr")) { 2538 // Size directive; part of an instruction. 2539 break; 2540 } 2541 LLVM_FALLTHROUGH; 2542 case DK_SBYTE: 2543 case DK_DB: 2544 Lex(); 2545 return parseDirectiveNamedValue(nextVal, 1, IDVal, IDLoc); 2546 case DK_WORD: 2547 if (afterNextTok.is(AsmToken::Identifier) && 2548 afterNextTok.getString().equals_insensitive("ptr")) { 2549 // Size directive; part of an instruction. 2550 break; 2551 } 2552 LLVM_FALLTHROUGH; 2553 case DK_SWORD: 2554 case DK_DW: 2555 Lex(); 2556 return parseDirectiveNamedValue(nextVal, 2, IDVal, IDLoc); 2557 case DK_DWORD: 2558 if (afterNextTok.is(AsmToken::Identifier) && 2559 afterNextTok.getString().equals_insensitive("ptr")) { 2560 // Size directive; part of an instruction. 2561 break; 2562 } 2563 LLVM_FALLTHROUGH; 2564 case DK_SDWORD: 2565 case DK_DD: 2566 Lex(); 2567 return parseDirectiveNamedValue(nextVal, 4, IDVal, IDLoc); 2568 case DK_FWORD: 2569 if (afterNextTok.is(AsmToken::Identifier) && 2570 afterNextTok.getString().equals_insensitive("ptr")) { 2571 // Size directive; part of an instruction. 2572 break; 2573 } 2574 LLVM_FALLTHROUGH; 2575 case DK_DF: 2576 Lex(); 2577 return parseDirectiveNamedValue(nextVal, 6, IDVal, IDLoc); 2578 case DK_QWORD: 2579 if (afterNextTok.is(AsmToken::Identifier) && 2580 afterNextTok.getString().equals_insensitive("ptr")) { 2581 // Size directive; part of an instruction. 2582 break; 2583 } 2584 LLVM_FALLTHROUGH; 2585 case DK_SQWORD: 2586 case DK_DQ: 2587 Lex(); 2588 return parseDirectiveNamedValue(nextVal, 8, IDVal, IDLoc); 2589 case DK_REAL4: 2590 Lex(); 2591 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEsingle(), 4, 2592 IDVal, IDLoc); 2593 case DK_REAL8: 2594 Lex(); 2595 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEdouble(), 8, 2596 IDVal, IDLoc); 2597 case DK_REAL10: 2598 Lex(); 2599 return parseDirectiveNamedRealValue(nextVal, APFloat::x87DoubleExtended(), 2600 10, IDVal, IDLoc); 2601 case DK_STRUCT: 2602 case DK_UNION: 2603 Lex(); 2604 return parseDirectiveStruct(nextVal, DirKind, IDVal, IDLoc); 2605 case DK_ENDS: 2606 Lex(); 2607 return parseDirectiveEnds(IDVal, IDLoc); 2608 case DK_MACRO: 2609 Lex(); 2610 return parseDirectiveMacro(IDVal, IDLoc); 2611 } 2612 2613 // Finally, we check if this is allocating a variable with user-defined type. 2614 auto NextIt = Structs.find(nextVal.lower()); 2615 if (NextIt != Structs.end()) { 2616 Lex(); 2617 return parseDirectiveNamedStructValue(/*Structure=*/NextIt->getValue(), 2618 nextVal, nextLoc, IDVal); 2619 } 2620 2621 // __asm _emit or __asm __emit 2622 if (ParsingMSInlineAsm && (IDVal == "_emit" || IDVal == "__emit" || 2623 IDVal == "_EMIT" || IDVal == "__EMIT")) 2624 return parseDirectiveMSEmit(IDLoc, Info, IDVal.size()); 2625 2626 // __asm align 2627 if (ParsingMSInlineAsm && (IDVal == "align" || IDVal == "ALIGN")) 2628 return parseDirectiveMSAlign(IDLoc, Info); 2629 2630 if (ParsingMSInlineAsm && (IDVal == "even" || IDVal == "EVEN")) 2631 Info.AsmRewrites->emplace_back(AOK_EVEN, IDLoc, 4); 2632 if (checkForValidSection()) 2633 return true; 2634 2635 // Canonicalize the opcode to lower case. 2636 std::string OpcodeStr = IDVal.lower(); 2637 ParseInstructionInfo IInfo(Info.AsmRewrites); 2638 bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID, 2639 Info.ParsedOperands); 2640 Info.ParseError = ParseHadError; 2641 2642 // Dump the parsed representation, if requested. 2643 if (getShowParsedOperands()) { 2644 SmallString<256> Str; 2645 raw_svector_ostream OS(Str); 2646 OS << "parsed instruction: ["; 2647 for (unsigned i = 0; i != Info.ParsedOperands.size(); ++i) { 2648 if (i != 0) 2649 OS << ", "; 2650 Info.ParsedOperands[i]->print(OS); 2651 } 2652 OS << "]"; 2653 2654 printMessage(IDLoc, SourceMgr::DK_Note, OS.str()); 2655 } 2656 2657 // Fail even if ParseInstruction erroneously returns false. 2658 if (hasPendingError() || ParseHadError) 2659 return true; 2660 2661 // If we are generating dwarf for the current section then generate a .loc 2662 // directive for the instruction. 2663 if (!ParseHadError && enabledGenDwarfForAssembly() && 2664 getContext().getGenDwarfSectionSyms().count( 2665 getStreamer().getCurrentSectionOnly())) { 2666 unsigned Line; 2667 if (ActiveMacros.empty()) 2668 Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer); 2669 else 2670 Line = SrcMgr.FindLineNumber(ActiveMacros.front()->InstantiationLoc, 2671 ActiveMacros.front()->ExitBuffer); 2672 2673 // If we previously parsed a cpp hash file line comment then make sure the 2674 // current Dwarf File is for the CppHashFilename if not then emit the 2675 // Dwarf File table for it and adjust the line number for the .loc. 2676 if (!CppHashInfo.Filename.empty()) { 2677 unsigned FileNumber = getStreamer().emitDwarfFileDirective( 2678 0, StringRef(), CppHashInfo.Filename); 2679 getContext().setGenDwarfFileNumber(FileNumber); 2680 2681 unsigned CppHashLocLineNo = 2682 SrcMgr.FindLineNumber(CppHashInfo.Loc, CppHashInfo.Buf); 2683 Line = CppHashInfo.LineNumber - 1 + (Line - CppHashLocLineNo); 2684 } 2685 2686 getStreamer().emitDwarfLocDirective( 2687 getContext().getGenDwarfFileNumber(), Line, 0, 2688 DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0, 0, 0, 2689 StringRef()); 2690 } 2691 2692 // If parsing succeeded, match the instruction. 2693 if (!ParseHadError) { 2694 uint64_t ErrorInfo; 2695 if (getTargetParser().MatchAndEmitInstruction( 2696 IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo, 2697 getTargetParser().isParsingMSInlineAsm())) 2698 return true; 2699 } 2700 return false; 2701 } 2702 2703 // Parse and erase curly braces marking block start/end. 2704 bool MasmParser::parseCurlyBlockScope( 2705 SmallVectorImpl<AsmRewrite> &AsmStrRewrites) { 2706 // Identify curly brace marking block start/end. 2707 if (Lexer.isNot(AsmToken::LCurly) && Lexer.isNot(AsmToken::RCurly)) 2708 return false; 2709 2710 SMLoc StartLoc = Lexer.getLoc(); 2711 Lex(); // Eat the brace. 2712 if (Lexer.is(AsmToken::EndOfStatement)) 2713 Lex(); // Eat EndOfStatement following the brace. 2714 2715 // Erase the block start/end brace from the output asm string. 2716 AsmStrRewrites.emplace_back(AOK_Skip, StartLoc, Lexer.getLoc().getPointer() - 2717 StartLoc.getPointer()); 2718 return true; 2719 } 2720 2721 /// parseCppHashLineFilenameComment as this: 2722 /// ::= # number "filename" 2723 bool MasmParser::parseCppHashLineFilenameComment(SMLoc L) { 2724 Lex(); // Eat the hash token. 2725 // Lexer only ever emits HashDirective if it fully formed if it's 2726 // done the checking already so this is an internal error. 2727 assert(getTok().is(AsmToken::Integer) && 2728 "Lexing Cpp line comment: Expected Integer"); 2729 int64_t LineNumber = getTok().getIntVal(); 2730 Lex(); 2731 assert(getTok().is(AsmToken::String) && 2732 "Lexing Cpp line comment: Expected String"); 2733 StringRef Filename = getTok().getString(); 2734 Lex(); 2735 2736 // Get rid of the enclosing quotes. 2737 Filename = Filename.substr(1, Filename.size() - 2); 2738 2739 // Save the SMLoc, Filename and LineNumber for later use by diagnostics 2740 // and possibly DWARF file info. 2741 CppHashInfo.Loc = L; 2742 CppHashInfo.Filename = Filename; 2743 CppHashInfo.LineNumber = LineNumber; 2744 CppHashInfo.Buf = CurBuffer; 2745 if (FirstCppHashFilename.empty()) 2746 FirstCppHashFilename = Filename; 2747 return false; 2748 } 2749 2750 /// will use the last parsed cpp hash line filename comment 2751 /// for the Filename and LineNo if any in the diagnostic. 2752 void MasmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { 2753 const MasmParser *Parser = static_cast<const MasmParser *>(Context); 2754 raw_ostream &OS = errs(); 2755 2756 const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr(); 2757 SMLoc DiagLoc = Diag.getLoc(); 2758 unsigned DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); 2759 unsigned CppHashBuf = 2760 Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc); 2761 2762 // Like SourceMgr::printMessage() we need to print the include stack if any 2763 // before printing the message. 2764 unsigned DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); 2765 if (!Parser->SavedDiagHandler && DiagCurBuffer && 2766 DiagCurBuffer != DiagSrcMgr.getMainFileID()) { 2767 SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer); 2768 DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS); 2769 } 2770 2771 // If we have not parsed a cpp hash line filename comment or the source 2772 // manager changed or buffer changed (like in a nested include) then just 2773 // print the normal diagnostic using its Filename and LineNo. 2774 if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr || 2775 DiagBuf != CppHashBuf) { 2776 if (Parser->SavedDiagHandler) 2777 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext); 2778 else 2779 Diag.print(nullptr, OS); 2780 return; 2781 } 2782 2783 // Use the CppHashFilename and calculate a line number based on the 2784 // CppHashInfo.Loc and CppHashInfo.LineNumber relative to this Diag's SMLoc 2785 // for the diagnostic. 2786 const std::string &Filename = std::string(Parser->CppHashInfo.Filename); 2787 2788 int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf); 2789 int CppHashLocLineNo = 2790 Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf); 2791 int LineNo = 2792 Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo); 2793 2794 SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo, 2795 Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(), 2796 Diag.getLineContents(), Diag.getRanges()); 2797 2798 if (Parser->SavedDiagHandler) 2799 Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext); 2800 else 2801 NewDiag.print(nullptr, OS); 2802 } 2803 2804 // This is similar to the IsIdentifierChar function in AsmLexer.cpp, but does 2805 // not accept '.'. 2806 static bool isMacroParameterChar(char C) { 2807 return isAlnum(C) || C == '_' || C == '$' || C == '@' || C == '?'; 2808 } 2809 2810 bool MasmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, 2811 ArrayRef<MCAsmMacroParameter> Parameters, 2812 ArrayRef<MCAsmMacroArgument> A, 2813 const std::vector<std::string> &Locals, SMLoc L) { 2814 unsigned NParameters = Parameters.size(); 2815 if (NParameters != A.size()) 2816 return Error(L, "Wrong number of arguments"); 2817 StringMap<std::string> LocalSymbols; 2818 std::string Name; 2819 Name.reserve(6); 2820 for (StringRef Local : Locals) { 2821 raw_string_ostream LocalName(Name); 2822 LocalName << "??" 2823 << format_hex_no_prefix(LocalCounter++, 4, /*Upper=*/true); 2824 LocalSymbols.insert({Local, LocalName.str()}); 2825 Name.clear(); 2826 } 2827 2828 Optional<char> CurrentQuote; 2829 while (!Body.empty()) { 2830 // Scan for the next substitution. 2831 std::size_t End = Body.size(), Pos = 0; 2832 std::size_t IdentifierPos = End; 2833 for (; Pos != End; ++Pos) { 2834 // Find the next possible macro parameter, including preceding a '&' 2835 // inside quotes. 2836 if (Body[Pos] == '&') 2837 break; 2838 if (isMacroParameterChar(Body[Pos])) { 2839 if (!CurrentQuote.hasValue()) 2840 break; 2841 if (IdentifierPos == End) 2842 IdentifierPos = Pos; 2843 } else { 2844 IdentifierPos = End; 2845 } 2846 2847 // Track quotation status 2848 if (!CurrentQuote.hasValue()) { 2849 if (Body[Pos] == '\'' || Body[Pos] == '"') 2850 CurrentQuote = Body[Pos]; 2851 } else if (Body[Pos] == CurrentQuote) { 2852 if (Pos + 1 != End && Body[Pos + 1] == CurrentQuote) { 2853 // Escaped quote, and quotes aren't identifier chars; skip 2854 ++Pos; 2855 continue; 2856 } else { 2857 CurrentQuote.reset(); 2858 } 2859 } 2860 } 2861 if (IdentifierPos != End) { 2862 // We've recognized an identifier before an apostrophe inside quotes; 2863 // check once to see if we can expand it. 2864 Pos = IdentifierPos; 2865 IdentifierPos = End; 2866 } 2867 2868 // Add the prefix. 2869 OS << Body.slice(0, Pos); 2870 2871 // Check if we reached the end. 2872 if (Pos == End) 2873 break; 2874 2875 unsigned I = Pos; 2876 bool InitialAmpersand = (Body[I] == '&'); 2877 if (InitialAmpersand) { 2878 ++I; 2879 ++Pos; 2880 } 2881 while (I < End && isMacroParameterChar(Body[I])) 2882 ++I; 2883 2884 const char *Begin = Body.data() + Pos; 2885 StringRef Argument(Begin, I - Pos); 2886 unsigned Index = 0; 2887 2888 for (; Index < NParameters; ++Index) 2889 if (Parameters[Index].Name == Argument) 2890 break; 2891 2892 if (Index == NParameters) { 2893 if (InitialAmpersand) 2894 OS << '&'; 2895 auto it = LocalSymbols.find(Argument.lower()); 2896 if (it != LocalSymbols.end()) 2897 OS << it->second; 2898 else 2899 OS << Argument; 2900 Pos = I; 2901 } else { 2902 for (const AsmToken &Token : A[Index]) { 2903 // In MASM, you can write '%expr'. 2904 // The prefix '%' evaluates the expression 'expr' 2905 // and uses the result as a string (e.g. replace %(1+2) with the 2906 // string "3"). 2907 // Here, we identify the integer token which is the result of the 2908 // absolute expression evaluation and replace it with its string 2909 // representation. 2910 if (Token.getString().front() == '%' && Token.is(AsmToken::Integer)) 2911 // Emit an integer value to the buffer. 2912 OS << Token.getIntVal(); 2913 else 2914 OS << Token.getString(); 2915 } 2916 2917 Pos += Argument.size(); 2918 if (Pos < End && Body[Pos] == '&') { 2919 ++Pos; 2920 } 2921 } 2922 // Update the scan point. 2923 Body = Body.substr(Pos); 2924 } 2925 2926 return false; 2927 } 2928 2929 static bool isOperator(AsmToken::TokenKind kind) { 2930 switch (kind) { 2931 default: 2932 return false; 2933 case AsmToken::Plus: 2934 case AsmToken::Minus: 2935 case AsmToken::Tilde: 2936 case AsmToken::Slash: 2937 case AsmToken::Star: 2938 case AsmToken::Dot: 2939 case AsmToken::Equal: 2940 case AsmToken::EqualEqual: 2941 case AsmToken::Pipe: 2942 case AsmToken::PipePipe: 2943 case AsmToken::Caret: 2944 case AsmToken::Amp: 2945 case AsmToken::AmpAmp: 2946 case AsmToken::Exclaim: 2947 case AsmToken::ExclaimEqual: 2948 case AsmToken::Less: 2949 case AsmToken::LessEqual: 2950 case AsmToken::LessLess: 2951 case AsmToken::LessGreater: 2952 case AsmToken::Greater: 2953 case AsmToken::GreaterEqual: 2954 case AsmToken::GreaterGreater: 2955 return true; 2956 } 2957 } 2958 2959 namespace { 2960 2961 class AsmLexerSkipSpaceRAII { 2962 public: 2963 AsmLexerSkipSpaceRAII(AsmLexer &Lexer, bool SkipSpace) : Lexer(Lexer) { 2964 Lexer.setSkipSpace(SkipSpace); 2965 } 2966 2967 ~AsmLexerSkipSpaceRAII() { 2968 Lexer.setSkipSpace(true); 2969 } 2970 2971 private: 2972 AsmLexer &Lexer; 2973 }; 2974 2975 } // end anonymous namespace 2976 2977 bool MasmParser::parseMacroArgument(const MCAsmMacroParameter *MP, 2978 MCAsmMacroArgument &MA, 2979 AsmToken::TokenKind EndTok) { 2980 if (MP && MP->Vararg) { 2981 if (Lexer.isNot(EndTok)) { 2982 SmallVector<StringRef, 1> Str = parseStringRefsTo(EndTok); 2983 for (StringRef S : Str) { 2984 MA.emplace_back(AsmToken::String, S); 2985 } 2986 } 2987 return false; 2988 } 2989 2990 SMLoc StrLoc = Lexer.getLoc(), EndLoc; 2991 if (Lexer.is(AsmToken::Less) && isAngleBracketString(StrLoc, EndLoc)) { 2992 const char *StrChar = StrLoc.getPointer() + 1; 2993 const char *EndChar = EndLoc.getPointer() - 1; 2994 jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back()); 2995 /// Eat from '<' to '>'. 2996 Lex(); 2997 MA.emplace_back(AsmToken::String, StringRef(StrChar, EndChar - StrChar)); 2998 return false; 2999 } 3000 3001 unsigned ParenLevel = 0; 3002 3003 // Darwin doesn't use spaces to delmit arguments. 3004 AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin); 3005 3006 bool SpaceEaten; 3007 3008 while (true) { 3009 SpaceEaten = false; 3010 if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal)) 3011 return TokError("unexpected token"); 3012 3013 if (ParenLevel == 0) { 3014 if (Lexer.is(AsmToken::Comma)) 3015 break; 3016 3017 if (Lexer.is(AsmToken::Space)) { 3018 SpaceEaten = true; 3019 Lex(); // Eat spaces. 3020 } 3021 3022 // Spaces can delimit parameters, but could also be part an expression. 3023 // If the token after a space is an operator, add the token and the next 3024 // one into this argument 3025 if (!IsDarwin) { 3026 if (isOperator(Lexer.getKind()) && Lexer.isNot(EndTok)) { 3027 MA.push_back(getTok()); 3028 Lex(); 3029 3030 // Whitespace after an operator can be ignored. 3031 if (Lexer.is(AsmToken::Space)) 3032 Lex(); 3033 3034 continue; 3035 } 3036 } 3037 if (SpaceEaten) 3038 break; 3039 } 3040 3041 // handleMacroEntry relies on not advancing the lexer here 3042 // to be able to fill in the remaining default parameter values 3043 if (Lexer.is(EndTok) && (EndTok != AsmToken::RParen || ParenLevel == 0)) 3044 break; 3045 3046 // Adjust the current parentheses level. 3047 if (Lexer.is(AsmToken::LParen)) 3048 ++ParenLevel; 3049 else if (Lexer.is(AsmToken::RParen) && ParenLevel) 3050 --ParenLevel; 3051 3052 // Append the token to the current argument list. 3053 MA.push_back(getTok()); 3054 Lex(); 3055 } 3056 3057 if (ParenLevel != 0) 3058 return TokError("unbalanced parentheses in argument"); 3059 3060 if (MA.empty() && MP) { 3061 if (MP->Required) { 3062 return TokError("missing value for required parameter '" + MP->Name + 3063 "'"); 3064 } else { 3065 MA = MP->Value; 3066 } 3067 } 3068 return false; 3069 } 3070 3071 // Parse the macro instantiation arguments. 3072 bool MasmParser::parseMacroArguments(const MCAsmMacro *M, 3073 MCAsmMacroArguments &A, 3074 AsmToken::TokenKind EndTok) { 3075 const unsigned NParameters = M ? M->Parameters.size() : 0; 3076 bool NamedParametersFound = false; 3077 SmallVector<SMLoc, 4> FALocs; 3078 3079 A.resize(NParameters); 3080 FALocs.resize(NParameters); 3081 3082 // Parse two kinds of macro invocations: 3083 // - macros defined without any parameters accept an arbitrary number of them 3084 // - macros defined with parameters accept at most that many of them 3085 for (unsigned Parameter = 0; !NParameters || Parameter < NParameters; 3086 ++Parameter) { 3087 SMLoc IDLoc = Lexer.getLoc(); 3088 MCAsmMacroParameter FA; 3089 3090 if (Lexer.is(AsmToken::Identifier) && peekTok().is(AsmToken::Equal)) { 3091 if (parseIdentifier(FA.Name)) 3092 return Error(IDLoc, "invalid argument identifier for formal argument"); 3093 3094 if (Lexer.isNot(AsmToken::Equal)) 3095 return TokError("expected '=' after formal parameter identifier"); 3096 3097 Lex(); 3098 3099 NamedParametersFound = true; 3100 } 3101 3102 if (NamedParametersFound && FA.Name.empty()) 3103 return Error(IDLoc, "cannot mix positional and keyword arguments"); 3104 3105 unsigned PI = Parameter; 3106 if (!FA.Name.empty()) { 3107 assert(M && "expected macro to be defined"); 3108 unsigned FAI = 0; 3109 for (FAI = 0; FAI < NParameters; ++FAI) 3110 if (M->Parameters[FAI].Name == FA.Name) 3111 break; 3112 3113 if (FAI >= NParameters) { 3114 return Error(IDLoc, "parameter named '" + FA.Name + 3115 "' does not exist for macro '" + M->Name + "'"); 3116 } 3117 PI = FAI; 3118 } 3119 const MCAsmMacroParameter *MP = nullptr; 3120 if (M && PI < NParameters) 3121 MP = &M->Parameters[PI]; 3122 3123 SMLoc StrLoc = Lexer.getLoc(); 3124 SMLoc EndLoc; 3125 if (Lexer.is(AsmToken::Percent)) { 3126 const MCExpr *AbsoluteExp; 3127 int64_t Value; 3128 /// Eat '%'. 3129 Lex(); 3130 if (parseExpression(AbsoluteExp, EndLoc)) 3131 return false; 3132 if (!AbsoluteExp->evaluateAsAbsolute(Value, 3133 getStreamer().getAssemblerPtr())) 3134 return Error(StrLoc, "expected absolute expression"); 3135 const char *StrChar = StrLoc.getPointer(); 3136 const char *EndChar = EndLoc.getPointer(); 3137 AsmToken newToken(AsmToken::Integer, 3138 StringRef(StrChar, EndChar - StrChar), Value); 3139 FA.Value.push_back(newToken); 3140 } else if (parseMacroArgument(MP, FA.Value, EndTok)) { 3141 if (M) 3142 return addErrorSuffix(" in '" + M->Name + "' macro"); 3143 else 3144 return true; 3145 } 3146 3147 if (!FA.Value.empty()) { 3148 if (A.size() <= PI) 3149 A.resize(PI + 1); 3150 A[PI] = FA.Value; 3151 3152 if (FALocs.size() <= PI) 3153 FALocs.resize(PI + 1); 3154 3155 FALocs[PI] = Lexer.getLoc(); 3156 } 3157 3158 // At the end of the statement, fill in remaining arguments that have 3159 // default values. If there aren't any, then the next argument is 3160 // required but missing 3161 if (Lexer.is(EndTok)) { 3162 bool Failure = false; 3163 for (unsigned FAI = 0; FAI < NParameters; ++FAI) { 3164 if (A[FAI].empty()) { 3165 if (M->Parameters[FAI].Required) { 3166 Error(FALocs[FAI].isValid() ? FALocs[FAI] : Lexer.getLoc(), 3167 "missing value for required parameter " 3168 "'" + 3169 M->Parameters[FAI].Name + "' in macro '" + M->Name + "'"); 3170 Failure = true; 3171 } 3172 3173 if (!M->Parameters[FAI].Value.empty()) 3174 A[FAI] = M->Parameters[FAI].Value; 3175 } 3176 } 3177 return Failure; 3178 } 3179 3180 if (Lexer.is(AsmToken::Comma)) 3181 Lex(); 3182 } 3183 3184 return TokError("too many positional arguments"); 3185 } 3186 3187 bool MasmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc, 3188 AsmToken::TokenKind ArgumentEndTok) { 3189 // Arbitrarily limit macro nesting depth (default matches 'as'). We can 3190 // eliminate this, although we should protect against infinite loops. 3191 unsigned MaxNestingDepth = AsmMacroMaxNestingDepth; 3192 if (ActiveMacros.size() == MaxNestingDepth) { 3193 std::ostringstream MaxNestingDepthError; 3194 MaxNestingDepthError << "macros cannot be nested more than " 3195 << MaxNestingDepth << " levels deep." 3196 << " Use -asm-macro-max-nesting-depth to increase " 3197 "this limit."; 3198 return TokError(MaxNestingDepthError.str()); 3199 } 3200 3201 MCAsmMacroArguments A; 3202 if (parseMacroArguments(M, A, ArgumentEndTok)) 3203 return true; 3204 3205 // Macro instantiation is lexical, unfortunately. We construct a new buffer 3206 // to hold the macro body with substitutions. 3207 SmallString<256> Buf; 3208 StringRef Body = M->Body; 3209 raw_svector_ostream OS(Buf); 3210 3211 if (expandMacro(OS, Body, M->Parameters, A, M->Locals, getTok().getLoc())) 3212 return true; 3213 3214 // We include the endm in the buffer as our cue to exit the macro 3215 // instantiation. 3216 OS << "endm\n"; 3217 3218 std::unique_ptr<MemoryBuffer> Instantiation = 3219 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); 3220 3221 // Create the macro instantiation object and add to the current macro 3222 // instantiation stack. 3223 MacroInstantiation *MI = new MacroInstantiation{ 3224 NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()}; 3225 ActiveMacros.push_back(MI); 3226 3227 ++NumOfMacroInstantiations; 3228 3229 // Jump to the macro instantiation and prime the lexer. 3230 CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc()); 3231 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); 3232 EndStatementAtEOFStack.push_back(true); 3233 Lex(); 3234 3235 return false; 3236 } 3237 3238 void MasmParser::handleMacroExit() { 3239 // Jump to the token we should return to, and consume it. 3240 EndStatementAtEOFStack.pop_back(); 3241 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer, 3242 EndStatementAtEOFStack.back()); 3243 Lex(); 3244 3245 // Pop the instantiation entry. 3246 delete ActiveMacros.back(); 3247 ActiveMacros.pop_back(); 3248 } 3249 3250 bool MasmParser::handleMacroInvocation(const MCAsmMacro *M, SMLoc NameLoc) { 3251 if (!M->IsFunction) 3252 return Error(NameLoc, "cannot invoke macro procedure as function"); 3253 3254 if (parseToken(AsmToken::LParen, "invoking macro function '" + M->Name + 3255 "' requires arguments in parentheses") || 3256 handleMacroEntry(M, NameLoc, AsmToken::RParen)) 3257 return true; 3258 3259 // Parse all statements in the macro, retrieving the exit value when it ends. 3260 std::string ExitValue; 3261 SmallVector<AsmRewrite, 4> AsmStrRewrites; 3262 while (Lexer.isNot(AsmToken::Eof)) { 3263 ParseStatementInfo Info(&AsmStrRewrites); 3264 bool Parsed = parseStatement(Info, nullptr); 3265 3266 if (!Parsed && Info.ExitValue.hasValue()) { 3267 ExitValue = std::move(*Info.ExitValue); 3268 break; 3269 } 3270 3271 // If we have a Lexer Error we are on an Error Token. Load in Lexer Error 3272 // for printing ErrMsg via Lex() only if no (presumably better) parser error 3273 // exists. 3274 if (Parsed && !hasPendingError() && Lexer.getTok().is(AsmToken::Error)) { 3275 Lex(); 3276 } 3277 3278 // parseStatement returned true so may need to emit an error. 3279 printPendingErrors(); 3280 3281 // Skipping to the next line if needed. 3282 if (Parsed && !getLexer().isAtStartOfStatement()) 3283 eatToEndOfStatement(); 3284 } 3285 3286 // Consume the right-parenthesis on the other side of the arguments. 3287 if (parseToken(AsmToken::RParen, "invoking macro function '" + M->Name + 3288 "' requires arguments in parentheses")) 3289 return true; 3290 3291 // Exit values may require lexing, unfortunately. We construct a new buffer to 3292 // hold the exit value. 3293 std::unique_ptr<MemoryBuffer> MacroValue = 3294 MemoryBuffer::getMemBufferCopy(ExitValue, "<macro-value>"); 3295 3296 // Jump from this location to the instantiated exit value, and prime the 3297 // lexer. 3298 CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(MacroValue), Lexer.getLoc()); 3299 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(), nullptr, 3300 /*EndStatementAtEOF=*/false); 3301 EndStatementAtEOFStack.push_back(false); 3302 Lex(); 3303 3304 return false; 3305 } 3306 3307 /// parseIdentifier: 3308 /// ::= identifier 3309 /// ::= string 3310 bool MasmParser::parseIdentifier(StringRef &Res) { 3311 // The assembler has relaxed rules for accepting identifiers, in particular we 3312 // allow things like '.globl $foo' and '.def @feat.00', which would normally 3313 // be separate tokens. At this level, we have already lexed so we cannot 3314 // (currently) handle this as a context dependent token, instead we detect 3315 // adjacent tokens and return the combined identifier. 3316 if (Lexer.is(AsmToken::Dollar) || Lexer.is(AsmToken::At)) { 3317 SMLoc PrefixLoc = getLexer().getLoc(); 3318 3319 // Consume the prefix character, and check for a following identifier. 3320 3321 AsmToken nextTok = peekTok(false); 3322 3323 if (nextTok.isNot(AsmToken::Identifier)) 3324 return true; 3325 3326 // We have a '$' or '@' followed by an identifier, make sure they are adjacent. 3327 if (PrefixLoc.getPointer() + 1 != nextTok.getLoc().getPointer()) 3328 return true; 3329 3330 // eat $ or @ 3331 Lexer.Lex(); // Lexer's Lex guarantees consecutive token. 3332 // Construct the joined identifier and consume the token. 3333 Res = 3334 StringRef(PrefixLoc.getPointer(), getTok().getIdentifier().size() + 1); 3335 Lex(); // Parser Lex to maintain invariants. 3336 return false; 3337 } 3338 3339 if (Lexer.isNot(AsmToken::Identifier) && Lexer.isNot(AsmToken::String)) 3340 return true; 3341 3342 Res = getTok().getIdentifier(); 3343 3344 Lex(); // Consume the identifier token. 3345 3346 return false; 3347 } 3348 3349 /// parseDirectiveEquate: 3350 /// ::= name "=" expression 3351 /// | name "equ" expression (not redefinable) 3352 /// | name "equ" text-list 3353 /// | name "textequ" text-list (redefinability unspecified) 3354 bool MasmParser::parseDirectiveEquate(StringRef IDVal, StringRef Name, 3355 DirectiveKind DirKind, SMLoc NameLoc) { 3356 Variable &Var = Variables[Name.lower()]; 3357 if (Var.Name.empty()) { 3358 Var.Name = Name; 3359 } 3360 3361 SMLoc StartLoc = Lexer.getLoc(); 3362 if (DirKind == DK_EQU || DirKind == DK_TEXTEQU) { 3363 // "equ" and "textequ" both allow text expressions. 3364 std::string Value; 3365 std::string TextItem; 3366 if (!parseTextItem(TextItem)) { 3367 Value += TextItem; 3368 3369 // Accept a text-list, not just one text-item. 3370 auto parseItem = [&]() -> bool { 3371 if (parseTextItem(TextItem)) 3372 return TokError("expected text item"); 3373 Value += TextItem; 3374 return false; 3375 }; 3376 if (parseOptionalToken(AsmToken::Comma) && parseMany(parseItem)) 3377 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive"); 3378 3379 if (!Var.IsText || Var.TextValue != Value) { 3380 switch (Var.Redefinable) { 3381 case Variable::NOT_REDEFINABLE: 3382 return Error(getTok().getLoc(), "invalid variable redefinition"); 3383 case Variable::WARN_ON_REDEFINITION: 3384 if (Warning(NameLoc, "redefining '" + Name + 3385 "', already defined on the command line")) { 3386 return true; 3387 } 3388 break; 3389 default: 3390 break; 3391 } 3392 } 3393 Var.IsText = true; 3394 Var.TextValue = Value; 3395 Var.Redefinable = Variable::REDEFINABLE; 3396 3397 return false; 3398 } 3399 } 3400 if (DirKind == DK_TEXTEQU) 3401 return TokError("expected <text> in '" + Twine(IDVal) + "' directive"); 3402 3403 // Parse as expression assignment. 3404 const MCExpr *Expr; 3405 SMLoc EndLoc; 3406 if (parseExpression(Expr, EndLoc)) 3407 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive"); 3408 3409 int64_t Value; 3410 if (!Expr->evaluateAsAbsolute(Value, getStreamer().getAssemblerPtr())) { 3411 // Not an absolute expression; define as a text replacement. 3412 StringRef ExprAsString = StringRef( 3413 StartLoc.getPointer(), EndLoc.getPointer() - StartLoc.getPointer()); 3414 if (!Var.IsText || Var.TextValue != ExprAsString) { 3415 switch (Var.Redefinable) { 3416 case Variable::NOT_REDEFINABLE: 3417 return Error(getTok().getLoc(), "invalid variable redefinition"); 3418 case Variable::WARN_ON_REDEFINITION: 3419 if (Warning(NameLoc, "redefining '" + Name + 3420 "', already defined on the command line")) { 3421 return true; 3422 } 3423 break; 3424 default: 3425 break; 3426 } 3427 } 3428 Var.IsText = true; 3429 Var.TextValue = ExprAsString.str(); 3430 } else { 3431 if (Var.IsText || Var.NumericValue != Value) { 3432 switch (Var.Redefinable) { 3433 case Variable::NOT_REDEFINABLE: 3434 return Error(getTok().getLoc(), "invalid variable redefinition"); 3435 case Variable::WARN_ON_REDEFINITION: 3436 if (Warning(NameLoc, "redefining '" + Name + 3437 "', already defined on the command line")) { 3438 return true; 3439 } 3440 break; 3441 default: 3442 break; 3443 } 3444 } 3445 Var.NumericValue = Value; 3446 } 3447 Var.Redefinable = (DirKind == DK_ASSIGN) ? Variable::REDEFINABLE 3448 : Variable::NOT_REDEFINABLE; 3449 3450 MCSymbol *Sym = getContext().getOrCreateSymbol(Var.Name); 3451 Sym->setRedefinable(Var.Redefinable != Variable::NOT_REDEFINABLE); 3452 Sym->setVariableValue(Expr); 3453 Sym->setExternal(false); 3454 3455 return false; 3456 } 3457 3458 bool MasmParser::parseEscapedString(std::string &Data) { 3459 if (check(getTok().isNot(AsmToken::String), "expected string")) 3460 return true; 3461 3462 Data = ""; 3463 char Quote = getTok().getString().front(); 3464 StringRef Str = getTok().getStringContents(); 3465 Data.reserve(Str.size()); 3466 for (size_t i = 0, e = Str.size(); i != e; ++i) { 3467 Data.push_back(Str[i]); 3468 if (Str[i] == Quote) { 3469 // MASM treats doubled delimiting quotes as an escaped delimiting quote. 3470 // If we're escaping the string's trailing delimiter, we're definitely 3471 // missing a quotation mark. 3472 if (i + 1 == Str.size()) 3473 return Error(getTok().getLoc(), "missing quotation mark in string"); 3474 if (Str[i + 1] == Quote) 3475 ++i; 3476 } 3477 } 3478 3479 Lex(); 3480 return false; 3481 } 3482 3483 bool MasmParser::parseAngleBracketString(std::string &Data) { 3484 SMLoc EndLoc, StartLoc = getTok().getLoc(); 3485 if (isAngleBracketString(StartLoc, EndLoc)) { 3486 const char *StartChar = StartLoc.getPointer() + 1; 3487 const char *EndChar = EndLoc.getPointer() - 1; 3488 jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back()); 3489 // Eat from '<' to '>'. 3490 Lex(); 3491 3492 Data = angleBracketString(StringRef(StartChar, EndChar - StartChar)); 3493 return false; 3494 } 3495 return true; 3496 } 3497 3498 /// textItem ::= textLiteral | textMacroID | % constExpr 3499 bool MasmParser::parseTextItem(std::string &Data) { 3500 switch (getTok().getKind()) { 3501 default: 3502 return true; 3503 case AsmToken::Percent: { 3504 int64_t Res; 3505 if (parseToken(AsmToken::Percent) || parseAbsoluteExpression(Res)) 3506 return true; 3507 Data = std::to_string(Res); 3508 return false; 3509 } 3510 case AsmToken::Less: 3511 case AsmToken::LessEqual: 3512 case AsmToken::LessLess: 3513 case AsmToken::LessGreater: 3514 return parseAngleBracketString(Data); 3515 case AsmToken::Identifier: { 3516 // This must be a text macro; we need to expand it accordingly. 3517 StringRef ID; 3518 if (parseIdentifier(ID)) 3519 return true; 3520 Data = ID.str(); 3521 3522 auto it = Variables.find(ID.lower()); 3523 if (it == Variables.end()) { 3524 // Not a variable; since we haven't used the token, put it back for better 3525 // error recovery. 3526 getLexer().UnLex(AsmToken(AsmToken::Identifier, ID)); 3527 return true; 3528 } 3529 3530 while (it != Variables.end()) { 3531 const Variable &Var = it->second; 3532 if (!Var.IsText) { 3533 // Not a text macro; not usable in TextItem context. Since we haven't 3534 // used the token, put it back for better error recovery. 3535 getLexer().UnLex(AsmToken(AsmToken::Identifier, ID)); 3536 return true; 3537 } 3538 Data = Var.TextValue; 3539 it = Variables.find(StringRef(Data).lower()); 3540 } 3541 return false; 3542 } 3543 } 3544 llvm_unreachable("unhandled token kind"); 3545 } 3546 3547 /// parseDirectiveAscii: 3548 /// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ] 3549 bool MasmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) { 3550 auto parseOp = [&]() -> bool { 3551 std::string Data; 3552 if (checkForValidSection() || parseEscapedString(Data)) 3553 return true; 3554 getStreamer().emitBytes(Data); 3555 if (ZeroTerminated) 3556 getStreamer().emitBytes(StringRef("\0", 1)); 3557 return false; 3558 }; 3559 3560 if (parseMany(parseOp)) 3561 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive"); 3562 return false; 3563 } 3564 3565 bool MasmParser::emitIntValue(const MCExpr *Value, unsigned Size) { 3566 // Special case constant expressions to match code generator. 3567 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 3568 assert(Size <= 8 && "Invalid size"); 3569 int64_t IntValue = MCE->getValue(); 3570 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue)) 3571 return Error(MCE->getLoc(), "out of range literal value"); 3572 getStreamer().emitIntValue(IntValue, Size); 3573 } else { 3574 const MCSymbolRefExpr *MSE = dyn_cast<MCSymbolRefExpr>(Value); 3575 if (MSE && MSE->getSymbol().getName() == "?") { 3576 // ? initializer; treat as 0. 3577 getStreamer().emitIntValue(0, Size); 3578 } else { 3579 getStreamer().emitValue(Value, Size, Value->getLoc()); 3580 } 3581 } 3582 return false; 3583 } 3584 3585 bool MasmParser::parseScalarInitializer(unsigned Size, 3586 SmallVectorImpl<const MCExpr *> &Values, 3587 unsigned StringPadLength) { 3588 if (Size == 1 && getTok().is(AsmToken::String)) { 3589 std::string Value; 3590 if (parseEscapedString(Value)) 3591 return true; 3592 // Treat each character as an initializer. 3593 for (const unsigned char CharVal : Value) 3594 Values.push_back(MCConstantExpr::create(CharVal, getContext())); 3595 3596 // Pad the string with spaces to the specified length. 3597 for (size_t i = Value.size(); i < StringPadLength; ++i) 3598 Values.push_back(MCConstantExpr::create(' ', getContext())); 3599 } else { 3600 const MCExpr *Value; 3601 if (parseExpression(Value)) 3602 return true; 3603 if (getTok().is(AsmToken::Identifier) && 3604 getTok().getString().equals_insensitive("dup")) { 3605 Lex(); // Eat 'dup'. 3606 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 3607 if (!MCE) 3608 return Error(Value->getLoc(), 3609 "cannot repeat value a non-constant number of times"); 3610 const int64_t Repetitions = MCE->getValue(); 3611 if (Repetitions < 0) 3612 return Error(Value->getLoc(), 3613 "cannot repeat value a negative number of times"); 3614 3615 SmallVector<const MCExpr *, 1> DuplicatedValues; 3616 if (parseToken(AsmToken::LParen, 3617 "parentheses required for 'dup' contents") || 3618 parseScalarInstList(Size, DuplicatedValues) || 3619 parseToken(AsmToken::RParen, "unmatched parentheses")) 3620 return true; 3621 3622 for (int i = 0; i < Repetitions; ++i) 3623 Values.append(DuplicatedValues.begin(), DuplicatedValues.end()); 3624 } else { 3625 Values.push_back(Value); 3626 } 3627 } 3628 return false; 3629 } 3630 3631 bool MasmParser::parseScalarInstList(unsigned Size, 3632 SmallVectorImpl<const MCExpr *> &Values, 3633 const AsmToken::TokenKind EndToken) { 3634 while (getTok().isNot(EndToken) && 3635 (EndToken != AsmToken::Greater || 3636 getTok().isNot(AsmToken::GreaterGreater))) { 3637 parseScalarInitializer(Size, Values); 3638 3639 // If we see a comma, continue, and allow line continuation. 3640 if (!parseOptionalToken(AsmToken::Comma)) 3641 break; 3642 parseOptionalToken(AsmToken::EndOfStatement); 3643 } 3644 return false; 3645 } 3646 3647 bool MasmParser::emitIntegralValues(unsigned Size, unsigned *Count) { 3648 SmallVector<const MCExpr *, 1> Values; 3649 if (checkForValidSection() || parseScalarInstList(Size, Values)) 3650 return true; 3651 3652 for (auto Value : Values) { 3653 emitIntValue(Value, Size); 3654 } 3655 if (Count) 3656 *Count = Values.size(); 3657 return false; 3658 } 3659 3660 // Add a field to the current structure. 3661 bool MasmParser::addIntegralField(StringRef Name, unsigned Size) { 3662 StructInfo &Struct = StructInProgress.back(); 3663 FieldInfo &Field = Struct.addField(Name, FT_INTEGRAL, Size); 3664 IntFieldInfo &IntInfo = Field.Contents.IntInfo; 3665 3666 Field.Type = Size; 3667 3668 if (parseScalarInstList(Size, IntInfo.Values)) 3669 return true; 3670 3671 Field.SizeOf = Field.Type * IntInfo.Values.size(); 3672 Field.LengthOf = IntInfo.Values.size(); 3673 const unsigned FieldEnd = Field.Offset + Field.SizeOf; 3674 if (!Struct.IsUnion) { 3675 Struct.NextOffset = FieldEnd; 3676 } 3677 Struct.Size = std::max(Struct.Size, FieldEnd); 3678 return false; 3679 } 3680 3681 /// parseDirectiveValue 3682 /// ::= (byte | word | ... ) [ expression (, expression)* ] 3683 bool MasmParser::parseDirectiveValue(StringRef IDVal, unsigned Size) { 3684 if (StructInProgress.empty()) { 3685 // Initialize data value. 3686 if (emitIntegralValues(Size)) 3687 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive"); 3688 } else if (addIntegralField("", Size)) { 3689 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive"); 3690 } 3691 3692 return false; 3693 } 3694 3695 /// parseDirectiveNamedValue 3696 /// ::= name (byte | word | ... ) [ expression (, expression)* ] 3697 bool MasmParser::parseDirectiveNamedValue(StringRef TypeName, unsigned Size, 3698 StringRef Name, SMLoc NameLoc) { 3699 if (StructInProgress.empty()) { 3700 // Initialize named data value. 3701 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 3702 getStreamer().emitLabel(Sym); 3703 unsigned Count; 3704 if (emitIntegralValues(Size, &Count)) 3705 return addErrorSuffix(" in '" + Twine(TypeName) + "' directive"); 3706 3707 AsmTypeInfo Type; 3708 Type.Name = TypeName; 3709 Type.Size = Size * Count; 3710 Type.ElementSize = Size; 3711 Type.Length = Count; 3712 KnownType[Name.lower()] = Type; 3713 } else if (addIntegralField(Name, Size)) { 3714 return addErrorSuffix(" in '" + Twine(TypeName) + "' directive"); 3715 } 3716 3717 return false; 3718 } 3719 3720 static bool parseHexOcta(MasmParser &Asm, uint64_t &hi, uint64_t &lo) { 3721 if (Asm.getTok().isNot(AsmToken::Integer) && 3722 Asm.getTok().isNot(AsmToken::BigNum)) 3723 return Asm.TokError("unknown token in expression"); 3724 SMLoc ExprLoc = Asm.getTok().getLoc(); 3725 APInt IntValue = Asm.getTok().getAPIntVal(); 3726 Asm.Lex(); 3727 if (!IntValue.isIntN(128)) 3728 return Asm.Error(ExprLoc, "out of range literal value"); 3729 if (!IntValue.isIntN(64)) { 3730 hi = IntValue.getHiBits(IntValue.getBitWidth() - 64).getZExtValue(); 3731 lo = IntValue.getLoBits(64).getZExtValue(); 3732 } else { 3733 hi = 0; 3734 lo = IntValue.getZExtValue(); 3735 } 3736 return false; 3737 } 3738 3739 bool MasmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) { 3740 // We don't truly support arithmetic on floating point expressions, so we 3741 // have to manually parse unary prefixes. 3742 bool IsNeg = false; 3743 SMLoc SignLoc; 3744 if (getLexer().is(AsmToken::Minus)) { 3745 SignLoc = getLexer().getLoc(); 3746 Lexer.Lex(); 3747 IsNeg = true; 3748 } else if (getLexer().is(AsmToken::Plus)) { 3749 SignLoc = getLexer().getLoc(); 3750 Lexer.Lex(); 3751 } 3752 3753 if (Lexer.is(AsmToken::Error)) 3754 return TokError(Lexer.getErr()); 3755 if (Lexer.isNot(AsmToken::Integer) && Lexer.isNot(AsmToken::Real) && 3756 Lexer.isNot(AsmToken::Identifier)) 3757 return TokError("unexpected token in directive"); 3758 3759 // Convert to an APFloat. 3760 APFloat Value(Semantics); 3761 StringRef IDVal = getTok().getString(); 3762 if (getLexer().is(AsmToken::Identifier)) { 3763 if (IDVal.equals_insensitive("infinity") || IDVal.equals_insensitive("inf")) 3764 Value = APFloat::getInf(Semantics); 3765 else if (IDVal.equals_insensitive("nan")) 3766 Value = APFloat::getNaN(Semantics, false, ~0); 3767 else if (IDVal.equals_insensitive("?")) 3768 Value = APFloat::getZero(Semantics); 3769 else 3770 return TokError("invalid floating point literal"); 3771 } else if (IDVal.consume_back("r") || IDVal.consume_back("R")) { 3772 // MASM hexadecimal floating-point literal; no APFloat conversion needed. 3773 // To match ML64.exe, ignore the initial sign. 3774 unsigned SizeInBits = Value.getSizeInBits(Semantics); 3775 if (SizeInBits != (IDVal.size() << 2)) 3776 return TokError("invalid floating point literal"); 3777 3778 // Consume the numeric token. 3779 Lex(); 3780 3781 Res = APInt(SizeInBits, IDVal, 16); 3782 if (SignLoc.isValid()) 3783 return Warning(SignLoc, "MASM-style hex floats ignore explicit sign"); 3784 return false; 3785 } else if (errorToBool( 3786 Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) 3787 .takeError())) { 3788 return TokError("invalid floating point literal"); 3789 } 3790 if (IsNeg) 3791 Value.changeSign(); 3792 3793 // Consume the numeric token. 3794 Lex(); 3795 3796 Res = Value.bitcastToAPInt(); 3797 3798 return false; 3799 } 3800 3801 bool MasmParser::parseRealInstList(const fltSemantics &Semantics, 3802 SmallVectorImpl<APInt> &ValuesAsInt, 3803 const AsmToken::TokenKind EndToken) { 3804 while (getTok().isNot(EndToken) || 3805 (EndToken == AsmToken::Greater && 3806 getTok().isNot(AsmToken::GreaterGreater))) { 3807 const AsmToken NextTok = peekTok(); 3808 if (NextTok.is(AsmToken::Identifier) && 3809 NextTok.getString().equals_insensitive("dup")) { 3810 const MCExpr *Value; 3811 if (parseExpression(Value) || parseToken(AsmToken::Identifier)) 3812 return true; 3813 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 3814 if (!MCE) 3815 return Error(Value->getLoc(), 3816 "cannot repeat value a non-constant number of times"); 3817 const int64_t Repetitions = MCE->getValue(); 3818 if (Repetitions < 0) 3819 return Error(Value->getLoc(), 3820 "cannot repeat value a negative number of times"); 3821 3822 SmallVector<APInt, 1> DuplicatedValues; 3823 if (parseToken(AsmToken::LParen, 3824 "parentheses required for 'dup' contents") || 3825 parseRealInstList(Semantics, DuplicatedValues) || 3826 parseToken(AsmToken::RParen, "unmatched parentheses")) 3827 return true; 3828 3829 for (int i = 0; i < Repetitions; ++i) 3830 ValuesAsInt.append(DuplicatedValues.begin(), DuplicatedValues.end()); 3831 } else { 3832 APInt AsInt; 3833 if (parseRealValue(Semantics, AsInt)) 3834 return true; 3835 ValuesAsInt.push_back(AsInt); 3836 } 3837 3838 // Continue if we see a comma. (Also, allow line continuation.) 3839 if (!parseOptionalToken(AsmToken::Comma)) 3840 break; 3841 parseOptionalToken(AsmToken::EndOfStatement); 3842 } 3843 3844 return false; 3845 } 3846 3847 // Initialize real data values. 3848 bool MasmParser::emitRealValues(const fltSemantics &Semantics, 3849 unsigned *Count) { 3850 if (checkForValidSection()) 3851 return true; 3852 3853 SmallVector<APInt, 1> ValuesAsInt; 3854 if (parseRealInstList(Semantics, ValuesAsInt)) 3855 return true; 3856 3857 for (const APInt &AsInt : ValuesAsInt) { 3858 getStreamer().emitIntValue(AsInt); 3859 } 3860 if (Count) 3861 *Count = ValuesAsInt.size(); 3862 return false; 3863 } 3864 3865 // Add a real field to the current struct. 3866 bool MasmParser::addRealField(StringRef Name, const fltSemantics &Semantics, 3867 size_t Size) { 3868 StructInfo &Struct = StructInProgress.back(); 3869 FieldInfo &Field = Struct.addField(Name, FT_REAL, Size); 3870 RealFieldInfo &RealInfo = Field.Contents.RealInfo; 3871 3872 Field.SizeOf = 0; 3873 3874 if (parseRealInstList(Semantics, RealInfo.AsIntValues)) 3875 return true; 3876 3877 Field.Type = RealInfo.AsIntValues.back().getBitWidth() / 8; 3878 Field.LengthOf = RealInfo.AsIntValues.size(); 3879 Field.SizeOf = Field.Type * Field.LengthOf; 3880 3881 const unsigned FieldEnd = Field.Offset + Field.SizeOf; 3882 if (!Struct.IsUnion) { 3883 Struct.NextOffset = FieldEnd; 3884 } 3885 Struct.Size = std::max(Struct.Size, FieldEnd); 3886 return false; 3887 } 3888 3889 /// parseDirectiveRealValue 3890 /// ::= (real4 | real8 | real10) [ expression (, expression)* ] 3891 bool MasmParser::parseDirectiveRealValue(StringRef IDVal, 3892 const fltSemantics &Semantics, 3893 size_t Size) { 3894 if (StructInProgress.empty()) { 3895 // Initialize data value. 3896 if (emitRealValues(Semantics)) 3897 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive"); 3898 } else if (addRealField("", Semantics, Size)) { 3899 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive"); 3900 } 3901 return false; 3902 } 3903 3904 /// parseDirectiveNamedRealValue 3905 /// ::= name (real4 | real8 | real10) [ expression (, expression)* ] 3906 bool MasmParser::parseDirectiveNamedRealValue(StringRef TypeName, 3907 const fltSemantics &Semantics, 3908 unsigned Size, StringRef Name, 3909 SMLoc NameLoc) { 3910 if (StructInProgress.empty()) { 3911 // Initialize named data value. 3912 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 3913 getStreamer().emitLabel(Sym); 3914 unsigned Count; 3915 if (emitRealValues(Semantics, &Count)) 3916 return addErrorSuffix(" in '" + TypeName + "' directive"); 3917 3918 AsmTypeInfo Type; 3919 Type.Name = TypeName; 3920 Type.Size = Size * Count; 3921 Type.ElementSize = Size; 3922 Type.Length = Count; 3923 KnownType[Name.lower()] = Type; 3924 } else if (addRealField(Name, Semantics, Size)) { 3925 return addErrorSuffix(" in '" + TypeName + "' directive"); 3926 } 3927 return false; 3928 } 3929 3930 bool MasmParser::parseOptionalAngleBracketOpen() { 3931 const AsmToken Tok = getTok(); 3932 if (parseOptionalToken(AsmToken::LessLess)) { 3933 AngleBracketDepth++; 3934 Lexer.UnLex(AsmToken(AsmToken::Less, Tok.getString().substr(1))); 3935 return true; 3936 } else if (parseOptionalToken(AsmToken::LessGreater)) { 3937 AngleBracketDepth++; 3938 Lexer.UnLex(AsmToken(AsmToken::Greater, Tok.getString().substr(1))); 3939 return true; 3940 } else if (parseOptionalToken(AsmToken::Less)) { 3941 AngleBracketDepth++; 3942 return true; 3943 } 3944 3945 return false; 3946 } 3947 3948 bool MasmParser::parseAngleBracketClose(const Twine &Msg) { 3949 const AsmToken Tok = getTok(); 3950 if (parseOptionalToken(AsmToken::GreaterGreater)) { 3951 Lexer.UnLex(AsmToken(AsmToken::Greater, Tok.getString().substr(1))); 3952 } else if (parseToken(AsmToken::Greater, Msg)) { 3953 return true; 3954 } 3955 AngleBracketDepth--; 3956 return false; 3957 } 3958 3959 bool MasmParser::parseFieldInitializer(const FieldInfo &Field, 3960 const IntFieldInfo &Contents, 3961 FieldInitializer &Initializer) { 3962 SMLoc Loc = getTok().getLoc(); 3963 3964 SmallVector<const MCExpr *, 1> Values; 3965 if (parseOptionalToken(AsmToken::LCurly)) { 3966 if (Field.LengthOf == 1 && Field.Type > 1) 3967 return Error(Loc, "Cannot initialize scalar field with array value"); 3968 if (parseScalarInstList(Field.Type, Values, AsmToken::RCurly) || 3969 parseToken(AsmToken::RCurly)) 3970 return true; 3971 } else if (parseOptionalAngleBracketOpen()) { 3972 if (Field.LengthOf == 1 && Field.Type > 1) 3973 return Error(Loc, "Cannot initialize scalar field with array value"); 3974 if (parseScalarInstList(Field.Type, Values, AsmToken::Greater) || 3975 parseAngleBracketClose()) 3976 return true; 3977 } else if (Field.LengthOf > 1 && Field.Type > 1) { 3978 return Error(Loc, "Cannot initialize array field with scalar value"); 3979 } else if (parseScalarInitializer(Field.Type, Values, 3980 /*StringPadLength=*/Field.LengthOf)) { 3981 return true; 3982 } 3983 3984 if (Values.size() > Field.LengthOf) { 3985 return Error(Loc, "Initializer too long for field; expected at most " + 3986 std::to_string(Field.LengthOf) + " elements, got " + 3987 std::to_string(Values.size())); 3988 } 3989 // Default-initialize all remaining values. 3990 Values.append(Contents.Values.begin() + Values.size(), Contents.Values.end()); 3991 3992 Initializer = FieldInitializer(std::move(Values)); 3993 return false; 3994 } 3995 3996 bool MasmParser::parseFieldInitializer(const FieldInfo &Field, 3997 const RealFieldInfo &Contents, 3998 FieldInitializer &Initializer) { 3999 const fltSemantics *Semantics; 4000 switch (Field.Type) { 4001 case 4: 4002 Semantics = &APFloat::IEEEsingle(); 4003 break; 4004 case 8: 4005 Semantics = &APFloat::IEEEdouble(); 4006 break; 4007 case 10: 4008 Semantics = &APFloat::x87DoubleExtended(); 4009 break; 4010 default: 4011 llvm_unreachable("unknown real field type"); 4012 } 4013 4014 SMLoc Loc = getTok().getLoc(); 4015 4016 SmallVector<APInt, 1> AsIntValues; 4017 if (parseOptionalToken(AsmToken::LCurly)) { 4018 if (Field.LengthOf == 1) 4019 return Error(Loc, "Cannot initialize scalar field with array value"); 4020 if (parseRealInstList(*Semantics, AsIntValues, AsmToken::RCurly) || 4021 parseToken(AsmToken::RCurly)) 4022 return true; 4023 } else if (parseOptionalAngleBracketOpen()) { 4024 if (Field.LengthOf == 1) 4025 return Error(Loc, "Cannot initialize scalar field with array value"); 4026 if (parseRealInstList(*Semantics, AsIntValues, AsmToken::Greater) || 4027 parseAngleBracketClose()) 4028 return true; 4029 } else if (Field.LengthOf > 1) { 4030 return Error(Loc, "Cannot initialize array field with scalar value"); 4031 } else { 4032 AsIntValues.emplace_back(); 4033 if (parseRealValue(*Semantics, AsIntValues.back())) 4034 return true; 4035 } 4036 4037 if (AsIntValues.size() > Field.LengthOf) { 4038 return Error(Loc, "Initializer too long for field; expected at most " + 4039 std::to_string(Field.LengthOf) + " elements, got " + 4040 std::to_string(AsIntValues.size())); 4041 } 4042 // Default-initialize all remaining values. 4043 AsIntValues.append(Contents.AsIntValues.begin() + AsIntValues.size(), 4044 Contents.AsIntValues.end()); 4045 4046 Initializer = FieldInitializer(std::move(AsIntValues)); 4047 return false; 4048 } 4049 4050 bool MasmParser::parseFieldInitializer(const FieldInfo &Field, 4051 const StructFieldInfo &Contents, 4052 FieldInitializer &Initializer) { 4053 SMLoc Loc = getTok().getLoc(); 4054 4055 std::vector<StructInitializer> Initializers; 4056 if (Field.LengthOf > 1) { 4057 if (parseOptionalToken(AsmToken::LCurly)) { 4058 if (parseStructInstList(Contents.Structure, Initializers, 4059 AsmToken::RCurly) || 4060 parseToken(AsmToken::RCurly)) 4061 return true; 4062 } else if (parseOptionalAngleBracketOpen()) { 4063 if (parseStructInstList(Contents.Structure, Initializers, 4064 AsmToken::Greater) || 4065 parseAngleBracketClose()) 4066 return true; 4067 } else { 4068 return Error(Loc, "Cannot initialize array field with scalar value"); 4069 } 4070 } else { 4071 Initializers.emplace_back(); 4072 if (parseStructInitializer(Contents.Structure, Initializers.back())) 4073 return true; 4074 } 4075 4076 if (Initializers.size() > Field.LengthOf) { 4077 return Error(Loc, "Initializer too long for field; expected at most " + 4078 std::to_string(Field.LengthOf) + " elements, got " + 4079 std::to_string(Initializers.size())); 4080 } 4081 // Default-initialize all remaining values. 4082 Initializers.insert(Initializers.end(), 4083 Contents.Initializers.begin() + Initializers.size(), 4084 Contents.Initializers.end()); 4085 4086 Initializer = FieldInitializer(std::move(Initializers), Contents.Structure); 4087 return false; 4088 } 4089 4090 bool MasmParser::parseFieldInitializer(const FieldInfo &Field, 4091 FieldInitializer &Initializer) { 4092 switch (Field.Contents.FT) { 4093 case FT_INTEGRAL: 4094 return parseFieldInitializer(Field, Field.Contents.IntInfo, Initializer); 4095 case FT_REAL: 4096 return parseFieldInitializer(Field, Field.Contents.RealInfo, Initializer); 4097 case FT_STRUCT: 4098 return parseFieldInitializer(Field, Field.Contents.StructInfo, Initializer); 4099 } 4100 llvm_unreachable("Unhandled FieldType enum"); 4101 } 4102 4103 bool MasmParser::parseStructInitializer(const StructInfo &Structure, 4104 StructInitializer &Initializer) { 4105 const AsmToken FirstToken = getTok(); 4106 4107 Optional<AsmToken::TokenKind> EndToken; 4108 if (parseOptionalToken(AsmToken::LCurly)) { 4109 EndToken = AsmToken::RCurly; 4110 } else if (parseOptionalAngleBracketOpen()) { 4111 EndToken = AsmToken::Greater; 4112 AngleBracketDepth++; 4113 } else if (FirstToken.is(AsmToken::Identifier) && 4114 FirstToken.getString() == "?") { 4115 // ? initializer; leave EndToken uninitialized to treat as empty. 4116 if (parseToken(AsmToken::Identifier)) 4117 return true; 4118 } else { 4119 return Error(FirstToken.getLoc(), "Expected struct initializer"); 4120 } 4121 4122 auto &FieldInitializers = Initializer.FieldInitializers; 4123 size_t FieldIndex = 0; 4124 if (EndToken.hasValue()) { 4125 // Initialize all fields with given initializers. 4126 while (getTok().isNot(EndToken.getValue()) && 4127 FieldIndex < Structure.Fields.size()) { 4128 const FieldInfo &Field = Structure.Fields[FieldIndex++]; 4129 if (parseOptionalToken(AsmToken::Comma)) { 4130 // Empty initializer; use the default and continue. (Also, allow line 4131 // continuation.) 4132 FieldInitializers.push_back(Field.Contents); 4133 parseOptionalToken(AsmToken::EndOfStatement); 4134 continue; 4135 } 4136 FieldInitializers.emplace_back(Field.Contents.FT); 4137 if (parseFieldInitializer(Field, FieldInitializers.back())) 4138 return true; 4139 4140 // Continue if we see a comma. (Also, allow line continuation.) 4141 SMLoc CommaLoc = getTok().getLoc(); 4142 if (!parseOptionalToken(AsmToken::Comma)) 4143 break; 4144 if (FieldIndex == Structure.Fields.size()) 4145 return Error(CommaLoc, "'" + Structure.Name + 4146 "' initializer initializes too many fields"); 4147 parseOptionalToken(AsmToken::EndOfStatement); 4148 } 4149 } 4150 // Default-initialize all remaining fields. 4151 for (auto It = Structure.Fields.begin() + FieldIndex; 4152 It != Structure.Fields.end(); ++It) { 4153 const FieldInfo &Field = *It; 4154 FieldInitializers.push_back(Field.Contents); 4155 } 4156 4157 if (EndToken.hasValue()) { 4158 if (EndToken.getValue() == AsmToken::Greater) 4159 return parseAngleBracketClose(); 4160 4161 return parseToken(EndToken.getValue()); 4162 } 4163 4164 return false; 4165 } 4166 4167 bool MasmParser::parseStructInstList( 4168 const StructInfo &Structure, std::vector<StructInitializer> &Initializers, 4169 const AsmToken::TokenKind EndToken) { 4170 while (getTok().isNot(EndToken) || 4171 (EndToken == AsmToken::Greater && 4172 getTok().isNot(AsmToken::GreaterGreater))) { 4173 const AsmToken NextTok = peekTok(); 4174 if (NextTok.is(AsmToken::Identifier) && 4175 NextTok.getString().equals_insensitive("dup")) { 4176 const MCExpr *Value; 4177 if (parseExpression(Value) || parseToken(AsmToken::Identifier)) 4178 return true; 4179 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 4180 if (!MCE) 4181 return Error(Value->getLoc(), 4182 "cannot repeat value a non-constant number of times"); 4183 const int64_t Repetitions = MCE->getValue(); 4184 if (Repetitions < 0) 4185 return Error(Value->getLoc(), 4186 "cannot repeat value a negative number of times"); 4187 4188 std::vector<StructInitializer> DuplicatedValues; 4189 if (parseToken(AsmToken::LParen, 4190 "parentheses required for 'dup' contents") || 4191 parseStructInstList(Structure, DuplicatedValues) || 4192 parseToken(AsmToken::RParen, "unmatched parentheses")) 4193 return true; 4194 4195 for (int i = 0; i < Repetitions; ++i) 4196 llvm::append_range(Initializers, DuplicatedValues); 4197 } else { 4198 Initializers.emplace_back(); 4199 if (parseStructInitializer(Structure, Initializers.back())) 4200 return true; 4201 } 4202 4203 // Continue if we see a comma. (Also, allow line continuation.) 4204 if (!parseOptionalToken(AsmToken::Comma)) 4205 break; 4206 parseOptionalToken(AsmToken::EndOfStatement); 4207 } 4208 4209 return false; 4210 } 4211 4212 bool MasmParser::emitFieldValue(const FieldInfo &Field, 4213 const IntFieldInfo &Contents) { 4214 // Default-initialize all values. 4215 for (const MCExpr *Value : Contents.Values) { 4216 if (emitIntValue(Value, Field.Type)) 4217 return true; 4218 } 4219 return false; 4220 } 4221 4222 bool MasmParser::emitFieldValue(const FieldInfo &Field, 4223 const RealFieldInfo &Contents) { 4224 for (const APInt &AsInt : Contents.AsIntValues) { 4225 getStreamer().emitIntValue(AsInt.getLimitedValue(), 4226 AsInt.getBitWidth() / 8); 4227 } 4228 return false; 4229 } 4230 4231 bool MasmParser::emitFieldValue(const FieldInfo &Field, 4232 const StructFieldInfo &Contents) { 4233 for (const auto &Initializer : Contents.Initializers) { 4234 size_t Index = 0, Offset = 0; 4235 for (const auto &SubField : Contents.Structure.Fields) { 4236 getStreamer().emitZeros(SubField.Offset - Offset); 4237 Offset = SubField.Offset + SubField.SizeOf; 4238 emitFieldInitializer(SubField, Initializer.FieldInitializers[Index++]); 4239 } 4240 } 4241 return false; 4242 } 4243 4244 bool MasmParser::emitFieldValue(const FieldInfo &Field) { 4245 switch (Field.Contents.FT) { 4246 case FT_INTEGRAL: 4247 return emitFieldValue(Field, Field.Contents.IntInfo); 4248 case FT_REAL: 4249 return emitFieldValue(Field, Field.Contents.RealInfo); 4250 case FT_STRUCT: 4251 return emitFieldValue(Field, Field.Contents.StructInfo); 4252 } 4253 llvm_unreachable("Unhandled FieldType enum"); 4254 } 4255 4256 bool MasmParser::emitFieldInitializer(const FieldInfo &Field, 4257 const IntFieldInfo &Contents, 4258 const IntFieldInfo &Initializer) { 4259 for (const auto &Value : Initializer.Values) { 4260 if (emitIntValue(Value, Field.Type)) 4261 return true; 4262 } 4263 // Default-initialize all remaining values. 4264 for (auto it = Contents.Values.begin() + Initializer.Values.size(); 4265 it != Contents.Values.end(); ++it) { 4266 const auto &Value = *it; 4267 if (emitIntValue(Value, Field.Type)) 4268 return true; 4269 } 4270 return false; 4271 } 4272 4273 bool MasmParser::emitFieldInitializer(const FieldInfo &Field, 4274 const RealFieldInfo &Contents, 4275 const RealFieldInfo &Initializer) { 4276 for (const auto &AsInt : Initializer.AsIntValues) { 4277 getStreamer().emitIntValue(AsInt.getLimitedValue(), 4278 AsInt.getBitWidth() / 8); 4279 } 4280 // Default-initialize all remaining values. 4281 for (auto It = Contents.AsIntValues.begin() + Initializer.AsIntValues.size(); 4282 It != Contents.AsIntValues.end(); ++It) { 4283 const auto &AsInt = *It; 4284 getStreamer().emitIntValue(AsInt.getLimitedValue(), 4285 AsInt.getBitWidth() / 8); 4286 } 4287 return false; 4288 } 4289 4290 bool MasmParser::emitFieldInitializer(const FieldInfo &Field, 4291 const StructFieldInfo &Contents, 4292 const StructFieldInfo &Initializer) { 4293 for (const auto &Init : Initializer.Initializers) { 4294 if (emitStructInitializer(Contents.Structure, Init)) 4295 return true; 4296 } 4297 // Default-initialize all remaining values. 4298 for (auto It = 4299 Contents.Initializers.begin() + Initializer.Initializers.size(); 4300 It != Contents.Initializers.end(); ++It) { 4301 const auto &Init = *It; 4302 if (emitStructInitializer(Contents.Structure, Init)) 4303 return true; 4304 } 4305 return false; 4306 } 4307 4308 bool MasmParser::emitFieldInitializer(const FieldInfo &Field, 4309 const FieldInitializer &Initializer) { 4310 switch (Field.Contents.FT) { 4311 case FT_INTEGRAL: 4312 return emitFieldInitializer(Field, Field.Contents.IntInfo, 4313 Initializer.IntInfo); 4314 case FT_REAL: 4315 return emitFieldInitializer(Field, Field.Contents.RealInfo, 4316 Initializer.RealInfo); 4317 case FT_STRUCT: 4318 return emitFieldInitializer(Field, Field.Contents.StructInfo, 4319 Initializer.StructInfo); 4320 } 4321 llvm_unreachable("Unhandled FieldType enum"); 4322 } 4323 4324 bool MasmParser::emitStructInitializer(const StructInfo &Structure, 4325 const StructInitializer &Initializer) { 4326 if (!Structure.Initializable) 4327 return Error(getLexer().getLoc(), 4328 "cannot initialize a value of type '" + Structure.Name + 4329 "'; 'org' was used in the type's declaration"); 4330 size_t Index = 0, Offset = 0; 4331 for (const auto &Init : Initializer.FieldInitializers) { 4332 const auto &Field = Structure.Fields[Index++]; 4333 getStreamer().emitZeros(Field.Offset - Offset); 4334 Offset = Field.Offset + Field.SizeOf; 4335 if (emitFieldInitializer(Field, Init)) 4336 return true; 4337 } 4338 // Default-initialize all remaining fields. 4339 for (auto It = 4340 Structure.Fields.begin() + Initializer.FieldInitializers.size(); 4341 It != Structure.Fields.end(); ++It) { 4342 const auto &Field = *It; 4343 getStreamer().emitZeros(Field.Offset - Offset); 4344 Offset = Field.Offset + Field.SizeOf; 4345 if (emitFieldValue(Field)) 4346 return true; 4347 } 4348 // Add final padding. 4349 if (Offset != Structure.Size) 4350 getStreamer().emitZeros(Structure.Size - Offset); 4351 return false; 4352 } 4353 4354 // Set data values from initializers. 4355 bool MasmParser::emitStructValues(const StructInfo &Structure, 4356 unsigned *Count) { 4357 std::vector<StructInitializer> Initializers; 4358 if (parseStructInstList(Structure, Initializers)) 4359 return true; 4360 4361 for (const auto &Initializer : Initializers) { 4362 if (emitStructInitializer(Structure, Initializer)) 4363 return true; 4364 } 4365 4366 if (Count) 4367 *Count = Initializers.size(); 4368 return false; 4369 } 4370 4371 // Declare a field in the current struct. 4372 bool MasmParser::addStructField(StringRef Name, const StructInfo &Structure) { 4373 StructInfo &OwningStruct = StructInProgress.back(); 4374 FieldInfo &Field = 4375 OwningStruct.addField(Name, FT_STRUCT, Structure.AlignmentSize); 4376 StructFieldInfo &StructInfo = Field.Contents.StructInfo; 4377 4378 StructInfo.Structure = Structure; 4379 Field.Type = Structure.Size; 4380 4381 if (parseStructInstList(Structure, StructInfo.Initializers)) 4382 return true; 4383 4384 Field.LengthOf = StructInfo.Initializers.size(); 4385 Field.SizeOf = Field.Type * Field.LengthOf; 4386 4387 const unsigned FieldEnd = Field.Offset + Field.SizeOf; 4388 if (!OwningStruct.IsUnion) { 4389 OwningStruct.NextOffset = FieldEnd; 4390 } 4391 OwningStruct.Size = std::max(OwningStruct.Size, FieldEnd); 4392 4393 return false; 4394 } 4395 4396 /// parseDirectiveStructValue 4397 /// ::= struct-id (<struct-initializer> | {struct-initializer}) 4398 /// [, (<struct-initializer> | {struct-initializer})]* 4399 bool MasmParser::parseDirectiveStructValue(const StructInfo &Structure, 4400 StringRef Directive, SMLoc DirLoc) { 4401 if (StructInProgress.empty()) { 4402 if (emitStructValues(Structure)) 4403 return true; 4404 } else if (addStructField("", Structure)) { 4405 return addErrorSuffix(" in '" + Twine(Directive) + "' directive"); 4406 } 4407 4408 return false; 4409 } 4410 4411 /// parseDirectiveNamedValue 4412 /// ::= name (byte | word | ... ) [ expression (, expression)* ] 4413 bool MasmParser::parseDirectiveNamedStructValue(const StructInfo &Structure, 4414 StringRef Directive, 4415 SMLoc DirLoc, StringRef Name) { 4416 if (StructInProgress.empty()) { 4417 // Initialize named data value. 4418 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 4419 getStreamer().emitLabel(Sym); 4420 unsigned Count; 4421 if (emitStructValues(Structure, &Count)) 4422 return true; 4423 AsmTypeInfo Type; 4424 Type.Name = Structure.Name; 4425 Type.Size = Structure.Size * Count; 4426 Type.ElementSize = Structure.Size; 4427 Type.Length = Count; 4428 KnownType[Name.lower()] = Type; 4429 } else if (addStructField(Name, Structure)) { 4430 return addErrorSuffix(" in '" + Twine(Directive) + "' directive"); 4431 } 4432 4433 return false; 4434 } 4435 4436 /// parseDirectiveStruct 4437 /// ::= <name> (STRUC | STRUCT | UNION) [fieldAlign] [, NONUNIQUE] 4438 /// (dataDir | generalDir | offsetDir | nestedStruct)+ 4439 /// <name> ENDS 4440 ////// dataDir = data declaration 4441 ////// offsetDir = EVEN, ORG, ALIGN 4442 bool MasmParser::parseDirectiveStruct(StringRef Directive, 4443 DirectiveKind DirKind, StringRef Name, 4444 SMLoc NameLoc) { 4445 // We ignore NONUNIQUE; we do not support OPTION M510 or OPTION OLDSTRUCTS 4446 // anyway, so all field accesses must be qualified. 4447 AsmToken NextTok = getTok(); 4448 int64_t AlignmentValue = 1; 4449 if (NextTok.isNot(AsmToken::Comma) && 4450 NextTok.isNot(AsmToken::EndOfStatement) && 4451 parseAbsoluteExpression(AlignmentValue)) { 4452 return addErrorSuffix(" in alignment value for '" + Twine(Directive) + 4453 "' directive"); 4454 } 4455 if (!isPowerOf2_64(AlignmentValue)) { 4456 return Error(NextTok.getLoc(), "alignment must be a power of two; was " + 4457 std::to_string(AlignmentValue)); 4458 } 4459 4460 StringRef Qualifier; 4461 SMLoc QualifierLoc; 4462 if (parseOptionalToken(AsmToken::Comma)) { 4463 QualifierLoc = getTok().getLoc(); 4464 if (parseIdentifier(Qualifier)) 4465 return addErrorSuffix(" in '" + Twine(Directive) + "' directive"); 4466 if (!Qualifier.equals_insensitive("nonunique")) 4467 return Error(QualifierLoc, "Unrecognized qualifier for '" + 4468 Twine(Directive) + 4469 "' directive; expected none or NONUNIQUE"); 4470 } 4471 4472 if (parseToken(AsmToken::EndOfStatement)) 4473 return addErrorSuffix(" in '" + Twine(Directive) + "' directive"); 4474 4475 StructInProgress.emplace_back(Name, DirKind == DK_UNION, AlignmentValue); 4476 return false; 4477 } 4478 4479 /// parseDirectiveNestedStruct 4480 /// ::= (STRUC | STRUCT | UNION) [name] 4481 /// (dataDir | generalDir | offsetDir | nestedStruct)+ 4482 /// ENDS 4483 bool MasmParser::parseDirectiveNestedStruct(StringRef Directive, 4484 DirectiveKind DirKind) { 4485 if (StructInProgress.empty()) 4486 return TokError("missing name in top-level '" + Twine(Directive) + 4487 "' directive"); 4488 4489 StringRef Name; 4490 if (getTok().is(AsmToken::Identifier)) { 4491 Name = getTok().getIdentifier(); 4492 parseToken(AsmToken::Identifier); 4493 } 4494 if (parseToken(AsmToken::EndOfStatement)) 4495 return addErrorSuffix(" in '" + Twine(Directive) + "' directive"); 4496 4497 // Reserve space to ensure Alignment doesn't get invalidated when 4498 // StructInProgress grows. 4499 StructInProgress.reserve(StructInProgress.size() + 1); 4500 StructInProgress.emplace_back(Name, DirKind == DK_UNION, 4501 StructInProgress.back().Alignment); 4502 return false; 4503 } 4504 4505 bool MasmParser::parseDirectiveEnds(StringRef Name, SMLoc NameLoc) { 4506 if (StructInProgress.empty()) 4507 return Error(NameLoc, "ENDS directive without matching STRUC/STRUCT/UNION"); 4508 if (StructInProgress.size() > 1) 4509 return Error(NameLoc, "unexpected name in nested ENDS directive"); 4510 if (StructInProgress.back().Name.compare_insensitive(Name)) 4511 return Error(NameLoc, "mismatched name in ENDS directive; expected '" + 4512 StructInProgress.back().Name + "'"); 4513 StructInfo Structure = StructInProgress.pop_back_val(); 4514 // Pad to make the structure's size divisible by the smaller of its alignment 4515 // and the size of its largest field. 4516 Structure.Size = llvm::alignTo( 4517 Structure.Size, std::min(Structure.Alignment, Structure.AlignmentSize)); 4518 Structs[Name.lower()] = Structure; 4519 4520 if (parseToken(AsmToken::EndOfStatement)) 4521 return addErrorSuffix(" in ENDS directive"); 4522 4523 return false; 4524 } 4525 4526 bool MasmParser::parseDirectiveNestedEnds() { 4527 if (StructInProgress.empty()) 4528 return TokError("ENDS directive without matching STRUC/STRUCT/UNION"); 4529 if (StructInProgress.size() == 1) 4530 return TokError("missing name in top-level ENDS directive"); 4531 4532 if (parseToken(AsmToken::EndOfStatement)) 4533 return addErrorSuffix(" in nested ENDS directive"); 4534 4535 StructInfo Structure = StructInProgress.pop_back_val(); 4536 // Pad to make the structure's size divisible by its alignment. 4537 Structure.Size = llvm::alignTo(Structure.Size, Structure.Alignment); 4538 4539 StructInfo &ParentStruct = StructInProgress.back(); 4540 if (Structure.Name.empty()) { 4541 // Anonymous substructures' fields are addressed as if they belong to the 4542 // parent structure - so we transfer them to the parent here. 4543 const size_t OldFields = ParentStruct.Fields.size(); 4544 ParentStruct.Fields.insert( 4545 ParentStruct.Fields.end(), 4546 std::make_move_iterator(Structure.Fields.begin()), 4547 std::make_move_iterator(Structure.Fields.end())); 4548 for (const auto &FieldByName : Structure.FieldsByName) { 4549 ParentStruct.FieldsByName[FieldByName.getKey()] = 4550 FieldByName.getValue() + OldFields; 4551 } 4552 4553 unsigned FirstFieldOffset = 0; 4554 if (!Structure.Fields.empty() && !ParentStruct.IsUnion) { 4555 FirstFieldOffset = llvm::alignTo( 4556 ParentStruct.NextOffset, 4557 std::min(ParentStruct.Alignment, Structure.AlignmentSize)); 4558 } 4559 4560 if (ParentStruct.IsUnion) { 4561 ParentStruct.Size = std::max(ParentStruct.Size, Structure.Size); 4562 } else { 4563 for (auto FieldIter = ParentStruct.Fields.begin() + OldFields; 4564 FieldIter != ParentStruct.Fields.end(); ++FieldIter) { 4565 FieldIter->Offset += FirstFieldOffset; 4566 } 4567 4568 const unsigned StructureEnd = FirstFieldOffset + Structure.Size; 4569 if (!ParentStruct.IsUnion) { 4570 ParentStruct.NextOffset = StructureEnd; 4571 } 4572 ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd); 4573 } 4574 } else { 4575 FieldInfo &Field = ParentStruct.addField(Structure.Name, FT_STRUCT, 4576 Structure.AlignmentSize); 4577 StructFieldInfo &StructInfo = Field.Contents.StructInfo; 4578 Field.Type = Structure.Size; 4579 Field.LengthOf = 1; 4580 Field.SizeOf = Structure.Size; 4581 4582 const unsigned StructureEnd = Field.Offset + Field.SizeOf; 4583 if (!ParentStruct.IsUnion) { 4584 ParentStruct.NextOffset = StructureEnd; 4585 } 4586 ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd); 4587 4588 StructInfo.Structure = Structure; 4589 StructInfo.Initializers.emplace_back(); 4590 auto &FieldInitializers = StructInfo.Initializers.back().FieldInitializers; 4591 for (const auto &SubField : Structure.Fields) { 4592 FieldInitializers.push_back(SubField.Contents); 4593 } 4594 } 4595 4596 return false; 4597 } 4598 4599 /// parseDirectiveOrg 4600 /// ::= org expression 4601 bool MasmParser::parseDirectiveOrg() { 4602 const MCExpr *Offset; 4603 SMLoc OffsetLoc = Lexer.getLoc(); 4604 if (checkForValidSection() || parseExpression(Offset)) 4605 return true; 4606 if (parseToken(AsmToken::EndOfStatement)) 4607 return addErrorSuffix(" in 'org' directive"); 4608 4609 if (StructInProgress.empty()) { 4610 // Not in a struct; change the offset for the next instruction or data 4611 if (checkForValidSection()) 4612 return addErrorSuffix(" in 'org' directive"); 4613 4614 getStreamer().emitValueToOffset(Offset, 0, OffsetLoc); 4615 } else { 4616 // Offset the next field of this struct 4617 StructInfo &Structure = StructInProgress.back(); 4618 int64_t OffsetRes; 4619 if (!Offset->evaluateAsAbsolute(OffsetRes, getStreamer().getAssemblerPtr())) 4620 return Error(OffsetLoc, 4621 "expected absolute expression in 'org' directive"); 4622 if (OffsetRes < 0) 4623 return Error( 4624 OffsetLoc, 4625 "expected non-negative value in struct's 'org' directive; was " + 4626 std::to_string(OffsetRes)); 4627 Structure.NextOffset = static_cast<unsigned>(OffsetRes); 4628 4629 // ORG-affected structures cannot be initialized 4630 Structure.Initializable = false; 4631 } 4632 4633 return false; 4634 } 4635 4636 bool MasmParser::emitAlignTo(int64_t Alignment) { 4637 if (StructInProgress.empty()) { 4638 // Not in a struct; align the next instruction or data 4639 if (checkForValidSection()) 4640 return true; 4641 4642 // Check whether we should use optimal code alignment for this align 4643 // directive. 4644 const MCSection *Section = getStreamer().getCurrentSectionOnly(); 4645 assert(Section && "must have section to emit alignment"); 4646 if (Section->UseCodeAlign()) { 4647 getStreamer().emitCodeAlignment(Alignment, /*MaxBytesToEmit=*/0); 4648 } else { 4649 // FIXME: Target specific behavior about how the "extra" bytes are filled. 4650 getStreamer().emitValueToAlignment(Alignment, /*Value=*/0, 4651 /*ValueSize=*/1, 4652 /*MaxBytesToEmit=*/0); 4653 } 4654 } else { 4655 // Align the next field of this struct 4656 StructInfo &Structure = StructInProgress.back(); 4657 Structure.NextOffset = llvm::alignTo(Structure.NextOffset, Alignment); 4658 } 4659 4660 return false; 4661 } 4662 4663 /// parseDirectiveAlign 4664 /// ::= align expression 4665 bool MasmParser::parseDirectiveAlign() { 4666 SMLoc AlignmentLoc = getLexer().getLoc(); 4667 int64_t Alignment; 4668 4669 // Ignore empty 'align' directives. 4670 if (getTok().is(AsmToken::EndOfStatement)) { 4671 return Warning(AlignmentLoc, 4672 "align directive with no operand is ignored") && 4673 parseToken(AsmToken::EndOfStatement); 4674 } 4675 if (parseAbsoluteExpression(Alignment) || 4676 parseToken(AsmToken::EndOfStatement)) 4677 return addErrorSuffix(" in align directive"); 4678 4679 // Always emit an alignment here even if we throw an error. 4680 bool ReturnVal = false; 4681 4682 // Reject alignments that aren't either a power of two or zero, for ML.exe 4683 // compatibility. Alignment of zero is silently rounded up to one. 4684 if (Alignment == 0) 4685 Alignment = 1; 4686 if (!isPowerOf2_64(Alignment)) 4687 ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2; was " + 4688 std::to_string(Alignment)); 4689 4690 if (emitAlignTo(Alignment)) 4691 ReturnVal |= addErrorSuffix(" in align directive"); 4692 4693 return ReturnVal; 4694 } 4695 4696 /// parseDirectiveEven 4697 /// ::= even 4698 bool MasmParser::parseDirectiveEven() { 4699 if (parseToken(AsmToken::EndOfStatement) || emitAlignTo(2)) 4700 return addErrorSuffix(" in even directive"); 4701 4702 return false; 4703 } 4704 4705 /// parseDirectiveFile 4706 /// ::= .file filename 4707 /// ::= .file number [directory] filename [md5 checksum] [source source-text] 4708 bool MasmParser::parseDirectiveFile(SMLoc DirectiveLoc) { 4709 // FIXME: I'm not sure what this is. 4710 int64_t FileNumber = -1; 4711 if (getLexer().is(AsmToken::Integer)) { 4712 FileNumber = getTok().getIntVal(); 4713 Lex(); 4714 4715 if (FileNumber < 0) 4716 return TokError("negative file number"); 4717 } 4718 4719 std::string Path; 4720 4721 // Usually the directory and filename together, otherwise just the directory. 4722 // Allow the strings to have escaped octal character sequence. 4723 if (check(getTok().isNot(AsmToken::String), 4724 "unexpected token in '.file' directive") || 4725 parseEscapedString(Path)) 4726 return true; 4727 4728 StringRef Directory; 4729 StringRef Filename; 4730 std::string FilenameData; 4731 if (getLexer().is(AsmToken::String)) { 4732 if (check(FileNumber == -1, 4733 "explicit path specified, but no file number") || 4734 parseEscapedString(FilenameData)) 4735 return true; 4736 Filename = FilenameData; 4737 Directory = Path; 4738 } else { 4739 Filename = Path; 4740 } 4741 4742 uint64_t MD5Hi, MD5Lo; 4743 bool HasMD5 = false; 4744 4745 Optional<StringRef> Source; 4746 bool HasSource = false; 4747 std::string SourceString; 4748 4749 while (!parseOptionalToken(AsmToken::EndOfStatement)) { 4750 StringRef Keyword; 4751 if (check(getTok().isNot(AsmToken::Identifier), 4752 "unexpected token in '.file' directive") || 4753 parseIdentifier(Keyword)) 4754 return true; 4755 if (Keyword == "md5") { 4756 HasMD5 = true; 4757 if (check(FileNumber == -1, 4758 "MD5 checksum specified, but no file number") || 4759 parseHexOcta(*this, MD5Hi, MD5Lo)) 4760 return true; 4761 } else if (Keyword == "source") { 4762 HasSource = true; 4763 if (check(FileNumber == -1, 4764 "source specified, but no file number") || 4765 check(getTok().isNot(AsmToken::String), 4766 "unexpected token in '.file' directive") || 4767 parseEscapedString(SourceString)) 4768 return true; 4769 } else { 4770 return TokError("unexpected token in '.file' directive"); 4771 } 4772 } 4773 4774 if (FileNumber == -1) { 4775 // Ignore the directive if there is no number and the target doesn't support 4776 // numberless .file directives. This allows some portability of assembler 4777 // between different object file formats. 4778 if (getContext().getAsmInfo()->hasSingleParameterDotFile()) 4779 getStreamer().emitFileDirective(Filename); 4780 } else { 4781 // In case there is a -g option as well as debug info from directive .file, 4782 // we turn off the -g option, directly use the existing debug info instead. 4783 // Throw away any implicit file table for the assembler source. 4784 if (Ctx.getGenDwarfForAssembly()) { 4785 Ctx.getMCDwarfLineTable(0).resetFileTable(); 4786 Ctx.setGenDwarfForAssembly(false); 4787 } 4788 4789 Optional<MD5::MD5Result> CKMem; 4790 if (HasMD5) { 4791 MD5::MD5Result Sum; 4792 for (unsigned i = 0; i != 8; ++i) { 4793 Sum.Bytes[i] = uint8_t(MD5Hi >> ((7 - i) * 8)); 4794 Sum.Bytes[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8)); 4795 } 4796 CKMem = Sum; 4797 } 4798 if (HasSource) { 4799 char *SourceBuf = static_cast<char *>(Ctx.allocate(SourceString.size())); 4800 memcpy(SourceBuf, SourceString.data(), SourceString.size()); 4801 Source = StringRef(SourceBuf, SourceString.size()); 4802 } 4803 if (FileNumber == 0) { 4804 if (Ctx.getDwarfVersion() < 5) 4805 return Warning(DirectiveLoc, "file 0 not supported prior to DWARF-5"); 4806 getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source); 4807 } else { 4808 Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective( 4809 FileNumber, Directory, Filename, CKMem, Source); 4810 if (!FileNumOrErr) 4811 return Error(DirectiveLoc, toString(FileNumOrErr.takeError())); 4812 } 4813 // Alert the user if there are some .file directives with MD5 and some not. 4814 // But only do that once. 4815 if (!ReportedInconsistentMD5 && !Ctx.isDwarfMD5UsageConsistent(0)) { 4816 ReportedInconsistentMD5 = true; 4817 return Warning(DirectiveLoc, "inconsistent use of MD5 checksums"); 4818 } 4819 } 4820 4821 return false; 4822 } 4823 4824 /// parseDirectiveLine 4825 /// ::= .line [number] 4826 bool MasmParser::parseDirectiveLine() { 4827 int64_t LineNumber; 4828 if (getLexer().is(AsmToken::Integer)) { 4829 if (parseIntToken(LineNumber, "unexpected token in '.line' directive")) 4830 return true; 4831 (void)LineNumber; 4832 // FIXME: Do something with the .line. 4833 } 4834 if (parseToken(AsmToken::EndOfStatement, 4835 "unexpected token in '.line' directive")) 4836 return true; 4837 4838 return false; 4839 } 4840 4841 /// parseDirectiveLoc 4842 /// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end] 4843 /// [epilogue_begin] [is_stmt VALUE] [isa VALUE] 4844 /// The first number is a file number, must have been previously assigned with 4845 /// a .file directive, the second number is the line number and optionally the 4846 /// third number is a column position (zero if not specified). The remaining 4847 /// optional items are .loc sub-directives. 4848 bool MasmParser::parseDirectiveLoc() { 4849 int64_t FileNumber = 0, LineNumber = 0; 4850 SMLoc Loc = getTok().getLoc(); 4851 if (parseIntToken(FileNumber, "unexpected token in '.loc' directive") || 4852 check(FileNumber < 1 && Ctx.getDwarfVersion() < 5, Loc, 4853 "file number less than one in '.loc' directive") || 4854 check(!getContext().isValidDwarfFileNumber(FileNumber), Loc, 4855 "unassigned file number in '.loc' directive")) 4856 return true; 4857 4858 // optional 4859 if (getLexer().is(AsmToken::Integer)) { 4860 LineNumber = getTok().getIntVal(); 4861 if (LineNumber < 0) 4862 return TokError("line number less than zero in '.loc' directive"); 4863 Lex(); 4864 } 4865 4866 int64_t ColumnPos = 0; 4867 if (getLexer().is(AsmToken::Integer)) { 4868 ColumnPos = getTok().getIntVal(); 4869 if (ColumnPos < 0) 4870 return TokError("column position less than zero in '.loc' directive"); 4871 Lex(); 4872 } 4873 4874 auto PrevFlags = getContext().getCurrentDwarfLoc().getFlags(); 4875 unsigned Flags = PrevFlags & DWARF2_FLAG_IS_STMT; 4876 unsigned Isa = 0; 4877 int64_t Discriminator = 0; 4878 4879 auto parseLocOp = [&]() -> bool { 4880 StringRef Name; 4881 SMLoc Loc = getTok().getLoc(); 4882 if (parseIdentifier(Name)) 4883 return TokError("unexpected token in '.loc' directive"); 4884 4885 if (Name == "basic_block") 4886 Flags |= DWARF2_FLAG_BASIC_BLOCK; 4887 else if (Name == "prologue_end") 4888 Flags |= DWARF2_FLAG_PROLOGUE_END; 4889 else if (Name == "epilogue_begin") 4890 Flags |= DWARF2_FLAG_EPILOGUE_BEGIN; 4891 else if (Name == "is_stmt") { 4892 Loc = getTok().getLoc(); 4893 const MCExpr *Value; 4894 if (parseExpression(Value)) 4895 return true; 4896 // The expression must be the constant 0 or 1. 4897 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 4898 int Value = MCE->getValue(); 4899 if (Value == 0) 4900 Flags &= ~DWARF2_FLAG_IS_STMT; 4901 else if (Value == 1) 4902 Flags |= DWARF2_FLAG_IS_STMT; 4903 else 4904 return Error(Loc, "is_stmt value not 0 or 1"); 4905 } else { 4906 return Error(Loc, "is_stmt value not the constant value of 0 or 1"); 4907 } 4908 } else if (Name == "isa") { 4909 Loc = getTok().getLoc(); 4910 const MCExpr *Value; 4911 if (parseExpression(Value)) 4912 return true; 4913 // The expression must be a constant greater or equal to 0. 4914 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 4915 int Value = MCE->getValue(); 4916 if (Value < 0) 4917 return Error(Loc, "isa number less than zero"); 4918 Isa = Value; 4919 } else { 4920 return Error(Loc, "isa number not a constant value"); 4921 } 4922 } else if (Name == "discriminator") { 4923 if (parseAbsoluteExpression(Discriminator)) 4924 return true; 4925 } else { 4926 return Error(Loc, "unknown sub-directive in '.loc' directive"); 4927 } 4928 return false; 4929 }; 4930 4931 if (parseMany(parseLocOp, false /*hasComma*/)) 4932 return true; 4933 4934 getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags, 4935 Isa, Discriminator, StringRef()); 4936 4937 return false; 4938 } 4939 4940 /// parseDirectiveStabs 4941 /// ::= .stabs string, number, number, number 4942 bool MasmParser::parseDirectiveStabs() { 4943 return TokError("unsupported directive '.stabs'"); 4944 } 4945 4946 /// parseDirectiveCVFile 4947 /// ::= .cv_file number filename [checksum] [checksumkind] 4948 bool MasmParser::parseDirectiveCVFile() { 4949 SMLoc FileNumberLoc = getTok().getLoc(); 4950 int64_t FileNumber; 4951 std::string Filename; 4952 std::string Checksum; 4953 int64_t ChecksumKind = 0; 4954 4955 if (parseIntToken(FileNumber, 4956 "expected file number in '.cv_file' directive") || 4957 check(FileNumber < 1, FileNumberLoc, "file number less than one") || 4958 check(getTok().isNot(AsmToken::String), 4959 "unexpected token in '.cv_file' directive") || 4960 parseEscapedString(Filename)) 4961 return true; 4962 if (!parseOptionalToken(AsmToken::EndOfStatement)) { 4963 if (check(getTok().isNot(AsmToken::String), 4964 "unexpected token in '.cv_file' directive") || 4965 parseEscapedString(Checksum) || 4966 parseIntToken(ChecksumKind, 4967 "expected checksum kind in '.cv_file' directive") || 4968 parseToken(AsmToken::EndOfStatement, 4969 "unexpected token in '.cv_file' directive")) 4970 return true; 4971 } 4972 4973 Checksum = fromHex(Checksum); 4974 void *CKMem = Ctx.allocate(Checksum.size(), 1); 4975 memcpy(CKMem, Checksum.data(), Checksum.size()); 4976 ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem), 4977 Checksum.size()); 4978 4979 if (!getStreamer().EmitCVFileDirective(FileNumber, Filename, ChecksumAsBytes, 4980 static_cast<uint8_t>(ChecksumKind))) 4981 return Error(FileNumberLoc, "file number already allocated"); 4982 4983 return false; 4984 } 4985 4986 bool MasmParser::parseCVFunctionId(int64_t &FunctionId, 4987 StringRef DirectiveName) { 4988 SMLoc Loc; 4989 return parseTokenLoc(Loc) || 4990 parseIntToken(FunctionId, "expected function id in '" + DirectiveName + 4991 "' directive") || 4992 check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc, 4993 "expected function id within range [0, UINT_MAX)"); 4994 } 4995 4996 bool MasmParser::parseCVFileId(int64_t &FileNumber, StringRef DirectiveName) { 4997 SMLoc Loc; 4998 return parseTokenLoc(Loc) || 4999 parseIntToken(FileNumber, "expected integer in '" + DirectiveName + 5000 "' directive") || 5001 check(FileNumber < 1, Loc, "file number less than one in '" + 5002 DirectiveName + "' directive") || 5003 check(!getCVContext().isValidFileNumber(FileNumber), Loc, 5004 "unassigned file number in '" + DirectiveName + "' directive"); 5005 } 5006 5007 /// parseDirectiveCVFuncId 5008 /// ::= .cv_func_id FunctionId 5009 /// 5010 /// Introduces a function ID that can be used with .cv_loc. 5011 bool MasmParser::parseDirectiveCVFuncId() { 5012 SMLoc FunctionIdLoc = getTok().getLoc(); 5013 int64_t FunctionId; 5014 5015 if (parseCVFunctionId(FunctionId, ".cv_func_id") || 5016 parseToken(AsmToken::EndOfStatement, 5017 "unexpected token in '.cv_func_id' directive")) 5018 return true; 5019 5020 if (!getStreamer().EmitCVFuncIdDirective(FunctionId)) 5021 return Error(FunctionIdLoc, "function id already allocated"); 5022 5023 return false; 5024 } 5025 5026 /// parseDirectiveCVInlineSiteId 5027 /// ::= .cv_inline_site_id FunctionId 5028 /// "within" IAFunc 5029 /// "inlined_at" IAFile IALine [IACol] 5030 /// 5031 /// Introduces a function ID that can be used with .cv_loc. Includes "inlined 5032 /// at" source location information for use in the line table of the caller, 5033 /// whether the caller is a real function or another inlined call site. 5034 bool MasmParser::parseDirectiveCVInlineSiteId() { 5035 SMLoc FunctionIdLoc = getTok().getLoc(); 5036 int64_t FunctionId; 5037 int64_t IAFunc; 5038 int64_t IAFile; 5039 int64_t IALine; 5040 int64_t IACol = 0; 5041 5042 // FunctionId 5043 if (parseCVFunctionId(FunctionId, ".cv_inline_site_id")) 5044 return true; 5045 5046 // "within" 5047 if (check((getLexer().isNot(AsmToken::Identifier) || 5048 getTok().getIdentifier() != "within"), 5049 "expected 'within' identifier in '.cv_inline_site_id' directive")) 5050 return true; 5051 Lex(); 5052 5053 // IAFunc 5054 if (parseCVFunctionId(IAFunc, ".cv_inline_site_id")) 5055 return true; 5056 5057 // "inlined_at" 5058 if (check((getLexer().isNot(AsmToken::Identifier) || 5059 getTok().getIdentifier() != "inlined_at"), 5060 "expected 'inlined_at' identifier in '.cv_inline_site_id' " 5061 "directive") ) 5062 return true; 5063 Lex(); 5064 5065 // IAFile IALine 5066 if (parseCVFileId(IAFile, ".cv_inline_site_id") || 5067 parseIntToken(IALine, "expected line number after 'inlined_at'")) 5068 return true; 5069 5070 // [IACol] 5071 if (getLexer().is(AsmToken::Integer)) { 5072 IACol = getTok().getIntVal(); 5073 Lex(); 5074 } 5075 5076 if (parseToken(AsmToken::EndOfStatement, 5077 "unexpected token in '.cv_inline_site_id' directive")) 5078 return true; 5079 5080 if (!getStreamer().EmitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile, 5081 IALine, IACol, FunctionIdLoc)) 5082 return Error(FunctionIdLoc, "function id already allocated"); 5083 5084 return false; 5085 } 5086 5087 /// parseDirectiveCVLoc 5088 /// ::= .cv_loc FunctionId FileNumber [LineNumber] [ColumnPos] [prologue_end] 5089 /// [is_stmt VALUE] 5090 /// The first number is a file number, must have been previously assigned with 5091 /// a .file directive, the second number is the line number and optionally the 5092 /// third number is a column position (zero if not specified). The remaining 5093 /// optional items are .loc sub-directives. 5094 bool MasmParser::parseDirectiveCVLoc() { 5095 SMLoc DirectiveLoc = getTok().getLoc(); 5096 int64_t FunctionId, FileNumber; 5097 if (parseCVFunctionId(FunctionId, ".cv_loc") || 5098 parseCVFileId(FileNumber, ".cv_loc")) 5099 return true; 5100 5101 int64_t LineNumber = 0; 5102 if (getLexer().is(AsmToken::Integer)) { 5103 LineNumber = getTok().getIntVal(); 5104 if (LineNumber < 0) 5105 return TokError("line number less than zero in '.cv_loc' directive"); 5106 Lex(); 5107 } 5108 5109 int64_t ColumnPos = 0; 5110 if (getLexer().is(AsmToken::Integer)) { 5111 ColumnPos = getTok().getIntVal(); 5112 if (ColumnPos < 0) 5113 return TokError("column position less than zero in '.cv_loc' directive"); 5114 Lex(); 5115 } 5116 5117 bool PrologueEnd = false; 5118 uint64_t IsStmt = 0; 5119 5120 auto parseOp = [&]() -> bool { 5121 StringRef Name; 5122 SMLoc Loc = getTok().getLoc(); 5123 if (parseIdentifier(Name)) 5124 return TokError("unexpected token in '.cv_loc' directive"); 5125 if (Name == "prologue_end") 5126 PrologueEnd = true; 5127 else if (Name == "is_stmt") { 5128 Loc = getTok().getLoc(); 5129 const MCExpr *Value; 5130 if (parseExpression(Value)) 5131 return true; 5132 // The expression must be the constant 0 or 1. 5133 IsStmt = ~0ULL; 5134 if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) 5135 IsStmt = MCE->getValue(); 5136 5137 if (IsStmt > 1) 5138 return Error(Loc, "is_stmt value not 0 or 1"); 5139 } else { 5140 return Error(Loc, "unknown sub-directive in '.cv_loc' directive"); 5141 } 5142 return false; 5143 }; 5144 5145 if (parseMany(parseOp, false /*hasComma*/)) 5146 return true; 5147 5148 getStreamer().emitCVLocDirective(FunctionId, FileNumber, LineNumber, 5149 ColumnPos, PrologueEnd, IsStmt, StringRef(), 5150 DirectiveLoc); 5151 return false; 5152 } 5153 5154 /// parseDirectiveCVLinetable 5155 /// ::= .cv_linetable FunctionId, FnStart, FnEnd 5156 bool MasmParser::parseDirectiveCVLinetable() { 5157 int64_t FunctionId; 5158 StringRef FnStartName, FnEndName; 5159 SMLoc Loc = getTok().getLoc(); 5160 if (parseCVFunctionId(FunctionId, ".cv_linetable") || 5161 parseToken(AsmToken::Comma, 5162 "unexpected token in '.cv_linetable' directive") || 5163 parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc, 5164 "expected identifier in directive") || 5165 parseToken(AsmToken::Comma, 5166 "unexpected token in '.cv_linetable' directive") || 5167 parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc, 5168 "expected identifier in directive")) 5169 return true; 5170 5171 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName); 5172 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName); 5173 5174 getStreamer().emitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym); 5175 return false; 5176 } 5177 5178 /// parseDirectiveCVInlineLinetable 5179 /// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart FnEnd 5180 bool MasmParser::parseDirectiveCVInlineLinetable() { 5181 int64_t PrimaryFunctionId, SourceFileId, SourceLineNum; 5182 StringRef FnStartName, FnEndName; 5183 SMLoc Loc = getTok().getLoc(); 5184 if (parseCVFunctionId(PrimaryFunctionId, ".cv_inline_linetable") || 5185 parseTokenLoc(Loc) || 5186 parseIntToken( 5187 SourceFileId, 5188 "expected SourceField in '.cv_inline_linetable' directive") || 5189 check(SourceFileId <= 0, Loc, 5190 "File id less than zero in '.cv_inline_linetable' directive") || 5191 parseTokenLoc(Loc) || 5192 parseIntToken( 5193 SourceLineNum, 5194 "expected SourceLineNum in '.cv_inline_linetable' directive") || 5195 check(SourceLineNum < 0, Loc, 5196 "Line number less than zero in '.cv_inline_linetable' directive") || 5197 parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc, 5198 "expected identifier in directive") || 5199 parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc, 5200 "expected identifier in directive")) 5201 return true; 5202 5203 if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement")) 5204 return true; 5205 5206 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName); 5207 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName); 5208 getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId, 5209 SourceLineNum, FnStartSym, 5210 FnEndSym); 5211 return false; 5212 } 5213 5214 void MasmParser::initializeCVDefRangeTypeMap() { 5215 CVDefRangeTypeMap["reg"] = CVDR_DEFRANGE_REGISTER; 5216 CVDefRangeTypeMap["frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL; 5217 CVDefRangeTypeMap["subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER; 5218 CVDefRangeTypeMap["reg_rel"] = CVDR_DEFRANGE_REGISTER_REL; 5219 } 5220 5221 /// parseDirectiveCVDefRange 5222 /// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes* 5223 bool MasmParser::parseDirectiveCVDefRange() { 5224 SMLoc Loc; 5225 std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges; 5226 while (getLexer().is(AsmToken::Identifier)) { 5227 Loc = getLexer().getLoc(); 5228 StringRef GapStartName; 5229 if (parseIdentifier(GapStartName)) 5230 return Error(Loc, "expected identifier in directive"); 5231 MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName); 5232 5233 Loc = getLexer().getLoc(); 5234 StringRef GapEndName; 5235 if (parseIdentifier(GapEndName)) 5236 return Error(Loc, "expected identifier in directive"); 5237 MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName); 5238 5239 Ranges.push_back({GapStartSym, GapEndSym}); 5240 } 5241 5242 StringRef CVDefRangeTypeStr; 5243 if (parseToken( 5244 AsmToken::Comma, 5245 "expected comma before def_range type in .cv_def_range directive") || 5246 parseIdentifier(CVDefRangeTypeStr)) 5247 return Error(Loc, "expected def_range type in directive"); 5248 5249 StringMap<CVDefRangeType>::const_iterator CVTypeIt = 5250 CVDefRangeTypeMap.find(CVDefRangeTypeStr); 5251 CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end()) 5252 ? CVDR_DEFRANGE 5253 : CVTypeIt->getValue(); 5254 switch (CVDRType) { 5255 case CVDR_DEFRANGE_REGISTER: { 5256 int64_t DRRegister; 5257 if (parseToken(AsmToken::Comma, "expected comma before register number in " 5258 ".cv_def_range directive") || 5259 parseAbsoluteExpression(DRRegister)) 5260 return Error(Loc, "expected register number"); 5261 5262 codeview::DefRangeRegisterHeader DRHdr; 5263 DRHdr.Register = DRRegister; 5264 DRHdr.MayHaveNoName = 0; 5265 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr); 5266 break; 5267 } 5268 case CVDR_DEFRANGE_FRAMEPOINTER_REL: { 5269 int64_t DROffset; 5270 if (parseToken(AsmToken::Comma, 5271 "expected comma before offset in .cv_def_range directive") || 5272 parseAbsoluteExpression(DROffset)) 5273 return Error(Loc, "expected offset value"); 5274 5275 codeview::DefRangeFramePointerRelHeader DRHdr; 5276 DRHdr.Offset = DROffset; 5277 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr); 5278 break; 5279 } 5280 case CVDR_DEFRANGE_SUBFIELD_REGISTER: { 5281 int64_t DRRegister; 5282 int64_t DROffsetInParent; 5283 if (parseToken(AsmToken::Comma, "expected comma before register number in " 5284 ".cv_def_range directive") || 5285 parseAbsoluteExpression(DRRegister)) 5286 return Error(Loc, "expected register number"); 5287 if (parseToken(AsmToken::Comma, 5288 "expected comma before offset in .cv_def_range directive") || 5289 parseAbsoluteExpression(DROffsetInParent)) 5290 return Error(Loc, "expected offset value"); 5291 5292 codeview::DefRangeSubfieldRegisterHeader DRHdr; 5293 DRHdr.Register = DRRegister; 5294 DRHdr.MayHaveNoName = 0; 5295 DRHdr.OffsetInParent = DROffsetInParent; 5296 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr); 5297 break; 5298 } 5299 case CVDR_DEFRANGE_REGISTER_REL: { 5300 int64_t DRRegister; 5301 int64_t DRFlags; 5302 int64_t DRBasePointerOffset; 5303 if (parseToken(AsmToken::Comma, "expected comma before register number in " 5304 ".cv_def_range directive") || 5305 parseAbsoluteExpression(DRRegister)) 5306 return Error(Loc, "expected register value"); 5307 if (parseToken( 5308 AsmToken::Comma, 5309 "expected comma before flag value in .cv_def_range directive") || 5310 parseAbsoluteExpression(DRFlags)) 5311 return Error(Loc, "expected flag value"); 5312 if (parseToken(AsmToken::Comma, "expected comma before base pointer offset " 5313 "in .cv_def_range directive") || 5314 parseAbsoluteExpression(DRBasePointerOffset)) 5315 return Error(Loc, "expected base pointer offset value"); 5316 5317 codeview::DefRangeRegisterRelHeader DRHdr; 5318 DRHdr.Register = DRRegister; 5319 DRHdr.Flags = DRFlags; 5320 DRHdr.BasePointerOffset = DRBasePointerOffset; 5321 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr); 5322 break; 5323 } 5324 default: 5325 return Error(Loc, "unexpected def_range type in .cv_def_range directive"); 5326 } 5327 return true; 5328 } 5329 5330 /// parseDirectiveCVString 5331 /// ::= .cv_stringtable "string" 5332 bool MasmParser::parseDirectiveCVString() { 5333 std::string Data; 5334 if (checkForValidSection() || parseEscapedString(Data)) 5335 return addErrorSuffix(" in '.cv_string' directive"); 5336 5337 // Put the string in the table and emit the offset. 5338 std::pair<StringRef, unsigned> Insertion = 5339 getCVContext().addToStringTable(Data); 5340 getStreamer().emitIntValue(Insertion.second, 4); 5341 return false; 5342 } 5343 5344 /// parseDirectiveCVStringTable 5345 /// ::= .cv_stringtable 5346 bool MasmParser::parseDirectiveCVStringTable() { 5347 getStreamer().emitCVStringTableDirective(); 5348 return false; 5349 } 5350 5351 /// parseDirectiveCVFileChecksums 5352 /// ::= .cv_filechecksums 5353 bool MasmParser::parseDirectiveCVFileChecksums() { 5354 getStreamer().emitCVFileChecksumsDirective(); 5355 return false; 5356 } 5357 5358 /// parseDirectiveCVFileChecksumOffset 5359 /// ::= .cv_filechecksumoffset fileno 5360 bool MasmParser::parseDirectiveCVFileChecksumOffset() { 5361 int64_t FileNo; 5362 if (parseIntToken(FileNo, "expected identifier in directive")) 5363 return true; 5364 if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement")) 5365 return true; 5366 getStreamer().emitCVFileChecksumOffsetDirective(FileNo); 5367 return false; 5368 } 5369 5370 /// parseDirectiveCVFPOData 5371 /// ::= .cv_fpo_data procsym 5372 bool MasmParser::parseDirectiveCVFPOData() { 5373 SMLoc DirLoc = getLexer().getLoc(); 5374 StringRef ProcName; 5375 if (parseIdentifier(ProcName)) 5376 return TokError("expected symbol name"); 5377 if (parseEOL("unexpected tokens")) 5378 return addErrorSuffix(" in '.cv_fpo_data' directive"); 5379 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName); 5380 getStreamer().EmitCVFPOData(ProcSym, DirLoc); 5381 return false; 5382 } 5383 5384 /// parseDirectiveCFISections 5385 /// ::= .cfi_sections section [, section] 5386 bool MasmParser::parseDirectiveCFISections() { 5387 StringRef Name; 5388 bool EH = false; 5389 bool Debug = false; 5390 5391 if (parseIdentifier(Name)) 5392 return TokError("Expected an identifier"); 5393 5394 if (Name == ".eh_frame") 5395 EH = true; 5396 else if (Name == ".debug_frame") 5397 Debug = true; 5398 5399 if (getLexer().is(AsmToken::Comma)) { 5400 Lex(); 5401 5402 if (parseIdentifier(Name)) 5403 return TokError("Expected an identifier"); 5404 5405 if (Name == ".eh_frame") 5406 EH = true; 5407 else if (Name == ".debug_frame") 5408 Debug = true; 5409 } 5410 5411 getStreamer().emitCFISections(EH, Debug); 5412 return false; 5413 } 5414 5415 /// parseDirectiveCFIStartProc 5416 /// ::= .cfi_startproc [simple] 5417 bool MasmParser::parseDirectiveCFIStartProc() { 5418 StringRef Simple; 5419 if (!parseOptionalToken(AsmToken::EndOfStatement)) { 5420 if (check(parseIdentifier(Simple) || Simple != "simple", 5421 "unexpected token") || 5422 parseToken(AsmToken::EndOfStatement)) 5423 return addErrorSuffix(" in '.cfi_startproc' directive"); 5424 } 5425 5426 // TODO(kristina): Deal with a corner case of incorrect diagnostic context 5427 // being produced if this directive is emitted as part of preprocessor macro 5428 // expansion which can *ONLY* happen if Clang's cc1as is the API consumer. 5429 // Tools like llvm-mc on the other hand are not affected by it, and report 5430 // correct context information. 5431 getStreamer().emitCFIStartProc(!Simple.empty(), Lexer.getLoc()); 5432 return false; 5433 } 5434 5435 /// parseDirectiveCFIEndProc 5436 /// ::= .cfi_endproc 5437 bool MasmParser::parseDirectiveCFIEndProc() { 5438 getStreamer().emitCFIEndProc(); 5439 return false; 5440 } 5441 5442 /// parse register name or number. 5443 bool MasmParser::parseRegisterOrRegisterNumber(int64_t &Register, 5444 SMLoc DirectiveLoc) { 5445 unsigned RegNo; 5446 5447 if (getLexer().isNot(AsmToken::Integer)) { 5448 if (getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc)) 5449 return true; 5450 Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true); 5451 } else 5452 return parseAbsoluteExpression(Register); 5453 5454 return false; 5455 } 5456 5457 /// parseDirectiveCFIDefCfa 5458 /// ::= .cfi_def_cfa register, offset 5459 bool MasmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) { 5460 int64_t Register = 0, Offset = 0; 5461 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || 5462 parseToken(AsmToken::Comma, "unexpected token in directive") || 5463 parseAbsoluteExpression(Offset)) 5464 return true; 5465 5466 getStreamer().emitCFIDefCfa(Register, Offset); 5467 return false; 5468 } 5469 5470 /// parseDirectiveCFIDefCfaOffset 5471 /// ::= .cfi_def_cfa_offset offset 5472 bool MasmParser::parseDirectiveCFIDefCfaOffset() { 5473 int64_t Offset = 0; 5474 if (parseAbsoluteExpression(Offset)) 5475 return true; 5476 5477 getStreamer().emitCFIDefCfaOffset(Offset); 5478 return false; 5479 } 5480 5481 /// parseDirectiveCFIRegister 5482 /// ::= .cfi_register register, register 5483 bool MasmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) { 5484 int64_t Register1 = 0, Register2 = 0; 5485 if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) || 5486 parseToken(AsmToken::Comma, "unexpected token in directive") || 5487 parseRegisterOrRegisterNumber(Register2, DirectiveLoc)) 5488 return true; 5489 5490 getStreamer().emitCFIRegister(Register1, Register2); 5491 return false; 5492 } 5493 5494 /// parseDirectiveCFIWindowSave 5495 /// ::= .cfi_window_save 5496 bool MasmParser::parseDirectiveCFIWindowSave() { 5497 getStreamer().emitCFIWindowSave(); 5498 return false; 5499 } 5500 5501 /// parseDirectiveCFIAdjustCfaOffset 5502 /// ::= .cfi_adjust_cfa_offset adjustment 5503 bool MasmParser::parseDirectiveCFIAdjustCfaOffset() { 5504 int64_t Adjustment = 0; 5505 if (parseAbsoluteExpression(Adjustment)) 5506 return true; 5507 5508 getStreamer().emitCFIAdjustCfaOffset(Adjustment); 5509 return false; 5510 } 5511 5512 /// parseDirectiveCFIDefCfaRegister 5513 /// ::= .cfi_def_cfa_register register 5514 bool MasmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) { 5515 int64_t Register = 0; 5516 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 5517 return true; 5518 5519 getStreamer().emitCFIDefCfaRegister(Register); 5520 return false; 5521 } 5522 5523 /// parseDirectiveCFIOffset 5524 /// ::= .cfi_offset register, offset 5525 bool MasmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) { 5526 int64_t Register = 0; 5527 int64_t Offset = 0; 5528 5529 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || 5530 parseToken(AsmToken::Comma, "unexpected token in directive") || 5531 parseAbsoluteExpression(Offset)) 5532 return true; 5533 5534 getStreamer().emitCFIOffset(Register, Offset); 5535 return false; 5536 } 5537 5538 /// parseDirectiveCFIRelOffset 5539 /// ::= .cfi_rel_offset register, offset 5540 bool MasmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) { 5541 int64_t Register = 0, Offset = 0; 5542 5543 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || 5544 parseToken(AsmToken::Comma, "unexpected token in directive") || 5545 parseAbsoluteExpression(Offset)) 5546 return true; 5547 5548 getStreamer().emitCFIRelOffset(Register, Offset); 5549 return false; 5550 } 5551 5552 static bool isValidEncoding(int64_t Encoding) { 5553 if (Encoding & ~0xff) 5554 return false; 5555 5556 if (Encoding == dwarf::DW_EH_PE_omit) 5557 return true; 5558 5559 const unsigned Format = Encoding & 0xf; 5560 if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 && 5561 Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 && 5562 Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 && 5563 Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed) 5564 return false; 5565 5566 const unsigned Application = Encoding & 0x70; 5567 if (Application != dwarf::DW_EH_PE_absptr && 5568 Application != dwarf::DW_EH_PE_pcrel) 5569 return false; 5570 5571 return true; 5572 } 5573 5574 /// parseDirectiveCFIPersonalityOrLsda 5575 /// IsPersonality true for cfi_personality, false for cfi_lsda 5576 /// ::= .cfi_personality encoding, [symbol_name] 5577 /// ::= .cfi_lsda encoding, [symbol_name] 5578 bool MasmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) { 5579 int64_t Encoding = 0; 5580 if (parseAbsoluteExpression(Encoding)) 5581 return true; 5582 if (Encoding == dwarf::DW_EH_PE_omit) 5583 return false; 5584 5585 StringRef Name; 5586 if (check(!isValidEncoding(Encoding), "unsupported encoding.") || 5587 parseToken(AsmToken::Comma, "unexpected token in directive") || 5588 check(parseIdentifier(Name), "expected identifier in directive")) 5589 return true; 5590 5591 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 5592 5593 if (IsPersonality) 5594 getStreamer().emitCFIPersonality(Sym, Encoding); 5595 else 5596 getStreamer().emitCFILsda(Sym, Encoding); 5597 return false; 5598 } 5599 5600 /// parseDirectiveCFIRememberState 5601 /// ::= .cfi_remember_state 5602 bool MasmParser::parseDirectiveCFIRememberState() { 5603 getStreamer().emitCFIRememberState(); 5604 return false; 5605 } 5606 5607 /// parseDirectiveCFIRestoreState 5608 /// ::= .cfi_remember_state 5609 bool MasmParser::parseDirectiveCFIRestoreState() { 5610 getStreamer().emitCFIRestoreState(); 5611 return false; 5612 } 5613 5614 /// parseDirectiveCFISameValue 5615 /// ::= .cfi_same_value register 5616 bool MasmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) { 5617 int64_t Register = 0; 5618 5619 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 5620 return true; 5621 5622 getStreamer().emitCFISameValue(Register); 5623 return false; 5624 } 5625 5626 /// parseDirectiveCFIRestore 5627 /// ::= .cfi_restore register 5628 bool MasmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) { 5629 int64_t Register = 0; 5630 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 5631 return true; 5632 5633 getStreamer().emitCFIRestore(Register); 5634 return false; 5635 } 5636 5637 /// parseDirectiveCFIEscape 5638 /// ::= .cfi_escape expression[,...] 5639 bool MasmParser::parseDirectiveCFIEscape() { 5640 std::string Values; 5641 int64_t CurrValue; 5642 if (parseAbsoluteExpression(CurrValue)) 5643 return true; 5644 5645 Values.push_back((uint8_t)CurrValue); 5646 5647 while (getLexer().is(AsmToken::Comma)) { 5648 Lex(); 5649 5650 if (parseAbsoluteExpression(CurrValue)) 5651 return true; 5652 5653 Values.push_back((uint8_t)CurrValue); 5654 } 5655 5656 getStreamer().emitCFIEscape(Values); 5657 return false; 5658 } 5659 5660 /// parseDirectiveCFIReturnColumn 5661 /// ::= .cfi_return_column register 5662 bool MasmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) { 5663 int64_t Register = 0; 5664 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 5665 return true; 5666 getStreamer().emitCFIReturnColumn(Register); 5667 return false; 5668 } 5669 5670 /// parseDirectiveCFISignalFrame 5671 /// ::= .cfi_signal_frame 5672 bool MasmParser::parseDirectiveCFISignalFrame() { 5673 if (parseToken(AsmToken::EndOfStatement, 5674 "unexpected token in '.cfi_signal_frame'")) 5675 return true; 5676 5677 getStreamer().emitCFISignalFrame(); 5678 return false; 5679 } 5680 5681 /// parseDirectiveCFIUndefined 5682 /// ::= .cfi_undefined register 5683 bool MasmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) { 5684 int64_t Register = 0; 5685 5686 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 5687 return true; 5688 5689 getStreamer().emitCFIUndefined(Register); 5690 return false; 5691 } 5692 5693 /// parseDirectiveMacro 5694 /// ::= name macro [parameters] 5695 /// ["LOCAL" identifiers] 5696 /// parameters ::= parameter [, parameter]* 5697 /// parameter ::= name ":" qualifier 5698 /// qualifier ::= "req" | "vararg" | "=" macro_argument 5699 bool MasmParser::parseDirectiveMacro(StringRef Name, SMLoc NameLoc) { 5700 MCAsmMacroParameters Parameters; 5701 while (getLexer().isNot(AsmToken::EndOfStatement)) { 5702 if (!Parameters.empty() && Parameters.back().Vararg) 5703 return Error(Lexer.getLoc(), 5704 "Vararg parameter '" + Parameters.back().Name + 5705 "' should be last in the list of parameters"); 5706 5707 MCAsmMacroParameter Parameter; 5708 if (parseIdentifier(Parameter.Name)) 5709 return TokError("expected identifier in 'macro' directive"); 5710 5711 // Emit an error if two (or more) named parameters share the same name. 5712 for (const MCAsmMacroParameter& CurrParam : Parameters) 5713 if (CurrParam.Name.equals_insensitive(Parameter.Name)) 5714 return TokError("macro '" + Name + "' has multiple parameters" 5715 " named '" + Parameter.Name + "'"); 5716 5717 if (Lexer.is(AsmToken::Colon)) { 5718 Lex(); // consume ':' 5719 5720 if (parseOptionalToken(AsmToken::Equal)) { 5721 // Default value 5722 SMLoc ParamLoc; 5723 5724 ParamLoc = Lexer.getLoc(); 5725 if (parseMacroArgument(nullptr, Parameter.Value)) 5726 return true; 5727 } else { 5728 SMLoc QualLoc; 5729 StringRef Qualifier; 5730 5731 QualLoc = Lexer.getLoc(); 5732 if (parseIdentifier(Qualifier)) 5733 return Error(QualLoc, "missing parameter qualifier for " 5734 "'" + 5735 Parameter.Name + "' in macro '" + Name + 5736 "'"); 5737 5738 if (Qualifier.equals_insensitive("req")) 5739 Parameter.Required = true; 5740 else if (Qualifier.equals_insensitive("vararg")) 5741 Parameter.Vararg = true; 5742 else 5743 return Error(QualLoc, 5744 Qualifier + " is not a valid parameter qualifier for '" + 5745 Parameter.Name + "' in macro '" + Name + "'"); 5746 } 5747 } 5748 5749 Parameters.push_back(std::move(Parameter)); 5750 5751 if (getLexer().is(AsmToken::Comma)) 5752 Lex(); 5753 } 5754 5755 // Eat just the end of statement. 5756 Lexer.Lex(); 5757 5758 std::vector<std::string> Locals; 5759 if (getTok().is(AsmToken::Identifier) && 5760 getTok().getIdentifier().equals_insensitive("local")) { 5761 Lex(); // Eat the LOCAL directive. 5762 5763 StringRef ID; 5764 while (true) { 5765 if (parseIdentifier(ID)) 5766 return true; 5767 Locals.push_back(ID.lower()); 5768 5769 // If we see a comma, continue (and allow line continuation). 5770 if (!parseOptionalToken(AsmToken::Comma)) 5771 break; 5772 parseOptionalToken(AsmToken::EndOfStatement); 5773 } 5774 } 5775 5776 // Consuming deferred text, so use Lexer.Lex to ignore Lexing Errors. 5777 AsmToken EndToken, StartToken = getTok(); 5778 unsigned MacroDepth = 0; 5779 bool IsMacroFunction = false; 5780 // Lex the macro definition. 5781 while (true) { 5782 // Ignore Lexing errors in macros. 5783 while (Lexer.is(AsmToken::Error)) { 5784 Lexer.Lex(); 5785 } 5786 5787 // Check whether we have reached the end of the file. 5788 if (getLexer().is(AsmToken::Eof)) 5789 return Error(NameLoc, "no matching 'endm' in definition"); 5790 5791 // Otherwise, check whether we have reached the 'endm'... and determine if 5792 // this is a macro function. 5793 if (getLexer().is(AsmToken::Identifier)) { 5794 if (getTok().getIdentifier().equals_insensitive("endm")) { 5795 if (MacroDepth == 0) { // Outermost macro. 5796 EndToken = getTok(); 5797 Lexer.Lex(); 5798 if (getLexer().isNot(AsmToken::EndOfStatement)) 5799 return TokError("unexpected token in '" + EndToken.getIdentifier() + 5800 "' directive"); 5801 break; 5802 } else { 5803 // Otherwise we just found the end of an inner macro. 5804 --MacroDepth; 5805 } 5806 } else if (getTok().getIdentifier().equals_insensitive("exitm")) { 5807 if (MacroDepth == 0 && peekTok().isNot(AsmToken::EndOfStatement)) { 5808 IsMacroFunction = true; 5809 } 5810 } else if (isMacroLikeDirective()) { 5811 // We allow nested macros. Those aren't instantiated until the 5812 // outermost macro is expanded so just ignore them for now. 5813 ++MacroDepth; 5814 } 5815 } 5816 5817 // Otherwise, scan til the end of the statement. 5818 eatToEndOfStatement(); 5819 } 5820 5821 if (getContext().lookupMacro(Name.lower())) { 5822 return Error(NameLoc, "macro '" + Name + "' is already defined"); 5823 } 5824 5825 const char *BodyStart = StartToken.getLoc().getPointer(); 5826 const char *BodyEnd = EndToken.getLoc().getPointer(); 5827 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); 5828 MCAsmMacro Macro(Name, Body, std::move(Parameters), std::move(Locals), 5829 IsMacroFunction); 5830 DEBUG_WITH_TYPE("asm-macros", dbgs() << "Defining new macro:\n"; 5831 Macro.dump()); 5832 getContext().defineMacro(Name, std::move(Macro)); 5833 return false; 5834 } 5835 5836 /// parseDirectiveExitMacro 5837 /// ::= "exitm" [textitem] 5838 bool MasmParser::parseDirectiveExitMacro(SMLoc DirectiveLoc, 5839 StringRef Directive, 5840 std::string &Value) { 5841 SMLoc EndLoc = getTok().getLoc(); 5842 if (getTok().isNot(AsmToken::EndOfStatement) && parseTextItem(Value)) 5843 return Error(EndLoc, 5844 "unable to parse text item in '" + Directive + "' directive"); 5845 eatToEndOfStatement(); 5846 5847 if (!isInsideMacroInstantiation()) 5848 return TokError("unexpected '" + Directive + "' in file, " 5849 "no current macro definition"); 5850 5851 // Exit all conditionals that are active in the current macro. 5852 while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) { 5853 TheCondState = TheCondStack.back(); 5854 TheCondStack.pop_back(); 5855 } 5856 5857 handleMacroExit(); 5858 return false; 5859 } 5860 5861 /// parseDirectiveEndMacro 5862 /// ::= endm 5863 bool MasmParser::parseDirectiveEndMacro(StringRef Directive) { 5864 if (getLexer().isNot(AsmToken::EndOfStatement)) 5865 return TokError("unexpected token in '" + Directive + "' directive"); 5866 5867 // If we are inside a macro instantiation, terminate the current 5868 // instantiation. 5869 if (isInsideMacroInstantiation()) { 5870 handleMacroExit(); 5871 return false; 5872 } 5873 5874 // Otherwise, this .endmacro is a stray entry in the file; well formed 5875 // .endmacro directives are handled during the macro definition parsing. 5876 return TokError("unexpected '" + Directive + "' in file, " 5877 "no current macro definition"); 5878 } 5879 5880 /// parseDirectivePurgeMacro 5881 /// ::= purge identifier ( , identifier )* 5882 bool MasmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) { 5883 StringRef Name; 5884 while (true) { 5885 SMLoc NameLoc; 5886 if (parseTokenLoc(NameLoc) || 5887 check(parseIdentifier(Name), NameLoc, 5888 "expected identifier in 'purge' directive")) 5889 return true; 5890 5891 DEBUG_WITH_TYPE("asm-macros", dbgs() 5892 << "Un-defining macro: " << Name << "\n"); 5893 if (!getContext().lookupMacro(Name.lower())) 5894 return Error(NameLoc, "macro '" + Name + "' is not defined"); 5895 getContext().undefineMacro(Name.lower()); 5896 5897 if (!parseOptionalToken(AsmToken::Comma)) 5898 break; 5899 parseOptionalToken(AsmToken::EndOfStatement); 5900 } 5901 5902 return false; 5903 } 5904 5905 /// parseDirectiveSymbolAttribute 5906 /// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ] 5907 bool MasmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) { 5908 auto parseOp = [&]() -> bool { 5909 StringRef Name; 5910 SMLoc Loc = getTok().getLoc(); 5911 if (parseIdentifier(Name)) 5912 return Error(Loc, "expected identifier"); 5913 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 5914 5915 // Assembler local symbols don't make any sense here. Complain loudly. 5916 if (Sym->isTemporary()) 5917 return Error(Loc, "non-local symbol required"); 5918 5919 if (!getStreamer().emitSymbolAttribute(Sym, Attr)) 5920 return Error(Loc, "unable to emit symbol attribute"); 5921 return false; 5922 }; 5923 5924 if (parseMany(parseOp)) 5925 return addErrorSuffix(" in directive"); 5926 return false; 5927 } 5928 5929 /// parseDirectiveComm 5930 /// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ] 5931 bool MasmParser::parseDirectiveComm(bool IsLocal) { 5932 if (checkForValidSection()) 5933 return true; 5934 5935 SMLoc IDLoc = getLexer().getLoc(); 5936 StringRef Name; 5937 if (parseIdentifier(Name)) 5938 return TokError("expected identifier in directive"); 5939 5940 // Handle the identifier as the key symbol. 5941 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 5942 5943 if (getLexer().isNot(AsmToken::Comma)) 5944 return TokError("unexpected token in directive"); 5945 Lex(); 5946 5947 int64_t Size; 5948 SMLoc SizeLoc = getLexer().getLoc(); 5949 if (parseAbsoluteExpression(Size)) 5950 return true; 5951 5952 int64_t Pow2Alignment = 0; 5953 SMLoc Pow2AlignmentLoc; 5954 if (getLexer().is(AsmToken::Comma)) { 5955 Lex(); 5956 Pow2AlignmentLoc = getLexer().getLoc(); 5957 if (parseAbsoluteExpression(Pow2Alignment)) 5958 return true; 5959 5960 LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType(); 5961 if (IsLocal && LCOMM == LCOMM::NoAlignment) 5962 return Error(Pow2AlignmentLoc, "alignment not supported on this target"); 5963 5964 // If this target takes alignments in bytes (not log) validate and convert. 5965 if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) || 5966 (IsLocal && LCOMM == LCOMM::ByteAlignment)) { 5967 if (!isPowerOf2_64(Pow2Alignment)) 5968 return Error(Pow2AlignmentLoc, "alignment must be a power of 2"); 5969 Pow2Alignment = Log2_64(Pow2Alignment); 5970 } 5971 } 5972 5973 if (parseToken(AsmToken::EndOfStatement, 5974 "unexpected token in '.comm' or '.lcomm' directive")) 5975 return true; 5976 5977 // NOTE: a size of zero for a .comm should create a undefined symbol 5978 // but a size of .lcomm creates a bss symbol of size zero. 5979 if (Size < 0) 5980 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't " 5981 "be less than zero"); 5982 5983 // NOTE: The alignment in the directive is a power of 2 value, the assembler 5984 // may internally end up wanting an alignment in bytes. 5985 // FIXME: Diagnose overflow. 5986 if (Pow2Alignment < 0) 5987 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive " 5988 "alignment, can't be less than zero"); 5989 5990 Sym->redefineIfPossible(); 5991 if (!Sym->isUndefined()) 5992 return Error(IDLoc, "invalid symbol redefinition"); 5993 5994 // Create the Symbol as a common or local common with Size and Pow2Alignment. 5995 if (IsLocal) { 5996 getStreamer().emitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment); 5997 return false; 5998 } 5999 6000 getStreamer().emitCommonSymbol(Sym, Size, 1 << Pow2Alignment); 6001 return false; 6002 } 6003 6004 /// parseDirectiveComment 6005 /// ::= comment delimiter [[text]] 6006 /// [[text]] 6007 /// [[text]] delimiter [[text]] 6008 bool MasmParser::parseDirectiveComment(SMLoc DirectiveLoc) { 6009 std::string FirstLine = parseStringTo(AsmToken::EndOfStatement); 6010 size_t DelimiterEnd = FirstLine.find_first_of("\b\t\v\f\r\x1A "); 6011 StringRef Delimiter = StringRef(FirstLine).take_front(DelimiterEnd); 6012 if (Delimiter.empty()) 6013 return Error(DirectiveLoc, "no delimiter in 'comment' directive"); 6014 do { 6015 if (getTok().is(AsmToken::Eof)) 6016 return Error(DirectiveLoc, "unmatched delimiter in 'comment' directive"); 6017 Lex(); // eat end of statement 6018 } while ( 6019 !StringRef(parseStringTo(AsmToken::EndOfStatement)).contains(Delimiter)); 6020 return parseToken(AsmToken::EndOfStatement, 6021 "unexpected token in 'comment' directive"); 6022 } 6023 6024 /// parseDirectiveInclude 6025 /// ::= include <filename> 6026 /// | include filename 6027 bool MasmParser::parseDirectiveInclude() { 6028 // Allow the strings to have escaped octal character sequence. 6029 std::string Filename; 6030 SMLoc IncludeLoc = getTok().getLoc(); 6031 6032 if (parseAngleBracketString(Filename)) 6033 Filename = parseStringTo(AsmToken::EndOfStatement); 6034 if (check(Filename.empty(), "missing filename in 'include' directive") || 6035 check(getTok().isNot(AsmToken::EndOfStatement), 6036 "unexpected token in 'include' directive") || 6037 // Attempt to switch the lexer to the included file before consuming the 6038 // end of statement to avoid losing it when we switch. 6039 check(enterIncludeFile(Filename), IncludeLoc, 6040 "Could not find include file '" + Filename + "'")) 6041 return true; 6042 6043 return false; 6044 } 6045 6046 /// parseDirectiveIf 6047 /// ::= .if{,eq,ge,gt,le,lt,ne} expression 6048 bool MasmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) { 6049 TheCondStack.push_back(TheCondState); 6050 TheCondState.TheCond = AsmCond::IfCond; 6051 if (TheCondState.Ignore) { 6052 eatToEndOfStatement(); 6053 } else { 6054 int64_t ExprValue; 6055 if (parseAbsoluteExpression(ExprValue) || 6056 parseToken(AsmToken::EndOfStatement, 6057 "unexpected token in '.if' directive")) 6058 return true; 6059 6060 switch (DirKind) { 6061 default: 6062 llvm_unreachable("unsupported directive"); 6063 case DK_IF: 6064 break; 6065 case DK_IFE: 6066 ExprValue = ExprValue == 0; 6067 break; 6068 } 6069 6070 TheCondState.CondMet = ExprValue; 6071 TheCondState.Ignore = !TheCondState.CondMet; 6072 } 6073 6074 return false; 6075 } 6076 6077 /// parseDirectiveIfb 6078 /// ::= .ifb textitem 6079 bool MasmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) { 6080 TheCondStack.push_back(TheCondState); 6081 TheCondState.TheCond = AsmCond::IfCond; 6082 6083 if (TheCondState.Ignore) { 6084 eatToEndOfStatement(); 6085 } else { 6086 std::string Str; 6087 if (parseTextItem(Str)) 6088 return TokError("expected text item parameter for 'ifb' directive"); 6089 6090 if (parseToken(AsmToken::EndOfStatement, 6091 "unexpected token in 'ifb' directive")) 6092 return true; 6093 6094 TheCondState.CondMet = ExpectBlank == Str.empty(); 6095 TheCondState.Ignore = !TheCondState.CondMet; 6096 } 6097 6098 return false; 6099 } 6100 6101 /// parseDirectiveIfidn 6102 /// ::= ifidn textitem, textitem 6103 bool MasmParser::parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual, 6104 bool CaseInsensitive) { 6105 std::string String1, String2; 6106 6107 if (parseTextItem(String1)) { 6108 if (ExpectEqual) 6109 return TokError("expected text item parameter for 'ifidn' directive"); 6110 return TokError("expected text item parameter for 'ifdif' directive"); 6111 } 6112 6113 if (Lexer.isNot(AsmToken::Comma)) { 6114 if (ExpectEqual) 6115 return TokError( 6116 "expected comma after first string for 'ifidn' directive"); 6117 return TokError("expected comma after first string for 'ifdif' directive"); 6118 } 6119 Lex(); 6120 6121 if (parseTextItem(String2)) { 6122 if (ExpectEqual) 6123 return TokError("expected text item parameter for 'ifidn' directive"); 6124 return TokError("expected text item parameter for 'ifdif' directive"); 6125 } 6126 6127 TheCondStack.push_back(TheCondState); 6128 TheCondState.TheCond = AsmCond::IfCond; 6129 if (CaseInsensitive) 6130 TheCondState.CondMet = 6131 ExpectEqual == (StringRef(String1).equals_insensitive(String2)); 6132 else 6133 TheCondState.CondMet = ExpectEqual == (String1 == String2); 6134 TheCondState.Ignore = !TheCondState.CondMet; 6135 6136 return false; 6137 } 6138 6139 /// parseDirectiveIfdef 6140 /// ::= ifdef symbol 6141 /// | ifdef variable 6142 bool MasmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { 6143 TheCondStack.push_back(TheCondState); 6144 TheCondState.TheCond = AsmCond::IfCond; 6145 6146 if (TheCondState.Ignore) { 6147 eatToEndOfStatement(); 6148 } else { 6149 bool is_defined = false; 6150 unsigned RegNo; 6151 SMLoc StartLoc, EndLoc; 6152 is_defined = (getTargetParser().tryParseRegister( 6153 RegNo, StartLoc, EndLoc) == MatchOperand_Success); 6154 if (!is_defined) { 6155 StringRef Name; 6156 if (check(parseIdentifier(Name), "expected identifier after 'ifdef'") || 6157 parseToken(AsmToken::EndOfStatement, "unexpected token in 'ifdef'")) 6158 return true; 6159 6160 if (Variables.find(Name.lower()) != Variables.end()) { 6161 is_defined = true; 6162 } else { 6163 MCSymbol *Sym = getContext().lookupSymbol(Name.lower()); 6164 is_defined = (Sym && !Sym->isUndefined(false)); 6165 } 6166 } 6167 6168 TheCondState.CondMet = (is_defined == expect_defined); 6169 TheCondState.Ignore = !TheCondState.CondMet; 6170 } 6171 6172 return false; 6173 } 6174 6175 /// parseDirectiveElseIf 6176 /// ::= elseif expression 6177 bool MasmParser::parseDirectiveElseIf(SMLoc DirectiveLoc, 6178 DirectiveKind DirKind) { 6179 if (TheCondState.TheCond != AsmCond::IfCond && 6180 TheCondState.TheCond != AsmCond::ElseIfCond) 6181 return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an" 6182 " .if or an .elseif"); 6183 TheCondState.TheCond = AsmCond::ElseIfCond; 6184 6185 bool LastIgnoreState = false; 6186 if (!TheCondStack.empty()) 6187 LastIgnoreState = TheCondStack.back().Ignore; 6188 if (LastIgnoreState || TheCondState.CondMet) { 6189 TheCondState.Ignore = true; 6190 eatToEndOfStatement(); 6191 } else { 6192 int64_t ExprValue; 6193 if (parseAbsoluteExpression(ExprValue)) 6194 return true; 6195 6196 if (parseToken(AsmToken::EndOfStatement, 6197 "unexpected token in '.elseif' directive")) 6198 return true; 6199 6200 switch (DirKind) { 6201 default: 6202 llvm_unreachable("unsupported directive"); 6203 case DK_ELSEIF: 6204 break; 6205 case DK_ELSEIFE: 6206 ExprValue = ExprValue == 0; 6207 break; 6208 } 6209 6210 TheCondState.CondMet = ExprValue; 6211 TheCondState.Ignore = !TheCondState.CondMet; 6212 } 6213 6214 return false; 6215 } 6216 6217 /// parseDirectiveElseIfb 6218 /// ::= elseifb textitem 6219 bool MasmParser::parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank) { 6220 if (TheCondState.TheCond != AsmCond::IfCond && 6221 TheCondState.TheCond != AsmCond::ElseIfCond) 6222 return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an" 6223 " if or an elseif"); 6224 TheCondState.TheCond = AsmCond::ElseIfCond; 6225 6226 bool LastIgnoreState = false; 6227 if (!TheCondStack.empty()) 6228 LastIgnoreState = TheCondStack.back().Ignore; 6229 if (LastIgnoreState || TheCondState.CondMet) { 6230 TheCondState.Ignore = true; 6231 eatToEndOfStatement(); 6232 } else { 6233 std::string Str; 6234 if (parseTextItem(Str)) { 6235 if (ExpectBlank) 6236 return TokError("expected text item parameter for 'elseifb' directive"); 6237 return TokError("expected text item parameter for 'elseifnb' directive"); 6238 } 6239 6240 if (parseToken(AsmToken::EndOfStatement, 6241 "unexpected token in 'elseifb' directive")) 6242 return true; 6243 6244 TheCondState.CondMet = ExpectBlank == Str.empty(); 6245 TheCondState.Ignore = !TheCondState.CondMet; 6246 } 6247 6248 return false; 6249 } 6250 6251 /// parseDirectiveElseIfdef 6252 /// ::= elseifdef symbol 6253 /// | elseifdef variable 6254 bool MasmParser::parseDirectiveElseIfdef(SMLoc DirectiveLoc, 6255 bool expect_defined) { 6256 if (TheCondState.TheCond != AsmCond::IfCond && 6257 TheCondState.TheCond != AsmCond::ElseIfCond) 6258 return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an" 6259 " if or an elseif"); 6260 TheCondState.TheCond = AsmCond::ElseIfCond; 6261 6262 bool LastIgnoreState = false; 6263 if (!TheCondStack.empty()) 6264 LastIgnoreState = TheCondStack.back().Ignore; 6265 if (LastIgnoreState || TheCondState.CondMet) { 6266 TheCondState.Ignore = true; 6267 eatToEndOfStatement(); 6268 } else { 6269 bool is_defined = false; 6270 unsigned RegNo; 6271 SMLoc StartLoc, EndLoc; 6272 is_defined = (getTargetParser().tryParseRegister(RegNo, StartLoc, EndLoc) == 6273 MatchOperand_Success); 6274 if (!is_defined) { 6275 StringRef Name; 6276 if (check(parseIdentifier(Name), 6277 "expected identifier after 'elseifdef'") || 6278 parseToken(AsmToken::EndOfStatement, 6279 "unexpected token in 'elseifdef'")) 6280 return true; 6281 6282 if (Variables.find(Name.lower()) != Variables.end()) { 6283 is_defined = true; 6284 } else { 6285 MCSymbol *Sym = getContext().lookupSymbol(Name); 6286 is_defined = (Sym && !Sym->isUndefined(false)); 6287 } 6288 } 6289 6290 TheCondState.CondMet = (is_defined == expect_defined); 6291 TheCondState.Ignore = !TheCondState.CondMet; 6292 } 6293 6294 return false; 6295 } 6296 6297 /// parseDirectiveElseIfidn 6298 /// ::= elseifidn textitem, textitem 6299 bool MasmParser::parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual, 6300 bool CaseInsensitive) { 6301 if (TheCondState.TheCond != AsmCond::IfCond && 6302 TheCondState.TheCond != AsmCond::ElseIfCond) 6303 return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an" 6304 " if or an elseif"); 6305 TheCondState.TheCond = AsmCond::ElseIfCond; 6306 6307 bool LastIgnoreState = false; 6308 if (!TheCondStack.empty()) 6309 LastIgnoreState = TheCondStack.back().Ignore; 6310 if (LastIgnoreState || TheCondState.CondMet) { 6311 TheCondState.Ignore = true; 6312 eatToEndOfStatement(); 6313 } else { 6314 std::string String1, String2; 6315 6316 if (parseTextItem(String1)) { 6317 if (ExpectEqual) 6318 return TokError( 6319 "expected text item parameter for 'elseifidn' directive"); 6320 return TokError("expected text item parameter for 'elseifdif' directive"); 6321 } 6322 6323 if (Lexer.isNot(AsmToken::Comma)) { 6324 if (ExpectEqual) 6325 return TokError( 6326 "expected comma after first string for 'elseifidn' directive"); 6327 return TokError( 6328 "expected comma after first string for 'elseifdif' directive"); 6329 } 6330 Lex(); 6331 6332 if (parseTextItem(String2)) { 6333 if (ExpectEqual) 6334 return TokError( 6335 "expected text item parameter for 'elseifidn' directive"); 6336 return TokError("expected text item parameter for 'elseifdif' directive"); 6337 } 6338 6339 if (CaseInsensitive) 6340 TheCondState.CondMet = 6341 ExpectEqual == (StringRef(String1).equals_insensitive(String2)); 6342 else 6343 TheCondState.CondMet = ExpectEqual == (String1 == String2); 6344 TheCondState.Ignore = !TheCondState.CondMet; 6345 } 6346 6347 return false; 6348 } 6349 6350 /// parseDirectiveElse 6351 /// ::= else 6352 bool MasmParser::parseDirectiveElse(SMLoc DirectiveLoc) { 6353 if (parseToken(AsmToken::EndOfStatement, 6354 "unexpected token in 'else' directive")) 6355 return true; 6356 6357 if (TheCondState.TheCond != AsmCond::IfCond && 6358 TheCondState.TheCond != AsmCond::ElseIfCond) 6359 return Error(DirectiveLoc, "Encountered an else that doesn't follow an if" 6360 " or an elseif"); 6361 TheCondState.TheCond = AsmCond::ElseCond; 6362 bool LastIgnoreState = false; 6363 if (!TheCondStack.empty()) 6364 LastIgnoreState = TheCondStack.back().Ignore; 6365 if (LastIgnoreState || TheCondState.CondMet) 6366 TheCondState.Ignore = true; 6367 else 6368 TheCondState.Ignore = false; 6369 6370 return false; 6371 } 6372 6373 /// parseDirectiveEnd 6374 /// ::= end 6375 bool MasmParser::parseDirectiveEnd(SMLoc DirectiveLoc) { 6376 if (parseToken(AsmToken::EndOfStatement, 6377 "unexpected token in 'end' directive")) 6378 return true; 6379 6380 while (Lexer.isNot(AsmToken::Eof)) 6381 Lexer.Lex(); 6382 6383 return false; 6384 } 6385 6386 /// parseDirectiveError 6387 /// ::= .err [message] 6388 bool MasmParser::parseDirectiveError(SMLoc DirectiveLoc) { 6389 if (!TheCondStack.empty()) { 6390 if (TheCondStack.back().Ignore) { 6391 eatToEndOfStatement(); 6392 return false; 6393 } 6394 } 6395 6396 std::string Message = ".err directive invoked in source file"; 6397 if (Lexer.isNot(AsmToken::EndOfStatement)) 6398 Message = parseStringTo(AsmToken::EndOfStatement); 6399 Lex(); 6400 6401 return Error(DirectiveLoc, Message); 6402 } 6403 6404 /// parseDirectiveErrorIfb 6405 /// ::= .errb textitem[, message] 6406 bool MasmParser::parseDirectiveErrorIfb(SMLoc DirectiveLoc, bool ExpectBlank) { 6407 if (!TheCondStack.empty()) { 6408 if (TheCondStack.back().Ignore) { 6409 eatToEndOfStatement(); 6410 return false; 6411 } 6412 } 6413 6414 std::string Text; 6415 if (parseTextItem(Text)) 6416 return Error(getTok().getLoc(), "missing text item in '.errb' directive"); 6417 6418 std::string Message = ".errb directive invoked in source file"; 6419 if (Lexer.isNot(AsmToken::EndOfStatement)) { 6420 if (parseToken(AsmToken::Comma)) 6421 return addErrorSuffix(" in '.errb' directive"); 6422 Message = parseStringTo(AsmToken::EndOfStatement); 6423 } 6424 Lex(); 6425 6426 if (Text.empty() == ExpectBlank) 6427 return Error(DirectiveLoc, Message); 6428 return false; 6429 } 6430 6431 /// parseDirectiveErrorIfdef 6432 /// ::= .errdef name[, message] 6433 bool MasmParser::parseDirectiveErrorIfdef(SMLoc DirectiveLoc, 6434 bool ExpectDefined) { 6435 if (!TheCondStack.empty()) { 6436 if (TheCondStack.back().Ignore) { 6437 eatToEndOfStatement(); 6438 return false; 6439 } 6440 } 6441 6442 bool IsDefined = false; 6443 unsigned RegNo; 6444 SMLoc StartLoc, EndLoc; 6445 IsDefined = (getTargetParser().tryParseRegister(RegNo, StartLoc, EndLoc) == 6446 MatchOperand_Success); 6447 if (!IsDefined) { 6448 StringRef Name; 6449 if (check(parseIdentifier(Name), "expected identifier after '.errdef'")) 6450 return true; 6451 6452 if (Variables.find(Name.lower()) != Variables.end()) { 6453 IsDefined = true; 6454 } else { 6455 MCSymbol *Sym = getContext().lookupSymbol(Name); 6456 IsDefined = (Sym && !Sym->isUndefined(false)); 6457 } 6458 } 6459 6460 std::string Message = ".errdef directive invoked in source file"; 6461 if (Lexer.isNot(AsmToken::EndOfStatement)) { 6462 if (parseToken(AsmToken::Comma)) 6463 return addErrorSuffix(" in '.errdef' directive"); 6464 Message = parseStringTo(AsmToken::EndOfStatement); 6465 } 6466 Lex(); 6467 6468 if (IsDefined == ExpectDefined) 6469 return Error(DirectiveLoc, Message); 6470 return false; 6471 } 6472 6473 /// parseDirectiveErrorIfidn 6474 /// ::= .erridn textitem, textitem[, message] 6475 bool MasmParser::parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual, 6476 bool CaseInsensitive) { 6477 if (!TheCondStack.empty()) { 6478 if (TheCondStack.back().Ignore) { 6479 eatToEndOfStatement(); 6480 return false; 6481 } 6482 } 6483 6484 std::string String1, String2; 6485 6486 if (parseTextItem(String1)) { 6487 if (ExpectEqual) 6488 return TokError("expected string parameter for '.erridn' directive"); 6489 return TokError("expected string parameter for '.errdif' directive"); 6490 } 6491 6492 if (Lexer.isNot(AsmToken::Comma)) { 6493 if (ExpectEqual) 6494 return TokError( 6495 "expected comma after first string for '.erridn' directive"); 6496 return TokError( 6497 "expected comma after first string for '.errdif' directive"); 6498 } 6499 Lex(); 6500 6501 if (parseTextItem(String2)) { 6502 if (ExpectEqual) 6503 return TokError("expected string parameter for '.erridn' directive"); 6504 return TokError("expected string parameter for '.errdif' directive"); 6505 } 6506 6507 std::string Message; 6508 if (ExpectEqual) 6509 Message = ".erridn directive invoked in source file"; 6510 else 6511 Message = ".errdif directive invoked in source file"; 6512 if (Lexer.isNot(AsmToken::EndOfStatement)) { 6513 if (parseToken(AsmToken::Comma)) 6514 return addErrorSuffix(" in '.erridn' directive"); 6515 Message = parseStringTo(AsmToken::EndOfStatement); 6516 } 6517 Lex(); 6518 6519 if (CaseInsensitive) 6520 TheCondState.CondMet = 6521 ExpectEqual == (StringRef(String1).equals_insensitive(String2)); 6522 else 6523 TheCondState.CondMet = ExpectEqual == (String1 == String2); 6524 TheCondState.Ignore = !TheCondState.CondMet; 6525 6526 if ((CaseInsensitive && 6527 ExpectEqual == StringRef(String1).equals_insensitive(String2)) || 6528 (ExpectEqual == (String1 == String2))) 6529 return Error(DirectiveLoc, Message); 6530 return false; 6531 } 6532 6533 /// parseDirectiveErrorIfe 6534 /// ::= .erre expression[, message] 6535 bool MasmParser::parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero) { 6536 if (!TheCondStack.empty()) { 6537 if (TheCondStack.back().Ignore) { 6538 eatToEndOfStatement(); 6539 return false; 6540 } 6541 } 6542 6543 int64_t ExprValue; 6544 if (parseAbsoluteExpression(ExprValue)) 6545 return addErrorSuffix(" in '.erre' directive"); 6546 6547 std::string Message = ".erre directive invoked in source file"; 6548 if (Lexer.isNot(AsmToken::EndOfStatement)) { 6549 if (parseToken(AsmToken::Comma)) 6550 return addErrorSuffix(" in '.erre' directive"); 6551 Message = parseStringTo(AsmToken::EndOfStatement); 6552 } 6553 Lex(); 6554 6555 if ((ExprValue == 0) == ExpectZero) 6556 return Error(DirectiveLoc, Message); 6557 return false; 6558 } 6559 6560 /// parseDirectiveEndIf 6561 /// ::= .endif 6562 bool MasmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) { 6563 if (parseToken(AsmToken::EndOfStatement, 6564 "unexpected token in '.endif' directive")) 6565 return true; 6566 6567 if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty()) 6568 return Error(DirectiveLoc, "Encountered a .endif that doesn't follow " 6569 "an .if or .else"); 6570 if (!TheCondStack.empty()) { 6571 TheCondState = TheCondStack.back(); 6572 TheCondStack.pop_back(); 6573 } 6574 6575 return false; 6576 } 6577 6578 void MasmParser::initializeDirectiveKindMap() { 6579 DirectiveKindMap["="] = DK_ASSIGN; 6580 DirectiveKindMap["equ"] = DK_EQU; 6581 DirectiveKindMap["textequ"] = DK_TEXTEQU; 6582 // DirectiveKindMap[".ascii"] = DK_ASCII; 6583 // DirectiveKindMap[".asciz"] = DK_ASCIZ; 6584 // DirectiveKindMap[".string"] = DK_STRING; 6585 DirectiveKindMap["byte"] = DK_BYTE; 6586 DirectiveKindMap["sbyte"] = DK_SBYTE; 6587 DirectiveKindMap["word"] = DK_WORD; 6588 DirectiveKindMap["sword"] = DK_SWORD; 6589 DirectiveKindMap["dword"] = DK_DWORD; 6590 DirectiveKindMap["sdword"] = DK_SDWORD; 6591 DirectiveKindMap["fword"] = DK_FWORD; 6592 DirectiveKindMap["qword"] = DK_QWORD; 6593 DirectiveKindMap["sqword"] = DK_SQWORD; 6594 DirectiveKindMap["real4"] = DK_REAL4; 6595 DirectiveKindMap["real8"] = DK_REAL8; 6596 DirectiveKindMap["real10"] = DK_REAL10; 6597 DirectiveKindMap["align"] = DK_ALIGN; 6598 DirectiveKindMap["even"] = DK_EVEN; 6599 DirectiveKindMap["org"] = DK_ORG; 6600 DirectiveKindMap["extern"] = DK_EXTERN; 6601 DirectiveKindMap["public"] = DK_PUBLIC; 6602 // DirectiveKindMap[".comm"] = DK_COMM; 6603 DirectiveKindMap["comment"] = DK_COMMENT; 6604 DirectiveKindMap["include"] = DK_INCLUDE; 6605 DirectiveKindMap["repeat"] = DK_REPEAT; 6606 DirectiveKindMap["rept"] = DK_REPEAT; 6607 DirectiveKindMap["while"] = DK_WHILE; 6608 DirectiveKindMap["for"] = DK_FOR; 6609 DirectiveKindMap["irp"] = DK_FOR; 6610 DirectiveKindMap["forc"] = DK_FORC; 6611 DirectiveKindMap["irpc"] = DK_FORC; 6612 DirectiveKindMap["if"] = DK_IF; 6613 DirectiveKindMap["ife"] = DK_IFE; 6614 DirectiveKindMap["ifb"] = DK_IFB; 6615 DirectiveKindMap["ifnb"] = DK_IFNB; 6616 DirectiveKindMap["ifdef"] = DK_IFDEF; 6617 DirectiveKindMap["ifndef"] = DK_IFNDEF; 6618 DirectiveKindMap["ifdif"] = DK_IFDIF; 6619 DirectiveKindMap["ifdifi"] = DK_IFDIFI; 6620 DirectiveKindMap["ifidn"] = DK_IFIDN; 6621 DirectiveKindMap["ifidni"] = DK_IFIDNI; 6622 DirectiveKindMap["elseif"] = DK_ELSEIF; 6623 DirectiveKindMap["elseifdef"] = DK_ELSEIFDEF; 6624 DirectiveKindMap["elseifndef"] = DK_ELSEIFNDEF; 6625 DirectiveKindMap["elseifdif"] = DK_ELSEIFDIF; 6626 DirectiveKindMap["elseifidn"] = DK_ELSEIFIDN; 6627 DirectiveKindMap["else"] = DK_ELSE; 6628 DirectiveKindMap["end"] = DK_END; 6629 DirectiveKindMap["endif"] = DK_ENDIF; 6630 // DirectiveKindMap[".file"] = DK_FILE; 6631 // DirectiveKindMap[".line"] = DK_LINE; 6632 // DirectiveKindMap[".loc"] = DK_LOC; 6633 // DirectiveKindMap[".stabs"] = DK_STABS; 6634 // DirectiveKindMap[".cv_file"] = DK_CV_FILE; 6635 // DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID; 6636 // DirectiveKindMap[".cv_loc"] = DK_CV_LOC; 6637 // DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE; 6638 // DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE; 6639 // DirectiveKindMap[".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID; 6640 // DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE; 6641 // DirectiveKindMap[".cv_string"] = DK_CV_STRING; 6642 // DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE; 6643 // DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS; 6644 // DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET; 6645 // DirectiveKindMap[".cv_fpo_data"] = DK_CV_FPO_DATA; 6646 // DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS; 6647 // DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC; 6648 // DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC; 6649 // DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA; 6650 // DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET; 6651 // DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET; 6652 // DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER; 6653 // DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET; 6654 // DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET; 6655 // DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY; 6656 // DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA; 6657 // DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE; 6658 // DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE; 6659 // DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE; 6660 // DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE; 6661 // DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE; 6662 // DirectiveKindMap[".cfi_return_column"] = DK_CFI_RETURN_COLUMN; 6663 // DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME; 6664 // DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED; 6665 // DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER; 6666 // DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE; 6667 // DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME; 6668 DirectiveKindMap["macro"] = DK_MACRO; 6669 DirectiveKindMap["exitm"] = DK_EXITM; 6670 DirectiveKindMap["endm"] = DK_ENDM; 6671 DirectiveKindMap["purge"] = DK_PURGE; 6672 DirectiveKindMap[".err"] = DK_ERR; 6673 DirectiveKindMap[".errb"] = DK_ERRB; 6674 DirectiveKindMap[".errnb"] = DK_ERRNB; 6675 DirectiveKindMap[".errdef"] = DK_ERRDEF; 6676 DirectiveKindMap[".errndef"] = DK_ERRNDEF; 6677 DirectiveKindMap[".errdif"] = DK_ERRDIF; 6678 DirectiveKindMap[".errdifi"] = DK_ERRDIFI; 6679 DirectiveKindMap[".erridn"] = DK_ERRIDN; 6680 DirectiveKindMap[".erridni"] = DK_ERRIDNI; 6681 DirectiveKindMap[".erre"] = DK_ERRE; 6682 DirectiveKindMap[".errnz"] = DK_ERRNZ; 6683 DirectiveKindMap[".pushframe"] = DK_PUSHFRAME; 6684 DirectiveKindMap[".pushreg"] = DK_PUSHREG; 6685 DirectiveKindMap[".savereg"] = DK_SAVEREG; 6686 DirectiveKindMap[".savexmm128"] = DK_SAVEXMM128; 6687 DirectiveKindMap[".setframe"] = DK_SETFRAME; 6688 DirectiveKindMap[".radix"] = DK_RADIX; 6689 DirectiveKindMap["db"] = DK_DB; 6690 DirectiveKindMap["dd"] = DK_DD; 6691 DirectiveKindMap["df"] = DK_DF; 6692 DirectiveKindMap["dq"] = DK_DQ; 6693 DirectiveKindMap["dw"] = DK_DW; 6694 DirectiveKindMap["echo"] = DK_ECHO; 6695 DirectiveKindMap["struc"] = DK_STRUCT; 6696 DirectiveKindMap["struct"] = DK_STRUCT; 6697 DirectiveKindMap["union"] = DK_UNION; 6698 DirectiveKindMap["ends"] = DK_ENDS; 6699 } 6700 6701 bool MasmParser::isMacroLikeDirective() { 6702 if (getLexer().is(AsmToken::Identifier)) { 6703 bool IsMacroLike = StringSwitch<bool>(getTok().getIdentifier()) 6704 .CasesLower("repeat", "rept", true) 6705 .CaseLower("while", true) 6706 .CasesLower("for", "irp", true) 6707 .CasesLower("forc", "irpc", true) 6708 .Default(false); 6709 if (IsMacroLike) 6710 return true; 6711 } 6712 if (peekTok().is(AsmToken::Identifier) && 6713 peekTok().getIdentifier().equals_insensitive("macro")) 6714 return true; 6715 6716 return false; 6717 } 6718 6719 MCAsmMacro *MasmParser::parseMacroLikeBody(SMLoc DirectiveLoc) { 6720 AsmToken EndToken, StartToken = getTok(); 6721 6722 unsigned NestLevel = 0; 6723 while (true) { 6724 // Check whether we have reached the end of the file. 6725 if (getLexer().is(AsmToken::Eof)) { 6726 printError(DirectiveLoc, "no matching 'endm' in definition"); 6727 return nullptr; 6728 } 6729 6730 if (isMacroLikeDirective()) 6731 ++NestLevel; 6732 6733 // Otherwise, check whether we have reached the endm. 6734 if (Lexer.is(AsmToken::Identifier) && 6735 getTok().getIdentifier().equals_insensitive("endm")) { 6736 if (NestLevel == 0) { 6737 EndToken = getTok(); 6738 Lex(); 6739 if (Lexer.isNot(AsmToken::EndOfStatement)) { 6740 printError(getTok().getLoc(), "unexpected token in 'endm' directive"); 6741 return nullptr; 6742 } 6743 break; 6744 } 6745 --NestLevel; 6746 } 6747 6748 // Otherwise, scan till the end of the statement. 6749 eatToEndOfStatement(); 6750 } 6751 6752 const char *BodyStart = StartToken.getLoc().getPointer(); 6753 const char *BodyEnd = EndToken.getLoc().getPointer(); 6754 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); 6755 6756 // We Are Anonymous. 6757 MacroLikeBodies.emplace_back(StringRef(), Body, MCAsmMacroParameters()); 6758 return &MacroLikeBodies.back(); 6759 } 6760 6761 bool MasmParser::expandStatement(SMLoc Loc) { 6762 std::string Body = parseStringTo(AsmToken::EndOfStatement); 6763 SMLoc EndLoc = getTok().getLoc(); 6764 6765 MCAsmMacroParameters Parameters; 6766 MCAsmMacroArguments Arguments; 6767 for (const auto &V : Variables) { 6768 const Variable &Var = V.getValue(); 6769 if (Var.IsText) { 6770 Parameters.emplace_back(); 6771 Arguments.emplace_back(); 6772 MCAsmMacroParameter &P = Parameters.back(); 6773 MCAsmMacroArgument &A = Arguments.back(); 6774 P.Name = Var.Name; 6775 P.Required = true; 6776 A.push_back(AsmToken(AsmToken::String, Var.TextValue)); 6777 } 6778 } 6779 MacroLikeBodies.emplace_back(StringRef(), Body, Parameters); 6780 MCAsmMacro M = MacroLikeBodies.back(); 6781 6782 // Expand the statement in a new buffer. 6783 SmallString<80> Buf; 6784 raw_svector_ostream OS(Buf); 6785 if (expandMacro(OS, M.Body, M.Parameters, Arguments, M.Locals, EndLoc)) 6786 return true; 6787 std::unique_ptr<MemoryBuffer> Expansion = 6788 MemoryBuffer::getMemBufferCopy(OS.str(), "<expansion>"); 6789 6790 // Jump to the expanded statement and prime the lexer. 6791 CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Expansion), EndLoc); 6792 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); 6793 EndStatementAtEOFStack.push_back(false); 6794 Lex(); 6795 return false; 6796 } 6797 6798 void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, 6799 raw_svector_ostream &OS) { 6800 instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/getTok().getLoc(), OS); 6801 } 6802 void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, 6803 SMLoc ExitLoc, 6804 raw_svector_ostream &OS) { 6805 OS << "endm\n"; 6806 6807 std::unique_ptr<MemoryBuffer> Instantiation = 6808 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); 6809 6810 // Create the macro instantiation object and add to the current macro 6811 // instantiation stack. 6812 MacroInstantiation *MI = new MacroInstantiation{DirectiveLoc, CurBuffer, 6813 ExitLoc, TheCondStack.size()}; 6814 ActiveMacros.push_back(MI); 6815 6816 // Jump to the macro instantiation and prime the lexer. 6817 CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc()); 6818 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); 6819 EndStatementAtEOFStack.push_back(true); 6820 Lex(); 6821 } 6822 6823 /// parseDirectiveRepeat 6824 /// ::= ("repeat" | "rept") count 6825 /// body 6826 /// endm 6827 bool MasmParser::parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Dir) { 6828 const MCExpr *CountExpr; 6829 SMLoc CountLoc = getTok().getLoc(); 6830 if (parseExpression(CountExpr)) 6831 return true; 6832 6833 int64_t Count; 6834 if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) { 6835 return Error(CountLoc, "unexpected token in '" + Dir + "' directive"); 6836 } 6837 6838 if (check(Count < 0, CountLoc, "Count is negative") || 6839 parseToken(AsmToken::EndOfStatement, 6840 "unexpected token in '" + Dir + "' directive")) 6841 return true; 6842 6843 // Lex the repeat definition. 6844 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 6845 if (!M) 6846 return true; 6847 6848 // Macro instantiation is lexical, unfortunately. We construct a new buffer 6849 // to hold the macro body with substitutions. 6850 SmallString<256> Buf; 6851 raw_svector_ostream OS(Buf); 6852 while (Count--) { 6853 if (expandMacro(OS, M->Body, None, None, M->Locals, getTok().getLoc())) 6854 return true; 6855 } 6856 instantiateMacroLikeBody(M, DirectiveLoc, OS); 6857 6858 return false; 6859 } 6860 6861 /// parseDirectiveWhile 6862 /// ::= "while" expression 6863 /// body 6864 /// endm 6865 bool MasmParser::parseDirectiveWhile(SMLoc DirectiveLoc) { 6866 const MCExpr *CondExpr; 6867 SMLoc CondLoc = getTok().getLoc(); 6868 if (parseExpression(CondExpr)) 6869 return true; 6870 6871 // Lex the repeat definition. 6872 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 6873 if (!M) 6874 return true; 6875 6876 // Macro instantiation is lexical, unfortunately. We construct a new buffer 6877 // to hold the macro body with substitutions. 6878 SmallString<256> Buf; 6879 raw_svector_ostream OS(Buf); 6880 int64_t Condition; 6881 if (!CondExpr->evaluateAsAbsolute(Condition, getStreamer().getAssemblerPtr())) 6882 return Error(CondLoc, "expected absolute expression in 'while' directive"); 6883 if (Condition) { 6884 // Instantiate the macro, then resume at this directive to recheck the 6885 // condition. 6886 if (expandMacro(OS, M->Body, None, None, M->Locals, getTok().getLoc())) 6887 return true; 6888 instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/DirectiveLoc, OS); 6889 } 6890 6891 return false; 6892 } 6893 6894 /// parseDirectiveFor 6895 /// ::= ("for" | "irp") symbol [":" qualifier], <values> 6896 /// body 6897 /// endm 6898 bool MasmParser::parseDirectiveFor(SMLoc DirectiveLoc, StringRef Dir) { 6899 MCAsmMacroParameter Parameter; 6900 MCAsmMacroArguments A; 6901 if (check(parseIdentifier(Parameter.Name), 6902 "expected identifier in '" + Dir + "' directive")) 6903 return true; 6904 6905 // Parse optional qualifier (default value, or "req") 6906 if (parseOptionalToken(AsmToken::Colon)) { 6907 if (parseOptionalToken(AsmToken::Equal)) { 6908 // Default value 6909 SMLoc ParamLoc; 6910 6911 ParamLoc = Lexer.getLoc(); 6912 if (parseMacroArgument(nullptr, Parameter.Value)) 6913 return true; 6914 } else { 6915 SMLoc QualLoc; 6916 StringRef Qualifier; 6917 6918 QualLoc = Lexer.getLoc(); 6919 if (parseIdentifier(Qualifier)) 6920 return Error(QualLoc, "missing parameter qualifier for " 6921 "'" + 6922 Parameter.Name + "' in '" + Dir + 6923 "' directive"); 6924 6925 if (Qualifier.equals_insensitive("req")) 6926 Parameter.Required = true; 6927 else 6928 return Error(QualLoc, 6929 Qualifier + " is not a valid parameter qualifier for '" + 6930 Parameter.Name + "' in '" + Dir + "' directive"); 6931 } 6932 } 6933 6934 if (parseToken(AsmToken::Comma, 6935 "expected comma in '" + Dir + "' directive") || 6936 parseToken(AsmToken::Less, 6937 "values in '" + Dir + 6938 "' directive must be enclosed in angle brackets")) 6939 return true; 6940 6941 while (true) { 6942 A.emplace_back(); 6943 if (parseMacroArgument(&Parameter, A.back(), /*EndTok=*/AsmToken::Greater)) 6944 return addErrorSuffix(" in arguments for '" + Dir + "' directive"); 6945 6946 // If we see a comma, continue, and allow line continuation. 6947 if (!parseOptionalToken(AsmToken::Comma)) 6948 break; 6949 parseOptionalToken(AsmToken::EndOfStatement); 6950 } 6951 6952 if (parseToken(AsmToken::Greater, 6953 "values in '" + Dir + 6954 "' directive must be enclosed in angle brackets") || 6955 parseToken(AsmToken::EndOfStatement, "expected End of Statement")) 6956 return true; 6957 6958 // Lex the for definition. 6959 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 6960 if (!M) 6961 return true; 6962 6963 // Macro instantiation is lexical, unfortunately. We construct a new buffer 6964 // to hold the macro body with substitutions. 6965 SmallString<256> Buf; 6966 raw_svector_ostream OS(Buf); 6967 6968 for (const MCAsmMacroArgument &Arg : A) { 6969 if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc())) 6970 return true; 6971 } 6972 6973 instantiateMacroLikeBody(M, DirectiveLoc, OS); 6974 6975 return false; 6976 } 6977 6978 /// parseDirectiveForc 6979 /// ::= ("forc" | "irpc") symbol, <string> 6980 /// body 6981 /// endm 6982 bool MasmParser::parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive) { 6983 MCAsmMacroParameter Parameter; 6984 6985 std::string Argument; 6986 if (check(parseIdentifier(Parameter.Name), 6987 "expected identifier in '" + Directive + "' directive") || 6988 parseToken(AsmToken::Comma, 6989 "expected comma in '" + Directive + "' directive")) 6990 return true; 6991 if (parseAngleBracketString(Argument)) { 6992 // Match ml64.exe; treat all characters to end of statement as a string, 6993 // ignoring comment markers, then discard anything following a space (using 6994 // the C locale). 6995 Argument = parseStringTo(AsmToken::EndOfStatement); 6996 if (getTok().is(AsmToken::EndOfStatement)) 6997 Argument += getTok().getString(); 6998 size_t End = 0; 6999 for (; End < Argument.size(); ++End) { 7000 if (isSpace(Argument[End])) 7001 break; 7002 } 7003 Argument.resize(End); 7004 } 7005 if (parseToken(AsmToken::EndOfStatement, "expected end of statement")) 7006 return true; 7007 7008 // Lex the irpc definition. 7009 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 7010 if (!M) 7011 return true; 7012 7013 // Macro instantiation is lexical, unfortunately. We construct a new buffer 7014 // to hold the macro body with substitutions. 7015 SmallString<256> Buf; 7016 raw_svector_ostream OS(Buf); 7017 7018 StringRef Values(Argument); 7019 for (std::size_t I = 0, End = Values.size(); I != End; ++I) { 7020 MCAsmMacroArgument Arg; 7021 Arg.emplace_back(AsmToken::Identifier, Values.slice(I, I + 1)); 7022 7023 if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc())) 7024 return true; 7025 } 7026 7027 instantiateMacroLikeBody(M, DirectiveLoc, OS); 7028 7029 return false; 7030 } 7031 7032 bool MasmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info, 7033 size_t Len) { 7034 const MCExpr *Value; 7035 SMLoc ExprLoc = getLexer().getLoc(); 7036 if (parseExpression(Value)) 7037 return true; 7038 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 7039 if (!MCE) 7040 return Error(ExprLoc, "unexpected expression in _emit"); 7041 uint64_t IntValue = MCE->getValue(); 7042 if (!isUInt<8>(IntValue) && !isInt<8>(IntValue)) 7043 return Error(ExprLoc, "literal value out of range for directive"); 7044 7045 Info.AsmRewrites->emplace_back(AOK_Emit, IDLoc, Len); 7046 return false; 7047 } 7048 7049 bool MasmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) { 7050 const MCExpr *Value; 7051 SMLoc ExprLoc = getLexer().getLoc(); 7052 if (parseExpression(Value)) 7053 return true; 7054 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 7055 if (!MCE) 7056 return Error(ExprLoc, "unexpected expression in align"); 7057 uint64_t IntValue = MCE->getValue(); 7058 if (!isPowerOf2_64(IntValue)) 7059 return Error(ExprLoc, "literal value not a power of two greater then zero"); 7060 7061 Info.AsmRewrites->emplace_back(AOK_Align, IDLoc, 5, Log2_64(IntValue)); 7062 return false; 7063 } 7064 7065 bool MasmParser::parseDirectiveRadix(SMLoc DirectiveLoc) { 7066 const SMLoc Loc = getLexer().getLoc(); 7067 std::string RadixStringRaw = parseStringTo(AsmToken::EndOfStatement); 7068 StringRef RadixString = StringRef(RadixStringRaw).trim(); 7069 unsigned Radix; 7070 if (RadixString.getAsInteger(10, Radix)) { 7071 return Error(Loc, 7072 "radix must be a decimal number in the range 2 to 16; was " + 7073 RadixString); 7074 } 7075 if (Radix < 2 || Radix > 16) 7076 return Error(Loc, "radix must be in the range 2 to 16; was " + 7077 std::to_string(Radix)); 7078 getLexer().setMasmDefaultRadix(Radix); 7079 return false; 7080 } 7081 7082 /// parseDirectiveEcho 7083 /// ::= "echo" message 7084 bool MasmParser::parseDirectiveEcho() { 7085 // We're called before the directive is parsed, to avoid triggering lexical 7086 // substitutions in the message. Assert that the next token is the directive, 7087 // then eat it without using the Parser's Lex method. 7088 assert(getTok().is(AsmToken::Identifier) && 7089 getTok().getString().equals_insensitive("echo")); 7090 Lexer.Lex(); 7091 7092 std::string Message = parseStringTo(AsmToken::EndOfStatement); 7093 llvm::outs() << Message; 7094 if (!StringRef(Message).endswith("\n")) 7095 llvm::outs() << '\n'; 7096 return false; 7097 } 7098 7099 // We are comparing pointers, but the pointers are relative to a single string. 7100 // Thus, this should always be deterministic. 7101 static int rewritesSort(const AsmRewrite *AsmRewriteA, 7102 const AsmRewrite *AsmRewriteB) { 7103 if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer()) 7104 return -1; 7105 if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer()) 7106 return 1; 7107 7108 // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output 7109 // rewrite to the same location. Make sure the SizeDirective rewrite is 7110 // performed first, then the Imm/ImmPrefix and finally the Input/Output. This 7111 // ensures the sort algorithm is stable. 7112 if (AsmRewritePrecedence[AsmRewriteA->Kind] > 7113 AsmRewritePrecedence[AsmRewriteB->Kind]) 7114 return -1; 7115 7116 if (AsmRewritePrecedence[AsmRewriteA->Kind] < 7117 AsmRewritePrecedence[AsmRewriteB->Kind]) 7118 return 1; 7119 llvm_unreachable("Unstable rewrite sort."); 7120 } 7121 7122 bool MasmParser::defineMacro(StringRef Name, StringRef Value) { 7123 Variable &Var = Variables[Name.lower()]; 7124 if (Var.Name.empty()) { 7125 Var.Name = Name; 7126 } else if (Var.Redefinable == Variable::NOT_REDEFINABLE) { 7127 return Error(SMLoc(), "invalid variable redefinition"); 7128 } else if (Var.Redefinable == Variable::WARN_ON_REDEFINITION && 7129 Warning(SMLoc(), "redefining '" + Name + 7130 "', already defined on the command line")) { 7131 return true; 7132 } 7133 Var.Redefinable = Variable::WARN_ON_REDEFINITION; 7134 Var.IsText = true; 7135 Var.TextValue = Value.str(); 7136 return false; 7137 } 7138 7139 bool MasmParser::lookUpField(StringRef Name, AsmFieldInfo &Info) const { 7140 const std::pair<StringRef, StringRef> BaseMember = Name.split('.'); 7141 const StringRef Base = BaseMember.first, Member = BaseMember.second; 7142 return lookUpField(Base, Member, Info); 7143 } 7144 7145 bool MasmParser::lookUpField(StringRef Base, StringRef Member, 7146 AsmFieldInfo &Info) const { 7147 if (Base.empty()) 7148 return true; 7149 7150 AsmFieldInfo BaseInfo; 7151 if (Base.contains('.') && !lookUpField(Base, BaseInfo)) 7152 Base = BaseInfo.Type.Name; 7153 7154 auto StructIt = Structs.find(Base.lower()); 7155 auto TypeIt = KnownType.find(Base.lower()); 7156 if (TypeIt != KnownType.end()) { 7157 StructIt = Structs.find(TypeIt->second.Name.lower()); 7158 } 7159 if (StructIt != Structs.end()) 7160 return lookUpField(StructIt->second, Member, Info); 7161 7162 return true; 7163 } 7164 7165 bool MasmParser::lookUpField(const StructInfo &Structure, StringRef Member, 7166 AsmFieldInfo &Info) const { 7167 if (Member.empty()) { 7168 Info.Type.Name = Structure.Name; 7169 Info.Type.Size = Structure.Size; 7170 Info.Type.ElementSize = Structure.Size; 7171 Info.Type.Length = 1; 7172 return false; 7173 } 7174 7175 std::pair<StringRef, StringRef> Split = Member.split('.'); 7176 const StringRef FieldName = Split.first, FieldMember = Split.second; 7177 7178 auto StructIt = Structs.find(FieldName.lower()); 7179 if (StructIt != Structs.end()) 7180 return lookUpField(StructIt->second, FieldMember, Info); 7181 7182 auto FieldIt = Structure.FieldsByName.find(FieldName.lower()); 7183 if (FieldIt == Structure.FieldsByName.end()) 7184 return true; 7185 7186 const FieldInfo &Field = Structure.Fields[FieldIt->second]; 7187 if (FieldMember.empty()) { 7188 Info.Offset += Field.Offset; 7189 Info.Type.Size = Field.SizeOf; 7190 Info.Type.ElementSize = Field.Type; 7191 Info.Type.Length = Field.LengthOf; 7192 if (Field.Contents.FT == FT_STRUCT) 7193 Info.Type.Name = Field.Contents.StructInfo.Structure.Name; 7194 else 7195 Info.Type.Name = ""; 7196 return false; 7197 } 7198 7199 if (Field.Contents.FT != FT_STRUCT) 7200 return true; 7201 const StructFieldInfo &StructInfo = Field.Contents.StructInfo; 7202 7203 if (lookUpField(StructInfo.Structure, FieldMember, Info)) 7204 return true; 7205 7206 Info.Offset += Field.Offset; 7207 return false; 7208 } 7209 7210 bool MasmParser::lookUpType(StringRef Name, AsmTypeInfo &Info) const { 7211 unsigned Size = StringSwitch<unsigned>(Name) 7212 .CasesLower("byte", "db", "sbyte", 1) 7213 .CasesLower("word", "dw", "sword", 2) 7214 .CasesLower("dword", "dd", "sdword", 4) 7215 .CasesLower("fword", "df", 6) 7216 .CasesLower("qword", "dq", "sqword", 8) 7217 .CaseLower("real4", 4) 7218 .CaseLower("real8", 8) 7219 .CaseLower("real10", 10) 7220 .Default(0); 7221 if (Size) { 7222 Info.Name = Name; 7223 Info.ElementSize = Size; 7224 Info.Length = 1; 7225 Info.Size = Size; 7226 return false; 7227 } 7228 7229 auto StructIt = Structs.find(Name.lower()); 7230 if (StructIt != Structs.end()) { 7231 const StructInfo &Structure = StructIt->second; 7232 Info.Name = Name; 7233 Info.ElementSize = Structure.Size; 7234 Info.Length = 1; 7235 Info.Size = Structure.Size; 7236 return false; 7237 } 7238 7239 return true; 7240 } 7241 7242 bool MasmParser::parseMSInlineAsm( 7243 void *AsmLoc, std::string &AsmString, unsigned &NumOutputs, 7244 unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls, 7245 SmallVectorImpl<std::string> &Constraints, 7246 SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII, 7247 const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) { 7248 SmallVector<void *, 4> InputDecls; 7249 SmallVector<void *, 4> OutputDecls; 7250 SmallVector<bool, 4> InputDeclsAddressOf; 7251 SmallVector<bool, 4> OutputDeclsAddressOf; 7252 SmallVector<std::string, 4> InputConstraints; 7253 SmallVector<std::string, 4> OutputConstraints; 7254 SmallVector<unsigned, 4> ClobberRegs; 7255 7256 SmallVector<AsmRewrite, 4> AsmStrRewrites; 7257 7258 // Prime the lexer. 7259 Lex(); 7260 7261 // While we have input, parse each statement. 7262 unsigned InputIdx = 0; 7263 unsigned OutputIdx = 0; 7264 while (getLexer().isNot(AsmToken::Eof)) { 7265 // Parse curly braces marking block start/end. 7266 if (parseCurlyBlockScope(AsmStrRewrites)) 7267 continue; 7268 7269 ParseStatementInfo Info(&AsmStrRewrites); 7270 bool StatementErr = parseStatement(Info, &SI); 7271 7272 if (StatementErr || Info.ParseError) { 7273 // Emit pending errors if any exist. 7274 printPendingErrors(); 7275 return true; 7276 } 7277 7278 // No pending error should exist here. 7279 assert(!hasPendingError() && "unexpected error from parseStatement"); 7280 7281 if (Info.Opcode == ~0U) 7282 continue; 7283 7284 const MCInstrDesc &Desc = MII->get(Info.Opcode); 7285 7286 // Build the list of clobbers, outputs and inputs. 7287 for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) { 7288 MCParsedAsmOperand &Operand = *Info.ParsedOperands[i]; 7289 7290 // Register operand. 7291 if (Operand.isReg() && !Operand.needAddressOf() && 7292 !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) { 7293 unsigned NumDefs = Desc.getNumDefs(); 7294 // Clobber. 7295 if (NumDefs && Operand.getMCOperandNum() < NumDefs) 7296 ClobberRegs.push_back(Operand.getReg()); 7297 continue; 7298 } 7299 7300 // Expr/Input or Output. 7301 StringRef SymName = Operand.getSymName(); 7302 if (SymName.empty()) 7303 continue; 7304 7305 void *OpDecl = Operand.getOpDecl(); 7306 if (!OpDecl) 7307 continue; 7308 7309 StringRef Constraint = Operand.getConstraint(); 7310 if (Operand.isImm()) { 7311 // Offset as immediate. 7312 if (Operand.isOffsetOfLocal()) 7313 Constraint = "r"; 7314 else 7315 Constraint = "i"; 7316 } 7317 7318 bool isOutput = (i == 1) && Desc.mayStore(); 7319 SMLoc Start = SMLoc::getFromPointer(SymName.data()); 7320 if (isOutput) { 7321 ++InputIdx; 7322 OutputDecls.push_back(OpDecl); 7323 OutputDeclsAddressOf.push_back(Operand.needAddressOf()); 7324 OutputConstraints.push_back(("=" + Constraint).str()); 7325 AsmStrRewrites.emplace_back(AOK_Output, Start, SymName.size()); 7326 } else { 7327 InputDecls.push_back(OpDecl); 7328 InputDeclsAddressOf.push_back(Operand.needAddressOf()); 7329 InputConstraints.push_back(Constraint.str()); 7330 if (Desc.OpInfo[i - 1].isBranchTarget()) 7331 AsmStrRewrites.emplace_back(AOK_CallInput, Start, SymName.size()); 7332 else 7333 AsmStrRewrites.emplace_back(AOK_Input, Start, SymName.size()); 7334 } 7335 } 7336 7337 // Consider implicit defs to be clobbers. Think of cpuid and push. 7338 ArrayRef<MCPhysReg> ImpDefs(Desc.getImplicitDefs(), 7339 Desc.getNumImplicitDefs()); 7340 llvm::append_range(ClobberRegs, ImpDefs); 7341 } 7342 7343 // Set the number of Outputs and Inputs. 7344 NumOutputs = OutputDecls.size(); 7345 NumInputs = InputDecls.size(); 7346 7347 // Set the unique clobbers. 7348 array_pod_sort(ClobberRegs.begin(), ClobberRegs.end()); 7349 ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()), 7350 ClobberRegs.end()); 7351 Clobbers.assign(ClobberRegs.size(), std::string()); 7352 for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) { 7353 raw_string_ostream OS(Clobbers[I]); 7354 IP->printRegName(OS, ClobberRegs[I]); 7355 } 7356 7357 // Merge the various outputs and inputs. Output are expected first. 7358 if (NumOutputs || NumInputs) { 7359 unsigned NumExprs = NumOutputs + NumInputs; 7360 OpDecls.resize(NumExprs); 7361 Constraints.resize(NumExprs); 7362 for (unsigned i = 0; i < NumOutputs; ++i) { 7363 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]); 7364 Constraints[i] = OutputConstraints[i]; 7365 } 7366 for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) { 7367 OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]); 7368 Constraints[j] = InputConstraints[i]; 7369 } 7370 } 7371 7372 // Build the IR assembly string. 7373 std::string AsmStringIR; 7374 raw_string_ostream OS(AsmStringIR); 7375 StringRef ASMString = 7376 SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer(); 7377 const char *AsmStart = ASMString.begin(); 7378 const char *AsmEnd = ASMString.end(); 7379 array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort); 7380 for (auto it = AsmStrRewrites.begin(); it != AsmStrRewrites.end(); ++it) { 7381 const AsmRewrite &AR = *it; 7382 // Check if this has already been covered by another rewrite... 7383 if (AR.Done) 7384 continue; 7385 AsmRewriteKind Kind = AR.Kind; 7386 7387 const char *Loc = AR.Loc.getPointer(); 7388 assert(Loc >= AsmStart && "Expected Loc to be at or after Start!"); 7389 7390 // Emit everything up to the immediate/expression. 7391 if (unsigned Len = Loc - AsmStart) 7392 OS << StringRef(AsmStart, Len); 7393 7394 // Skip the original expression. 7395 if (Kind == AOK_Skip) { 7396 AsmStart = Loc + AR.Len; 7397 continue; 7398 } 7399 7400 unsigned AdditionalSkip = 0; 7401 // Rewrite expressions in $N notation. 7402 switch (Kind) { 7403 default: 7404 break; 7405 case AOK_IntelExpr: 7406 assert(AR.IntelExp.isValid() && "cannot write invalid intel expression"); 7407 if (AR.IntelExp.NeedBracs) 7408 OS << "["; 7409 if (AR.IntelExp.hasBaseReg()) 7410 OS << AR.IntelExp.BaseReg; 7411 if (AR.IntelExp.hasIndexReg()) 7412 OS << (AR.IntelExp.hasBaseReg() ? " + " : "") 7413 << AR.IntelExp.IndexReg; 7414 if (AR.IntelExp.Scale > 1) 7415 OS << " * $$" << AR.IntelExp.Scale; 7416 if (AR.IntelExp.hasOffset()) { 7417 if (AR.IntelExp.hasRegs()) 7418 OS << " + "; 7419 // Fuse this rewrite with a rewrite of the offset name, if present. 7420 StringRef OffsetName = AR.IntelExp.OffsetName; 7421 SMLoc OffsetLoc = SMLoc::getFromPointer(AR.IntelExp.OffsetName.data()); 7422 size_t OffsetLen = OffsetName.size(); 7423 auto rewrite_it = std::find_if( 7424 it, AsmStrRewrites.end(), [&](const AsmRewrite &FusingAR) { 7425 return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen && 7426 (FusingAR.Kind == AOK_Input || 7427 FusingAR.Kind == AOK_CallInput); 7428 }); 7429 if (rewrite_it == AsmStrRewrites.end()) { 7430 OS << "offset " << OffsetName; 7431 } else if (rewrite_it->Kind == AOK_CallInput) { 7432 OS << "${" << InputIdx++ << ":P}"; 7433 rewrite_it->Done = true; 7434 } else { 7435 OS << '$' << InputIdx++; 7436 rewrite_it->Done = true; 7437 } 7438 } 7439 if (AR.IntelExp.Imm || AR.IntelExp.emitImm()) 7440 OS << (AR.IntelExp.emitImm() ? "$$" : " + $$") << AR.IntelExp.Imm; 7441 if (AR.IntelExp.NeedBracs) 7442 OS << "]"; 7443 break; 7444 case AOK_Label: 7445 OS << Ctx.getAsmInfo()->getPrivateLabelPrefix() << AR.Label; 7446 break; 7447 case AOK_Input: 7448 OS << '$' << InputIdx++; 7449 break; 7450 case AOK_CallInput: 7451 OS << "${" << InputIdx++ << ":P}"; 7452 break; 7453 case AOK_Output: 7454 OS << '$' << OutputIdx++; 7455 break; 7456 case AOK_SizeDirective: 7457 switch (AR.Val) { 7458 default: break; 7459 case 8: OS << "byte ptr "; break; 7460 case 16: OS << "word ptr "; break; 7461 case 32: OS << "dword ptr "; break; 7462 case 64: OS << "qword ptr "; break; 7463 case 80: OS << "xword ptr "; break; 7464 case 128: OS << "xmmword ptr "; break; 7465 case 256: OS << "ymmword ptr "; break; 7466 } 7467 break; 7468 case AOK_Emit: 7469 OS << ".byte"; 7470 break; 7471 case AOK_Align: { 7472 // MS alignment directives are measured in bytes. If the native assembler 7473 // measures alignment in bytes, we can pass it straight through. 7474 OS << ".align"; 7475 if (getContext().getAsmInfo()->getAlignmentIsInBytes()) 7476 break; 7477 7478 // Alignment is in log2 form, so print that instead and skip the original 7479 // immediate. 7480 unsigned Val = AR.Val; 7481 OS << ' ' << Val; 7482 assert(Val < 10 && "Expected alignment less then 2^10."); 7483 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4; 7484 break; 7485 } 7486 case AOK_EVEN: 7487 OS << ".even"; 7488 break; 7489 case AOK_EndOfStatement: 7490 OS << "\n\t"; 7491 break; 7492 } 7493 7494 // Skip the original expression. 7495 AsmStart = Loc + AR.Len + AdditionalSkip; 7496 } 7497 7498 // Emit the remainder of the asm string. 7499 if (AsmStart != AsmEnd) 7500 OS << StringRef(AsmStart, AsmEnd - AsmStart); 7501 7502 AsmString = OS.str(); 7503 return false; 7504 } 7505 7506 /// Create an MCAsmParser instance. 7507 MCAsmParser *llvm::createMCMasmParser(SourceMgr &SM, MCContext &C, 7508 MCStreamer &Out, const MCAsmInfo &MAI, 7509 unsigned CB) { 7510 return new MasmParser(SM, C, Out, MAI, CB); 7511 } 7512