Skip to content
Open
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
60 changes: 60 additions & 0 deletions xls/public/c_api_dslx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,16 @@ struct xls_dslx_type_alias* xls_dslx_module_member_get_type_alias(
return reinterpret_cast<xls_dslx_type_alias*>(cpp_type_alias);
}

struct xls_dslx_import* xls_dslx_module_member_get_import(
struct xls_dslx_module_member* member) {
auto* cpp_member = reinterpret_cast<xls::dslx::ModuleMember*>(member);
if (std::holds_alternative<xls::dslx::Import*>(*cpp_member)) {
auto* cpp_import = std::get<xls::dslx::Import*>(*cpp_member);
return reinterpret_cast<xls_dslx_import*>(cpp_import);
}
return nullptr;
}

struct xls_dslx_function* xls_dslx_module_member_get_function(
struct xls_dslx_module_member* member) {
auto* cpp_member = reinterpret_cast<xls::dslx::ModuleMember*>(member);
Expand Down Expand Up @@ -1222,6 +1232,21 @@ bool xls_dslx_struct_def_is_parametric(struct xls_dslx_struct_def* n) {
return cpp_struct_def->IsParametric();
}

int64_t xls_dslx_struct_def_get_parametric_binding_count(
struct xls_dslx_struct_def* n) {
auto* cpp_struct_def = reinterpret_cast<xls::dslx::StructDef*>(n);
return static_cast<int64_t>(cpp_struct_def->parametric_bindings().size());
}

struct xls_dslx_parametric_binding*
xls_dslx_struct_def_get_parametric_binding(struct xls_dslx_struct_def* n,
int64_t index) {
auto* cpp_struct_def = reinterpret_cast<xls::dslx::StructDef*>(n);
xls::dslx::ParametricBinding* cpp_binding =
cpp_struct_def->parametric_bindings().at(index);
return reinterpret_cast<xls_dslx_parametric_binding*>(cpp_binding);
}

int64_t xls_dslx_struct_def_get_member_count(struct xls_dslx_struct_def* n) {
auto* cpp_struct_def = reinterpret_cast<xls::dslx::StructDef*>(n);
return cpp_struct_def->size();
Expand Down Expand Up @@ -1290,6 +1315,24 @@ xls_dslx_type_annotation_get_type_ref_type_annotation(
return reinterpret_cast<xls_dslx_type_ref_type_annotation*>(cpp_type_ref);
}

struct xls_dslx_array_type_annotation*
xls_dslx_type_annotation_get_array_type_annotation(
struct xls_dslx_type_annotation* n) {
auto* cpp = reinterpret_cast<xls::dslx::TypeAnnotation*>(n);
auto* cpp_array = dynamic_cast<xls::dslx::ArrayTypeAnnotation*>(cpp);
return reinterpret_cast<xls_dslx_array_type_annotation*>(cpp_array);
}

// -- array_type_annotation

struct xls_dslx_type_annotation*
xls_dslx_array_type_annotation_get_element_type(
struct xls_dslx_array_type_annotation* n) {
auto* cpp = reinterpret_cast<xls::dslx::ArrayTypeAnnotation*>(n);
xls::dslx::TypeAnnotation* cpp_element_type = cpp->element_type();
return reinterpret_cast<xls_dslx_type_annotation*>(cpp_element_type);
}

// -- type_ref_type_annotation

struct xls_dslx_type_ref* xls_dslx_type_ref_type_annotation_get_type_ref(
Expand All @@ -1299,6 +1342,23 @@ struct xls_dslx_type_ref* xls_dslx_type_ref_type_annotation_get_type_ref(
return reinterpret_cast<xls_dslx_type_ref*>(cpp_type_ref);
}

int64_t xls_dslx_type_ref_type_annotation_get_parametric_count(
struct xls_dslx_type_ref_type_annotation* n) {
auto* cpp = reinterpret_cast<xls::dslx::TypeRefTypeAnnotation*>(n);
return static_cast<int64_t>(cpp->parametrics().size());
}

struct xls_dslx_expr* xls_dslx_type_ref_type_annotation_get_parametric_expr(
struct xls_dslx_type_ref_type_annotation* n, int64_t index) {
auto* cpp = reinterpret_cast<xls::dslx::TypeRefTypeAnnotation*>(n);
const xls::dslx::ExprOrType& parametric = cpp->parametrics().at(index);
if (std::holds_alternative<xls::dslx::Expr*>(parametric)) {
xls::dslx::Expr* cpp_expr = std::get<xls::dslx::Expr*>(parametric);
return reinterpret_cast<xls_dslx_expr*>(cpp_expr);
}
return nullptr;
}

// -- type_ref

struct xls_dslx_type_definition* xls_dslx_type_ref_get_type_definition(
Expand Down
32 changes: 32 additions & 0 deletions xls/public/c_api_dslx.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,12 @@ struct xls_dslx_type_alias;
struct xls_dslx_type_info;
struct xls_dslx_type;
struct xls_dslx_type_annotation;
struct xls_dslx_array_type_annotation;
struct xls_dslx_constant_def;
struct xls_dslx_function;
struct xls_dslx_quickcheck;
struct xls_dslx_function;
struct xls_dslx_import;
struct xls_dslx_param;
struct xls_dslx_parametric_binding;
struct xls_dslx_expr;
Expand Down Expand Up @@ -266,6 +268,11 @@ struct xls_dslx_enum_def* xls_dslx_module_member_get_enum_def(
struct xls_dslx_type_alias* xls_dslx_module_member_get_type_alias(
struct xls_dslx_module_member*);

// Returns the import AST node from the given module member if it is an import;
// otherwise returns nullptr.
struct xls_dslx_import* xls_dslx_module_member_get_import(
struct xls_dslx_module_member*);

// Returns the function AST node from the given module member if it is a
// function; otherwise returns nullptr.
struct xls_dslx_function* xls_dslx_module_member_get_function(
Expand Down Expand Up @@ -503,6 +510,11 @@ char* xls_dslx_constant_def_to_string(struct xls_dslx_constant_def*);
char* xls_dslx_struct_def_get_identifier(struct xls_dslx_struct_def*);

bool xls_dslx_struct_def_is_parametric(struct xls_dslx_struct_def*);
int64_t xls_dslx_struct_def_get_parametric_binding_count(
struct xls_dslx_struct_def*);
struct xls_dslx_parametric_binding*
xls_dslx_struct_def_get_parametric_binding(struct xls_dslx_struct_def*,
int64_t);
int64_t xls_dslx_struct_def_get_member_count(struct xls_dslx_struct_def*);

struct xls_dslx_struct_member* xls_dslx_struct_def_get_member(
Expand Down Expand Up @@ -552,11 +564,31 @@ struct xls_dslx_type_ref_type_annotation*
xls_dslx_type_annotation_get_type_ref_type_annotation(
struct xls_dslx_type_annotation*);

// Attempts to convert the given type annotation to an ArrayTypeAnnotation --
// returns nullptr if the conversion is not viable.
struct xls_dslx_array_type_annotation*
xls_dslx_type_annotation_get_array_type_annotation(
struct xls_dslx_type_annotation*);

// -- array_type_annotation

struct xls_dslx_type_annotation*
xls_dslx_array_type_annotation_get_element_type(
struct xls_dslx_array_type_annotation*);

// -- type_ref_type_annotation

struct xls_dslx_type_ref* xls_dslx_type_ref_type_annotation_get_type_ref(
struct xls_dslx_type_ref_type_annotation*);

int64_t xls_dslx_type_ref_type_annotation_get_parametric_count(
struct xls_dslx_type_ref_type_annotation*);

// Returns nullptr if the parametric argument at `index` is a type annotation
// instead of an expression.
struct xls_dslx_expr* xls_dslx_type_ref_type_annotation_get_parametric_expr(
struct xls_dslx_type_ref_type_annotation*, int64_t index);

// -- type_ref

struct xls_dslx_type_definition* xls_dslx_type_ref_get_type_definition(
Expand Down
7 changes: 7 additions & 0 deletions xls/public/c_api_symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ xls_convert_dslx_path_to_ir_with_warnings
xls_convert_dslx_to_ir
xls_convert_dslx_to_ir_with_warnings
xls_create_bits_rope
xls_dslx_array_type_annotation_get_element_type
xls_dslx_attribute_get_argument_count
xls_dslx_attribute_get_argument_kind
xls_dslx_attribute_get_key_value_argument_key
Expand Down Expand Up @@ -201,6 +202,7 @@ xls_dslx_module_member_from_type_alias
xls_dslx_module_member_get_constant_def
xls_dslx_module_member_get_enum_def
xls_dslx_module_member_get_function
xls_dslx_module_member_get_import
xls_dslx_module_member_get_kind
xls_dslx_module_member_get_quickcheck
xls_dslx_module_member_get_struct_def
Expand Down Expand Up @@ -230,13 +232,16 @@ xls_dslx_replace_invocations_in_module
xls_dslx_struct_def_get_identifier
xls_dslx_struct_def_get_member
xls_dslx_struct_def_get_member_count
xls_dslx_struct_def_get_parametric_binding
xls_dslx_struct_def_get_parametric_binding_count
xls_dslx_struct_def_is_parametric
xls_dslx_struct_def_to_string
xls_dslx_struct_member_get_name
xls_dslx_struct_member_get_type
xls_dslx_type_alias_get_identifier
xls_dslx_type_alias_get_type_annotation
xls_dslx_type_alias_to_string
xls_dslx_type_annotation_get_array_type_annotation
xls_dslx_type_annotation_get_type_ref_type_annotation
xls_dslx_type_array_get_element_type
xls_dslx_type_array_get_size
Expand Down Expand Up @@ -267,6 +272,8 @@ xls_dslx_type_is_enum
xls_dslx_type_is_signed_bits
xls_dslx_type_is_struct
xls_dslx_type_ref_get_type_definition
xls_dslx_type_ref_type_annotation_get_parametric_count
xls_dslx_type_ref_type_annotation_get_parametric_expr
xls_dslx_type_ref_type_annotation_get_type_ref
xls_dslx_type_to_string
xls_dslx_typechecked_module_clone_removing_functions
Expand Down
187 changes: 187 additions & 0 deletions xls/public/c_api_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1754,6 +1754,193 @@ type MyOtherTypeAlias = MyTypeAlias;
}
}

TEST(XlsCApiTest, DslxInspectArrayTypeAnnotationElement) {
const char kImported[] = "pub struct Widget { value: u32 }";
XLS_ASSERT_OK_AND_ASSIGN(xls::TempDirectory tempdir,
xls::TempDirectory::Create());
const std::filesystem::path& tempdir_path = tempdir.path();
const std::filesystem::path module_path =
tempdir_path / "my_imported_module.x";
XLS_ASSERT_OK(xls::SetFileContents(module_path, kImported));

const char kProgram[] = R"(import my_imported_module;

type Widgets = my_imported_module::Widget[2];
)";
const char* additional_search_paths[] = {tempdir_path.c_str()};

xls_dslx_import_data* import_data = xls_dslx_import_data_create(
std::string{xls::kDefaultDslxStdlibPath}.c_str(), additional_search_paths,
ABSL_ARRAYSIZE(additional_search_paths));
ASSERT_NE(import_data, nullptr);
absl::Cleanup free_import_data(
[&] { xls_dslx_import_data_free(import_data); });

xls_dslx_typechecked_module* tm = nullptr;
char* error = nullptr;
absl::Cleanup free_error([&] { xls_c_str_free(error); });
bool ok = xls_dslx_parse_and_typecheck(kProgram, "foo.x", "foo", import_data,
&error, &tm);
ASSERT_TRUE(ok) << "got not-ok result from parse-and-typecheck; error: "
<< error;
ASSERT_EQ(error, nullptr);
ASSERT_NE(tm, nullptr);
absl::Cleanup free_tm([&] { xls_dslx_typechecked_module_free(tm); });

xls_dslx_module* module = xls_dslx_typechecked_module_get_module(tm);
ASSERT_EQ(xls_dslx_module_get_type_definition_count(module), 1);
xls_dslx_type_alias* type_alias =
xls_dslx_module_get_type_definition_as_type_alias(module, 0);
xls_dslx_type_annotation* type =
xls_dslx_type_alias_get_type_annotation(type_alias);
xls_dslx_array_type_annotation* array_type =
xls_dslx_type_annotation_get_array_type_annotation(type);
ASSERT_NE(array_type, nullptr);

xls_dslx_type_annotation* element_type =
xls_dslx_array_type_annotation_get_element_type(array_type);
ASSERT_NE(element_type, nullptr);
xls_dslx_type_ref_type_annotation* element_type_ref_annotation =
xls_dslx_type_annotation_get_type_ref_type_annotation(element_type);
ASSERT_NE(element_type_ref_annotation, nullptr);
xls_dslx_type_ref* element_type_ref =
xls_dslx_type_ref_type_annotation_get_type_ref(
element_type_ref_annotation);
xls_dslx_type_definition* element_type_definition =
xls_dslx_type_ref_get_type_definition(element_type_ref);
xls_dslx_colon_ref* colon_ref =
xls_dslx_type_definition_get_colon_ref(element_type_definition);
ASSERT_NE(colon_ref, nullptr);

xls_dslx_import* import_subject =
xls_dslx_colon_ref_resolve_import_subject(colon_ref);
ASSERT_NE(import_subject, nullptr);
EXPECT_EQ(xls_dslx_import_get_subject_count(import_subject), 1);
char* subject = xls_dslx_import_get_subject(import_subject, 0);
absl::Cleanup free_subject([&] { xls_c_str_free(subject); });
EXPECT_EQ(std::string_view{subject}, "my_imported_module");

char* attr = xls_dslx_colon_ref_get_attr(colon_ref);
absl::Cleanup free_attr([&] { xls_c_str_free(attr); });
EXPECT_EQ(std::string_view{attr}, "Widget");
}

TEST(XlsCApiTest, DslxInspectTypeRefParametricExprsAndStructBindings) {
const char kProgram[] = R"(
struct Box<N: u32> {
value: bits[N],
}

type Box8 = Box<u32:8>;
)";
const char* additional_search_paths[] = {};

xls_dslx_import_data* import_data = xls_dslx_import_data_create(
std::string{xls::kDefaultDslxStdlibPath}.c_str(), additional_search_paths,
0);
ASSERT_NE(import_data, nullptr);
absl::Cleanup free_import_data(
[&] { xls_dslx_import_data_free(import_data); });

xls_dslx_typechecked_module* tm = nullptr;
char* error = nullptr;
absl::Cleanup free_error([&] { xls_c_str_free(error); });
bool ok = xls_dslx_parse_and_typecheck(kProgram, "foo.x", "foo", import_data,
&error, &tm);
ASSERT_TRUE(ok) << "got not-ok result from parse-and-typecheck; error: "
<< error;
ASSERT_EQ(error, nullptr);
ASSERT_NE(tm, nullptr);
absl::Cleanup free_tm([&] { xls_dslx_typechecked_module_free(tm); });

xls_dslx_module* module = xls_dslx_typechecked_module_get_module(tm);
xls_dslx_type_info* type_info = xls_dslx_typechecked_module_get_type_info(tm);
ASSERT_EQ(xls_dslx_module_get_type_definition_count(module), 2);

xls_dslx_struct_def* box_struct =
xls_dslx_module_get_type_definition_as_struct_def(module, 0);
ASSERT_TRUE(xls_dslx_struct_def_is_parametric(box_struct));
ASSERT_EQ(xls_dslx_struct_def_get_parametric_binding_count(box_struct), 1);
xls_dslx_parametric_binding* binding =
xls_dslx_struct_def_get_parametric_binding(box_struct, 0);
ASSERT_NE(binding, nullptr);
char* identifier = xls_dslx_parametric_binding_get_identifier(binding);
absl::Cleanup free_identifier([&] { xls_c_str_free(identifier); });
EXPECT_EQ(std::string_view{identifier}, "N");

xls_dslx_type_alias* type_alias =
xls_dslx_module_get_type_definition_as_type_alias(module, 1);
xls_dslx_type_annotation* rhs =
xls_dslx_type_alias_get_type_annotation(type_alias);
xls_dslx_type_ref_type_annotation* type_ref_type_annotation =
xls_dslx_type_annotation_get_type_ref_type_annotation(rhs);
ASSERT_NE(type_ref_type_annotation, nullptr);
ASSERT_EQ(xls_dslx_type_ref_type_annotation_get_parametric_count(
type_ref_type_annotation),
1);
xls_dslx_expr* parametric_expr =
xls_dslx_type_ref_type_annotation_get_parametric_expr(
type_ref_type_annotation, 0);
ASSERT_NE(parametric_expr, nullptr);

xls_dslx_interp_value* parametric_value = nullptr;
ASSERT_TRUE(xls_dslx_type_info_get_const_expr(
type_info, parametric_expr, &error, &parametric_value))
<< error;
ASSERT_NE(parametric_value, nullptr);
absl::Cleanup free_parametric_value(
[&] { xls_dslx_interp_value_free(parametric_value); });

char* parametric_value_str =
xls_dslx_interp_value_to_string(parametric_value);
absl::Cleanup free_parametric_value_str(
[&] { xls_c_str_free(parametric_value_str); });
EXPECT_EQ(std::string_view{parametric_value_str}, "u32:8");
}

TEST(XlsCApiTest, DslxInspectImportModuleMember) {
const char kImported[] = "pub const VALUE = u32:7;";
XLS_ASSERT_OK_AND_ASSIGN(xls::TempDirectory tempdir,
xls::TempDirectory::Create());
const std::filesystem::path& tempdir_path = tempdir.path();
const std::filesystem::path module_path =
tempdir_path / "my_imported_module.x";
XLS_ASSERT_OK(xls::SetFileContents(module_path, kImported));

const char kProgram[] = "import my_imported_module as mim;";
const char* additional_search_paths[] = {tempdir_path.c_str()};

xls_dslx_import_data* import_data = xls_dslx_import_data_create(
std::string{xls::kDefaultDslxStdlibPath}.c_str(), additional_search_paths,
ABSL_ARRAYSIZE(additional_search_paths));
ASSERT_NE(import_data, nullptr);
absl::Cleanup free_import_data(
[&] { xls_dslx_import_data_free(import_data); });

xls_dslx_typechecked_module* tm = nullptr;
char* error = nullptr;
absl::Cleanup free_error([&] { xls_c_str_free(error); });
bool ok = xls_dslx_parse_and_typecheck(kProgram, "foo.x", "foo", import_data,
&error, &tm);
ASSERT_TRUE(ok) << "got not-ok result from parse-and-typecheck; error: "
<< error;
ASSERT_EQ(error, nullptr);
ASSERT_NE(tm, nullptr);
absl::Cleanup free_tm([&] { xls_dslx_typechecked_module_free(tm); });

xls_dslx_module* module = xls_dslx_typechecked_module_get_module(tm);
ASSERT_EQ(xls_dslx_module_get_member_count(module), 1);
xls_dslx_module_member* member = xls_dslx_module_get_member(module, 0);
EXPECT_EQ(xls_dslx_module_member_get_kind(member),
xls_dslx_module_member_kind_import);
xls_dslx_import* import = xls_dslx_module_member_get_import(member);
ASSERT_NE(import, nullptr);
EXPECT_EQ(xls_dslx_import_get_subject_count(import), 1);
char* subject = xls_dslx_import_get_subject(import, 0);
absl::Cleanup free_subject([&] { xls_c_str_free(subject); });
EXPECT_EQ(std::string_view{subject}, "my_imported_module");
}

TEST(XlsCApiTest, DslxModuleMembers) {
const std::string_view kProgram = R"(
struct MyStruct {}
Expand Down
Loading