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 base for TypeTraitExpr and implement support for __builtin_types_compatible_p #716

Merged
merged 5 commits into from
Sep 6, 2024
Merged
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
18 changes: 18 additions & 0 deletions include/vast/CodeGen/DefaultStmtVisitor.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/DefaultStmtVisitor.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter (18, 22.04)

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

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

#pragma once

Expand Down Expand Up @@ -244,6 +244,9 @@
// operation VisitParenListExpr(const clang::ParenListExpr *expr)
operation VisitStmtExpr(const clang::StmtExpr *expr);

template< typename op_t >
operation mk_type_trait_expr(const clang::TypeTraitExpr *expr);

template< typename op_t >
operation mk_type_trait_expr(const clang::UnaryExprOrTypeTraitExpr *expr);

Expand All @@ -254,6 +257,7 @@
operation mk_trait_expr(const clang::UnaryExprOrTypeTraitExpr *expr);

operation VisitUnaryExprOrTypeTraitExpr(const clang::UnaryExprOrTypeTraitExpr *expr);
operation VisitTypeTraitExpr(const clang::TypeTraitExpr *expr);
operation VisitVAArgExpr(const clang::VAArgExpr *expr);
operation VisitNullStmt(const clang::NullStmt *stmt);
operation VisitCXXThisExpr(const clang::CXXThisExpr *expr);
Expand Down Expand Up @@ -476,6 +480,20 @@
return {};
}

template< typename op_t >
operation default_stmt_visitor::mk_type_trait_expr(const clang::TypeTraitExpr *expr) {
types_t types;
for (auto type_info : expr->getArgs()) {
types.push_back(self.visit(type_info->getType()));
}
return bld.compose< op_t >()
.bind(self.location(expr))
.bind(self.visit(expr->getType()))
.bind(types)
.bind_always(expr->isValueDependent() ? std::nullopt : std::optional(expr->getValue()))
.freeze();
}

template< typename op_t >
operation default_stmt_visitor::mk_type_trait_expr(const clang::UnaryExprOrTypeTraitExpr *expr) {
return bld.compose< op_t >()
Expand Down
1 change: 1 addition & 0 deletions include/vast/Dialect/HighLevel/HighLevelOps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ VAST_UNRELAX_WARNINGS

#include "vast/Dialect/Core/Interfaces/SymbolInterface.hpp"
#include "vast/Interfaces/AggregateTypeDefinitionInterface.hpp"
#include "vast/Interfaces/TypeTraitExprInterface.hpp"
#include "vast/Interfaces/AST/DeclInterface.hpp"


Expand Down
39 changes: 39 additions & 0 deletions include/vast/Dialect/HighLevel/HighLevelOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ include "mlir/IR/BuiltinAttributes.td"
include "mlir/Interfaces/CastInterfaces.td"

include "vast/Interfaces/AggregateTypeDefinitionInterface.td"
include "vast/Interfaces/TypeTraitExprInterface.td"
include "vast/Dialect/Core/Interfaces/SymbolInterface.td"
include "vast/Dialect/Core/Interfaces/SymbolTableInterface.td"

Expand Down Expand Up @@ -1379,6 +1380,44 @@ class HighLevel_AlignOfExprOpBase< string mnemonic, list< Trait > traits = [] >
def HighLevel_AlignOfExprOp : HighLevel_AlignOfExprOpBase< "alignof.expr" >;
def HighLevel_PreferredAlignOfExprOp : HighLevel_AlignOfExprOpBase< "preferred_alignof.expr" >;

class HighLevel_TypeTraitExprOp< string mnemonic, list< Trait > traits = [] >
: HighLevel_Op< mnemonic, !listconcat([Pure, DeclareOpInterfaceMethods<TypeTraitExprInterface>], traits) >
{
let skipDefaultBuilders = 1;
let builders = [
OpBuilder< (ins
"Type":$resultType,
"llvm::ArrayRef< mlir::Type >":$types,
CArg< "std::optional< bool >", "std::nullopt" >:$result
), [{
auto attr_names = getAttributeNames();
for (auto [type, attr_name] : llvm::zip_first(types, attr_names)) {
$_state.addAttribute(attr_name, mlir::TypeAttr::get(type));
}
if (result) {
$_state.addAttribute(attr_names.back(), $_builder.getBoolAttr(result.value()));
}
$_state.addTypes(resultType);
}] >,
OpBuilder< (ins
"Type":$resultType,
"clang::ArrayRef< mlir::Type >":$types,
"bool":$result
), [{
build($_builder, $_state, resultType, types, std::optional(result));
}] >
];
}

def HighLevel_BuiltinTypesCompatiblePOp
: HighLevel_TypeTraitExprOp< "builtin_types_compatible_p.type" >
, Arguments<(ins TypeAttr:$Type1, TypeAttr:$Type2, BoolAttr:$compatible)>
, Results<(outs HighLevel_IntegerLikeType:$result)>
{
let summary = "VAST representation of __builtin_types_compatible_p";
let assemblyFormat = [{ $Type1`,` $Type2 `compatible` $compatible attr-dict `->` type($result) }];
}

def HighLevel_OffsetOfNodeAttr
: HighLevel_Attr< "OffsetOfNode", "offset_of_node" > {
let parameters = (ins
Expand Down
1 change: 1 addition & 0 deletions include/vast/Interfaces/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_vast_op_interface(AggregateTypeDefinitionInterface)
add_vast_op_interface(TypeTraitExprInterface)
add_vast_attr_interface(TypeQualifiersInterfaces)
add_vast_type_interface(AliasTypeInterface)
add_vast_type_interface(DefaultDataLayoutTypeInterface)
Expand Down
16 changes: 16 additions & 0 deletions include/vast/Interfaces/TypeTraitExprInterface.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) 2024-present, Trail of Bits, Inc.

Check notice on line 1 in include/vast/Interfaces/TypeTraitExprInterface.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter (18, 22.04)

Run clang-format on include/vast/Interfaces/TypeTraitExprInterface.hpp

File include/vast/Interfaces/TypeTraitExprInterface.hpp does not conform to Custom style guidelines. (lines 12)

#pragma once

#include "vast/Util/Warnings.hpp"

VAST_RELAX_WARNINGS
#include <mlir/IR/BuiltinOps.h>
#include <mlir/IR/BuiltinTypes.h>
#include <mlir/IR/Dialect.h>
#include <mlir/IR/OperationSupport.h>
VAST_RELAX_WARNINGS


/// Include the generated interface declarations.
#include "vast/Interfaces/TypeTraitExprInterface.h.inc"

Check failure on line 16 in include/vast/Interfaces/TypeTraitExprInterface.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter (18, 22.04)

include/vast/Interfaces/TypeTraitExprInterface.hpp:16:10 [clang-diagnostic-error]

'vast/Interfaces/TypeTraitExprInterface.h.inc' file not found
24 changes: 24 additions & 0 deletions include/vast/Interfaces/TypeTraitExprInterface.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) 2024-present, Trail of Bits, Inc.

#ifndef VAST_INTERFACES_TYPE_TRAIT_EXPR_INTERFACE
#define VAST_INTERFACES_TYPE_TRAIT_EXPR_INTERFACE

include "mlir/IR/OpBase.td"
include "vast/Interfaces/Common.td"

def TypeTraitExprInterface : VastOpInterface< "TypeTraitExprInterface" > {
let description = [{
Interface to use type trait expressions uniformly
}];

let methods = [
InterfaceMethod< "Returns type trait arguments.",
"llvm::SmallVector< mlir::Type >", "getArgs", (ins), ""
>,
InterfaceMethod< "Returns trait value, if possible.",
"std::optional< bool >", "getValue", (ins), ""
>
];
}

#endif // VAST_INTERFACES_TYPE_TRAIT_EXPR_INTERFACE
10 changes: 10 additions & 0 deletions lib/vast/CodeGen/DefaultStmtVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1093,6 +1093,16 @@ namespace vast::cg
}
}

