diff options
author | Akira Hatanaka <ahatanaka@apple.com> | 2017-06-27 04:34:04 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@apple.com> | 2017-06-27 04:34:04 +0000 |
commit | 4b1c48441d8f094d5397a79482ba15dceb387b8c (patch) | |
tree | 995b6166bb83e531ea70247476217d36fe2f0eab /clang/lib/AST/ASTContext.cpp | |
parent | c9d9d7976a103e9551ff314323619890b54d4ab6 (diff) | |
download | bcm5719-llvm-4b1c48441d8f094d5397a79482ba15dceb387b8c.tar.gz bcm5719-llvm-4b1c48441d8f094d5397a79482ba15dceb387b8c.zip |
[CodeGen][ObjC] Fix GNU's encoding of bit-field ivars.
According to the documentation, when encoding a bit-field, GNU runtime
needs its starting position in addition to its type and size.
https://gcc.gnu.org/onlinedocs/gcc/Type-encoding.html
Prior to r297702, the starting position information was not being
encoded, which is incorrect, and after r297702, an assertion started to
fail because an ObjCIvarDecl was being passed to a function expecting a
FieldDecl.
This commit moves LookupFieldBitOffset to ASTContext and uses the
function to encode the starting position of bit-fields.
llvm-svn: 306364
Diffstat (limited to 'clang/lib/AST/ASTContext.cpp')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index fabfdc9ef7e..a2ff176df11 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -5990,9 +5990,19 @@ static void EncodeBitField(const ASTContext *Ctx, std::string& S, // compatibility with GCC, although providing it breaks anything that // actually uses runtime introspection and wants to work on both runtimes... if (Ctx->getLangOpts().ObjCRuntime.isGNUFamily()) { - const RecordDecl *RD = FD->getParent(); - const ASTRecordLayout &RL = Ctx->getASTRecordLayout(RD); - S += llvm::utostr(RL.getFieldOffset(FD->getFieldIndex())); + uint64_t Offset; + + if (const auto *IVD = dyn_cast<ObjCIvarDecl>(FD)) { + Offset = Ctx->lookupFieldBitOffset(IVD->getContainingInterface(), nullptr, + IVD); + } else { + const RecordDecl *RD = FD->getParent(); + const ASTRecordLayout &RL = Ctx->getASTRecordLayout(RD); + Offset = RL.getFieldOffset(FD->getFieldIndex()); + } + + S += llvm::utostr(Offset); + if (const EnumType *ET = T->getAs<EnumType>()) S += ObjCEncodingForEnumType(Ctx, ET); else { |