summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarina Yatsina <marina.yatsina@intel.com>2015-12-17 12:51:51 +0000
committerMarina Yatsina <marina.yatsina@intel.com>2015-12-17 12:51:51 +0000
commit71ebc691f66f7b407531d8899248995eadd8abac (patch)
tree72a37bd99902c67e9ded62dc7c0c202385553d2e
parenta0fbd39f83069bd3222fd0de05bc25726b2673c5 (diff)
downloadbcm5719-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.cpp66
-rw-r--r--clang/test/CodeGen/ms-inline-asm.c20
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}"()
}
OpenPOWER on IntegriCloud