Index: include/llvm/MC/MCParser/MCAsmParser.h =================================================================== --- include/llvm/MC/MCParser/MCAsmParser.h +++ include/llvm/MC/MCParser/MCAsmParser.h @@ -35,6 +35,7 @@ void *OpDecl; bool IsVarDecl; unsigned Length, Size, Type; + StringRef InternalName; void clear() { OpDecl = nullptr; @@ -42,6 +43,7 @@ Length = 1; Size = 0; Type = 0; + InternalName = ""; } }; @@ -52,6 +54,9 @@ 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; Index: include/llvm/MC/MCTargetAsmParser.h =================================================================== --- include/llvm/MC/MCTargetAsmParser.h +++ include/llvm/MC/MCTargetAsmParser.h @@ -38,6 +38,7 @@ 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 @@ 2, // AOK_Input 2, // AOK_Output 4, // AOK_SizeDirective + 1, // AOK_Label 1 // AOK_Skip }; @@ -59,9 +61,12 @@ 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 { Index: lib/MC/MCParser/AsmParser.cpp =================================================================== --- lib/MC/MCParser/AsmParser.cpp +++ lib/MC/MCParser/AsmParser.cpp @@ -238,7 +238,8 @@ private: - bool parseStatement(ParseStatementInfo &Info); + bool parseStatement(ParseStatementInfo &Info, + MCAsmParserSemaCallback *SI); void eatToEndOfLine(); bool parseCppHashLineFilenameComment(const SMLoc &L); @@ -640,7 +641,7 @@ // 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 @@ /// ::= 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 @@ // 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 @@ 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 @@ case AOK_ImmPrefix: OS << "$$"; break; + case AOK_Label: + OS << Ctx.getAsmInfo()->getPrivateGlobalPrefix() << AR.Label; + break; case AOK_Input: OS << '$' << InputIdx++; break; Index: lib/Target/X86/AsmParser/X86AsmParser.cpp =================================================================== --- lib/Target/X86/AsmParser/X86AsmParser.cpp +++ lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -1047,6 +1047,12 @@ 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 @@ 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 @@ 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());