• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tudasc / TypeART / 25177145272

30 Apr 2026 04:30PM UTC coverage: 84.647% (-5.6%) from 90.246%
25177145272

Pull #188

github

web-flow
Merge 88918912c into 278119205
Pull Request #188: GPU memory allocation support

127 of 259 new or added lines in 19 files covered. (49.03%)

200 existing lines in 18 files now uncovered.

4510 of 5328 relevant lines covered (84.65%)

27776.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.6
/lib/passes/instrumentation/TypeIDProvider.cpp
1
#include "TypeIDProvider.h"
2

3
#include "TypeDB.h"
4
#include "TypeDatabase.h"
5
#include "TypeInterface.h"
6
#include "configuration/Configuration.h"
7
#include "instrumentation/TypeARTFunctions.h"
8
#include "support/ConfigurationBase.h"
9
#include "support/Logger.h"
10

11
#include <cstdint>
12
#include <llvm/ADT/ArrayRef.h>
13
#include <llvm/ADT/StringMap.h>
14
#include <llvm/ADT/StringRef.h>
15
#include <llvm/IR/BasicBlock.h>
16
#include <llvm/IR/Constant.h>
17
#include <llvm/IR/Constants.h>
18
#include <llvm/IR/GlobalValue.h>
19
#include <llvm/IR/GlobalVariable.h>
20
#include <llvm/IR/IRBuilder.h>
21
#include <llvm/IR/InstrTypes.h>
22
#include <llvm/IR/Instruction.h>
23
#include <llvm/IR/Module.h>
24
#include <llvm/IR/Type.h>
25
#include <llvm/IR/Value.h>
26
#include <llvm/Support/Casting.h>
27
#include <llvm/Support/ErrorHandling.h>
28
#include <llvm/Transforms/Utils/ModuleUtils.h>
29
#include <memory>
30
#include <optional>
31
#include <string>
32
#include <utility>
33
#include <vector>
34

