Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add operations for C++ constructors and destructors #346

Draft
wants to merge 5 commits into
base: frabert/cxx-methods
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions include/vast/Dialect/HighLevel/HighLevelOps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,14 @@ namespace vast::hl
namespace vast::hl
{
FuncOp getCallee(CallOp call);

using funclike_ops = util::type_list<
hl::FuncOp,
hl::MethodOp,
hl::DtorOp,
hl::CtorOp
>;

template< typename T >
concept function_like = funclike_ops::contains< T >;
}
30 changes: 29 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,32 @@ 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)
}];
}

def CtorOp : FuncLikeOp< "ctor" >
{
let summary = "VAST high-level constructor definintion or declaration";

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

#endif // VAST_DIALECT_HIGHLEVEL_IR_HIGHLEVELOPS_CXX
6 changes: 6 additions & 0 deletions include/vast/Translation/CodeGen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ 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 CtorsScope = ScopedSymbolTable< mangled_name_ref, hl::CtorOp >;
using VariablesScope = ScopedSymbolTable< const clang::VarDecl *, Value >;

struct CodegenScope {
Expand All @@ -100,6 +102,8 @@ namespace vast::cg
LabelTable labels;
FunctionsScope funcdecls;
MethodsScope methdecls;
DtorsScope dtordecls;
CtorsScope ctordecls;
VariablesScope globs;
};

Expand Down Expand Up @@ -600,6 +604,8 @@ namespace vast::cg
.labels = _cgctx.labels,
.funcdecls = _cgctx.funcdecls,
.methdecls = _cgctx.methdecls,
.dtordecls = _cgctx.dtordecls,
.ctordecls = _cgctx.ctordecls,
.globs = _cgctx.vars
});

Expand Down
22 changes: 20 additions & 2 deletions include/vast/Translation/CodeGenContext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ 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 CtorDeclTable = scoped_table< mangled_name_ref, hl::CtorOp >;
CtorDeclTable ctordecls;

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

Expand Down Expand Up @@ -214,12 +220,24 @@ namespace vast::cg
return symbol(methdecls, mangled, "undeclared method '" + mangled.name + "'", with_error);
}

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

hl::CtorOp lookup_constructor(mangled_name_ref mangled, bool with_error = true) {
return symbol(ctordecls, mangled, "undeclared constructor '" + mangled.name + "'", with_error);
}

template< hl::function_like 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);
} else if constexpr (std::is_same_v< Op, hl::CtorOp >) {
return declare< Op >(ctordecls, mangled, vast_decl_builder, mangled.name);
}
}

Expand Down
41 changes: 19 additions & 22 deletions include/vast/Translation/CodeGenDeclVisitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,22 +292,27 @@ namespace vast::cg {
return clang::GlobalDecl(decl, clang::CXXDtorType::Dtor_Complete);
}

template< hl::function_like Op >
operation lookup_funclike(mangled_name_ref mangled) {
if constexpr (std::is_same_v< Op, hl::FuncOp >) {
return context().lookup_function(mangled, false /* emit no error */);
} else if constexpr (std::is_same_v< Op, hl::MethodOp >) {
return context().lookup_method(mangled, false /* emit no error */);
} else if constexpr (std::is_same_v< Op, hl::DtorOp >) {
return context().lookup_destructor(mangled, false /* emit no error */);
} else if constexpr (std::is_same_v< Op, hl::CtorOp >) {
return context().lookup_constructor(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 @@ -450,22 +455,14 @@ namespace vast::cg {
}

operation VisitCXXConstructorDecl(const clang::CXXConstructorDecl *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::CtorOp >(decl, [&](auto loc, auto name, auto type, auto linkage) {
return make< hl::CtorOp >(loc, name, type, linkage);
});
}

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
8 changes: 8 additions & 0 deletions lib/vast/Dialect/HighLevel/HighLevelOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ namespace vast::hl
return verify_funclike(this);
}

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

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

ParseResult parseFunctionSignatureAndBody(
Parser &parser, Attribute &funcion_type, mlir::NamedAttrList &attr_dict, Region &body
) {
Expand Down
10 changes: 9 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 Expand Up @@ -34,4 +39,7 @@ class C : public A, protected virtual B {

// CHECK: hl.method external ref_rvalue @_ZNO1C5get_pEv () -> !hl.int
int get_p() &&;

// CHECK: hl.ctor external @_ZN1CC1Ei (!hl.lvalue<!hl.int>)
C(int x);
};