add new accessors to reflect new terminology in struct types.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137468 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2011-08-12 17:31:02 +00:00
parent b2c4eea9d0
commit 2c38d65fd9
3 changed files with 104 additions and 29 deletions

View File

@ -2031,20 +2031,22 @@ in signal handlers).</p>
<p>Structures may optionally be "packed" structures, which indicate that the
alignment of the struct is one byte, and that there is no padding between
the elements. In non-packed structs, padding between field types is defined
by the target data string to match the underlying processor.</p>
the elements. In non-packed structs, padding between field types is inserted
as defined by the TargetData string in the module, which is required to match
what the underlying processor expects.</p>
<p>Structures can either be "anonymous" or "named". An anonymous structure is
defined inline with other types (e.g. <tt>{i32, i32}*</tt>) and a named types
are always defined at the top level with a name. Anonmyous types are uniqued
by their contents and can never be recursive since there is no way to write
one. Named types can be recursive.
<p>Structures can either be "literal" or "identified". A literal structure is
defined inline with other types (e.g. <tt>{i32, i32}*</tt>) whereas identified
types are always defined at the top level with a name. Literal types are
uniqued by their contents and can never be recursive or opaque since there is
no way to write one. Named types can be recursive, can be opaqued, and are
never uniqued.
</p>
<h5>Syntax:</h5>
<pre>
%T1 = type { &lt;type list&gt; } <i>; Named normal struct type</i>
%T2 = type &lt;{ &lt;type list&gt; }&gt; <i>; Named packed struct type</i>
%T1 = type { &lt;type list&gt; } <i>; Identified normal struct type</i>
%T2 = type &lt;{ &lt;type list&gt; }&gt; <i>; Identified packed struct type</i>
</pre>
<h5>Examples:</h5>

View File

@ -166,10 +166,25 @@ public:
};
/// StructType - Class to represent struct types, both normal and packed.
/// Besides being optionally packed, structs can be either "anonymous" or may
/// have an identity. Anonymous structs are uniqued by structural equivalence,
/// but types are each unique when created, and optionally have a name.
/// StructType - Class to represent struct types. There are two different kinds
/// of struct types: Literal structs and Identified structs.
///
/// Literal struct types (e.g. { i32, i32 }) are uniqued structurally, and must
/// always have a body when created. You can get one of these by using one of
/// the StructType::get() forms.
///
/// Identified structs (e.g. %foo or %42) may optionally have a name and are not
/// uniqued. The names for identified structs are managed at the LLVMContext
/// level, so there can only be a single identified struct with a given name in
/// a particular LLVMContext. Identified structs may also optionally be opaque
/// (have no body specified). You get one of these by using one of the
/// StructType::create() forms.
///
/// Independent of what kind of struct you have, the body of a struct type are
/// laid out in memory consequtively with the elements directly one after the
/// other (if the struct is packed) or (if not packed) with padding between the
/// elements as defined by TargetData (which is required to match what the code
/// generator for a target expects).
///
class StructType : public CompositeType {
StructType(const StructType &); // Do not implement
@ -180,13 +195,13 @@ class StructType : public CompositeType {
// This is the contents of the SubClassData field.
SCDB_HasBody = 1,
SCDB_Packed = 2,
SCDB_IsAnonymous = 4
SCDB_IsLiteral = 4
};
/// SymbolTableEntry - For a named struct that actually has a name, this is a
/// pointer to the symbol table entry (maintained by LLVMContext) for the
/// struct. This is null if the type is an anonymous struct or if it is
/// a named type that has an empty name.
/// struct. This is null if the type is an literal struct or if it is
/// a identified type that has an empty name.
///
void *SymbolTableEntry;
public:
@ -194,10 +209,26 @@ public:
delete [] ContainedTys; // Delete the body.
}
/// StructType::createNamed - This creates a named struct with no body
/// specified. If the name is empty, it creates an unnamed struct, which has
/// a unique identity but no actual name.
static StructType *createNamed(LLVMContext &Context, StringRef Name);
/// StructType::create - This creates an identified struct.
static StructType *create(LLVMContext &Context, StringRef Name);
static StructType *create(LLVMContext &Context);
static StructType *create(ArrayRef<Type*> Elements,
StringRef Name,
bool isPacked = false);
static StructType *create(ArrayRef<Type*> Elements);
static StructType *create(LLVMContext &Context,
ArrayRef<Type*> Elements,
StringRef Name,
bool isPacked = false);
static StructType *create(LLVMContext &Context, ArrayRef<Type*> Elements);
static StructType *create(StringRef Name, Type *elt1, ...) END_WITH_NULL;
// FIXME: Remove these.
bool isAnonymous() const {return (getSubclassData() & SCDB_IsLiteral) != 0;}
static StructType *createNamed(LLVMContext &Context,
StringRef Name);
static StructType *createNamed(StringRef Name, ArrayRef<Type*> Elements,
bool isPacked = false);
@ -207,7 +238,7 @@ public:
static StructType *createNamed(StringRef Name, Type *elt1, ...) END_WITH_NULL;
/// StructType::get - This static method is the primary way to create a
/// StructType.
/// literal StructType.
static StructType *get(LLVMContext &Context, ArrayRef<Type*> Elements,
bool isPacked = false);
@ -223,9 +254,9 @@ public:
bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; }
/// isAnonymous - Return true if this type is uniqued by structural
/// equivalence, false if it has an identity.
bool isAnonymous() const {return (getSubclassData() & SCDB_IsAnonymous) != 0;}
/// isLiteral - Return true if this type is uniqued by structural
/// equivalence, false if it is a struct definition.
bool isLiteral() const {return (getSubclassData() & SCDB_IsLiteral) != 0;}
/// isOpaque - Return true if this is a type with an identity that has no body
/// specified yet. These prints as 'opaque' in .ll files.
@ -236,15 +267,15 @@ public:
/// getName - Return the name for this struct type if it has an identity.
/// This may return an empty string for an unnamed struct type. Do not call
/// this on an anonymous type.
/// this on an literal type.
StringRef getName() const;
/// setName - Change the name of this type to the specified name, or to a name
/// with a suffix if there is a collision. Do not call this on an anonymous
/// with a suffix if there is a collision. Do not call this on an literal
/// type.
void setName(StringRef Name);
/// setBody - Specify a body for an opaque type.
/// setBody - Specify a body for an opaque identified type.
void setBody(ArrayRef<Type*> Elements, bool isPacked = false);
void setBody(Type *elt1, ...) END_WITH_NULL;

