[ms-inline asm] Refactor the logic to generate the AsmString into Sema. No
functional change intended.
llvm-svn: 161518
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 80f58b9..a8a06a9 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -2749,9 +2749,6 @@
// needSpaceAsmToken - This function handles whitespace around asm punctuation.
// Returns true if a space should be emitted.
-//
-// FIXME: This is replicated in ParseStmt.cpp. Maybe we should defer building
-// the AsmString (i.e., non-patched AsmString) until Sema.
static inline bool needSpaceAsmToken(Token currTok) {
static Token prevTok;
@@ -2840,13 +2837,42 @@
return Res;
}
+// Build the unmodified MSAsmString.
+static std::string buildMSAsmString(Sema &SemaRef,
+ ArrayRef<Token> AsmToks,
+ ArrayRef<unsigned> LineEnds) {
+ // Collect the tokens into a string
+ SmallString<512> Asm;
+ SmallString<512> TokenBuf;
+ TokenBuf.resize(512);
+ unsigned AsmLineNum = 0;
+ 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, SemaRef.getSourceManager(),
+ SemaRef.getLangOpts(), &StringInvalid);
+ 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';
+ ++AsmLineNum;
+ }
+ }
+ return Asm.c_str();
+}
+
StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc,
ArrayRef<Token> AsmToks,
- std::string &AsmString,
+ ArrayRef<unsigned> LineEnds,
SourceLocation EndLoc) {
// MS-style inline assembly is not fully supported, so emit a warning.
Diag(AsmLoc, diag::warn_unsupported_msasm);
+ std::string AsmString = buildMSAsmString(*this, AsmToks, LineEnds);
+
bool IsSimple;
// Rewrite operands to appease the AsmParser.
std::string PatchedAsmString =
@@ -2858,7 +2884,7 @@
MSAsmStmt *NS =
new (Context) MSAsmStmt(Context, AsmLoc, IsSimple, /* IsVolatile */ true,
- AsmToks, AsmString, EndLoc);
+ AsmToks, LineEnds, AsmString, EndLoc);
return Owned(NS);
}
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 6b211b0..90d5840 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -1186,9 +1186,9 @@
/// Subclasses may override this routine to provide different behavior.
StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc,
ArrayRef<Token> AsmToks,
- std::string &AsmString,
+ ArrayRef<unsigned> LineEnds,
SourceLocation EndLoc) {
- return getSema().ActOnMSAsmStmt(AsmLoc, AsmToks, AsmString, EndLoc);
+ return getSema().ActOnMSAsmStmt(AsmLoc, AsmToks, LineEnds, EndLoc);
}
/// \brief Build a new Objective-C \@try statement.
@@ -5612,10 +5612,11 @@
TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
ArrayRef<Token> AsmToks =
llvm::makeArrayRef(S->getAsmToks(), S->getNumAsmToks());
+ ArrayRef<unsigned> LineEnds =
+ llvm::makeArrayRef(S->getLineEnds(), S->getNumLineEnds());
+
// No need to transform the asm string literal.
- return getDerived().RebuildMSAsmStmt(S->getAsmLoc(),
- AsmToks,
- *S->getAsmString(),
+ return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), AsmToks, LineEnds,
S->getEndLoc());
}