21 #include "llvm/Support/Casting.h" 22 #include "llvm/Support/raw_ostream.h" 48 if (
const auto *TR = dyn_cast<TypedRegion>(MR))
51 if (
const auto *SR = dyn_cast<SymbolicRegion>(MR)) {
61 return State->get<DynamicTypeMap>(MR);
68 const auto *Lookup = State->get<DynamicCastMap>().lookup(MR);
73 if (
Cast.equals(CastFromTy, CastToTy))
81 State = State->set<DynamicTypeMap>(MR->
StripCasts(), NewTy);
87 QualType NewTy,
bool CanBeSubClassed) {
101 "DynamicTypeInfo should always be a pointer.");
102 State = State->set<DynamicTypeMap>(MR, CastToTy);
106 CastSucceeds ? DynamicCastInfo::CastResult::Success
107 : DynamicCastInfo::CastResult::Failure;
109 CastSet::Factory &F = State->get_context<CastSet>();
111 const CastSet *TempSet = State->get<DynamicCastMap>(MR);
112 CastSet Set = TempSet ? *TempSet : F.getEmptySet();
114 Set = F.add(Set, {CastFromTy, CastToTy, ResultKind});
115 State = State->set<DynamicCastMap>(MR, Set);
121 template <
typename MapTy>
124 for (
const auto &Elem : Map)
126 State = State->remove<DynamicCastMap>(Elem.first);
132 return removeDead(State, State->get<DynamicTypeMap>(), SR);
136 return removeDead(State, State->get<DynamicCastMap>(), SR);
140 const char *NL,
unsigned int Space,
142 Indent(Out, Space, IsDot) <<
"\"dynamic_types\": ";
144 const DynamicTypeMapTy &Map = State->get<DynamicTypeMap>();
146 Out <<
"null," << NL;
152 for (DynamicTypeMapTy::iterator I = Map.begin(); I != Map.end(); ++I) {
156 <<
"{ \"region\": \"" << MR <<
"\", \"dyn_type\": ";
161 <<
"\", \"sub_classable\": " 166 if (std::next(I) != Map.end())
172 Indent(Out, Space, IsDot) <<
"]," << NL;
176 const char *NL,
unsigned int Space,
178 Indent(Out, Space, IsDot) <<
"\"dynamic_casts\": ";
180 const DynamicCastMapTy &Map = State->get<DynamicCastMap>();
182 Out <<
"null," << NL;
188 for (DynamicCastMapTy::iterator I = Map.begin(); I != Map.end(); ++I) {
190 const CastSet &Set = I->second;
192 Indent(Out, Space, IsDot) <<
"{ \"region\": \"" << MR <<
"\", \"casts\": ";
198 for (CastSet::iterator SI = Set.begin(); SI != Set.end(); ++SI) {
200 <<
"{ \"from\": \"" << SI->from().getAsString() <<
"\", \"to\": \"" 201 << SI->to().getAsString() <<
"\", \"kind\": \"" 202 << (SI->succeeds() ?
"success" :
"fail") <<
"\" }";
204 if (std::next(SI) != Set.end())
209 Indent(Out, Space, IsDot) <<
']';
213 if (std::next(I) != Map.end())
219 Indent(Out, Space, IsDot) <<
"]," << NL;
223 const char *NL,
unsigned int Space,
bool IsDot) {
bool Cast(InterpState &S, CodePtr OpPC)
A (possibly-)qualified type.
MemRegion - The root abstract class for all memory regions.
static void printDynamicCastsJson(raw_ostream &Out, ProgramStateRef State, const char *NL, unsigned int Space, bool IsDot)
REGISTER_MAP_WITH_PROGRAMSTATE(DynamicTypeMap, const clang::ento::MemRegion *, clang::ento::DynamicTypeInfo) REGISTER_MAP_WITH_PROGRAMSTATE(DynamicCastMap
The GDM component containing the dynamic type info.
ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR, DynamicTypeInfo NewTy)
Set dynamic type information of the region; return the new state.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
llvm::DenseMap< Stmt *, Stmt * > MapTy
const DynamicCastInfo * getDynamicCastInfo(ProgramStateRef State, const MemRegion *MR, QualType CastFromTy, QualType CastToTy)
Get dynamic cast information from CastFromTy to CastToTy of MR.
static void printDynamicTypesJson(raw_ostream &Out, ProgramStateRef State, const char *NL, unsigned int Space, bool IsDot)
bool isValid() const
Returns true if the dynamic type info is available.
bool isReferenceType() const
bool isLiveRegion(const MemRegion *region)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
ProgramStateRef removeDeadCasts(ProgramStateRef State, SymbolReaper &SR)
Removes the dead cast informations from State.
QualType getType() const
Returns the currently inferred upper bound on the runtime type.
virtual QualType getType() const =0
ProgramStateRef removeDeadTypes(ProgramStateRef State, SymbolReaper &SR)
Removes the dead type informations from State.
bool canBeASubClass() const
Returns false if the type information is precise (the type 'DynTy' is the only type in the lattice)...
Stores the currently inferred strictest bound on the runtime type of a region in a given state along ...
const DynamicTypeInfo * getRawDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR)
Get raw dynamic type information for the region MR.
#define REGISTER_SET_FACTORY_WITH_PROGRAMSTATE(Name, Elem)
Declares an immutable set type Name and registers the factory for such sets in the program state...
bool isAnyPointerType() const
A class responsible for cleaning up unused symbols.
Dataflow Directional Tag Classes.
ProgramStateRef setDynamicTypeAndCastInfo(ProgramStateRef State, const MemRegion *MR, QualType CastFromTy, QualType CastToTy, bool IsCastSucceeds)
Set dynamic type and cast information of the region; return the new state.
ProgramStateRef removeDead(ProgramStateRef State, const MapTy &Map, SymbolReaper &SR)
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
DynamicTypeInfo getDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR)
Get dynamic type information for the region MR.
void printDynamicTypeInfoJson(raw_ostream &Out, ProgramStateRef State, const char *NL="\, unsigned int Space=0, bool IsDot=false)
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)