void *OpDecl;
bool IsVarDecl;
unsigned Length, Size, Type;
+ StringRef InternalName;
void clear() {
OpDecl = nullptr;
Length = 1;
Size = 0;
Type = 0;
+ InternalName = "";
}
};
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;
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).
};
2, // AOK_Input
2, // AOK_Output
4, // AOK_SizeDirective
+ 1, // AOK_Label
1 // AOK_Skip
};
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 {
private:
- bool parseStatement(ParseStatementInfo &Info);
+ bool parseStatement(ParseStatementInfo &Info,
+ MCAsmParserSemaCallback *SI);
void eatToEndOfLine();
bool parseCppHashLineFilenameComment(const SMLoc &L);
// 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
/// ::= 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();
// 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");
unsigned OutputIdx = 0;
while (getLexer().isNot(AsmToken::Eof)) {
ParseStatementInfo Info(&AsmStrRewrites);
- if (parseStatement(Info))
+ if (parseStatement(Info, &SI))
return true;
if (Info.ParseError)
case AOK_ImmPrefix:
OS << "$$";
break;
+ case AOK_Label:
+ OS << Ctx.getAsmInfo()->getPrivateGlobalPrefix() << AR.Label;
+ break;
case AOK_Input:
OS << '$' << InputIdx++;
break;
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
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.
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());