@@ -2044,7 +2044,7 @@ EmitCheckedMixedSignMultiply(CodeGenFunction &CGF, const clang::Expr *Op1,
2044
2044
}
2045
2045
2046
2046
static llvm::Value *dumpRecord(CodeGenFunction &CGF, QualType RType,
2047
- Value *&RecordPtr , CharUnits Align,
2047
+ LValue RecordLV , CharUnits Align,
2048
2048
llvm::FunctionCallee Func, int Lvl) {
2049
2049
ASTContext &Context = CGF.getContext();
2050
2050
RecordDecl *RD = RType->castAs<RecordType>()->getDecl()->getDefinition();
@@ -2077,47 +2077,60 @@ static llvm::Value *dumpRecord(CodeGenFunction &CGF, QualType RType,
2077
2077
}
2078
2078
2079
2079
for (const auto *FD : RD->fields()) {
2080
- Value *FieldPtr = RecordPtr;
2081
- if (RD->isUnion())
2082
- FieldPtr = CGF.Builder.CreatePointerCast(
2083
- FieldPtr, CGF.ConvertType(Context.getPointerType(FD->getType())));
2084
- else
2085
- FieldPtr = CGF.Builder.CreateStructGEP(CGF.ConvertType(RType), FieldPtr,
2086
- FD->getFieldIndex());
2087
-
2088
- GString = CGF.Builder.CreateGlobalStringPtr(
2089
- llvm::Twine(Pad)
2090
- .concat(FD->getType().getAsString())
2091
- .concat(llvm::Twine(' '))
2092
- .concat(FD->getNameAsString())
2093
- .concat(" : ")
2094
- .str());
2095
- Value *TmpRes = CGF.Builder.CreateCall(Func, {GString});
2096
- Res = CGF.Builder.CreateAdd(Res, TmpRes);
2080
+ Value *TmpRes = nullptr;
2081
+
2082
+ std::string Format = llvm::Twine(Pad)
2083
+ .concat(FD->getType().getAsString())
2084
+ .concat(llvm::Twine(' '))
2085
+ .concat(FD->getNameAsString())
2086
+ .str();
2087
+
2088
+ if (FD->isBitField()) {
2089
+ unsigned BitfieldWidth = FD->getBitWidthValue(CGF.getContext());
2090
+
2091
+ // If current field is a unnamed bitfield, we should dump only one ' '
2092
+ // between type-name and ':'
2093
+ if (!FD->getDeclName().isEmpty())
2094
+ Format += ' ';
2095
+ Format += llvm::Twine(": ").concat(llvm::Twine(BitfieldWidth)).str();
2096
+
2097
+ // If current field is a zero-width bitfield, we just dump a string like
2098
+ // 'type-name : 0'
2099
+ if (FD->isZeroSize(CGF.getContext())) {
2100
+ Format += "\n";
2101
+ GString = CGF.Builder.CreateGlobalStringPtr(Format);
2102
+ TmpRes = CGF.Builder.CreateCall(Func, {GString});
2103
+ Res = CGF.Builder.CreateAdd(Res, TmpRes);
2104
+ continue;
2105
+ }
2106
+ }
2097
2107
2108
+ LValue FieldLV = CGF.EmitLValueForField(RecordLV, FD);
2098
2109
QualType CanonicalType =
2099
2110
FD->getType().getUnqualifiedType().getCanonicalType();
2100
2111
2101
2112
// We check whether we are in a recursive type
2102
2113
if (CanonicalType->isRecordType()) {
2103
- TmpRes = dumpRecord(CGF, CanonicalType, FieldPtr , Align, Func, Lvl + 1);
2114
+ TmpRes = dumpRecord(CGF, CanonicalType, FieldLV , Align, Func, Lvl + 1);
2104
2115
Res = CGF.Builder.CreateAdd(TmpRes, Res);
2105
2116
continue;
2106
2117
}
2107
2118
2108
2119
// We try to determine the best format to print the current field
2109
- llvm::Twine Format = Types.find(CanonicalType) == Types.end()
2110
- ? Types[Context.VoidPtrTy]
2111
- : Types[CanonicalType];
2112
-
2113
- Address FieldAddress =
2114
- Address(FieldPtr, CGF.ConvertTypeForMem(FD->getType()), Align);
2115
- FieldPtr = CGF.Builder.CreateLoad(FieldAddress);
2116
-
2117
- // FIXME Need to handle bitfield here
2118
- GString = CGF.Builder.CreateGlobalStringPtr(
2119
- Format.concat(llvm::Twine('\n')).str());
2120
- TmpRes = CGF.Builder.CreateCall(Func, {GString, FieldPtr});
2120
+ const char *TypeFormat = Types.find(CanonicalType) == Types.end()
2121
+ ? Types[Context.VoidPtrTy]
2122
+ : Types[CanonicalType];
2123
+
2124
+ GString = CGF.Builder.CreateGlobalStringPtr(llvm::Twine(Format)
2125
+ .concat(" = ")
2126
+ .concat(TypeFormat)
2127
+ .concat(llvm::Twine('\n'))
2128
+ .str());
2129
+
2130
+ RValue RV = FD->isBitField()
2131
+ ? CGF.EmitLoadOfBitfieldLValue(FieldLV, FD->getLocation())
2132
+ : CGF.EmitLoadOfLValue(FieldLV, FD->getLocation());
2133
+ TmpRes = CGF.Builder.CreateCall(Func, {GString, RV.getScalarVal()});
2121
2134
Res = CGF.Builder.CreateAdd(Res, TmpRes);
2122
2135
}
2123
2136
@@ -2664,7 +2677,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
2664
2677
QualType Arg0Type = Arg0->getType()->getPointeeType();
2665
2678
2666
2679
Value *RecordPtr = EmitScalarExpr(Arg0);
2667
- Value *Res = dumpRecord(*this, Arg0Type, RecordPtr, Arg0Align,
2680
+ LValue RecordLV = MakeAddrLValue(RecordPtr, Arg0Type, Arg0Align);
2681
+ Value *Res = dumpRecord(*this, Arg0Type, RecordLV, Arg0Align,
2668
2682
{LLVMFuncType, Func}, 0);
2669
2683
return RValue::get(Res);
2670
2684
}
0 commit comments