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("xor", AsmToken::Caret) 2032 .CaseLower("shl", AsmToken::LessLess) 2033 .CaseLower("shr", AsmToken::GreaterGreater) 2034 .CaseLower("eq", AsmToken::EqualEqual) 2035 .CaseLower("ne", AsmToken::ExclaimEqual) 2036 .CaseLower("lt", AsmToken::Less) 2037 .CaseLower("le", AsmToken::LessEqual) 2038 .CaseLower("gt", AsmToken::Greater) 2039 .CaseLower("ge", AsmToken::GreaterEqual) 2040 .Default(TokKind); 2041 } 2042 MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add; 2043 unsigned TokPrec = getBinOpPrecedence(TokKind, Kind); 2044 2045 // If the next token is lower precedence than we are allowed to eat, return 2046 // successfully with what we ate already. 2047 if (TokPrec < Precedence) 2048 return false; 2049 2050 Lex(); 2051 2052 // Eat the next primary expression. 2053 const MCExpr *RHS; 2054 if (getTargetParser().parsePrimaryExpr(RHS, EndLoc)) 2055 return true; 2056 2057 // If BinOp binds less tightly with RHS than the operator after RHS, let 2058 // the pending operator take RHS as its LHS. 2059 MCBinaryExpr::Opcode Dummy; 2060 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy); 2061 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc)) 2062 return true; 2063 2064 // Merge LHS and RHS according to operator. 2065 Res = MCBinaryExpr::create(Kind, Res, RHS, getContext(), StartLoc); 2066 } 2067 } 2068 2069 /// ParseStatement: 2070 /// ::= % statement 2071 /// ::= EndOfStatement 2072 /// ::= Label* Directive ...Operands... EndOfStatement 2073 /// ::= Label* Identifier OperandList* EndOfStatement 2074 bool MasmParser::parseStatement(ParseStatementInfo &Info, 2075 MCAsmParserSemaCallback *SI) { 2076 assert(!hasPendingError() && "parseStatement started with pending error"); 2077 // Eat initial spaces and comments. 2078 while (Lexer.is(AsmToken::Space)) 2079 Lex(); 2080 if (Lexer.is(AsmToken::EndOfStatement)) { 2081 // If this is a line comment we can drop it safely. 2082 if (getTok().getString().empty() || getTok().getString().front() == '\r' || 2083 getTok().getString().front() == '\n') 2084 Out.addBlankLine(); 2085 Lex(); 2086 return false; 2087 } 2088 2089 // If preceded by an expansion operator, first expand all text macros and 2090 // macro functions. 2091 if (getTok().is(AsmToken::Percent)) { 2092 SMLoc ExpansionLoc = getTok().getLoc(); 2093 if (parseToken(AsmToken::Percent) || expandStatement(ExpansionLoc)) 2094 return true; 2095 } 2096 2097 // Statements always start with an identifier, unless we're dealing with a 2098 // processor directive (.386, .686, etc.) that lexes as a real. 2099 AsmToken ID = getTok(); 2100 SMLoc IDLoc = ID.getLoc(); 2101 StringRef IDVal; 2102 if (Lexer.is(AsmToken::HashDirective)) 2103 return parseCppHashLineFilenameComment(IDLoc); 2104 if (Lexer.is(AsmToken::Dot)) { 2105 // Treat '.' as a valid identifier in this context. 2106 Lex(); 2107 IDVal = "."; 2108 } else if (Lexer.is(AsmToken::LCurly)) { 2109 // Treat '{' as a valid identifier in this context. 2110 Lex(); 2111 IDVal = "{"; 2112 2113 } else if (Lexer.is(AsmToken::RCurly)) { 2114 // Treat '}' as a valid identifier in this context. 2115 Lex(); 2116 IDVal = "}"; 2117 } else if (Lexer.is(AsmToken::Star) && 2118 getTargetParser().starIsStartOfStatement()) { 2119 // Accept '*' as a valid start of statement. 2120 Lex(); 2121 IDVal = "*"; 2122 } else if (Lexer.is(AsmToken::Real)) { 2123 // Treat ".<number>" as a valid identifier in this context. 2124 IDVal = getTok().getString(); 2125 Lex(); // always eat a token 2126 if (!IDVal.startswith(".")) 2127 return Error(IDLoc, "unexpected token at start of statement"); 2128 } else if (parseIdentifier(IDVal, StartOfStatement)) { 2129 if (!TheCondState.Ignore) { 2130 Lex(); // always eat a token 2131 return Error(IDLoc, "unexpected token at start of statement"); 2132 } 2133 IDVal = ""; 2134 } 2135 2136 // Handle conditional assembly here before checking for skipping. We 2137 // have to do this so that .endif isn't skipped in a ".if 0" block for 2138 // example. 2139 StringMap<DirectiveKind>::const_iterator DirKindIt = 2140 DirectiveKindMap.find(IDVal.lower()); 2141 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end()) 2142 ? DK_NO_DIRECTIVE 2143 : DirKindIt->getValue(); 2144 switch (DirKind) { 2145 default: 2146 break; 2147 case DK_IF: 2148 case DK_IFE: 2149 return parseDirectiveIf(IDLoc, DirKind); 2150 case DK_IFB: 2151 return parseDirectiveIfb(IDLoc, true); 2152 case DK_IFNB: 2153 return parseDirectiveIfb(IDLoc, false); 2154 case DK_IFDEF: 2155 return parseDirectiveIfdef(IDLoc, true); 2156 case DK_IFNDEF: 2157 return parseDirectiveIfdef(IDLoc, false); 2158 case DK_IFDIF: 2159 return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/false, 2160 /*CaseInsensitive=*/false); 2161 case DK_IFDIFI: 2162 return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/false, 2163 /*CaseInsensitive=*/true); 2164 case DK_IFIDN: 2165 return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/true, 2166 /*CaseInsensitive=*/false); 2167 case DK_IFIDNI: 2168 return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/true, 2169 /*CaseInsensitive=*/true); 2170 case DK_ELSEIF: 2171 case DK_ELSEIFE: 2172 return parseDirectiveElseIf(IDLoc, DirKind); 2173 case DK_ELSEIFB: 2174 return parseDirectiveElseIfb(IDLoc, true); 2175 case DK_ELSEIFNB: 2176 return parseDirectiveElseIfb(IDLoc, false); 2177 case DK_ELSEIFDEF: 2178 return parseDirectiveElseIfdef(IDLoc, true); 2179 case DK_ELSEIFNDEF: 2180 return parseDirectiveElseIfdef(IDLoc, false); 2181 case DK_ELSEIFDIF: 2182 return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/false, 2183 /*CaseInsensitive=*/false); 2184 case DK_ELSEIFDIFI: 2185 return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/false, 2186 /*CaseInsensitive=*/true); 2187 case DK_ELSEIFIDN: 2188 return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/true, 2189 /*CaseInsensitive=*/false); 2190 case DK_ELSEIFIDNI: 2191 return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/true, 2192 /*CaseInsensitive=*/true); 2193 case DK_ELSE: 2194 return parseDirectiveElse(IDLoc); 2195 case DK_ENDIF: 2196 return parseDirectiveEndIf(IDLoc); 2197 } 2198 2199 // Ignore the statement if in the middle of inactive conditional 2200 // (e.g. ".if 0"). 2201 if (TheCondState.Ignore) { 2202 eatToEndOfStatement(); 2203 return false; 2204 } 2205 2206 // FIXME: Recurse on local labels? 2207 2208 // See what kind of statement we have. 2209 switch (Lexer.getKind()) { 2210 case AsmToken::Colon: { 2211 if (!getTargetParser().isLabel(ID)) 2212 break; 2213 if (checkForValidSection()) 2214 return true; 2215 2216 // identifier ':' -> Label. 2217 Lex(); 2218 2219 // Diagnose attempt to use '.' as a label. 2220 if (IDVal == ".") 2221 return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label"); 2222 2223 // Diagnose attempt to use a variable as a label. 2224 // 2225 // FIXME: Diagnostics. Note the location of the definition as a label. 2226 // FIXME: This doesn't diagnose assignment to a symbol which has been 2227 // implicitly marked as external. 2228 MCSymbol *Sym; 2229 if (ParsingMSInlineAsm && SI) { 2230 StringRef RewrittenLabel = 2231 SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true); 2232 assert(!RewrittenLabel.empty() && 2233 "We should have an internal name here."); 2234 Info.AsmRewrites->emplace_back(AOK_Label, IDLoc, IDVal.size(), 2235 RewrittenLabel); 2236 IDVal = RewrittenLabel; 2237 } 2238 // Handle directional local labels 2239 if (IDVal == "@@") { 2240 Sym = Ctx.createDirectionalLocalSymbol(0); 2241 } else { 2242 Sym = getContext().getOrCreateSymbol(IDVal); 2243 } 2244 2245 // End of Labels should be treated as end of line for lexing 2246 // purposes but that information is not available to the Lexer who 2247 // does not understand Labels. This may cause us to see a Hash 2248 // here instead of a preprocessor line comment. 2249 if (getTok().is(AsmToken::Hash)) { 2250 std::string CommentStr = parseStringTo(AsmToken::EndOfStatement); 2251 Lexer.Lex(); 2252 Lexer.UnLex(AsmToken(AsmToken::EndOfStatement, CommentStr)); 2253 } 2254 2255 // Consume any end of statement token, if present, to avoid spurious 2256 // addBlankLine calls(). 2257 if (getTok().is(AsmToken::EndOfStatement)) { 2258 Lex(); 2259 } 2260 2261 getTargetParser().doBeforeLabelEmit(Sym); 2262 2263 // Emit the label. 2264 if (!getTargetParser().isParsingMSInlineAsm()) 2265 Out.emitLabel(Sym, IDLoc); 2266 2267 // If we are generating dwarf for assembly source files then gather the 2268 // info to make a dwarf label entry for this label if needed. 2269 if (enabledGenDwarfForAssembly()) 2270 MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(), 2271 IDLoc); 2272 2273 getTargetParser().onLabelParsed(Sym); 2274 2275 return false; 2276 } 2277 2278 default: // Normal instruction or directive. 2279 break; 2280 } 2281 2282 // If macros are enabled, check to see if this is a macro instantiation. 2283 if (const MCAsmMacro *M = getContext().lookupMacro(IDVal.lower())) { 2284 return handleMacroEntry(M, IDLoc); 2285 } 2286 2287 // Otherwise, we have a normal instruction or directive. 2288 2289 if (DirKind != DK_NO_DIRECTIVE) { 2290 // There are several entities interested in parsing directives: 2291 // 2292 // 1. Asm parser extensions. For example, platform-specific parsers 2293 // (like the ELF parser) register themselves as extensions. 2294 // 2. The target-specific assembly parser. Some directives are target 2295 // specific or may potentially behave differently on certain targets. 2296 // 3. The generic directive parser implemented by this class. These are 2297 // all the directives that behave in a target and platform independent 2298 // manner, or at least have a default behavior that's shared between 2299 // all targets and platforms. 2300 2301 getTargetParser().flushPendingInstructions(getStreamer()); 2302 2303 // Special-case handling of structure-end directives at higher priority, 2304 // since ENDS is overloaded as a segment-end directive. 2305 if (IDVal.equals_insensitive("ends") && StructInProgress.size() > 1 && 2306 getTok().is(AsmToken::EndOfStatement)) { 2307 return parseDirectiveNestedEnds(); 2308 } 2309 2310 // First, check the extension directive map to see if any extension has 2311 // registered itself to parse this directive. 2312 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler = 2313 ExtensionDirectiveMap.lookup(IDVal.lower()); 2314 if (Handler.first) 2315 return (*Handler.second)(Handler.first, IDVal, IDLoc); 2316 2317 // Next, let the target-specific assembly parser try. 2318 SMLoc StartTokLoc = getTok().getLoc(); 2319 bool TPDirectiveReturn = 2320 ID.is(AsmToken::Identifier) && getTargetParser().ParseDirective(ID); 2321 2322 if (hasPendingError()) 2323 return true; 2324 // Currently the return value should be true if we are 2325 // uninterested but as this is at odds with the standard parsing 2326 // convention (return true = error) we have instances of a parsed 2327 // directive that fails returning true as an error. Catch these 2328 // cases as best as possible errors here. 2329 if (TPDirectiveReturn && StartTokLoc != getTok().getLoc()) 2330 return true; 2331 // Return if we did some parsing or believe we succeeded. 2332 if (!TPDirectiveReturn || StartTokLoc != getTok().getLoc()) 2333 return false; 2334 2335 // Finally, if no one else is interested in this directive, it must be 2336 // generic and familiar to this class. 2337 switch (DirKind) { 2338 default: 2339 break; 2340 case DK_ASCII: 2341 return parseDirectiveAscii(IDVal, false); 2342 case DK_ASCIZ: 2343 case DK_STRING: 2344 return parseDirectiveAscii(IDVal, true); 2345 case DK_BYTE: 2346 case DK_SBYTE: 2347 case DK_DB: 2348 return parseDirectiveValue(IDVal, 1); 2349 case DK_WORD: 2350 case DK_SWORD: 2351 case DK_DW: 2352 return parseDirectiveValue(IDVal, 2); 2353 case DK_DWORD: 2354 case DK_SDWORD: 2355 case DK_DD: 2356 return parseDirectiveValue(IDVal, 4); 2357 case DK_FWORD: 2358 case DK_DF: 2359 return parseDirectiveValue(IDVal, 6); 2360 case DK_QWORD: 2361 case DK_SQWORD: 2362 case DK_DQ: 2363 return parseDirectiveValue(IDVal, 8); 2364 case DK_REAL4: 2365 return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle(), 4); 2366 case DK_REAL8: 2367 return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble(), 8); 2368 case DK_REAL10: 2369 return parseDirectiveRealValue(IDVal, APFloat::x87DoubleExtended(), 10); 2370 case DK_STRUCT: 2371 case DK_UNION: 2372 return parseDirectiveNestedStruct(IDVal, DirKind); 2373 case DK_ENDS: 2374 return parseDirectiveNestedEnds(); 2375 case DK_ALIGN: 2376 return parseDirectiveAlign(); 2377 case DK_EVEN: 2378 return parseDirectiveEven(); 2379 case DK_ORG: 2380 return parseDirectiveOrg(); 2381 case DK_EXTERN: 2382 return parseDirectiveExtern(); 2383 case DK_PUBLIC: 2384 return parseDirectiveSymbolAttribute(MCSA_Global); 2385 case DK_COMM: 2386 return parseDirectiveComm(/*IsLocal=*/false); 2387 case DK_COMMENT: 2388 return parseDirectiveComment(IDLoc); 2389 case DK_INCLUDE: 2390 return parseDirectiveInclude(); 2391 case DK_REPEAT: 2392 return parseDirectiveRepeat(IDLoc, IDVal); 2393 case DK_WHILE: 2394 return parseDirectiveWhile(IDLoc); 2395 case DK_FOR: 2396 return parseDirectiveFor(IDLoc, IDVal); 2397 case DK_FORC: 2398 return parseDirectiveForc(IDLoc, IDVal); 2399 case DK_FILE: 2400 return parseDirectiveFile(IDLoc); 2401 case DK_LINE: 2402 return parseDirectiveLine(); 2403 case DK_LOC: 2404 return parseDirectiveLoc(); 2405 case DK_STABS: 2406 return parseDirectiveStabs(); 2407 case DK_CV_FILE: 2408 return parseDirectiveCVFile(); 2409 case DK_CV_FUNC_ID: 2410 return parseDirectiveCVFuncId(); 2411 case DK_CV_INLINE_SITE_ID: 2412 return parseDirectiveCVInlineSiteId(); 2413 case DK_CV_LOC: 2414 return parseDirectiveCVLoc(); 2415 case DK_CV_LINETABLE: 2416 return parseDirectiveCVLinetable(); 2417 case DK_CV_INLINE_LINETABLE: 2418 return parseDirectiveCVInlineLinetable(); 2419 case DK_CV_DEF_RANGE: 2420 return parseDirectiveCVDefRange(); 2421 case DK_CV_STRING: 2422 return parseDirectiveCVString(); 2423 case DK_CV_STRINGTABLE: 2424 return parseDirectiveCVStringTable(); 2425 case DK_CV_FILECHECKSUMS: 2426 return parseDirectiveCVFileChecksums(); 2427 case DK_CV_FILECHECKSUM_OFFSET: 2428 return parseDirectiveCVFileChecksumOffset(); 2429 case DK_CV_FPO_DATA: 2430 return parseDirectiveCVFPOData(); 2431 case DK_CFI_SECTIONS: 2432 return parseDirectiveCFISections(); 2433 case DK_CFI_STARTPROC: 2434 return parseDirectiveCFIStartProc(); 2435 case DK_CFI_ENDPROC: 2436 return parseDirectiveCFIEndProc(); 2437 case DK_CFI_DEF_CFA: 2438 return parseDirectiveCFIDefCfa(IDLoc); 2439 case DK_CFI_DEF_CFA_OFFSET: 2440 return parseDirectiveCFIDefCfaOffset(); 2441 case DK_CFI_ADJUST_CFA_OFFSET: 2442 return parseDirectiveCFIAdjustCfaOffset(); 2443 case DK_CFI_DEF_CFA_REGISTER: 2444 return parseDirectiveCFIDefCfaRegister(IDLoc); 2445 case DK_CFI_OFFSET: 2446 return parseDirectiveCFIOffset(IDLoc); 2447 case DK_CFI_REL_OFFSET: 2448 return parseDirectiveCFIRelOffset(IDLoc); 2449 case DK_CFI_PERSONALITY: 2450 return parseDirectiveCFIPersonalityOrLsda(true); 2451 case DK_CFI_LSDA: 2452 return parseDirectiveCFIPersonalityOrLsda(false); 2453 case DK_CFI_REMEMBER_STATE: 2454 return parseDirectiveCFIRememberState(); 2455 case DK_CFI_RESTORE_STATE: 2456 return parseDirectiveCFIRestoreState(); 2457 case DK_CFI_SAME_VALUE: 2458 return parseDirectiveCFISameValue(IDLoc); 2459 case DK_CFI_RESTORE: 2460 return parseDirectiveCFIRestore(IDLoc); 2461 case DK_CFI_ESCAPE: 2462 return parseDirectiveCFIEscape(); 2463 case DK_CFI_RETURN_COLUMN: 2464 return parseDirectiveCFIReturnColumn(IDLoc); 2465 case DK_CFI_SIGNAL_FRAME: 2466 return parseDirectiveCFISignalFrame(); 2467 case DK_CFI_UNDEFINED: 2468 return parseDirectiveCFIUndefined(IDLoc); 2469 case DK_CFI_REGISTER: 2470 return parseDirectiveCFIRegister(IDLoc); 2471 case DK_CFI_WINDOW_SAVE: 2472 return parseDirectiveCFIWindowSave(); 2473 case DK_EXITM: 2474 Info.ExitValue = ""; 2475 return parseDirectiveExitMacro(IDLoc, IDVal, *Info.ExitValue); 2476 case DK_ENDM: 2477 Info.ExitValue = ""; 2478 return parseDirectiveEndMacro(IDVal); 2479 case DK_PURGE: 2480 return parseDirectivePurgeMacro(IDLoc); 2481 case DK_END: 2482 return parseDirectiveEnd(IDLoc); 2483 case DK_ERR: 2484 return parseDirectiveError(IDLoc); 2485 case DK_ERRB: 2486 return parseDirectiveErrorIfb(IDLoc, true); 2487 case DK_ERRNB: 2488 return parseDirectiveErrorIfb(IDLoc, false); 2489 case DK_ERRDEF: 2490 return parseDirectiveErrorIfdef(IDLoc, true); 2491 case DK_ERRNDEF: 2492 return parseDirectiveErrorIfdef(IDLoc, false); 2493 case DK_ERRDIF: 2494 return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/false, 2495 /*CaseInsensitive=*/false); 2496 case DK_ERRDIFI: 2497 return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/false, 2498 /*CaseInsensitive=*/true); 2499 case DK_ERRIDN: 2500 return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/true, 2501 /*CaseInsensitive=*/false); 2502 case DK_ERRIDNI: 2503 return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/true, 2504 /*CaseInsensitive=*/true); 2505 case DK_ERRE: 2506 return parseDirectiveErrorIfe(IDLoc, true); 2507 case DK_ERRNZ: 2508 return parseDirectiveErrorIfe(IDLoc, false); 2509 case DK_RADIX: 2510 return parseDirectiveRadix(IDLoc); 2511 case DK_ECHO: 2512 return parseDirectiveEcho(IDLoc); 2513 } 2514 2515 return Error(IDLoc, "unknown directive"); 2516 } 2517 2518 // We also check if this is allocating memory with user-defined type. 2519 auto IDIt = Structs.find(IDVal.lower()); 2520 if (IDIt != Structs.end()) 2521 return parseDirectiveStructValue(/*Structure=*/IDIt->getValue(), IDVal, 2522 IDLoc); 2523 2524 // Non-conditional Microsoft directives sometimes follow their first argument. 2525 const AsmToken nextTok = getTok(); 2526 const StringRef nextVal = nextTok.getString(); 2527 const SMLoc nextLoc = nextTok.getLoc(); 2528 2529 const AsmToken afterNextTok = peekTok(); 2530 2531 // There are several entities interested in parsing infix directives: 2532 // 2533 // 1. Asm parser extensions. For example, platform-specific parsers 2534 // (like the ELF parser) register themselves as extensions. 2535 // 2. The generic directive parser implemented by this class. These are 2536 // all the directives that behave in a target and platform independent 2537 // manner, or at least have a default behavior that's shared between 2538 // all targets and platforms. 2539 2540 getTargetParser().flushPendingInstructions(getStreamer()); 2541 2542 // Special-case handling of structure-end directives at higher priority, since 2543 // ENDS is overloaded as a segment-end directive. 2544 if (nextVal.equals_insensitive("ends") && StructInProgress.size() == 1) { 2545 Lex(); 2546 return parseDirectiveEnds(IDVal, IDLoc); 2547 } 2548 2549 // First, check the extension directive map to see if any extension has 2550 // registered itself to parse this directive. 2551 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler = 2552 ExtensionDirectiveMap.lookup(nextVal.lower()); 2553 if (Handler.first) { 2554 Lex(); 2555 Lexer.UnLex(ID); 2556 return (*Handler.second)(Handler.first, nextVal, nextLoc); 2557 } 2558 2559 // If no one else is interested in this directive, it must be 2560 // generic and familiar to this class. 2561 DirKindIt = DirectiveKindMap.find(nextVal.lower()); 2562 DirKind = (DirKindIt == DirectiveKindMap.end()) 2563 ? DK_NO_DIRECTIVE 2564 : DirKindIt->getValue(); 2565 switch (DirKind) { 2566 default: 2567 break; 2568 case DK_ASSIGN: 2569 case DK_EQU: 2570 case DK_TEXTEQU: 2571 Lex(); 2572 return parseDirectiveEquate(nextVal, IDVal, DirKind, IDLoc); 2573 case DK_BYTE: 2574 if (afterNextTok.is(AsmToken::Identifier) && 2575 afterNextTok.getString().equals_insensitive("ptr")) { 2576 // Size directive; part of an instruction. 2577 break; 2578 } 2579 LLVM_FALLTHROUGH; 2580 case DK_SBYTE: 2581 case DK_DB: 2582 Lex(); 2583 return parseDirectiveNamedValue(nextVal, 1, IDVal, IDLoc); 2584 case DK_WORD: 2585 if (afterNextTok.is(AsmToken::Identifier) && 2586 afterNextTok.getString().equals_insensitive("ptr")) { 2587 // Size directive; part of an instruction. 2588 break; 2589 } 2590 LLVM_FALLTHROUGH; 2591 case DK_SWORD: 2592 case DK_DW: 2593 Lex(); 2594 return parseDirectiveNamedValue(nextVal, 2, IDVal, IDLoc); 2595 case DK_DWORD: 2596 if (afterNextTok.is(AsmToken::Identifier) && 2597 afterNextTok.getString().equals_insensitive("ptr")) { 2598 // Size directive; part of an instruction. 2599 break; 2600 } 2601 LLVM_FALLTHROUGH; 2602 case DK_SDWORD: 2603 case DK_DD: 2604 Lex(); 2605 return parseDirectiveNamedValue(nextVal, 4, IDVal, IDLoc); 2606 case DK_FWORD: 2607 if (afterNextTok.is(AsmToken::Identifier) && 2608 afterNextTok.getString().equals_insensitive("ptr")) { 2609 // Size directive; part of an instruction. 2610 break; 2611 } 2612 LLVM_FALLTHROUGH; 2613 case DK_DF: 2614 Lex(); 2615 return parseDirectiveNamedValue(nextVal, 6, IDVal, IDLoc); 2616 case DK_QWORD: 2617 if (afterNextTok.is(AsmToken::Identifier) && 2618 afterNextTok.getString().equals_insensitive("ptr")) { 2619 // Size directive; part of an instruction. 2620 break; 2621 } 2622 LLVM_FALLTHROUGH; 2623 case DK_SQWORD: 2624 case DK_DQ: 2625 Lex(); 2626 return parseDirectiveNamedValue(nextVal, 8, IDVal, IDLoc); 2627 case DK_REAL4: 2628 Lex(); 2629 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEsingle(), 4, 2630 IDVal, IDLoc); 2631 case DK_REAL8: 2632 Lex(); 2633 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEdouble(), 8, 2634 IDVal, IDLoc); 2635 case DK_REAL10: 2636 Lex(); 2637 return parseDirectiveNamedRealValue(nextVal, APFloat::x87DoubleExtended(), 2638 10, IDVal, IDLoc); 2639 case DK_STRUCT: 2640 case DK_UNION: 2641 Lex(); 2642 return parseDirectiveStruct(nextVal, DirKind, IDVal, IDLoc); 2643 case DK_ENDS: 2644 Lex(); 2645 return parseDirectiveEnds(IDVal, IDLoc); 2646 case DK_MACRO: 2647 Lex(); 2648 return parseDirectiveMacro(IDVal, IDLoc); 2649 } 2650 2651 // Finally, we check if this is allocating a variable with user-defined type. 2652 auto NextIt = Structs.find(nextVal.lower()); 2653 if (NextIt != Structs.end()) { 2654 Lex(); 2655 return parseDirectiveNamedStructValue(/*Structure=*/NextIt->getValue(), 2656 nextVal, nextLoc, IDVal); 2657 } 2658 2659 // __asm _emit or __asm __emit 2660 if (ParsingMSInlineAsm && (IDVal == "_emit" || IDVal == "__emit" || 2661 IDVal == "_EMIT" || IDVal == "__EMIT")) 2662 return parseDirectiveMSEmit(IDLoc, Info, IDVal.size()); 2663 2664 // __asm align 2665 if (ParsingMSInlineAsm && (IDVal == "align" || IDVal == "ALIGN")) 2666 return parseDirectiveMSAlign(IDLoc, Info); 2667 2668 if (ParsingMSInlineAsm && (IDVal == "even" || IDVal == "EVEN")) 2669 Info.AsmRewrites->emplace_back(AOK_EVEN, IDLoc, 4); 2670 if (checkForValidSection()) 2671 return true; 2672 2673 // Canonicalize the opcode to lower case. 2674 std::string OpcodeStr = IDVal.lower(); 2675 ParseInstructionInfo IInfo(Info.AsmRewrites); 2676 bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID, 2677 Info.ParsedOperands); 2678 Info.ParseError = ParseHadError; 2679 2680 // Dump the parsed representation, if requested. 2681 if (getShowParsedOperands()) { 2682 SmallString<256> Str; 2683 raw_svector_ostream OS(Str); 2684 OS << "parsed instruction: ["; 2685 for (unsigned i = 0; i != Info.ParsedOperands.size(); ++i) { 2686 if (i != 0) 2687 OS << ", "; 2688 Info.ParsedOperands[i]->print(OS); 2689 } 2690 OS << "]"; 2691 2692 printMessage(IDLoc, SourceMgr::DK_Note, OS.str()); 2693 } 2694 2695 // Fail even if ParseInstruction erroneously returns false. 2696 if (hasPendingError() || ParseHadError) 2697 return true; 2698 2699 // If we are generating dwarf for the current section then generate a .loc 2700 // directive for the instruction. 2701 if (!ParseHadError && enabledGenDwarfForAssembly() && 2702 getContext().getGenDwarfSectionSyms().count( 2703 getStreamer().getCurrentSectionOnly())) { 2704 unsigned Line; 2705 if (ActiveMacros.empty()) 2706 Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer); 2707 else 2708 Line = SrcMgr.FindLineNumber(ActiveMacros.front()->InstantiationLoc, 2709 ActiveMacros.front()->ExitBuffer); 2710 2711 // If we previously parsed a cpp hash file line comment then make sure the 2712 // current Dwarf File is for the CppHashFilename if not then emit the 2713 // Dwarf File table for it and adjust the line number for the .loc. 2714 if (!CppHashInfo.Filename.empty()) { 2715 unsigned FileNumber = getStreamer().emitDwarfFileDirective( 2716 0, StringRef(), CppHashInfo.Filename); 2717 getContext().setGenDwarfFileNumber(FileNumber); 2718 2719 unsigned CppHashLocLineNo = 2720 SrcMgr.FindLineNumber(CppHashInfo.Loc, CppHashInfo.Buf); 2721 Line = CppHashInfo.LineNumber - 1 + (Line - CppHashLocLineNo); 2722 } 2723 2724 getStreamer().emitDwarfLocDirective( 2725 getContext().getGenDwarfFileNumber(), Line, 0, 2726 DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0, 0, 0, 2727 StringRef()); 2728 } 2729 2730 // If parsing succeeded, match the instruction. 2731 if (!ParseHadError) { 2732 uint64_t ErrorInfo; 2733 if (getTargetParser().MatchAndEmitInstruction( 2734 IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo, 2735 getTargetParser().isParsingMSInlineAsm())) 2736 return true; 2737 } 2738 return false; 2739 } 2740 2741 // Parse and erase curly braces marking block start/end. 2742 bool MasmParser::parseCurlyBlockScope( 2743 SmallVectorImpl<AsmRewrite> &AsmStrRewrites) { 2744 // Identify curly brace marking block start/end. 2745 if (Lexer.isNot(AsmToken::LCurly) && Lexer.isNot(AsmToken::RCurly)) 2746 return false; 2747 2748 SMLoc StartLoc = Lexer.getLoc(); 2749 Lex(); // Eat the brace. 2750 if (Lexer.is(AsmToken::EndOfStatement)) 2751 Lex(); // Eat EndOfStatement following the brace. 2752 2753 // Erase the block start/end brace from the output asm string. 2754 AsmStrRewrites.emplace_back(AOK_Skip, StartLoc, Lexer.getLoc().getPointer() - 2755 StartLoc.getPointer()); 2756 return true; 2757 } 2758 2759 /// parseCppHashLineFilenameComment as this: 2760 /// ::= # number "filename" 2761 bool MasmParser::parseCppHashLineFilenameComment(SMLoc L) { 2762 Lex(); // Eat the hash token. 2763 // Lexer only ever emits HashDirective if it fully formed if it's 2764 // done the checking already so this is an internal error. 2765 assert(getTok().is(AsmToken::Integer) && 2766 "Lexing Cpp line comment: Expected Integer"); 2767 int64_t LineNumber = getTok().getIntVal(); 2768 Lex(); 2769 assert(getTok().is(AsmToken::String) && 2770 "Lexing Cpp line comment: Expected String"); 2771 StringRef Filename = getTok().getString(); 2772 Lex(); 2773 2774 // Get rid of the enclosing quotes. 2775 Filename = Filename.substr(1, Filename.size() - 2); 2776 2777 // Save the SMLoc, Filename and LineNumber for later use by diagnostics 2778 // and possibly DWARF file info. 2779 CppHashInfo.Loc = L; 2780 CppHashInfo.Filename = Filename; 2781 CppHashInfo.LineNumber = LineNumber; 2782 CppHashInfo.Buf = CurBuffer; 2783 if (FirstCppHashFilename.empty()) 2784 FirstCppHashFilename = Filename; 2785 return false; 2786 } 2787 2788 /// will use the last parsed cpp hash line filename comment 2789 /// for the Filename and LineNo if any in the diagnostic. 2790 void MasmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { 2791 const MasmParser *Parser = static_cast<const MasmParser *>(Context); 2792 raw_ostream &OS = errs(); 2793 2794 const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr(); 2795 SMLoc DiagLoc = Diag.getLoc(); 2796 unsigned DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); 2797 unsigned CppHashBuf = 2798 Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc); 2799 2800 // Like SourceMgr::printMessage() we need to print the include stack if any 2801 // before printing the message. 2802 unsigned DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); 2803 if (!Parser->SavedDiagHandler && DiagCurBuffer && 2804 DiagCurBuffer != DiagSrcMgr.getMainFileID()) { 2805 SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer); 2806 DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS); 2807 } 2808 2809 // If we have not parsed a cpp hash line filename comment or the source 2810 // manager changed or buffer changed (like in a nested include) then just 2811 // print the normal diagnostic using its Filename and LineNo. 2812 if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr || 2813 DiagBuf != CppHashBuf) { 2814 if (Parser->SavedDiagHandler) 2815 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext); 2816 else 2817 Diag.print(nullptr, OS); 2818 return; 2819 } 2820 2821 // Use the CppHashFilename and calculate a line number based on the 2822 // CppHashInfo.Loc and CppHashInfo.LineNumber relative to this Diag's SMLoc 2823 // for the diagnostic. 2824 const std::string &Filename = std::string(Parser->CppHashInfo.Filename); 2825 2826 int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf); 2827 int CppHashLocLineNo = 2828 Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf); 2829 int LineNo = 2830 Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo); 2831 2832 SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo, 2833 Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(), 2834 Diag.getLineContents(), Diag.getRanges()); 2835 2836 if (Parser->SavedDiagHandler) 2837 Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext); 2838 else 2839 NewDiag.print(nullptr, OS); 2840 } 2841 2842 // This is similar to the IsIdentifierChar function in AsmLexer.cpp, but does 2843 // not accept '.'. 2844 static bool isMacroParameterChar(char C) { 2845 return isAlnum(C) || C == '_' || C == '$' || C == '@' || C == '?'; 2846 } 2847 2848 bool MasmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, 2849 ArrayRef<MCAsmMacroParameter> Parameters, 2850 ArrayRef<MCAsmMacroArgument> A, 2851 const std::vector<std::string> &Locals, SMLoc L) { 2852 unsigned NParameters = Parameters.size(); 2853 if (NParameters != A.size()) 2854 return Error(L, "Wrong number of arguments"); 2855 StringMap<std::string> LocalSymbols; 2856 std::string Name; 2857 Name.reserve(6); 2858 for (StringRef Local : Locals) { 2859 raw_string_ostream LocalName(Name); 2860 LocalName << "??" 2861 << format_hex_no_prefix(LocalCounter++, 4, /*Upper=*/true); 2862 LocalSymbols.insert({Local, LocalName.str()}); 2863 Name.clear(); 2864 } 2865 2866 Optional<char> CurrentQuote; 2867 while (!Body.empty()) { 2868 // Scan for the next substitution. 2869 std::size_t End = Body.size(), Pos = 0; 2870 std::size_t IdentifierPos = End; 2871 for (; Pos != End; ++Pos) { 2872 // Find the next possible macro parameter, including preceding a '&' 2873 // inside quotes. 2874 if (Body[Pos] == '&') 2875 break; 2876 if (isMacroParameterChar(Body[Pos])) { 2877 if (!CurrentQuote) 2878 break; 2879 if (IdentifierPos == End) 2880 IdentifierPos = Pos; 2881 } else { 2882 IdentifierPos = End; 2883 } 2884 2885 // Track quotation status 2886 if (!CurrentQuote) { 2887 if (Body[Pos] == '\'' || Body[Pos] == '"') 2888 CurrentQuote = Body[Pos]; 2889 } else if (Body[Pos] == CurrentQuote) { 2890 if (Pos + 1 != End && Body[Pos + 1] == CurrentQuote) { 2891 // Escaped quote, and quotes aren't identifier chars; skip 2892 ++Pos; 2893 continue; 2894 } else { 2895 CurrentQuote.reset(); 2896 } 2897 } 2898 } 2899 if (IdentifierPos != End) { 2900 // We've recognized an identifier before an apostrophe inside quotes; 2901 // check once to see if we can expand it. 2902 Pos = IdentifierPos; 2903 IdentifierPos = End; 2904 } 2905 2906 // Add the prefix. 2907 OS << Body.slice(0, Pos); 2908 2909 // Check if we reached the end. 2910 if (Pos == End) 2911 break; 2912 2913 unsigned I = Pos; 2914 bool InitialAmpersand = (Body[I] == '&'); 2915 if (InitialAmpersand) { 2916 ++I; 2917 ++Pos; 2918 } 2919 while (I < End && isMacroParameterChar(Body[I])) 2920 ++I; 2921 2922 const char *Begin = Body.data() + Pos; 2923 StringRef Argument(Begin, I - Pos); 2924 const std::string ArgumentLower = Argument.lower(); 2925 unsigned Index = 0; 2926 2927 for (; Index < NParameters; ++Index) 2928 if (Parameters[Index].Name.equals_insensitive(ArgumentLower)) 2929 break; 2930 2931 if (Index == NParameters) { 2932 if (InitialAmpersand) 2933 OS << '&'; 2934 auto it = LocalSymbols.find(ArgumentLower); 2935 if (it != LocalSymbols.end()) 2936 OS << it->second; 2937 else 2938 OS << Argument; 2939 Pos = I; 2940 } else { 2941 for (const AsmToken &Token : A[Index]) { 2942 // In MASM, you can write '%expr'. 2943 // The prefix '%' evaluates the expression 'expr' 2944 // and uses the result as a string (e.g. replace %(1+2) with the 2945 // string "3"). 2946 // Here, we identify the integer token which is the result of the 2947 // absolute expression evaluation and replace it with its string 2948 // representation. 2949 if (Token.getString().front() == '%' && Token.is(AsmToken::Integer)) 2950 // Emit an integer value to the buffer. 2951 OS << Token.getIntVal(); 2952 else 2953 OS << Token.getString(); 2954 } 2955 2956 Pos += Argument.size(); 2957 if (Pos < End && Body[Pos] == '&') { 2958 ++Pos; 2959 } 2960 } 2961 // Update the scan point. 2962 Body = Body.substr(Pos); 2963 } 2964 2965 return false; 2966 } 2967 2968 static bool isOperator(AsmToken::TokenKind kind) { 2969 switch (kind) { 2970 default: 2971 return false; 2972 case AsmToken::Plus: 2973 case AsmToken::Minus: 2974 case AsmToken::Tilde: 2975 case AsmToken::Slash: 2976 case AsmToken::Star: 2977 case AsmToken::Dot: 2978 case AsmToken::Equal: 2979 case AsmToken::EqualEqual: 2980 case AsmToken::Pipe: 2981 case AsmToken::PipePipe: 2982 case AsmToken::Caret: 2983 case AsmToken::Amp: 2984 case AsmToken::AmpAmp: 2985 case AsmToken::Exclaim: 2986 case AsmToken::ExclaimEqual: 2987 case AsmToken::Less: 2988 case AsmToken::LessEqual: 2989 case AsmToken::LessLess: 2990 case AsmToken::LessGreater: 2991 case AsmToken::Greater: 2992 case AsmToken::GreaterEqual: 2993 case AsmToken::GreaterGreater: 2994 return true; 2995 } 2996 } 2997 2998 namespace { 2999 3000 class AsmLexerSkipSpaceRAII { 3001 public: 3002 AsmLexerSkipSpaceRAII(AsmLexer &Lexer, bool SkipSpace) : Lexer(Lexer) { 3003 Lexer.setSkipSpace(SkipSpace); 3004 } 3005 3006 ~AsmLexerSkipSpaceRAII() { 3007 Lexer.setSkipSpace(true); 3008 } 3009 3010 private: 3011 AsmLexer &Lexer; 3012 }; 3013 3014 } // end anonymous namespace 3015 3016 bool MasmParser::parseMacroArgument(const MCAsmMacroParameter *MP, 3017 MCAsmMacroArgument &MA, 3018 AsmToken::TokenKind EndTok) { 3019 if (MP && MP->Vararg) { 3020 if (Lexer.isNot(EndTok)) { 3021 SmallVector<StringRef, 1> Str = parseStringRefsTo(EndTok); 3022 for (StringRef S : Str) { 3023 MA.emplace_back(AsmToken::String, S); 3024 } 3025 } 3026 return false; 3027 } 3028 3029 SMLoc StrLoc = Lexer.getLoc(), EndLoc; 3030 if (Lexer.is(AsmToken::Less) && isAngleBracketString(StrLoc, EndLoc)) { 3031 const char *StrChar = StrLoc.getPointer() + 1; 3032 const char *EndChar = EndLoc.getPointer() - 1; 3033 jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back()); 3034 /// Eat from '<' to '>'. 3035 Lex(); 3036 MA.emplace_back(AsmToken::String, StringRef(StrChar, EndChar - StrChar)); 3037 return false; 3038 } 3039 3040 unsigned ParenLevel = 0; 3041 3042 // Darwin doesn't use spaces to delmit arguments. 3043 AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin); 3044 3045 bool SpaceEaten; 3046 3047 while (true) { 3048 SpaceEaten = false; 3049 if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal)) 3050 return TokError("unexpected token"); 3051 3052 if (ParenLevel == 0) { 3053 if (Lexer.is(AsmToken::Comma)) 3054 break; 3055 3056 if (Lexer.is(AsmToken::Space)) { 3057 SpaceEaten = true; 3058 Lex(); // Eat spaces. 3059 } 3060 3061 // Spaces can delimit parameters, but could also be part an expression. 3062 // If the token after a space is an operator, add the token and the next 3063 // one into this argument 3064 if (!IsDarwin) { 3065 if (isOperator(Lexer.getKind()) && Lexer.isNot(EndTok)) { 3066 MA.push_back(getTok()); 3067 Lex(); 3068 3069 // Whitespace after an operator can be ignored. 3070 if (Lexer.is(AsmToken::Space)) 3071 Lex(); 3072 3073 continue; 3074 } 3075 } 3076 if (SpaceEaten) 3077 break; 3078 } 3079 3080 // handleMacroEntry relies on not advancing the lexer here 3081 // to be able to fill in the remaining default parameter values 3082 if (Lexer.is(EndTok) && (EndTok != AsmToken::RParen || ParenLevel == 0)) 3083 break; 3084 3085 // Adjust the current parentheses level. 3086 if (Lexer.is(AsmToken::LParen)) 3087 ++ParenLevel; 3088 else if (Lexer.is(AsmToken::RParen) && ParenLevel) 3089 --ParenLevel; 3090 3091 // Append the token to the current argument list. 3092 MA.push_back(getTok()); 3093 Lex(); 3094 } 3095 3096 if (ParenLevel != 0) 3097 return TokError("unbalanced parentheses in argument"); 3098 3099 if (MA.empty() && MP) { 3100 if (MP->Required) { 3101 return TokError("missing value for required parameter '" + MP->Name + 3102 "'"); 3103 } else { 3104 MA = MP->Value; 3105 } 3106 } 3107 return false; 3108 } 3109 3110 // Parse the macro instantiation arguments. 3111 bool MasmParser::parseMacroArguments(const MCAsmMacro *M, 3112 MCAsmMacroArguments &A, 3113 AsmToken::TokenKind EndTok) { 3114 const unsigned NParameters = M ? M->Parameters.size() : 0; 3115 bool NamedParametersFound = false; 3116 SmallVector<SMLoc, 4> FALocs; 3117 3118 A.resize(NParameters); 3119 FALocs.resize(NParameters); 3120 3121 // Parse two kinds of macro invocations: 3122 // - macros defined without any parameters accept an arbitrary number of them 3123 // - macros defined with parameters accept at most that many of them 3124 for (unsigned Parameter = 0; !NParameters || Parameter < NParameters; 3125 ++Parameter) { 3126 SMLoc IDLoc = Lexer.getLoc(); 3127 MCAsmMacroParameter FA; 3128 3129 if (Lexer.is(AsmToken::Identifier) && peekTok().is(AsmToken::Equal)) { 3130 if (parseIdentifier(FA.Name)) 3131 return Error(IDLoc, "invalid argument identifier for formal argument"); 3132 3133 if (Lexer.isNot(AsmToken::Equal)) 3134 return TokError("expected '=' after formal parameter identifier"); 3135 3136 Lex(); 3137 3138 NamedParametersFound = true; 3139 } 3140 3141 if (NamedParametersFound && FA.Name.empty()) 3142 return Error(IDLoc, "cannot mix positional and keyword arguments"); 3143 3144 unsigned PI = Parameter; 3145 if (!FA.Name.empty()) { 3146 assert(M && "expected macro to be defined"); 3147 unsigned FAI = 0; 3148 for (FAI = 0; FAI < NParameters; ++FAI) 3149 if (M->Parameters[FAI].Name == FA.Name) 3150 break; 3151 3152 if (FAI >= NParameters) { 3153 return Error(IDLoc, "parameter named '" + FA.Name + 3154 "' does not exist for macro '" + M->Name + "'"); 3155 } 3156 PI = FAI; 3157 } 3158 const MCAsmMacroParameter *MP = nullptr; 3159 if (M && PI < NParameters) 3160 MP = &M->Parameters[PI]; 3161 3162 SMLoc StrLoc = Lexer.getLoc(); 3163 SMLoc EndLoc; 3164 if (Lexer.is(AsmToken::Percent)) { 3165 const MCExpr *AbsoluteExp; 3166 int64_t Value; 3167 /// Eat '%'. 3168 Lex(); 3169 if (parseExpression(AbsoluteExp, EndLoc)) 3170 return false; 3171 if (!AbsoluteExp->evaluateAsAbsolute(Value, 3172 getStreamer().getAssemblerPtr())) 3173 return Error(StrLoc, "expected absolute expression"); 3174 const char *StrChar = StrLoc.getPointer(); 3175 const char *EndChar = EndLoc.getPointer(); 3176 AsmToken newToken(AsmToken::Integer, 3177 StringRef(StrChar, EndChar - StrChar), Value); 3178 FA.Value.push_back(newToken); 3179 } else if (parseMacroArgument(MP, FA.Value, EndTok)) { 3180 if (M) 3181 return addErrorSuffix(" in '" + M->Name + "' macro"); 3182 else 3183 return true; 3184 } 3185 3186 if (!FA.Value.empty()) { 3187 if (A.size() <= PI) 3188 A.resize(PI + 1); 3189 A[PI] = FA.Value; 3190 3191 if (FALocs.size() <= PI) 3192 FALocs.resize(PI + 1); 3193 3194 FALocs[PI] = Lexer.getLoc(); 3195 } 3196 3197 // At the end of the statement, fill in remaining arguments that have 3198 // default values. If there aren't any, then the next argument is 3199 // required but missing 3200 if (Lexer.is(EndTok)) { 3201 bool Failure = false; 3202 for (unsigned FAI = 0; FAI < NParameters; ++FAI) { 3203 if (A[FAI].empty()) { 3204 if (M->Parameters[FAI].Required) { 3205 Error(FALocs[FAI].isValid() ? FALocs[FAI] : Lexer.getLoc(), 3206 "missing value for required parameter " 3207 "'" + 3208 M->Parameters[FAI].Name + "' in macro '" + M->Name + "'"); 3209 Failure = true; 3210 } 3211 3212 if (!M->Parameters[FAI].Value.empty()) 3213 A[FAI] = M->Parameters[FAI].Value; 3214 } 3215 } 3216 return Failure; 3217 } 3218 3219 if (Lexer.is(AsmToken::Comma)) 3220 Lex(); 3221 } 3222 3223 return TokError("too many positional arguments"); 3224 } 3225 3226 bool MasmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc, 3227 AsmToken::TokenKind ArgumentEndTok) { 3228 // Arbitrarily limit macro nesting depth (default matches 'as'). We can 3229 // eliminate this, although we should protect against infinite loops. 3230 unsigned MaxNestingDepth = AsmMacroMaxNestingDepth; 3231 if (ActiveMacros.size() == MaxNestingDepth) { 3232 std::ostringstream MaxNestingDepthError; 3233 MaxNestingDepthError << "macros cannot be nested more than " 3234 << MaxNestingDepth << " levels deep." 3235 << " Use -asm-macro-max-nesting-depth to increase " 3236 "this limit."; 3237 return TokError(MaxNestingDepthError.str()); 3238 } 3239 3240 MCAsmMacroArguments A; 3241 if (parseMacroArguments(M, A, ArgumentEndTok)) 3242 return true; 3243 3244 // Macro instantiation is lexical, unfortunately. We construct a new buffer 3245 // to hold the macro body with substitutions. 3246 SmallString<256> Buf; 3247 StringRef Body = M->Body; 3248 raw_svector_ostream OS(Buf); 3249 3250 if (expandMacro(OS, Body, M->Parameters, A, M->Locals, getTok().getLoc())) 3251 return true; 3252 3253 // We include the endm in the buffer as our cue to exit the macro 3254 // instantiation. 3255 OS << "endm\n"; 3256 3257 std::unique_ptr<MemoryBuffer> Instantiation = 3258 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); 3259 3260 // Create the macro instantiation object and add to the current macro 3261 // instantiation stack. 3262 MacroInstantiation *MI = new MacroInstantiation{ 3263 NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()}; 3264 ActiveMacros.push_back(MI); 3265 3266 ++NumOfMacroInstantiations; 3267 3268 // Jump to the macro instantiation and prime the lexer. 3269 CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc()); 3270 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); 3271 EndStatementAtEOFStack.push_back(true); 3272 Lex(); 3273 3274 return false; 3275 } 3276 3277 void MasmParser::handleMacroExit() { 3278 // Jump to the token we should return to, and consume it. 3279 EndStatementAtEOFStack.pop_back(); 3280 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer, 3281 EndStatementAtEOFStack.back()); 3282 Lex(); 3283 3284 // Pop the instantiation entry. 3285 delete ActiveMacros.back(); 3286 ActiveMacros.pop_back(); 3287 } 3288 3289 bool MasmParser::handleMacroInvocation(const MCAsmMacro *M, SMLoc NameLoc) { 3290 if (!M->IsFunction) 3291 return Error(NameLoc, "cannot invoke macro procedure as function"); 3292 3293 if (parseToken(AsmToken::LParen, "invoking macro function '" + M->Name + 3294 "' requires arguments in parentheses") || 3295 handleMacroEntry(M, NameLoc, AsmToken::RParen)) 3296 return true; 3297 3298 // Parse all statements in the macro, retrieving the exit value when it ends. 3299 std::string ExitValue; 3300 SmallVector<AsmRewrite, 4> AsmStrRewrites; 3301 while (Lexer.isNot(AsmToken::Eof)) { 3302 ParseStatementInfo Info(&AsmStrRewrites); 3303 bool Parsed = parseStatement(Info, nullptr); 3304 3305 if (!Parsed && Info.ExitValue) { 3306 ExitValue = std::move(*Info.ExitValue); 3307 break; 3308 } 3309 3310 // If we have a Lexer Error we are on an Error Token. Load in Lexer Error 3311 // for printing ErrMsg via Lex() only if no (presumably better) parser error 3312 // exists. 3313 if (Parsed && !hasPendingError() && Lexer.getTok().is(AsmToken::Error)) { 3314 Lex(); 3315 } 3316 3317 // parseStatement returned true so may need to emit an error. 3318 printPendingErrors(); 3319 3320 // Skipping to the next line if needed. 3321 if (Parsed && !getLexer().isAtStartOfStatement()) 3322 eatToEndOfStatement(); 3323 } 3324 3325 // Consume the right-parenthesis on the other side of the arguments. 3326 if (parseRParen()) 3327 return true; 3328 3329 // Exit values may require lexing, unfortunately. We construct a new buffer to 3330 // hold the exit value. 3331 std::unique_ptr<MemoryBuffer> MacroValue = 3332 MemoryBuffer::getMemBufferCopy(ExitValue, "<macro-value>"); 3333 3334 // Jump from this location to the instantiated exit value, and prime the 3335 // lexer. 3336 CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(MacroValue), Lexer.getLoc()); 3337 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(), nullptr, 3338 /*EndStatementAtEOF=*/false); 3339 EndStatementAtEOFStack.push_back(false); 3340 Lex(); 3341 3342 return false; 3343 } 3344 3345 /// parseIdentifier: 3346 /// ::= identifier 3347 /// ::= string 3348 bool MasmParser::parseIdentifier(StringRef &Res, 3349 IdentifierPositionKind Position) { 3350 // The assembler has relaxed rules for accepting identifiers, in particular we 3351 // allow things like '.globl $foo' and '.def @feat.00', which would normally 3352 // be separate tokens. At this level, we have already lexed so we cannot 3353 // (currently) handle this as a context dependent token, instead we detect 3354 // adjacent tokens and return the combined identifier. 3355 if (Lexer.is(AsmToken::Dollar) || Lexer.is(AsmToken::At)) { 3356 SMLoc PrefixLoc = getLexer().getLoc(); 3357 3358 // Consume the prefix character, and check for a following identifier. 3359 3360 AsmToken nextTok = peekTok(false); 3361 3362 if (nextTok.isNot(AsmToken::Identifier)) 3363 return true; 3364 3365 // We have a '$' or '@' followed by an identifier, make sure they are adjacent. 3366 if (PrefixLoc.getPointer() + 1 != nextTok.getLoc().getPointer()) 3367 return true; 3368 3369 // eat $ or @ 3370 Lexer.Lex(); // Lexer's Lex guarantees consecutive token. 3371 // Construct the joined identifier and consume the token. 3372 Res = 3373 StringRef(PrefixLoc.getPointer(), getTok().getIdentifier().size() + 1); 3374 Lex(); // Parser Lex to maintain invariants. 3375 return false; 3376 } 3377 3378 if (Lexer.isNot(AsmToken::Identifier) && Lexer.isNot(AsmToken::String)) 3379 return true; 3380 3381 Res = getTok().getIdentifier(); 3382 3383 // Consume the identifier token - but if parsing certain directives, avoid 3384 // lexical expansion of the next token. 3385 ExpandKind ExpandNextToken = ExpandMacros; 3386 if (Position == StartOfStatement && 3387 StringSwitch<bool>(Res) 3388 .CaseLower("echo", true) 3389 .CasesLower("ifdef", "ifndef", "elseifdef", "elseifndef", true) 3390 .Default(false)) { 3391 ExpandNextToken = DoNotExpandMacros; 3392 } 3393 Lex(ExpandNextToken); 3394 3395 return false; 3396 } 3397 3398 /// parseDirectiveEquate: 3399 /// ::= name "=" expression 3400 /// | name "equ" expression (not redefinable) 3401 /// | name "equ" text-list 3402 /// | name "textequ" text-list (redefinability unspecified) 3403 bool MasmParser::parseDirectiveEquate(StringRef IDVal, StringRef Name, 3404 DirectiveKind DirKind, SMLoc NameLoc) { 3405 auto BuiltinIt = BuiltinSymbolMap.find(Name.lower()); 3406 if (BuiltinIt != BuiltinSymbolMap.end()) 3407 return Error(NameLoc, "cannot redefine a built-in symbol"); 3408 3409 Variable &Var = Variables[Name.lower()]; 3410 if (Var.Name.empty()) { 3411 Var.Name = Name; 3412 } 3413 3414 SMLoc StartLoc = Lexer.getLoc(); 3415 if (DirKind == DK_EQU || DirKind == DK_TEXTEQU) { 3416 // "equ" and "textequ" both allow text expressions. 3417 std::string Value; 3418 std::string TextItem; 3419 if (!parseTextItem(TextItem)) { 3420 Value += TextItem; 3421 3422 // Accept a text-list, not just one text-item. 3423 auto parseItem = [&]() -> bool { 3424 if (parseTextItem(TextItem)) 3425 return TokError("expected text item"); 3426 Value += TextItem; 3427 return false; 3428 }; 3429 if (parseOptionalToken(AsmToken::Comma) && parseMany(parseItem)) 3430 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive"); 3431 3432 if (!Var.IsText || Var.TextValue != Value) { 3433 switch (Var.Redefinable) { 3434 case Variable::NOT_REDEFINABLE: 3435 return Error(getTok().getLoc(), "invalid variable redefinition"); 3436 case Variable::WARN_ON_REDEFINITION: 3437 if (Warning(NameLoc, "redefining '" + Name + 3438 "', already defined on the command line")) { 3439 return true; 3440 } 3441 break; 3442 default: 3443 break; 3444 } 3445 } 3446 Var.IsText = true; 3447 Var.TextValue = Value; 3448 Var.Redefinable = Variable::REDEFINABLE; 3449 3450 return false; 3451 } 3452 } 3453 if (DirKind == DK_TEXTEQU) 3454 return TokError("expected <text> in '" + Twine(IDVal) + "' directive"); 3455 3456 // Parse as expression assignment. 3457 const MCExpr *Expr; 3458 SMLoc EndLoc; 3459 if (parseExpression(Expr, EndLoc)) 3460 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive"); 3461 StringRef ExprAsString = StringRef( 3462 StartLoc.getPointer(), EndLoc.getPointer() - StartLoc.getPointer()); 3463 3464 int64_t Value; 3465 if (!Expr->evaluateAsAbsolute(Value, getStreamer().getAssemblerPtr())) { 3466 if (DirKind == DK_ASSIGN) 3467 return Error( 3468 StartLoc, 3469 "expected absolute expression; not all symbols have known values", 3470 {StartLoc, EndLoc}); 3471 3472 // Not an absolute expression; define as a text replacement. 3473 if (!Var.IsText || Var.TextValue != ExprAsString) { 3474 switch (Var.Redefinable) { 3475 case Variable::NOT_REDEFINABLE: 3476 return Error(getTok().getLoc(), "invalid variable redefinition"); 3477 case Variable::WARN_ON_REDEFINITION: 3478 if (Warning(NameLoc, "redefining '" + Name + 3479 "', already defined on the command line")) { 3480 return true; 3481 } 3482 break; 3483 default: 3484 break; 3485 } 3486 } 3487 3488 Var.IsText = true; 3489 Var.TextValue = ExprAsString.str(); 3490 Var.Redefinable = Variable::REDEFINABLE; 3491 3492 return false; 3493 } 3494 3495 MCSymbol *Sym = getContext().getOrCreateSymbol(Var.Name); 3496 3497 const MCConstantExpr *PrevValue = 3498 Sym->isVariable() ? dyn_cast_or_null<MCConstantExpr>( 3499 Sym->getVariableValue(/*SetUsed=*/false)) 3500 : nullptr; 3501 if (Var.IsText || !PrevValue || PrevValue->getValue() != Value) { 3502 switch (Var.Redefinable) { 3503 case Variable::NOT_REDEFINABLE: 3504 return Error(getTok().getLoc(), "invalid variable redefinition"); 3505 case Variable::WARN_ON_REDEFINITION: 3506 if (Warning(NameLoc, "redefining '" + Name + 3507 "', already defined on the command line")) { 3508 return true; 3509 } 3510 break; 3511 default: 3512 break; 3513 } 3514 } 3515 3516 Var.IsText = false; 3517 Var.TextValue.clear(); 3518 Var.Redefinable = (DirKind == DK_ASSIGN) ? Variable::REDEFINABLE 3519 : Variable::NOT_REDEFINABLE; 3520 3521 Sym->setRedefinable(Var.Redefinable != Variable::NOT_REDEFINABLE); 3522 Sym->setVariableValue(Expr); 3523 Sym->setExternal(false); 3524 3525 return false; 3526 } 3527 3528 bool MasmParser::parseEscapedString(std::string &Data) { 3529 if (check(getTok().isNot(AsmToken::String), "expected string")) 3530 return true; 3531 3532 Data = ""; 3533 char Quote = getTok().getString().front(); 3534 StringRef Str = getTok().getStringContents(); 3535 Data.reserve(Str.size()); 3536 for (size_t i = 0, e = Str.size(); i != e; ++i) { 3537 Data.push_back(Str[i]); 3538 if (Str[i] == Quote) { 3539 // MASM treats doubled delimiting quotes as an escaped delimiting quote. 3540 // If we're escaping the string's trailing delimiter, we're definitely 3541 // missing a quotation mark. 3542 if (i + 1 == Str.size()) 3543 return Error(getTok().getLoc(), "missing quotation mark in string"); 3544 if (Str[i + 1] == Quote) 3545 ++i; 3546 } 3547 } 3548 3549 Lex(); 3550 return false; 3551 } 3552 3553 bool MasmParser::parseAngleBracketString(std::string &Data) { 3554 SMLoc EndLoc, StartLoc = getTok().getLoc(); 3555 if (isAngleBracketString(StartLoc, EndLoc)) { 3556 const char *StartChar = StartLoc.getPointer() + 1; 3557 const char *EndChar = EndLoc.getPointer() - 1; 3558 jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back()); 3559 // Eat from '<' to '>'. 3560 Lex(); 3561 3562 Data = angleBracketString(StringRef(StartChar, EndChar - StartChar)); 3563 return false; 3564 } 3565 return true; 3566 } 3567 3568 /// textItem ::= textLiteral | textMacroID | % constExpr 3569 bool MasmParser::parseTextItem(std::string &Data) { 3570 switch (getTok().getKind()) { 3571 default: 3572 return true; 3573 case AsmToken::Percent: { 3574 int64_t Res; 3575 if (parseToken(AsmToken::Percent) || parseAbsoluteExpression(Res)) 3576 return true; 3577 Data = std::to_string(Res); 3578 return false; 3579 } 3580 case AsmToken::Less: 3581 case AsmToken::LessEqual: 3582 case AsmToken::LessLess: 3583 case AsmToken::LessGreater: 3584 return parseAngleBracketString(Data); 3585 case AsmToken::Identifier: { 3586 // This must be a text macro; we need to expand it accordingly. 3587 StringRef ID; 3588 SMLoc StartLoc = getTok().getLoc(); 3589 if (parseIdentifier(ID)) 3590 return true; 3591 Data = ID.str(); 3592 3593 bool Expanded = false; 3594 while (true) { 3595 // Try to resolve as a built-in text macro 3596 auto BuiltinIt = BuiltinSymbolMap.find(ID.lower()); 3597 if (BuiltinIt != BuiltinSymbolMap.end()) { 3598 llvm::Optional<std::string> BuiltinText = 3599 evaluateBuiltinTextMacro(BuiltinIt->getValue(), StartLoc); 3600 if (!BuiltinText) { 3601 // Not a text macro; break without substituting 3602 break; 3603 } 3604 Data = std::move(*BuiltinText); 3605 ID = StringRef(Data); 3606 Expanded = true; 3607 continue; 3608 } 3609 3610 // Try to resolve as a variable text macro 3611 auto VarIt = Variables.find(ID.lower()); 3612 if (VarIt != Variables.end()) { 3613 const Variable &Var = VarIt->getValue(); 3614 if (!Var.IsText) { 3615 // Not a text macro; break without substituting 3616 break; 3617 } 3618 Data = Var.TextValue; 3619 ID = StringRef(Data); 3620 Expanded = true; 3621 continue; 3622 } 3623 3624 break; 3625 } 3626 3627 if (!Expanded) { 3628 // Not a text macro; not usable in TextItem context. Since we haven't used 3629 // the token, put it back for better error recovery. 3630 getLexer().UnLex(AsmToken(AsmToken::Identifier, ID)); 3631 return true; 3632 } 3633 return false; 3634 } 3635 } 3636 llvm_unreachable("unhandled token kind"); 3637 } 3638 3639 /// parseDirectiveAscii: 3640 /// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ] 3641 bool MasmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) { 3642 auto parseOp = [&]() -> bool { 3643 std::string Data; 3644 if (checkForValidSection() || parseEscapedString(Data)) 3645 return true; 3646 getStreamer().emitBytes(Data); 3647 if (ZeroTerminated) 3648 getStreamer().emitBytes(StringRef("\0", 1)); 3649 return false; 3650 }; 3651 3652 if (parseMany(parseOp)) 3653 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive"); 3654 return false; 3655 } 3656 3657 bool MasmParser::emitIntValue(const MCExpr *Value, unsigned Size) { 3658 // Special case constant expressions to match code generator. 3659 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 3660 assert(Size <= 8 && "Invalid size"); 3661 int64_t IntValue = MCE->getValue(); 3662 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue)) 3663 return Error(MCE->getLoc(), "out of range literal value"); 3664 getStreamer().emitIntValue(IntValue, Size); 3665 } else { 3666 const MCSymbolRefExpr *MSE = dyn_cast<MCSymbolRefExpr>(Value); 3667 if (MSE && MSE->getSymbol().getName() == "?") { 3668 // ? initializer; treat as 0. 3669 getStreamer().emitIntValue(0, Size); 3670 } else { 3671 getStreamer().emitValue(Value, Size, Value->getLoc()); 3672 } 3673 } 3674 return false; 3675 } 3676 3677 bool MasmParser::parseScalarInitializer(unsigned Size, 3678 SmallVectorImpl<const MCExpr *> &Values, 3679 unsigned StringPadLength) { 3680 if (Size == 1 && getTok().is(AsmToken::String)) { 3681 std::string Value; 3682 if (parseEscapedString(Value)) 3683 return true; 3684 // Treat each character as an initializer. 3685 for (const unsigned char CharVal : Value) 3686 Values.push_back(MCConstantExpr::create(CharVal, getContext())); 3687 3688 // Pad the string with spaces to the specified length. 3689 for (size_t i = Value.size(); i < StringPadLength; ++i) 3690 Values.push_back(MCConstantExpr::create(' ', getContext())); 3691 } else { 3692 const MCExpr *Value; 3693 if (parseExpression(Value)) 3694 return true; 3695 if (getTok().is(AsmToken::Identifier) && 3696 getTok().getString().equals_insensitive("dup")) { 3697 Lex(); // Eat 'dup'. 3698 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 3699 if (!MCE) 3700 return Error(Value->getLoc(), 3701 "cannot repeat value a non-constant number of times"); 3702 const int64_t Repetitions = MCE->getValue(); 3703 if (Repetitions < 0) 3704 return Error(Value->getLoc(), 3705 "cannot repeat value a negative number of times"); 3706 3707 SmallVector<const MCExpr *, 1> DuplicatedValues; 3708 if (parseToken(AsmToken::LParen, 3709 "parentheses required for 'dup' contents") || 3710 parseScalarInstList(Size, DuplicatedValues) || parseRParen()) 3711 return true; 3712 3713 for (int i = 0; i < Repetitions; ++i) 3714 Values.append(DuplicatedValues.begin(), DuplicatedValues.end()); 3715 } else { 3716 Values.push_back(Value); 3717 } 3718 } 3719 return false; 3720 } 3721 3722 bool MasmParser::parseScalarInstList(unsigned Size, 3723 SmallVectorImpl<const MCExpr *> &Values, 3724 const AsmToken::TokenKind EndToken) { 3725 while (getTok().isNot(EndToken) && 3726 (EndToken != AsmToken::Greater || 3727 getTok().isNot(AsmToken::GreaterGreater))) { 3728 parseScalarInitializer(Size, Values); 3729 3730 // If we see a comma, continue, and allow line continuation. 3731 if (!parseOptionalToken(AsmToken::Comma)) 3732 break; 3733 parseOptionalToken(AsmToken::EndOfStatement); 3734 } 3735 return false; 3736 } 3737 3738 bool MasmParser::emitIntegralValues(unsigned Size, unsigned *Count) { 3739 SmallVector<const MCExpr *, 1> Values; 3740 if (checkForValidSection() || parseScalarInstList(Size, Values)) 3741 return true; 3742 3743 for (auto Value : Values) { 3744 emitIntValue(Value, Size); 3745 } 3746 if (Count) 3747 *Count = Values.size(); 3748 return false; 3749 } 3750 3751 // Add a field to the current structure. 3752 bool MasmParser::addIntegralField(StringRef Name, unsigned Size) { 3753 StructInfo &Struct = StructInProgress.back(); 3754 FieldInfo &Field = Struct.addField(Name, FT_INTEGRAL, Size); 3755 IntFieldInfo &IntInfo = Field.Contents.IntInfo; 3756 3757 Field.Type = Size; 3758 3759 if (parseScalarInstList(Size, IntInfo.Values)) 3760 return true; 3761 3762 Field.SizeOf = Field.Type * IntInfo.Values.size(); 3763 Field.LengthOf = IntInfo.Values.size(); 3764 const unsigned FieldEnd = Field.Offset + Field.SizeOf; 3765 if (!Struct.IsUnion) { 3766 Struct.NextOffset = FieldEnd; 3767 } 3768 Struct.Size = std::max(Struct.Size, FieldEnd); 3769 return false; 3770 } 3771 3772 /// parseDirectiveValue 3773 /// ::= (byte | word | ... ) [ expression (, expression)* ] 3774 bool MasmParser::parseDirectiveValue(StringRef IDVal, unsigned Size) { 3775 if (StructInProgress.empty()) { 3776 // Initialize data value. 3777 if (emitIntegralValues(Size)) 3778 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive"); 3779 } else if (addIntegralField("", Size)) { 3780 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive"); 3781 } 3782 3783 return false; 3784 } 3785 3786 /// parseDirectiveNamedValue 3787 /// ::= name (byte | word | ... ) [ expression (, expression)* ] 3788 bool MasmParser::parseDirectiveNamedValue(StringRef TypeName, unsigned Size, 3789 StringRef Name, SMLoc NameLoc) { 3790 if (StructInProgress.empty()) { 3791 // Initialize named data value. 3792 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 3793 getStreamer().emitLabel(Sym); 3794 unsigned Count; 3795 if (emitIntegralValues(Size, &Count)) 3796 return addErrorSuffix(" in '" + Twine(TypeName) + "' directive"); 3797 3798 AsmTypeInfo Type; 3799 Type.Name = TypeName; 3800 Type.Size = Size * Count; 3801 Type.ElementSize = Size; 3802 Type.Length = Count; 3803 KnownType[Name.lower()] = Type; 3804 } else if (addIntegralField(Name, Size)) { 3805 return addErrorSuffix(" in '" + Twine(TypeName) + "' directive"); 3806 } 3807 3808 return false; 3809 } 3810 3811 static bool parseHexOcta(MasmParser &Asm, uint64_t &hi, uint64_t &lo) { 3812 if (Asm.getTok().isNot(AsmToken::Integer) && 3813 Asm.getTok().isNot(AsmToken::BigNum)) 3814 return Asm.TokError("unknown token in expression"); 3815 SMLoc ExprLoc = Asm.getTok().getLoc(); 3816 APInt IntValue = Asm.getTok().getAPIntVal(); 3817 Asm.Lex(); 3818 if (!IntValue.isIntN(128)) 3819 return Asm.Error(ExprLoc, "out of range literal value"); 3820 if (!IntValue.isIntN(64)) { 3821 hi = IntValue.getHiBits(IntValue.getBitWidth() - 64).getZExtValue(); 3822 lo = IntValue.getLoBits(64).getZExtValue(); 3823 } else { 3824 hi = 0; 3825 lo = IntValue.getZExtValue(); 3826 } 3827 return false; 3828 } 3829 3830 bool MasmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) { 3831 // We don't truly support arithmetic on floating point expressions, so we 3832 // have to manually parse unary prefixes. 3833 bool IsNeg = false; 3834 SMLoc SignLoc; 3835 if (getLexer().is(AsmToken::Minus)) { 3836 SignLoc = getLexer().getLoc(); 3837 Lexer.Lex(); 3838 IsNeg = true; 3839 } else if (getLexer().is(AsmToken::Plus)) { 3840 SignLoc = getLexer().getLoc(); 3841 Lexer.Lex(); 3842 } 3843 3844 if (Lexer.is(AsmToken::Error)) 3845 return TokError(Lexer.getErr()); 3846 if (Lexer.isNot(AsmToken::Integer) && Lexer.isNot(AsmToken::Real) && 3847 Lexer.isNot(AsmToken::Identifier)) 3848 return TokError("unexpected token in directive"); 3849 3850 // Convert to an APFloat. 3851 APFloat Value(Semantics); 3852 StringRef IDVal = getTok().getString(); 3853 if (getLexer().is(AsmToken::Identifier)) { 3854 if (IDVal.equals_insensitive("infinity") || IDVal.equals_insensitive("inf")) 3855 Value = APFloat::getInf(Semantics); 3856 else if (IDVal.equals_insensitive("nan")) 3857 Value = APFloat::getNaN(Semantics, false, ~0); 3858 else if (IDVal.equals_insensitive("?")) 3859 Value = APFloat::getZero(Semantics); 3860 else 3861 return TokError("invalid floating point literal"); 3862 } else if (IDVal.consume_back("r") || IDVal.consume_back("R")) { 3863 // MASM hexadecimal floating-point literal; no APFloat conversion needed. 3864 // To match ML64.exe, ignore the initial sign. 3865 unsigned SizeInBits = Value.getSizeInBits(Semantics); 3866 if (SizeInBits != (IDVal.size() << 2)) 3867 return TokError("invalid floating point literal"); 3868 3869 // Consume the numeric token. 3870 Lex(); 3871 3872 Res = APInt(SizeInBits, IDVal, 16); 3873 if (SignLoc.isValid()) 3874 return Warning(SignLoc, "MASM-style hex floats ignore explicit sign"); 3875 return false; 3876 } else if (errorToBool( 3877 Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) 3878 .takeError())) { 3879 return TokError("invalid floating point literal"); 3880 } 3881 if (IsNeg) 3882 Value.changeSign(); 3883 3884 // Consume the numeric token. 3885 Lex(); 3886 3887 Res = Value.bitcastToAPInt(); 3888 3889 return false; 3890 } 3891 3892 bool MasmParser::parseRealInstList(const fltSemantics &Semantics, 3893 SmallVectorImpl<APInt> &ValuesAsInt, 3894 const AsmToken::TokenKind EndToken) { 3895 while (getTok().isNot(EndToken) || 3896 (EndToken == AsmToken::Greater && 3897 getTok().isNot(AsmToken::GreaterGreater))) { 3898 const AsmToken NextTok = peekTok(); 3899 if (NextTok.is(AsmToken::Identifier) && 3900 NextTok.getString().equals_insensitive("dup")) { 3901 const MCExpr *Value; 3902 if (parseExpression(Value) || parseToken(AsmToken::Identifier)) 3903 return true; 3904 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 3905 if (!MCE) 3906 return Error(Value->getLoc(), 3907 "cannot repeat value a non-constant number of times"); 3908 const int64_t Repetitions = MCE->getValue(); 3909 if (Repetitions < 0) 3910 return Error(Value->getLoc(), 3911 "cannot repeat value a negative number of times"); 3912 3913 SmallVector<APInt, 1> DuplicatedValues; 3914 if (parseToken(AsmToken::LParen, 3915 "parentheses required for 'dup' contents") || 3916 parseRealInstList(Semantics, DuplicatedValues) || parseRParen()) 3917 return true; 3918 3919 for (int i = 0; i < Repetitions; ++i) 3920 ValuesAsInt.append(DuplicatedValues.begin(), DuplicatedValues.end()); 3921 } else { 3922 APInt AsInt; 3923 if (parseRealValue(Semantics, AsInt)) 3924 return true; 3925 ValuesAsInt.push_back(AsInt); 3926 } 3927 3928 // Continue if we see a comma. (Also, allow line continuation.) 3929 if (!parseOptionalToken(AsmToken::Comma)) 3930 break; 3931 parseOptionalToken(AsmToken::EndOfStatement); 3932 } 3933 3934 return false; 3935 } 3936 3937 // Initialize real data values. 3938 bool MasmParser::emitRealValues(const fltSemantics &Semantics, 3939 unsigned *Count) { 3940 if (checkForValidSection()) 3941 return true; 3942 3943 SmallVector<APInt, 1> ValuesAsInt; 3944 if (parseRealInstList(Semantics, ValuesAsInt)) 3945 return true; 3946 3947 for (const APInt &AsInt : ValuesAsInt) { 3948 getStreamer().emitIntValue(AsInt); 3949 } 3950 if (Count) 3951 *Count = ValuesAsInt.size(); 3952 return false; 3953 } 3954 3955 // Add a real field to the current struct. 3956 bool MasmParser::addRealField(StringRef Name, const fltSemantics &Semantics, 3957 size_t Size) { 3958 StructInfo &Struct = StructInProgress.back(); 3959 FieldInfo &Field = Struct.addField(Name, FT_REAL, Size); 3960 RealFieldInfo &RealInfo = Field.Contents.RealInfo; 3961 3962 Field.SizeOf = 0; 3963 3964 if (parseRealInstList(Semantics, RealInfo.AsIntValues)) 3965 return true; 3966 3967 Field.Type = RealInfo.AsIntValues.back().getBitWidth() / 8; 3968 Field.LengthOf = RealInfo.AsIntValues.size(); 3969 Field.SizeOf = Field.Type * Field.LengthOf; 3970 3971 const unsigned FieldEnd = Field.Offset + Field.SizeOf; 3972 if (!Struct.IsUnion) { 3973 Struct.NextOffset = FieldEnd; 3974 } 3975 Struct.Size = std::max(Struct.Size, FieldEnd); 3976 return false; 3977 } 3978 3979 /// parseDirectiveRealValue 3980 /// ::= (real4 | real8 | real10) [ expression (, expression)* ] 3981 bool MasmParser::parseDirectiveRealValue(StringRef IDVal, 3982 const fltSemantics &Semantics, 3983 size_t Size) { 3984 if (StructInProgress.empty()) { 3985 // Initialize data value. 3986 if (emitRealValues(Semantics)) 3987 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive"); 3988 } else if (addRealField("", Semantics, Size)) { 3989 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive"); 3990 } 3991 return false; 3992 } 3993 3994 /// parseDirectiveNamedRealValue 3995 /// ::= name (real4 | real8 | real10) [ expression (, expression)* ] 3996 bool MasmParser::parseDirectiveNamedRealValue(StringRef TypeName, 3997 const fltSemantics &Semantics, 3998 unsigned Size, StringRef Name, 3999 SMLoc NameLoc) { 4000 if (StructInProgress.empty()) { 4001 // Initialize named data value. 4002 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 4003 getStreamer().emitLabel(Sym); 4004 unsigned Count; 4005 if (emitRealValues(Semantics, &Count)) 4006 return addErrorSuffix(" in '" + TypeName + "' directive"); 4007 4008 AsmTypeInfo Type; 4009 Type.Name = TypeName; 4010 Type.Size = Size * Count; 4011 Type.ElementSize = Size; 4012 Type.Length = Count; 4013 KnownType[Name.lower()] = Type; 4014 } else if (addRealField(Name, Semantics, Size)) { 4015 return addErrorSuffix(" in '" + TypeName + "' directive"); 4016 } 4017 return false; 4018 } 4019 4020 bool MasmParser::parseOptionalAngleBracketOpen() { 4021 const AsmToken Tok = getTok(); 4022 if (parseOptionalToken(AsmToken::LessLess)) { 4023 AngleBracketDepth++; 4024 Lexer.UnLex(AsmToken(AsmToken::Less, Tok.getString().substr(1))); 4025 return true; 4026 } else if (parseOptionalToken(AsmToken::LessGreater)) { 4027 AngleBracketDepth++; 4028 Lexer.UnLex(AsmToken(AsmToken::Greater, Tok.getString().substr(1))); 4029 return true; 4030 } else if (parseOptionalToken(AsmToken::Less)) { 4031 AngleBracketDepth++; 4032 return true; 4033 } 4034 4035 return false; 4036 } 4037 4038 bool MasmParser::parseAngleBracketClose(const Twine &Msg) { 4039 const AsmToken Tok = getTok(); 4040 if (parseOptionalToken(AsmToken::GreaterGreater)) { 4041 Lexer.UnLex(AsmToken(AsmToken::Greater, Tok.getString().substr(1))); 4042 } else if (parseToken(AsmToken::Greater, Msg)) { 4043 return true; 4044 } 4045 AngleBracketDepth--; 4046 return false; 4047 } 4048 4049 bool MasmParser::parseFieldInitializer(const FieldInfo &Field, 4050 const IntFieldInfo &Contents, 4051 FieldInitializer &Initializer) { 4052 SMLoc Loc = getTok().getLoc(); 4053 4054 SmallVector<const MCExpr *, 1> Values; 4055 if (parseOptionalToken(AsmToken::LCurly)) { 4056 if (Field.LengthOf == 1 && Field.Type > 1) 4057 return Error(Loc, "Cannot initialize scalar field with array value"); 4058 if (parseScalarInstList(Field.Type, Values, AsmToken::RCurly) || 4059 parseToken(AsmToken::RCurly)) 4060 return true; 4061 } else if (parseOptionalAngleBracketOpen()) { 4062 if (Field.LengthOf == 1 && Field.Type > 1) 4063 return Error(Loc, "Cannot initialize scalar field with array value"); 4064 if (parseScalarInstList(Field.Type, Values, AsmToken::Greater) || 4065 parseAngleBracketClose()) 4066 return true; 4067 } else if (Field.LengthOf > 1 && Field.Type > 1) { 4068 return Error(Loc, "Cannot initialize array field with scalar value"); 4069 } else if (parseScalarInitializer(Field.Type, Values, 4070 /*StringPadLength=*/Field.LengthOf)) { 4071 return true; 4072 } 4073 4074 if (Values.size() > Field.LengthOf) { 4075 return Error(Loc, "Initializer too long for field; expected at most " + 4076 std::to_string(Field.LengthOf) + " elements, got " + 4077 std::to_string(Values.size())); 4078 } 4079 // Default-initialize all remaining values. 4080 Values.append(Contents.Values.begin() + Values.size(), Contents.Values.end()); 4081 4082 Initializer = FieldInitializer(std::move(Values)); 4083 return false; 4084 } 4085 4086 bool MasmParser::parseFieldInitializer(const FieldInfo &Field, 4087 const RealFieldInfo &Contents, 4088 FieldInitializer &Initializer) { 4089 const fltSemantics *Semantics; 4090 switch (Field.Type) { 4091 case 4: 4092 Semantics = &APFloat::IEEEsingle(); 4093 break; 4094 case 8: 4095 Semantics = &APFloat::IEEEdouble(); 4096 break; 4097 case 10: 4098 Semantics = &APFloat::x87DoubleExtended(); 4099 break; 4100 default: 4101 llvm_unreachable("unknown real field type"); 4102 } 4103 4104 SMLoc Loc = getTok().getLoc(); 4105 4106 SmallVector<APInt, 1> AsIntValues; 4107 if (parseOptionalToken(AsmToken::LCurly)) { 4108 if (Field.LengthOf == 1) 4109 return Error(Loc, "Cannot initialize scalar field with array value"); 4110 if (parseRealInstList(*Semantics, AsIntValues, AsmToken::RCurly) || 4111 parseToken(AsmToken::RCurly)) 4112 return true; 4113 } else if (parseOptionalAngleBracketOpen()) { 4114 if (Field.LengthOf == 1) 4115 return Error(Loc, "Cannot initialize scalar field with array value"); 4116 if (parseRealInstList(*Semantics, AsIntValues, AsmToken::Greater) || 4117 parseAngleBracketClose()) 4118 return true; 4119 } else if (Field.LengthOf > 1) { 4120 return Error(Loc, "Cannot initialize array field with scalar value"); 4121 } else { 4122 AsIntValues.emplace_back(); 4123 if (parseRealValue(*Semantics, AsIntValues.back())) 4124 return true; 4125 } 4126 4127 if (AsIntValues.size() > Field.LengthOf) { 4128 return Error(Loc, "Initializer too long for field; expected at most " + 4129 std::to_string(Field.LengthOf) + " elements, got " + 4130 std::to_string(AsIntValues.size())); 4131 } 4132 // Default-initialize all remaining values. 4133 AsIntValues.append(Contents.AsIntValues.begin() + AsIntValues.size(), 4134 Contents.AsIntValues.end()); 4135 4136 Initializer = FieldInitializer(std::move(AsIntValues)); 4137 return false; 4138 } 4139 4140 bool MasmParser::parseFieldInitializer(const FieldInfo &Field, 4141 const StructFieldInfo &Contents, 4142 FieldInitializer &Initializer) { 4143 SMLoc Loc = getTok().getLoc(); 4144 4145 std::vector<StructInitializer> Initializers; 4146 if (Field.LengthOf > 1) { 4147 if (parseOptionalToken(AsmToken::LCurly)) { 4148 if (parseStructInstList(Contents.Structure, Initializers, 4149 AsmToken::RCurly) || 4150 parseToken(AsmToken::RCurly)) 4151 return true; 4152 } else if (parseOptionalAngleBracketOpen()) { 4153 if (parseStructInstList(Contents.Structure, Initializers, 4154 AsmToken::Greater) || 4155 parseAngleBracketClose()) 4156 return true; 4157 } else { 4158 return Error(Loc, "Cannot initialize array field with scalar value"); 4159 } 4160 } else { 4161 Initializers.emplace_back(); 4162 if (parseStructInitializer(Contents.Structure, Initializers.back())) 4163 return true; 4164 } 4165 4166 if (Initializers.size() > Field.LengthOf) { 4167 return Error(Loc, "Initializer too long for field; expected at most " + 4168 std::to_string(Field.LengthOf) + " elements, got " + 4169 std::to_string(Initializers.size())); 4170 } 4171 // Default-initialize all remaining values. 4172 Initializers.insert(Initializers.end(), 4173 Contents.Initializers.begin() + Initializers.size(), 4174 Contents.Initializers.end()); 4175 4176 Initializer = FieldInitializer(std::move(Initializers), Contents.Structure); 4177 return false; 4178 } 4179 4180 bool MasmParser::parseFieldInitializer(const FieldInfo &Field, 4181 FieldInitializer &Initializer) { 4182 switch (Field.Contents.FT) { 4183 case FT_INTEGRAL: 4184 return parseFieldInitializer(Field, Field.Contents.IntInfo, Initializer); 4185 case FT_REAL: 4186 return parseFieldInitializer(Field, Field.Contents.RealInfo, Initializer); 4187 case FT_STRUCT: 4188 return parseFieldInitializer(Field, Field.Contents.StructInfo, Initializer); 4189 } 4190 llvm_unreachable("Unhandled FieldType enum"); 4191 } 4192 4193 bool MasmParser::parseStructInitializer(const StructInfo &Structure, 4194 StructInitializer &Initializer) { 4195 const AsmToken FirstToken = getTok(); 4196 4197 Optional<AsmToken::TokenKind> EndToken; 4198 if (parseOptionalToken(AsmToken::LCurly)) { 4199 EndToken = AsmToken::RCurly; 4200 } else if (parseOptionalAngleBracketOpen()) { 4201 EndToken = AsmToken::Greater; 4202 AngleBracketDepth++; 4203 } else if (FirstToken.is(AsmToken::Identifier) && 4204 FirstToken.getString() == "?") { 4205 // ? initializer; leave EndToken uninitialized to treat as empty. 4206 if (parseToken(AsmToken::Identifier)) 4207 return true; 4208 } else { 4209 return Error(FirstToken.getLoc(), "Expected struct initializer"); 4210 } 4211 4212 auto &FieldInitializers = Initializer.FieldInitializers; 4213 size_t FieldIndex = 0; 4214 if (EndToken) { 4215 // Initialize all fields with given initializers. 4216 while (getTok().isNot(EndToken.value()) && 4217 FieldIndex < Structure.Fields.size()) { 4218 const FieldInfo &Field = Structure.Fields[FieldIndex++]; 4219 if (parseOptionalToken(AsmToken::Comma)) { 4220 // Empty initializer; use the default and continue. (Also, allow line 4221 // continuation.) 4222 FieldInitializers.push_back(Field.Contents); 4223 parseOptionalToken(AsmToken::EndOfStatement); 4224 continue; 4225 } 4226 FieldInitializers.emplace_back(Field.Contents.FT); 4227 if (parseFieldInitializer(Field, FieldInitializers.back())) 4228 return true; 4229 4230 // Continue if we see a comma. (Also, allow line continuation.) 4231 SMLoc CommaLoc = getTok().getLoc(); 4232 if (!parseOptionalToken(AsmToken::Comma)) 4233 break; 4234 if (FieldIndex == Structure.Fields.size()) 4235 return Error(CommaLoc, "'" + Structure.Name + 4236 "' initializer initializes too many fields"); 4237 parseOptionalToken(AsmToken::EndOfStatement); 4238 } 4239 } 4240 // Default-initialize all remaining fields. 4241 for (auto It = Structure.Fields.begin() + FieldIndex; 4242 It != Structure.Fields.end(); ++It) { 4243 const FieldInfo &Field = *It; 4244 FieldInitializers.push_back(Field.Contents); 4245 } 4246 4247 if (EndToken) { 4248 if (EndToken.value() == AsmToken::Greater) 4249 return parseAngleBracketClose(); 4250 4251 return parseToken(EndToken.value()); 4252 } 4253 4254 return false; 4255 } 4256 4257 bool MasmParser::parseStructInstList( 4258 const StructInfo &Structure, std::vector<StructInitializer> &Initializers, 4259 const AsmToken::TokenKind EndToken) { 4260 while (getTok().isNot(EndToken) || 4261 (EndToken == AsmToken::Greater && 4262 getTok().isNot(AsmToken::GreaterGreater))) { 4263 const AsmToken NextTok = peekTok(); 4264 if (NextTok.is(AsmToken::Identifier) && 4265 NextTok.getString().equals_insensitive("dup")) { 4266 const MCExpr *Value; 4267 if (parseExpression(Value) || parseToken(AsmToken::Identifier)) 4268 return true; 4269 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 4270 if (!MCE) 4271 return Error(Value->getLoc(), 4272 "cannot repeat value a non-constant number of times"); 4273 const int64_t Repetitions = MCE->getValue(); 4274 if (Repetitions < 0) 4275 return Error(Value->getLoc(), 4276 "cannot repeat value a negative number of times"); 4277 4278 std::vector<StructInitializer> DuplicatedValues; 4279 if (parseToken(AsmToken::LParen, 4280 "parentheses required for 'dup' contents") || 4281 parseStructInstList(Structure, DuplicatedValues) || parseRParen()) 4282 return true; 4283 4284 for (int i = 0; i < Repetitions; ++i) 4285 llvm::append_range(Initializers, DuplicatedValues); 4286 } else { 4287 Initializers.emplace_back(); 4288 if (parseStructInitializer(Structure, Initializers.back())) 4289 return true; 4290 } 4291 4292 // Continue if we see a comma. (Also, allow line continuation.) 4293 if (!parseOptionalToken(AsmToken::Comma)) 4294 break; 4295 parseOptionalToken(AsmToken::EndOfStatement); 4296 } 4297 4298 return false; 4299 } 4300 4301 bool MasmParser::emitFieldValue(const FieldInfo &Field, 4302 const IntFieldInfo &Contents) { 4303 // Default-initialize all values. 4304 for (const MCExpr *Value : Contents.Values) { 4305 if (emitIntValue(Value, Field.Type)) 4306 return true; 4307 } 4308 return false; 4309 } 4310 4311 bool MasmParser::emitFieldValue(const FieldInfo &Field, 4312 const RealFieldInfo &Contents) { 4313 for (const APInt &AsInt : Contents.AsIntValues) { 4314 getStreamer().emitIntValue(AsInt.getLimitedValue(), 4315 AsInt.getBitWidth() / 8); 4316 } 4317 return false; 4318 } 4319 4320 bool MasmParser::emitFieldValue(const FieldInfo &Field, 4321 const StructFieldInfo &Contents) { 4322 for (const auto &Initializer : Contents.Initializers) { 4323 size_t Index = 0, Offset = 0; 4324 for (const auto &SubField : Contents.Structure.Fields) { 4325 getStreamer().emitZeros(SubField.Offset - Offset); 4326 Offset = SubField.Offset + SubField.SizeOf; 4327 emitFieldInitializer(SubField, Initializer.FieldInitializers[Index++]); 4328 } 4329 } 4330 return false; 4331 } 4332 4333 bool MasmParser::emitFieldValue(const FieldInfo &Field) { 4334 switch (Field.Contents.FT) { 4335 case FT_INTEGRAL: 4336 return emitFieldValue(Field, Field.Contents.IntInfo); 4337 case FT_REAL: 4338 return emitFieldValue(Field, Field.Contents.RealInfo); 4339 case FT_STRUCT: 4340 return emitFieldValue(Field, Field.Contents.StructInfo); 4341 } 4342 llvm_unreachable("Unhandled FieldType enum"); 4343 } 4344 4345 bool MasmParser::emitFieldInitializer(const FieldInfo &Field, 4346 const IntFieldInfo &Contents, 4347 const IntFieldInfo &Initializer) { 4348 for (const auto &Value : Initializer.Values) { 4349 if (emitIntValue(Value, Field.Type)) 4350 return true; 4351 } 4352 // Default-initialize all remaining values. 4353 for (auto it = Contents.Values.begin() + Initializer.Values.size(); 4354 it != Contents.Values.end(); ++it) { 4355 const auto &Value = *it; 4356 if (emitIntValue(Value, Field.Type)) 4357 return true; 4358 } 4359 return false; 4360 } 4361 4362 bool MasmParser::emitFieldInitializer(const FieldInfo &Field, 4363 const RealFieldInfo &Contents, 4364 const RealFieldInfo &Initializer) { 4365 for (const auto &AsInt : Initializer.AsIntValues) { 4366 getStreamer().emitIntValue(AsInt.getLimitedValue(), 4367 AsInt.getBitWidth() / 8); 4368 } 4369 // Default-initialize all remaining values. 4370 for (auto It = Contents.AsIntValues.begin() + Initializer.AsIntValues.size(); 4371 It != Contents.AsIntValues.end(); ++It) { 4372 const auto &AsInt = *It; 4373 getStreamer().emitIntValue(AsInt.getLimitedValue(), 4374 AsInt.getBitWidth() / 8); 4375 } 4376 return false; 4377 } 4378 4379 bool MasmParser::emitFieldInitializer(const FieldInfo &Field, 4380 const StructFieldInfo &Contents, 4381 const StructFieldInfo &Initializer) { 4382 for (const auto &Init : Initializer.Initializers) { 4383 if (emitStructInitializer(Contents.Structure, Init)) 4384 return true; 4385 } 4386 // Default-initialize all remaining values. 4387 for (auto It = 4388 Contents.Initializers.begin() + Initializer.Initializers.size(); 4389 It != Contents.Initializers.end(); ++It) { 4390 const auto &Init = *It; 4391 if (emitStructInitializer(Contents.Structure, Init)) 4392 return true; 4393 } 4394 return false; 4395 } 4396 4397 bool MasmParser::emitFieldInitializer(const FieldInfo &Field, 4398 const FieldInitializer &Initializer) { 4399 switch (Field.Contents.FT) { 4400 case FT_INTEGRAL: 4401 return emitFieldInitializer(Field, Field.Contents.IntInfo, 4402 Initializer.IntInfo); 4403 case FT_REAL: 4404 return emitFieldInitializer(Field, Field.Contents.RealInfo, 4405 Initializer.RealInfo); 4406 case FT_STRUCT: 4407 return emitFieldInitializer(Field, Field.Contents.StructInfo, 4408 Initializer.StructInfo); 4409 } 4410 llvm_unreachable("Unhandled FieldType enum"); 4411 } 4412 4413 bool MasmParser::emitStructInitializer(const StructInfo &Structure, 4414 const StructInitializer &Initializer) { 4415 if (!Structure.Initializable) 4416 return Error(getLexer().getLoc(), 4417 "cannot initialize a value of type '" + Structure.Name + 4418 "'; 'org' was used in the type's declaration"); 4419 size_t Index = 0, Offset = 0; 4420 for (const auto &Init : Initializer.FieldInitializers) { 4421 const auto &Field = Structure.Fields[Index++]; 4422 getStreamer().emitZeros(Field.Offset - Offset); 4423 Offset = Field.Offset + Field.SizeOf; 4424 if (emitFieldInitializer(Field, Init)) 4425 return true; 4426 } 4427 // Default-initialize all remaining fields. 4428 for (auto It = 4429 Structure.Fields.begin() + Initializer.FieldInitializers.size(); 4430 It != Structure.Fields.end(); ++It) { 4431 const auto &Field = *It; 4432 getStreamer().emitZeros(Field.Offset - Offset); 4433 Offset = Field.Offset + Field.SizeOf; 4434 if (emitFieldValue(Field)) 4435 return true; 4436 } 4437 // Add final padding. 4438 if (Offset != Structure.Size) 4439 getStreamer().emitZeros(Structure.Size - Offset); 4440 return false; 4441 } 4442 4443 // Set data values from initializers. 4444 bool MasmParser::emitStructValues(const StructInfo &Structure, 4445 unsigned *Count) { 4446 std::vector<StructInitializer> Initializers; 4447 if (parseStructInstList(Structure, Initializers)) 4448 return true; 4449 4450 for (const auto &Initializer : Initializers) { 4451 if (emitStructInitializer(Structure, Initializer)) 4452 return true; 4453 } 4454 4455 if (Count) 4456 *Count = Initializers.size(); 4457 return false; 4458 } 4459 4460 // Declare a field in the current struct. 4461 bool MasmParser::addStructField(StringRef Name, const StructInfo &Structure) { 4462 StructInfo &OwningStruct = StructInProgress.back(); 4463 FieldInfo &Field = 4464 OwningStruct.addField(Name, FT_STRUCT, Structure.AlignmentSize); 4465 StructFieldInfo &StructInfo = Field.Contents.StructInfo; 4466 4467 StructInfo.Structure = Structure; 4468 Field.Type = Structure.Size; 4469 4470 if (parseStructInstList(Structure, StructInfo.Initializers)) 4471 return true; 4472 4473 Field.LengthOf = StructInfo.Initializers.size(); 4474 Field.SizeOf = Field.Type * Field.LengthOf; 4475 4476 const unsigned FieldEnd = Field.Offset + Field.SizeOf; 4477 if (!OwningStruct.IsUnion) { 4478 OwningStruct.NextOffset = FieldEnd; 4479 } 4480 OwningStruct.Size = std::max(OwningStruct.Size, FieldEnd); 4481 4482 return false; 4483 } 4484 4485 /// parseDirectiveStructValue 4486 /// ::= struct-id (<struct-initializer> | {struct-initializer}) 4487 /// [, (<struct-initializer> | {struct-initializer})]* 4488 bool MasmParser::parseDirectiveStructValue(const StructInfo &Structure, 4489 StringRef Directive, SMLoc DirLoc) { 4490 if (StructInProgress.empty()) { 4491 if (emitStructValues(Structure)) 4492 return true; 4493 } else if (addStructField("", Structure)) { 4494 return addErrorSuffix(" in '" + Twine(Directive) + "' directive"); 4495 } 4496 4497 return false; 4498 } 4499 4500 /// parseDirectiveNamedValue 4501 /// ::= name (byte | word | ... ) [ expression (, expression)* ] 4502 bool MasmParser::parseDirectiveNamedStructValue(const StructInfo &Structure, 4503 StringRef Directive, 4504 SMLoc DirLoc, StringRef Name) { 4505 if (StructInProgress.empty()) { 4506 // Initialize named data value. 4507 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 4508 getStreamer().emitLabel(Sym); 4509 unsigned Count; 4510 if (emitStructValues(Structure, &Count)) 4511 return true; 4512 AsmTypeInfo Type; 4513 Type.Name = Structure.Name; 4514 Type.Size = Structure.Size * Count; 4515 Type.ElementSize = Structure.Size; 4516 Type.Length = Count; 4517 KnownType[Name.lower()] = Type; 4518 } else if (addStructField(Name, Structure)) { 4519 return addErrorSuffix(" in '" + Twine(Directive) + "' directive"); 4520 } 4521 4522 return false; 4523 } 4524 4525 /// parseDirectiveStruct 4526 /// ::= <name> (STRUC | STRUCT | UNION) [fieldAlign] [, NONUNIQUE] 4527 /// (dataDir | generalDir | offsetDir | nestedStruct)+ 4528 /// <name> ENDS 4529 ////// dataDir = data declaration 4530 ////// offsetDir = EVEN, ORG, ALIGN 4531 bool MasmParser::parseDirectiveStruct(StringRef Directive, 4532 DirectiveKind DirKind, StringRef Name, 4533 SMLoc NameLoc) { 4534 // We ignore NONUNIQUE; we do not support OPTION M510 or OPTION OLDSTRUCTS 4535 // anyway, so all field accesses must be qualified. 4536 AsmToken NextTok = getTok(); 4537 int64_t AlignmentValue = 1; 4538 if (NextTok.isNot(AsmToken::Comma) && 4539 NextTok.isNot(AsmToken::EndOfStatement) && 4540 parseAbsoluteExpression(AlignmentValue)) { 4541 return addErrorSuffix(" in alignment value for '" + Twine(Directive) + 4542 "' directive"); 4543 } 4544 if (!isPowerOf2_64(AlignmentValue)) { 4545 return Error(NextTok.getLoc(), "alignment must be a power of two; was " + 4546 std::to_string(AlignmentValue)); 4547 } 4548 4549 StringRef Qualifier; 4550 SMLoc QualifierLoc; 4551 if (parseOptionalToken(AsmToken::Comma)) { 4552 QualifierLoc = getTok().getLoc(); 4553 if (parseIdentifier(Qualifier)) 4554 return addErrorSuffix(" in '" + Twine(Directive) + "' directive"); 4555 if (!Qualifier.equals_insensitive("nonunique")) 4556 return Error(QualifierLoc, "Unrecognized qualifier for '" + 4557 Twine(Directive) + 4558 "' directive; expected none or NONUNIQUE"); 4559 } 4560 4561 if (parseToken(AsmToken::EndOfStatement)) 4562 return addErrorSuffix(" in '" + Twine(Directive) + "' directive"); 4563 4564 StructInProgress.emplace_back(Name, DirKind == DK_UNION, AlignmentValue); 4565 return false; 4566 } 4567 4568 /// parseDirectiveNestedStruct 4569 /// ::= (STRUC | STRUCT | UNION) [name] 4570 /// (dataDir | generalDir | offsetDir | nestedStruct)+ 4571 /// ENDS 4572 bool MasmParser::parseDirectiveNestedStruct(StringRef Directive, 4573 DirectiveKind DirKind) { 4574 if (StructInProgress.empty()) 4575 return TokError("missing name in top-level '" + Twine(Directive) + 4576 "' directive"); 4577 4578 StringRef Name; 4579 if (getTok().is(AsmToken::Identifier)) { 4580 Name = getTok().getIdentifier(); 4581 parseToken(AsmToken::Identifier); 4582 } 4583 if (parseToken(AsmToken::EndOfStatement)) 4584 return addErrorSuffix(" in '" + Twine(Directive) + "' directive"); 4585 4586 // Reserve space to ensure Alignment doesn't get invalidated when 4587 // StructInProgress grows. 4588 StructInProgress.reserve(StructInProgress.size() + 1); 4589 StructInProgress.emplace_back(Name, DirKind == DK_UNION, 4590 StructInProgress.back().Alignment); 4591 return false; 4592 } 4593 4594 bool MasmParser::parseDirectiveEnds(StringRef Name, SMLoc NameLoc) { 4595 if (StructInProgress.empty()) 4596 return Error(NameLoc, "ENDS directive without matching STRUC/STRUCT/UNION"); 4597 if (StructInProgress.size() > 1) 4598 return Error(NameLoc, "unexpected name in nested ENDS directive"); 4599 if (StructInProgress.back().Name.compare_insensitive(Name)) 4600 return Error(NameLoc, "mismatched name in ENDS directive; expected '" + 4601 StructInProgress.back().Name + "'"); 4602 StructInfo Structure = StructInProgress.pop_back_val(); 4603 // Pad to make the structure's size divisible by the smaller of its alignment 4604 // and the size of its largest field. 4605 Structure.Size = llvm::alignTo( 4606 Structure.Size, std::min(Structure.Alignment, Structure.AlignmentSize)); 4607 Structs[Name.lower()] = Structure; 4608 4609 if (parseToken(AsmToken::EndOfStatement)) 4610 return addErrorSuffix(" in ENDS directive"); 4611 4612 return false; 4613 } 4614 4615 bool MasmParser::parseDirectiveNestedEnds() { 4616 if (StructInProgress.empty()) 4617 return TokError("ENDS directive without matching STRUC/STRUCT/UNION"); 4618 if (StructInProgress.size() == 1) 4619 return TokError("missing name in top-level ENDS directive"); 4620 4621 if (parseToken(AsmToken::EndOfStatement)) 4622 return addErrorSuffix(" in nested ENDS directive"); 4623 4624 StructInfo Structure = StructInProgress.pop_back_val(); 4625 // Pad to make the structure's size divisible by its alignment. 4626 Structure.Size = llvm::alignTo(Structure.Size, Structure.Alignment); 4627 4628 StructInfo &ParentStruct = StructInProgress.back(); 4629 if (Structure.Name.empty()) { 4630 // Anonymous substructures' fields are addressed as if they belong to the 4631 // parent structure - so we transfer them to the parent here. 4632 const size_t OldFields = ParentStruct.Fields.size(); 4633 ParentStruct.Fields.insert( 4634 ParentStruct.Fields.end(), 4635 std::make_move_iterator(Structure.Fields.begin()), 4636 std::make_move_iterator(Structure.Fields.end())); 4637 for (const auto &FieldByName : Structure.FieldsByName) { 4638 ParentStruct.FieldsByName[FieldByName.getKey()] = 4639 FieldByName.getValue() + OldFields; 4640 } 4641 4642 unsigned FirstFieldOffset = 0; 4643 if (!Structure.Fields.empty() && !ParentStruct.IsUnion) { 4644 FirstFieldOffset = llvm::alignTo( 4645 ParentStruct.NextOffset, 4646 std::min(ParentStruct.Alignment, Structure.AlignmentSize)); 4647 } 4648 4649 if (ParentStruct.IsUnion) { 4650 ParentStruct.Size = std::max(ParentStruct.Size, Structure.Size); 4651 } else { 4652 for (auto FieldIter = ParentStruct.Fields.begin() + OldFields; 4653 FieldIter != ParentStruct.Fields.end(); ++FieldIter) { 4654 FieldIter->Offset += FirstFieldOffset; 4655 } 4656 4657 const unsigned StructureEnd = FirstFieldOffset + Structure.Size; 4658 if (!ParentStruct.IsUnion) { 4659 ParentStruct.NextOffset = StructureEnd; 4660 } 4661 ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd); 4662 } 4663 } else { 4664 FieldInfo &Field = ParentStruct.addField(Structure.Name, FT_STRUCT, 4665 Structure.AlignmentSize); 4666 StructFieldInfo &StructInfo = Field.Contents.StructInfo; 4667 Field.Type = Structure.Size; 4668 Field.LengthOf = 1; 4669 Field.SizeOf = Structure.Size; 4670 4671 const unsigned StructureEnd = Field.Offset + Field.SizeOf; 4672 if (!ParentStruct.IsUnion) { 4673 ParentStruct.NextOffset = StructureEnd; 4674 } 4675 ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd); 4676 4677 StructInfo.Structure = Structure; 4678 StructInfo.Initializers.emplace_back(); 4679 auto &FieldInitializers = StructInfo.Initializers.back().FieldInitializers; 4680 for (const auto &SubField : Structure.Fields) { 4681 FieldInitializers.push_back(SubField.Contents); 4682 } 4683 } 4684 4685 return false; 4686 } 4687 4688 /// parseDirectiveOrg 4689 /// ::= org expression 4690 bool MasmParser::parseDirectiveOrg() { 4691 const MCExpr *Offset; 4692 SMLoc OffsetLoc = Lexer.getLoc(); 4693 if (checkForValidSection() || parseExpression(Offset)) 4694 return true; 4695 if (parseToken(AsmToken::EndOfStatement)) 4696 return addErrorSuffix(" in 'org' directive"); 4697 4698 if (StructInProgress.empty()) { 4699 // Not in a struct; change the offset for the next instruction or data 4700 if (checkForValidSection()) 4701 return addErrorSuffix(" in 'org' directive"); 4702 4703 getStreamer().emitValueToOffset(Offset, 0, OffsetLoc); 4704 } else { 4705 // Offset the next field of this struct 4706 StructInfo &Structure = StructInProgress.back(); 4707 int64_t OffsetRes; 4708 if (!Offset->evaluateAsAbsolute(OffsetRes, getStreamer().getAssemblerPtr())) 4709 return Error(OffsetLoc, 4710 "expected absolute expression in 'org' directive"); 4711 if (OffsetRes < 0) 4712 return Error( 4713 OffsetLoc, 4714 "expected non-negative value in struct's 'org' directive; was " + 4715 std::to_string(OffsetRes)); 4716 Structure.NextOffset = static_cast<unsigned>(OffsetRes); 4717 4718 // ORG-affected structures cannot be initialized 4719 Structure.Initializable = false; 4720 } 4721 4722 return false; 4723 } 4724 4725 bool MasmParser::emitAlignTo(int64_t Alignment) { 4726 if (StructInProgress.empty()) { 4727 // Not in a struct; align the next instruction or data 4728 if (checkForValidSection()) 4729 return true; 4730 4731 // Check whether we should use optimal code alignment for this align 4732 // directive. 4733 const MCSection *Section = getStreamer().getCurrentSectionOnly(); 4734 assert(Section && "must have section to emit alignment"); 4735 if (Section->useCodeAlign()) { 4736 getStreamer().emitCodeAlignment(Alignment, &getTargetParser().getSTI(), 4737 /*MaxBytesToEmit=*/0); 4738 } else { 4739 // FIXME: Target specific behavior about how the "extra" bytes are filled. 4740 getStreamer().emitValueToAlignment(Alignment, /*Value=*/0, 4741 /*ValueSize=*/1, 4742 /*MaxBytesToEmit=*/0); 4743 } 4744 } else { 4745 // Align the next field of this struct 4746 StructInfo &Structure = StructInProgress.back(); 4747 Structure.NextOffset = llvm::alignTo(Structure.NextOffset, Alignment); 4748 } 4749 4750 return false; 4751 } 4752 4753 /// parseDirectiveAlign 4754 /// ::= align expression 4755 bool MasmParser::parseDirectiveAlign() { 4756 SMLoc AlignmentLoc = getLexer().getLoc(); 4757 int64_t Alignment; 4758 4759 // Ignore empty 'align' directives. 4760 if (getTok().is(AsmToken::EndOfStatement)) { 4761 return Warning(AlignmentLoc, 4762 "align directive with no operand is ignored") && 4763 parseToken(AsmToken::EndOfStatement); 4764 } 4765 if (parseAbsoluteExpression(Alignment) || 4766 parseToken(AsmToken::EndOfStatement)) 4767 return addErrorSuffix(" in align directive"); 4768 4769 // Always emit an alignment here even if we throw an error. 4770 bool ReturnVal = false; 4771 4772 // Reject alignments that aren't either a power of two or zero, for ML.exe 4773 // compatibility. Alignment of zero is silently rounded up to one. 4774 if (Alignment == 0) 4775 Alignment = 1; 4776 if (!isPowerOf2_64(Alignment)) 4777 ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2; was " + 4778 std::to_string(Alignment)); 4779 4780 if (emitAlignTo(Alignment)) 4781 ReturnVal |= addErrorSuffix(" in align directive"); 4782 4783 return ReturnVal; 4784 } 4785 4786 /// parseDirectiveEven 4787 /// ::= even 4788 bool MasmParser::parseDirectiveEven() { 4789 if (parseToken(AsmToken::EndOfStatement) || emitAlignTo(2)) 4790 return addErrorSuffix(" in even directive"); 4791 4792 return false; 4793 } 4794 4795 /// parseDirectiveFile 4796 /// ::= .file filename 4797 /// ::= .file number [directory] filename [md5 checksum] [source source-text] 4798 bool MasmParser::parseDirectiveFile(SMLoc DirectiveLoc) { 4799 // FIXME: I'm not sure what this is. 4800 int64_t FileNumber = -1; 4801 if (getLexer().is(AsmToken::Integer)) { 4802 FileNumber = getTok().getIntVal(); 4803 Lex(); 4804 4805 if (FileNumber < 0) 4806 return TokError("negative file number"); 4807 } 4808 4809 std::string Path; 4810 4811 // Usually the directory and filename together, otherwise just the directory. 4812 // Allow the strings to have escaped octal character sequence. 4813 if (check(getTok().isNot(AsmToken::String), 4814 "unexpected token in '.file' directive") || 4815 parseEscapedString(Path)) 4816 return true; 4817 4818 StringRef Directory; 4819 StringRef Filename; 4820 std::string FilenameData; 4821 if (getLexer().is(AsmToken::String)) { 4822 if (check(FileNumber == -1, 4823 "explicit path specified, but no file number") || 4824 parseEscapedString(FilenameData)) 4825 return true; 4826 Filename = FilenameData; 4827 Directory = Path; 4828 } else { 4829 Filename = Path; 4830 } 4831 4832 uint64_t MD5Hi, MD5Lo; 4833 bool HasMD5 = false; 4834 4835 Optional<StringRef> Source; 4836 bool HasSource = false; 4837 std::string SourceString; 4838 4839 while (!parseOptionalToken(AsmToken::EndOfStatement)) { 4840 StringRef Keyword; 4841 if (check(getTok().isNot(AsmToken::Identifier), 4842 "unexpected token in '.file' directive") || 4843 parseIdentifier(Keyword)) 4844 return true; 4845 if (Keyword == "md5") { 4846 HasMD5 = true; 4847 if (check(FileNumber == -1, 4848 "MD5 checksum specified, but no file number") || 4849 parseHexOcta(*this, MD5Hi, MD5Lo)) 4850 return true; 4851 } else if (Keyword == "source") { 4852 HasSource = true; 4853 if (check(FileNumber == -1, 4854 "source specified, but no file number") || 4855 check(getTok().isNot(AsmToken::String), 4856 "unexpected token in '.file' directive") || 4857 parseEscapedString(SourceString)) 4858 return true; 4859 } else { 4860 return TokError("unexpected token in '.file' directive"); 4861 } 4862 } 4863 4864 if (FileNumber == -1) { 4865 // Ignore the directive if there is no number and the target doesn't support 4866 // numberless .file directives. This allows some portability of assembler 4867 // between different object file formats. 4868 if (getContext().getAsmInfo()->hasSingleParameterDotFile()) 4869 getStreamer().emitFileDirective(Filename); 4870 } else { 4871 // In case there is a -g option as well as debug info from directive .file, 4872 // we turn off the -g option, directly use the existing debug info instead. 4873 // Throw away any implicit file table for the assembler source. 4874 if (Ctx.getGenDwarfForAssembly()) { 4875 Ctx.getMCDwarfLineTable(0).resetFileTable(); 4876 Ctx.setGenDwarfForAssembly(false); 4877 } 4878 4879 Optional<MD5::MD5Result> CKMem; 4880 if (HasMD5) { 4881 MD5::MD5Result Sum; 4882 for (unsigned i = 0; i != 8; ++i) { 4883 Sum[i] = uint8_t(MD5Hi >> ((7 - i) * 8)); 4884 Sum[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8)); 4885 } 4886 CKMem = Sum; 4887 } 4888 if (HasSource) { 4889 char *SourceBuf = static_cast<char *>(Ctx.allocate(SourceString.size())); 4890 memcpy(SourceBuf, SourceString.data(), SourceString.size()); 4891 Source = StringRef(SourceBuf, SourceString.size()); 4892 } 4893 if (FileNumber == 0) { 4894 if (Ctx.getDwarfVersion() < 5) 4895 return Warning(DirectiveLoc, "file 0 not supported prior to DWARF-5"); 4896 getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source); 4897 } else { 4898 Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective( 4899 FileNumber, Directory, Filename, CKMem, Source); 4900 if (!FileNumOrErr) 4901 return Error(DirectiveLoc, toString(FileNumOrErr.takeError())); 4902 } 4903 // Alert the user if there are some .file directives with MD5 and some not. 4904 // But only do that once. 4905 if (!ReportedInconsistentMD5 && !Ctx.isDwarfMD5UsageConsistent(0)) { 4906 ReportedInconsistentMD5 = true; 4907 return Warning(DirectiveLoc, "inconsistent use of MD5 checksums"); 4908 } 4909 } 4910 4911 return false; 4912 } 4913 4914 /// parseDirectiveLine 4915 /// ::= .line [number] 4916 bool MasmParser::parseDirectiveLine() { 4917 int64_t LineNumber; 4918 if (getLexer().is(AsmToken::Integer)) { 4919 if (parseIntToken(LineNumber, "unexpected token in '.line' directive")) 4920 return true; 4921 (void)LineNumber; 4922 // FIXME: Do something with the .line. 4923 } 4924 if (parseEOL()) 4925 return true; 4926 4927 return false; 4928 } 4929 4930 /// parseDirectiveLoc 4931 /// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end] 4932 /// [epilogue_begin] [is_stmt VALUE] [isa VALUE] 4933 /// The first number is a file number, must have been previously assigned with 4934 /// a .file directive, the second number is the line number and optionally the 4935 /// third number is a column position (zero if not specified). The remaining 4936 /// optional items are .loc sub-directives. 4937 bool MasmParser::parseDirectiveLoc() { 4938 int64_t FileNumber = 0, LineNumber = 0; 4939 SMLoc Loc = getTok().getLoc(); 4940 if (parseIntToken(FileNumber, "unexpected token in '.loc' directive") || 4941 check(FileNumber < 1 && Ctx.getDwarfVersion() < 5, Loc, 4942 "file number less than one in '.loc' directive") || 4943 check(!getContext().isValidDwarfFileNumber(FileNumber), Loc, 4944 "unassigned file number in '.loc' directive")) 4945 return true; 4946 4947 // optional 4948 if (getLexer().is(AsmToken::Integer)) { 4949 LineNumber = getTok().getIntVal(); 4950 if (LineNumber < 0) 4951 return TokError("line number less than zero in '.loc' directive"); 4952 Lex(); 4953 } 4954 4955 int64_t ColumnPos = 0; 4956 if (getLexer().is(AsmToken::Integer)) { 4957 ColumnPos = getTok().getIntVal(); 4958 if (ColumnPos < 0) 4959 return TokError("column position less than zero in '.loc' directive"); 4960 Lex(); 4961 } 4962 4963 auto PrevFlags = getContext().getCurrentDwarfLoc().getFlags(); 4964 unsigned Flags = PrevFlags & DWARF2_FLAG_IS_STMT; 4965 unsigned Isa = 0; 4966 int64_t Discriminator = 0; 4967 4968 auto parseLocOp = [&]() -> bool { 4969 StringRef Name; 4970 SMLoc Loc = getTok().getLoc(); 4971 if (parseIdentifier(Name)) 4972 return TokError("unexpected token in '.loc' directive"); 4973 4974 if (Name == "basic_block") 4975 Flags |= DWARF2_FLAG_BASIC_BLOCK; 4976 else if (Name == "prologue_end") 4977 Flags |= DWARF2_FLAG_PROLOGUE_END; 4978 else if (Name == "epilogue_begin") 4979 Flags |= DWARF2_FLAG_EPILOGUE_BEGIN; 4980 else if (Name == "is_stmt") { 4981 Loc = getTok().getLoc(); 4982 const MCExpr *Value; 4983 if (parseExpression(Value)) 4984 return true; 4985 // The expression must be the constant 0 or 1. 4986 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 4987 int Value = MCE->getValue(); 4988 if (Value == 0) 4989 Flags &= ~DWARF2_FLAG_IS_STMT; 4990 else if (Value == 1) 4991 Flags |= DWARF2_FLAG_IS_STMT; 4992 else 4993 return Error(Loc, "is_stmt value not 0 or 1"); 4994 } else { 4995 return Error(Loc, "is_stmt value not the constant value of 0 or 1"); 4996 } 4997 } else if (Name == "isa") { 4998 Loc = getTok().getLoc(); 4999 const MCExpr *Value; 5000 if (parseExpression(Value)) 5001 return true; 5002 // The expression must be a constant greater or equal to 0. 5003 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 5004 int Value = MCE->getValue(); 5005 if (Value < 0) 5006 return Error(Loc, "isa number less than zero"); 5007 Isa = Value; 5008 } else { 5009 return Error(Loc, "isa number not a constant value"); 5010 } 5011 } else if (Name == "discriminator") { 5012 if (parseAbsoluteExpression(Discriminator)) 5013 return true; 5014 } else { 5015 return Error(Loc, "unknown sub-directive in '.loc' directive"); 5016 } 5017 return false; 5018 }; 5019 5020 if (parseMany(parseLocOp, false /*hasComma*/)) 5021 return true; 5022 5023 getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags, 5024 Isa, Discriminator, StringRef()); 5025 5026 return false; 5027 } 5028 5029 /// parseDirectiveStabs 5030 /// ::= .stabs string, number, number, number 5031 bool MasmParser::parseDirectiveStabs() { 5032 return TokError("unsupported directive '.stabs'"); 5033 } 5034 5035 /// parseDirectiveCVFile 5036 /// ::= .cv_file number filename [checksum] [checksumkind] 5037 bool MasmParser::parseDirectiveCVFile() { 5038 SMLoc FileNumberLoc = getTok().getLoc(); 5039 int64_t FileNumber; 5040 std::string Filename; 5041 std::string Checksum; 5042 int64_t ChecksumKind = 0; 5043 5044 if (parseIntToken(FileNumber, 5045 "expected file number in '.cv_file' directive") || 5046 check(FileNumber < 1, FileNumberLoc, "file number less than one") || 5047 check(getTok().isNot(AsmToken::String), 5048 "unexpected token in '.cv_file' directive") || 5049 parseEscapedString(Filename)) 5050 return true; 5051 if (!parseOptionalToken(AsmToken::EndOfStatement)) { 5052 if (check(getTok().isNot(AsmToken::String), 5053 "unexpected token in '.cv_file' directive") || 5054 parseEscapedString(Checksum) || 5055 parseIntToken(ChecksumKind, 5056 "expected checksum kind in '.cv_file' directive") || 5057 parseEOL()) 5058 return true; 5059 } 5060 5061 Checksum = fromHex(Checksum); 5062 void *CKMem = Ctx.allocate(Checksum.size(), 1); 5063 memcpy(CKMem, Checksum.data(), Checksum.size()); 5064 ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem), 5065 Checksum.size()); 5066 5067 if (!getStreamer().emitCVFileDirective(FileNumber, Filename, ChecksumAsBytes, 5068 static_cast<uint8_t>(ChecksumKind))) 5069 return Error(FileNumberLoc, "file number already allocated"); 5070 5071 return false; 5072 } 5073 5074 bool MasmParser::parseCVFunctionId(int64_t &FunctionId, 5075 StringRef DirectiveName) { 5076 SMLoc Loc; 5077 return parseTokenLoc(Loc) || 5078 parseIntToken(FunctionId, "expected function id in '" + DirectiveName + 5079 "' directive") || 5080 check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc, 5081 "expected function id within range [0, UINT_MAX)"); 5082 } 5083 5084 bool MasmParser::parseCVFileId(int64_t &FileNumber, StringRef DirectiveName) { 5085 SMLoc Loc; 5086 return parseTokenLoc(Loc) || 5087 parseIntToken(FileNumber, "expected integer in '" + DirectiveName + 5088 "' directive") || 5089 check(FileNumber < 1, Loc, "file number less than one in '" + 5090 DirectiveName + "' directive") || 5091 check(!getCVContext().isValidFileNumber(FileNumber), Loc, 5092 "unassigned file number in '" + DirectiveName + "' directive"); 5093 } 5094 5095 /// parseDirectiveCVFuncId 5096 /// ::= .cv_func_id FunctionId 5097 /// 5098 /// Introduces a function ID that can be used with .cv_loc. 5099 bool MasmParser::parseDirectiveCVFuncId() { 5100 SMLoc FunctionIdLoc = getTok().getLoc(); 5101 int64_t FunctionId; 5102 5103 if (parseCVFunctionId(FunctionId, ".cv_func_id") || parseEOL()) 5104 return true; 5105 5106 if (!getStreamer().emitCVFuncIdDirective(FunctionId)) 5107 return Error(FunctionIdLoc, "function id already allocated"); 5108 5109 return false; 5110 } 5111 5112 /// parseDirectiveCVInlineSiteId 5113 /// ::= .cv_inline_site_id FunctionId 5114 /// "within" IAFunc 5115 /// "inlined_at" IAFile IALine [IACol] 5116 /// 5117 /// Introduces a function ID that can be used with .cv_loc. Includes "inlined 5118 /// at" source location information for use in the line table of the caller, 5119 /// whether the caller is a real function or another inlined call site. 5120 bool MasmParser::parseDirectiveCVInlineSiteId() { 5121 SMLoc FunctionIdLoc = getTok().getLoc(); 5122 int64_t FunctionId; 5123 int64_t IAFunc; 5124 int64_t IAFile; 5125 int64_t IALine; 5126 int64_t IACol = 0; 5127 5128 // FunctionId 5129 if (parseCVFunctionId(FunctionId, ".cv_inline_site_id")) 5130 return true; 5131 5132 // "within" 5133 if (check((getLexer().isNot(AsmToken::Identifier) || 5134 getTok().getIdentifier() != "within"), 5135 "expected 'within' identifier in '.cv_inline_site_id' directive")) 5136 return true; 5137 Lex(); 5138 5139 // IAFunc 5140 if (parseCVFunctionId(IAFunc, ".cv_inline_site_id")) 5141 return true; 5142 5143 // "inlined_at" 5144 if (check((getLexer().isNot(AsmToken::Identifier) || 5145 getTok().getIdentifier() != "inlined_at"), 5146 "expected 'inlined_at' identifier in '.cv_inline_site_id' " 5147 "directive") ) 5148 return true; 5149 Lex(); 5150 5151 // IAFile IALine 5152 if (parseCVFileId(IAFile, ".cv_inline_site_id") || 5153 parseIntToken(IALine, "expected line number after 'inlined_at'")) 5154 return true; 5155 5156 // [IACol] 5157 if (getLexer().is(AsmToken::Integer)) { 5158 IACol = getTok().getIntVal(); 5159 Lex(); 5160 } 5161 5162 if (parseEOL()) 5163 return true; 5164 5165 if (!getStreamer().emitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile, 5166 IALine, IACol, FunctionIdLoc)) 5167 return Error(FunctionIdLoc, "function id already allocated"); 5168 5169 return false; 5170 } 5171 5172 /// parseDirectiveCVLoc 5173 /// ::= .cv_loc FunctionId FileNumber [LineNumber] [ColumnPos] [prologue_end] 5174 /// [is_stmt VALUE] 5175 /// The first number is a file number, must have been previously assigned with 5176 /// a .file directive, the second number is the line number and optionally the 5177 /// third number is a column position (zero if not specified). The remaining 5178 /// optional items are .loc sub-directives. 5179 bool MasmParser::parseDirectiveCVLoc() { 5180 SMLoc DirectiveLoc = getTok().getLoc(); 5181 int64_t FunctionId, FileNumber; 5182 if (parseCVFunctionId(FunctionId, ".cv_loc") || 5183 parseCVFileId(FileNumber, ".cv_loc")) 5184 return true; 5185 5186 int64_t LineNumber = 0; 5187 if (getLexer().is(AsmToken::Integer)) { 5188 LineNumber = getTok().getIntVal(); 5189 if (LineNumber < 0) 5190 return TokError("line number less than zero in '.cv_loc' directive"); 5191 Lex(); 5192 } 5193 5194 int64_t ColumnPos = 0; 5195 if (getLexer().is(AsmToken::Integer)) { 5196 ColumnPos = getTok().getIntVal(); 5197 if (ColumnPos < 0) 5198 return TokError("column position less than zero in '.cv_loc' directive"); 5199 Lex(); 5200 } 5201 5202 bool PrologueEnd = false; 5203 uint64_t IsStmt = 0; 5204 5205 auto parseOp = [&]() -> bool { 5206 StringRef Name; 5207 SMLoc Loc = getTok().getLoc(); 5208 if (parseIdentifier(Name)) 5209 return TokError("unexpected token in '.cv_loc' directive"); 5210 if (Name == "prologue_end") 5211 PrologueEnd = true; 5212 else if (Name == "is_stmt") { 5213 Loc = getTok().getLoc(); 5214 const MCExpr *Value; 5215 if (parseExpression(Value)) 5216 return true; 5217 // The expression must be the constant 0 or 1. 5218 IsStmt = ~0ULL; 5219 if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) 5220 IsStmt = MCE->getValue(); 5221 5222 if (IsStmt > 1) 5223 return Error(Loc, "is_stmt value not 0 or 1"); 5224 } else { 5225 return Error(Loc, "unknown sub-directive in '.cv_loc' directive"); 5226 } 5227 return false; 5228 }; 5229 5230 if (parseMany(parseOp, false /*hasComma*/)) 5231 return true; 5232 5233 getStreamer().emitCVLocDirective(FunctionId, FileNumber, LineNumber, 5234 ColumnPos, PrologueEnd, IsStmt, StringRef(), 5235 DirectiveLoc); 5236 return false; 5237 } 5238 5239 /// parseDirectiveCVLinetable 5240 /// ::= .cv_linetable FunctionId, FnStart, FnEnd 5241 bool MasmParser::parseDirectiveCVLinetable() { 5242 int64_t FunctionId; 5243 StringRef FnStartName, FnEndName; 5244 SMLoc Loc = getTok().getLoc(); 5245 if (parseCVFunctionId(FunctionId, ".cv_linetable") || 5246 parseToken(AsmToken::Comma, 5247 "unexpected token in '.cv_linetable' directive") || 5248 parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc, 5249 "expected identifier in directive") || 5250 parseToken(AsmToken::Comma, 5251 "unexpected token in '.cv_linetable' directive") || 5252 parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc, 5253 "expected identifier in directive")) 5254 return true; 5255 5256 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName); 5257 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName); 5258 5259 getStreamer().emitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym); 5260 return false; 5261 } 5262 5263 /// parseDirectiveCVInlineLinetable 5264 /// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart FnEnd 5265 bool MasmParser::parseDirectiveCVInlineLinetable() { 5266 int64_t PrimaryFunctionId, SourceFileId, SourceLineNum; 5267 StringRef FnStartName, FnEndName; 5268 SMLoc Loc = getTok().getLoc(); 5269 if (parseCVFunctionId(PrimaryFunctionId, ".cv_inline_linetable") || 5270 parseTokenLoc(Loc) || 5271 parseIntToken( 5272 SourceFileId, 5273 "expected SourceField in '.cv_inline_linetable' directive") || 5274 check(SourceFileId <= 0, Loc, 5275 "File id less than zero in '.cv_inline_linetable' directive") || 5276 parseTokenLoc(Loc) || 5277 parseIntToken( 5278 SourceLineNum, 5279 "expected SourceLineNum in '.cv_inline_linetable' directive") || 5280 check(SourceLineNum < 0, Loc, 5281 "Line number less than zero in '.cv_inline_linetable' directive") || 5282 parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc, 5283 "expected identifier in directive") || 5284 parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc, 5285 "expected identifier in directive")) 5286 return true; 5287 5288 if (parseEOL()) 5289 return true; 5290 5291 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName); 5292 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName); 5293 getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId, 5294 SourceLineNum, FnStartSym, 5295 FnEndSym); 5296 return false; 5297 } 5298 5299 void MasmParser::initializeCVDefRangeTypeMap() { 5300 CVDefRangeTypeMap["reg"] = CVDR_DEFRANGE_REGISTER; 5301 CVDefRangeTypeMap["frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL; 5302 CVDefRangeTypeMap["subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER; 5303 CVDefRangeTypeMap["reg_rel"] = CVDR_DEFRANGE_REGISTER_REL; 5304 } 5305 5306 /// parseDirectiveCVDefRange 5307 /// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes* 5308 bool MasmParser::parseDirectiveCVDefRange() { 5309 SMLoc Loc; 5310 std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges; 5311 while (getLexer().is(AsmToken::Identifier)) { 5312 Loc = getLexer().getLoc(); 5313 StringRef GapStartName; 5314 if (parseIdentifier(GapStartName)) 5315 return Error(Loc, "expected identifier in directive"); 5316 MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName); 5317 5318 Loc = getLexer().getLoc(); 5319 StringRef GapEndName; 5320 if (parseIdentifier(GapEndName)) 5321 return Error(Loc, "expected identifier in directive"); 5322 MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName); 5323 5324 Ranges.push_back({GapStartSym, GapEndSym}); 5325 } 5326 5327 StringRef CVDefRangeTypeStr; 5328 if (parseToken( 5329 AsmToken::Comma, 5330 "expected comma before def_range type in .cv_def_range directive") || 5331 parseIdentifier(CVDefRangeTypeStr)) 5332 return Error(Loc, "expected def_range type in directive"); 5333 5334 StringMap<CVDefRangeType>::const_iterator CVTypeIt = 5335 CVDefRangeTypeMap.find(CVDefRangeTypeStr); 5336 CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end()) 5337 ? CVDR_DEFRANGE 5338 : CVTypeIt->getValue(); 5339 switch (CVDRType) { 5340 case CVDR_DEFRANGE_REGISTER: { 5341 int64_t DRRegister; 5342 if (parseToken(AsmToken::Comma, "expected comma before register number in " 5343 ".cv_def_range directive") || 5344 parseAbsoluteExpression(DRRegister)) 5345 return Error(Loc, "expected register number"); 5346 5347 codeview::DefRangeRegisterHeader DRHdr; 5348 DRHdr.Register = DRRegister; 5349 DRHdr.MayHaveNoName = 0; 5350 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr); 5351 break; 5352 } 5353 case CVDR_DEFRANGE_FRAMEPOINTER_REL: { 5354 int64_t DROffset; 5355 if (parseToken(AsmToken::Comma, 5356 "expected comma before offset in .cv_def_range directive") || 5357 parseAbsoluteExpression(DROffset)) 5358 return Error(Loc, "expected offset value"); 5359 5360 codeview::DefRangeFramePointerRelHeader DRHdr; 5361 DRHdr.Offset = DROffset; 5362 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr); 5363 break; 5364 } 5365 case CVDR_DEFRANGE_SUBFIELD_REGISTER: { 5366 int64_t DRRegister; 5367 int64_t DROffsetInParent; 5368 if (parseToken(AsmToken::Comma, "expected comma before register number in " 5369 ".cv_def_range directive") || 5370 parseAbsoluteExpression(DRRegister)) 5371 return Error(Loc, "expected register number"); 5372 if (parseToken(AsmToken::Comma, 5373 "expected comma before offset in .cv_def_range directive") || 5374 parseAbsoluteExpression(DROffsetInParent)) 5375 return Error(Loc, "expected offset value"); 5376 5377 codeview::DefRangeSubfieldRegisterHeader DRHdr; 5378 DRHdr.Register = DRRegister; 5379 DRHdr.MayHaveNoName = 0; 5380 DRHdr.OffsetInParent = DROffsetInParent; 5381 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr); 5382 break; 5383 } 5384 case CVDR_DEFRANGE_REGISTER_REL: { 5385 int64_t DRRegister; 5386 int64_t DRFlags; 5387 int64_t DRBasePointerOffset; 5388 if (parseToken(AsmToken::Comma, "expected comma before register number in " 5389 ".cv_def_range directive") || 5390 parseAbsoluteExpression(DRRegister)) 5391 return Error(Loc, "expected register value"); 5392 if (parseToken( 5393 AsmToken::Comma, 5394 "expected comma before flag value in .cv_def_range directive") || 5395 parseAbsoluteExpression(DRFlags)) 5396 return Error(Loc, "expected flag value"); 5397 if (parseToken(AsmToken::Comma, "expected comma before base pointer offset " 5398 "in .cv_def_range directive") || 5399 parseAbsoluteExpression(DRBasePointerOffset)) 5400 return Error(Loc, "expected base pointer offset value"); 5401 5402 codeview::DefRangeRegisterRelHeader DRHdr; 5403 DRHdr.Register = DRRegister; 5404 DRHdr.Flags = DRFlags; 5405 DRHdr.BasePointerOffset = DRBasePointerOffset; 5406 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr); 5407 break; 5408 } 5409 default: 5410 return Error(Loc, "unexpected def_range type in .cv_def_range directive"); 5411 } 5412 return true; 5413 } 5414 5415 /// parseDirectiveCVString 5416 /// ::= .cv_stringtable "string" 5417 bool MasmParser::parseDirectiveCVString() { 5418 std::string Data; 5419 if (checkForValidSection() || parseEscapedString(Data)) 5420 return addErrorSuffix(" in '.cv_string' directive"); 5421 5422 // Put the string in the table and emit the offset. 5423 std::pair<StringRef, unsigned> Insertion = 5424 getCVContext().addToStringTable(Data); 5425 getStreamer().emitIntValue(Insertion.second, 4); 5426 return false; 5427 } 5428 5429 /// parseDirectiveCVStringTable 5430 /// ::= .cv_stringtable 5431 bool MasmParser::parseDirectiveCVStringTable() { 5432 getStreamer().emitCVStringTableDirective(); 5433 return false; 5434 } 5435 5436 /// parseDirectiveCVFileChecksums 5437 /// ::= .cv_filechecksums 5438 bool MasmParser::parseDirectiveCVFileChecksums() { 5439 getStreamer().emitCVFileChecksumsDirective(); 5440 return false; 5441 } 5442 5443 /// parseDirectiveCVFileChecksumOffset 5444 /// ::= .cv_filechecksumoffset fileno 5445 bool MasmParser::parseDirectiveCVFileChecksumOffset() { 5446 int64_t FileNo; 5447 if (parseIntToken(FileNo, "expected identifier in directive")) 5448 return true; 5449 if (parseEOL()) 5450 return true; 5451 getStreamer().emitCVFileChecksumOffsetDirective(FileNo); 5452 return false; 5453 } 5454 5455 /// parseDirectiveCVFPOData 5456 /// ::= .cv_fpo_data procsym 5457 bool MasmParser::parseDirectiveCVFPOData() { 5458 SMLoc DirLoc = getLexer().getLoc(); 5459 StringRef ProcName; 5460 if (parseIdentifier(ProcName)) 5461 return TokError("expected symbol name"); 5462 if (parseEOL("unexpected tokens")) 5463 return addErrorSuffix(" in '.cv_fpo_data' directive"); 5464 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName); 5465 getStreamer().emitCVFPOData(ProcSym, DirLoc); 5466 return false; 5467 } 5468 5469 /// parseDirectiveCFISections 5470 /// ::= .cfi_sections section [, section] 5471 bool MasmParser::parseDirectiveCFISections() { 5472 StringRef Name; 5473 bool EH = false; 5474 bool Debug = false; 5475 5476 if (parseIdentifier(Name)) 5477 return TokError("Expected an identifier"); 5478 5479 if (Name == ".eh_frame") 5480 EH = true; 5481 else if (Name == ".debug_frame") 5482 Debug = true; 5483 5484 if (getLexer().is(AsmToken::Comma)) { 5485 Lex(); 5486 5487 if (parseIdentifier(Name)) 5488 return TokError("Expected an identifier"); 5489 5490 if (Name == ".eh_frame") 5491 EH = true; 5492 else if (Name == ".debug_frame") 5493 Debug = true; 5494 } 5495 5496 getStreamer().emitCFISections(EH, Debug); 5497 return false; 5498 } 5499 5500 /// parseDirectiveCFIStartProc 5501 /// ::= .cfi_startproc [simple] 5502 bool MasmParser::parseDirectiveCFIStartProc() { 5503 StringRef Simple; 5504 if (!parseOptionalToken(AsmToken::EndOfStatement)) { 5505 if (check(parseIdentifier(Simple) || Simple != "simple", 5506 "unexpected token") || 5507 parseToken(AsmToken::EndOfStatement)) 5508 return addErrorSuffix(" in '.cfi_startproc' directive"); 5509 } 5510 5511 // TODO(kristina): Deal with a corner case of incorrect diagnostic context 5512 // being produced if this directive is emitted as part of preprocessor macro 5513 // expansion which can *ONLY* happen if Clang's cc1as is the API consumer. 5514 // Tools like llvm-mc on the other hand are not affected by it, and report 5515 // correct context information. 5516 getStreamer().emitCFIStartProc(!Simple.empty(), Lexer.getLoc()); 5517 return false; 5518 } 5519 5520 /// parseDirectiveCFIEndProc 5521 /// ::= .cfi_endproc 5522 bool MasmParser::parseDirectiveCFIEndProc() { 5523 getStreamer().emitCFIEndProc(); 5524 return false; 5525 } 5526 5527 /// parse register name or number. 5528 bool MasmParser::parseRegisterOrRegisterNumber(int64_t &Register, 5529 SMLoc DirectiveLoc) { 5530 unsigned RegNo; 5531 5532 if (getLexer().isNot(AsmToken::Integer)) { 5533 if (getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc)) 5534 return true; 5535 Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true); 5536 } else 5537 return parseAbsoluteExpression(Register); 5538 5539 return false; 5540 } 5541 5542 /// parseDirectiveCFIDefCfa 5543 /// ::= .cfi_def_cfa register, offset 5544 bool MasmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) { 5545 int64_t Register = 0, Offset = 0; 5546 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || 5547 parseToken(AsmToken::Comma, "unexpected token in directive") || 5548 parseAbsoluteExpression(Offset)) 5549 return true; 5550 5551 getStreamer().emitCFIDefCfa(Register, Offset); 5552 return false; 5553 } 5554 5555 /// parseDirectiveCFIDefCfaOffset 5556 /// ::= .cfi_def_cfa_offset offset 5557 bool MasmParser::parseDirectiveCFIDefCfaOffset() { 5558 int64_t Offset = 0; 5559 if (parseAbsoluteExpression(Offset)) 5560 return true; 5561 5562 getStreamer().emitCFIDefCfaOffset(Offset); 5563 return false; 5564 } 5565 5566 /// parseDirectiveCFIRegister 5567 /// ::= .cfi_register register, register 5568 bool MasmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) { 5569 int64_t Register1 = 0, Register2 = 0; 5570 if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) || 5571 parseToken(AsmToken::Comma, "unexpected token in directive") || 5572 parseRegisterOrRegisterNumber(Register2, DirectiveLoc)) 5573 return true; 5574 5575 getStreamer().emitCFIRegister(Register1, Register2); 5576 return false; 5577 } 5578 5579 /// parseDirectiveCFIWindowSave 5580 /// ::= .cfi_window_save 5581 bool MasmParser::parseDirectiveCFIWindowSave() { 5582 getStreamer().emitCFIWindowSave(); 5583 return false; 5584 } 5585 5586 /// parseDirectiveCFIAdjustCfaOffset 5587 /// ::= .cfi_adjust_cfa_offset adjustment 5588 bool MasmParser::parseDirectiveCFIAdjustCfaOffset() { 5589 int64_t Adjustment = 0; 5590 if (parseAbsoluteExpression(Adjustment)) 5591 return true; 5592 5593 getStreamer().emitCFIAdjustCfaOffset(Adjustment); 5594 return false; 5595 } 5596 5597 /// parseDirectiveCFIDefCfaRegister 5598 /// ::= .cfi_def_cfa_register register 5599 bool MasmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) { 5600 int64_t Register = 0; 5601 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 5602 return true; 5603 5604 getStreamer().emitCFIDefCfaRegister(Register); 5605 return false; 5606 } 5607 5608 /// parseDirectiveCFIOffset 5609 /// ::= .cfi_offset register, offset 5610 bool MasmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) { 5611 int64_t Register = 0; 5612 int64_t Offset = 0; 5613 5614 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || 5615 parseToken(AsmToken::Comma, "unexpected token in directive") || 5616 parseAbsoluteExpression(Offset)) 5617 return true; 5618 5619 getStreamer().emitCFIOffset(Register, Offset); 5620 return false; 5621 } 5622 5623 /// parseDirectiveCFIRelOffset 5624 /// ::= .cfi_rel_offset register, offset 5625 bool MasmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) { 5626 int64_t Register = 0, Offset = 0; 5627 5628 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || 5629 parseToken(AsmToken::Comma, "unexpected token in directive") || 5630 parseAbsoluteExpression(Offset)) 5631 return true; 5632 5633 getStreamer().emitCFIRelOffset(Register, Offset); 5634 return false; 5635 } 5636 5637 static bool isValidEncoding(int64_t Encoding) { 5638 if (Encoding & ~0xff) 5639 return false; 5640 5641 if (Encoding == dwarf::DW_EH_PE_omit) 5642 return true; 5643 5644 const unsigned Format = Encoding & 0xf; 5645 if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 && 5646 Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 && 5647 Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 && 5648 Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed) 5649 return false; 5650 5651 const unsigned Application = Encoding & 0x70; 5652 if (Application != dwarf::DW_EH_PE_absptr && 5653 Application != dwarf::DW_EH_PE_pcrel) 5654 return false; 5655 5656 return true; 5657 } 5658 5659 /// parseDirectiveCFIPersonalityOrLsda 5660 /// IsPersonality true for cfi_personality, false for cfi_lsda 5661 /// ::= .cfi_personality encoding, [symbol_name] 5662 /// ::= .cfi_lsda encoding, [symbol_name] 5663 bool MasmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) { 5664 int64_t Encoding = 0; 5665 if (parseAbsoluteExpression(Encoding)) 5666 return true; 5667 if (Encoding == dwarf::DW_EH_PE_omit) 5668 return false; 5669 5670 StringRef Name; 5671 if (check(!isValidEncoding(Encoding), "unsupported encoding.") || 5672 parseToken(AsmToken::Comma, "unexpected token in directive") || 5673 check(parseIdentifier(Name), "expected identifier in directive")) 5674 return true; 5675 5676 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 5677 5678 if (IsPersonality) 5679 getStreamer().emitCFIPersonality(Sym, Encoding); 5680 else 5681 getStreamer().emitCFILsda(Sym, Encoding); 5682 return false; 5683 } 5684 5685 /// parseDirectiveCFIRememberState 5686 /// ::= .cfi_remember_state 5687 bool MasmParser::parseDirectiveCFIRememberState() { 5688 getStreamer().emitCFIRememberState(); 5689 return false; 5690 } 5691 5692 /// parseDirectiveCFIRestoreState 5693 /// ::= .cfi_remember_state 5694 bool MasmParser::parseDirectiveCFIRestoreState() { 5695 getStreamer().emitCFIRestoreState(); 5696 return false; 5697 } 5698 5699 /// parseDirectiveCFISameValue 5700 /// ::= .cfi_same_value register 5701 bool MasmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) { 5702 int64_t Register = 0; 5703 5704 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 5705 return true; 5706 5707 getStreamer().emitCFISameValue(Register); 5708 return false; 5709 } 5710 5711 /// parseDirectiveCFIRestore 5712 /// ::= .cfi_restore register 5713 bool MasmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) { 5714 int64_t Register = 0; 5715 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 5716 return true; 5717 5718 getStreamer().emitCFIRestore(Register); 5719 return false; 5720 } 5721 5722 /// parseDirectiveCFIEscape 5723 /// ::= .cfi_escape expression[,...] 5724 bool MasmParser::parseDirectiveCFIEscape() { 5725 std::string Values; 5726 int64_t CurrValue; 5727 if (parseAbsoluteExpression(CurrValue)) 5728 return true; 5729 5730 Values.push_back((uint8_t)CurrValue); 5731 5732 while (getLexer().is(AsmToken::Comma)) { 5733 Lex(); 5734 5735 if (parseAbsoluteExpression(CurrValue)) 5736 return true; 5737 5738 Values.push_back((uint8_t)CurrValue); 5739 } 5740 5741 getStreamer().emitCFIEscape(Values); 5742 return false; 5743 } 5744 5745 /// parseDirectiveCFIReturnColumn 5746 /// ::= .cfi_return_column register 5747 bool MasmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) { 5748 int64_t Register = 0; 5749 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 5750 return true; 5751 getStreamer().emitCFIReturnColumn(Register); 5752 return false; 5753 } 5754 5755 /// parseDirectiveCFISignalFrame 5756 /// ::= .cfi_signal_frame 5757 bool MasmParser::parseDirectiveCFISignalFrame() { 5758 if (parseEOL()) 5759 return true; 5760 5761 getStreamer().emitCFISignalFrame(); 5762 return false; 5763 } 5764 5765 /// parseDirectiveCFIUndefined 5766 /// ::= .cfi_undefined register 5767 bool MasmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) { 5768 int64_t Register = 0; 5769 5770 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 5771 return true; 5772 5773 getStreamer().emitCFIUndefined(Register); 5774 return false; 5775 } 5776 5777 /// parseDirectiveMacro 5778 /// ::= name macro [parameters] 5779 /// ["LOCAL" identifiers] 5780 /// parameters ::= parameter [, parameter]* 5781 /// parameter ::= name ":" qualifier 5782 /// qualifier ::= "req" | "vararg" | "=" macro_argument 5783 bool MasmParser::parseDirectiveMacro(StringRef Name, SMLoc NameLoc) { 5784 MCAsmMacroParameters Parameters; 5785 while (getLexer().isNot(AsmToken::EndOfStatement)) { 5786 if (!Parameters.empty() && Parameters.back().Vararg) 5787 return Error(Lexer.getLoc(), 5788 "Vararg parameter '" + Parameters.back().Name + 5789 "' should be last in the list of parameters"); 5790 5791 MCAsmMacroParameter Parameter; 5792 if (parseIdentifier(Parameter.Name)) 5793 return TokError("expected identifier in 'macro' directive"); 5794 5795 // Emit an error if two (or more) named parameters share the same name. 5796 for (const MCAsmMacroParameter& CurrParam : Parameters) 5797 if (CurrParam.Name.equals_insensitive(Parameter.Name)) 5798 return TokError("macro '" + Name + "' has multiple parameters" 5799 " named '" + Parameter.Name + "'"); 5800 5801 if (Lexer.is(AsmToken::Colon)) { 5802 Lex(); // consume ':' 5803 5804 if (parseOptionalToken(AsmToken::Equal)) { 5805 // Default value 5806 SMLoc ParamLoc; 5807 5808 ParamLoc = Lexer.getLoc(); 5809 if (parseMacroArgument(nullptr, Parameter.Value)) 5810 return true; 5811 } else { 5812 SMLoc QualLoc; 5813 StringRef Qualifier; 5814 5815 QualLoc = Lexer.getLoc(); 5816 if (parseIdentifier(Qualifier)) 5817 return Error(QualLoc, "missing parameter qualifier for " 5818 "'" + 5819 Parameter.Name + "' in macro '" + Name + 5820 "'"); 5821 5822 if (Qualifier.equals_insensitive("req")) 5823 Parameter.Required = true; 5824 else if (Qualifier.equals_insensitive("vararg")) 5825 Parameter.Vararg = true; 5826 else 5827 return Error(QualLoc, 5828 Qualifier + " is not a valid parameter qualifier for '" + 5829 Parameter.Name + "' in macro '" + Name + "'"); 5830 } 5831 } 5832 5833 Parameters.push_back(std::move(Parameter)); 5834 5835 if (getLexer().is(AsmToken::Comma)) 5836 Lex(); 5837 } 5838 5839 // Eat just the end of statement. 5840 Lexer.Lex(); 5841 5842 std::vector<std::string> Locals; 5843 if (getTok().is(AsmToken::Identifier) && 5844 getTok().getIdentifier().equals_insensitive("local")) { 5845 Lex(); // Eat the LOCAL directive. 5846 5847 StringRef ID; 5848 while (true) { 5849 if (parseIdentifier(ID)) 5850 return true; 5851 Locals.push_back(ID.lower()); 5852 5853 // If we see a comma, continue (and allow line continuation). 5854 if (!parseOptionalToken(AsmToken::Comma)) 5855 break; 5856 parseOptionalToken(AsmToken::EndOfStatement); 5857 } 5858 } 5859 5860 // Consuming deferred text, so use Lexer.Lex to ignore Lexing Errors. 5861 AsmToken EndToken, StartToken = getTok(); 5862 unsigned MacroDepth = 0; 5863 bool IsMacroFunction = false; 5864 // Lex the macro definition. 5865 while (true) { 5866 // Ignore Lexing errors in macros. 5867 while (Lexer.is(AsmToken::Error)) { 5868 Lexer.Lex(); 5869 } 5870 5871 // Check whether we have reached the end of the file. 5872 if (getLexer().is(AsmToken::Eof)) 5873 return Error(NameLoc, "no matching 'endm' in definition"); 5874 5875 // Otherwise, check whether we have reached the 'endm'... and determine if 5876 // this is a macro function. 5877 if (getLexer().is(AsmToken::Identifier)) { 5878 if (getTok().getIdentifier().equals_insensitive("endm")) { 5879 if (MacroDepth == 0) { // Outermost macro. 5880 EndToken = getTok(); 5881 Lexer.Lex(); 5882 if (getLexer().isNot(AsmToken::EndOfStatement)) 5883 return TokError("unexpected token in '" + EndToken.getIdentifier() + 5884 "' directive"); 5885 break; 5886 } else { 5887 // Otherwise we just found the end of an inner macro. 5888 --MacroDepth; 5889 } 5890 } else if (getTok().getIdentifier().equals_insensitive("exitm")) { 5891 if (MacroDepth == 0 && peekTok().isNot(AsmToken::EndOfStatement)) { 5892 IsMacroFunction = true; 5893 } 5894 } else if (isMacroLikeDirective()) { 5895 // We allow nested macros. Those aren't instantiated until the 5896 // outermost macro is expanded so just ignore them for now. 5897 ++MacroDepth; 5898 } 5899 } 5900 5901 // Otherwise, scan til the end of the statement. 5902 eatToEndOfStatement(); 5903 } 5904 5905 if (getContext().lookupMacro(Name.lower())) { 5906 return Error(NameLoc, "macro '" + Name + "' is already defined"); 5907 } 5908 5909 const char *BodyStart = StartToken.getLoc().getPointer(); 5910 const char *BodyEnd = EndToken.getLoc().getPointer(); 5911 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); 5912 MCAsmMacro Macro(Name, Body, std::move(Parameters), std::move(Locals), 5913 IsMacroFunction); 5914 DEBUG_WITH_TYPE("asm-macros", dbgs() << "Defining new macro:\n"; 5915 Macro.dump()); 5916 getContext().defineMacro(Name.lower(), std::move(Macro)); 5917 return false; 5918 } 5919 5920 /// parseDirectiveExitMacro 5921 /// ::= "exitm" [textitem] 5922 bool MasmParser::parseDirectiveExitMacro(SMLoc DirectiveLoc, 5923 StringRef Directive, 5924 std::string &Value) { 5925 SMLoc EndLoc = getTok().getLoc(); 5926 if (getTok().isNot(AsmToken::EndOfStatement) && parseTextItem(Value)) 5927 return Error(EndLoc, 5928 "unable to parse text item in '" + Directive + "' directive"); 5929 eatToEndOfStatement(); 5930 5931 if (!isInsideMacroInstantiation()) 5932 return TokError("unexpected '" + Directive + "' in file, " 5933 "no current macro definition"); 5934 5935 // Exit all conditionals that are active in the current macro. 5936 while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) { 5937 TheCondState = TheCondStack.back(); 5938 TheCondStack.pop_back(); 5939 } 5940 5941 handleMacroExit(); 5942 return false; 5943 } 5944 5945 /// parseDirectiveEndMacro 5946 /// ::= endm 5947 bool MasmParser::parseDirectiveEndMacro(StringRef Directive) { 5948 if (getLexer().isNot(AsmToken::EndOfStatement)) 5949 return TokError("unexpected token in '" + Directive + "' directive"); 5950 5951 // If we are inside a macro instantiation, terminate the current 5952 // instantiation. 5953 if (isInsideMacroInstantiation()) { 5954 handleMacroExit(); 5955 return false; 5956 } 5957 5958 // Otherwise, this .endmacro is a stray entry in the file; well formed 5959 // .endmacro directives are handled during the macro definition parsing. 5960 return TokError("unexpected '" + Directive + "' in file, " 5961 "no current macro definition"); 5962 } 5963 5964 /// parseDirectivePurgeMacro 5965 /// ::= purge identifier ( , identifier )* 5966 bool MasmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) { 5967 StringRef Name; 5968 while (true) { 5969 SMLoc NameLoc; 5970 if (parseTokenLoc(NameLoc) || 5971 check(parseIdentifier(Name), NameLoc, 5972 "expected identifier in 'purge' directive")) 5973 return true; 5974 5975 DEBUG_WITH_TYPE("asm-macros", dbgs() 5976 << "Un-defining macro: " << Name << "\n"); 5977 if (!getContext().lookupMacro(Name.lower())) 5978 return Error(NameLoc, "macro '" + Name + "' is not defined"); 5979 getContext().undefineMacro(Name.lower()); 5980 5981 if (!parseOptionalToken(AsmToken::Comma)) 5982 break; 5983 parseOptionalToken(AsmToken::EndOfStatement); 5984 } 5985 5986 return false; 5987 } 5988 5989 bool MasmParser::parseDirectiveExtern() { 5990 // .extern is the default - but we still need to take any provided type info. 5991 auto parseOp = [&]() -> bool { 5992 StringRef Name; 5993 SMLoc NameLoc = getTok().getLoc(); 5994 if (parseIdentifier(Name)) 5995 return Error(NameLoc, "expected name"); 5996 if (parseToken(AsmToken::Colon)) 5997 return true; 5998 5999 StringRef TypeName; 6000 SMLoc TypeLoc = getTok().getLoc(); 6001 if (parseIdentifier(TypeName)) 6002 return Error(TypeLoc, "expected type"); 6003 if (!TypeName.equals_insensitive("proc")) { 6004 AsmTypeInfo Type; 6005 if (lookUpType(TypeName, Type)) 6006 return Error(TypeLoc, "unrecognized type"); 6007 KnownType[Name.lower()] = Type; 6008 } 6009 6010 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 6011 Sym->setExternal(true); 6012 getStreamer().emitSymbolAttribute(Sym, MCSA_Extern); 6013 6014 return false; 6015 }; 6016 6017 if (parseMany(parseOp)) 6018 return addErrorSuffix(" in directive 'extern'"); 6019 return false; 6020 } 6021 6022 /// parseDirectiveSymbolAttribute 6023 /// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ] 6024 bool MasmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) { 6025 auto parseOp = [&]() -> bool { 6026 StringRef Name; 6027 SMLoc Loc = getTok().getLoc(); 6028 if (parseIdentifier(Name)) 6029 return Error(Loc, "expected identifier"); 6030 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 6031 6032 // Assembler local symbols don't make any sense here. Complain loudly. 6033 if (Sym->isTemporary()) 6034 return Error(Loc, "non-local symbol required"); 6035 6036 if (!getStreamer().emitSymbolAttribute(Sym, Attr)) 6037 return Error(Loc, "unable to emit symbol attribute"); 6038 return false; 6039 }; 6040 6041 if (parseMany(parseOp)) 6042 return addErrorSuffix(" in directive"); 6043 return false; 6044 } 6045 6046 /// parseDirectiveComm 6047 /// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ] 6048 bool MasmParser::parseDirectiveComm(bool IsLocal) { 6049 if (checkForValidSection()) 6050 return true; 6051 6052 SMLoc IDLoc = getLexer().getLoc(); 6053 StringRef Name; 6054 if (parseIdentifier(Name)) 6055 return TokError("expected identifier in directive"); 6056 6057 // Handle the identifier as the key symbol. 6058 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 6059 6060 if (getLexer().isNot(AsmToken::Comma)) 6061 return TokError("unexpected token in directive"); 6062 Lex(); 6063 6064 int64_t Size; 6065 SMLoc SizeLoc = getLexer().getLoc(); 6066 if (parseAbsoluteExpression(Size)) 6067 return true; 6068 6069 int64_t Pow2Alignment = 0; 6070 SMLoc Pow2AlignmentLoc; 6071 if (getLexer().is(AsmToken::Comma)) { 6072 Lex(); 6073 Pow2AlignmentLoc = getLexer().getLoc(); 6074 if (parseAbsoluteExpression(Pow2Alignment)) 6075 return true; 6076 6077 LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType(); 6078 if (IsLocal && LCOMM == LCOMM::NoAlignment) 6079 return Error(Pow2AlignmentLoc, "alignment not supported on this target"); 6080 6081 // If this target takes alignments in bytes (not log) validate and convert. 6082 if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) || 6083 (IsLocal && LCOMM == LCOMM::ByteAlignment)) { 6084 if (!isPowerOf2_64(Pow2Alignment)) 6085 return Error(Pow2AlignmentLoc, "alignment must be a power of 2"); 6086 Pow2Alignment = Log2_64(Pow2Alignment); 6087 } 6088 } 6089 6090 if (parseEOL()) 6091 return true; 6092 6093 // NOTE: a size of zero for a .comm should create a undefined symbol 6094 // but a size of .lcomm creates a bss symbol of size zero. 6095 if (Size < 0) 6096 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't " 6097 "be less than zero"); 6098 6099 // NOTE: The alignment in the directive is a power of 2 value, the assembler 6100 // may internally end up wanting an alignment in bytes. 6101 // FIXME: Diagnose overflow. 6102 if (Pow2Alignment < 0) 6103 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive " 6104 "alignment, can't be less than zero"); 6105 6106 Sym->redefineIfPossible(); 6107 if (!Sym->isUndefined()) 6108 return Error(IDLoc, "invalid symbol redefinition"); 6109 6110 // Create the Symbol as a common or local common with Size and Pow2Alignment. 6111 if (IsLocal) { 6112 getStreamer().emitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment); 6113 return false; 6114 } 6115 6116 getStreamer().emitCommonSymbol(Sym, Size, 1 << Pow2Alignment); 6117 return false; 6118 } 6119 6120 /// parseDirectiveComment 6121 /// ::= comment delimiter [[text]] 6122 /// [[text]] 6123 /// [[text]] delimiter [[text]] 6124 bool MasmParser::parseDirectiveComment(SMLoc DirectiveLoc) { 6125 std::string FirstLine = parseStringTo(AsmToken::EndOfStatement); 6126 size_t DelimiterEnd = FirstLine.find_first_of("\b\t\v\f\r\x1A "); 6127 StringRef Delimiter = StringRef(FirstLine).take_front(DelimiterEnd); 6128 if (Delimiter.empty()) 6129 return Error(DirectiveLoc, "no delimiter in 'comment' directive"); 6130 do { 6131 if (getTok().is(AsmToken::Eof)) 6132 return Error(DirectiveLoc, "unmatched delimiter in 'comment' directive"); 6133 Lex(); // eat end of statement 6134 } while ( 6135 !StringRef(parseStringTo(AsmToken::EndOfStatement)).contains(Delimiter)); 6136 return parseEOL(); 6137 } 6138 6139 /// parseDirectiveInclude 6140 /// ::= include <filename> 6141 /// | include filename 6142 bool MasmParser::parseDirectiveInclude() { 6143 // Allow the strings to have escaped octal character sequence. 6144 std::string Filename; 6145 SMLoc IncludeLoc = getTok().getLoc(); 6146 6147 if (parseAngleBracketString(Filename)) 6148 Filename = parseStringTo(AsmToken::EndOfStatement); 6149 if (check(Filename.empty(), "missing filename in 'include' directive") || 6150 check(getTok().isNot(AsmToken::EndOfStatement), 6151 "unexpected token in 'include' directive") || 6152 // Attempt to switch the lexer to the included file before consuming the 6153 // end of statement to avoid losing it when we switch. 6154 check(enterIncludeFile(Filename), IncludeLoc, 6155 "Could not find include file '" + Filename + "'")) 6156 return true; 6157 6158 return false; 6159 } 6160 6161 /// parseDirectiveIf 6162 /// ::= .if{,eq,ge,gt,le,lt,ne} expression 6163 bool MasmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) { 6164 TheCondStack.push_back(TheCondState); 6165 TheCondState.TheCond = AsmCond::IfCond; 6166 if (TheCondState.Ignore) { 6167 eatToEndOfStatement(); 6168 } else { 6169 int64_t ExprValue; 6170 if (parseAbsoluteExpression(ExprValue) || parseEOL()) 6171 return true; 6172 6173 switch (DirKind) { 6174 default: 6175 llvm_unreachable("unsupported directive"); 6176 case DK_IF: 6177 break; 6178 case DK_IFE: 6179 ExprValue = ExprValue == 0; 6180 break; 6181 } 6182 6183 TheCondState.CondMet = ExprValue; 6184 TheCondState.Ignore = !TheCondState.CondMet; 6185 } 6186 6187 return false; 6188 } 6189 6190 /// parseDirectiveIfb 6191 /// ::= .ifb textitem 6192 bool MasmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) { 6193 TheCondStack.push_back(TheCondState); 6194 TheCondState.TheCond = AsmCond::IfCond; 6195 6196 if (TheCondState.Ignore) { 6197 eatToEndOfStatement(); 6198 } else { 6199 std::string Str; 6200 if (parseTextItem(Str)) 6201 return TokError("expected text item parameter for 'ifb' directive"); 6202 6203 if (parseEOL()) 6204 return true; 6205 6206 TheCondState.CondMet = ExpectBlank == Str.empty(); 6207 TheCondState.Ignore = !TheCondState.CondMet; 6208 } 6209 6210 return false; 6211 } 6212 6213 /// parseDirectiveIfidn 6214 /// ::= ifidn textitem, textitem 6215 bool MasmParser::parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual, 6216 bool CaseInsensitive) { 6217 std::string String1, String2; 6218 6219 if (parseTextItem(String1)) { 6220 if (ExpectEqual) 6221 return TokError("expected text item parameter for 'ifidn' directive"); 6222 return TokError("expected text item parameter for 'ifdif' directive"); 6223 } 6224 6225 if (Lexer.isNot(AsmToken::Comma)) { 6226 if (ExpectEqual) 6227 return TokError( 6228 "expected comma after first string for 'ifidn' directive"); 6229 return TokError("expected comma after first string for 'ifdif' directive"); 6230 } 6231 Lex(); 6232 6233 if (parseTextItem(String2)) { 6234 if (ExpectEqual) 6235 return TokError("expected text item parameter for 'ifidn' directive"); 6236 return TokError("expected text item parameter for 'ifdif' directive"); 6237 } 6238 6239 TheCondStack.push_back(TheCondState); 6240 TheCondState.TheCond = AsmCond::IfCond; 6241 if (CaseInsensitive) 6242 TheCondState.CondMet = 6243 ExpectEqual == (StringRef(String1).equals_insensitive(String2)); 6244 else 6245 TheCondState.CondMet = ExpectEqual == (String1 == String2); 6246 TheCondState.Ignore = !TheCondState.CondMet; 6247 6248 return false; 6249 } 6250 6251 /// parseDirectiveIfdef 6252 /// ::= ifdef symbol 6253 /// | ifdef variable 6254 bool MasmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { 6255 TheCondStack.push_back(TheCondState); 6256 TheCondState.TheCond = AsmCond::IfCond; 6257 6258 if (TheCondState.Ignore) { 6259 eatToEndOfStatement(); 6260 } else { 6261 bool is_defined = false; 6262 unsigned RegNo; 6263 SMLoc StartLoc, EndLoc; 6264 is_defined = (getTargetParser().tryParseRegister( 6265 RegNo, StartLoc, EndLoc) == MatchOperand_Success); 6266 if (!is_defined) { 6267 StringRef Name; 6268 if (check(parseIdentifier(Name), "expected identifier after 'ifdef'") || 6269 parseEOL()) 6270 return true; 6271 6272 if (BuiltinSymbolMap.find(Name.lower()) != BuiltinSymbolMap.end()) { 6273 is_defined = true; 6274 } else if (Variables.find(Name.lower()) != Variables.end()) { 6275 is_defined = true; 6276 } else { 6277 MCSymbol *Sym = getContext().lookupSymbol(Name.lower()); 6278 is_defined = (Sym && !Sym->isUndefined(false)); 6279 } 6280 } 6281 6282 TheCondState.CondMet = (is_defined == expect_defined); 6283 TheCondState.Ignore = !TheCondState.CondMet; 6284 } 6285 6286 return false; 6287 } 6288 6289 /// parseDirectiveElseIf 6290 /// ::= elseif expression 6291 bool MasmParser::parseDirectiveElseIf(SMLoc DirectiveLoc, 6292 DirectiveKind DirKind) { 6293 if (TheCondState.TheCond != AsmCond::IfCond && 6294 TheCondState.TheCond != AsmCond::ElseIfCond) 6295 return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an" 6296 " .if or an .elseif"); 6297 TheCondState.TheCond = AsmCond::ElseIfCond; 6298 6299 bool LastIgnoreState = false; 6300 if (!TheCondStack.empty()) 6301 LastIgnoreState = TheCondStack.back().Ignore; 6302 if (LastIgnoreState || TheCondState.CondMet) { 6303 TheCondState.Ignore = true; 6304 eatToEndOfStatement(); 6305 } else { 6306 int64_t ExprValue; 6307 if (parseAbsoluteExpression(ExprValue)) 6308 return true; 6309 6310 if (parseEOL()) 6311 return true; 6312 6313 switch (DirKind) { 6314 default: 6315 llvm_unreachable("unsupported directive"); 6316 case DK_ELSEIF: 6317 break; 6318 case DK_ELSEIFE: 6319 ExprValue = ExprValue == 0; 6320 break; 6321 } 6322 6323 TheCondState.CondMet = ExprValue; 6324 TheCondState.Ignore = !TheCondState.CondMet; 6325 } 6326 6327 return false; 6328 } 6329 6330 /// parseDirectiveElseIfb 6331 /// ::= elseifb textitem 6332 bool MasmParser::parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank) { 6333 if (TheCondState.TheCond != AsmCond::IfCond && 6334 TheCondState.TheCond != AsmCond::ElseIfCond) 6335 return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an" 6336 " if or an elseif"); 6337 TheCondState.TheCond = AsmCond::ElseIfCond; 6338 6339 bool LastIgnoreState = false; 6340 if (!TheCondStack.empty()) 6341 LastIgnoreState = TheCondStack.back().Ignore; 6342 if (LastIgnoreState || TheCondState.CondMet) { 6343 TheCondState.Ignore = true; 6344 eatToEndOfStatement(); 6345 } else { 6346 std::string Str; 6347 if (parseTextItem(Str)) { 6348 if (ExpectBlank) 6349 return TokError("expected text item parameter for 'elseifb' directive"); 6350 return TokError("expected text item parameter for 'elseifnb' directive"); 6351 } 6352 6353 if (parseEOL()) 6354 return true; 6355 6356 TheCondState.CondMet = ExpectBlank == Str.empty(); 6357 TheCondState.Ignore = !TheCondState.CondMet; 6358 } 6359 6360 return false; 6361 } 6362 6363 /// parseDirectiveElseIfdef 6364 /// ::= elseifdef symbol 6365 /// | elseifdef variable 6366 bool MasmParser::parseDirectiveElseIfdef(SMLoc DirectiveLoc, 6367 bool expect_defined) { 6368 if (TheCondState.TheCond != AsmCond::IfCond && 6369 TheCondState.TheCond != AsmCond::ElseIfCond) 6370 return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an" 6371 " if or an elseif"); 6372 TheCondState.TheCond = AsmCond::ElseIfCond; 6373 6374 bool LastIgnoreState = false; 6375 if (!TheCondStack.empty()) 6376 LastIgnoreState = TheCondStack.back().Ignore; 6377 if (LastIgnoreState || TheCondState.CondMet) { 6378 TheCondState.Ignore = true; 6379 eatToEndOfStatement(); 6380 } else { 6381 bool is_defined = false; 6382 unsigned RegNo; 6383 SMLoc StartLoc, EndLoc; 6384 is_defined = (getTargetParser().tryParseRegister(RegNo, StartLoc, EndLoc) == 6385 MatchOperand_Success); 6386 if (!is_defined) { 6387 StringRef Name; 6388 if (check(parseIdentifier(Name), 6389 "expected identifier after 'elseifdef'") || 6390 parseEOL()) 6391 return true; 6392 6393 if (BuiltinSymbolMap.find(Name.lower()) != BuiltinSymbolMap.end()) { 6394 is_defined = true; 6395 } else if (Variables.find(Name.lower()) != Variables.end()) { 6396 is_defined = true; 6397 } else { 6398 MCSymbol *Sym = getContext().lookupSymbol(Name); 6399 is_defined = (Sym && !Sym->isUndefined(false)); 6400 } 6401 } 6402 6403 TheCondState.CondMet = (is_defined == expect_defined); 6404 TheCondState.Ignore = !TheCondState.CondMet; 6405 } 6406 6407 return false; 6408 } 6409 6410 /// parseDirectiveElseIfidn 6411 /// ::= elseifidn textitem, textitem 6412 bool MasmParser::parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual, 6413 bool CaseInsensitive) { 6414 if (TheCondState.TheCond != AsmCond::IfCond && 6415 TheCondState.TheCond != AsmCond::ElseIfCond) 6416 return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an" 6417 " if or an elseif"); 6418 TheCondState.TheCond = AsmCond::ElseIfCond; 6419 6420 bool LastIgnoreState = false; 6421 if (!TheCondStack.empty()) 6422 LastIgnoreState = TheCondStack.back().Ignore; 6423 if (LastIgnoreState || TheCondState.CondMet) { 6424 TheCondState.Ignore = true; 6425 eatToEndOfStatement(); 6426 } else { 6427 std::string String1, String2; 6428 6429 if (parseTextItem(String1)) { 6430 if (ExpectEqual) 6431 return TokError( 6432 "expected text item parameter for 'elseifidn' directive"); 6433 return TokError("expected text item parameter for 'elseifdif' directive"); 6434 } 6435 6436 if (Lexer.isNot(AsmToken::Comma)) { 6437 if (ExpectEqual) 6438 return TokError( 6439 "expected comma after first string for 'elseifidn' directive"); 6440 return TokError( 6441 "expected comma after first string for 'elseifdif' directive"); 6442 } 6443 Lex(); 6444 6445 if (parseTextItem(String2)) { 6446 if (ExpectEqual) 6447 return TokError( 6448 "expected text item parameter for 'elseifidn' directive"); 6449 return TokError("expected text item parameter for 'elseifdif' directive"); 6450 } 6451 6452 if (CaseInsensitive) 6453 TheCondState.CondMet = 6454 ExpectEqual == (StringRef(String1).equals_insensitive(String2)); 6455 else 6456 TheCondState.CondMet = ExpectEqual == (String1 == String2); 6457 TheCondState.Ignore = !TheCondState.CondMet; 6458 } 6459 6460 return false; 6461 } 6462 6463 /// parseDirectiveElse 6464 /// ::= else 6465 bool MasmParser::parseDirectiveElse(SMLoc DirectiveLoc) { 6466 if (parseEOL()) 6467 return true; 6468 6469 if (TheCondState.TheCond != AsmCond::IfCond && 6470 TheCondState.TheCond != AsmCond::ElseIfCond) 6471 return Error(DirectiveLoc, "Encountered an else that doesn't follow an if" 6472 " or an elseif"); 6473 TheCondState.TheCond = AsmCond::ElseCond; 6474 bool LastIgnoreState = false; 6475 if (!TheCondStack.empty()) 6476 LastIgnoreState = TheCondStack.back().Ignore; 6477 if (LastIgnoreState || TheCondState.CondMet) 6478 TheCondState.Ignore = true; 6479 else 6480 TheCondState.Ignore = false; 6481 6482 return false; 6483 } 6484 6485 /// parseDirectiveEnd 6486 /// ::= end 6487 bool MasmParser::parseDirectiveEnd(SMLoc DirectiveLoc) { 6488 if (parseEOL()) 6489 return true; 6490 6491 while (Lexer.isNot(AsmToken::Eof)) 6492 Lexer.Lex(); 6493 6494 return false; 6495 } 6496 6497 /// parseDirectiveError 6498 /// ::= .err [message] 6499 bool MasmParser::parseDirectiveError(SMLoc DirectiveLoc) { 6500 if (!TheCondStack.empty()) { 6501 if (TheCondStack.back().Ignore) { 6502 eatToEndOfStatement(); 6503 return false; 6504 } 6505 } 6506 6507 std::string Message = ".err directive invoked in source file"; 6508 if (Lexer.isNot(AsmToken::EndOfStatement)) 6509 Message = parseStringTo(AsmToken::EndOfStatement); 6510 Lex(); 6511 6512 return Error(DirectiveLoc, Message); 6513 } 6514 6515 /// parseDirectiveErrorIfb 6516 /// ::= .errb textitem[, message] 6517 bool MasmParser::parseDirectiveErrorIfb(SMLoc DirectiveLoc, bool ExpectBlank) { 6518 if (!TheCondStack.empty()) { 6519 if (TheCondStack.back().Ignore) { 6520 eatToEndOfStatement(); 6521 return false; 6522 } 6523 } 6524 6525 std::string Text; 6526 if (parseTextItem(Text)) 6527 return Error(getTok().getLoc(), "missing text item in '.errb' directive"); 6528 6529 std::string Message = ".errb directive invoked in source file"; 6530 if (Lexer.isNot(AsmToken::EndOfStatement)) { 6531 if (parseToken(AsmToken::Comma)) 6532 return addErrorSuffix(" in '.errb' directive"); 6533 Message = parseStringTo(AsmToken::EndOfStatement); 6534 } 6535 Lex(); 6536 6537 if (Text.empty() == ExpectBlank) 6538 return Error(DirectiveLoc, Message); 6539 return false; 6540 } 6541 6542 /// parseDirectiveErrorIfdef 6543 /// ::= .errdef name[, message] 6544 bool MasmParser::parseDirectiveErrorIfdef(SMLoc DirectiveLoc, 6545 bool ExpectDefined) { 6546 if (!TheCondStack.empty()) { 6547 if (TheCondStack.back().Ignore) { 6548 eatToEndOfStatement(); 6549 return false; 6550 } 6551 } 6552 6553 bool IsDefined = false; 6554 unsigned RegNo; 6555 SMLoc StartLoc, EndLoc; 6556 IsDefined = (getTargetParser().tryParseRegister(RegNo, StartLoc, EndLoc) == 6557 MatchOperand_Success); 6558 if (!IsDefined) { 6559 StringRef Name; 6560 if (check(parseIdentifier(Name), "expected identifier after '.errdef'")) 6561 return true; 6562 6563 if (BuiltinSymbolMap.find(Name.lower()) != BuiltinSymbolMap.end()) { 6564 IsDefined = true; 6565 } else if (Variables.find(Name.lower()) != Variables.end()) { 6566 IsDefined = true; 6567 } else { 6568 MCSymbol *Sym = getContext().lookupSymbol(Name); 6569 IsDefined = (Sym && !Sym->isUndefined(false)); 6570 } 6571 } 6572 6573 std::string Message = ".errdef directive invoked in source file"; 6574 if (Lexer.isNot(AsmToken::EndOfStatement)) { 6575 if (parseToken(AsmToken::Comma)) 6576 return addErrorSuffix(" in '.errdef' directive"); 6577 Message = parseStringTo(AsmToken::EndOfStatement); 6578 } 6579 Lex(); 6580 6581 if (IsDefined == ExpectDefined) 6582 return Error(DirectiveLoc, Message); 6583 return false; 6584 } 6585 6586 /// parseDirectiveErrorIfidn 6587 /// ::= .erridn textitem, textitem[, message] 6588 bool MasmParser::parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual, 6589 bool CaseInsensitive) { 6590 if (!TheCondStack.empty()) { 6591 if (TheCondStack.back().Ignore) { 6592 eatToEndOfStatement(); 6593 return false; 6594 } 6595 } 6596 6597 std::string String1, String2; 6598 6599 if (parseTextItem(String1)) { 6600 if (ExpectEqual) 6601 return TokError("expected string parameter for '.erridn' directive"); 6602 return TokError("expected string parameter for '.errdif' directive"); 6603 } 6604 6605 if (Lexer.isNot(AsmToken::Comma)) { 6606 if (ExpectEqual) 6607 return TokError( 6608 "expected comma after first string for '.erridn' directive"); 6609 return TokError( 6610 "expected comma after first string for '.errdif' directive"); 6611 } 6612 Lex(); 6613 6614 if (parseTextItem(String2)) { 6615 if (ExpectEqual) 6616 return TokError("expected string parameter for '.erridn' directive"); 6617 return TokError("expected string parameter for '.errdif' directive"); 6618 } 6619 6620 std::string Message; 6621 if (ExpectEqual) 6622 Message = ".erridn directive invoked in source file"; 6623 else 6624 Message = ".errdif directive invoked in source file"; 6625 if (Lexer.isNot(AsmToken::EndOfStatement)) { 6626 if (parseToken(AsmToken::Comma)) 6627 return addErrorSuffix(" in '.erridn' directive"); 6628 Message = parseStringTo(AsmToken::EndOfStatement); 6629 } 6630 Lex(); 6631 6632 if (CaseInsensitive) 6633 TheCondState.CondMet = 6634 ExpectEqual == (StringRef(String1).equals_insensitive(String2)); 6635 else 6636 TheCondState.CondMet = ExpectEqual == (String1 == String2); 6637 TheCondState.Ignore = !TheCondState.CondMet; 6638 6639 if ((CaseInsensitive && 6640 ExpectEqual == StringRef(String1).equals_insensitive(String2)) || 6641 (ExpectEqual == (String1 == String2))) 6642 return Error(DirectiveLoc, Message); 6643 return false; 6644 } 6645 6646 /// parseDirectiveErrorIfe 6647 /// ::= .erre expression[, message] 6648 bool MasmParser::parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero) { 6649 if (!TheCondStack.empty()) { 6650 if (TheCondStack.back().Ignore) { 6651 eatToEndOfStatement(); 6652 return false; 6653 } 6654 } 6655 6656 int64_t ExprValue; 6657 if (parseAbsoluteExpression(ExprValue)) 6658 return addErrorSuffix(" in '.erre' directive"); 6659 6660 std::string Message = ".erre directive invoked in source file"; 6661 if (Lexer.isNot(AsmToken::EndOfStatement)) { 6662 if (parseToken(AsmToken::Comma)) 6663 return addErrorSuffix(" in '.erre' directive"); 6664 Message = parseStringTo(AsmToken::EndOfStatement); 6665 } 6666 Lex(); 6667 6668 if ((ExprValue == 0) == ExpectZero) 6669 return Error(DirectiveLoc, Message); 6670 return false; 6671 } 6672 6673 /// parseDirectiveEndIf 6674 /// ::= .endif 6675 bool MasmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) { 6676 if (parseEOL()) 6677 return true; 6678 6679 if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty()) 6680 return Error(DirectiveLoc, "Encountered a .endif that doesn't follow " 6681 "an .if or .else"); 6682 if (!TheCondStack.empty()) { 6683 TheCondState = TheCondStack.back(); 6684 TheCondStack.pop_back(); 6685 } 6686 6687 return false; 6688 } 6689 6690 void MasmParser::initializeDirectiveKindMap() { 6691 DirectiveKindMap["="] = DK_ASSIGN; 6692 DirectiveKindMap["equ"] = DK_EQU; 6693 DirectiveKindMap["textequ"] = DK_TEXTEQU; 6694 // DirectiveKindMap[".ascii"] = DK_ASCII; 6695 // DirectiveKindMap[".asciz"] = DK_ASCIZ; 6696 // DirectiveKindMap[".string"] = DK_STRING; 6697 DirectiveKindMap["byte"] = DK_BYTE; 6698 DirectiveKindMap["sbyte"] = DK_SBYTE; 6699 DirectiveKindMap["word"] = DK_WORD; 6700 DirectiveKindMap["sword"] = DK_SWORD; 6701 DirectiveKindMap["dword"] = DK_DWORD; 6702 DirectiveKindMap["sdword"] = DK_SDWORD; 6703 DirectiveKindMap["fword"] = DK_FWORD; 6704 DirectiveKindMap["qword"] = DK_QWORD; 6705 DirectiveKindMap["sqword"] = DK_SQWORD; 6706 DirectiveKindMap["real4"] = DK_REAL4; 6707 DirectiveKindMap["real8"] = DK_REAL8; 6708 DirectiveKindMap["real10"] = DK_REAL10; 6709 DirectiveKindMap["align"] = DK_ALIGN; 6710 DirectiveKindMap["even"] = DK_EVEN; 6711 DirectiveKindMap["org"] = DK_ORG; 6712 DirectiveKindMap["extern"] = DK_EXTERN; 6713 DirectiveKindMap["public"] = DK_PUBLIC; 6714 // DirectiveKindMap[".comm"] = DK_COMM; 6715 DirectiveKindMap["comment"] = DK_COMMENT; 6716 DirectiveKindMap["include"] = DK_INCLUDE; 6717 DirectiveKindMap["repeat"] = DK_REPEAT; 6718 DirectiveKindMap["rept"] = DK_REPEAT; 6719 DirectiveKindMap["while"] = DK_WHILE; 6720 DirectiveKindMap["for"] = DK_FOR; 6721 DirectiveKindMap["irp"] = DK_FOR; 6722 DirectiveKindMap["forc"] = DK_FORC; 6723 DirectiveKindMap["irpc"] = DK_FORC; 6724 DirectiveKindMap["if"] = DK_IF; 6725 DirectiveKindMap["ife"] = DK_IFE; 6726 DirectiveKindMap["ifb"] = DK_IFB; 6727 DirectiveKindMap["ifnb"] = DK_IFNB; 6728 DirectiveKindMap["ifdef"] = DK_IFDEF; 6729 DirectiveKindMap["ifndef"] = DK_IFNDEF; 6730 DirectiveKindMap["ifdif"] = DK_IFDIF; 6731 DirectiveKindMap["ifdifi"] = DK_IFDIFI; 6732 DirectiveKindMap["ifidn"] = DK_IFIDN; 6733 DirectiveKindMap["ifidni"] = DK_IFIDNI; 6734 DirectiveKindMap["elseif"] = DK_ELSEIF; 6735 DirectiveKindMap["elseifdef"] = DK_ELSEIFDEF; 6736 DirectiveKindMap["elseifndef"] = DK_ELSEIFNDEF; 6737 DirectiveKindMap["elseifdif"] = DK_ELSEIFDIF; 6738 DirectiveKindMap["elseifidn"] = DK_ELSEIFIDN; 6739 DirectiveKindMap["else"] = DK_ELSE; 6740 DirectiveKindMap["end"] = DK_END; 6741 DirectiveKindMap["endif"] = DK_ENDIF; 6742 // DirectiveKindMap[".file"] = DK_FILE; 6743 // DirectiveKindMap[".line"] = DK_LINE; 6744 // DirectiveKindMap[".loc"] = DK_LOC; 6745 // DirectiveKindMap[".stabs"] = DK_STABS; 6746 // DirectiveKindMap[".cv_file"] = DK_CV_FILE; 6747 // DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID; 6748 // DirectiveKindMap[".cv_loc"] = DK_CV_LOC; 6749 // DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE; 6750 // DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE; 6751 // DirectiveKindMap[".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID; 6752 // DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE; 6753 // DirectiveKindMap[".cv_string"] = DK_CV_STRING; 6754 // DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE; 6755 // DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS; 6756 // DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET; 6757 // DirectiveKindMap[".cv_fpo_data"] = DK_CV_FPO_DATA; 6758 // DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS; 6759 // DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC; 6760 // DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC; 6761 // DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA; 6762 // DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET; 6763 // DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET; 6764 // DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER; 6765 // DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET; 6766 // DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET; 6767 // DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY; 6768 // DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA; 6769 // DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE; 6770 // DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE; 6771 // DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE; 6772 // DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE; 6773 // DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE; 6774 // DirectiveKindMap[".cfi_return_column"] = DK_CFI_RETURN_COLUMN; 6775 // DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME; 6776 // DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED; 6777 // DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER; 6778 // DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE; 6779 // DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME; 6780 DirectiveKindMap["macro"] = DK_MACRO; 6781 DirectiveKindMap["exitm"] = DK_EXITM; 6782 DirectiveKindMap["endm"] = DK_ENDM; 6783 DirectiveKindMap["purge"] = DK_PURGE; 6784 DirectiveKindMap[".err"] = DK_ERR; 6785 DirectiveKindMap[".errb"] = DK_ERRB; 6786 DirectiveKindMap[".errnb"] = DK_ERRNB; 6787 DirectiveKindMap[".errdef"] = DK_ERRDEF; 6788 DirectiveKindMap[".errndef"] = DK_ERRNDEF; 6789 DirectiveKindMap[".errdif"] = DK_ERRDIF; 6790 DirectiveKindMap[".errdifi"] = DK_ERRDIFI; 6791 DirectiveKindMap[".erridn"] = DK_ERRIDN; 6792 DirectiveKindMap[".erridni"] = DK_ERRIDNI; 6793 DirectiveKindMap[".erre"] = DK_ERRE; 6794 DirectiveKindMap[".errnz"] = DK_ERRNZ; 6795 DirectiveKindMap[".pushframe"] = DK_PUSHFRAME; 6796 DirectiveKindMap[".pushreg"] = DK_PUSHREG; 6797 DirectiveKindMap[".savereg"] = DK_SAVEREG; 6798 DirectiveKindMap[".savexmm128"] = DK_SAVEXMM128; 6799 DirectiveKindMap[".setframe"] = DK_SETFRAME; 6800 DirectiveKindMap[".radix"] = DK_RADIX; 6801 DirectiveKindMap["db"] = DK_DB; 6802 DirectiveKindMap["dd"] = DK_DD; 6803 DirectiveKindMap["df"] = DK_DF; 6804 DirectiveKindMap["dq"] = DK_DQ; 6805 DirectiveKindMap["dw"] = DK_DW; 6806 DirectiveKindMap["echo"] = DK_ECHO; 6807 DirectiveKindMap["struc"] = DK_STRUCT; 6808 DirectiveKindMap["struct"] = DK_STRUCT; 6809 DirectiveKindMap["union"] = DK_UNION; 6810 DirectiveKindMap["ends"] = DK_ENDS; 6811 } 6812 6813 bool MasmParser::isMacroLikeDirective() { 6814 if (getLexer().is(AsmToken::Identifier)) { 6815 bool IsMacroLike = StringSwitch<bool>(getTok().getIdentifier()) 6816 .CasesLower("repeat", "rept", true) 6817 .CaseLower("while", true) 6818 .CasesLower("for", "irp", true) 6819 .CasesLower("forc", "irpc", true) 6820 .Default(false); 6821 if (IsMacroLike) 6822 return true; 6823 } 6824 if (peekTok().is(AsmToken::Identifier) && 6825 peekTok().getIdentifier().equals_insensitive("macro")) 6826 return true; 6827 6828 return false; 6829 } 6830 6831 MCAsmMacro *MasmParser::parseMacroLikeBody(SMLoc DirectiveLoc) { 6832 AsmToken EndToken, StartToken = getTok(); 6833 6834 unsigned NestLevel = 0; 6835 while (true) { 6836 // Check whether we have reached the end of the file. 6837 if (getLexer().is(AsmToken::Eof)) { 6838 printError(DirectiveLoc, "no matching 'endm' in definition"); 6839 return nullptr; 6840 } 6841 6842 if (isMacroLikeDirective()) 6843 ++NestLevel; 6844 6845 // Otherwise, check whether we have reached the endm. 6846 if (Lexer.is(AsmToken::Identifier) && 6847 getTok().getIdentifier().equals_insensitive("endm")) { 6848 if (NestLevel == 0) { 6849 EndToken = getTok(); 6850 Lex(); 6851 if (Lexer.isNot(AsmToken::EndOfStatement)) { 6852 printError(getTok().getLoc(), "unexpected token in 'endm' directive"); 6853 return nullptr; 6854 } 6855 break; 6856 } 6857 --NestLevel; 6858 } 6859 6860 // Otherwise, scan till the end of the statement. 6861 eatToEndOfStatement(); 6862 } 6863 6864 const char *BodyStart = StartToken.getLoc().getPointer(); 6865 const char *BodyEnd = EndToken.getLoc().getPointer(); 6866 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); 6867 6868 // We Are Anonymous. 6869 MacroLikeBodies.emplace_back(StringRef(), Body, MCAsmMacroParameters()); 6870 return &MacroLikeBodies.back(); 6871 } 6872 6873 bool MasmParser::expandStatement(SMLoc Loc) { 6874 std::string Body = parseStringTo(AsmToken::EndOfStatement); 6875 SMLoc EndLoc = getTok().getLoc(); 6876 6877 MCAsmMacroParameters Parameters; 6878 MCAsmMacroArguments Arguments; 6879 6880 StringMap<std::string> BuiltinValues; 6881 for (const auto &S : BuiltinSymbolMap) { 6882 const BuiltinSymbol &Sym = S.getValue(); 6883 if (llvm::Optional<std::string> Text = evaluateBuiltinTextMacro(Sym, Loc)) { 6884 BuiltinValues[S.getKey().lower()] = std::move(*Text); 6885 } 6886 } 6887 for (const auto &B : BuiltinValues) { 6888 MCAsmMacroParameter P; 6889 MCAsmMacroArgument A; 6890 P.Name = B.getKey(); 6891 P.Required = true; 6892 A.push_back(AsmToken(AsmToken::String, B.getValue())); 6893 6894 Parameters.push_back(std::move(P)); 6895 Arguments.push_back(std::move(A)); 6896 } 6897 6898 for (const auto &V : Variables) { 6899 const Variable &Var = V.getValue(); 6900 if (Var.IsText) { 6901 MCAsmMacroParameter P; 6902 MCAsmMacroArgument A; 6903 P.Name = Var.Name; 6904 P.Required = true; 6905 A.push_back(AsmToken(AsmToken::String, Var.TextValue)); 6906 6907 Parameters.push_back(std::move(P)); 6908 Arguments.push_back(std::move(A)); 6909 } 6910 } 6911 MacroLikeBodies.emplace_back(StringRef(), Body, Parameters); 6912 MCAsmMacro M = MacroLikeBodies.back(); 6913 6914 // Expand the statement in a new buffer. 6915 SmallString<80> Buf; 6916 raw_svector_ostream OS(Buf); 6917 if (expandMacro(OS, M.Body, M.Parameters, Arguments, M.Locals, EndLoc)) 6918 return true; 6919 std::unique_ptr<MemoryBuffer> Expansion = 6920 MemoryBuffer::getMemBufferCopy(OS.str(), "<expansion>"); 6921 6922 // Jump to the expanded statement and prime the lexer. 6923 CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Expansion), EndLoc); 6924 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); 6925 EndStatementAtEOFStack.push_back(false); 6926 Lex(); 6927 return false; 6928 } 6929 6930 void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, 6931 raw_svector_ostream &OS) { 6932 instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/getTok().getLoc(), OS); 6933 } 6934 void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, 6935 SMLoc ExitLoc, 6936 raw_svector_ostream &OS) { 6937 OS << "endm\n"; 6938 6939 std::unique_ptr<MemoryBuffer> Instantiation = 6940 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); 6941 6942 // Create the macro instantiation object and add to the current macro 6943 // instantiation stack. 6944 MacroInstantiation *MI = new MacroInstantiation{DirectiveLoc, CurBuffer, 6945 ExitLoc, TheCondStack.size()}; 6946 ActiveMacros.push_back(MI); 6947 6948 // Jump to the macro instantiation and prime the lexer. 6949 CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc()); 6950 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); 6951 EndStatementAtEOFStack.push_back(true); 6952 Lex(); 6953 } 6954 6955 /// parseDirectiveRepeat 6956 /// ::= ("repeat" | "rept") count 6957 /// body 6958 /// endm 6959 bool MasmParser::parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Dir) { 6960 const MCExpr *CountExpr; 6961 SMLoc CountLoc = getTok().getLoc(); 6962 if (parseExpression(CountExpr)) 6963 return true; 6964 6965 int64_t Count; 6966 if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) { 6967 return Error(CountLoc, "unexpected token in '" + Dir + "' directive"); 6968 } 6969 6970 if (check(Count < 0, CountLoc, "Count is negative") || parseEOL()) 6971 return true; 6972 6973 // Lex the repeat definition. 6974 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 6975 if (!M) 6976 return true; 6977 6978 // Macro instantiation is lexical, unfortunately. We construct a new buffer 6979 // to hold the macro body with substitutions. 6980 SmallString<256> Buf; 6981 raw_svector_ostream OS(Buf); 6982 while (Count--) { 6983 if (expandMacro(OS, M->Body, None, None, M->Locals, getTok().getLoc())) 6984 return true; 6985 } 6986 instantiateMacroLikeBody(M, DirectiveLoc, OS); 6987 6988 return false; 6989 } 6990 6991 /// parseDirectiveWhile 6992 /// ::= "while" expression 6993 /// body 6994 /// endm 6995 bool MasmParser::parseDirectiveWhile(SMLoc DirectiveLoc) { 6996 const MCExpr *CondExpr; 6997 SMLoc CondLoc = getTok().getLoc(); 6998 if (parseExpression(CondExpr)) 6999 return true; 7000 7001 // Lex the repeat definition. 7002 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 7003 if (!M) 7004 return true; 7005 7006 // Macro instantiation is lexical, unfortunately. We construct a new buffer 7007 // to hold the macro body with substitutions. 7008 SmallString<256> Buf; 7009 raw_svector_ostream OS(Buf); 7010 int64_t Condition; 7011 if (!CondExpr->evaluateAsAbsolute(Condition, getStreamer().getAssemblerPtr())) 7012 return Error(CondLoc, "expected absolute expression in 'while' directive"); 7013 if (Condition) { 7014 // Instantiate the macro, then resume at this directive to recheck the 7015 // condition. 7016 if (expandMacro(OS, M->Body, None, None, M->Locals, getTok().getLoc())) 7017 return true; 7018 instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/DirectiveLoc, OS); 7019 } 7020 7021 return false; 7022 } 7023 7024 /// parseDirectiveFor 7025 /// ::= ("for" | "irp") symbol [":" qualifier], <values> 7026 /// body 7027 /// endm 7028 bool MasmParser::parseDirectiveFor(SMLoc DirectiveLoc, StringRef Dir) { 7029 MCAsmMacroParameter Parameter; 7030 MCAsmMacroArguments A; 7031 if (check(parseIdentifier(Parameter.Name), 7032 "expected identifier in '" + Dir + "' directive")) 7033 return true; 7034 7035 // Parse optional qualifier (default value, or "req") 7036 if (parseOptionalToken(AsmToken::Colon)) { 7037 if (parseOptionalToken(AsmToken::Equal)) { 7038 // Default value 7039 SMLoc ParamLoc; 7040 7041 ParamLoc = Lexer.getLoc(); 7042 if (parseMacroArgument(nullptr, Parameter.Value)) 7043 return true; 7044 } else { 7045 SMLoc QualLoc; 7046 StringRef Qualifier; 7047 7048 QualLoc = Lexer.getLoc(); 7049 if (parseIdentifier(Qualifier)) 7050 return Error(QualLoc, "missing parameter qualifier for " 7051 "'" + 7052 Parameter.Name + "' in '" + Dir + 7053 "' directive"); 7054 7055 if (Qualifier.equals_insensitive("req")) 7056 Parameter.Required = true; 7057 else 7058 return Error(QualLoc, 7059 Qualifier + " is not a valid parameter qualifier for '" + 7060 Parameter.Name + "' in '" + Dir + "' directive"); 7061 } 7062 } 7063 7064 if (parseToken(AsmToken::Comma, 7065 "expected comma in '" + Dir + "' directive") || 7066 parseToken(AsmToken::Less, 7067 "values in '" + Dir + 7068 "' directive must be enclosed in angle brackets")) 7069 return true; 7070 7071 while (true) { 7072 A.emplace_back(); 7073 if (parseMacroArgument(&Parameter, A.back(), /*EndTok=*/AsmToken::Greater)) 7074 return addErrorSuffix(" in arguments for '" + Dir + "' directive"); 7075 7076 // If we see a comma, continue, and allow line continuation. 7077 if (!parseOptionalToken(AsmToken::Comma)) 7078 break; 7079 parseOptionalToken(AsmToken::EndOfStatement); 7080 } 7081 7082 if (parseToken(AsmToken::Greater, 7083 "values in '" + Dir + 7084 "' directive must be enclosed in angle brackets") || 7085 parseEOL()) 7086 return true; 7087 7088 // Lex the for definition. 7089 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 7090 if (!M) 7091 return true; 7092 7093 // Macro instantiation is lexical, unfortunately. We construct a new buffer 7094 // to hold the macro body with substitutions. 7095 SmallString<256> Buf; 7096 raw_svector_ostream OS(Buf); 7097 7098 for (const MCAsmMacroArgument &Arg : A) { 7099 if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc())) 7100 return true; 7101 } 7102 7103 instantiateMacroLikeBody(M, DirectiveLoc, OS); 7104 7105 return false; 7106 } 7107 7108 /// parseDirectiveForc 7109 /// ::= ("forc" | "irpc") symbol, <string> 7110 /// body 7111 /// endm 7112 bool MasmParser::parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive) { 7113 MCAsmMacroParameter Parameter; 7114 7115 std::string Argument; 7116 if (check(parseIdentifier(Parameter.Name), 7117 "expected identifier in '" + Directive + "' directive") || 7118 parseToken(AsmToken::Comma, 7119 "expected comma in '" + Directive + "' directive")) 7120 return true; 7121 if (parseAngleBracketString(Argument)) { 7122 // Match ml64.exe; treat all characters to end of statement as a string, 7123 // ignoring comment markers, then discard anything following a space (using 7124 // the C locale). 7125 Argument = parseStringTo(AsmToken::EndOfStatement); 7126 if (getTok().is(AsmToken::EndOfStatement)) 7127 Argument += getTok().getString(); 7128 size_t End = 0; 7129 for (; End < Argument.size(); ++End) { 7130 if (isSpace(Argument[End])) 7131 break; 7132 } 7133 Argument.resize(End); 7134 } 7135 if (parseEOL()) 7136 return true; 7137 7138 // Lex the irpc definition. 7139 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 7140 if (!M) 7141 return true; 7142 7143 // Macro instantiation is lexical, unfortunately. We construct a new buffer 7144 // to hold the macro body with substitutions. 7145 SmallString<256> Buf; 7146 raw_svector_ostream OS(Buf); 7147 7148 StringRef Values(Argument); 7149 for (std::size_t I = 0, End = Values.size(); I != End; ++I) { 7150 MCAsmMacroArgument Arg; 7151 Arg.emplace_back(AsmToken::Identifier, Values.slice(I, I + 1)); 7152 7153 if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc())) 7154 return true; 7155 } 7156 7157 instantiateMacroLikeBody(M, DirectiveLoc, OS); 7158 7159 return false; 7160 } 7161 7162 bool MasmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info, 7163 size_t Len) { 7164 const MCExpr *Value; 7165 SMLoc ExprLoc = getLexer().getLoc(); 7166 if (parseExpression(Value)) 7167 return true; 7168 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 7169 if (!MCE) 7170 return Error(ExprLoc, "unexpected expression in _emit"); 7171 uint64_t IntValue = MCE->getValue(); 7172 if (!isUInt<8>(IntValue) && !isInt<8>(IntValue)) 7173 return Error(ExprLoc, "literal value out of range for directive"); 7174 7175 Info.AsmRewrites->emplace_back(AOK_Emit, IDLoc, Len); 7176 return false; 7177 } 7178 7179 bool MasmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) { 7180 const MCExpr *Value; 7181 SMLoc ExprLoc = getLexer().getLoc(); 7182 if (parseExpression(Value)) 7183 return true; 7184 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 7185 if (!MCE) 7186 return Error(ExprLoc, "unexpected expression in align"); 7187 uint64_t IntValue = MCE->getValue(); 7188 if (!isPowerOf2_64(IntValue)) 7189 return Error(ExprLoc, "literal value not a power of two greater then zero"); 7190 7191 Info.AsmRewrites->emplace_back(AOK_Align, IDLoc, 5, Log2_64(IntValue)); 7192 return false; 7193 } 7194 7195 bool MasmParser::parseDirectiveRadix(SMLoc DirectiveLoc) { 7196 const SMLoc Loc = getLexer().getLoc(); 7197 std::string RadixStringRaw = parseStringTo(AsmToken::EndOfStatement); 7198 StringRef RadixString = StringRef(RadixStringRaw).trim(); 7199 unsigned Radix; 7200 if (RadixString.getAsInteger(10, Radix)) { 7201 return Error(Loc, 7202 "radix must be a decimal number in the range 2 to 16; was " + 7203 RadixString); 7204 } 7205 if (Radix < 2 || Radix > 16) 7206 return Error(Loc, "radix must be in the range 2 to 16; was " + 7207 std::to_string(Radix)); 7208 getLexer().setMasmDefaultRadix(Radix); 7209 return false; 7210 } 7211 7212 /// parseDirectiveEcho 7213 /// ::= "echo" message 7214 bool MasmParser::parseDirectiveEcho(SMLoc DirectiveLoc) { 7215 std::string Message = parseStringTo(AsmToken::EndOfStatement); 7216 llvm::outs() << Message; 7217 if (!StringRef(Message).endswith("\n")) 7218 llvm::outs() << '\n'; 7219 return false; 7220 } 7221 7222 // We are comparing pointers, but the pointers are relative to a single string. 7223 // Thus, this should always be deterministic. 7224 static int rewritesSort(const AsmRewrite *AsmRewriteA, 7225 const AsmRewrite *AsmRewriteB) { 7226 if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer()) 7227 return -1; 7228 if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer()) 7229 return 1; 7230 7231 // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output 7232 // rewrite to the same location. Make sure the SizeDirective rewrite is 7233 // performed first, then the Imm/ImmPrefix and finally the Input/Output. This 7234 // ensures the sort algorithm is stable. 7235 if (AsmRewritePrecedence[AsmRewriteA->Kind] > 7236 AsmRewritePrecedence[AsmRewriteB->Kind]) 7237 return -1; 7238 7239 if (AsmRewritePrecedence[AsmRewriteA->Kind] < 7240 AsmRewritePrecedence[AsmRewriteB->Kind]) 7241 return 1; 7242 llvm_unreachable("Unstable rewrite sort."); 7243 } 7244 7245 bool MasmParser::defineMacro(StringRef Name, StringRef Value) { 7246 Variable &Var = Variables[Name.lower()]; 7247 if (Var.Name.empty()) { 7248 Var.Name = Name; 7249 } else if (Var.Redefinable == Variable::NOT_REDEFINABLE) { 7250 return Error(SMLoc(), "invalid variable redefinition"); 7251 } else if (Var.Redefinable == Variable::WARN_ON_REDEFINITION && 7252 Warning(SMLoc(), "redefining '" + Name + 7253 "', already defined on the command line")) { 7254 return true; 7255 } 7256 Var.Redefinable = Variable::WARN_ON_REDEFINITION; 7257 Var.IsText = true; 7258 Var.TextValue = Value.str(); 7259 return false; 7260 } 7261 7262 bool MasmParser::lookUpField(StringRef Name, AsmFieldInfo &Info) const { 7263 const std::pair<StringRef, StringRef> BaseMember = Name.split('.'); 7264 const StringRef Base = BaseMember.first, Member = BaseMember.second; 7265 return lookUpField(Base, Member, Info); 7266 } 7267 7268 bool MasmParser::lookUpField(StringRef Base, StringRef Member, 7269 AsmFieldInfo &Info) const { 7270 if (Base.empty()) 7271 return true; 7272 7273 AsmFieldInfo BaseInfo; 7274 if (Base.contains('.') && !lookUpField(Base, BaseInfo)) 7275 Base = BaseInfo.Type.Name; 7276 7277 auto StructIt = Structs.find(Base.lower()); 7278 auto TypeIt = KnownType.find(Base.lower()); 7279 if (TypeIt != KnownType.end()) { 7280 StructIt = Structs.find(TypeIt->second.Name.lower()); 7281 } 7282 if (StructIt != Structs.end()) 7283 return lookUpField(StructIt->second, Member, Info); 7284 7285 return true; 7286 } 7287 7288 bool MasmParser::lookUpField(const StructInfo &Structure, StringRef Member, 7289 AsmFieldInfo &Info) const { 7290 if (Member.empty()) { 7291 Info.Type.Name = Structure.Name; 7292 Info.Type.Size = Structure.Size; 7293 Info.Type.ElementSize = Structure.Size; 7294 Info.Type.Length = 1; 7295 return false; 7296 } 7297 7298 std::pair<StringRef, StringRef> Split = Member.split('.'); 7299 const StringRef FieldName = Split.first, FieldMember = Split.second; 7300 7301 auto StructIt = Structs.find(FieldName.lower()); 7302 if (StructIt != Structs.end()) 7303 return lookUpField(StructIt->second, FieldMember, Info); 7304 7305 auto FieldIt = Structure.FieldsByName.find(FieldName.lower()); 7306 if (FieldIt == Structure.FieldsByName.end()) 7307 return true; 7308 7309 const FieldInfo &Field = Structure.Fields[FieldIt->second]; 7310 if (FieldMember.empty()) { 7311 Info.Offset += Field.Offset; 7312 Info.Type.Size = Field.SizeOf; 7313 Info.Type.ElementSize = Field.Type; 7314 Info.Type.Length = Field.LengthOf; 7315 if (Field.Contents.FT == FT_STRUCT) 7316 Info.Type.Name = Field.Contents.StructInfo.Structure.Name; 7317 else 7318 Info.Type.Name = ""; 7319 return false; 7320 } 7321 7322 if (Field.Contents.FT != FT_STRUCT) 7323 return true; 7324 const StructFieldInfo &StructInfo = Field.Contents.StructInfo; 7325 7326 if (lookUpField(StructInfo.Structure, FieldMember, Info)) 7327 return true; 7328 7329 Info.Offset += Field.Offset; 7330 return false; 7331 } 7332 7333 bool MasmParser::lookUpType(StringRef Name, AsmTypeInfo &Info) const { 7334 unsigned Size = StringSwitch<unsigned>(Name) 7335 .CasesLower("byte", "db", "sbyte", 1) 7336 .CasesLower("word", "dw", "sword", 2) 7337 .CasesLower("dword", "dd", "sdword", 4) 7338 .CasesLower("fword", "df", 6) 7339 .CasesLower("qword", "dq", "sqword", 8) 7340 .CaseLower("real4", 4) 7341 .CaseLower("real8", 8) 7342 .CaseLower("real10", 10) 7343 .Default(0); 7344 if (Size) { 7345 Info.Name = Name; 7346 Info.ElementSize = Size; 7347 Info.Length = 1; 7348 Info.Size = Size; 7349 return false; 7350 } 7351 7352 auto StructIt = Structs.find(Name.lower()); 7353 if (StructIt != Structs.end()) { 7354 const StructInfo &Structure = StructIt->second; 7355 Info.Name = Name; 7356 Info.ElementSize = Structure.Size; 7357 Info.Length = 1; 7358 Info.Size = Structure.Size; 7359 return false; 7360 } 7361 7362 return true; 7363 } 7364 7365 bool MasmParser::parseMSInlineAsm( 7366 std::string &AsmString, unsigned &NumOutputs, unsigned &NumInputs, 7367 SmallVectorImpl<std::pair<void *, bool>> &OpDecls, 7368 SmallVectorImpl<std::string> &Constraints, 7369 SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII, 7370 const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) { 7371 SmallVector<void *, 4> InputDecls; 7372 SmallVector<void *, 4> OutputDecls; 7373 SmallVector<bool, 4> InputDeclsAddressOf; 7374 SmallVector<bool, 4> OutputDeclsAddressOf; 7375 SmallVector<std::string, 4> InputConstraints; 7376 SmallVector<std::string, 4> OutputConstraints; 7377 SmallVector<unsigned, 4> ClobberRegs; 7378 7379 SmallVector<AsmRewrite, 4> AsmStrRewrites; 7380 7381 // Prime the lexer. 7382 Lex(); 7383 7384 // While we have input, parse each statement. 7385 unsigned InputIdx = 0; 7386 unsigned OutputIdx = 0; 7387 while (getLexer().isNot(AsmToken::Eof)) { 7388 // Parse curly braces marking block start/end. 7389 if (parseCurlyBlockScope(AsmStrRewrites)) 7390 continue; 7391 7392 ParseStatementInfo Info(&AsmStrRewrites); 7393 bool StatementErr = parseStatement(Info, &SI); 7394 7395 if (StatementErr || Info.ParseError) { 7396 // Emit pending errors if any exist. 7397 printPendingErrors(); 7398 return true; 7399 } 7400 7401 // No pending error should exist here. 7402 assert(!hasPendingError() && "unexpected error from parseStatement"); 7403 7404 if (Info.Opcode == ~0U) 7405 continue; 7406 7407 const MCInstrDesc &Desc = MII->get(Info.Opcode); 7408 7409 // Build the list of clobbers, outputs and inputs. 7410 for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) { 7411 MCParsedAsmOperand &Operand = *Info.ParsedOperands[i]; 7412 7413 // Register operand. 7414 if (Operand.isReg() && !Operand.needAddressOf() && 7415 !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) { 7416 unsigned NumDefs = Desc.getNumDefs(); 7417 // Clobber. 7418 if (NumDefs && Operand.getMCOperandNum() < NumDefs) 7419 ClobberRegs.push_back(Operand.getReg()); 7420 continue; 7421 } 7422 7423 // Expr/Input or Output. 7424 StringRef SymName = Operand.getSymName(); 7425 if (SymName.empty()) 7426 continue; 7427 7428 void *OpDecl = Operand.getOpDecl(); 7429 if (!OpDecl) 7430 continue; 7431 7432 StringRef Constraint = Operand.getConstraint(); 7433 if (Operand.isImm()) { 7434 // Offset as immediate. 7435 if (Operand.isOffsetOfLocal()) 7436 Constraint = "r"; 7437 else 7438 Constraint = "i"; 7439 } 7440 7441 bool isOutput = (i == 1) && Desc.mayStore(); 7442 SMLoc Start = SMLoc::getFromPointer(SymName.data()); 7443 if (isOutput) { 7444 ++InputIdx; 7445 OutputDecls.push_back(OpDecl); 7446 OutputDeclsAddressOf.push_back(Operand.needAddressOf()); 7447 OutputConstraints.push_back(("=" + Constraint).str()); 7448 AsmStrRewrites.emplace_back(AOK_Output, Start, SymName.size()); 7449 } else { 7450 InputDecls.push_back(OpDecl); 7451 InputDeclsAddressOf.push_back(Operand.needAddressOf()); 7452 InputConstraints.push_back(Constraint.str()); 7453 if (Desc.OpInfo[i - 1].isBranchTarget()) 7454 AsmStrRewrites.emplace_back(AOK_CallInput, Start, SymName.size()); 7455 else 7456 AsmStrRewrites.emplace_back(AOK_Input, Start, SymName.size()); 7457 } 7458 } 7459 7460 // Consider implicit defs to be clobbers. Think of cpuid and push. 7461 ArrayRef<MCPhysReg> ImpDefs(Desc.getImplicitDefs(), 7462 Desc.getNumImplicitDefs()); 7463 llvm::append_range(ClobberRegs, ImpDefs); 7464 } 7465 7466 // Set the number of Outputs and Inputs. 7467 NumOutputs = OutputDecls.size(); 7468 NumInputs = InputDecls.size(); 7469 7470 // Set the unique clobbers. 7471 array_pod_sort(ClobberRegs.begin(), ClobberRegs.end()); 7472 ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()), 7473 ClobberRegs.end()); 7474 Clobbers.assign(ClobberRegs.size(), std::string()); 7475 for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) { 7476 raw_string_ostream OS(Clobbers[I]); 7477 IP->printRegName(OS, ClobberRegs[I]); 7478 } 7479 7480 // Merge the various outputs and inputs. Output are expected first. 7481 if (NumOutputs || NumInputs) { 7482 unsigned NumExprs = NumOutputs + NumInputs; 7483 OpDecls.resize(NumExprs); 7484 Constraints.resize(NumExprs); 7485 for (unsigned i = 0; i < NumOutputs; ++i) { 7486 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]); 7487 Constraints[i] = OutputConstraints[i]; 7488 } 7489 for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) { 7490 OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]); 7491 Constraints[j] = InputConstraints[i]; 7492 } 7493 } 7494 7495 // Build the IR assembly string. 7496 std::string AsmStringIR; 7497 raw_string_ostream OS(AsmStringIR); 7498 StringRef ASMString = 7499 SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer(); 7500 const char *AsmStart = ASMString.begin(); 7501 const char *AsmEnd = ASMString.end(); 7502 array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort); 7503 for (auto it = AsmStrRewrites.begin(); it != AsmStrRewrites.end(); ++it) { 7504 const AsmRewrite &AR = *it; 7505 // Check if this has already been covered by another rewrite... 7506 if (AR.Done) 7507 continue; 7508 AsmRewriteKind Kind = AR.Kind; 7509 7510 const char *Loc = AR.Loc.getPointer(); 7511 assert(Loc >= AsmStart && "Expected Loc to be at or after Start!"); 7512 7513 // Emit everything up to the immediate/expression. 7514 if (unsigned Len = Loc - AsmStart) 7515 OS << StringRef(AsmStart, Len); 7516 7517 // Skip the original expression. 7518 if (Kind == AOK_Skip) { 7519 AsmStart = Loc + AR.Len; 7520 continue; 7521 } 7522 7523 unsigned AdditionalSkip = 0; 7524 // Rewrite expressions in $N notation. 7525 switch (Kind) { 7526 default: 7527 break; 7528 case AOK_IntelExpr: 7529 assert(AR.IntelExp.isValid() && "cannot write invalid intel expression"); 7530 if (AR.IntelExp.NeedBracs) 7531 OS << "["; 7532 if (AR.IntelExp.hasBaseReg()) 7533 OS << AR.IntelExp.BaseReg; 7534 if (AR.IntelExp.hasIndexReg()) 7535 OS << (AR.IntelExp.hasBaseReg() ? " + " : "") 7536 << AR.IntelExp.IndexReg; 7537 if (AR.IntelExp.Scale > 1) 7538 OS << " * $$" << AR.IntelExp.Scale; 7539 if (AR.IntelExp.hasOffset()) { 7540 if (AR.IntelExp.hasRegs()) 7541 OS << " + "; 7542 // Fuse this rewrite with a rewrite of the offset name, if present. 7543 StringRef OffsetName = AR.IntelExp.OffsetName; 7544 SMLoc OffsetLoc = SMLoc::getFromPointer(AR.IntelExp.OffsetName.data()); 7545 size_t OffsetLen = OffsetName.size(); 7546 auto rewrite_it = std::find_if( 7547 it, AsmStrRewrites.end(), [&](const AsmRewrite &FusingAR) { 7548 return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen && 7549 (FusingAR.Kind == AOK_Input || 7550 FusingAR.Kind == AOK_CallInput); 7551 }); 7552 if (rewrite_it == AsmStrRewrites.end()) { 7553 OS << "offset " << OffsetName; 7554 } else if (rewrite_it->Kind == AOK_CallInput) { 7555 OS << "${" << InputIdx++ << ":P}"; 7556 rewrite_it->Done = true; 7557 } else { 7558 OS << '$' << InputIdx++; 7559 rewrite_it->Done = true; 7560 } 7561 } 7562 if (AR.IntelExp.Imm || AR.IntelExp.emitImm()) 7563 OS << (AR.IntelExp.emitImm() ? "$$" : " + $$") << AR.IntelExp.Imm; 7564 if (AR.IntelExp.NeedBracs) 7565 OS << "]"; 7566 break; 7567 case AOK_Label: 7568 OS << Ctx.getAsmInfo()->getPrivateLabelPrefix() << AR.Label; 7569 break; 7570 case AOK_Input: 7571 OS << '$' << InputIdx++; 7572 break; 7573 case AOK_CallInput: 7574 OS << "${" << InputIdx++ << ":P}"; 7575 break; 7576 case AOK_Output: 7577 OS << '$' << OutputIdx++; 7578 break; 7579 case AOK_SizeDirective: 7580 switch (AR.Val) { 7581 default: break; 7582 case 8: OS << "byte ptr "; break; 7583 case 16: OS << "word ptr "; break; 7584 case 32: OS << "dword ptr "; break; 7585 case 64: OS << "qword ptr "; break; 7586 case 80: OS << "xword ptr "; break; 7587 case 128: OS << "xmmword ptr "; break; 7588 case 256: OS << "ymmword ptr "; break; 7589 } 7590 break; 7591 case AOK_Emit: 7592 OS << ".byte"; 7593 break; 7594 case AOK_Align: { 7595 // MS alignment directives are measured in bytes. If the native assembler 7596 // measures alignment in bytes, we can pass it straight through. 7597 OS << ".align"; 7598 if (getContext().getAsmInfo()->getAlignmentIsInBytes()) 7599 break; 7600 7601 // Alignment is in log2 form, so print that instead and skip the original 7602 // immediate. 7603 unsigned Val = AR.Val; 7604 OS << ' ' << Val; 7605 assert(Val < 10 && "Expected alignment less then 2^10."); 7606 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4; 7607 break; 7608 } 7609 case AOK_EVEN: 7610 OS << ".even"; 7611 break; 7612 case AOK_EndOfStatement: 7613 OS << "\n\t"; 7614 break; 7615 } 7616 7617 // Skip the original expression. 7618 AsmStart = Loc + AR.Len + AdditionalSkip; 7619 } 7620 7621 // Emit the remainder of the asm string. 7622 if (AsmStart != AsmEnd) 7623 OS << StringRef(AsmStart, AsmEnd - AsmStart); 7624 7625 AsmString = OS.str(); 7626 return false; 7627 } 7628 7629 void MasmParser::initializeBuiltinSymbolMap() { 7630 // Numeric built-ins (supported in all versions) 7631 BuiltinSymbolMap["@version"] = BI_VERSION; 7632 BuiltinSymbolMap["@line"] = BI_LINE; 7633 7634 // Text built-ins (supported in all versions) 7635 BuiltinSymbolMap["@date"] = BI_DATE; 7636 BuiltinSymbolMap["@time"] = BI_TIME; 7637 BuiltinSymbolMap["@filecur"] = BI_FILECUR; 7638 BuiltinSymbolMap["@filename"] = BI_FILENAME; 7639 BuiltinSymbolMap["@curseg"] = BI_CURSEG; 7640 7641 // Some built-ins exist only for MASM32 (32-bit x86) 7642 if (getContext().getSubtargetInfo()->getTargetTriple().getArch() == 7643 Triple::x86) { 7644 // Numeric built-ins 7645 // BuiltinSymbolMap["@cpu"] = BI_CPU; 7646 // BuiltinSymbolMap["@interface"] = BI_INTERFACE; 7647 // BuiltinSymbolMap["@wordsize"] = BI_WORDSIZE; 7648 // BuiltinSymbolMap["@codesize"] = BI_CODESIZE; 7649 // BuiltinSymbolMap["@datasize"] = BI_DATASIZE; 7650 // BuiltinSymbolMap["@model"] = BI_MODEL; 7651 7652 // Text built-ins 7653 // BuiltinSymbolMap["@code"] = BI_CODE; 7654 // BuiltinSymbolMap["@data"] = BI_DATA; 7655 // BuiltinSymbolMap["@fardata?"] = BI_FARDATA; 7656 // BuiltinSymbolMap["@stack"] = BI_STACK; 7657 } 7658 } 7659 7660 const MCExpr *MasmParser::evaluateBuiltinValue(BuiltinSymbol Symbol, 7661 SMLoc StartLoc) { 7662 switch (Symbol) { 7663 default: 7664 return nullptr; 7665 case BI_VERSION: 7666 // Match a recent version of ML.EXE. 7667 return MCConstantExpr::create(1427, getContext()); 7668 case BI_LINE: { 7669 int64_t Line; 7670 if (ActiveMacros.empty()) 7671 Line = SrcMgr.FindLineNumber(StartLoc, CurBuffer); 7672 else 7673 Line = SrcMgr.FindLineNumber(ActiveMacros.front()->InstantiationLoc, 7674 ActiveMacros.front()->ExitBuffer); 7675 return MCConstantExpr::create(Line, getContext()); 7676 } 7677 } 7678 llvm_unreachable("unhandled built-in symbol"); 7679 } 7680 7681 llvm::Optional<std::string> 7682 MasmParser::evaluateBuiltinTextMacro(BuiltinSymbol Symbol, SMLoc StartLoc) { 7683 switch (Symbol) { 7684 default: 7685 return {}; 7686 case BI_DATE: { 7687 // Current local date, formatted MM/DD/YY 7688 char TmpBuffer[sizeof("mm/dd/yy")]; 7689 const size_t Len = strftime(TmpBuffer, sizeof(TmpBuffer), "%D", &TM); 7690 return std::string(TmpBuffer, Len); 7691 } 7692 case BI_TIME: { 7693 // Current local time, formatted HH:MM:SS (24-hour clock) 7694 char TmpBuffer[sizeof("hh:mm:ss")]; 7695 const size_t Len = strftime(TmpBuffer, sizeof(TmpBuffer), "%T", &TM); 7696 return std::string(TmpBuffer, Len); 7697 } 7698 case BI_FILECUR: 7699 return SrcMgr 7700 .getMemoryBuffer( 7701 ActiveMacros.empty() ? CurBuffer : ActiveMacros.front()->ExitBuffer) 7702 ->getBufferIdentifier() 7703 .str(); 7704 case BI_FILENAME: 7705 return sys::path::stem(SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID()) 7706 ->getBufferIdentifier()) 7707 .upper(); 7708 case BI_CURSEG: 7709 return getStreamer().getCurrentSectionOnly()->getName().str(); 7710 } 7711 llvm_unreachable("unhandled built-in symbol"); 7712 } 7713 7714 /// Create an MCAsmParser instance. 7715 MCAsmParser *llvm::createMCMasmParser(SourceMgr &SM, MCContext &C, 7716 MCStreamer &Out, const MCAsmInfo &MAI, 7717 struct tm TM, unsigned CB) { 7718 return new MasmParser(SM, C, Out, MAI, TM, CB); 7719 } 7720