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