diff options
author | Chad Rosier <mcrosier@apple.com> | 2012-06-12 19:03:42 +0000 |
---|---|---|
committer | Chad Rosier <mcrosier@apple.com> | 2012-06-12 19:03:42 +0000 |
commit | a01eddbd07aa7e864da14cae20ce772dfdd082fa (patch) | |
tree | 06cd613ae88d75862f8aebbba42fe02f52007069 /lib/Parse/ParseStmt.cpp | |
parent | 8c2467567f8adc6f13ad2c0372f79ba36123a11d (diff) |
[ms-inline-asm] Cleanup MS style inline assembly parsing.
Specifically, improve the handling of whitespace, stop saving tokens that are
in comments and fix the case where we have a comment followed by a closing brace
on the next line.
Unfortunately, there's no easy way of testing this code.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158367 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseStmt.cpp')
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 9f49ab59ce..dd5ccc2f5d 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -1626,6 +1626,41 @@ StmtResult Parser::ParseReturnStatement() { return Actions.ActOnReturnStmt(ReturnLoc, R.take()); } +// needSpaceAsmToken - This function handles whitespace around asm punctuation. +// Returns true if a space should be emitted. +static inline bool needSpaceAsmToken(Token currTok) { + static Token prevTok; + + // No need for space after prevToken. + switch(prevTok.getKind()) { + default: + break; + case tok::l_square: + case tok::r_square: + case tok::l_brace: + case tok::r_brace: + case tok::colon: + prevTok = currTok; + return false; + } + + // No need for a space before currToken. + switch(currTok.getKind()) { + default: + break; + case tok::l_square: + case tok::r_square: + case tok::l_brace: + case tok::r_brace: + case tok::comma: + case tok::colon: + prevTok = currTok; + return false; + } + prevTok = currTok; + return true; +} + /// ParseMicrosoftAsmStatement. When -fms-extensions/-fasm-blocks is enabled, /// this routine is called to collect the tokens for an MS asm statement. /// @@ -1703,22 +1738,23 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { // does MSVC do here? break; } - } else if (InBraces && Tok.is(tok::r_brace) && - BraceCount == savedBraceCount + 1) { + } + if (!InAsmComment && InBraces && Tok.is(tok::r_brace) && + BraceCount == (savedBraceCount + 1)) { // Consume the closing brace, and finish EndLoc = ConsumeBrace(); break; } - AsmToks.push_back(Tok); - // Consume the next token; make sure we don't modify the brace count etc. // if we are in a comment. EndLoc = TokLoc; if (InAsmComment) PP.Lex(Tok); - else + else { + AsmToks.push_back(Tok); ConsumeAnyToken(); + } TokLoc = Tok.getLocation(); ++NumTokensRead; } while (1); @@ -1747,14 +1783,15 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { SmallString<512> TokenBuf; TokenBuf.resize(512); unsigned AsmLineNum = 0; - for (unsigned i = 0, e = AsmToks.size(); i < e; i++) { + for (unsigned i = 0, e = AsmToks.size(); i < e; ++i) { const char *ThisTokBuf = &TokenBuf[0]; bool StringInvalid = false; unsigned ThisTokLen = Lexer::getSpelling(AsmToks[i], ThisTokBuf, PP.getSourceManager(), PP.getLangOpts(), &StringInvalid); - if (i && (!AsmLineNum || i != LineEnds[AsmLineNum-1])) - Asm += ' '; // FIXME: Too much whitespace around punctuation + if (i && (!AsmLineNum || i != LineEnds[AsmLineNum-1]) && + needSpaceAsmToken(AsmToks[i])) + Asm += ' '; Asm += StringRef(ThisTokBuf, ThisTokLen); if (i + 1 == LineEnds[AsmLineNum] && i + 1 != AsmToks.size()) { Asm += '\n'; @@ -1766,7 +1803,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { // (or possibly in addition to the) AsmString. Sema is going to interact with // MC to determine Constraints, Clobbers, etc., which would be simplest to // do with the tokens. - std::string AsmString = Asm.data(); + std::string AsmString = Asm.c_str(); return Actions.ActOnMSAsmStmt(AsmLoc, AsmString, EndLoc); } |