/// in the environment.
StorageLocation *getThisPointeeStorageLocation() const;
- /// Creates a value appropriate for `Type`, assigns it to `Loc`, and returns
- /// it, if `Type` is supported, otherwise return null. If `Type` is a pointer
- /// or reference type, creates all the necessary storage locations and values
- /// for indirections until it finds a non-pointer/non-reference type.
+ /// Creates a value appropriate for `Type`, if `Type` is supported, otherwise
+ /// return null. If `Type` is a pointer or reference type, creates all the
+ /// necessary storage locations and values for indirections until it finds a
+ /// non-pointer/non-reference type.
///
/// Requirements:
///
/// `Type` must not be null.
- Value *initValueInStorageLocation(const StorageLocation &Loc, QualType Type);
+ Value *createValue(QualType Type);
/// Assigns `Val` as the value of `Loc` in the environment.
void setValue(const StorageLocation &Loc, Value &Val);
Value &takeOwnership(std::unique_ptr<Value> Val);
private:
- /// Returns the value assigned to `Loc` in the environment or null if `Type`
- /// isn't supported.
+ /// Creates a value appropriate for `Type`, if `Type` is supported, otherwise
+ /// return null.
///
/// Recursively initializes storage locations and values until it sees a
/// self-referential pointer or reference type. `Visited` is used to track
/// Requirements:
///
/// `Type` must not be null.
- Value *initValueInStorageLocationUnlessSelfReferential(
- const StorageLocation &Loc, QualType Type,
- llvm::DenseSet<QualType> &Visited);
+ Value *createValueUnlessSelfReferential(QualType Type,
+ llvm::DenseSet<QualType> &Visited);
StorageLocation &skip(StorageLocation &Loc, SkipPast SP) const;
const StorageLocation &skip(const StorageLocation &Loc, SkipPast SP) const;
assert(ParamDecl != nullptr);
auto &ParamLoc = createStorageLocation(*ParamDecl);
setStorageLocation(*ParamDecl, ParamLoc);
- initValueInStorageLocation(ParamLoc, ParamDecl->getType());
+ if (Value *ParamVal = createValue(ParamDecl->getType()))
+ setValue(ParamLoc, *ParamVal);
}
}
if (!ThisPointeeType->isUnionType()) {
auto &ThisPointeeLoc = createStorageLocation(ThisPointeeType);
DACtx.setThisPointeeStorageLocation(ThisPointeeLoc);
- initValueInStorageLocation(ThisPointeeLoc, ThisPointeeType);
+ if (Value *ThisPointeeVal = createValue(ThisPointeeType))
+ setValue(ThisPointeeLoc, *ThisPointeeVal);
}
}
}
return getValue(*Loc);
}
-Value *Environment::initValueInStorageLocation(const StorageLocation &Loc,
- QualType Type) {
+Value *Environment::createValue(QualType Type) {
llvm::DenseSet<QualType> Visited;
- return initValueInStorageLocationUnlessSelfReferential(Loc, Type, Visited);
+ return createValueUnlessSelfReferential(Type, Visited);
}
-Value *Environment::initValueInStorageLocationUnlessSelfReferential(
- const StorageLocation &Loc, QualType Type,
- llvm::DenseSet<QualType> &Visited) {
+Value *Environment::createValueUnlessSelfReferential(
+ QualType Type, llvm::DenseSet<QualType> &Visited) {
assert(!Type.isNull());
if (Type->isIntegerType()) {
- auto &Val = takeOwnership(std::make_unique<IntegerValue>());
- setValue(Loc, Val);
- return &Val;
+ return &takeOwnership(std::make_unique<IntegerValue>());
}
if (Type->isReferenceType()) {
if (!Visited.contains(PointeeType.getCanonicalType())) {
Visited.insert(PointeeType.getCanonicalType());
- initValueInStorageLocationUnlessSelfReferential(PointeeLoc, PointeeType,
- Visited);
+ Value *PointeeVal =
+ createValueUnlessSelfReferential(PointeeType, Visited);
Visited.erase(PointeeType.getCanonicalType());
+
+ if (PointeeVal != nullptr)
+ setValue(PointeeLoc, *PointeeVal);
}
- auto &Val = takeOwnership(std::make_unique<ReferenceValue>(PointeeLoc));
- setValue(Loc, Val);
- return &Val;
+ return &takeOwnership(std::make_unique<ReferenceValue>(PointeeLoc));
}
if (Type->isPointerType()) {
if (!Visited.contains(PointeeType.getCanonicalType())) {
Visited.insert(PointeeType.getCanonicalType());
- initValueInStorageLocationUnlessSelfReferential(PointeeLoc, PointeeType,
- Visited);
+ Value *PointeeVal =
+ createValueUnlessSelfReferential(PointeeType, Visited);
Visited.erase(PointeeType.getCanonicalType());
+
+ if (PointeeVal != nullptr)
+ setValue(PointeeLoc, *PointeeVal);
}
- auto &Val = takeOwnership(std::make_unique<PointerValue>(PointeeLoc));
- setValue(Loc, Val);
- return &Val;
+ return &takeOwnership(std::make_unique<PointerValue>(PointeeLoc));
}
if (Type->isStructureOrClassType()) {
- auto *AggregateLoc = cast<AggregateStorageLocation>(&Loc);
-
// FIXME: Initialize only fields that are accessed in the context that is
// being analyzed.
llvm::DenseMap<const ValueDecl *, Value *> FieldValues;
Visited.insert(FieldType.getCanonicalType());
FieldValues.insert(
- {Field, initValueInStorageLocationUnlessSelfReferential(
- AggregateLoc->getChild(*Field), FieldType, Visited)});
+ {Field, createValueUnlessSelfReferential(FieldType, Visited)});
Visited.erase(FieldType.getCanonicalType());
}
- auto &Val =
- takeOwnership(std::make_unique<StructValue>(std::move(FieldValues)));
- setValue(Loc, Val);
- return &Val;
+ return &takeOwnership(
+ std::make_unique<StructValue>(std::move(FieldValues)));
}
return nullptr;
const Expr *InitExpr = D.getInit();
if (InitExpr == nullptr) {
// No initializer expression - associate `Loc` with a new value.
- Env.initValueInStorageLocation(Loc, D.getType());
+ if (Value *Val = Env.createValue(D.getType()))
+ Env.setValue(Loc, *Val);
return;
}
// FIXME: The initializer expression must always be assigned a value.
// Replace this with an assert when we have sufficient coverage of
// language features.
- Env.initValueInStorageLocation(Loc, D.getType());
+ if (Value *Val = Env.createValue(D.getType()))
+ Env.setValue(Loc, *Val);
}
return;
}
// FIXME: The initializer expression must always be assigned a value.
// Replace this with an assert when we have sufficient coverage of
// language features.
- Env.initValueInStorageLocation(Loc, D.getType());
+ if (Value *Val = Env.createValue(D.getType()))
+ Env.setValue(Loc, *Val);
} else {
llvm_unreachable("structs and classes must always be assigned values");
}
auto &Loc = Env.createStorageLocation(*S);
Env.setStorageLocation(*S, Loc);
- Env.initValueInStorageLocation(Loc, S->getType());
+ if (Value *Val = Env.createValue(S->getType()))
+ Env.setValue(Loc, *Val);
}
void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *S) {
auto &Loc = Env.createStorageLocation(*S);
Env.setStorageLocation(*S, Loc);
- Env.initValueInStorageLocation(Loc, S->getType());
+ if (Value *Val = Env.createValue(S->getType()))
+ Env.setValue(Loc, *Val);
}
void VisitCallExpr(const CallExpr *S) {