paulsemel created this revision. paulsemel added a reviewer: aaron.ballman.
This is an attempt for adding bitfield support to __builtin_dump_struct. Repository: rC Clang https://reviews.llvm.org/D47953 Files: lib/CodeGen/CGBuiltin.cpp Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -1170,6 +1170,7 @@ RecordDecl *RD = RT->getDecl()->getDefinition(); ASTContext &Ctx = RD->getASTContext(); const ASTRecordLayout &RL = Ctx.getASTRecordLayout(RD); + const CGRecordLayout &CGRL = CGF.getTypes().getCGRecordLayout(RD); std::string Pad = std::string(Lvl * 4, ' '); Value *GString = @@ -1208,7 +1209,7 @@ FieldPtr, CGF.ConvertType(Context.getPointerType(FD->getType()))); else FieldPtr = CGF.Builder.CreateStructGEP(CGF.ConvertType(RType), FieldPtr, - FD->getFieldIndex()); + CGRL.getLLVMFieldNo(FD)); GString = CGF.Builder.CreateGlobalStringPtr( llvm::Twine(Pad) @@ -1236,10 +1237,37 @@ ? Types[Context.VoidPtrTy] : Types[CanonicalType]; + if (FD->isBitField()) + FieldPtr = CGF.Builder.CreatePointerCast( + FieldPtr, CGF.ConvertType(Context.getPointerType(CanonicalType))); + Address FieldAddress = Address(FieldPtr, Align); FieldPtr = CGF.Builder.CreateLoad(FieldAddress); - // FIXME Need to handle bitfield here + if (FD->isBitField()) { + const CGBitFieldInfo &Info = CGRL.getBitFieldInfo(FD); + if (Info.IsSigned) { + unsigned HighBits = Info.StorageSize - Info.Offset - Info.Size; + if (HighBits) + FieldPtr = CGF.Builder.CreateShl(FieldPtr, HighBits); + if (Info.Offset + HighBits) + FieldPtr = CGF.Builder.CreateAShr(FieldPtr, Info.Offset + HighBits); + } else { + if (Info.Offset) + FieldPtr = CGF.Builder.CreateLShr(FieldPtr, Info.Offset); + if (static_cast<unsigned>(Info.Offset) + Info.Size < Info.StorageSize) + FieldPtr = CGF.Builder.CreateAnd( + FieldPtr, + ConstantInt::get( + CGF.ConvertType(CanonicalType), + llvm::APInt::getLowBitsSet( + CGF.CGM.getDataLayout().getTypeSizeInBits(CanonicalType), + Info.Size))); + } + FieldPtr = CGF.Builder.CreateIntCast( + FieldPtr, CGF.ConvertType(CanonicalType), Info.IsSigned); + } + GString = CGF.Builder.CreateGlobalStringPtr( Format.concat(llvm::Twine('\n')).str()); TmpRes = CGF.Builder.CreateCall(Func, {GString, FieldPtr});
Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -1170,6 +1170,7 @@ RecordDecl *RD = RT->getDecl()->getDefinition(); ASTContext &Ctx = RD->getASTContext(); const ASTRecordLayout &RL = Ctx.getASTRecordLayout(RD); + const CGRecordLayout &CGRL = CGF.getTypes().getCGRecordLayout(RD); std::string Pad = std::string(Lvl * 4, ' '); Value *GString = @@ -1208,7 +1209,7 @@ FieldPtr, CGF.ConvertType(Context.getPointerType(FD->getType()))); else FieldPtr = CGF.Builder.CreateStructGEP(CGF.ConvertType(RType), FieldPtr, - FD->getFieldIndex()); + CGRL.getLLVMFieldNo(FD)); GString = CGF.Builder.CreateGlobalStringPtr( llvm::Twine(Pad) @@ -1236,10 +1237,37 @@ ? Types[Context.VoidPtrTy] : Types[CanonicalType]; + if (FD->isBitField()) + FieldPtr = CGF.Builder.CreatePointerCast( + FieldPtr, CGF.ConvertType(Context.getPointerType(CanonicalType))); + Address FieldAddress = Address(FieldPtr, Align); FieldPtr = CGF.Builder.CreateLoad(FieldAddress); - // FIXME Need to handle bitfield here + if (FD->isBitField()) { + const CGBitFieldInfo &Info = CGRL.getBitFieldInfo(FD); + if (Info.IsSigned) { + unsigned HighBits = Info.StorageSize - Info.Offset - Info.Size; + if (HighBits) + FieldPtr = CGF.Builder.CreateShl(FieldPtr, HighBits); + if (Info.Offset + HighBits) + FieldPtr = CGF.Builder.CreateAShr(FieldPtr, Info.Offset + HighBits); + } else { + if (Info.Offset) + FieldPtr = CGF.Builder.CreateLShr(FieldPtr, Info.Offset); + if (static_cast<unsigned>(Info.Offset) + Info.Size < Info.StorageSize) + FieldPtr = CGF.Builder.CreateAnd( + FieldPtr, + ConstantInt::get( + CGF.ConvertType(CanonicalType), + llvm::APInt::getLowBitsSet( + CGF.CGM.getDataLayout().getTypeSizeInBits(CanonicalType), + Info.Size))); + } + FieldPtr = CGF.Builder.CreateIntCast( + FieldPtr, CGF.ConvertType(CanonicalType), Info.IsSigned); + } + GString = CGF.Builder.CreateGlobalStringPtr( Format.concat(llvm::Twine('\n')).str()); TmpRes = CGF.Builder.CreateCall(Func, {GString, FieldPtr});
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits