1 //===- AsmParser.cpp - Parser for Assembly Files --------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This class implements the parser for assembly files.
12 //===----------------------------------------------------------------------===//
14 #include "AsmParser.h"
16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/ADT/Twine.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCParsedAsmOperand.h"
22 #include "llvm/MC/MCSectionMachO.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSymbol.h"
25 #include "llvm/MC/MCValue.h"
26 #include "llvm/Support/Compiler.h"
27 #include "llvm/Support/SourceMgr.h"
28 #include "llvm/Support/raw_ostream.h"
29 #include "llvm/Target/TargetAsmParser.h"
33 enum { DEFAULT_ADDRSPACE = 0 };
35 // Mach-O section uniquing.
37 // FIXME: Figure out where this should live, it should be shared by
38 // TargetLoweringObjectFile.
39 typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
41 AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out,
42 const MCAsmInfo &_MAI)
43 : Lexer(_SM, _MAI), Ctx(_Ctx), Out(_Out), TargetParser(0),
44 SectionUniquingMap(0) {
45 // Debugging directives.
46 AddDirectiveHandler(".file", &AsmParser::ParseDirectiveFile);
47 AddDirectiveHandler(".line", &AsmParser::ParseDirectiveLine);
48 AddDirectiveHandler(".loc", &AsmParser::ParseDirectiveLoc);
53 AsmParser::~AsmParser() {
54 // If we have the MachO uniquing map, free it.
55 delete (MachOUniqueMapTy*)SectionUniquingMap;
58 const MCSection *AsmParser::getMachOSection(const StringRef &Segment,
59 const StringRef &Section,
60 unsigned TypeAndAttributes,
62 SectionKind Kind) const {
63 // We unique sections by their segment/section pair. The returned section
64 // may not have the same flags as the requested section, if so this should be
65 // diagnosed by the client as an error.
67 // Create the map if it doesn't already exist.
68 if (SectionUniquingMap == 0)
69 SectionUniquingMap = new MachOUniqueMapTy();
70 MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)SectionUniquingMap;
72 // Form the name to look up.
78 // Do the lookup, if we have a hit, return it.
79 const MCSectionMachO *&Entry = Map[Name.str()];
81 // FIXME: This should validate the type and attributes.
82 if (Entry) return Entry;
84 // Otherwise, return a new section.
85 return Entry = MCSectionMachO::Create(Segment, Section, TypeAndAttributes,
86 Reserved2, Kind, Ctx);
89 void AsmParser::Warning(SMLoc L, const Twine &Msg) {
90 Lexer.PrintMessage(L, Msg.str(), "warning");
93 bool AsmParser::Error(SMLoc L, const Twine &Msg) {
94 Lexer.PrintMessage(L, Msg.str(), "error");
98 bool AsmParser::TokError(const char *Msg) {
99 Lexer.PrintMessage(Lexer.getLoc(), Msg, "error");
103 const AsmToken &AsmParser::Lex() {
107 bool AsmParser::Run() {
108 // Create the initial section.
110 // FIXME: Support -n.
111 // FIXME: Target hook & command line option for initial section.
112 Out.SwitchSection(getMachOSection("__TEXT", "__text",
113 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
120 bool HadError = false;
122 AsmCond StartingCondState = TheCondState;
124 // While we have input, parse each statement.
125 while (Lexer.isNot(AsmToken::Eof)) {
126 // Handle conditional assembly here before calling ParseStatement()
127 if (Lexer.getKind() == AsmToken::Identifier) {
128 // If we have an identifier, handle it as the key symbol.
129 AsmToken ID = getTok();
130 SMLoc IDLoc = ID.getLoc();
131 StringRef IDVal = ID.getString();
133 if (IDVal == ".if" ||
134 IDVal == ".elseif" ||
137 if (!ParseConditionalAssemblyDirectives(IDVal, IDLoc))
140 EatToEndOfStatement();
144 if (TheCondState.Ignore) {
145 EatToEndOfStatement();
149 if (!ParseStatement()) continue;
151 // We had an error, remember it and recover by skipping to the next line.
153 EatToEndOfStatement();
156 if (TheCondState.TheCond != StartingCondState.TheCond ||
157 TheCondState.Ignore != StartingCondState.Ignore)
158 return TokError("unmatched .ifs or .elses");
166 /// ParseConditionalAssemblyDirectives - parse the conditional assembly
168 bool AsmParser::ParseConditionalAssemblyDirectives(StringRef Directive,
169 SMLoc DirectiveLoc) {
170 if (Directive == ".if")
171 return ParseDirectiveIf(DirectiveLoc);
172 if (Directive == ".elseif")
173 return ParseDirectiveElseIf(DirectiveLoc);
174 if (Directive == ".else")
175 return ParseDirectiveElse(DirectiveLoc);
176 if (Directive == ".endif")
177 return ParseDirectiveEndIf(DirectiveLoc);
181 /// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
182 void AsmParser::EatToEndOfStatement() {
183 while (Lexer.isNot(AsmToken::EndOfStatement) &&
184 Lexer.isNot(AsmToken::Eof))
188 if (Lexer.is(AsmToken::EndOfStatement))
193 /// ParseParenExpr - Parse a paren expression and return it.
194 /// NOTE: This assumes the leading '(' has already been consumed.
196 /// parenexpr ::= expr)
198 bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
199 if (ParseExpression(Res)) return true;
200 if (Lexer.isNot(AsmToken::RParen))
201 return TokError("expected ')' in parentheses expression");
202 EndLoc = Lexer.getLoc();
207 MCSymbol *AsmParser::CreateSymbol(StringRef Name) {
208 if (MCSymbol *S = Ctx.LookupSymbol(Name))
211 // If the label starts with L it is an assembler temporary label.
212 if (Name.startswith("L"))
213 return Ctx.CreateTemporarySymbol(Name);
215 return Ctx.CreateSymbol(Name);
218 /// ParsePrimaryExpr - Parse a primary expression and return it.
219 /// primaryexpr ::= (parenexpr
220 /// primaryexpr ::= symbol
221 /// primaryexpr ::= number
222 /// primaryexpr ::= ~,+,- primaryexpr
223 bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
224 switch (Lexer.getKind()) {
226 return TokError("unknown token in expression");
227 case AsmToken::Exclaim:
228 Lex(); // Eat the operator.
229 if (ParsePrimaryExpr(Res, EndLoc))
231 Res = MCUnaryExpr::CreateLNot(Res, getContext());
233 case AsmToken::String:
234 case AsmToken::Identifier: {
235 // This is a symbol reference.
236 MCSymbol *Sym = CreateSymbol(getTok().getIdentifier());
237 EndLoc = Lexer.getLoc();
238 Lex(); // Eat identifier.
240 // If this is an absolute variable reference, substitute it now to preserve
241 // semantics in the face of reassignment.
242 if (Sym->getValue() && isa<MCConstantExpr>(Sym->getValue())) {
243 Res = Sym->getValue();
247 // Otherwise create a symbol ref.
248 Res = MCSymbolRefExpr::Create(Sym, getContext());
251 case AsmToken::Integer:
252 Res = MCConstantExpr::Create(getTok().getIntVal(), getContext());
253 EndLoc = Lexer.getLoc();
256 case AsmToken::LParen:
257 Lex(); // Eat the '('.
258 return ParseParenExpr(Res, EndLoc);
259 case AsmToken::Minus:
260 Lex(); // Eat the operator.
261 if (ParsePrimaryExpr(Res, EndLoc))
263 Res = MCUnaryExpr::CreateMinus(Res, getContext());
266 Lex(); // Eat the operator.
267 if (ParsePrimaryExpr(Res, EndLoc))
269 Res = MCUnaryExpr::CreatePlus(Res, getContext());
271 case AsmToken::Tilde:
272 Lex(); // Eat the operator.
273 if (ParsePrimaryExpr(Res, EndLoc))
275 Res = MCUnaryExpr::CreateNot(Res, getContext());
280 bool AsmParser::ParseExpression(const MCExpr *&Res) {
282 return ParseExpression(Res, EndLoc);
285 /// ParseExpression - Parse an expression and return it.
287 /// expr ::= expr +,- expr -> lowest.
288 /// expr ::= expr |,^,&,! expr -> middle.
289 /// expr ::= expr *,/,%,<<,>> expr -> highest.
290 /// expr ::= primaryexpr
292 bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
294 return ParsePrimaryExpr(Res, EndLoc) ||
295 ParseBinOpRHS(1, Res, EndLoc);
298 bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
299 if (ParseParenExpr(Res, EndLoc))
305 bool AsmParser::ParseAbsoluteExpression(int64_t &Res) {
308 SMLoc StartLoc = Lexer.getLoc();
309 if (ParseExpression(Expr))
312 if (!Expr->EvaluateAsAbsolute(Res))
313 return Error(StartLoc, "expected absolute expression");
318 static unsigned getBinOpPrecedence(AsmToken::TokenKind K,
319 MCBinaryExpr::Opcode &Kind) {
322 return 0; // not a binop.
324 // Lowest Precedence: &&, ||
325 case AsmToken::AmpAmp:
326 Kind = MCBinaryExpr::LAnd;
328 case AsmToken::PipePipe:
329 Kind = MCBinaryExpr::LOr;
332 // Low Precedence: +, -, ==, !=, <>, <, <=, >, >=
334 Kind = MCBinaryExpr::Add;
336 case AsmToken::Minus:
337 Kind = MCBinaryExpr::Sub;
339 case AsmToken::EqualEqual:
340 Kind = MCBinaryExpr::EQ;
342 case AsmToken::ExclaimEqual:
343 case AsmToken::LessGreater:
344 Kind = MCBinaryExpr::NE;
347 Kind = MCBinaryExpr::LT;
349 case AsmToken::LessEqual:
350 Kind = MCBinaryExpr::LTE;
352 case AsmToken::Greater:
353 Kind = MCBinaryExpr::GT;
355 case AsmToken::GreaterEqual:
356 Kind = MCBinaryExpr::GTE;
359 // Intermediate Precedence: |, &, ^
361 // FIXME: gas seems to support '!' as an infix operator?
363 Kind = MCBinaryExpr::Or;
365 case AsmToken::Caret:
366 Kind = MCBinaryExpr::Xor;
369 Kind = MCBinaryExpr::And;
372 // Highest Precedence: *, /, %, <<, >>
374 Kind = MCBinaryExpr::Mul;
376 case AsmToken::Slash:
377 Kind = MCBinaryExpr::Div;
379 case AsmToken::Percent:
380 Kind = MCBinaryExpr::Mod;
382 case AsmToken::LessLess:
383 Kind = MCBinaryExpr::Shl;
385 case AsmToken::GreaterGreater:
386 Kind = MCBinaryExpr::Shr;
392 /// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
393 /// Res contains the LHS of the expression on input.
394 bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
397 MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
398 unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
400 // If the next token is lower precedence than we are allowed to eat, return
401 // successfully with what we ate already.
402 if (TokPrec < Precedence)
407 // Eat the next primary expression.
409 if (ParsePrimaryExpr(RHS, EndLoc)) return true;
411 // If BinOp binds less tightly with RHS than the operator after RHS, let
412 // the pending operator take RHS as its LHS.
413 MCBinaryExpr::Opcode Dummy;
414 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
415 if (TokPrec < NextTokPrec) {
416 if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true;
419 // Merge LHS and RHS according to operator.
420 Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext());
428 /// ::= EndOfStatement
429 /// ::= Label* Directive ...Operands... EndOfStatement
430 /// ::= Label* Identifier OperandList* EndOfStatement
431 bool AsmParser::ParseStatement() {
432 if (Lexer.is(AsmToken::EndOfStatement)) {
437 // Statements always start with an identifier.
438 AsmToken ID = getTok();
439 SMLoc IDLoc = ID.getLoc();
441 if (ParseIdentifier(IDVal))
442 return TokError("unexpected token at start of statement");
444 // FIXME: Recurse on local labels?
446 // See what kind of statement we have.
447 switch (Lexer.getKind()) {
448 case AsmToken::Colon: {
449 // identifier ':' -> Label.
452 // Diagnose attempt to use a variable as a label.
454 // FIXME: Diagnostics. Note the location of the definition as a label.
455 // FIXME: This doesn't diagnose assignment to a symbol which has been
456 // implicitly marked as external.
457 MCSymbol *Sym = CreateSymbol(IDVal);
458 if (!Sym->isUndefined())
459 return Error(IDLoc, "invalid symbol redefinition");
464 return ParseStatement();
467 case AsmToken::Equal:
468 // identifier '=' ... -> assignment statement
471 return ParseAssignment(IDVal);
473 default: // Normal instruction or directive.
477 // Otherwise, we have a normal instruction or directive.
478 if (IDVal[0] == '.') {
479 // FIXME: This should be driven based on a hash lookup and callback.
480 if (IDVal == ".section")
481 return ParseDirectiveDarwinSection();
482 if (IDVal == ".text")
483 // FIXME: This changes behavior based on the -static flag to the
485 return ParseDirectiveSectionSwitch("__TEXT", "__text",
486 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
487 if (IDVal == ".const")
488 return ParseDirectiveSectionSwitch("__TEXT", "__const");
489 if (IDVal == ".static_const")
490 return ParseDirectiveSectionSwitch("__TEXT", "__static_const");
491 if (IDVal == ".cstring")
492 return ParseDirectiveSectionSwitch("__TEXT","__cstring",
493 MCSectionMachO::S_CSTRING_LITERALS);
494 if (IDVal == ".literal4")
495 return ParseDirectiveSectionSwitch("__TEXT", "__literal4",
496 MCSectionMachO::S_4BYTE_LITERALS,
498 if (IDVal == ".literal8")
499 return ParseDirectiveSectionSwitch("__TEXT", "__literal8",
500 MCSectionMachO::S_8BYTE_LITERALS,
502 if (IDVal == ".literal16")
503 return ParseDirectiveSectionSwitch("__TEXT","__literal16",
504 MCSectionMachO::S_16BYTE_LITERALS,
506 if (IDVal == ".constructor")
507 return ParseDirectiveSectionSwitch("__TEXT","__constructor");
508 if (IDVal == ".destructor")
509 return ParseDirectiveSectionSwitch("__TEXT","__destructor");
510 if (IDVal == ".fvmlib_init0")
511 return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init0");
512 if (IDVal == ".fvmlib_init1")
513 return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init1");
515 // FIXME: The assembler manual claims that this has the self modify code
516 // flag, at least on x86-32, but that does not appear to be correct.
517 if (IDVal == ".symbol_stub")
518 return ParseDirectiveSectionSwitch("__TEXT","__symbol_stub",
519 MCSectionMachO::S_SYMBOL_STUBS |
520 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
521 // FIXME: Different on PPC and ARM.
523 // FIXME: PowerPC only?
524 if (IDVal == ".picsymbol_stub")
525 return ParseDirectiveSectionSwitch("__TEXT","__picsymbol_stub",
526 MCSectionMachO::S_SYMBOL_STUBS |
527 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
529 if (IDVal == ".data")
530 return ParseDirectiveSectionSwitch("__DATA", "__data");
531 if (IDVal == ".static_data")
532 return ParseDirectiveSectionSwitch("__DATA", "__static_data");
534 // FIXME: The section names of these two are misspelled in the assembler
536 if (IDVal == ".non_lazy_symbol_pointer")
537 return ParseDirectiveSectionSwitch("__DATA", "__nl_symbol_ptr",
538 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
540 if (IDVal == ".lazy_symbol_pointer")
541 return ParseDirectiveSectionSwitch("__DATA", "__la_symbol_ptr",
542 MCSectionMachO::S_LAZY_SYMBOL_POINTERS,
545 if (IDVal == ".dyld")
546 return ParseDirectiveSectionSwitch("__DATA", "__dyld");
547 if (IDVal == ".mod_init_func")
548 return ParseDirectiveSectionSwitch("__DATA", "__mod_init_func",
549 MCSectionMachO::S_MOD_INIT_FUNC_POINTERS,
551 if (IDVal == ".mod_term_func")
552 return ParseDirectiveSectionSwitch("__DATA", "__mod_term_func",
553 MCSectionMachO::S_MOD_TERM_FUNC_POINTERS,
555 if (IDVal == ".const_data")
556 return ParseDirectiveSectionSwitch("__DATA", "__const");
559 if (IDVal == ".objc_class")
560 return ParseDirectiveSectionSwitch("__OBJC", "__class",
561 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
562 if (IDVal == ".objc_meta_class")
563 return ParseDirectiveSectionSwitch("__OBJC", "__meta_class",
564 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
565 if (IDVal == ".objc_cat_cls_meth")
566 return ParseDirectiveSectionSwitch("__OBJC", "__cat_cls_meth",
567 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
568 if (IDVal == ".objc_cat_inst_meth")
569 return ParseDirectiveSectionSwitch("__OBJC", "__cat_inst_meth",
570 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
571 if (IDVal == ".objc_protocol")
572 return ParseDirectiveSectionSwitch("__OBJC", "__protocol",
573 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
574 if (IDVal == ".objc_string_object")
575 return ParseDirectiveSectionSwitch("__OBJC", "__string_object",
576 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
577 if (IDVal == ".objc_cls_meth")
578 return ParseDirectiveSectionSwitch("__OBJC", "__cls_meth",
579 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
580 if (IDVal == ".objc_inst_meth")
581 return ParseDirectiveSectionSwitch("__OBJC", "__inst_meth",
582 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
583 if (IDVal == ".objc_cls_refs")
584 return ParseDirectiveSectionSwitch("__OBJC", "__cls_refs",
585 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
586 MCSectionMachO::S_LITERAL_POINTERS,
588 if (IDVal == ".objc_message_refs")
589 return ParseDirectiveSectionSwitch("__OBJC", "__message_refs",
590 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
591 MCSectionMachO::S_LITERAL_POINTERS,
593 if (IDVal == ".objc_symbols")
594 return ParseDirectiveSectionSwitch("__OBJC", "__symbols",
595 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
596 if (IDVal == ".objc_category")
597 return ParseDirectiveSectionSwitch("__OBJC", "__category",
598 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
599 if (IDVal == ".objc_class_vars")
600 return ParseDirectiveSectionSwitch("__OBJC", "__class_vars",
601 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
602 if (IDVal == ".objc_instance_vars")
603 return ParseDirectiveSectionSwitch("__OBJC", "__instance_vars",
604 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
605 if (IDVal == ".objc_module_info")
606 return ParseDirectiveSectionSwitch("__OBJC", "__module_info",
607 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
608 if (IDVal == ".objc_class_names")
609 return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
610 MCSectionMachO::S_CSTRING_LITERALS);
611 if (IDVal == ".objc_meth_var_types")
612 return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
613 MCSectionMachO::S_CSTRING_LITERALS);
614 if (IDVal == ".objc_meth_var_names")
615 return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
616 MCSectionMachO::S_CSTRING_LITERALS);
617 if (IDVal == ".objc_selector_strs")
618 return ParseDirectiveSectionSwitch("__OBJC", "__selector_strs",
619 MCSectionMachO::S_CSTRING_LITERALS);
621 // Assembler features
623 return ParseDirectiveSet();
627 if (IDVal == ".ascii")
628 return ParseDirectiveAscii(false);
629 if (IDVal == ".asciz")
630 return ParseDirectiveAscii(true);
632 if (IDVal == ".byte")
633 return ParseDirectiveValue(1);
634 if (IDVal == ".short")
635 return ParseDirectiveValue(2);
636 if (IDVal == ".long")
637 return ParseDirectiveValue(4);
638 if (IDVal == ".quad")
639 return ParseDirectiveValue(8);
641 // FIXME: Target hooks for IsPow2.
642 if (IDVal == ".align")
643 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
644 if (IDVal == ".align32")
645 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
646 if (IDVal == ".balign")
647 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
648 if (IDVal == ".balignw")
649 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
650 if (IDVal == ".balignl")
651 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
652 if (IDVal == ".p2align")
653 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
654 if (IDVal == ".p2alignw")
655 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
656 if (IDVal == ".p2alignl")
657 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
660 return ParseDirectiveOrg();
662 if (IDVal == ".fill")
663 return ParseDirectiveFill();
664 if (IDVal == ".space")
665 return ParseDirectiveSpace();
667 // Symbol attribute directives
669 if (IDVal == ".globl" || IDVal == ".global")
670 return ParseDirectiveSymbolAttribute(MCStreamer::Global);
671 if (IDVal == ".hidden")
672 return ParseDirectiveSymbolAttribute(MCStreamer::Hidden);
673 if (IDVal == ".indirect_symbol")
674 return ParseDirectiveSymbolAttribute(MCStreamer::IndirectSymbol);
675 if (IDVal == ".internal")
676 return ParseDirectiveSymbolAttribute(MCStreamer::Internal);
677 if (IDVal == ".lazy_reference")
678 return ParseDirectiveSymbolAttribute(MCStreamer::LazyReference);
679 if (IDVal == ".no_dead_strip")
680 return ParseDirectiveSymbolAttribute(MCStreamer::NoDeadStrip);
681 if (IDVal == ".private_extern")
682 return ParseDirectiveSymbolAttribute(MCStreamer::PrivateExtern);
683 if (IDVal == ".protected")
684 return ParseDirectiveSymbolAttribute(MCStreamer::Protected);
685 if (IDVal == ".reference")
686 return ParseDirectiveSymbolAttribute(MCStreamer::Reference);
687 if (IDVal == ".weak")
688 return ParseDirectiveSymbolAttribute(MCStreamer::Weak);
689 if (IDVal == ".weak_definition")
690 return ParseDirectiveSymbolAttribute(MCStreamer::WeakDefinition);
691 if (IDVal == ".weak_reference")
692 return ParseDirectiveSymbolAttribute(MCStreamer::WeakReference);
694 if (IDVal == ".comm")
695 return ParseDirectiveComm(/*IsLocal=*/false);
696 if (IDVal == ".lcomm")
697 return ParseDirectiveComm(/*IsLocal=*/true);
698 if (IDVal == ".zerofill")
699 return ParseDirectiveDarwinZerofill();
700 if (IDVal == ".desc")
701 return ParseDirectiveDarwinSymbolDesc();
702 if (IDVal == ".lsym")
703 return ParseDirectiveDarwinLsym();
705 if (IDVal == ".subsections_via_symbols")
706 return ParseDirectiveDarwinSubsectionsViaSymbols();
707 if (IDVal == ".abort")
708 return ParseDirectiveAbort();
709 if (IDVal == ".include")
710 return ParseDirectiveInclude();
711 if (IDVal == ".dump")
712 return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsDump=*/true);
713 if (IDVal == ".load")
714 return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsLoad=*/false);
716 // Look up the handler in the handler table,
717 bool(AsmParser::*Handler)(StringRef, SMLoc) = DirectiveMap[IDVal];
719 return (this->*Handler)(IDVal, IDLoc);
721 // Target hook for parsing target specific directives.
722 if (!getTargetParser().ParseDirective(ID))
725 Warning(IDLoc, "ignoring directive for now");
726 EatToEndOfStatement();
731 SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
732 if (getTargetParser().ParseInstruction(IDVal, IDLoc, ParsedOperands))
733 // FIXME: Leaking ParsedOperands on failure.
736 if (Lexer.isNot(AsmToken::EndOfStatement))
737 // FIXME: Leaking ParsedOperands on failure.
738 return TokError("unexpected token in argument list");
740 // Eat the end of statement marker.
746 bool MatchFail = getTargetParser().MatchInstruction(ParsedOperands, Inst);
748 // Free any parsed operands.
749 for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
750 delete ParsedOperands[i];
753 // FIXME: We should give nicer diagnostics about the exact failure.
754 Error(IDLoc, "unrecognized instruction");
758 // Instruction is good, process it.
759 Out.EmitInstruction(Inst);
761 // Skip to end of line for now.
765 bool AsmParser::ParseAssignment(const StringRef &Name) {
766 // FIXME: Use better location, we should use proper tokens.
767 SMLoc EqualLoc = Lexer.getLoc();
770 SMLoc StartLoc = Lexer.getLoc();
771 if (ParseExpression(Value))
774 if (Lexer.isNot(AsmToken::EndOfStatement))
775 return TokError("unexpected token in assignment");
777 // Eat the end of statement marker.
780 // Validate that the LHS is allowed to be a variable (either it has not been
781 // used as a symbol, or it is an absolute symbol).
782 MCSymbol *Sym = getContext().LookupSymbol(Name);
784 // Diagnose assignment to a label.
786 // FIXME: Diagnostics. Note the location of the definition as a label.
787 // FIXME: Diagnose assignment to protected identifier (e.g., register name).
788 if (!Sym->isUndefined() && !Sym->isAbsolute())
789 return Error(EqualLoc, "redefinition of '" + Name + "'");
790 else if (!Sym->isVariable())
791 return Error(EqualLoc, "invalid assignment to '" + Name + "'");
792 else if (!isa<MCConstantExpr>(Sym->getValue()))
793 return Error(EqualLoc, "invalid reassignment of non-absolute variable '" +
796 Sym = CreateSymbol(Name);
798 // FIXME: Handle '.'.
800 // Do the assignment.
801 Out.EmitAssignment(Sym, Value);
809 bool AsmParser::ParseIdentifier(StringRef &Res) {
810 if (Lexer.isNot(AsmToken::Identifier) &&
811 Lexer.isNot(AsmToken::String))
814 Res = getTok().getIdentifier();
816 Lex(); // Consume the identifier token.
821 /// ParseDirectiveSet:
822 /// ::= .set identifier ',' expression
823 bool AsmParser::ParseDirectiveSet() {
826 if (ParseIdentifier(Name))
827 return TokError("expected identifier after '.set' directive");
829 if (Lexer.isNot(AsmToken::Comma))
830 return TokError("unexpected token in '.set'");
833 return ParseAssignment(Name);
836 /// ParseDirectiveSection:
837 /// ::= .section identifier (',' identifier)*
838 /// FIXME: This should actually parse out the segment, section, attributes and
839 /// sizeof_stub fields.
840 bool AsmParser::ParseDirectiveDarwinSection() {
841 SMLoc Loc = Lexer.getLoc();
843 StringRef SectionName;
844 if (ParseIdentifier(SectionName))
845 return Error(Loc, "expected identifier after '.section' directive");
847 // Verify there is a following comma.
848 if (!Lexer.is(AsmToken::Comma))
849 return TokError("unexpected token in '.section' directive");
851 std::string SectionSpec = SectionName;
854 // Add all the tokens until the end of the line, ParseSectionSpecifier will
856 StringRef EOL = Lexer.LexUntilEndOfStatement();
857 SectionSpec.append(EOL.begin(), EOL.end());
860 if (Lexer.isNot(AsmToken::EndOfStatement))
861 return TokError("unexpected token in '.section' directive");
865 StringRef Segment, Section;
866 unsigned TAA, StubSize;
867 std::string ErrorStr =
868 MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
871 if (!ErrorStr.empty())
872 return Error(Loc, ErrorStr.c_str());
874 // FIXME: Arch specific.
875 Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize,
880 /// ParseDirectiveSectionSwitch -
881 bool AsmParser::ParseDirectiveSectionSwitch(const char *Segment,
883 unsigned TAA, unsigned Align,
885 if (Lexer.isNot(AsmToken::EndOfStatement))
886 return TokError("unexpected token in section switching directive");
889 // FIXME: Arch specific.
890 Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize,
893 // Set the implicit alignment, if any.
895 // FIXME: This isn't really what 'as' does; I think it just uses the implicit
896 // alignment on the section (e.g., if one manually inserts bytes into the
897 // section, then just issueing the section switch directive will not realign
898 // the section. However, this is arguably more reasonable behavior, and there
899 // is no good reason for someone to intentionally emit incorrectly sized
900 // values into the implicitly aligned sections.
902 Out.EmitValueToAlignment(Align, 0, 1, 0);
907 bool AsmParser::ParseEscapedString(std::string &Data) {
908 assert(Lexer.is(AsmToken::String) && "Unexpected current token!");
911 StringRef Str = getTok().getStringContents();
912 for (unsigned i = 0, e = Str.size(); i != e; ++i) {
913 if (Str[i] != '\\') {
918 // Recognize escaped characters. Note that this escape semantics currently
919 // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes.
922 return TokError("unexpected backslash at end of string");
924 // Recognize octal sequences.
925 if ((unsigned) (Str[i] - '0') <= 7) {
926 // Consume up to three octal characters.
927 unsigned Value = Str[i] - '0';
929 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
931 Value = Value * 8 + (Str[i] - '0');
933 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
935 Value = Value * 8 + (Str[i] - '0');
940 return TokError("invalid octal escape sequence (out of range)");
942 Data += (unsigned char) Value;
946 // Otherwise recognize individual escapes.
949 // Just reject invalid escape sequences for now.
950 return TokError("invalid escape sequence (unrecognized character)");
952 case 'b': Data += '\b'; break;
953 case 'f': Data += '\f'; break;
954 case 'n': Data += '\n'; break;
955 case 'r': Data += '\r'; break;
956 case 't': Data += '\t'; break;
957 case '"': Data += '"'; break;
958 case '\\': Data += '\\'; break;
965 /// ParseDirectiveAscii:
966 /// ::= ( .ascii | .asciz ) [ "string" ( , "string" )* ]
967 bool AsmParser::ParseDirectiveAscii(bool ZeroTerminated) {
968 if (Lexer.isNot(AsmToken::EndOfStatement)) {
970 if (Lexer.isNot(AsmToken::String))
971 return TokError("expected string in '.ascii' or '.asciz' directive");
974 if (ParseEscapedString(Data))
977 Out.EmitBytes(Data, DEFAULT_ADDRSPACE);
979 Out.EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE);
983 if (Lexer.is(AsmToken::EndOfStatement))
986 if (Lexer.isNot(AsmToken::Comma))
987 return TokError("unexpected token in '.ascii' or '.asciz' directive");
996 /// ParseDirectiveValue
997 /// ::= (.byte | .short | ... ) [ expression (, expression)* ]
998 bool AsmParser::ParseDirectiveValue(unsigned Size) {
999 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1001 const MCExpr *Value;
1002 SMLoc ATTRIBUTE_UNUSED StartLoc = Lexer.getLoc();
1003 if (ParseExpression(Value))
1006 Out.EmitValue(Value, Size, DEFAULT_ADDRSPACE);
1008 if (Lexer.is(AsmToken::EndOfStatement))
1011 // FIXME: Improve diagnostic.
1012 if (Lexer.isNot(AsmToken::Comma))
1013 return TokError("unexpected token in directive");
1022 /// ParseDirectiveSpace
1023 /// ::= .space expression [ , expression ]
1024 bool AsmParser::ParseDirectiveSpace() {
1026 if (ParseAbsoluteExpression(NumBytes))
1029 int64_t FillExpr = 0;
1030 bool HasFillExpr = false;
1031 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1032 if (Lexer.isNot(AsmToken::Comma))
1033 return TokError("unexpected token in '.space' directive");
1036 if (ParseAbsoluteExpression(FillExpr))
1041 if (Lexer.isNot(AsmToken::EndOfStatement))
1042 return TokError("unexpected token in '.space' directive");
1048 return TokError("invalid number of bytes in '.space' directive");
1050 // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
1051 Out.EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE);
1056 /// ParseDirectiveFill
1057 /// ::= .fill expression , expression , expression
1058 bool AsmParser::ParseDirectiveFill() {
1060 if (ParseAbsoluteExpression(NumValues))
1063 if (Lexer.isNot(AsmToken::Comma))
1064 return TokError("unexpected token in '.fill' directive");
1068 if (ParseAbsoluteExpression(FillSize))
1071 if (Lexer.isNot(AsmToken::Comma))
1072 return TokError("unexpected token in '.fill' directive");
1076 if (ParseAbsoluteExpression(FillExpr))
1079 if (Lexer.isNot(AsmToken::EndOfStatement))
1080 return TokError("unexpected token in '.fill' directive");
1084 if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8)
1085 return TokError("invalid '.fill' size, expected 1, 2, 4, or 8");
1087 for (uint64_t i = 0, e = NumValues; i != e; ++i)
1088 Out.EmitValue(MCConstantExpr::Create(FillExpr, getContext()), FillSize,
1094 /// ParseDirectiveOrg
1095 /// ::= .org expression [ , expression ]
1096 bool AsmParser::ParseDirectiveOrg() {
1097 const MCExpr *Offset;
1098 SMLoc StartLoc = Lexer.getLoc();
1099 if (ParseExpression(Offset))
1102 // Parse optional fill expression.
1103 int64_t FillExpr = 0;
1104 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1105 if (Lexer.isNot(AsmToken::Comma))
1106 return TokError("unexpected token in '.org' directive");
1109 if (ParseAbsoluteExpression(FillExpr))
1112 if (Lexer.isNot(AsmToken::EndOfStatement))
1113 return TokError("unexpected token in '.org' directive");
1118 // FIXME: Only limited forms of relocatable expressions are accepted here, it
1119 // has to be relative to the current section.
1120 Out.EmitValueToOffset(Offset, FillExpr);
1125 /// ParseDirectiveAlign
1126 /// ::= {.align, ...} expression [ , expression [ , expression ]]
1127 bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
1128 SMLoc AlignmentLoc = Lexer.getLoc();
1130 if (ParseAbsoluteExpression(Alignment))
1134 bool HasFillExpr = false;
1135 int64_t FillExpr = 0;
1136 int64_t MaxBytesToFill = 0;
1137 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1138 if (Lexer.isNot(AsmToken::Comma))
1139 return TokError("unexpected token in directive");
1142 // The fill expression can be omitted while specifying a maximum number of
1143 // alignment bytes, e.g:
1145 if (Lexer.isNot(AsmToken::Comma)) {
1147 if (ParseAbsoluteExpression(FillExpr))
1151 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1152 if (Lexer.isNot(AsmToken::Comma))
1153 return TokError("unexpected token in directive");
1156 MaxBytesLoc = Lexer.getLoc();
1157 if (ParseAbsoluteExpression(MaxBytesToFill))
1160 if (Lexer.isNot(AsmToken::EndOfStatement))
1161 return TokError("unexpected token in directive");
1168 // FIXME: Sometimes fill with nop.
1172 // Compute alignment in bytes.
1174 // FIXME: Diagnose overflow.
1175 if (Alignment >= 32) {
1176 Error(AlignmentLoc, "invalid alignment value");
1180 Alignment = 1ULL << Alignment;
1183 // Diagnose non-sensical max bytes to align.
1184 if (MaxBytesLoc.isValid()) {
1185 if (MaxBytesToFill < 1) {
1186 Error(MaxBytesLoc, "alignment directive can never be satisfied in this "
1187 "many bytes, ignoring maximum bytes expression");
1191 if (MaxBytesToFill >= Alignment) {
1192 Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and "
1198 // FIXME: Target specific behavior about how the "extra" bytes are filled.
1199 Out.EmitValueToAlignment(Alignment, FillExpr, ValueSize, MaxBytesToFill);
1204 /// ParseDirectiveSymbolAttribute
1205 /// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
1206 bool AsmParser::ParseDirectiveSymbolAttribute(MCStreamer::SymbolAttr Attr) {
1207 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1211 if (ParseIdentifier(Name))
1212 return TokError("expected identifier in directive");
1214 MCSymbol *Sym = CreateSymbol(Name);
1216 Out.EmitSymbolAttribute(Sym, Attr);
1218 if (Lexer.is(AsmToken::EndOfStatement))
1221 if (Lexer.isNot(AsmToken::Comma))
1222 return TokError("unexpected token in directive");
1231 /// ParseDirectiveDarwinSymbolDesc
1232 /// ::= .desc identifier , expression
1233 bool AsmParser::ParseDirectiveDarwinSymbolDesc() {
1235 if (ParseIdentifier(Name))
1236 return TokError("expected identifier in directive");
1238 // Handle the identifier as the key symbol.
1239 MCSymbol *Sym = CreateSymbol(Name);
1241 if (Lexer.isNot(AsmToken::Comma))
1242 return TokError("unexpected token in '.desc' directive");
1245 SMLoc DescLoc = Lexer.getLoc();
1247 if (ParseAbsoluteExpression(DescValue))
1250 if (Lexer.isNot(AsmToken::EndOfStatement))
1251 return TokError("unexpected token in '.desc' directive");
1255 // Set the n_desc field of this Symbol to this DescValue
1256 Out.EmitSymbolDesc(Sym, DescValue);
1261 /// ParseDirectiveComm
1262 /// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
1263 bool AsmParser::ParseDirectiveComm(bool IsLocal) {
1264 SMLoc IDLoc = Lexer.getLoc();
1266 if (ParseIdentifier(Name))
1267 return TokError("expected identifier in directive");
1269 // Handle the identifier as the key symbol.
1270 MCSymbol *Sym = CreateSymbol(Name);
1272 if (Lexer.isNot(AsmToken::Comma))
1273 return TokError("unexpected token in directive");
1277 SMLoc SizeLoc = Lexer.getLoc();
1278 if (ParseAbsoluteExpression(Size))
1281 int64_t Pow2Alignment = 0;
1282 SMLoc Pow2AlignmentLoc;
1283 if (Lexer.is(AsmToken::Comma)) {
1285 Pow2AlignmentLoc = Lexer.getLoc();
1286 if (ParseAbsoluteExpression(Pow2Alignment))
1289 // If this target takes alignments in bytes (not log) validate and convert.
1290 if (Lexer.getMAI().getAlignmentIsInBytes()) {
1291 if (!isPowerOf2_64(Pow2Alignment))
1292 return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
1293 Pow2Alignment = Log2_64(Pow2Alignment);
1297 if (Lexer.isNot(AsmToken::EndOfStatement))
1298 return TokError("unexpected token in '.comm' or '.lcomm' directive");
1302 // NOTE: a size of zero for a .comm should create a undefined symbol
1303 // but a size of .lcomm creates a bss symbol of size zero.
1305 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
1306 "be less than zero");
1308 // NOTE: The alignment in the directive is a power of 2 value, the assember
1309 // may internally end up wanting an alignment in bytes.
1310 // FIXME: Diagnose overflow.
1311 if (Pow2Alignment < 0)
1312 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
1313 "alignment, can't be less than zero");
1315 if (!Sym->isUndefined())
1316 return Error(IDLoc, "invalid symbol redefinition");
1318 // '.lcomm' is equivalent to '.zerofill'.
1319 // Create the Symbol as a common or local common with Size and Pow2Alignment
1321 Out.EmitZerofill(getMachOSection("__DATA", "__bss",
1322 MCSectionMachO::S_ZEROFILL, 0,
1324 Sym, Size, 1 << Pow2Alignment);
1328 Out.EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
1332 /// ParseDirectiveDarwinZerofill
1333 /// ::= .zerofill segname , sectname [, identifier , size_expression [
1334 /// , align_expression ]]
1335 bool AsmParser::ParseDirectiveDarwinZerofill() {
1336 // FIXME: Handle quoted names here.
1338 if (Lexer.isNot(AsmToken::Identifier))
1339 return TokError("expected segment name after '.zerofill' directive");
1340 StringRef Segment = getTok().getString();
1343 if (Lexer.isNot(AsmToken::Comma))
1344 return TokError("unexpected token in directive");
1347 if (Lexer.isNot(AsmToken::Identifier))
1348 return TokError("expected section name after comma in '.zerofill' "
1350 StringRef Section = getTok().getString();
1353 // If this is the end of the line all that was wanted was to create the
1354 // the section but with no symbol.
1355 if (Lexer.is(AsmToken::EndOfStatement)) {
1356 // Create the zerofill section but no symbol
1357 Out.EmitZerofill(getMachOSection(Segment, Section,
1358 MCSectionMachO::S_ZEROFILL, 0,
1363 if (Lexer.isNot(AsmToken::Comma))
1364 return TokError("unexpected token in directive");
1367 if (Lexer.isNot(AsmToken::Identifier))
1368 return TokError("expected identifier in directive");
1370 // handle the identifier as the key symbol.
1371 SMLoc IDLoc = Lexer.getLoc();
1372 MCSymbol *Sym = CreateSymbol(getTok().getString());
1375 if (Lexer.isNot(AsmToken::Comma))
1376 return TokError("unexpected token in directive");
1380 SMLoc SizeLoc = Lexer.getLoc();
1381 if (ParseAbsoluteExpression(Size))
1384 int64_t Pow2Alignment = 0;
1385 SMLoc Pow2AlignmentLoc;
1386 if (Lexer.is(AsmToken::Comma)) {
1388 Pow2AlignmentLoc = Lexer.getLoc();
1389 if (ParseAbsoluteExpression(Pow2Alignment))
1393 if (Lexer.isNot(AsmToken::EndOfStatement))
1394 return TokError("unexpected token in '.zerofill' directive");
1399 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
1402 // NOTE: The alignment in the directive is a power of 2 value, the assember
1403 // may internally end up wanting an alignment in bytes.
1404 // FIXME: Diagnose overflow.
1405 if (Pow2Alignment < 0)
1406 return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
1407 "can't be less than zero");
1409 if (!Sym->isUndefined())
1410 return Error(IDLoc, "invalid symbol redefinition");
1412 // Create the zerofill Symbol with Size and Pow2Alignment
1414 // FIXME: Arch specific.
1415 Out.EmitZerofill(getMachOSection(Segment, Section,
1416 MCSectionMachO::S_ZEROFILL, 0,
1418 Sym, Size, 1 << Pow2Alignment);
1423 /// ParseDirectiveDarwinSubsectionsViaSymbols
1424 /// ::= .subsections_via_symbols
1425 bool AsmParser::ParseDirectiveDarwinSubsectionsViaSymbols() {
1426 if (Lexer.isNot(AsmToken::EndOfStatement))
1427 return TokError("unexpected token in '.subsections_via_symbols' directive");
1431 Out.EmitAssemblerFlag(MCStreamer::SubsectionsViaSymbols);
1436 /// ParseDirectiveAbort
1437 /// ::= .abort [ "abort_string" ]
1438 bool AsmParser::ParseDirectiveAbort() {
1439 // FIXME: Use loc from directive.
1440 SMLoc Loc = Lexer.getLoc();
1443 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1444 if (Lexer.isNot(AsmToken::String))
1445 return TokError("expected string in '.abort' directive");
1447 Str = getTok().getString();
1452 if (Lexer.isNot(AsmToken::EndOfStatement))
1453 return TokError("unexpected token in '.abort' directive");
1457 // FIXME: Handle here.
1459 Error(Loc, ".abort detected. Assembly stopping.");
1461 Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
1466 /// ParseDirectiveLsym
1467 /// ::= .lsym identifier , expression
1468 bool AsmParser::ParseDirectiveDarwinLsym() {
1470 if (ParseIdentifier(Name))
1471 return TokError("expected identifier in directive");
1473 // Handle the identifier as the key symbol.
1474 MCSymbol *Sym = CreateSymbol(Name);
1476 if (Lexer.isNot(AsmToken::Comma))
1477 return TokError("unexpected token in '.lsym' directive");
1480 const MCExpr *Value;
1481 SMLoc StartLoc = Lexer.getLoc();
1482 if (ParseExpression(Value))
1485 if (Lexer.isNot(AsmToken::EndOfStatement))
1486 return TokError("unexpected token in '.lsym' directive");
1490 // We don't currently support this directive.
1492 // FIXME: Diagnostic location!
1494 return TokError("directive '.lsym' is unsupported");
1497 /// ParseDirectiveInclude
1498 /// ::= .include "filename"
1499 bool AsmParser::ParseDirectiveInclude() {
1500 if (Lexer.isNot(AsmToken::String))
1501 return TokError("expected string in '.include' directive");
1503 std::string Filename = getTok().getString();
1504 SMLoc IncludeLoc = Lexer.getLoc();
1507 if (Lexer.isNot(AsmToken::EndOfStatement))
1508 return TokError("unexpected token in '.include' directive");
1510 // Strip the quotes.
1511 Filename = Filename.substr(1, Filename.size()-2);
1513 // Attempt to switch the lexer to the included file before consuming the end
1514 // of statement to avoid losing it when we switch.
1515 if (Lexer.EnterIncludeFile(Filename)) {
1516 Lexer.PrintMessage(IncludeLoc,
1517 "Could not find include file '" + Filename + "'",
1525 /// ParseDirectiveDarwinDumpOrLoad
1526 /// ::= ( .dump | .load ) "filename"
1527 bool AsmParser::ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump) {
1528 if (Lexer.isNot(AsmToken::String))
1529 return TokError("expected string in '.dump' or '.load' directive");
1533 if (Lexer.isNot(AsmToken::EndOfStatement))
1534 return TokError("unexpected token in '.dump' or '.load' directive");
1538 // FIXME: If/when .dump and .load are implemented they will be done in the
1539 // the assembly parser and not have any need for an MCStreamer API.
1541 Warning(IDLoc, "ignoring directive .dump for now");
1543 Warning(IDLoc, "ignoring directive .load for now");
1548 /// ParseDirectiveIf
1549 /// ::= .if expression
1550 bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
1551 // Consume the identifier that was the .if directive
1554 TheCondStack.push_back(TheCondState);
1555 TheCondState.TheCond = AsmCond::IfCond;
1556 if(TheCondState.Ignore) {
1557 EatToEndOfStatement();
1561 if (ParseAbsoluteExpression(ExprValue))
1564 if (Lexer.isNot(AsmToken::EndOfStatement))
1565 return TokError("unexpected token in '.if' directive");
1569 TheCondState.CondMet = ExprValue;
1570 TheCondState.Ignore = !TheCondState.CondMet;
1576 /// ParseDirectiveElseIf
1577 /// ::= .elseif expression
1578 bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
1579 if (TheCondState.TheCond != AsmCond::IfCond &&
1580 TheCondState.TheCond != AsmCond::ElseIfCond)
1581 Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
1583 TheCondState.TheCond = AsmCond::ElseIfCond;
1585 // Consume the identifier that was the .elseif directive
1588 bool LastIgnoreState = false;
1589 if (!TheCondStack.empty())
1590 LastIgnoreState = TheCondStack.back().Ignore;
1591 if (LastIgnoreState || TheCondState.CondMet) {
1592 TheCondState.Ignore = true;
1593 EatToEndOfStatement();
1597 if (ParseAbsoluteExpression(ExprValue))
1600 if (Lexer.isNot(AsmToken::EndOfStatement))
1601 return TokError("unexpected token in '.elseif' directive");
1604 TheCondState.CondMet = ExprValue;
1605 TheCondState.Ignore = !TheCondState.CondMet;
1611 /// ParseDirectiveElse
1613 bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
1614 // Consume the identifier that was the .else directive
1617 if (Lexer.isNot(AsmToken::EndOfStatement))
1618 return TokError("unexpected token in '.else' directive");
1622 if (TheCondState.TheCond != AsmCond::IfCond &&
1623 TheCondState.TheCond != AsmCond::ElseIfCond)
1624 Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
1626 TheCondState.TheCond = AsmCond::ElseCond;
1627 bool LastIgnoreState = false;
1628 if (!TheCondStack.empty())
1629 LastIgnoreState = TheCondStack.back().Ignore;
1630 if (LastIgnoreState || TheCondState.CondMet)
1631 TheCondState.Ignore = true;
1633 TheCondState.Ignore = false;
1638 /// ParseDirectiveEndIf
1640 bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
1641 // Consume the identifier that was the .endif directive
1644 if (Lexer.isNot(AsmToken::EndOfStatement))
1645 return TokError("unexpected token in '.endif' directive");
1649 if ((TheCondState.TheCond == AsmCond::NoCond) ||
1650 TheCondStack.empty())
1651 Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
1653 if (!TheCondStack.empty()) {
1654 TheCondState = TheCondStack.back();
1655 TheCondStack.pop_back();
1661 /// ParseDirectiveFile
1662 /// ::= .file [number] string
1663 bool AsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
1664 // FIXME: I'm not sure what this is.
1665 int64_t FileNumber = -1;
1666 if (Lexer.is(AsmToken::Integer)) {
1667 FileNumber = getTok().getIntVal();
1671 return TokError("file number less than one");
1674 if (Lexer.isNot(AsmToken::String))
1675 return TokError("unexpected token in '.file' directive");
1677 StringRef ATTRIBUTE_UNUSED FileName = getTok().getString();
1680 if (Lexer.isNot(AsmToken::EndOfStatement))
1681 return TokError("unexpected token in '.file' directive");
1683 // FIXME: Do something with the .file.
1688 /// ParseDirectiveLine
1689 /// ::= .line [number]
1690 bool AsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) {
1691 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1692 if (Lexer.isNot(AsmToken::Integer))
1693 return TokError("unexpected token in '.line' directive");
1695 int64_t LineNumber = getTok().getIntVal();
1699 // FIXME: Do something with the .line.
1702 if (Lexer.isNot(AsmToken::EndOfStatement))
1703 return TokError("unexpected token in '.file' directive");
1709 /// ParseDirectiveLoc
1710 /// ::= .loc number [number [number]]
1711 bool AsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
1712 if (Lexer.isNot(AsmToken::Integer))
1713 return TokError("unexpected token in '.loc' directive");
1715 // FIXME: What are these fields?
1716 int64_t FileNumber = getTok().getIntVal();
1718 // FIXME: Validate file.
1721 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1722 if (Lexer.isNot(AsmToken::Integer))
1723 return TokError("unexpected token in '.loc' directive");
1725 int64_t Param2 = getTok().getIntVal();
1729 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1730 if (Lexer.isNot(AsmToken::Integer))
1731 return TokError("unexpected token in '.loc' directive");
1733 int64_t Param3 = getTok().getIntVal();
1737 // FIXME: Do something with the .loc.
1741 if (Lexer.isNot(AsmToken::EndOfStatement))
1742 return TokError("unexpected token in '.file' directive");