diff options
author | Chad Rosier <mcrosier@apple.com> | 2012-08-15 21:03:27 +0000 |
---|---|---|
committer | Chad Rosier <mcrosier@apple.com> | 2012-08-15 21:03:27 +0000 |
commit | f37e4218bb40ed956f0ef1d2e5eee2b2c3aa20d2 (patch) | |
tree | 0cf93be1024300abf7efccf459d39b2503070eb2 /lib/Sema/SemaStmt.cpp | |
parent | 4e79fdfe22db1c982e8fdf8397fee426a8c57821 (diff) |
[ms-inline asm] MSVC parses multiple __asm statements on a single line as one
statement. For example,
if (x)
__asm out dx, ax __asm out dx, ax
results in a single inline asm statement (i.e., both "out dx, ax" statements are
predicated on if(x)).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161986 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 3d58a5d57f..2aabd9ee79 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -2777,12 +2777,21 @@ static void patchMSAsmStrings(Sema &SemaRef, bool &IsSimple, unsigned NumAsmStrings = 0; for (unsigned i = 0, e = AsmToks.size(); i != e; ++i) { + // Determine if this should be considered a new asm. + bool isNewAsm = i == 0 || AsmToks[i].isAtStartOfLine() || + AsmToks[i].is(tok::kw_asm); + // Emit the previous asm string. - if (i && AsmToks[i].isAtStartOfLine()) + if (i && isNewAsm) { AsmStrings[NumAsmStrings++] = Asm.c_str(); + if (AsmToks[i].is(tok::kw_asm)) { + ++i; // Skip __asm + assert (i != e && "Expected another token."); + } + } // Start a new asm string with the opcode. - if (i == 0 || AsmToks[i].isAtStartOfLine()) { + if (isNewAsm) { Asm = AsmToks[i].getIdentifierInfo()->getName().str(); continue; } @@ -2831,17 +2840,29 @@ static void patchMSAsmStrings(Sema &SemaRef, bool &IsSimple, // Build the unmodified MSAsmString. static std::string buildMSAsmString(Sema &SemaRef, - ArrayRef<Token> AsmToks) { + ArrayRef<Token> AsmToks) { assert (!AsmToks.empty() && "Didn't expect an empty AsmToks!"); SmallString<512> Asm; SmallString<512> TokenBuf; TokenBuf.resize(512); + for (unsigned i = 0, e = AsmToks.size(); i < e; ++i) { - bool StringInvalid = false; - if (i && AsmToks[i].isAtStartOfLine()) - Asm += '\n'; - else if (i && AsmToks[i].hasLeadingSpace()) + bool isNewAsm = i == 0 || AsmToks[i].isAtStartOfLine() || + AsmToks[i].is(tok::kw_asm); + + if (isNewAsm) { + if (i) + Asm += '\n'; + if (AsmToks[i].is(tok::kw_asm)) { + i++; // Skip __asm + assert (i != e && "Expected another token"); + } + } + + if (i && AsmToks[i].hasLeadingSpace() && !isNewAsm) Asm += ' '; + + bool StringInvalid = false; Asm += SemaRef.PP.getSpelling(AsmToks[i], TokenBuf, &StringInvalid); assert (!StringInvalid && "Expected valid string!"); } @@ -2876,7 +2897,7 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, // FIXME: Count this while parsing. unsigned NumAsmStrings = 0; for (unsigned i = 0, e = AsmToks.size(); i != e; ++i) - if (AsmToks[i].isAtStartOfLine()) + if (i == 0 || AsmToks[i].isAtStartOfLine() || AsmToks[i].is(tok::kw_asm)) ++NumAsmStrings; PatchedAsmStrings.resize(NumAsmStrings ? NumAsmStrings : 1); |