diff --git a/llvm/docs/LangRef.html b/llvm/docs/LangRef.html index b20f085176ed..8190e7dc8dd1 100644 --- a/llvm/docs/LangRef.html +++ b/llvm/docs/LangRef.html @@ -2031,20 +2031,22 @@ in signal handlers).

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.

+ 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.

-

Structures can either be "anonymous" or "named". An anonymous structure is - defined inline with other types (e.g. {i32, i32}*) 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. +

Structures can either be "literal" or "identified". A literal structure is + defined inline with other types (e.g. {i32, i32}*) 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.

Syntax:
-  %T1 = type { <type list> }     ; Named normal struct type
-  %T2 = type <{ <type list> }>   ; Named packed struct type
+  %T1 = type { <type list> }     ; Identified normal struct type
+  %T2 = type <{ <type list> }>   ; Identified packed struct type
 
Examples:
diff --git a/llvm/include/llvm/DerivedTypes.h b/llvm/include/llvm/DerivedTypes.h index f90eb4258123..ff5ee6575e14 100644 --- a/llvm/include/llvm/DerivedTypes.h +++ b/llvm/include/llvm/DerivedTypes.h @@ -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 Elements, + StringRef Name, + bool isPacked = false); + static StructType *create(ArrayRef Elements); + static StructType *create(LLVMContext &Context, + ArrayRef Elements, + StringRef Name, + bool isPacked = false); + static StructType *create(LLVMContext &Context, ArrayRef 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 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 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 Elements, bool isPacked = false); void setBody(Type *elt1, ...) END_WITH_NULL; diff --git a/llvm/lib/VMCore/Type.cpp b/llvm/lib/VMCore/Type.cpp index bf8af07030a6..f7ba59606abc 100644 --- a/llvm/lib/VMCore/Type.cpp +++ b/llvm/lib/VMCore/Type.cpp @@ -392,7 +392,7 @@ StructType *StructType::get(LLVMContext &Context, ArrayRef 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 Elements, + StringRef Name, bool isPacked) { + StructType *ST = createNamed(Context, Name); + ST->setBody(Elements, isPacked); + return ST; +} + +StructType *StructType::create(LLVMContext &Context, ArrayRef Elements) { + return create(Context, Elements, StringRef()); +} + + +StructType *StructType::create(ArrayRef 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 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 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 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 *)SymbolTableEntry)->getKey();