19#include "llvm/ADT/StringMap.h"
21#define DEBUG_TYPE "dataflow"
28 assert(Field.getType()->isReferenceType() ||
29 (SrcFieldLoc !=
nullptr && DstFieldLoc !=
nullptr));
31 if (Field.getType()->isRecordType()) {
34 }
else if (Field.getType()->isReferenceType()) {
63 auto DstDecl = DstType->getAsCXXRecordDecl();
68 [[maybe_unused]]
bool CompatibleTypes =
70 (SrcDecl !=
nullptr && DstDecl !=
nullptr &&
71 (SrcDecl->isDerivedFrom(DstDecl) || DstDecl->isDerivedFrom(SrcDecl) ||
72 (DeclToCopy !=
nullptr && SrcDecl->
isDerivedFrom(DeclToCopy) &&
73 DstDecl->isDerivedFrom(DeclToCopy))));
76 if (!CompatibleTypes) {
77 llvm::dbgs() <<
"Source type " << Src.
getType() <<
"\n";
78 llvm::dbgs() <<
"Destination type " << Dst.
getType() <<
"\n";
81 assert(CompatibleTypes);
83 if (SrcType == DstType || (SrcDecl !=
nullptr && DstDecl !=
nullptr &&
84 SrcDecl->isDerivedFrom(DstDecl))) {
90 for (
auto [Field, DstFieldLoc] : Dst.
children())
91 if (
const auto *FieldAsFieldDecl = dyn_cast<FieldDecl>(Field);
92 FieldAsFieldDecl && FieldsInSrcType.contains(FieldAsFieldDecl))
94 const llvm::StringMap<QualType> SyntheticFieldsForSrcType =
97 if (SyntheticFieldsForSrcType.contains(Name))
100 }
else if (SrcDecl !=
nullptr && DstDecl !=
nullptr &&
101 DstDecl->isDerivedFrom(SrcDecl)) {
108 for (
auto [Field, SrcFieldLoc] : Src.
children()) {
109 if (
const auto *FieldAsFieldDecl = dyn_cast<FieldDecl>(Field);
110 FieldAsFieldDecl && FieldsInDstType.contains(FieldAsFieldDecl))
113 const llvm::StringMap<QualType> SyntheticFieldsForDstType =
116 if (SyntheticFieldsForDstType.contains(Name))
125 for (
const auto &[SyntheticFieldName, SyntheticFieldType] :
139 llvm::dbgs() <<
"Loc1 type " << Loc1.
getType() <<
"\n";
140 llvm::dbgs() <<
"Loc2 type " << Loc2.
getType() <<
"\n";
146 for (
auto [Field, FieldLoc1] : Loc1.
children()) {
149 assert(Field->getType()->isReferenceType() ||
150 (FieldLoc1 !=
nullptr && FieldLoc2 !=
nullptr));
152 if (Field->getType()->isRecordType()) {
156 }
else if (Field->getType()->isReferenceType()) {
157 if (FieldLoc1 != FieldLoc2)
165 if (SynthFieldLoc1->getType()->isRecordType()) {
170 }
else if (Env1.
getValue(*SynthFieldLoc1) !=
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
C Language Family Type Representation.
Represents a C++ struct/union/class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
Represents a member of a struct/union/class.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isRecordType() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
const FieldSet & getModeledFields(QualType Type)
Returns the fields of Type, limited to the set of fields modeled by this context.
llvm::StringMap< QualType > getSyntheticFields(QualType Type)
Returns the names and types of the synthetic fields for the given record type.
Holds the state of the program (store and heap) at a given program point.
void clearValue(const StorageLocation &Loc)
Clears any association between Loc and a value in the environment.
Value * getValue(const StorageLocation &Loc) const
Returns the value assigned to Loc in the environment or null if Loc isn't assigned a value in the env...
DataflowAnalysisContext & getDataflowAnalysisContext() const
Returns the DataflowAnalysisContext used by the environment.
void setValue(const StorageLocation &Loc, Value &Val)
Assigns Val as the value of Loc in the environment.
A storage location for a record (struct, class, or union).
llvm::iterator_range< SyntheticFieldMap::const_iterator > synthetic_fields() const
StorageLocation * getChild(const ValueDecl &D) const
Returns the child storage location for D.
void setChild(const ValueDecl &D, StorageLocation *Loc)
Changes the child storage location for a field D of reference type.
StorageLocation & getSyntheticField(llvm::StringRef Name) const
Returns the storage location for the synthetic field Name.
llvm::iterator_range< FieldToLoc::const_iterator > children() const
Base class for elements of the local variable store and of the heap.
Base class for all values computed by abstract interpretation.
Dataflow Directional Tag Classes.
void copyRecord(RecordStorageLocation &Src, RecordStorageLocation &Dst, Environment &Env, QualType TypeToCopy=QualType())
Copies a record (struct, class, or union) from Src to Dst.
bool recordsEqual(const RecordStorageLocation &Loc1, const Environment &Env1, const RecordStorageLocation &Loc2, const Environment &Env2)
Returns whether the records Loc1 and Loc2 are equal.
static void copyField(const ValueDecl &Field, StorageLocation *SrcFieldLoc, StorageLocation *DstFieldLoc, RecordStorageLocation &Dst, Environment &Env)
static void copySyntheticField(QualType FieldType, StorageLocation &SrcFieldLoc, StorageLocation &DstFieldLoc, Environment &Env)
llvm::SmallSetVector< const FieldDecl *, 4 > FieldSet
A set of FieldDecl *.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
U cast(CodeGen::Address addr)