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