-//===----- ConstantBuilder.h - Builder for LLVM IR constants ----*- C++ -*-===//
+//===- ConstantInitBuilder.h - Builder for LLVM IR constants ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
//===----------------------------------------------------------------------===//
//
// This class provides a convenient interface for building complex
-// global initializers.
+// global initializers of the sort that are frequently required for
+// language ABIs.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_LIB_CODEGEN_CONSTANTBUILDER_H
-#define LLVM_CLANG_LIB_CODEGEN_CONSTANTBUILDER_H
+#ifndef LLVM_CLANG_CODEGEN_CONSTANTINITBUILDER_H
+#define LLVM_CLANG_CODEGEN_CONSTANTINITBUILDER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Constants.h"
-
-#include "CodeGenModule.h"
+#include "llvm/IR/GlobalValue.h"
+#include "clang/AST/CharUnits.h"
#include <vector>
namespace clang {
namespace CodeGen {
+class CodeGenModule;
class ConstantStructBuilder;
class ConstantArrayBuilder;
}
/// Add an integer value of type size_t.
- void addSize(CharUnits size) {
- add(Builder.CGM.getSize(size));
- }
+ void addSize(CharUnits size);
/// Add an integer value of a specific type.
void addInt(llvm::IntegerType *intTy, uint64_t value,
}
/// Add a bunch of new values to this initializer.
- void addAll(ArrayRef<llvm::Constant *> values) {
+ void addAll(llvm::ArrayRef<llvm::Constant *> values) {
assert(!Finished && "cannot add more values after finishing builder");
assert(!Frozen && "cannot add values while subbuilder is active");
Builder.Buffer.append(values.begin(), values.end());
///
/// The returned pointer will have type T*, where T is the given
/// position.
- llvm::Constant *getAddrOfCurrentPosition(llvm::Type *type) {
- // Make a global variable. We will replace this with a GEP to this
- // position after installing the initializer.
- auto dummy =
- new llvm::GlobalVariable(Builder.CGM.getModule(), type, true,
- llvm::GlobalVariable::PrivateLinkage,
- nullptr, "");
- Builder.SelfReferences.emplace_back(dummy);
- auto &entry = Builder.SelfReferences.back();
- (void) getGEPIndicesToCurrentPosition(entry.Indices);
- return dummy;
- }
+ llvm::Constant *getAddrOfCurrentPosition(llvm::Type *type);
- ArrayRef<llvm::Constant*> getGEPIndicesToCurrentPosition(
+ llvm::ArrayRef<llvm::Constant*> getGEPIndicesToCurrentPosition(
llvm::SmallVectorImpl<llvm::Constant*> &indices) {
getGEPIndicesTo(indices, Builder.Buffer.size());
return indices;
private:
void getGEPIndicesTo(llvm::SmallVectorImpl<llvm::Constant*> &indices,
- size_t position) const {
- // Recurse on the parent builder if present.
- if (Parent) {
- Parent->getGEPIndicesTo(indices, Begin);
-
- // Otherwise, add an index to drill into the first level of pointer.
- } else {
- assert(indices.empty());
- indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty, 0));
- }
-
- assert(position >= Begin);
- // We have to use i32 here because struct GEPs demand i32 indices.
- // It's rather unlikely to matter in practice.
- indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty,
- position - Begin));
- }
+ size_t position) const;
};
template <class Impl>
bool constant = false,
llvm::GlobalValue::LinkageTypes linkage
= llvm::GlobalValue::InternalLinkage,
- unsigned addressSpace = 0) {
- auto GV = new llvm::GlobalVariable(CGM.getModule(),
- initializer->getType(),
- constant,
- linkage,
- initializer,
- name,
- /*insert before*/ nullptr,
- llvm::GlobalValue::NotThreadLocal,
- addressSpace);
- GV->setAlignment(alignment.getQuantity());
- resolveSelfReferences(GV);
- return GV;
- }
+ unsigned addressSpace = 0);
void setGlobalInitializer(llvm::GlobalVariable *GV,
- llvm::Constant *initializer) {
- GV->setInitializer(initializer);
- resolveSelfReferences(GV);
- }
+ llvm::Constant *initializer);
- void resolveSelfReferences(llvm::GlobalVariable *GV) {
- for (auto &entry : SelfReferences) {
- llvm::Constant *resolvedReference =
- llvm::ConstantExpr::getInBoundsGetElementPtr(
- GV->getValueType(), GV, entry.Indices);
- entry.Dummy->replaceAllUsesWith(resolvedReference);
- entry.Dummy->eraseFromParent();
- }
- }
+ void resolveSelfReferences(llvm::GlobalVariable *GV);
};
/// A helper class of ConstantInitBuilder, used for building constant
private:
/// Form an array constant from the values that have been added to this
/// builder.
- llvm::Constant *finishImpl() {
- markFinished();
-
- auto &buffer = getBuffer();
- assert((Begin < buffer.size() ||
- (Begin == buffer.size() && EltTy))
- && "didn't add any array elements without element type");
- auto elts = llvm::makeArrayRef(buffer).slice(Begin);
- auto eltTy = EltTy ? EltTy : elts[0]->getType();
- auto type = llvm::ArrayType::get(eltTy, elts.size());
- auto constant = llvm::ConstantArray::get(type, elts);
- buffer.erase(buffer.begin() + Begin, buffer.end());
- return constant;
- }
+ llvm::Constant *finishImpl();
};
inline ConstantArrayBuilder
: AggregateBuilder(builder, parent), Ty(ty) {}
/// Finish the struct.
- llvm::Constant *finishImpl() {
- markFinished();
-
- auto &buffer = getBuffer();
- assert(Begin < buffer.size() && "didn't add any struct elements?");
- auto elts = llvm::makeArrayRef(buffer).slice(Begin);
-
- llvm::Constant *constant;
- if (Ty) {
- constant = llvm::ConstantStruct::get(Ty, elts);
- } else {
- constant = llvm::ConstantStruct::getAnon(elts, /*packed*/ false);
- }
-
- buffer.erase(buffer.begin() + Begin, buffer.end());
- return constant;
- }
+ llvm::Constant *finishImpl();
};
inline ConstantStructBuilder
#include "CGObjCRuntime.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
#include "clang/AST/DeclObjC.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/IR/CallSite.h"
#include "CGCUDARuntime.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
#include "clang/AST/Decl.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallSite.h"
#include "CGCleanup.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "CGRecordLayout.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "CGCleanup.h"
#include "CGOpenMPRuntime.h"
#include "CodeGenFunction.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
#include "clang/AST/Decl.h"
#include "clang/AST/StmtOpenMP.h"
#include "llvm/ADT/ArrayRef.h"
#include "CGCXXABI.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/RecordLayout.h"
#include "clang/CodeGen/CGFunctionInfo.h"
CodeGenPGO.cpp
CodeGenTBAA.cpp
CodeGenTypes.cpp
+ ConstantInitBuilder.cpp
CoverageMappingGen.cpp
ItaniumCXXABI.cpp
MacroPPCallbacks.cpp
#include "CodeGenFunction.h"
#include "CodeGenPGO.h"
#include "CodeGenTBAA.h"
-#include "ConstantBuilder.h"
#include "CoverageMappingGen.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Version.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "llvm/ADT/Triple.h"
--- /dev/null
+//===--- ConstantInitBuilder.cpp - Global initializer builder -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines out-of-line routines for building initializers for
+// global variables, in particular the kind of globals that are implicitly
+// introduced by various language ABIs.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CodeGen/ConstantInitBuilder.h"
+#include "CodeGenModule.h"
+
+using namespace clang;
+using namespace CodeGen;
+
+llvm::GlobalVariable *
+ConstantInitBuilder::createGlobal(llvm::Constant *initializer,
+ const llvm::Twine &name,
+ CharUnits alignment,
+ bool constant,
+ llvm::GlobalValue::LinkageTypes linkage,
+ unsigned addressSpace) {
+ auto GV = new llvm::GlobalVariable(CGM.getModule(),
+ initializer->getType(),
+ constant,
+ linkage,
+ initializer,
+ name,
+ /*insert before*/ nullptr,
+ llvm::GlobalValue::NotThreadLocal,
+ addressSpace);
+ GV->setAlignment(alignment.getQuantity());
+ resolveSelfReferences(GV);
+ return GV;
+}
+
+void ConstantInitBuilder::setGlobalInitializer(llvm::GlobalVariable *GV,
+ llvm::Constant *initializer) {
+ GV->setInitializer(initializer);
+
+ if (!SelfReferences.empty())
+ resolveSelfReferences(GV);
+}
+
+void ConstantInitBuilder::resolveSelfReferences(llvm::GlobalVariable *GV) {
+ for (auto &entry : SelfReferences) {
+ llvm::Constant *resolvedReference =
+ llvm::ConstantExpr::getInBoundsGetElementPtr(
+ GV->getValueType(), GV, entry.Indices);
+ entry.Dummy->replaceAllUsesWith(resolvedReference);
+ entry.Dummy->eraseFromParent();
+ }
+}
+
+void ConstantInitBuilder::AggregateBuilderBase::addSize(CharUnits size) {
+ add(Builder.CGM.getSize(size));
+}
+
+llvm::Constant *
+ConstantInitBuilder::AggregateBuilderBase::getAddrOfCurrentPosition(
+ llvm::Type *type) {
+ // Make a global variable. We will replace this with a GEP to this
+ // position after installing the initializer.
+ auto dummy =
+ new llvm::GlobalVariable(Builder.CGM.getModule(), type, true,
+ llvm::GlobalVariable::PrivateLinkage,
+ nullptr, "");
+ Builder.SelfReferences.emplace_back(dummy);
+ auto &entry = Builder.SelfReferences.back();
+ (void) getGEPIndicesToCurrentPosition(entry.Indices);
+ return dummy;
+}
+
+void ConstantInitBuilder::AggregateBuilderBase::getGEPIndicesTo(
+ llvm::SmallVectorImpl<llvm::Constant*> &indices,
+ size_t position) const {
+ // Recurse on the parent builder if present.
+ if (Parent) {
+ Parent->getGEPIndicesTo(indices, Begin);
+
+ // Otherwise, add an index to drill into the first level of pointer.
+ } else {
+ assert(indices.empty());
+ indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty, 0));
+ }
+
+ assert(position >= Begin);
+ // We have to use i32 here because struct GEPs demand i32 indices.
+ // It's rather unlikely to matter in practice.
+ indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty,
+ position - Begin));
+}
+
+llvm::Constant *ConstantArrayBuilder::finishImpl() {
+ markFinished();
+
+ auto &buffer = getBuffer();
+ assert((Begin < buffer.size() ||
+ (Begin == buffer.size() && EltTy))
+ && "didn't add any array elements without element type");
+ auto elts = llvm::makeArrayRef(buffer).slice(Begin);
+ auto eltTy = EltTy ? EltTy : elts[0]->getType();
+ auto type = llvm::ArrayType::get(eltTy, elts.size());
+ auto constant = llvm::ConstantArray::get(type, elts);
+ buffer.erase(buffer.begin() + Begin, buffer.end());
+ return constant;
+}
+
+llvm::Constant *ConstantStructBuilder::finishImpl() {
+ markFinished();
+
+ auto &buffer = getBuffer();
+ assert(Begin < buffer.size() && "didn't add any struct elements?");
+ auto elts = llvm::makeArrayRef(buffer).slice(Begin);
+
+ llvm::Constant *constant;
+ if (Ty) {
+ constant = llvm::ConstantStruct::get(Ty, elts);
+ } else {
+ constant = llvm::ConstantStruct::getAnon(elts, /*packed*/ false);
+ }
+
+ buffer.erase(buffer.begin() + Begin, buffer.end());
+ return constant;
+}
#include "CGVTables.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
-#include "ConstantBuilder.h"
#include "TargetInfo.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
#include "clang/AST/Mangle.h"
#include "clang/AST/Type.h"
#include "clang/AST/StmtCXX.h"
#include "CGVTables.h"
#include "CodeGenModule.h"
#include "CodeGenTypes.h"
-#include "ConstantBuilder.h"
#include "TargetInfo.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/StmtCXX.h"