View File

@ -392,7 +392,7 @@ StructType *StructType::get(LLVMContext &Context, ArrayRef<Type*> ETypes,
// Value not found. Create a new type!
ST = new (Context.pImpl->TypeAllocator) StructType(Context);
ST->setSubclassData(SCDB_IsAnonymous); // Anonymous struct.
ST->setSubclassData(SCDB_IsLiteral); // Literal struct.
ST->setBody(ETypes, isPacked);
return ST;
}
@ -478,6 +478,48 @@ StructType *StructType::get(Type *type, ...) {
return llvm::StructType::get(Ctx, StructFields);
}
StructType *StructType::create(LLVMContext &Context, ArrayRef<Type*> Elements,
StringRef Name, bool isPacked) {
StructType *ST = createNamed(Context, Name);
ST->setBody(Elements, isPacked);
return ST;
}
StructType *StructType::create(LLVMContext &Context, ArrayRef<Type*> Elements) {
return create(Context, Elements, StringRef());
}
StructType *StructType::create(ArrayRef<Type*> Elements, StringRef Name,
bool isPacked) {
assert(!Elements.empty() &&
"This method may not be invoked with an empty list");
return create(Elements[0]->getContext(), Elements, Name, isPacked);
}
StructType *StructType::create(ArrayRef<Type*> Elements) {
assert(!Elements.empty() &&
"This method may not be invoked with an empty list");
return create(Elements[0]->getContext(), Elements, StringRef());
}
StructType *StructType::create(StringRef Name, Type *type, ...) {
assert(type != 0 && "Cannot create a struct type with no elements with this");
LLVMContext &Ctx = type->getContext();
va_list ap;
SmallVector<llvm::Type*, 8> StructFields;
va_start(ap, type);
while (type) {
StructFields.push_back(type);
type = va_arg(ap, llvm::Type*);
}
return llvm::StructType::create(Ctx, StructFields, Name);
}
StructType *StructType::createNamed(LLVMContext &Context, StringRef Name,
ArrayRef<Type*> Elements, bool isPacked) {
StructType *ST = createNamed(Context, Name);
@ -506,7 +548,7 @@ StructType *StructType::createNamed(StringRef Name, Type *type, ...) {
}
StringRef StructType::getName() const {
assert(!isAnonymous() && "Anonymous structs never have names");
assert(!isLiteral() && "Literal structs never have names");
if (SymbolTableEntry == 0) return StringRef();
return ((StringMapEntry<StructType*> *)SymbolTableEntry)->getKey();