1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 19:52:54 +01:00

ms-inline-asm: Add a sema callback for looking up label names

The implementation of the callback in clang's Sema will return an
internal name for labels.

Test Plan: Will be tested in clang.

Reviewers: rnk

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D4587

llvm-svn: 218229
This commit is contained in:
Ehsan Akhgari 2014-09-22 02:21:35 +00:00
parent 973771fcb4
commit 0a0d085305
4 changed files with 46 additions and 8 deletions

View File

@ -35,6 +35,7 @@ public:
void *OpDecl;
bool IsVarDecl;
unsigned Length, Size, Type;
StringRef InternalName;
void clear() {
OpDecl = nullptr;
@ -42,6 +43,7 @@ public:
Length = 1;
Size = 0;
Type = 0;
InternalName = "";
}
};
@ -52,6 +54,9 @@ public:
virtual void *LookupInlineAsmIdentifier(StringRef &LineBuf,
InlineAsmIdentifierInfo &Info,
bool IsUnevaluatedContext) = 0;
virtual StringRef LookupInlineAsmLabel(StringRef Identifier, SourceMgr &SM,
SMLoc Location, bool Create)
{ return nullptr; }
virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,
unsigned &Offset) = 0;

View File

@ -38,6 +38,7 @@ enum AsmRewriteKind {
AOK_Input, // Rewrite in terms of $N.
AOK_Output, // Rewrite in terms of $N.
AOK_SizeDirective, // Add a sizing directive (e.g., dword ptr).
AOK_Label, // Rewrite local labels.
AOK_Skip // Skip emission (e.g., offset/type operators).
};
@ -51,6 +52,7 @@ const char AsmRewritePrecedence [] = {
2, // AOK_Input
2, // AOK_Output
4, // AOK_SizeDirective
1, // AOK_Label
1 // AOK_Skip
};
@ -59,9 +61,12 @@ struct AsmRewrite {
SMLoc Loc;
unsigned Len;
unsigned Val;
StringRef Label;
public:
AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len = 0, unsigned val = 0)
: Kind(kind), Loc(loc), Len(len), Val(val) {}
AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len, StringRef label)
: Kind(kind), Loc(loc), Len(len), Val(0), Label(label) {}
};
struct ParseInstructionInfo {

View File

@ -238,7 +238,8 @@ public:
private:
bool parseStatement(ParseStatementInfo &Info);
bool parseStatement(ParseStatementInfo &Info,
MCAsmParserSemaCallback *SI);
void eatToEndOfLine();
bool parseCppHashLineFilenameComment(const SMLoc &L);
@ -640,7 +641,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// While we have input, parse each statement.
while (Lexer.isNot(AsmToken::Eof)) {
ParseStatementInfo Info;
if (!parseStatement(Info))
if (!parseStatement(Info, nullptr))
continue;
// We had an error, validate that one was emitted and recover by skipping to
@ -1185,7 +1186,8 @@ bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
/// ::= EndOfStatement
/// ::= Label* Directive ...Operands... EndOfStatement
/// ::= Label* Identifier OperandList* EndOfStatement
bool AsmParser::parseStatement(ParseStatementInfo &Info) {
bool AsmParser::parseStatement(ParseStatementInfo &Info,
MCAsmParserSemaCallback *SI) {
if (Lexer.is(AsmToken::EndOfStatement)) {
Out.AddBlankLine();
Lex();
@ -1295,9 +1297,16 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
// FIXME: This doesn't diagnose assignment to a symbol which has been
// implicitly marked as external.
MCSymbol *Sym;
if (LocalLabelVal == -1)
if (LocalLabelVal == -1) {
if (ParsingInlineAsm && SI) {
StringRef RewrittenLabel = SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true);
assert(RewrittenLabel.size() && "We should have an internal name here.");
Info.AsmRewrites->push_back(AsmRewrite(AOK_Label, IDLoc,
IDVal.size(), RewrittenLabel));
IDVal = RewrittenLabel;
}
Sym = getContext().GetOrCreateSymbol(IDVal);
else
} else
Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal);
if (!Sym->isUndefined() || Sym->isVariable())
return Error(IDLoc, "invalid symbol redefinition");
@ -4541,7 +4550,7 @@ bool AsmParser::parseMSInlineAsm(
unsigned OutputIdx = 0;
while (getLexer().isNot(AsmToken::Eof)) {
ParseStatementInfo Info(&AsmStrRewrites);
if (parseStatement(Info))
if (parseStatement(Info, &SI))
return true;
if (Info.ParseError)
@ -4667,6 +4676,9 @@ bool AsmParser::parseMSInlineAsm(
case AOK_ImmPrefix:
OS << "$$";
break;
case AOK_Label:
OS << Ctx.getAsmInfo()->getPrivateGlobalPrefix() << AR.Label;
break;
case AOK_Input:
OS << '$' << InputIdx++;
break;

View File

@ -1047,6 +1047,12 @@ std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
/*Len=*/0, Size));
}
if (!Info.InternalName.empty()) {
// Push a rewrite for replacing the identifier name with the internal name.
InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Label, Start,
End.getPointer() - Start.getPointer(),
Info.InternalName));
}
}
// When parsing inline assembly we set the base register to a non-zero value
@ -1320,9 +1326,11 @@ bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
Val = nullptr;
StringRef LineBuf(Identifier.data());
SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
void *Result =
SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
const AsmToken &Tok = Parser.getTok();
SMLoc Loc = Tok.getLoc();
// Advance the token stream until the end of the current token is
// after the end of what the frontend claimed.
@ -1334,9 +1342,17 @@ bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
assert(End.getPointer() <= EndPtr && "frontend claimed part of a token?");
if (End.getPointer() == EndPtr) break;
}
Identifier = LineBuf;
// If the identifier lookup was unsuccessful, assume that we are dealing with
// a label.
if (!Result) {
Identifier = SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(), Loc, false);
assert(Identifier.size() && "We should have an internal name here.");
Info.InternalName = Identifier;
}
// Create the symbol reference.
Identifier = LineBuf;
MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
Val = MCSymbolRefExpr::Create(Sym, Variant, getParser().getContext());