mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-13 11:23:14 +01:00
This avoids problems where we would codegen children of an "inner" template instantiation (i.e. a member of a non-template aggregate in another module) because we have no way to know the outer (declare-only) entity exists in the respective mustDefineSymbol invocation. An example for this are the std.typecons.RefCounted internals of std.file.DirIterator, as used from std.datetime and other modules. This is not only inefficient, but also causes linking issues due to attribute inference for these functions not having run yet (and consequently the mangled name being different from the actual definition).
158 lines
5.2 KiB
C++
158 lines
5.2 KiB
C++
//===-- ir/iraggr.h - Codegen state for D aggregates ------------*- C++ -*-===//
|
||
//
|
||
// LDC – the LLVM D compiler
|
||
//
|
||
// This file is distributed under the BSD-style LDC license. See the LICENSE
|
||
// file for details.
|
||
//
|
||
//===----------------------------------------------------------------------===//
|
||
//
|
||
// Represents the state of a D aggregate (struct/class) on its way through
|
||
// codegen, also managing the associated init and RTTI symbols.
|
||
//
|
||
//===----------------------------------------------------------------------===//
|
||
|
||
#ifndef LDC_IR_IRAGGR_H
|
||
#define LDC_IR_IRAGGR_H
|
||
|
||
#include "ir/ir.h"
|
||
#include "llvm/ADT/SmallVector.h"
|
||
#include <map>
|
||
#include <vector>
|
||
|
||
// DMD forward declarations
|
||
struct StructInitializer;
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
|
||
// represents a struct or class
|
||
// it is used during codegen to hold all the vital info we need
|
||
struct IrAggr
|
||
{
|
||
/// Constructor.
|
||
IrAggr(AggregateDeclaration* agg);
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
// public fields,
|
||
// FIXME this is basically stuff I just haven't gotten around to yet.
|
||
|
||
/// The D aggregate.
|
||
AggregateDeclaration* aggrdecl;
|
||
|
||
/// Aggregate D type.
|
||
Type* type;
|
||
|
||
/// true only for: align(1) struct S { ... }
|
||
bool packed;
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
|
||
/// Create the __initZ symbol lazily.
|
||
LLGlobalVariable* getInitSymbol();
|
||
/// Builds the __initZ initializer constant lazily.
|
||
LLConstant* getDefaultInit();
|
||
|
||
/// Create the __vtblZ symbol lazily.
|
||
LLGlobalVariable* getVtblSymbol();
|
||
/// Builds the __vtblZ initializer constant lazily.
|
||
LLConstant* getVtblInit();
|
||
|
||
/// Create the __ClassZ symbol lazily.
|
||
LLGlobalVariable* getClassInfoSymbol();
|
||
/// Builds the __ClassZ initializer constant lazily.
|
||
LLConstant* getClassInfoInit();
|
||
|
||
/// Create the __interfaceInfos symbol lazily.
|
||
LLGlobalVariable* getInterfaceArraySymbol();
|
||
|
||
/// Creates a StructInitializer constant.
|
||
LLConstant* createStructInitializer(StructInitializer* si);
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
|
||
/// Initialize interface.
|
||
void initializeInterface();
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
|
||
typedef std::map<VarDeclaration*, llvm::Constant*> VarInitMap;
|
||
|
||
/// Creates an initializer constant for the struct type with the given
|
||
/// fields set to the provided constants. The remaining space (not
|
||
/// explicitly specified fields, padding) is default-initialized.
|
||
///
|
||
/// The optional initializerType parmeter can be used to specify the exact
|
||
/// LLVM type to use for the initializer. If non-null and non-opaque, the
|
||
/// type must exactly match the generated constant. This parameter is used
|
||
/// mainly for supporting legacy code.
|
||
///
|
||
/// Note that in the general case (if e.g. unions are involved), the
|
||
/// returned type is not necessarily the same as getLLType().
|
||
llvm::Constant* createInitializerConstant(
|
||
const VarInitMap& explicitInitializers,
|
||
llvm::StructType* initializerType = 0);
|
||
|
||
protected:
|
||
/// Static default initializer global.
|
||
LLGlobalVariable* init;
|
||
/// Static default initializer constant.
|
||
LLConstant* constInit;
|
||
/// Static default initialier type.
|
||
LLStructType* init_type;
|
||
|
||
/// Vtbl global.
|
||
LLGlobalVariable* vtbl;
|
||
/// Vtbl initializer constant.
|
||
LLConstant* constVtbl;
|
||
|
||
/// ClassInfo global.
|
||
LLGlobalVariable* classInfo;
|
||
/// ClassInfo initializer constant.
|
||
LLConstant* constClassInfo;
|
||
|
||
/// Map for mapping ClassDeclaration* to LLVM GlobalVariable.
|
||
typedef std::map<ClassDeclaration*, llvm::GlobalVariable*> ClassGlobalMap;
|
||
|
||
/// Map from of interface vtbls implemented by this class.
|
||
ClassGlobalMap interfaceVtblMap;
|
||
|
||
/// Interface info array global.
|
||
/// Basically: static object.Interface[num_interfaces]
|
||
llvm::GlobalVariable* classInterfacesArray;
|
||
|
||
/// std::vector of BaseClass*
|
||
typedef std::vector<BaseClass*> BaseClassVector;
|
||
|
||
/// Array of all interface vtbl implementations - in order - implemented
|
||
/// by this class.
|
||
/// Corresponds to the Interface instances needed to be output.
|
||
BaseClassVector interfacesWithVtbls;
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
|
||
/// Returns vtbl for interface implementation, creates it if not already built.
|
||
llvm::GlobalVariable* getInterfaceVtbl(
|
||
BaseClass* b,
|
||
bool new_inst,
|
||
size_t interfaces_index);
|
||
|
||
// FIXME make this a member instead
|
||
friend LLConstant* DtoDefineClassInfo(ClassDeclaration* cd);
|
||
|
||
/// Create the Interface[] interfaces ClassInfo field initializer.
|
||
LLConstant* getClassInfoInterfaces();
|
||
|
||
private:
|
||
/// Recursively adds all the initializers for the given aggregate and, in
|
||
/// case of a class type, all its base classes.
|
||
void addFieldInitializers(
|
||
llvm::SmallVectorImpl<llvm::Constant*>& constants,
|
||
const VarInitMap& explicitInitializers,
|
||
AggregateDeclaration* decl,
|
||
unsigned& offset);
|
||
};
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
|
||
#endif
|