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

ahueck / llvm-dimeta / 13933486559

18 Mar 2025 09:06PM UTC coverage: 83.197% (-0.4%) from 83.637%
13933486559

push

github

web-flow
Refactoring (#35)

1027 of 1482 branches covered (69.3%)

Branch coverage included in aggregate %.

86 of 87 new or added lines in 10 files covered. (98.85%)

17 existing lines in 7 files now uncovered.

1924 of 2065 relevant lines covered (93.17%)

3950.95 hits per line

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

79.81
/lib/type/SourceLocType.cpp
1
//  llvm-dimeta library
2
//  Copyright (c) 2022-2025 llvm-dimeta authors
3
//  Distributed under the BSD 3-Clause license.
4
//  (See accompanying file LICENSE)
5
//  SPDX-License-Identifier: BSD-3-Clause
6
//
7

8
#include "Dimeta.h"
9
#include "DimetaData.h"
10
#include "DimetaParse.h"
11
#include "support/Logger.h"
12

13
#include "llvm/IR/DebugInfoMetadata.h"
14

15
#include <llvm/ADT/STLExtras.h>
16
#include <optional>
17

18
namespace dimeta {
19

20
std::optional<location::SourceLocation> location_for(const DimetaData& data) {
2,724✔
21
  if (data.di_location) {
2,724✔
22
    auto loc = data.di_location.value();
2,575✔
23
    return location::SourceLocation{std::string{loc->getFilename()},          //
7,725✔
24
                                    std::string{loc->getScope()->getName()},  //
2,575✔
25
                                    loc->getLine()};
2,575✔
26
  }
2,575✔
27
  if (!data.di_variable) {
149✔
28
    return {};
8✔
29
  }
30

31
  const auto make_source_loc = [](const auto* variable) {
282✔
32
    const auto file           = std::string{variable->getFilename()};
141✔
33
    const auto function_scope = [](const auto alloc) -> std::string {
423✔
34
      const auto* scope = alloc->getScope();
141✔
35
      if (scope) {
141!
36
        return std::string{scope->getName()};
135✔
37
      }
38
      return "";
6✔
39
    }(variable);
282✔
40
    return location::SourceLocation{file,            //
423✔
41
                                    function_scope,  //
141✔
42
                                    variable->getLine()};
141✔
43
  };
141✔
44

45
  if (const auto gv = std::get_if<llvm::DIGlobalVariable*>(&data.di_variable.value())) {
282!
46
    const auto* global_var = *gv;
141✔
47
    return make_source_loc(global_var);
141✔
48
  }
141✔
49

50
  if (const auto alloc_var = std::get_if<llvm::DILocalVariable*>(&data.di_variable.value())) {
×
51
    const auto* alloc = *alloc_var;
×
52
    return make_source_loc(alloc);
×
UNCOV
53
  }
×
54

55
  return {};
×
56
}
2,724✔
57

58
namespace detail {
59
template <class... Ts>
60
struct overload : Ts... {
61
  using Ts::operator()...;
62
};
63
template <class... Ts>
64
overload(Ts...) -> overload<Ts...>;
65

66
template <typename Type>
67
void reset_pointer_qualifier(Type& type, int ptr_level) {
2,716✔
68
  // "new" can have type_data.pointer_level != metadata pointer level -> if that is the case, we add that qualifier to
69
  // begin of list
70
  const auto add_pointer = [&](auto& f) {
5,432✔
71
    auto count = llvm::count_if(f.qual, [](auto& qual) { return qual == Qualifier::kPtr; });
4,859✔
72
    if (count < ptr_level) {
2,716✔
73
      const auto begin = f.qual.begin();
201✔
74
      f.qual.insert(begin, Qualifier{Qualifier::kPtr});
201✔
75
    }
201✔
76
  };
2,716✔
77
  std::visit(overload{[&](dimeta::QualifiedFundamental& f) -> void { add_pointer(f); },
7,128✔
78
                      [&](dimeta::QualifiedCompound& q) -> void { add_pointer(q); }},
3,736✔
79
             type);
2,716✔
80
}
2,716✔
81

82
}  // namespace detail
83

84
std::optional<LocatedType> located_type_for(const DimetaData& type_data) {
2,724✔
85
  auto loc = location_for(type_data);
2,724✔
86
  if (!loc) {
2,724✔
87
    LOG_DEBUG("Could not determine source location.");
88
    return {};
8✔
89
  }
90

91
  if (!type_data.entry_type) {
2,716!
92
    LOG_DEBUG("Could not determine type (missing entry type).");
93
    return {};
×
94
  }
95

96
  assert(type_data.entry_type.has_value() && "Parsing stack type requires entry type.");
5,432!
97
  auto dimeta_result = parser::make_dimetadata(type_data.entry_type.value());
2,716✔
98
  if (!dimeta_result) {
2,716!
99
    return {};
×
100
  }
101

102
  detail::reset_pointer_qualifier(dimeta_result->type_, type_data.pointer_level);
2,716✔
103
  return LocatedType{dimeta_result->type_, loc.value()};
2,716✔
104
}
2,724✔
105

106
template <typename IRNode>
107
std::optional<LocatedType> get_located_type(const IRNode* node) {
6,726✔
108
  auto type_data = type_for(node);
6,726✔
109
  if (!type_data) {
6,726!
110
    LOG_DEBUG("Could not determine type.");
111
    return {};
4,002✔
112
  }
113
  return located_type_for(type_data.value());
2,724✔
114
}
6,726✔
115

116
std::optional<LocatedType> located_type_for(const llvm::AllocaInst* ai) {
1,805✔
117
  return get_located_type(ai);
1,805✔
118
}
119

120
std::optional<LocatedType> located_type_for(const llvm::CallBase* cb) {
4,780✔
121
  return get_located_type(cb);
4,780✔
122
}
123

124
std::optional<LocatedType> located_type_for(const llvm::GlobalVariable* gv) {
141✔
125
  return get_located_type(gv);
141✔
126
}
127

128
}  // namespace dimeta
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