aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseStmt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Parse/ParseStmt.cpp')
-rw-r--r--lib/Parse/ParseStmt.cpp55
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);
}