[cfe-commits] r161508 - /cfe/trunk/lib/Sema/SemaStmt.cpp
Chad Rosier
mcrosier at apple.com
Wed Aug 8 11:22:06 PDT 2012
Author: mcrosier
Date: Wed Aug 8 13:22:06 2012
New Revision: 161508
URL: http://llvm.org/viewvc/llvm-project?rev=161508&view=rev
Log:
[ms-inline asm] Add support for detecting simple ms-style inline asm. Simple
asm statements are those that don't reference variable names, function names,
and labels.
Add logic to generate a patched AsmString that will eventually be consumed by
the AsmParser. No functional change at this point, so unfortunately no test
case.
Modified:
cfe/trunk/lib/Sema/SemaStmt.cpp
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=161508&r1=161507&r2=161508&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Wed Aug 8 13:22:06 2012
@@ -2747,6 +2747,99 @@
return Owned(NS);
}
+// 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;
+
+ // 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;
+}
+
+static std::string PatchMSAsmString(Sema &SemaRef, bool &IsSimple,
+ SourceLocation AsmLoc,
+ ArrayRef<Token> AsmToks,
+ const TargetInfo &TI) {
+ std::string Res;
+ IdentifierInfo *II = AsmToks[0].getIdentifierInfo();
+ Res = II->getName().str();
+
+ // Assume simple asm stmt until we parse a non-register identifer.
+ IsSimple = true;
+
+ // Check the operands.
+ for (unsigned i = 1, e = AsmToks.size(); i != e; ++i) {
+ if (needSpaceAsmToken(AsmToks[i]))
+ Res += " ";
+
+ switch (AsmToks[i].getKind()) {
+ default:
+ //llvm_unreachable("Unknown token.");
+ break;
+ case tok::comma: Res += ","; break;
+ case tok::colon: Res += ":"; break;
+ case tok::l_square: Res += "["; break;
+ case tok::r_square: Res += "]"; break;
+ case tok::l_brace: Res += "{"; break;
+ case tok::r_brace: Res += "}"; break;
+ case tok::numeric_constant: {
+ SmallString<32> TokenBuf;
+ TokenBuf.resize(32);
+ bool StringInvalid = false;
+ const char *ThisTokBuf = &TokenBuf[0];
+ unsigned ThisTokLen =
+ Lexer::getSpelling(AsmToks[i], ThisTokBuf, SemaRef.getSourceManager(),
+ SemaRef.getLangOpts(), &StringInvalid);
+ Res += StringRef(ThisTokBuf, ThisTokLen);
+ break;
+ }
+ case tok::identifier: {
+ II = AsmToks[i].getIdentifierInfo();
+ StringRef Name = II->getName();
+
+ // Valid registers don't need modification.
+ if (TI.isValidGCCRegisterName(Name)) {
+ Res += Name;
+ break;
+ }
+
+ // TODO: Lookup the identifier.
+ IsSimple = false;
+ }
+ } // AsmToks[i].getKind()
+ }
+ return Res;
+}
+
StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc,
ArrayRef<Token> AsmToks,
std::string &AsmString,
@@ -2754,9 +2847,18 @@
// MS-style inline assembly is not fully supported, so emit a warning.
Diag(AsmLoc, diag::warn_unsupported_msasm);
+ bool IsSimple;
+ // Rewrite operands to appease the AsmParser.
+ std::string PatchedAsmString =
+ PatchMSAsmString(*this, IsSimple, AsmLoc, AsmToks, Context.getTargetInfo());
+
+ // Silence compiler warnings. Eventually, the PatchedAsmString will be
+ // passed to the AsmParser.
+ (void)PatchedAsmString;
+
MSAsmStmt *NS =
- new (Context) MSAsmStmt(Context, AsmLoc, true, true, AsmToks, AsmString,
- EndLoc);
+ new (Context) MSAsmStmt(Context, AsmLoc, IsSimple, /* IsVolatile */ true,
+ AsmToks, AsmString, EndLoc);
return Owned(NS);
}
More information about the cfe-commits
mailing list