35
namespace typeart {
36

37
void TypeRegistry::registerModule(const ModuleData&) {
150✔
38
}
150✔
39

40
class TypeRegistryNoOp final : public TypeRegistry {
41
 public:
42
  llvm::Value* getOrRegister(llvm::Value* type_id_const) override {
12,624✔
43
    return type_id_const;
12,624✔
44
  }
45
};
46

47
namespace helper {
48

49
void replace_whitespace_with_underscore(std::string& s) {
52,905✔
50
  std::replace_if(s.begin(), s.end(), [](unsigned char c) { return std::isspace(c); }, '_');
2,213,900✔
51
}
52,905✔
52

53
inline int get_type_id(llvm::Value* type_id_const) {
19,579✔
54
  auto* constant_int = llvm::dyn_cast<llvm::ConstantInt>(type_id_const);
19,579✔
55
  assert(constant_int && "Expected llvm::ConstantInt");
39,158✔
56
  if (constant_int == nullptr) {
19,579✔
UNCOV
57
    return TYPEART_UNKNOWN_TYPE;
×
58
  }
59
  assert(constant_int->getBitWidth() <= 32 && "Type ID is too wide");
39,158✔
60
  const int type_id = static_cast<int>(constant_int->getSExtValue());
19,579✔
61
  return type_id;
19,579✔
62
}
19,579✔
63

64
template <typename... Args>
65
inline std::string concat(Args&&... args) {
64,765✔
66
  const auto str = (std::string{} + ... + std::string{std::forward<Args>(args)});
64,765✔
67
  return str;
64,765✔
68
}
64,765✔
69

70
template <typename... Args>
71
inline std::string create_prefixed_name(Args&&... args) {
50,700✔
72
  std::string name = concat("_typeart_", std::forward<Args>(args)...);
50,700✔
73
  replace_whitespace_with_underscore(name);
50,700✔
74
  return name;
50,700✔
75
}
50,700✔
76

77
inline bool is_forward_declaration(int type_id, const TypeDatabase& db) {
37,615✔
78
  if (db.isBuiltinType(type_id)) {
37,615✔
79
    return false;
11,520✔
80
  }
81
  const auto* struct_info = db.getStructInfo(type_id);
26,095✔
82
  return struct_info != nullptr && struct_info->flag == StructTypeFlag::FWD_DECL;
26,095✔
83
}
37,615✔
84

85
inline std::string get_link_name(int type_id, const TypeDatabase& db) {
26,160✔
86
  const auto base_name = db.getTypeName(type_id);
26,160✔
87
  return is_forward_declaration(type_id, db) ? concat(base_name, "_fwd") : base_name;
26,160✔
88
}
26,160✔
89

90
inline std::string get_prefixed_name(int type_id, const TypeDatabase& db) {
19,330✔
91
  return create_prefixed_name(get_link_name(type_id, db));
19,330✔
92
}
93

94
namespace detail {
95
template <typename T, typename SourceT>
96
T safe_cast(SourceT val) {
25,405✔
97
  // Check if value exceeds the maximum limit of the target type T
98
  // We cast max() to size_t to ensure we are comparing compatible types safely
99
  assert(static_cast<size_t>(val) <= static_cast<size_t>(std::numeric_limits<T>::max()) &&
50,810✔
100
         "Data loss detected: Value exceeds target type limits!");
101
  return static_cast<T>(val);
25,405✔
102
}
103
}  // namespace detail
104

105
template <typename T>
106
std::vector<T> get_serialized_members_for(const StructTypeInfo& info) {
4,625✔
107
  using namespace detail;
108
  std::vector<T> dest;
4,625✔
109
  const size_t required_space = info.offsets.size() + info.array_sizes.size() + 2;
4,625✔
110
  dest.reserve(required_space);
4,625✔
111

112
  // Layout : [ num_member, flag, offsets...[num_member], array_sizes...[num_member] ]
113

114
  dest.push_back(safe_cast<T>(info.num_members));
4,625✔
115
  dest.push_back(safe_cast<T>(static_cast<std::underlying_type_t<StructTypeFlag>>(info.flag)));
4,625✔
116

117
  for (size_t offset : info.offsets) {
11,740✔
118
    dest.push_back(safe_cast<T>(offset));
7,115✔
119
  }
120

121
  for (size_t size : info.array_sizes) {
13,665✔
122
    dest.push_back(safe_cast<T>(size));
9,040✔
123
  }
124

125
  return dest;
4,625✔
126
}
4,625✔
127

128
}  // namespace helper
129

130
namespace typedb {
131

132
struct GlobalTypeCallback {
133
  llvm::Module* module_;
134
  const TAFunctionQuery* f_query_;
135
  llvm::StringRef ctor_function_name{"__typeart_init_module_type_globals"};
3,472✔
136

137
 private:
138
  bool has_function() const {
139
    auto func = module_->getFunction(ctor_function_name);
140
    return func != nullptr;
141
  }
142

143
  llvm::BasicBlock* make_type_callback() const {
785✔
144
    using namespace llvm;
145
    const auto makeCtorFuncBody = [&]() -> BasicBlock* {
1,570✔
146
      auto& c                = module_->getContext();
785✔
147
      FunctionType* ctorType = FunctionType::get(llvm::Type::getVoidTy(c), false);
785✔
148
      Function* ctorFunction = Function::Create(ctorType, Function::PrivateLinkage, ctor_function_name, module_);
785✔
149
      BasicBlock* entry      = BasicBlock::Create(c, "entry", ctorFunction);
785✔
150
      auto* ret_inst         = ReturnInst::Create(c);
785✔
151
#if LLVM_VERSION_MAJOR > 17
152
      ret_inst->insertInto(entry, entry->getFirstInsertionPt());
785✔
153
#else
154
      entry->getInstList().push_back(ret_inst);
155
#endif
156

157
      llvm::appendToGlobalCtors(*module_, ctorFunction, 0, nullptr);
785✔
158

159
      return entry;
785✔
160
    };
161

162
    auto* func = module_->getFunction(ctor_function_name);
785✔
163
    if (func == nullptr) {
785✔
164
      return makeCtorFuncBody();
785✔
165
    }
UNCOV
166
    return &func->getEntryBlock();
×
167
  }
785✔
168

169
  llvm::BasicBlock* get_entry() {
6,830✔
170
    auto* func = module_->getFunction(ctor_function_name);
6,830✔
171
    if (func == nullptr) {
6,830✔
172
      return make_type_callback();
785✔
173
    }
174
    return &func->getEntryBlock();
6,045✔
175
  }
6,830✔
176

177
 public:
178
  GlobalTypeCallback(llvm::Module* module, const TAFunctionQuery* f_query) : module_(module), f_query_(f_query) {
3,472✔
179
  }
3,472✔
180

181
  void insert(llvm::Constant* global) {
6,830✔
182
    auto* block = get_entry();
6,830✔
183
    for (auto& inst : *block) {
89,645✔
184
      if (auto* call_base = llvm::dyn_cast<llvm::CallBase>(&inst)) {
82,815✔
185
        auto* argument = call_base->getArgOperand(0);
75,985✔
186
        if (global == argument) {
75,985✔
187
          LOG_DEBUG("Skipping, already contained");
UNCOV
188
          return;
×
189
        }
190
      }
75,985✔
191
    }
192
    llvm::IRBuilder<> IRB{&*block->getFirstInsertionPt()};
6,830✔
193

194
    IRB.CreateCall(f_query_->getFunctionFor(IFunc::type), llvm::ArrayRef<llvm::Value*>{global});
6,830✔
195
  }
6,830✔
196
};
197

198
enum class IGlobalType : short {
199
  type_id,
200
  name,
201
  extent,
202
  num_members,
203
  member_offsets,
204
  member_types,
205
  member_count,
206
  type_flag,
207
  ptr,
208
  info_holder
209
};
210

211
struct TypeHelper {
212
  llvm::IRBuilder<>& ir_build_;
213
  explicit TypeHelper(llvm::IRBuilder<>& ir_build) : ir_build_(ir_build) {
3,472✔
214
  }
3,472✔
215

216
  llvm::Type* get_type_for(IGlobalType type, bool as_array = false) {
33,077✔
217
    switch (type) {
33,077✔
218
      case IGlobalType::type_id:
219
      case IGlobalType::extent:
220
        return ir_build_.getInt32Ty();
6,944✔
221
      case IGlobalType::type_flag:
222
      case IGlobalType::num_members:
UNCOV
223
        return ir_build_.getInt16Ty();
×
224
      case IGlobalType::member_offsets:
225
      case IGlobalType::member_types:
226
      case IGlobalType::member_count: {
227
        if (as_array) {
16,194✔
228
          return ir_build_.getInt16Ty();
4,625✔
229
        }
230
#if LLVM_VERSION_MAJOR < 15
231
        return ir_build_.getInt8PtrTy();
232
#else
233
        return ir_build_.getPtrTy();
11,569✔
234
#endif
235
      }
236
      case IGlobalType::name:
237
      case IGlobalType::ptr:
238
      case IGlobalType::info_holder:
239
#if LLVM_VERSION_MAJOR < 15
240
        return ir_build_.getInt8PtrTy();
241
#else
242
        return ir_build_.getPtrTy();
9,939✔
243
#endif
244
    }
UNCOV
245
    llvm_unreachable("Should not be reached");
×
246
  }
33,077✔
247

248
  llvm::Constant* get_constant_for(IGlobalType type, size_t value) {
39,065✔
249
    switch (type) {
39,065✔
250
      case IGlobalType::type_id:
251
      case IGlobalType::extent:
252
        return ir_build_.getInt32(value);
13,660✔
253
      case IGlobalType::type_flag:
254
      case IGlobalType::num_members:
255
      case IGlobalType::member_offsets:
256
      case IGlobalType::member_count:
257
        return ir_build_.getInt16(value);
25,405✔
258
      default:
UNCOV
259
        break;
×
260
    }
UNCOV
261
    return ir_build_.getInt32(value);
×
262
  }
39,065✔
263

264
  llvm::Constant* get_constant_nullptr() {
2,995✔
265
    return llvm::ConstantPointerNull::get(llvm::dyn_cast<llvm::PointerType>(get_type_for(IGlobalType::ptr)));
2,995✔
266
  }
267
};
268

269
struct GlobalTypeRegistrar {
270
 private:
271
  llvm::Module* module_;
272
  const TypeDatabase* type_db_;
273
  llvm::IRBuilder<> ir_build;
274
  GlobalTypeCallback type_callback;
275
  llvm::StructType* struct_layout_type_;
276
  llvm::StructType* struct_layout_type_cold_;
277
  TypeHelper types_helper;
278
  const bool builtin_emit_name{false};
3,472✔
279

280
  void declare_layout() {
3,472✔
281
    auto& context       = module_->getContext();
3,472✔
282
    struct_layout_type_ = llvm::StructType::create(context, "struct._typeart_struct_layout_t");
3,472✔
283
    struct_layout_type_->setBody({
13,888✔
284
        types_helper.get_type_for(IGlobalType::type_id),  // uint32 type_id
3,472✔
285
        types_helper.get_type_for(IGlobalType::extent),   // uint32 extent
3,472✔
286
        types_helper.get_type_for(IGlobalType::info_holder),
3,472✔
287
    });
288
    struct_layout_type_cold_ = llvm::StructType::create(context, "struct._typeart_struct_layout_info_t");
3,472✔
289
    struct_layout_type_cold_->setBody({
13,888✔
290
        types_helper.get_type_for(IGlobalType::name),            // const char* name
3,472✔
291
        types_helper.get_type_for(IGlobalType::member_offsets),  // const uint16* offsets
3,472✔
292
        types_helper.get_type_for(IGlobalType::member_types),    // const typeart_struct_layout_t** member_types
3,472✔
293
    });
294
  }
3,472✔
295

296
  llvm::GlobalVariable* create_global(
19,915✔
297
      llvm::StringRef name, llvm::Type* type, llvm::Constant* init = nullptr,
298
      llvm::GlobalVariable::LinkageTypes link_type = llvm::GlobalValue::PrivateLinkage) const {
299
    auto* global_struct =
19,915✔
300
        new llvm::GlobalVariable(*module_, type, true, link_type, init, helper::create_prefixed_name(name));
19,915✔
301
    return global_struct;
19,915✔
302
  }
303

304
  llvm::Constant* create_global_constant_string(llvm::StringRef name, llvm::StringRef payload) {
4,625✔
305
    auto* global_string =
4,625✔
306
        ir_build.CreateGlobalString(payload, helper::create_prefixed_name("typename_", name), 0, module_);
4,625✔
307
    global_string->setConstant(true);
4,625✔
308
    global_string->setLinkage(llvm::GlobalValue::PrivateLinkage);
4,625✔
309
    return global_string;
4,625✔
310
  }
311

312
  template <typename InputRange, typename ConversionFunc>
313
  llvm::Constant* create_global_array_from_range(llvm::StringRef global_name, const InputRange& inputs,
9,250✔
314
                                                 llvm::Type* element_type, ConversionFunc&& convert_element) {
315
    if (inputs.empty()) {
9,250✔
316
      LOG_DEBUG("No values for global array, returning nullptr");
317
      return types_helper.get_constant_nullptr();
790✔
318
    }
319

320
    std::vector<llvm::Constant*> constants;
8,460✔
321
    constants.reserve(inputs.size());
8,460✔
322

323
    for (const auto& val : inputs) {
42,905✔
324
      constants.push_back(convert_element(val));
34,445✔
325
    }
326

327
    auto* array_ty       = llvm::ArrayType::get(element_type, inputs.size());
8,460✔
328
    auto* constant_array = llvm::ConstantArray::get(array_ty, constants);
8,460✔
329

330
    return create_global(global_name, array_ty, constant_array);
8,460✔
331
  }
9,250✔
332

333
  template <typename T>
334
  llvm::Constant* create_global_array_ptr(const llvm::StringRef name, llvm::ArrayRef<T> values,
4,625✔
335
                                          IGlobalType type = IGlobalType::member_offsets) {
336
    return create_global_array_from_range(name, values, types_helper.get_type_for(IGlobalType::member_offsets, true),
9,250✔
337
                                          [&](const T& val) { return types_helper.get_constant_for(type, val); });
30,030✔
338
  }
339

340
  llvm::Constant* create_global_member_array_ptr(const llvm::StringRef name, llvm::ArrayRef<int> member_types) {
4,625✔
341
    return create_global_array_from_range(name, member_types, types_helper.get_type_for(IGlobalType::member_types),
9,250✔
342
                                          [&](int member_id) { return getOrRegister(member_id); });
13,665✔
343
  }
344

345
  llvm::GlobalVariable* registerTypeStruct(const StructTypeInfo* type_struct) {
6,830✔
346
    const auto base_name = type_struct->name;
6,830✔
347
    const auto type_id   = type_struct->type_id;
6,830✔
348
    const bool is_fwd    = helper::is_forward_declaration(type_id, *type_db_);
6,830✔
349
    const auto link_name = helper::get_link_name(type_id, *type_db_);
6,830✔
350

351
    if (is_fwd) {
6,830✔
352
      LOG_DEBUG("Type is forward decl " << base_name)
353
    }
85✔
354

355
    const bool is_builtin = type_struct->flag == StructTypeFlag::BUILTIN;
6,830✔
356
    const bool emit_name  = !is_builtin || builtin_emit_name;
6,830✔
357

358
    llvm::GlobalVariable* global_struct =
6,830✔
359
        create_global(link_name, struct_layout_type_, nullptr, llvm::GlobalValue::LinkOnceODRLinkage);
6,830✔
360
    global_struct->setConstant(false);
6,830✔
361

362
    llvm::Comdat* comdat = this->module_->getOrInsertComdat(helper::create_prefixed_name(link_name));
6,830✔
363
    comdat->setSelectionKind(llvm::Comdat::Any);
6,830✔
364
    global_struct->setComdat(comdat);
6,830✔
365

366
    auto add_to_comdat = [&](llvm::Constant* ptr) {
25,330✔
367
      if (auto* global = llvm::dyn_cast_or_null<llvm::GlobalObject>(ptr)) {
18,500✔
368
        global->setComdat(comdat);
17,710✔
369
      }
17,710✔
370
    };
18,500✔
371

372
    const auto get_info_object = [&]() -> llvm::Constant* {
13,660✔
373
      if (emit_name) {
6,830✔
374
        llvm::Constant* name_str_ptr = create_global_constant_string(link_name, base_name);
4,625✔
375
        const auto info_data         = helper::get_serialized_members_for<uint16_t>(*type_struct);
4,625✔
376
        llvm::Constant* data_ptr =
4,625✔
377
            create_global_array_ptr<uint16_t>(helper::concat("info_data_", link_name), info_data);
4,625✔
378
        llvm::Constant* members_ptr =
4,625✔
379
            create_global_member_array_ptr(helper::concat("member_types_", link_name), type_struct->member_types);
4,625✔
380

381
        llvm::GlobalVariable* global_struct_info =
4,625✔
382
            create_global(helper::concat(link_name, "_info"), struct_layout_type_cold_, nullptr);
4,625✔
383

384
        std::vector<llvm::Constant*> init_fields_cold = {name_str_ptr, data_ptr, members_ptr};
4,625✔
385
        global_struct_info->setInitializer(llvm::ConstantStruct::get(struct_layout_type_cold_, init_fields_cold));
4,625✔
386

387
        {
388
          add_to_comdat(global_struct_info);
4,625✔
389
          add_to_comdat(data_ptr);
4,625✔
390
          add_to_comdat(members_ptr);
4,625✔
391
          add_to_comdat(name_str_ptr);
4,625✔
392
        }
393

394
        return global_struct_info;
4,625✔
395
      }
4,625✔
396
      return types_helper.get_constant_nullptr();
2,205✔
397
    };
6,830✔
398

399
    std::vector<llvm::Constant*> init_fields = {
21,856✔
400
        types_helper.get_constant_for(IGlobalType::type_id, type_struct->type_id),
6,830✔
401
        types_helper.get_constant_for(IGlobalType::extent, type_struct->extent), get_info_object()};
13,660✔
402
    llvm::Constant* init = llvm::ConstantStruct::get(struct_layout_type_, init_fields);
6,830✔
403
    global_struct->setInitializer(init);
6,830✔
404

405
    return global_struct;
6,830✔
406
  }
6,830✔
407

408
  llvm::GlobalVariable* registerBuiltin(int type_id) {
2,205✔
409
    auto type_name = type_db_->getTypeName(type_id);
2,205✔
410
    helper::replace_whitespace_with_underscore(type_name);
2,205✔
411
    StructTypeInfo type_struct{type_id, type_name, type_db_->getTypeSize(type_id), 1, {},
6,615✔
412
                               {},      {},        StructTypeFlag::BUILTIN};
4,410✔
413
    return registerTypeStruct(&type_struct);
2,205✔
414
  }
2,205✔
415

416
  llvm::GlobalVariable* registerUserDefined(int type_id) {
4,625✔
417
    const auto* const type_struct = type_db_->getStructInfo(type_id);
4,625✔
418
    if (type_struct == nullptr) {
4,625✔
UNCOV
419
      LOG_WARNING("Struct info is nullptr for id " << type_id)
×
UNCOV
420
    }
×
421
    return registerTypeStruct(type_struct);
4,625✔
422
  }
423

424
 public:
425
  GlobalTypeRegistrar(llvm::Module* m, const TypeDatabase* type_db, const TAFunctionQuery* f_query)
3,472✔
426
      : module_(m),
3,472✔
427
        type_db_(type_db),
3,472✔
428
        ir_build(m->getContext()),
3,472✔
429
        type_callback(module_, f_query),
3,472✔
430
        types_helper(ir_build) {
3,472✔
431
    declare_layout();
3,472✔
432
  }
3,472✔
433

434
  const TypeDatabase& db() const {
6,400✔
435
    return *type_db_;
6,400✔
436
  }
437

438
  llvm::Constant* getOrRegister(int type_id) {
19,330✔
439
    const auto base_name     = type_db_->getTypeName(type_id);
19,330✔
440
    const auto prefixed_name = helper::get_prefixed_name(type_id, *type_db_);
19,330✔
441

442
    LOG_DEBUG(base_name << " aka " << prefixed_name)
443

444
    return module_->getOrInsertGlobal(prefixed_name, struct_layout_type_, [&]() -> llvm::GlobalVariable* {
26,160✔
445
      LOG_DEBUG("Registering << " << type_id << " " << base_name << " aka " << prefixed_name)
446

447
      if (type_db_->isBuiltinType(type_id)) {
6,830✔
448
        auto* global = registerBuiltin(type_id);
2,205✔
449
        type_callback.insert(global);
2,205✔
450
        return global;
2,205✔
451
      }
452

453
      auto* global = registerUserDefined(type_id);
4,625✔
454

455
      if (!helper::is_forward_declaration(type_id, *type_db_)) {
4,625✔
456
        LOG_DEBUG("Registering forward declared variable " << *global)
457
      }
4,540✔
458
      type_callback.insert(global);
4,625✔
459
      return global;
4,625✔
460
    });
6,830✔
461
  }
19,330✔
462
};  // namespace typedb
463
}  // namespace typedb
464

465
class TypeRegistryGlobals final : public TypeRegistry {
466
  // llvm::Module* module_;
467
  typedb::GlobalTypeRegistrar registrar_;
468

469
 public:
470
  TypeRegistryGlobals(llvm::Module& m, const TypeDatabase* type_db, const TAFunctionQuery* f_query)
3,472✔
471
      : registrar_(&m, type_db, f_query) {
3,472✔
472
  }
3,472✔
473

474
  void registerModule(const ModuleData& m) override {
1,416✔
475
    for (const auto& type : m.types_list) {
10,332✔
476
      if (builtins::BuiltInQuery::is_builtin_type(type.type_id)) {
8,916✔
477
        continue;
2,516✔
478
      }
479
      if (!registrar_.db().isValid(type.type_id)) {
6,400✔
480
        continue;
480✔
481
      }
482
      LOG_DEBUG("Registering type_id " << type.type_id)
483
      /*const auto* type_id =*/registrar_.getOrRegister(type.type_id);
5,920✔
484
    }
485
  }
1,416✔
486

487
  llvm::Value* getOrRegister(llvm::Value* type_id_const) override {
4,370✔
488
    return registrar_.getOrRegister(helper::get_type_id(type_id_const));
4,370✔
489
  }
490
};
491

492
class TypeRegistryAlternatives final : public TypeRegistry {
493
  TypeRegistryGlobals globals;
494
  TypeRegistryNoOp noops;
495

496
 public:
497
  TypeRegistryAlternatives(llvm::Module& m, const TypeDatabase* type_db, const TAFunctionQuery* f_query)
6,314✔
498
      : globals(m, type_db, f_query) {
3,157✔
499
  }
3,157✔
500

501
  void registerModule(const ModuleData& m) override {
1,161✔
502
    globals.registerModule(m);
1,161✔
503
  }
1,161✔
504

505
  llvm::Value* getOrRegister(llvm::Value* type_id_const) override {
15,209✔
506
    if (builtins::BuiltInQuery::is_builtin_type(helper::get_type_id(type_id_const))) {
15,209✔
507
      return noops.getOrRegister(type_id_const);
11,079✔
508
    }
509
    return globals.getOrRegister(type_id_const);
4,130✔
510
  }
15,209✔
511
};
512

513
std::unique_ptr<TypeRegistry> get_type_id_handler(llvm::Module& m, const TypeDatabase* type_db,
4,042✔
514
                                                  const config::Configuration& configuration,
515
                                                  const TAFunctionQuery* f_query) {
516
  TypeSerializationImplementation impl = configuration[config::ConfigStdArgs::type_serialization];
4,042✔
517
#if LLVM_VERSION_MAJOR < 15
518
  if (impl != typeart::TypeSerializationImplementation::FILE) {
519
    LOG_WARNING("Unsupported type serialization mode for LLVM-" << LLVM_VERSION_MAJOR)
520
  }
521
  // using llvm-14 would require opaque pointer mode for globals
522
  return std::make_unique<TypeRegistryNoOp>();
523
#else
524
  switch (impl) {
4,042✔
525
    case typeart::TypeSerializationImplementation::FILE:
526
      return std::make_unique<TypeRegistryNoOp>();
570✔
527
    case typeart::TypeSerializationImplementation::HYBRID:
528
      return std::make_unique<TypeRegistryAlternatives>(m, type_db, f_query);
3,157✔
529
    default:
530
      return std::make_unique<TypeRegistryGlobals>(m, type_db, f_query);
315✔
531
  }
532
#endif
533
}
4,042✔
534

535
}  // namespace typeart
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc