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