diff options
-rw-r--r-- | clang/lib/Sema/SemaStmtAsm.cpp | 27 | ||||
-rw-r--r-- | clang/test/CodeGen/ms-inline-asm.c | 8 | ||||
-rw-r--r-- | clang/test/CodeGen/ms-inline-asm.cpp | 16 |
3 files changed, 41 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index c182b35bfad..603f970dbc2 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -677,22 +677,33 @@ bool Sema::LookupInlineAsmField(StringRef Base, StringRef Member, SmallVector<StringRef, 2> Members; Member.split(Members, "."); - LookupResult BaseResult(*this, &Context.Idents.get(Base), SourceLocation(), - LookupOrdinaryName); + NamedDecl *FoundDecl = nullptr; - if (!LookupName(BaseResult, getCurScope())) - return true; - - if(!BaseResult.isSingleResult()) + // MS InlineAsm uses 'this' as a base + if (getLangOpts().CPlusPlus && Base.equals("this")) { + if (const Type *PT = getCurrentThisType().getTypePtrOrNull()) + FoundDecl = PT->getPointeeType()->getAsTagDecl(); + } else { + LookupResult BaseResult(*this, &Context.Idents.get(Base), SourceLocation(), + LookupOrdinaryName); + if (LookupName(BaseResult, getCurScope()) && BaseResult.isSingleResult()) + FoundDecl = BaseResult.getFoundDecl(); + } + + if (!FoundDecl) return true; - NamedDecl *FoundDecl = BaseResult.getFoundDecl(); + for (StringRef NextMember : Members) { const RecordType *RT = nullptr; if (VarDecl *VD = dyn_cast<VarDecl>(FoundDecl)) RT = VD->getType()->getAs<RecordType>(); else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(FoundDecl)) { MarkAnyDeclReferenced(TD->getLocation(), TD, /*OdrUse=*/false); - RT = TD->getUnderlyingType()->getAs<RecordType>(); + // MS InlineAsm often uses struct pointer aliases as a base + QualType QT = TD->getUnderlyingType(); + if (const auto *PT = QT->getAs<PointerType>()) + QT = PT->getPointeeType(); + RT = QT->getAs<RecordType>(); } else if (TypeDecl *TD = dyn_cast<TypeDecl>(FoundDecl)) RT = TD->getTypeForDecl()->getAs<RecordType>(); else if (FieldDecl *TD = dyn_cast<FieldDecl>(FoundDecl)) diff --git a/clang/test/CodeGen/ms-inline-asm.c b/clang/test/CodeGen/ms-inline-asm.c index 60dffb02b84..9f6852fd477 100644 --- a/clang/test/CodeGen/ms-inline-asm.c +++ b/clang/test/CodeGen/ms-inline-asm.c @@ -527,7 +527,7 @@ void cpuid() { typedef struct { int a; int b; -} A; +} A, *pA; typedef struct { int b1; @@ -539,7 +539,7 @@ typedef struct { A c2; int c3; B c4; -} C; +} C, *pC; void t39() { // CHECK-LABEL: define void @t39 @@ -547,6 +547,8 @@ void t39() { // CHECK: mov eax, [eax].4 __asm mov eax, [eax] A.b // CHECK: mov eax, [eax] .4 + __asm mov eax, [eax] pA.b +// CHECK: mov eax, [eax] .4 __asm mov eax, fs:[0] A.b // CHECK: mov eax, fs:[$$0] .4 __asm mov eax, [eax].B.b2.a @@ -557,6 +559,8 @@ void t39() { // CHECK: mov eax, fs:[$$0] .8 __asm mov eax, [eax]C.c4.b2.b // CHECK: mov eax, [eax].24 + __asm mov eax, [eax]pC.c4.b2.b +// CHECK: mov eax, [eax].24 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"() } diff --git a/clang/test/CodeGen/ms-inline-asm.cpp b/clang/test/CodeGen/ms-inline-asm.cpp index a435e4b826d..094e34aed2f 100644 --- a/clang/test/CodeGen/ms-inline-asm.cpp +++ b/clang/test/CodeGen/ms-inline-asm.cpp @@ -180,3 +180,19 @@ void t8() { A::g(); } +void t9() { + // CHECK-LABEL: define void @_Z2t9v() + struct A { + int a; + int b; + void g() { + __asm mov eax, dword ptr [eax]this.b + // CHECK: call void asm sideeffect inteldialect + // CHECK-SAME: mov eax, dword ptr [eax].4 + // CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"() + } + }; + A AA; + AA.g(); +} + |