11 #include <llvm/IR/DIBuilder.h> 12 #include <llvm/IR/DebugInfo.h> 13 #include <llvm/IR/DerivedTypes.h> 15 #if LLVM_VERSION_LESS_EQUAL(3, 6) 16 #include <llvm/IR/Module.h> 22 : mModule{&mod}, mContext{&mod.context()}, mName{std::move(
name)} {}
25 assert(!newName.empty() &&
"Cannot pass an empty name to GraphStruct::setName");
29 auto oldName =
name();
30 mName = std::move(newName);
33 if (updateReferences) {
37 for (
auto makeInst : makeInstances) {
38 std::unique_ptr<NodeType> type;
41 if (!res) {
return {}; }
43 makeInst->setType(std::move(type));
49 for (
auto breakInst : breakInstances) {
50 std::unique_ptr<NodeType> type;
53 if (!res) {
return {}; }
55 breakInst->setType(std::move(type));
59 makeInstances.reserve(breakInstances.size() + makeInstances.size());
60 std::copy(breakInstances.begin(), breakInstances.end(), std::back_inserter(makeInstances));
69 assert(addBefore <=
types().size() && ty.
valid());
74 mTypes.emplace_back(name, ty);
79 if (updateReferences) { updateNodeReferences(); }
83 bool updateReferences) {
84 assert(
id <
types().size() && newTy.
valid() && !newName.empty());
89 mTypes[id] = {std::move(newName), std::move(newTy)};
94 if (updateReferences) { updateNodeReferences(); }
98 assert(
id <
types().size());
103 mTypes.erase(mTypes.begin() + id);
108 if (updateReferences) { updateNodeReferences(); }
113 if (mDataType.
valid()) {
return mDataType; }
115 if (
types().empty()) {
return {}; }
118 std::vector<llvm::Type*> llTypes;
119 llTypes.reserve(
types().size());
122 #if LLVM_VERSION_LESS_EQUAL(3, 5) 129 diTypes.reserve(
types().size());
131 size_t currentOffset = 0;
133 #if LLVM_VERSION_LESS_EQUAL(3, 6) 136 auto diBuilder = std::make_unique<llvm::DIBuilder>(*tmpMod);
139 for (
const auto& type :
types()) {
140 auto debugType = type.type.debugType();
142 llTypes.push_back(type.type.llvmType());
145 #if LLVM_VERSION_LESS_EQUAL(3, 6) 146 diBuilder->createMemberType(llvm::DIDescriptor(), type.name, llvm::DIFile(), 0,
147 debugType->getSizeInBits(), 8, currentOffset, 0, *debugType)
150 #if LLVM_VERSION_LESS_EQUAL(3, 8) 151 llvm::MDString::get(
context().llvmContext(), type.name),
155 nullptr, 0,
nullptr, debugType, debugType->getSizeInBits(), 8,
157 #if LLVM_VERSION_AT_LEAST(5, 0) 160 llvm::DINode::DIFlags{},
nullptr)
164 diTypes.push_back(member);
166 currentOffset += debugType->getSizeInBits();
168 auto llType = llvm::StructType::create(llTypes,
name());
171 #if LLVM_VERSION_LESS_EQUAL(3, 6) 172 new llvm::DICompositeType(diBuilder->createStructType(
173 llvm::DIDescriptor(),
name(), llvm::DIFile(), 0, currentOffset, 8, 0, llvm::DIType(),
174 diBuilder->getOrCreateArray(
177 llvm::DICompositeType::get(
178 context().llvmContext(), llvm::dwarf::DW_TAG_structure_type,
name(),
nullptr, 0,
179 nullptr,
nullptr, currentOffset, 8, 0, llvm::DINode::DIFlags{},
180 llvm::MDTuple::get(
context().llvmContext(), diTypes), 0,
nullptr, {},
"")
189 void GraphStruct::updateNodeReferences() {
192 for (
auto inst : makeInstances) {
194 std::unique_ptr<NodeType> ty;
196 if (!res) {
return; }
198 inst->setType(std::move(ty));
201 auto breakInstances =
203 for (
auto inst : breakInstances) {
205 std::unique_ptr<NodeType> ty;
207 if (!res) {
return; }
209 inst->setType(std::move(ty));
std::vector< NodeInstance * > setName(std::string newName, bool updateReferences=true)
Set the name of the struct, and optionally update all references in the context.
const std::string & name() const
Get the name of the type.
void modifyType(size_t id, DataType newTy, std::string newName, bool updateReferences=true)
Change the type and name of a type.
Defines the Result class and related functions.
GraphModule & module() const
Get the module.
std::vector< NodeInstance * > findInstancesOfType(const boost::filesystem::path &moduleName, boost::string_view typeName) const
Find all uses of a node type in all the loaded modules.
GraphStruct(GraphModule &mod, std::string name)
GraphType constructor; don't use this use GraphModule::newStruct.
Context & context() const
Get the context.
DataType dataType()
Get the DataType of the struct.
Defines the NodeType class.
llvm::LLVMContext & llvmContext()
Get the LLVMContext
void removeType(size_t id, bool updateReferences=true)
Remove a type from a struct.
const std::vector< NamedDataType > & types() const
Get the types the struct contains.
void updateLastEditTime(std::time_t newLastEditTime=std::time(nullptr))
Update the last edit time, signifying that it's been edited.
Result nodeTypeFromName(boost::string_view name, const nlohmann::json &jsonData, std::unique_ptr< NodeType > *toFill) override
Create a node type that is in the module from the name and json.
bool valid() const
Check if the DataType is valid (if it's actually bound to a type and module)
void addType(DataType ty, std::string name, size_t addBefore, bool updateReferences=true)
Add a new type to the struct.
Module that holds graph functions.
Defines the GraphModule class.
The namespace where chigraph lives.
Defines the Context class and related functions.
A type of data Loose wrapper around llvm::Type*, except it knows which ChiModule it's in and it embed...
Defines the NodeInstance class and related functions.