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/ADT/APFloat.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/StringMap.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/ADT/Twine.h"
19 #include "llvm/MC/MCAsmInfo.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCParser/AsmCond.h"
23 #include "llvm/MC/MCParser/AsmLexer.h"
24 #include "llvm/MC/MCParser/MCAsmParser.h"
25 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
26 #include "llvm/MC/MCSectionMachO.h"
27 #include "llvm/MC/MCStreamer.h"
28 #include "llvm/MC/MCSymbol.h"
29 #include "llvm/MC/MCDwarf.h"
30 #include "llvm/Support/MemoryBuffer.h"
31 #include "llvm/Support/SourceMgr.h"
32 #include "llvm/Support/raw_ostream.h"
33 #include "llvm/Target/TargetAsmInfo.h"
34 #include "llvm/Target/TargetAsmParser.h"
41 /// \brief Helper class for tracking macro definitions.
47 Macro(StringRef N
, StringRef B
) : Name(N
), Body(B
) {}
50 /// \brief Helper class for storing information about an active macro
52 struct MacroInstantiation
{
53 /// The macro being instantiated.
54 const Macro
*TheMacro
;
56 /// The macro instantiation with substitutions.
57 MemoryBuffer
*Instantiation
;
59 /// The location of the instantiation.
60 SMLoc InstantiationLoc
;
62 /// The location where parsing should resume upon instantiation completion.
66 MacroInstantiation(const Macro
*M
, SMLoc IL
, SMLoc EL
,
67 const std::vector
<std::vector
<AsmToken
> > &A
);
70 /// \brief The concrete assembly parser instance.
71 class AsmParser
: public MCAsmParser
{
72 friend class GenericAsmParser
;
74 AsmParser(const AsmParser
&); // DO NOT IMPLEMENT
75 void operator=(const AsmParser
&); // DO NOT IMPLEMENT
81 MCAsmParserExtension
*GenericParser
;
82 MCAsmParserExtension
*PlatformParser
;
84 /// This is the current buffer index we're lexing from as managed by the
89 std::vector
<AsmCond
> TheCondStack
;
91 /// DirectiveMap - This is a table handlers for directives. Each handler is
92 /// invoked after the directive identifier is read and is responsible for
93 /// parsing and validating the rest of the directive. The handler is passed
94 /// in the directive name and the location of the directive keyword.
95 StringMap
<std::pair
<MCAsmParserExtension
*, DirectiveHandler
> > DirectiveMap
;
97 /// MacroMap - Map of currently defined macros.
98 StringMap
<Macro
*> MacroMap
;
100 /// ActiveMacros - Stack of active macro instantiations.
101 std::vector
<MacroInstantiation
*> ActiveMacros
;
103 /// Boolean tracking whether macro substitution is enabled.
104 unsigned MacrosEnabled
: 1;
106 /// Flag tracking whether any errors have been encountered.
107 unsigned HadError
: 1;
110 AsmParser(const Target
&T
, SourceMgr
&SM
, MCContext
&Ctx
, MCStreamer
&Out
,
111 const MCAsmInfo
&MAI
);
114 virtual bool Run(bool NoInitialTextSection
, bool NoFinalize
= false);
116 void AddDirectiveHandler(MCAsmParserExtension
*Object
,
118 DirectiveHandler Handler
) {
119 DirectiveMap
[Directive
] = std::make_pair(Object
, Handler
);
123 /// @name MCAsmParser Interface
126 virtual SourceMgr
&getSourceManager() { return SrcMgr
; }
127 virtual MCAsmLexer
&getLexer() { return Lexer
; }
128 virtual MCContext
&getContext() { return Ctx
; }
129 virtual MCStreamer
&getStreamer() { return Out
; }
131 virtual void Warning(SMLoc L
, const Twine
&Meg
);
132 virtual bool Error(SMLoc L
, const Twine
&Msg
);
134 const AsmToken
&Lex();
136 bool ParseExpression(const MCExpr
*&Res
);
137 virtual bool ParseExpression(const MCExpr
*&Res
, SMLoc
&EndLoc
);
138 virtual bool ParseParenExpression(const MCExpr
*&Res
, SMLoc
&EndLoc
);
139 virtual bool ParseAbsoluteExpression(int64_t &Res
);
144 void CheckForValidSection();
146 bool ParseStatement();
148 bool HandleMacroEntry(StringRef Name
, SMLoc NameLoc
, const Macro
*M
);
149 void HandleMacroExit();
151 void PrintMacroInstantiations();
152 void PrintMessage(SMLoc Loc
, const Twine
&Msg
, const char *Type
) const {
153 SrcMgr
.PrintMessage(Loc
, Msg
, Type
);
156 /// EnterIncludeFile - Enter the specified file. This returns true on failure.
157 bool EnterIncludeFile(const std::string
&Filename
);
159 /// \brief Reset the current lexer position to that given by \arg Loc. The
160 /// current token is not set; clients should ensure Lex() is called
162 void JumpToLoc(SMLoc Loc
);
164 void EatToEndOfStatement();
166 /// \brief Parse up to the end of statement and a return the contents from the
167 /// current token until the end of the statement; the current token on exit
168 /// will be either the EndOfStatement or EOF.
169 StringRef
ParseStringToEndOfStatement();
171 bool ParseAssignment(StringRef Name
, bool allow_redef
);
173 bool ParsePrimaryExpr(const MCExpr
*&Res
, SMLoc
&EndLoc
);
174 bool ParseBinOpRHS(unsigned Precedence
, const MCExpr
*&Res
, SMLoc
&EndLoc
);
175 bool ParseParenExpr(const MCExpr
*&Res
, SMLoc
&EndLoc
);
176 bool ParseBracketExpr(const MCExpr
*&Res
, SMLoc
&EndLoc
);
178 /// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
179 /// and set \arg Res to the identifier contents.
180 bool ParseIdentifier(StringRef
&Res
);
182 // Directive Parsing.
184 // ".ascii", ".asciiz", ".string"
185 bool ParseDirectiveAscii(StringRef IDVal
, bool ZeroTerminated
);
186 bool ParseDirectiveValue(unsigned Size
); // ".byte", ".long", ...
187 bool ParseDirectiveRealValue(const fltSemantics
&); // ".single", ...
188 bool ParseDirectiveFill(); // ".fill"
189 bool ParseDirectiveSpace(); // ".space"
190 bool ParseDirectiveZero(); // ".zero"
191 bool ParseDirectiveSet(StringRef IDVal
, bool allow_redef
); // ".set", ".equ", ".equiv"
192 bool ParseDirectiveOrg(); // ".org"
193 // ".align{,32}", ".p2align{,w,l}"
194 bool ParseDirectiveAlign(bool IsPow2
, unsigned ValueSize
);
196 /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which
197 /// accepts a single symbol (which should be a label or an external).
198 bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr
);
200 bool ParseDirectiveComm(bool IsLocal
); // ".comm" and ".lcomm"
202 bool ParseDirectiveAbort(); // ".abort"
203 bool ParseDirectiveInclude(); // ".include"
205 bool ParseDirectiveIf(SMLoc DirectiveLoc
); // ".if"
206 // ".ifdef" or ".ifndef", depending on expect_defined
207 bool ParseDirectiveIfdef(SMLoc DirectiveLoc
, bool expect_defined
);
208 bool ParseDirectiveElseIf(SMLoc DirectiveLoc
); // ".elseif"
209 bool ParseDirectiveElse(SMLoc DirectiveLoc
); // ".else"
210 bool ParseDirectiveEndIf(SMLoc DirectiveLoc
); // .endif
212 /// ParseEscapedString - Parse the current token as a string which may include
213 /// escaped characters and return the string contents.
214 bool ParseEscapedString(std::string
&Data
);
216 const MCExpr
*ApplyModifierToExpr(const MCExpr
*E
,
217 MCSymbolRefExpr::VariantKind Variant
);
220 /// \brief Generic implementations of directive handling, etc. which is shared
221 /// (or the default, at least) for all assembler parser.
222 class GenericAsmParser
: public MCAsmParserExtension
{
223 template<bool (GenericAsmParser::*Handler
)(StringRef
, SMLoc
)>
224 void AddDirectiveHandler(StringRef Directive
) {
225 getParser().AddDirectiveHandler(this, Directive
,
226 HandleDirective
<GenericAsmParser
, Handler
>);
229 GenericAsmParser() {}
231 AsmParser
&getParser() {
232 return (AsmParser
&) this->MCAsmParserExtension::getParser();
235 virtual void Initialize(MCAsmParser
&Parser
) {
236 // Call the base implementation.
237 this->MCAsmParserExtension::Initialize(Parser
);
239 // Debugging directives.
240 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveFile
>(".file");
241 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveLine
>(".line");
242 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveLoc
>(".loc");
243 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveStabs
>(".stabs");
246 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveCFIStartProc
>(
248 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveCFIEndProc
>(
250 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveCFIDefCfa
>(
252 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveCFIDefCfaOffset
>(
253 ".cfi_def_cfa_offset");
254 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveCFIAdjustCfaOffset
>(
255 ".cfi_adjust_cfa_offset");
256 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveCFIDefCfaRegister
>(
257 ".cfi_def_cfa_register");
258 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveCFIOffset
>(
260 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveCFIRelOffset
>(
263 &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda
>(".cfi_personality");
265 &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda
>(".cfi_lsda");
267 &GenericAsmParser::ParseDirectiveCFIRememberState
>(".cfi_remember_state");
269 &GenericAsmParser::ParseDirectiveCFIRestoreState
>(".cfi_restore_state");
271 &GenericAsmParser::ParseDirectiveCFISameValue
>(".cfi_same_value");
274 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveMacrosOnOff
>(
276 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveMacrosOnOff
>(
278 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveMacro
>(".macro");
279 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveEndMacro
>(".endm");
280 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveEndMacro
>(".endmacro");
282 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveLEB128
>(".sleb128");
283 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveLEB128
>(".uleb128");
286 bool ParseRegisterOrRegisterNumber(int64_t &Register
, SMLoc DirectiveLoc
);
288 bool ParseDirectiveFile(StringRef
, SMLoc DirectiveLoc
);
289 bool ParseDirectiveLine(StringRef
, SMLoc DirectiveLoc
);
290 bool ParseDirectiveLoc(StringRef
, SMLoc DirectiveLoc
);
291 bool ParseDirectiveStabs(StringRef
, SMLoc DirectiveLoc
);
292 bool ParseDirectiveCFIStartProc(StringRef
, SMLoc DirectiveLoc
);
293 bool ParseDirectiveCFIEndProc(StringRef
, SMLoc DirectiveLoc
);
294 bool ParseDirectiveCFIDefCfa(StringRef
, SMLoc DirectiveLoc
);
295 bool ParseDirectiveCFIDefCfaOffset(StringRef
, SMLoc DirectiveLoc
);
296 bool ParseDirectiveCFIAdjustCfaOffset(StringRef
, SMLoc DirectiveLoc
);
297 bool ParseDirectiveCFIDefCfaRegister(StringRef
, SMLoc DirectiveLoc
);
298 bool ParseDirectiveCFIOffset(StringRef
, SMLoc DirectiveLoc
);
299 bool ParseDirectiveCFIRelOffset(StringRef
, SMLoc DirectiveLoc
);
300 bool ParseDirectiveCFIPersonalityOrLsda(StringRef
, SMLoc DirectiveLoc
);
301 bool ParseDirectiveCFIRememberState(StringRef
, SMLoc DirectiveLoc
);
302 bool ParseDirectiveCFIRestoreState(StringRef
, SMLoc DirectiveLoc
);
303 bool ParseDirectiveCFISameValue(StringRef
, SMLoc DirectiveLoc
);
305 bool ParseDirectiveMacrosOnOff(StringRef
, SMLoc DirectiveLoc
);
306 bool ParseDirectiveMacro(StringRef
, SMLoc DirectiveLoc
);
307 bool ParseDirectiveEndMacro(StringRef
, SMLoc DirectiveLoc
);
309 bool ParseDirectiveLEB128(StringRef
, SMLoc
);
316 extern MCAsmParserExtension
*createDarwinAsmParser();
317 extern MCAsmParserExtension
*createELFAsmParser();
318 extern MCAsmParserExtension
*createCOFFAsmParser();
322 enum { DEFAULT_ADDRSPACE
= 0 };
324 AsmParser::AsmParser(const Target
&T
, SourceMgr
&_SM
, MCContext
&_Ctx
,
325 MCStreamer
&_Out
, const MCAsmInfo
&_MAI
)
326 : Lexer(_MAI
), Ctx(_Ctx
), Out(_Out
), SrcMgr(_SM
),
327 GenericParser(new GenericAsmParser
), PlatformParser(0),
328 CurBuffer(0), MacrosEnabled(true) {
329 Lexer
.setBuffer(SrcMgr
.getMemoryBuffer(CurBuffer
));
331 // Initialize the generic parser.
332 GenericParser
->Initialize(*this);
334 // Initialize the platform / file format parser.
336 // FIXME: This is a hack, we need to (majorly) cleanup how these objects are
338 if (_MAI
.hasMicrosoftFastStdCallMangling()) {
339 PlatformParser
= createCOFFAsmParser();
340 PlatformParser
->Initialize(*this);
341 } else if (_MAI
.hasSubsectionsViaSymbols()) {
342 PlatformParser
= createDarwinAsmParser();
343 PlatformParser
->Initialize(*this);
345 PlatformParser
= createELFAsmParser();
346 PlatformParser
->Initialize(*this);
350 AsmParser::~AsmParser() {
351 assert(ActiveMacros
.empty() && "Unexpected active macro instantiation!");
353 // Destroy any macros.
354 for (StringMap
<Macro
*>::iterator it
= MacroMap
.begin(),
355 ie
= MacroMap
.end(); it
!= ie
; ++it
)
356 delete it
->getValue();
358 delete PlatformParser
;
359 delete GenericParser
;
362 void AsmParser::PrintMacroInstantiations() {
363 // Print the active macro instantiation stack.
364 for (std::vector
<MacroInstantiation
*>::const_reverse_iterator
365 it
= ActiveMacros
.rbegin(), ie
= ActiveMacros
.rend(); it
!= ie
; ++it
)
366 PrintMessage((*it
)->InstantiationLoc
, "while in macro instantiation",
370 void AsmParser::Warning(SMLoc L
, const Twine
&Msg
) {
371 PrintMessage(L
, Msg
, "warning");
372 PrintMacroInstantiations();
375 bool AsmParser::Error(SMLoc L
, const Twine
&Msg
) {
377 PrintMessage(L
, Msg
, "error");
378 PrintMacroInstantiations();
382 bool AsmParser::EnterIncludeFile(const std::string
&Filename
) {
383 int NewBuf
= SrcMgr
.AddIncludeFile(Filename
, Lexer
.getLoc());
389 Lexer
.setBuffer(SrcMgr
.getMemoryBuffer(CurBuffer
));
394 void AsmParser::JumpToLoc(SMLoc Loc
) {
395 CurBuffer
= SrcMgr
.FindBufferContainingLoc(Loc
);
396 Lexer
.setBuffer(SrcMgr
.getMemoryBuffer(CurBuffer
), Loc
.getPointer());
399 const AsmToken
&AsmParser::Lex() {
400 const AsmToken
*tok
= &Lexer
.Lex();
402 if (tok
->is(AsmToken::Eof
)) {
403 // If this is the end of an included file, pop the parent file off the
405 SMLoc ParentIncludeLoc
= SrcMgr
.getParentIncludeLoc(CurBuffer
);
406 if (ParentIncludeLoc
!= SMLoc()) {
407 JumpToLoc(ParentIncludeLoc
);
412 if (tok
->is(AsmToken::Error
))
413 Error(Lexer
.getErrLoc(), Lexer
.getErr());
418 bool AsmParser::Run(bool NoInitialTextSection
, bool NoFinalize
) {
419 // Create the initial section, if requested.
420 if (!NoInitialTextSection
)
427 AsmCond StartingCondState
= TheCondState
;
429 // While we have input, parse each statement.
430 while (Lexer
.isNot(AsmToken::Eof
)) {
431 if (!ParseStatement()) continue;
433 // We had an error, validate that one was emitted and recover by skipping to
435 assert(HadError
&& "Parse statement returned an error, but none emitted!");
436 EatToEndOfStatement();
439 if (TheCondState
.TheCond
!= StartingCondState
.TheCond
||
440 TheCondState
.Ignore
!= StartingCondState
.Ignore
)
441 return TokError("unmatched .ifs or .elses");
443 // Check to see there are no empty DwarfFile slots.
444 const std::vector
<MCDwarfFile
*> &MCDwarfFiles
=
445 getContext().getMCDwarfFiles();
446 for (unsigned i
= 1; i
< MCDwarfFiles
.size(); i
++) {
447 if (!MCDwarfFiles
[i
])
448 TokError("unassigned file number: " + Twine(i
) + " for .file directives");
451 // Finalize the output stream if there are no errors and if the client wants
453 if (!HadError
&& !NoFinalize
)
459 void AsmParser::CheckForValidSection() {
460 if (!getStreamer().getCurrentSection()) {
461 TokError("expected section directive before assembly directive");
462 Out
.SwitchSection(Ctx
.getMachOSection(
464 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS
,
465 0, SectionKind::getText()));
469 /// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
470 void AsmParser::EatToEndOfStatement() {
471 while (Lexer
.isNot(AsmToken::EndOfStatement
) &&
472 Lexer
.isNot(AsmToken::Eof
))
476 if (Lexer
.is(AsmToken::EndOfStatement
))
480 StringRef
AsmParser::ParseStringToEndOfStatement() {
481 const char *Start
= getTok().getLoc().getPointer();
483 while (Lexer
.isNot(AsmToken::EndOfStatement
) &&
484 Lexer
.isNot(AsmToken::Eof
))
487 const char *End
= getTok().getLoc().getPointer();
488 return StringRef(Start
, End
- Start
);
491 /// ParseParenExpr - Parse a paren expression and return it.
492 /// NOTE: This assumes the leading '(' has already been consumed.
494 /// parenexpr ::= expr)
496 bool AsmParser::ParseParenExpr(const MCExpr
*&Res
, SMLoc
&EndLoc
) {
497 if (ParseExpression(Res
)) return true;
498 if (Lexer
.isNot(AsmToken::RParen
))
499 return TokError("expected ')' in parentheses expression");
500 EndLoc
= Lexer
.getLoc();
505 /// ParseBracketExpr - Parse a bracket expression and return it.
506 /// NOTE: This assumes the leading '[' has already been consumed.
508 /// bracketexpr ::= expr]
510 bool AsmParser::ParseBracketExpr(const MCExpr
*&Res
, SMLoc
&EndLoc
) {
511 if (ParseExpression(Res
)) return true;
512 if (Lexer
.isNot(AsmToken::RBrac
))
513 return TokError("expected ']' in brackets expression");
514 EndLoc
= Lexer
.getLoc();
519 /// ParsePrimaryExpr - Parse a primary expression and return it.
520 /// primaryexpr ::= (parenexpr
521 /// primaryexpr ::= symbol
522 /// primaryexpr ::= number
523 /// primaryexpr ::= '.'
524 /// primaryexpr ::= ~,+,- primaryexpr
525 bool AsmParser::ParsePrimaryExpr(const MCExpr
*&Res
, SMLoc
&EndLoc
) {
526 switch (Lexer
.getKind()) {
528 return TokError("unknown token in expression");
529 // If we have an error assume that we've already handled it.
530 case AsmToken::Error
:
532 case AsmToken::Exclaim
:
533 Lex(); // Eat the operator.
534 if (ParsePrimaryExpr(Res
, EndLoc
))
536 Res
= MCUnaryExpr::CreateLNot(Res
, getContext());
538 case AsmToken::Dollar
:
539 case AsmToken::String
:
540 case AsmToken::Identifier
: {
541 EndLoc
= Lexer
.getLoc();
543 StringRef Identifier
;
544 if (ParseIdentifier(Identifier
))
547 // This is a symbol reference.
548 std::pair
<StringRef
, StringRef
> Split
= Identifier
.split('@');
549 MCSymbol
*Sym
= getContext().GetOrCreateSymbol(Split
.first
);
551 // Lookup the symbol variant if used.
552 MCSymbolRefExpr::VariantKind Variant
= MCSymbolRefExpr::VK_None
;
553 if (Split
.first
.size() != Identifier
.size()) {
554 Variant
= MCSymbolRefExpr::getVariantKindForName(Split
.second
);
555 if (Variant
== MCSymbolRefExpr::VK_Invalid
) {
556 Variant
= MCSymbolRefExpr::VK_None
;
557 return TokError("invalid variant '" + Split
.second
+ "'");
561 // If this is an absolute variable reference, substitute it now to preserve
562 // semantics in the face of reassignment.
563 if (Sym
->isVariable() && isa
<MCConstantExpr
>(Sym
->getVariableValue())) {
565 return Error(EndLoc
, "unexpected modifier on variable reference");
567 Res
= Sym
->getVariableValue();
571 // Otherwise create a symbol ref.
572 Res
= MCSymbolRefExpr::Create(Sym
, Variant
, getContext());
575 case AsmToken::Integer
: {
576 SMLoc Loc
= getTok().getLoc();
577 int64_t IntVal
= getTok().getIntVal();
578 Res
= MCConstantExpr::Create(IntVal
, getContext());
579 EndLoc
= Lexer
.getLoc();
581 // Look for 'b' or 'f' following an Integer as a directional label
582 if (Lexer
.getKind() == AsmToken::Identifier
) {
583 StringRef IDVal
= getTok().getString();
584 if (IDVal
== "f" || IDVal
== "b"){
585 MCSymbol
*Sym
= Ctx
.GetDirectionalLocalSymbol(IntVal
,
586 IDVal
== "f" ? 1 : 0);
587 Res
= MCSymbolRefExpr::Create(Sym
, MCSymbolRefExpr::VK_None
,
589 if(IDVal
== "b" && Sym
->isUndefined())
590 return Error(Loc
, "invalid reference to undefined symbol");
591 EndLoc
= Lexer
.getLoc();
592 Lex(); // Eat identifier.
597 case AsmToken::Real
: {
598 APFloat
RealVal(APFloat::IEEEdouble
, getTok().getString());
599 uint64_t IntVal
= RealVal
.bitcastToAPInt().getZExtValue();
600 Res
= MCConstantExpr::Create(IntVal
, getContext());
604 case AsmToken::Dot
: {
605 // This is a '.' reference, which references the current PC. Emit a
606 // temporary label to the streamer and refer to it.
607 MCSymbol
*Sym
= Ctx
.CreateTempSymbol();
609 Res
= MCSymbolRefExpr::Create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
610 EndLoc
= Lexer
.getLoc();
611 Lex(); // Eat identifier.
614 case AsmToken::LParen
:
615 Lex(); // Eat the '('.
616 return ParseParenExpr(Res
, EndLoc
);
617 case AsmToken::LBrac
:
618 if (!PlatformParser
->HasBracketExpressions())
619 return TokError("brackets expression not supported on this target");
620 Lex(); // Eat the '['.
621 return ParseBracketExpr(Res
, EndLoc
);
622 case AsmToken::Minus
:
623 Lex(); // Eat the operator.
624 if (ParsePrimaryExpr(Res
, EndLoc
))
626 Res
= MCUnaryExpr::CreateMinus(Res
, getContext());
629 Lex(); // Eat the operator.
630 if (ParsePrimaryExpr(Res
, EndLoc
))
632 Res
= MCUnaryExpr::CreatePlus(Res
, getContext());
634 case AsmToken::Tilde
:
635 Lex(); // Eat the operator.
636 if (ParsePrimaryExpr(Res
, EndLoc
))
638 Res
= MCUnaryExpr::CreateNot(Res
, getContext());
643 bool AsmParser::ParseExpression(const MCExpr
*&Res
) {
645 return ParseExpression(Res
, EndLoc
);
649 AsmParser::ApplyModifierToExpr(const MCExpr
*E
,
650 MCSymbolRefExpr::VariantKind Variant
) {
651 // Recurse over the given expression, rebuilding it to apply the given variant
652 // if there is exactly one symbol.
653 switch (E
->getKind()) {
655 case MCExpr::Constant
:
658 case MCExpr::SymbolRef
: {
659 const MCSymbolRefExpr
*SRE
= cast
<MCSymbolRefExpr
>(E
);
661 if (SRE
->getKind() != MCSymbolRefExpr::VK_None
) {
662 TokError("invalid variant on expression '" +
663 getTok().getIdentifier() + "' (already modified)");
667 return MCSymbolRefExpr::Create(&SRE
->getSymbol(), Variant
, getContext());
670 case MCExpr::Unary
: {
671 const MCUnaryExpr
*UE
= cast
<MCUnaryExpr
>(E
);
672 const MCExpr
*Sub
= ApplyModifierToExpr(UE
->getSubExpr(), Variant
);
675 return MCUnaryExpr::Create(UE
->getOpcode(), Sub
, getContext());
678 case MCExpr::Binary
: {
679 const MCBinaryExpr
*BE
= cast
<MCBinaryExpr
>(E
);
680 const MCExpr
*LHS
= ApplyModifierToExpr(BE
->getLHS(), Variant
);
681 const MCExpr
*RHS
= ApplyModifierToExpr(BE
->getRHS(), Variant
);
686 if (!LHS
) LHS
= BE
->getLHS();
687 if (!RHS
) RHS
= BE
->getRHS();
689 return MCBinaryExpr::Create(BE
->getOpcode(), LHS
, RHS
, getContext());
693 assert(0 && "Invalid expression kind!");
697 /// ParseExpression - Parse an expression and return it.
699 /// expr ::= expr +,- expr -> lowest.
700 /// expr ::= expr |,^,&,! expr -> middle.
701 /// expr ::= expr *,/,%,<<,>> expr -> highest.
702 /// expr ::= primaryexpr
704 bool AsmParser::ParseExpression(const MCExpr
*&Res
, SMLoc
&EndLoc
) {
705 // Parse the expression.
707 if (ParsePrimaryExpr(Res
, EndLoc
) || ParseBinOpRHS(1, Res
, EndLoc
))
710 // As a special case, we support 'a op b @ modifier' by rewriting the
711 // expression to include the modifier. This is inefficient, but in general we
712 // expect users to use 'a@modifier op b'.
713 if (Lexer
.getKind() == AsmToken::At
) {
716 if (Lexer
.isNot(AsmToken::Identifier
))
717 return TokError("unexpected symbol modifier following '@'");
719 MCSymbolRefExpr::VariantKind Variant
=
720 MCSymbolRefExpr::getVariantKindForName(getTok().getIdentifier());
721 if (Variant
== MCSymbolRefExpr::VK_Invalid
)
722 return TokError("invalid variant '" + getTok().getIdentifier() + "'");
724 const MCExpr
*ModifiedRes
= ApplyModifierToExpr(Res
, Variant
);
726 return TokError("invalid modifier '" + getTok().getIdentifier() +
727 "' (no symbols present)");
735 // Try to constant fold it up front, if possible.
737 if (Res
->EvaluateAsAbsolute(Value
))
738 Res
= MCConstantExpr::Create(Value
, getContext());
743 bool AsmParser::ParseParenExpression(const MCExpr
*&Res
, SMLoc
&EndLoc
) {
745 return ParseParenExpr(Res
, EndLoc
) ||
746 ParseBinOpRHS(1, Res
, EndLoc
);
749 bool AsmParser::ParseAbsoluteExpression(int64_t &Res
) {
752 SMLoc StartLoc
= Lexer
.getLoc();
753 if (ParseExpression(Expr
))
756 if (!Expr
->EvaluateAsAbsolute(Res
))
757 return Error(StartLoc
, "expected absolute expression");
762 static unsigned getBinOpPrecedence(AsmToken::TokenKind K
,
763 MCBinaryExpr::Opcode
&Kind
) {
766 return 0; // not a binop.
768 // Lowest Precedence: &&, ||, @
769 case AsmToken::AmpAmp
:
770 Kind
= MCBinaryExpr::LAnd
;
772 case AsmToken::PipePipe
:
773 Kind
= MCBinaryExpr::LOr
;
777 // Low Precedence: |, &, ^
779 // FIXME: gas seems to support '!' as an infix operator?
781 Kind
= MCBinaryExpr::Or
;
783 case AsmToken::Caret
:
784 Kind
= MCBinaryExpr::Xor
;
787 Kind
= MCBinaryExpr::And
;
790 // Low Intermediate Precedence: ==, !=, <>, <, <=, >, >=
791 case AsmToken::EqualEqual
:
792 Kind
= MCBinaryExpr::EQ
;
794 case AsmToken::ExclaimEqual
:
795 case AsmToken::LessGreater
:
796 Kind
= MCBinaryExpr::NE
;
799 Kind
= MCBinaryExpr::LT
;
801 case AsmToken::LessEqual
:
802 Kind
= MCBinaryExpr::LTE
;
804 case AsmToken::Greater
:
805 Kind
= MCBinaryExpr::GT
;
807 case AsmToken::GreaterEqual
:
808 Kind
= MCBinaryExpr::GTE
;
811 // High Intermediate Precedence: +, -
813 Kind
= MCBinaryExpr::Add
;
815 case AsmToken::Minus
:
816 Kind
= MCBinaryExpr::Sub
;
819 // Highest Precedence: *, /, %, <<, >>
821 Kind
= MCBinaryExpr::Mul
;
823 case AsmToken::Slash
:
824 Kind
= MCBinaryExpr::Div
;
826 case AsmToken::Percent
:
827 Kind
= MCBinaryExpr::Mod
;
829 case AsmToken::LessLess
:
830 Kind
= MCBinaryExpr::Shl
;
832 case AsmToken::GreaterGreater
:
833 Kind
= MCBinaryExpr::Shr
;
839 /// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
840 /// Res contains the LHS of the expression on input.
841 bool AsmParser::ParseBinOpRHS(unsigned Precedence
, const MCExpr
*&Res
,
844 MCBinaryExpr::Opcode Kind
= MCBinaryExpr::Add
;
845 unsigned TokPrec
= getBinOpPrecedence(Lexer
.getKind(), Kind
);
847 // If the next token is lower precedence than we are allowed to eat, return
848 // successfully with what we ate already.
849 if (TokPrec
< Precedence
)
854 // Eat the next primary expression.
856 if (ParsePrimaryExpr(RHS
, EndLoc
)) return true;
858 // If BinOp binds less tightly with RHS than the operator after RHS, let
859 // the pending operator take RHS as its LHS.
860 MCBinaryExpr::Opcode Dummy
;
861 unsigned NextTokPrec
= getBinOpPrecedence(Lexer
.getKind(), Dummy
);
862 if (TokPrec
< NextTokPrec
) {
863 if (ParseBinOpRHS(Precedence
+1, RHS
, EndLoc
)) return true;
866 // Merge LHS and RHS according to operator.
867 Res
= MCBinaryExpr::Create(Kind
, Res
, RHS
, getContext());
875 /// ::= EndOfStatement
876 /// ::= Label* Directive ...Operands... EndOfStatement
877 /// ::= Label* Identifier OperandList* EndOfStatement
878 bool AsmParser::ParseStatement() {
879 if (Lexer
.is(AsmToken::EndOfStatement
)) {
885 // Statements always start with an identifier or are a full line comment.
886 AsmToken ID
= getTok();
887 SMLoc IDLoc
= ID
.getLoc();
889 int64_t LocalLabelVal
= -1;
890 // A full line comment is a '#' as the first token.
891 if (Lexer
.is(AsmToken::Hash
)) {
892 EatToEndOfStatement();
896 // Allow an integer followed by a ':' as a directional local label.
897 if (Lexer
.is(AsmToken::Integer
)) {
898 LocalLabelVal
= getTok().getIntVal();
899 if (LocalLabelVal
< 0) {
900 if (!TheCondState
.Ignore
)
901 return TokError("unexpected token at start of statement");
905 IDVal
= getTok().getString();
906 Lex(); // Consume the integer token to be used as an identifier token.
907 if (Lexer
.getKind() != AsmToken::Colon
) {
908 if (!TheCondState
.Ignore
)
909 return TokError("unexpected token at start of statement");
913 } else if (Lexer
.is(AsmToken::Dot
)) {
914 // Treat '.' as a valid identifier in this context.
918 } else if (ParseIdentifier(IDVal
)) {
919 if (!TheCondState
.Ignore
)
920 return TokError("unexpected token at start of statement");
925 // Handle conditional assembly here before checking for skipping. We
926 // have to do this so that .endif isn't skipped in a ".if 0" block for
929 return ParseDirectiveIf(IDLoc
);
930 if (IDVal
== ".ifdef")
931 return ParseDirectiveIfdef(IDLoc
, true);
932 if (IDVal
== ".ifndef" || IDVal
== ".ifnotdef")
933 return ParseDirectiveIfdef(IDLoc
, false);
934 if (IDVal
== ".elseif")
935 return ParseDirectiveElseIf(IDLoc
);
936 if (IDVal
== ".else")
937 return ParseDirectiveElse(IDLoc
);
938 if (IDVal
== ".endif")
939 return ParseDirectiveEndIf(IDLoc
);
941 // If we are in a ".if 0" block, ignore this statement.
942 if (TheCondState
.Ignore
) {
943 EatToEndOfStatement();
947 // FIXME: Recurse on local labels?
949 // See what kind of statement we have.
950 switch (Lexer
.getKind()) {
951 case AsmToken::Colon
: {
952 CheckForValidSection();
954 // identifier ':' -> Label.
957 // Diagnose attempt to use '.' as a label.
959 return Error(IDLoc
, "invalid use of pseudo-symbol '.' as a label");
961 // Diagnose attempt to use a variable as a label.
963 // FIXME: Diagnostics. Note the location of the definition as a label.
964 // FIXME: This doesn't diagnose assignment to a symbol which has been
965 // implicitly marked as external.
967 if (LocalLabelVal
== -1)
968 Sym
= getContext().GetOrCreateSymbol(IDVal
);
970 Sym
= Ctx
.CreateDirectionalLocalSymbol(LocalLabelVal
);
971 if (!Sym
->isUndefined() || Sym
->isVariable())
972 return Error(IDLoc
, "invalid symbol redefinition");
977 // Consume any end of statement token, if present, to avoid spurious
978 // AddBlankLine calls().
979 if (Lexer
.is(AsmToken::EndOfStatement
)) {
981 if (Lexer
.is(AsmToken::Eof
))
985 return ParseStatement();
988 case AsmToken::Equal
:
989 // identifier '=' ... -> assignment statement
992 return ParseAssignment(IDVal
, true);
994 default: // Normal instruction or directive.
998 // If macros are enabled, check to see if this is a macro instantiation.
1000 if (const Macro
*M
= MacroMap
.lookup(IDVal
))
1001 return HandleMacroEntry(IDVal
, IDLoc
, M
);
1003 // Otherwise, we have a normal instruction or directive.
1004 if (IDVal
[0] == '.' && IDVal
!= ".") {
1005 // Assembler features
1006 if (IDVal
== ".set" || IDVal
== ".equ")
1007 return ParseDirectiveSet(IDVal
, true);
1008 if (IDVal
== ".equiv")
1009 return ParseDirectiveSet(IDVal
, false);
1013 if (IDVal
== ".ascii")
1014 return ParseDirectiveAscii(IDVal
, false);
1015 if (IDVal
== ".asciz" || IDVal
== ".string")
1016 return ParseDirectiveAscii(IDVal
, true);
1018 if (IDVal
== ".byte")
1019 return ParseDirectiveValue(1);
1020 if (IDVal
== ".short")
1021 return ParseDirectiveValue(2);
1022 if (IDVal
== ".value")
1023 return ParseDirectiveValue(2);
1024 if (IDVal
== ".2byte")
1025 return ParseDirectiveValue(2);
1026 if (IDVal
== ".long")
1027 return ParseDirectiveValue(4);
1028 if (IDVal
== ".int")
1029 return ParseDirectiveValue(4);
1030 if (IDVal
== ".4byte")
1031 return ParseDirectiveValue(4);
1032 if (IDVal
== ".quad")
1033 return ParseDirectiveValue(8);
1034 if (IDVal
== ".8byte")
1035 return ParseDirectiveValue(8);
1036 if (IDVal
== ".single" || IDVal
== ".float")
1037 return ParseDirectiveRealValue(APFloat::IEEEsingle
);
1038 if (IDVal
== ".double")
1039 return ParseDirectiveRealValue(APFloat::IEEEdouble
);
1041 if (IDVal
== ".align") {
1042 bool IsPow2
= !getContext().getAsmInfo().getAlignmentIsInBytes();
1043 return ParseDirectiveAlign(IsPow2
, /*ExprSize=*/1);
1045 if (IDVal
== ".align32") {
1046 bool IsPow2
= !getContext().getAsmInfo().getAlignmentIsInBytes();
1047 return ParseDirectiveAlign(IsPow2
, /*ExprSize=*/4);
1049 if (IDVal
== ".balign")
1050 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
1051 if (IDVal
== ".balignw")
1052 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
1053 if (IDVal
== ".balignl")
1054 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
1055 if (IDVal
== ".p2align")
1056 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
1057 if (IDVal
== ".p2alignw")
1058 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
1059 if (IDVal
== ".p2alignl")
1060 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
1062 if (IDVal
== ".org")
1063 return ParseDirectiveOrg();
1065 if (IDVal
== ".fill")
1066 return ParseDirectiveFill();
1067 if (IDVal
== ".space" || IDVal
== ".skip")
1068 return ParseDirectiveSpace();
1069 if (IDVal
== ".zero")
1070 return ParseDirectiveZero();
1072 // Symbol attribute directives
1074 if (IDVal
== ".globl" || IDVal
== ".global")
1075 return ParseDirectiveSymbolAttribute(MCSA_Global
);
1076 // ELF only? Should it be here?
1077 if (IDVal
== ".local")
1078 return ParseDirectiveSymbolAttribute(MCSA_Local
);
1079 if (IDVal
== ".hidden")
1080 return ParseDirectiveSymbolAttribute(MCSA_Hidden
);
1081 if (IDVal
== ".indirect_symbol")
1082 return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol
);
1083 if (IDVal
== ".internal")
1084 return ParseDirectiveSymbolAttribute(MCSA_Internal
);
1085 if (IDVal
== ".lazy_reference")
1086 return ParseDirectiveSymbolAttribute(MCSA_LazyReference
);
1087 if (IDVal
== ".no_dead_strip")
1088 return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip
);
1089 if (IDVal
== ".symbol_resolver")
1090 return ParseDirectiveSymbolAttribute(MCSA_SymbolResolver
);
1091 if (IDVal
== ".private_extern")
1092 return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern
);
1093 if (IDVal
== ".protected")
1094 return ParseDirectiveSymbolAttribute(MCSA_Protected
);
1095 if (IDVal
== ".reference")
1096 return ParseDirectiveSymbolAttribute(MCSA_Reference
);
1097 if (IDVal
== ".weak")
1098 return ParseDirectiveSymbolAttribute(MCSA_Weak
);
1099 if (IDVal
== ".weak_definition")
1100 return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition
);
1101 if (IDVal
== ".weak_reference")
1102 return ParseDirectiveSymbolAttribute(MCSA_WeakReference
);
1103 if (IDVal
== ".weak_def_can_be_hidden")
1104 return ParseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate
);
1106 if (IDVal
== ".comm")
1107 return ParseDirectiveComm(/*IsLocal=*/false);
1108 if (IDVal
== ".lcomm")
1109 return ParseDirectiveComm(/*IsLocal=*/true);
1111 if (IDVal
== ".abort")
1112 return ParseDirectiveAbort();
1113 if (IDVal
== ".include")
1114 return ParseDirectiveInclude();
1116 if (IDVal
== ".code16" || IDVal
== ".code32" || IDVal
== ".code64")
1117 return TokError(Twine(IDVal
) + " not supported yet");
1119 // Look up the handler in the handler table.
1120 std::pair
<MCAsmParserExtension
*, DirectiveHandler
> Handler
=
1121 DirectiveMap
.lookup(IDVal
);
1123 return (*Handler
.second
)(Handler
.first
, IDVal
, IDLoc
);
1125 // Target hook for parsing target specific directives.
1126 if (!getTargetParser().ParseDirective(ID
))
1129 Warning(IDLoc
, "ignoring directive for now");
1130 EatToEndOfStatement();
1134 CheckForValidSection();
1136 // Canonicalize the opcode to lower case.
1137 SmallString
<128> Opcode
;
1138 for (unsigned i
= 0, e
= IDVal
.size(); i
!= e
; ++i
)
1139 Opcode
.push_back(tolower(IDVal
[i
]));
1141 SmallVector
<MCParsedAsmOperand
*, 8> ParsedOperands
;
1142 bool HadError
= getTargetParser().ParseInstruction(Opcode
.str(), IDLoc
,
1145 // Dump the parsed representation, if requested.
1146 if (getShowParsedOperands()) {
1147 SmallString
<256> Str
;
1148 raw_svector_ostream
OS(Str
);
1149 OS
<< "parsed instruction: [";
1150 for (unsigned i
= 0; i
!= ParsedOperands
.size(); ++i
) {
1153 ParsedOperands
[i
]->dump(OS
);
1157 PrintMessage(IDLoc
, OS
.str(), "note");
1160 // If parsing succeeded, match the instruction.
1162 HadError
= getTargetParser().MatchAndEmitInstruction(IDLoc
, ParsedOperands
,
1165 // Free any parsed operands.
1166 for (unsigned i
= 0, e
= ParsedOperands
.size(); i
!= e
; ++i
)
1167 delete ParsedOperands
[i
];
1169 // Don't skip the rest of the line, the instruction parser is responsible for
1174 MacroInstantiation::MacroInstantiation(const Macro
*M
, SMLoc IL
, SMLoc EL
,
1175 const std::vector
<std::vector
<AsmToken
> > &A
)
1176 : TheMacro(M
), InstantiationLoc(IL
), ExitLoc(EL
)
1178 // Macro instantiation is lexical, unfortunately. We construct a new buffer
1179 // to hold the macro body with substitutions.
1180 SmallString
<256> Buf
;
1181 raw_svector_ostream
OS(Buf
);
1183 StringRef Body
= M
->Body
;
1184 while (!Body
.empty()) {
1185 // Scan for the next substitution.
1186 std::size_t End
= Body
.size(), Pos
= 0;
1187 for (; Pos
!= End
; ++Pos
) {
1188 // Check for a substitution or escape.
1189 if (Body
[Pos
] != '$' || Pos
+ 1 == End
)
1192 char Next
= Body
[Pos
+ 1];
1193 if (Next
== '$' || Next
== 'n' || isdigit(Next
))
1198 OS
<< Body
.slice(0, Pos
);
1200 // Check if we reached the end.
1204 switch (Body
[Pos
+1]) {
1210 // $n => number of arguments
1215 // $[0-9] => argument
1217 // Missing arguments are ignored.
1218 unsigned Index
= Body
[Pos
+1] - '0';
1219 if (Index
>= A
.size())
1222 // Otherwise substitute with the token values, with spaces eliminated.
1223 for (std::vector
<AsmToken
>::const_iterator it
= A
[Index
].begin(),
1224 ie
= A
[Index
].end(); it
!= ie
; ++it
)
1225 OS
<< it
->getString();
1230 // Update the scan point.
1231 Body
= Body
.substr(Pos
+ 2);
1234 // We include the .endmacro in the buffer as our queue to exit the macro
1236 OS
<< ".endmacro\n";
1238 Instantiation
= MemoryBuffer::getMemBufferCopy(OS
.str(), "<instantiation>");
1241 bool AsmParser::HandleMacroEntry(StringRef Name
, SMLoc NameLoc
,
1243 // Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate
1244 // this, although we should protect against infinite loops.
1245 if (ActiveMacros
.size() == 20)
1246 return TokError("macros cannot be nested more than 20 levels deep");
1248 // Parse the macro instantiation arguments.
1249 std::vector
<std::vector
<AsmToken
> > MacroArguments
;
1250 MacroArguments
.push_back(std::vector
<AsmToken
>());
1251 unsigned ParenLevel
= 0;
1253 if (Lexer
.is(AsmToken::Eof
))
1254 return TokError("unexpected token in macro instantiation");
1255 if (Lexer
.is(AsmToken::EndOfStatement
))
1258 // If we aren't inside parentheses and this is a comma, start a new token
1260 if (ParenLevel
== 0 && Lexer
.is(AsmToken::Comma
)) {
1261 MacroArguments
.push_back(std::vector
<AsmToken
>());
1263 // Adjust the current parentheses level.
1264 if (Lexer
.is(AsmToken::LParen
))
1266 else if (Lexer
.is(AsmToken::RParen
) && ParenLevel
)
1269 // Append the token to the current argument list.
1270 MacroArguments
.back().push_back(getTok());
1275 // Create the macro instantiation object and add to the current macro
1276 // instantiation stack.
1277 MacroInstantiation
*MI
= new MacroInstantiation(M
, NameLoc
,
1280 ActiveMacros
.push_back(MI
);
1282 // Jump to the macro instantiation and prime the lexer.
1283 CurBuffer
= SrcMgr
.AddNewSourceBuffer(MI
->Instantiation
, SMLoc());
1284 Lexer
.setBuffer(SrcMgr
.getMemoryBuffer(CurBuffer
));
1290 void AsmParser::HandleMacroExit() {
1291 // Jump to the EndOfStatement we should return to, and consume it.
1292 JumpToLoc(ActiveMacros
.back()->ExitLoc
);
1295 // Pop the instantiation entry.
1296 delete ActiveMacros
.back();
1297 ActiveMacros
.pop_back();
1300 static void MarkUsed(const MCExpr
*Value
) {
1301 switch (Value
->getKind()) {
1302 case MCExpr::Binary
:
1303 MarkUsed(static_cast<const MCBinaryExpr
*>(Value
)->getLHS());
1304 MarkUsed(static_cast<const MCBinaryExpr
*>(Value
)->getRHS());
1306 case MCExpr::Target
:
1307 case MCExpr::Constant
:
1309 case MCExpr::SymbolRef
: {
1310 static_cast<const MCSymbolRefExpr
*>(Value
)->getSymbol().setUsed(true);
1314 MarkUsed(static_cast<const MCUnaryExpr
*>(Value
)->getSubExpr());
1319 bool AsmParser::ParseAssignment(StringRef Name
, bool allow_redef
) {
1320 // FIXME: Use better location, we should use proper tokens.
1321 SMLoc EqualLoc
= Lexer
.getLoc();
1323 const MCExpr
*Value
;
1324 if (ParseExpression(Value
))
1329 if (Lexer
.isNot(AsmToken::EndOfStatement
))
1330 return TokError("unexpected token in assignment");
1332 // Error on assignment to '.'.
1334 return Error(EqualLoc
, ("assignment to pseudo-symbol '.' is unsupported "
1335 "(use '.space' or '.org').)"));
1338 // Eat the end of statement marker.
1341 // Validate that the LHS is allowed to be a variable (either it has not been
1342 // used as a symbol, or it is an absolute symbol).
1343 MCSymbol
*Sym
= getContext().LookupSymbol(Name
);
1345 // Diagnose assignment to a label.
1347 // FIXME: Diagnostics. Note the location of the definition as a label.
1348 // FIXME: Diagnose assignment to protected identifier (e.g., register name).
1349 if (Sym
->isUndefined() && !Sym
->isUsed() && !Sym
->isVariable())
1350 ; // Allow redefinitions of undefined symbols only used in directives.
1351 else if (!Sym
->isUndefined() && (!Sym
->isAbsolute() || !allow_redef
))
1352 return Error(EqualLoc
, "redefinition of '" + Name
+ "'");
1353 else if (!Sym
->isVariable())
1354 return Error(EqualLoc
, "invalid assignment to '" + Name
+ "'");
1355 else if (!isa
<MCConstantExpr
>(Sym
->getVariableValue()))
1356 return Error(EqualLoc
, "invalid reassignment of non-absolute variable '" +
1359 // Don't count these checks as uses.
1360 Sym
->setUsed(false);
1362 Sym
= getContext().GetOrCreateSymbol(Name
);
1364 // FIXME: Handle '.'.
1366 // Do the assignment.
1367 Out
.EmitAssignment(Sym
, Value
);
1372 /// ParseIdentifier:
1375 bool AsmParser::ParseIdentifier(StringRef
&Res
) {
1376 // The assembler has relaxed rules for accepting identifiers, in particular we
1377 // allow things like '.globl $foo', which would normally be separate
1378 // tokens. At this level, we have already lexed so we cannot (currently)
1379 // handle this as a context dependent token, instead we detect adjacent tokens
1380 // and return the combined identifier.
1381 if (Lexer
.is(AsmToken::Dollar
)) {
1382 SMLoc DollarLoc
= getLexer().getLoc();
1384 // Consume the dollar sign, and check for a following identifier.
1386 if (Lexer
.isNot(AsmToken::Identifier
))
1389 // We have a '$' followed by an identifier, make sure they are adjacent.
1390 if (DollarLoc
.getPointer() + 1 != getTok().getLoc().getPointer())
1393 // Construct the joined identifier and consume the token.
1394 Res
= StringRef(DollarLoc
.getPointer(),
1395 getTok().getIdentifier().size() + 1);
1400 if (Lexer
.isNot(AsmToken::Identifier
) &&
1401 Lexer
.isNot(AsmToken::String
))
1404 Res
= getTok().getIdentifier();
1406 Lex(); // Consume the identifier token.
1411 /// ParseDirectiveSet:
1412 /// ::= .equ identifier ',' expression
1413 /// ::= .equiv identifier ',' expression
1414 /// ::= .set identifier ',' expression
1415 bool AsmParser::ParseDirectiveSet(StringRef IDVal
, bool allow_redef
) {
1418 if (ParseIdentifier(Name
))
1419 return TokError("expected identifier after '" + Twine(IDVal
) + "'");
1421 if (getLexer().isNot(AsmToken::Comma
))
1422 return TokError("unexpected token in '" + Twine(IDVal
) + "'");
1425 return ParseAssignment(Name
, allow_redef
);
1428 bool AsmParser::ParseEscapedString(std::string
&Data
) {
1429 assert(getLexer().is(AsmToken::String
) && "Unexpected current token!");
1432 StringRef Str
= getTok().getStringContents();
1433 for (unsigned i
= 0, e
= Str
.size(); i
!= e
; ++i
) {
1434 if (Str
[i
] != '\\') {
1439 // Recognize escaped characters. Note that this escape semantics currently
1440 // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes.
1443 return TokError("unexpected backslash at end of string");
1445 // Recognize octal sequences.
1446 if ((unsigned) (Str
[i
] - '0') <= 7) {
1447 // Consume up to three octal characters.
1448 unsigned Value
= Str
[i
] - '0';
1450 if (i
+ 1 != e
&& ((unsigned) (Str
[i
+ 1] - '0')) <= 7) {
1452 Value
= Value
* 8 + (Str
[i
] - '0');
1454 if (i
+ 1 != e
&& ((unsigned) (Str
[i
+ 1] - '0')) <= 7) {
1456 Value
= Value
* 8 + (Str
[i
] - '0');
1461 return TokError("invalid octal escape sequence (out of range)");
1463 Data
+= (unsigned char) Value
;
1467 // Otherwise recognize individual escapes.
1470 // Just reject invalid escape sequences for now.
1471 return TokError("invalid escape sequence (unrecognized character)");
1473 case 'b': Data
+= '\b'; break;
1474 case 'f': Data
+= '\f'; break;
1475 case 'n': Data
+= '\n'; break;
1476 case 'r': Data
+= '\r'; break;
1477 case 't': Data
+= '\t'; break;
1478 case '"': Data
+= '"'; break;
1479 case '\\': Data
+= '\\'; break;
1486 /// ParseDirectiveAscii:
1487 /// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ]
1488 bool AsmParser::ParseDirectiveAscii(StringRef IDVal
, bool ZeroTerminated
) {
1489 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1490 CheckForValidSection();
1493 if (getLexer().isNot(AsmToken::String
))
1494 return TokError("expected string in '" + Twine(IDVal
) + "' directive");
1497 if (ParseEscapedString(Data
))
1500 getStreamer().EmitBytes(Data
, DEFAULT_ADDRSPACE
);
1502 getStreamer().EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE
);
1506 if (getLexer().is(AsmToken::EndOfStatement
))
1509 if (getLexer().isNot(AsmToken::Comma
))
1510 return TokError("unexpected token in '" + Twine(IDVal
) + "' directive");
1519 /// ParseDirectiveValue
1520 /// ::= (.byte | .short | ... ) [ expression (, expression)* ]
1521 bool AsmParser::ParseDirectiveValue(unsigned Size
) {
1522 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1523 CheckForValidSection();
1526 const MCExpr
*Value
;
1527 if (ParseExpression(Value
))
1530 // Special case constant expressions to match code generator.
1531 if (const MCConstantExpr
*MCE
= dyn_cast
<MCConstantExpr
>(Value
))
1532 getStreamer().EmitIntValue(MCE
->getValue(), Size
, DEFAULT_ADDRSPACE
);
1534 getStreamer().EmitValue(Value
, Size
, DEFAULT_ADDRSPACE
);
1536 if (getLexer().is(AsmToken::EndOfStatement
))
1539 // FIXME: Improve diagnostic.
1540 if (getLexer().isNot(AsmToken::Comma
))
1541 return TokError("unexpected token in directive");
1550 /// ParseDirectiveRealValue
1551 /// ::= (.single | .double) [ expression (, expression)* ]
1552 bool AsmParser::ParseDirectiveRealValue(const fltSemantics
&Semantics
) {
1553 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1554 CheckForValidSection();
1557 // We don't truly support arithmetic on floating point expressions, so we
1558 // have to manually parse unary prefixes.
1560 if (getLexer().is(AsmToken::Minus
)) {
1563 } else if (getLexer().is(AsmToken::Plus
))
1566 if (getLexer().isNot(AsmToken::Integer
) &&
1567 getLexer().isNot(AsmToken::Real
) &&
1568 getLexer().isNot(AsmToken::Identifier
))
1569 return TokError("unexpected token in directive");
1571 // Convert to an APFloat.
1572 APFloat
Value(Semantics
);
1573 StringRef IDVal
= getTok().getString();
1574 if (getLexer().is(AsmToken::Identifier
)) {
1575 if (!IDVal
.compare_lower("infinity") || !IDVal
.compare_lower("inf"))
1576 Value
= APFloat::getInf(Semantics
);
1577 else if (!IDVal
.compare_lower("nan"))
1578 Value
= APFloat::getNaN(Semantics
, false, ~0);
1580 return TokError("invalid floating point literal");
1581 } else if (Value
.convertFromString(IDVal
, APFloat::rmNearestTiesToEven
) ==
1582 APFloat::opInvalidOp
)
1583 return TokError("invalid floating point literal");
1587 // Consume the numeric token.
1590 // Emit the value as an integer.
1591 APInt AsInt
= Value
.bitcastToAPInt();
1592 getStreamer().EmitIntValue(AsInt
.getLimitedValue(),
1593 AsInt
.getBitWidth() / 8, DEFAULT_ADDRSPACE
);
1595 if (getLexer().is(AsmToken::EndOfStatement
))
1598 if (getLexer().isNot(AsmToken::Comma
))
1599 return TokError("unexpected token in directive");
1608 /// ParseDirectiveSpace
1609 /// ::= .space expression [ , expression ]
1610 bool AsmParser::ParseDirectiveSpace() {
1611 CheckForValidSection();
1614 if (ParseAbsoluteExpression(NumBytes
))
1617 int64_t FillExpr
= 0;
1618 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1619 if (getLexer().isNot(AsmToken::Comma
))
1620 return TokError("unexpected token in '.space' directive");
1623 if (ParseAbsoluteExpression(FillExpr
))
1626 if (getLexer().isNot(AsmToken::EndOfStatement
))
1627 return TokError("unexpected token in '.space' directive");
1633 return TokError("invalid number of bytes in '.space' directive");
1635 // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
1636 getStreamer().EmitFill(NumBytes
, FillExpr
, DEFAULT_ADDRSPACE
);
1641 /// ParseDirectiveZero
1642 /// ::= .zero expression
1643 bool AsmParser::ParseDirectiveZero() {
1644 CheckForValidSection();
1647 if (ParseAbsoluteExpression(NumBytes
))
1651 if (getLexer().is(AsmToken::Comma
)) {
1653 if (ParseAbsoluteExpression(Val
))
1657 if (getLexer().isNot(AsmToken::EndOfStatement
))
1658 return TokError("unexpected token in '.zero' directive");
1662 getStreamer().EmitFill(NumBytes
, Val
, DEFAULT_ADDRSPACE
);
1667 /// ParseDirectiveFill
1668 /// ::= .fill expression , expression , expression
1669 bool AsmParser::ParseDirectiveFill() {
1670 CheckForValidSection();
1673 if (ParseAbsoluteExpression(NumValues
))
1676 if (getLexer().isNot(AsmToken::Comma
))
1677 return TokError("unexpected token in '.fill' directive");
1681 if (ParseAbsoluteExpression(FillSize
))
1684 if (getLexer().isNot(AsmToken::Comma
))
1685 return TokError("unexpected token in '.fill' directive");
1689 if (ParseAbsoluteExpression(FillExpr
))
1692 if (getLexer().isNot(AsmToken::EndOfStatement
))
1693 return TokError("unexpected token in '.fill' directive");
1697 if (FillSize
!= 1 && FillSize
!= 2 && FillSize
!= 4 && FillSize
!= 8)
1698 return TokError("invalid '.fill' size, expected 1, 2, 4, or 8");
1700 for (uint64_t i
= 0, e
= NumValues
; i
!= e
; ++i
)
1701 getStreamer().EmitIntValue(FillExpr
, FillSize
, DEFAULT_ADDRSPACE
);
1706 /// ParseDirectiveOrg
1707 /// ::= .org expression [ , expression ]
1708 bool AsmParser::ParseDirectiveOrg() {
1709 CheckForValidSection();
1711 const MCExpr
*Offset
;
1712 if (ParseExpression(Offset
))
1715 // Parse optional fill expression.
1716 int64_t FillExpr
= 0;
1717 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1718 if (getLexer().isNot(AsmToken::Comma
))
1719 return TokError("unexpected token in '.org' directive");
1722 if (ParseAbsoluteExpression(FillExpr
))
1725 if (getLexer().isNot(AsmToken::EndOfStatement
))
1726 return TokError("unexpected token in '.org' directive");
1731 // FIXME: Only limited forms of relocatable expressions are accepted here, it
1732 // has to be relative to the current section.
1733 getStreamer().EmitValueToOffset(Offset
, FillExpr
);
1738 /// ParseDirectiveAlign
1739 /// ::= {.align, ...} expression [ , expression [ , expression ]]
1740 bool AsmParser::ParseDirectiveAlign(bool IsPow2
, unsigned ValueSize
) {
1741 CheckForValidSection();
1743 SMLoc AlignmentLoc
= getLexer().getLoc();
1745 if (ParseAbsoluteExpression(Alignment
))
1749 bool HasFillExpr
= false;
1750 int64_t FillExpr
= 0;
1751 int64_t MaxBytesToFill
= 0;
1752 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1753 if (getLexer().isNot(AsmToken::Comma
))
1754 return TokError("unexpected token in directive");
1757 // The fill expression can be omitted while specifying a maximum number of
1758 // alignment bytes, e.g:
1760 if (getLexer().isNot(AsmToken::Comma
)) {
1762 if (ParseAbsoluteExpression(FillExpr
))
1766 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1767 if (getLexer().isNot(AsmToken::Comma
))
1768 return TokError("unexpected token in directive");
1771 MaxBytesLoc
= getLexer().getLoc();
1772 if (ParseAbsoluteExpression(MaxBytesToFill
))
1775 if (getLexer().isNot(AsmToken::EndOfStatement
))
1776 return TokError("unexpected token in directive");
1785 // Compute alignment in bytes.
1787 // FIXME: Diagnose overflow.
1788 if (Alignment
>= 32) {
1789 Error(AlignmentLoc
, "invalid alignment value");
1793 Alignment
= 1ULL << Alignment
;
1796 // Diagnose non-sensical max bytes to align.
1797 if (MaxBytesLoc
.isValid()) {
1798 if (MaxBytesToFill
< 1) {
1799 Error(MaxBytesLoc
, "alignment directive can never be satisfied in this "
1800 "many bytes, ignoring maximum bytes expression");
1804 if (MaxBytesToFill
>= Alignment
) {
1805 Warning(MaxBytesLoc
, "maximum bytes expression exceeds alignment and "
1811 // Check whether we should use optimal code alignment for this .align
1813 bool UseCodeAlign
= getStreamer().getCurrentSection()->UseCodeAlign();
1814 if ((!HasFillExpr
|| Lexer
.getMAI().getTextAlignFillValue() == FillExpr
) &&
1815 ValueSize
== 1 && UseCodeAlign
) {
1816 getStreamer().EmitCodeAlignment(Alignment
, MaxBytesToFill
);
1818 // FIXME: Target specific behavior about how the "extra" bytes are filled.
1819 getStreamer().EmitValueToAlignment(Alignment
, FillExpr
, ValueSize
,
1826 /// ParseDirectiveSymbolAttribute
1827 /// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
1828 bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr
) {
1829 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1833 if (ParseIdentifier(Name
))
1834 return TokError("expected identifier in directive");
1836 MCSymbol
*Sym
= getContext().GetOrCreateSymbol(Name
);
1838 getStreamer().EmitSymbolAttribute(Sym
, Attr
);
1840 if (getLexer().is(AsmToken::EndOfStatement
))
1843 if (getLexer().isNot(AsmToken::Comma
))
1844 return TokError("unexpected token in directive");
1853 /// ParseDirectiveComm
1854 /// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
1855 bool AsmParser::ParseDirectiveComm(bool IsLocal
) {
1856 CheckForValidSection();
1858 SMLoc IDLoc
= getLexer().getLoc();
1860 if (ParseIdentifier(Name
))
1861 return TokError("expected identifier in directive");
1863 // Handle the identifier as the key symbol.
1864 MCSymbol
*Sym
= getContext().GetOrCreateSymbol(Name
);
1866 if (getLexer().isNot(AsmToken::Comma
))
1867 return TokError("unexpected token in directive");
1871 SMLoc SizeLoc
= getLexer().getLoc();
1872 if (ParseAbsoluteExpression(Size
))
1875 int64_t Pow2Alignment
= 0;
1876 SMLoc Pow2AlignmentLoc
;
1877 if (getLexer().is(AsmToken::Comma
)) {
1879 Pow2AlignmentLoc
= getLexer().getLoc();
1880 if (ParseAbsoluteExpression(Pow2Alignment
))
1883 // If this target takes alignments in bytes (not log) validate and convert.
1884 if (Lexer
.getMAI().getAlignmentIsInBytes()) {
1885 if (!isPowerOf2_64(Pow2Alignment
))
1886 return Error(Pow2AlignmentLoc
, "alignment must be a power of 2");
1887 Pow2Alignment
= Log2_64(Pow2Alignment
);
1891 if (getLexer().isNot(AsmToken::EndOfStatement
))
1892 return TokError("unexpected token in '.comm' or '.lcomm' directive");
1896 // NOTE: a size of zero for a .comm should create a undefined symbol
1897 // but a size of .lcomm creates a bss symbol of size zero.
1899 return Error(SizeLoc
, "invalid '.comm' or '.lcomm' directive size, can't "
1900 "be less than zero");
1902 // NOTE: The alignment in the directive is a power of 2 value, the assembler
1903 // may internally end up wanting an alignment in bytes.
1904 // FIXME: Diagnose overflow.
1905 if (Pow2Alignment
< 0)
1906 return Error(Pow2AlignmentLoc
, "invalid '.comm' or '.lcomm' directive "
1907 "alignment, can't be less than zero");
1909 if (!Sym
->isUndefined())
1910 return Error(IDLoc
, "invalid symbol redefinition");
1912 // '.lcomm' is equivalent to '.zerofill'.
1913 // Create the Symbol as a common or local common with Size and Pow2Alignment
1915 getStreamer().EmitZerofill(Ctx
.getMachOSection(
1916 "__DATA", "__bss", MCSectionMachO::S_ZEROFILL
,
1917 0, SectionKind::getBSS()),
1918 Sym
, Size
, 1 << Pow2Alignment
);
1922 getStreamer().EmitCommonSymbol(Sym
, Size
, 1 << Pow2Alignment
);
1926 /// ParseDirectiveAbort
1927 /// ::= .abort [... message ...]
1928 bool AsmParser::ParseDirectiveAbort() {
1929 // FIXME: Use loc from directive.
1930 SMLoc Loc
= getLexer().getLoc();
1932 StringRef Str
= ParseStringToEndOfStatement();
1933 if (getLexer().isNot(AsmToken::EndOfStatement
))
1934 return TokError("unexpected token in '.abort' directive");
1939 Error(Loc
, ".abort detected. Assembly stopping.");
1941 Error(Loc
, ".abort '" + Str
+ "' detected. Assembly stopping.");
1942 // FIXME: Actually abort assembly here.
1947 /// ParseDirectiveInclude
1948 /// ::= .include "filename"
1949 bool AsmParser::ParseDirectiveInclude() {
1950 if (getLexer().isNot(AsmToken::String
))
1951 return TokError("expected string in '.include' directive");
1953 std::string Filename
= getTok().getString();
1954 SMLoc IncludeLoc
= getLexer().getLoc();
1957 if (getLexer().isNot(AsmToken::EndOfStatement
))
1958 return TokError("unexpected token in '.include' directive");
1960 // Strip the quotes.
1961 Filename
= Filename
.substr(1, Filename
.size()-2);
1963 // Attempt to switch the lexer to the included file before consuming the end
1964 // of statement to avoid losing it when we switch.
1965 if (EnterIncludeFile(Filename
)) {
1966 Error(IncludeLoc
, "Could not find include file '" + Filename
+ "'");
1973 /// ParseDirectiveIf
1974 /// ::= .if expression
1975 bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc
) {
1976 TheCondStack
.push_back(TheCondState
);
1977 TheCondState
.TheCond
= AsmCond::IfCond
;
1978 if(TheCondState
.Ignore
) {
1979 EatToEndOfStatement();
1983 if (ParseAbsoluteExpression(ExprValue
))
1986 if (getLexer().isNot(AsmToken::EndOfStatement
))
1987 return TokError("unexpected token in '.if' directive");
1991 TheCondState
.CondMet
= ExprValue
;
1992 TheCondState
.Ignore
= !TheCondState
.CondMet
;
1998 bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc
, bool expect_defined
) {
2000 TheCondStack
.push_back(TheCondState
);
2001 TheCondState
.TheCond
= AsmCond::IfCond
;
2003 if (TheCondState
.Ignore
) {
2004 EatToEndOfStatement();
2006 if (ParseIdentifier(Name
))
2007 return TokError("expected identifier after '.ifdef'");
2011 MCSymbol
*Sym
= getContext().LookupSymbol(Name
);
2014 TheCondState
.CondMet
= (Sym
!= NULL
&& !Sym
->isUndefined());
2016 TheCondState
.CondMet
= (Sym
== NULL
|| Sym
->isUndefined());
2017 TheCondState
.Ignore
= !TheCondState
.CondMet
;
2023 /// ParseDirectiveElseIf
2024 /// ::= .elseif expression
2025 bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc
) {
2026 if (TheCondState
.TheCond
!= AsmCond::IfCond
&&
2027 TheCondState
.TheCond
!= AsmCond::ElseIfCond
)
2028 Error(DirectiveLoc
, "Encountered a .elseif that doesn't follow a .if or "
2030 TheCondState
.TheCond
= AsmCond::ElseIfCond
;
2032 bool LastIgnoreState
= false;
2033 if (!TheCondStack
.empty())
2034 LastIgnoreState
= TheCondStack
.back().Ignore
;
2035 if (LastIgnoreState
|| TheCondState
.CondMet
) {
2036 TheCondState
.Ignore
= true;
2037 EatToEndOfStatement();
2041 if (ParseAbsoluteExpression(ExprValue
))
2044 if (getLexer().isNot(AsmToken::EndOfStatement
))
2045 return TokError("unexpected token in '.elseif' directive");
2048 TheCondState
.CondMet
= ExprValue
;
2049 TheCondState
.Ignore
= !TheCondState
.CondMet
;
2055 /// ParseDirectiveElse
2057 bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc
) {
2058 if (getLexer().isNot(AsmToken::EndOfStatement
))
2059 return TokError("unexpected token in '.else' directive");
2063 if (TheCondState
.TheCond
!= AsmCond::IfCond
&&
2064 TheCondState
.TheCond
!= AsmCond::ElseIfCond
)
2065 Error(DirectiveLoc
, "Encountered a .else that doesn't follow a .if or an "
2067 TheCondState
.TheCond
= AsmCond::ElseCond
;
2068 bool LastIgnoreState
= false;
2069 if (!TheCondStack
.empty())
2070 LastIgnoreState
= TheCondStack
.back().Ignore
;
2071 if (LastIgnoreState
|| TheCondState
.CondMet
)
2072 TheCondState
.Ignore
= true;
2074 TheCondState
.Ignore
= false;
2079 /// ParseDirectiveEndIf
2081 bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc
) {
2082 if (getLexer().isNot(AsmToken::EndOfStatement
))
2083 return TokError("unexpected token in '.endif' directive");
2087 if ((TheCondState
.TheCond
== AsmCond::NoCond
) ||
2088 TheCondStack
.empty())
2089 Error(DirectiveLoc
, "Encountered a .endif that doesn't follow a .if or "
2091 if (!TheCondStack
.empty()) {
2092 TheCondState
= TheCondStack
.back();
2093 TheCondStack
.pop_back();
2099 /// ParseDirectiveFile
2100 /// ::= .file [number] string
2101 bool GenericAsmParser::ParseDirectiveFile(StringRef
, SMLoc DirectiveLoc
) {
2102 // FIXME: I'm not sure what this is.
2103 int64_t FileNumber
= -1;
2104 SMLoc FileNumberLoc
= getLexer().getLoc();
2105 if (getLexer().is(AsmToken::Integer
)) {
2106 FileNumber
= getTok().getIntVal();
2110 return TokError("file number less than one");
2113 if (getLexer().isNot(AsmToken::String
))
2114 return TokError("unexpected token in '.file' directive");
2116 StringRef Filename
= getTok().getString();
2117 Filename
= Filename
.substr(1, Filename
.size()-2);
2120 if (getLexer().isNot(AsmToken::EndOfStatement
))
2121 return TokError("unexpected token in '.file' directive");
2123 if (FileNumber
== -1)
2124 getStreamer().EmitFileDirective(Filename
);
2126 if (getStreamer().EmitDwarfFileDirective(FileNumber
, Filename
))
2127 Error(FileNumberLoc
, "file number already allocated");
2133 /// ParseDirectiveLine
2134 /// ::= .line [number]
2135 bool GenericAsmParser::ParseDirectiveLine(StringRef
, SMLoc DirectiveLoc
) {
2136 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
2137 if (getLexer().isNot(AsmToken::Integer
))
2138 return TokError("unexpected token in '.line' directive");
2140 int64_t LineNumber
= getTok().getIntVal();
2144 // FIXME: Do something with the .line.
2147 if (getLexer().isNot(AsmToken::EndOfStatement
))
2148 return TokError("unexpected token in '.line' directive");
2154 /// ParseDirectiveLoc
2155 /// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end]
2156 /// [epilogue_begin] [is_stmt VALUE] [isa VALUE]
2157 /// The first number is a file number, must have been previously assigned with
2158 /// a .file directive, the second number is the line number and optionally the
2159 /// third number is a column position (zero if not specified). The remaining
2160 /// optional items are .loc sub-directives.
2161 bool GenericAsmParser::ParseDirectiveLoc(StringRef
, SMLoc DirectiveLoc
) {
2163 if (getLexer().isNot(AsmToken::Integer
))
2164 return TokError("unexpected token in '.loc' directive");
2165 int64_t FileNumber
= getTok().getIntVal();
2167 return TokError("file number less than one in '.loc' directive");
2168 if (!getContext().isValidDwarfFileNumber(FileNumber
))
2169 return TokError("unassigned file number in '.loc' directive");
2172 int64_t LineNumber
= 0;
2173 if (getLexer().is(AsmToken::Integer
)) {
2174 LineNumber
= getTok().getIntVal();
2176 return TokError("line number less than one in '.loc' directive");
2180 int64_t ColumnPos
= 0;
2181 if (getLexer().is(AsmToken::Integer
)) {
2182 ColumnPos
= getTok().getIntVal();
2184 return TokError("column position less than zero in '.loc' directive");
2188 unsigned Flags
= DWARF2_LINE_DEFAULT_IS_STMT
? DWARF2_FLAG_IS_STMT
: 0;
2190 int64_t Discriminator
= 0;
2191 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
2193 if (getLexer().is(AsmToken::EndOfStatement
))
2197 SMLoc Loc
= getTok().getLoc();
2198 if (getParser().ParseIdentifier(Name
))
2199 return TokError("unexpected token in '.loc' directive");
2201 if (Name
== "basic_block")
2202 Flags
|= DWARF2_FLAG_BASIC_BLOCK
;
2203 else if (Name
== "prologue_end")
2204 Flags
|= DWARF2_FLAG_PROLOGUE_END
;
2205 else if (Name
== "epilogue_begin")
2206 Flags
|= DWARF2_FLAG_EPILOGUE_BEGIN
;
2207 else if (Name
== "is_stmt") {
2208 SMLoc Loc
= getTok().getLoc();
2209 const MCExpr
*Value
;
2210 if (getParser().ParseExpression(Value
))
2212 // The expression must be the constant 0 or 1.
2213 if (const MCConstantExpr
*MCE
= dyn_cast
<MCConstantExpr
>(Value
)) {
2214 int Value
= MCE
->getValue();
2216 Flags
&= ~DWARF2_FLAG_IS_STMT
;
2217 else if (Value
== 1)
2218 Flags
|= DWARF2_FLAG_IS_STMT
;
2220 return Error(Loc
, "is_stmt value not 0 or 1");
2223 return Error(Loc
, "is_stmt value not the constant value of 0 or 1");
2226 else if (Name
== "isa") {
2227 SMLoc Loc
= getTok().getLoc();
2228 const MCExpr
*Value
;
2229 if (getParser().ParseExpression(Value
))
2231 // The expression must be a constant greater or equal to 0.
2232 if (const MCConstantExpr
*MCE
= dyn_cast
<MCConstantExpr
>(Value
)) {
2233 int Value
= MCE
->getValue();
2235 return Error(Loc
, "isa number less than zero");
2239 return Error(Loc
, "isa number not a constant value");
2242 else if (Name
== "discriminator") {
2243 if (getParser().ParseAbsoluteExpression(Discriminator
))
2247 return Error(Loc
, "unknown sub-directive in '.loc' directive");
2250 if (getLexer().is(AsmToken::EndOfStatement
))
2255 getStreamer().EmitDwarfLocDirective(FileNumber
, LineNumber
, ColumnPos
, Flags
,
2256 Isa
, Discriminator
);
2261 /// ParseDirectiveStabs
2262 /// ::= .stabs string, number, number, number
2263 bool GenericAsmParser::ParseDirectiveStabs(StringRef Directive
,
2264 SMLoc DirectiveLoc
) {
2265 return TokError("unsupported directive '" + Directive
+ "'");
2268 /// ParseDirectiveCFIStartProc
2269 /// ::= .cfi_startproc
2270 bool GenericAsmParser::ParseDirectiveCFIStartProc(StringRef
,
2271 SMLoc DirectiveLoc
) {
2272 getStreamer().EmitCFIStartProc();
2276 /// ParseDirectiveCFIEndProc
2277 /// ::= .cfi_endproc
2278 bool GenericAsmParser::ParseDirectiveCFIEndProc(StringRef
, SMLoc DirectiveLoc
) {
2279 getStreamer().EmitCFIEndProc();
2283 /// ParseRegisterOrRegisterNumber - parse register name or number.
2284 bool GenericAsmParser::ParseRegisterOrRegisterNumber(int64_t &Register
,
2285 SMLoc DirectiveLoc
) {
2288 if (getLexer().is(AsmToken::Percent
)) {
2289 if (getParser().getTargetParser().ParseRegister(RegNo
, DirectiveLoc
,
2292 Register
= getContext().getTargetAsmInfo().getDwarfRegNum(RegNo
, true);
2294 return getParser().ParseAbsoluteExpression(Register
);
2299 /// ParseDirectiveCFIDefCfa
2300 /// ::= .cfi_def_cfa register, offset
2301 bool GenericAsmParser::ParseDirectiveCFIDefCfa(StringRef
,
2302 SMLoc DirectiveLoc
) {
2303 int64_t Register
= 0;
2304 if (ParseRegisterOrRegisterNumber(Register
, DirectiveLoc
))
2307 if (getLexer().isNot(AsmToken::Comma
))
2308 return TokError("unexpected token in directive");
2312 if (getParser().ParseAbsoluteExpression(Offset
))
2315 getStreamer().EmitCFIDefCfa(Register
, Offset
);
2319 /// ParseDirectiveCFIDefCfaOffset
2320 /// ::= .cfi_def_cfa_offset offset
2321 bool GenericAsmParser::ParseDirectiveCFIDefCfaOffset(StringRef
,
2322 SMLoc DirectiveLoc
) {
2324 if (getParser().ParseAbsoluteExpression(Offset
))
2327 getStreamer().EmitCFIDefCfaOffset(Offset
);
2331 /// ParseDirectiveCFIAdjustCfaOffset
2332 /// ::= .cfi_adjust_cfa_offset adjustment
2333 bool GenericAsmParser::ParseDirectiveCFIAdjustCfaOffset(StringRef
,
2334 SMLoc DirectiveLoc
) {
2335 int64_t Adjustment
= 0;
2336 if (getParser().ParseAbsoluteExpression(Adjustment
))
2339 getStreamer().EmitCFIAdjustCfaOffset(Adjustment
);
2343 /// ParseDirectiveCFIDefCfaRegister
2344 /// ::= .cfi_def_cfa_register register
2345 bool GenericAsmParser::ParseDirectiveCFIDefCfaRegister(StringRef
,
2346 SMLoc DirectiveLoc
) {
2347 int64_t Register
= 0;
2348 if (ParseRegisterOrRegisterNumber(Register
, DirectiveLoc
))
2351 getStreamer().EmitCFIDefCfaRegister(Register
);
2355 /// ParseDirectiveCFIOffset
2356 /// ::= .cfi_offset register, offset
2357 bool GenericAsmParser::ParseDirectiveCFIOffset(StringRef
, SMLoc DirectiveLoc
) {
2358 int64_t Register
= 0;
2361 if (ParseRegisterOrRegisterNumber(Register
, DirectiveLoc
))
2364 if (getLexer().isNot(AsmToken::Comma
))
2365 return TokError("unexpected token in directive");
2368 if (getParser().ParseAbsoluteExpression(Offset
))
2371 getStreamer().EmitCFIOffset(Register
, Offset
);
2375 /// ParseDirectiveCFIRelOffset
2376 /// ::= .cfi_rel_offset register, offset
2377 bool GenericAsmParser::ParseDirectiveCFIRelOffset(StringRef
,
2378 SMLoc DirectiveLoc
) {
2379 int64_t Register
= 0;
2381 if (ParseRegisterOrRegisterNumber(Register
, DirectiveLoc
))
2384 if (getLexer().isNot(AsmToken::Comma
))
2385 return TokError("unexpected token in directive");
2389 if (getParser().ParseAbsoluteExpression(Offset
))
2392 getStreamer().EmitCFIRelOffset(Register
, Offset
);
2396 static bool isValidEncoding(int64_t Encoding
) {
2397 if (Encoding
& ~0xff)
2400 if (Encoding
== dwarf::DW_EH_PE_omit
)
2403 const unsigned Format
= Encoding
& 0xf;
2404 if (Format
!= dwarf::DW_EH_PE_absptr
&& Format
!= dwarf::DW_EH_PE_udata2
&&
2405 Format
!= dwarf::DW_EH_PE_udata4
&& Format
!= dwarf::DW_EH_PE_udata8
&&
2406 Format
!= dwarf::DW_EH_PE_sdata2
&& Format
!= dwarf::DW_EH_PE_sdata4
&&
2407 Format
!= dwarf::DW_EH_PE_sdata8
&& Format
!= dwarf::DW_EH_PE_signed
)
2410 const unsigned Application
= Encoding
& 0x70;
2411 if (Application
!= dwarf::DW_EH_PE_absptr
&&
2412 Application
!= dwarf::DW_EH_PE_pcrel
)
2418 /// ParseDirectiveCFIPersonalityOrLsda
2419 /// ::= .cfi_personality encoding, [symbol_name]
2420 /// ::= .cfi_lsda encoding, [symbol_name]
2421 bool GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda(StringRef IDVal
,
2422 SMLoc DirectiveLoc
) {
2423 int64_t Encoding
= 0;
2424 if (getParser().ParseAbsoluteExpression(Encoding
))
2426 if (Encoding
== dwarf::DW_EH_PE_omit
)
2429 if (!isValidEncoding(Encoding
))
2430 return TokError("unsupported encoding.");
2432 if (getLexer().isNot(AsmToken::Comma
))
2433 return TokError("unexpected token in directive");
2437 if (getParser().ParseIdentifier(Name
))
2438 return TokError("expected identifier in directive");
2440 MCSymbol
*Sym
= getContext().GetOrCreateSymbol(Name
);
2442 if (IDVal
== ".cfi_personality")
2443 getStreamer().EmitCFIPersonality(Sym
, Encoding
);
2445 assert(IDVal
== ".cfi_lsda");
2446 getStreamer().EmitCFILsda(Sym
, Encoding
);
2451 /// ParseDirectiveCFIRememberState
2452 /// ::= .cfi_remember_state
2453 bool GenericAsmParser::ParseDirectiveCFIRememberState(StringRef IDVal
,
2454 SMLoc DirectiveLoc
) {
2455 getStreamer().EmitCFIRememberState();
2459 /// ParseDirectiveCFIRestoreState
2460 /// ::= .cfi_remember_state
2461 bool GenericAsmParser::ParseDirectiveCFIRestoreState(StringRef IDVal
,
2462 SMLoc DirectiveLoc
) {
2463 getStreamer().EmitCFIRestoreState();
2467 /// ParseDirectiveCFISameValue
2468 /// ::= .cfi_same_value register
2469 bool GenericAsmParser::ParseDirectiveCFISameValue(StringRef IDVal
,
2470 SMLoc DirectiveLoc
) {
2471 int64_t Register
= 0;
2473 if (ParseRegisterOrRegisterNumber(Register
, DirectiveLoc
))
2476 getStreamer().EmitCFISameValue(Register
);
2481 /// ParseDirectiveMacrosOnOff
2484 bool GenericAsmParser::ParseDirectiveMacrosOnOff(StringRef Directive
,
2485 SMLoc DirectiveLoc
) {
2486 if (getLexer().isNot(AsmToken::EndOfStatement
))
2487 return Error(getLexer().getLoc(),
2488 "unexpected token in '" + Directive
+ "' directive");
2490 getParser().MacrosEnabled
= Directive
== ".macros_on";
2495 /// ParseDirectiveMacro
2497 bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive
,
2498 SMLoc DirectiveLoc
) {
2500 if (getParser().ParseIdentifier(Name
))
2501 return TokError("expected identifier in directive");
2503 if (getLexer().isNot(AsmToken::EndOfStatement
))
2504 return TokError("unexpected token in '.macro' directive");
2506 // Eat the end of statement.
2509 AsmToken EndToken
, StartToken
= getTok();
2511 // Lex the macro definition.
2513 // Check whether we have reached the end of the file.
2514 if (getLexer().is(AsmToken::Eof
))
2515 return Error(DirectiveLoc
, "no matching '.endmacro' in definition");
2517 // Otherwise, check whether we have reach the .endmacro.
2518 if (getLexer().is(AsmToken::Identifier
) &&
2519 (getTok().getIdentifier() == ".endm" ||
2520 getTok().getIdentifier() == ".endmacro")) {
2521 EndToken
= getTok();
2523 if (getLexer().isNot(AsmToken::EndOfStatement
))
2524 return TokError("unexpected token in '" + EndToken
.getIdentifier() +
2529 // Otherwise, scan til the end of the statement.
2530 getParser().EatToEndOfStatement();
2533 if (getParser().MacroMap
.lookup(Name
)) {
2534 return Error(DirectiveLoc
, "macro '" + Name
+ "' is already defined");
2537 const char *BodyStart
= StartToken
.getLoc().getPointer();
2538 const char *BodyEnd
= EndToken
.getLoc().getPointer();
2539 StringRef Body
= StringRef(BodyStart
, BodyEnd
- BodyStart
);
2540 getParser().MacroMap
[Name
] = new Macro(Name
, Body
);
2544 /// ParseDirectiveEndMacro
2547 bool GenericAsmParser::ParseDirectiveEndMacro(StringRef Directive
,
2548 SMLoc DirectiveLoc
) {
2549 if (getLexer().isNot(AsmToken::EndOfStatement
))
2550 return TokError("unexpected token in '" + Directive
+ "' directive");
2552 // If we are inside a macro instantiation, terminate the current
2554 if (!getParser().ActiveMacros
.empty()) {
2555 getParser().HandleMacroExit();
2559 // Otherwise, this .endmacro is a stray entry in the file; well formed
2560 // .endmacro directives are handled during the macro definition parsing.
2561 return TokError("unexpected '" + Directive
+ "' in file, "
2562 "no current macro definition");
2565 bool GenericAsmParser::ParseDirectiveLEB128(StringRef DirName
, SMLoc
) {
2566 getParser().CheckForValidSection();
2568 const MCExpr
*Value
;
2570 if (getParser().ParseExpression(Value
))
2573 if (getLexer().isNot(AsmToken::EndOfStatement
))
2574 return TokError("unexpected token in directive");
2576 if (DirName
[1] == 's')
2577 getStreamer().EmitSLEB128Value(Value
);
2579 getStreamer().EmitULEB128Value(Value
);
2585 /// \brief Create an MCAsmParser instance.
2586 MCAsmParser
*llvm::createMCAsmParser(const Target
&T
, SourceMgr
&SM
,
2587 MCContext
&C
, MCStreamer
&Out
,
2588 const MCAsmInfo
&MAI
) {
2589 return new AsmParser(T
, SM
, C
, Out
, MAI
);