diff --git a/docs/LangRef.html b/docs/LangRef.html index 08d84df4a8f..5959b3d5dca 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -74,16 +74,14 @@
The structure type is used to represent a collection of data members together - in memory. The packing of the field types is defined to match the ABI of the - underlying processor. The elements of a structure may be any type that has a - size.
+ in memory. The elements of a structure may be any type that has a size.Structures in memory are accessed using 'load' and 'store' by getting a pointer to a field @@ -1852,66 +1849,76 @@ synchronization behavior.
Structures in registers are accessed using the 'extractvalue' and 'insertvalue' instructions. + +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.
+ +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. +
+- { <type list> } + %T1 = type { <type list> } ; Named normal struct type + %T2 = type <{ <type list> }> ; Named packed struct type- +
{ i32, i32, i32 } | A triple of three i32 values | -
{ float, i32 (i32) * } | A pair, where the first element is a float and the second element is a pointer to a function that takes an i32, returning an i32. |
<{ i8, i32 }> | +A packed struct known to be 5 bytes in size. | +
The packed structure type is used to represent a collection of data members - together in memory. There is no padding between fields. Further, the - alignment of a packed structure is 1 byte. The elements of a packed - structure may be any type that has a size.
- -Structures are accessed using 'load and - 'store' by getting a pointer to a field with - the 'getelementptr' instruction.
+Opaque types are used to represent named structure types that do not have a + body specified. This corresponds (for example) to the C notion of a forward + declared structure.
- < { <type list> } > + %X = type opaque + %52 = type opaque
< { i32, i32, i32 } > | -A triple of three i32 values | -||
-< { float, i32 (i32)* } > | -A pair, where the first element is a float and the - second element is a pointer to a - function that takes an i32, returning - an i32. | +opaque | +An opaque type. |
Opaque types are used to represent unknown types in the system. This - corresponds (for example) to the C notion of a forward declared structure - type. In LLVM, opaque types can eventually be resolved to any type (not just - a structure type).
- -- opaque -- -
opaque | -An opaque type. | -
An "up reference" allows you to refer to a lexically enclosing type without - requiring it to have a name. For instance, a structure declaration may - contain a pointer to any of the types it is lexically a member of. Example - of up references (with their equivalent as named type declarations) - include:
- -- { \2 * } %x = type { %x* } - { \2 }* %y = type { %y }* - \1* %z = type %z* -- -
An up reference is needed by the asmprinter for printing out cyclic types - when there is no declared name for a type in the cycle. Because the - asmprinter does not want to print out an infinite type string, it needs a - syntax to handle recursive types that have no names (all names are optional - in llvm IR).
- -- \<level> -- -
The level is the count of the lexical type that is being referred to.
- -\1* | -Self-referential pointer. | -
{ { \3*, i8 }, i32 } | -Recursive structure where the upref refers to the out-most - structure. | -
-The LLVM type system has a very simple goal: allow clients to compare types for -structural equality with a simple pointer comparison (aka a shallow compare). -This goal makes clients much simpler and faster, and is used throughout the LLVM -system. -
- --Unfortunately achieving this goal is not a simple matter. In particular, -recursive types and late resolution of opaque types makes the situation very -difficult to handle. Fortunately, for the most part, our implementation makes -most clients able to be completely unaware of the nasty internal details. The -primary case where clients are exposed to the inner workings of it are when -building a recursive type. In addition to this case, the LLVM bitcode reader, -assembly parser, and linker also have to be aware of the inner workings of this -system. -
- --For our purposes below, we need three concepts. First, an "Opaque Type" is -exactly as defined in the language -reference. Second an "Abstract Type" is any type which includes an -opaque type as part of its type graph (for example "{ opaque, i32 }"). -Third, a concrete type is a type that is not an abstract type (e.g. "{ i32, -float }"). -
- - --Because the most common question is "how do I build a recursive type with LLVM", -we answer it now and explain it as we go. Here we include enough to cause this -to be emitted to an output .ll file: -
- --%mylist = type { %mylist*, i32 } --
-To build this, use the following LLVM APIs: -
- --// Create the initial outer struct -PATypeHolder StructTy = OpaqueType::get(); -std::vector<const Type*> Elts; -Elts.push_back(PointerType::getUnqual(StructTy)); -Elts.push_back(Type::Int32Ty); -StructType *NewSTy = StructType::get(Elts); - -// At this point, NewSTy = "{ opaque*, i32 }". Tell VMCore that -// the struct and the opaque type are actually the same. -cast<OpaqueType>(StructTy.get())->refineAbstractTypeTo(NewSTy); - -// NewSTy is potentially invalidated, but StructTy (a PATypeHolder) is -// kept up-to-date -NewSTy = cast<StructType>(StructTy.get()); - -// Add a name for the type to the module symbol table (optional) -MyModule->addTypeName("mylist", NewSTy); --
-This code shows the basic approach used to build recursive types: build a -non-recursive type using 'opaque', then use type unification to close the cycle. -The type unification step is performed by the refineAbstractTypeTo method, which is -described next. After that, we describe the PATypeHolder class. -
- --The refineAbstractTypeTo method starts the type unification process. -While this method is actually a member of the DerivedType class, it is most -often used on OpaqueType instances. Type unification is actually a recursive -process. After unification, types can become structurally isomorphic to -existing types, and all duplicates are deleted (to preserve pointer equality). -
- --In the example above, the OpaqueType object is definitely deleted. -Additionally, if there is an "{ \2*, i32}" type already created in the system, -the pointer and struct type created are also deleted. Obviously whenever -a type is deleted, any "Type*" pointers in the program are invalidated. As -such, it is safest to avoid having any "Type*" pointers to abstract types -live across a call to refineAbstractTypeTo (note that non-abstract -types can never move or be deleted). To deal with this, the PATypeHolder class is used to maintain a stable -reference to a possibly refined type, and the AbstractTypeUser class is used to update more -complex datastructures. -
- --PATypeHolder is a form of a "smart pointer" for Type objects. When VMCore -happily goes about nuking types that become isomorphic to existing types, it -automatically updates all PATypeHolder objects to point to the new type. In the -example above, this allows the code to maintain a pointer to the resultant -resolved recursive type, even though the Type*'s are potentially invalidated. -
- --PATypeHolder is an extremely light-weight object that uses a lazy union-find -implementation to update pointers. For example the pointer from a Value to its -Type is maintained by PATypeHolder objects. -
- --Some data structures need more to perform more complex updates when types get -resolved. To support this, a class can derive from the AbstractTypeUser class. -This class -allows it to get callbacks when certain types are resolved. To register to get -callbacks for a particular type, the DerivedType::{add/remove}AbstractTypeUser -methods can be called on a type. Note that these methods only work for - abstract types. Concrete types (those that do not include any opaque -objects) can never be refined. -
-Note that the SymbolTable class should not be directly accessed by most clients. It should only be used when iteration over the symbol table @@ -2832,13 +2660,12 @@ all LLVM an empty name) do not exist in the symbol table.
-These symbol tables support iteration over the values/types in the symbol +
Symbol tables support iteration over the values in the symbol table with begin/end/iterator and supports querying to see if a specific name is in the symbol table (with lookup). The ValueSymbolTable class exposes no public mutator methods, instead, simply call setName on a value, which will autoinsert it into the -appropriate symbol table. For types, use the Module::addTypeName method to -insert entries into the symbol table.
+appropriate symbol table.