Skip to content

Commit

Permalink
Extract source location
Browse files Browse the repository at this point in the history
  • Loading branch information
ahueck committed Dec 30, 2023
1 parent 51436c8 commit 155db2d
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 23 deletions.
5 changes: 1 addition & 4 deletions lib/type/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ set(LIB_SOURCES
TBAA.cpp
DataflowAnalysis.cpp
GEP.cpp
#MetaDB.cpp
#MetaDB.h
#MetaParseID.h
#DimetaDataID.cpp
SourceLocParser.cpp
)

add_library(dimeta_Types STATIC
Expand Down
4 changes: 4 additions & 0 deletions lib/type/Dimeta.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#ifndef DIMETA_DIMETA_H
#define DIMETA_DIMETA_H

#include "DimetaData.h"

#include <optional>
#include <variant>

Expand Down Expand Up @@ -42,6 +44,8 @@ std::optional<DimetaData> type_for(const llvm::CallBase*);

std::optional<DimetaData> type_for(const llvm::GlobalVariable*);

std::optional<location::SourceLocation> location_for(const DimetaData&);

} // namespace dimeta

#endif // DIMETA_DIMETA_H
37 changes: 27 additions & 10 deletions lib/type/DimetaData.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,25 @@
#include <vector>

namespace dimeta {

using Extent = std::uint64_t;
using Offset = std::uint64_t;
using ArraySize = std::uint64_t;

enum class Qualifier {
kNone = 0x0,
kConst = 0x1,
kPtr = 0x2,
kRef = 0x4,
};

struct Member;
struct BaseClass;
using Members = std::vector<std::shared_ptr<Member>>;
using Bases = std::vector<std::shared_ptr<BaseClass>>;
using Offsets = std::vector<Offset>;
using MemberSizes = std::vector<Extent>;
using Qualifiers = std::vector<Qualifier>;

struct CompoundType {
// struct, union, class etc.
Expand Down Expand Up @@ -73,15 +82,6 @@ struct FundamentalType {
Encoding encoding{Encoding::kUnknown};
};

enum class Qualifier {
kNone = 0x0,
kConst = 0x1,
kPtr = 0x2,
kRef = 0x4,
};

using Qualifiers = std::vector<Qualifier>;

template <typename T>
struct QualType {
T type{};
Expand All @@ -92,15 +92,32 @@ struct QualType {

using QualifiedFundamental = QualType<FundamentalType>;
using QualifiedCompound = QualType<CompoundType>;
using QualifiedType = std::variant<std::monostate, QualifiedCompound, QualifiedFundamental>;

struct BaseClass {
QualifiedCompound base{};
};

struct Member {
std::string name;
std::variant<std::monostate, QualifiedCompound, QualifiedFundamental> member;
QualifiedType member;
};

namespace location {

struct SourceLocation {
std::string file{};
std::string function{};
unsigned line{};
};

struct LocatedType {
QualifiedType type;
SourceLocation location;
};

} // namespace location

} // namespace dimeta

#endif // DIMETA_DIMETADATA_H
30 changes: 30 additions & 0 deletions lib/type/SourceLocParser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "Dimeta.h"

#include "llvm/IR/DebugInfoMetadata.h"

#include <optional>

namespace dimeta {

std::optional<location::SourceLocation> location_for(const DimetaData& data) {
if (data.di_location) {
auto loc = data.di_location.value();
return location::SourceLocation{std::string{loc->getFilename()}, //
std::string{loc->getScope()->getName()}, //
loc->getLine()};
}
if (!data.di_variable) {
return {};
}

if (const auto gv = std::get_if<llvm::DIGlobalVariable*>(&data.di_variable.value())) {
const auto* global_var = *gv;
return location::SourceLocation{std::string{global_var->getFilename()}, //
std::string{global_var->getScope()->getName()}, //
global_var->getLine()};
}

return {};
}

} // namespace dimeta
1 change: 1 addition & 0 deletions test/pass/c/global_basic.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

// CHECK: Final Type Global: {{.*}} = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
// CHECK: Pointer level: 0
// CHECK: Location: "{{.*}}":"":7

int a;

Expand Down
1 change: 1 addition & 0 deletions test/pass/c/heap_function.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ void g(int* data);
void foo(int n) {
// CHECK: Extracted Type: {{.*}} = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[DIREF:![0-9]+]], size: 64)
// CHECK: Final Type: [[DIREF]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
// CHECK: Location: "{{.*}}":"foo":12
g(malloc(sizeof(int) * n));
}
1 change: 1 addition & 0 deletions test/pass/c/heap_lhs_obj.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ void foo(int n) {
// CHECK: Extracted Type: {{.*}} = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[DIREF:![0-9]+]], size: 64)
// CHECK: Final Type: [[DIREF]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
// CHECK-NEXT: Pointer level: 1
// CHECK: Location: "{{.*}}":"foo":19
struct Data d;
*get_data(&d) = (int*)malloc(sizeof(int));
}
1 change: 1 addition & 0 deletions test/pass/c/heap_malloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
void foo(int n) {
// CHECK: Extracted Type: {{.*}} = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[DIREF:![0-9]+]], size: 64)
// CHECK: Final Type: [[DIREF]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
// CHECK: Location: "{{.*}}":"foo":9
int* p = malloc(sizeof(int) * n);
}
1 change: 1 addition & 0 deletions test/pass/c/heap_milc_struct_mock.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ void foo(int sites_on_node, int dir) {
// CHECK: Extracted Type: {{.*}} = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[DIREF:![0-9]+]], size: 64)
// CHECK: Final Type: [[DIREF]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
// CHECK-NEXT: Pointer level: 1
// CHECK: Location: "{{.*}}":"foo":36
gather_array[dir].neighbor = (int*)malloc(sites_on_node * sizeof(int));
}
1 change: 1 addition & 0 deletions test/pass/c/heap_return.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
int* foo(int n) {
// CHECK: Extracted Type: {{.*}} = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[DIREF:![0-9]+]], size: 64)
// CHECK: Final Type: [[DIREF]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
// CHECK: Location: "{{.*}}":"foo":10
return malloc(sizeof(int) * n);
}
1 change: 1 addition & 0 deletions test/pass/c/malloc_type_opt_out.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ void setVartypes(struct_grid* pgrid, int nvars, int* vartypes /* = i32 ptr */) {
taFree(pgrid->vartypes);
// CHECK: Extracted Type: {{.*}} = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[DIREF:![0-9]+]], size: 64)
// CHECK: Final Type: [[DIREF]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
// CHECK: Location: "{{.*}}":"setVartypes":21
new_vartypes = taMalloc(int, nvars); // llvm does not use bitcast (with -O1 and higher)
for (int i = 0; i < nvars; i++) {
new_vartypes[i] = vartypes[i]; // this is a memcpy (with -O1 and higher)
Expand Down
13 changes: 4 additions & 9 deletions test/verifier/TestPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"

#include <iomanip>
#include <iterator>
#include <optional>
#include <sstream>
Expand Down Expand Up @@ -98,17 +99,11 @@ const auto to_string(dimeta::DimetaData& data, bool stack = false) {
}
}();
const auto print_loc = [](auto& rso, DimetaData& data) {
if (data.di_location) {
auto loc = data.di_location.value();
rso << loc->getLine() << ", " << loc->getColumn();
auto loc = dimeta::location_for(data);
if (loc) {
rso << "\"" << loc->file << "\":\"" << loc->function << "\":" << loc->line;
return;
}
if (data.di_variable) {
if (const auto gv = *std::get_if<llvm::DIGlobalVariable*>(&data.di_variable.value())) {
rso << gv->getLine();
return;
}
}
rso << "empty";
};

Expand Down

0 comments on commit 155db2d

Please sign in to comment.