//===----------------------------------------------------------------------===//
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/Target/TargetAsmInfo.h"
-#include "llvm/Target/TargetAsmParser.h"
+#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/Support/COFF.h"
using namespace llvm;
namespace {
class COFFAsmParser : public MCAsmParserExtension {
- template<bool (COFFAsmParser::*Handler)(StringRef, SMLoc)>
- void AddDirectiveHandler(StringRef Directive) {
- getParser().AddDirectiveHandler(this, Directive,
- HandleDirective<COFFAsmParser, Handler>);
+ template<bool (COFFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
+ void addDirectiveHandler(StringRef Directive) {
+ MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
+ this, HandleDirective<COFFAsmParser, HandlerMethod>);
+ getParser().addDirectiveHandler(Directive, Handler);
}
bool ParseSectionSwitch(StringRef Section,
// Call the base implementation.
MCAsmParserExtension::Initialize(Parser);
- AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
- AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
- AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
- AddDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
- AddDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
- AddDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
- AddDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
+ addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
+ addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
+ addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
// Win64 EH directives.
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
".seh_proc");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
".seh_endproc");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
".seh_startchained");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
".seh_endchained");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
".seh_handler");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
".seh_handlerdata");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
".seh_pushreg");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
".seh_setframe");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
".seh_stackalloc");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
".seh_savereg");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
".seh_savexmm");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
".seh_pushframe");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
".seh_endprologue");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
}
bool ParseSectionDirectiveText(StringRef, SMLoc) {
bool ParseDirectiveScl(StringRef, SMLoc);
bool ParseDirectiveType(StringRef, SMLoc);
bool ParseDirectiveEndef(StringRef, SMLoc);
+ bool ParseDirectiveSecRel32(StringRef, SMLoc);
// Win64 EH directives.
bool ParseSEHDirectiveStartProc(StringRef, SMLoc);
bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except);
bool ParseSEHRegisterNumber(unsigned &RegNo);
+ bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc);
public:
COFFAsmParser() {}
};
} // end annonomous namespace.
+/// ParseDirectiveSymbolAttribute
+/// ::= { ".weak", ... } [ identifier ( , identifier )* ]
+bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
+ MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
+ .Case(".weak", MCSA_Weak)
+ .Default(MCSA_Invalid);
+ assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ for (;;) {
+ StringRef Name;
+
+ if (getParser().parseIdentifier(Name))
+ return TokError("expected identifier in directive");
+
+ MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
+
+ 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;
+}
+
bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
unsigned Characteristics,
SectionKind Kind) {
bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
StringRef SymbolName;
- if (getParser().ParseIdentifier(SymbolName))
+ if (getParser().parseIdentifier(SymbolName))
return TokError("expected identifier in directive");
MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
int64_t SymbolStorageClass;
- if (getParser().ParseAbsoluteExpression(SymbolStorageClass))
+ if (getParser().parseAbsoluteExpression(SymbolStorageClass))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
bool COFFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
int64_t Type;
- if (getParser().ParseAbsoluteExpression(Type))
+ if (getParser().parseAbsoluteExpression(Type))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
return false;
}
+bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
+ StringRef SymbolID;
+ if (getParser().parseIdentifier(SymbolID))
+ return true;
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
+
+ MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID);
+
+ Lex();
+ getStreamer().EmitCOFFSecRel32(Symbol);
+ return false;
+}
+
bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
StringRef SymbolID;
- if (getParser().ParseIdentifier(SymbolID))
+ if (getParser().parseIdentifier(SymbolID))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) {
StringRef SymbolID;
- if (getParser().ParseIdentifier(SymbolID))
+ if (getParser().parseIdentifier(SymbolID))
return true;
if (getLexer().isNot(AsmToken::Comma))
int64_t Off;
if (ParseSEHRegisterNumber(Reg))
return true;
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("you must specify a stack pointer offset");
+
+ Lex();
SMLoc startLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Off))
+ if (getParser().parseAbsoluteExpression(Off))
return true;
if (Off & 0x0F)
bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc) {
int64_t Size;
SMLoc startLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Size))
+ if (getParser().parseAbsoluteExpression(Size))
return true;
if (Size & 7)
if (ParseSEHRegisterNumber(Reg))
return true;
if (getLexer().isNot(AsmToken::Comma))
- return TokError("expected comma");
+ return TokError("you must specify an offset on the stack");
Lex();
SMLoc startLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Off))
+ if (getParser().parseAbsoluteExpression(Off))
return true;
if (Off & 7)
if (ParseSEHRegisterNumber(Reg))
return true;
if (getLexer().isNot(AsmToken::Comma))
- return TokError("expected comma");
+ return TokError("you must specify an offset on the stack");
Lex();
SMLoc startLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Off))
+ if (getParser().parseAbsoluteExpression(Off))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
if (getLexer().is(AsmToken::At)) {
SMLoc startLoc = getLexer().getLoc();
Lex();
- if (!getParser().ParseIdentifier(CodeID)) {
+ if (!getParser().parseIdentifier(CodeID)) {
if (CodeID != "code")
return Error(startLoc, "expected @code");
Code = true;
return TokError("a handler attribute must begin with '@'");
SMLoc startLoc = getLexer().getLoc();
Lex();
- if (getParser().ParseIdentifier(identifier))
+ if (getParser().parseIdentifier(identifier))
return Error(startLoc, "expected @unwind or @except");
if (identifier == "unwind")
unwind = true;
bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) {
SMLoc startLoc = getLexer().getLoc();
if (getLexer().is(AsmToken::Percent)) {
- const TargetAsmInfo &asmInfo = getContext().getTargetAsmInfo();
+ const MCRegisterInfo &MRI = getContext().getRegisterInfo();
SMLoc endLoc;
unsigned LLVMRegNo;
if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc))
return true;
+#if 0
+ // FIXME: TargetAsmInfo::getCalleeSavedRegs() commits a serious layering
+ // violation so this validation code is disabled.
+
// Check that this is a non-volatile register.
- const unsigned *NVRegs = asmInfo.getCalleeSavedRegs();
+ const unsigned *NVRegs = TAI.getCalleeSavedRegs();
unsigned i;
for (i = 0; NVRegs[i] != 0; ++i)
if (NVRegs[i] == LLVMRegNo)
break;
if (NVRegs[i] == 0)
return Error(startLoc, "expected non-volatile register");
+#endif
- int SEHRegNo = asmInfo.getSEHRegNum(LLVMRegNo);
+ int SEHRegNo = MRI.getSEHRegNum(LLVMRegNo);
if (SEHRegNo < 0)
return Error(startLoc,"register can't be represented in SEH unwind info");
RegNo = SEHRegNo;
}
else {
int64_t n;
- if (getParser().ParseAbsoluteExpression(n))
+ if (getParser().parseAbsoluteExpression(n))
return true;
if (n > 15)
return Error(startLoc, "register number is too high");