|
@@ -225,6 +225,10 @@ QualType CXXBaseObjectRegion::getValueType() const {
|
|
return QualType(getDecl()->getTypeForDecl(), 0);
|
|
return QualType(getDecl()->getTypeForDecl(), 0);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+QualType CXXDerivedObjectRegion::getValueType() const {
|
|
|
|
+ return QualType(getDecl()->getTypeForDecl(), 0);
|
|
|
|
+}
|
|
|
|
+
|
|
//===----------------------------------------------------------------------===//
|
|
//===----------------------------------------------------------------------===//
|
|
// FoldingSet profiling.
|
|
// FoldingSet profiling.
|
|
//===----------------------------------------------------------------------===//
|
|
//===----------------------------------------------------------------------===//
|
|
@@ -404,6 +408,17 @@ void CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
|
|
ProfileRegion(ID, getDecl(), isVirtual(), superRegion);
|
|
ProfileRegion(ID, getDecl(), isVirtual(), superRegion);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void CXXDerivedObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
|
|
|
|
+ const CXXRecordDecl *RD,
|
|
|
|
+ const MemRegion *SReg) {
|
|
|
|
+ ID.AddPointer(RD);
|
|
|
|
+ ID.AddPointer(SReg);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CXXDerivedObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
|
|
|
|
+ ProfileRegion(ID, getDecl(), superRegion);
|
|
|
|
+}
|
|
|
|
+
|
|
//===----------------------------------------------------------------------===//
|
|
//===----------------------------------------------------------------------===//
|
|
// Region anchors.
|
|
// Region anchors.
|
|
//===----------------------------------------------------------------------===//
|
|
//===----------------------------------------------------------------------===//
|
|
@@ -475,7 +490,11 @@ void CXXTempObjectRegion::dumpToStream(raw_ostream &os) const {
|
|
}
|
|
}
|
|
|
|
|
|
void CXXBaseObjectRegion::dumpToStream(raw_ostream &os) const {
|
|
void CXXBaseObjectRegion::dumpToStream(raw_ostream &os) const {
|
|
- os << "base{" << superRegion << ',' << getDecl()->getName() << '}';
|
|
|
|
|
|
+ os << "Base{" << superRegion << ',' << getDecl()->getName() << '}';
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CXXDerivedObjectRegion::dumpToStream(raw_ostream &os) const {
|
|
|
|
+ os << "Derived{" << superRegion << ',' << getDecl()->getName() << '}';
|
|
}
|
|
}
|
|
|
|
|
|
void CXXThisRegion::dumpToStream(raw_ostream &os) const {
|
|
void CXXThisRegion::dumpToStream(raw_ostream &os) const {
|
|
@@ -483,7 +502,7 @@ void CXXThisRegion::dumpToStream(raw_ostream &os) const {
|
|
}
|
|
}
|
|
|
|
|
|
void ElementRegion::dumpToStream(raw_ostream &os) const {
|
|
void ElementRegion::dumpToStream(raw_ostream &os) const {
|
|
- os << "element{" << superRegion << ','
|
|
|
|
|
|
+ os << "Element{" << superRegion << ','
|
|
<< Index << ',' << getElementType().getAsString() << '}';
|
|
<< Index << ',' << getElementType().getAsString() << '}';
|
|
}
|
|
}
|
|
|
|
|
|
@@ -492,7 +511,7 @@ void FieldRegion::dumpToStream(raw_ostream &os) const {
|
|
}
|
|
}
|
|
|
|
|
|
void ObjCIvarRegion::dumpToStream(raw_ostream &os) const {
|
|
void ObjCIvarRegion::dumpToStream(raw_ostream &os) const {
|
|
- os << "ivar{" << superRegion << ',' << *getDecl() << '}';
|
|
|
|
|
|
+ os << "Ivar{" << superRegion << ',' << *getDecl() << '}';
|
|
}
|
|
}
|
|
|
|
|
|
void StringRegion::dumpToStream(raw_ostream &os) const {
|
|
void StringRegion::dumpToStream(raw_ostream &os) const {
|
|
@@ -630,6 +649,14 @@ void CXXBaseObjectRegion::printPrettyAsExpr(raw_ostream &os) const {
|
|
superRegion->printPrettyAsExpr(os);
|
|
superRegion->printPrettyAsExpr(os);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+bool CXXDerivedObjectRegion::canPrintPrettyAsExpr() const {
|
|
|
|
+ return superRegion->canPrintPrettyAsExpr();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CXXDerivedObjectRegion::printPrettyAsExpr(raw_ostream &os) const {
|
|
|
|
+ superRegion->printPrettyAsExpr(os);
|
|
|
|
+}
|
|
|
|
+
|
|
std::string MemRegion::getDescriptiveName(bool UseQuotes) const {
|
|
std::string MemRegion::getDescriptiveName(bool UseQuotes) const {
|
|
std::string VariableName;
|
|
std::string VariableName;
|
|
std::string ArrayIndices;
|
|
std::string ArrayIndices;
|
|
@@ -1061,6 +1088,12 @@ MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD,
|
|
return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super);
|
|
return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+const CXXDerivedObjectRegion *
|
|
|
|
+MemRegionManager::getCXXDerivedObjectRegion(const CXXRecordDecl *RD,
|
|
|
|
+ const SubRegion *Super) {
|
|
|
|
+ return getSubRegion<CXXDerivedObjectRegion>(RD, Super);
|
|
|
|
+}
|
|
|
|
+
|
|
const CXXThisRegion*
|
|
const CXXThisRegion*
|
|
MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
|
|
MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
|
|
const LocationContext *LC) {
|
|
const LocationContext *LC) {
|
|
@@ -1131,6 +1164,7 @@ const MemRegion *MemRegion::getBaseRegion() const {
|
|
case MemRegion::FieldRegionKind:
|
|
case MemRegion::FieldRegionKind:
|
|
case MemRegion::ObjCIvarRegionKind:
|
|
case MemRegion::ObjCIvarRegionKind:
|
|
case MemRegion::CXXBaseObjectRegionKind:
|
|
case MemRegion::CXXBaseObjectRegionKind:
|
|
|
|
+ case MemRegion::CXXDerivedObjectRegionKind:
|
|
R = cast<SubRegion>(R)->getSuperRegion();
|
|
R = cast<SubRegion>(R)->getSuperRegion();
|
|
continue;
|
|
continue;
|
|
default:
|
|
default:
|
|
@@ -1149,7 +1183,7 @@ bool MemRegion::isSubRegionOf(const MemRegion *R) const {
|
|
// View handling.
|
|
// View handling.
|
|
//===----------------------------------------------------------------------===//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
-const MemRegion *MemRegion::StripCasts(bool StripBaseCasts) const {
|
|
|
|
|
|
+const MemRegion *MemRegion::StripCasts(bool StripBaseAndDerivedCasts) const {
|
|
const MemRegion *R = this;
|
|
const MemRegion *R = this;
|
|
while (true) {
|
|
while (true) {
|
|
switch (R->getKind()) {
|
|
switch (R->getKind()) {
|
|
@@ -1161,9 +1195,10 @@ const MemRegion *MemRegion::StripCasts(bool StripBaseCasts) const {
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
case CXXBaseObjectRegionKind:
|
|
case CXXBaseObjectRegionKind:
|
|
- if (!StripBaseCasts)
|
|
|
|
|
|
+ case CXXDerivedObjectRegionKind:
|
|
|
|
+ if (!StripBaseAndDerivedCasts)
|
|
return R;
|
|
return R;
|
|
- R = cast<CXXBaseObjectRegion>(R)->getSuperRegion();
|
|
|
|
|
|
+ R = cast<TypedValueRegion>(R)->getSuperRegion();
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
return R;
|
|
return R;
|
|
@@ -1344,6 +1379,12 @@ static RegionOffset calculateOffset(const MemRegion *R) {
|
|
Offset += BaseOffset.getQuantity() * R->getContext().getCharWidth();
|
|
Offset += BaseOffset.getQuantity() * R->getContext().getCharWidth();
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ case MemRegion::CXXDerivedObjectRegionKind: {
|
|
|
|
+ // TODO: Store the base type in the CXXDerivedObjectRegion and use it.
|
|
|
|
+ goto Finish;
|
|
|
|
+ }
|
|
|
|
+
|
|
case MemRegion::ElementRegionKind: {
|
|
case MemRegion::ElementRegionKind: {
|
|
const auto *ER = cast<ElementRegion>(R);
|
|
const auto *ER = cast<ElementRegion>(R);
|
|
R = ER->getSuperRegion();
|
|
R = ER->getSuperRegion();
|