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 ...
llvm::StringMap< QualType > getSyntheticFields(QualType Type)
Returns the names and types of the synthetic fields for the given record type.
FieldSet getModeledFields(QualType Type)
Returns the fields of Type, limited to the set of fields modeled by this context.
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)