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 "llvm/MC/MCParser/AsmParser.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/StringSwitch.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/MCSectionMachO.h"
22 #include "llvm/MC/MCStreamer.h"
23 #include "llvm/MC/MCSymbol.h"
24 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
25 #include "llvm/Support/Compiler.h"
26 #include "llvm/Support/SourceMgr.h"
27 #include "llvm/Support/MemoryBuffer.h"
28 #include "llvm/Support/raw_ostream.h"
29 #include "llvm/Target/TargetAsmParser.h"
35 /// \brief Generic implementations of directive handling, etc. which is shared
36 /// (or the default, at least) for all assembler parser.
37 class GenericAsmParser : public MCAsmParserExtension {
41 virtual void Initialize(MCAsmParser &Parser) {
42 // Call the base implementation.
43 this->MCAsmParserExtension::Initialize(Parser);
45 // Debugging directives.
46 Parser.AddDirectiveHandler(this, ".file", MCAsmParser::DirectiveHandler(
47 &GenericAsmParser::ParseDirectiveFile));
48 Parser.AddDirectiveHandler(this, ".line", MCAsmParser::DirectiveHandler(
49 &GenericAsmParser::ParseDirectiveLine));
50 Parser.AddDirectiveHandler(this, ".loc", MCAsmParser::DirectiveHandler(
51 &GenericAsmParser::ParseDirectiveLoc));
54 bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc); // ".file"
55 bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc); // ".line"
56 bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc); // ".loc"
61 enum { DEFAULT_ADDRSPACE = 0 };
63 AsmParser::AsmParser(const Target &T, SourceMgr &_SM, MCContext &_Ctx,
64 MCStreamer &_Out, const MCAsmInfo &_MAI)
65 : Lexer(_MAI), Ctx(_Ctx), Out(_Out), SrcMgr(_SM),
66 GenericParser(new GenericAsmParser), TargetParser(0), CurBuffer(0) {
67 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
69 // Initialize the generic parser.
70 GenericParser->Initialize(*this);
73 AsmParser::~AsmParser() {
77 void AsmParser::setTargetParser(TargetAsmParser &P) {
78 assert(!TargetParser && "Target parser is already initialized!");
80 TargetParser->Initialize(*this);
83 void AsmParser::Warning(SMLoc L, const Twine &Msg) {
84 PrintMessage(L, Msg.str(), "warning");
87 bool AsmParser::Error(SMLoc L, const Twine &Msg) {
88 PrintMessage(L, Msg.str(), "error");
92 void AsmParser::PrintMessage(SMLoc Loc, const std::string &Msg,
93 const char *Type) const {
94 SrcMgr.PrintMessage(Loc, Msg, Type);
97 bool AsmParser::EnterIncludeFile(const std::string &Filename) {
98 int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc());
104 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
109 const AsmToken &AsmParser::Lex() {
110 const AsmToken *tok = &Lexer.Lex();
112 if (tok->is(AsmToken::Eof)) {
113 // If this is the end of an included file, pop the parent file off the
115 SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
116 if (ParentIncludeLoc != SMLoc()) {
117 CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc);
118 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer),
119 ParentIncludeLoc.getPointer());
124 if (tok->is(AsmToken::Error))
125 PrintMessage(Lexer.getErrLoc(), Lexer.getErr(), "error");
130 bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
131 // Create the initial section, if requested.
133 // FIXME: Target hook & command line option for initial section.
134 if (!NoInitialTextSection)
135 Out.SwitchSection(Ctx.getMachOSection("__TEXT", "__text",
136 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
137 0, SectionKind::getText()));
142 bool HadError = false;
144 AsmCond StartingCondState = TheCondState;
146 // While we have input, parse each statement.
147 while (Lexer.isNot(AsmToken::Eof)) {
148 if (!ParseStatement()) continue;
150 // We had an error, remember it and recover by skipping to the next line.
152 EatToEndOfStatement();
155 if (TheCondState.TheCond != StartingCondState.TheCond ||
156 TheCondState.Ignore != StartingCondState.Ignore)
157 return TokError("unmatched .ifs or .elses");
159 // Finalize the output stream if there are no errors and if the client wants
161 if (!HadError && !NoFinalize)
167 /// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
168 void AsmParser::EatToEndOfStatement() {
169 while (Lexer.isNot(AsmToken::EndOfStatement) &&
170 Lexer.isNot(AsmToken::Eof))
174 if (Lexer.is(AsmToken::EndOfStatement))
179 /// ParseParenExpr - Parse a paren expression and return it.
180 /// NOTE: This assumes the leading '(' has already been consumed.
182 /// parenexpr ::= expr)
184 bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
185 if (ParseExpression(Res)) return true;
186 if (Lexer.isNot(AsmToken::RParen))
187 return TokError("expected ')' in parentheses expression");
188 EndLoc = Lexer.getLoc();
193 MCSymbol *AsmParser::CreateSymbol(StringRef Name) {
194 // FIXME: Inline into callers.
195 return Ctx.GetOrCreateSymbol(Name);
198 /// ParsePrimaryExpr - Parse a primary expression and return it.
199 /// primaryexpr ::= (parenexpr
200 /// primaryexpr ::= symbol
201 /// primaryexpr ::= number
202 /// primaryexpr ::= '.'
203 /// primaryexpr ::= ~,+,- primaryexpr
204 bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
205 switch (Lexer.getKind()) {
207 return TokError("unknown token in expression");
208 case AsmToken::Exclaim:
209 Lex(); // Eat the operator.
210 if (ParsePrimaryExpr(Res, EndLoc))
212 Res = MCUnaryExpr::CreateLNot(Res, getContext());
214 case AsmToken::String:
215 case AsmToken::Identifier: {
216 // This is a symbol reference.
217 std::pair<StringRef, StringRef> Split = getTok().getIdentifier().split('@');
218 MCSymbol *Sym = CreateSymbol(Split.first);
220 // Mark the symbol as used in an expression.
221 Sym->setUsedInExpr(true);
223 // Lookup the symbol variant if used.
224 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
225 if (Split.first.size() != getTok().getIdentifier().size())
226 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
228 EndLoc = Lexer.getLoc();
229 Lex(); // Eat identifier.
231 // If this is an absolute variable reference, substitute it now to preserve
232 // semantics in the face of reassignment.
233 if (Sym->isVariable() && isa<MCConstantExpr>(Sym->getVariableValue())) {
235 return Error(EndLoc, "unexpected modified on variable reference");
237 Res = Sym->getVariableValue();
241 // Otherwise create a symbol ref.
242 Res = MCSymbolRefExpr::Create(Sym, Variant, getContext());
245 case AsmToken::Integer: {
246 SMLoc Loc = getTok().getLoc();
247 int64_t IntVal = getTok().getIntVal();
248 Res = MCConstantExpr::Create(IntVal, getContext());
249 EndLoc = Lexer.getLoc();
251 // Look for 'b' or 'f' following an Integer as a directional label
252 if (Lexer.getKind() == AsmToken::Identifier) {
253 StringRef IDVal = getTok().getString();
254 if (IDVal == "f" || IDVal == "b"){
255 MCSymbol *Sym = Ctx.GetDirectionalLocalSymbol(IntVal,
256 IDVal == "f" ? 1 : 0);
257 Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
259 if(IDVal == "b" && Sym->isUndefined())
260 return Error(Loc, "invalid reference to undefined symbol");
261 EndLoc = Lexer.getLoc();
262 Lex(); // Eat identifier.
267 case AsmToken::Dot: {
268 // This is a '.' reference, which references the current PC. Emit a
269 // temporary label to the streamer and refer to it.
270 MCSymbol *Sym = Ctx.CreateTempSymbol();
272 Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
273 EndLoc = Lexer.getLoc();
274 Lex(); // Eat identifier.
278 case AsmToken::LParen:
279 Lex(); // Eat the '('.
280 return ParseParenExpr(Res, EndLoc);
281 case AsmToken::Minus:
282 Lex(); // Eat the operator.
283 if (ParsePrimaryExpr(Res, EndLoc))
285 Res = MCUnaryExpr::CreateMinus(Res, getContext());
288 Lex(); // Eat the operator.
289 if (ParsePrimaryExpr(Res, EndLoc))
291 Res = MCUnaryExpr::CreatePlus(Res, getContext());
293 case AsmToken::Tilde:
294 Lex(); // Eat the operator.
295 if (ParsePrimaryExpr(Res, EndLoc))
297 Res = MCUnaryExpr::CreateNot(Res, getContext());
302 bool AsmParser::ParseExpression(const MCExpr *&Res) {
304 return ParseExpression(Res, EndLoc);
307 /// ParseExpression - Parse an expression and return it.
309 /// expr ::= expr +,- expr -> lowest.
310 /// expr ::= expr |,^,&,! expr -> middle.
311 /// expr ::= expr *,/,%,<<,>> expr -> highest.
312 /// expr ::= primaryexpr
314 bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
315 // Parse the expression.
317 if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc))
320 // Try to constant fold it up front, if possible.
322 if (Res->EvaluateAsAbsolute(Value))
323 Res = MCConstantExpr::Create(Value, getContext());
328 bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
330 return ParseParenExpr(Res, EndLoc) ||
331 ParseBinOpRHS(1, Res, EndLoc);
334 bool AsmParser::ParseAbsoluteExpression(int64_t &Res) {
337 SMLoc StartLoc = Lexer.getLoc();
338 if (ParseExpression(Expr))
341 if (!Expr->EvaluateAsAbsolute(Res))
342 return Error(StartLoc, "expected absolute expression");
347 static unsigned getBinOpPrecedence(AsmToken::TokenKind K,
348 MCBinaryExpr::Opcode &Kind) {
351 return 0; // not a binop.
353 // Lowest Precedence: &&, ||
354 case AsmToken::AmpAmp:
355 Kind = MCBinaryExpr::LAnd;
357 case AsmToken::PipePipe:
358 Kind = MCBinaryExpr::LOr;
361 // Low Precedence: +, -, ==, !=, <>, <, <=, >, >=
363 Kind = MCBinaryExpr::Add;
365 case AsmToken::Minus:
366 Kind = MCBinaryExpr::Sub;
368 case AsmToken::EqualEqual:
369 Kind = MCBinaryExpr::EQ;
371 case AsmToken::ExclaimEqual:
372 case AsmToken::LessGreater:
373 Kind = MCBinaryExpr::NE;
376 Kind = MCBinaryExpr::LT;
378 case AsmToken::LessEqual:
379 Kind = MCBinaryExpr::LTE;
381 case AsmToken::Greater:
382 Kind = MCBinaryExpr::GT;
384 case AsmToken::GreaterEqual:
385 Kind = MCBinaryExpr::GTE;
388 // Intermediate Precedence: |, &, ^
390 // FIXME: gas seems to support '!' as an infix operator?
392 Kind = MCBinaryExpr::Or;
394 case AsmToken::Caret:
395 Kind = MCBinaryExpr::Xor;
398 Kind = MCBinaryExpr::And;
401 // Highest Precedence: *, /, %, <<, >>
403 Kind = MCBinaryExpr::Mul;
405 case AsmToken::Slash:
406 Kind = MCBinaryExpr::Div;
408 case AsmToken::Percent:
409 Kind = MCBinaryExpr::Mod;
411 case AsmToken::LessLess:
412 Kind = MCBinaryExpr::Shl;
414 case AsmToken::GreaterGreater:
415 Kind = MCBinaryExpr::Shr;
421 /// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
422 /// Res contains the LHS of the expression on input.
423 bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
426 MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
427 unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
429 // If the next token is lower precedence than we are allowed to eat, return
430 // successfully with what we ate already.
431 if (TokPrec < Precedence)
436 // Eat the next primary expression.
438 if (ParsePrimaryExpr(RHS, EndLoc)) return true;
440 // If BinOp binds less tightly with RHS than the operator after RHS, let
441 // the pending operator take RHS as its LHS.
442 MCBinaryExpr::Opcode Dummy;
443 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
444 if (TokPrec < NextTokPrec) {
445 if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true;
448 // Merge LHS and RHS according to operator.
449 Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext());
457 /// ::= EndOfStatement
458 /// ::= Label* Directive ...Operands... EndOfStatement
459 /// ::= Label* Identifier OperandList* EndOfStatement
460 bool AsmParser::ParseStatement() {
461 if (Lexer.is(AsmToken::EndOfStatement)) {
467 // Statements always start with an identifier.
468 AsmToken ID = getTok();
469 SMLoc IDLoc = ID.getLoc();
471 int64_t LocalLabelVal = -1;
472 // GUESS allow an integer followed by a ':' as a directional local label
473 if (Lexer.is(AsmToken::Integer)) {
474 LocalLabelVal = getTok().getIntVal();
475 if (LocalLabelVal < 0) {
476 if (!TheCondState.Ignore)
477 return TokError("unexpected token at start of statement");
481 IDVal = getTok().getString();
482 Lex(); // Consume the integer token to be used as an identifier token.
483 if (Lexer.getKind() != AsmToken::Colon) {
484 if (!TheCondState.Ignore)
485 return TokError("unexpected token at start of statement");
489 else if (ParseIdentifier(IDVal)) {
490 if (!TheCondState.Ignore)
491 return TokError("unexpected token at start of statement");
495 // Handle conditional assembly here before checking for skipping. We
496 // have to do this so that .endif isn't skipped in a ".if 0" block for
499 return ParseDirectiveIf(IDLoc);
500 if (IDVal == ".elseif")
501 return ParseDirectiveElseIf(IDLoc);
502 if (IDVal == ".else")
503 return ParseDirectiveElse(IDLoc);
504 if (IDVal == ".endif")
505 return ParseDirectiveEndIf(IDLoc);
507 // If we are in a ".if 0" block, ignore this statement.
508 if (TheCondState.Ignore) {
509 EatToEndOfStatement();
513 // FIXME: Recurse on local labels?
515 // See what kind of statement we have.
516 switch (Lexer.getKind()) {
517 case AsmToken::Colon: {
518 // identifier ':' -> Label.
521 // Diagnose attempt to use a variable as a label.
523 // FIXME: Diagnostics. Note the location of the definition as a label.
524 // FIXME: This doesn't diagnose assignment to a symbol which has been
525 // implicitly marked as external.
527 if (LocalLabelVal == -1)
528 Sym = CreateSymbol(IDVal);
530 Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal);
531 if (!Sym->isUndefined() || Sym->isVariable())
532 return Error(IDLoc, "invalid symbol redefinition");
537 // Consume any end of statement token, if present, to avoid spurious
538 // AddBlankLine calls().
539 if (Lexer.is(AsmToken::EndOfStatement)) {
541 if (Lexer.is(AsmToken::Eof))
545 return ParseStatement();
548 case AsmToken::Equal:
549 // identifier '=' ... -> assignment statement
552 return ParseAssignment(IDVal);
554 default: // Normal instruction or directive.
558 // Otherwise, we have a normal instruction or directive.
559 if (IDVal[0] == '.') {
560 // FIXME: This should be driven based on a hash lookup and callback.
561 if (IDVal == ".section")
562 return ParseDirectiveDarwinSection();
563 if (IDVal == ".text")
564 // FIXME: This changes behavior based on the -static flag to the
566 return ParseDirectiveSectionSwitch("__TEXT", "__text",
567 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
568 if (IDVal == ".const")
569 return ParseDirectiveSectionSwitch("__TEXT", "__const");
570 if (IDVal == ".static_const")
571 return ParseDirectiveSectionSwitch("__TEXT", "__static_const");
572 if (IDVal == ".cstring")
573 return ParseDirectiveSectionSwitch("__TEXT","__cstring",
574 MCSectionMachO::S_CSTRING_LITERALS);
575 if (IDVal == ".literal4")
576 return ParseDirectiveSectionSwitch("__TEXT", "__literal4",
577 MCSectionMachO::S_4BYTE_LITERALS,
579 if (IDVal == ".literal8")
580 return ParseDirectiveSectionSwitch("__TEXT", "__literal8",
581 MCSectionMachO::S_8BYTE_LITERALS,
583 if (IDVal == ".literal16")
584 return ParseDirectiveSectionSwitch("__TEXT","__literal16",
585 MCSectionMachO::S_16BYTE_LITERALS,
587 if (IDVal == ".constructor")
588 return ParseDirectiveSectionSwitch("__TEXT","__constructor");
589 if (IDVal == ".destructor")
590 return ParseDirectiveSectionSwitch("__TEXT","__destructor");
591 if (IDVal == ".fvmlib_init0")
592 return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init0");
593 if (IDVal == ".fvmlib_init1")
594 return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init1");
596 // FIXME: The assembler manual claims that this has the self modify code
597 // flag, at least on x86-32, but that does not appear to be correct.
598 if (IDVal == ".symbol_stub")
599 return ParseDirectiveSectionSwitch("__TEXT","__symbol_stub",
600 MCSectionMachO::S_SYMBOL_STUBS |
601 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
602 // FIXME: Different on PPC and ARM.
604 // FIXME: PowerPC only?
605 if (IDVal == ".picsymbol_stub")
606 return ParseDirectiveSectionSwitch("__TEXT","__picsymbol_stub",
607 MCSectionMachO::S_SYMBOL_STUBS |
608 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
610 if (IDVal == ".data")
611 return ParseDirectiveSectionSwitch("__DATA", "__data");
612 if (IDVal == ".static_data")
613 return ParseDirectiveSectionSwitch("__DATA", "__static_data");
615 // FIXME: The section names of these two are misspelled in the assembler
617 if (IDVal == ".non_lazy_symbol_pointer")
618 return ParseDirectiveSectionSwitch("__DATA", "__nl_symbol_ptr",
619 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
621 if (IDVal == ".lazy_symbol_pointer")
622 return ParseDirectiveSectionSwitch("__DATA", "__la_symbol_ptr",
623 MCSectionMachO::S_LAZY_SYMBOL_POINTERS,
626 if (IDVal == ".dyld")
627 return ParseDirectiveSectionSwitch("__DATA", "__dyld");
628 if (IDVal == ".mod_init_func")
629 return ParseDirectiveSectionSwitch("__DATA", "__mod_init_func",
630 MCSectionMachO::S_MOD_INIT_FUNC_POINTERS,
632 if (IDVal == ".mod_term_func")
633 return ParseDirectiveSectionSwitch("__DATA", "__mod_term_func",
634 MCSectionMachO::S_MOD_TERM_FUNC_POINTERS,
636 if (IDVal == ".const_data")
637 return ParseDirectiveSectionSwitch("__DATA", "__const");
640 if (IDVal == ".objc_class")
641 return ParseDirectiveSectionSwitch("__OBJC", "__class",
642 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
643 if (IDVal == ".objc_meta_class")
644 return ParseDirectiveSectionSwitch("__OBJC", "__meta_class",
645 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
646 if (IDVal == ".objc_cat_cls_meth")
647 return ParseDirectiveSectionSwitch("__OBJC", "__cat_cls_meth",
648 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
649 if (IDVal == ".objc_cat_inst_meth")
650 return ParseDirectiveSectionSwitch("__OBJC", "__cat_inst_meth",
651 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
652 if (IDVal == ".objc_protocol")
653 return ParseDirectiveSectionSwitch("__OBJC", "__protocol",
654 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
655 if (IDVal == ".objc_string_object")
656 return ParseDirectiveSectionSwitch("__OBJC", "__string_object",
657 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
658 if (IDVal == ".objc_cls_meth")
659 return ParseDirectiveSectionSwitch("__OBJC", "__cls_meth",
660 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
661 if (IDVal == ".objc_inst_meth")
662 return ParseDirectiveSectionSwitch("__OBJC", "__inst_meth",
663 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
664 if (IDVal == ".objc_cls_refs")
665 return ParseDirectiveSectionSwitch("__OBJC", "__cls_refs",
666 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
667 MCSectionMachO::S_LITERAL_POINTERS,
669 if (IDVal == ".objc_message_refs")
670 return ParseDirectiveSectionSwitch("__OBJC", "__message_refs",
671 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
672 MCSectionMachO::S_LITERAL_POINTERS,
674 if (IDVal == ".objc_symbols")
675 return ParseDirectiveSectionSwitch("__OBJC", "__symbols",
676 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
677 if (IDVal == ".objc_category")
678 return ParseDirectiveSectionSwitch("__OBJC", "__category",
679 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
680 if (IDVal == ".objc_class_vars")
681 return ParseDirectiveSectionSwitch("__OBJC", "__class_vars",
682 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
683 if (IDVal == ".objc_instance_vars")
684 return ParseDirectiveSectionSwitch("__OBJC", "__instance_vars",
685 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
686 if (IDVal == ".objc_module_info")
687 return ParseDirectiveSectionSwitch("__OBJC", "__module_info",
688 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
689 if (IDVal == ".objc_class_names")
690 return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
691 MCSectionMachO::S_CSTRING_LITERALS);
692 if (IDVal == ".objc_meth_var_types")
693 return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
694 MCSectionMachO::S_CSTRING_LITERALS);
695 if (IDVal == ".objc_meth_var_names")
696 return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
697 MCSectionMachO::S_CSTRING_LITERALS);
698 if (IDVal == ".objc_selector_strs")
699 return ParseDirectiveSectionSwitch("__OBJC", "__selector_strs",
700 MCSectionMachO::S_CSTRING_LITERALS);
702 if (IDVal == ".tdata")
703 return ParseDirectiveSectionSwitch("__DATA", "__thread_data",
704 MCSectionMachO::S_THREAD_LOCAL_REGULAR);
706 return ParseDirectiveSectionSwitch("__DATA", "__thread_vars",
707 MCSectionMachO::S_THREAD_LOCAL_VARIABLES);
708 if (IDVal == ".thread_init_func")
709 return ParseDirectiveSectionSwitch("__DATA", "__thread_init",
710 MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
712 // Assembler features
714 return ParseDirectiveSet();
718 if (IDVal == ".ascii")
719 return ParseDirectiveAscii(false);
720 if (IDVal == ".asciz")
721 return ParseDirectiveAscii(true);
723 if (IDVal == ".byte")
724 return ParseDirectiveValue(1);
725 if (IDVal == ".short")
726 return ParseDirectiveValue(2);
727 if (IDVal == ".long")
728 return ParseDirectiveValue(4);
729 if (IDVal == ".quad")
730 return ParseDirectiveValue(8);
732 // FIXME: Target hooks for IsPow2.
733 if (IDVal == ".align")
734 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
735 if (IDVal == ".align32")
736 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
737 if (IDVal == ".balign")
738 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
739 if (IDVal == ".balignw")
740 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
741 if (IDVal == ".balignl")
742 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
743 if (IDVal == ".p2align")
744 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
745 if (IDVal == ".p2alignw")
746 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
747 if (IDVal == ".p2alignl")
748 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
751 return ParseDirectiveOrg();
753 if (IDVal == ".fill")
754 return ParseDirectiveFill();
755 if (IDVal == ".space")
756 return ParseDirectiveSpace();
758 // Symbol attribute directives
760 if (IDVal == ".globl" || IDVal == ".global")
761 return ParseDirectiveSymbolAttribute(MCSA_Global);
762 if (IDVal == ".hidden")
763 return ParseDirectiveSymbolAttribute(MCSA_Hidden);
764 if (IDVal == ".indirect_symbol")
765 return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol);
766 if (IDVal == ".internal")
767 return ParseDirectiveSymbolAttribute(MCSA_Internal);
768 if (IDVal == ".lazy_reference")
769 return ParseDirectiveSymbolAttribute(MCSA_LazyReference);
770 if (IDVal == ".no_dead_strip")
771 return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip);
772 if (IDVal == ".private_extern")
773 return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern);
774 if (IDVal == ".protected")
775 return ParseDirectiveSymbolAttribute(MCSA_Protected);
776 if (IDVal == ".reference")
777 return ParseDirectiveSymbolAttribute(MCSA_Reference);
778 if (IDVal == ".type")
779 return ParseDirectiveELFType();
780 if (IDVal == ".weak")
781 return ParseDirectiveSymbolAttribute(MCSA_Weak);
782 if (IDVal == ".weak_definition")
783 return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition);
784 if (IDVal == ".weak_reference")
785 return ParseDirectiveSymbolAttribute(MCSA_WeakReference);
786 if (IDVal == ".weak_def_can_be_hidden")
787 return ParseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate);
789 if (IDVal == ".comm")
790 return ParseDirectiveComm(/*IsLocal=*/false);
791 if (IDVal == ".lcomm")
792 return ParseDirectiveComm(/*IsLocal=*/true);
793 if (IDVal == ".zerofill")
794 return ParseDirectiveDarwinZerofill();
795 if (IDVal == ".desc")
796 return ParseDirectiveDarwinSymbolDesc();
797 if (IDVal == ".lsym")
798 return ParseDirectiveDarwinLsym();
799 if (IDVal == ".tbss")
800 return ParseDirectiveDarwinTBSS();
802 if (IDVal == ".subsections_via_symbols")
803 return ParseDirectiveDarwinSubsectionsViaSymbols();
804 if (IDVal == ".abort")
805 return ParseDirectiveAbort();
806 if (IDVal == ".include")
807 return ParseDirectiveInclude();
808 if (IDVal == ".dump")
809 return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsDump=*/true);
810 if (IDVal == ".load")
811 return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsLoad=*/false);
812 if (IDVal == ".secure_log_unique")
813 return ParseDirectiveDarwinSecureLogUnique(IDLoc);
814 if (IDVal == ".secure_log_reset")
815 return ParseDirectiveDarwinSecureLogReset(IDLoc);
817 // Look up the handler in the handler table.
818 std::pair<MCAsmParserExtension*, DirectiveHandler> Handler =
819 DirectiveMap.lookup(IDVal);
821 return (Handler.first->*Handler.second)(IDVal, IDLoc);
823 // Target hook for parsing target specific directives.
824 if (!getTargetParser().ParseDirective(ID))
827 Warning(IDLoc, "ignoring directive for now");
828 EatToEndOfStatement();
832 // Canonicalize the opcode to lower case.
833 SmallString<128> Opcode;
834 for (unsigned i = 0, e = IDVal.size(); i != e; ++i)
835 Opcode.push_back(tolower(IDVal[i]));
837 SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
838 bool HadError = getTargetParser().ParseInstruction(Opcode.str(), IDLoc,
840 if (!HadError && Lexer.isNot(AsmToken::EndOfStatement))
841 HadError = TokError("unexpected token in argument list");
843 // If parsing succeeded, match the instruction.
846 if (!getTargetParser().MatchInstruction(ParsedOperands, Inst)) {
847 // Emit the instruction on success.
848 Out.EmitInstruction(Inst);
850 // Otherwise emit a diagnostic about the match failure and set the error
853 // FIXME: We should give nicer diagnostics about the exact failure.
854 Error(IDLoc, "unrecognized instruction");
859 // If there was no error, consume the end-of-statement token. Otherwise this
860 // will be done by our caller.
864 // Free any parsed operands.
865 for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
866 delete ParsedOperands[i];
871 bool AsmParser::ParseAssignment(const StringRef &Name) {
872 // FIXME: Use better location, we should use proper tokens.
873 SMLoc EqualLoc = Lexer.getLoc();
876 if (ParseExpression(Value))
879 if (Lexer.isNot(AsmToken::EndOfStatement))
880 return TokError("unexpected token in assignment");
882 // Eat the end of statement marker.
885 // Validate that the LHS is allowed to be a variable (either it has not been
886 // used as a symbol, or it is an absolute symbol).
887 MCSymbol *Sym = getContext().LookupSymbol(Name);
889 // Diagnose assignment to a label.
891 // FIXME: Diagnostics. Note the location of the definition as a label.
892 // FIXME: Diagnose assignment to protected identifier (e.g., register name).
893 if (Sym->isUndefined() && !Sym->isUsedInExpr())
894 ; // Allow redefinitions of undefined symbols only used in directives.
895 else if (!Sym->isUndefined() && !Sym->isAbsolute())
896 return Error(EqualLoc, "redefinition of '" + Name + "'");
897 else if (!Sym->isVariable())
898 return Error(EqualLoc, "invalid assignment to '" + Name + "'");
899 else if (!isa<MCConstantExpr>(Sym->getVariableValue()))
900 return Error(EqualLoc, "invalid reassignment of non-absolute variable '" +
903 Sym = CreateSymbol(Name);
905 // FIXME: Handle '.'.
907 Sym->setUsedInExpr(true);
909 // Do the assignment.
910 Out.EmitAssignment(Sym, Value);
918 bool AsmParser::ParseIdentifier(StringRef &Res) {
919 if (Lexer.isNot(AsmToken::Identifier) &&
920 Lexer.isNot(AsmToken::String))
923 Res = getTok().getIdentifier();
925 Lex(); // Consume the identifier token.
930 /// ParseDirectiveSet:
931 /// ::= .set identifier ',' expression
932 bool AsmParser::ParseDirectiveSet() {
935 if (ParseIdentifier(Name))
936 return TokError("expected identifier after '.set' directive");
938 if (Lexer.isNot(AsmToken::Comma))
939 return TokError("unexpected token in '.set'");
942 return ParseAssignment(Name);
945 /// ParseDirectiveSection:
946 /// ::= .section identifier (',' identifier)*
947 /// FIXME: This should actually parse out the segment, section, attributes and
948 /// sizeof_stub fields.
949 bool AsmParser::ParseDirectiveDarwinSection() {
950 SMLoc Loc = Lexer.getLoc();
952 StringRef SectionName;
953 if (ParseIdentifier(SectionName))
954 return Error(Loc, "expected identifier after '.section' directive");
956 // Verify there is a following comma.
957 if (!Lexer.is(AsmToken::Comma))
958 return TokError("unexpected token in '.section' directive");
960 std::string SectionSpec = SectionName;
963 // Add all the tokens until the end of the line, ParseSectionSpecifier will
965 StringRef EOL = Lexer.LexUntilEndOfStatement();
966 SectionSpec.append(EOL.begin(), EOL.end());
969 if (Lexer.isNot(AsmToken::EndOfStatement))
970 return TokError("unexpected token in '.section' directive");
974 StringRef Segment, Section;
975 unsigned TAA, StubSize;
976 std::string ErrorStr =
977 MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
980 if (!ErrorStr.empty())
981 return Error(Loc, ErrorStr.c_str());
983 // FIXME: Arch specific.
984 bool isText = Segment == "__TEXT"; // FIXME: Hack.
985 Out.SwitchSection(Ctx.getMachOSection(Segment, Section, TAA, StubSize,
986 isText ? SectionKind::getText()
987 : SectionKind::getDataRel()));
991 /// ParseDirectiveSectionSwitch -
992 bool AsmParser::ParseDirectiveSectionSwitch(const char *Segment,
994 unsigned TAA, unsigned Align,
996 if (Lexer.isNot(AsmToken::EndOfStatement))
997 return TokError("unexpected token in section switching directive");
1000 // FIXME: Arch specific.
1001 bool isText = StringRef(Segment) == "__TEXT"; // FIXME: Hack.
1002 Out.SwitchSection(Ctx.getMachOSection(Segment, Section, TAA, StubSize,
1003 isText ? SectionKind::getText()
1004 : SectionKind::getDataRel()));
1006 // Set the implicit alignment, if any.
1008 // FIXME: This isn't really what 'as' does; I think it just uses the implicit
1009 // alignment on the section (e.g., if one manually inserts bytes into the
1010 // section, then just issueing the section switch directive will not realign
1011 // the section. However, this is arguably more reasonable behavior, and there
1012 // is no good reason for someone to intentionally emit incorrectly sized
1013 // values into the implicitly aligned sections.
1015 Out.EmitValueToAlignment(Align, 0, 1, 0);
1020 bool AsmParser::ParseEscapedString(std::string &Data) {
1021 assert(Lexer.is(AsmToken::String) && "Unexpected current token!");
1024 StringRef Str = getTok().getStringContents();
1025 for (unsigned i = 0, e = Str.size(); i != e; ++i) {
1026 if (Str[i] != '\\') {
1031 // Recognize escaped characters. Note that this escape semantics currently
1032 // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes.
1035 return TokError("unexpected backslash at end of string");
1037 // Recognize octal sequences.
1038 if ((unsigned) (Str[i] - '0') <= 7) {
1039 // Consume up to three octal characters.
1040 unsigned Value = Str[i] - '0';
1042 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
1044 Value = Value * 8 + (Str[i] - '0');
1046 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
1048 Value = Value * 8 + (Str[i] - '0');
1053 return TokError("invalid octal escape sequence (out of range)");
1055 Data += (unsigned char) Value;
1059 // Otherwise recognize individual escapes.
1062 // Just reject invalid escape sequences for now.
1063 return TokError("invalid escape sequence (unrecognized character)");
1065 case 'b': Data += '\b'; break;
1066 case 'f': Data += '\f'; break;
1067 case 'n': Data += '\n'; break;
1068 case 'r': Data += '\r'; break;
1069 case 't': Data += '\t'; break;
1070 case '"': Data += '"'; break;
1071 case '\\': Data += '\\'; break;
1078 /// ParseDirectiveAscii:
1079 /// ::= ( .ascii | .asciz ) [ "string" ( , "string" )* ]
1080 bool AsmParser::ParseDirectiveAscii(bool ZeroTerminated) {
1081 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1083 if (Lexer.isNot(AsmToken::String))
1084 return TokError("expected string in '.ascii' or '.asciz' directive");
1087 if (ParseEscapedString(Data))
1090 Out.EmitBytes(Data, DEFAULT_ADDRSPACE);
1092 Out.EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE);
1096 if (Lexer.is(AsmToken::EndOfStatement))
1099 if (Lexer.isNot(AsmToken::Comma))
1100 return TokError("unexpected token in '.ascii' or '.asciz' directive");
1109 /// ParseDirectiveValue
1110 /// ::= (.byte | .short | ... ) [ expression (, expression)* ]
1111 bool AsmParser::ParseDirectiveValue(unsigned Size) {
1112 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1114 const MCExpr *Value;
1115 SMLoc ATTRIBUTE_UNUSED StartLoc = Lexer.getLoc();
1116 if (ParseExpression(Value))
1119 // Special case constant expressions to match code generator.
1120 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value))
1121 Out.EmitIntValue(MCE->getValue(), Size, DEFAULT_ADDRSPACE);
1123 Out.EmitValue(Value, Size, DEFAULT_ADDRSPACE);
1125 if (Lexer.is(AsmToken::EndOfStatement))
1128 // FIXME: Improve diagnostic.
1129 if (Lexer.isNot(AsmToken::Comma))
1130 return TokError("unexpected token in directive");
1139 /// ParseDirectiveSpace
1140 /// ::= .space expression [ , expression ]
1141 bool AsmParser::ParseDirectiveSpace() {
1143 if (ParseAbsoluteExpression(NumBytes))
1146 int64_t FillExpr = 0;
1147 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1148 if (Lexer.isNot(AsmToken::Comma))
1149 return TokError("unexpected token in '.space' directive");
1152 if (ParseAbsoluteExpression(FillExpr))
1155 if (Lexer.isNot(AsmToken::EndOfStatement))
1156 return TokError("unexpected token in '.space' directive");
1162 return TokError("invalid number of bytes in '.space' directive");
1164 // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
1165 Out.EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE);
1170 /// ParseDirectiveFill
1171 /// ::= .fill expression , expression , expression
1172 bool AsmParser::ParseDirectiveFill() {
1174 if (ParseAbsoluteExpression(NumValues))
1177 if (Lexer.isNot(AsmToken::Comma))
1178 return TokError("unexpected token in '.fill' directive");
1182 if (ParseAbsoluteExpression(FillSize))
1185 if (Lexer.isNot(AsmToken::Comma))
1186 return TokError("unexpected token in '.fill' directive");
1190 if (ParseAbsoluteExpression(FillExpr))
1193 if (Lexer.isNot(AsmToken::EndOfStatement))
1194 return TokError("unexpected token in '.fill' directive");
1198 if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8)
1199 return TokError("invalid '.fill' size, expected 1, 2, 4, or 8");
1201 for (uint64_t i = 0, e = NumValues; i != e; ++i)
1202 Out.EmitIntValue(FillExpr, FillSize, DEFAULT_ADDRSPACE);
1207 /// ParseDirectiveOrg
1208 /// ::= .org expression [ , expression ]
1209 bool AsmParser::ParseDirectiveOrg() {
1210 const MCExpr *Offset;
1211 if (ParseExpression(Offset))
1214 // Parse optional fill expression.
1215 int64_t FillExpr = 0;
1216 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1217 if (Lexer.isNot(AsmToken::Comma))
1218 return TokError("unexpected token in '.org' directive");
1221 if (ParseAbsoluteExpression(FillExpr))
1224 if (Lexer.isNot(AsmToken::EndOfStatement))
1225 return TokError("unexpected token in '.org' directive");
1230 // FIXME: Only limited forms of relocatable expressions are accepted here, it
1231 // has to be relative to the current section.
1232 Out.EmitValueToOffset(Offset, FillExpr);
1237 /// ParseDirectiveAlign
1238 /// ::= {.align, ...} expression [ , expression [ , expression ]]
1239 bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
1240 SMLoc AlignmentLoc = Lexer.getLoc();
1242 if (ParseAbsoluteExpression(Alignment))
1246 bool HasFillExpr = false;
1247 int64_t FillExpr = 0;
1248 int64_t MaxBytesToFill = 0;
1249 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1250 if (Lexer.isNot(AsmToken::Comma))
1251 return TokError("unexpected token in directive");
1254 // The fill expression can be omitted while specifying a maximum number of
1255 // alignment bytes, e.g:
1257 if (Lexer.isNot(AsmToken::Comma)) {
1259 if (ParseAbsoluteExpression(FillExpr))
1263 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1264 if (Lexer.isNot(AsmToken::Comma))
1265 return TokError("unexpected token in directive");
1268 MaxBytesLoc = Lexer.getLoc();
1269 if (ParseAbsoluteExpression(MaxBytesToFill))
1272 if (Lexer.isNot(AsmToken::EndOfStatement))
1273 return TokError("unexpected token in directive");
1282 // Compute alignment in bytes.
1284 // FIXME: Diagnose overflow.
1285 if (Alignment >= 32) {
1286 Error(AlignmentLoc, "invalid alignment value");
1290 Alignment = 1ULL << Alignment;
1293 // Diagnose non-sensical max bytes to align.
1294 if (MaxBytesLoc.isValid()) {
1295 if (MaxBytesToFill < 1) {
1296 Error(MaxBytesLoc, "alignment directive can never be satisfied in this "
1297 "many bytes, ignoring maximum bytes expression");
1301 if (MaxBytesToFill >= Alignment) {
1302 Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and "
1308 // Check whether we should use optimal code alignment for this .align
1311 // FIXME: This should be using a target hook.
1312 bool UseCodeAlign = false;
1313 if (const MCSectionMachO *S = dyn_cast<MCSectionMachO>(
1314 Out.getCurrentSection()))
1315 UseCodeAlign = S->hasAttribute(MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
1316 if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
1317 ValueSize == 1 && UseCodeAlign) {
1318 Out.EmitCodeAlignment(Alignment, MaxBytesToFill);
1320 // FIXME: Target specific behavior about how the "extra" bytes are filled.
1321 Out.EmitValueToAlignment(Alignment, FillExpr, ValueSize, MaxBytesToFill);
1327 /// ParseDirectiveSymbolAttribute
1328 /// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
1329 bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
1330 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1334 if (ParseIdentifier(Name))
1335 return TokError("expected identifier in directive");
1337 MCSymbol *Sym = CreateSymbol(Name);
1339 Out.EmitSymbolAttribute(Sym, Attr);
1341 if (Lexer.is(AsmToken::EndOfStatement))
1344 if (Lexer.isNot(AsmToken::Comma))
1345 return TokError("unexpected token in directive");
1354 /// ParseDirectiveELFType
1355 /// ::= .type identifier , @attribute
1356 bool AsmParser::ParseDirectiveELFType() {
1358 if (ParseIdentifier(Name))
1359 return TokError("expected identifier in directive");
1361 // Handle the identifier as the key symbol.
1362 MCSymbol *Sym = CreateSymbol(Name);
1364 if (Lexer.isNot(AsmToken::Comma))
1365 return TokError("unexpected token in '.type' directive");
1368 if (Lexer.isNot(AsmToken::At))
1369 return TokError("expected '@' before type");
1375 TypeLoc = Lexer.getLoc();
1376 if (ParseIdentifier(Type))
1377 return TokError("expected symbol type in directive");
1379 MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Type)
1380 .Case("function", MCSA_ELF_TypeFunction)
1381 .Case("object", MCSA_ELF_TypeObject)
1382 .Case("tls_object", MCSA_ELF_TypeTLS)
1383 .Case("common", MCSA_ELF_TypeCommon)
1384 .Case("notype", MCSA_ELF_TypeNoType)
1385 .Default(MCSA_Invalid);
1387 if (Attr == MCSA_Invalid)
1388 return Error(TypeLoc, "unsupported attribute in '.type' directive");
1390 if (Lexer.isNot(AsmToken::EndOfStatement))
1391 return TokError("unexpected token in '.type' directive");
1395 Out.EmitSymbolAttribute(Sym, Attr);
1400 /// ParseDirectiveDarwinSymbolDesc
1401 /// ::= .desc identifier , expression
1402 bool AsmParser::ParseDirectiveDarwinSymbolDesc() {
1404 if (ParseIdentifier(Name))
1405 return TokError("expected identifier in directive");
1407 // Handle the identifier as the key symbol.
1408 MCSymbol *Sym = CreateSymbol(Name);
1410 if (Lexer.isNot(AsmToken::Comma))
1411 return TokError("unexpected token in '.desc' directive");
1415 if (ParseAbsoluteExpression(DescValue))
1418 if (Lexer.isNot(AsmToken::EndOfStatement))
1419 return TokError("unexpected token in '.desc' directive");
1423 // Set the n_desc field of this Symbol to this DescValue
1424 Out.EmitSymbolDesc(Sym, DescValue);
1429 /// ParseDirectiveComm
1430 /// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
1431 bool AsmParser::ParseDirectiveComm(bool IsLocal) {
1432 SMLoc IDLoc = Lexer.getLoc();
1434 if (ParseIdentifier(Name))
1435 return TokError("expected identifier in directive");
1437 // Handle the identifier as the key symbol.
1438 MCSymbol *Sym = CreateSymbol(Name);
1440 if (Lexer.isNot(AsmToken::Comma))
1441 return TokError("unexpected token in directive");
1445 SMLoc SizeLoc = Lexer.getLoc();
1446 if (ParseAbsoluteExpression(Size))
1449 int64_t Pow2Alignment = 0;
1450 SMLoc Pow2AlignmentLoc;
1451 if (Lexer.is(AsmToken::Comma)) {
1453 Pow2AlignmentLoc = Lexer.getLoc();
1454 if (ParseAbsoluteExpression(Pow2Alignment))
1457 // If this target takes alignments in bytes (not log) validate and convert.
1458 if (Lexer.getMAI().getAlignmentIsInBytes()) {
1459 if (!isPowerOf2_64(Pow2Alignment))
1460 return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
1461 Pow2Alignment = Log2_64(Pow2Alignment);
1465 if (Lexer.isNot(AsmToken::EndOfStatement))
1466 return TokError("unexpected token in '.comm' or '.lcomm' directive");
1470 // NOTE: a size of zero for a .comm should create a undefined symbol
1471 // but a size of .lcomm creates a bss symbol of size zero.
1473 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
1474 "be less than zero");
1476 // NOTE: The alignment in the directive is a power of 2 value, the assembler
1477 // may internally end up wanting an alignment in bytes.
1478 // FIXME: Diagnose overflow.
1479 if (Pow2Alignment < 0)
1480 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
1481 "alignment, can't be less than zero");
1483 if (!Sym->isUndefined())
1484 return Error(IDLoc, "invalid symbol redefinition");
1486 // '.lcomm' is equivalent to '.zerofill'.
1487 // Create the Symbol as a common or local common with Size and Pow2Alignment
1489 Out.EmitZerofill(Ctx.getMachOSection("__DATA", "__bss",
1490 MCSectionMachO::S_ZEROFILL, 0,
1491 SectionKind::getBSS()),
1492 Sym, Size, 1 << Pow2Alignment);
1496 Out.EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
1500 /// ParseDirectiveDarwinZerofill
1501 /// ::= .zerofill segname , sectname [, identifier , size_expression [
1502 /// , align_expression ]]
1503 bool AsmParser::ParseDirectiveDarwinZerofill() {
1505 if (ParseIdentifier(Segment))
1506 return TokError("expected segment name after '.zerofill' directive");
1508 if (Lexer.isNot(AsmToken::Comma))
1509 return TokError("unexpected token in directive");
1513 if (ParseIdentifier(Section))
1514 return TokError("expected section name after comma in '.zerofill' "
1517 // If this is the end of the line all that was wanted was to create the
1518 // the section but with no symbol.
1519 if (Lexer.is(AsmToken::EndOfStatement)) {
1520 // Create the zerofill section but no symbol
1521 Out.EmitZerofill(Ctx.getMachOSection(Segment, Section,
1522 MCSectionMachO::S_ZEROFILL, 0,
1523 SectionKind::getBSS()));
1527 if (Lexer.isNot(AsmToken::Comma))
1528 return TokError("unexpected token in directive");
1531 SMLoc IDLoc = Lexer.getLoc();
1533 if (ParseIdentifier(IDStr))
1534 return TokError("expected identifier in directive");
1536 // handle the identifier as the key symbol.
1537 MCSymbol *Sym = CreateSymbol(IDStr);
1539 if (Lexer.isNot(AsmToken::Comma))
1540 return TokError("unexpected token in directive");
1544 SMLoc SizeLoc = Lexer.getLoc();
1545 if (ParseAbsoluteExpression(Size))
1548 int64_t Pow2Alignment = 0;
1549 SMLoc Pow2AlignmentLoc;
1550 if (Lexer.is(AsmToken::Comma)) {
1552 Pow2AlignmentLoc = Lexer.getLoc();
1553 if (ParseAbsoluteExpression(Pow2Alignment))
1557 if (Lexer.isNot(AsmToken::EndOfStatement))
1558 return TokError("unexpected token in '.zerofill' directive");
1563 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
1566 // NOTE: The alignment in the directive is a power of 2 value, the assembler
1567 // may internally end up wanting an alignment in bytes.
1568 // FIXME: Diagnose overflow.
1569 if (Pow2Alignment < 0)
1570 return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
1571 "can't be less than zero");
1573 if (!Sym->isUndefined())
1574 return Error(IDLoc, "invalid symbol redefinition");
1576 // Create the zerofill Symbol with Size and Pow2Alignment
1578 // FIXME: Arch specific.
1579 Out.EmitZerofill(Ctx.getMachOSection(Segment, Section,
1580 MCSectionMachO::S_ZEROFILL, 0,
1581 SectionKind::getBSS()),
1582 Sym, Size, 1 << Pow2Alignment);
1587 /// ParseDirectiveDarwinTBSS
1588 /// ::= .tbss identifier, size, align
1589 bool AsmParser::ParseDirectiveDarwinTBSS() {
1590 SMLoc IDLoc = Lexer.getLoc();
1592 if (ParseIdentifier(Name))
1593 return TokError("expected identifier in directive");
1595 // Handle the identifier as the key symbol.
1596 MCSymbol *Sym = CreateSymbol(Name);
1598 if (Lexer.isNot(AsmToken::Comma))
1599 return TokError("unexpected token in directive");
1603 SMLoc SizeLoc = Lexer.getLoc();
1604 if (ParseAbsoluteExpression(Size))
1607 int64_t Pow2Alignment = 0;
1608 SMLoc Pow2AlignmentLoc;
1609 if (Lexer.is(AsmToken::Comma)) {
1611 Pow2AlignmentLoc = Lexer.getLoc();
1612 if (ParseAbsoluteExpression(Pow2Alignment))
1616 if (Lexer.isNot(AsmToken::EndOfStatement))
1617 return TokError("unexpected token in '.tbss' directive");
1622 return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
1625 // FIXME: Diagnose overflow.
1626 if (Pow2Alignment < 0)
1627 return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
1630 if (!Sym->isUndefined())
1631 return Error(IDLoc, "invalid symbol redefinition");
1633 Out.EmitTBSSSymbol(Ctx.getMachOSection("__DATA", "__thread_bss",
1634 MCSectionMachO::S_THREAD_LOCAL_ZEROFILL,
1635 0, SectionKind::getThreadBSS()),
1636 Sym, Size, 1 << Pow2Alignment);
1641 /// ParseDirectiveDarwinSubsectionsViaSymbols
1642 /// ::= .subsections_via_symbols
1643 bool AsmParser::ParseDirectiveDarwinSubsectionsViaSymbols() {
1644 if (Lexer.isNot(AsmToken::EndOfStatement))
1645 return TokError("unexpected token in '.subsections_via_symbols' directive");
1649 Out.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1654 /// ParseDirectiveAbort
1655 /// ::= .abort [ "abort_string" ]
1656 bool AsmParser::ParseDirectiveAbort() {
1657 // FIXME: Use loc from directive.
1658 SMLoc Loc = Lexer.getLoc();
1661 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1662 if (Lexer.isNot(AsmToken::String))
1663 return TokError("expected string in '.abort' directive");
1665 Str = getTok().getString();
1670 if (Lexer.isNot(AsmToken::EndOfStatement))
1671 return TokError("unexpected token in '.abort' directive");
1675 // FIXME: Handle here.
1677 Error(Loc, ".abort detected. Assembly stopping.");
1679 Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
1684 /// ParseDirectiveLsym
1685 /// ::= .lsym identifier , expression
1686 bool AsmParser::ParseDirectiveDarwinLsym() {
1688 if (ParseIdentifier(Name))
1689 return TokError("expected identifier in directive");
1691 // Handle the identifier as the key symbol.
1692 MCSymbol *Sym = CreateSymbol(Name);
1694 if (Lexer.isNot(AsmToken::Comma))
1695 return TokError("unexpected token in '.lsym' directive");
1698 const MCExpr *Value;
1699 if (ParseExpression(Value))
1702 if (Lexer.isNot(AsmToken::EndOfStatement))
1703 return TokError("unexpected token in '.lsym' directive");
1707 // We don't currently support this directive.
1709 // FIXME: Diagnostic location!
1711 return TokError("directive '.lsym' is unsupported");
1714 /// ParseDirectiveInclude
1715 /// ::= .include "filename"
1716 bool AsmParser::ParseDirectiveInclude() {
1717 if (Lexer.isNot(AsmToken::String))
1718 return TokError("expected string in '.include' directive");
1720 std::string Filename = getTok().getString();
1721 SMLoc IncludeLoc = Lexer.getLoc();
1724 if (Lexer.isNot(AsmToken::EndOfStatement))
1725 return TokError("unexpected token in '.include' directive");
1727 // Strip the quotes.
1728 Filename = Filename.substr(1, Filename.size()-2);
1730 // Attempt to switch the lexer to the included file before consuming the end
1731 // of statement to avoid losing it when we switch.
1732 if (EnterIncludeFile(Filename)) {
1733 PrintMessage(IncludeLoc,
1734 "Could not find include file '" + Filename + "'",
1742 /// ParseDirectiveDarwinDumpOrLoad
1743 /// ::= ( .dump | .load ) "filename"
1744 bool AsmParser::ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump) {
1745 if (Lexer.isNot(AsmToken::String))
1746 return TokError("expected string in '.dump' or '.load' directive");
1750 if (Lexer.isNot(AsmToken::EndOfStatement))
1751 return TokError("unexpected token in '.dump' or '.load' directive");
1755 // FIXME: If/when .dump and .load are implemented they will be done in the
1756 // the assembly parser and not have any need for an MCStreamer API.
1758 Warning(IDLoc, "ignoring directive .dump for now");
1760 Warning(IDLoc, "ignoring directive .load for now");
1765 /// ParseDirectiveDarwinSecureLogUnique
1766 /// ::= .secure_log_unique "log message"
1767 bool AsmParser::ParseDirectiveDarwinSecureLogUnique(SMLoc IDLoc) {
1768 std::string LogMessage;
1770 if (Lexer.isNot(AsmToken::String))
1773 LogMessage = getTok().getString();
1777 if (Lexer.isNot(AsmToken::EndOfStatement))
1778 return TokError("unexpected token in '.secure_log_unique' directive");
1780 if (getContext().getSecureLogUsed() != false)
1781 return Error(IDLoc, ".secure_log_unique specified multiple times");
1783 char *SecureLogFile = getContext().getSecureLogFile();
1784 if (SecureLogFile == NULL)
1785 return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
1786 "environment variable unset.");
1788 raw_ostream *OS = getContext().getSecureLog();
1791 OS = new raw_fd_ostream(SecureLogFile, Err, raw_fd_ostream::F_Append);
1794 return Error(IDLoc, Twine("can't open secure log file: ") +
1795 SecureLogFile + " (" + Err + ")");
1797 getContext().setSecureLog(OS);
1800 int CurBuf = SrcMgr.FindBufferContainingLoc(IDLoc);
1801 *OS << SrcMgr.getBufferInfo(CurBuf).Buffer->getBufferIdentifier() << ":"
1802 << SrcMgr.FindLineNumber(IDLoc, CurBuf) << ":"
1803 << LogMessage + "\n";
1805 getContext().setSecureLogUsed(true);
1810 /// ParseDirectiveDarwinSecureLogReset
1811 /// ::= .secure_log_reset
1812 bool AsmParser::ParseDirectiveDarwinSecureLogReset(SMLoc IDLoc) {
1813 if (Lexer.isNot(AsmToken::EndOfStatement))
1814 return TokError("unexpected token in '.secure_log_reset' directive");
1818 getContext().setSecureLogUsed(false);
1823 /// ParseDirectiveIf
1824 /// ::= .if expression
1825 bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
1826 TheCondStack.push_back(TheCondState);
1827 TheCondState.TheCond = AsmCond::IfCond;
1828 if(TheCondState.Ignore) {
1829 EatToEndOfStatement();
1833 if (ParseAbsoluteExpression(ExprValue))
1836 if (Lexer.isNot(AsmToken::EndOfStatement))
1837 return TokError("unexpected token in '.if' directive");
1841 TheCondState.CondMet = ExprValue;
1842 TheCondState.Ignore = !TheCondState.CondMet;
1848 /// ParseDirectiveElseIf
1849 /// ::= .elseif expression
1850 bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
1851 if (TheCondState.TheCond != AsmCond::IfCond &&
1852 TheCondState.TheCond != AsmCond::ElseIfCond)
1853 Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
1855 TheCondState.TheCond = AsmCond::ElseIfCond;
1857 bool LastIgnoreState = false;
1858 if (!TheCondStack.empty())
1859 LastIgnoreState = TheCondStack.back().Ignore;
1860 if (LastIgnoreState || TheCondState.CondMet) {
1861 TheCondState.Ignore = true;
1862 EatToEndOfStatement();
1866 if (ParseAbsoluteExpression(ExprValue))
1869 if (Lexer.isNot(AsmToken::EndOfStatement))
1870 return TokError("unexpected token in '.elseif' directive");
1873 TheCondState.CondMet = ExprValue;
1874 TheCondState.Ignore = !TheCondState.CondMet;
1880 /// ParseDirectiveElse
1882 bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
1883 if (Lexer.isNot(AsmToken::EndOfStatement))
1884 return TokError("unexpected token in '.else' directive");
1888 if (TheCondState.TheCond != AsmCond::IfCond &&
1889 TheCondState.TheCond != AsmCond::ElseIfCond)
1890 Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
1892 TheCondState.TheCond = AsmCond::ElseCond;
1893 bool LastIgnoreState = false;
1894 if (!TheCondStack.empty())
1895 LastIgnoreState = TheCondStack.back().Ignore;
1896 if (LastIgnoreState || TheCondState.CondMet)
1897 TheCondState.Ignore = true;
1899 TheCondState.Ignore = false;
1904 /// ParseDirectiveEndIf
1906 bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
1907 if (Lexer.isNot(AsmToken::EndOfStatement))
1908 return TokError("unexpected token in '.endif' directive");
1912 if ((TheCondState.TheCond == AsmCond::NoCond) ||
1913 TheCondStack.empty())
1914 Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
1916 if (!TheCondStack.empty()) {
1917 TheCondState = TheCondStack.back();
1918 TheCondStack.pop_back();
1924 /// ParseDirectiveFile
1925 /// ::= .file [number] string
1926 bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
1927 // FIXME: I'm not sure what this is.
1928 int64_t FileNumber = -1;
1929 if (getLexer().is(AsmToken::Integer)) {
1930 FileNumber = getTok().getIntVal();
1934 return TokError("file number less than one");
1937 if (getLexer().isNot(AsmToken::String))
1938 return TokError("unexpected token in '.file' directive");
1940 StringRef Filename = getTok().getString();
1941 Filename = Filename.substr(1, Filename.size()-2);
1944 if (getLexer().isNot(AsmToken::EndOfStatement))
1945 return TokError("unexpected token in '.file' directive");
1947 if (FileNumber == -1)
1948 getStreamer().EmitFileDirective(Filename);
1950 getStreamer().EmitDwarfFileDirective(FileNumber, Filename);
1955 /// ParseDirectiveLine
1956 /// ::= .line [number]
1957 bool GenericAsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) {
1958 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1959 if (getLexer().isNot(AsmToken::Integer))
1960 return TokError("unexpected token in '.line' directive");
1962 int64_t LineNumber = getTok().getIntVal();
1966 // FIXME: Do something with the .line.
1969 if (getLexer().isNot(AsmToken::EndOfStatement))
1970 return TokError("unexpected token in '.line' directive");
1976 /// ParseDirectiveLoc
1977 /// ::= .loc number [number [number]]
1978 bool GenericAsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
1979 if (getLexer().isNot(AsmToken::Integer))
1980 return TokError("unexpected token in '.loc' directive");
1982 // FIXME: What are these fields?
1983 int64_t FileNumber = getTok().getIntVal();
1985 // FIXME: Validate file.
1988 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1989 if (getLexer().isNot(AsmToken::Integer))
1990 return TokError("unexpected token in '.loc' directive");
1992 int64_t Param2 = getTok().getIntVal();
1996 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1997 if (getLexer().isNot(AsmToken::Integer))
1998 return TokError("unexpected token in '.loc' directive");
2000 int64_t Param3 = getTok().getIntVal();
2004 // FIXME: Do something with the .loc.
2008 if (getLexer().isNot(AsmToken::EndOfStatement))
2009 return TokError("unexpected token in '.file' directive");