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/SmallString.h" 16#include "llvm/ADT/StringMap.h" 17#include "llvm/ADT/Twine.h" 18#include "llvm/MC/MCAsmInfo.h" 19#include "llvm/MC/MCContext.h" 20#include "llvm/MC/MCDwarf.h" 21#include "llvm/MC/MCExpr.h" 22#include "llvm/MC/MCParser/AsmCond.h" 23#include "llvm/MC/MCParser/AsmLexer.h" 24#include "llvm/MC/MCParser/MCAsmParser.h" 25#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 26#include "llvm/MC/MCRegisterInfo.h" 27#include "llvm/MC/MCSectionMachO.h" 28#include "llvm/MC/MCStreamer.h" 29#include "llvm/MC/MCSymbol.h" 30#include "llvm/MC/MCTargetAsmParser.h" 31#include "llvm/Support/CommandLine.h" 32#include "llvm/Support/ErrorHandling.h" 33#include "llvm/Support/MathExtras.h" 34#include "llvm/Support/MemoryBuffer.h" 35#include "llvm/Support/SourceMgr.h" 36#include "llvm/Support/raw_ostream.h" 37#include <cctype> 38#include <vector> 39using namespace llvm; 40 41static cl::opt<bool> 42FatalAssemblerWarnings("fatal-assembler-warnings", 43 cl::desc("Consider warnings as error")); 44 45namespace { 46 47/// \brief Helper class for tracking macro definitions. 48typedef std::vector<AsmToken> MacroArgument; 49typedef std::vector<MacroArgument> MacroArguments; 50typedef StringRef MacroParameter; 51typedef std::vector<MacroParameter> MacroParameters; 52 53struct Macro { 54 StringRef Name; 55 StringRef Body; 56 MacroParameters Parameters; 57 58public: 59 Macro(StringRef N, StringRef B, const MacroParameters &P) : 60 Name(N), Body(B), Parameters(P) {} 61}; 62 63/// \brief Helper class for storing information about an active macro 64/// instantiation. 65struct MacroInstantiation { 66 /// The macro being instantiated. 67 const Macro *TheMacro; 68 69 /// The macro instantiation with substitutions. 70 MemoryBuffer *Instantiation; 71 72 /// The location of the instantiation. 73 SMLoc InstantiationLoc; 74 75 /// The location where parsing should resume upon instantiation completion. 76 SMLoc ExitLoc; 77 78public: 79 MacroInstantiation(const Macro *M, SMLoc IL, SMLoc EL, 80 MemoryBuffer *I); 81}; 82 83/// \brief The concrete assembly parser instance. 84class AsmParser : public MCAsmParser { 85 friend class GenericAsmParser; 86 87 AsmParser(const AsmParser &); // DO NOT IMPLEMENT 88 void operator=(const AsmParser &); // DO NOT IMPLEMENT 89private: 90 AsmLexer Lexer; 91 MCContext &Ctx; 92 MCStreamer &Out; 93 const MCAsmInfo &MAI; 94 SourceMgr &SrcMgr; 95 SourceMgr::DiagHandlerTy SavedDiagHandler; 96 void *SavedDiagContext; 97 MCAsmParserExtension *GenericParser; 98 MCAsmParserExtension *PlatformParser; 99 100 /// This is the current buffer index we're lexing from as managed by the 101 /// SourceMgr object. 102 int CurBuffer; 103 104 AsmCond TheCondState; 105 std::vector<AsmCond> TheCondStack; 106 107 /// DirectiveMap - This is a table handlers for directives. Each handler is 108 /// invoked after the directive identifier is read and is responsible for 109 /// parsing and validating the rest of the directive. The handler is passed 110 /// in the directive name and the location of the directive keyword. 111 StringMap<std::pair<MCAsmParserExtension*, DirectiveHandler> > DirectiveMap; 112 113 /// MacroMap - Map of currently defined macros. 114 StringMap<Macro*> MacroMap; 115 116 /// ActiveMacros - Stack of active macro instantiations. 117 std::vector<MacroInstantiation*> ActiveMacros; 118 119 /// Boolean tracking whether macro substitution is enabled. 120 unsigned MacrosEnabled : 1; 121 122 /// Flag tracking whether any errors have been encountered. 123 unsigned HadError : 1; 124 125 /// The values from the last parsed cpp hash file line comment if any. 126 StringRef CppHashFilename; 127 int64_t CppHashLineNumber; 128 SMLoc CppHashLoc; 129 130 /// AssemblerDialect. ~OU means unset value and use value provided by MAI. 131 unsigned AssemblerDialect; 132 133public: 134 AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, 135 const MCAsmInfo &MAI); 136 virtual ~AsmParser(); 137 138 virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false); 139 140 virtual void AddDirectiveHandler(MCAsmParserExtension *Object, 141 StringRef Directive, 142 DirectiveHandler Handler) { 143 DirectiveMap[Directive] = std::make_pair(Object, Handler); 144 } 145 146public: 147 /// @name MCAsmParser Interface 148 /// { 149 150 virtual SourceMgr &getSourceManager() { return SrcMgr; } 151 virtual MCAsmLexer &getLexer() { return Lexer; } 152 virtual MCContext &getContext() { return Ctx; } 153 virtual MCStreamer &getStreamer() { return Out; } 154 virtual unsigned getAssemblerDialect() { 155 if (AssemblerDialect == ~0U) 156 return MAI.getAssemblerDialect(); 157 else 158 return AssemblerDialect; 159 } 160 virtual void setAssemblerDialect(unsigned i) { 161 AssemblerDialect = i; 162 } 163 164 virtual bool Warning(SMLoc L, const Twine &Msg, 165 ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()); 166 virtual bool Error(SMLoc L, const Twine &Msg, 167 ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()); 168 169 virtual const AsmToken &Lex(); 170 171 bool ParseExpression(const MCExpr *&Res); 172 virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc); 173 virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc); 174 virtual bool ParseAbsoluteExpression(int64_t &Res); 175 176 /// } 177 178private: 179 void CheckForValidSection(); 180 181 bool ParseStatement(); 182 void EatToEndOfLine(); 183 bool ParseCppHashLineFilenameComment(const SMLoc &L); 184 185 bool HandleMacroEntry(StringRef Name, SMLoc NameLoc, const Macro *M); 186 bool expandMacro(raw_svector_ostream &OS, StringRef Body, 187 const MacroParameters &Parameters, 188 const MacroArguments &A, 189 const SMLoc &L); 190 void HandleMacroExit(); 191 192 void PrintMacroInstantiations(); 193 void PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg, 194 ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) const { 195 SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges); 196 } 197 static void DiagHandler(const SMDiagnostic &Diag, void *Context); 198 199 /// EnterIncludeFile - Enter the specified file. This returns true on failure. 200 bool EnterIncludeFile(const std::string &Filename); 201 /// ProcessIncbinFile - Process the specified file for the .incbin directive. 202 /// This returns true on failure. 203 bool ProcessIncbinFile(const std::string &Filename); 204 205 /// \brief Reset the current lexer position to that given by \arg Loc. The 206 /// current token is not set; clients should ensure Lex() is called 207 /// subsequently. 208 void JumpToLoc(SMLoc Loc); 209 210 virtual void EatToEndOfStatement(); 211 212 bool ParseMacroArgument(MacroArgument &MA); 213 bool ParseMacroArguments(const Macro *M, MacroArguments &A); 214 215 /// \brief Parse up to the end of statement and a return the contents from the 216 /// current token until the end of the statement; the current token on exit 217 /// will be either the EndOfStatement or EOF. 218 virtual StringRef ParseStringToEndOfStatement(); 219 220 /// \brief Parse until the end of a statement or a comma is encountered, 221 /// return the contents from the current token up to the end or comma. 222 StringRef ParseStringToComma(); 223 224 bool ParseAssignment(StringRef Name, bool allow_redef); 225 226 bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc); 227 bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc); 228 bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc); 229 bool ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc); 230 231 /// ParseIdentifier - Parse an identifier or string (as a quoted identifier) 232 /// and set \arg Res to the identifier contents. 233 virtual bool ParseIdentifier(StringRef &Res); 234 235 // Directive Parsing. 236 237 // ".ascii", ".asciiz", ".string" 238 bool ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated); 239 bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ... 240 bool ParseDirectiveRealValue(const fltSemantics &); // ".single", ... 241 bool ParseDirectiveFill(); // ".fill" 242 bool ParseDirectiveSpace(); // ".space" 243 bool ParseDirectiveZero(); // ".zero" 244 bool ParseDirectiveSet(StringRef IDVal, bool allow_redef); // ".set", ".equ", ".equiv" 245 bool ParseDirectiveOrg(); // ".org" 246 // ".align{,32}", ".p2align{,w,l}" 247 bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize); 248 249 /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which 250 /// accepts a single symbol (which should be a label or an external). 251 bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr); 252 253 bool ParseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm" 254 255 bool ParseDirectiveAbort(); // ".abort" 256 bool ParseDirectiveInclude(); // ".include" 257 bool ParseDirectiveIncbin(); // ".incbin" 258 259 bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if" 260 // ".ifb" or ".ifnb", depending on ExpectBlank. 261 bool ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank); 262 // ".ifc" or ".ifnc", depending on ExpectEqual. 263 bool ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual); 264 // ".ifdef" or ".ifndef", depending on expect_defined 265 bool ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined); 266 bool ParseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif" 267 bool ParseDirectiveElse(SMLoc DirectiveLoc); // ".else" 268 bool ParseDirectiveEndIf(SMLoc DirectiveLoc); // .endif 269 270 /// ParseEscapedString - Parse the current token as a string which may include 271 /// escaped characters and return the string contents. 272 bool ParseEscapedString(std::string &Data); 273 274 const MCExpr *ApplyModifierToExpr(const MCExpr *E, 275 MCSymbolRefExpr::VariantKind Variant); 276 277 // Macro-like directives 278 Macro *ParseMacroLikeBody(SMLoc DirectiveLoc); 279 void InstantiateMacroLikeBody(Macro *M, SMLoc DirectiveLoc, 280 raw_svector_ostream &OS); 281 bool ParseDirectiveRept(SMLoc DirectiveLoc); // ".rept" 282 bool ParseDirectiveIrp(SMLoc DirectiveLoc); // ".irp" 283 bool ParseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc" 284 bool ParseDirectiveEndr(SMLoc DirectiveLoc); // ".endr" 285}; 286 287/// \brief Generic implementations of directive handling, etc. which is shared 288/// (or the default, at least) for all assembler parser. 289class GenericAsmParser : public MCAsmParserExtension { 290 template<bool (GenericAsmParser::*Handler)(StringRef, SMLoc)> 291 void AddDirectiveHandler(StringRef Directive) { 292 getParser().AddDirectiveHandler(this, Directive, 293 HandleDirective<GenericAsmParser, Handler>); 294 } 295public: 296 GenericAsmParser() {} 297 298 AsmParser &getParser() { 299 return (AsmParser&) this->MCAsmParserExtension::getParser(); 300 } 301 302 virtual void Initialize(MCAsmParser &Parser) { 303 // Call the base implementation. 304 this->MCAsmParserExtension::Initialize(Parser); 305 306 // Debugging directives. 307 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveFile>(".file"); 308 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLine>(".line"); 309 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLoc>(".loc"); 310 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveStabs>(".stabs"); 311 312 // CFI directives. 313 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFISections>( 314 ".cfi_sections"); 315 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIStartProc>( 316 ".cfi_startproc"); 317 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIEndProc>( 318 ".cfi_endproc"); 319 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfa>( 320 ".cfi_def_cfa"); 321 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaOffset>( 322 ".cfi_def_cfa_offset"); 323 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIAdjustCfaOffset>( 324 ".cfi_adjust_cfa_offset"); 325 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaRegister>( 326 ".cfi_def_cfa_register"); 327 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIOffset>( 328 ".cfi_offset"); 329 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIRelOffset>( 330 ".cfi_rel_offset"); 331 AddDirectiveHandler< 332 &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_personality"); 333 AddDirectiveHandler< 334 &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_lsda"); 335 AddDirectiveHandler< 336 &GenericAsmParser::ParseDirectiveCFIRememberState>(".cfi_remember_state"); 337 AddDirectiveHandler< 338 &GenericAsmParser::ParseDirectiveCFIRestoreState>(".cfi_restore_state"); 339 AddDirectiveHandler< 340 &GenericAsmParser::ParseDirectiveCFISameValue>(".cfi_same_value"); 341 AddDirectiveHandler< 342 &GenericAsmParser::ParseDirectiveCFIRestore>(".cfi_restore"); 343 AddDirectiveHandler< 344 &GenericAsmParser::ParseDirectiveCFIEscape>(".cfi_escape"); 345 AddDirectiveHandler< 346 &GenericAsmParser::ParseDirectiveCFISignalFrame>(".cfi_signal_frame"); 347 348 // Macro directives. 349 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>( 350 ".macros_on"); 351 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>( 352 ".macros_off"); 353 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacro>(".macro"); 354 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveEndMacro>(".endm"); 355 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveEndMacro>(".endmacro"); 356 AddDirectiveHandler<&GenericAsmParser::ParseDirectivePurgeMacro>(".purgem"); 357 358 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLEB128>(".sleb128"); 359 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLEB128>(".uleb128"); 360 } 361 362 bool ParseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc); 363 364 bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc); 365 bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc); 366 bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc); 367 bool ParseDirectiveStabs(StringRef, SMLoc DirectiveLoc); 368 bool ParseDirectiveCFISections(StringRef, SMLoc DirectiveLoc); 369 bool ParseDirectiveCFIStartProc(StringRef, SMLoc DirectiveLoc); 370 bool ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc); 371 bool ParseDirectiveCFIDefCfa(StringRef, SMLoc DirectiveLoc); 372 bool ParseDirectiveCFIDefCfaOffset(StringRef, SMLoc DirectiveLoc); 373 bool ParseDirectiveCFIAdjustCfaOffset(StringRef, SMLoc DirectiveLoc); 374 bool ParseDirectiveCFIDefCfaRegister(StringRef, SMLoc DirectiveLoc); 375 bool ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc); 376 bool ParseDirectiveCFIRelOffset(StringRef, SMLoc DirectiveLoc); 377 bool ParseDirectiveCFIPersonalityOrLsda(StringRef, SMLoc DirectiveLoc); 378 bool ParseDirectiveCFIRememberState(StringRef, SMLoc DirectiveLoc); 379 bool ParseDirectiveCFIRestoreState(StringRef, SMLoc DirectiveLoc); 380 bool ParseDirectiveCFISameValue(StringRef, SMLoc DirectiveLoc); 381 bool ParseDirectiveCFIRestore(StringRef, SMLoc DirectiveLoc); 382 bool ParseDirectiveCFIEscape(StringRef, SMLoc DirectiveLoc); 383 bool ParseDirectiveCFISignalFrame(StringRef, SMLoc DirectiveLoc); 384 385 bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc); 386 bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc); 387 bool ParseDirectiveEndMacro(StringRef, SMLoc DirectiveLoc); 388 bool ParseDirectivePurgeMacro(StringRef, SMLoc DirectiveLoc); 389 390 bool ParseDirectiveLEB128(StringRef, SMLoc); 391}; 392 393} 394 395namespace llvm { 396 397extern MCAsmParserExtension *createDarwinAsmParser(); 398extern MCAsmParserExtension *createELFAsmParser(); 399extern MCAsmParserExtension *createCOFFAsmParser(); 400 401} 402 403enum { DEFAULT_ADDRSPACE = 0 }; 404 405AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, 406 MCStreamer &_Out, const MCAsmInfo &_MAI) 407 : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM), 408 GenericParser(new GenericAsmParser), PlatformParser(0), 409 CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0), 410 AssemblerDialect(~0U) { 411 // Save the old handler. 412 SavedDiagHandler = SrcMgr.getDiagHandler(); 413 SavedDiagContext = SrcMgr.getDiagContext(); 414 // Set our own handler which calls the saved handler. 415 SrcMgr.setDiagHandler(DiagHandler, this); 416 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 417 418 // Initialize the generic parser. 419 GenericParser->Initialize(*this); 420 421 // Initialize the platform / file format parser. 422 // 423 // FIXME: This is a hack, we need to (majorly) cleanup how these objects are 424 // created. 425 if (_MAI.hasMicrosoftFastStdCallMangling()) { 426 PlatformParser = createCOFFAsmParser(); 427 PlatformParser->Initialize(*this); 428 } else if (_MAI.hasSubsectionsViaSymbols()) { 429 PlatformParser = createDarwinAsmParser(); 430 PlatformParser->Initialize(*this); 431 } else { 432 PlatformParser = createELFAsmParser(); 433 PlatformParser->Initialize(*this); 434 } 435} 436 437AsmParser::~AsmParser() { 438 assert(ActiveMacros.empty() && "Unexpected active macro instantiation!"); 439 440 // Destroy any macros. 441 for (StringMap<Macro*>::iterator it = MacroMap.begin(), 442 ie = MacroMap.end(); it != ie; ++it) 443 delete it->getValue(); 444 445 delete PlatformParser; 446 delete GenericParser; 447} 448 449void AsmParser::PrintMacroInstantiations() { 450 // Print the active macro instantiation stack. 451 for (std::vector<MacroInstantiation*>::const_reverse_iterator 452 it = ActiveMacros.rbegin(), ie = ActiveMacros.rend(); it != ie; ++it) 453 PrintMessage((*it)->InstantiationLoc, SourceMgr::DK_Note, 454 "while in macro instantiation"); 455} 456 457bool AsmParser::Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { 458 if (FatalAssemblerWarnings) 459 return Error(L, Msg, Ranges); 460 PrintMessage(L, SourceMgr::DK_Warning, Msg, Ranges); 461 PrintMacroInstantiations(); 462 return false; 463} 464 465bool AsmParser::Error(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { 466 HadError = true; 467 PrintMessage(L, SourceMgr::DK_Error, Msg, Ranges); 468 PrintMacroInstantiations(); 469 return true; 470} 471 472bool AsmParser::EnterIncludeFile(const std::string &Filename) { 473 std::string IncludedFile; 474 int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); 475 if (NewBuf == -1) 476 return true; 477 478 CurBuffer = NewBuf; 479 480 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 481 482 return false; 483} 484 485/// Process the specified .incbin file by seaching for it in the include paths 486/// then just emitting the byte contents of the file to the streamer. This 487/// returns true on failure. 488bool AsmParser::ProcessIncbinFile(const std::string &Filename) { 489 std::string IncludedFile; 490 int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); 491 if (NewBuf == -1) 492 return true; 493 494 // Pick up the bytes from the file and emit them. 495 getStreamer().EmitBytes(SrcMgr.getMemoryBuffer(NewBuf)->getBuffer(), 496 DEFAULT_ADDRSPACE); 497 return false; 498} 499 500void AsmParser::JumpToLoc(SMLoc Loc) { 501 CurBuffer = SrcMgr.FindBufferContainingLoc(Loc); 502 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer), Loc.getPointer()); 503} 504 505const AsmToken &AsmParser::Lex() { 506 const AsmToken *tok = &Lexer.Lex(); 507 508 if (tok->is(AsmToken::Eof)) { 509 // If this is the end of an included file, pop the parent file off the 510 // include stack. 511 SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer); 512 if (ParentIncludeLoc != SMLoc()) { 513 JumpToLoc(ParentIncludeLoc); 514 tok = &Lexer.Lex(); 515 } 516 } 517 518 if (tok->is(AsmToken::Error)) 519 Error(Lexer.getErrLoc(), Lexer.getErr()); 520 521 return *tok; 522} 523 524bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { 525 // Create the initial section, if requested. 526 if (!NoInitialTextSection) 527 Out.InitSections(); 528 529 // Prime the lexer. 530 Lex(); 531 532 HadError = false; 533 AsmCond StartingCondState = TheCondState; 534 535 // If we are generating dwarf for assembly source files save the initial text 536 // section and generate a .file directive. 537 if (getContext().getGenDwarfForAssembly()) { 538 getContext().setGenDwarfSection(getStreamer().getCurrentSection()); 539 MCSymbol *SectionStartSym = getContext().CreateTempSymbol(); 540 getStreamer().EmitLabel(SectionStartSym); 541 getContext().setGenDwarfSectionStartSym(SectionStartSym); 542 getStreamer().EmitDwarfFileDirective(getContext().nextGenDwarfFileNumber(), 543 StringRef(), SrcMgr.getMemoryBuffer(CurBuffer)->getBufferIdentifier()); 544 } 545 546 // While we have input, parse each statement. 547 while (Lexer.isNot(AsmToken::Eof)) { 548 if (!ParseStatement()) continue; 549 550 // We had an error, validate that one was emitted and recover by skipping to 551 // the next line. 552 assert(HadError && "Parse statement returned an error, but none emitted!"); 553 EatToEndOfStatement(); 554 } 555 556 if (TheCondState.TheCond != StartingCondState.TheCond || 557 TheCondState.Ignore != StartingCondState.Ignore) 558 return TokError("unmatched .ifs or .elses"); 559 560 // Check to see there are no empty DwarfFile slots. 561 const std::vector<MCDwarfFile *> &MCDwarfFiles = 562 getContext().getMCDwarfFiles(); 563 for (unsigned i = 1; i < MCDwarfFiles.size(); i++) { 564 if (!MCDwarfFiles[i]) 565 TokError("unassigned file number: " + Twine(i) + " for .file directives"); 566 } 567 568 // Check to see that all assembler local symbols were actually defined. 569 // Targets that don't do subsections via symbols may not want this, though, 570 // so conservatively exclude them. Only do this if we're finalizing, though, 571 // as otherwise we won't necessarilly have seen everything yet. 572 if (!NoFinalize && MAI.hasSubsectionsViaSymbols()) { 573 const MCContext::SymbolTable &Symbols = getContext().getSymbols(); 574 for (MCContext::SymbolTable::const_iterator i = Symbols.begin(), 575 e = Symbols.end(); 576 i != e; ++i) { 577 MCSymbol *Sym = i->getValue(); 578 // Variable symbols may not be marked as defined, so check those 579 // explicitly. If we know it's a variable, we have a definition for 580 // the purposes of this check. 581 if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined()) 582 // FIXME: We would really like to refer back to where the symbol was 583 // first referenced for a source location. We need to add something 584 // to track that. Currently, we just point to the end of the file. 585 PrintMessage(getLexer().getLoc(), SourceMgr::DK_Error, 586 "assembler local symbol '" + Sym->getName() + 587 "' not defined"); 588 } 589 } 590 591 592 // Finalize the output stream if there are no errors and if the client wants 593 // us to. 594 if (!HadError && !NoFinalize) 595 Out.Finish(); 596 597 return HadError; 598} 599 600void AsmParser::CheckForValidSection() { 601 if (!getStreamer().getCurrentSection()) { 602 TokError("expected section directive before assembly directive"); 603 Out.SwitchSection(Ctx.getMachOSection( 604 "__TEXT", "__text", 605 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 606 0, SectionKind::getText())); 607 } 608} 609 610/// EatToEndOfStatement - Throw away the rest of the line for testing purposes. 611void AsmParser::EatToEndOfStatement() { 612 while (Lexer.isNot(AsmToken::EndOfStatement) && 613 Lexer.isNot(AsmToken::Eof)) 614 Lex(); 615 616 // Eat EOL. 617 if (Lexer.is(AsmToken::EndOfStatement)) 618 Lex(); 619} 620 621StringRef AsmParser::ParseStringToEndOfStatement() { 622 const char *Start = getTok().getLoc().getPointer(); 623 624 while (Lexer.isNot(AsmToken::EndOfStatement) && 625 Lexer.isNot(AsmToken::Eof)) 626 Lex(); 627 628 const char *End = getTok().getLoc().getPointer(); 629 return StringRef(Start, End - Start); 630} 631 632StringRef AsmParser::ParseStringToComma() { 633 const char *Start = getTok().getLoc().getPointer(); 634 635 while (Lexer.isNot(AsmToken::EndOfStatement) && 636 Lexer.isNot(AsmToken::Comma) && 637 Lexer.isNot(AsmToken::Eof)) 638 Lex(); 639 640 const char *End = getTok().getLoc().getPointer(); 641 return StringRef(Start, End - Start); 642} 643 644/// ParseParenExpr - Parse a paren expression and return it. 645/// NOTE: This assumes the leading '(' has already been consumed. 646/// 647/// parenexpr ::= expr) 648/// 649bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) { 650 if (ParseExpression(Res)) return true; 651 if (Lexer.isNot(AsmToken::RParen)) 652 return TokError("expected ')' in parentheses expression"); 653 EndLoc = Lexer.getLoc(); 654 Lex(); 655 return false; 656} 657 658/// ParseBracketExpr - Parse a bracket expression and return it. 659/// NOTE: This assumes the leading '[' has already been consumed. 660/// 661/// bracketexpr ::= expr] 662/// 663bool AsmParser::ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) { 664 if (ParseExpression(Res)) return true; 665 if (Lexer.isNot(AsmToken::RBrac)) 666 return TokError("expected ']' in brackets expression"); 667 EndLoc = Lexer.getLoc(); 668 Lex(); 669 return false; 670} 671 672/// ParsePrimaryExpr - Parse a primary expression and return it. 673/// primaryexpr ::= (parenexpr 674/// primaryexpr ::= symbol 675/// primaryexpr ::= number 676/// primaryexpr ::= '.' 677/// primaryexpr ::= ~,+,- primaryexpr 678bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { 679 switch (Lexer.getKind()) { 680 default: 681 return TokError("unknown token in expression"); 682 // If we have an error assume that we've already handled it. 683 case AsmToken::Error: 684 return true; 685 case AsmToken::Exclaim: 686 Lex(); // Eat the operator. 687 if (ParsePrimaryExpr(Res, EndLoc)) 688 return true; 689 Res = MCUnaryExpr::CreateLNot(Res, getContext()); 690 return false; 691 case AsmToken::Dollar: 692 case AsmToken::String: 693 case AsmToken::Identifier: { 694 EndLoc = Lexer.getLoc(); 695 696 StringRef Identifier; 697 if (ParseIdentifier(Identifier)) 698 return true; 699 700 // This is a symbol reference. 701 std::pair<StringRef, StringRef> Split = Identifier.split('@'); 702 MCSymbol *Sym = getContext().GetOrCreateSymbol(Split.first); 703 704 // Lookup the symbol variant if used. 705 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 706 if (Split.first.size() != Identifier.size()) { 707 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second); 708 if (Variant == MCSymbolRefExpr::VK_Invalid) { 709 Variant = MCSymbolRefExpr::VK_None; 710 return TokError("invalid variant '" + Split.second + "'"); 711 } 712 } 713 714 // If this is an absolute variable reference, substitute it now to preserve 715 // semantics in the face of reassignment. 716 if (Sym->isVariable() && isa<MCConstantExpr>(Sym->getVariableValue())) { 717 if (Variant) 718 return Error(EndLoc, "unexpected modifier on variable reference"); 719 720 Res = Sym->getVariableValue(); 721 return false; 722 } 723 724 // Otherwise create a symbol ref. 725 Res = MCSymbolRefExpr::Create(Sym, Variant, getContext()); 726 return false; 727 } 728 case AsmToken::Integer: { 729 SMLoc Loc = getTok().getLoc(); 730 int64_t IntVal = getTok().getIntVal(); 731 Res = MCConstantExpr::Create(IntVal, getContext()); 732 EndLoc = Lexer.getLoc(); 733 Lex(); // Eat token. 734 // Look for 'b' or 'f' following an Integer as a directional label 735 if (Lexer.getKind() == AsmToken::Identifier) { 736 StringRef IDVal = getTok().getString(); 737 if (IDVal == "f" || IDVal == "b"){ 738 MCSymbol *Sym = Ctx.GetDirectionalLocalSymbol(IntVal, 739 IDVal == "f" ? 1 : 0); 740 Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 741 getContext()); 742 if (IDVal == "b" && Sym->isUndefined()) 743 return Error(Loc, "invalid reference to undefined symbol"); 744 EndLoc = Lexer.getLoc(); 745 Lex(); // Eat identifier. 746 } 747 } 748 return false; 749 } 750 case AsmToken::Real: { 751 APFloat RealVal(APFloat::IEEEdouble, getTok().getString()); 752 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 753 Res = MCConstantExpr::Create(IntVal, getContext()); 754 Lex(); // Eat token. 755 return false; 756 } 757 case AsmToken::Dot: { 758 // This is a '.' reference, which references the current PC. Emit a 759 // temporary label to the streamer and refer to it. 760 MCSymbol *Sym = Ctx.CreateTempSymbol(); 761 Out.EmitLabel(Sym); 762 Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); 763 EndLoc = Lexer.getLoc(); 764 Lex(); // Eat identifier. 765 return false; 766 } 767 case AsmToken::LParen: 768 Lex(); // Eat the '('. 769 return ParseParenExpr(Res, EndLoc); 770 case AsmToken::LBrac: 771 if (!PlatformParser->HasBracketExpressions()) 772 return TokError("brackets expression not supported on this target"); 773 Lex(); // Eat the '['. 774 return ParseBracketExpr(Res, EndLoc); 775 case AsmToken::Minus: 776 Lex(); // Eat the operator. 777 if (ParsePrimaryExpr(Res, EndLoc)) 778 return true; 779 Res = MCUnaryExpr::CreateMinus(Res, getContext()); 780 return false; 781 case AsmToken::Plus: 782 Lex(); // Eat the operator. 783 if (ParsePrimaryExpr(Res, EndLoc)) 784 return true; 785 Res = MCUnaryExpr::CreatePlus(Res, getContext()); 786 return false; 787 case AsmToken::Tilde: 788 Lex(); // Eat the operator. 789 if (ParsePrimaryExpr(Res, EndLoc)) 790 return true; 791 Res = MCUnaryExpr::CreateNot(Res, getContext()); 792 return false; 793 } 794} 795 796bool AsmParser::ParseExpression(const MCExpr *&Res) { 797 SMLoc EndLoc; 798 return ParseExpression(Res, EndLoc); 799} 800 801const MCExpr * 802AsmParser::ApplyModifierToExpr(const MCExpr *E, 803 MCSymbolRefExpr::VariantKind Variant) { 804 // Recurse over the given expression, rebuilding it to apply the given variant 805 // if there is exactly one symbol. 806 switch (E->getKind()) { 807 case MCExpr::Target: 808 case MCExpr::Constant: 809 return 0; 810 811 case MCExpr::SymbolRef: { 812 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 813 814 if (SRE->getKind() != MCSymbolRefExpr::VK_None) { 815 TokError("invalid variant on expression '" + 816 getTok().getIdentifier() + "' (already modified)"); 817 return E; 818 } 819 820 return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 821 } 822 823 case MCExpr::Unary: { 824 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E); 825 const MCExpr *Sub = ApplyModifierToExpr(UE->getSubExpr(), Variant); 826 if (!Sub) 827 return 0; 828 return MCUnaryExpr::Create(UE->getOpcode(), Sub, getContext()); 829 } 830 831 case MCExpr::Binary: { 832 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 833 const MCExpr *LHS = ApplyModifierToExpr(BE->getLHS(), Variant); 834 const MCExpr *RHS = ApplyModifierToExpr(BE->getRHS(), Variant); 835 836 if (!LHS && !RHS) 837 return 0; 838 839 if (!LHS) LHS = BE->getLHS(); 840 if (!RHS) RHS = BE->getRHS(); 841 842 return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 843 } 844 } 845 846 llvm_unreachable("Invalid expression kind!"); 847} 848 849/// ParseExpression - Parse an expression and return it. 850/// 851/// expr ::= expr &&,|| expr -> lowest. 852/// expr ::= expr |,^,&,! expr 853/// expr ::= expr ==,!=,<>,<,<=,>,>= expr 854/// expr ::= expr <<,>> expr 855/// expr ::= expr +,- expr 856/// expr ::= expr *,/,% expr -> highest. 857/// expr ::= primaryexpr 858/// 859bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) { 860 // Parse the expression. 861 Res = 0; 862 if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc)) 863 return true; 864 865 // As a special case, we support 'a op b @ modifier' by rewriting the 866 // expression to include the modifier. This is inefficient, but in general we 867 // expect users to use 'a@modifier op b'. 868 if (Lexer.getKind() == AsmToken::At) { 869 Lex(); 870 871 if (Lexer.isNot(AsmToken::Identifier)) 872 return TokError("unexpected symbol modifier following '@'"); 873 874 MCSymbolRefExpr::VariantKind Variant = 875 MCSymbolRefExpr::getVariantKindForName(getTok().getIdentifier()); 876 if (Variant == MCSymbolRefExpr::VK_Invalid) 877 return TokError("invalid variant '" + getTok().getIdentifier() + "'"); 878 879 const MCExpr *ModifiedRes = ApplyModifierToExpr(Res, Variant); 880 if (!ModifiedRes) { 881 return TokError("invalid modifier '" + getTok().getIdentifier() + 882 "' (no symbols present)"); 883 } 884 885 Res = ModifiedRes; 886 Lex(); 887 } 888 889 // Try to constant fold it up front, if possible. 890 int64_t Value; 891 if (Res->EvaluateAsAbsolute(Value)) 892 Res = MCConstantExpr::Create(Value, getContext()); 893 894 return false; 895} 896 897bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) { 898 Res = 0; 899 return ParseParenExpr(Res, EndLoc) || 900 ParseBinOpRHS(1, Res, EndLoc); 901} 902 903bool AsmParser::ParseAbsoluteExpression(int64_t &Res) { 904 const MCExpr *Expr; 905 906 SMLoc StartLoc = Lexer.getLoc(); 907 if (ParseExpression(Expr)) 908 return true; 909 910 if (!Expr->EvaluateAsAbsolute(Res)) 911 return Error(StartLoc, "expected absolute expression"); 912 913 return false; 914} 915 916static unsigned getBinOpPrecedence(AsmToken::TokenKind K, 917 MCBinaryExpr::Opcode &Kind) { 918 switch (K) { 919 default: 920 return 0; // not a binop. 921 922 // Lowest Precedence: &&, || 923 case AsmToken::AmpAmp: 924 Kind = MCBinaryExpr::LAnd; 925 return 1; 926 case AsmToken::PipePipe: 927 Kind = MCBinaryExpr::LOr; 928 return 1; 929 930 931 // Low Precedence: |, &, ^ 932 // 933 // FIXME: gas seems to support '!' as an infix operator? 934 case AsmToken::Pipe: 935 Kind = MCBinaryExpr::Or; 936 return 2; 937 case AsmToken::Caret: 938 Kind = MCBinaryExpr::Xor; 939 return 2; 940 case AsmToken::Amp: 941 Kind = MCBinaryExpr::And; 942 return 2; 943 944 // Low Intermediate Precedence: ==, !=, <>, <, <=, >, >= 945 case AsmToken::EqualEqual: 946 Kind = MCBinaryExpr::EQ; 947 return 3; 948 case AsmToken::ExclaimEqual: 949 case AsmToken::LessGreater: 950 Kind = MCBinaryExpr::NE; 951 return 3; 952 case AsmToken::Less: 953 Kind = MCBinaryExpr::LT; 954 return 3; 955 case AsmToken::LessEqual: 956 Kind = MCBinaryExpr::LTE; 957 return 3; 958 case AsmToken::Greater: 959 Kind = MCBinaryExpr::GT; 960 return 3; 961 case AsmToken::GreaterEqual: 962 Kind = MCBinaryExpr::GTE; 963 return 3; 964 965 // Intermediate Precedence: <<, >> 966 case AsmToken::LessLess: 967 Kind = MCBinaryExpr::Shl; 968 return 4; 969 case AsmToken::GreaterGreater: 970 Kind = MCBinaryExpr::Shr; 971 return 4; 972 973 // High Intermediate Precedence: +, - 974 case AsmToken::Plus: 975 Kind = MCBinaryExpr::Add; 976 return 5; 977 case AsmToken::Minus: 978 Kind = MCBinaryExpr::Sub; 979 return 5; 980 981 // Highest Precedence: *, /, % 982 case AsmToken::Star: 983 Kind = MCBinaryExpr::Mul; 984 return 6; 985 case AsmToken::Slash: 986 Kind = MCBinaryExpr::Div; 987 return 6; 988 case AsmToken::Percent: 989 Kind = MCBinaryExpr::Mod; 990 return 6; 991 } 992} 993 994 995/// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'. 996/// Res contains the LHS of the expression on input. 997bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, 998 SMLoc &EndLoc) { 999 while (1) { 1000 MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add; 1001 unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind); 1002 1003 // If the next token is lower precedence than we are allowed to eat, return 1004 // successfully with what we ate already. 1005 if (TokPrec < Precedence) 1006 return false; 1007 1008 Lex(); 1009 1010 // Eat the next primary expression. 1011 const MCExpr *RHS; 1012 if (ParsePrimaryExpr(RHS, EndLoc)) return true; 1013 1014 // If BinOp binds less tightly with RHS than the operator after RHS, let 1015 // the pending operator take RHS as its LHS. 1016 MCBinaryExpr::Opcode Dummy; 1017 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy); 1018 if (TokPrec < NextTokPrec) { 1019 if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true; 1020 } 1021 1022 // Merge LHS and RHS according to operator. 1023 Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext()); 1024 } 1025} 1026 1027 1028 1029 1030/// ParseStatement: 1031/// ::= EndOfStatement 1032/// ::= Label* Directive ...Operands... EndOfStatement 1033/// ::= Label* Identifier OperandList* EndOfStatement 1034bool AsmParser::ParseStatement() { 1035 if (Lexer.is(AsmToken::EndOfStatement)) { 1036 Out.AddBlankLine(); 1037 Lex(); 1038 return false; 1039 } 1040 1041 // Statements always start with an identifier or are a full line comment. 1042 AsmToken ID = getTok(); 1043 SMLoc IDLoc = ID.getLoc(); 1044 StringRef IDVal; 1045 int64_t LocalLabelVal = -1; 1046 // A full line comment is a '#' as the first token. 1047 if (Lexer.is(AsmToken::Hash)) 1048 return ParseCppHashLineFilenameComment(IDLoc); 1049 1050 // Allow an integer followed by a ':' as a directional local label. 1051 if (Lexer.is(AsmToken::Integer)) { 1052 LocalLabelVal = getTok().getIntVal(); 1053 if (LocalLabelVal < 0) { 1054 if (!TheCondState.Ignore) 1055 return TokError("unexpected token at start of statement"); 1056 IDVal = ""; 1057 } 1058 else { 1059 IDVal = getTok().getString(); 1060 Lex(); // Consume the integer token to be used as an identifier token. 1061 if (Lexer.getKind() != AsmToken::Colon) { 1062 if (!TheCondState.Ignore) 1063 return TokError("unexpected token at start of statement"); 1064 } 1065 } 1066 1067 } else if (Lexer.is(AsmToken::Dot)) { 1068 // Treat '.' as a valid identifier in this context. 1069 Lex(); 1070 IDVal = "."; 1071 1072 } else if (ParseIdentifier(IDVal)) { 1073 if (!TheCondState.Ignore) 1074 return TokError("unexpected token at start of statement"); 1075 IDVal = ""; 1076 } 1077 1078 1079 // Handle conditional assembly here before checking for skipping. We 1080 // have to do this so that .endif isn't skipped in a ".if 0" block for 1081 // example. 1082 if (IDVal == ".if") 1083 return ParseDirectiveIf(IDLoc); 1084 if (IDVal == ".ifb") 1085 return ParseDirectiveIfb(IDLoc, true); 1086 if (IDVal == ".ifnb") 1087 return ParseDirectiveIfb(IDLoc, false); 1088 if (IDVal == ".ifc") 1089 return ParseDirectiveIfc(IDLoc, true); 1090 if (IDVal == ".ifnc") 1091 return ParseDirectiveIfc(IDLoc, false); 1092 if (IDVal == ".ifdef") 1093 return ParseDirectiveIfdef(IDLoc, true); 1094 if (IDVal == ".ifndef" || IDVal == ".ifnotdef") 1095 return ParseDirectiveIfdef(IDLoc, false); 1096 if (IDVal == ".elseif") 1097 return ParseDirectiveElseIf(IDLoc); 1098 if (IDVal == ".else") 1099 return ParseDirectiveElse(IDLoc); 1100 if (IDVal == ".endif") 1101 return ParseDirectiveEndIf(IDLoc); 1102 1103 // If we are in a ".if 0" block, ignore this statement. 1104 if (TheCondState.Ignore) { 1105 EatToEndOfStatement(); 1106 return false; 1107 } 1108 1109 // FIXME: Recurse on local labels? 1110 1111 // See what kind of statement we have. 1112 switch (Lexer.getKind()) { 1113 case AsmToken::Colon: { 1114 CheckForValidSection(); 1115 1116 // identifier ':' -> Label. 1117 Lex(); 1118 1119 // Diagnose attempt to use '.' as a label. 1120 if (IDVal == ".") 1121 return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label"); 1122 1123 // Diagnose attempt to use a variable as a label. 1124 // 1125 // FIXME: Diagnostics. Note the location of the definition as a label. 1126 // FIXME: This doesn't diagnose assignment to a symbol which has been 1127 // implicitly marked as external. 1128 MCSymbol *Sym; 1129 if (LocalLabelVal == -1) 1130 Sym = getContext().GetOrCreateSymbol(IDVal); 1131 else 1132 Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal); 1133 if (!Sym->isUndefined() || Sym->isVariable()) 1134 return Error(IDLoc, "invalid symbol redefinition"); 1135 1136 // Emit the label. 1137 Out.EmitLabel(Sym); 1138 1139 // If we are generating dwarf for assembly source files then gather the 1140 // info to make a dwarf label entry for this label if needed. 1141 if (getContext().getGenDwarfForAssembly()) 1142 MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(), 1143 IDLoc); 1144 1145 // Consume any end of statement token, if present, to avoid spurious 1146 // AddBlankLine calls(). 1147 if (Lexer.is(AsmToken::EndOfStatement)) { 1148 Lex(); 1149 if (Lexer.is(AsmToken::Eof)) 1150 return false; 1151 } 1152 1153 return ParseStatement(); 1154 } 1155 1156 case AsmToken::Equal: 1157 // identifier '=' ... -> assignment statement 1158 Lex(); 1159 1160 return ParseAssignment(IDVal, true); 1161 1162 default: // Normal instruction or directive. 1163 break; 1164 } 1165 1166 // If macros are enabled, check to see if this is a macro instantiation. 1167 if (MacrosEnabled) 1168 if (const Macro *M = MacroMap.lookup(IDVal)) 1169 return HandleMacroEntry(IDVal, IDLoc, M); 1170 1171 // Otherwise, we have a normal instruction or directive. 1172 if (IDVal[0] == '.' && IDVal != ".") { 1173 1174 // Target hook for parsing target specific directives. 1175 if (!getTargetParser().ParseDirective(ID)) 1176 return false; 1177 1178 // Assembler features 1179 if (IDVal == ".set" || IDVal == ".equ") 1180 return ParseDirectiveSet(IDVal, true); 1181 if (IDVal == ".equiv") 1182 return ParseDirectiveSet(IDVal, false); 1183 1184 // Data directives 1185 1186 if (IDVal == ".ascii") 1187 return ParseDirectiveAscii(IDVal, false); 1188 if (IDVal == ".asciz" || IDVal == ".string") 1189 return ParseDirectiveAscii(IDVal, true); 1190 1191 if (IDVal == ".byte") 1192 return ParseDirectiveValue(1); 1193 if (IDVal == ".short") 1194 return ParseDirectiveValue(2); 1195 if (IDVal == ".value") 1196 return ParseDirectiveValue(2); 1197 if (IDVal == ".2byte") 1198 return ParseDirectiveValue(2); 1199 if (IDVal == ".long") 1200 return ParseDirectiveValue(4); 1201 if (IDVal == ".int") 1202 return ParseDirectiveValue(4); 1203 if (IDVal == ".4byte") 1204 return ParseDirectiveValue(4); 1205 if (IDVal == ".quad") 1206 return ParseDirectiveValue(8); 1207 if (IDVal == ".8byte") 1208 return ParseDirectiveValue(8); 1209 if (IDVal == ".single" || IDVal == ".float") 1210 return ParseDirectiveRealValue(APFloat::IEEEsingle); 1211 if (IDVal == ".double") 1212 return ParseDirectiveRealValue(APFloat::IEEEdouble); 1213 1214 if (IDVal == ".align") { 1215 bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes(); 1216 return ParseDirectiveAlign(IsPow2, /*ExprSize=*/1); 1217 } 1218 if (IDVal == ".align32") { 1219 bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes(); 1220 return ParseDirectiveAlign(IsPow2, /*ExprSize=*/4); 1221 } 1222 if (IDVal == ".balign") 1223 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1); 1224 if (IDVal == ".balignw") 1225 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2); 1226 if (IDVal == ".balignl") 1227 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4); 1228 if (IDVal == ".p2align") 1229 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1); 1230 if (IDVal == ".p2alignw") 1231 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2); 1232 if (IDVal == ".p2alignl") 1233 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4); 1234 1235 if (IDVal == ".org") 1236 return ParseDirectiveOrg(); 1237 1238 if (IDVal == ".fill") 1239 return ParseDirectiveFill(); 1240 if (IDVal == ".space" || IDVal == ".skip") 1241 return ParseDirectiveSpace(); 1242 if (IDVal == ".zero") 1243 return ParseDirectiveZero(); 1244 1245 // Symbol attribute directives 1246 1247 if (IDVal == ".extern") { 1248 EatToEndOfStatement(); // .extern is the default, ignore it. 1249 return false; 1250 } 1251 if (IDVal == ".globl" || IDVal == ".global") 1252 return ParseDirectiveSymbolAttribute(MCSA_Global); 1253 if (IDVal == ".indirect_symbol") 1254 return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol); 1255 if (IDVal == ".lazy_reference") 1256 return ParseDirectiveSymbolAttribute(MCSA_LazyReference); 1257 if (IDVal == ".no_dead_strip") 1258 return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip); 1259 if (IDVal == ".symbol_resolver") 1260 return ParseDirectiveSymbolAttribute(MCSA_SymbolResolver); 1261 if (IDVal == ".private_extern") 1262 return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern); 1263 if (IDVal == ".reference") 1264 return ParseDirectiveSymbolAttribute(MCSA_Reference); 1265 if (IDVal == ".weak_definition") 1266 return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition); 1267 if (IDVal == ".weak_reference") 1268 return ParseDirectiveSymbolAttribute(MCSA_WeakReference); 1269 if (IDVal == ".weak_def_can_be_hidden") 1270 return ParseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate); 1271 1272 if (IDVal == ".comm" || IDVal == ".common") 1273 return ParseDirectiveComm(/*IsLocal=*/false); 1274 if (IDVal == ".lcomm") 1275 return ParseDirectiveComm(/*IsLocal=*/true); 1276 1277 if (IDVal == ".abort") 1278 return ParseDirectiveAbort(); 1279 if (IDVal == ".include") 1280 return ParseDirectiveInclude(); 1281 if (IDVal == ".incbin") 1282 return ParseDirectiveIncbin(); 1283 1284 if (IDVal == ".code16" || IDVal == ".code16gcc") 1285 return TokError(Twine(IDVal) + " not supported yet"); 1286 1287 // Macro-like directives 1288 if (IDVal == ".rept") 1289 return ParseDirectiveRept(IDLoc); 1290 if (IDVal == ".irp") 1291 return ParseDirectiveIrp(IDLoc); 1292 if (IDVal == ".irpc") 1293 return ParseDirectiveIrpc(IDLoc); 1294 if (IDVal == ".endr") 1295 return ParseDirectiveEndr(IDLoc); 1296 1297 // Look up the handler in the handler table. 1298 std::pair<MCAsmParserExtension*, DirectiveHandler> Handler = 1299 DirectiveMap.lookup(IDVal); 1300 if (Handler.first) 1301 return (*Handler.second)(Handler.first, IDVal, IDLoc); 1302 1303 1304 return Error(IDLoc, "unknown directive"); 1305 } 1306 1307 CheckForValidSection(); 1308 1309 // Canonicalize the opcode to lower case. 1310 SmallString<128> Opcode; 1311 for (unsigned i = 0, e = IDVal.size(); i != e; ++i) 1312 Opcode.push_back(tolower(IDVal[i])); 1313 1314 SmallVector<MCParsedAsmOperand*, 8> ParsedOperands; 1315 bool HadError = getTargetParser().ParseInstruction(Opcode.str(), IDLoc, 1316 ParsedOperands); 1317 1318 // Dump the parsed representation, if requested. 1319 if (getShowParsedOperands()) { 1320 SmallString<256> Str; 1321 raw_svector_ostream OS(Str); 1322 OS << "parsed instruction: ["; 1323 for (unsigned i = 0; i != ParsedOperands.size(); ++i) { 1324 if (i != 0) 1325 OS << ", "; 1326 ParsedOperands[i]->print(OS); 1327 } 1328 OS << "]"; 1329 1330 PrintMessage(IDLoc, SourceMgr::DK_Note, OS.str()); 1331 } 1332 1333 // If we are generating dwarf for assembly source files and the current 1334 // section is the initial text section then generate a .loc directive for 1335 // the instruction. 1336 if (!HadError && getContext().getGenDwarfForAssembly() && 1337 getContext().getGenDwarfSection() == getStreamer().getCurrentSection() ) { 1338 getStreamer().EmitDwarfLocDirective(getContext().getGenDwarfFileNumber(), 1339 SrcMgr.FindLineNumber(IDLoc, CurBuffer), 1340 0, DWARF2_LINE_DEFAULT_IS_STMT ? 1341 DWARF2_FLAG_IS_STMT : 0, 0, 0, 1342 StringRef()); 1343 } 1344 1345 // If parsing succeeded, match the instruction. 1346 if (!HadError) 1347 HadError = getTargetParser().MatchAndEmitInstruction(IDLoc, ParsedOperands, 1348 Out); 1349 1350 // Free any parsed operands. 1351 for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i) 1352 delete ParsedOperands[i]; 1353 1354 // Don't skip the rest of the line, the instruction parser is responsible for 1355 // that. 1356 return false; 1357} 1358 1359/// EatToEndOfLine uses the Lexer to eat the characters to the end of the line 1360/// since they may not be able to be tokenized to get to the end of line token. 1361void AsmParser::EatToEndOfLine() { 1362 if (!Lexer.is(AsmToken::EndOfStatement)) 1363 Lexer.LexUntilEndOfLine(); 1364 // Eat EOL. 1365 Lex(); 1366} 1367 1368/// ParseCppHashLineFilenameComment as this: 1369/// ::= # number "filename" 1370/// or just as a full line comment if it doesn't have a number and a string. 1371bool AsmParser::ParseCppHashLineFilenameComment(const SMLoc &L) { 1372 Lex(); // Eat the hash token. 1373 1374 if (getLexer().isNot(AsmToken::Integer)) { 1375 // Consume the line since in cases it is not a well-formed line directive, 1376 // as if were simply a full line comment. 1377 EatToEndOfLine(); 1378 return false; 1379 } 1380 1381 int64_t LineNumber = getTok().getIntVal(); 1382 Lex(); 1383 1384 if (getLexer().isNot(AsmToken::String)) { 1385 EatToEndOfLine(); 1386 return false; 1387 } 1388 1389 StringRef Filename = getTok().getString(); 1390 // Get rid of the enclosing quotes. 1391 Filename = Filename.substr(1, Filename.size()-2); 1392 1393 // Save the SMLoc, Filename and LineNumber for later use by diagnostics. 1394 CppHashLoc = L; 1395 CppHashFilename = Filename; 1396 CppHashLineNumber = LineNumber; 1397 1398 // Ignore any trailing characters, they're just comment. 1399 EatToEndOfLine(); 1400 return false; 1401} 1402 1403/// DiagHandler - will use the last parsed cpp hash line filename comment 1404/// for the Filename and LineNo if any in the diagnostic. 1405void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { 1406 const AsmParser *Parser = static_cast<const AsmParser*>(Context); 1407 raw_ostream &OS = errs(); 1408 1409 const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr(); 1410 const SMLoc &DiagLoc = Diag.getLoc(); 1411 int DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); 1412 int CppHashBuf = Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc); 1413 1414 // Like SourceMgr::PrintMessage() we need to print the include stack if any 1415 // before printing the message. 1416 int DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); 1417 if (!Parser->SavedDiagHandler && DiagCurBuffer > 0) { 1418 SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer); 1419 DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS); 1420 } 1421 1422 // If we have not parsed a cpp hash line filename comment or the source 1423 // manager changed or buffer changed (like in a nested include) then just 1424 // print the normal diagnostic using its Filename and LineNo. 1425 if (!Parser->CppHashLineNumber || 1426 &DiagSrcMgr != &Parser->SrcMgr || 1427 DiagBuf != CppHashBuf) { 1428 if (Parser->SavedDiagHandler) 1429 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext); 1430 else 1431 Diag.print(0, OS); 1432 return; 1433 } 1434 1435 // Use the CppHashFilename and calculate a line number based on the 1436 // CppHashLoc and CppHashLineNumber relative to this Diag's SMLoc for 1437 // the diagnostic. 1438 const std::string Filename = Parser->CppHashFilename; 1439 1440 int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf); 1441 int CppHashLocLineNo = 1442 Parser->SrcMgr.FindLineNumber(Parser->CppHashLoc, CppHashBuf); 1443 int LineNo = Parser->CppHashLineNumber - 1 + 1444 (DiagLocLineNo - CppHashLocLineNo); 1445 1446 SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), 1447 Filename, LineNo, Diag.getColumnNo(), 1448 Diag.getKind(), Diag.getMessage(), 1449 Diag.getLineContents(), Diag.getRanges()); 1450 1451 if (Parser->SavedDiagHandler) 1452 Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext); 1453 else 1454 NewDiag.print(0, OS); 1455} 1456 1457// FIXME: This is mostly duplicated from the function in AsmLexer.cpp. The 1458// difference being that that function accepts '@' as part of identifiers and 1459// we can't do that. AsmLexer.cpp should probably be changed to handle 1460// '@' as a special case when needed. 1461static bool isIdentifierChar(char c) { 1462 return isalnum(c) || c == '_' || c == '$' || c == '.'; 1463} 1464 1465bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, 1466 const MacroParameters &Parameters, 1467 const MacroArguments &A, 1468 const SMLoc &L) { 1469 unsigned NParameters = Parameters.size(); 1470 if (NParameters != 0 && NParameters != A.size()) 1471 return Error(L, "Wrong number of arguments"); 1472 1473 while (!Body.empty()) { 1474 // Scan for the next substitution. 1475 std::size_t End = Body.size(), Pos = 0; 1476 for (; Pos != End; ++Pos) { 1477 // Check for a substitution or escape. 1478 if (!NParameters) { 1479 // This macro has no parameters, look for $0, $1, etc. 1480 if (Body[Pos] != '$' || Pos + 1 == End) 1481 continue; 1482 1483 char Next = Body[Pos + 1]; 1484 if (Next == '$' || Next == 'n' || isdigit(Next)) 1485 break; 1486 } else { 1487 // This macro has parameters, look for \foo, \bar, etc. 1488 if (Body[Pos] == '\\' && Pos + 1 != End) 1489 break; 1490 } 1491 } 1492 1493 // Add the prefix. 1494 OS << Body.slice(0, Pos); 1495 1496 // Check if we reached the end. 1497 if (Pos == End) 1498 break; 1499 1500 if (!NParameters) { 1501 switch (Body[Pos+1]) { 1502 // $$ => $ 1503 case '$': 1504 OS << '$'; 1505 break; 1506 1507 // $n => number of arguments 1508 case 'n': 1509 OS << A.size(); 1510 break; 1511 1512 // $[0-9] => argument 1513 default: { 1514 // Missing arguments are ignored. 1515 unsigned Index = Body[Pos+1] - '0'; 1516 if (Index >= A.size()) 1517 break; 1518 1519 // Otherwise substitute with the token values, with spaces eliminated. 1520 for (MacroArgument::const_iterator it = A[Index].begin(), 1521 ie = A[Index].end(); it != ie; ++it) 1522 OS << it->getString(); 1523 break; 1524 } 1525 } 1526 Pos += 2; 1527 } else { 1528 unsigned I = Pos + 1; 1529 while (isIdentifierChar(Body[I]) && I + 1 != End) 1530 ++I; 1531 1532 const char *Begin = Body.data() + Pos +1; 1533 StringRef Argument(Begin, I - (Pos +1)); 1534 unsigned Index = 0; 1535 for (; Index < NParameters; ++Index) 1536 if (Parameters[Index] == Argument) 1537 break; 1538 1539 // FIXME: We should error at the macro definition. 1540 if (Index == NParameters) 1541 return Error(L, "Parameter not found"); 1542 1543 for (MacroArgument::const_iterator it = A[Index].begin(), 1544 ie = A[Index].end(); it != ie; ++it) 1545 OS << it->getString(); 1546 1547 Pos += 1 + Argument.size(); 1548 } 1549 // Update the scan point. 1550 Body = Body.substr(Pos); 1551 } 1552 1553 return false; 1554} 1555 1556MacroInstantiation::MacroInstantiation(const Macro *M, SMLoc IL, SMLoc EL, 1557 MemoryBuffer *I) 1558 : TheMacro(M), Instantiation(I), InstantiationLoc(IL), ExitLoc(EL) 1559{ 1560} 1561 1562/// ParseMacroArgument - Extract AsmTokens for a macro argument. 1563/// This is used for both default macro parameter values and the 1564/// arguments in macro invocations 1565bool AsmParser::ParseMacroArgument(MacroArgument &MA) { 1566 unsigned ParenLevel = 0; 1567 1568 for (;;) { 1569 if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal)) 1570 return TokError("unexpected token in macro instantiation"); 1571 1572 // HandleMacroEntry relies on not advancing the lexer here 1573 // to be able to fill in the remaining default parameter values 1574 if (Lexer.is(AsmToken::EndOfStatement)) 1575 break; 1576 if (ParenLevel == 0 && Lexer.is(AsmToken::Comma)) 1577 break; 1578 1579 // Adjust the current parentheses level. 1580 if (Lexer.is(AsmToken::LParen)) 1581 ++ParenLevel; 1582 else if (Lexer.is(AsmToken::RParen) && ParenLevel) 1583 --ParenLevel; 1584 1585 // Append the token to the current argument list. 1586 MA.push_back(getTok()); 1587 Lex(); 1588 } 1589 if (ParenLevel != 0) 1590 return TokError("unbalanced parentheses in macro argument"); 1591 return false; 1592} 1593 1594// Parse the macro instantiation arguments. 1595bool AsmParser::ParseMacroArguments(const Macro *M, MacroArguments &A) { 1596 const unsigned NParameters = M ? M->Parameters.size() : 0; 1597 1598 // Parse two kinds of macro invocations: 1599 // - macros defined without any parameters accept an arbitrary number of them 1600 // - macros defined with parameters accept at most that many of them 1601 for (unsigned Parameter = 0; !NParameters || Parameter < NParameters; 1602 ++Parameter) { 1603 MacroArgument MA; 1604 1605 if (ParseMacroArgument(MA)) 1606 return true; 1607 1608 A.push_back(MA); 1609 1610 if (Lexer.is(AsmToken::EndOfStatement)) 1611 return false; 1612 1613 if (Lexer.is(AsmToken::Comma)) 1614 Lex(); 1615 } 1616 return TokError("Too many arguments"); 1617} 1618 1619bool AsmParser::HandleMacroEntry(StringRef Name, SMLoc NameLoc, 1620 const Macro *M) { 1621 // Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate 1622 // this, although we should protect against infinite loops. 1623 if (ActiveMacros.size() == 20) 1624 return TokError("macros cannot be nested more than 20 levels deep"); 1625 1626 MacroArguments A; 1627 if (ParseMacroArguments(M, A)) 1628 return true; 1629 1630 // Remove any trailing empty arguments. Do this after-the-fact as we have 1631 // to keep empty arguments in the middle of the list or positionality 1632 // gets off. e.g., "foo 1, , 2" vs. "foo 1, 2," 1633 while (!A.empty() && A.back().empty()) 1634 A.pop_back(); 1635 1636 // Macro instantiation is lexical, unfortunately. We construct a new buffer 1637 // to hold the macro body with substitutions. 1638 SmallString<256> Buf; 1639 StringRef Body = M->Body; 1640 raw_svector_ostream OS(Buf); 1641 1642 if (expandMacro(OS, Body, M->Parameters, A, getTok().getLoc())) 1643 return true; 1644 1645 // We include the .endmacro in the buffer as our queue to exit the macro 1646 // instantiation. 1647 OS << ".endmacro\n"; 1648 1649 MemoryBuffer *Instantiation = 1650 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); 1651 1652 // Create the macro instantiation object and add to the current macro 1653 // instantiation stack. 1654 MacroInstantiation *MI = new MacroInstantiation(M, NameLoc, 1655 getTok().getLoc(), 1656 Instantiation); 1657 ActiveMacros.push_back(MI); 1658 1659 // Jump to the macro instantiation and prime the lexer. 1660 CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc()); 1661 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 1662 Lex(); 1663 1664 return false; 1665} 1666 1667void AsmParser::HandleMacroExit() { 1668 // Jump to the EndOfStatement we should return to, and consume it. 1669 JumpToLoc(ActiveMacros.back()->ExitLoc); 1670 Lex(); 1671 1672 // Pop the instantiation entry. 1673 delete ActiveMacros.back(); 1674 ActiveMacros.pop_back(); 1675} 1676 1677static bool IsUsedIn(const MCSymbol *Sym, const MCExpr *Value) { 1678 switch (Value->getKind()) { 1679 case MCExpr::Binary: { 1680 const MCBinaryExpr *BE = static_cast<const MCBinaryExpr*>(Value); 1681 return IsUsedIn(Sym, BE->getLHS()) || IsUsedIn(Sym, BE->getRHS()); 1682 break; 1683 } 1684 case MCExpr::Target: 1685 case MCExpr::Constant: 1686 return false; 1687 case MCExpr::SymbolRef: { 1688 const MCSymbol &S = static_cast<const MCSymbolRefExpr*>(Value)->getSymbol(); 1689 if (S.isVariable()) 1690 return IsUsedIn(Sym, S.getVariableValue()); 1691 return &S == Sym; 1692 } 1693 case MCExpr::Unary: 1694 return IsUsedIn(Sym, static_cast<const MCUnaryExpr*>(Value)->getSubExpr()); 1695 } 1696 1697 llvm_unreachable("Unknown expr kind!"); 1698} 1699 1700bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef) { 1701 // FIXME: Use better location, we should use proper tokens. 1702 SMLoc EqualLoc = Lexer.getLoc(); 1703 1704 const MCExpr *Value; 1705 if (ParseExpression(Value)) 1706 return true; 1707 1708 // Note: we don't count b as used in "a = b". This is to allow 1709 // a = b 1710 // b = c 1711 1712 if (Lexer.isNot(AsmToken::EndOfStatement)) 1713 return TokError("unexpected token in assignment"); 1714 1715 // Error on assignment to '.'. 1716 if (Name == ".") { 1717 return Error(EqualLoc, ("assignment to pseudo-symbol '.' is unsupported " 1718 "(use '.space' or '.org').)")); 1719 } 1720 1721 // Eat the end of statement marker. 1722 Lex(); 1723 1724 // Validate that the LHS is allowed to be a variable (either it has not been 1725 // used as a symbol, or it is an absolute symbol). 1726 MCSymbol *Sym = getContext().LookupSymbol(Name); 1727 if (Sym) { 1728 // Diagnose assignment to a label. 1729 // 1730 // FIXME: Diagnostics. Note the location of the definition as a label. 1731 // FIXME: Diagnose assignment to protected identifier (e.g., register name). 1732 if (IsUsedIn(Sym, Value)) 1733 return Error(EqualLoc, "Recursive use of '" + Name + "'"); 1734 else if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable()) 1735 ; // Allow redefinitions of undefined symbols only used in directives. 1736 else if (Sym->isVariable() && !Sym->isUsed() && allow_redef) 1737 ; // Allow redefinitions of variables that haven't yet been used. 1738 else if (!Sym->isUndefined() && (!Sym->isVariable() || !allow_redef)) 1739 return Error(EqualLoc, "redefinition of '" + Name + "'"); 1740 else if (!Sym->isVariable()) 1741 return Error(EqualLoc, "invalid assignment to '" + Name + "'"); 1742 else if (!isa<MCConstantExpr>(Sym->getVariableValue())) 1743 return Error(EqualLoc, "invalid reassignment of non-absolute variable '" + 1744 Name + "'"); 1745 1746 // Don't count these checks as uses. 1747 Sym->setUsed(false); 1748 } else 1749 Sym = getContext().GetOrCreateSymbol(Name); 1750 1751 // FIXME: Handle '.'. 1752 1753 // Do the assignment. 1754 Out.EmitAssignment(Sym, Value); 1755 1756 return false; 1757} 1758 1759/// ParseIdentifier: 1760/// ::= identifier 1761/// ::= string 1762bool AsmParser::ParseIdentifier(StringRef &Res) { 1763 // The assembler has relaxed rules for accepting identifiers, in particular we 1764 // allow things like '.globl $foo', which would normally be separate 1765 // tokens. At this level, we have already lexed so we cannot (currently) 1766 // handle this as a context dependent token, instead we detect adjacent tokens 1767 // and return the combined identifier. 1768 if (Lexer.is(AsmToken::Dollar)) { 1769 SMLoc DollarLoc = getLexer().getLoc(); 1770 1771 // Consume the dollar sign, and check for a following identifier. 1772 Lex(); 1773 if (Lexer.isNot(AsmToken::Identifier)) 1774 return true; 1775 1776 // We have a '$' followed by an identifier, make sure they are adjacent. 1777 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer()) 1778 return true; 1779 1780 // Construct the joined identifier and consume the token. 1781 Res = StringRef(DollarLoc.getPointer(), 1782 getTok().getIdentifier().size() + 1); 1783 Lex(); 1784 return false; 1785 } 1786 1787 if (Lexer.isNot(AsmToken::Identifier) && 1788 Lexer.isNot(AsmToken::String)) 1789 return true; 1790 1791 Res = getTok().getIdentifier(); 1792 1793 Lex(); // Consume the identifier token. 1794 1795 return false; 1796} 1797 1798/// ParseDirectiveSet: 1799/// ::= .equ identifier ',' expression 1800/// ::= .equiv identifier ',' expression 1801/// ::= .set identifier ',' expression 1802bool AsmParser::ParseDirectiveSet(StringRef IDVal, bool allow_redef) { 1803 StringRef Name; 1804 1805 if (ParseIdentifier(Name)) 1806 return TokError("expected identifier after '" + Twine(IDVal) + "'"); 1807 1808 if (getLexer().isNot(AsmToken::Comma)) 1809 return TokError("unexpected token in '" + Twine(IDVal) + "'"); 1810 Lex(); 1811 1812 return ParseAssignment(Name, allow_redef); 1813} 1814 1815bool AsmParser::ParseEscapedString(std::string &Data) { 1816 assert(getLexer().is(AsmToken::String) && "Unexpected current token!"); 1817 1818 Data = ""; 1819 StringRef Str = getTok().getStringContents(); 1820 for (unsigned i = 0, e = Str.size(); i != e; ++i) { 1821 if (Str[i] != '\\') { 1822 Data += Str[i]; 1823 continue; 1824 } 1825 1826 // Recognize escaped characters. Note that this escape semantics currently 1827 // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes. 1828 ++i; 1829 if (i == e) 1830 return TokError("unexpected backslash at end of string"); 1831 1832 // Recognize octal sequences. 1833 if ((unsigned) (Str[i] - '0') <= 7) { 1834 // Consume up to three octal characters. 1835 unsigned Value = Str[i] - '0'; 1836 1837 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) { 1838 ++i; 1839 Value = Value * 8 + (Str[i] - '0'); 1840 1841 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) { 1842 ++i; 1843 Value = Value * 8 + (Str[i] - '0'); 1844 } 1845 } 1846 1847 if (Value > 255) 1848 return TokError("invalid octal escape sequence (out of range)"); 1849 1850 Data += (unsigned char) Value; 1851 continue; 1852 } 1853 1854 // Otherwise recognize individual escapes. 1855 switch (Str[i]) { 1856 default: 1857 // Just reject invalid escape sequences for now. 1858 return TokError("invalid escape sequence (unrecognized character)"); 1859 1860 case 'b': Data += '\b'; break; 1861 case 'f': Data += '\f'; break; 1862 case 'n': Data += '\n'; break; 1863 case 'r': Data += '\r'; break; 1864 case 't': Data += '\t'; break; 1865 case '"': Data += '"'; break; 1866 case '\\': Data += '\\'; break; 1867 } 1868 } 1869 1870 return false; 1871} 1872 1873/// ParseDirectiveAscii: 1874/// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ] 1875bool AsmParser::ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) { 1876 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1877 CheckForValidSection(); 1878 1879 for (;;) { 1880 if (getLexer().isNot(AsmToken::String)) 1881 return TokError("expected string in '" + Twine(IDVal) + "' directive"); 1882 1883 std::string Data; 1884 if (ParseEscapedString(Data)) 1885 return true; 1886 1887 getStreamer().EmitBytes(Data, DEFAULT_ADDRSPACE); 1888 if (ZeroTerminated) 1889 getStreamer().EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE); 1890 1891 Lex(); 1892 1893 if (getLexer().is(AsmToken::EndOfStatement)) 1894 break; 1895 1896 if (getLexer().isNot(AsmToken::Comma)) 1897 return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); 1898 Lex(); 1899 } 1900 } 1901 1902 Lex(); 1903 return false; 1904} 1905 1906/// ParseDirectiveValue 1907/// ::= (.byte | .short | ... ) [ expression (, expression)* ] 1908bool AsmParser::ParseDirectiveValue(unsigned Size) { 1909 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1910 CheckForValidSection(); 1911 1912 for (;;) { 1913 const MCExpr *Value; 1914 SMLoc ExprLoc = getLexer().getLoc(); 1915 if (ParseExpression(Value)) 1916 return true; 1917 1918 // Special case constant expressions to match code generator. 1919 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 1920 assert(Size <= 8 && "Invalid size"); 1921 uint64_t IntValue = MCE->getValue(); 1922 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue)) 1923 return Error(ExprLoc, "literal value out of range for directive"); 1924 getStreamer().EmitIntValue(IntValue, Size, DEFAULT_ADDRSPACE); 1925 } else 1926 getStreamer().EmitValue(Value, Size, DEFAULT_ADDRSPACE); 1927 1928 if (getLexer().is(AsmToken::EndOfStatement)) 1929 break; 1930 1931 // FIXME: Improve diagnostic. 1932 if (getLexer().isNot(AsmToken::Comma)) 1933 return TokError("unexpected token in directive"); 1934 Lex(); 1935 } 1936 } 1937 1938 Lex(); 1939 return false; 1940} 1941 1942/// ParseDirectiveRealValue 1943/// ::= (.single | .double) [ expression (, expression)* ] 1944bool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) { 1945 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1946 CheckForValidSection(); 1947 1948 for (;;) { 1949 // We don't truly support arithmetic on floating point expressions, so we 1950 // have to manually parse unary prefixes. 1951 bool IsNeg = false; 1952 if (getLexer().is(AsmToken::Minus)) { 1953 Lex(); 1954 IsNeg = true; 1955 } else if (getLexer().is(AsmToken::Plus)) 1956 Lex(); 1957 1958 if (getLexer().isNot(AsmToken::Integer) && 1959 getLexer().isNot(AsmToken::Real) && 1960 getLexer().isNot(AsmToken::Identifier)) 1961 return TokError("unexpected token in directive"); 1962 1963 // Convert to an APFloat. 1964 APFloat Value(Semantics); 1965 StringRef IDVal = getTok().getString(); 1966 if (getLexer().is(AsmToken::Identifier)) { 1967 if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf")) 1968 Value = APFloat::getInf(Semantics); 1969 else if (!IDVal.compare_lower("nan")) 1970 Value = APFloat::getNaN(Semantics, false, ~0); 1971 else 1972 return TokError("invalid floating point literal"); 1973 } else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) == 1974 APFloat::opInvalidOp) 1975 return TokError("invalid floating point literal"); 1976 if (IsNeg) 1977 Value.changeSign(); 1978 1979 // Consume the numeric token. 1980 Lex(); 1981 1982 // Emit the value as an integer. 1983 APInt AsInt = Value.bitcastToAPInt(); 1984 getStreamer().EmitIntValue(AsInt.getLimitedValue(), 1985 AsInt.getBitWidth() / 8, DEFAULT_ADDRSPACE); 1986 1987 if (getLexer().is(AsmToken::EndOfStatement)) 1988 break; 1989 1990 if (getLexer().isNot(AsmToken::Comma)) 1991 return TokError("unexpected token in directive"); 1992 Lex(); 1993 } 1994 } 1995 1996 Lex(); 1997 return false; 1998} 1999 2000/// ParseDirectiveSpace 2001/// ::= .space expression [ , expression ] 2002bool AsmParser::ParseDirectiveSpace() { 2003 CheckForValidSection(); 2004 2005 int64_t NumBytes; 2006 if (ParseAbsoluteExpression(NumBytes)) 2007 return true; 2008 2009 int64_t FillExpr = 0; 2010 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2011 if (getLexer().isNot(AsmToken::Comma)) 2012 return TokError("unexpected token in '.space' directive"); 2013 Lex(); 2014 2015 if (ParseAbsoluteExpression(FillExpr)) 2016 return true; 2017 2018 if (getLexer().isNot(AsmToken::EndOfStatement)) 2019 return TokError("unexpected token in '.space' directive"); 2020 } 2021 2022 Lex(); 2023 2024 if (NumBytes <= 0) 2025 return TokError("invalid number of bytes in '.space' directive"); 2026 2027 // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0. 2028 getStreamer().EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE); 2029 2030 return false; 2031} 2032 2033/// ParseDirectiveZero 2034/// ::= .zero expression 2035bool AsmParser::ParseDirectiveZero() { 2036 CheckForValidSection(); 2037 2038 int64_t NumBytes; 2039 if (ParseAbsoluteExpression(NumBytes)) 2040 return true; 2041 2042 int64_t Val = 0; 2043 if (getLexer().is(AsmToken::Comma)) { 2044 Lex(); 2045 if (ParseAbsoluteExpression(Val)) 2046 return true; 2047 } 2048 2049 if (getLexer().isNot(AsmToken::EndOfStatement)) 2050 return TokError("unexpected token in '.zero' directive"); 2051 2052 Lex(); 2053 2054 getStreamer().EmitFill(NumBytes, Val, DEFAULT_ADDRSPACE); 2055 2056 return false; 2057} 2058 2059/// ParseDirectiveFill 2060/// ::= .fill expression , expression , expression 2061bool AsmParser::ParseDirectiveFill() { 2062 CheckForValidSection(); 2063 2064 int64_t NumValues; 2065 if (ParseAbsoluteExpression(NumValues)) 2066 return true; 2067 2068 if (getLexer().isNot(AsmToken::Comma)) 2069 return TokError("unexpected token in '.fill' directive"); 2070 Lex(); 2071 2072 int64_t FillSize; 2073 if (ParseAbsoluteExpression(FillSize)) 2074 return true; 2075 2076 if (getLexer().isNot(AsmToken::Comma)) 2077 return TokError("unexpected token in '.fill' directive"); 2078 Lex(); 2079 2080 int64_t FillExpr; 2081 if (ParseAbsoluteExpression(FillExpr)) 2082 return true; 2083 2084 if (getLexer().isNot(AsmToken::EndOfStatement)) 2085 return TokError("unexpected token in '.fill' directive"); 2086 2087 Lex(); 2088 2089 if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8) 2090 return TokError("invalid '.fill' size, expected 1, 2, 4, or 8"); 2091 2092 for (uint64_t i = 0, e = NumValues; i != e; ++i) 2093 getStreamer().EmitIntValue(FillExpr, FillSize, DEFAULT_ADDRSPACE); 2094 2095 return false; 2096} 2097 2098/// ParseDirectiveOrg 2099/// ::= .org expression [ , expression ] 2100bool AsmParser::ParseDirectiveOrg() { 2101 CheckForValidSection(); 2102 2103 const MCExpr *Offset; 2104 SMLoc Loc = getTok().getLoc(); 2105 if (ParseExpression(Offset)) 2106 return true; 2107 2108 // Parse optional fill expression. 2109 int64_t FillExpr = 0; 2110 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2111 if (getLexer().isNot(AsmToken::Comma)) 2112 return TokError("unexpected token in '.org' directive"); 2113 Lex(); 2114 2115 if (ParseAbsoluteExpression(FillExpr)) 2116 return true; 2117 2118 if (getLexer().isNot(AsmToken::EndOfStatement)) 2119 return TokError("unexpected token in '.org' directive"); 2120 } 2121 2122 Lex(); 2123 2124 // Only limited forms of relocatable expressions are accepted here, it 2125 // has to be relative to the current section. The streamer will return 2126 // 'true' if the expression wasn't evaluatable. 2127 if (getStreamer().EmitValueToOffset(Offset, FillExpr)) 2128 return Error(Loc, "expected assembly-time absolute expression"); 2129 2130 return false; 2131} 2132 2133/// ParseDirectiveAlign 2134/// ::= {.align, ...} expression [ , expression [ , expression ]] 2135bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) { 2136 CheckForValidSection(); 2137 2138 SMLoc AlignmentLoc = getLexer().getLoc(); 2139 int64_t Alignment; 2140 if (ParseAbsoluteExpression(Alignment)) 2141 return true; 2142 2143 SMLoc MaxBytesLoc; 2144 bool HasFillExpr = false; 2145 int64_t FillExpr = 0; 2146 int64_t MaxBytesToFill = 0; 2147 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2148 if (getLexer().isNot(AsmToken::Comma)) 2149 return TokError("unexpected token in directive"); 2150 Lex(); 2151 2152 // The fill expression can be omitted while specifying a maximum number of 2153 // alignment bytes, e.g: 2154 // .align 3,,4 2155 if (getLexer().isNot(AsmToken::Comma)) { 2156 HasFillExpr = true; 2157 if (ParseAbsoluteExpression(FillExpr)) 2158 return true; 2159 } 2160 2161 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2162 if (getLexer().isNot(AsmToken::Comma)) 2163 return TokError("unexpected token in directive"); 2164 Lex(); 2165 2166 MaxBytesLoc = getLexer().getLoc(); 2167 if (ParseAbsoluteExpression(MaxBytesToFill)) 2168 return true; 2169 2170 if (getLexer().isNot(AsmToken::EndOfStatement)) 2171 return TokError("unexpected token in directive"); 2172 } 2173 } 2174 2175 Lex(); 2176 2177 if (!HasFillExpr) 2178 FillExpr = 0; 2179 2180 // Compute alignment in bytes. 2181 if (IsPow2) { 2182 // FIXME: Diagnose overflow. 2183 if (Alignment >= 32) { 2184 Error(AlignmentLoc, "invalid alignment value"); 2185 Alignment = 31; 2186 } 2187 2188 Alignment = 1ULL << Alignment; 2189 } 2190 2191 // Diagnose non-sensical max bytes to align. 2192 if (MaxBytesLoc.isValid()) { 2193 if (MaxBytesToFill < 1) { 2194 Error(MaxBytesLoc, "alignment directive can never be satisfied in this " 2195 "many bytes, ignoring maximum bytes expression"); 2196 MaxBytesToFill = 0; 2197 } 2198 2199 if (MaxBytesToFill >= Alignment) { 2200 Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and " 2201 "has no effect"); 2202 MaxBytesToFill = 0; 2203 } 2204 } 2205 2206 // Check whether we should use optimal code alignment for this .align 2207 // directive. 2208 bool UseCodeAlign = getStreamer().getCurrentSection()->UseCodeAlign(); 2209 if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) && 2210 ValueSize == 1 && UseCodeAlign) { 2211 getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill); 2212 } else { 2213 // FIXME: Target specific behavior about how the "extra" bytes are filled. 2214 getStreamer().EmitValueToAlignment(Alignment, FillExpr, ValueSize, 2215 MaxBytesToFill); 2216 } 2217 2218 return false; 2219} 2220 2221/// ParseDirectiveSymbolAttribute 2222/// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ] 2223bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) { 2224 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2225 for (;;) { 2226 StringRef Name; 2227 SMLoc Loc = getTok().getLoc(); 2228 2229 if (ParseIdentifier(Name)) 2230 return Error(Loc, "expected identifier in directive"); 2231 2232 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 2233 2234 // Assembler local symbols don't make any sense here. Complain loudly. 2235 if (Sym->isTemporary()) 2236 return Error(Loc, "non-local symbol required in directive"); 2237 2238 getStreamer().EmitSymbolAttribute(Sym, Attr); 2239 2240 if (getLexer().is(AsmToken::EndOfStatement)) 2241 break; 2242 2243 if (getLexer().isNot(AsmToken::Comma)) 2244 return TokError("unexpected token in directive"); 2245 Lex(); 2246 } 2247 } 2248 2249 Lex(); 2250 return false; 2251} 2252 2253/// ParseDirectiveComm 2254/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ] 2255bool AsmParser::ParseDirectiveComm(bool IsLocal) { 2256 CheckForValidSection(); 2257 2258 SMLoc IDLoc = getLexer().getLoc(); 2259 StringRef Name; 2260 if (ParseIdentifier(Name)) 2261 return TokError("expected identifier in directive"); 2262 2263 // Handle the identifier as the key symbol. 2264 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 2265 2266 if (getLexer().isNot(AsmToken::Comma)) 2267 return TokError("unexpected token in directive"); 2268 Lex(); 2269 2270 int64_t Size; 2271 SMLoc SizeLoc = getLexer().getLoc(); 2272 if (ParseAbsoluteExpression(Size)) 2273 return true; 2274 2275 int64_t Pow2Alignment = 0; 2276 SMLoc Pow2AlignmentLoc; 2277 if (getLexer().is(AsmToken::Comma)) { 2278 Lex(); 2279 Pow2AlignmentLoc = getLexer().getLoc(); 2280 if (ParseAbsoluteExpression(Pow2Alignment)) 2281 return true; 2282 2283 LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType(); 2284 if (IsLocal && LCOMM == LCOMM::NoAlignment) 2285 return Error(Pow2AlignmentLoc, "alignment not supported on this target"); 2286 2287 // If this target takes alignments in bytes (not log) validate and convert. 2288 if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) || 2289 (IsLocal && LCOMM == LCOMM::ByteAlignment)) { 2290 if (!isPowerOf2_64(Pow2Alignment)) 2291 return Error(Pow2AlignmentLoc, "alignment must be a power of 2"); 2292 Pow2Alignment = Log2_64(Pow2Alignment); 2293 } 2294 } 2295 2296 if (getLexer().isNot(AsmToken::EndOfStatement)) 2297 return TokError("unexpected token in '.comm' or '.lcomm' directive"); 2298 2299 Lex(); 2300 2301 // NOTE: a size of zero for a .comm should create a undefined symbol 2302 // but a size of .lcomm creates a bss symbol of size zero. 2303 if (Size < 0) 2304 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't " 2305 "be less than zero"); 2306 2307 // NOTE: The alignment in the directive is a power of 2 value, the assembler 2308 // may internally end up wanting an alignment in bytes. 2309 // FIXME: Diagnose overflow. 2310 if (Pow2Alignment < 0) 2311 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive " 2312 "alignment, can't be less than zero"); 2313 2314 if (!Sym->isUndefined()) 2315 return Error(IDLoc, "invalid symbol redefinition"); 2316 2317 // Create the Symbol as a common or local common with Size and Pow2Alignment 2318 if (IsLocal) { 2319 getStreamer().EmitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment); 2320 return false; 2321 } 2322 2323 getStreamer().EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment); 2324 return false; 2325} 2326 2327/// ParseDirectiveAbort 2328/// ::= .abort [... message ...] 2329bool AsmParser::ParseDirectiveAbort() { 2330 // FIXME: Use loc from directive. 2331 SMLoc Loc = getLexer().getLoc(); 2332 2333 StringRef Str = ParseStringToEndOfStatement(); 2334 if (getLexer().isNot(AsmToken::EndOfStatement)) 2335 return TokError("unexpected token in '.abort' directive"); 2336 2337 Lex(); 2338 2339 if (Str.empty()) 2340 Error(Loc, ".abort detected. Assembly stopping."); 2341 else 2342 Error(Loc, ".abort '" + Str + "' detected. Assembly stopping."); 2343 // FIXME: Actually abort assembly here. 2344 2345 return false; 2346} 2347 2348/// ParseDirectiveInclude 2349/// ::= .include "filename" 2350bool AsmParser::ParseDirectiveInclude() { 2351 if (getLexer().isNot(AsmToken::String)) 2352 return TokError("expected string in '.include' directive"); 2353 2354 std::string Filename = getTok().getString(); 2355 SMLoc IncludeLoc = getLexer().getLoc(); 2356 Lex(); 2357 2358 if (getLexer().isNot(AsmToken::EndOfStatement)) 2359 return TokError("unexpected token in '.include' directive"); 2360 2361 // Strip the quotes. 2362 Filename = Filename.substr(1, Filename.size()-2); 2363 2364 // Attempt to switch the lexer to the included file before consuming the end 2365 // of statement to avoid losing it when we switch. 2366 if (EnterIncludeFile(Filename)) { 2367 Error(IncludeLoc, "Could not find include file '" + Filename + "'"); 2368 return true; 2369 } 2370 2371 return false; 2372} 2373 2374/// ParseDirectiveIncbin 2375/// ::= .incbin "filename" 2376bool AsmParser::ParseDirectiveIncbin() { 2377 if (getLexer().isNot(AsmToken::String)) 2378 return TokError("expected string in '.incbin' directive"); 2379 2380 std::string Filename = getTok().getString(); 2381 SMLoc IncbinLoc = getLexer().getLoc(); 2382 Lex(); 2383 2384 if (getLexer().isNot(AsmToken::EndOfStatement)) 2385 return TokError("unexpected token in '.incbin' directive"); 2386 2387 // Strip the quotes. 2388 Filename = Filename.substr(1, Filename.size()-2); 2389 2390 // Attempt to process the included file. 2391 if (ProcessIncbinFile(Filename)) { 2392 Error(IncbinLoc, "Could not find incbin file '" + Filename + "'"); 2393 return true; 2394 } 2395 2396 return false; 2397} 2398 2399/// ParseDirectiveIf 2400/// ::= .if expression 2401bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) { 2402 TheCondStack.push_back(TheCondState); 2403 TheCondState.TheCond = AsmCond::IfCond; 2404 if (TheCondState.Ignore) { 2405 EatToEndOfStatement(); 2406 } else { 2407 int64_t ExprValue; 2408 if (ParseAbsoluteExpression(ExprValue)) 2409 return true; 2410 2411 if (getLexer().isNot(AsmToken::EndOfStatement)) 2412 return TokError("unexpected token in '.if' directive"); 2413 2414 Lex(); 2415 2416 TheCondState.CondMet = ExprValue; 2417 TheCondState.Ignore = !TheCondState.CondMet; 2418 } 2419 2420 return false; 2421} 2422 2423/// ParseDirectiveIfb 2424/// ::= .ifb string 2425bool AsmParser::ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) { 2426 TheCondStack.push_back(TheCondState); 2427 TheCondState.TheCond = AsmCond::IfCond; 2428 2429 if (TheCondState.Ignore) { 2430 EatToEndOfStatement(); 2431 } else { 2432 StringRef Str = ParseStringToEndOfStatement(); 2433 2434 if (getLexer().isNot(AsmToken::EndOfStatement)) 2435 return TokError("unexpected token in '.ifb' directive"); 2436 2437 Lex(); 2438 2439 TheCondState.CondMet = ExpectBlank == Str.empty(); 2440 TheCondState.Ignore = !TheCondState.CondMet; 2441 } 2442 2443 return false; 2444} 2445 2446/// ParseDirectiveIfc 2447/// ::= .ifc string1, string2 2448bool AsmParser::ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) { 2449 TheCondStack.push_back(TheCondState); 2450 TheCondState.TheCond = AsmCond::IfCond; 2451 2452 if (TheCondState.Ignore) { 2453 EatToEndOfStatement(); 2454 } else { 2455 StringRef Str1 = ParseStringToComma(); 2456 2457 if (getLexer().isNot(AsmToken::Comma)) 2458 return TokError("unexpected token in '.ifc' directive"); 2459 2460 Lex(); 2461 2462 StringRef Str2 = ParseStringToEndOfStatement(); 2463 2464 if (getLexer().isNot(AsmToken::EndOfStatement)) 2465 return TokError("unexpected token in '.ifc' directive"); 2466 2467 Lex(); 2468 2469 TheCondState.CondMet = ExpectEqual == (Str1 == Str2); 2470 TheCondState.Ignore = !TheCondState.CondMet; 2471 } 2472 2473 return false; 2474} 2475 2476/// ParseDirectiveIfdef 2477/// ::= .ifdef symbol 2478bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { 2479 StringRef Name; 2480 TheCondStack.push_back(TheCondState); 2481 TheCondState.TheCond = AsmCond::IfCond; 2482 2483 if (TheCondState.Ignore) { 2484 EatToEndOfStatement(); 2485 } else { 2486 if (ParseIdentifier(Name)) 2487 return TokError("expected identifier after '.ifdef'"); 2488 2489 Lex(); 2490 2491 MCSymbol *Sym = getContext().LookupSymbol(Name); 2492 2493 if (expect_defined) 2494 TheCondState.CondMet = (Sym != NULL && !Sym->isUndefined()); 2495 else 2496 TheCondState.CondMet = (Sym == NULL || Sym->isUndefined()); 2497 TheCondState.Ignore = !TheCondState.CondMet; 2498 } 2499 2500 return false; 2501} 2502 2503/// ParseDirectiveElseIf 2504/// ::= .elseif expression 2505bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) { 2506 if (TheCondState.TheCond != AsmCond::IfCond && 2507 TheCondState.TheCond != AsmCond::ElseIfCond) 2508 Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or " 2509 " an .elseif"); 2510 TheCondState.TheCond = AsmCond::ElseIfCond; 2511 2512 bool LastIgnoreState = false; 2513 if (!TheCondStack.empty()) 2514 LastIgnoreState = TheCondStack.back().Ignore; 2515 if (LastIgnoreState || TheCondState.CondMet) { 2516 TheCondState.Ignore = true; 2517 EatToEndOfStatement(); 2518 } 2519 else { 2520 int64_t ExprValue; 2521 if (ParseAbsoluteExpression(ExprValue)) 2522 return true; 2523 2524 if (getLexer().isNot(AsmToken::EndOfStatement)) 2525 return TokError("unexpected token in '.elseif' directive"); 2526 2527 Lex(); 2528 TheCondState.CondMet = ExprValue; 2529 TheCondState.Ignore = !TheCondState.CondMet; 2530 } 2531 2532 return false; 2533} 2534 2535/// ParseDirectiveElse 2536/// ::= .else 2537bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) { 2538 if (getLexer().isNot(AsmToken::EndOfStatement)) 2539 return TokError("unexpected token in '.else' directive"); 2540 2541 Lex(); 2542 2543 if (TheCondState.TheCond != AsmCond::IfCond && 2544 TheCondState.TheCond != AsmCond::ElseIfCond) 2545 Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an " 2546 ".elseif"); 2547 TheCondState.TheCond = AsmCond::ElseCond; 2548 bool LastIgnoreState = false; 2549 if (!TheCondStack.empty()) 2550 LastIgnoreState = TheCondStack.back().Ignore; 2551 if (LastIgnoreState || TheCondState.CondMet) 2552 TheCondState.Ignore = true; 2553 else 2554 TheCondState.Ignore = false; 2555 2556 return false; 2557} 2558 2559/// ParseDirectiveEndIf 2560/// ::= .endif 2561bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) { 2562 if (getLexer().isNot(AsmToken::EndOfStatement)) 2563 return TokError("unexpected token in '.endif' directive"); 2564 2565 Lex(); 2566 2567 if ((TheCondState.TheCond == AsmCond::NoCond) || 2568 TheCondStack.empty()) 2569 Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or " 2570 ".else"); 2571 if (!TheCondStack.empty()) { 2572 TheCondState = TheCondStack.back(); 2573 TheCondStack.pop_back(); 2574 } 2575 2576 return false; 2577} 2578 2579/// ParseDirectiveFile 2580/// ::= .file [number] filename 2581/// ::= .file number directory filename 2582bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) { 2583 // FIXME: I'm not sure what this is. 2584 int64_t FileNumber = -1; 2585 SMLoc FileNumberLoc = getLexer().getLoc(); 2586 if (getLexer().is(AsmToken::Integer)) { 2587 FileNumber = getTok().getIntVal(); 2588 Lex(); 2589 2590 if (FileNumber < 1) 2591 return TokError("file number less than one"); 2592 } 2593 2594 if (getLexer().isNot(AsmToken::String)) 2595 return TokError("unexpected token in '.file' directive"); 2596 2597 // Usually the directory and filename together, otherwise just the directory. 2598 StringRef Path = getTok().getString(); 2599 Path = Path.substr(1, Path.size()-2); 2600 Lex(); 2601 2602 StringRef Directory; 2603 StringRef Filename; 2604 if (getLexer().is(AsmToken::String)) { 2605 if (FileNumber == -1) 2606 return TokError("explicit path specified, but no file number"); 2607 Filename = getTok().getString(); 2608 Filename = Filename.substr(1, Filename.size()-2); 2609 Directory = Path; 2610 Lex(); 2611 } else { 2612 Filename = Path; 2613 } 2614 2615 if (getLexer().isNot(AsmToken::EndOfStatement)) 2616 return TokError("unexpected token in '.file' directive"); 2617 2618 if (FileNumber == -1) 2619 getStreamer().EmitFileDirective(Filename); 2620 else { 2621 if (getContext().getGenDwarfForAssembly() == true) 2622 Error(DirectiveLoc, "input can't have .file dwarf directives when -g is " 2623 "used to generate dwarf debug info for assembly code"); 2624 2625 if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename)) 2626 Error(FileNumberLoc, "file number already allocated"); 2627 } 2628 2629 return false; 2630} 2631 2632/// ParseDirectiveLine 2633/// ::= .line [number] 2634bool GenericAsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) { 2635 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2636 if (getLexer().isNot(AsmToken::Integer)) 2637 return TokError("unexpected token in '.line' directive"); 2638 2639 int64_t LineNumber = getTok().getIntVal(); 2640 (void) LineNumber; 2641 Lex(); 2642 2643 // FIXME: Do something with the .line. 2644 } 2645 2646 if (getLexer().isNot(AsmToken::EndOfStatement)) 2647 return TokError("unexpected token in '.line' directive"); 2648 2649 return false; 2650} 2651 2652 2653/// ParseDirectiveLoc 2654/// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end] 2655/// [epilogue_begin] [is_stmt VALUE] [isa VALUE] 2656/// The first number is a file number, must have been previously assigned with 2657/// a .file directive, the second number is the line number and optionally the 2658/// third number is a column position (zero if not specified). The remaining 2659/// optional items are .loc sub-directives. 2660bool GenericAsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) { 2661 2662 if (getLexer().isNot(AsmToken::Integer)) 2663 return TokError("unexpected token in '.loc' directive"); 2664 int64_t FileNumber = getTok().getIntVal(); 2665 if (FileNumber < 1) 2666 return TokError("file number less than one in '.loc' directive"); 2667 if (!getContext().isValidDwarfFileNumber(FileNumber)) 2668 return TokError("unassigned file number in '.loc' directive"); 2669 Lex(); 2670 2671 int64_t LineNumber = 0; 2672 if (getLexer().is(AsmToken::Integer)) { 2673 LineNumber = getTok().getIntVal(); 2674 if (LineNumber < 1) 2675 return TokError("line number less than one in '.loc' directive"); 2676 Lex(); 2677 } 2678 2679 int64_t ColumnPos = 0; 2680 if (getLexer().is(AsmToken::Integer)) { 2681 ColumnPos = getTok().getIntVal(); 2682 if (ColumnPos < 0) 2683 return TokError("column position less than zero in '.loc' directive"); 2684 Lex(); 2685 } 2686 2687 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 2688 unsigned Isa = 0; 2689 int64_t Discriminator = 0; 2690 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2691 for (;;) { 2692 if (getLexer().is(AsmToken::EndOfStatement)) 2693 break; 2694 2695 StringRef Name; 2696 SMLoc Loc = getTok().getLoc(); 2697 if (getParser().ParseIdentifier(Name)) 2698 return TokError("unexpected token in '.loc' directive"); 2699 2700 if (Name == "basic_block") 2701 Flags |= DWARF2_FLAG_BASIC_BLOCK; 2702 else if (Name == "prologue_end") 2703 Flags |= DWARF2_FLAG_PROLOGUE_END; 2704 else if (Name == "epilogue_begin") 2705 Flags |= DWARF2_FLAG_EPILOGUE_BEGIN; 2706 else if (Name == "is_stmt") { 2707 SMLoc Loc = getTok().getLoc(); 2708 const MCExpr *Value; 2709 if (getParser().ParseExpression(Value)) 2710 return true; 2711 // The expression must be the constant 0 or 1. 2712 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 2713 int Value = MCE->getValue(); 2714 if (Value == 0) 2715 Flags &= ~DWARF2_FLAG_IS_STMT; 2716 else if (Value == 1) 2717 Flags |= DWARF2_FLAG_IS_STMT; 2718 else 2719 return Error(Loc, "is_stmt value not 0 or 1"); 2720 } 2721 else { 2722 return Error(Loc, "is_stmt value not the constant value of 0 or 1"); 2723 } 2724 } 2725 else if (Name == "isa") { 2726 SMLoc Loc = getTok().getLoc(); 2727 const MCExpr *Value; 2728 if (getParser().ParseExpression(Value)) 2729 return true; 2730 // The expression must be a constant greater or equal to 0. 2731 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 2732 int Value = MCE->getValue(); 2733 if (Value < 0) 2734 return Error(Loc, "isa number less than zero"); 2735 Isa = Value; 2736 } 2737 else { 2738 return Error(Loc, "isa number not a constant value"); 2739 } 2740 } 2741 else if (Name == "discriminator") { 2742 if (getParser().ParseAbsoluteExpression(Discriminator)) 2743 return true; 2744 } 2745 else { 2746 return Error(Loc, "unknown sub-directive in '.loc' directive"); 2747 } 2748 2749 if (getLexer().is(AsmToken::EndOfStatement)) 2750 break; 2751 } 2752 } 2753 2754 getStreamer().EmitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags, 2755 Isa, Discriminator, StringRef()); 2756 2757 return false; 2758} 2759 2760/// ParseDirectiveStabs 2761/// ::= .stabs string, number, number, number 2762bool GenericAsmParser::ParseDirectiveStabs(StringRef Directive, 2763 SMLoc DirectiveLoc) { 2764 return TokError("unsupported directive '" + Directive + "'"); 2765} 2766 2767/// ParseDirectiveCFISections 2768/// ::= .cfi_sections section [, section] 2769bool GenericAsmParser::ParseDirectiveCFISections(StringRef, 2770 SMLoc DirectiveLoc) { 2771 StringRef Name; 2772 bool EH = false; 2773 bool Debug = false; 2774 2775 if (getParser().ParseIdentifier(Name)) 2776 return TokError("Expected an identifier"); 2777 2778 if (Name == ".eh_frame") 2779 EH = true; 2780 else if (Name == ".debug_frame") 2781 Debug = true; 2782 2783 if (getLexer().is(AsmToken::Comma)) { 2784 Lex(); 2785 2786 if (getParser().ParseIdentifier(Name)) 2787 return TokError("Expected an identifier"); 2788 2789 if (Name == ".eh_frame") 2790 EH = true; 2791 else if (Name == ".debug_frame") 2792 Debug = true; 2793 } 2794 2795 getStreamer().EmitCFISections(EH, Debug); 2796 2797 return false; 2798} 2799 2800/// ParseDirectiveCFIStartProc 2801/// ::= .cfi_startproc 2802bool GenericAsmParser::ParseDirectiveCFIStartProc(StringRef, 2803 SMLoc DirectiveLoc) { 2804 getStreamer().EmitCFIStartProc(); 2805 return false; 2806} 2807 2808/// ParseDirectiveCFIEndProc 2809/// ::= .cfi_endproc 2810bool GenericAsmParser::ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc) { 2811 getStreamer().EmitCFIEndProc(); 2812 return false; 2813} 2814 2815/// ParseRegisterOrRegisterNumber - parse register name or number. 2816bool GenericAsmParser::ParseRegisterOrRegisterNumber(int64_t &Register, 2817 SMLoc DirectiveLoc) { 2818 unsigned RegNo; 2819 2820 if (getLexer().isNot(AsmToken::Integer)) { 2821 if (getParser().getTargetParser().ParseRegister(RegNo, DirectiveLoc, 2822 DirectiveLoc)) 2823 return true; 2824 Register = getContext().getRegisterInfo().getDwarfRegNum(RegNo, true); 2825 } else 2826 return getParser().ParseAbsoluteExpression(Register); 2827 2828 return false; 2829} 2830 2831/// ParseDirectiveCFIDefCfa 2832/// ::= .cfi_def_cfa register, offset 2833bool GenericAsmParser::ParseDirectiveCFIDefCfa(StringRef, 2834 SMLoc DirectiveLoc) { 2835 int64_t Register = 0; 2836 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 2837 return true; 2838 2839 if (getLexer().isNot(AsmToken::Comma)) 2840 return TokError("unexpected token in directive"); 2841 Lex(); 2842 2843 int64_t Offset = 0; 2844 if (getParser().ParseAbsoluteExpression(Offset)) 2845 return true; 2846 2847 getStreamer().EmitCFIDefCfa(Register, Offset); 2848 return false; 2849} 2850 2851/// ParseDirectiveCFIDefCfaOffset 2852/// ::= .cfi_def_cfa_offset offset 2853bool GenericAsmParser::ParseDirectiveCFIDefCfaOffset(StringRef, 2854 SMLoc DirectiveLoc) { 2855 int64_t Offset = 0; 2856 if (getParser().ParseAbsoluteExpression(Offset)) 2857 return true; 2858 2859 getStreamer().EmitCFIDefCfaOffset(Offset); 2860 return false; 2861} 2862 2863/// ParseDirectiveCFIAdjustCfaOffset 2864/// ::= .cfi_adjust_cfa_offset adjustment 2865bool GenericAsmParser::ParseDirectiveCFIAdjustCfaOffset(StringRef, 2866 SMLoc DirectiveLoc) { 2867 int64_t Adjustment = 0; 2868 if (getParser().ParseAbsoluteExpression(Adjustment)) 2869 return true; 2870 2871 getStreamer().EmitCFIAdjustCfaOffset(Adjustment); 2872 return false; 2873} 2874 2875/// ParseDirectiveCFIDefCfaRegister 2876/// ::= .cfi_def_cfa_register register 2877bool GenericAsmParser::ParseDirectiveCFIDefCfaRegister(StringRef, 2878 SMLoc DirectiveLoc) { 2879 int64_t Register = 0; 2880 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 2881 return true; 2882 2883 getStreamer().EmitCFIDefCfaRegister(Register); 2884 return false; 2885} 2886 2887/// ParseDirectiveCFIOffset 2888/// ::= .cfi_offset register, offset 2889bool GenericAsmParser::ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc) { 2890 int64_t Register = 0; 2891 int64_t Offset = 0; 2892 2893 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 2894 return true; 2895 2896 if (getLexer().isNot(AsmToken::Comma)) 2897 return TokError("unexpected token in directive"); 2898 Lex(); 2899 2900 if (getParser().ParseAbsoluteExpression(Offset)) 2901 return true; 2902 2903 getStreamer().EmitCFIOffset(Register, Offset); 2904 return false; 2905} 2906 2907/// ParseDirectiveCFIRelOffset 2908/// ::= .cfi_rel_offset register, offset 2909bool GenericAsmParser::ParseDirectiveCFIRelOffset(StringRef, 2910 SMLoc DirectiveLoc) { 2911 int64_t Register = 0; 2912 2913 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 2914 return true; 2915 2916 if (getLexer().isNot(AsmToken::Comma)) 2917 return TokError("unexpected token in directive"); 2918 Lex(); 2919 2920 int64_t Offset = 0; 2921 if (getParser().ParseAbsoluteExpression(Offset)) 2922 return true; 2923 2924 getStreamer().EmitCFIRelOffset(Register, Offset); 2925 return false; 2926} 2927 2928static bool isValidEncoding(int64_t Encoding) { 2929 if (Encoding & ~0xff) 2930 return false; 2931 2932 if (Encoding == dwarf::DW_EH_PE_omit) 2933 return true; 2934 2935 const unsigned Format = Encoding & 0xf; 2936 if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 && 2937 Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 && 2938 Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 && 2939 Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed) 2940 return false; 2941 2942 const unsigned Application = Encoding & 0x70; 2943 if (Application != dwarf::DW_EH_PE_absptr && 2944 Application != dwarf::DW_EH_PE_pcrel) 2945 return false; 2946 2947 return true; 2948} 2949 2950/// ParseDirectiveCFIPersonalityOrLsda 2951/// ::= .cfi_personality encoding, [symbol_name] 2952/// ::= .cfi_lsda encoding, [symbol_name] 2953bool GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda(StringRef IDVal, 2954 SMLoc DirectiveLoc) { 2955 int64_t Encoding = 0; 2956 if (getParser().ParseAbsoluteExpression(Encoding)) 2957 return true; 2958 if (Encoding == dwarf::DW_EH_PE_omit) 2959 return false; 2960 2961 if (!isValidEncoding(Encoding)) 2962 return TokError("unsupported encoding."); 2963 2964 if (getLexer().isNot(AsmToken::Comma)) 2965 return TokError("unexpected token in directive"); 2966 Lex(); 2967 2968 StringRef Name; 2969 if (getParser().ParseIdentifier(Name)) 2970 return TokError("expected identifier in directive"); 2971 2972 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 2973 2974 if (IDVal == ".cfi_personality") 2975 getStreamer().EmitCFIPersonality(Sym, Encoding); 2976 else { 2977 assert(IDVal == ".cfi_lsda"); 2978 getStreamer().EmitCFILsda(Sym, Encoding); 2979 } 2980 return false; 2981} 2982 2983/// ParseDirectiveCFIRememberState 2984/// ::= .cfi_remember_state 2985bool GenericAsmParser::ParseDirectiveCFIRememberState(StringRef IDVal, 2986 SMLoc DirectiveLoc) { 2987 getStreamer().EmitCFIRememberState(); 2988 return false; 2989} 2990 2991/// ParseDirectiveCFIRestoreState 2992/// ::= .cfi_remember_state 2993bool GenericAsmParser::ParseDirectiveCFIRestoreState(StringRef IDVal, 2994 SMLoc DirectiveLoc) { 2995 getStreamer().EmitCFIRestoreState(); 2996 return false; 2997} 2998 2999/// ParseDirectiveCFISameValue 3000/// ::= .cfi_same_value register 3001bool GenericAsmParser::ParseDirectiveCFISameValue(StringRef IDVal, 3002 SMLoc DirectiveLoc) { 3003 int64_t Register = 0; 3004 3005 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3006 return true; 3007 3008 getStreamer().EmitCFISameValue(Register); 3009 3010 return false; 3011} 3012 3013/// ParseDirectiveCFIRestore 3014/// ::= .cfi_restore register 3015bool GenericAsmParser::ParseDirectiveCFIRestore(StringRef IDVal, 3016 SMLoc DirectiveLoc) { 3017 int64_t Register = 0; 3018 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3019 return true; 3020 3021 getStreamer().EmitCFIRestore(Register); 3022 3023 return false; 3024} 3025 3026/// ParseDirectiveCFIEscape 3027/// ::= .cfi_escape expression[,...] 3028bool GenericAsmParser::ParseDirectiveCFIEscape(StringRef IDVal, 3029 SMLoc DirectiveLoc) { 3030 std::string Values; 3031 int64_t CurrValue; 3032 if (getParser().ParseAbsoluteExpression(CurrValue)) 3033 return true; 3034 3035 Values.push_back((uint8_t)CurrValue); 3036 3037 while (getLexer().is(AsmToken::Comma)) { 3038 Lex(); 3039 3040 if (getParser().ParseAbsoluteExpression(CurrValue)) 3041 return true; 3042 3043 Values.push_back((uint8_t)CurrValue); 3044 } 3045 3046 getStreamer().EmitCFIEscape(Values); 3047 return false; 3048} 3049 3050/// ParseDirectiveCFISignalFrame 3051/// ::= .cfi_signal_frame 3052bool GenericAsmParser::ParseDirectiveCFISignalFrame(StringRef Directive, 3053 SMLoc DirectiveLoc) { 3054 if (getLexer().isNot(AsmToken::EndOfStatement)) 3055 return Error(getLexer().getLoc(), 3056 "unexpected token in '" + Directive + "' directive"); 3057 3058 getStreamer().EmitCFISignalFrame(); 3059 3060 return false; 3061} 3062 3063/// ParseDirectiveMacrosOnOff 3064/// ::= .macros_on 3065/// ::= .macros_off 3066bool GenericAsmParser::ParseDirectiveMacrosOnOff(StringRef Directive, 3067 SMLoc DirectiveLoc) { 3068 if (getLexer().isNot(AsmToken::EndOfStatement)) 3069 return Error(getLexer().getLoc(), 3070 "unexpected token in '" + Directive + "' directive"); 3071 3072 getParser().MacrosEnabled = Directive == ".macros_on"; 3073 3074 return false; 3075} 3076 3077/// ParseDirectiveMacro 3078/// ::= .macro name [parameters] 3079bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive, 3080 SMLoc DirectiveLoc) { 3081 StringRef Name; 3082 if (getParser().ParseIdentifier(Name)) 3083 return TokError("expected identifier in '.macro' directive"); 3084 3085 MacroParameters Parameters; 3086 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3087 for (;;) { 3088 MacroParameter Parameter; 3089 if (getParser().ParseIdentifier(Parameter)) 3090 return TokError("expected identifier in '.macro' directive"); 3091 Parameters.push_back(Parameter); 3092 3093 if (getLexer().isNot(AsmToken::Comma)) 3094 break; 3095 Lex(); 3096 } 3097 } 3098 3099 if (getLexer().isNot(AsmToken::EndOfStatement)) 3100 return TokError("unexpected token in '.macro' directive"); 3101 3102 // Eat the end of statement. 3103 Lex(); 3104 3105 AsmToken EndToken, StartToken = getTok(); 3106 3107 // Lex the macro definition. 3108 for (;;) { 3109 // Check whether we have reached the end of the file. 3110 if (getLexer().is(AsmToken::Eof)) 3111 return Error(DirectiveLoc, "no matching '.endmacro' in definition"); 3112 3113 // Otherwise, check whether we have reach the .endmacro. 3114 if (getLexer().is(AsmToken::Identifier) && 3115 (getTok().getIdentifier() == ".endm" || 3116 getTok().getIdentifier() == ".endmacro")) { 3117 EndToken = getTok(); 3118 Lex(); 3119 if (getLexer().isNot(AsmToken::EndOfStatement)) 3120 return TokError("unexpected token in '" + EndToken.getIdentifier() + 3121 "' directive"); 3122 break; 3123 } 3124 3125 // Otherwise, scan til the end of the statement. 3126 getParser().EatToEndOfStatement(); 3127 } 3128 3129 if (getParser().MacroMap.lookup(Name)) { 3130 return Error(DirectiveLoc, "macro '" + Name + "' is already defined"); 3131 } 3132 3133 const char *BodyStart = StartToken.getLoc().getPointer(); 3134 const char *BodyEnd = EndToken.getLoc().getPointer(); 3135 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); 3136 getParser().MacroMap[Name] = new Macro(Name, Body, Parameters); 3137 return false; 3138} 3139 3140/// ParseDirectiveEndMacro 3141/// ::= .endm 3142/// ::= .endmacro 3143bool GenericAsmParser::ParseDirectiveEndMacro(StringRef Directive, 3144 SMLoc DirectiveLoc) { 3145 if (getLexer().isNot(AsmToken::EndOfStatement)) 3146 return TokError("unexpected token in '" + Directive + "' directive"); 3147 3148 // If we are inside a macro instantiation, terminate the current 3149 // instantiation. 3150 if (!getParser().ActiveMacros.empty()) { 3151 getParser().HandleMacroExit(); 3152 return false; 3153 } 3154 3155 // Otherwise, this .endmacro is a stray entry in the file; well formed 3156 // .endmacro directives are handled during the macro definition parsing. 3157 return TokError("unexpected '" + Directive + "' in file, " 3158 "no current macro definition"); 3159} 3160 3161/// ParseDirectivePurgeMacro 3162/// ::= .purgem 3163bool GenericAsmParser::ParseDirectivePurgeMacro(StringRef Directive, 3164 SMLoc DirectiveLoc) { 3165 StringRef Name; 3166 if (getParser().ParseIdentifier(Name)) 3167 return TokError("expected identifier in '.purgem' directive"); 3168 3169 if (getLexer().isNot(AsmToken::EndOfStatement)) 3170 return TokError("unexpected token in '.purgem' directive"); 3171 3172 StringMap<Macro*>::iterator I = getParser().MacroMap.find(Name); 3173 if (I == getParser().MacroMap.end()) 3174 return Error(DirectiveLoc, "macro '" + Name + "' is not defined"); 3175 3176 // Undefine the macro. 3177 delete I->getValue(); 3178 getParser().MacroMap.erase(I); 3179 return false; 3180} 3181 3182bool GenericAsmParser::ParseDirectiveLEB128(StringRef DirName, SMLoc) { 3183 getParser().CheckForValidSection(); 3184 3185 const MCExpr *Value; 3186 3187 if (getParser().ParseExpression(Value)) 3188 return true; 3189 3190 if (getLexer().isNot(AsmToken::EndOfStatement)) 3191 return TokError("unexpected token in directive"); 3192 3193 if (DirName[1] == 's') 3194 getStreamer().EmitSLEB128Value(Value); 3195 else 3196 getStreamer().EmitULEB128Value(Value); 3197 3198 return false; 3199} 3200 3201Macro *AsmParser::ParseMacroLikeBody(SMLoc DirectiveLoc) { 3202 AsmToken EndToken, StartToken = getTok(); 3203 3204 unsigned NestLevel = 0; 3205 for (;;) { 3206 // Check whether we have reached the end of the file. 3207 if (getLexer().is(AsmToken::Eof)) { 3208 Error(DirectiveLoc, "no matching '.endr' in definition"); 3209 return 0; 3210 } 3211 3212 if (Lexer.is(AsmToken::Identifier) && 3213 (getTok().getIdentifier() == ".rept")) { 3214 ++NestLevel; 3215 } 3216 3217 // Otherwise, check whether we have reached the .endr. 3218 if (Lexer.is(AsmToken::Identifier) && 3219 getTok().getIdentifier() == ".endr") { 3220 if (NestLevel == 0) { 3221 EndToken = getTok(); 3222 Lex(); 3223 if (Lexer.isNot(AsmToken::EndOfStatement)) { 3224 TokError("unexpected token in '.endr' directive"); 3225 return 0; 3226 } 3227 break; 3228 } 3229 --NestLevel; 3230 } 3231 3232 // Otherwise, scan till the end of the statement. 3233 EatToEndOfStatement(); 3234 } 3235 3236 const char *BodyStart = StartToken.getLoc().getPointer(); 3237 const char *BodyEnd = EndToken.getLoc().getPointer(); 3238 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); 3239 3240 // We Are Anonymous. 3241 StringRef Name; 3242 MacroParameters Parameters; 3243 return new Macro(Name, Body, Parameters); 3244} 3245 3246void AsmParser::InstantiateMacroLikeBody(Macro *M, SMLoc DirectiveLoc, 3247 raw_svector_ostream &OS) { 3248 OS << ".endr\n"; 3249 3250 MemoryBuffer *Instantiation = 3251 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); 3252 3253 // Create the macro instantiation object and add to the current macro 3254 // instantiation stack. 3255 MacroInstantiation *MI = new MacroInstantiation(M, DirectiveLoc, 3256 getTok().getLoc(), 3257 Instantiation); 3258 ActiveMacros.push_back(MI); 3259 3260 // Jump to the macro instantiation and prime the lexer. 3261 CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc()); 3262 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 3263 Lex(); 3264} 3265 3266bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) { 3267 int64_t Count; 3268 if (ParseAbsoluteExpression(Count)) 3269 return TokError("unexpected token in '.rept' directive"); 3270 3271 if (Count < 0) 3272 return TokError("Count is negative"); 3273 3274 if (Lexer.isNot(AsmToken::EndOfStatement)) 3275 return TokError("unexpected token in '.rept' directive"); 3276 3277 // Eat the end of statement. 3278 Lex(); 3279 3280 // Lex the rept definition. 3281 Macro *M = ParseMacroLikeBody(DirectiveLoc); 3282 if (!M) 3283 return true; 3284 3285 // Macro instantiation is lexical, unfortunately. We construct a new buffer 3286 // to hold the macro body with substitutions. 3287 SmallString<256> Buf; 3288 MacroParameters Parameters; 3289 MacroArguments A; 3290 raw_svector_ostream OS(Buf); 3291 while (Count--) { 3292 if (expandMacro(OS, M->Body, Parameters, A, getTok().getLoc())) 3293 return true; 3294 } 3295 InstantiateMacroLikeBody(M, DirectiveLoc, OS); 3296 3297 return false; 3298} 3299 3300/// ParseDirectiveIrp 3301/// ::= .irp symbol,values 3302bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) { 3303 MacroParameters Parameters; 3304 MacroParameter Parameter; 3305 3306 if (ParseIdentifier(Parameter)) 3307 return TokError("expected identifier in '.irp' directive"); 3308 3309 Parameters.push_back(Parameter); 3310 3311 if (Lexer.isNot(AsmToken::Comma)) 3312 return TokError("expected comma in '.irp' directive"); 3313 3314 Lex(); 3315 3316 MacroArguments A; 3317 if (ParseMacroArguments(0, A)) 3318 return true; 3319 3320 // Eat the end of statement. 3321 Lex(); 3322 3323 // Lex the irp definition. 3324 Macro *M = ParseMacroLikeBody(DirectiveLoc); 3325 if (!M) 3326 return true; 3327 3328 // Macro instantiation is lexical, unfortunately. We construct a new buffer 3329 // to hold the macro body with substitutions. 3330 SmallString<256> Buf; 3331 raw_svector_ostream OS(Buf); 3332 3333 for (MacroArguments::iterator i = A.begin(), e = A.end(); i != e; ++i) { 3334 MacroArguments Args; 3335 Args.push_back(*i); 3336 3337 if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc())) 3338 return true; 3339 } 3340 3341 InstantiateMacroLikeBody(M, DirectiveLoc, OS); 3342 3343 return false; 3344} 3345 3346/// ParseDirectiveIrpc 3347/// ::= .irpc symbol,values 3348bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) { 3349 MacroParameters Parameters; 3350 MacroParameter Parameter; 3351 3352 if (ParseIdentifier(Parameter)) 3353 return TokError("expected identifier in '.irpc' directive"); 3354 3355 Parameters.push_back(Parameter); 3356 3357 if (Lexer.isNot(AsmToken::Comma)) 3358 return TokError("expected comma in '.irpc' directive"); 3359 3360 Lex(); 3361 3362 MacroArguments A; 3363 if (ParseMacroArguments(0, A)) 3364 return true; 3365 3366 if (A.size() != 1 || A.front().size() != 1) 3367 return TokError("unexpected token in '.irpc' directive"); 3368 3369 // Eat the end of statement. 3370 Lex(); 3371 3372 // Lex the irpc definition. 3373 Macro *M = ParseMacroLikeBody(DirectiveLoc); 3374 if (!M) 3375 return true; 3376 3377 // Macro instantiation is lexical, unfortunately. We construct a new buffer 3378 // to hold the macro body with substitutions. 3379 SmallString<256> Buf; 3380 raw_svector_ostream OS(Buf); 3381 3382 StringRef Values = A.front().front().getString(); 3383 std::size_t I, End = Values.size(); 3384 for (I = 0; I < End; ++I) { 3385 MacroArgument Arg; 3386 Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I+1))); 3387 3388 MacroArguments Args; 3389 Args.push_back(Arg); 3390 3391 if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc())) 3392 return true; 3393 } 3394 3395 InstantiateMacroLikeBody(M, DirectiveLoc, OS); 3396 3397 return false; 3398} 3399 3400bool AsmParser::ParseDirectiveEndr(SMLoc DirectiveLoc) { 3401 if (ActiveMacros.empty()) 3402 return TokError("unexpected '.endr' directive, no current .rept"); 3403 3404 // The only .repl that should get here are the ones created by 3405 // InstantiateMacroLikeBody. 3406 assert(getLexer().is(AsmToken::EndOfStatement)); 3407 3408 HandleMacroExit(); 3409 return false; 3410} 3411 3412/// \brief Create an MCAsmParser instance. 3413MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM, 3414 MCContext &C, MCStreamer &Out, 3415 const MCAsmInfo &MAI) { 3416 return new AsmParser(SM, C, Out, MAI); 3417} 3418