aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@apple.com>2012-08-16 22:25:38 +0000
committerChad Rosier <mcrosier@apple.com>2012-08-16 22:25:38 +0000
commit700ce64db453624d2a3f2d34d25207c97b2b064f (patch)
tree67c0357ad3bd0a1647db84905394300d359d52c6
parentbc20bbb0bf90446a469848c658ca376832f43dc8 (diff)
[ms-inline asm] Add a helper function, isMSAsmKeyword().
These require special handling, which we don't currently handle. This is being put in place to ensure we don't do invalid symbol table lookups or try to parse invalid assembly. The test cases just makes sure the latter isn't happening. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162050 91177308-0d34-0410-b5e6-96231b3b80d8
-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])
+}