AsmParser.cpp revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
1//===- AsmParser.cpp - Parser for Assembly Files --------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This class implements the parser for assembly files. 11// 12//===----------------------------------------------------------------------===// 13 14#include "llvm/ADT/APFloat.h" 15#include "llvm/ADT/STLExtras.h" 16#include "llvm/ADT/SmallString.h" 17#include "llvm/ADT/StringMap.h" 18#include "llvm/ADT/Twine.h" 19#include "llvm/MC/MCAsmInfo.h" 20#include "llvm/MC/MCContext.h" 21#include "llvm/MC/MCDwarf.h" 22#include "llvm/MC/MCExpr.h" 23#include "llvm/MC/MCInstPrinter.h" 24#include "llvm/MC/MCInstrInfo.h" 25#include "llvm/MC/MCObjectFileInfo.h" 26#include "llvm/MC/MCParser/AsmCond.h" 27#include "llvm/MC/MCParser/AsmLexer.h" 28#include "llvm/MC/MCParser/MCAsmParser.h" 29#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 30#include "llvm/MC/MCRegisterInfo.h" 31#include "llvm/MC/MCSectionMachO.h" 32#include "llvm/MC/MCStreamer.h" 33#include "llvm/MC/MCSymbol.h" 34#include "llvm/MC/MCTargetAsmParser.h" 35#include "llvm/Support/CommandLine.h" 36#include "llvm/Support/ErrorHandling.h" 37#include "llvm/Support/MathExtras.h" 38#include "llvm/Support/MemoryBuffer.h" 39#include "llvm/Support/SourceMgr.h" 40#include "llvm/Support/raw_ostream.h" 41#include <cctype> 42#include <deque> 43#include <set> 44#include <string> 45#include <vector> 46using namespace llvm; 47 48static cl::opt<bool> 49FatalAssemblerWarnings("fatal-assembler-warnings", 50 cl::desc("Consider warnings as error")); 51 52MCAsmParserSemaCallback::~MCAsmParserSemaCallback() {} 53 54namespace { 55/// \brief Helper types for tracking macro definitions. 56typedef std::vector<AsmToken> MCAsmMacroArgument; 57typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments; 58 59struct MCAsmMacroParameter { 60 StringRef Name; 61 MCAsmMacroArgument Value; 62 bool Required; 63 bool Vararg; 64 65 MCAsmMacroParameter() : Required(false), Vararg(false) {} 66}; 67 68typedef std::vector<MCAsmMacroParameter> MCAsmMacroParameters; 69 70struct MCAsmMacro { 71 StringRef Name; 72 StringRef Body; 73 MCAsmMacroParameters Parameters; 74 75public: 76 MCAsmMacro(StringRef N, StringRef B, ArrayRef<MCAsmMacroParameter> P) : 77 Name(N), Body(B), Parameters(P) {} 78}; 79 80/// \brief Helper class for storing information about an active macro 81/// instantiation. 82struct MacroInstantiation { 83 /// The macro being instantiated. 84 const MCAsmMacro *TheMacro; 85 86 /// The macro instantiation with substitutions. 87 MemoryBuffer *Instantiation; 88 89 /// The location of the instantiation. 90 SMLoc InstantiationLoc; 91 92 /// The buffer where parsing should resume upon instantiation completion. 93 int ExitBuffer; 94 95 /// The location where parsing should resume upon instantiation completion. 96 SMLoc ExitLoc; 97 98public: 99 MacroInstantiation(const MCAsmMacro *M, SMLoc IL, int EB, SMLoc EL, 100 MemoryBuffer *I); 101}; 102 103struct ParseStatementInfo { 104 /// \brief The parsed operands from the last parsed statement. 105 SmallVector<MCParsedAsmOperand*, 8> ParsedOperands; 106 107 /// \brief The opcode from the last parsed instruction. 108 unsigned Opcode; 109 110 /// \brief Was there an error parsing the inline assembly? 111 bool ParseError; 112 113 SmallVectorImpl<AsmRewrite> *AsmRewrites; 114 115 ParseStatementInfo() : Opcode(~0U), ParseError(false), AsmRewrites(nullptr) {} 116 ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites) 117 : Opcode(~0), ParseError(false), AsmRewrites(rewrites) {} 118 119 ~ParseStatementInfo() { 120 // Free any parsed operands. 121 for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i) 122 delete ParsedOperands[i]; 123 ParsedOperands.clear(); 124 } 125}; 126 127/// \brief The concrete assembly parser instance. 128class AsmParser : public MCAsmParser { 129 AsmParser(const AsmParser &) LLVM_DELETED_FUNCTION; 130 void operator=(const AsmParser &) LLVM_DELETED_FUNCTION; 131private: 132 AsmLexer Lexer; 133 MCContext &Ctx; 134 MCStreamer &Out; 135 const MCAsmInfo &MAI; 136 SourceMgr &SrcMgr; 137 SourceMgr::DiagHandlerTy SavedDiagHandler; 138 void *SavedDiagContext; 139 MCAsmParserExtension *PlatformParser; 140 141 /// This is the current buffer index we're lexing from as managed by the 142 /// SourceMgr object. 143 int CurBuffer; 144 145 AsmCond TheCondState; 146 std::vector<AsmCond> TheCondStack; 147 148 /// \brief maps directive names to handler methods in parser 149 /// extensions. Extensions register themselves in this map by calling 150 /// addDirectiveHandler. 151 StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap; 152 153 /// \brief Map of currently defined macros. 154 StringMap<MCAsmMacro*> MacroMap; 155 156 /// \brief Stack of active macro instantiations. 157 std::vector<MacroInstantiation*> ActiveMacros; 158 159 /// \brief List of bodies of anonymous macros. 160 std::deque<MCAsmMacro> MacroLikeBodies; 161 162 /// Boolean tracking whether macro substitution is enabled. 163 unsigned MacrosEnabledFlag : 1; 164 165 /// Flag tracking whether any errors have been encountered. 166 unsigned HadError : 1; 167 168 /// The values from the last parsed cpp hash file line comment if any. 169 StringRef CppHashFilename; 170 int64_t CppHashLineNumber; 171 SMLoc CppHashLoc; 172 int CppHashBuf; 173 /// When generating dwarf for assembly source files we need to calculate the 174 /// logical line number based on the last parsed cpp hash file line comment 175 /// and current line. Since this is slow and messes up the SourceMgr's 176 /// cache we save the last info we queried with SrcMgr.FindLineNumber(). 177 SMLoc LastQueryIDLoc; 178 int LastQueryBuffer; 179 unsigned LastQueryLine; 180 181 /// AssemblerDialect. ~OU means unset value and use value provided by MAI. 182 unsigned AssemblerDialect; 183 184 /// \brief is Darwin compatibility enabled? 185 bool IsDarwin; 186 187 /// \brief Are we parsing ms-style inline assembly? 188 bool ParsingInlineAsm; 189 190public: 191 AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, 192 const MCAsmInfo &MAI); 193 virtual ~AsmParser(); 194 195 bool Run(bool NoInitialTextSection, bool NoFinalize = false) override; 196 197 void addDirectiveHandler(StringRef Directive, 198 ExtensionDirectiveHandler Handler) override { 199 ExtensionDirectiveMap[Directive] = Handler; 200 } 201 202public: 203 /// @name MCAsmParser Interface 204 /// { 205 206 SourceMgr &getSourceManager() override { return SrcMgr; } 207 MCAsmLexer &getLexer() override { return Lexer; } 208 MCContext &getContext() override { return Ctx; } 209 MCStreamer &getStreamer() override { return Out; } 210 unsigned getAssemblerDialect() override { 211 if (AssemblerDialect == ~0U) 212 return MAI.getAssemblerDialect(); 213 else 214 return AssemblerDialect; 215 } 216 void setAssemblerDialect(unsigned i) override { 217 AssemblerDialect = i; 218 } 219 220 void Note(SMLoc L, const Twine &Msg, 221 ArrayRef<SMRange> Ranges = None) override; 222 bool Warning(SMLoc L, const Twine &Msg, 223 ArrayRef<SMRange> Ranges = None) override; 224 bool Error(SMLoc L, const Twine &Msg, 225 ArrayRef<SMRange> Ranges = None) override; 226 227 const AsmToken &Lex() override; 228 229 void setParsingInlineAsm(bool V) override { ParsingInlineAsm = V; } 230 bool isParsingInlineAsm() override { return ParsingInlineAsm; } 231 232 bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString, 233 unsigned &NumOutputs, unsigned &NumInputs, 234 SmallVectorImpl<std::pair<void *,bool> > &OpDecls, 235 SmallVectorImpl<std::string> &Constraints, 236 SmallVectorImpl<std::string> &Clobbers, 237 const MCInstrInfo *MII, const MCInstPrinter *IP, 238 MCAsmParserSemaCallback &SI) override; 239 240 bool parseExpression(const MCExpr *&Res); 241 bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) override; 242 bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override; 243 bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) override; 244 bool parseAbsoluteExpression(int64_t &Res) override; 245 246 /// \brief Parse an identifier or string (as a quoted identifier) 247 /// and set \p Res to the identifier contents. 248 bool parseIdentifier(StringRef &Res) override; 249 void eatToEndOfStatement() override; 250 251 void checkForValidSection() override; 252 /// } 253 254private: 255 256 bool parseStatement(ParseStatementInfo &Info); 257 void eatToEndOfLine(); 258 bool parseCppHashLineFilenameComment(const SMLoc &L); 259 260 void checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body, 261 ArrayRef<MCAsmMacroParameter> Parameters); 262 bool expandMacro(raw_svector_ostream &OS, StringRef Body, 263 ArrayRef<MCAsmMacroParameter> Parameters, 264 ArrayRef<MCAsmMacroArgument> A, 265 const SMLoc &L); 266 267 /// \brief Are macros enabled in the parser? 268 bool areMacrosEnabled() {return MacrosEnabledFlag;} 269 270 /// \brief Control a flag in the parser that enables or disables macros. 271 void setMacrosEnabled(bool Flag) {MacrosEnabledFlag = Flag;} 272 273 /// \brief Lookup a previously defined macro. 274 /// \param Name Macro name. 275 /// \returns Pointer to macro. NULL if no such macro was defined. 276 const MCAsmMacro* lookupMacro(StringRef Name); 277 278 /// \brief Define a new macro with the given name and information. 279 void defineMacro(StringRef Name, const MCAsmMacro& Macro); 280 281 /// \brief Undefine a macro. If no such macro was defined, it's a no-op. 282 void undefineMacro(StringRef Name); 283 284 /// \brief Are we inside a macro instantiation? 285 bool isInsideMacroInstantiation() {return !ActiveMacros.empty();} 286 287 /// \brief Handle entry to macro instantiation. 288 /// 289 /// \param M The macro. 290 /// \param NameLoc Instantiation location. 291 bool handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc); 292 293 /// \brief Handle exit from macro instantiation. 294 void handleMacroExit(); 295 296 /// \brief Extract AsmTokens for a macro argument. 297 bool parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg); 298 299 /// \brief Parse all macro arguments for a given macro. 300 bool parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A); 301 302 void printMacroInstantiations(); 303 void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg, 304 ArrayRef<SMRange> Ranges = None) const { 305 SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges); 306 } 307 static void DiagHandler(const SMDiagnostic &Diag, void *Context); 308 309 /// \brief Enter the specified file. This returns true on failure. 310 bool enterIncludeFile(const std::string &Filename); 311 312 /// \brief Process the specified file for the .incbin directive. 313 /// This returns true on failure. 314 bool processIncbinFile(const std::string &Filename); 315 316 /// \brief Reset the current lexer position to that given by \p Loc. The 317 /// current token is not set; clients should ensure Lex() is called 318 /// subsequently. 319 /// 320 /// \param InBuffer If not -1, should be the known buffer id that contains the 321 /// location. 322 void jumpToLoc(SMLoc Loc, int InBuffer=-1); 323 324 /// \brief Parse up to the end of statement and a return the contents from the 325 /// current token until the end of the statement; the current token on exit 326 /// will be either the EndOfStatement or EOF. 327 StringRef parseStringToEndOfStatement() override; 328 329 /// \brief Parse until the end of a statement or a comma is encountered, 330 /// return the contents from the current token up to the end or comma. 331 StringRef parseStringToComma(); 332 333 bool parseAssignment(StringRef Name, bool allow_redef, 334 bool NoDeadStrip = false); 335 336 bool parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc); 337 bool parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc); 338 bool parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc); 339 340 bool parseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc); 341 342 // Generic (target and platform independent) directive parsing. 343 enum DirectiveKind { 344 DK_NO_DIRECTIVE, // Placeholder 345 DK_SET, DK_EQU, DK_EQUIV, DK_ASCII, DK_ASCIZ, DK_STRING, DK_BYTE, DK_SHORT, 346 DK_VALUE, DK_2BYTE, DK_LONG, DK_INT, DK_4BYTE, DK_QUAD, DK_8BYTE, DK_OCTA, 347 DK_SINGLE, DK_FLOAT, DK_DOUBLE, DK_ALIGN, DK_ALIGN32, DK_BALIGN, DK_BALIGNW, 348 DK_BALIGNL, DK_P2ALIGN, DK_P2ALIGNW, DK_P2ALIGNL, DK_ORG, DK_FILL, DK_ENDR, 349 DK_BUNDLE_ALIGN_MODE, DK_BUNDLE_LOCK, DK_BUNDLE_UNLOCK, 350 DK_ZERO, DK_EXTERN, DK_GLOBL, DK_GLOBAL, 351 DK_LAZY_REFERENCE, DK_NO_DEAD_STRIP, DK_SYMBOL_RESOLVER, DK_PRIVATE_EXTERN, 352 DK_REFERENCE, DK_WEAK_DEFINITION, DK_WEAK_REFERENCE, 353 DK_WEAK_DEF_CAN_BE_HIDDEN, DK_COMM, DK_COMMON, DK_LCOMM, DK_ABORT, 354 DK_INCLUDE, DK_INCBIN, DK_CODE16, DK_CODE16GCC, DK_REPT, DK_IRP, DK_IRPC, 355 DK_IF, DK_IFNE, DK_IFB, DK_IFNB, DK_IFC, DK_IFEQS, DK_IFNC, DK_IFDEF, 356 DK_IFNDEF, DK_IFNOTDEF, DK_ELSEIF, DK_ELSE, DK_ENDIF, 357 DK_SPACE, DK_SKIP, DK_FILE, DK_LINE, DK_LOC, DK_STABS, 358 DK_CFI_SECTIONS, DK_CFI_STARTPROC, DK_CFI_ENDPROC, DK_CFI_DEF_CFA, 359 DK_CFI_DEF_CFA_OFFSET, DK_CFI_ADJUST_CFA_OFFSET, DK_CFI_DEF_CFA_REGISTER, 360 DK_CFI_OFFSET, DK_CFI_REL_OFFSET, DK_CFI_PERSONALITY, DK_CFI_LSDA, 361 DK_CFI_REMEMBER_STATE, DK_CFI_RESTORE_STATE, DK_CFI_SAME_VALUE, 362 DK_CFI_RESTORE, DK_CFI_ESCAPE, DK_CFI_SIGNAL_FRAME, DK_CFI_UNDEFINED, 363 DK_CFI_REGISTER, DK_CFI_WINDOW_SAVE, 364 DK_MACROS_ON, DK_MACROS_OFF, DK_MACRO, DK_ENDM, DK_ENDMACRO, DK_PURGEM, 365 DK_SLEB128, DK_ULEB128, 366 DK_ERR, DK_ERROR, 367 DK_END 368 }; 369 370 /// \brief Maps directive name --> DirectiveKind enum, for 371 /// directives parsed by this class. 372 StringMap<DirectiveKind> DirectiveKindMap; 373 374 // ".ascii", ".asciz", ".string" 375 bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated); 376 bool parseDirectiveValue(unsigned Size); // ".byte", ".long", ... 377 bool parseDirectiveOctaValue(); // ".octa" 378 bool parseDirectiveRealValue(const fltSemantics &); // ".single", ... 379 bool parseDirectiveFill(); // ".fill" 380 bool parseDirectiveZero(); // ".zero" 381 // ".set", ".equ", ".equiv" 382 bool parseDirectiveSet(StringRef IDVal, bool allow_redef); 383 bool parseDirectiveOrg(); // ".org" 384 // ".align{,32}", ".p2align{,w,l}" 385 bool parseDirectiveAlign(bool IsPow2, unsigned ValueSize); 386 387 // ".file", ".line", ".loc", ".stabs" 388 bool parseDirectiveFile(SMLoc DirectiveLoc); 389 bool parseDirectiveLine(); 390 bool parseDirectiveLoc(); 391 bool parseDirectiveStabs(); 392 393 // .cfi directives 394 bool parseDirectiveCFIRegister(SMLoc DirectiveLoc); 395 bool parseDirectiveCFIWindowSave(); 396 bool parseDirectiveCFISections(); 397 bool parseDirectiveCFIStartProc(); 398 bool parseDirectiveCFIEndProc(); 399 bool parseDirectiveCFIDefCfaOffset(); 400 bool parseDirectiveCFIDefCfa(SMLoc DirectiveLoc); 401 bool parseDirectiveCFIAdjustCfaOffset(); 402 bool parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc); 403 bool parseDirectiveCFIOffset(SMLoc DirectiveLoc); 404 bool parseDirectiveCFIRelOffset(SMLoc DirectiveLoc); 405 bool parseDirectiveCFIPersonalityOrLsda(bool IsPersonality); 406 bool parseDirectiveCFIRememberState(); 407 bool parseDirectiveCFIRestoreState(); 408 bool parseDirectiveCFISameValue(SMLoc DirectiveLoc); 409 bool parseDirectiveCFIRestore(SMLoc DirectiveLoc); 410 bool parseDirectiveCFIEscape(); 411 bool parseDirectiveCFISignalFrame(); 412 bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc); 413 414 // macro directives 415 bool parseDirectivePurgeMacro(SMLoc DirectiveLoc); 416 bool parseDirectiveEndMacro(StringRef Directive); 417 bool parseDirectiveMacro(SMLoc DirectiveLoc); 418 bool parseDirectiveMacrosOnOff(StringRef Directive); 419 420 // ".bundle_align_mode" 421 bool parseDirectiveBundleAlignMode(); 422 // ".bundle_lock" 423 bool parseDirectiveBundleLock(); 424 // ".bundle_unlock" 425 bool parseDirectiveBundleUnlock(); 426 427 // ".space", ".skip" 428 bool parseDirectiveSpace(StringRef IDVal); 429 430 // .sleb128 (Signed=true) and .uleb128 (Signed=false) 431 bool parseDirectiveLEB128(bool Signed); 432 433 /// \brief Parse a directive like ".globl" which 434 /// accepts a single symbol (which should be a label or an external). 435 bool parseDirectiveSymbolAttribute(MCSymbolAttr Attr); 436 437 bool parseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm" 438 439 bool parseDirectiveAbort(); // ".abort" 440 bool parseDirectiveInclude(); // ".include" 441 bool parseDirectiveIncbin(); // ".incbin" 442 443 // ".if" or ".ifne" 444 bool parseDirectiveIf(SMLoc DirectiveLoc); 445 // ".ifb" or ".ifnb", depending on ExpectBlank. 446 bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank); 447 // ".ifc" or ".ifnc", depending on ExpectEqual. 448 bool parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual); 449 // ".ifeqs" 450 bool parseDirectiveIfeqs(SMLoc DirectiveLoc); 451 // ".ifdef" or ".ifndef", depending on expect_defined 452 bool parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined); 453 bool parseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif" 454 bool parseDirectiveElse(SMLoc DirectiveLoc); // ".else" 455 bool parseDirectiveEndIf(SMLoc DirectiveLoc); // .endif 456 bool parseEscapedString(std::string &Data) override; 457 458 const MCExpr *applyModifierToExpr(const MCExpr *E, 459 MCSymbolRefExpr::VariantKind Variant); 460 461 // Macro-like directives 462 MCAsmMacro *parseMacroLikeBody(SMLoc DirectiveLoc); 463 void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, 464 raw_svector_ostream &OS); 465 bool parseDirectiveRept(SMLoc DirectiveLoc, StringRef Directive); 466 bool parseDirectiveIrp(SMLoc DirectiveLoc); // ".irp" 467 bool parseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc" 468 bool parseDirectiveEndr(SMLoc DirectiveLoc); // ".endr" 469 470 // "_emit" or "__emit" 471 bool parseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info, 472 size_t Len); 473 474 // "align" 475 bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info); 476 477 // "end" 478 bool parseDirectiveEnd(SMLoc DirectiveLoc); 479 480 // ".err" or ".error" 481 bool parseDirectiveError(SMLoc DirectiveLoc, bool WithMessage); 482 483 void initializeDirectiveKindMap(); 484}; 485} 486 487namespace llvm { 488 489extern MCAsmParserExtension *createDarwinAsmParser(); 490extern MCAsmParserExtension *createELFAsmParser(); 491extern MCAsmParserExtension *createCOFFAsmParser(); 492 493} 494 495enum { DEFAULT_ADDRSPACE = 0 }; 496 497AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, 498 const MCAsmInfo &_MAI) 499 : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM), 500 PlatformParser(nullptr), CurBuffer(0), MacrosEnabledFlag(true), 501 HadError(false), CppHashLineNumber(0), AssemblerDialect(~0U), 502 IsDarwin(false), ParsingInlineAsm(false) { 503 // Save the old handler. 504 SavedDiagHandler = SrcMgr.getDiagHandler(); 505 SavedDiagContext = SrcMgr.getDiagContext(); 506 // Set our own handler which calls the saved handler. 507 SrcMgr.setDiagHandler(DiagHandler, this); 508 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 509 510 // Initialize the platform / file format parser. 511 switch (_Ctx.getObjectFileInfo()->getObjectFileType()) { 512 case MCObjectFileInfo::IsCOFF: 513 PlatformParser = createCOFFAsmParser(); 514 PlatformParser->Initialize(*this); 515 break; 516 case MCObjectFileInfo::IsMachO: 517 PlatformParser = createDarwinAsmParser(); 518 PlatformParser->Initialize(*this); 519 IsDarwin = true; 520 break; 521 case MCObjectFileInfo::IsELF: 522 PlatformParser = createELFAsmParser(); 523 PlatformParser->Initialize(*this); 524 break; 525 } 526 527 initializeDirectiveKindMap(); 528} 529 530AsmParser::~AsmParser() { 531 assert((HadError || ActiveMacros.empty()) && 532 "Unexpected active macro instantiation!"); 533 534 // Destroy any macros. 535 for (StringMap<MCAsmMacro *>::iterator it = MacroMap.begin(), 536 ie = MacroMap.end(); 537 it != ie; ++it) 538 delete it->getValue(); 539 540 delete PlatformParser; 541} 542 543void AsmParser::printMacroInstantiations() { 544 // Print the active macro instantiation stack. 545 for (std::vector<MacroInstantiation *>::const_reverse_iterator 546 it = ActiveMacros.rbegin(), 547 ie = ActiveMacros.rend(); 548 it != ie; ++it) 549 printMessage((*it)->InstantiationLoc, SourceMgr::DK_Note, 550 "while in macro instantiation"); 551} 552 553void AsmParser::Note(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { 554 printMessage(L, SourceMgr::DK_Note, Msg, Ranges); 555 printMacroInstantiations(); 556} 557 558bool AsmParser::Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { 559 if (FatalAssemblerWarnings) 560 return Error(L, Msg, Ranges); 561 printMessage(L, SourceMgr::DK_Warning, Msg, Ranges); 562 printMacroInstantiations(); 563 return false; 564} 565 566bool AsmParser::Error(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { 567 HadError = true; 568 printMessage(L, SourceMgr::DK_Error, Msg, Ranges); 569 printMacroInstantiations(); 570 return true; 571} 572 573bool AsmParser::enterIncludeFile(const std::string &Filename) { 574 std::string IncludedFile; 575 int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); 576 if (NewBuf == -1) 577 return true; 578 579 CurBuffer = NewBuf; 580 581 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 582 583 return false; 584} 585 586/// Process the specified .incbin file by searching for it in the include paths 587/// then just emitting the byte contents of the file to the streamer. This 588/// returns true on failure. 589bool AsmParser::processIncbinFile(const std::string &Filename) { 590 std::string IncludedFile; 591 int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); 592 if (NewBuf == -1) 593 return true; 594 595 // Pick up the bytes from the file and emit them. 596 getStreamer().EmitBytes(SrcMgr.getMemoryBuffer(NewBuf)->getBuffer()); 597 return false; 598} 599 600void AsmParser::jumpToLoc(SMLoc Loc, int InBuffer) { 601 if (InBuffer != -1) { 602 CurBuffer = InBuffer; 603 } else { 604 CurBuffer = SrcMgr.FindBufferContainingLoc(Loc); 605 } 606 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer), Loc.getPointer()); 607} 608 609const AsmToken &AsmParser::Lex() { 610 const AsmToken *tok = &Lexer.Lex(); 611 612 if (tok->is(AsmToken::Eof)) { 613 // If this is the end of an included file, pop the parent file off the 614 // include stack. 615 SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer); 616 if (ParentIncludeLoc != SMLoc()) { 617 jumpToLoc(ParentIncludeLoc); 618 tok = &Lexer.Lex(); 619 } 620 } 621 622 if (tok->is(AsmToken::Error)) 623 Error(Lexer.getErrLoc(), Lexer.getErr()); 624 625 return *tok; 626} 627 628bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { 629 // Create the initial section, if requested. 630 if (!NoInitialTextSection) 631 Out.InitSections(); 632 633 // Prime the lexer. 634 Lex(); 635 636 HadError = false; 637 AsmCond StartingCondState = TheCondState; 638 639 // If we are generating dwarf for assembly source files save the initial text 640 // section and generate a .file directive. 641 if (getContext().getGenDwarfForAssembly()) { 642 getContext().setGenDwarfSection(getStreamer().getCurrentSection().first); 643 MCSymbol *SectionStartSym = getContext().CreateTempSymbol(); 644 getStreamer().EmitLabel(SectionStartSym); 645 getContext().setGenDwarfSectionStartSym(SectionStartSym); 646 getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective( 647 0, StringRef(), getContext().getMainFileName())); 648 } 649 650 // While we have input, parse each statement. 651 while (Lexer.isNot(AsmToken::Eof)) { 652 ParseStatementInfo Info; 653 if (!parseStatement(Info)) 654 continue; 655 656 // We had an error, validate that one was emitted and recover by skipping to 657 // the next line. 658 assert(HadError && "Parse statement returned an error, but none emitted!"); 659 eatToEndOfStatement(); 660 } 661 662 if (TheCondState.TheCond != StartingCondState.TheCond || 663 TheCondState.Ignore != StartingCondState.Ignore) 664 return TokError("unmatched .ifs or .elses"); 665 666 // Check to see there are no empty DwarfFile slots. 667 const auto &LineTables = getContext().getMCDwarfLineTables(); 668 if (!LineTables.empty()) { 669 unsigned Index = 0; 670 for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) { 671 if (File.Name.empty() && Index != 0) 672 TokError("unassigned file number: " + Twine(Index) + 673 " for .file directives"); 674 ++Index; 675 } 676 } 677 678 // Check to see that all assembler local symbols were actually defined. 679 // Targets that don't do subsections via symbols may not want this, though, 680 // so conservatively exclude them. Only do this if we're finalizing, though, 681 // as otherwise we won't necessarilly have seen everything yet. 682 if (!NoFinalize && MAI.hasSubsectionsViaSymbols()) { 683 const MCContext::SymbolTable &Symbols = getContext().getSymbols(); 684 for (MCContext::SymbolTable::const_iterator i = Symbols.begin(), 685 e = Symbols.end(); 686 i != e; ++i) { 687 MCSymbol *Sym = i->getValue(); 688 // Variable symbols may not be marked as defined, so check those 689 // explicitly. If we know it's a variable, we have a definition for 690 // the purposes of this check. 691 if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined()) 692 // FIXME: We would really like to refer back to where the symbol was 693 // first referenced for a source location. We need to add something 694 // to track that. Currently, we just point to the end of the file. 695 printMessage( 696 getLexer().getLoc(), SourceMgr::DK_Error, 697 "assembler local symbol '" + Sym->getName() + "' not defined"); 698 } 699 } 700 701 // Finalize the output stream if there are no errors and if the client wants 702 // us to. 703 if (!HadError && !NoFinalize) 704 Out.Finish(); 705 706 return HadError; 707} 708 709void AsmParser::checkForValidSection() { 710 if (!ParsingInlineAsm && !getStreamer().getCurrentSection().first) { 711 TokError("expected section directive before assembly directive"); 712 Out.InitSections(); 713 } 714} 715 716/// \brief Throw away the rest of the line for testing purposes. 717void AsmParser::eatToEndOfStatement() { 718 while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof)) 719 Lex(); 720 721 // Eat EOL. 722 if (Lexer.is(AsmToken::EndOfStatement)) 723 Lex(); 724} 725 726StringRef AsmParser::parseStringToEndOfStatement() { 727 const char *Start = getTok().getLoc().getPointer(); 728 729 while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof)) 730 Lex(); 731 732 const char *End = getTok().getLoc().getPointer(); 733 return StringRef(Start, End - Start); 734} 735 736StringRef AsmParser::parseStringToComma() { 737 const char *Start = getTok().getLoc().getPointer(); 738 739 while (Lexer.isNot(AsmToken::EndOfStatement) && 740 Lexer.isNot(AsmToken::Comma) && Lexer.isNot(AsmToken::Eof)) 741 Lex(); 742 743 const char *End = getTok().getLoc().getPointer(); 744 return StringRef(Start, End - Start); 745} 746 747/// \brief Parse a paren expression and return it. 748/// NOTE: This assumes the leading '(' has already been consumed. 749/// 750/// parenexpr ::= expr) 751/// 752bool AsmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) { 753 if (parseExpression(Res)) 754 return true; 755 if (Lexer.isNot(AsmToken::RParen)) 756 return TokError("expected ')' in parentheses expression"); 757 EndLoc = Lexer.getTok().getEndLoc(); 758 Lex(); 759 return false; 760} 761 762/// \brief Parse a bracket expression and return it. 763/// NOTE: This assumes the leading '[' has already been consumed. 764/// 765/// bracketexpr ::= expr] 766/// 767bool AsmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) { 768 if (parseExpression(Res)) 769 return true; 770 if (Lexer.isNot(AsmToken::RBrac)) 771 return TokError("expected ']' in brackets expression"); 772 EndLoc = Lexer.getTok().getEndLoc(); 773 Lex(); 774 return false; 775} 776 777/// \brief Parse a primary expression and return it. 778/// primaryexpr ::= (parenexpr 779/// primaryexpr ::= symbol 780/// primaryexpr ::= number 781/// primaryexpr ::= '.' 782/// primaryexpr ::= ~,+,- primaryexpr 783bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { 784 SMLoc FirstTokenLoc = getLexer().getLoc(); 785 AsmToken::TokenKind FirstTokenKind = Lexer.getKind(); 786 switch (FirstTokenKind) { 787 default: 788 return TokError("unknown token in expression"); 789 // If we have an error assume that we've already handled it. 790 case AsmToken::Error: 791 return true; 792 case AsmToken::Exclaim: 793 Lex(); // Eat the operator. 794 if (parsePrimaryExpr(Res, EndLoc)) 795 return true; 796 Res = MCUnaryExpr::CreateLNot(Res, getContext()); 797 return false; 798 case AsmToken::Dollar: 799 case AsmToken::At: 800 case AsmToken::String: 801 case AsmToken::Identifier: { 802 StringRef Identifier; 803 if (parseIdentifier(Identifier)) { 804 if (FirstTokenKind == AsmToken::Dollar) { 805 if (Lexer.getMAI().getDollarIsPC()) { 806 // This is a '$' reference, which references the current PC. Emit a 807 // temporary label to the streamer and refer to it. 808 MCSymbol *Sym = Ctx.CreateTempSymbol(); 809 Out.EmitLabel(Sym); 810 Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 811 getContext()); 812 EndLoc = FirstTokenLoc; 813 return false; 814 } 815 return Error(FirstTokenLoc, "invalid token in expression"); 816 } 817 } 818 // Parse symbol variant 819 std::pair<StringRef, StringRef> Split; 820 if (!MAI.useParensForSymbolVariant()) { 821 Split = Identifier.split('@'); 822 } else if (Lexer.is(AsmToken::LParen)) { 823 Lexer.Lex(); // eat ( 824 StringRef VName; 825 parseIdentifier(VName); 826 if (Lexer.isNot(AsmToken::RParen)) { 827 return Error(Lexer.getTok().getLoc(), 828 "unexpected token in variant, expected ')'"); 829 } 830 Lexer.Lex(); // eat ) 831 Split = std::make_pair(Identifier, VName); 832 } 833 834 EndLoc = SMLoc::getFromPointer(Identifier.end()); 835 836 // This is a symbol reference. 837 StringRef SymbolName = Identifier; 838 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 839 840 // Lookup the symbol variant if used. 841 if (Split.second.size()) { 842 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second); 843 if (Variant != MCSymbolRefExpr::VK_Invalid) { 844 SymbolName = Split.first; 845 } else if (MAI.doesAllowAtInName() && !MAI.useParensForSymbolVariant()) { 846 Variant = MCSymbolRefExpr::VK_None; 847 } else { 848 return Error(SMLoc::getFromPointer(Split.second.begin()), 849 "invalid variant '" + Split.second + "'"); 850 } 851 } 852 853 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName); 854 855 // If this is an absolute variable reference, substitute it now to preserve 856 // semantics in the face of reassignment. 857 if (Sym->isVariable() && isa<MCConstantExpr>(Sym->getVariableValue())) { 858 if (Variant) 859 return Error(EndLoc, "unexpected modifier on variable reference"); 860 861 Res = Sym->getVariableValue(); 862 return false; 863 } 864 865 // Otherwise create a symbol ref. 866 Res = MCSymbolRefExpr::Create(Sym, Variant, getContext()); 867 return false; 868 } 869 case AsmToken::BigNum: 870 return TokError("literal value out of range for directive"); 871 case AsmToken::Integer: { 872 SMLoc Loc = getTok().getLoc(); 873 int64_t IntVal = getTok().getIntVal(); 874 Res = MCConstantExpr::Create(IntVal, getContext()); 875 EndLoc = Lexer.getTok().getEndLoc(); 876 Lex(); // Eat token. 877 // Look for 'b' or 'f' following an Integer as a directional label 878 if (Lexer.getKind() == AsmToken::Identifier) { 879 StringRef IDVal = getTok().getString(); 880 // Lookup the symbol variant if used. 881 std::pair<StringRef, StringRef> Split = IDVal.split('@'); 882 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 883 if (Split.first.size() != IDVal.size()) { 884 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second); 885 if (Variant == MCSymbolRefExpr::VK_Invalid) 886 return TokError("invalid variant '" + Split.second + "'"); 887 IDVal = Split.first; 888 } 889 if (IDVal == "f" || IDVal == "b") { 890 MCSymbol *Sym = 891 Ctx.GetDirectionalLocalSymbol(IntVal, IDVal == "b"); 892 Res = MCSymbolRefExpr::Create(Sym, Variant, getContext()); 893 if (IDVal == "b" && Sym->isUndefined()) 894 return Error(Loc, "invalid reference to undefined symbol"); 895 EndLoc = Lexer.getTok().getEndLoc(); 896 Lex(); // Eat identifier. 897 } 898 } 899 return false; 900 } 901 case AsmToken::Real: { 902 APFloat RealVal(APFloat::IEEEdouble, getTok().getString()); 903 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 904 Res = MCConstantExpr::Create(IntVal, getContext()); 905 EndLoc = Lexer.getTok().getEndLoc(); 906 Lex(); // Eat token. 907 return false; 908 } 909 case AsmToken::Dot: { 910 // This is a '.' reference, which references the current PC. Emit a 911 // temporary label to the streamer and refer to it. 912 MCSymbol *Sym = Ctx.CreateTempSymbol(); 913 Out.EmitLabel(Sym); 914 Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); 915 EndLoc = Lexer.getTok().getEndLoc(); 916 Lex(); // Eat identifier. 917 return false; 918 } 919 case AsmToken::LParen: 920 Lex(); // Eat the '('. 921 return parseParenExpr(Res, EndLoc); 922 case AsmToken::LBrac: 923 if (!PlatformParser->HasBracketExpressions()) 924 return TokError("brackets expression not supported on this target"); 925 Lex(); // Eat the '['. 926 return parseBracketExpr(Res, EndLoc); 927 case AsmToken::Minus: 928 Lex(); // Eat the operator. 929 if (parsePrimaryExpr(Res, EndLoc)) 930 return true; 931 Res = MCUnaryExpr::CreateMinus(Res, getContext()); 932 return false; 933 case AsmToken::Plus: 934 Lex(); // Eat the operator. 935 if (parsePrimaryExpr(Res, EndLoc)) 936 return true; 937 Res = MCUnaryExpr::CreatePlus(Res, getContext()); 938 return false; 939 case AsmToken::Tilde: 940 Lex(); // Eat the operator. 941 if (parsePrimaryExpr(Res, EndLoc)) 942 return true; 943 Res = MCUnaryExpr::CreateNot(Res, getContext()); 944 return false; 945 } 946} 947 948bool AsmParser::parseExpression(const MCExpr *&Res) { 949 SMLoc EndLoc; 950 return parseExpression(Res, EndLoc); 951} 952 953const MCExpr * 954AsmParser::applyModifierToExpr(const MCExpr *E, 955 MCSymbolRefExpr::VariantKind Variant) { 956 // Ask the target implementation about this expression first. 957 const MCExpr *NewE = getTargetParser().applyModifierToExpr(E, Variant, Ctx); 958 if (NewE) 959 return NewE; 960 // Recurse over the given expression, rebuilding it to apply the given variant 961 // if there is exactly one symbol. 962 switch (E->getKind()) { 963 case MCExpr::Target: 964 case MCExpr::Constant: 965 return nullptr; 966 967 case MCExpr::SymbolRef: { 968 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 969 970 if (SRE->getKind() != MCSymbolRefExpr::VK_None) { 971 TokError("invalid variant on expression '" + getTok().getIdentifier() + 972 "' (already modified)"); 973 return E; 974 } 975 976 return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 977 } 978 979 case MCExpr::Unary: { 980 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E); 981 const MCExpr *Sub = applyModifierToExpr(UE->getSubExpr(), Variant); 982 if (!Sub) 983 return nullptr; 984 return MCUnaryExpr::Create(UE->getOpcode(), Sub, getContext()); 985 } 986 987 case MCExpr::Binary: { 988 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 989 const MCExpr *LHS = applyModifierToExpr(BE->getLHS(), Variant); 990 const MCExpr *RHS = applyModifierToExpr(BE->getRHS(), Variant); 991 992 if (!LHS && !RHS) 993 return nullptr; 994 995 if (!LHS) 996 LHS = BE->getLHS(); 997 if (!RHS) 998 RHS = BE->getRHS(); 999 1000 return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 1001 } 1002 } 1003 1004 llvm_unreachable("Invalid expression kind!"); 1005} 1006 1007/// \brief Parse an expression and return it. 1008/// 1009/// expr ::= expr &&,|| expr -> lowest. 1010/// expr ::= expr |,^,&,! expr 1011/// expr ::= expr ==,!=,<>,<,<=,>,>= expr 1012/// expr ::= expr <<,>> expr 1013/// expr ::= expr +,- expr 1014/// expr ::= expr *,/,% expr -> highest. 1015/// expr ::= primaryexpr 1016/// 1017bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) { 1018 // Parse the expression. 1019 Res = nullptr; 1020 if (parsePrimaryExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc)) 1021 return true; 1022 1023 // As a special case, we support 'a op b @ modifier' by rewriting the 1024 // expression to include the modifier. This is inefficient, but in general we 1025 // expect users to use 'a@modifier op b'. 1026 if (Lexer.getKind() == AsmToken::At) { 1027 Lex(); 1028 1029 if (Lexer.isNot(AsmToken::Identifier)) 1030 return TokError("unexpected symbol modifier following '@'"); 1031 1032 MCSymbolRefExpr::VariantKind Variant = 1033 MCSymbolRefExpr::getVariantKindForName(getTok().getIdentifier()); 1034 if (Variant == MCSymbolRefExpr::VK_Invalid) 1035 return TokError("invalid variant '" + getTok().getIdentifier() + "'"); 1036 1037 const MCExpr *ModifiedRes = applyModifierToExpr(Res, Variant); 1038 if (!ModifiedRes) { 1039 return TokError("invalid modifier '" + getTok().getIdentifier() + 1040 "' (no symbols present)"); 1041 } 1042 1043 Res = ModifiedRes; 1044 Lex(); 1045 } 1046 1047 // Try to constant fold it up front, if possible. 1048 int64_t Value; 1049 if (Res->EvaluateAsAbsolute(Value)) 1050 Res = MCConstantExpr::Create(Value, getContext()); 1051 1052 return false; 1053} 1054 1055bool AsmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) { 1056 Res = nullptr; 1057 return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc); 1058} 1059 1060bool AsmParser::parseAbsoluteExpression(int64_t &Res) { 1061 const MCExpr *Expr; 1062 1063 SMLoc StartLoc = Lexer.getLoc(); 1064 if (parseExpression(Expr)) 1065 return true; 1066 1067 if (!Expr->EvaluateAsAbsolute(Res)) 1068 return Error(StartLoc, "expected absolute expression"); 1069 1070 return false; 1071} 1072 1073static unsigned getBinOpPrecedence(AsmToken::TokenKind K, 1074 MCBinaryExpr::Opcode &Kind) { 1075 switch (K) { 1076 default: 1077 return 0; // not a binop. 1078 1079 // Lowest Precedence: &&, || 1080 case AsmToken::AmpAmp: 1081 Kind = MCBinaryExpr::LAnd; 1082 return 1; 1083 case AsmToken::PipePipe: 1084 Kind = MCBinaryExpr::LOr; 1085 return 1; 1086 1087 // Low Precedence: |, &, ^ 1088 // 1089 // FIXME: gas seems to support '!' as an infix operator? 1090 case AsmToken::Pipe: 1091 Kind = MCBinaryExpr::Or; 1092 return 2; 1093 case AsmToken::Caret: 1094 Kind = MCBinaryExpr::Xor; 1095 return 2; 1096 case AsmToken::Amp: 1097 Kind = MCBinaryExpr::And; 1098 return 2; 1099 1100 // Low Intermediate Precedence: ==, !=, <>, <, <=, >, >= 1101 case AsmToken::EqualEqual: 1102 Kind = MCBinaryExpr::EQ; 1103 return 3; 1104 case AsmToken::ExclaimEqual: 1105 case AsmToken::LessGreater: 1106 Kind = MCBinaryExpr::NE; 1107 return 3; 1108 case AsmToken::Less: 1109 Kind = MCBinaryExpr::LT; 1110 return 3; 1111 case AsmToken::LessEqual: 1112 Kind = MCBinaryExpr::LTE; 1113 return 3; 1114 case AsmToken::Greater: 1115 Kind = MCBinaryExpr::GT; 1116 return 3; 1117 case AsmToken::GreaterEqual: 1118 Kind = MCBinaryExpr::GTE; 1119 return 3; 1120 1121 // Intermediate Precedence: <<, >> 1122 case AsmToken::LessLess: 1123 Kind = MCBinaryExpr::Shl; 1124 return 4; 1125 case AsmToken::GreaterGreater: 1126 Kind = MCBinaryExpr::Shr; 1127 return 4; 1128 1129 // High Intermediate Precedence: +, - 1130 case AsmToken::Plus: 1131 Kind = MCBinaryExpr::Add; 1132 return 5; 1133 case AsmToken::Minus: 1134 Kind = MCBinaryExpr::Sub; 1135 return 5; 1136 1137 // Highest Precedence: *, /, % 1138 case AsmToken::Star: 1139 Kind = MCBinaryExpr::Mul; 1140 return 6; 1141 case AsmToken::Slash: 1142 Kind = MCBinaryExpr::Div; 1143 return 6; 1144 case AsmToken::Percent: 1145 Kind = MCBinaryExpr::Mod; 1146 return 6; 1147 } 1148} 1149 1150/// \brief Parse all binary operators with precedence >= 'Precedence'. 1151/// Res contains the LHS of the expression on input. 1152bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, 1153 SMLoc &EndLoc) { 1154 while (1) { 1155 MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add; 1156 unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind); 1157 1158 // If the next token is lower precedence than we are allowed to eat, return 1159 // successfully with what we ate already. 1160 if (TokPrec < Precedence) 1161 return false; 1162 1163 Lex(); 1164 1165 // Eat the next primary expression. 1166 const MCExpr *RHS; 1167 if (parsePrimaryExpr(RHS, EndLoc)) 1168 return true; 1169 1170 // If BinOp binds less tightly with RHS than the operator after RHS, let 1171 // the pending operator take RHS as its LHS. 1172 MCBinaryExpr::Opcode Dummy; 1173 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy); 1174 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc)) 1175 return true; 1176 1177 // Merge LHS and RHS according to operator. 1178 Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext()); 1179 } 1180} 1181 1182/// ParseStatement: 1183/// ::= EndOfStatement 1184/// ::= Label* Directive ...Operands... EndOfStatement 1185/// ::= Label* Identifier OperandList* EndOfStatement 1186bool AsmParser::parseStatement(ParseStatementInfo &Info) { 1187 if (Lexer.is(AsmToken::EndOfStatement)) { 1188 Out.AddBlankLine(); 1189 Lex(); 1190 return false; 1191 } 1192 1193 // Statements always start with an identifier or are a full line comment. 1194 AsmToken ID = getTok(); 1195 SMLoc IDLoc = ID.getLoc(); 1196 StringRef IDVal; 1197 int64_t LocalLabelVal = -1; 1198 // A full line comment is a '#' as the first token. 1199 if (Lexer.is(AsmToken::Hash)) 1200 return parseCppHashLineFilenameComment(IDLoc); 1201 1202 // Allow an integer followed by a ':' as a directional local label. 1203 if (Lexer.is(AsmToken::Integer)) { 1204 LocalLabelVal = getTok().getIntVal(); 1205 if (LocalLabelVal < 0) { 1206 if (!TheCondState.Ignore) 1207 return TokError("unexpected token at start of statement"); 1208 IDVal = ""; 1209 } else { 1210 IDVal = getTok().getString(); 1211 Lex(); // Consume the integer token to be used as an identifier token. 1212 if (Lexer.getKind() != AsmToken::Colon) { 1213 if (!TheCondState.Ignore) 1214 return TokError("unexpected token at start of statement"); 1215 } 1216 } 1217 } else if (Lexer.is(AsmToken::Dot)) { 1218 // Treat '.' as a valid identifier in this context. 1219 Lex(); 1220 IDVal = "."; 1221 } else if (parseIdentifier(IDVal)) { 1222 if (!TheCondState.Ignore) 1223 return TokError("unexpected token at start of statement"); 1224 IDVal = ""; 1225 } 1226 1227 // Handle conditional assembly here before checking for skipping. We 1228 // have to do this so that .endif isn't skipped in a ".if 0" block for 1229 // example. 1230 StringMap<DirectiveKind>::const_iterator DirKindIt = 1231 DirectiveKindMap.find(IDVal); 1232 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end()) 1233 ? DK_NO_DIRECTIVE 1234 : DirKindIt->getValue(); 1235 switch (DirKind) { 1236 default: 1237 break; 1238 case DK_IF: 1239 case DK_IFNE: 1240 return parseDirectiveIf(IDLoc); 1241 case DK_IFB: 1242 return parseDirectiveIfb(IDLoc, true); 1243 case DK_IFNB: 1244 return parseDirectiveIfb(IDLoc, false); 1245 case DK_IFC: 1246 return parseDirectiveIfc(IDLoc, true); 1247 case DK_IFEQS: 1248 return parseDirectiveIfeqs(IDLoc); 1249 case DK_IFNC: 1250 return parseDirectiveIfc(IDLoc, false); 1251 case DK_IFDEF: 1252 return parseDirectiveIfdef(IDLoc, true); 1253 case DK_IFNDEF: 1254 case DK_IFNOTDEF: 1255 return parseDirectiveIfdef(IDLoc, false); 1256 case DK_ELSEIF: 1257 return parseDirectiveElseIf(IDLoc); 1258 case DK_ELSE: 1259 return parseDirectiveElse(IDLoc); 1260 case DK_ENDIF: 1261 return parseDirectiveEndIf(IDLoc); 1262 } 1263 1264 // Ignore the statement if in the middle of inactive conditional 1265 // (e.g. ".if 0"). 1266 if (TheCondState.Ignore) { 1267 eatToEndOfStatement(); 1268 return false; 1269 } 1270 1271 // FIXME: Recurse on local labels? 1272 1273 // See what kind of statement we have. 1274 switch (Lexer.getKind()) { 1275 case AsmToken::Colon: { 1276 checkForValidSection(); 1277 1278 // identifier ':' -> Label. 1279 Lex(); 1280 1281 // Diagnose attempt to use '.' as a label. 1282 if (IDVal == ".") 1283 return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label"); 1284 1285 // Diagnose attempt to use a variable as a label. 1286 // 1287 // FIXME: Diagnostics. Note the location of the definition as a label. 1288 // FIXME: This doesn't diagnose assignment to a symbol which has been 1289 // implicitly marked as external. 1290 MCSymbol *Sym; 1291 if (LocalLabelVal == -1) 1292 Sym = getContext().GetOrCreateSymbol(IDVal); 1293 else 1294 Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal); 1295 if (!Sym->isUndefined() || Sym->isVariable()) 1296 return Error(IDLoc, "invalid symbol redefinition"); 1297 1298 // Emit the label. 1299 if (!ParsingInlineAsm) 1300 Out.EmitLabel(Sym); 1301 1302 // If we are generating dwarf for assembly source files then gather the 1303 // info to make a dwarf label entry for this label if needed. 1304 if (getContext().getGenDwarfForAssembly()) 1305 MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(), 1306 IDLoc); 1307 1308 getTargetParser().onLabelParsed(Sym); 1309 1310 // Consume any end of statement token, if present, to avoid spurious 1311 // AddBlankLine calls(). 1312 if (Lexer.is(AsmToken::EndOfStatement)) { 1313 Lex(); 1314 if (Lexer.is(AsmToken::Eof)) 1315 return false; 1316 } 1317 1318 return false; 1319 } 1320 1321 case AsmToken::Equal: 1322 // identifier '=' ... -> assignment statement 1323 Lex(); 1324 1325 return parseAssignment(IDVal, true); 1326 1327 default: // Normal instruction or directive. 1328 break; 1329 } 1330 1331 // If macros are enabled, check to see if this is a macro instantiation. 1332 if (areMacrosEnabled()) 1333 if (const MCAsmMacro *M = lookupMacro(IDVal)) { 1334 return handleMacroEntry(M, IDLoc); 1335 } 1336 1337 // Otherwise, we have a normal instruction or directive. 1338 1339 // Directives start with "." 1340 if (IDVal[0] == '.' && IDVal != ".") { 1341 // There are several entities interested in parsing directives: 1342 // 1343 // 1. The target-specific assembly parser. Some directives are target 1344 // specific or may potentially behave differently on certain targets. 1345 // 2. Asm parser extensions. For example, platform-specific parsers 1346 // (like the ELF parser) register themselves as extensions. 1347 // 3. The generic directive parser implemented by this class. These are 1348 // all the directives that behave in a target and platform independent 1349 // manner, or at least have a default behavior that's shared between 1350 // all targets and platforms. 1351 1352 // First query the target-specific parser. It will return 'true' if it 1353 // isn't interested in this directive. 1354 if (!getTargetParser().ParseDirective(ID)) 1355 return false; 1356 1357 // Next, check the extension directive map to see if any extension has 1358 // registered itself to parse this directive. 1359 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler = 1360 ExtensionDirectiveMap.lookup(IDVal); 1361 if (Handler.first) 1362 return (*Handler.second)(Handler.first, IDVal, IDLoc); 1363 1364 // Finally, if no one else is interested in this directive, it must be 1365 // generic and familiar to this class. 1366 switch (DirKind) { 1367 default: 1368 break; 1369 case DK_SET: 1370 case DK_EQU: 1371 return parseDirectiveSet(IDVal, true); 1372 case DK_EQUIV: 1373 return parseDirectiveSet(IDVal, false); 1374 case DK_ASCII: 1375 return parseDirectiveAscii(IDVal, false); 1376 case DK_ASCIZ: 1377 case DK_STRING: 1378 return parseDirectiveAscii(IDVal, true); 1379 case DK_BYTE: 1380 return parseDirectiveValue(1); 1381 case DK_SHORT: 1382 case DK_VALUE: 1383 case DK_2BYTE: 1384 return parseDirectiveValue(2); 1385 case DK_LONG: 1386 case DK_INT: 1387 case DK_4BYTE: 1388 return parseDirectiveValue(4); 1389 case DK_QUAD: 1390 case DK_8BYTE: 1391 return parseDirectiveValue(8); 1392 case DK_OCTA: 1393 return parseDirectiveOctaValue(); 1394 case DK_SINGLE: 1395 case DK_FLOAT: 1396 return parseDirectiveRealValue(APFloat::IEEEsingle); 1397 case DK_DOUBLE: 1398 return parseDirectiveRealValue(APFloat::IEEEdouble); 1399 case DK_ALIGN: { 1400 bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes(); 1401 return parseDirectiveAlign(IsPow2, /*ExprSize=*/1); 1402 } 1403 case DK_ALIGN32: { 1404 bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes(); 1405 return parseDirectiveAlign(IsPow2, /*ExprSize=*/4); 1406 } 1407 case DK_BALIGN: 1408 return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1); 1409 case DK_BALIGNW: 1410 return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2); 1411 case DK_BALIGNL: 1412 return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4); 1413 case DK_P2ALIGN: 1414 return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1); 1415 case DK_P2ALIGNW: 1416 return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2); 1417 case DK_P2ALIGNL: 1418 return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4); 1419 case DK_ORG: 1420 return parseDirectiveOrg(); 1421 case DK_FILL: 1422 return parseDirectiveFill(); 1423 case DK_ZERO: 1424 return parseDirectiveZero(); 1425 case DK_EXTERN: 1426 eatToEndOfStatement(); // .extern is the default, ignore it. 1427 return false; 1428 case DK_GLOBL: 1429 case DK_GLOBAL: 1430 return parseDirectiveSymbolAttribute(MCSA_Global); 1431 case DK_LAZY_REFERENCE: 1432 return parseDirectiveSymbolAttribute(MCSA_LazyReference); 1433 case DK_NO_DEAD_STRIP: 1434 return parseDirectiveSymbolAttribute(MCSA_NoDeadStrip); 1435 case DK_SYMBOL_RESOLVER: 1436 return parseDirectiveSymbolAttribute(MCSA_SymbolResolver); 1437 case DK_PRIVATE_EXTERN: 1438 return parseDirectiveSymbolAttribute(MCSA_PrivateExtern); 1439 case DK_REFERENCE: 1440 return parseDirectiveSymbolAttribute(MCSA_Reference); 1441 case DK_WEAK_DEFINITION: 1442 return parseDirectiveSymbolAttribute(MCSA_WeakDefinition); 1443 case DK_WEAK_REFERENCE: 1444 return parseDirectiveSymbolAttribute(MCSA_WeakReference); 1445 case DK_WEAK_DEF_CAN_BE_HIDDEN: 1446 return parseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate); 1447 case DK_COMM: 1448 case DK_COMMON: 1449 return parseDirectiveComm(/*IsLocal=*/false); 1450 case DK_LCOMM: 1451 return parseDirectiveComm(/*IsLocal=*/true); 1452 case DK_ABORT: 1453 return parseDirectiveAbort(); 1454 case DK_INCLUDE: 1455 return parseDirectiveInclude(); 1456 case DK_INCBIN: 1457 return parseDirectiveIncbin(); 1458 case DK_CODE16: 1459 case DK_CODE16GCC: 1460 return TokError(Twine(IDVal) + " not supported yet"); 1461 case DK_REPT: 1462 return parseDirectiveRept(IDLoc, IDVal); 1463 case DK_IRP: 1464 return parseDirectiveIrp(IDLoc); 1465 case DK_IRPC: 1466 return parseDirectiveIrpc(IDLoc); 1467 case DK_ENDR: 1468 return parseDirectiveEndr(IDLoc); 1469 case DK_BUNDLE_ALIGN_MODE: 1470 return parseDirectiveBundleAlignMode(); 1471 case DK_BUNDLE_LOCK: 1472 return parseDirectiveBundleLock(); 1473 case DK_BUNDLE_UNLOCK: 1474 return parseDirectiveBundleUnlock(); 1475 case DK_SLEB128: 1476 return parseDirectiveLEB128(true); 1477 case DK_ULEB128: 1478 return parseDirectiveLEB128(false); 1479 case DK_SPACE: 1480 case DK_SKIP: 1481 return parseDirectiveSpace(IDVal); 1482 case DK_FILE: 1483 return parseDirectiveFile(IDLoc); 1484 case DK_LINE: 1485 return parseDirectiveLine(); 1486 case DK_LOC: 1487 return parseDirectiveLoc(); 1488 case DK_STABS: 1489 return parseDirectiveStabs(); 1490 case DK_CFI_SECTIONS: 1491 return parseDirectiveCFISections(); 1492 case DK_CFI_STARTPROC: 1493 return parseDirectiveCFIStartProc(); 1494 case DK_CFI_ENDPROC: 1495 return parseDirectiveCFIEndProc(); 1496 case DK_CFI_DEF_CFA: 1497 return parseDirectiveCFIDefCfa(IDLoc); 1498 case DK_CFI_DEF_CFA_OFFSET: 1499 return parseDirectiveCFIDefCfaOffset(); 1500 case DK_CFI_ADJUST_CFA_OFFSET: 1501 return parseDirectiveCFIAdjustCfaOffset(); 1502 case DK_CFI_DEF_CFA_REGISTER: 1503 return parseDirectiveCFIDefCfaRegister(IDLoc); 1504 case DK_CFI_OFFSET: 1505 return parseDirectiveCFIOffset(IDLoc); 1506 case DK_CFI_REL_OFFSET: 1507 return parseDirectiveCFIRelOffset(IDLoc); 1508 case DK_CFI_PERSONALITY: 1509 return parseDirectiveCFIPersonalityOrLsda(true); 1510 case DK_CFI_LSDA: 1511 return parseDirectiveCFIPersonalityOrLsda(false); 1512 case DK_CFI_REMEMBER_STATE: 1513 return parseDirectiveCFIRememberState(); 1514 case DK_CFI_RESTORE_STATE: 1515 return parseDirectiveCFIRestoreState(); 1516 case DK_CFI_SAME_VALUE: 1517 return parseDirectiveCFISameValue(IDLoc); 1518 case DK_CFI_RESTORE: 1519 return parseDirectiveCFIRestore(IDLoc); 1520 case DK_CFI_ESCAPE: 1521 return parseDirectiveCFIEscape(); 1522 case DK_CFI_SIGNAL_FRAME: 1523 return parseDirectiveCFISignalFrame(); 1524 case DK_CFI_UNDEFINED: 1525 return parseDirectiveCFIUndefined(IDLoc); 1526 case DK_CFI_REGISTER: 1527 return parseDirectiveCFIRegister(IDLoc); 1528 case DK_CFI_WINDOW_SAVE: 1529 return parseDirectiveCFIWindowSave(); 1530 case DK_MACROS_ON: 1531 case DK_MACROS_OFF: 1532 return parseDirectiveMacrosOnOff(IDVal); 1533 case DK_MACRO: 1534 return parseDirectiveMacro(IDLoc); 1535 case DK_ENDM: 1536 case DK_ENDMACRO: 1537 return parseDirectiveEndMacro(IDVal); 1538 case DK_PURGEM: 1539 return parseDirectivePurgeMacro(IDLoc); 1540 case DK_END: 1541 return parseDirectiveEnd(IDLoc); 1542 case DK_ERR: 1543 return parseDirectiveError(IDLoc, false); 1544 case DK_ERROR: 1545 return parseDirectiveError(IDLoc, true); 1546 } 1547 1548 return Error(IDLoc, "unknown directive"); 1549 } 1550 1551 // __asm _emit or __asm __emit 1552 if (ParsingInlineAsm && (IDVal == "_emit" || IDVal == "__emit" || 1553 IDVal == "_EMIT" || IDVal == "__EMIT")) 1554 return parseDirectiveMSEmit(IDLoc, Info, IDVal.size()); 1555 1556 // __asm align 1557 if (ParsingInlineAsm && (IDVal == "align" || IDVal == "ALIGN")) 1558 return parseDirectiveMSAlign(IDLoc, Info); 1559 1560 checkForValidSection(); 1561 1562 // Canonicalize the opcode to lower case. 1563 std::string OpcodeStr = IDVal.lower(); 1564 ParseInstructionInfo IInfo(Info.AsmRewrites); 1565 bool HadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, IDLoc, 1566 Info.ParsedOperands); 1567 Info.ParseError = HadError; 1568 1569 // Dump the parsed representation, if requested. 1570 if (getShowParsedOperands()) { 1571 SmallString<256> Str; 1572 raw_svector_ostream OS(Str); 1573 OS << "parsed instruction: ["; 1574 for (unsigned i = 0; i != Info.ParsedOperands.size(); ++i) { 1575 if (i != 0) 1576 OS << ", "; 1577 Info.ParsedOperands[i]->print(OS); 1578 } 1579 OS << "]"; 1580 1581 printMessage(IDLoc, SourceMgr::DK_Note, OS.str()); 1582 } 1583 1584 // If we are generating dwarf for assembly source files and the current 1585 // section is the initial text section then generate a .loc directive for 1586 // the instruction. 1587 if (!HadError && getContext().getGenDwarfForAssembly() && 1588 getContext().getGenDwarfSection() == 1589 getStreamer().getCurrentSection().first) { 1590 1591 unsigned Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer); 1592 1593 // If we previously parsed a cpp hash file line comment then make sure the 1594 // current Dwarf File is for the CppHashFilename if not then emit the 1595 // Dwarf File table for it and adjust the line number for the .loc. 1596 if (CppHashFilename.size() != 0) { 1597 unsigned FileNumber = getStreamer().EmitDwarfFileDirective( 1598 0, StringRef(), CppHashFilename); 1599 getContext().setGenDwarfFileNumber(FileNumber); 1600 1601 // Since SrcMgr.FindLineNumber() is slow and messes up the SourceMgr's 1602 // cache with the different Loc from the call above we save the last 1603 // info we queried here with SrcMgr.FindLineNumber(). 1604 unsigned CppHashLocLineNo; 1605 if (LastQueryIDLoc == CppHashLoc && LastQueryBuffer == CppHashBuf) 1606 CppHashLocLineNo = LastQueryLine; 1607 else { 1608 CppHashLocLineNo = SrcMgr.FindLineNumber(CppHashLoc, CppHashBuf); 1609 LastQueryLine = CppHashLocLineNo; 1610 LastQueryIDLoc = CppHashLoc; 1611 LastQueryBuffer = CppHashBuf; 1612 } 1613 Line = CppHashLineNumber - 1 + (Line - CppHashLocLineNo); 1614 } 1615 1616 getStreamer().EmitDwarfLocDirective( 1617 getContext().getGenDwarfFileNumber(), Line, 0, 1618 DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0, 0, 0, 1619 StringRef()); 1620 } 1621 1622 // If parsing succeeded, match the instruction. 1623 if (!HadError) { 1624 unsigned ErrorInfo; 1625 getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode, 1626 Info.ParsedOperands, Out, 1627 ErrorInfo, ParsingInlineAsm); 1628 } 1629 1630 // Don't skip the rest of the line, the instruction parser is responsible for 1631 // that. 1632 return false; 1633} 1634 1635/// eatToEndOfLine uses the Lexer to eat the characters to the end of the line 1636/// since they may not be able to be tokenized to get to the end of line token. 1637void AsmParser::eatToEndOfLine() { 1638 if (!Lexer.is(AsmToken::EndOfStatement)) 1639 Lexer.LexUntilEndOfLine(); 1640 // Eat EOL. 1641 Lex(); 1642} 1643 1644/// parseCppHashLineFilenameComment as this: 1645/// ::= # number "filename" 1646/// or just as a full line comment if it doesn't have a number and a string. 1647bool AsmParser::parseCppHashLineFilenameComment(const SMLoc &L) { 1648 Lex(); // Eat the hash token. 1649 1650 if (getLexer().isNot(AsmToken::Integer)) { 1651 // Consume the line since in cases it is not a well-formed line directive, 1652 // as if were simply a full line comment. 1653 eatToEndOfLine(); 1654 return false; 1655 } 1656 1657 int64_t LineNumber = getTok().getIntVal(); 1658 Lex(); 1659 1660 if (getLexer().isNot(AsmToken::String)) { 1661 eatToEndOfLine(); 1662 return false; 1663 } 1664 1665 StringRef Filename = getTok().getString(); 1666 // Get rid of the enclosing quotes. 1667 Filename = Filename.substr(1, Filename.size() - 2); 1668 1669 // Save the SMLoc, Filename and LineNumber for later use by diagnostics. 1670 CppHashLoc = L; 1671 CppHashFilename = Filename; 1672 CppHashLineNumber = LineNumber; 1673 CppHashBuf = CurBuffer; 1674 1675 // Ignore any trailing characters, they're just comment. 1676 eatToEndOfLine(); 1677 return false; 1678} 1679 1680/// \brief will use the last parsed cpp hash line filename comment 1681/// for the Filename and LineNo if any in the diagnostic. 1682void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { 1683 const AsmParser *Parser = static_cast<const AsmParser *>(Context); 1684 raw_ostream &OS = errs(); 1685 1686 const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr(); 1687 const SMLoc &DiagLoc = Diag.getLoc(); 1688 int DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); 1689 int CppHashBuf = Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc); 1690 1691 // Like SourceMgr::printMessage() we need to print the include stack if any 1692 // before printing the message. 1693 int DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); 1694 if (!Parser->SavedDiagHandler && DiagCurBuffer > 0) { 1695 SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer); 1696 DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS); 1697 } 1698 1699 // If we have not parsed a cpp hash line filename comment or the source 1700 // manager changed or buffer changed (like in a nested include) then just 1701 // print the normal diagnostic using its Filename and LineNo. 1702 if (!Parser->CppHashLineNumber || &DiagSrcMgr != &Parser->SrcMgr || 1703 DiagBuf != CppHashBuf) { 1704 if (Parser->SavedDiagHandler) 1705 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext); 1706 else 1707 Diag.print(nullptr, OS); 1708 return; 1709 } 1710 1711 // Use the CppHashFilename and calculate a line number based on the 1712 // CppHashLoc and CppHashLineNumber relative to this Diag's SMLoc for 1713 // the diagnostic. 1714 const std::string &Filename = Parser->CppHashFilename; 1715 1716 int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf); 1717 int CppHashLocLineNo = 1718 Parser->SrcMgr.FindLineNumber(Parser->CppHashLoc, CppHashBuf); 1719 int LineNo = 1720 Parser->CppHashLineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo); 1721 1722 SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo, 1723 Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(), 1724 Diag.getLineContents(), Diag.getRanges()); 1725 1726 if (Parser->SavedDiagHandler) 1727 Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext); 1728 else 1729 NewDiag.print(nullptr, OS); 1730} 1731 1732// FIXME: This is mostly duplicated from the function in AsmLexer.cpp. The 1733// difference being that that function accepts '@' as part of identifiers and 1734// we can't do that. AsmLexer.cpp should probably be changed to handle 1735// '@' as a special case when needed. 1736static bool isIdentifierChar(char c) { 1737 return isalnum(static_cast<unsigned char>(c)) || c == '_' || c == '$' || 1738 c == '.'; 1739} 1740 1741bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, 1742 ArrayRef<MCAsmMacroParameter> Parameters, 1743 ArrayRef<MCAsmMacroArgument> A, const SMLoc &L) { 1744 unsigned NParameters = Parameters.size(); 1745 bool HasVararg = NParameters ? Parameters.back().Vararg : false; 1746 if ((!IsDarwin || NParameters != 0) && NParameters != A.size()) 1747 return Error(L, "Wrong number of arguments"); 1748 1749 // A macro without parameters is handled differently on Darwin: 1750 // gas accepts no arguments and does no substitutions 1751 while (!Body.empty()) { 1752 // Scan for the next substitution. 1753 std::size_t End = Body.size(), Pos = 0; 1754 for (; Pos != End; ++Pos) { 1755 // Check for a substitution or escape. 1756 if (IsDarwin && !NParameters) { 1757 // This macro has no parameters, look for $0, $1, etc. 1758 if (Body[Pos] != '$' || Pos + 1 == End) 1759 continue; 1760 1761 char Next = Body[Pos + 1]; 1762 if (Next == '$' || Next == 'n' || 1763 isdigit(static_cast<unsigned char>(Next))) 1764 break; 1765 } else { 1766 // This macro has parameters, look for \foo, \bar, etc. 1767 if (Body[Pos] == '\\' && Pos + 1 != End) 1768 break; 1769 } 1770 } 1771 1772 // Add the prefix. 1773 OS << Body.slice(0, Pos); 1774 1775 // Check if we reached the end. 1776 if (Pos == End) 1777 break; 1778 1779 if (IsDarwin && !NParameters) { 1780 switch (Body[Pos + 1]) { 1781 // $$ => $ 1782 case '$': 1783 OS << '$'; 1784 break; 1785 1786 // $n => number of arguments 1787 case 'n': 1788 OS << A.size(); 1789 break; 1790 1791 // $[0-9] => argument 1792 default: { 1793 // Missing arguments are ignored. 1794 unsigned Index = Body[Pos + 1] - '0'; 1795 if (Index >= A.size()) 1796 break; 1797 1798 // Otherwise substitute with the token values, with spaces eliminated. 1799 for (MCAsmMacroArgument::const_iterator it = A[Index].begin(), 1800 ie = A[Index].end(); 1801 it != ie; ++it) 1802 OS << it->getString(); 1803 break; 1804 } 1805 } 1806 Pos += 2; 1807 } else { 1808 unsigned I = Pos + 1; 1809 while (isIdentifierChar(Body[I]) && I + 1 != End) 1810 ++I; 1811 1812 const char *Begin = Body.data() + Pos + 1; 1813 StringRef Argument(Begin, I - (Pos + 1)); 1814 unsigned Index = 0; 1815 for (; Index < NParameters; ++Index) 1816 if (Parameters[Index].Name == Argument) 1817 break; 1818 1819 if (Index == NParameters) { 1820 if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')') 1821 Pos += 3; 1822 else { 1823 OS << '\\' << Argument; 1824 Pos = I; 1825 } 1826 } else { 1827 bool VarargParameter = HasVararg && Index == (NParameters - 1); 1828 for (MCAsmMacroArgument::const_iterator it = A[Index].begin(), 1829 ie = A[Index].end(); 1830 it != ie; ++it) 1831 // We expect no quotes around the string's contents when 1832 // parsing for varargs. 1833 if (it->getKind() != AsmToken::String || VarargParameter) 1834 OS << it->getString(); 1835 else 1836 OS << it->getStringContents(); 1837 1838 Pos += 1 + Argument.size(); 1839 } 1840 } 1841 // Update the scan point. 1842 Body = Body.substr(Pos); 1843 } 1844 1845 return false; 1846} 1847 1848MacroInstantiation::MacroInstantiation(const MCAsmMacro *M, SMLoc IL, int EB, 1849 SMLoc EL, MemoryBuffer *I) 1850 : TheMacro(M), Instantiation(I), InstantiationLoc(IL), ExitBuffer(EB), 1851 ExitLoc(EL) {} 1852 1853static bool isOperator(AsmToken::TokenKind kind) { 1854 switch (kind) { 1855 default: 1856 return false; 1857 case AsmToken::Plus: 1858 case AsmToken::Minus: 1859 case AsmToken::Tilde: 1860 case AsmToken::Slash: 1861 case AsmToken::Star: 1862 case AsmToken::Dot: 1863 case AsmToken::Equal: 1864 case AsmToken::EqualEqual: 1865 case AsmToken::Pipe: 1866 case AsmToken::PipePipe: 1867 case AsmToken::Caret: 1868 case AsmToken::Amp: 1869 case AsmToken::AmpAmp: 1870 case AsmToken::Exclaim: 1871 case AsmToken::ExclaimEqual: 1872 case AsmToken::Percent: 1873 case AsmToken::Less: 1874 case AsmToken::LessEqual: 1875 case AsmToken::LessLess: 1876 case AsmToken::LessGreater: 1877 case AsmToken::Greater: 1878 case AsmToken::GreaterEqual: 1879 case AsmToken::GreaterGreater: 1880 return true; 1881 } 1882} 1883 1884namespace { 1885class AsmLexerSkipSpaceRAII { 1886public: 1887 AsmLexerSkipSpaceRAII(AsmLexer &Lexer, bool SkipSpace) : Lexer(Lexer) { 1888 Lexer.setSkipSpace(SkipSpace); 1889 } 1890 1891 ~AsmLexerSkipSpaceRAII() { 1892 Lexer.setSkipSpace(true); 1893 } 1894 1895private: 1896 AsmLexer &Lexer; 1897}; 1898} 1899 1900bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg) { 1901 1902 if (Vararg) { 1903 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1904 StringRef Str = parseStringToEndOfStatement(); 1905 MA.push_back(AsmToken(AsmToken::String, Str)); 1906 } 1907 return false; 1908 } 1909 1910 unsigned ParenLevel = 0; 1911 unsigned AddTokens = 0; 1912 1913 // Darwin doesn't use spaces to delmit arguments. 1914 AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin); 1915 1916 for (;;) { 1917 if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal)) 1918 return TokError("unexpected token in macro instantiation"); 1919 1920 if (ParenLevel == 0 && Lexer.is(AsmToken::Comma)) 1921 break; 1922 1923 if (Lexer.is(AsmToken::Space)) { 1924 Lex(); // Eat spaces 1925 1926 // Spaces can delimit parameters, but could also be part an expression. 1927 // If the token after a space is an operator, add the token and the next 1928 // one into this argument 1929 if (!IsDarwin) { 1930 if (isOperator(Lexer.getKind())) { 1931 // Check to see whether the token is used as an operator, 1932 // or part of an identifier 1933 const char *NextChar = getTok().getEndLoc().getPointer(); 1934 if (*NextChar == ' ') 1935 AddTokens = 2; 1936 } 1937 1938 if (!AddTokens && ParenLevel == 0) { 1939 break; 1940 } 1941 } 1942 } 1943 1944 // handleMacroEntry relies on not advancing the lexer here 1945 // to be able to fill in the remaining default parameter values 1946 if (Lexer.is(AsmToken::EndOfStatement)) 1947 break; 1948 1949 // Adjust the current parentheses level. 1950 if (Lexer.is(AsmToken::LParen)) 1951 ++ParenLevel; 1952 else if (Lexer.is(AsmToken::RParen) && ParenLevel) 1953 --ParenLevel; 1954 1955 // Append the token to the current argument list. 1956 MA.push_back(getTok()); 1957 if (AddTokens) 1958 AddTokens--; 1959 Lex(); 1960 } 1961 1962 if (ParenLevel != 0) 1963 return TokError("unbalanced parentheses in macro argument"); 1964 return false; 1965} 1966 1967// Parse the macro instantiation arguments. 1968bool AsmParser::parseMacroArguments(const MCAsmMacro *M, 1969 MCAsmMacroArguments &A) { 1970 const unsigned NParameters = M ? M->Parameters.size() : 0; 1971 bool NamedParametersFound = false; 1972 SmallVector<SMLoc, 4> FALocs; 1973 1974 A.resize(NParameters); 1975 FALocs.resize(NParameters); 1976 1977 // Parse two kinds of macro invocations: 1978 // - macros defined without any parameters accept an arbitrary number of them 1979 // - macros defined with parameters accept at most that many of them 1980 bool HasVararg = NParameters ? M->Parameters.back().Vararg : false; 1981 for (unsigned Parameter = 0; !NParameters || Parameter < NParameters; 1982 ++Parameter) { 1983 SMLoc IDLoc = Lexer.getLoc(); 1984 MCAsmMacroParameter FA; 1985 1986 if (Lexer.is(AsmToken::Identifier) && Lexer.peekTok().is(AsmToken::Equal)) { 1987 if (parseIdentifier(FA.Name)) { 1988 Error(IDLoc, "invalid argument identifier for formal argument"); 1989 eatToEndOfStatement(); 1990 return true; 1991 } 1992 1993 if (!Lexer.is(AsmToken::Equal)) { 1994 TokError("expected '=' after formal parameter identifier"); 1995 eatToEndOfStatement(); 1996 return true; 1997 } 1998 Lex(); 1999 2000 NamedParametersFound = true; 2001 } 2002 2003 if (NamedParametersFound && FA.Name.empty()) { 2004 Error(IDLoc, "cannot mix positional and keyword arguments"); 2005 eatToEndOfStatement(); 2006 return true; 2007 } 2008 2009 bool Vararg = HasVararg && Parameter == (NParameters - 1); 2010 if (parseMacroArgument(FA.Value, Vararg)) 2011 return true; 2012 2013 unsigned PI = Parameter; 2014 if (!FA.Name.empty()) { 2015 unsigned FAI = 0; 2016 for (FAI = 0; FAI < NParameters; ++FAI) 2017 if (M->Parameters[FAI].Name == FA.Name) 2018 break; 2019 2020 if (FAI >= NParameters) { 2021 assert(M && "expected macro to be defined"); 2022 Error(IDLoc, 2023 "parameter named '" + FA.Name + "' does not exist for macro '" + 2024 M->Name + "'"); 2025 return true; 2026 } 2027 PI = FAI; 2028 } 2029 2030 if (!FA.Value.empty()) { 2031 if (A.size() <= PI) 2032 A.resize(PI + 1); 2033 A[PI] = FA.Value; 2034 2035 if (FALocs.size() <= PI) 2036 FALocs.resize(PI + 1); 2037 2038 FALocs[PI] = Lexer.getLoc(); 2039 } 2040 2041 // At the end of the statement, fill in remaining arguments that have 2042 // default values. If there aren't any, then the next argument is 2043 // required but missing 2044 if (Lexer.is(AsmToken::EndOfStatement)) { 2045 bool Failure = false; 2046 for (unsigned FAI = 0; FAI < NParameters; ++FAI) { 2047 if (A[FAI].empty()) { 2048 if (M->Parameters[FAI].Required) { 2049 Error(FALocs[FAI].isValid() ? FALocs[FAI] : Lexer.getLoc(), 2050 "missing value for required parameter " 2051 "'" + M->Parameters[FAI].Name + "' in macro '" + M->Name + "'"); 2052 Failure = true; 2053 } 2054 2055 if (!M->Parameters[FAI].Value.empty()) 2056 A[FAI] = M->Parameters[FAI].Value; 2057 } 2058 } 2059 return Failure; 2060 } 2061 2062 if (Lexer.is(AsmToken::Comma)) 2063 Lex(); 2064 } 2065 2066 return TokError("too many positional arguments"); 2067} 2068 2069const MCAsmMacro *AsmParser::lookupMacro(StringRef Name) { 2070 StringMap<MCAsmMacro *>::iterator I = MacroMap.find(Name); 2071 return (I == MacroMap.end()) ? nullptr : I->getValue(); 2072} 2073 2074void AsmParser::defineMacro(StringRef Name, const MCAsmMacro &Macro) { 2075 MacroMap[Name] = new MCAsmMacro(Macro); 2076} 2077 2078void AsmParser::undefineMacro(StringRef Name) { 2079 StringMap<MCAsmMacro *>::iterator I = MacroMap.find(Name); 2080 if (I != MacroMap.end()) { 2081 delete I->getValue(); 2082 MacroMap.erase(I); 2083 } 2084} 2085 2086bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) { 2087 // Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate 2088 // this, although we should protect against infinite loops. 2089 if (ActiveMacros.size() == 20) 2090 return TokError("macros cannot be nested more than 20 levels deep"); 2091 2092 MCAsmMacroArguments A; 2093 if (parseMacroArguments(M, A)) 2094 return true; 2095 2096 // Macro instantiation is lexical, unfortunately. We construct a new buffer 2097 // to hold the macro body with substitutions. 2098 SmallString<256> Buf; 2099 StringRef Body = M->Body; 2100 raw_svector_ostream OS(Buf); 2101 2102 if (expandMacro(OS, Body, M->Parameters, A, getTok().getLoc())) 2103 return true; 2104 2105 // We include the .endmacro in the buffer as our cue to exit the macro 2106 // instantiation. 2107 OS << ".endmacro\n"; 2108 2109 MemoryBuffer *Instantiation = 2110 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); 2111 2112 // Create the macro instantiation object and add to the current macro 2113 // instantiation stack. 2114 MacroInstantiation *MI = new MacroInstantiation( 2115 M, NameLoc, CurBuffer, getTok().getLoc(), Instantiation); 2116 ActiveMacros.push_back(MI); 2117 2118 // Jump to the macro instantiation and prime the lexer. 2119 CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc()); 2120 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 2121 Lex(); 2122 2123 return false; 2124} 2125 2126void AsmParser::handleMacroExit() { 2127 // Jump to the EndOfStatement we should return to, and consume it. 2128 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer); 2129 Lex(); 2130 2131 // Pop the instantiation entry. 2132 delete ActiveMacros.back(); 2133 ActiveMacros.pop_back(); 2134} 2135 2136static bool isUsedIn(const MCSymbol *Sym, const MCExpr *Value) { 2137 switch (Value->getKind()) { 2138 case MCExpr::Binary: { 2139 const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(Value); 2140 return isUsedIn(Sym, BE->getLHS()) || isUsedIn(Sym, BE->getRHS()); 2141 } 2142 case MCExpr::Target: 2143 case MCExpr::Constant: 2144 return false; 2145 case MCExpr::SymbolRef: { 2146 const MCSymbol &S = 2147 static_cast<const MCSymbolRefExpr *>(Value)->getSymbol(); 2148 if (S.isVariable()) 2149 return isUsedIn(Sym, S.getVariableValue()); 2150 return &S == Sym; 2151 } 2152 case MCExpr::Unary: 2153 return isUsedIn(Sym, static_cast<const MCUnaryExpr *>(Value)->getSubExpr()); 2154 } 2155 2156 llvm_unreachable("Unknown expr kind!"); 2157} 2158 2159bool AsmParser::parseAssignment(StringRef Name, bool allow_redef, 2160 bool NoDeadStrip) { 2161 // FIXME: Use better location, we should use proper tokens. 2162 SMLoc EqualLoc = Lexer.getLoc(); 2163 2164 const MCExpr *Value; 2165 if (parseExpression(Value)) 2166 return true; 2167 2168 // Note: we don't count b as used in "a = b". This is to allow 2169 // a = b 2170 // b = c 2171 2172 if (Lexer.isNot(AsmToken::EndOfStatement)) 2173 return TokError("unexpected token in assignment"); 2174 2175 // Eat the end of statement marker. 2176 Lex(); 2177 2178 // Validate that the LHS is allowed to be a variable (either it has not been 2179 // used as a symbol, or it is an absolute symbol). 2180 MCSymbol *Sym = getContext().LookupSymbol(Name); 2181 if (Sym) { 2182 // Diagnose assignment to a label. 2183 // 2184 // FIXME: Diagnostics. Note the location of the definition as a label. 2185 // FIXME: Diagnose assignment to protected identifier (e.g., register name). 2186 if (isUsedIn(Sym, Value)) 2187 return Error(EqualLoc, "Recursive use of '" + Name + "'"); 2188 else if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable()) 2189 ; // Allow redefinitions of undefined symbols only used in directives. 2190 else if (Sym->isVariable() && !Sym->isUsed() && allow_redef) 2191 ; // Allow redefinitions of variables that haven't yet been used. 2192 else if (!Sym->isUndefined() && (!Sym->isVariable() || !allow_redef)) 2193 return Error(EqualLoc, "redefinition of '" + Name + "'"); 2194 else if (!Sym->isVariable()) 2195 return Error(EqualLoc, "invalid assignment to '" + Name + "'"); 2196 else if (!isa<MCConstantExpr>(Sym->getVariableValue())) 2197 return Error(EqualLoc, "invalid reassignment of non-absolute variable '" + 2198 Name + "'"); 2199 2200 // Don't count these checks as uses. 2201 Sym->setUsed(false); 2202 } else if (Name == ".") { 2203 if (Out.EmitValueToOffset(Value, 0)) { 2204 Error(EqualLoc, "expected absolute expression"); 2205 eatToEndOfStatement(); 2206 } 2207 return false; 2208 } else 2209 Sym = getContext().GetOrCreateSymbol(Name); 2210 2211 // Do the assignment. 2212 Out.EmitAssignment(Sym, Value); 2213 if (NoDeadStrip) 2214 Out.EmitSymbolAttribute(Sym, MCSA_NoDeadStrip); 2215 2216 return false; 2217} 2218 2219/// parseIdentifier: 2220/// ::= identifier 2221/// ::= string 2222bool AsmParser::parseIdentifier(StringRef &Res) { 2223 // The assembler has relaxed rules for accepting identifiers, in particular we 2224 // allow things like '.globl $foo' and '.def @feat.00', which would normally be 2225 // separate tokens. At this level, we have already lexed so we cannot (currently) 2226 // handle this as a context dependent token, instead we detect adjacent tokens 2227 // and return the combined identifier. 2228 if (Lexer.is(AsmToken::Dollar) || Lexer.is(AsmToken::At)) { 2229 SMLoc PrefixLoc = getLexer().getLoc(); 2230 2231 // Consume the prefix character, and check for a following identifier. 2232 Lex(); 2233 if (Lexer.isNot(AsmToken::Identifier)) 2234 return true; 2235 2236 // We have a '$' or '@' followed by an identifier, make sure they are adjacent. 2237 if (PrefixLoc.getPointer() + 1 != getTok().getLoc().getPointer()) 2238 return true; 2239 2240 // Construct the joined identifier and consume the token. 2241 Res = 2242 StringRef(PrefixLoc.getPointer(), getTok().getIdentifier().size() + 1); 2243 Lex(); 2244 return false; 2245 } 2246 2247 if (Lexer.isNot(AsmToken::Identifier) && Lexer.isNot(AsmToken::String)) 2248 return true; 2249 2250 Res = getTok().getIdentifier(); 2251 2252 Lex(); // Consume the identifier token. 2253 2254 return false; 2255} 2256 2257/// parseDirectiveSet: 2258/// ::= .equ identifier ',' expression 2259/// ::= .equiv identifier ',' expression 2260/// ::= .set identifier ',' expression 2261bool AsmParser::parseDirectiveSet(StringRef IDVal, bool allow_redef) { 2262 StringRef Name; 2263 2264 if (parseIdentifier(Name)) 2265 return TokError("expected identifier after '" + Twine(IDVal) + "'"); 2266 2267 if (getLexer().isNot(AsmToken::Comma)) 2268 return TokError("unexpected token in '" + Twine(IDVal) + "'"); 2269 Lex(); 2270 2271 return parseAssignment(Name, allow_redef, true); 2272} 2273 2274bool AsmParser::parseEscapedString(std::string &Data) { 2275 assert(getLexer().is(AsmToken::String) && "Unexpected current token!"); 2276 2277 Data = ""; 2278 StringRef Str = getTok().getStringContents(); 2279 for (unsigned i = 0, e = Str.size(); i != e; ++i) { 2280 if (Str[i] != '\\') { 2281 Data += Str[i]; 2282 continue; 2283 } 2284 2285 // Recognize escaped characters. Note that this escape semantics currently 2286 // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes. 2287 ++i; 2288 if (i == e) 2289 return TokError("unexpected backslash at end of string"); 2290 2291 // Recognize octal sequences. 2292 if ((unsigned)(Str[i] - '0') <= 7) { 2293 // Consume up to three octal characters. 2294 unsigned Value = Str[i] - '0'; 2295 2296 if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) { 2297 ++i; 2298 Value = Value * 8 + (Str[i] - '0'); 2299 2300 if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) { 2301 ++i; 2302 Value = Value * 8 + (Str[i] - '0'); 2303 } 2304 } 2305 2306 if (Value > 255) 2307 return TokError("invalid octal escape sequence (out of range)"); 2308 2309 Data += (unsigned char)Value; 2310 continue; 2311 } 2312 2313 // Otherwise recognize individual escapes. 2314 switch (Str[i]) { 2315 default: 2316 // Just reject invalid escape sequences for now. 2317 return TokError("invalid escape sequence (unrecognized character)"); 2318 2319 case 'b': Data += '\b'; break; 2320 case 'f': Data += '\f'; break; 2321 case 'n': Data += '\n'; break; 2322 case 'r': Data += '\r'; break; 2323 case 't': Data += '\t'; break; 2324 case '"': Data += '"'; break; 2325 case '\\': Data += '\\'; break; 2326 } 2327 } 2328 2329 return false; 2330} 2331 2332/// parseDirectiveAscii: 2333/// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ] 2334bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) { 2335 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2336 checkForValidSection(); 2337 2338 for (;;) { 2339 if (getLexer().isNot(AsmToken::String)) 2340 return TokError("expected string in '" + Twine(IDVal) + "' directive"); 2341 2342 std::string Data; 2343 if (parseEscapedString(Data)) 2344 return true; 2345 2346 getStreamer().EmitBytes(Data); 2347 if (ZeroTerminated) 2348 getStreamer().EmitBytes(StringRef("\0", 1)); 2349 2350 Lex(); 2351 2352 if (getLexer().is(AsmToken::EndOfStatement)) 2353 break; 2354 2355 if (getLexer().isNot(AsmToken::Comma)) 2356 return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); 2357 Lex(); 2358 } 2359 } 2360 2361 Lex(); 2362 return false; 2363} 2364 2365/// parseDirectiveValue 2366/// ::= (.byte | .short | ... ) [ expression (, expression)* ] 2367bool AsmParser::parseDirectiveValue(unsigned Size) { 2368 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2369 checkForValidSection(); 2370 2371 for (;;) { 2372 const MCExpr *Value; 2373 SMLoc ExprLoc = getLexer().getLoc(); 2374 if (parseExpression(Value)) 2375 return true; 2376 2377 // Special case constant expressions to match code generator. 2378 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 2379 assert(Size <= 8 && "Invalid size"); 2380 uint64_t IntValue = MCE->getValue(); 2381 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue)) 2382 return Error(ExprLoc, "literal value out of range for directive"); 2383 getStreamer().EmitIntValue(IntValue, Size); 2384 } else 2385 getStreamer().EmitValue(Value, Size, ExprLoc); 2386 2387 if (getLexer().is(AsmToken::EndOfStatement)) 2388 break; 2389 2390 // FIXME: Improve diagnostic. 2391 if (getLexer().isNot(AsmToken::Comma)) 2392 return TokError("unexpected token in directive"); 2393 Lex(); 2394 } 2395 } 2396 2397 Lex(); 2398 return false; 2399} 2400 2401/// ParseDirectiveOctaValue 2402/// ::= .octa [ hexconstant (, hexconstant)* ] 2403bool AsmParser::parseDirectiveOctaValue() { 2404 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2405 checkForValidSection(); 2406 2407 for (;;) { 2408 if (Lexer.getKind() == AsmToken::Error) 2409 return true; 2410 if (Lexer.getKind() != AsmToken::Integer && 2411 Lexer.getKind() != AsmToken::BigNum) 2412 return TokError("unknown token in expression"); 2413 2414 SMLoc ExprLoc = getLexer().getLoc(); 2415 APInt IntValue = getTok().getAPIntVal(); 2416 Lex(); 2417 2418 uint64_t hi, lo; 2419 if (IntValue.isIntN(64)) { 2420 hi = 0; 2421 lo = IntValue.getZExtValue(); 2422 } else if (IntValue.isIntN(128)) { 2423 // It might actually have more than 128 bits, but the top ones are zero. 2424 hi = IntValue.getHiBits(IntValue.getBitWidth() - 64).getZExtValue(); 2425 lo = IntValue.getLoBits(64).getZExtValue(); 2426 } else 2427 return Error(ExprLoc, "literal value out of range for directive"); 2428 2429 if (MAI.isLittleEndian()) { 2430 getStreamer().EmitIntValue(lo, 8); 2431 getStreamer().EmitIntValue(hi, 8); 2432 } else { 2433 getStreamer().EmitIntValue(hi, 8); 2434 getStreamer().EmitIntValue(lo, 8); 2435 } 2436 2437 if (getLexer().is(AsmToken::EndOfStatement)) 2438 break; 2439 2440 // FIXME: Improve diagnostic. 2441 if (getLexer().isNot(AsmToken::Comma)) 2442 return TokError("unexpected token in directive"); 2443 Lex(); 2444 } 2445 } 2446 2447 Lex(); 2448 return false; 2449} 2450 2451/// parseDirectiveRealValue 2452/// ::= (.single | .double) [ expression (, expression)* ] 2453bool AsmParser::parseDirectiveRealValue(const fltSemantics &Semantics) { 2454 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2455 checkForValidSection(); 2456 2457 for (;;) { 2458 // We don't truly support arithmetic on floating point expressions, so we 2459 // have to manually parse unary prefixes. 2460 bool IsNeg = false; 2461 if (getLexer().is(AsmToken::Minus)) { 2462 Lex(); 2463 IsNeg = true; 2464 } else if (getLexer().is(AsmToken::Plus)) 2465 Lex(); 2466 2467 if (getLexer().isNot(AsmToken::Integer) && 2468 getLexer().isNot(AsmToken::Real) && 2469 getLexer().isNot(AsmToken::Identifier)) 2470 return TokError("unexpected token in directive"); 2471 2472 // Convert to an APFloat. 2473 APFloat Value(Semantics); 2474 StringRef IDVal = getTok().getString(); 2475 if (getLexer().is(AsmToken::Identifier)) { 2476 if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf")) 2477 Value = APFloat::getInf(Semantics); 2478 else if (!IDVal.compare_lower("nan")) 2479 Value = APFloat::getNaN(Semantics, false, ~0); 2480 else 2481 return TokError("invalid floating point literal"); 2482 } else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) == 2483 APFloat::opInvalidOp) 2484 return TokError("invalid floating point literal"); 2485 if (IsNeg) 2486 Value.changeSign(); 2487 2488 // Consume the numeric token. 2489 Lex(); 2490 2491 // Emit the value as an integer. 2492 APInt AsInt = Value.bitcastToAPInt(); 2493 getStreamer().EmitIntValue(AsInt.getLimitedValue(), 2494 AsInt.getBitWidth() / 8); 2495 2496 if (getLexer().is(AsmToken::EndOfStatement)) 2497 break; 2498 2499 if (getLexer().isNot(AsmToken::Comma)) 2500 return TokError("unexpected token in directive"); 2501 Lex(); 2502 } 2503 } 2504 2505 Lex(); 2506 return false; 2507} 2508 2509/// parseDirectiveZero 2510/// ::= .zero expression 2511bool AsmParser::parseDirectiveZero() { 2512 checkForValidSection(); 2513 2514 int64_t NumBytes; 2515 if (parseAbsoluteExpression(NumBytes)) 2516 return true; 2517 2518 int64_t Val = 0; 2519 if (getLexer().is(AsmToken::Comma)) { 2520 Lex(); 2521 if (parseAbsoluteExpression(Val)) 2522 return true; 2523 } 2524 2525 if (getLexer().isNot(AsmToken::EndOfStatement)) 2526 return TokError("unexpected token in '.zero' directive"); 2527 2528 Lex(); 2529 2530 getStreamer().EmitFill(NumBytes, Val); 2531 2532 return false; 2533} 2534 2535/// parseDirectiveFill 2536/// ::= .fill expression [ , expression [ , expression ] ] 2537bool AsmParser::parseDirectiveFill() { 2538 checkForValidSection(); 2539 2540 SMLoc RepeatLoc = getLexer().getLoc(); 2541 int64_t NumValues; 2542 if (parseAbsoluteExpression(NumValues)) 2543 return true; 2544 2545 if (NumValues < 0) { 2546 Warning(RepeatLoc, 2547 "'.fill' directive with negative repeat count has no effect"); 2548 NumValues = 0; 2549 } 2550 2551 int64_t FillSize = 1; 2552 int64_t FillExpr = 0; 2553 2554 SMLoc SizeLoc, ExprLoc; 2555 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2556 if (getLexer().isNot(AsmToken::Comma)) 2557 return TokError("unexpected token in '.fill' directive"); 2558 Lex(); 2559 2560 SizeLoc = getLexer().getLoc(); 2561 if (parseAbsoluteExpression(FillSize)) 2562 return true; 2563 2564 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2565 if (getLexer().isNot(AsmToken::Comma)) 2566 return TokError("unexpected token in '.fill' directive"); 2567 Lex(); 2568 2569 ExprLoc = getLexer().getLoc(); 2570 if (parseAbsoluteExpression(FillExpr)) 2571 return true; 2572 2573 if (getLexer().isNot(AsmToken::EndOfStatement)) 2574 return TokError("unexpected token in '.fill' directive"); 2575 2576 Lex(); 2577 } 2578 } 2579 2580 if (FillSize < 0) { 2581 Warning(SizeLoc, "'.fill' directive with negative size has no effect"); 2582 NumValues = 0; 2583 } 2584 if (FillSize > 8) { 2585 Warning(SizeLoc, "'.fill' directive with size greater than 8 has been truncated to 8"); 2586 FillSize = 8; 2587 } 2588 2589 if (!isUInt<32>(FillExpr) && FillSize > 4) 2590 Warning(ExprLoc, "'.fill' directive pattern has been truncated to 32-bits"); 2591 2592 int64_t NonZeroFillSize = FillSize > 4 ? 4 : FillSize; 2593 FillExpr &= ~0ULL >> (64 - NonZeroFillSize * 8); 2594 2595 for (uint64_t i = 0, e = NumValues; i != e; ++i) { 2596 getStreamer().EmitIntValue(FillExpr, NonZeroFillSize); 2597 getStreamer().EmitIntValue(0, FillSize - NonZeroFillSize); 2598 } 2599 2600 return false; 2601} 2602 2603/// parseDirectiveOrg 2604/// ::= .org expression [ , expression ] 2605bool AsmParser::parseDirectiveOrg() { 2606 checkForValidSection(); 2607 2608 const MCExpr *Offset; 2609 SMLoc Loc = getTok().getLoc(); 2610 if (parseExpression(Offset)) 2611 return true; 2612 2613 // Parse optional fill expression. 2614 int64_t FillExpr = 0; 2615 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2616 if (getLexer().isNot(AsmToken::Comma)) 2617 return TokError("unexpected token in '.org' directive"); 2618 Lex(); 2619 2620 if (parseAbsoluteExpression(FillExpr)) 2621 return true; 2622 2623 if (getLexer().isNot(AsmToken::EndOfStatement)) 2624 return TokError("unexpected token in '.org' directive"); 2625 } 2626 2627 Lex(); 2628 2629 // Only limited forms of relocatable expressions are accepted here, it 2630 // has to be relative to the current section. The streamer will return 2631 // 'true' if the expression wasn't evaluatable. 2632 if (getStreamer().EmitValueToOffset(Offset, FillExpr)) 2633 return Error(Loc, "expected assembly-time absolute expression"); 2634 2635 return false; 2636} 2637 2638/// parseDirectiveAlign 2639/// ::= {.align, ...} expression [ , expression [ , expression ]] 2640bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) { 2641 checkForValidSection(); 2642 2643 SMLoc AlignmentLoc = getLexer().getLoc(); 2644 int64_t Alignment; 2645 if (parseAbsoluteExpression(Alignment)) 2646 return true; 2647 2648 SMLoc MaxBytesLoc; 2649 bool HasFillExpr = false; 2650 int64_t FillExpr = 0; 2651 int64_t MaxBytesToFill = 0; 2652 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2653 if (getLexer().isNot(AsmToken::Comma)) 2654 return TokError("unexpected token in directive"); 2655 Lex(); 2656 2657 // The fill expression can be omitted while specifying a maximum number of 2658 // alignment bytes, e.g: 2659 // .align 3,,4 2660 if (getLexer().isNot(AsmToken::Comma)) { 2661 HasFillExpr = true; 2662 if (parseAbsoluteExpression(FillExpr)) 2663 return true; 2664 } 2665 2666 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2667 if (getLexer().isNot(AsmToken::Comma)) 2668 return TokError("unexpected token in directive"); 2669 Lex(); 2670 2671 MaxBytesLoc = getLexer().getLoc(); 2672 if (parseAbsoluteExpression(MaxBytesToFill)) 2673 return true; 2674 2675 if (getLexer().isNot(AsmToken::EndOfStatement)) 2676 return TokError("unexpected token in directive"); 2677 } 2678 } 2679 2680 Lex(); 2681 2682 if (!HasFillExpr) 2683 FillExpr = 0; 2684 2685 // Compute alignment in bytes. 2686 if (IsPow2) { 2687 // FIXME: Diagnose overflow. 2688 if (Alignment >= 32) { 2689 Error(AlignmentLoc, "invalid alignment value"); 2690 Alignment = 31; 2691 } 2692 2693 Alignment = 1ULL << Alignment; 2694 } else { 2695 // Reject alignments that aren't a power of two, for gas compatibility. 2696 if (!isPowerOf2_64(Alignment)) 2697 Error(AlignmentLoc, "alignment must be a power of 2"); 2698 } 2699 2700 // Diagnose non-sensical max bytes to align. 2701 if (MaxBytesLoc.isValid()) { 2702 if (MaxBytesToFill < 1) { 2703 Error(MaxBytesLoc, "alignment directive can never be satisfied in this " 2704 "many bytes, ignoring maximum bytes expression"); 2705 MaxBytesToFill = 0; 2706 } 2707 2708 if (MaxBytesToFill >= Alignment) { 2709 Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and " 2710 "has no effect"); 2711 MaxBytesToFill = 0; 2712 } 2713 } 2714 2715 // Check whether we should use optimal code alignment for this .align 2716 // directive. 2717 const MCSection *Section = getStreamer().getCurrentSection().first; 2718 assert(Section && "must have section to emit alignment"); 2719 bool UseCodeAlign = Section->UseCodeAlign(); 2720 if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) && 2721 ValueSize == 1 && UseCodeAlign) { 2722 getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill); 2723 } else { 2724 // FIXME: Target specific behavior about how the "extra" bytes are filled. 2725 getStreamer().EmitValueToAlignment(Alignment, FillExpr, ValueSize, 2726 MaxBytesToFill); 2727 } 2728 2729 return false; 2730} 2731 2732/// parseDirectiveFile 2733/// ::= .file [number] filename 2734/// ::= .file number directory filename 2735bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { 2736 // FIXME: I'm not sure what this is. 2737 int64_t FileNumber = -1; 2738 SMLoc FileNumberLoc = getLexer().getLoc(); 2739 if (getLexer().is(AsmToken::Integer)) { 2740 FileNumber = getTok().getIntVal(); 2741 Lex(); 2742 2743 if (FileNumber < 1) 2744 return TokError("file number less than one"); 2745 } 2746 2747 if (getLexer().isNot(AsmToken::String)) 2748 return TokError("unexpected token in '.file' directive"); 2749 2750 // Usually the directory and filename together, otherwise just the directory. 2751 // Allow the strings to have escaped octal character sequence. 2752 std::string Path = getTok().getString(); 2753 if (parseEscapedString(Path)) 2754 return true; 2755 Lex(); 2756 2757 StringRef Directory; 2758 StringRef Filename; 2759 std::string FilenameData; 2760 if (getLexer().is(AsmToken::String)) { 2761 if (FileNumber == -1) 2762 return TokError("explicit path specified, but no file number"); 2763 if (parseEscapedString(FilenameData)) 2764 return true; 2765 Filename = FilenameData; 2766 Directory = Path; 2767 Lex(); 2768 } else { 2769 Filename = Path; 2770 } 2771 2772 if (getLexer().isNot(AsmToken::EndOfStatement)) 2773 return TokError("unexpected token in '.file' directive"); 2774 2775 if (FileNumber == -1) 2776 getStreamer().EmitFileDirective(Filename); 2777 else { 2778 if (getContext().getGenDwarfForAssembly() == true) 2779 Error(DirectiveLoc, 2780 "input can't have .file dwarf directives when -g is " 2781 "used to generate dwarf debug info for assembly code"); 2782 2783 if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename) == 2784 0) 2785 Error(FileNumberLoc, "file number already allocated"); 2786 } 2787 2788 return false; 2789} 2790 2791/// parseDirectiveLine 2792/// ::= .line [number] 2793bool AsmParser::parseDirectiveLine() { 2794 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2795 if (getLexer().isNot(AsmToken::Integer)) 2796 return TokError("unexpected token in '.line' directive"); 2797 2798 int64_t LineNumber = getTok().getIntVal(); 2799 (void)LineNumber; 2800 Lex(); 2801 2802 // FIXME: Do something with the .line. 2803 } 2804 2805 if (getLexer().isNot(AsmToken::EndOfStatement)) 2806 return TokError("unexpected token in '.line' directive"); 2807 2808 return false; 2809} 2810 2811/// parseDirectiveLoc 2812/// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end] 2813/// [epilogue_begin] [is_stmt VALUE] [isa VALUE] 2814/// The first number is a file number, must have been previously assigned with 2815/// a .file directive, the second number is the line number and optionally the 2816/// third number is a column position (zero if not specified). The remaining 2817/// optional items are .loc sub-directives. 2818bool AsmParser::parseDirectiveLoc() { 2819 if (getLexer().isNot(AsmToken::Integer)) 2820 return TokError("unexpected token in '.loc' directive"); 2821 int64_t FileNumber = getTok().getIntVal(); 2822 if (FileNumber < 1) 2823 return TokError("file number less than one in '.loc' directive"); 2824 if (!getContext().isValidDwarfFileNumber(FileNumber)) 2825 return TokError("unassigned file number in '.loc' directive"); 2826 Lex(); 2827 2828 int64_t LineNumber = 0; 2829 if (getLexer().is(AsmToken::Integer)) { 2830 LineNumber = getTok().getIntVal(); 2831 if (LineNumber < 0) 2832 return TokError("line number less than zero in '.loc' directive"); 2833 Lex(); 2834 } 2835 2836 int64_t ColumnPos = 0; 2837 if (getLexer().is(AsmToken::Integer)) { 2838 ColumnPos = getTok().getIntVal(); 2839 if (ColumnPos < 0) 2840 return TokError("column position less than zero in '.loc' directive"); 2841 Lex(); 2842 } 2843 2844 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 2845 unsigned Isa = 0; 2846 int64_t Discriminator = 0; 2847 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2848 for (;;) { 2849 if (getLexer().is(AsmToken::EndOfStatement)) 2850 break; 2851 2852 StringRef Name; 2853 SMLoc Loc = getTok().getLoc(); 2854 if (parseIdentifier(Name)) 2855 return TokError("unexpected token in '.loc' directive"); 2856 2857 if (Name == "basic_block") 2858 Flags |= DWARF2_FLAG_BASIC_BLOCK; 2859 else if (Name == "prologue_end") 2860 Flags |= DWARF2_FLAG_PROLOGUE_END; 2861 else if (Name == "epilogue_begin") 2862 Flags |= DWARF2_FLAG_EPILOGUE_BEGIN; 2863 else if (Name == "is_stmt") { 2864 Loc = getTok().getLoc(); 2865 const MCExpr *Value; 2866 if (parseExpression(Value)) 2867 return true; 2868 // The expression must be the constant 0 or 1. 2869 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 2870 int Value = MCE->getValue(); 2871 if (Value == 0) 2872 Flags &= ~DWARF2_FLAG_IS_STMT; 2873 else if (Value == 1) 2874 Flags |= DWARF2_FLAG_IS_STMT; 2875 else 2876 return Error(Loc, "is_stmt value not 0 or 1"); 2877 } else { 2878 return Error(Loc, "is_stmt value not the constant value of 0 or 1"); 2879 } 2880 } else if (Name == "isa") { 2881 Loc = getTok().getLoc(); 2882 const MCExpr *Value; 2883 if (parseExpression(Value)) 2884 return true; 2885 // The expression must be a constant greater or equal to 0. 2886 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 2887 int Value = MCE->getValue(); 2888 if (Value < 0) 2889 return Error(Loc, "isa number less than zero"); 2890 Isa = Value; 2891 } else { 2892 return Error(Loc, "isa number not a constant value"); 2893 } 2894 } else if (Name == "discriminator") { 2895 if (parseAbsoluteExpression(Discriminator)) 2896 return true; 2897 } else { 2898 return Error(Loc, "unknown sub-directive in '.loc' directive"); 2899 } 2900 2901 if (getLexer().is(AsmToken::EndOfStatement)) 2902 break; 2903 } 2904 } 2905 2906 getStreamer().EmitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags, 2907 Isa, Discriminator, StringRef()); 2908 2909 return false; 2910} 2911 2912/// parseDirectiveStabs 2913/// ::= .stabs string, number, number, number 2914bool AsmParser::parseDirectiveStabs() { 2915 return TokError("unsupported directive '.stabs'"); 2916} 2917 2918/// parseDirectiveCFISections 2919/// ::= .cfi_sections section [, section] 2920bool AsmParser::parseDirectiveCFISections() { 2921 StringRef Name; 2922 bool EH = false; 2923 bool Debug = false; 2924 2925 if (parseIdentifier(Name)) 2926 return TokError("Expected an identifier"); 2927 2928 if (Name == ".eh_frame") 2929 EH = true; 2930 else if (Name == ".debug_frame") 2931 Debug = true; 2932 2933 if (getLexer().is(AsmToken::Comma)) { 2934 Lex(); 2935 2936 if (parseIdentifier(Name)) 2937 return TokError("Expected an identifier"); 2938 2939 if (Name == ".eh_frame") 2940 EH = true; 2941 else if (Name == ".debug_frame") 2942 Debug = true; 2943 } 2944 2945 getStreamer().EmitCFISections(EH, Debug); 2946 return false; 2947} 2948 2949/// parseDirectiveCFIStartProc 2950/// ::= .cfi_startproc [simple] 2951bool AsmParser::parseDirectiveCFIStartProc() { 2952 StringRef Simple; 2953 if (getLexer().isNot(AsmToken::EndOfStatement)) 2954 if (parseIdentifier(Simple) || Simple != "simple") 2955 return TokError("unexpected token in .cfi_startproc directive"); 2956 2957 getStreamer().EmitCFIStartProc(!Simple.empty()); 2958 return false; 2959} 2960 2961/// parseDirectiveCFIEndProc 2962/// ::= .cfi_endproc 2963bool AsmParser::parseDirectiveCFIEndProc() { 2964 getStreamer().EmitCFIEndProc(); 2965 return false; 2966} 2967 2968/// \brief parse register name or number. 2969bool AsmParser::parseRegisterOrRegisterNumber(int64_t &Register, 2970 SMLoc DirectiveLoc) { 2971 unsigned RegNo; 2972 2973 if (getLexer().isNot(AsmToken::Integer)) { 2974 if (getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc)) 2975 return true; 2976 Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true); 2977 } else 2978 return parseAbsoluteExpression(Register); 2979 2980 return false; 2981} 2982 2983/// parseDirectiveCFIDefCfa 2984/// ::= .cfi_def_cfa register, offset 2985bool AsmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) { 2986 int64_t Register = 0; 2987 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 2988 return true; 2989 2990 if (getLexer().isNot(AsmToken::Comma)) 2991 return TokError("unexpected token in directive"); 2992 Lex(); 2993 2994 int64_t Offset = 0; 2995 if (parseAbsoluteExpression(Offset)) 2996 return true; 2997 2998 getStreamer().EmitCFIDefCfa(Register, Offset); 2999 return false; 3000} 3001 3002/// parseDirectiveCFIDefCfaOffset 3003/// ::= .cfi_def_cfa_offset offset 3004bool AsmParser::parseDirectiveCFIDefCfaOffset() { 3005 int64_t Offset = 0; 3006 if (parseAbsoluteExpression(Offset)) 3007 return true; 3008 3009 getStreamer().EmitCFIDefCfaOffset(Offset); 3010 return false; 3011} 3012 3013/// parseDirectiveCFIRegister 3014/// ::= .cfi_register register, register 3015bool AsmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) { 3016 int64_t Register1 = 0; 3017 if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc)) 3018 return true; 3019 3020 if (getLexer().isNot(AsmToken::Comma)) 3021 return TokError("unexpected token in directive"); 3022 Lex(); 3023 3024 int64_t Register2 = 0; 3025 if (parseRegisterOrRegisterNumber(Register2, DirectiveLoc)) 3026 return true; 3027 3028 getStreamer().EmitCFIRegister(Register1, Register2); 3029 return false; 3030} 3031 3032/// parseDirectiveCFIWindowSave 3033/// ::= .cfi_window_save 3034bool AsmParser::parseDirectiveCFIWindowSave() { 3035 getStreamer().EmitCFIWindowSave(); 3036 return false; 3037} 3038 3039/// parseDirectiveCFIAdjustCfaOffset 3040/// ::= .cfi_adjust_cfa_offset adjustment 3041bool AsmParser::parseDirectiveCFIAdjustCfaOffset() { 3042 int64_t Adjustment = 0; 3043 if (parseAbsoluteExpression(Adjustment)) 3044 return true; 3045 3046 getStreamer().EmitCFIAdjustCfaOffset(Adjustment); 3047 return false; 3048} 3049 3050/// parseDirectiveCFIDefCfaRegister 3051/// ::= .cfi_def_cfa_register register 3052bool AsmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) { 3053 int64_t Register = 0; 3054 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3055 return true; 3056 3057 getStreamer().EmitCFIDefCfaRegister(Register); 3058 return false; 3059} 3060 3061/// parseDirectiveCFIOffset 3062/// ::= .cfi_offset register, offset 3063bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) { 3064 int64_t Register = 0; 3065 int64_t Offset = 0; 3066 3067 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3068 return true; 3069 3070 if (getLexer().isNot(AsmToken::Comma)) 3071 return TokError("unexpected token in directive"); 3072 Lex(); 3073 3074 if (parseAbsoluteExpression(Offset)) 3075 return true; 3076 3077 getStreamer().EmitCFIOffset(Register, Offset); 3078 return false; 3079} 3080 3081/// parseDirectiveCFIRelOffset 3082/// ::= .cfi_rel_offset register, offset 3083bool AsmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) { 3084 int64_t Register = 0; 3085 3086 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3087 return true; 3088 3089 if (getLexer().isNot(AsmToken::Comma)) 3090 return TokError("unexpected token in directive"); 3091 Lex(); 3092 3093 int64_t Offset = 0; 3094 if (parseAbsoluteExpression(Offset)) 3095 return true; 3096 3097 getStreamer().EmitCFIRelOffset(Register, Offset); 3098 return false; 3099} 3100 3101static bool isValidEncoding(int64_t Encoding) { 3102 if (Encoding & ~0xff) 3103 return false; 3104 3105 if (Encoding == dwarf::DW_EH_PE_omit) 3106 return true; 3107 3108 const unsigned Format = Encoding & 0xf; 3109 if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 && 3110 Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 && 3111 Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 && 3112 Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed) 3113 return false; 3114 3115 const unsigned Application = Encoding & 0x70; 3116 if (Application != dwarf::DW_EH_PE_absptr && 3117 Application != dwarf::DW_EH_PE_pcrel) 3118 return false; 3119 3120 return true; 3121} 3122 3123/// parseDirectiveCFIPersonalityOrLsda 3124/// IsPersonality true for cfi_personality, false for cfi_lsda 3125/// ::= .cfi_personality encoding, [symbol_name] 3126/// ::= .cfi_lsda encoding, [symbol_name] 3127bool AsmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) { 3128 int64_t Encoding = 0; 3129 if (parseAbsoluteExpression(Encoding)) 3130 return true; 3131 if (Encoding == dwarf::DW_EH_PE_omit) 3132 return false; 3133 3134 if (!isValidEncoding(Encoding)) 3135 return TokError("unsupported encoding."); 3136 3137 if (getLexer().isNot(AsmToken::Comma)) 3138 return TokError("unexpected token in directive"); 3139 Lex(); 3140 3141 StringRef Name; 3142 if (parseIdentifier(Name)) 3143 return TokError("expected identifier in directive"); 3144 3145 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 3146 3147 if (IsPersonality) 3148 getStreamer().EmitCFIPersonality(Sym, Encoding); 3149 else 3150 getStreamer().EmitCFILsda(Sym, Encoding); 3151 return false; 3152} 3153 3154/// parseDirectiveCFIRememberState 3155/// ::= .cfi_remember_state 3156bool AsmParser::parseDirectiveCFIRememberState() { 3157 getStreamer().EmitCFIRememberState(); 3158 return false; 3159} 3160 3161/// parseDirectiveCFIRestoreState 3162/// ::= .cfi_remember_state 3163bool AsmParser::parseDirectiveCFIRestoreState() { 3164 getStreamer().EmitCFIRestoreState(); 3165 return false; 3166} 3167 3168/// parseDirectiveCFISameValue 3169/// ::= .cfi_same_value register 3170bool AsmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) { 3171 int64_t Register = 0; 3172 3173 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3174 return true; 3175 3176 getStreamer().EmitCFISameValue(Register); 3177 return false; 3178} 3179 3180/// parseDirectiveCFIRestore 3181/// ::= .cfi_restore register 3182bool AsmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) { 3183 int64_t Register = 0; 3184 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3185 return true; 3186 3187 getStreamer().EmitCFIRestore(Register); 3188 return false; 3189} 3190 3191/// parseDirectiveCFIEscape 3192/// ::= .cfi_escape expression[,...] 3193bool AsmParser::parseDirectiveCFIEscape() { 3194 std::string Values; 3195 int64_t CurrValue; 3196 if (parseAbsoluteExpression(CurrValue)) 3197 return true; 3198 3199 Values.push_back((uint8_t)CurrValue); 3200 3201 while (getLexer().is(AsmToken::Comma)) { 3202 Lex(); 3203 3204 if (parseAbsoluteExpression(CurrValue)) 3205 return true; 3206 3207 Values.push_back((uint8_t)CurrValue); 3208 } 3209 3210 getStreamer().EmitCFIEscape(Values); 3211 return false; 3212} 3213 3214/// parseDirectiveCFISignalFrame 3215/// ::= .cfi_signal_frame 3216bool AsmParser::parseDirectiveCFISignalFrame() { 3217 if (getLexer().isNot(AsmToken::EndOfStatement)) 3218 return Error(getLexer().getLoc(), 3219 "unexpected token in '.cfi_signal_frame'"); 3220 3221 getStreamer().EmitCFISignalFrame(); 3222 return false; 3223} 3224 3225/// parseDirectiveCFIUndefined 3226/// ::= .cfi_undefined register 3227bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) { 3228 int64_t Register = 0; 3229 3230 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3231 return true; 3232 3233 getStreamer().EmitCFIUndefined(Register); 3234 return false; 3235} 3236 3237/// parseDirectiveMacrosOnOff 3238/// ::= .macros_on 3239/// ::= .macros_off 3240bool AsmParser::parseDirectiveMacrosOnOff(StringRef Directive) { 3241 if (getLexer().isNot(AsmToken::EndOfStatement)) 3242 return Error(getLexer().getLoc(), 3243 "unexpected token in '" + Directive + "' directive"); 3244 3245 setMacrosEnabled(Directive == ".macros_on"); 3246 return false; 3247} 3248 3249/// parseDirectiveMacro 3250/// ::= .macro name[,] [parameters] 3251bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) { 3252 StringRef Name; 3253 if (parseIdentifier(Name)) 3254 return TokError("expected identifier in '.macro' directive"); 3255 3256 if (getLexer().is(AsmToken::Comma)) 3257 Lex(); 3258 3259 MCAsmMacroParameters Parameters; 3260 while (getLexer().isNot(AsmToken::EndOfStatement)) { 3261 3262 if (Parameters.size() && Parameters.back().Vararg) 3263 return Error(Lexer.getLoc(), 3264 "Vararg parameter '" + Parameters.back().Name + 3265 "' should be last one in the list of parameters."); 3266 3267 MCAsmMacroParameter Parameter; 3268 if (parseIdentifier(Parameter.Name)) 3269 return TokError("expected identifier in '.macro' directive"); 3270 3271 if (Lexer.is(AsmToken::Colon)) { 3272 Lex(); // consume ':' 3273 3274 SMLoc QualLoc; 3275 StringRef Qualifier; 3276 3277 QualLoc = Lexer.getLoc(); 3278 if (parseIdentifier(Qualifier)) 3279 return Error(QualLoc, "missing parameter qualifier for " 3280 "'" + Parameter.Name + "' in macro '" + Name + "'"); 3281 3282 if (Qualifier == "req") 3283 Parameter.Required = true; 3284 else if (Qualifier == "vararg" && !IsDarwin) 3285 Parameter.Vararg = true; 3286 else 3287 return Error(QualLoc, Qualifier + " is not a valid parameter qualifier " 3288 "for '" + Parameter.Name + "' in macro '" + Name + "'"); 3289 } 3290 3291 if (getLexer().is(AsmToken::Equal)) { 3292 Lex(); 3293 3294 SMLoc ParamLoc; 3295 3296 ParamLoc = Lexer.getLoc(); 3297 if (parseMacroArgument(Parameter.Value, /*Vararg=*/false )) 3298 return true; 3299 3300 if (Parameter.Required) 3301 Warning(ParamLoc, "pointless default value for required parameter " 3302 "'" + Parameter.Name + "' in macro '" + Name + "'"); 3303 } 3304 3305 Parameters.push_back(Parameter); 3306 3307 if (getLexer().is(AsmToken::Comma)) 3308 Lex(); 3309 } 3310 3311 // Eat the end of statement. 3312 Lex(); 3313 3314 AsmToken EndToken, StartToken = getTok(); 3315 unsigned MacroDepth = 0; 3316 3317 // Lex the macro definition. 3318 for (;;) { 3319 // Check whether we have reached the end of the file. 3320 if (getLexer().is(AsmToken::Eof)) 3321 return Error(DirectiveLoc, "no matching '.endmacro' in definition"); 3322 3323 // Otherwise, check whether we have reach the .endmacro. 3324 if (getLexer().is(AsmToken::Identifier)) { 3325 if (getTok().getIdentifier() == ".endm" || 3326 getTok().getIdentifier() == ".endmacro") { 3327 if (MacroDepth == 0) { // Outermost macro. 3328 EndToken = getTok(); 3329 Lex(); 3330 if (getLexer().isNot(AsmToken::EndOfStatement)) 3331 return TokError("unexpected token in '" + EndToken.getIdentifier() + 3332 "' directive"); 3333 break; 3334 } else { 3335 // Otherwise we just found the end of an inner macro. 3336 --MacroDepth; 3337 } 3338 } else if (getTok().getIdentifier() == ".macro") { 3339 // We allow nested macros. Those aren't instantiated until the outermost 3340 // macro is expanded so just ignore them for now. 3341 ++MacroDepth; 3342 } 3343 } 3344 3345 // Otherwise, scan til the end of the statement. 3346 eatToEndOfStatement(); 3347 } 3348 3349 if (lookupMacro(Name)) { 3350 return Error(DirectiveLoc, "macro '" + Name + "' is already defined"); 3351 } 3352 3353 const char *BodyStart = StartToken.getLoc().getPointer(); 3354 const char *BodyEnd = EndToken.getLoc().getPointer(); 3355 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); 3356 checkForBadMacro(DirectiveLoc, Name, Body, Parameters); 3357 defineMacro(Name, MCAsmMacro(Name, Body, Parameters)); 3358 return false; 3359} 3360 3361/// checkForBadMacro 3362/// 3363/// With the support added for named parameters there may be code out there that 3364/// is transitioning from positional parameters. In versions of gas that did 3365/// not support named parameters they would be ignored on the macro definition. 3366/// But to support both styles of parameters this is not possible so if a macro 3367/// definition has named parameters but does not use them and has what appears 3368/// to be positional parameters, strings like $1, $2, ... and $n, then issue a 3369/// warning that the positional parameter found in body which have no effect. 3370/// Hoping the developer will either remove the named parameters from the macro 3371/// definition so the positional parameters get used if that was what was 3372/// intended or change the macro to use the named parameters. It is possible 3373/// this warning will trigger when the none of the named parameters are used 3374/// and the strings like $1 are infact to simply to be passed trough unchanged. 3375void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, 3376 StringRef Body, 3377 ArrayRef<MCAsmMacroParameter> Parameters) { 3378 // If this macro is not defined with named parameters the warning we are 3379 // checking for here doesn't apply. 3380 unsigned NParameters = Parameters.size(); 3381 if (NParameters == 0) 3382 return; 3383 3384 bool NamedParametersFound = false; 3385 bool PositionalParametersFound = false; 3386 3387 // Look at the body of the macro for use of both the named parameters and what 3388 // are likely to be positional parameters. This is what expandMacro() is 3389 // doing when it finds the parameters in the body. 3390 while (!Body.empty()) { 3391 // Scan for the next possible parameter. 3392 std::size_t End = Body.size(), Pos = 0; 3393 for (; Pos != End; ++Pos) { 3394 // Check for a substitution or escape. 3395 // This macro is defined with parameters, look for \foo, \bar, etc. 3396 if (Body[Pos] == '\\' && Pos + 1 != End) 3397 break; 3398 3399 // This macro should have parameters, but look for $0, $1, ..., $n too. 3400 if (Body[Pos] != '$' || Pos + 1 == End) 3401 continue; 3402 char Next = Body[Pos + 1]; 3403 if (Next == '$' || Next == 'n' || 3404 isdigit(static_cast<unsigned char>(Next))) 3405 break; 3406 } 3407 3408 // Check if we reached the end. 3409 if (Pos == End) 3410 break; 3411 3412 if (Body[Pos] == '$') { 3413 switch (Body[Pos + 1]) { 3414 // $$ => $ 3415 case '$': 3416 break; 3417 3418 // $n => number of arguments 3419 case 'n': 3420 PositionalParametersFound = true; 3421 break; 3422 3423 // $[0-9] => argument 3424 default: { 3425 PositionalParametersFound = true; 3426 break; 3427 } 3428 } 3429 Pos += 2; 3430 } else { 3431 unsigned I = Pos + 1; 3432 while (isIdentifierChar(Body[I]) && I + 1 != End) 3433 ++I; 3434 3435 const char *Begin = Body.data() + Pos + 1; 3436 StringRef Argument(Begin, I - (Pos + 1)); 3437 unsigned Index = 0; 3438 for (; Index < NParameters; ++Index) 3439 if (Parameters[Index].Name == Argument) 3440 break; 3441 3442 if (Index == NParameters) { 3443 if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')') 3444 Pos += 3; 3445 else { 3446 Pos = I; 3447 } 3448 } else { 3449 NamedParametersFound = true; 3450 Pos += 1 + Argument.size(); 3451 } 3452 } 3453 // Update the scan point. 3454 Body = Body.substr(Pos); 3455 } 3456 3457 if (!NamedParametersFound && PositionalParametersFound) 3458 Warning(DirectiveLoc, "macro defined with named parameters which are not " 3459 "used in macro body, possible positional parameter " 3460 "found in body which will have no effect"); 3461} 3462 3463/// parseDirectiveEndMacro 3464/// ::= .endm 3465/// ::= .endmacro 3466bool AsmParser::parseDirectiveEndMacro(StringRef Directive) { 3467 if (getLexer().isNot(AsmToken::EndOfStatement)) 3468 return TokError("unexpected token in '" + Directive + "' directive"); 3469 3470 // If we are inside a macro instantiation, terminate the current 3471 // instantiation. 3472 if (isInsideMacroInstantiation()) { 3473 handleMacroExit(); 3474 return false; 3475 } 3476 3477 // Otherwise, this .endmacro is a stray entry in the file; well formed 3478 // .endmacro directives are handled during the macro definition parsing. 3479 return TokError("unexpected '" + Directive + "' in file, " 3480 "no current macro definition"); 3481} 3482 3483/// parseDirectivePurgeMacro 3484/// ::= .purgem 3485bool AsmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) { 3486 StringRef Name; 3487 if (parseIdentifier(Name)) 3488 return TokError("expected identifier in '.purgem' directive"); 3489 3490 if (getLexer().isNot(AsmToken::EndOfStatement)) 3491 return TokError("unexpected token in '.purgem' directive"); 3492 3493 if (!lookupMacro(Name)) 3494 return Error(DirectiveLoc, "macro '" + Name + "' is not defined"); 3495 3496 undefineMacro(Name); 3497 return false; 3498} 3499 3500/// parseDirectiveBundleAlignMode 3501/// ::= {.bundle_align_mode} expression 3502bool AsmParser::parseDirectiveBundleAlignMode() { 3503 checkForValidSection(); 3504 3505 // Expect a single argument: an expression that evaluates to a constant 3506 // in the inclusive range 0-30. 3507 SMLoc ExprLoc = getLexer().getLoc(); 3508 int64_t AlignSizePow2; 3509 if (parseAbsoluteExpression(AlignSizePow2)) 3510 return true; 3511 else if (getLexer().isNot(AsmToken::EndOfStatement)) 3512 return TokError("unexpected token after expression in" 3513 " '.bundle_align_mode' directive"); 3514 else if (AlignSizePow2 < 0 || AlignSizePow2 > 30) 3515 return Error(ExprLoc, 3516 "invalid bundle alignment size (expected between 0 and 30)"); 3517 3518 Lex(); 3519 3520 // Because of AlignSizePow2's verified range we can safely truncate it to 3521 // unsigned. 3522 getStreamer().EmitBundleAlignMode(static_cast<unsigned>(AlignSizePow2)); 3523 return false; 3524} 3525 3526/// parseDirectiveBundleLock 3527/// ::= {.bundle_lock} [align_to_end] 3528bool AsmParser::parseDirectiveBundleLock() { 3529 checkForValidSection(); 3530 bool AlignToEnd = false; 3531 3532 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3533 StringRef Option; 3534 SMLoc Loc = getTok().getLoc(); 3535 const char *kInvalidOptionError = 3536 "invalid option for '.bundle_lock' directive"; 3537 3538 if (parseIdentifier(Option)) 3539 return Error(Loc, kInvalidOptionError); 3540 3541 if (Option != "align_to_end") 3542 return Error(Loc, kInvalidOptionError); 3543 else if (getLexer().isNot(AsmToken::EndOfStatement)) 3544 return Error(Loc, 3545 "unexpected token after '.bundle_lock' directive option"); 3546 AlignToEnd = true; 3547 } 3548 3549 Lex(); 3550 3551 getStreamer().EmitBundleLock(AlignToEnd); 3552 return false; 3553} 3554 3555/// parseDirectiveBundleLock 3556/// ::= {.bundle_lock} 3557bool AsmParser::parseDirectiveBundleUnlock() { 3558 checkForValidSection(); 3559 3560 if (getLexer().isNot(AsmToken::EndOfStatement)) 3561 return TokError("unexpected token in '.bundle_unlock' directive"); 3562 Lex(); 3563 3564 getStreamer().EmitBundleUnlock(); 3565 return false; 3566} 3567 3568/// parseDirectiveSpace 3569/// ::= (.skip | .space) expression [ , expression ] 3570bool AsmParser::parseDirectiveSpace(StringRef IDVal) { 3571 checkForValidSection(); 3572 3573 int64_t NumBytes; 3574 if (parseAbsoluteExpression(NumBytes)) 3575 return true; 3576 3577 int64_t FillExpr = 0; 3578 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3579 if (getLexer().isNot(AsmToken::Comma)) 3580 return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); 3581 Lex(); 3582 3583 if (parseAbsoluteExpression(FillExpr)) 3584 return true; 3585 3586 if (getLexer().isNot(AsmToken::EndOfStatement)) 3587 return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); 3588 } 3589 3590 Lex(); 3591 3592 if (NumBytes <= 0) 3593 return TokError("invalid number of bytes in '" + Twine(IDVal) + 3594 "' directive"); 3595 3596 // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0. 3597 getStreamer().EmitFill(NumBytes, FillExpr); 3598 3599 return false; 3600} 3601 3602/// parseDirectiveLEB128 3603/// ::= (.sleb128 | .uleb128) expression 3604bool AsmParser::parseDirectiveLEB128(bool Signed) { 3605 checkForValidSection(); 3606 const MCExpr *Value; 3607 3608 if (parseExpression(Value)) 3609 return true; 3610 3611 if (getLexer().isNot(AsmToken::EndOfStatement)) 3612 return TokError("unexpected token in directive"); 3613 3614 if (Signed) 3615 getStreamer().EmitSLEB128Value(Value); 3616 else 3617 getStreamer().EmitULEB128Value(Value); 3618 3619 return false; 3620} 3621 3622/// parseDirectiveSymbolAttribute 3623/// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ] 3624bool AsmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) { 3625 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3626 for (;;) { 3627 StringRef Name; 3628 SMLoc Loc = getTok().getLoc(); 3629 3630 if (parseIdentifier(Name)) 3631 return Error(Loc, "expected identifier in directive"); 3632 3633 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 3634 3635 // Assembler local symbols don't make any sense here. Complain loudly. 3636 if (Sym->isTemporary()) 3637 return Error(Loc, "non-local symbol required in directive"); 3638 3639 if (!getStreamer().EmitSymbolAttribute(Sym, Attr)) 3640 return Error(Loc, "unable to emit symbol attribute"); 3641 3642 if (getLexer().is(AsmToken::EndOfStatement)) 3643 break; 3644 3645 if (getLexer().isNot(AsmToken::Comma)) 3646 return TokError("unexpected token in directive"); 3647 Lex(); 3648 } 3649 } 3650 3651 Lex(); 3652 return false; 3653} 3654 3655/// parseDirectiveComm 3656/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ] 3657bool AsmParser::parseDirectiveComm(bool IsLocal) { 3658 checkForValidSection(); 3659 3660 SMLoc IDLoc = getLexer().getLoc(); 3661 StringRef Name; 3662 if (parseIdentifier(Name)) 3663 return TokError("expected identifier in directive"); 3664 3665 // Handle the identifier as the key symbol. 3666 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 3667 3668 if (getLexer().isNot(AsmToken::Comma)) 3669 return TokError("unexpected token in directive"); 3670 Lex(); 3671 3672 int64_t Size; 3673 SMLoc SizeLoc = getLexer().getLoc(); 3674 if (parseAbsoluteExpression(Size)) 3675 return true; 3676 3677 int64_t Pow2Alignment = 0; 3678 SMLoc Pow2AlignmentLoc; 3679 if (getLexer().is(AsmToken::Comma)) { 3680 Lex(); 3681 Pow2AlignmentLoc = getLexer().getLoc(); 3682 if (parseAbsoluteExpression(Pow2Alignment)) 3683 return true; 3684 3685 LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType(); 3686 if (IsLocal && LCOMM == LCOMM::NoAlignment) 3687 return Error(Pow2AlignmentLoc, "alignment not supported on this target"); 3688 3689 // If this target takes alignments in bytes (not log) validate and convert. 3690 if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) || 3691 (IsLocal && LCOMM == LCOMM::ByteAlignment)) { 3692 if (!isPowerOf2_64(Pow2Alignment)) 3693 return Error(Pow2AlignmentLoc, "alignment must be a power of 2"); 3694 Pow2Alignment = Log2_64(Pow2Alignment); 3695 } 3696 } 3697 3698 if (getLexer().isNot(AsmToken::EndOfStatement)) 3699 return TokError("unexpected token in '.comm' or '.lcomm' directive"); 3700 3701 Lex(); 3702 3703 // NOTE: a size of zero for a .comm should create a undefined symbol 3704 // but a size of .lcomm creates a bss symbol of size zero. 3705 if (Size < 0) 3706 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't " 3707 "be less than zero"); 3708 3709 // NOTE: The alignment in the directive is a power of 2 value, the assembler 3710 // may internally end up wanting an alignment in bytes. 3711 // FIXME: Diagnose overflow. 3712 if (Pow2Alignment < 0) 3713 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive " 3714 "alignment, can't be less than zero"); 3715 3716 if (!Sym->isUndefined()) 3717 return Error(IDLoc, "invalid symbol redefinition"); 3718 3719 // Create the Symbol as a common or local common with Size and Pow2Alignment 3720 if (IsLocal) { 3721 getStreamer().EmitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment); 3722 return false; 3723 } 3724 3725 getStreamer().EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment); 3726 return false; 3727} 3728 3729/// parseDirectiveAbort 3730/// ::= .abort [... message ...] 3731bool AsmParser::parseDirectiveAbort() { 3732 // FIXME: Use loc from directive. 3733 SMLoc Loc = getLexer().getLoc(); 3734 3735 StringRef Str = parseStringToEndOfStatement(); 3736 if (getLexer().isNot(AsmToken::EndOfStatement)) 3737 return TokError("unexpected token in '.abort' directive"); 3738 3739 Lex(); 3740 3741 if (Str.empty()) 3742 Error(Loc, ".abort detected. Assembly stopping."); 3743 else 3744 Error(Loc, ".abort '" + Str + "' detected. Assembly stopping."); 3745 // FIXME: Actually abort assembly here. 3746 3747 return false; 3748} 3749 3750/// parseDirectiveInclude 3751/// ::= .include "filename" 3752bool AsmParser::parseDirectiveInclude() { 3753 if (getLexer().isNot(AsmToken::String)) 3754 return TokError("expected string in '.include' directive"); 3755 3756 // Allow the strings to have escaped octal character sequence. 3757 std::string Filename; 3758 if (parseEscapedString(Filename)) 3759 return true; 3760 SMLoc IncludeLoc = getLexer().getLoc(); 3761 Lex(); 3762 3763 if (getLexer().isNot(AsmToken::EndOfStatement)) 3764 return TokError("unexpected token in '.include' directive"); 3765 3766 // Attempt to switch the lexer to the included file before consuming the end 3767 // of statement to avoid losing it when we switch. 3768 if (enterIncludeFile(Filename)) { 3769 Error(IncludeLoc, "Could not find include file '" + Filename + "'"); 3770 return true; 3771 } 3772 3773 return false; 3774} 3775 3776/// parseDirectiveIncbin 3777/// ::= .incbin "filename" 3778bool AsmParser::parseDirectiveIncbin() { 3779 if (getLexer().isNot(AsmToken::String)) 3780 return TokError("expected string in '.incbin' directive"); 3781 3782 // Allow the strings to have escaped octal character sequence. 3783 std::string Filename; 3784 if (parseEscapedString(Filename)) 3785 return true; 3786 SMLoc IncbinLoc = getLexer().getLoc(); 3787 Lex(); 3788 3789 if (getLexer().isNot(AsmToken::EndOfStatement)) 3790 return TokError("unexpected token in '.incbin' directive"); 3791 3792 // Attempt to process the included file. 3793 if (processIncbinFile(Filename)) { 3794 Error(IncbinLoc, "Could not find incbin file '" + Filename + "'"); 3795 return true; 3796 } 3797 3798 return false; 3799} 3800 3801/// parseDirectiveIf 3802/// ::= .if expression 3803/// ::= .ifne expression 3804bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc) { 3805 TheCondStack.push_back(TheCondState); 3806 TheCondState.TheCond = AsmCond::IfCond; 3807 if (TheCondState.Ignore) { 3808 eatToEndOfStatement(); 3809 } else { 3810 int64_t ExprValue; 3811 if (parseAbsoluteExpression(ExprValue)) 3812 return true; 3813 3814 if (getLexer().isNot(AsmToken::EndOfStatement)) 3815 return TokError("unexpected token in '.if' directive"); 3816 3817 Lex(); 3818 3819 TheCondState.CondMet = ExprValue; 3820 TheCondState.Ignore = !TheCondState.CondMet; 3821 } 3822 3823 return false; 3824} 3825 3826/// parseDirectiveIfb 3827/// ::= .ifb string 3828bool AsmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) { 3829 TheCondStack.push_back(TheCondState); 3830 TheCondState.TheCond = AsmCond::IfCond; 3831 3832 if (TheCondState.Ignore) { 3833 eatToEndOfStatement(); 3834 } else { 3835 StringRef Str = parseStringToEndOfStatement(); 3836 3837 if (getLexer().isNot(AsmToken::EndOfStatement)) 3838 return TokError("unexpected token in '.ifb' directive"); 3839 3840 Lex(); 3841 3842 TheCondState.CondMet = ExpectBlank == Str.empty(); 3843 TheCondState.Ignore = !TheCondState.CondMet; 3844 } 3845 3846 return false; 3847} 3848 3849/// parseDirectiveIfc 3850/// ::= .ifc string1, string2 3851/// ::= .ifnc string1, string2 3852bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) { 3853 TheCondStack.push_back(TheCondState); 3854 TheCondState.TheCond = AsmCond::IfCond; 3855 3856 if (TheCondState.Ignore) { 3857 eatToEndOfStatement(); 3858 } else { 3859 StringRef Str1 = parseStringToComma(); 3860 3861 if (getLexer().isNot(AsmToken::Comma)) 3862 return TokError("unexpected token in '.ifc' directive"); 3863 3864 Lex(); 3865 3866 StringRef Str2 = parseStringToEndOfStatement(); 3867 3868 if (getLexer().isNot(AsmToken::EndOfStatement)) 3869 return TokError("unexpected token in '.ifc' directive"); 3870 3871 Lex(); 3872 3873 TheCondState.CondMet = ExpectEqual == (Str1.trim() == Str2.trim()); 3874 TheCondState.Ignore = !TheCondState.CondMet; 3875 } 3876 3877 return false; 3878} 3879 3880/// parseDirectiveIfeqs 3881/// ::= .ifeqs string1, string2 3882bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc) { 3883 if (Lexer.isNot(AsmToken::String)) { 3884 TokError("expected string parameter for '.ifeqs' directive"); 3885 eatToEndOfStatement(); 3886 return true; 3887 } 3888 3889 StringRef String1 = getTok().getStringContents(); 3890 Lex(); 3891 3892 if (Lexer.isNot(AsmToken::Comma)) { 3893 TokError("expected comma after first string for '.ifeqs' directive"); 3894 eatToEndOfStatement(); 3895 return true; 3896 } 3897 3898 Lex(); 3899 3900 if (Lexer.isNot(AsmToken::String)) { 3901 TokError("expected string parameter for '.ifeqs' directive"); 3902 eatToEndOfStatement(); 3903 return true; 3904 } 3905 3906 StringRef String2 = getTok().getStringContents(); 3907 Lex(); 3908 3909 TheCondStack.push_back(TheCondState); 3910 TheCondState.TheCond = AsmCond::IfCond; 3911 TheCondState.CondMet = String1 == String2; 3912 TheCondState.Ignore = !TheCondState.CondMet; 3913 3914 return false; 3915} 3916 3917/// parseDirectiveIfdef 3918/// ::= .ifdef symbol 3919bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { 3920 StringRef Name; 3921 TheCondStack.push_back(TheCondState); 3922 TheCondState.TheCond = AsmCond::IfCond; 3923 3924 if (TheCondState.Ignore) { 3925 eatToEndOfStatement(); 3926 } else { 3927 if (parseIdentifier(Name)) 3928 return TokError("expected identifier after '.ifdef'"); 3929 3930 Lex(); 3931 3932 MCSymbol *Sym = getContext().LookupSymbol(Name); 3933 3934 if (expect_defined) 3935 TheCondState.CondMet = (Sym && !Sym->isUndefined()); 3936 else 3937 TheCondState.CondMet = (!Sym || Sym->isUndefined()); 3938 TheCondState.Ignore = !TheCondState.CondMet; 3939 } 3940 3941 return false; 3942} 3943 3944/// parseDirectiveElseIf 3945/// ::= .elseif expression 3946bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) { 3947 if (TheCondState.TheCond != AsmCond::IfCond && 3948 TheCondState.TheCond != AsmCond::ElseIfCond) 3949 Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or " 3950 " an .elseif"); 3951 TheCondState.TheCond = AsmCond::ElseIfCond; 3952 3953 bool LastIgnoreState = false; 3954 if (!TheCondStack.empty()) 3955 LastIgnoreState = TheCondStack.back().Ignore; 3956 if (LastIgnoreState || TheCondState.CondMet) { 3957 TheCondState.Ignore = true; 3958 eatToEndOfStatement(); 3959 } else { 3960 int64_t ExprValue; 3961 if (parseAbsoluteExpression(ExprValue)) 3962 return true; 3963 3964 if (getLexer().isNot(AsmToken::EndOfStatement)) 3965 return TokError("unexpected token in '.elseif' directive"); 3966 3967 Lex(); 3968 TheCondState.CondMet = ExprValue; 3969 TheCondState.Ignore = !TheCondState.CondMet; 3970 } 3971 3972 return false; 3973} 3974 3975/// parseDirectiveElse 3976/// ::= .else 3977bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) { 3978 if (getLexer().isNot(AsmToken::EndOfStatement)) 3979 return TokError("unexpected token in '.else' directive"); 3980 3981 Lex(); 3982 3983 if (TheCondState.TheCond != AsmCond::IfCond && 3984 TheCondState.TheCond != AsmCond::ElseIfCond) 3985 Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an " 3986 ".elseif"); 3987 TheCondState.TheCond = AsmCond::ElseCond; 3988 bool LastIgnoreState = false; 3989 if (!TheCondStack.empty()) 3990 LastIgnoreState = TheCondStack.back().Ignore; 3991 if (LastIgnoreState || TheCondState.CondMet) 3992 TheCondState.Ignore = true; 3993 else 3994 TheCondState.Ignore = false; 3995 3996 return false; 3997} 3998 3999/// parseDirectiveEnd 4000/// ::= .end 4001bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) { 4002 if (getLexer().isNot(AsmToken::EndOfStatement)) 4003 return TokError("unexpected token in '.end' directive"); 4004 4005 Lex(); 4006 4007 while (Lexer.isNot(AsmToken::Eof)) 4008 Lex(); 4009 4010 return false; 4011} 4012 4013/// parseDirectiveError 4014/// ::= .err 4015/// ::= .error [string] 4016bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) { 4017 if (!TheCondStack.empty()) { 4018 if (TheCondStack.back().Ignore) { 4019 eatToEndOfStatement(); 4020 return false; 4021 } 4022 } 4023 4024 if (!WithMessage) 4025 return Error(L, ".err encountered"); 4026 4027 StringRef Message = ".error directive invoked in source file"; 4028 if (Lexer.isNot(AsmToken::EndOfStatement)) { 4029 if (Lexer.isNot(AsmToken::String)) { 4030 TokError(".error argument must be a string"); 4031 eatToEndOfStatement(); 4032 return true; 4033 } 4034 4035 Message = getTok().getStringContents(); 4036 Lex(); 4037 } 4038 4039 Error(L, Message); 4040 return true; 4041} 4042 4043/// parseDirectiveEndIf 4044/// ::= .endif 4045bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) { 4046 if (getLexer().isNot(AsmToken::EndOfStatement)) 4047 return TokError("unexpected token in '.endif' directive"); 4048 4049 Lex(); 4050 4051 if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty()) 4052 Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or " 4053 ".else"); 4054 if (!TheCondStack.empty()) { 4055 TheCondState = TheCondStack.back(); 4056 TheCondStack.pop_back(); 4057 } 4058 4059 return false; 4060} 4061 4062void AsmParser::initializeDirectiveKindMap() { 4063 DirectiveKindMap[".set"] = DK_SET; 4064 DirectiveKindMap[".equ"] = DK_EQU; 4065 DirectiveKindMap[".equiv"] = DK_EQUIV; 4066 DirectiveKindMap[".ascii"] = DK_ASCII; 4067 DirectiveKindMap[".asciz"] = DK_ASCIZ; 4068 DirectiveKindMap[".string"] = DK_STRING; 4069 DirectiveKindMap[".byte"] = DK_BYTE; 4070 DirectiveKindMap[".short"] = DK_SHORT; 4071 DirectiveKindMap[".value"] = DK_VALUE; 4072 DirectiveKindMap[".2byte"] = DK_2BYTE; 4073 DirectiveKindMap[".long"] = DK_LONG; 4074 DirectiveKindMap[".int"] = DK_INT; 4075 DirectiveKindMap[".4byte"] = DK_4BYTE; 4076 DirectiveKindMap[".quad"] = DK_QUAD; 4077 DirectiveKindMap[".8byte"] = DK_8BYTE; 4078 DirectiveKindMap[".octa"] = DK_OCTA; 4079 DirectiveKindMap[".single"] = DK_SINGLE; 4080 DirectiveKindMap[".float"] = DK_FLOAT; 4081 DirectiveKindMap[".double"] = DK_DOUBLE; 4082 DirectiveKindMap[".align"] = DK_ALIGN; 4083 DirectiveKindMap[".align32"] = DK_ALIGN32; 4084 DirectiveKindMap[".balign"] = DK_BALIGN; 4085 DirectiveKindMap[".balignw"] = DK_BALIGNW; 4086 DirectiveKindMap[".balignl"] = DK_BALIGNL; 4087 DirectiveKindMap[".p2align"] = DK_P2ALIGN; 4088 DirectiveKindMap[".p2alignw"] = DK_P2ALIGNW; 4089 DirectiveKindMap[".p2alignl"] = DK_P2ALIGNL; 4090 DirectiveKindMap[".org"] = DK_ORG; 4091 DirectiveKindMap[".fill"] = DK_FILL; 4092 DirectiveKindMap[".zero"] = DK_ZERO; 4093 DirectiveKindMap[".extern"] = DK_EXTERN; 4094 DirectiveKindMap[".globl"] = DK_GLOBL; 4095 DirectiveKindMap[".global"] = DK_GLOBAL; 4096 DirectiveKindMap[".lazy_reference"] = DK_LAZY_REFERENCE; 4097 DirectiveKindMap[".no_dead_strip"] = DK_NO_DEAD_STRIP; 4098 DirectiveKindMap[".symbol_resolver"] = DK_SYMBOL_RESOLVER; 4099 DirectiveKindMap[".private_extern"] = DK_PRIVATE_EXTERN; 4100 DirectiveKindMap[".reference"] = DK_REFERENCE; 4101 DirectiveKindMap[".weak_definition"] = DK_WEAK_DEFINITION; 4102 DirectiveKindMap[".weak_reference"] = DK_WEAK_REFERENCE; 4103 DirectiveKindMap[".weak_def_can_be_hidden"] = DK_WEAK_DEF_CAN_BE_HIDDEN; 4104 DirectiveKindMap[".comm"] = DK_COMM; 4105 DirectiveKindMap[".common"] = DK_COMMON; 4106 DirectiveKindMap[".lcomm"] = DK_LCOMM; 4107 DirectiveKindMap[".abort"] = DK_ABORT; 4108 DirectiveKindMap[".include"] = DK_INCLUDE; 4109 DirectiveKindMap[".incbin"] = DK_INCBIN; 4110 DirectiveKindMap[".code16"] = DK_CODE16; 4111 DirectiveKindMap[".code16gcc"] = DK_CODE16GCC; 4112 DirectiveKindMap[".rept"] = DK_REPT; 4113 DirectiveKindMap[".rep"] = DK_REPT; 4114 DirectiveKindMap[".irp"] = DK_IRP; 4115 DirectiveKindMap[".irpc"] = DK_IRPC; 4116 DirectiveKindMap[".endr"] = DK_ENDR; 4117 DirectiveKindMap[".bundle_align_mode"] = DK_BUNDLE_ALIGN_MODE; 4118 DirectiveKindMap[".bundle_lock"] = DK_BUNDLE_LOCK; 4119 DirectiveKindMap[".bundle_unlock"] = DK_BUNDLE_UNLOCK; 4120 DirectiveKindMap[".if"] = DK_IF; 4121 DirectiveKindMap[".ifne"] = DK_IFNE; 4122 DirectiveKindMap[".ifb"] = DK_IFB; 4123 DirectiveKindMap[".ifnb"] = DK_IFNB; 4124 DirectiveKindMap[".ifc"] = DK_IFC; 4125 DirectiveKindMap[".ifeqs"] = DK_IFEQS; 4126 DirectiveKindMap[".ifnc"] = DK_IFNC; 4127 DirectiveKindMap[".ifdef"] = DK_IFDEF; 4128 DirectiveKindMap[".ifndef"] = DK_IFNDEF; 4129 DirectiveKindMap[".ifnotdef"] = DK_IFNOTDEF; 4130 DirectiveKindMap[".elseif"] = DK_ELSEIF; 4131 DirectiveKindMap[".else"] = DK_ELSE; 4132 DirectiveKindMap[".end"] = DK_END; 4133 DirectiveKindMap[".endif"] = DK_ENDIF; 4134 DirectiveKindMap[".skip"] = DK_SKIP; 4135 DirectiveKindMap[".space"] = DK_SPACE; 4136 DirectiveKindMap[".file"] = DK_FILE; 4137 DirectiveKindMap[".line"] = DK_LINE; 4138 DirectiveKindMap[".loc"] = DK_LOC; 4139 DirectiveKindMap[".stabs"] = DK_STABS; 4140 DirectiveKindMap[".sleb128"] = DK_SLEB128; 4141 DirectiveKindMap[".uleb128"] = DK_ULEB128; 4142 DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS; 4143 DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC; 4144 DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC; 4145 DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA; 4146 DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET; 4147 DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET; 4148 DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER; 4149 DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET; 4150 DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET; 4151 DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY; 4152 DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA; 4153 DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE; 4154 DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE; 4155 DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE; 4156 DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE; 4157 DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE; 4158 DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME; 4159 DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED; 4160 DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER; 4161 DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE; 4162 DirectiveKindMap[".macros_on"] = DK_MACROS_ON; 4163 DirectiveKindMap[".macros_off"] = DK_MACROS_OFF; 4164 DirectiveKindMap[".macro"] = DK_MACRO; 4165 DirectiveKindMap[".endm"] = DK_ENDM; 4166 DirectiveKindMap[".endmacro"] = DK_ENDMACRO; 4167 DirectiveKindMap[".purgem"] = DK_PURGEM; 4168 DirectiveKindMap[".err"] = DK_ERR; 4169 DirectiveKindMap[".error"] = DK_ERROR; 4170} 4171 4172MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) { 4173 AsmToken EndToken, StartToken = getTok(); 4174 4175 unsigned NestLevel = 0; 4176 for (;;) { 4177 // Check whether we have reached the end of the file. 4178 if (getLexer().is(AsmToken::Eof)) { 4179 Error(DirectiveLoc, "no matching '.endr' in definition"); 4180 return nullptr; 4181 } 4182 4183 if (Lexer.is(AsmToken::Identifier) && 4184 (getTok().getIdentifier() == ".rept")) { 4185 ++NestLevel; 4186 } 4187 4188 // Otherwise, check whether we have reached the .endr. 4189 if (Lexer.is(AsmToken::Identifier) && getTok().getIdentifier() == ".endr") { 4190 if (NestLevel == 0) { 4191 EndToken = getTok(); 4192 Lex(); 4193 if (Lexer.isNot(AsmToken::EndOfStatement)) { 4194 TokError("unexpected token in '.endr' directive"); 4195 return nullptr; 4196 } 4197 break; 4198 } 4199 --NestLevel; 4200 } 4201 4202 // Otherwise, scan till the end of the statement. 4203 eatToEndOfStatement(); 4204 } 4205 4206 const char *BodyStart = StartToken.getLoc().getPointer(); 4207 const char *BodyEnd = EndToken.getLoc().getPointer(); 4208 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); 4209 4210 // We Are Anonymous. 4211 MacroLikeBodies.push_back(MCAsmMacro(StringRef(), Body, None)); 4212 return &MacroLikeBodies.back(); 4213} 4214 4215void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, 4216 raw_svector_ostream &OS) { 4217 OS << ".endr\n"; 4218 4219 MemoryBuffer *Instantiation = 4220 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); 4221 4222 // Create the macro instantiation object and add to the current macro 4223 // instantiation stack. 4224 MacroInstantiation *MI = new MacroInstantiation( 4225 M, DirectiveLoc, CurBuffer, getTok().getLoc(), Instantiation); 4226 ActiveMacros.push_back(MI); 4227 4228 // Jump to the macro instantiation and prime the lexer. 4229 CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc()); 4230 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 4231 Lex(); 4232} 4233 4234/// parseDirectiveRept 4235/// ::= .rep | .rept count 4236bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) { 4237 const MCExpr *CountExpr; 4238 SMLoc CountLoc = getTok().getLoc(); 4239 if (parseExpression(CountExpr)) 4240 return true; 4241 4242 int64_t Count; 4243 if (!CountExpr->EvaluateAsAbsolute(Count)) { 4244 eatToEndOfStatement(); 4245 return Error(CountLoc, "unexpected token in '" + Dir + "' directive"); 4246 } 4247 4248 if (Count < 0) 4249 return Error(CountLoc, "Count is negative"); 4250 4251 if (Lexer.isNot(AsmToken::EndOfStatement)) 4252 return TokError("unexpected token in '" + Dir + "' directive"); 4253 4254 // Eat the end of statement. 4255 Lex(); 4256 4257 // Lex the rept definition. 4258 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 4259 if (!M) 4260 return true; 4261 4262 // Macro instantiation is lexical, unfortunately. We construct a new buffer 4263 // to hold the macro body with substitutions. 4264 SmallString<256> Buf; 4265 raw_svector_ostream OS(Buf); 4266 while (Count--) { 4267 if (expandMacro(OS, M->Body, None, None, getTok().getLoc())) 4268 return true; 4269 } 4270 instantiateMacroLikeBody(M, DirectiveLoc, OS); 4271 4272 return false; 4273} 4274 4275/// parseDirectiveIrp 4276/// ::= .irp symbol,values 4277bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) { 4278 MCAsmMacroParameter Parameter; 4279 4280 if (parseIdentifier(Parameter.Name)) 4281 return TokError("expected identifier in '.irp' directive"); 4282 4283 if (Lexer.isNot(AsmToken::Comma)) 4284 return TokError("expected comma in '.irp' directive"); 4285 4286 Lex(); 4287 4288 MCAsmMacroArguments A; 4289 if (parseMacroArguments(nullptr, A)) 4290 return true; 4291 4292 // Eat the end of statement. 4293 Lex(); 4294 4295 // Lex the irp definition. 4296 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 4297 if (!M) 4298 return true; 4299 4300 // Macro instantiation is lexical, unfortunately. We construct a new buffer 4301 // to hold the macro body with substitutions. 4302 SmallString<256> Buf; 4303 raw_svector_ostream OS(Buf); 4304 4305 for (MCAsmMacroArguments::iterator i = A.begin(), e = A.end(); i != e; ++i) { 4306 if (expandMacro(OS, M->Body, Parameter, *i, getTok().getLoc())) 4307 return true; 4308 } 4309 4310 instantiateMacroLikeBody(M, DirectiveLoc, OS); 4311 4312 return false; 4313} 4314 4315/// parseDirectiveIrpc 4316/// ::= .irpc symbol,values 4317bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) { 4318 MCAsmMacroParameter Parameter; 4319 4320 if (parseIdentifier(Parameter.Name)) 4321 return TokError("expected identifier in '.irpc' directive"); 4322 4323 if (Lexer.isNot(AsmToken::Comma)) 4324 return TokError("expected comma in '.irpc' directive"); 4325 4326 Lex(); 4327 4328 MCAsmMacroArguments A; 4329 if (parseMacroArguments(nullptr, A)) 4330 return true; 4331 4332 if (A.size() != 1 || A.front().size() != 1) 4333 return TokError("unexpected token in '.irpc' directive"); 4334 4335 // Eat the end of statement. 4336 Lex(); 4337 4338 // Lex the irpc definition. 4339 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 4340 if (!M) 4341 return true; 4342 4343 // Macro instantiation is lexical, unfortunately. We construct a new buffer 4344 // to hold the macro body with substitutions. 4345 SmallString<256> Buf; 4346 raw_svector_ostream OS(Buf); 4347 4348 StringRef Values = A.front().front().getString(); 4349 for (std::size_t I = 0, End = Values.size(); I != End; ++I) { 4350 MCAsmMacroArgument Arg; 4351 Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I + 1))); 4352 4353 if (expandMacro(OS, M->Body, Parameter, Arg, getTok().getLoc())) 4354 return true; 4355 } 4356 4357 instantiateMacroLikeBody(M, DirectiveLoc, OS); 4358 4359 return false; 4360} 4361 4362bool AsmParser::parseDirectiveEndr(SMLoc DirectiveLoc) { 4363 if (ActiveMacros.empty()) 4364 return TokError("unmatched '.endr' directive"); 4365 4366 // The only .repl that should get here are the ones created by 4367 // instantiateMacroLikeBody. 4368 assert(getLexer().is(AsmToken::EndOfStatement)); 4369 4370 handleMacroExit(); 4371 return false; 4372} 4373 4374bool AsmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info, 4375 size_t Len) { 4376 const MCExpr *Value; 4377 SMLoc ExprLoc = getLexer().getLoc(); 4378 if (parseExpression(Value)) 4379 return true; 4380 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 4381 if (!MCE) 4382 return Error(ExprLoc, "unexpected expression in _emit"); 4383 uint64_t IntValue = MCE->getValue(); 4384 if (!isUIntN(8, IntValue) && !isIntN(8, IntValue)) 4385 return Error(ExprLoc, "literal value out of range for directive"); 4386 4387 Info.AsmRewrites->push_back(AsmRewrite(AOK_Emit, IDLoc, Len)); 4388 return false; 4389} 4390 4391bool AsmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) { 4392 const MCExpr *Value; 4393 SMLoc ExprLoc = getLexer().getLoc(); 4394 if (parseExpression(Value)) 4395 return true; 4396 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 4397 if (!MCE) 4398 return Error(ExprLoc, "unexpected expression in align"); 4399 uint64_t IntValue = MCE->getValue(); 4400 if (!isPowerOf2_64(IntValue)) 4401 return Error(ExprLoc, "literal value not a power of two greater then zero"); 4402 4403 Info.AsmRewrites->push_back( 4404 AsmRewrite(AOK_Align, IDLoc, 5, Log2_64(IntValue))); 4405 return false; 4406} 4407 4408// We are comparing pointers, but the pointers are relative to a single string. 4409// Thus, this should always be deterministic. 4410static int rewritesSort(const AsmRewrite *AsmRewriteA, 4411 const AsmRewrite *AsmRewriteB) { 4412 if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer()) 4413 return -1; 4414 if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer()) 4415 return 1; 4416 4417 // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output 4418 // rewrite to the same location. Make sure the SizeDirective rewrite is 4419 // performed first, then the Imm/ImmPrefix and finally the Input/Output. This 4420 // ensures the sort algorithm is stable. 4421 if (AsmRewritePrecedence[AsmRewriteA->Kind] > 4422 AsmRewritePrecedence[AsmRewriteB->Kind]) 4423 return -1; 4424 4425 if (AsmRewritePrecedence[AsmRewriteA->Kind] < 4426 AsmRewritePrecedence[AsmRewriteB->Kind]) 4427 return 1; 4428 llvm_unreachable("Unstable rewrite sort."); 4429} 4430 4431bool AsmParser::parseMSInlineAsm( 4432 void *AsmLoc, std::string &AsmString, unsigned &NumOutputs, 4433 unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool> > &OpDecls, 4434 SmallVectorImpl<std::string> &Constraints, 4435 SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII, 4436 const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) { 4437 SmallVector<void *, 4> InputDecls; 4438 SmallVector<void *, 4> OutputDecls; 4439 SmallVector<bool, 4> InputDeclsAddressOf; 4440 SmallVector<bool, 4> OutputDeclsAddressOf; 4441 SmallVector<std::string, 4> InputConstraints; 4442 SmallVector<std::string, 4> OutputConstraints; 4443 SmallVector<unsigned, 4> ClobberRegs; 4444 4445 SmallVector<AsmRewrite, 4> AsmStrRewrites; 4446 4447 // Prime the lexer. 4448 Lex(); 4449 4450 // While we have input, parse each statement. 4451 unsigned InputIdx = 0; 4452 unsigned OutputIdx = 0; 4453 while (getLexer().isNot(AsmToken::Eof)) { 4454 ParseStatementInfo Info(&AsmStrRewrites); 4455 if (parseStatement(Info)) 4456 return true; 4457 4458 if (Info.ParseError) 4459 return true; 4460 4461 if (Info.Opcode == ~0U) 4462 continue; 4463 4464 const MCInstrDesc &Desc = MII->get(Info.Opcode); 4465 4466 // Build the list of clobbers, outputs and inputs. 4467 for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) { 4468 MCParsedAsmOperand *Operand = Info.ParsedOperands[i]; 4469 4470 // Immediate. 4471 if (Operand->isImm()) 4472 continue; 4473 4474 // Register operand. 4475 if (Operand->isReg() && !Operand->needAddressOf()) { 4476 unsigned NumDefs = Desc.getNumDefs(); 4477 // Clobber. 4478 if (NumDefs && Operand->getMCOperandNum() < NumDefs) 4479 ClobberRegs.push_back(Operand->getReg()); 4480 continue; 4481 } 4482 4483 // Expr/Input or Output. 4484 StringRef SymName = Operand->getSymName(); 4485 if (SymName.empty()) 4486 continue; 4487 4488 void *OpDecl = Operand->getOpDecl(); 4489 if (!OpDecl) 4490 continue; 4491 4492 bool isOutput = (i == 1) && Desc.mayStore(); 4493 SMLoc Start = SMLoc::getFromPointer(SymName.data()); 4494 if (isOutput) { 4495 ++InputIdx; 4496 OutputDecls.push_back(OpDecl); 4497 OutputDeclsAddressOf.push_back(Operand->needAddressOf()); 4498 OutputConstraints.push_back('=' + Operand->getConstraint().str()); 4499 AsmStrRewrites.push_back(AsmRewrite(AOK_Output, Start, SymName.size())); 4500 } else { 4501 InputDecls.push_back(OpDecl); 4502 InputDeclsAddressOf.push_back(Operand->needAddressOf()); 4503 InputConstraints.push_back(Operand->getConstraint().str()); 4504 AsmStrRewrites.push_back(AsmRewrite(AOK_Input, Start, SymName.size())); 4505 } 4506 } 4507 4508 // Consider implicit defs to be clobbers. Think of cpuid and push. 4509 const uint16_t *ImpDefs = Desc.getImplicitDefs(); 4510 for (unsigned I = 0, E = Desc.getNumImplicitDefs(); I != E; ++I) 4511 ClobberRegs.push_back(ImpDefs[I]); 4512 } 4513 4514 // Set the number of Outputs and Inputs. 4515 NumOutputs = OutputDecls.size(); 4516 NumInputs = InputDecls.size(); 4517 4518 // Set the unique clobbers. 4519 array_pod_sort(ClobberRegs.begin(), ClobberRegs.end()); 4520 ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()), 4521 ClobberRegs.end()); 4522 Clobbers.assign(ClobberRegs.size(), std::string()); 4523 for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) { 4524 raw_string_ostream OS(Clobbers[I]); 4525 IP->printRegName(OS, ClobberRegs[I]); 4526 } 4527 4528 // Merge the various outputs and inputs. Output are expected first. 4529 if (NumOutputs || NumInputs) { 4530 unsigned NumExprs = NumOutputs + NumInputs; 4531 OpDecls.resize(NumExprs); 4532 Constraints.resize(NumExprs); 4533 for (unsigned i = 0; i < NumOutputs; ++i) { 4534 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]); 4535 Constraints[i] = OutputConstraints[i]; 4536 } 4537 for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) { 4538 OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]); 4539 Constraints[j] = InputConstraints[i]; 4540 } 4541 } 4542 4543 // Build the IR assembly string. 4544 std::string AsmStringIR; 4545 raw_string_ostream OS(AsmStringIR); 4546 const char *AsmStart = SrcMgr.getMemoryBuffer(0)->getBufferStart(); 4547 const char *AsmEnd = SrcMgr.getMemoryBuffer(0)->getBufferEnd(); 4548 array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort); 4549 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmStrRewrites.begin(), 4550 E = AsmStrRewrites.end(); 4551 I != E; ++I) { 4552 AsmRewriteKind Kind = (*I).Kind; 4553 if (Kind == AOK_Delete) 4554 continue; 4555 4556 const char *Loc = (*I).Loc.getPointer(); 4557 assert(Loc >= AsmStart && "Expected Loc to be at or after Start!"); 4558 4559 // Emit everything up to the immediate/expression. 4560 unsigned Len = Loc - AsmStart; 4561 if (Len) 4562 OS << StringRef(AsmStart, Len); 4563 4564 // Skip the original expression. 4565 if (Kind == AOK_Skip) { 4566 AsmStart = Loc + (*I).Len; 4567 continue; 4568 } 4569 4570 unsigned AdditionalSkip = 0; 4571 // Rewrite expressions in $N notation. 4572 switch (Kind) { 4573 default: 4574 break; 4575 case AOK_Imm: 4576 OS << "$$" << (*I).Val; 4577 break; 4578 case AOK_ImmPrefix: 4579 OS << "$$"; 4580 break; 4581 case AOK_Input: 4582 OS << '$' << InputIdx++; 4583 break; 4584 case AOK_Output: 4585 OS << '$' << OutputIdx++; 4586 break; 4587 case AOK_SizeDirective: 4588 switch ((*I).Val) { 4589 default: break; 4590 case 8: OS << "byte ptr "; break; 4591 case 16: OS << "word ptr "; break; 4592 case 32: OS << "dword ptr "; break; 4593 case 64: OS << "qword ptr "; break; 4594 case 80: OS << "xword ptr "; break; 4595 case 128: OS << "xmmword ptr "; break; 4596 case 256: OS << "ymmword ptr "; break; 4597 } 4598 break; 4599 case AOK_Emit: 4600 OS << ".byte"; 4601 break; 4602 case AOK_Align: { 4603 unsigned Val = (*I).Val; 4604 OS << ".align " << Val; 4605 4606 // Skip the original immediate. 4607 assert(Val < 10 && "Expected alignment less then 2^10."); 4608 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4; 4609 break; 4610 } 4611 case AOK_DotOperator: 4612 // Insert the dot if the user omitted it. 4613 OS.flush(); 4614 if (AsmStringIR.back() != '.') 4615 OS << '.'; 4616 OS << (*I).Val; 4617 break; 4618 } 4619 4620 // Skip the original expression. 4621 AsmStart = Loc + (*I).Len + AdditionalSkip; 4622 } 4623 4624 // Emit the remainder of the asm string. 4625 if (AsmStart != AsmEnd) 4626 OS << StringRef(AsmStart, AsmEnd - AsmStart); 4627 4628 AsmString = OS.str(); 4629 return false; 4630} 4631 4632/// \brief Create an MCAsmParser instance. 4633MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM, MCContext &C, 4634 MCStreamer &Out, const MCAsmInfo &MAI) { 4635 return new AsmParser(SM, C, Out, MAI); 4636} 4637