Skip to content

Commit

Permalink
hl: Add DtorOp for C++ destructors.
Browse files Browse the repository at this point in the history
  • Loading branch information
frabert committed Jul 21, 2023
1 parent 23a033f commit bd6b10e
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 19 deletions.
21 changes: 20 additions & 1 deletion include/vast/Dialect/HighLevel/HighLevelOpsCxx.td
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def RefQualifier : I32EnumAttr<
let cppNamespace = "::vast::hl";
}

def MethodOp
def MethodOp
: FuncLikeOp< "method", (ins
UnitAttr:$is_virtual,
UnitAttr:$is_const,
Expand Down Expand Up @@ -138,4 +138,23 @@ def MethodOp
}];
}

def DtorOp
: FuncLikeOp< "dtor",
(ins UnitAttr:$is_virtual),
(ins CArg< "bool", "false" >:$is_virtual),
[{
if (is_virtual) {
$_state.addAttribute(
"is_virtual", mlir::UnitAttr::get($_builder.getContext())
);
}
}] >
{
let summary = "VAST high-level destructor definintion or declaration";

let assemblyFormat = [{
$linkage (`virtual` $is_virtual^)? $sym_name custom< FunctionSignatureAndBody >($function_type, attr-dict, $body)
}];
}

#endif // VAST_DIALECT_HIGHLEVEL_IR_HIGHLEVELOPS_CXX
3 changes: 3 additions & 0 deletions include/vast/Translation/CodeGen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ namespace vast::cg
using LabelTable = ScopedSymbolTable< const clang::LabelDecl*, hl::LabelDeclOp >;
using FunctionsScope = ScopedSymbolTable< mangled_name_ref, hl::FuncOp >;
using MethodsScope = ScopedSymbolTable< mangled_name_ref, hl::MethodOp >;
using DtorsScope = ScopedSymbolTable< mangled_name_ref, hl::DtorOp >;
using VariablesScope = ScopedSymbolTable< const clang::VarDecl *, Value >;

struct CodegenScope {
Expand All @@ -115,6 +116,7 @@ namespace vast::cg
LabelTable labels;
FunctionsScope funcdecls;
MethodsScope methdecls;
DtorsScope dtordecls;
VariablesScope globs;
};

Expand Down Expand Up @@ -623,6 +625,7 @@ namespace vast::cg
.labels = _cgctx->labels,
.funcdecls = _cgctx->funcdecls,
.methdecls = _cgctx->methdecls,
.dtordecls = _cgctx->dtordecls,
.globs = _cgctx->vars
});

Expand Down
32 changes: 31 additions & 1 deletion include/vast/Translation/CodeGenContext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ namespace vast::cg
using MethodDeclTable = scoped_table< mangled_name_ref, hl::MethodOp >;
MethodDeclTable methdecls;

using DtorDeclTable = scoped_table< mangled_name_ref, hl::DtorOp >;
DtorDeclTable dtordecls;

using EnumDecls = scoped_table< const clang::EnumDecl *, hl::EnumDeclOp >;
EnumDecls enumdecls;

Expand Down Expand Up @@ -198,13 +201,40 @@ namespace vast::cg
return symbol(methdecls, mangled, "undeclared method '" + mangled.name + "'", with_error);
}

hl::DtorOp lookup_destructor(mangled_name_ref mangled, bool with_error = true) {
return symbol(dtordecls, mangled, "undeclared destructor '" + mangled.name + "'", with_error);
}

template< typename Op >
struct is_funclike {
static constexpr bool value = false;
};

template<>
struct is_funclike< hl::FuncOp > {
static constexpr bool value = true;
};

template<>
struct is_funclike< hl::MethodOp > {
static constexpr bool value = true;
};

template<>
struct is_funclike< hl::DtorOp > {
static constexpr bool value = true;
};

template< typename Op >
Op declare(mangled_name_ref mangled, auto vast_decl_builder) {
if constexpr (std::is_same_v< Op, hl::FuncOp >) {
return declare< Op >(funcdecls, mangled, vast_decl_builder, mangled.name);
} else {
} else if constexpr (std::is_same_v< Op, hl::MethodOp >) {
return declare< Op >(methdecls, mangled, vast_decl_builder, mangled.name);
} else if constexpr (std::is_same_v< Op, hl::DtorOp >) {
return declare< Op >(dtordecls, mangled, vast_decl_builder, mangled.name);
}
static_assert(is_funclike< Op >::value, "Declaring unknown operation type");
}

mlir_value declare(const clang::VarDecl *decl, mlir_value vast_value) {
Expand Down
38 changes: 22 additions & 16 deletions include/vast/Translation/CodeGenDeclVisitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,22 +292,32 @@ namespace vast::cg {
return clang::GlobalDecl(decl, clang::CXXDtorType::Dtor_Complete);
}

template< typename Op >
operation lookup_funclike(mangled_name_ref mangled);

template< >
operation lookup_funclike< hl::FuncOp >(mangled_name_ref mangled) {
return context().lookup_function(mangled, false /* emit no error */);
}

template< >
operation lookup_funclike< hl::MethodOp >(mangled_name_ref mangled) {
return context().lookup_method(mangled, false /* emit no error */);
}

template< >
operation lookup_funclike< hl::DtorOp >(mangled_name_ref mangled) {
return context().lookup_destructor(mangled, false /* emit no error */);
}

// FIXME: remove as this duplicates logic from codegen driver
template< typename Op, typename Decl, typename Builder >
operation VisitFunctionLikeDecl(const Decl *decl, Builder builder_callback) {
auto gdecl = get_gdecl(decl);
auto mangled = context().get_mangled_name(gdecl);

if constexpr (std::is_same_v< Op, hl::FuncOp >) {
if (auto fn = context().lookup_function(mangled, false /* emit no error */)) {
return fn;
}
}

if constexpr (std::is_same_v< Op, hl::MethodOp >) {
if (auto fn = context().lookup_method(mangled, false /* emit no error */)) {
return fn;
}
if (auto fn = lookup_funclike< Op >(mangled)) {
return fn;
}

InsertionGuard guard(builder());
Expand Down Expand Up @@ -460,12 +470,8 @@ namespace vast::cg {
}

operation VisitCXXDestructorDecl(const clang::CXXDestructorDecl *decl) {
return VisitFunctionLikeDecl< hl::MethodOp >(decl, [&](auto loc, auto name, auto type, auto linkage) {
return make< hl::MethodOp >(loc, name, type, linkage,
decl->isVirtual(),
decl->isConst(),
decl->isVolatile(),
convert_ref_qual(decl->getRefQualifier()));
return VisitFunctionLikeDecl< hl::DtorOp >(decl, [&](auto loc, auto name, auto type, auto linkage) {
return make< hl::DtorOp >(loc, name, type, linkage, decl->isVirtual());
});
}

Expand Down
4 changes: 4 additions & 0 deletions lib/vast/Dialect/HighLevel/HighLevelOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ namespace vast::hl
return verify_funclike(this);
}

logical_result DtorOp::verify() {
return verify_funclike(this);
}

ParseResult parseFunctionSignatureAndBody(
Parser &parser, Attribute &funcion_type, mlir::NamedAttrList &attr_dict, Region &body
) {
Expand Down
7 changes: 6 additions & 1 deletion test/vast/Dialect/HighLevel/Cxx/class-a.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
// RUN: vast-cc --from-source %s > %t && vast-opt %t | diff -B %t -

// CHECK: hl.class "A" :
class A {};
class A {
// CHECK: hl.access protected
protected:
// CHECK: hl.dtor external virtual @_ZN1AD1Ev ()
virtual ~A();
};

// CHECK: hl.class "B" :
class B {};
Expand Down

0 comments on commit bd6b10e

Please sign in to comment.