diff options
author | martinboehme <mboehme@google.com> | 2024-03-28 10:12:45 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-28 10:12:45 +0100 |
commit | 8d77d362af6ade32f087c051fe4774a3891f6ec9 (patch) | |
tree | 25ced265f1deb4b1eb2b41df3ac7e6dc539dfc91 /clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp | |
parent | eff4593a642692deb2b76d9d144ad5611bb69e08 (diff) | |
download | llvm-8d77d362af6ade32f087c051fe4774a3891f6ec9.zip llvm-8d77d362af6ade32f087c051fe4774a3891f6ec9.tar.gz llvm-8d77d362af6ade32f087c051fe4774a3891f6ec9.tar.bz2 |
[clang][dataflow] Introduce a helper class for handling record initializer lists. (#86675)
This is currently only used in one place, but I'm working on a patch
that will
use this from a second place. And I think this already improves the
readability
of the one place this is used so far.
Diffstat (limited to 'clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp')
-rw-r--r-- | clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index 70e0623..f729d67 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -1169,6 +1169,42 @@ getFieldsForInitListExpr(const InitListExpr *InitList) { return Fields; } +RecordInitListHelper::RecordInitListHelper(const InitListExpr *InitList) { + auto *RD = InitList->getType()->getAsCXXRecordDecl(); + assert(RD != nullptr); + + std::vector<const FieldDecl *> Fields = getFieldsForInitListExpr(InitList); + ArrayRef<Expr *> Inits = InitList->inits(); + + // Unions initialized with an empty initializer list need special treatment. + // For structs/classes initialized with an empty initializer list, Clang + // puts `ImplicitValueInitExpr`s in `InitListExpr::inits()`, but for unions, + // it doesn't do this -- so we create an `ImplicitValueInitExpr` ourselves. + SmallVector<Expr *> InitsForUnion; + if (InitList->getType()->isUnionType() && Inits.empty()) { + assert(Fields.size() == 1); + ImplicitValueInitForUnion.emplace(Fields.front()->getType()); + InitsForUnion.push_back(&*ImplicitValueInitForUnion); + Inits = InitsForUnion; + } + + size_t InitIdx = 0; + + assert(Fields.size() + RD->getNumBases() == Inits.size()); + for (const CXXBaseSpecifier &Base : RD->bases()) { + assert(InitIdx < Inits.size()); + Expr *Init = Inits[InitIdx++]; + BaseInits.emplace_back(&Base, Init); + } + + assert(Fields.size() == Inits.size() - InitIdx); + for (const FieldDecl *Field : Fields) { + assert(InitIdx < Inits.size()); + Expr *Init = Inits[InitIdx++]; + FieldInits.emplace_back(Field, Init); + } +} + RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env) { auto &NewVal = Env.create<RecordValue>(Loc); Env.setValue(Loc, NewVal); |