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

Enables VAST codegen to be used directly on a TranslatioUnitDecl independent of an ASTConsumer. #461

Closed
wants to merge 1 commit into from
Closed
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
63 changes: 29 additions & 34 deletions include/vast/CodeGen/CodeGenDeclVisitor.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2022-present, Trail of Bits, Inc.

Check notice on line 1 in include/vast/CodeGen/CodeGenDeclVisitor.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter (18, 22.04)

Run clang-format on include/vast/CodeGen/CodeGenDeclVisitor.hpp

File include/vast/CodeGen/CodeGenDeclVisitor.hpp does not conform to Custom style guidelines. (lines 336, 337, 354, 371, 430, 431, 434, 435, 436)

#pragma once

Expand Down Expand Up @@ -332,18 +332,9 @@
operation VisitFunctionLikeDecl(const Decl *decl) {
auto gdecl = get_gdecl(decl);
auto mangled = context().get_mangled_name(gdecl);

if (auto fn = context().lookup_function(mangled, false /* emit no error */)) {
return fn;
}

auto guard = insertion_guard();
auto is_definition = decl->isThisDeclarationADefinition();

// emit definition instead of declaration
if (!is_definition && decl->getDefinition()) {
return visit(decl->getDefinition());
}
auto fn = context().lookup_function(mangled, false /* emit no error */);
auto guard = insertion_guard();

auto is_terminator = [] (auto &op) {
return op.template hasTrait< mlir::OpTrait::IsTerminator >() ||
Expand All @@ -354,13 +345,13 @@
// In MLIR the entry block of the function must have the same
// argument list as the function itself.
// FIXME: driver solves this already
auto params = llvm::zip(decl->getDefinition()->parameters(), entry->getArguments());
auto params = llvm::zip(decl->parameters(), entry->getArguments());
for (const auto &[arg, earg] : params) {
context().declare(arg, mlir_value(earg));
}
};

auto emit_function_terminator = [&] (auto fn) {
auto emit_function_terminator = [&] () {
auto loc = fn.getLoc();
if (decl->getReturnType()->isVoidType()) {
auto void_val = constant(loc);
Expand All @@ -377,7 +368,7 @@
}
};

auto emit_function_body = [&] (auto fn) {
auto emit_function_body = [&] () {
auto entry = fn.addEntryBlock();
set_insertion_point_to_start(entry);

Expand Down Expand Up @@ -430,32 +421,38 @@
|| !last_op
|| !is_terminator(*last_op))
{
emit_function_terminator(fn);
emit_function_terminator();
}
};

llvm::ScopedHashTableScope scope(context().vars);

auto linkage = core::get_function_linkage(gdecl);

auto fn = context().declare(mangled, [&] () {
auto loc = meta_location(decl);
auto type = visit_function_type(decl->getFunctionType(), decl->isVariadic());
// make function header, that will be later filled with function body
// or returned as declaration in the case of external function
return make< hl::FuncOp >(loc, mangled.name, type, linkage);
});
auto def = decl->getDefinition();
auto linkage = core::get_function_linkage(def ? get_gdecl(def) : gdecl);

if (!fn) {
fn = context().declare(mangled, [&] () {
auto loc = meta_location(decl);
auto type = visit_function_type(decl->getFunctionType(), decl->isVariadic());

// make function header, that will be later filled with function body
// or returned as declaration in the case of external function
auto ret = make< hl::FuncOp >(loc, mangled.name, type, linkage);

// MLIR requires declrations to have private visibility
ret.setVisibility(mlir::SymbolTable::Visibility::Private);

return ret;
});
}

if (!is_definition) {
// MLIR requires declrations to have private visibility
fn.setVisibility(mlir::SymbolTable::Visibility::Private);
return fn;
}

fn.setVisibility(core::get_visibility_from_linkage(linkage));

if (fn.empty()) {
emit_function_body(fn);
emit_function_body();
}

return fn;
Expand Down Expand Up @@ -564,12 +561,10 @@
// operation VisitLinkageSpecDecl(const clang::LinkageSpecDecl *decl)

operation VisitTranslationUnitDecl(const clang::TranslationUnitDecl *tu) {
auto loc = meta_location(tu);
return derived().template make_scoped< TranslationUnitScope >(loc, [&] {
for (const auto &decl : tu->decls()) {
visit(decl);
}
});
for (const auto &decl : tu->decls()) {
visit(decl);
}
return {};
}

// operation VisitTypedefNameDecl(const clang::TypedefNameDecl *decl)
Expand Down
36 changes: 16 additions & 20 deletions include/vast/CodeGen/CodeGenStmtVisitor.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2022-present, Trail of Bits, Inc.

Check notice on line 1 in include/vast/CodeGen/CodeGenStmtVisitor.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter (18, 22.04)

Run clang-format on include/vast/CodeGen/CodeGenStmtVisitor.hpp

File include/vast/CodeGen/CodeGenStmtVisitor.hpp does not conform to Custom style guidelines. (lines 670, 671, 688, 689, 700, 701, 715, 716, 969)

#pragma once

Expand Down Expand Up @@ -663,16 +663,12 @@
return visit_as_lvalue_type(expr->getType());
}

const clang::VarDecl * getDeclForVarRef(const clang::DeclRefExpr *expr) {
return clang::cast< clang::VarDecl >(expr->getDecl()->getUnderlyingDecl());
}

hl::VarDeclOp getDefiningOpOfGlobalVar(const clang::VarDecl *decl) {
return context().vars.lookup(decl).template getDefiningOp< hl::VarDeclOp >();
}

operation VisitEnumDeclRefExpr(const clang::DeclRefExpr *expr) {
auto decl = clang::cast< clang::EnumConstantDecl >(expr->getDecl()->getUnderlyingDecl());
operation VisitEnumDeclRefExpr(const clang::DeclRefExpr *expr, const clang::Decl *underlying_decl) {
auto decl = clang::cast< clang::EnumConstantDecl >( underlying_decl )->getFirstDecl();
if (auto val = context().enumconsts.lookup(decl)) {
auto rty = visit(expr->getType());
return make< hl::EnumRefOp >(meta_location(expr), rty, val.getName());
Expand All @@ -689,8 +685,8 @@
return make< hl::DeclRefOp >(meta_location(expr), rty, var);
}

operation VisitVarDeclRefExpr(const clang::DeclRefExpr *expr) {
auto decl = getDeclForVarRef(expr);
operation VisitVarDeclRefExpr(const clang::DeclRefExpr *expr, const clang::Decl *underlying_decl) {
auto decl = clang::cast< clang::VarDecl >( underlying_decl )->getFirstDecl();
if (auto var = context().vars.lookup(decl)) {
return VisitVarDeclRefExprImpl(expr, var);
}
Expand All @@ -701,8 +697,8 @@
return nullptr;
}

operation VisitFileVarDeclRefExpr(const clang::DeclRefExpr *expr) {
auto decl = getDeclForVarRef(expr);
operation VisitFileVarDeclRefExpr(const clang::DeclRefExpr *expr, const clang::Decl *underlying_decl) {
auto decl = clang::cast< clang::VarDecl >( underlying_decl )->getFirstDecl();
if (!context().vars.lookup(decl)) {
// Ref: https://github.com/trailofbits/vast/issues/384
// github issue to avoid emitting error if declaration is missing
Expand All @@ -716,8 +712,8 @@
return make< hl::GlobalRefOp >(meta_location(expr), rty, name);
}

operation VisitFunctionDeclRefExpr(const clang::DeclRefExpr *expr) {
auto decl = clang::cast< clang::FunctionDecl >( expr->getDecl()->getUnderlyingDecl() );
operation VisitFunctionDeclRefExpr(const clang::DeclRefExpr *expr, const clang::Decl *underlying_decl) {
auto decl = clang::cast< clang::FunctionDecl >( underlying_decl )->getFirstDecl();
auto mangled = context().get_mangled_name(decl);
auto fn = context().lookup_function(mangled, false);
if (!fn) {
Expand All @@ -734,17 +730,17 @@
auto underlying = expr->getDecl()->getUnderlyingDecl();

if (clang::isa< clang::EnumConstantDecl >(underlying)) {
return VisitEnumDeclRefExpr(expr);
return VisitEnumDeclRefExpr(expr, underlying);
}

if (auto decl = clang::dyn_cast< clang::VarDecl >(underlying)) {
if (decl->isFileVarDecl())
return VisitFileVarDeclRefExpr(expr);
return VisitVarDeclRefExpr(expr);
return VisitFileVarDeclRefExpr(expr, underlying);
return VisitVarDeclRefExpr(expr, underlying);
}

if (clang::isa< clang::FunctionDecl >(underlying)) {
return VisitFunctionDeclRefExpr(expr);
return VisitFunctionDeclRefExpr(expr, underlying);
}

VAST_UNIMPLEMENTED_MSG("unknown underlying declaration to be referenced");
Expand Down Expand Up @@ -969,8 +965,8 @@
return args;
}

operation VisitDirectCall(const clang::CallExpr *expr) {
auto callee = VisitDirectCallee(expr->getDirectCallee());
operation VisitDirectCall(const clang::CallExpr *expr, const clang::Decl *decl) {
auto callee = VisitDirectCallee(clang::cast< clang::FunctionDecl >( decl ));
auto args = VisitArguments(expr);
return make< hl::CallOp >(meta_location(expr), callee, args);
}
Expand All @@ -989,8 +985,8 @@
}

operation VisitCallExpr(const clang::CallExpr *expr) {
if (expr->getDirectCallee()) {
return VisitDirectCall(expr);
if (auto callee = expr->getDirectCallee()) {
return VisitDirectCall(expr, callee->getFirstDecl());
}

return VisitIndirectCall(expr);
Expand Down
2 changes: 1 addition & 1 deletion include/vast/CodeGen/CodeGenTypeVisitor.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2022-present, Trail of Bits, Inc.

Check notice on line 1 in include/vast/CodeGen/CodeGenTypeVisitor.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter (18, 22.04)

Run clang-format on include/vast/CodeGen/CodeGenTypeVisitor.hpp

File include/vast/CodeGen/CodeGenTypeVisitor.hpp does not conform to Custom style guidelines. (lines 120)

#pragma once

Expand Down Expand Up @@ -117,7 +117,7 @@

auto with_qualifiers(const clang::EnumType *ty, qualifiers quals) -> mlir_type {
auto name = make_name_attr( context().decl_name(ty->getDecl()) );
return with_cv_qualifiers( type_builder< hl::RecordType >().bind(name), quals ).freeze();
return with_cv_qualifiers( type_builder< hl::EnumType >().bind(name), quals ).freeze();
}

auto with_qualifiers(const clang::TypedefType *ty, qualifiers quals) -> mlir_type {
Expand Down
10 changes: 8 additions & 2 deletions include/vast/Dialect/HighLevel/HighLevelTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ class IsMaybeWrappedTypedef< string arg > : PredOpTrait<
CPred< "::vast::hl::strip_elaborated($" # arg # ").hasTrait< mlir::TypeTrait::TypedefTrait >()" >
>;

class IsMaybeWrappedEnum< string arg > : PredOpTrait<
"type is an enum, maybe wrapped in the elaborated type",
CPred< "::vast::hl::strip_elaborated($" # arg # ").isa< ::vast::hl::EnumType >()" >
>;

class ContainsTypedef< list< string > tl > : PredOpTrait< "contains typedef type",
Or< !foreach(type, tl, IsMaybeWrappedTypedef< type >.predicate) >
>;
Expand Down Expand Up @@ -264,12 +269,13 @@ def LongLongType : IntegerType< "LongLong", "longlong", [LongLongTypeTrait] >;
def Int128Type : IntegerType< "Int128", "int128", [Int128TypeTrait] >;

def HLIntegerType : AnyTypeOf<[
CharType, ShortType, IntType, LongType, LongLongType, Int128Type, TypedefType
CharType, ShortType, IntType, LongType, LongLongType, Int128Type, TypedefType, EnumType
]>;

def IntegerLikeType : TypeConstraint<
Or< [HLIntegerType.predicate, AnyInteger.predicate,
IsMaybeWrappedTypedef< "_self" >.predicate] >,
IsMaybeWrappedTypedef< "_self" >.predicate,
IsMaybeWrappedEnum< "_self" >.predicate] >,
"integer like type"
>;

Expand Down
Loading