mirror of https://github.com/microsoft/clang.git
Add support for nested blocks in Microsoft inline assembly
This fixes http://llvm.org/PR20204. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@212389 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1088db3c87
commit
eb5c8705ec
|
@ -322,19 +322,21 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
|
|||
SourceLocation EndLoc = AsmLoc;
|
||||
SmallVector<Token, 4> AsmToks;
|
||||
|
||||
bool InBraces = false;
|
||||
unsigned BraceNesting = 0;
|
||||
unsigned short savedBraceCount = 0;
|
||||
bool InAsmComment = false;
|
||||
FileID FID;
|
||||
unsigned LineNo = 0;
|
||||
unsigned NumTokensRead = 0;
|
||||
SourceLocation LBraceLoc;
|
||||
SmallVector<SourceLocation, 4> LBraceLocs;
|
||||
bool SkippedStartOfLine = false;
|
||||
|
||||
if (Tok.is(tok::l_brace)) {
|
||||
// Braced inline asm: consume the opening brace.
|
||||
InBraces = true;
|
||||
BraceNesting = 1;
|
||||
savedBraceCount = BraceCount;
|
||||
EndLoc = LBraceLoc = ConsumeBrace();
|
||||
EndLoc = ConsumeBrace();
|
||||
LBraceLocs.push_back(EndLoc);
|
||||
++NumTokensRead;
|
||||
} else {
|
||||
// Single-line inline asm; compute which line it is on.
|
||||
|
@ -342,6 +344,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
|
|||
SrcMgr.getDecomposedExpansionLoc(EndLoc);
|
||||
FID = ExpAsmLoc.first;
|
||||
LineNo = SrcMgr.getLineNumber(FID, ExpAsmLoc.second);
|
||||
LBraceLocs.push_back(SourceLocation());
|
||||
}
|
||||
|
||||
SourceLocation TokLoc = Tok.getLocation();
|
||||
|
@ -350,17 +353,26 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
|
|||
if (isEofOrEom())
|
||||
break;
|
||||
|
||||
if (!InAsmComment && Tok.is(tok::semi)) {
|
||||
if (!InAsmComment && Tok.is(tok::l_brace)) {
|
||||
// Consume the opening brace.
|
||||
SkippedStartOfLine = Tok.isAtStartOfLine();
|
||||
EndLoc = ConsumeBrace();
|
||||
BraceNesting++;
|
||||
LBraceLocs.push_back(EndLoc);
|
||||
TokLoc = Tok.getLocation();
|
||||
++NumTokensRead;
|
||||
continue;
|
||||
} else if (!InAsmComment && Tok.is(tok::semi)) {
|
||||
// A semicolon in an asm is the start of a comment.
|
||||
InAsmComment = true;
|
||||
if (InBraces) {
|
||||
if (BraceNesting) {
|
||||
// Compute which line the comment is on.
|
||||
std::pair<FileID, unsigned> ExpSemiLoc =
|
||||
SrcMgr.getDecomposedExpansionLoc(TokLoc);
|
||||
FID = ExpSemiLoc.first;
|
||||
LineNo = SrcMgr.getLineNumber(FID, ExpSemiLoc.second);
|
||||
}
|
||||
} else if (!InBraces || InAsmComment) {
|
||||
} else if (!BraceNesting || InAsmComment) {
|
||||
// If end-of-line is significant, check whether this token is on a
|
||||
// new line.
|
||||
std::pair<FileID, unsigned> ExpLoc =
|
||||
|
@ -368,7 +380,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
|
|||
if (ExpLoc.first != FID ||
|
||||
SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second) != LineNo) {
|
||||
// If this is a single-line __asm, we're done.
|
||||
if (!InBraces)
|
||||
if (!BraceNesting)
|
||||
break;
|
||||
// We're no longer in a comment.
|
||||
InAsmComment = false;
|
||||
|
@ -379,11 +391,21 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!InAsmComment && InBraces && Tok.is(tok::r_brace) &&
|
||||
BraceCount == (savedBraceCount + 1)) {
|
||||
// Consume the closing brace, and finish
|
||||
if (!InAsmComment && BraceNesting && Tok.is(tok::r_brace) &&
|
||||
BraceCount == (savedBraceCount + BraceNesting)) {
|
||||
// Consume the closing brace.
|
||||
SkippedStartOfLine = Tok.isAtStartOfLine();
|
||||
EndLoc = ConsumeBrace();
|
||||
break;
|
||||
BraceNesting--;
|
||||
// Finish if all of the opened braces in the inline asm section were consumed.
|
||||
if (BraceNesting == 0)
|
||||
break;
|
||||
else {
|
||||
LBraceLocs.pop_back();
|
||||
TokLoc = Tok.getLocation();
|
||||
++NumTokensRead;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Consume the next token; make sure we don't modify the brace count etc.
|
||||
|
@ -392,17 +414,25 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
|
|||
if (InAsmComment)
|
||||
PP.Lex(Tok);
|
||||
else {
|
||||
// Set the token as the start of line if we skipped the original start
|
||||
// of line token in case it was a nested brace.
|
||||
if (SkippedStartOfLine)
|
||||
Tok.setFlag(Token::StartOfLine);
|
||||
AsmToks.push_back(Tok);
|
||||
ConsumeAnyToken();
|
||||
}
|
||||
TokLoc = Tok.getLocation();
|
||||
++NumTokensRead;
|
||||
SkippedStartOfLine = false;
|
||||
} while (1);
|
||||
|
||||
if (InBraces && BraceCount != savedBraceCount) {
|
||||
if (BraceNesting && BraceCount != savedBraceCount) {
|
||||
// __asm without closing brace (this can happen at EOF).
|
||||
Diag(Tok, diag::err_expected) << tok::r_brace;
|
||||
Diag(LBraceLoc, diag::note_matching) << tok::l_brace;
|
||||
for (unsigned i = 0; i < BraceNesting; ++i) {
|
||||
Diag(Tok, diag::err_expected) << tok::r_brace;
|
||||
Diag(LBraceLocs.back(), diag::note_matching) << tok::l_brace;
|
||||
LBraceLocs.pop_back();
|
||||
}
|
||||
return StmtError();
|
||||
} else if (NumTokensRead == 0) {
|
||||
// Empty __asm.
|
||||
|
@ -431,10 +461,12 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
|
|||
Diag(AsmLoc, diag::err_msasm_unable_to_create_target) << Error;
|
||||
}
|
||||
|
||||
assert(!LBraceLocs.empty() && "Should have at least one location here");
|
||||
|
||||
// If we don't support assembly, or the assembly is empty, we don't
|
||||
// need to instantiate the AsmParser, etc.
|
||||
if (!TheTarget || AsmToks.empty()) {
|
||||
return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, StringRef(),
|
||||
return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLocs[0], AsmToks, StringRef(),
|
||||
/*NumOutputs*/ 0, /*NumInputs*/ 0,
|
||||
ConstraintRefs, ClobberRefs, Exprs, EndLoc);
|
||||
}
|
||||
|
@ -523,7 +555,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
|
|||
}
|
||||
|
||||
// FIXME: We should be passing source locations for better diagnostics.
|
||||
return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmStringIR,
|
||||
return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLocs[0], AsmToks, AsmStringIR,
|
||||
NumOutputs, NumInputs, ConstraintRefs,
|
||||
ClobberRefs, Exprs, EndLoc);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,9 @@ int t4() {
|
|||
foo.b = 2;
|
||||
__asm {
|
||||
lea ebx, foo
|
||||
mov eax, [ebx].foo.a
|
||||
{
|
||||
mov eax, [ebx].foo.a
|
||||
}
|
||||
mov [ebx].foo.b, ecx
|
||||
}
|
||||
return foo.b;
|
||||
|
|
|
@ -52,6 +52,11 @@ void t7() {
|
|||
__asm {
|
||||
int 0x2c ; } asm comments are fun! }{
|
||||
}
|
||||
__asm {
|
||||
{
|
||||
int 0x2c ; } asm comments are fun! }{
|
||||
}
|
||||
}
|
||||
__asm {}
|
||||
// CHECK: t7
|
||||
// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"()
|
||||
|
@ -73,8 +78,8 @@ int t8() {
|
|||
void t9() {
|
||||
__asm {
|
||||
push ebx
|
||||
mov ebx, 0x07
|
||||
pop ebx
|
||||
{ mov ebx, 0x07 }
|
||||
__asm { pop ebx }
|
||||
}
|
||||
// CHECK: t9
|
||||
// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
|
||||
|
@ -129,7 +134,7 @@ void t14() {
|
|||
unsigned i = 1, j = 2;
|
||||
__asm {
|
||||
.if 1
|
||||
mov eax, i
|
||||
{ mov eax, i }
|
||||
.else
|
||||
mov ebx, j
|
||||
.endif
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
// REQUIRES: x86-registered-target
|
||||
// RUN: %clang_cc1 %s -triple i386-apple-darwin10 -verify -fasm-blocks
|
||||
|
||||
int t_fail() { // expected-note {{to match this}}
|
||||
__asm
|
||||
{ // expected-note {{to match this}}
|
||||
{ // expected-note {{to match this}}
|
||||
{
|
||||
} // expected-error 3 {{expected}}
|
|
@ -34,6 +34,17 @@ void t8() {
|
|||
void t9() {
|
||||
__asm nop __asm nop ; __asm nop
|
||||
}
|
||||
void t10() {
|
||||
__asm {
|
||||
mov eax, 0
|
||||
__asm {
|
||||
mov eax, 1
|
||||
{
|
||||
mov eax, 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int t_fail() { // expected-note {{to match this}}
|
||||
__asm
|
||||
__asm { // expected-error 3 {{expected}} expected-note {{to match this}}
|
||||
|
|
Loading…
Reference in New Issue