Preserve address space information through member accesses, e.g.,
__attribute__((address_space(1))) struct {int arr[ 3 ]; } *p1;
... = p1->arr[2]; // load from address space 1
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76717 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 145a928..6ad2040 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -794,6 +794,7 @@
// Build the implicit member references to the field of the
// anonymous struct/union.
Expr *Result = BaseObjectExpr;
+ unsigned BaseAddrSpace = BaseObjectExpr->getType().getAddressSpace();
for (llvm::SmallVector<FieldDecl *, 4>::reverse_iterator
FI = AnonFields.rbegin(), FIEnd = AnonFields.rend();
FI != FIEnd; ++FI) {
@@ -803,6 +804,8 @@
= MemberType.getCVRQualifiers() | ExtraQuals;
MemberType = MemberType.getQualifiedType(combinedQualifiers);
}
+ if (BaseAddrSpace != MemberType.getAddressSpace())
+ MemberType = Context.getAddrSpaceQualType(MemberType, BaseAddrSpace);
MarkDeclarationReferenced(Loc, *FI);
Result = new (Context) MemberExpr(Result, BaseObjectIsPointer, *FI,
OpLoc, MemberType);
@@ -2175,16 +2178,18 @@
BaseExpr, OpLoc);
// Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref]
- // FIXME: Handle address space modifiers
QualType MemberType = FD->getType();
if (const ReferenceType *Ref = MemberType->getAsReferenceType())
MemberType = Ref->getPointeeType();
else {
+ unsigned BaseAddrSpace = BaseType.getAddressSpace();
unsigned combinedQualifiers =
MemberType.getCVRQualifiers() | BaseType.getCVRQualifiers();
if (FD->isMutable())
combinedQualifiers &= ~QualType::Const;
MemberType = MemberType.getQualifiedType(combinedQualifiers);
+ if (BaseAddrSpace != MemberType.getAddressSpace())
+ MemberType = Context.getAddrSpaceQualType(MemberType, BaseAddrSpace);
}
MarkDeclarationReferenced(MemberLoc, FD);