mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 01:20:51 +03:00
95 lines
2.9 KiB
C++
95 lines
2.9 KiB
C++
//===-- ir/irtypeaggr.h - IrType subclasses for aggregates ------*- C++ -*-===//
|
||
//
|
||
// LDC – the LLVM D compiler
|
||
//
|
||
// This file is distributed under the BSD-style LDC license. See the LICENSE
|
||
// file for details.
|
||
//
|
||
//===----------------------------------------------------------------------===//
|
||
|
||
#ifndef LDC_IR_IRTYPEAGGR_H
|
||
#define LDC_IR_IRTYPEAGGR_H
|
||
|
||
#include "ir/irtype.h"
|
||
#include "llvm/ADT/ArrayRef.h"
|
||
#include "llvm/IR/DebugInfo.h"
|
||
#include <map>
|
||
#include <vector>
|
||
|
||
namespace llvm {
|
||
class Constant;
|
||
class StructType;
|
||
}
|
||
|
||
class AggregateDeclaration;
|
||
class VarDeclaration;
|
||
|
||
using VarGEPIndices = std::map<VarDeclaration *, unsigned>;
|
||
|
||
class AggrTypeBuilder {
|
||
public:
|
||
explicit AggrTypeBuilder(bool packed);
|
||
void addType(llvm::Type *type, unsigned size);
|
||
void addAggregate(AggregateDeclaration *ad);
|
||
void alignCurrentOffset(unsigned alignment);
|
||
void addTailPadding(unsigned aggregateSize);
|
||
unsigned currentFieldIndex() const { return m_fieldIndex; }
|
||
std::vector<llvm::Type *> defaultTypes() const { return m_defaultTypes; }
|
||
VarGEPIndices varGEPIndices() const { return m_varGEPIndices; }
|
||
unsigned overallAlignment() const { return m_overallAlignment; }
|
||
|
||
protected:
|
||
std::vector<llvm::Type *> m_defaultTypes;
|
||
VarGEPIndices m_varGEPIndices;
|
||
unsigned m_offset = 0;
|
||
unsigned m_fieldIndex = 0;
|
||
unsigned m_overallAlignment = 0;
|
||
bool m_packed = false;
|
||
};
|
||
|
||
/// Base class of IrTypes for aggregate types.
|
||
class IrTypeAggr : public IrType {
|
||
public:
|
||
///
|
||
IrTypeAggr *isAggr() override { return this; }
|
||
|
||
/// Returns the index of the field in the LLVM struct type that corresponds
|
||
/// to the given member variable, plus the offset to the actual field start
|
||
/// due to overlapping (union) fields, if any.
|
||
void getMemberLocation(VarDeclaration *var, unsigned &fieldIndex,
|
||
unsigned &byteOffset) const;
|
||
|
||
/// Composite type debug description. This is not only to cache, but also
|
||
/// used for resolving forward references.
|
||
#if LDC_LLVM_VER >= 307
|
||
llvm::DIType *diCompositeType = nullptr;
|
||
#else
|
||
llvm::DIType diCompositeType;
|
||
#endif
|
||
|
||
/// true, if the LLVM struct type for the aggregate is declared as packed
|
||
bool packed = false;
|
||
|
||
protected:
|
||
///
|
||
explicit IrTypeAggr(AggregateDeclaration *ad);
|
||
|
||
/// Returns true, if the LLVM struct type for the aggregate must be declared
|
||
/// as packed.
|
||
static bool isPacked(AggregateDeclaration *ad);
|
||
|
||
/// AggregateDeclaration this type represents.
|
||
AggregateDeclaration *aggr = nullptr;
|
||
|
||
/// Stores the mapping from member variables to field indices in the actual
|
||
/// LLVM type. If a member variable is not present, this means that it does
|
||
/// not resolve to a "clean" GEP but extra offsetting due to overlapping
|
||
/// members is needed (i.e., a union).
|
||
///
|
||
/// We need to keep track of this separately, because there is no way to get
|
||
/// the field index of a variable in the frontend, it only stores the byte
|
||
/// offset.
|
||
VarGEPIndices varGEPIndices;
|
||
};
|
||
|
||
#endif
|