llvm.org GIT mirror llvm / ffaafbe
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218229 91177308-0d34-0410-b5e6-96231b3b80d8 Ehsan Akhgari 6 years ago
4 changed file(s) with 46 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
3434 void *OpDecl;
3535 bool IsVarDecl;
3636 unsigned Length, Size, Type;
37 StringRef InternalName;
3738
3839 void clear() {
3940 OpDecl = nullptr;
4142 Length = 1;
4243 Size = 0;
4344 Type = 0;
45 InternalName = "";
4446 }
4547 };
4648
5153 virtual void *LookupInlineAsmIdentifier(StringRef &LineBuf,
5254 InlineAsmIdentifierInfo &Info,
5355 bool IsUnevaluatedContext) = 0;
56 virtual StringRef LookupInlineAsmLabel(StringRef Identifier, SourceMgr &SM,
57 SMLoc Location, bool Create)
58 { return nullptr; }
5459
5560 virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,
5661 unsigned &Offset) = 0;
3737 AOK_Input, // Rewrite in terms of $N.
3838 AOK_Output, // Rewrite in terms of $N.
3939 AOK_SizeDirective, // Add a sizing directive (e.g., dword ptr).
40 AOK_Label, // Rewrite local labels.
4041 AOK_Skip // Skip emission (e.g., offset/type operators).
4142 };
4243
5051 2, // AOK_Input
5152 2, // AOK_Output
5253 4, // AOK_SizeDirective
54 1, // AOK_Label
5355 1 // AOK_Skip
5456 };
5557
5860 SMLoc Loc;
5961 unsigned Len;
6062 unsigned Val;
63 StringRef Label;
6164 public:
6265 AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len = 0, unsigned val = 0)
6366 : Kind(kind), Loc(loc), Len(len), Val(val) {}
67 AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len, StringRef label)
68 : Kind(kind), Loc(loc), Len(len), Val(0), Label(label) {}
6469 };
6570
6671 struct ParseInstructionInfo {
237237
238238 private:
239239
240 bool parseStatement(ParseStatementInfo &Info);
240 bool parseStatement(ParseStatementInfo &Info,
241 MCAsmParserSemaCallback *SI);
241242 void eatToEndOfLine();
242243 bool parseCppHashLineFilenameComment(const SMLoc &L);
243244
639640 // While we have input, parse each statement.
640641 while (Lexer.isNot(AsmToken::Eof)) {
641642 ParseStatementInfo Info;
642 if (!parseStatement(Info))
643 if (!parseStatement(Info, nullptr))
643644 continue;
644645
645646 // We had an error, validate that one was emitted and recover by skipping to
11841185 /// ::= EndOfStatement
11851186 /// ::= Label* Directive ...Operands... EndOfStatement
11861187 /// ::= Label* Identifier OperandList* EndOfStatement
1187 bool AsmParser::parseStatement(ParseStatementInfo &Info) {
1188 bool AsmParser::parseStatement(ParseStatementInfo &Info,
1189 MCAsmParserSemaCallback *SI) {
11881190 if (Lexer.is(AsmToken::EndOfStatement)) {
11891191 Out.AddBlankLine();
11901192 Lex();
12941296 // FIXME: This doesn't diagnose assignment to a symbol which has been
12951297 // implicitly marked as external.
12961298 MCSymbol *Sym;
1297 if (LocalLabelVal == -1)
1299 if (LocalLabelVal == -1) {
1300 if (ParsingInlineAsm && SI) {
1301 StringRef RewrittenLabel = SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true);
1302 assert(RewrittenLabel.size() && "We should have an internal name here.");
1303 Info.AsmRewrites->push_back(AsmRewrite(AOK_Label, IDLoc,
1304 IDVal.size(), RewrittenLabel));
1305 IDVal = RewrittenLabel;
1306 }
12981307 Sym = getContext().GetOrCreateSymbol(IDVal);
1299 else
1308 } else
13001309 Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal);
13011310 if (!Sym->isUndefined() || Sym->isVariable())
13021311 return Error(IDLoc, "invalid symbol redefinition");
45404549 unsigned OutputIdx = 0;
45414550 while (getLexer().isNot(AsmToken::Eof)) {
45424551 ParseStatementInfo Info(&AsmStrRewrites);
4543 if (parseStatement(Info))
4552 if (parseStatement(Info, &SI))
45444553 return true;
45454554
45464555 if (Info.ParseError)
46654674 break;
46664675 case AOK_ImmPrefix:
46674676 OS << "$$";
4677 break;
4678 case AOK_Label:
4679 OS << Ctx.getAsmInfo()->getPrivateGlobalPrefix() << AR.Label;
46684680 break;
46694681 case AOK_Input:
46704682 OS << '$' << InputIdx++;
10461046 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
10471047 /*Len=*/0, Size));
10481048 }
1049 if (!Info.InternalName.empty()) {
1050 // Push a rewrite for replacing the identifier name with the internal name.
1051 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Label, Start,
1052 End.getPointer() - Start.getPointer(),
1053 Info.InternalName));
1054 }
10491055 }
10501056
10511057 // When parsing inline assembly we set the base register to a non-zero value
13191325 Val = nullptr;
13201326
13211327 StringRef LineBuf(Identifier.data());
1322 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1328 void *Result =
1329 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
13231330
13241331 const AsmToken &Tok = Parser.getTok();
1332 SMLoc Loc = Tok.getLoc();
13251333
13261334 // Advance the token stream until the end of the current token is
13271335 // after the end of what the frontend claimed.
13331341 assert(End.getPointer() <= EndPtr && "frontend claimed part of a token?");
13341342 if (End.getPointer() == EndPtr) break;
13351343 }
1344 Identifier = LineBuf;
1345
1346 // If the identifier lookup was unsuccessful, assume that we are dealing with
1347 // a label.
1348 if (!Result) {
1349 Identifier = SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(), Loc, false);
1350 assert(Identifier.size() && "We should have an internal name here.");
1351 Info.InternalName = Identifier;
1352 }
13361353
13371354 // Create the symbol reference.
1338 Identifier = LineBuf;
13391355 MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
13401356 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
13411357 Val = MCSymbolRefExpr::Create(Sym, Variant, getParser().getContext());