]> granicus.if.org Git - clang/commitdiff
[ms-inline-asm] Handle dependent identifiers in inline asm
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 4 Jan 2016 23:51:15 +0000 (23:51 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 4 Jan 2016 23:51:15 +0000 (23:51 +0000)
Build up a dependent expression for MS-style inline assembly if the
identifier's type is dependent.

This fixes PR26001.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@256795 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaStmtAsm.cpp
test/CodeGenCXX/ms-inline-asm-fields.cpp

index 0d6e0f8e41b07ed4fbc7a20233640725ed366d2a..6eadf0d1da91e66940ff49972f2434cdf29c3f7f 100644 (file)
@@ -589,10 +589,8 @@ ExprResult Sema::LookupInlineAsmIdentifier(CXXScopeSpec &SS,
 
   QualType T = Result.get()->getType();
 
-  // For now, reject dependent types.
   if (T->isDependentType()) {
-    Diag(Id.getLocStart(), diag::err_asm_incomplete_type) << T;
-    return ExprError();
+    return Result;
   }
 
   // Any sort of function type is fine.
@@ -679,7 +677,18 @@ Sema::LookupInlineAsmVarDeclField(Expr *E, StringRef Member, unsigned &Offset,
                                   SourceLocation AsmLoc) {
   Info.clear();
 
-  const RecordType *RT = E->getType()->getAs<RecordType>();
+  QualType T = E->getType();
+  if (T->isDependentType()) {
+    DeclarationNameInfo NameInfo;
+    NameInfo.setLoc(AsmLoc);
+    NameInfo.setName(&Context.Idents.get(Member));
+    return CXXDependentScopeMemberExpr::Create(
+        Context, E, T, /*IsArrow=*/false, AsmLoc, NestedNameSpecifierLoc(),
+        SourceLocation(),
+        /*FirstQualifierInScope=*/nullptr, NameInfo, /*TemplateArgs=*/nullptr);
+  }
+
+  const RecordType *RT = T->getAs<RecordType>();
   // FIXME: Diagnose this as field access into a scalar type.
   if (!RT)
     return ExprResult();
index a78d511485aad082a92c0abd578ed96b3538a7e9..6f329330bda42a1d5108eac243d57a5d3ad8ff24 100644 (file)
@@ -29,3 +29,28 @@ extern "C" int test_namespace_global() {
   __asm mov eax, asdf::a_global.a3.b2
 }
 
+template <bool Signed>
+struct make_storage_type {
+  struct type {
+    struct B {
+      int a;
+      int x;
+    } b;
+  };
+};
+
+template <bool Signed>
+struct msvc_dcas_x86 {
+  typedef typename make_storage_type<Signed>::type storage_type;
+  void store() __asm("PR26001") {
+    storage_type p;
+    __asm mov edx, p.b.x;
+  }
+};
+
+template void msvc_dcas_x86<false>::store();
+// CHECK: define weak_odr void @"\01PR26001"(
+// CHECK: %[[P:.*]] = alloca %"struct.make_storage_type<false>::type", align 4
+// CHECK: %[[B:.*]] = getelementptr inbounds %"struct.make_storage_type<false>::type", %"struct.make_storage_type<false>::type"* %[[P]], i32 0, i32 0
+// CHECK: %[[X:.*]] = getelementptr inbounds %"struct.make_storage_type<false>::type::B", %"struct.make_storage_type<false>::type::B"* %[[B]], i32 0, i32 1
+// CHECK: call void asm sideeffect inteldialect "mov edx, dword ptr $0", "*m,~{edx},~{dirflag},~{fpsr},~{flags}"(i32* %[[X]])