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