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