/// isSizedDerivedType - Derived types like structures and arrays are sized
/// iff all of the members of the type are sized as well. Since asking for
/// their size is relatively uncommon, move this operation out of line.
-bool Type::isSizedDerivedType() const {
- if (this->isIntegerTy())
- return true;
-
+bool Type::isSizedDerivedType(SmallPtrSet<const Type*, 4> *Visited) const {
if (const ArrayType *ATy = dyn_cast<ArrayType>(this))
- return ATy->getElementType()->isSized();
+ return ATy->getElementType()->isSized(Visited);
if (const VectorType *VTy = dyn_cast<VectorType>(this))
- return VTy->getElementType()->isSized();
-
- if (!this->isStructTy())
- return false;
+ return VTy->getElementType()->isSized(Visited);
- return cast<StructType>(this)->isSized();
+ return cast<StructType>(this)->isSized(Visited);
}
//===----------------------------------------------------------------------===//
return llvm::StructType::create(Ctx, StructFields, Name);
}
-bool StructType::isSized() const {
+bool StructType::isSized(SmallPtrSet<const Type*, 4> *Visited) const {
if ((getSubclassData() & SCDB_IsSized) != 0)
return true;
if (isOpaque())
return false;
+ if (Visited && !Visited->insert(this))
+ return false;
+
// Okay, our struct is sized if all of the elements are, but if one of the
// elements is opaque, the struct isn't sized *yet*, but may become sized in
// the future, so just bail out without caching.
for (element_iterator I = element_begin(), E = element_end(); I != E; ++I)
- if (!(*I)->isSized())
+ if (!(*I)->isSized(Visited))
return false;
// Here we cheat a bit and cast away const-ness. The goal is to memoize when