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