diff options
author | Marina Yatsina <marina.yatsina@intel.com> | 2015-12-17 12:51:51 +0000 |
---|---|---|
committer | Marina Yatsina <marina.yatsina@intel.com> | 2015-12-17 12:51:51 +0000 |
commit | 71ebc691f66f7b407531d8899248995eadd8abac (patch) | |
tree | 72a37bd99902c67e9ded62dc7c0c202385553d2e | |
parent | a0fbd39f83069bd3222fd0de05bc25726b2673c5 (diff) | |
download | bcm5719-llvm-71ebc691f66f7b407531d8899248995eadd8abac.tar.gz bcm5719-llvm-71ebc691f66f7b407531d8899248995eadd8abac.zip |
[ms-inline-asm] Add support for composite structs in MS inline asm
Add MS inline asm support for structs that contain fields that are also structs.
Differential Revision: http://reviews.llvm.org/D15578
llvm-svn: 255890
-rw-r--r-- | clang/lib/Sema/SemaStmtAsm.cpp | 66 | ||||
-rw-r--r-- | clang/test/CodeGen/ms-inline-asm.c | 20 |
2 files changed, 59 insertions, 27 deletions
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index bb6657b8031..6991fd999b1 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -617,45 +617,57 @@ ExprResult Sema::LookupInlineAsmIdentifier(CXXScopeSpec &SS, bool Sema::LookupInlineAsmField(StringRef Base, StringRef Member, unsigned &Offset, SourceLocation AsmLoc) { Offset = 0; + SmallVector<StringRef, 2> Members; + Member.split(Members, "."); + LookupResult BaseResult(*this, &Context.Idents.get(Base), SourceLocation(), LookupOrdinaryName); if (!LookupName(BaseResult, getCurScope())) return true; - if (!BaseResult.isSingleResult()) - return true; + LookupResult CurrBaseResult(BaseResult); - const RecordType *RT = nullptr; - NamedDecl *FoundDecl = BaseResult.getFoundDecl(); - 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>(); - } else if (TypeDecl *TD = dyn_cast<TypeDecl>(FoundDecl)) - RT = TD->getTypeForDecl()->getAs<RecordType>(); - if (!RT) - return true; + for (StringRef NextMember : Members) { - if (RequireCompleteType(AsmLoc, QualType(RT, 0), 0)) - return true; + if (!CurrBaseResult.isSingleResult()) + return true; - LookupResult FieldResult(*this, &Context.Idents.get(Member), SourceLocation(), - LookupMemberName); + const RecordType *RT = nullptr; + NamedDecl *FoundDecl = CurrBaseResult.getFoundDecl(); + 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>(); + } else if (TypeDecl *TD = dyn_cast<TypeDecl>(FoundDecl)) + RT = TD->getTypeForDecl()->getAs<RecordType>(); + else if (FieldDecl *TD = dyn_cast<FieldDecl>(FoundDecl)) + RT = TD->getType()->getAs<RecordType>(); + if (!RT) + return true; - if (!LookupQualifiedName(FieldResult, RT->getDecl())) - return true; + if (RequireCompleteType(AsmLoc, QualType(RT, 0), 0)) + return true; - // FIXME: Handle IndirectFieldDecl? - FieldDecl *FD = dyn_cast<FieldDecl>(FieldResult.getFoundDecl()); - if (!FD) - return true; + LookupResult FieldResult(*this, &Context.Idents.get(NextMember), + SourceLocation(), LookupMemberName); + + if (!LookupQualifiedName(FieldResult, RT->getDecl())) + return true; - const ASTRecordLayout &RL = Context.getASTRecordLayout(RT->getDecl()); - unsigned i = FD->getFieldIndex(); - CharUnits Result = Context.toCharUnitsFromBits(RL.getFieldOffset(i)); - Offset = (unsigned)Result.getQuantity(); + // FIXME: Handle IndirectFieldDecl? + FieldDecl *FD = dyn_cast<FieldDecl>(FieldResult.getFoundDecl()); + if (!FD) + return true; + + CurrBaseResult = FieldResult; + + const ASTRecordLayout &RL = Context.getASTRecordLayout(RT->getDecl()); + unsigned i = FD->getFieldIndex(); + CharUnits Result = Context.toCharUnitsFromBits(RL.getFieldOffset(i)); + Offset += (unsigned)Result.getQuantity(); + } return false; } diff --git a/clang/test/CodeGen/ms-inline-asm.c b/clang/test/CodeGen/ms-inline-asm.c index 36dac6e69e7..f530c37fc45 100644 --- a/clang/test/CodeGen/ms-inline-asm.c +++ b/clang/test/CodeGen/ms-inline-asm.c @@ -470,6 +470,18 @@ typedef struct { int b; } A; +typedef struct { + int b1; + A b2; +} B; + +typedef struct { + int c1; + A c2; + int c3; + B c4; +} C; + void t39() { // CHECK-LABEL: define void @t39 __asm mov eax, [eax].A.b @@ -478,6 +490,14 @@ void t39() { // 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, [eax].4 + __asm mov eax, [eax] B.b2.b +// CHECK: mov eax, [eax] .8 + __asm mov eax, fs:[0] C.c2.b +// CHECK: mov eax, fs:[$$0] .8 + __asm mov eax, [eax]C.c4.b2.b +// CHECK: mov eax, [eax].24 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"() } |