forked from OSchip/llvm-project
[ms-inline asm] Add support for parsing variables with namespace alias
qualifiers. This patch only adds support for parsing these identifiers in the X86AsmParser. The front-end interface isn't capable of looking up these identifiers at this point in time. The end result is the compiler now errors during object file emission, rather than at parse time. Test case coming shortly. Part of rdar://13499009 and PR13340 llvm-svn: 178566
This commit is contained in:
parent
70e19bd31e
commit
8a24466f69
|
@ -13,6 +13,7 @@
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/StringSwitch.h"
|
#include "llvm/ADT/StringSwitch.h"
|
||||||
#include "llvm/ADT/Twine.h"
|
#include "llvm/ADT/Twine.h"
|
||||||
|
#include "llvm/MC/MCContext.h"
|
||||||
#include "llvm/MC/MCExpr.h"
|
#include "llvm/MC/MCExpr.h"
|
||||||
#include "llvm/MC/MCInst.h"
|
#include "llvm/MC/MCInst.h"
|
||||||
#include "llvm/MC/MCParser/MCAsmLexer.h"
|
#include "llvm/MC/MCParser/MCAsmLexer.h"
|
||||||
|
@ -62,6 +63,8 @@ private:
|
||||||
SMLoc StartLoc);
|
SMLoc StartLoc);
|
||||||
X86Operand *ParseIntelBracExpression(unsigned SegReg, uint64_t ImmDisp,
|
X86Operand *ParseIntelBracExpression(unsigned SegReg, uint64_t ImmDisp,
|
||||||
unsigned Size);
|
unsigned Size);
|
||||||
|
X86Operand *ParseIntelVarWithQualifier(const MCExpr *&Disp,
|
||||||
|
SMLoc &IdentStart);
|
||||||
X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
|
X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
|
||||||
|
|
||||||
X86Operand *CreateMemForInlineAsm(const MCExpr *Disp, SMLoc Start, SMLoc End,
|
X86Operand *CreateMemForInlineAsm(const MCExpr *Disp, SMLoc Start, SMLoc End,
|
||||||
|
@ -935,9 +938,13 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
|
||||||
if (getLexer().is(AsmToken::Identifier)) {
|
if (getLexer().is(AsmToken::Identifier)) {
|
||||||
if (ParseRegister(TmpReg, Start, End)) {
|
if (ParseRegister(TmpReg, Start, End)) {
|
||||||
const MCExpr *Disp;
|
const MCExpr *Disp;
|
||||||
|
SMLoc IdentStart = Tok.getLoc();
|
||||||
if (getParser().parseExpression(Disp, End))
|
if (getParser().parseExpression(Disp, End))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (X86Operand *Err = ParseIntelVarWithQualifier(Disp, IdentStart))
|
||||||
|
return Err;
|
||||||
|
|
||||||
if (getLexer().isNot(AsmToken::RBrac))
|
if (getLexer().isNot(AsmToken::RBrac))
|
||||||
return ErrorOperand(Parser.getTok().getLoc(), "Expected ']' token!");
|
return ErrorOperand(Parser.getTok().getLoc(), "Expected ']' token!");
|
||||||
|
|
||||||
|
@ -1046,6 +1053,48 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
|
||||||
Start, End, Size);
|
Start, End, Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inline assembly may use variable names with namespace alias qualifiers.
|
||||||
|
X86Operand *X86AsmParser::ParseIntelVarWithQualifier(const MCExpr *&Disp,
|
||||||
|
SMLoc &IdentStart) {
|
||||||
|
// We should only see Foo::Bar if we're parsing inline assembly.
|
||||||
|
if (!isParsingInlineAsm())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// If we don't see a ':' then there can't be a qualifier.
|
||||||
|
if (getLexer().isNot(AsmToken::Colon))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
bool Done = false;
|
||||||
|
const AsmToken &Tok = Parser.getTok();
|
||||||
|
SMLoc IdentEnd = Tok.getEndLoc();
|
||||||
|
while (!Done) {
|
||||||
|
switch (getLexer().getKind()) {
|
||||||
|
default:
|
||||||
|
Done = true;
|
||||||
|
break;
|
||||||
|
case AsmToken::Colon:
|
||||||
|
getLexer().Lex(); // Consume ':'.
|
||||||
|
if (getLexer().isNot(AsmToken::Colon))
|
||||||
|
return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
|
||||||
|
getLexer().Lex(); // Consume second ':'.
|
||||||
|
if (getLexer().isNot(AsmToken::Identifier))
|
||||||
|
return ErrorOperand(Tok.getLoc(), "Expected an identifier token!");
|
||||||
|
break;
|
||||||
|
case AsmToken::Identifier:
|
||||||
|
IdentEnd = Tok.getEndLoc();
|
||||||
|
getLexer().Lex(); // Consume the identifier.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t Len = IdentEnd.getPointer() - IdentStart.getPointer();
|
||||||
|
StringRef Identifier(IdentStart.getPointer(), Len);
|
||||||
|
MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
|
||||||
|
MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
|
||||||
|
Disp = MCSymbolRefExpr::Create(Sym, Variant, getParser().getContext());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// ParseIntelMemOperand - Parse intel style memory operand.
|
/// ParseIntelMemOperand - Parse intel style memory operand.
|
||||||
X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg,
|
X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg,
|
||||||
uint64_t ImmDisp,
|
uint64_t ImmDisp,
|
||||||
|
@ -1088,11 +1137,16 @@ X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg,
|
||||||
}
|
}
|
||||||
|
|
||||||
const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
|
const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
|
||||||
|
SMLoc IdentStart = Tok.getLoc();
|
||||||
if (getParser().parseExpression(Disp, End))
|
if (getParser().parseExpression(Disp, End))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!isParsingInlineAsm())
|
if (!isParsingInlineAsm())
|
||||||
return X86Operand::CreateMem(Disp, Start, End, Size);
|
return X86Operand::CreateMem(Disp, Start, End, Size);
|
||||||
|
|
||||||
|
if (X86Operand *Err = ParseIntelVarWithQualifier(Disp, IdentStart))
|
||||||
|
return Err;
|
||||||
|
|
||||||
return CreateMemForInlineAsm(Disp, Start, End, Start, Size);
|
return CreateMemForInlineAsm(Disp, Start, End, Start, Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue