Skip to content

Commit

Permalink
Parse static members (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahueck authored Jan 27, 2025
1 parent ecc44ba commit f21f7a2
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 8 deletions.
28 changes: 22 additions & 6 deletions lib/type/DIParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "DimetaData.h"
#include "support/Logger.h"

#include <cstdlib>
#include <llvm/BinaryFormat/Dwarf.h>

namespace dimeta::diparser {
Expand Down Expand Up @@ -79,13 +80,28 @@ bool DIEventVisitor::visitBasicType(const llvm::DIBasicType* basic_type) {
bool DIEventVisitor::visitDerivedType(const llvm::DIDerivedType* derived_type) {
using namespace llvm::dwarf;

const auto make_member = [&](const auto* derived) {
current_.member_name = derived_type->getName();
current_.is_member = true;
current_.member_offset = derived_type->getOffsetInBits() / 8;
current_.member_size = derived_type->getSizeInBits() / 8;
current_.is_member_static = derived->isStaticMember();
};

const auto tag = derived_type->getTag();
switch (tag) {
case DW_TAG_member: {
current_.member_name = derived_type->getName();
current_.is_member = true;
current_.member_offset = derived_type->getOffsetInBits() / 8;
current_.member_size = derived_type->getSizeInBits() / 8;
make_member(derived_type);
break;
}
case DW_TAG_variable: {
// see test ir/02_mpicxx.ll: Datatype has a static member,
// which is encoded as a variable, and not as a member (variable)
if (!derived_type->isStaticMember()) {
LOG_WARNING("Variable is not a static member. " << *derived_type)
} else {
make_member(derived_type);
}
break;
}
case DW_TAG_typedef:
Expand Down Expand Up @@ -154,8 +170,8 @@ bool DIEventVisitor::visitCompositeType(const llvm::DICompositeType* composite_t
// See, e.g., pass/c/stack_struct_array.c:
if (composite_type->getTag() == llvm::dwarf::DW_TAG_array_type) {
current_.is_vector = composite_type->isVector();
current_.dwarf_tags.emplace_back(current_.is_vector ? state::CustomDwarfTag::kVector
: llvm::dwarf::DW_TAG_array_type);
current_.dwarf_tags.emplace_back(current_.is_vector ? static_cast<unsigned>(state::CustomDwarfTag::kVector)
: static_cast<unsigned>(llvm::dwarf::DW_TAG_array_type));
current_.arrays.emplace_back(
state::MetaData::ArrayData{composite_type->getSizeInBits(), Extent{0}, {}, composite_type->isVector()});
// current_.array_size_bits =composite_type->getSizeInBits();
Expand Down
1 change: 1 addition & 0 deletions lib/type/DIParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ struct MetaData {

llvm::SmallVector<unsigned, 8> dwarf_tags;
bool is_member{false};
bool is_member_static{false};
bool is_base_class{false};
bool has_vtable{false};
bool is_recurring{false};
Expand Down
3 changes: 2 additions & 1 deletion lib/type/DimetaData.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ enum class Qualifier {
kRef = 0x4,
kPtrToMember = 0x8,
kArray = 0x10,
kVector = 0x20
kVector = 0x20,
kStatic = 0x40
};

struct Member;
Expand Down
1 change: 1 addition & 0 deletions lib/type/DimetaIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ struct llvm::yaml::ScalarEnumerationTraits<dimeta::Qualifier> {
io.enumCase(info, "ptr_to_mem", dimeta::Qualifier::kPtrToMember);
io.enumCase(info, "array", dimeta::Qualifier::kArray);
io.enumCase(info, "vector", dimeta::Qualifier::kVector);
io.enumCase(info, "static", dimeta::Qualifier::kStatic);
}
};

Expand Down
6 changes: 5 additions & 1 deletion lib/type/DimetaParse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,11 @@ template <typename T>
inline QualType<T> make_qual_type(const T& type, const diparser::state::MetaData& meta_) {
static_assert(std::is_same_v<T, CompoundType> || std::is_same_v<T, FundamentalType>, "Wrong type.");

const Qualifiers quals = helper::make_qualifiers(meta_.dwarf_tags);
Qualifiers quals = helper::make_qualifiers(meta_.dwarf_tags);
if (meta_.is_member_static) {
// TODO should this be the last, or should it be position dependent w.r.t. dwarf_tags?
quals.emplace_back(Qualifier::kStatic);
}
const auto array_size = helper::make_array_sizes(type, meta_.arrays);
const auto typedef_name = meta_.typedef_names.empty() ? std::string{} : *meta_.typedef_names.begin();

Expand Down
2 changes: 2 additions & 0 deletions test/lit.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ if config.llvm_version < 14:
if config.llvm_version > 14:
config.available_features.add('hasopaque')

config.available_features.add('llvm-{}'.format(config.llvm_version))

config.available_features.add('{}'.format(config.llvm_version))

#config.available_features.add('local')
Expand Down
23 changes: 23 additions & 0 deletions test/pass/cpp/stack_class_basic_static.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// RUN: %cpp-to-llvm %s | %apply-verifier 2>&1 | %filecheck %s

// CHECK: Name: X
// CHECK-NEXT: Identifier: _ZTS1X
// CHECK-NEXT: Type: class
// CHECK-NEXT: Extent: 1
// CHECK-NEXT: Sizes: [ 0 ]
// CHECK-NEXT: Offsets: [ 0 ]
// CHECK-NEXT: Members:
// CHECK-NEXT: - Name: val
// CHECK-NEXT: Builtin: true
// CHECK-NEXT: Type:
// CHECK-NEXT: Fundamental: { Name: int, Extent: 4, Encoding: signed_int }
// CHECK-NEXT: Qualifiers: [ ptr, static ]

class X {
public:
static int* val;
};

void foo() {
X x;
}
39 changes: 39 additions & 0 deletions test/pass/cpp/stack_static_members.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// RUN: %cpp-to-llvm %s | %apply-verifier 2>&1 | %filecheck %s

struct Foo;

struct S {
static int a;
static Foo x;
static S s;
};

void bar() {
S struct_variable;
}

// CHECK: - Name: a
// CHECK-NEXT: Builtin: true
// CHECK-NEXT: Type:
// CHECK-NEXT: Fundamental: { Name: int, Extent: 4, Encoding: signed_int }
// CHECK-NEXT: Qualifiers: [ static ]
// CHECK-NEXT: - Name: x
// CHECK-NEXT: Builtin: false
// CHECK-NEXT: Type:
// CHECK-NEXT: Compound:
// CHECK-NEXT: Name: Foo
// CHECK-NEXT: Identifier: _ZTS3Foo
// CHECK-NEXT: Type: struct
// CHECK-NEXT: Extent: 0
// CHECK-NEXT: Qualifiers: [ static ]
// CHECK-NEXT: ForwardDecl: true
// CHECK-NEXT: - Name: s
// CHECK-NEXT: Builtin: false
// CHECK-NEXT: Type:
// CHECK-NEXT: Compound:
// CHECK-NEXT: Name: S
// CHECK-NEXT: Identifier: _ZTS1S
// CHECK-NEXT: Type: struct
// CHECK-NEXT: Extent: 1
// CHECK-NEXT: Qualifiers: [ static ]
// CHECK-NEXT: Recurring: true
68 changes: 68 additions & 0 deletions test/pass/ir/02_mpicxx.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
; RUN: %apply-verifier %s |& %filecheck %s
; CHECK-NOT: Assertion
; REQUIRES: llvm-18

; CHECK: SourceLoc:
; CHECK-NEXT: File: '/usr/lib/x86_64-linux-gnu/openmpi/include/openmpi/ompi/mpi/cxx/datatype_inln.h'
; CHECK-NEXT: Function: Create_contiguous
; CHECK-NEXT: Line: 0
; CHECK-NEXT: Builtin: false
; CHECK-NEXT: Type:
; CHECK-NEXT: Compound:
; CHECK-NEXT: Name: Datatype
; CHECK-NEXT: Identifier: _ZTSN3MPI8DatatypeE
; CHECK-NEXT: Type: class
; CHECK-NEXT: Extent: 16
; CHECK-NEXT: Sizes: [ 0 ]
; CHECK-NEXT: Offsets: [ 0 ]
; CHECK-NEXT: Members:
; CHECK-NEXT: - Name: cxx_extra_states_lock
; CHECK-NEXT: Builtin: false
; CHECK-NEXT: Type:
; CHECK-NEXT: Compound:
; CHECK-NEXT: Name: opal_mutex_t
; CHECK-NEXT: Identifier: _ZTS12opal_mutex_t
; CHECK-NEXT: Type: struct
; CHECK-NEXT: Extent: 0
; CHECK-NEXT: Qualifiers: [ static ]
; CHECK-NEXT: ForwardDecl: true
; CHECK-NEXT: Qualifiers: [ ptr, const ]


target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define void @_ZNK3MPI8Datatype17Create_contiguousEi() {
entry:
%this.addr = alloca ptr, i32 0, align 8
call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !4, metadata !DIExpression()), !dbg !18
ret void
}

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare void @llvm.dbg.declare(metadata, metadata, metadata) #0

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3}

!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 18.1.8", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, imports: !2, splitDebugInlining: false, nameTableKind: None)
!1 = !DIFile(filename: "typeart/test/script/05_wrapper_mpicxx.cpp", directory: "typeart", checksumkind: CSK_MD5, checksum: "c3331e3bb3d69c748d930e271bab2933")
!2 = !{}
!3 = !{i32 2, !"Debug Info Version", i32 3}
!4 = !DILocalVariable(name: "this", arg: 1, scope: !5, type: !16, flags: DIFlagArtificial | DIFlagObjectPointer)
!5 = distinct !DISubprogram(name: "Create_contiguous", linkageName: "_ZNK3MPI8Datatype17Create_contiguousEi", scope: !7, file: !6, line: 29, type: !14, scopeLine: 30, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, declaration: !15, retainedNodes: !2)
!6 = !DIFile(filename: "/usr/lib/x86_64-linux-gnu/openmpi/include/openmpi/ompi/mpi/cxx/datatype_inln.h", directory: "", checksumkind: CSK_MD5, checksum: "ca341002155830b958f1367079263e60")
!7 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "Datatype", scope: !9, file: !8, line: 24, size: 128, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !10, vtableHolder: !7, identifier: "_ZTSN3MPI8DatatypeE")
!8 = !DIFile(filename: "/usr/lib/x86_64-linux-gnu/openmpi/include/openmpi/ompi/mpi/cxx/datatype.h", directory: "", checksumkind: CSK_MD5, checksum: "d913c24e11a2093e97826064a436b07e")
!9 = !DINamespace(name: "MPI", scope: null)
!10 = !{!11}
!11 = !DIDerivedType(tag: DW_TAG_variable, name: "cxx_extra_states_lock", scope: !7, file: !8, line: 257, baseType: !12, flags: DIFlagPublic | DIFlagStaticMember)
!12 = !DICompositeType(tag: DW_TAG_structure_type, name: "opal_mutex_t", file: !13, line: 97, flags: DIFlagFwdDecl | DIFlagNonTrivial, identifier: "_ZTS12opal_mutex_t")
!13 = !DIFile(filename: "/usr/lib/x86_64-linux-gnu/openmpi/include/openmpi/ompi/mpi/cxx/mpicxx.h", directory: "", checksumkind: CSK_MD5, checksum: "73d4b420d7e4bd422e8c829e20bee55b")
!14 = distinct !DISubroutineType(types: !2)
!15 = !DISubprogram(name: "Create_contiguous", linkageName: "_ZNK3MPI8Datatype17Create_contiguousEi", scope: !7, file: !8, line: 112, type: !14, scopeLine: 112, containingType: !7, virtualIndex: 2, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagVirtual | DISPFlagOptimized)
!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !17, size: 64)
!17 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !7)
!18 = !DILocation(line: 0, scope: !5)

0 comments on commit f21f7a2

Please sign in to comment.