return false;
}
-RegionOffset MemRegion::getAsOffset() const {
- const MemRegion *R = this;
+static RegionOffset calculateOffset(const MemRegion *R) {
const MemRegion *SymbolicOffsetBase = nullptr;
int64_t Offset = 0;
while (1) {
switch (R->getKind()) {
- case CodeSpaceRegionKind:
- case StackLocalsSpaceRegionKind:
- case StackArgumentsSpaceRegionKind:
- case HeapSpaceRegionKind:
- case UnknownSpaceRegionKind:
- case StaticGlobalSpaceRegionKind:
- case GlobalInternalSpaceRegionKind:
- case GlobalSystemSpaceRegionKind:
- case GlobalImmutableSpaceRegionKind:
+ case MemRegion::CodeSpaceRegionKind:
+ case MemRegion::StackLocalsSpaceRegionKind:
+ case MemRegion::StackArgumentsSpaceRegionKind:
+ case MemRegion::HeapSpaceRegionKind:
+ case MemRegion::UnknownSpaceRegionKind:
+ case MemRegion::StaticGlobalSpaceRegionKind:
+ case MemRegion::GlobalInternalSpaceRegionKind:
+ case MemRegion::GlobalSystemSpaceRegionKind:
+ case MemRegion::GlobalImmutableSpaceRegionKind:
// Stores can bind directly to a region space to set a default value.
assert(Offset == 0 && !SymbolicOffsetBase);
goto Finish;
- case FunctionCodeRegionKind:
- case BlockCodeRegionKind:
- case BlockDataRegionKind:
+ case MemRegion::FunctionCodeRegionKind:
+ case MemRegion::BlockCodeRegionKind:
+ case MemRegion::BlockDataRegionKind:
// These will never have bindings, but may end up having values requested
// if the user does some strange casting.
if (Offset != 0)
SymbolicOffsetBase = R;
goto Finish;
- case SymbolicRegionKind:
- case AllocaRegionKind:
- case CompoundLiteralRegionKind:
- case CXXThisRegionKind:
- case StringRegionKind:
- case ObjCStringRegionKind:
- case VarRegionKind:
- case CXXTempObjectRegionKind:
+ case MemRegion::SymbolicRegionKind:
+ case MemRegion::AllocaRegionKind:
+ case MemRegion::CompoundLiteralRegionKind:
+ case MemRegion::CXXThisRegionKind:
+ case MemRegion::StringRegionKind:
+ case MemRegion::ObjCStringRegionKind:
+ case MemRegion::VarRegionKind:
+ case MemRegion::CXXTempObjectRegionKind:
// Usual base regions.
goto Finish;
- case ObjCIvarRegionKind:
+ case MemRegion::ObjCIvarRegionKind:
// This is a little strange, but it's a compromise between
// ObjCIvarRegions having unknown compile-time offsets (when using the
// non-fragile runtime) and yet still being distinct, non-overlapping
// of computing offsets.
goto Finish;
- case CXXBaseObjectRegionKind: {
+ case MemRegion::CXXBaseObjectRegionKind: {
const CXXBaseObjectRegion *BOR = cast<CXXBaseObjectRegion>(R);
R = BOR->getSuperRegion();
QualType Ty;
bool RootIsSymbolic = false;
if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R)) {
- Ty = TVR->getDesugaredValueType(getContext());
+ Ty = TVR->getDesugaredValueType(R->getContext());
} else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
// If our base region is symbolic, we don't know what type it really is.
// Pretend the type of the symbol is the true dynamic type.
continue;
CharUnits BaseOffset;
- const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Child);
+ const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(Child);
if (BOR->isVirtual())
BaseOffset = Layout.getVBaseClassOffset(BOR->getDecl());
else
BaseOffset = Layout.getBaseClassOffset(BOR->getDecl());
// The base offset is in chars, not in bits.
- Offset += BaseOffset.getQuantity() * getContext().getCharWidth();
+ Offset += BaseOffset.getQuantity() * R->getContext().getCharWidth();
break;
}
- case ElementRegionKind: {
+ case MemRegion::ElementRegionKind: {
const ElementRegion *ER = cast<ElementRegion>(R);
R = ER->getSuperRegion();
int64_t i = CI->getValue().getSExtValue();
// This type size is in bits.
- Offset += i * getContext().getTypeSize(EleTy);
+ Offset += i * R->getContext().getTypeSize(EleTy);
} else {
// We cannot compute offset for non-concrete index.
SymbolicOffsetBase = R;
}
break;
}
- case FieldRegionKind: {
+ case MemRegion::FieldRegionKind: {
const FieldRegion *FR = cast<FieldRegion>(R);
R = FR->getSuperRegion();
if (FR->getDecl() == *FI)
break;
}
- const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
+ const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(RD);
// This is offset in bits.
Offset += Layout.getFieldOffset(idx);
break;
return RegionOffset(R, Offset);
}
+RegionOffset MemRegion::getAsOffset() const {
+ if (!cachedOffset)
+ cachedOffset = calculateOffset(this);
+ return *cachedOffset;
+}
+
//===----------------------------------------------------------------------===//
// BlockDataRegion
//===----------------------------------------------------------------------===//