[clang][Serialization] Fix the serialization of ConstantExpr.
The serialization of ConstantExpr has currently a number of problems:
- Some fields are just not serialized (ConstantExprBits.APValueKind and
ConstantExprBits.IsImmediateInvocation).
- ASTStmtReader::VisitConstantExpr forgets to add the trailing APValue
to the list of objects to be destroyed when the APValue needs cleanup.
While we are at it, bring the serialization of ConstantExpr more in-line
with what is done with the other expressions by doing the following NFCs:
- Get rid of ConstantExpr::DefaultInit. It is better to not initialize
the fields of an empty ConstantExpr since this will allow msan to
detect if a field was not deserialized.
- Move the initialization of the fields of ConstantExpr to the constructor;
ConstantExpr::Create allocates the memory and ConstantExpr::ConstantExpr
is responsible for the initialization.
Review after commit since this is a straightforward mechanical fix
similar to the other serialization fixes.
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 3a3b7bd..b13d0df 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -548,16 +548,27 @@
void ASTStmtWriter::VisitConstantExpr(ConstantExpr *E) {
VisitExpr(E);
- Record.push_back(static_cast<uint64_t>(E->ConstantExprBits.ResultKind));
+ Record.push_back(E->ConstantExprBits.ResultKind);
+
+ Record.push_back(E->ConstantExprBits.APValueKind);
+ Record.push_back(E->ConstantExprBits.IsUnsigned);
+ Record.push_back(E->ConstantExprBits.BitWidth);
+ // HasCleanup not serialized since we can just query the APValue.
+ Record.push_back(E->ConstantExprBits.IsImmediateInvocation);
+
switch (E->ConstantExprBits.ResultKind) {
+ case ConstantExpr::RSK_None:
+ break;
case ConstantExpr::RSK_Int64:
Record.push_back(E->Int64Result());
- Record.push_back(E->ConstantExprBits.IsUnsigned |
- E->ConstantExprBits.BitWidth << 1);
break;
case ConstantExpr::RSK_APValue:
Record.AddAPValue(E->APValueResult());
+ break;
+ default:
+ llvm_unreachable("unexpected ResultKind!");
}
+
Record.AddStmt(E->getSubExpr());
Code = serialization::EXPR_CONSTANT;
}