//
//===----------------------------------------------------------------------===//
+#include "llvm/Type.h"
#include "LLVMContextImpl.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/Module.h"
#include <algorithm>
#include <cstdarg>
-#include "llvm/ADT/SmallString.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
return this;
}
+const Type *Type::getScalarType() const {
+ if (const VectorType *VTy = dyn_cast<VectorType>(this))
+ return VTy->getElementType();
+ return this;
+}
+
/// isIntegerTy - Return true if this is an IntegerType of the specified width.
bool Type::isIntegerTy(unsigned Bitwidth) const {
return isIntegerTy() && cast<IntegerType>(this)->getBitWidth() == Bitwidth;
}
-/// isIntOrIntVectorTy - Return true if this is an integer type or a vector of
-/// integer types.
-///
-bool Type::isIntOrIntVectorTy() const {
- if (isIntegerTy())
- return true;
- if (getTypeID() != Type::VectorTyID) return false;
-
- return cast<VectorType>(this)->getElementType()->isIntegerTy();
-}
-
-/// isFPOrFPVectorTy - Return true if this is a FP type or a vector of FP types.
-///
-bool Type::isFPOrFPVectorTy() const {
- if (getTypeID() == Type::HalfTyID || getTypeID() == Type::FloatTyID ||
- getTypeID() == Type::DoubleTyID ||
- getTypeID() == Type::FP128TyID || getTypeID() == Type::X86_FP80TyID ||
- getTypeID() == Type::PPC_FP128TyID)
- return true;
- if (getTypeID() != Type::VectorTyID) return false;
-
- return cast<VectorType>(this)->getElementType()->isFloatingPointTy();
-}
-
// canLosslesslyBitCastTo - Return true if this type can be converted to
// 'Ty' without any reinterpretation of bits. For example, i8* to i32*.
//
return cast<StructType>(this)->getElementType(N);
}
-
-
Type *Type::getSequentialElementType() const {
return cast<SequentialType>(this)->getElementType();
}
}
unsigned Type::getPointerAddressSpace() const {
- return cast<PointerType>(this)->getAddressSpace();
+ return cast<PointerType>(getScalarType())->getAddressSpace();
}
-
-
//===----------------------------------------------------------------------===//
// Primitive 'Type' data
//===----------------------------------------------------------------------===//
return FT;
}
-
FunctionType *FunctionType::get(Type *Result, bool isVarArg) {
return get(Result, ArrayRef<Type *>(), isVarArg);
}
-
/// isValidReturnType - Return true if the specified type is valid as a return
/// type.
bool FunctionType::isValidReturnType(Type *RetTy) {
void StructType::setName(StringRef Name) {
if (Name == getName()) return;
- // If this struct already had a name, remove its symbol table entry.
- if (SymbolTableEntry) {
- getContext().pImpl->NamedStructTypes.erase(getName());
- SymbolTableEntry = 0;
- }
-
+ StringMap<StructType *> &SymbolTable = getContext().pImpl->NamedStructTypes;
+ typedef StringMap<StructType *>::MapEntryTy EntryTy;
+
+ // If this struct already had a name, remove its symbol table entry. Don't
+ // delete the data yet because it may be part of the new name.
+ if (SymbolTableEntry)
+ SymbolTable.remove((EntryTy *)SymbolTableEntry);
+
// If this is just removing the name, we're done.
- if (Name.empty())
+ if (Name.empty()) {
+ if (SymbolTableEntry) {
+ // Delete the old string data.
+ ((EntryTy *)SymbolTableEntry)->Destroy(SymbolTable.getAllocator());
+ SymbolTableEntry = 0;
+ }
return;
+ }
// Look up the entry for the name.
- StringMapEntry<StructType*> *Entry =
- &getContext().pImpl->NamedStructTypes.GetOrCreateValue(Name);
+ EntryTy *Entry = &getContext().pImpl->NamedStructTypes.GetOrCreateValue(Name);
// While we have a name collision, try a random rename.
if (Entry->getValue()) {
// Okay, we found an entry that isn't used. It's us!
Entry->setValue(this);
-
+
+ // Delete the old string data.
+ if (SymbolTableEntry)
+ ((EntryTy *)SymbolTableEntry)->Destroy(SymbolTable.getAllocator());
SymbolTableEntry = Entry;
}
return create(Context, StringRef());
}
-
StructType *StructType::create(ArrayRef<Type*> Elements, StringRef Name,
bool isPacked) {
assert(!Elements.empty() &&
return std::equal(element_begin(), element_end(), Other->element_begin());
}
-
/// getTypeByName - Return the type with the specified name, or null if there
/// is none by that name.
StructType *Module::getTypeByName(StringRef Name) const {
return 0;
}
-/// getNumNamedStructTypes - Return the number of named struct types.
-unsigned Module::getNumNamedStructTypes() const {
- return getContext().pImpl->NamedStructTypes.size();
-}
//===----------------------------------------------------------------------===//
// CompositeType Implementation
Type *CompositeType::getTypeAtIndex(const Value *V) {
if (StructType *STy = dyn_cast<StructType>(this)) {
- unsigned Idx = (unsigned)cast<ConstantInt>(V)->getZExtValue();
+ unsigned Idx =
+ (unsigned)cast<Constant>(V)->getUniqueInteger().getZExtValue();
assert(indexValid(Idx) && "Invalid structure index!");
return STy->getElementType(Idx);
}
-
+
return cast<SequentialType>(this)->getElementType();
}
Type *CompositeType::getTypeAtIndex(unsigned Idx) {
}
bool CompositeType::indexValid(const Value *V) const {
if (const StructType *STy = dyn_cast<StructType>(this)) {
- // Structure indexes require 32-bit integer constants.
- if (V->getType()->isIntegerTy(32))
- if (const ConstantInt *CU = dyn_cast<ConstantInt>(V))
- return CU->getZExtValue() < STy->getNumElements();
- return false;
+ // Structure indexes require (vectors of) 32-bit integer constants. In the
+ // vector case all of the indices must be equal.
+ if (!V->getType()->getScalarType()->isIntegerTy(32))
+ return false;
+ const Constant *C = dyn_cast<Constant>(V);
+ if (C && V->getType()->isVectorTy())
+ C = C->getSplatValue();
+ const ConstantInt *CU = dyn_cast_or_null<ConstantInt>(C);
+ return CU && CU->getZExtValue() < STy->getNumElements();
}
-
+
// Sequential types can be indexed by any integer.
- return V->getType()->isIntegerTy();
+ return V->getType()->isIntOrIntVectorTy();
}
bool CompositeType::indexValid(unsigned Idx) const {
NumElements = NumEl;
}
-
ArrayType *ArrayType::get(Type *elementType, uint64_t NumElements) {
Type *ElementType = const_cast<Type*>(elementType);
assert(isValidElementType(ElementType) && "Invalid type for array element!");
}
bool VectorType::isValidElementType(Type *ElemTy) {
- if (PointerType *PTy = dyn_cast<PointerType>(ElemTy))
- ElemTy = PTy->getElementType();
- return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy();
+ return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy() ||
+ ElemTy->isPointerTy();
}
//===----------------------------------------------------------------------===//