aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@apple.com>2012-08-08 19:48:07 +0000
committerChad Rosier <mcrosier@apple.com>2012-08-08 19:48:07 +0000
commit62f22b87801882646418bae85111e565f7a53ddb (patch)
treec6b561e44f60d562e6626405c6ed058ee373099f
parentd24bf90ae72d7df5e0ef0a1d3dd2806462ec15b1 (diff)
[ms-inline asm] Refactor the logic to generate the AsmString into Sema. No
functional change intended. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161518 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/Stmt.h7
-rw-r--r--include/clang/Sema/Sema.h2
-rw-r--r--lib/AST/Stmt.cpp9
-rw-r--r--lib/Parse/ParseStmt.cpp61
-rw-r--r--lib/Sema/SemaStmt.cpp36
-rw-r--r--lib/Sema/TreeTransform.h11
6 files changed, 53 insertions, 73 deletions
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 1b5d45317d..5a082b7ecf 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -1627,13 +1627,16 @@ class MSAsmStmt : public Stmt {
bool IsVolatile;
unsigned NumAsmToks;
+ unsigned NumLineEnds;
Token *AsmToks;
+ unsigned *LineEnds;
Stmt **Exprs;
public:
MSAsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple,
- bool isvolatile, ArrayRef<Token> asmtoks, std::string &asmstr,
+ bool isvolatile, ArrayRef<Token> asmtoks,
+ ArrayRef<unsigned> lineends, std::string &asmstr,
SourceLocation endloc);
SourceLocation getAsmLoc() const { return AsmLoc; }
@@ -1643,6 +1646,8 @@ public:
unsigned getNumAsmToks() { return NumAsmToks; }
Token *getAsmToks() { return AsmToks; }
+ unsigned getNumLineEnds() { return NumLineEnds; }
+ unsigned *getLineEnds() { return LineEnds; }
bool isVolatile() const { return IsVolatile; }
void setVolatile(bool V) { IsVolatile = V; }
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 2dacdd74f6..fe8d297db0 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -2544,7 +2544,7 @@ public:
StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc,
ArrayRef<Token> AsmToks,
- std::string &AsmString,
+ ArrayRef<unsigned> LineEnds,
SourceLocation EndLoc);
VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType,
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index 2894720b76..e5ff75eac6 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -585,14 +585,19 @@ AsmStmt::AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple,
MSAsmStmt::MSAsmStmt(ASTContext &C, SourceLocation asmloc,
bool issimple, bool isvolatile, ArrayRef<Token> asmtoks,
- std::string &asmstr, SourceLocation endloc)
+ ArrayRef<unsigned> lineends, std::string &asmstr,
+ SourceLocation endloc)
: Stmt(MSAsmStmtClass), AsmLoc(asmloc), EndLoc(endloc),
AsmStr(asmstr), IsSimple(issimple), IsVolatile(isvolatile),
- NumAsmToks(asmtoks.size()) {
+ NumAsmToks(asmtoks.size()), NumLineEnds(lineends.size()) {
AsmToks = new (C) Token[NumAsmToks];
for (unsigned i = 0, e = NumAsmToks; i != e; ++i)
AsmToks[i] = asmtoks[i];
+
+ LineEnds = new (C) unsigned[NumLineEnds];
+ for (unsigned i = 0, e = NumLineEnds; i != e; ++i)
+ LineEnds[i] = lineends[i];
}
ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect,
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 56e87e4904..d2e4309c3f 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -1638,41 +1638,6 @@ 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.
///
@@ -1795,31 +1760,9 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
EndLoc = ConsumeToken();
} while (1);
- // 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, PP.getSourceManager(),
- PP.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;
- }
- }
-
// FIXME: We should be passing source locations for better diagnostics.
- std::string AsmString = Asm.c_str();
- return Actions.ActOnMSAsmStmt(AsmLoc, llvm::makeArrayRef(AsmToks), AsmString,
- EndLoc);
+ return Actions.ActOnMSAsmStmt(AsmLoc, llvm::makeArrayRef(AsmToks),
+ llvm::makeArrayRef(LineEnds), EndLoc);
}
/// ParseAsmStatement - Parse a GNU extended asm statement.
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 80f58b90c3..a8a06a93fc 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -2749,9 +2749,6 @@ StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, bool IsSimple,
// 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 @@ static std::string PatchMSAsmString(Sema &SemaRef, bool &IsSimple,
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 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc,
MSAsmStmt *NS =
new (Context) MSAsmStmt(Context, AsmLoc, IsSimple, /* IsVolatile */ true,
- AsmToks, AsmString, EndLoc);
+ AsmToks, LineEnds, AsmString, EndLoc);
return Owned(NS);
}
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 6b211b09a1..90d5840378 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -1186,9 +1186,9 @@ public:
/// 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 @@ StmtResult
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());
}