aboutsummaryrefslogtreecommitdiff
path: root/lib/MC/MCParser/AsmParser.cpp
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2013-01-31 10:07:41 -0800
committerDerek Schuff <dschuff@chromium.org>2013-01-31 10:07:41 -0800
commit3d5de9e56f3e5af59772bdf2cbedb0903d938bb8 (patch)
tree300b7a72c61b009f0122ec1d8a155672c74459fd /lib/MC/MCParser/AsmParser.cpp
parent659ebb8c18832df528effd5c970bfde7662ea368 (diff)
parent9ccb76998f741a7d3f0f217392a783dfb99c6e87 (diff)
Cherry-pick r174067
Diffstat (limited to 'lib/MC/MCParser/AsmParser.cpp')
-rw-r--r--lib/MC/MCParser/AsmParser.cpp1731
1 files changed, 871 insertions, 860 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 45aaa2ec75..43c872b809 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -50,26 +50,11 @@ MCAsmParserSemaCallback::~MCAsmParserSemaCallback() {}
namespace {
-/// \brief Helper class for tracking macro definitions.
-typedef std::vector<MCAsmMacroArgument> MacroArguments;
-typedef std::pair<StringRef, MCAsmMacroArgument> MacroParameter;
-typedef std::vector<MacroParameter> MacroParameters;
-
-struct Macro {
- StringRef Name;
- StringRef Body;
- MacroParameters Parameters;
-
-public:
- Macro(StringRef N, StringRef B, const MacroParameters &P) :
- Name(N), Body(B), Parameters(P) {}
-};
-
/// \brief Helper class for storing information about an active macro
/// instantiation.
struct MacroInstantiation {
/// The macro being instantiated.
- const Macro *TheMacro;
+ const MCAsmMacro *TheMacro;
/// The macro instantiation with substitutions.
MemoryBuffer *Instantiation;
@@ -84,7 +69,7 @@ struct MacroInstantiation {
SMLoc ExitLoc;
public:
- MacroInstantiation(const Macro *M, SMLoc IL, int EB, SMLoc EL,
+ MacroInstantiation(const MCAsmMacro *M, SMLoc IL, int EB, SMLoc EL,
MemoryBuffer *I);
};
@@ -115,8 +100,6 @@ struct ParseStatementInfo {
/// \brief The concrete assembly parser instance.
class AsmParser : public MCAsmParser {
- friend class GenericAsmParser;
-
AsmParser(const AsmParser &) LLVM_DELETED_FUNCTION;
void operator=(const AsmParser &) LLVM_DELETED_FUNCTION;
private:
@@ -127,7 +110,6 @@ private:
SourceMgr &SrcMgr;
SourceMgr::DiagHandlerTy SavedDiagHandler;
void *SavedDiagContext;
- MCAsmParserExtension *GenericParser;
MCAsmParserExtension *PlatformParser;
/// This is the current buffer index we're lexing from as managed by the
@@ -137,14 +119,15 @@ private:
AsmCond TheCondState;
std::vector<AsmCond> TheCondStack;
- /// DirectiveMap - This is a table handlers for directives. Each handler is
- /// invoked after the directive identifier is read and is responsible for
- /// parsing and validating the rest of the directive. The handler is passed
- /// in the directive name and the location of the directive keyword.
- StringMap<std::pair<MCAsmParserExtension*, DirectiveHandler> > DirectiveMap;
+ /// ExtensionDirectiveMap - maps directive names to handler methods in parser
+ /// extensions. Extensions register themselves in this map by calling
+ /// AddDirectiveHandler.
+ typedef std::pair<MCAsmParserExtension*, DirectiveHandler>
+ ExtensionDirectiveHandler;
+ StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap;
/// MacroMap - Map of currently defined macros.
- StringMap<Macro*> MacroMap;
+ StringMap<MCAsmMacro*> MacroMap;
/// ActiveMacros - Stack of active macro instantiations.
std::vector<MacroInstantiation*> ActiveMacros;
@@ -180,7 +163,7 @@ public:
virtual void AddDirectiveHandler(MCAsmParserExtension *Object,
StringRef Directive,
DirectiveHandler Handler) {
- DirectiveMap[Directive] = std::make_pair(Object, Handler);
+ ExtensionDirectiveMap[Directive] = std::make_pair(Object, Handler);
}
public:
@@ -225,6 +208,9 @@ public:
virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc);
virtual bool ParseAbsoluteExpression(int64_t &Res);
+ bool ParseMacroArgument(MCAsmMacroArgument &MA,
+ AsmToken::TokenKind &ArgumentDelimiter);
+
/// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
/// and set \p Res to the identifier contents.
virtual bool ParseIdentifier(StringRef &Res);
@@ -233,6 +219,14 @@ public:
virtual bool MacrosEnabled() {return MacrosEnabledFlag;}
virtual void SetMacrosEnabled(bool flag) {MacrosEnabledFlag = flag;}
+ virtual const MCAsmMacro* LookupMacro(StringRef Name);
+ virtual void DefineMacro(StringRef Name, const MCAsmMacro& Macro);
+ virtual void UndefineMacro(StringRef Name);
+
+ virtual bool InsideMacroInstantiation() {return !ActiveMacros.empty();}
+ virtual bool HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc);
+ void HandleMacroExit();
+
virtual void CheckForValidSection();
/// }
@@ -242,12 +236,10 @@ private:
void EatToEndOfLine();
bool ParseCppHashLineFilenameComment(const SMLoc &L);
- bool HandleMacroEntry(StringRef Name, SMLoc NameLoc, const Macro *M);
bool expandMacro(raw_svector_ostream &OS, StringRef Body,
- const MacroParameters &Parameters,
- const MacroArguments &A,
+ const MCAsmMacroParameters &Parameters,
+ const MCAsmMacroArguments &A,
const SMLoc &L);
- void HandleMacroExit();
void PrintMacroInstantiations();
void PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
@@ -270,9 +262,7 @@ private:
/// location.
void JumpToLoc(SMLoc Loc, int InBuffer=-1);
- bool ParseMacroArgument(MCAsmMacroArgument &MA,
- AsmToken::TokenKind &ArgumentDelimiter);
- bool ParseMacroArguments(const Macro *M, MacroArguments &A);
+ bool ParseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A);
/// \brief Parse up to the end of statement and a return the contents from the
/// current token until the end of the statement; the current token on exit
@@ -291,8 +281,9 @@ private:
bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
bool ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);
- // Directive Parsing.
+ bool ParseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
+ // Generic (target and platform independent) directive parsing.
enum DirectiveKind {
DK_NO_DIRECTIVE, // Placeholder
DK_SET, DK_EQU, DK_EQUIV, DK_ASCII, DK_ASCIZ, DK_STRING, DK_BYTE, DK_SHORT,
@@ -306,10 +297,21 @@ private:
DK_WEAK_DEF_CAN_BE_HIDDEN, DK_COMM, DK_COMMON, DK_LCOMM, DK_ABORT,
DK_INCLUDE, DK_INCBIN, DK_CODE16, DK_CODE16GCC, DK_REPT, DK_IRP, DK_IRPC,
DK_IF, DK_IFB, DK_IFNB, DK_IFC, DK_IFNC, DK_IFDEF, DK_IFNDEF, DK_IFNOTDEF,
- DK_ELSEIF, DK_ELSE, DK_ENDIF
+ DK_ELSEIF, DK_ELSE, DK_ENDIF,
+ DK_SPACE, DK_SKIP, DK_FILE, DK_LINE, DK_LOC, DK_STABS,
+ DK_CFI_SECTIONS, DK_CFI_STARTPROC, DK_CFI_ENDPROC, DK_CFI_DEF_CFA,
+ DK_CFI_DEF_CFA_OFFSET, DK_CFI_ADJUST_CFA_OFFSET, DK_CFI_DEF_CFA_REGISTER,
+ DK_CFI_OFFSET, DK_CFI_REL_OFFSET, DK_CFI_PERSONALITY, DK_CFI_LSDA,
+ DK_CFI_REMEMBER_STATE, DK_CFI_RESTORE_STATE, DK_CFI_SAME_VALUE,
+ DK_CFI_RESTORE, DK_CFI_ESCAPE, DK_CFI_SIGNAL_FRAME, DK_CFI_UNDEFINED,
+ DK_CFI_REGISTER,
+ DK_MACROS_ON, DK_MACROS_OFF, DK_MACRO, DK_ENDM, DK_ENDMACRO, DK_PURGEM,
+ DK_SLEB128, DK_ULEB128
};
- StringMap<DirectiveKind> DirectiveKindMapping;
+ /// DirectiveKindMap - Maps directive name --> DirectiveKind enum, for
+ /// directives parsed by this class.
+ StringMap<DirectiveKind> DirectiveKindMap;
// ".ascii", ".asciz", ".string"
bool ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
@@ -323,6 +325,38 @@ private:
// ".align{,32}", ".p2align{,w,l}"
bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize);
+ // ".file", ".line", ".loc", ".stabs"
+ bool ParseDirectiveFile(SMLoc DirectiveLoc);
+ bool ParseDirectiveLine();
+ bool ParseDirectiveLoc();
+ bool ParseDirectiveStabs();
+
+ // .cfi directives
+ bool ParseDirectiveCFIRegister(SMLoc DirectiveLoc);
+ bool ParseDirectiveCFISections();
+ bool ParseDirectiveCFIStartProc();
+ bool ParseDirectiveCFIEndProc();
+ bool ParseDirectiveCFIDefCfaOffset();
+ bool ParseDirectiveCFIDefCfa(SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIAdjustCfaOffset();
+ bool ParseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIOffset(SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIRelOffset(SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIPersonalityOrLsda(bool IsPersonality);
+ bool ParseDirectiveCFIRememberState();
+ bool ParseDirectiveCFIRestoreState();
+ bool ParseDirectiveCFISameValue(SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIRestore(SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIEscape();
+ bool ParseDirectiveCFISignalFrame();
+ bool ParseDirectiveCFIUndefined(SMLoc DirectiveLoc);
+
+ // macro directives
+ bool ParseDirectivePurgeMacro(SMLoc DirectiveLoc);
+ bool ParseDirectiveEndMacro(StringRef Directive);
+ bool ParseDirectiveMacro(SMLoc DirectiveLoc);
+ bool ParseDirectiveMacrosOnOff(StringRef Directive);
+
// ".bundle_align_mode"
bool ParseDirectiveBundleAlignMode();
// ".bundle_lock"
@@ -330,6 +364,12 @@ private:
// ".bundle_unlock"
bool ParseDirectiveBundleUnlock();
+ // ".space", ".skip"
+ bool ParseDirectiveSpace(StringRef IDVal);
+
+ // .sleb128 (Signed=true) and .uleb128 (Signed=false)
+ bool ParseDirectiveLEB128(bool Signed);
+
/// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which
/// accepts a single symbol (which should be a label or an external).
bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr);
@@ -359,8 +399,8 @@ private:
MCSymbolRefExpr::VariantKind Variant);
// Macro-like directives
- Macro *ParseMacroLikeBody(SMLoc DirectiveLoc);
- void InstantiateMacroLikeBody(Macro *M, SMLoc DirectiveLoc,
+ MCAsmMacro *ParseMacroLikeBody(SMLoc DirectiveLoc);
+ void InstantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
raw_svector_ostream &OS);
bool ParseDirectiveRept(SMLoc DirectiveLoc); // ".rept"
bool ParseDirectiveIrp(SMLoc DirectiveLoc); // ".irp"
@@ -370,125 +410,8 @@ private:
// "_emit"
bool ParseDirectiveEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info);
- void initializeDirectiveKindMapping();
-};
-
-/// \brief Generic implementation of directive handling, etc. which is shared
-/// (or the default, at least) for all assembler parsers.
-class GenericAsmParser : public MCAsmParserExtension {
- template<bool (GenericAsmParser::*Handler)(StringRef, SMLoc)>
- void AddDirectiveHandler(StringRef Directive) {
- getParser().AddDirectiveHandler(this, Directive,
- HandleDirective<GenericAsmParser, Handler>);
- }
-public:
- GenericAsmParser() {}
-
- AsmParser &getParser() {
- return (AsmParser&) this->MCAsmParserExtension::getParser();
- }
-
- virtual void Initialize(MCAsmParser &Parser) {
- // Call the base implementation.
- this->MCAsmParserExtension::Initialize(Parser);
-
- // Debugging directives.
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveFile>(".file");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLine>(".line");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLoc>(".loc");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveStabs>(".stabs");
-
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveSpace>(".space");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveSpace>(".skip");
-
- // CFI directives.
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFISections>(
- ".cfi_sections");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIStartProc>(
- ".cfi_startproc");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIEndProc>(
- ".cfi_endproc");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfa>(
- ".cfi_def_cfa");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaOffset>(
- ".cfi_def_cfa_offset");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIAdjustCfaOffset>(
- ".cfi_adjust_cfa_offset");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaRegister>(
- ".cfi_def_cfa_register");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIOffset>(
- ".cfi_offset");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIRelOffset>(
- ".cfi_rel_offset");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_personality");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_lsda");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFIRememberState>(".cfi_remember_state");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFIRestoreState>(".cfi_restore_state");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFISameValue>(".cfi_same_value");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFIRestore>(".cfi_restore");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFIEscape>(".cfi_escape");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFISignalFrame>(".cfi_signal_frame");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFIUndefined>(".cfi_undefined");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFIRegister>(".cfi_register");
-
- // Macro directives.
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>(
- ".macros_on");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>(
- ".macros_off");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacro>(".macro");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveEndMacro>(".endm");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveEndMacro>(".endmacro");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectivePurgeMacro>(".purgem");
-
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLEB128>(".sleb128");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLEB128>(".uleb128");
- }
-
- bool ParseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
-
- bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveStabs(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveSpace(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFISections(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIStartProc(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIDefCfa(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIDefCfaOffset(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIAdjustCfaOffset(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIDefCfaRegister(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIRelOffset(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIPersonalityOrLsda(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIRememberState(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIRestoreState(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFISameValue(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIRestore(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIEscape(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFISignalFrame(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIUndefined(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIRegister(StringRef, SMLoc DirectiveLoc);
-
- bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveEndMacro(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectivePurgeMacro(StringRef, SMLoc DirectiveLoc);
-
- bool ParseDirectiveLEB128(StringRef, SMLoc);
+ void initializeDirectiveKindMap();
};
-
}
namespace llvm {
@@ -504,7 +427,7 @@ enum { DEFAULT_ADDRSPACE = 0 };
AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx,
MCStreamer &_Out, const MCAsmInfo &_MAI)
: Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM),
- GenericParser(new GenericAsmParser), PlatformParser(0),
+ PlatformParser(0),
CurBuffer(0), MacrosEnabledFlag(true), CppHashLineNumber(0),
AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) {
// Save the old handler.
@@ -514,9 +437,6 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx,
SrcMgr.setDiagHandler(DiagHandler, this);
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
- // Initialize the generic parser.
- GenericParser->Initialize(*this);
-
// Initialize the platform / file format parser.
//
// FIXME: This is a hack, we need to (majorly) cleanup how these objects are
@@ -533,19 +453,18 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx,
PlatformParser->Initialize(*this);
}
- initializeDirectiveKindMapping();
+ initializeDirectiveKindMap();
}
AsmParser::~AsmParser() {
assert(ActiveMacros.empty() && "Unexpected active macro instantiation!");
// Destroy any macros.
- for (StringMap<Macro*>::iterator it = MacroMap.begin(),
+ for (StringMap<MCAsmMacro*>::iterator it = MacroMap.begin(),
ie = MacroMap.end(); it != ie; ++it)
delete it->getValue();
delete PlatformParser;
- delete GenericParser;
}
void AsmParser::PrintMacroInstantiations() {
@@ -1182,10 +1101,10 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
// have to do this so that .endif isn't skipped in a ".if 0" block for
// example.
StringMap<DirectiveKind>::const_iterator DirKindIt =
- DirectiveKindMapping.find(IDVal);
+ DirectiveKindMap.find(IDVal);
DirectiveKind DirKind =
- (DirKindIt == DirectiveKindMapping.end()) ? DK_NO_DIRECTIVE :
- DirKindIt->getValue();
+ (DirKindIt == DirectiveKindMap.end()) ? DK_NO_DIRECTIVE :
+ DirKindIt->getValue();
switch (DirKind) {
default:
break;
@@ -1278,16 +1197,39 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
// If macros are enabled, check to see if this is a macro instantiation.
if (MacrosEnabled())
- if (const Macro *M = MacroMap.lookup(IDVal))
- return HandleMacroEntry(IDVal, IDLoc, M);
+ if (const MCAsmMacro *M = LookupMacro(IDVal)) {
+ return HandleMacroEntry(M, IDLoc);
+ }
// Otherwise, we have a normal instruction or directive.
+
+ // Directives start with "."
if (IDVal[0] == '.' && IDVal != ".") {
-
- // Target hook for parsing target specific directives.
+ // There are several entities interested in parsing directives:
+ //
+ // 1. The target-specific assembly parser. Some directives are target
+ // specific or may potentially behave differently on certain targets.
+ // 2. Asm parser extensions. For example, platform-specific parsers
+ // (like the ELF parser) register themselves as extensions.
+ // 3. The generic directive parser implemented by this class. These are
+ // all the directives that behave in a target and platform independent
+ // manner, or at least have a default behavior that's shared between
+ // all targets and platforms.
+
+ // First query the target-specific parser. It will return 'true' if it
+ // isn't interested in this directive.
if (!getTargetParser().ParseDirective(ID))
return false;
+ // Next, check the extention directive map to see if any extension has
+ // registered itself to parse this directive.
+ std::pair<MCAsmParserExtension*, DirectiveHandler> Handler =
+ ExtensionDirectiveMap.lookup(IDVal);
+ if (Handler.first)
+ return (*Handler.second)(Handler.first, IDVal, IDLoc);
+
+ // Finally, if no one else is interested in this directive, it must be
+ // generic and familiar to this class.
switch (DirKind) {
default:
break;
@@ -1397,14 +1339,71 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
return ParseDirectiveBundleLock();
case DK_BUNDLE_UNLOCK:
return ParseDirectiveBundleUnlock();
+ case DK_SLEB128:
+ return ParseDirectiveLEB128(true);
+ case DK_ULEB128:
+ return ParseDirectiveLEB128(false);
+ case DK_SPACE:
+ case DK_SKIP:
+ return ParseDirectiveSpace(IDVal);
+ case DK_FILE:
+ return ParseDirectiveFile(IDLoc);
+ case DK_LINE:
+ return ParseDirectiveLine();
+ case DK_LOC:
+ return ParseDirectiveLoc();
+ case DK_STABS:
+ return ParseDirectiveStabs();
+ case DK_CFI_SECTIONS:
+ return ParseDirectiveCFISections();
+ case DK_CFI_STARTPROC:
+ return ParseDirectiveCFIStartProc();
+ case DK_CFI_ENDPROC:
+ return ParseDirectiveCFIEndProc();
+ case DK_CFI_DEF_CFA:
+ return ParseDirectiveCFIDefCfa(IDLoc);
+ case DK_CFI_DEF_CFA_OFFSET:
+ return ParseDirectiveCFIDefCfaOffset();
+ case DK_CFI_ADJUST_CFA_OFFSET:
+ return ParseDirectiveCFIAdjustCfaOffset();
+ case DK_CFI_DEF_CFA_REGISTER:
+ return ParseDirectiveCFIDefCfaRegister(IDLoc);
+ case DK_CFI_OFFSET:
+ return ParseDirectiveCFIOffset(IDLoc);
+ case DK_CFI_REL_OFFSET:
+ return ParseDirectiveCFIRelOffset(IDLoc);
+ case DK_CFI_PERSONALITY:
+ return ParseDirectiveCFIPersonalityOrLsda(true);
+ case DK_CFI_LSDA:
+ return ParseDirectiveCFIPersonalityOrLsda(false);
+ case DK_CFI_REMEMBER_STATE:
+ return ParseDirectiveCFIRememberState();
+ case DK_CFI_RESTORE_STATE:
+ return ParseDirectiveCFIRestoreState();
+ case DK_CFI_SAME_VALUE:
+ return ParseDirectiveCFISameValue(IDLoc);
+ case DK_CFI_RESTORE:
+ return ParseDirectiveCFIRestore(IDLoc);
+ case DK_CFI_ESCAPE:
+ return ParseDirectiveCFIEscape();
+ case DK_CFI_SIGNAL_FRAME:
+ return ParseDirectiveCFISignalFrame();
+ case DK_CFI_UNDEFINED:
+ return ParseDirectiveCFIUndefined(IDLoc);
+ case DK_CFI_REGISTER:
+ return ParseDirectiveCFIRegister(IDLoc);
+ case DK_MACROS_ON:
+ case DK_MACROS_OFF:
+ return ParseDirectiveMacrosOnOff(IDVal);
+ case DK_MACRO:
+ return ParseDirectiveMacro(IDLoc);
+ case DK_ENDM:
+ case DK_ENDMACRO:
+ return ParseDirectiveEndMacro(IDVal);
+ case DK_PURGEM:
+ return ParseDirectivePurgeMacro(IDLoc);
}
- // Look up the handler in the extension handler table.
- std::pair<MCAsmParserExtension*, DirectiveHandler> Handler =
- DirectiveMap.lookup(IDVal);
- if (Handler.first)
- return (*Handler.second)(Handler.first, IDVal, IDLoc);
-
return Error(IDLoc, "unknown directive");
}
@@ -1590,8 +1589,8 @@ static bool isIdentifierChar(char c) {
}
bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
- const MacroParameters &Parameters,
- const MacroArguments &A,
+ const MCAsmMacroParameters &Parameters,
+ const MCAsmMacroArguments &A,
const SMLoc &L) {
unsigned NParameters = Parameters.size();
if (NParameters != 0 && NParameters != A.size())
@@ -1690,7 +1689,7 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
return false;
}
-MacroInstantiation::MacroInstantiation(const Macro *M, SMLoc IL,
+MacroInstantiation::MacroInstantiation(const MCAsmMacro *M, SMLoc IL,
int EB, SMLoc EL,
MemoryBuffer *I)
: TheMacro(M), Instantiation(I), InstantiationLoc(IL), ExitBuffer(EB),
@@ -1807,7 +1806,7 @@ bool AsmParser::ParseMacroArgument(MCAsmMacroArgument &MA,
}
// Parse the macro instantiation arguments.
-bool AsmParser::ParseMacroArguments(const Macro *M, MacroArguments &A) {
+bool AsmParser::ParseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A) {
const unsigned NParameters = M ? M->Parameters.size() : 0;
// Argument delimiter is initially unknown. It will be set by
// ParseMacroArgument()
@@ -1851,14 +1850,30 @@ bool AsmParser::ParseMacroArguments(const Macro *M, MacroArguments &A) {
return TokError("Too many arguments");
}
-bool AsmParser::HandleMacroEntry(StringRef Name, SMLoc NameLoc,
- const Macro *M) {
+const MCAsmMacro* AsmParser::LookupMacro(StringRef Name) {
+ StringMap<MCAsmMacro*>::iterator I = MacroMap.find(Name);
+ return (I == MacroMap.end()) ? NULL : I->getValue();
+}
+
+void AsmParser::DefineMacro(StringRef Name, const MCAsmMacro& Macro) {
+ MacroMap[Name] = new MCAsmMacro(Macro);
+}
+
+void AsmParser::UndefineMacro(StringRef Name) {
+ StringMap<MCAsmMacro*>::iterator I = MacroMap.find(Name);
+ if (I != MacroMap.end()) {
+ delete I->getValue();
+ MacroMap.erase(I);
+ }
+}
+
+bool AsmParser::HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
// Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate
// this, although we should protect against infinite loops.
if (ActiveMacros.size() == 20)
return TokError("macros cannot be nested more than 20 levels deep");
- MacroArguments A;
+ MCAsmMacroArguments A;
if (ParseMacroArguments(M, A))
return true;
@@ -1877,7 +1892,7 @@ bool AsmParser::HandleMacroEntry(StringRef Name, SMLoc NameLoc,
if (expandMacro(OS, Body, M->Parameters, A, getTok().getLoc()))
return true;
- // We include the .endmacro in the buffer as our queue to exit the macro
+ // We include the .endmacro in the buffer as our cue to exit the macro
// instantiation.
OS << ".endmacro\n";
@@ -2425,507 +2440,10 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
return false;
}
-
-/// ParseDirectiveBundleAlignMode
-/// ::= {.bundle_align_mode} expression
-bool AsmParser::ParseDirectiveBundleAlignMode() {
- CheckForValidSection();
-
- // Expect a single argument: an expression that evaluates to a constant
- // in the inclusive range 0-30.
- SMLoc ExprLoc = getLexer().getLoc();
- int64_t AlignSizePow2;
- if (ParseAbsoluteExpression(AlignSizePow2))
- return true;
- else if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token after expression in"
- " '.bundle_align_mode' directive");
- else if (AlignSizePow2 < 0 || AlignSizePow2 > 30)
- return Error(ExprLoc,
- "invalid bundle alignment size (expected between 0 and 30)");
-
- Lex();
-
- // Because of AlignSizePow2's verified range we can safely truncate it to
- // unsigned.
- getStreamer().EmitBundleAlignMode(static_cast<unsigned>(AlignSizePow2));
- return false;
-}
-
-/// ParseDirectiveBundleLock
-/// ::= {.bundle_lock} [align_to_end]
-bool AsmParser::ParseDirectiveBundleLock() {
- CheckForValidSection();
- bool AlignToEnd = false;
-
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- StringRef Option;
- SMLoc Loc = getTok().getLoc();
- const char *kInvalidOptionError =
- "invalid option for '.bundle_lock' directive";
-
- if (ParseIdentifier(Option))
- return Error(Loc, kInvalidOptionError);
-
- if (Option != "align_to_end")
- return Error(Loc, kInvalidOptionError);
- else if (getLexer().isNot(AsmToken::EndOfStatement))
- return Error(Loc,
- "unexpected token after '.bundle_lock' directive option");
- AlignToEnd = true;
- }
-
- Lex();
-
- getStreamer().EmitBundleLock(AlignToEnd);
- return false;
-}
-
-/// ParseDirectiveBundleLock
-/// ::= {.bundle_lock}
-bool AsmParser::ParseDirectiveBundleUnlock() {
- CheckForValidSection();
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.bundle_unlock' directive");
- Lex();
-
- getStreamer().EmitBundleUnlock();
- return false;
-}
-
-/// ParseDirectiveSymbolAttribute
-/// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
-bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- for (;;) {
- StringRef Name;
- SMLoc Loc = getTok().getLoc();
-
- if (ParseIdentifier(Name))
- return Error(Loc, "expected identifier in directive");
-
- MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
-
- // Assembler local symbols don't make any sense here. Complain loudly.
- if (Sym->isTemporary())
- return Error(Loc, "non-local symbol required in directive");
-
- getStreamer().EmitSymbolAttribute(Sym, Attr);
-
- if (getLexer().is(AsmToken::EndOfStatement))
- break;
-
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
- }
- }
-
- Lex();
- return false;
-}
-
-/// ParseDirectiveComm
-/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
-bool AsmParser::ParseDirectiveComm(bool IsLocal) {
- CheckForValidSection();
-
- SMLoc IDLoc = getLexer().getLoc();
- StringRef Name;
- if (ParseIdentifier(Name))
- return TokError("expected identifier in directive");
-
- // Handle the identifier as the key symbol.
- MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
-
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- int64_t Size;
- SMLoc SizeLoc = getLexer().getLoc();
- if (ParseAbsoluteExpression(Size))
- return true;
-
- int64_t Pow2Alignment = 0;
- SMLoc Pow2AlignmentLoc;
- if (getLexer().is(AsmToken::Comma)) {
- Lex();
- Pow2AlignmentLoc = getLexer().getLoc();
- if (ParseAbsoluteExpression(Pow2Alignment))
- return true;
-
- LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType();
- if (IsLocal && LCOMM == LCOMM::NoAlignment)
- return Error(Pow2AlignmentLoc, "alignment not supported on this target");
-
- // If this target takes alignments in bytes (not log) validate and convert.
- if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
- (IsLocal && LCOMM == LCOMM::ByteAlignment)) {
- if (!isPowerOf2_64(Pow2Alignment))
- return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
- Pow2Alignment = Log2_64(Pow2Alignment);
- }
- }
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.comm' or '.lcomm' directive");
-
- Lex();
-
- // NOTE: a size of zero for a .comm should create a undefined symbol
- // but a size of .lcomm creates a bss symbol of size zero.
- if (Size < 0)
- return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
- "be less than zero");
-
- // NOTE: The alignment in the directive is a power of 2 value, the assembler
- // may internally end up wanting an alignment in bytes.
- // FIXME: Diagnose overflow.
- if (Pow2Alignment < 0)
- return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
- "alignment, can't be less than zero");
-
- if (!Sym->isUndefined())
- return Error(IDLoc, "invalid symbol redefinition");
-
- // Create the Symbol as a common or local common with Size and Pow2Alignment
- if (IsLocal) {
- getStreamer().EmitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment);
- return false;
- }
-
- getStreamer().EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
- return false;
-}
-
-/// ParseDirectiveAbort
-/// ::= .abort [... message ...]
-bool AsmParser::ParseDirectiveAbort() {
- // FIXME: Use loc from directive.
- SMLoc Loc = getLexer().getLoc();
-
- StringRef Str = ParseStringToEndOfStatement();
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.abort' directive");
-
- Lex();
-
- if (Str.empty())
- Error(Loc, ".abort detected. Assembly stopping.");
- else
- Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
- // FIXME: Actually abort assembly here.
-
- return false;
-}
-
-/// ParseDirectiveInclude
-/// ::= .include "filename"
-bool AsmParser::ParseDirectiveInclude() {
- if (getLexer().isNot(AsmToken::String))
- return TokError("expected string in '.include' directive");
-
- std::string Filename = getTok().getString();
- SMLoc IncludeLoc = getLexer().getLoc();
- Lex();
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.include' directive");
-
- // Strip the quotes.
- Filename = Filename.substr(1, Filename.size()-2);
-
- // Attempt to switch the lexer to the included file before consuming the end
- // of statement to avoid losing it when we switch.
- if (EnterIncludeFile(Filename)) {
- Error(IncludeLoc, "Could not find include file '" + Filename + "'");
- return true;
- }
-
- return false;
-}
-
-/// ParseDirectiveIncbin
-/// ::= .incbin "filename"
-bool AsmParser::ParseDirectiveIncbin() {
- if (getLexer().isNot(AsmToken::String))
- return TokError("expected string in '.incbin' directive");
-
- std::string Filename = getTok().getString();
- SMLoc IncbinLoc = getLexer().getLoc();
- Lex();
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.incbin' directive");
-
- // Strip the quotes.
- Filename = Filename.substr(1, Filename.size()-2);
-
- // Attempt to process the included file.
- if (ProcessIncbinFile(Filename)) {
- Error(IncbinLoc, "Could not find incbin file '" + Filename + "'");
- return true;
- }
-
- return false;
-}
-
-/// ParseDirectiveIf
-/// ::= .if expression
-bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
- TheCondStack.push_back(TheCondState);
- TheCondState.TheCond = AsmCond::IfCond;
- if (TheCondState.Ignore) {
- EatToEndOfStatement();
- } else {
- int64_t ExprValue;
- if (ParseAbsoluteExpression(ExprValue))
- return true;
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.if' directive");
-
- Lex();
-
- TheCondState.CondMet = ExprValue;
- TheCondState.Ignore = !TheCondState.CondMet;
- }
-
- return false;
-}
-
-/// ParseDirectiveIfb
-/// ::= .ifb string
-bool AsmParser::ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
- TheCondStack.push_back(TheCondState);
- TheCondState.TheCond = AsmCond::IfCond;
-
- if (TheCondState.Ignore) {
- EatToEndOfStatement();
- } else {
- StringRef Str = ParseStringToEndOfStatement();
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.ifb' directive");
-
- Lex();
-
- TheCondState.CondMet = ExpectBlank == Str.empty();
- TheCondState.Ignore = !TheCondState.CondMet;
- }
-
- return false;
-}
-
-/// ParseDirectiveIfc
-/// ::= .ifc string1, string2
-bool AsmParser::ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
- TheCondStack.push_back(TheCondState);
- TheCondState.TheCond = AsmCond::IfCond;
-
- if (TheCondState.Ignore) {
- EatToEndOfStatement();
- } else {
- StringRef Str1 = ParseStringToComma();
-
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '.ifc' directive");
-
- Lex();
-
- StringRef Str2 = ParseStringToEndOfStatement();
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.ifc' directive");
-
- Lex();
-
- TheCondState.CondMet = ExpectEqual == (Str1 == Str2);
- TheCondState.Ignore = !TheCondState.CondMet;
- }
-
- return false;
-}
-
-/// ParseDirectiveIfdef
-/// ::= .ifdef symbol
-bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
- StringRef Name;
- TheCondStack.push_back(TheCondState);
- TheCondState.TheCond = AsmCond::IfCond;
-
- if (TheCondState.Ignore)