llvm.org GIT mirror llvm / 6804971
[ms-inline asm] Remove the identifier parsing logic from the AsmParser. This is now taken care of by the frontend, which allows us to parse arbitrary C/C++ variables. Part of rdar://13663589 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180037 91177308-0d34-0410-b5e6-96231b3b80d8 Chad Rosier 7 years ago
2 changed file(s) with 58 addition(s) and 62 deletion(s). Raw diff Collapse all Expand all
5252 unsigned &Offset) = 0;
5353 };
5454
55 typedef MCAsmParserSemaCallback::InlineAsmIdentifierInfo
56 InlineAsmIdentifierInfo;
5557
5658 /// MCAsmParser - Generic assembler parser interface, for use by target specific
5759 /// assembly parsers.
205205 StringRef SymName;
206206 bool StopOnLBrac, AddImmPrefix;
207207 InfixCalculator IC;
208 InlineAsmIdentifierInfo Info;
208209 public:
209210 IntelExprStateMachine(int64_t imm, bool stoponlbrac, bool addimmprefix) :
210211 State(IES_PLUS), PrevState(IES_ERROR), BaseReg(0), IndexReg(0), TmpReg(0),
211212 Scale(1), Imm(imm), Sym(0), StopOnLBrac(stoponlbrac),
212 AddImmPrefix(addimmprefix) {}
213 AddImmPrefix(addimmprefix) { Info.clear(); }
213214
214215 unsigned getBaseReg() { return BaseReg; }
215216 unsigned getIndexReg() { return IndexReg; }
221222 bool getStopOnLBrac() { return StopOnLBrac; }
222223 bool getAddImmPrefix() { return AddImmPrefix; }
223224 bool hadError() { return State == IES_ERROR; }
225
226 InlineAsmIdentifierInfo &getIdentifierInfo() {
227 return Info;
228 }
224229
225230 void onPlus() {
226231 IntelExprState CurrState = State;
494499 X86Operand *ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
495500 int64_t ImmDisp, unsigned Size);
496501 X86Operand *ParseIntelIdentifier(const MCExpr *&Val, StringRef &Identifier,
497 SMLoc &End);
502 InlineAsmIdentifierInfo &Info, SMLoc &End);
503
498504 X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
499505
500506 X86Operand *CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp,
501507 unsigned BaseReg, unsigned IndexReg,
502508 unsigned Scale, SMLoc Start, SMLoc End,
503 unsigned Size, StringRef SymName);
509 unsigned Size, StringRef Identifier,
510 InlineAsmIdentifierInfo &Info);
504511
505512 bool ParseDirectiveWord(unsigned Size, SMLoc L);
506513 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
11181125 X86AsmParser::CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp,
11191126 unsigned BaseReg, unsigned IndexReg,
11201127 unsigned Scale, SMLoc Start, SMLoc End,
1121 unsigned Size, StringRef Identifier) {
1122 bool NeedSizeDir = false;
1128 unsigned Size, StringRef Identifier,
1129 InlineAsmIdentifierInfo &Info){
1130
1131
11231132 if (const MCSymbolRefExpr *SymRef = dyn_cast(Disp)) {
1124 const MCSymbol &Sym = SymRef->getSymbol();
1125 StringRef SymName = Sym.getName();
1126 MCAsmParserSemaCallback::InlineAsmIdentifierInfo Info;
1127 SemaCallback->LookupInlineAsmIdentifier(SymName, Info);
1128
1129 if (!Size) {
1130 Size = Info.Type * 8; // Size is in terms of bits in this context.
1131 NeedSizeDir = Size > 0;
1132 }
11331133 // If this is not a VarDecl then assume it is a FuncDecl or some other label
11341134 // reference. We need an 'r' constraint here, so we need to create register
11351135 // operand to ensure proper matching. Just pick a GPR based on the size of
11391139 return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true,
11401140 SMLoc(), Identifier);
11411141 }
1142 }
1143
1144 if (NeedSizeDir)
1145 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
1146 /*Len=*/0, Size));
1142 if (!Size) {
1143 Size = Info.Type * 8; // Size is in terms of bits in this context.
1144 if (Size)
1145 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
1146 /*Len=*/0, Size));
1147 }
1148 }
11471149
11481150 // When parsing inline assembly we set the base register to a non-zero value
11491151 // if we don't know the actual value at this time. This is necessary to
12581260 if (getParser().parsePrimaryExpr(Val, End))
12591261 return ErrorOperand(Tok.getLoc(), "Unexpected identifier!");
12601262 } else {
1261 if (X86Operand *Err = ParseIntelIdentifier(Val, Identifier, End))
1263 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1264 if (X86Operand *Err = ParseIntelIdentifier(Val, Identifier, Info, End))
12621265 return Err;
12631266 }
12641267 SM.onIdentifierExpr(Val, Identifier);
13491352 End, Size);
13501353 }
13511354
1355 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
13521356 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1353 End, Size, SM.getSymName());
1357 End, Size, SM.getSymName(), Info);
13541358 }
13551359
13561360 // Inline assembly may use variable names with namespace alias qualifiers.
13571361 X86Operand *X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
13581362 StringRef &Identifier,
1363 InlineAsmIdentifierInfo &Info,
13591364 SMLoc &End) {
13601365 assert (isParsingInlineAsm() && "Expected to be parsing inline assembly.");
13611366 Val = 0;
13621367
1363 bool Done = false;
1368 StringRef LineBuf(Identifier.data());
1369 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info);
1370 unsigned BufLen = LineBuf.size();
1371 assert (BufLen && "Expected a non-zero length identifier.");
1372
1373 // Advance the token stream based on what the frontend parsed.
13641374 const AsmToken &Tok = Parser.getTok();
13651375 AsmToken IdentEnd = Tok;
1366 while (!Done) {
1367 switch (getLexer().getKind()) {
1368 default:
1369 Done = true;
1370 break;
1371 case AsmToken::Colon:
1372 IdentEnd = Tok;
1373 getLexer().Lex(); // Consume ':'.
1374 if (getLexer().isNot(AsmToken::Colon))
1375 return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1376 getLexer().Lex(); // Consume second ':'.
1377 if (getLexer().isNot(AsmToken::Identifier))
1378 return ErrorOperand(Tok.getLoc(), "Expected an identifier token!");
1379 break;
1380 case AsmToken::Identifier:
1381 IdentEnd = Tok;
1382 getLexer().Lex(); // Consume the identifier.
1383 break;
1384 }
1385 }
1376 while (BufLen > 0) {
1377 IdentEnd = Tok;
1378 BufLen -= Tok.getString().size();
1379 getLexer().Lex(); // Consume the token.
1380 }
1381 if (BufLen != 0)
1382 return ErrorOperand(IdentEnd.getLoc(),
1383 "Frontend parser mismatch with asm lexer!");
13861384 End = IdentEnd.getEndLoc();
1387 unsigned Len = IdentEnd.getLoc().getPointer() - Identifier.data();
1388 Identifier = StringRef(Identifier.data(), Len + IdentEnd.getString().size());
1385
1386 // Create the symbol reference.
1387 Identifier = LineBuf;
13891388 MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
13901389 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
13911390 Val = MCSymbolRefExpr::Create(Sym, Variant, getParser().getContext());
14401439 return X86Operand::CreateMem(Val, Start, End, Size);
14411440 }
14421441
1442 InlineAsmIdentifierInfo Info;
14431443 StringRef Identifier = Tok.getString();
1444 if (X86Operand *Err = ParseIntelIdentifier(Val, Identifier, End))
1444 if (X86Operand *Err = ParseIntelIdentifier(Val, Identifier, Info, End))
14451445 return Err;
14461446 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
1447 /*Scale=*/1, Start, End, Size, Identifier);
1447 /*Scale=*/1, Start, End, Size, Identifier, Info);
14481448 }
14491449
14501450 /// Parse the '.' operator.
14971497 Parser.Lex(); // Eat offset.
14981498
14991499 const MCExpr *Val;
1500 InlineAsmIdentifierInfo Info;
15001501 SMLoc Start = Tok.getLoc(), End;
15011502 StringRef Identifier = Tok.getString();
1502 if (X86Operand *Err = ParseIntelIdentifier(Val, Identifier, End))
1503 if (X86Operand *Err = ParseIntelIdentifier(Val, Identifier, Info, End))
15031504 return Err;
15041505
15051506 // Don't emit the offset operator.
15311532 Parser.Lex(); // Eat operator.
15321533
15331534 const MCExpr *Val = 0;
1535 InlineAsmIdentifierInfo Info;
15341536 SMLoc Start = Tok.getLoc(), End;
15351537 StringRef Identifier = Tok.getString();
1536 if (X86Operand *Err = ParseIntelIdentifier(Val, Identifier, End))
1538 if (X86Operand *Err = ParseIntelIdentifier(Val, Identifier, Info, End))
15371539 return Err;
15381540
15391541 unsigned CVal = 0;
1540 if (const MCSymbolRefExpr *SymRef = dyn_cast(Val)) {
1541 const MCSymbol &Sym = SymRef->getSymbol();
1542 StringRef SymName = Sym.getName();
1543 MCAsmParserSemaCallback::InlineAsmIdentifierInfo Info;
1544 SemaCallback->LookupInlineAsmIdentifier(SymName, Info);
1545
1546 switch(OpKind) {
1547 default: llvm_unreachable("Unexpected operand kind!");
1548 case IOK_LENGTH: CVal = Info.Length; break;
1549 case IOK_SIZE: CVal = Info.Size; break;
1550 case IOK_TYPE: CVal = Info.Type; break;
1551 }
1552 } else
1553 return ErrorOperand(Start, "Expected a MCSymbolRefExpr!");
1542 switch(OpKind) {
1543 default: llvm_unreachable("Unexpected operand kind!");
1544 case IOK_LENGTH: CVal = Info.Length; break;
1545 case IOK_SIZE: CVal = Info.Size; break;
1546 case IOK_TYPE: CVal = Info.Type; break;
1547 }
15541548
15551549 // Rewrite the type operator and the C or C++ type or variable in terms of an
15561550 // immediate. E.g. TYPE foo -> $$4