r212389 - Add support for nested blocks in Microsoft inline assembly
Ehsan Akhgari
ehsan.akhgari at gmail.com
Sat Jul 5 22:26:54 PDT 2014
Author: ehsan
Date: Sun Jul 6 00:26:54 2014
New Revision: 212389
URL: http://llvm.org/viewvc/llvm-project?rev=212389&view=rev
Log:
Add support for nested blocks in Microsoft inline assembly
This fixes http://llvm.org/PR20204.
Added:
cfe/trunk/test/Parser/ms-inline-asm-nested-braces.c
Modified:
cfe/trunk/lib/Parse/ParseStmtAsm.cpp
cfe/trunk/test/CodeGen/ms-inline-asm-64.c
cfe/trunk/test/CodeGen/ms-inline-asm.c
cfe/trunk/test/Parser/ms-inline-asm.c
Modified: cfe/trunk/lib/Parse/ParseStmtAsm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmtAsm.cpp?rev=212389&r1=212388&r2=212389&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmtAsm.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmtAsm.cpp Sun Jul 6 00:26:54 2014
@@ -322,19 +322,21 @@ StmtResult Parser::ParseMicrosoftAsmStat
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::ParseMicrosoftAsmStat
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::ParseMicrosoftAsmStat
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::ParseMicrosoftAsmStat
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::ParseMicrosoftAsmStat
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::ParseMicrosoftAsmStat
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::ParseMicrosoftAsmStat
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::ParseMicrosoftAsmStat
}
// 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);
}
Modified: cfe/trunk/test/CodeGen/ms-inline-asm-64.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-inline-asm-64.c?rev=212389&r1=212388&r2=212389&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/ms-inline-asm-64.c (original)
+++ cfe/trunk/test/CodeGen/ms-inline-asm-64.c Sun Jul 6 00:26:54 2014
@@ -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;
Modified: cfe/trunk/test/CodeGen/ms-inline-asm.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-inline-asm.c?rev=212389&r1=212388&r2=212389&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/ms-inline-asm.c (original)
+++ cfe/trunk/test/CodeGen/ms-inline-asm.c Sun Jul 6 00:26:54 2014
@@ -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
Added: cfe/trunk/test/Parser/ms-inline-asm-nested-braces.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/ms-inline-asm-nested-braces.c?rev=212389&view=auto
==============================================================================
--- cfe/trunk/test/Parser/ms-inline-asm-nested-braces.c (added)
+++ cfe/trunk/test/Parser/ms-inline-asm-nested-braces.c Sun Jul 6 00:26:54 2014
@@ -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}}
Modified: cfe/trunk/test/Parser/ms-inline-asm.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/ms-inline-asm.c?rev=212389&r1=212388&r2=212389&view=diff
==============================================================================
--- cfe/trunk/test/Parser/ms-inline-asm.c (original)
+++ cfe/trunk/test/Parser/ms-inline-asm.c Sun Jul 6 00:26:54 2014
@@ -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}}
More information about the cfe-commits
mailing list