[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