aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaStmt.cpp27
-rw-r--r--test/CodeGen/ms-inline-asm.c20
2 files changed, 46 insertions, 1 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 74d1c596ad..5493e343c6 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -2762,6 +2762,17 @@ StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, bool IsSimple,
return Owned(NS);
}
+// isMSAsmKeyword - Return true if this is an MS-style inline asm keyword. These
+// require special handling.
+static bool isMSAsmKeyword(StringRef Name) {
+ bool Ret = llvm::StringSwitch<bool>(Name)
+ .Cases("EVEN", "ALIGN", true) // Alignment directives.
+ .Cases("LENGTH", "SIZE", "TYPE", true) // Type and variable sizes.
+ .Case("_emit", true) // _emit Pseudoinstruction.
+ .Default(false);
+ return Ret;
+}
+
static void patchMSAsmStrings(Sema &SemaRef, bool &IsSimple,
SourceLocation AsmLoc,
ArrayRef<Token> AsmToks,
@@ -2795,7 +2806,14 @@ static void patchMSAsmStrings(Sema &SemaRef, bool &IsSimple,
if (isNewAsm) {
AsmRegs[NumAsmStrings].resize(AsmToks.size());
AsmNames[NumAsmStrings].resize(AsmToks.size());
- Asm = AsmToks[i].getIdentifierInfo()->getName().str();
+
+ StringRef Piece = AsmToks[i].getIdentifierInfo()->getName();
+ // MS-style inline asm keywords require special handling.
+ if (isMSAsmKeyword(Piece))
+ IsSimple = false;
+
+ // TODO: Verify this is a valid opcode.
+ Asm = Piece;
continue;
}
@@ -2834,6 +2852,13 @@ static void patchMSAsmStrings(Sema &SemaRef, bool &IsSimple,
IsSimple = false;
+ // MS-style inline asm keywords require special handling.
+ if (isMSAsmKeyword(Name)) {
+ IsSimple = false;
+ Asm += Name;
+ break;
+ }
+
// FIXME: Why are we missing this segment register?
if (Name == "fs") {
Asm += Name;
diff --git a/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c
index 310fbd1e00..c140d60551 100644
--- a/test/CodeGen/ms-inline-asm.c
+++ b/test/CodeGen/ms-inline-asm.c
@@ -98,3 +98,23 @@ unsigned t11(void) {
// CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32* [[J]], align 4
// CHECK: ret i32 [[RET]]
}
+
+void t12(void) {
+ __asm EVEN
+ __asm ALIGN
+}
+
+void t13(void) {
+ __asm {
+ _emit 0x4A
+ _emit 0x43
+ _emit 0x4B
+ }
+}
+
+void t14(void) {
+ unsigned arr[10];
+ __asm LENGTH arr ; sizeof(arr)/sizeof(arr[0])
+ __asm SIZE arr ; sizeof(arr)
+ __asm TYPE arr ; sizeof(arr[0])
+}