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 <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 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 the elements. In non-packed structs, padding between field types is inserted
by the target data string to match the underlying processor.</p> 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 <p>Structures can either be "literal" or "identified". A literal structure is
defined inline with other types (e.g. <tt>{i32, i32}*</tt>) and a named types defined inline with other types (e.g. <tt>{i32, i32}*</tt>) whereas identified
are always defined at the top level with a name. Anonmyous types are uniqued types are always defined at the top level with a name. Literal types are
by their contents and can never be recursive since there is no way to write uniqued by their contents and can never be recursive or opaque since there is
one. Named types can be recursive. no way to write one. Named types can be recursive, can be opaqued, and are
never uniqued.
</p> </p>
<h5>Syntax:</h5> <h5>Syntax:</h5>
<pre> <pre>
%T1 = type { &lt;type list&gt; } <i>; Named normal struct type</i> %T1 = type { &lt;type list&gt; } <i>; Identified normal struct type</i>
%T2 = type &lt;{ &lt;type list&gt; }&gt; <i>; Named packed struct type</i> %T2 = type &lt;{ &lt;type list&gt; }&gt; <i>; Identified packed struct type</i>
</pre> </pre>
<h5>Examples:</h5> <h5>Examples:</h5>

View File

@@ -166,10 +166,25 @@ public:
}; };
/// StructType - Class to represent struct types, both normal and packed. /// StructType - Class to represent struct types. There are two different kinds
/// Besides being optionally packed, structs can be either "anonymous" or may /// of struct types: Literal structs and Identified structs.
/// have an identity. Anonymous structs are uniqued by structural equivalence, ///
/// but types are each unique when created, and optionally have a name. /// 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 { class StructType : public CompositeType {
StructType(const StructType &); // Do not implement StructType(const StructType &); // Do not implement
@@ -180,13 +195,13 @@ class StructType : public CompositeType {
// This is the contents of the SubClassData field. // This is the contents of the SubClassData field.
SCDB_HasBody = 1, SCDB_HasBody = 1,
SCDB_Packed = 2, SCDB_Packed = 2,
SCDB_IsAnonymous = 4 SCDB_IsLiteral = 4
}; };
/// SymbolTableEntry - For a named struct that actually has a name, this is a /// SymbolTableEntry - For a named struct that actually has a name, this is a
/// pointer to the symbol table entry (maintained by LLVMContext) for the /// 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 /// struct. This is null if the type is an literal struct or if it is
/// a named type that has an empty name. /// a identified type that has an empty name.
/// ///
void *SymbolTableEntry; void *SymbolTableEntry;
public: public:
@@ -194,10 +209,26 @@ public:
delete [] ContainedTys; // Delete the body. delete [] ContainedTys; // Delete the body.
} }
/// StructType::createNamed - This creates a named struct with no body /// StructType::create - This creates an identified struct.
/// specified. If the name is empty, it creates an unnamed struct, which has static StructType *create(LLVMContext &Context, StringRef Name);
/// a unique identity but no actual name. static StructType *create(LLVMContext &Context);
static StructType *createNamed(LLVMContext &Context, StringRef Name);
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, static StructType *createNamed(StringRef Name, ArrayRef<Type*> Elements,
bool isPacked = false); bool isPacked = false);
@@ -207,7 +238,7 @@ public:
static StructType *createNamed(StringRef Name, Type *elt1, ...) END_WITH_NULL; static StructType *createNamed(StringRef Name, Type *elt1, ...) END_WITH_NULL;
/// StructType::get - This static method is the primary way to create a /// StructType::get - This static method is the primary way to create a
/// StructType. /// literal StructType.
static StructType *get(LLVMContext &Context, ArrayRef<Type*> Elements, static StructType *get(LLVMContext &Context, ArrayRef<Type*> Elements,
bool isPacked = false); bool isPacked = false);
@@ -223,9 +254,9 @@ public:
bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; } bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; }
/// isAnonymous - Return true if this type is uniqued by structural /// isLiteral - Return true if this type is uniqued by structural
/// equivalence, false if it has an identity. /// equivalence, false if it is a struct definition.
bool isAnonymous() const {return (getSubclassData() & SCDB_IsAnonymous) != 0;} bool isLiteral() const {return (getSubclassData() & SCDB_IsLiteral) != 0;}
/// isOpaque - Return true if this is a type with an identity that has no body /// isOpaque - Return true if this is a type with an identity that has no body
/// specified yet. These prints as 'opaque' in .ll files. /// 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. /// 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 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; StringRef getName() const;
/// setName - Change the name of this type to the specified name, or to a name /// 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. /// type.
void setName(StringRef Name); 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(ArrayRef<Type*> Elements, bool isPacked = false);
void setBody(Type *elt1, ...) END_WITH_NULL; 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! // Value not found. Create a new type!
ST = new (Context.pImpl->TypeAllocator) StructType(Context); ST = new (Context.pImpl->TypeAllocator) StructType(Context);
ST->setSubclassData(SCDB_IsAnonymous); // Anonymous struct. ST->setSubclassData(SCDB_IsLiteral); // Literal struct.
ST->setBody(ETypes, isPacked); ST->setBody(ETypes, isPacked);
return ST; return ST;
} }
@@ -478,6 +478,48 @@ StructType *StructType::get(Type *type, ...) {
return llvm::StructType::get(Ctx, StructFields); 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, StructType *StructType::createNamed(LLVMContext &Context, StringRef Name,
ArrayRef<Type*> Elements, bool isPacked) { ArrayRef<Type*> Elements, bool isPacked) {
StructType *ST = createNamed(Context, Name); StructType *ST = createNamed(Context, Name);
@@ -506,7 +548,7 @@ StructType *StructType::createNamed(StringRef Name, Type *type, ...) {
} }
StringRef StructType::getName() const { StringRef StructType::getName() const {
assert(!isAnonymous() && "Anonymous structs never have names"); assert(!isLiteral() && "Literal structs never have names");
if (SymbolTableEntry == 0) return StringRef(); if (SymbolTableEntry == 0) return StringRef();
return ((StringMapEntry<StructType*> *)SymbolTableEntry)->getKey(); return ((StringMapEntry<StructType*> *)SymbolTableEntry)->getKey();