case MetadataTyID : return getMetadataTy(C);
case X86_MMXTyID : return getX86_MMXTy(C);
default:
- return 0;
+ return nullptr;
}
}
// At this point we have only various mismatches of the first class types
// remaining and ptr->ptr. Just select the lossless conversions. Everything
- // else is not lossless.
- if (this->isPointerTy())
- return Ty->isPointerTy();
+ // else is not lossless. Conservatively assume we can't losslessly convert
+ // between pointers with different address spaces.
+ if (const PointerType *PTy = dyn_cast<PointerType>(this)) {
+ if (const PointerType *OtherPTy = dyn_cast<PointerType>(Ty))
+ return PTy->getAddressSpace() == OtherPTy->getAddressSpace();
+ return false;
+ }
return false; // Other types have no identity values
}
/// getScalarSizeInBits - If this is a vector type, return the
/// getPrimitiveSizeInBits value for the element type. Otherwise return the
/// getPrimitiveSizeInBits value for this type.
-unsigned Type::getScalarSizeInBits() {
+unsigned Type::getScalarSizeInBits() const {
return getScalarType()->getPrimitiveSizeInBits();
}
/// 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 {
+bool Type::isSizedDerivedType(SmallPtrSetImpl<const Type*> *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();
+ return VTy->getElementType()->isSized(Visited);
- return cast<StructType>(this)->isSized();
+ return cast<StructType>(this)->isSized(Visited);
}
//===----------------------------------------------------------------------===//
}
IntegerType *&Entry = C.pImpl->IntegerTypes[NumBits];
-
- if (Entry == 0)
+
+ if (!Entry)
Entry = new (C.pImpl->TypeAllocator) IntegerType(C, NumBits);
return Entry;
if (SymbolTableEntry) {
// Delete the old string data.
((EntryTy *)SymbolTableEntry)->Destroy(SymbolTable.getAllocator());
- SymbolTableEntry = 0;
+ SymbolTableEntry = nullptr;
}
return;
}
// Look up the entry for the name.
- EntryTy *Entry = &getContext().pImpl->NamedStructTypes.GetOrCreateValue(Name);
-
+ auto IterBool =
+ getContext().pImpl->NamedStructTypes.insert(std::make_pair(Name, this));
+
// While we have a name collision, try a random rename.
- if (Entry->getValue()) {
+ if (!IterBool.second) {
SmallString<64> TempStr(Name);
TempStr.push_back('.');
raw_svector_ostream TmpStream(TempStr);
TempStr.resize(NameSize + 1);
TmpStream.resync();
TmpStream << getContext().pImpl->NamedStructTypesUniqueID++;
-
- Entry = &getContext().pImpl->
- NamedStructTypes.GetOrCreateValue(TmpStream.str());
- } while (Entry->getValue());
- }
- // Okay, we found an entry that isn't used. It's us!
- Entry->setValue(this);
+ IterBool = getContext().pImpl->NamedStructTypes.insert(
+ std::make_pair(TmpStream.str(), this));
+ } while (!IterBool.second);
+ }
// Delete the old string data.
if (SymbolTableEntry)
((EntryTy *)SymbolTableEntry)->Destroy(SymbolTable.getAllocator());
- SymbolTableEntry = Entry;
+ SymbolTableEntry = &*IterBool.first;
}
//===----------------------------------------------------------------------===//
}
StructType *StructType::get(Type *type, ...) {
- assert(type != 0 && "Cannot create a struct type with no elements with this");
+ assert(type && "Cannot create a struct type with no elements with this");
LLVMContext &Ctx = type->getContext();
va_list ap;
SmallVector<llvm::Type*, 8> StructFields;
StructFields.push_back(type);
type = va_arg(ap, llvm::Type*);
}
- return llvm::StructType::get(Ctx, StructFields);
+ auto *Ret = llvm::StructType::get(Ctx, StructFields);
+ va_end(ap);
+ return Ret;
}
StructType *StructType::create(LLVMContext &Context, ArrayRef<Type*> Elements,
}
StructType *StructType::create(StringRef Name, Type *type, ...) {
- assert(type != 0 && "Cannot create a struct type with no elements with this");
+ assert(type && "Cannot create a struct type with no elements with this");
LLVMContext &Ctx = type->getContext();
va_list ap;
SmallVector<llvm::Type*, 8> StructFields;
StructFields.push_back(type);
type = va_arg(ap, llvm::Type*);
}
- return llvm::StructType::create(Ctx, StructFields, Name);
+ auto *Ret = llvm::StructType::create(Ctx, StructFields, Name);
+ va_end(ap);
+ return Ret;
}
-bool StructType::isSized() const {
+bool StructType::isSized(SmallPtrSetImpl<const Type*> *Visited) const {
if ((getSubclassData() & SCDB_IsSized) != 0)
return true;
if (isOpaque())
return false;
+ if (Visited && !Visited->insert(this).second)
+ 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
StringRef StructType::getName() const {
assert(!isLiteral() && "Literal structs never have names");
- if (SymbolTableEntry == 0) return StringRef();
-
+ if (!SymbolTableEntry) return StringRef();
+
return ((StringMapEntry<StructType*> *)SymbolTableEntry)->getKey();
}
void StructType::setBody(Type *type, ...) {
- assert(type != 0 && "Cannot create a struct type with no elements with this");
+ assert(type && "Cannot create a struct type with no elements with this");
va_list ap;
SmallVector<llvm::Type*, 8> StructFields;
va_start(ap, type);
type = va_arg(ap, llvm::Type*);
}
setBody(StructFields);
+ va_end(ap);
}
bool StructType::isValidElementType(Type *ElemTy) {
LLVMContextImpl *pImpl = ElementType->getContext().pImpl;
ArrayType *&Entry =
pImpl->ArrayTypes[std::make_pair(ElementType, NumElements)];
-
- if (Entry == 0)
+
+ if (!Entry)
Entry = new (pImpl->TypeAllocator) ArrayType(ElementType, NumElements);
return Entry;
}
LLVMContextImpl *pImpl = ElementType->getContext().pImpl;
VectorType *&Entry = ElementType->getContext().pImpl
->VectorTypes[std::make_pair(ElementType, NumElements)];
-
- if (Entry == 0)
+
+ if (!Entry)
Entry = new (pImpl->TypeAllocator) VectorType(ElementType, NumElements);
return Entry;
}
PointerType *&Entry = AddressSpace == 0 ? CImpl->PointerTypes[EltTy]
: CImpl->ASPointerTypes[std::make_pair(EltTy, AddressSpace)];
- if (Entry == 0)
+ if (!Entry)
Entry = new (CImpl->TypeAllocator) PointerType(EltTy, AddressSpace);
return Entry;
}