LLZK 0.1.0
Veridise's ZK Language IR
Loading...
Searching...
No Matches
DialectCAPITestGen.cpp
Go to the documentation of this file.
1//===- DialectCAPITestGen.cpp - C API test generator for dialects ---------===//
2//
3// Part of the LLZK Project, under the Apache License v2.0.
4// See LICENSE.txt for license information.
5// Copyright 2025 Veridise Inc.
6// SPDX-License-Identifier: Apache-2.0
7//
8//===----------------------------------------------------------------------===//
9//
10// DialectCAPITestGen generates unit tests for dialect-level C API functions.
11// These are link-time tests that ensure dialect handle functions compile and
12// link properly.
13//
14// Test Strategy:
15// - Tests verify that mlirGetDialectHandle__<namespace>__() functions can be called
16// - This ensures the dialect handle is properly exported and linkable
17// - The test simply calls the function without asserting anything about the result
18//
19//===----------------------------------------------------------------------===//
20
21#include <mlir/TableGen/Dialect.h>
22#include <mlir/TableGen/GenInfo.h>
23
24#include <llvm/ADT/StringExtras.h>
25#include <llvm/Support/CommandLine.h>
26#include <llvm/Support/FormatVariadic.h>
27#include <llvm/TableGen/Record.h>
28#include <llvm/TableGen/TableGenBackend.h>
29
30#include <algorithm>
31
32#include "CommonCAPIGen.h"
33
34using namespace mlir;
35using namespace mlir::tblgen;
36
37static llvm::cl::OptionCategory dialectTestGenCat("Options for -gen-dialect-capi-tests");
38
39namespace test_templates {
40
41static constexpr char DialectTestTemplate[] = R"(
42#include <mlir-c/IR.h>
43
44class {0}DialectLinkTests : public CAPITest {{};
45
46TEST_F({0}DialectLinkTests, get_dialect_handle_{2}) {{
47 (void)mlirGetDialectHandle{1}__();
48}
49)";
50
51} // namespace test_templates
52
54static bool emitDialectCAPITests(const llvm::RecordKeeper &records, llvm::raw_ostream &os) {
55 // Find the dialect definition
56 const auto &defs = records.getAllDerivedDefinitions("Dialect");
57
58 if (defs.empty()) {
59 llvm::errs() << "Error: No Dialect definition found in the input file\n";
60 return true;
61 }
62
63 if (defs.size() > 1) {
64 llvm::errs() << "Warning: Multiple Dialect definitions found, using the first one\n";
65 }
66
67 Dialect dialect(defs[0]);
68
69 // Use command-line dialect name if provided, otherwise use from definition
70 std::string effectiveDialectName =
71 DialectName.empty() ? dialect.getName().str() : DialectName.getValue();
72
73 // Get the C++ namespace from the dialect definition. It's like "::llzk::boolean"
74 // so replace all ':' with '_' to form the handle suffix.
75 std::string cppNamespaceStr = dialect.getCppNamespace().str();
76 std::replace(cppNamespaceStr.begin(), cppNamespaceStr.end(), ':', '_');
77
78 // Generate the test file
79 emitSourceFileHeader("Dialect C API Tests", os, records);
80 os << llvm::formatv(
81 test_templates::DialectTestTemplate,
82 toPascalCase(effectiveDialectName), // {0} - Capitalized dialect name for class/file
83 cppNamespaceStr, // {1} - Dialect handle suffix (e.g., "__llzk__boolean")
84 effectiveDialectName // {2} - Dialect name for test name
85 );
86
87 return false;
88}
89
90static mlir::GenRegistration genDialectCAPITests(
91 "gen-dialect-capi-tests", "Generate dialect-level C API unit tests", &emitDialectCAPITests
92);
llvm::cl::opt< std::string > DialectName
std::string toPascalCase(mlir::StringRef str)
Convert names separated by underscore or colon to PascalCase.