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,8 @@ virtual void *LookupInlineAsmIdentifier(StringRef &LineBuf, InlineAsmIdentifierInfo &Info, bool IsUnevaluatedContext) = 0; + virtual void LookupInlineAsmLabel(StringRef &Identifier, SourceMgr &SM, + SMLoc Location, bool CreateLabel) {} 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 @@ -246,7 +246,8 @@ private: - bool parseStatement(ParseStatementInfo &Info); + bool parseStatement(ParseStatementInfo &Info, + MCAsmParserSemaCallback *SI); void eatToEndOfLine(); bool parseCppHashLineFilenameComment(const SMLoc &L); @@ -643,7 +644,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 @@ -1188,7 +1189,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(); @@ -1298,9 +1300,18 @@ // 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 = IDVal; + SI->LookupInlineAsmLabel(RewrittenLabel, getSourceManager(), IDLoc, true); + if (IDVal != RewrittenLabel) { + 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"); @@ -4490,7 +4501,7 @@ unsigned OutputIdx = 0; while (getLexer().isNot(AsmToken::Eof)) { ParseStatementInfo Info(&AsmStrRewrites); - if (parseStatement(Info)) + if (parseStatement(Info, &SI)) return true; if (Info.ParseError) @@ -4616,6 +4627,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 @@ -986,6 +986,12 @@ // operand to ensure proper matching. Just pick a GPR based on the size of // a pointer. if (isa(Disp) && !Info.IsVarDecl) { + 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)); + } unsigned RegNo = is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX); return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true, @@ -1278,9 +1284,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. @@ -1292,9 +1300,18 @@ 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) { + SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(), Loc, false); + if (Identifier != LineBuf) { + 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());