operation default_stmt_visitor::VisitTypeTraitExpr(const clang::TypeTraitExpr *expr) {
switch (expr->getTrait()) {
case clang::BTT_TypeCompatible:
return mk_type_trait_expr< hl::BuiltinTypesCompatiblePOp >(expr);
default:
return {};
}
return {};
}

operation default_stmt_visitor::VisitVAArgExpr(const clang::VAArgExpr *expr) {
return bld.compose< hl::VAArgExpr >()
.bind(self.location(expr))
Expand Down
11 changes: 11 additions & 0 deletions lib/vast/Dialect/HighLevel/HighLevelOps.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2021-present, Trail of Bits, Inc.

Check notice on line 1 in lib/vast/Dialect/HighLevel/HighLevelOps.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter (18, 22.04)

Run clang-format on lib/vast/Dialect/HighLevel/HighLevelOps.cpp

File lib/vast/Dialect/HighLevel/HighLevelOps.cpp does not conform to Custom style guidelines. (lines 870, 871)

#include "vast/Util/Warnings.hpp"

Expand Down Expand Up @@ -864,6 +864,17 @@
return core::IntegerAttr::get(getType(), apsint(getValue()));
}

//
// BuiltinTypesCompatiblePOp
//
types_t BuiltinTypesCompatiblePOp::getArgs() {
return types_t{getType1(), getType2()};
}

std::optional< bool > BuiltinTypesCompatiblePOp::getValue() {
return std::optional(getCompatibleAttr().getValue());
}

}

//===----------------------------------------------------------------------===//
Expand Down
5 changes: 5 additions & 0 deletions lib/vast/Interfaces/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ set(VAST_OPTIONAL_SOURCES
SymbolTableInterface.cpp
SymbolRefInterface.cpp
TypeQualifiersInterfaces.cpp
TypeTraitExprInterface.cpp
)

add_vast_interface_library(AggregateTypeDefinitionInterface
Expand Down Expand Up @@ -44,4 +45,8 @@ add_vast_interface_library(TypeQualifiersInterfaces
TypeQualifiersInterfaces.cpp
)

add_vast_interface_library(TypeTraitExprInterface
TypeTraitExprInterface.cpp
)

add_subdirectory(AST)
10 changes: 10 additions & 0 deletions lib/vast/Interfaces/TypeTraitExprInterface.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright (c) 2024-present, Trail of Bits, Inc.

#include "vast/Interfaces/TypeTraitExprInterface.hpp"

//===----------------------------------------------------------------------===//
// Alias Type Interface
//===----------------------------------------------------------------------===//

/// Include the generated interface.
#include "vast/Interfaces/TypeTraitExprInterface.cpp.inc"
12 changes: 12 additions & 0 deletions test/vast/Dialect/HighLevel/types-compatible-a.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s
// RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t -

typedef int INT;
int main() {
// CHECK: hl.builtin_types_compatible_p.type !hl.int, !hl.char compatible false -> !hl.int
__builtin_types_compatible_p(int, char);
// CHECK: hl.builtin_types_compatible_p.type !hl.int, !hl.int compatible true -> !hl.int
__builtin_types_compatible_p(int, int);
// CHECK: hl.builtin_types_compatible_p.type !hl.int, !hl.elaborated<!hl.typedef<"INT">> compatible true -> !hl.int
__builtin_types_compatible_p(int, INT);
}