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))
typedef struct {
int a;
int b;
-} A;
+} A, *pA;
typedef struct {
int b1;
A c2;
int c3;
B c4;
-} C;
+} C, *pC;
void t39() {
// CHECK-LABEL: define 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
// 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}"()
}
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();
+}
+