Here's a sketch of what I am proposing for ConstantBuilder.<br><br>I'd like feedback on naming conventions, doc comments, etc.<br><br><span style="font-family: courier new,monospace;">//===-- llvm/Support/ConstantBuilder.h - Builder for Constants --*- C++ -*-===//<br>
//<br>// The LLVM Compiler Infrastructure<br>//<br>// This file is distributed under the University of Illinois Open Source<br>// License. See LICENSE.TXT for details.<br>//<br>//===----------------------------------------------------------------------===//<br>
//<br>// This file defines the ConstantBuilder class, which is used as a convenient<br>// way to create LLVM Constants with a consistent and simplified interface.<br>//<br>//===----------------------------------------------------------------------===//<br>
<br>#ifndef LLVM_SUPPORT_CONSTANTBUILDER_H<br>#define LLVM_SUPPORT_CONSTANTBUILDER_H<br><br>#include "llvm/Constants.h"<br>#include "llvm/DerivedTypes.h"<br><br>namespace llvm {<br><br>/// ConstantBuilder - This provides a uniform API for creating constants.<br>
class ConstantBuilder {<br>public:<br><br> //===--------------------------------------------------------------------===//<br> // Constant arrays<br> //===--------------------------------------------------------------------===//<br>
<br> /// GetArray - return a constant array given an array type and a vector<br> /// of elements.<br> static Constant *GetArray(<br> const ArrayType *Ty, ///< The type of the array<br> const std::vector<Constant*> &V) { ///< The elements of the array<br>
return ConstantArray::get(Ty, V);<br> }<br><br> /// GetArray - return a constant array given an array type and a POD<br> /// array of elements.<br> static Constant *GetArray(<br> const ArrayType *Ty, ///< The type of the array<br>
Constant *const *Vals, ///< The elements of the array<br> unsigned NumVals) { ///< The length of the array<br> return ConstantArray::get(Ty, Vals, NumVals);<br> }<br><br> /// GetArray - return a constant array given an array type and an<br>
/// iterator pair<br> template<typename RandomAccessIterator><br> static Constant *GetArray(<br> const ArrayType *Ty, ///< The type of the array<br> RandomAccessIterator ArgBegin, ///< Iterator for the first element<br>
RandomAccessIterator ArgEnd) { ///< The elements of the array<br> return GetArray(Ty, &ArgBegin[0], ArgEnd - ArgBegin);<br> }<br><br> /// GetArrayOf - return a constant array given an element type and a vector<br>
/// of elements.<br> static Constant *GetArrayOf(<br> const Type *ElementTy, ///< The type of the array elements<br> const std::vector<Constant*> &V) { ///< The elements of the array<br>
return GetArray(ArrayType::get(ElementTy, (uint64_t) V.size()), V);<br> }<br><br> /// GetArrayOf - return a constant array given an element type and a POD<br> /// array of elements.<br> static Constant *GetArrayOf(<br>
const Type *ElementTy, ///< The type of the array elements<br> Constant *const *Vals, ///< The elements of the array<br> unsigned NumVals) { ///< The length of the array<br>
return GetArray(ArrayType::get(ElementTy, NumVals), Vals, NumVals);<br> }<br><br> /// GetArrayOf - return a constant array given an element type and an<br> /// iterator pair<br> template<typename RandomAccessIterator><br>
static Constant *GetArrayOf(<br> const Type *ElementTy, ///< The type of the array elements<br> RandomAccessIterator ArgBegin, ///< Iterator for the first element<br> RandomAccessIterator ArgEnd) { ///< The elements of the array<br>
return GetArray(<br> ArrayType::get(ElementTy, ArgEnd - ArgBegin), ArgBegin, ArgEnd);<br> }<br><br> //===--------------------------------------------------------------------===//<br> // Constant structs<br>
//===--------------------------------------------------------------------===//<br>
<br> /// GetStruct - return a constant struct given a struct type and a vector<br> /// of elements.<br> static Constant *GetStruct(<br> const StructType *Ty,<br> const std::vector<Constant*> &V) {<br>
return ConstantStruct::get(Ty, V);<br> }<br><br> /// GetStruct - return a constant struct given a context and a vector<br> /// of elements.<br> static Constant *GetStruct(<br> LLVMContext &Context,<br> const std::vector<Constant*> &V,<br>
bool Packed = false) {<br> return ConstantStruct::get(Context, V, Packed);<br> }<br><br> /// GetStruct - return a constant struct given a context and a POD<br> /// array of elements.<br> static Constant *GetStruct(<br>
LLVMContext &Context,<br> Constant *const *Vals,<br> unsigned NumVals,<br> bool Packed = false) {<br> return ConstantStruct::get(Context, Vals, NumVals, Packed);<br> }<br><br> /// GetStruct - return a constant struct given a context and an iterator<br>
/// pair.<br> template<typename RandomAccessIterator><br> static Constant *GetStruct(<br> LLVMContext &Context,<br> RandomAccessIterator ArgBegin, ///< Iterator for the first element<br> RandomAccessIterator ArgEnd) { ///< The elements of the array<br>
return GetStruct(Context, &ArgBegin[0], ArgEnd - ArgBegin);<br> }<br><br> /// GetStruct - return a constant struct given a variable number of elements,<br> /// ending with NULL.<br> static Constant *GetStruct(<br>
LLVMContext &Context,<br> Constant * Val, ...) END_WITH_NULL;<br><br> //===--------------------------------------------------------------------===//<br> // Constant expressions<br> //===--------------------------------------------------------------------===//<br>
<br> /// GetAlignOf constant expr - computes the alignment of a type in a target<br> /// independent way (Note: the return type is an i64).<br> static Constant *GetAlignOf(const Type* Ty) {<br> return ConstantExpr::getAlignOf(Ty);<br>
}<br><br> /// GetSizeOf constant expr - computes the (alloc) size of a type (in<br> /// address-units, not bits) in a target independent way (Note: the return<br> /// type is an i64).<br> ///<br> static Constant *GetSizeOf(const Type* Ty) {<br>
return ConstantExpr::getSizeOf(Ty);<br> }<br><br> /// GetOffsetOf constant expr - computes the offset of a struct field in a<br> /// target independent way (Note: the return type is an i64).<br> ///<br> static Constant *GetOffsetOf(const StructType* STy, unsigned FieldNo) {<br>
return ConstantExpr::getOffsetOf(STy, FieldNo);<br> }<br><br> /// GetOffsetOf constant expr - This is a generalized form of GetOffsetOf,<br> /// which supports any aggregate type, and any Constant index.<br> ///<br>
static Constant *GetOffsetOf(const Type* Ty, Constant *FieldNo) {<br> return ConstantExpr::getOffsetOf(Ty, FieldNo);<br> }<br><br> static Constant *GetNeg(Constant *C) {<br> return ConstantExpr::getNeg(C);<br> }<br>
<br> static Constant *GetFNeg(Constant *C) {<br> return ConstantExpr::getFNeg(C);<br> }<br><br> static Constant *GetNot(Constant *C) {<br> return ConstantExpr::getNot(C);<br> }<br><br> static Constant *GetAdd(Constant *C1, Constant *C2) {<br>
return ConstantExpr::getAdd(C1, C2);<br> }<br><br> static Constant *GetFAdd(Constant *C1, Constant *C2) {<br> return ConstantExpr::getFAdd(C1, C2);<br> }<br><br> static Constant *GetSub(Constant *C1, Constant *C2) {<br>
return ConstantExpr::getSub(C1, C2);<br> }<br><br> static Constant *GetFSub(Constant *C1, Constant *C2) {<br> return ConstantExpr::getFSub(C1, C2);<br> }<br><br> static Constant *GetMul(Constant *C1, Constant *C2) {<br>
return ConstantExpr::getMul(C1, C2);<br> }<br><br> static Constant *GetFMul(Constant *C1, Constant *C2) {<br> return ConstantExpr::getFMul(C1, C2);<br> }<br><br> static Constant *GetUDiv(Constant *C1, Constant *C2) {<br>
return ConstantExpr::getUDiv(C1, C2);<br> }<br><br> static Constant *GetSDiv(Constant *C1, Constant *C2) {<br> return ConstantExpr::getSDiv(C1, C2);<br> }<br><br> static Constant *GetFDiv(Constant *C1, Constant *C2) {<br>
return ConstantExpr::getFDiv(C1, C2);<br> }<br><br> static Constant *GetURem(Constant *C1, Constant *C2) {<br> return ConstantExpr::getURem(C1, C2);<br> }<br><br> static Constant *GetSRem(Constant *C1, Constant *C2) {<br>
return ConstantExpr::getSRem(C1, C2);<br> }<br><br> static Constant *GetFRem(Constant *C1, Constant *C2) {<br> return ConstantExpr::getFRem(C1, C2);<br> }<br><br> static Constant *GetAnd(Constant *C1, Constant *C2) {<br>
return ConstantExpr::getAnd(C1, C2);<br> }<br><br> static Constant *GetOr(Constant *C1, Constant *C2) {<br> return ConstantExpr::getOr(C1, C2);<br> }<br><br> static Constant *GetXor(Constant *C1, Constant *C2) {<br>
return ConstantExpr::getXor(C1, C2);<br> }<br><br> static Constant *GetShl(Constant *C1, Constant *C2) {<br> return ConstantExpr::getShl(C1, C2);<br> }<br><br> static Constant *GetLShr(Constant *C1, Constant *C2) {<br>
return ConstantExpr::getLShr(C1, C2);<br> }<br><br> static Constant *GetAShr(Constant *C1, Constant *C2) {<br> return ConstantExpr::getAShr(C1, C2);<br> }<br><br> static Constant *GetTrunc(Constant *C, const Type *Ty) {<br>
return ConstantExpr::getTrunc(C, Ty);<br> }<br><br> static Constant *GetSExt(Constant *C, const Type *Ty) {<br> return ConstantExpr::getSExt(C, Ty);<br> }<br><br> static Constant *GetZExt(Constant *C, const Type *Ty) {<br>
return ConstantExpr::getZExt(C, Ty);<br> }<br><br> static Constant *GetFPTrunc(Constant *C, const Type *Ty) {<br> return ConstantExpr::getFPTrunc(C, Ty);<br> }<br><br> static Constant *GetFPExtend(Constant *C, const Type *Ty) {<br>
return ConstantExpr::getFPExtend(C, Ty);<br> }<br><br> static Constant *GetUIToFP(Constant *C, const Type *Ty) {<br> return ConstantExpr::getUIToFP(C, Ty);<br> }<br><br> static Constant *GetSIToFP(Constant *C, const Type *Ty) {<br>
return ConstantExpr::getSIToFP(C, Ty);<br> }<br><br> static Constant *GetFPToUI(Constant *C, const Type *Ty) {<br> return ConstantExpr::getFPToUI(C, Ty);<br> }<br><br> static Constant *GetFPToSI(Constant *C, const Type *Ty) {<br>
return ConstantExpr::getFPToSI(C, Ty);<br> }<br><br> static Constant *GetPtrToInt(Constant *C, const Type *Ty) {<br> return ConstantExpr::getPtrToInt(C, Ty);<br> }<br><br> static Constant *GetIntToPtr(Constant *C, const Type *Ty) {<br>
return ConstantExpr::getIntToPtr(C, Ty);<br> }<br><br> static Constant *GetBitCast(Constant *C, const Type *Ty) {<br> return ConstantExpr::getBitCast(C, Ty);<br> }<br><br> static Constant *GetNSWNeg(Constant *C) {<br>
return ConstantExpr::getNSWNeg(C);<br> }<br><br> static Constant *GetNUWNeg(Constant *C) {<br> return ConstantExpr::getNUWNeg(C);<br> }<br><br> static Constant *GetNSWAdd(Constant *C1, Constant *C2) {<br> return ConstantExpr::getNSWAdd(C1, C2);<br>
}<br><br> static Constant *GetNUWAdd(Constant *C1, Constant *C2) {<br> return ConstantExpr::getNUWAdd(C1, C2);<br> }<br><br> static Constant *GetNSWSub(Constant *C1, Constant *C2) {<br> return ConstantExpr::getNSWSub(C1, C2);<br>
}<br><br> static Constant *GetNUWSub(Constant *C1, Constant *C2) {<br> return ConstantExpr::getNUWSub(C1, C2);<br> }<br><br> static Constant *GetNSWMul(Constant *C1, Constant *C2) {<br> return ConstantExpr::getNSWMul(C1, C2);<br>
}<br><br> static Constant *GetNUWMul(Constant *C1, Constant *C2) {<br> return ConstantExpr::getNUWMul(C1, C2);<br> }<br><br> static Constant *GetExactSDiv(Constant *C1, Constant *C2) {<br> return ConstantExpr::getExactSDiv(C1, C2);<br>
}<br><br> // @brief Convenience function for getting one of the casting operations<br> // using a CastOps opcode.<br> static Constant *GetCast(<br> unsigned ops, ///< The opcode for the conversion<br> Constant *C, ///< The constant to be converted<br>
const Type *Ty ///< The type to which the constant is converted<br> ) {<br> return ConstantExpr::getCast(ops, C, Ty);<br> }<br><br> // @brief Create a ZExt or BitCast cast constant expression<br> static Constant *GetZExtOrBitCast(<br>
Constant *C, ///< The constant to zext or bitcast<br> const Type *Ty ///< The type to zext or bitcast C to<br> ) {<br> return ConstantExpr::getZExtOrBitCast(C, Ty);<br> }<br><br> // @brief Create a SExt or BitCast cast constant expression<br>
static Constant *GetSExtOrBitCast(<br> Constant *C, ///< The constant to sext or bitcast<br> const Type *Ty ///< The type to sext or bitcast C to<br> ) {<br> return ConstantExpr::getSExtOrBitCast(C, Ty);<br>
}<br><br> // @brief Create a Trunc or BitCast cast constant expression<br> static Constant *GetTruncOrBitCast(<br> Constant *C, ///< The constant to trunc or bitcast<br> const Type *Ty ///< The type to trunc or bitcast C to<br>
) {<br> return ConstantExpr::getTruncOrBitCast(C, Ty);<br> }<br><br> /// @brief Create a BitCast or a PtrToInt cast constant expression<br> static Constant *GetPointerCast(<br> Constant *C, ///< The pointer value to be casted (operand 0)<br>
const Type *Ty ///< The type to which cast should be made<br> ) {<br> return ConstantExpr::getPointerCast(C, Ty);<br> }<br><br> /// @brief Create a ZExt, Bitcast or Trunc for integer -> integer casts<br> static Constant *GetIntegerCast(<br>
Constant *C, ///< The integer constant to be casted<br> const Type *Ty, ///< The integer type to cast to<br> bool isSigned ///< Whether C should be treated as signed or not<br> ) {<br> return ConstantExpr::getIntegerCast(C, Ty, isSigned);<br>
}<br><br> /// @brief Create a FPExt, Bitcast or FPTrunc for fp -> fp casts<br> static Constant *GetFPCast(<br> Constant *C, ///< The integer constant to be casted<br> const Type *Ty ///< The integer type to cast to<br>
) {<br> return ConstantExpr::getFPCast(C, Ty);<br> }<br><br> /// Select constant expr<br> static Constant *GetSelect(Constant *C, Constant *V1, Constant *V2) {<br> return ConstantExpr::getSelect(C, V1, V2);<br>
}<br><br> /// @brief Return an ICmp or FCmp comparison operator constant expression.<br> static Constant *GetCompare(unsigned short pred, Constant *C1, Constant *C2) {<br> return ConstantExpr::getCompare(pred, C1, C2);<br>
}<br><br> static Constant *GetICmp(unsigned short pred, Constant *C1, Constant *C2) {<br> return ConstantExpr::getICmp(pred, C1, C2);<br> }<br><br> static Constant *GetFCmp(unsigned short pred, Constant *C1, Constant *C2) {<br>
return ConstantExpr::getFCmp(pred, C1, C2);<br> }<br><br> //===--------------------------------------------------------------------===//<br> // Constant GEPs<br> //===--------------------------------------------------------------------===//<br>
<br> static Constant *GetGEP(<br> Constant *C, ///< Pointer to item being indexed<br> Constant *const *IdxList, ///< List of indices<br> unsigned NumIdx) { ///< Number of indices<br>
return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx);<br> }<br><br> template<typename RandomAccessIterator><br> static Constant *GetGEP(<br> Constant *C, ///< Pointer to item being indexed<br>
RandomAccessIterator ArgBegin, ///< Iterator for the first element<br> RandomAccessIterator ArgEnd) { ///< The elements of the array<br> return GetGEP(C, &ArgBegin[0], ArgEnd - ArgBegin);<br>
}<br><br> static Constant *GetGEP(<br> Constant *C, ///< Pointer to item being indexed<br> Constant * Idx, ...) END_WITH_NULL; ///< List of indices<br><br> static Constant *GetGEP1_32(<br>
Constant *C, ///< Pointer to item being indexed<br> unsigned Idx0); ///< Index 0 of GEP<br><br> static Constant *GetGEP2_32(<br> Constant *C, ///< Pointer to item being indexed<br>
unsigned Idx0, ///< Index 0 of GEP<br> unsigned Idx1); ///< Index 1 of GEP<br><br> static Constant *GetGEP1_64(<br> Constant *C, ///< Pointer to item being indexed<br>
uint64_t Idx0); ///< Index 0 of GEP<br><br> static Constant *GetGEP2_64(<br> Constant *C, ///< Pointer to item being indexed<br> uint64_t Idx0, ///< Index 0 of GEP<br>
uint64_t Idx1); ///< Index 1 of GEP<br><br> //===--------------------------------------------------------------------===//<br> // Constant Inbounds GEPs<br> //===--------------------------------------------------------------------===//<br>
<br> static Constant *GetInBoundsGEP(<br> Constant *C, ///< Pointer to item being indexed<br> Constant *const *IdxList, ///< POD array of indices<br> unsigned NumIdx) { ///< Number of indices<br>
return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx);<br> }<br><br> template<typename RandomAccessIterator><br> static Constant *GetInBoundsGEP(<br> Constant *C, ///< Pointer to item being indexed<br>
RandomAccessIterator ArgBegin, ///< Iterator for the first element<br> RandomAccessIterator ArgEnd) { ///< The elements of the array<br> return GetInBoundsGEP(C, &ArgBegin[0], ArgEnd - ArgBegin);<br>
}<br><br> static Constant *GetInBoundsGEP(<br> Constant *C, ///< Pointer to item being indexed<br> Constant * Idx, ...) END_WITH_NULL; ///< List of indices<br><br> static Constant *GetInBoundsGEP1_32(<br>
Constant *C, ///< Pointer to item being indexed<br> unsigned Idx0); ///< Index 0 of GEP<br><br> static Constant *GetInBoundsGEP2_32(<br> Constant *C, ///< Pointer to item being indexed<br>
unsigned Idx0, ///< Index 0 of GEP<br> unsigned Idx1); ///< Index 1 of GEP<br><br> static Constant *GetInBoundsGEP1_64(<br> Constant *C, ///< Pointer to item being indexed<br>
uint64_t Idx0); ///< Index 0 of GEP<br><br> static Constant *GetInBoundsGEP2_64(<br> Constant *C, ///< Pointer to item being indexed<br> uint64_t Idx0, ///< Index 0 of GEP<br>
uint64_t Idx1); ///< Index 1 of GEP<br><br> static Constant *GetStructGEP(<br> Constant *C, ///< Pointer to item being indexed<br> uint64_t Idx) { ///< Index of struct field<br>
return GetInBoundsGEP2_32(C, 0, Idx);<br> }<br><br> //===--------------------------------------------------------------------===//<br> // Constant Aggregate Ops<br> //===--------------------------------------------------------------------===//<br>
<br> static Constant *GetExtractElement(Constant *Vec, Constant *Idx) {<br> return ConstantExpr::getExtractElement(Vec, Idx);<br> }<br><br> static Constant *GetInsertElement(<br> Constant *Vec,<br> Constant *Elt,<br>
Constant *Idx) {<br> return ConstantExpr::getInsertElement(Vec, Elt, Idx);<br> }<br><br> static Constant *GetExtractValue(<br> Constant *Agg,<br> const unsigned *IdxList,<br> unsigned NumIdx) {<br> return ConstantExpr::getExtractValue(Agg, IdxList, NumIdx);<br>
}<br><br> static Constant *GetInsertValue(<br> Constant *Agg,<br> Constant *Val,<br> const unsigned *IdxList,<br> unsigned NumIdx) {<br> return ConstantExpr::getInsertValue(Agg, Val, IdxList, NumIdx);<br>
}<br><br> static Constant *GetShuffleVector(<br> Constant *V1,<br> Constant *V2,<br> Constant *Mask) {<br> return ConstantExpr::getShuffleVector(V1, V2, Mask);<br> }<br>};<br><br>}<br><br>#endif<br></span><br>