diff --git a/.clang_format b/.clang_format new file mode 100644 index 0000000..e2ed998 --- /dev/null +++ b/.clang_format @@ -0,0 +1,3 @@ +--- +BasedOnStyle: LLVM +SortIncludes: Never diff --git a/tests/test_basic_block.cpp b/tests/test_basic_block.cpp index 52e1a78..7256df0 100644 --- a/tests/test_basic_block.cpp +++ b/tests/test_basic_block.cpp @@ -16,129 +16,136 @@ * - LLVMDeleteBasicBlock() */ -#include -#include #include +#include +#include int main() { - LLVMContextRef ctx = LLVMContextCreate(); - LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_basic_block", ctx); + LLVMContextRef ctx = LLVMContextCreate(); + LLVMModuleRef mod = + LLVMModuleCreateWithNameInContext("test_basic_block", ctx); - LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); - LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx); + LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); + LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx); - // Create a function to hold basic blocks - LLVMTypeRef func_ty = LLVMFunctionType(void_ty, nullptr, 0, 0); - LLVMValueRef func = LLVMAddFunction(mod, "test_func", func_ty); + // Create a function to hold basic blocks + LLVMTypeRef func_ty = LLVMFunctionType(void_ty, nullptr, 0, 0); + LLVMValueRef func = LLVMAddFunction(mod, "test_func", func_ty); - // Append basic blocks - LLVMBasicBlockRef entry = LLVMAppendBasicBlockInContext(ctx, func, "entry"); - LLVMBasicBlockRef middle = LLVMAppendBasicBlockInContext(ctx, func, "middle"); - LLVMBasicBlockRef exit_bb = LLVMAppendBasicBlockInContext(ctx, func, "exit"); + // Append basic blocks + LLVMBasicBlockRef entry = LLVMAppendBasicBlockInContext(ctx, func, "entry"); + LLVMBasicBlockRef middle = LLVMAppendBasicBlockInContext(ctx, func, "middle"); + LLVMBasicBlockRef exit_bb = LLVMAppendBasicBlockInContext(ctx, func, "exit"); - // Get block names - const char *entry_name = LLVMGetBasicBlockName(entry); - const char *middle_name = LLVMGetBasicBlockName(middle); - const char *exit_name = LLVMGetBasicBlockName(exit_bb); + // Get block names + const char *entry_name = LLVMGetBasicBlockName(entry); + const char *middle_name = LLVMGetBasicBlockName(middle); + const char *exit_name = LLVMGetBasicBlockName(exit_bb); - // Get parent function - LLVMValueRef entry_parent = LLVMGetBasicBlockParent(entry); + // Get parent function + LLVMValueRef entry_parent = LLVMGetBasicBlockParent(entry); - // Get entry basic block - LLVMBasicBlockRef func_entry = LLVMGetEntryBasicBlock(func); + // Get entry basic block + LLVMBasicBlockRef func_entry = LLVMGetEntryBasicBlock(func); - // Count basic blocks - unsigned bb_count = LLVMCountBasicBlocks(func); + // Count basic blocks + unsigned bb_count = LLVMCountBasicBlocks(func); - // Create a builder to add instructions - LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); + // Create a builder to add instructions + LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); - // Add instructions to entry block - LLVMPositionBuilderAtEnd(builder, entry); - LLVMBuildBr(builder, middle); + // Add instructions to entry block + LLVMPositionBuilderAtEnd(builder, entry); + LLVMBuildBr(builder, middle); - // Add instructions to middle block - LLVMPositionBuilderAtEnd(builder, middle); - LLVMBuildBr(builder, exit_bb); + // Add instructions to middle block + LLVMPositionBuilderAtEnd(builder, middle); + LLVMBuildBr(builder, exit_bb); - // Add instructions to exit block - LLVMPositionBuilderAtEnd(builder, exit_bb); - LLVMBuildRetVoid(builder); + // Add instructions to exit block + LLVMPositionBuilderAtEnd(builder, exit_bb); + LLVMBuildRetVoid(builder); - // Get first/last instructions - LLVMValueRef entry_first = LLVMGetFirstInstruction(entry); - LLVMValueRef entry_last = LLVMGetLastInstruction(entry); - LLVMValueRef exit_terminator = LLVMGetBasicBlockTerminator(exit_bb); + // Get first/last instructions + LLVMValueRef entry_first = LLVMGetFirstInstruction(entry); + LLVMValueRef entry_last = LLVMGetLastInstruction(entry); + LLVMValueRef exit_terminator = LLVMGetBasicBlockTerminator(exit_bb); - // Create unattached block - LLVMBasicBlockRef unattached = LLVMCreateBasicBlockInContext(ctx, "unattached"); + // Create unattached block + LLVMBasicBlockRef unattached = + LLVMCreateBasicBlockInContext(ctx, "unattached"); - // Attach unattached block to function - LLVMAppendExistingBasicBlock(func, unattached); - LLVMPositionBuilderAtEnd(builder, unattached); - LLVMBuildUnreachable(builder); + // Attach unattached block to function + LLVMAppendExistingBasicBlock(func, unattached); + LLVMPositionBuilderAtEnd(builder, unattached); + LLVMBuildUnreachable(builder); - // Block count after adding unattached - unsigned bb_count_after = LLVMCountBasicBlocks(func); + // Block count after adding unattached + unsigned bb_count_after = LLVMCountBasicBlocks(func); - // Move blocks around: move unattached before exit - LLVMMoveBasicBlockBefore(unattached, exit_bb); + // Move blocks around: move unattached before exit + LLVMMoveBasicBlockBefore(unattached, exit_bb); - // Iterate through blocks - int block_index = 0; - printf("; Test: test_basic_block\n"); - printf(";\n"); - printf("; Basic block info:\n"); - printf("; entry name: %s\n", entry_name); - printf("; middle name: %s\n", middle_name); - printf("; exit name: %s\n", exit_name); - printf(";\n"); - printf("; Parent checks:\n"); - printf("; entry parent is func: %s\n", entry_parent == func ? "yes" : "no"); - printf("; func entry block is entry: %s\n", func_entry == entry ? "yes" : "no"); - printf(";\n"); - printf("; Block counts:\n"); - printf("; initial count: %u\n", bb_count); - printf("; after adding unattached: %u\n", bb_count_after); - printf(";\n"); - printf("; Instruction checks:\n"); - printf("; entry has first instruction: %s\n", entry_first != nullptr ? "yes" : "no"); - printf("; entry first == last (single inst): %s\n", entry_first == entry_last ? "yes" : "no"); - printf("; exit has terminator: %s\n", exit_terminator != nullptr ? "yes" : "no"); - printf(";\n"); - printf("; Block iteration (after move):\n"); - for (LLVMBasicBlockRef bb = LLVMGetFirstBasicBlock(func); bb; bb = LLVMGetNextBasicBlock(bb)) { - printf("; [%d] %s\n", block_index++, LLVMGetBasicBlockName(bb)); - } + // Iterate through blocks + int block_index = 0; + printf("; Test: test_basic_block\n"); + printf(";\n"); + printf("; Basic block info:\n"); + printf("; entry name: %s\n", entry_name); + printf("; middle name: %s\n", middle_name); + printf("; exit name: %s\n", exit_name); + printf(";\n"); + printf("; Parent checks:\n"); + printf("; entry parent is func: %s\n", entry_parent == func ? "yes" : "no"); + printf("; func entry block is entry: %s\n", + func_entry == entry ? "yes" : "no"); + printf(";\n"); + printf("; Block counts:\n"); + printf("; initial count: %u\n", bb_count); + printf("; after adding unattached: %u\n", bb_count_after); + printf(";\n"); + printf("; Instruction checks:\n"); + printf("; entry has first instruction: %s\n", + entry_first != nullptr ? "yes" : "no"); + printf("; entry first == last (single inst): %s\n", + entry_first == entry_last ? "yes" : "no"); + printf("; exit has terminator: %s\n", + exit_terminator != nullptr ? "yes" : "no"); + printf(";\n"); + printf("; Block iteration (after move):\n"); + for (LLVMBasicBlockRef bb = LLVMGetFirstBasicBlock(func); bb; + bb = LLVMGetNextBasicBlock(bb)) { + printf("; [%d] %s\n", block_index++, LLVMGetBasicBlockName(bb)); + } - // Get last block - LLVMBasicBlockRef last_bb = LLVMGetLastBasicBlock(func); - printf(";\n"); - printf("; Last block: %s\n", LLVMGetBasicBlockName(last_bb)); + // Get last block + LLVMBasicBlockRef last_bb = LLVMGetLastBasicBlock(func); + printf(";\n"); + printf("; Last block: %s\n", LLVMGetBasicBlockName(last_bb)); - LLVMDisposeBuilder(builder); + LLVMDisposeBuilder(builder); - // Verify module - char *error = nullptr; - if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { - fprintf(stderr, "; Verification failed: %s\n", error); - LLVMDisposeMessage(error); - LLVMDisposeModule(mod); - LLVMContextDispose(ctx); - return 1; - } + // Verify module + char *error = nullptr; + if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { + fprintf(stderr, "; Verification failed: %s\n", error); LLVMDisposeMessage(error); - - printf("\n"); - - // Print module IR - char *ir = LLVMPrintModuleToString(mod); - printf("%s", ir); - LLVMDisposeMessage(ir); - - // Cleanup LLVMDisposeModule(mod); LLVMContextDispose(ctx); + return 1; + } + LLVMDisposeMessage(error); - return 0; + printf("\n"); + + // Print module IR + char *ir = LLVMPrintModuleToString(mod); + printf("%s", ir); + LLVMDisposeMessage(ir); + + // Cleanup + LLVMDisposeModule(mod); + LLVMContextDispose(ctx); + + return 0; } diff --git a/tests/test_builder_arithmetic.cpp b/tests/test_builder_arithmetic.cpp index 298b2fb..10826b7 100644 --- a/tests/test_builder_arithmetic.cpp +++ b/tests/test_builder_arithmetic.cpp @@ -10,131 +10,136 @@ * - LLVMBuildMul(), LLVMBuildNSWMul(), LLVMBuildNUWMul() * - LLVMBuildSDiv(), LLVMBuildUDiv(), LLVMBuildExactSDiv() * - LLVMBuildSRem(), LLVMBuildURem() - * - LLVMBuildFAdd(), LLVMBuildFSub(), LLVMBuildFMul(), LLVMBuildFDiv(), LLVMBuildFRem() + * - LLVMBuildFAdd(), LLVMBuildFSub(), LLVMBuildFMul(), LLVMBuildFDiv(), + * LLVMBuildFRem() * - LLVMBuildShl(), LLVMBuildLShr(), LLVMBuildAShr() * - LLVMBuildAnd(), LLVMBuildOr(), LLVMBuildXor() * - LLVMBuildNeg(), LLVMBuildNSWNeg(), LLVMBuildFNeg(), LLVMBuildNot() */ -#include -#include #include +#include +#include int main() { - LLVMContextRef ctx = LLVMContextCreate(); - LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_builder_arithmetic", ctx); + LLVMContextRef ctx = LLVMContextCreate(); + LLVMModuleRef mod = + LLVMModuleCreateWithNameInContext("test_builder_arithmetic", ctx); - LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); - LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx); - LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx); + LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); + LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx); + LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx); - // Integer arithmetic function: i32 int_arith(i32, i32) - LLVMTypeRef int_params[] = {i32, i32}; - LLVMTypeRef int_func_ty = LLVMFunctionType(i32, int_params, 2, 0); - LLVMValueRef int_func = LLVMAddFunction(mod, "int_arith", int_func_ty); + // Integer arithmetic function: i32 int_arith(i32, i32) + LLVMTypeRef int_params[] = {i32, i32}; + LLVMTypeRef int_func_ty = LLVMFunctionType(i32, int_params, 2, 0); + LLVMValueRef int_func = LLVMAddFunction(mod, "int_arith", int_func_ty); - LLVMValueRef a = LLVMGetParam(int_func, 0); - LLVMValueRef b = LLVMGetParam(int_func, 1); - LLVMSetValueName2(a, "a", 1); - LLVMSetValueName2(b, "b", 1); + LLVMValueRef a = LLVMGetParam(int_func, 0); + LLVMValueRef b = LLVMGetParam(int_func, 1); + LLVMSetValueName2(a, "a", 1); + LLVMSetValueName2(b, "b", 1); - LLVMBasicBlockRef int_entry = LLVMAppendBasicBlockInContext(ctx, int_func, "entry"); - LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); - LLVMPositionBuilderAtEnd(builder, int_entry); + LLVMBasicBlockRef int_entry = + LLVMAppendBasicBlockInContext(ctx, int_func, "entry"); + LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); + LLVMPositionBuilderAtEnd(builder, int_entry); - // Basic arithmetic - LLVMValueRef add = LLVMBuildAdd(builder, a, b, "add"); - LLVMValueRef sub = LLVMBuildSub(builder, a, b, "sub"); - LLVMValueRef mul = LLVMBuildMul(builder, a, b, "mul"); - LLVMValueRef sdiv = LLVMBuildSDiv(builder, a, b, "sdiv"); - LLVMValueRef udiv = LLVMBuildUDiv(builder, a, b, "udiv"); - LLVMValueRef srem = LLVMBuildSRem(builder, a, b, "srem"); - LLVMValueRef urem = LLVMBuildURem(builder, a, b, "urem"); + // Basic arithmetic + LLVMValueRef add = LLVMBuildAdd(builder, a, b, "add"); + LLVMValueRef sub = LLVMBuildSub(builder, a, b, "sub"); + LLVMValueRef mul = LLVMBuildMul(builder, a, b, "mul"); + LLVMValueRef sdiv = LLVMBuildSDiv(builder, a, b, "sdiv"); + LLVMValueRef udiv = LLVMBuildUDiv(builder, a, b, "udiv"); + LLVMValueRef srem = LLVMBuildSRem(builder, a, b, "srem"); + LLVMValueRef urem = LLVMBuildURem(builder, a, b, "urem"); - // With overflow flags - LLVMValueRef nsw_add = LLVMBuildNSWAdd(builder, a, b, "nsw_add"); - LLVMValueRef nuw_add = LLVMBuildNUWAdd(builder, a, b, "nuw_add"); - LLVMValueRef nsw_sub = LLVMBuildNSWSub(builder, a, b, "nsw_sub"); - LLVMValueRef nuw_sub = LLVMBuildNUWSub(builder, a, b, "nuw_sub"); - LLVMValueRef nsw_mul = LLVMBuildNSWMul(builder, a, b, "nsw_mul"); - LLVMValueRef nuw_mul = LLVMBuildNUWMul(builder, a, b, "nuw_mul"); - LLVMValueRef exact_sdiv = LLVMBuildExactSDiv(builder, a, b, "exact_sdiv"); + // With overflow flags + LLVMValueRef nsw_add = LLVMBuildNSWAdd(builder, a, b, "nsw_add"); + LLVMValueRef nuw_add = LLVMBuildNUWAdd(builder, a, b, "nuw_add"); + LLVMValueRef nsw_sub = LLVMBuildNSWSub(builder, a, b, "nsw_sub"); + LLVMValueRef nuw_sub = LLVMBuildNUWSub(builder, a, b, "nuw_sub"); + LLVMValueRef nsw_mul = LLVMBuildNSWMul(builder, a, b, "nsw_mul"); + LLVMValueRef nuw_mul = LLVMBuildNUWMul(builder, a, b, "nuw_mul"); + LLVMValueRef exact_sdiv = LLVMBuildExactSDiv(builder, a, b, "exact_sdiv"); - // Bitwise operations - LLVMValueRef and_op = LLVMBuildAnd(builder, a, b, "and"); - LLVMValueRef or_op = LLVMBuildOr(builder, a, b, "or"); - LLVMValueRef xor_op = LLVMBuildXor(builder, a, b, "xor"); + // Bitwise operations + LLVMValueRef and_op = LLVMBuildAnd(builder, a, b, "and"); + LLVMValueRef or_op = LLVMBuildOr(builder, a, b, "or"); + LLVMValueRef xor_op = LLVMBuildXor(builder, a, b, "xor"); - // Shift operations - LLVMValueRef shl = LLVMBuildShl(builder, a, b, "shl"); - LLVMValueRef lshr = LLVMBuildLShr(builder, a, b, "lshr"); - LLVMValueRef ashr = LLVMBuildAShr(builder, a, b, "ashr"); + // Shift operations + LLVMValueRef shl = LLVMBuildShl(builder, a, b, "shl"); + LLVMValueRef lshr = LLVMBuildLShr(builder, a, b, "lshr"); + LLVMValueRef ashr = LLVMBuildAShr(builder, a, b, "ashr"); - // Unary operations - LLVMValueRef neg = LLVMBuildNeg(builder, a, "neg"); - LLVMValueRef nsw_neg = LLVMBuildNSWNeg(builder, a, "nsw_neg"); - LLVMValueRef not_op = LLVMBuildNot(builder, a, "not"); + // Unary operations + LLVMValueRef neg = LLVMBuildNeg(builder, a, "neg"); + LLVMValueRef nsw_neg = LLVMBuildNSWNeg(builder, a, "nsw_neg"); + LLVMValueRef not_op = LLVMBuildNot(builder, a, "not"); - // Return something to make function complete - LLVMBuildRet(builder, add); + // Return something to make function complete + LLVMBuildRet(builder, add); - // Floating point arithmetic function: f64 float_arith(f64, f64) - LLVMTypeRef fp_params[] = {f64, f64}; - LLVMTypeRef fp_func_ty = LLVMFunctionType(f64, fp_params, 2, 0); - LLVMValueRef fp_func = LLVMAddFunction(mod, "float_arith", fp_func_ty); + // Floating point arithmetic function: f64 float_arith(f64, f64) + LLVMTypeRef fp_params[] = {f64, f64}; + LLVMTypeRef fp_func_ty = LLVMFunctionType(f64, fp_params, 2, 0); + LLVMValueRef fp_func = LLVMAddFunction(mod, "float_arith", fp_func_ty); - LLVMValueRef x = LLVMGetParam(fp_func, 0); - LLVMValueRef y = LLVMGetParam(fp_func, 1); - LLVMSetValueName2(x, "x", 1); - LLVMSetValueName2(y, "y", 1); + LLVMValueRef x = LLVMGetParam(fp_func, 0); + LLVMValueRef y = LLVMGetParam(fp_func, 1); + LLVMSetValueName2(x, "x", 1); + LLVMSetValueName2(y, "y", 1); - LLVMBasicBlockRef fp_entry = LLVMAppendBasicBlockInContext(ctx, fp_func, "entry"); - LLVMPositionBuilderAtEnd(builder, fp_entry); + LLVMBasicBlockRef fp_entry = + LLVMAppendBasicBlockInContext(ctx, fp_func, "entry"); + LLVMPositionBuilderAtEnd(builder, fp_entry); - // Floating point operations - LLVMValueRef fadd = LLVMBuildFAdd(builder, x, y, "fadd"); - LLVMValueRef fsub = LLVMBuildFSub(builder, x, y, "fsub"); - LLVMValueRef fmul = LLVMBuildFMul(builder, x, y, "fmul"); - LLVMValueRef fdiv = LLVMBuildFDiv(builder, x, y, "fdiv"); - LLVMValueRef frem = LLVMBuildFRem(builder, x, y, "frem"); - LLVMValueRef fneg = LLVMBuildFNeg(builder, x, "fneg"); + // Floating point operations + LLVMValueRef fadd = LLVMBuildFAdd(builder, x, y, "fadd"); + LLVMValueRef fsub = LLVMBuildFSub(builder, x, y, "fsub"); + LLVMValueRef fmul = LLVMBuildFMul(builder, x, y, "fmul"); + LLVMValueRef fdiv = LLVMBuildFDiv(builder, x, y, "fdiv"); + LLVMValueRef frem = LLVMBuildFRem(builder, x, y, "frem"); + LLVMValueRef fneg = LLVMBuildFNeg(builder, x, "fneg"); - LLVMBuildRet(builder, fadd); + LLVMBuildRet(builder, fadd); - LLVMDisposeBuilder(builder); + LLVMDisposeBuilder(builder); - // Verify module - char *error = nullptr; - if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { - fprintf(stderr, "; Verification failed: %s\n", error); - LLVMDisposeMessage(error); - LLVMDisposeModule(mod); - LLVMContextDispose(ctx); - return 1; - } + // Verify module + char *error = nullptr; + if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { + fprintf(stderr, "; Verification failed: %s\n", error); LLVMDisposeMessage(error); - - // Print diagnostic comments - printf("; Test: test_builder_arithmetic\n"); - printf(";\n"); - printf("; Integer operations demonstrated:\n"); - printf("; add, sub, mul, sdiv, udiv, srem, urem\n"); - printf("; nsw_add, nuw_add, nsw_sub, nuw_sub, nsw_mul, nuw_mul, exact_sdiv\n"); - printf("; and, or, xor, shl, lshr, ashr\n"); - printf("; neg, nsw_neg, not\n"); - printf(";\n"); - printf("; Floating point operations demonstrated:\n"); - printf("; fadd, fsub, fmul, fdiv, frem, fneg\n"); - printf("\n"); - - // Print module IR - char *ir = LLVMPrintModuleToString(mod); - printf("%s", ir); - LLVMDisposeMessage(ir); - - // Cleanup LLVMDisposeModule(mod); LLVMContextDispose(ctx); + return 1; + } + LLVMDisposeMessage(error); - return 0; + // Print diagnostic comments + printf("; Test: test_builder_arithmetic\n"); + printf(";\n"); + printf("; Integer operations demonstrated:\n"); + printf("; add, sub, mul, sdiv, udiv, srem, urem\n"); + printf( + "; nsw_add, nuw_add, nsw_sub, nuw_sub, nsw_mul, nuw_mul, exact_sdiv\n"); + printf("; and, or, xor, shl, lshr, ashr\n"); + printf("; neg, nsw_neg, not\n"); + printf(";\n"); + printf("; Floating point operations demonstrated:\n"); + printf("; fadd, fsub, fmul, fdiv, frem, fneg\n"); + printf("\n"); + + // Print module IR + char *ir = LLVMPrintModuleToString(mod); + printf("%s", ir); + LLVMDisposeMessage(ir); + + // Cleanup + LLVMDisposeModule(mod); + LLVMContextDispose(ctx); + + return 0; } diff --git a/tests/test_builder_casts.cpp b/tests/test_builder_casts.cpp index 442981a..11930fb 100644 --- a/tests/test_builder_casts.cpp +++ b/tests/test_builder_casts.cpp @@ -12,174 +12,187 @@ * - LLVMBuildIntCast2() */ -#include -#include #include +#include +#include int main() { - LLVMContextRef ctx = LLVMContextCreate(); - LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_builder_casts", ctx); + LLVMContextRef ctx = LLVMContextCreate(); + LLVMModuleRef mod = + LLVMModuleCreateWithNameInContext("test_builder_casts", ctx); - LLVMTypeRef i8 = LLVMInt8TypeInContext(ctx); - LLVMTypeRef i16 = LLVMInt16TypeInContext(ctx); - LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); - LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx); - LLVMTypeRef f32 = LLVMFloatTypeInContext(ctx); - LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx); - LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0); - LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx); + LLVMTypeRef i8 = LLVMInt8TypeInContext(ctx); + LLVMTypeRef i16 = LLVMInt16TypeInContext(ctx); + LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); + LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx); + LLVMTypeRef f32 = LLVMFloatTypeInContext(ctx); + LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx); + LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0); + LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx); - LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); + LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); - // ========================================== - // Function 1: Integer casts - // ========================================== - LLVMTypeRef int_cast_params[] = {i64}; - LLVMTypeRef int_cast_ty = LLVMFunctionType(i8, int_cast_params, 1, 0); - LLVMValueRef int_cast_func = LLVMAddFunction(mod, "integer_casts", int_cast_ty); - LLVMValueRef i64_val = LLVMGetParam(int_cast_func, 0); - LLVMSetValueName2(i64_val, "val", 3); + // ========================================== + // Function 1: Integer casts + // ========================================== + LLVMTypeRef int_cast_params[] = {i64}; + LLVMTypeRef int_cast_ty = LLVMFunctionType(i8, int_cast_params, 1, 0); + LLVMValueRef int_cast_func = + LLVMAddFunction(mod, "integer_casts", int_cast_ty); + LLVMValueRef i64_val = LLVMGetParam(int_cast_func, 0); + LLVMSetValueName2(i64_val, "val", 3); - LLVMBasicBlockRef int_entry = LLVMAppendBasicBlockInContext(ctx, int_cast_func, "entry"); - LLVMPositionBuilderAtEnd(builder, int_entry); + LLVMBasicBlockRef int_entry = + LLVMAppendBasicBlockInContext(ctx, int_cast_func, "entry"); + LLVMPositionBuilderAtEnd(builder, int_entry); - // Truncate i64 -> i32 -> i16 -> i8 - LLVMValueRef trunc_32 = LLVMBuildTrunc(builder, i64_val, i32, "trunc_32"); - LLVMValueRef trunc_16 = LLVMBuildTrunc(builder, trunc_32, i16, "trunc_16"); - LLVMValueRef trunc_8 = LLVMBuildTrunc(builder, trunc_16, i8, "trunc_8"); + // Truncate i64 -> i32 -> i16 -> i8 + LLVMValueRef trunc_32 = LLVMBuildTrunc(builder, i64_val, i32, "trunc_32"); + LLVMValueRef trunc_16 = LLVMBuildTrunc(builder, trunc_32, i16, "trunc_16"); + LLVMValueRef trunc_8 = LLVMBuildTrunc(builder, trunc_16, i8, "trunc_8"); - // Zero extend i8 -> i16 -> i32 -> i64 - LLVMValueRef zext_16 = LLVMBuildZExt(builder, trunc_8, i16, "zext_16"); - LLVMValueRef zext_32 = LLVMBuildZExt(builder, zext_16, i32, "zext_32"); - LLVMValueRef zext_64 = LLVMBuildZExt(builder, zext_32, i64, "zext_64"); + // Zero extend i8 -> i16 -> i32 -> i64 + LLVMValueRef zext_16 = LLVMBuildZExt(builder, trunc_8, i16, "zext_16"); + LLVMValueRef zext_32 = LLVMBuildZExt(builder, zext_16, i32, "zext_32"); + LLVMValueRef zext_64 = LLVMBuildZExt(builder, zext_32, i64, "zext_64"); - // Sign extend i8 -> i16 -> i32 -> i64 - LLVMValueRef sext_16 = LLVMBuildSExt(builder, trunc_8, i16, "sext_16"); - LLVMValueRef sext_32 = LLVMBuildSExt(builder, sext_16, i32, "sext_32"); - LLVMValueRef sext_64 = LLVMBuildSExt(builder, sext_32, i64, "sext_64"); + // Sign extend i8 -> i16 -> i32 -> i64 + LLVMValueRef sext_16 = LLVMBuildSExt(builder, trunc_8, i16, "sext_16"); + LLVMValueRef sext_32 = LLVMBuildSExt(builder, sext_16, i32, "sext_32"); + LLVMValueRef sext_64 = LLVMBuildSExt(builder, sext_32, i64, "sext_64"); - // IntCast2 (auto-selects trunc/zext/sext) - LLVMValueRef intcast_unsigned = LLVMBuildIntCast2(builder, i64_val, i32, 0, "intcast_unsigned"); - LLVMValueRef intcast_signed = LLVMBuildIntCast2(builder, trunc_8, i32, 1, "intcast_signed"); + // IntCast2 (auto-selects trunc/zext/sext) + LLVMValueRef intcast_unsigned = + LLVMBuildIntCast2(builder, i64_val, i32, 0, "intcast_unsigned"); + LLVMValueRef intcast_signed = + LLVMBuildIntCast2(builder, trunc_8, i32, 1, "intcast_signed"); - LLVMBuildRet(builder, trunc_8); + LLVMBuildRet(builder, trunc_8); - // ========================================== - // Function 2: Float casts - // ========================================== - LLVMTypeRef fp_cast_params[] = {f64}; - LLVMTypeRef fp_cast_ty = LLVMFunctionType(f32, fp_cast_params, 1, 0); - LLVMValueRef fp_cast_func = LLVMAddFunction(mod, "float_casts", fp_cast_ty); - LLVMValueRef f64_val = LLVMGetParam(fp_cast_func, 0); - LLVMSetValueName2(f64_val, "val", 3); + // ========================================== + // Function 2: Float casts + // ========================================== + LLVMTypeRef fp_cast_params[] = {f64}; + LLVMTypeRef fp_cast_ty = LLVMFunctionType(f32, fp_cast_params, 1, 0); + LLVMValueRef fp_cast_func = LLVMAddFunction(mod, "float_casts", fp_cast_ty); + LLVMValueRef f64_val = LLVMGetParam(fp_cast_func, 0); + LLVMSetValueName2(f64_val, "val", 3); - LLVMBasicBlockRef fp_entry = LLVMAppendBasicBlockInContext(ctx, fp_cast_func, "entry"); - LLVMPositionBuilderAtEnd(builder, fp_entry); + LLVMBasicBlockRef fp_entry = + LLVMAppendBasicBlockInContext(ctx, fp_cast_func, "entry"); + LLVMPositionBuilderAtEnd(builder, fp_entry); - // FP truncate f64 -> f32 - LLVMValueRef fptrunc = LLVMBuildFPTrunc(builder, f64_val, f32, "fptrunc"); + // FP truncate f64 -> f32 + LLVMValueRef fptrunc = LLVMBuildFPTrunc(builder, f64_val, f32, "fptrunc"); - // FP extend f32 -> f64 - LLVMValueRef fpext = LLVMBuildFPExt(builder, fptrunc, f64, "fpext"); + // FP extend f32 -> f64 + LLVMValueRef fpext = LLVMBuildFPExt(builder, fptrunc, f64, "fpext"); - LLVMBuildRet(builder, fptrunc); + LLVMBuildRet(builder, fptrunc); - // ========================================== - // Function 3: Int <-> Float casts - // ========================================== - LLVMTypeRef mixed_params[] = {i32, f64}; - LLVMTypeRef mixed_ty = LLVMFunctionType(void_ty, mixed_params, 2, 0); - LLVMValueRef mixed_func = LLVMAddFunction(mod, "int_float_casts", mixed_ty); - LLVMValueRef int_param = LLVMGetParam(mixed_func, 0); - LLVMValueRef fp_param = LLVMGetParam(mixed_func, 1); - LLVMSetValueName2(int_param, "i", 1); - LLVMSetValueName2(fp_param, "f", 1); + // ========================================== + // Function 3: Int <-> Float casts + // ========================================== + LLVMTypeRef mixed_params[] = {i32, f64}; + LLVMTypeRef mixed_ty = LLVMFunctionType(void_ty, mixed_params, 2, 0); + LLVMValueRef mixed_func = LLVMAddFunction(mod, "int_float_casts", mixed_ty); + LLVMValueRef int_param = LLVMGetParam(mixed_func, 0); + LLVMValueRef fp_param = LLVMGetParam(mixed_func, 1); + LLVMSetValueName2(int_param, "i", 1); + LLVMSetValueName2(fp_param, "f", 1); - LLVMBasicBlockRef mixed_entry = LLVMAppendBasicBlockInContext(ctx, mixed_func, "entry"); - LLVMPositionBuilderAtEnd(builder, mixed_entry); + LLVMBasicBlockRef mixed_entry = + LLVMAppendBasicBlockInContext(ctx, mixed_func, "entry"); + LLVMPositionBuilderAtEnd(builder, mixed_entry); - // Int -> Float - LLVMValueRef uitofp = LLVMBuildUIToFP(builder, int_param, f64, "uitofp"); - LLVMValueRef sitofp = LLVMBuildSIToFP(builder, int_param, f64, "sitofp"); + // Int -> Float + LLVMValueRef uitofp = LLVMBuildUIToFP(builder, int_param, f64, "uitofp"); + LLVMValueRef sitofp = LLVMBuildSIToFP(builder, int_param, f64, "sitofp"); - // Float -> Int - LLVMValueRef fptoui = LLVMBuildFPToUI(builder, fp_param, i32, "fptoui"); - LLVMValueRef fptosi = LLVMBuildFPToSI(builder, fp_param, i32, "fptosi"); + // Float -> Int + LLVMValueRef fptoui = LLVMBuildFPToUI(builder, fp_param, i32, "fptoui"); + LLVMValueRef fptosi = LLVMBuildFPToSI(builder, fp_param, i32, "fptosi"); - LLVMBuildRetVoid(builder); + LLVMBuildRetVoid(builder); - // ========================================== - // Function 4: Pointer casts - // ========================================== - LLVMTypeRef ptr_params[] = {ptr, i64}; - LLVMTypeRef ptr_ty = LLVMFunctionType(void_ty, ptr_params, 2, 0); - LLVMValueRef ptr_func = LLVMAddFunction(mod, "pointer_casts", ptr_ty); - LLVMValueRef ptr_param = LLVMGetParam(ptr_func, 0); - LLVMValueRef int_for_ptr = LLVMGetParam(ptr_func, 1); - LLVMSetValueName2(ptr_param, "p", 1); - LLVMSetValueName2(int_for_ptr, "addr", 4); + // ========================================== + // Function 4: Pointer casts + // ========================================== + LLVMTypeRef ptr_params[] = {ptr, i64}; + LLVMTypeRef ptr_ty = LLVMFunctionType(void_ty, ptr_params, 2, 0); + LLVMValueRef ptr_func = LLVMAddFunction(mod, "pointer_casts", ptr_ty); + LLVMValueRef ptr_param = LLVMGetParam(ptr_func, 0); + LLVMValueRef int_for_ptr = LLVMGetParam(ptr_func, 1); + LLVMSetValueName2(ptr_param, "p", 1); + LLVMSetValueName2(int_for_ptr, "addr", 4); - LLVMBasicBlockRef ptr_entry = LLVMAppendBasicBlockInContext(ctx, ptr_func, "entry"); - LLVMPositionBuilderAtEnd(builder, ptr_entry); + LLVMBasicBlockRef ptr_entry = + LLVMAppendBasicBlockInContext(ctx, ptr_func, "entry"); + LLVMPositionBuilderAtEnd(builder, ptr_entry); - // Pointer -> Int - LLVMValueRef ptrtoint = LLVMBuildPtrToInt(builder, ptr_param, i64, "ptrtoint"); + // Pointer -> Int + LLVMValueRef ptrtoint = + LLVMBuildPtrToInt(builder, ptr_param, i64, "ptrtoint"); - // Int -> Pointer - LLVMValueRef inttoptr = LLVMBuildIntToPtr(builder, int_for_ptr, ptr, "inttoptr"); + // Int -> Pointer + LLVMValueRef inttoptr = + LLVMBuildIntToPtr(builder, int_for_ptr, ptr, "inttoptr"); - LLVMBuildRetVoid(builder); + LLVMBuildRetVoid(builder); - // ========================================== - // Function 5: Bitcast - // ========================================== - LLVMTypeRef vec_i32 = LLVMVectorType(i32, 4); - LLVMTypeRef vec_f32 = LLVMVectorType(f32, 4); + // ========================================== + // Function 5: Bitcast + // ========================================== + LLVMTypeRef vec_i32 = LLVMVectorType(i32, 4); + LLVMTypeRef vec_f32 = LLVMVectorType(f32, 4); - LLVMTypeRef bitcast_params[] = {vec_i32}; - LLVMTypeRef bitcast_ty = LLVMFunctionType(vec_f32, bitcast_params, 1, 0); - LLVMValueRef bitcast_func = LLVMAddFunction(mod, "bitcast_example", bitcast_ty); - LLVMValueRef vec_param = LLVMGetParam(bitcast_func, 0); - LLVMSetValueName2(vec_param, "v", 1); + LLVMTypeRef bitcast_params[] = {vec_i32}; + LLVMTypeRef bitcast_ty = LLVMFunctionType(vec_f32, bitcast_params, 1, 0); + LLVMValueRef bitcast_func = + LLVMAddFunction(mod, "bitcast_example", bitcast_ty); + LLVMValueRef vec_param = LLVMGetParam(bitcast_func, 0); + LLVMSetValueName2(vec_param, "v", 1); - LLVMBasicBlockRef bitcast_entry = LLVMAppendBasicBlockInContext(ctx, bitcast_func, "entry"); - LLVMPositionBuilderAtEnd(builder, bitcast_entry); + LLVMBasicBlockRef bitcast_entry = + LLVMAppendBasicBlockInContext(ctx, bitcast_func, "entry"); + LLVMPositionBuilderAtEnd(builder, bitcast_entry); - LLVMValueRef bitcast = LLVMBuildBitCast(builder, vec_param, vec_f32, "bitcast"); - LLVMBuildRet(builder, bitcast); + LLVMValueRef bitcast = + LLVMBuildBitCast(builder, vec_param, vec_f32, "bitcast"); + LLVMBuildRet(builder, bitcast); - LLVMDisposeBuilder(builder); + LLVMDisposeBuilder(builder); - // Verify module - char *error = nullptr; - if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { - fprintf(stderr, "; Verification failed: %s\n", error); - LLVMDisposeMessage(error); - LLVMDisposeModule(mod); - LLVMContextDispose(ctx); - return 1; - } + // Verify module + char *error = nullptr; + if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { + fprintf(stderr, "; Verification failed: %s\n", error); LLVMDisposeMessage(error); - - // Print diagnostic comments - printf("; Test: test_builder_casts\n"); - printf(";\n"); - printf("; Cast operations demonstrated:\n"); - printf("; Integer: trunc, zext, sext, intcast2\n"); - printf("; Float: fptrunc, fpext\n"); - printf("; Int<->Float: uitofp, sitofp, fptoui, fptosi\n"); - printf("; Pointer: ptrtoint, inttoptr\n"); - printf("; Reinterpret: bitcast\n"); - printf("\n"); - - // Print module IR - char *ir = LLVMPrintModuleToString(mod); - printf("%s", ir); - LLVMDisposeMessage(ir); - - // Cleanup LLVMDisposeModule(mod); LLVMContextDispose(ctx); + return 1; + } + LLVMDisposeMessage(error); - return 0; + // Print diagnostic comments + printf("; Test: test_builder_casts\n"); + printf(";\n"); + printf("; Cast operations demonstrated:\n"); + printf("; Integer: trunc, zext, sext, intcast2\n"); + printf("; Float: fptrunc, fpext\n"); + printf("; Int<->Float: uitofp, sitofp, fptoui, fptosi\n"); + printf("; Pointer: ptrtoint, inttoptr\n"); + printf("; Reinterpret: bitcast\n"); + printf("\n"); + + // Print module IR + char *ir = LLVMPrintModuleToString(mod); + printf("%s", ir); + LLVMDisposeMessage(ir); + + // Cleanup + LLVMDisposeModule(mod); + LLVMContextDispose(ctx); + + return 0; } diff --git a/tests/test_builder_cmp.cpp b/tests/test_builder_cmp.cpp index 333dc12..e8ffa27 100644 --- a/tests/test_builder_cmp.cpp +++ b/tests/test_builder_cmp.cpp @@ -9,205 +9,245 @@ * - LLVMGetICmpPredicate(), LLVMGetFCmpPredicate() */ -#include -#include #include +#include +#include -const char* int_pred_name(LLVMIntPredicate pred) { - switch (pred) { - case LLVMIntEQ: return "eq"; - case LLVMIntNE: return "ne"; - case LLVMIntUGT: return "ugt"; - case LLVMIntUGE: return "uge"; - case LLVMIntULT: return "ult"; - case LLVMIntULE: return "ule"; - case LLVMIntSGT: return "sgt"; - case LLVMIntSGE: return "sge"; - case LLVMIntSLT: return "slt"; - case LLVMIntSLE: return "sle"; - default: return "unknown"; - } +const char *int_pred_name(LLVMIntPredicate pred) { + switch (pred) { + case LLVMIntEQ: + return "eq"; + case LLVMIntNE: + return "ne"; + case LLVMIntUGT: + return "ugt"; + case LLVMIntUGE: + return "uge"; + case LLVMIntULT: + return "ult"; + case LLVMIntULE: + return "ule"; + case LLVMIntSGT: + return "sgt"; + case LLVMIntSGE: + return "sge"; + case LLVMIntSLT: + return "slt"; + case LLVMIntSLE: + return "sle"; + default: + return "unknown"; + } } -const char* real_pred_name(LLVMRealPredicate pred) { - switch (pred) { - case LLVMRealPredicateFalse: return "false"; - case LLVMRealOEQ: return "oeq"; - case LLVMRealOGT: return "ogt"; - case LLVMRealOGE: return "oge"; - case LLVMRealOLT: return "olt"; - case LLVMRealOLE: return "ole"; - case LLVMRealONE: return "one"; - case LLVMRealORD: return "ord"; - case LLVMRealUNO: return "uno"; - case LLVMRealUEQ: return "ueq"; - case LLVMRealUGT: return "ugt"; - case LLVMRealUGE: return "uge"; - case LLVMRealULT: return "ult"; - case LLVMRealULE: return "ule"; - case LLVMRealUNE: return "une"; - case LLVMRealPredicateTrue: return "true"; - default: return "unknown"; - } +const char *real_pred_name(LLVMRealPredicate pred) { + switch (pred) { + case LLVMRealPredicateFalse: + return "false"; + case LLVMRealOEQ: + return "oeq"; + case LLVMRealOGT: + return "ogt"; + case LLVMRealOGE: + return "oge"; + case LLVMRealOLT: + return "olt"; + case LLVMRealOLE: + return "ole"; + case LLVMRealONE: + return "one"; + case LLVMRealORD: + return "ord"; + case LLVMRealUNO: + return "uno"; + case LLVMRealUEQ: + return "ueq"; + case LLVMRealUGT: + return "ugt"; + case LLVMRealUGE: + return "uge"; + case LLVMRealULT: + return "ult"; + case LLVMRealULE: + return "ule"; + case LLVMRealUNE: + return "une"; + case LLVMRealPredicateTrue: + return "true"; + default: + return "unknown"; + } } int main() { - LLVMContextRef ctx = LLVMContextCreate(); - LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_builder_cmp", ctx); + LLVMContextRef ctx = LLVMContextCreate(); + LLVMModuleRef mod = + LLVMModuleCreateWithNameInContext("test_builder_cmp", ctx); - LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx); - LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); - LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx); - LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx); + LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx); + LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); + LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx); + LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx); - LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); + LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); - // ========================================== - // Function 1: Integer comparisons - // ========================================== - LLVMTypeRef icmp_params[] = {i32, i32}; - LLVMTypeRef icmp_ty = LLVMFunctionType(void_ty, icmp_params, 2, 0); - LLVMValueRef icmp_func = LLVMAddFunction(mod, "int_comparisons", icmp_ty); - LLVMValueRef a = LLVMGetParam(icmp_func, 0); - LLVMValueRef b = LLVMGetParam(icmp_func, 1); - LLVMSetValueName2(a, "a", 1); - LLVMSetValueName2(b, "b", 1); + // ========================================== + // Function 1: Integer comparisons + // ========================================== + LLVMTypeRef icmp_params[] = {i32, i32}; + LLVMTypeRef icmp_ty = LLVMFunctionType(void_ty, icmp_params, 2, 0); + LLVMValueRef icmp_func = LLVMAddFunction(mod, "int_comparisons", icmp_ty); + LLVMValueRef a = LLVMGetParam(icmp_func, 0); + LLVMValueRef b = LLVMGetParam(icmp_func, 1); + LLVMSetValueName2(a, "a", 1); + LLVMSetValueName2(b, "b", 1); - LLVMBasicBlockRef icmp_entry = LLVMAppendBasicBlockInContext(ctx, icmp_func, "entry"); - LLVMPositionBuilderAtEnd(builder, icmp_entry); + LLVMBasicBlockRef icmp_entry = + LLVMAppendBasicBlockInContext(ctx, icmp_func, "entry"); + LLVMPositionBuilderAtEnd(builder, icmp_entry); - // All integer predicates - LLVMValueRef icmp_eq = LLVMBuildICmp(builder, LLVMIntEQ, a, b, "eq"); - LLVMValueRef icmp_ne = LLVMBuildICmp(builder, LLVMIntNE, a, b, "ne"); - LLVMValueRef icmp_ugt = LLVMBuildICmp(builder, LLVMIntUGT, a, b, "ugt"); - LLVMValueRef icmp_uge = LLVMBuildICmp(builder, LLVMIntUGE, a, b, "uge"); - LLVMValueRef icmp_ult = LLVMBuildICmp(builder, LLVMIntULT, a, b, "ult"); - LLVMValueRef icmp_ule = LLVMBuildICmp(builder, LLVMIntULE, a, b, "ule"); - LLVMValueRef icmp_sgt = LLVMBuildICmp(builder, LLVMIntSGT, a, b, "sgt"); - LLVMValueRef icmp_sge = LLVMBuildICmp(builder, LLVMIntSGE, a, b, "sge"); - LLVMValueRef icmp_slt = LLVMBuildICmp(builder, LLVMIntSLT, a, b, "slt"); - LLVMValueRef icmp_sle = LLVMBuildICmp(builder, LLVMIntSLE, a, b, "sle"); + // All integer predicates + LLVMValueRef icmp_eq = LLVMBuildICmp(builder, LLVMIntEQ, a, b, "eq"); + LLVMValueRef icmp_ne = LLVMBuildICmp(builder, LLVMIntNE, a, b, "ne"); + LLVMValueRef icmp_ugt = LLVMBuildICmp(builder, LLVMIntUGT, a, b, "ugt"); + LLVMValueRef icmp_uge = LLVMBuildICmp(builder, LLVMIntUGE, a, b, "uge"); + LLVMValueRef icmp_ult = LLVMBuildICmp(builder, LLVMIntULT, a, b, "ult"); + LLVMValueRef icmp_ule = LLVMBuildICmp(builder, LLVMIntULE, a, b, "ule"); + LLVMValueRef icmp_sgt = LLVMBuildICmp(builder, LLVMIntSGT, a, b, "sgt"); + LLVMValueRef icmp_sge = LLVMBuildICmp(builder, LLVMIntSGE, a, b, "sge"); + LLVMValueRef icmp_slt = LLVMBuildICmp(builder, LLVMIntSLT, a, b, "slt"); + LLVMValueRef icmp_sle = LLVMBuildICmp(builder, LLVMIntSLE, a, b, "sle"); - LLVMBuildRetVoid(builder); + LLVMBuildRetVoid(builder); - // ========================================== - // Function 2: Float comparisons - // ========================================== - LLVMTypeRef fcmp_params[] = {f64, f64}; - LLVMTypeRef fcmp_ty = LLVMFunctionType(void_ty, fcmp_params, 2, 0); - LLVMValueRef fcmp_func = LLVMAddFunction(mod, "float_comparisons", fcmp_ty); - LLVMValueRef x = LLVMGetParam(fcmp_func, 0); - LLVMValueRef y = LLVMGetParam(fcmp_func, 1); - LLVMSetValueName2(x, "x", 1); - LLVMSetValueName2(y, "y", 1); + // ========================================== + // Function 2: Float comparisons + // ========================================== + LLVMTypeRef fcmp_params[] = {f64, f64}; + LLVMTypeRef fcmp_ty = LLVMFunctionType(void_ty, fcmp_params, 2, 0); + LLVMValueRef fcmp_func = LLVMAddFunction(mod, "float_comparisons", fcmp_ty); + LLVMValueRef x = LLVMGetParam(fcmp_func, 0); + LLVMValueRef y = LLVMGetParam(fcmp_func, 1); + LLVMSetValueName2(x, "x", 1); + LLVMSetValueName2(y, "y", 1); - LLVMBasicBlockRef fcmp_entry = LLVMAppendBasicBlockInContext(ctx, fcmp_func, "entry"); - LLVMPositionBuilderAtEnd(builder, fcmp_entry); + LLVMBasicBlockRef fcmp_entry = + LLVMAppendBasicBlockInContext(ctx, fcmp_func, "entry"); + LLVMPositionBuilderAtEnd(builder, fcmp_entry); - // Ordered comparisons (false if either is NaN) - LLVMValueRef fcmp_oeq = LLVMBuildFCmp(builder, LLVMRealOEQ, x, y, "oeq"); - LLVMValueRef fcmp_ogt = LLVMBuildFCmp(builder, LLVMRealOGT, x, y, "ogt"); - LLVMValueRef fcmp_oge = LLVMBuildFCmp(builder, LLVMRealOGE, x, y, "oge"); - LLVMValueRef fcmp_olt = LLVMBuildFCmp(builder, LLVMRealOLT, x, y, "olt"); - LLVMValueRef fcmp_ole = LLVMBuildFCmp(builder, LLVMRealOLE, x, y, "ole"); - LLVMValueRef fcmp_one = LLVMBuildFCmp(builder, LLVMRealONE, x, y, "one"); - LLVMValueRef fcmp_ord = LLVMBuildFCmp(builder, LLVMRealORD, x, y, "ord"); + // Ordered comparisons (false if either is NaN) + LLVMValueRef fcmp_oeq = LLVMBuildFCmp(builder, LLVMRealOEQ, x, y, "oeq"); + LLVMValueRef fcmp_ogt = LLVMBuildFCmp(builder, LLVMRealOGT, x, y, "ogt"); + LLVMValueRef fcmp_oge = LLVMBuildFCmp(builder, LLVMRealOGE, x, y, "oge"); + LLVMValueRef fcmp_olt = LLVMBuildFCmp(builder, LLVMRealOLT, x, y, "olt"); + LLVMValueRef fcmp_ole = LLVMBuildFCmp(builder, LLVMRealOLE, x, y, "ole"); + LLVMValueRef fcmp_one = LLVMBuildFCmp(builder, LLVMRealONE, x, y, "one"); + LLVMValueRef fcmp_ord = LLVMBuildFCmp(builder, LLVMRealORD, x, y, "ord"); - // Unordered comparisons (true if either is NaN) - LLVMValueRef fcmp_uno = LLVMBuildFCmp(builder, LLVMRealUNO, x, y, "uno"); - LLVMValueRef fcmp_ueq = LLVMBuildFCmp(builder, LLVMRealUEQ, x, y, "ueq"); - LLVMValueRef fcmp_ugt = LLVMBuildFCmp(builder, LLVMRealUGT, x, y, "ugt"); - LLVMValueRef fcmp_uge = LLVMBuildFCmp(builder, LLVMRealUGE, x, y, "uge"); - LLVMValueRef fcmp_ult = LLVMBuildFCmp(builder, LLVMRealULT, x, y, "ult"); - LLVMValueRef fcmp_ule = LLVMBuildFCmp(builder, LLVMRealULE, x, y, "ule"); - LLVMValueRef fcmp_une = LLVMBuildFCmp(builder, LLVMRealUNE, x, y, "une"); + // Unordered comparisons (true if either is NaN) + LLVMValueRef fcmp_uno = LLVMBuildFCmp(builder, LLVMRealUNO, x, y, "uno"); + LLVMValueRef fcmp_ueq = LLVMBuildFCmp(builder, LLVMRealUEQ, x, y, "ueq"); + LLVMValueRef fcmp_ugt = LLVMBuildFCmp(builder, LLVMRealUGT, x, y, "ugt"); + LLVMValueRef fcmp_uge = LLVMBuildFCmp(builder, LLVMRealUGE, x, y, "uge"); + LLVMValueRef fcmp_ult = LLVMBuildFCmp(builder, LLVMRealULT, x, y, "ult"); + LLVMValueRef fcmp_ule = LLVMBuildFCmp(builder, LLVMRealULE, x, y, "ule"); + LLVMValueRef fcmp_une = LLVMBuildFCmp(builder, LLVMRealUNE, x, y, "une"); - // Always true/false - LLVMValueRef fcmp_true = LLVMBuildFCmp(builder, LLVMRealPredicateTrue, x, y, "always_true"); - LLVMValueRef fcmp_false = LLVMBuildFCmp(builder, LLVMRealPredicateFalse, x, y, "always_false"); + // Always true/false + LLVMValueRef fcmp_true = + LLVMBuildFCmp(builder, LLVMRealPredicateTrue, x, y, "always_true"); + LLVMValueRef fcmp_false = + LLVMBuildFCmp(builder, LLVMRealPredicateFalse, x, y, "always_false"); - LLVMBuildRetVoid(builder); + LLVMBuildRetVoid(builder); - // ========================================== - // Function 3: Select instruction - // ========================================== - LLVMTypeRef sel_params[] = {i1, i32, i32}; - LLVMTypeRef sel_ty = LLVMFunctionType(i32, sel_params, 3, 0); - LLVMValueRef sel_func = LLVMAddFunction(mod, "select_example", sel_ty); - LLVMValueRef cond = LLVMGetParam(sel_func, 0); - LLVMValueRef true_val = LLVMGetParam(sel_func, 1); - LLVMValueRef false_val = LLVMGetParam(sel_func, 2); - LLVMSetValueName2(cond, "cond", 4); - LLVMSetValueName2(true_val, "true_val", 8); - LLVMSetValueName2(false_val, "false_val", 9); + // ========================================== + // Function 3: Select instruction + // ========================================== + LLVMTypeRef sel_params[] = {i1, i32, i32}; + LLVMTypeRef sel_ty = LLVMFunctionType(i32, sel_params, 3, 0); + LLVMValueRef sel_func = LLVMAddFunction(mod, "select_example", sel_ty); + LLVMValueRef cond = LLVMGetParam(sel_func, 0); + LLVMValueRef true_val = LLVMGetParam(sel_func, 1); + LLVMValueRef false_val = LLVMGetParam(sel_func, 2); + LLVMSetValueName2(cond, "cond", 4); + LLVMSetValueName2(true_val, "true_val", 8); + LLVMSetValueName2(false_val, "false_val", 9); - LLVMBasicBlockRef sel_entry = LLVMAppendBasicBlockInContext(ctx, sel_func, "entry"); - LLVMPositionBuilderAtEnd(builder, sel_entry); + LLVMBasicBlockRef sel_entry = + LLVMAppendBasicBlockInContext(ctx, sel_func, "entry"); + LLVMPositionBuilderAtEnd(builder, sel_entry); - LLVMValueRef selected = LLVMBuildSelect(builder, cond, true_val, false_val, "selected"); - LLVMBuildRet(builder, selected); + LLVMValueRef selected = + LLVMBuildSelect(builder, cond, true_val, false_val, "selected"); + LLVMBuildRet(builder, selected); - // ========================================== - // Function 4: Select with comparison - // ========================================== - LLVMTypeRef max_params[] = {i32, i32}; - LLVMTypeRef max_ty = LLVMFunctionType(i32, max_params, 2, 0); - LLVMValueRef max_func = LLVMAddFunction(mod, "max", max_ty); - LLVMValueRef m_a = LLVMGetParam(max_func, 0); - LLVMValueRef m_b = LLVMGetParam(max_func, 1); - LLVMSetValueName2(m_a, "a", 1); - LLVMSetValueName2(m_b, "b", 1); + // ========================================== + // Function 4: Select with comparison + // ========================================== + LLVMTypeRef max_params[] = {i32, i32}; + LLVMTypeRef max_ty = LLVMFunctionType(i32, max_params, 2, 0); + LLVMValueRef max_func = LLVMAddFunction(mod, "max", max_ty); + LLVMValueRef m_a = LLVMGetParam(max_func, 0); + LLVMValueRef m_b = LLVMGetParam(max_func, 1); + LLVMSetValueName2(m_a, "a", 1); + LLVMSetValueName2(m_b, "b", 1); - LLVMBasicBlockRef max_entry = LLVMAppendBasicBlockInContext(ctx, max_func, "entry"); - LLVMPositionBuilderAtEnd(builder, max_entry); + LLVMBasicBlockRef max_entry = + LLVMAppendBasicBlockInContext(ctx, max_func, "entry"); + LLVMPositionBuilderAtEnd(builder, max_entry); - LLVMValueRef cmp_gt = LLVMBuildICmp(builder, LLVMIntSGT, m_a, m_b, "a_gt_b"); - LLVMValueRef max_result = LLVMBuildSelect(builder, cmp_gt, m_a, m_b, "max"); - LLVMBuildRet(builder, max_result); + LLVMValueRef cmp_gt = LLVMBuildICmp(builder, LLVMIntSGT, m_a, m_b, "a_gt_b"); + LLVMValueRef max_result = LLVMBuildSelect(builder, cmp_gt, m_a, m_b, "max"); + LLVMBuildRet(builder, max_result); - LLVMDisposeBuilder(builder); + LLVMDisposeBuilder(builder); - // Verify module - char *error = nullptr; - if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { - fprintf(stderr, "; Verification failed: %s\n", error); - LLVMDisposeMessage(error); - LLVMDisposeModule(mod); - LLVMContextDispose(ctx); - return 1; - } + // Verify module + char *error = nullptr; + if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { + fprintf(stderr, "; Verification failed: %s\n", error); LLVMDisposeMessage(error); - - // Print diagnostic comments - printf("; Test: test_builder_cmp\n"); - printf(";\n"); - printf("; Integer comparison predicates:\n"); - printf("; eq, ne (equality)\n"); - printf("; ugt, uge, ult, ule (unsigned)\n"); - printf("; sgt, sge, slt, sle (signed)\n"); - printf(";\n"); - printf("; Float comparison predicates:\n"); - printf("; Ordered: oeq, ogt, oge, olt, ole, one, ord\n"); - printf("; Unordered: uno, ueq, ugt, uge, ult, ule, une\n"); - printf("; Constant: true, false\n"); - printf(";\n"); - printf("; Predicate extraction:\n"); - printf("; icmp_eq predicate: %s\n", int_pred_name(LLVMGetICmpPredicate(icmp_eq))); - printf("; icmp_slt predicate: %s\n", int_pred_name(LLVMGetICmpPredicate(icmp_slt))); - printf("; fcmp_oeq predicate: %s\n", real_pred_name(LLVMGetFCmpPredicate(fcmp_oeq))); - printf("; fcmp_uno predicate: %s\n", real_pred_name(LLVMGetFCmpPredicate(fcmp_uno))); - printf(";\n"); - printf("; Select instruction: cond ? true_val : false_val\n"); - printf("\n"); - - // Print module IR - char *ir = LLVMPrintModuleToString(mod); - printf("%s", ir); - LLVMDisposeMessage(ir); - - // Cleanup LLVMDisposeModule(mod); LLVMContextDispose(ctx); + return 1; + } + LLVMDisposeMessage(error); - return 0; + // Print diagnostic comments + printf("; Test: test_builder_cmp\n"); + printf(";\n"); + printf("; Integer comparison predicates:\n"); + printf("; eq, ne (equality)\n"); + printf("; ugt, uge, ult, ule (unsigned)\n"); + printf("; sgt, sge, slt, sle (signed)\n"); + printf(";\n"); + printf("; Float comparison predicates:\n"); + printf("; Ordered: oeq, ogt, oge, olt, ole, one, ord\n"); + printf("; Unordered: uno, ueq, ugt, uge, ult, ule, une\n"); + printf("; Constant: true, false\n"); + printf(";\n"); + printf("; Predicate extraction:\n"); + printf("; icmp_eq predicate: %s\n", + int_pred_name(LLVMGetICmpPredicate(icmp_eq))); + printf("; icmp_slt predicate: %s\n", + int_pred_name(LLVMGetICmpPredicate(icmp_slt))); + printf("; fcmp_oeq predicate: %s\n", + real_pred_name(LLVMGetFCmpPredicate(fcmp_oeq))); + printf("; fcmp_uno predicate: %s\n", + real_pred_name(LLVMGetFCmpPredicate(fcmp_uno))); + printf(";\n"); + printf("; Select instruction: cond ? true_val : false_val\n"); + printf("\n"); + + // Print module IR + char *ir = LLVMPrintModuleToString(mod); + printf("%s", ir); + LLVMDisposeMessage(ir); + + // Cleanup + LLVMDisposeModule(mod); + LLVMContextDispose(ctx); + + return 0; } diff --git a/tests/test_builder_control_flow.cpp b/tests/test_builder_control_flow.cpp index d9f5d3b..f13fb83 100644 --- a/tests/test_builder_control_flow.cpp +++ b/tests/test_builder_control_flow.cpp @@ -13,176 +13,202 @@ * - LLVMGetNumSuccessors(), LLVMGetSuccessor() */ -#include -#include #include +#include +#include int main() { - LLVMContextRef ctx = LLVMContextCreate(); - LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_builder_control_flow", ctx); + LLVMContextRef ctx = LLVMContextCreate(); + LLVMModuleRef mod = + LLVMModuleCreateWithNameInContext("test_builder_control_flow", ctx); - LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); - LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx); - LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx); + LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); + LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx); + LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx); - LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); + LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); - // ========================================== - // Function 1: void return - // ========================================== - LLVMTypeRef void_func_ty = LLVMFunctionType(void_ty, nullptr, 0, 0); - LLVMValueRef void_func = LLVMAddFunction(mod, "return_void", void_func_ty); - LLVMBasicBlockRef void_entry = LLVMAppendBasicBlockInContext(ctx, void_func, "entry"); - LLVMPositionBuilderAtEnd(builder, void_entry); - LLVMBuildRetVoid(builder); + // ========================================== + // Function 1: void return + // ========================================== + LLVMTypeRef void_func_ty = LLVMFunctionType(void_ty, nullptr, 0, 0); + LLVMValueRef void_func = LLVMAddFunction(mod, "return_void", void_func_ty); + LLVMBasicBlockRef void_entry = + LLVMAppendBasicBlockInContext(ctx, void_func, "entry"); + LLVMPositionBuilderAtEnd(builder, void_entry); + LLVMBuildRetVoid(builder); - // ========================================== - // Function 2: value return - // ========================================== - LLVMTypeRef ret_params[] = {i32}; - LLVMTypeRef ret_func_ty = LLVMFunctionType(i32, ret_params, 1, 0); - LLVMValueRef ret_func = LLVMAddFunction(mod, "return_value", ret_func_ty); - LLVMValueRef ret_param = LLVMGetParam(ret_func, 0); - LLVMSetValueName2(ret_param, "x", 1); + // ========================================== + // Function 2: value return + // ========================================== + LLVMTypeRef ret_params[] = {i32}; + LLVMTypeRef ret_func_ty = LLVMFunctionType(i32, ret_params, 1, 0); + LLVMValueRef ret_func = LLVMAddFunction(mod, "return_value", ret_func_ty); + LLVMValueRef ret_param = LLVMGetParam(ret_func, 0); + LLVMSetValueName2(ret_param, "x", 1); - LLVMBasicBlockRef ret_entry = LLVMAppendBasicBlockInContext(ctx, ret_func, "entry"); - LLVMPositionBuilderAtEnd(builder, ret_entry); - LLVMBuildRet(builder, ret_param); + LLVMBasicBlockRef ret_entry = + LLVMAppendBasicBlockInContext(ctx, ret_func, "entry"); + LLVMPositionBuilderAtEnd(builder, ret_entry); + LLVMBuildRet(builder, ret_param); - // ========================================== - // Function 3: unconditional branch - // ========================================== - LLVMValueRef br_func = LLVMAddFunction(mod, "unconditional_branch", void_func_ty); - LLVMBasicBlockRef br_entry = LLVMAppendBasicBlockInContext(ctx, br_func, "entry"); - LLVMBasicBlockRef br_target = LLVMAppendBasicBlockInContext(ctx, br_func, "target"); + // ========================================== + // Function 3: unconditional branch + // ========================================== + LLVMValueRef br_func = + LLVMAddFunction(mod, "unconditional_branch", void_func_ty); + LLVMBasicBlockRef br_entry = + LLVMAppendBasicBlockInContext(ctx, br_func, "entry"); + LLVMBasicBlockRef br_target = + LLVMAppendBasicBlockInContext(ctx, br_func, "target"); - LLVMPositionBuilderAtEnd(builder, br_entry); - LLVMValueRef br_inst = LLVMBuildBr(builder, br_target); + LLVMPositionBuilderAtEnd(builder, br_entry); + LLVMValueRef br_inst = LLVMBuildBr(builder, br_target); - LLVMPositionBuilderAtEnd(builder, br_target); - LLVMBuildRetVoid(builder); + LLVMPositionBuilderAtEnd(builder, br_target); + LLVMBuildRetVoid(builder); - // ========================================== - // Function 4: conditional branch - // ========================================== - LLVMTypeRef cond_params[] = {i1}; - LLVMTypeRef cond_func_ty = LLVMFunctionType(i32, cond_params, 1, 0); - LLVMValueRef cond_func = LLVMAddFunction(mod, "conditional_branch", cond_func_ty); - LLVMValueRef cond_param = LLVMGetParam(cond_func, 0); - LLVMSetValueName2(cond_param, "cond", 4); + // ========================================== + // Function 4: conditional branch + // ========================================== + LLVMTypeRef cond_params[] = {i1}; + LLVMTypeRef cond_func_ty = LLVMFunctionType(i32, cond_params, 1, 0); + LLVMValueRef cond_func = + LLVMAddFunction(mod, "conditional_branch", cond_func_ty); + LLVMValueRef cond_param = LLVMGetParam(cond_func, 0); + LLVMSetValueName2(cond_param, "cond", 4); - LLVMBasicBlockRef cond_entry = LLVMAppendBasicBlockInContext(ctx, cond_func, "entry"); - LLVMBasicBlockRef cond_true = LLVMAppendBasicBlockInContext(ctx, cond_func, "if_true"); - LLVMBasicBlockRef cond_false = LLVMAppendBasicBlockInContext(ctx, cond_func, "if_false"); + LLVMBasicBlockRef cond_entry = + LLVMAppendBasicBlockInContext(ctx, cond_func, "entry"); + LLVMBasicBlockRef cond_true = + LLVMAppendBasicBlockInContext(ctx, cond_func, "if_true"); + LLVMBasicBlockRef cond_false = + LLVMAppendBasicBlockInContext(ctx, cond_func, "if_false"); - LLVMPositionBuilderAtEnd(builder, cond_entry); - LLVMValueRef cond_br = LLVMBuildCondBr(builder, cond_param, cond_true, cond_false); + LLVMPositionBuilderAtEnd(builder, cond_entry); + LLVMValueRef cond_br = + LLVMBuildCondBr(builder, cond_param, cond_true, cond_false); - LLVMPositionBuilderAtEnd(builder, cond_true); - LLVMBuildRet(builder, LLVMConstInt(i32, 1, 0)); + LLVMPositionBuilderAtEnd(builder, cond_true); + LLVMBuildRet(builder, LLVMConstInt(i32, 1, 0)); - LLVMPositionBuilderAtEnd(builder, cond_false); - LLVMBuildRet(builder, LLVMConstInt(i32, 0, 0)); + LLVMPositionBuilderAtEnd(builder, cond_false); + LLVMBuildRet(builder, LLVMConstInt(i32, 0, 0)); - // ========================================== - // Function 5: switch statement - // ========================================== - LLVMTypeRef switch_params[] = {i32}; - LLVMTypeRef switch_func_ty = LLVMFunctionType(i32, switch_params, 1, 0); - LLVMValueRef switch_func = LLVMAddFunction(mod, "switch_example", switch_func_ty); - LLVMValueRef switch_param = LLVMGetParam(switch_func, 0); - LLVMSetValueName2(switch_param, "val", 3); + // ========================================== + // Function 5: switch statement + // ========================================== + LLVMTypeRef switch_params[] = {i32}; + LLVMTypeRef switch_func_ty = LLVMFunctionType(i32, switch_params, 1, 0); + LLVMValueRef switch_func = + LLVMAddFunction(mod, "switch_example", switch_func_ty); + LLVMValueRef switch_param = LLVMGetParam(switch_func, 0); + LLVMSetValueName2(switch_param, "val", 3); - LLVMBasicBlockRef switch_entry = LLVMAppendBasicBlockInContext(ctx, switch_func, "entry"); - LLVMBasicBlockRef case_0 = LLVMAppendBasicBlockInContext(ctx, switch_func, "case_0"); - LLVMBasicBlockRef case_1 = LLVMAppendBasicBlockInContext(ctx, switch_func, "case_1"); - LLVMBasicBlockRef case_2 = LLVMAppendBasicBlockInContext(ctx, switch_func, "case_2"); - LLVMBasicBlockRef default_case = LLVMAppendBasicBlockInContext(ctx, switch_func, "default"); + LLVMBasicBlockRef switch_entry = + LLVMAppendBasicBlockInContext(ctx, switch_func, "entry"); + LLVMBasicBlockRef case_0 = + LLVMAppendBasicBlockInContext(ctx, switch_func, "case_0"); + LLVMBasicBlockRef case_1 = + LLVMAppendBasicBlockInContext(ctx, switch_func, "case_1"); + LLVMBasicBlockRef case_2 = + LLVMAppendBasicBlockInContext(ctx, switch_func, "case_2"); + LLVMBasicBlockRef default_case = + LLVMAppendBasicBlockInContext(ctx, switch_func, "default"); - LLVMPositionBuilderAtEnd(builder, switch_entry); - LLVMValueRef switch_inst = LLVMBuildSwitch(builder, switch_param, default_case, 3); - LLVMAddCase(switch_inst, LLVMConstInt(i32, 0, 0), case_0); - LLVMAddCase(switch_inst, LLVMConstInt(i32, 1, 0), case_1); - LLVMAddCase(switch_inst, LLVMConstInt(i32, 2, 0), case_2); + LLVMPositionBuilderAtEnd(builder, switch_entry); + LLVMValueRef switch_inst = + LLVMBuildSwitch(builder, switch_param, default_case, 3); + LLVMAddCase(switch_inst, LLVMConstInt(i32, 0, 0), case_0); + LLVMAddCase(switch_inst, LLVMConstInt(i32, 1, 0), case_1); + LLVMAddCase(switch_inst, LLVMConstInt(i32, 2, 0), case_2); - LLVMPositionBuilderAtEnd(builder, case_0); - LLVMBuildRet(builder, LLVMConstInt(i32, 100, 0)); + LLVMPositionBuilderAtEnd(builder, case_0); + LLVMBuildRet(builder, LLVMConstInt(i32, 100, 0)); - LLVMPositionBuilderAtEnd(builder, case_1); - LLVMBuildRet(builder, LLVMConstInt(i32, 200, 0)); + LLVMPositionBuilderAtEnd(builder, case_1); + LLVMBuildRet(builder, LLVMConstInt(i32, 200, 0)); - LLVMPositionBuilderAtEnd(builder, case_2); - LLVMBuildRet(builder, LLVMConstInt(i32, 300, 0)); + LLVMPositionBuilderAtEnd(builder, case_2); + LLVMBuildRet(builder, LLVMConstInt(i32, 300, 0)); - LLVMPositionBuilderAtEnd(builder, default_case); - LLVMBuildRet(builder, LLVMConstInt(i32, -1, 1)); + LLVMPositionBuilderAtEnd(builder, default_case); + LLVMBuildRet(builder, LLVMConstInt(i32, -1, 1)); - // ========================================== - // Function 6: function call - // ========================================== - LLVMValueRef call_func = LLVMAddFunction(mod, "call_example", ret_func_ty); - LLVMValueRef call_param = LLVMGetParam(call_func, 0); - LLVMSetValueName2(call_param, "n", 1); + // ========================================== + // Function 6: function call + // ========================================== + LLVMValueRef call_func = LLVMAddFunction(mod, "call_example", ret_func_ty); + LLVMValueRef call_param = LLVMGetParam(call_func, 0); + LLVMSetValueName2(call_param, "n", 1); - LLVMBasicBlockRef call_entry = LLVMAppendBasicBlockInContext(ctx, call_func, "entry"); - LLVMPositionBuilderAtEnd(builder, call_entry); + LLVMBasicBlockRef call_entry = + LLVMAppendBasicBlockInContext(ctx, call_func, "entry"); + LLVMPositionBuilderAtEnd(builder, call_entry); - LLVMValueRef args[] = {call_param}; - LLVMValueRef call_result = LLVMBuildCall2(builder, ret_func_ty, ret_func, args, 1, "result"); - LLVMBuildRet(builder, call_result); + LLVMValueRef args[] = {call_param}; + LLVMValueRef call_result = + LLVMBuildCall2(builder, ret_func_ty, ret_func, args, 1, "result"); + LLVMBuildRet(builder, call_result); - // ========================================== - // Function 7: unreachable - // ========================================== - LLVMValueRef unreach_func = LLVMAddFunction(mod, "unreachable_example", void_func_ty); - LLVMBasicBlockRef unreach_entry = LLVMAppendBasicBlockInContext(ctx, unreach_func, "entry"); - LLVMPositionBuilderAtEnd(builder, unreach_entry); - LLVMBuildUnreachable(builder); + // ========================================== + // Function 7: unreachable + // ========================================== + LLVMValueRef unreach_func = + LLVMAddFunction(mod, "unreachable_example", void_func_ty); + LLVMBasicBlockRef unreach_entry = + LLVMAppendBasicBlockInContext(ctx, unreach_func, "entry"); + LLVMPositionBuilderAtEnd(builder, unreach_entry); + LLVMBuildUnreachable(builder); - // Check insert block - LLVMBasicBlockRef current_block = LLVMGetInsertBlock(builder); + // Check insert block + LLVMBasicBlockRef current_block = LLVMGetInsertBlock(builder); - LLVMDisposeBuilder(builder); + LLVMDisposeBuilder(builder); - // Verify module - char *error = nullptr; - if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { - fprintf(stderr, "; Verification failed: %s\n", error); - LLVMDisposeMessage(error); - LLVMDisposeModule(mod); - LLVMContextDispose(ctx); - return 1; - } + // Verify module + char *error = nullptr; + if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { + fprintf(stderr, "; Verification failed: %s\n", error); LLVMDisposeMessage(error); - - // Print diagnostic comments - printf("; Test: test_builder_control_flow\n"); - printf(";\n"); - printf("; Control flow operations demonstrated:\n"); - printf("; ret void, ret value\n"); - printf("; br (unconditional)\n"); - printf("; br (conditional)\n"); - printf("; switch with 3 cases + default\n"); - printf("; call\n"); - printf("; unreachable\n"); - printf(";\n"); - printf("; Branch analysis:\n"); - printf("; unconditional br is conditional: %s\n", LLVMIsConditional(br_inst) ? "yes" : "no"); - printf("; conditional br is conditional: %s\n", LLVMIsConditional(cond_br) ? "yes" : "no"); - printf("; unconditional br num successors: %u\n", LLVMGetNumSuccessors(br_inst)); - printf("; conditional br num successors: %u\n", LLVMGetNumSuccessors(cond_br)); - printf(";\n"); - printf("; Current insert block: %s\n", LLVMGetBasicBlockName(current_block)); - printf("\n"); - - // Print module IR - char *ir = LLVMPrintModuleToString(mod); - printf("%s", ir); - LLVMDisposeMessage(ir); - - // Cleanup LLVMDisposeModule(mod); LLVMContextDispose(ctx); + return 1; + } + LLVMDisposeMessage(error); - return 0; + // Print diagnostic comments + printf("; Test: test_builder_control_flow\n"); + printf(";\n"); + printf("; Control flow operations demonstrated:\n"); + printf("; ret void, ret value\n"); + printf("; br (unconditional)\n"); + printf("; br (conditional)\n"); + printf("; switch with 3 cases + default\n"); + printf("; call\n"); + printf("; unreachable\n"); + printf(";\n"); + printf("; Branch analysis:\n"); + printf("; unconditional br is conditional: %s\n", + LLVMIsConditional(br_inst) ? "yes" : "no"); + printf("; conditional br is conditional: %s\n", + LLVMIsConditional(cond_br) ? "yes" : "no"); + printf("; unconditional br num successors: %u\n", + LLVMGetNumSuccessors(br_inst)); + printf("; conditional br num successors: %u\n", + LLVMGetNumSuccessors(cond_br)); + printf(";\n"); + printf("; Current insert block: %s\n", LLVMGetBasicBlockName(current_block)); + printf("\n"); + + // Print module IR + char *ir = LLVMPrintModuleToString(mod); + printf("%s", ir); + LLVMDisposeMessage(ir); + + // Cleanup + LLVMDisposeModule(mod); + LLVMContextDispose(ctx); + + return 0; } diff --git a/tests/test_builder_memory.cpp b/tests/test_builder_memory.cpp index e23ab17..def8f06 100644 --- a/tests/test_builder_memory.cpp +++ b/tests/test_builder_memory.cpp @@ -10,130 +10,147 @@ * - LLVMGetAlignment(), LLVMSetAlignment() */ -#include -#include #include +#include +#include int main() { - LLVMContextRef ctx = LLVMContextCreate(); - LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_builder_memory", ctx); + LLVMContextRef ctx = LLVMContextCreate(); + LLVMModuleRef mod = + LLVMModuleCreateWithNameInContext("test_builder_memory", ctx); - LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); - LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx); - LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0); - LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx); + LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); + LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx); + LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0); + LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx); - // Array type for array alloca test - LLVMTypeRef arr_ty = LLVMArrayType2(i32, 10); + // Array type for array alloca test + LLVMTypeRef arr_ty = LLVMArrayType2(i32, 10); - // Struct type for struct GEP test - LLVMTypeRef struct_elems[] = {i32, i64, i32}; - LLVMTypeRef struct_ty = LLVMStructTypeInContext(ctx, struct_elems, 3, 0); + // Struct type for struct GEP test + LLVMTypeRef struct_elems[] = {i32, i64, i32}; + LLVMTypeRef struct_ty = LLVMStructTypeInContext(ctx, struct_elems, 3, 0); - // Function: void memory_ops() - LLVMTypeRef func_ty = LLVMFunctionType(void_ty, nullptr, 0, 0); - LLVMValueRef func = LLVMAddFunction(mod, "memory_ops", func_ty); + // Function: void memory_ops() + LLVMTypeRef func_ty = LLVMFunctionType(void_ty, nullptr, 0, 0); + LLVMValueRef func = LLVMAddFunction(mod, "memory_ops", func_ty); - LLVMBasicBlockRef entry = LLVMAppendBasicBlockInContext(ctx, func, "entry"); - LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); - LLVMPositionBuilderAtEnd(builder, entry); + LLVMBasicBlockRef entry = LLVMAppendBasicBlockInContext(ctx, func, "entry"); + LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); + LLVMPositionBuilderAtEnd(builder, entry); - // Basic alloca - LLVMValueRef alloca_i32 = LLVMBuildAlloca(builder, i32, "local_i32"); + // Basic alloca + LLVMValueRef alloca_i32 = LLVMBuildAlloca(builder, i32, "local_i32"); - // Alloca with explicit alignment - LLVMValueRef alloca_aligned = LLVMBuildAlloca(builder, i64, "local_aligned"); - LLVMSetAlignment(alloca_aligned, 16); + // Alloca with explicit alignment + LLVMValueRef alloca_aligned = LLVMBuildAlloca(builder, i64, "local_aligned"); + LLVMSetAlignment(alloca_aligned, 16); - // Array alloca (dynamic size) - LLVMValueRef array_size = LLVMConstInt(i32, 5, 0); - LLVMValueRef array_alloca = LLVMBuildArrayAlloca(builder, i32, array_size, "dynamic_array"); + // Array alloca (dynamic size) + LLVMValueRef array_size = LLVMConstInt(i32, 5, 0); + LLVMValueRef array_alloca = + LLVMBuildArrayAlloca(builder, i32, array_size, "dynamic_array"); - // Static array alloca - LLVMValueRef static_array = LLVMBuildAlloca(builder, arr_ty, "static_array"); + // Static array alloca + LLVMValueRef static_array = LLVMBuildAlloca(builder, arr_ty, "static_array"); - // Struct alloca - LLVMValueRef struct_alloca = LLVMBuildAlloca(builder, struct_ty, "local_struct"); + // Struct alloca + LLVMValueRef struct_alloca = + LLVMBuildAlloca(builder, struct_ty, "local_struct"); - // Store and load - LLVMValueRef val = LLVMConstInt(i32, 42, 0); - LLVMValueRef store = LLVMBuildStore(builder, val, alloca_i32); - LLVMValueRef load = LLVMBuildLoad2(builder, i32, alloca_i32, "loaded"); + // Store and load + LLVMValueRef val = LLVMConstInt(i32, 42, 0); + LLVMValueRef store = LLVMBuildStore(builder, val, alloca_i32); + LLVMValueRef load = LLVMBuildLoad2(builder, i32, alloca_i32, "loaded"); - // Volatile load/store - LLVMValueRef volatile_store = LLVMBuildStore(builder, val, alloca_i32); - LLVMSetVolatile(volatile_store, 1); - LLVMValueRef volatile_load = LLVMBuildLoad2(builder, i32, alloca_i32, "volatile_loaded"); - LLVMSetVolatile(volatile_load, 1); + // Volatile load/store + LLVMValueRef volatile_store = LLVMBuildStore(builder, val, alloca_i32); + LLVMSetVolatile(volatile_store, 1); + LLVMValueRef volatile_load = + LLVMBuildLoad2(builder, i32, alloca_i32, "volatile_loaded"); + LLVMSetVolatile(volatile_load, 1); - // Load with alignment - LLVMValueRef aligned_load = LLVMBuildLoad2(builder, i64, alloca_aligned, "aligned_loaded"); - LLVMSetAlignment(aligned_load, 16); + // Load with alignment + LLVMValueRef aligned_load = + LLVMBuildLoad2(builder, i64, alloca_aligned, "aligned_loaded"); + LLVMSetAlignment(aligned_load, 16); - // GEP into array (static) - LLVMValueRef indices[] = {LLVMConstInt(i64, 0, 0), LLVMConstInt(i64, 3, 0)}; - LLVMValueRef gep = LLVMBuildGEP2(builder, arr_ty, static_array, indices, 2, "arr_elem"); + // GEP into array (static) + LLVMValueRef indices[] = {LLVMConstInt(i64, 0, 0), LLVMConstInt(i64, 3, 0)}; + LLVMValueRef gep = + LLVMBuildGEP2(builder, arr_ty, static_array, indices, 2, "arr_elem"); - // Inbounds GEP - LLVMValueRef inbounds_gep = LLVMBuildInBoundsGEP2(builder, arr_ty, static_array, indices, 2, "arr_elem_inbounds"); + // Inbounds GEP + LLVMValueRef inbounds_gep = LLVMBuildInBoundsGEP2( + builder, arr_ty, static_array, indices, 2, "arr_elem_inbounds"); - // Struct GEP - LLVMValueRef struct_gep_0 = LLVMBuildStructGEP2(builder, struct_ty, struct_alloca, 0, "field_0"); - LLVMValueRef struct_gep_1 = LLVMBuildStructGEP2(builder, struct_ty, struct_alloca, 1, "field_1"); - LLVMValueRef struct_gep_2 = LLVMBuildStructGEP2(builder, struct_ty, struct_alloca, 2, "field_2"); + // Struct GEP + LLVMValueRef struct_gep_0 = + LLVMBuildStructGEP2(builder, struct_ty, struct_alloca, 0, "field_0"); + LLVMValueRef struct_gep_1 = + LLVMBuildStructGEP2(builder, struct_ty, struct_alloca, 1, "field_1"); + LLVMValueRef struct_gep_2 = + LLVMBuildStructGEP2(builder, struct_ty, struct_alloca, 2, "field_2"); - // Store to struct fields - LLVMBuildStore(builder, LLVMConstInt(i32, 100, 0), struct_gep_0); - LLVMBuildStore(builder, LLVMConstInt(i64, 200, 0), struct_gep_1); - LLVMBuildStore(builder, LLVMConstInt(i32, 300, 0), struct_gep_2); + // Store to struct fields + LLVMBuildStore(builder, LLVMConstInt(i32, 100, 0), struct_gep_0); + LLVMBuildStore(builder, LLVMConstInt(i64, 200, 0), struct_gep_1); + LLVMBuildStore(builder, LLVMConstInt(i32, 300, 0), struct_gep_2); - // Load from struct fields - LLVMValueRef field_0_val = LLVMBuildLoad2(builder, i32, struct_gep_0, "field_0_val"); - LLVMValueRef field_1_val = LLVMBuildLoad2(builder, i64, struct_gep_1, "field_1_val"); + // Load from struct fields + LLVMValueRef field_0_val = + LLVMBuildLoad2(builder, i32, struct_gep_0, "field_0_val"); + LLVMValueRef field_1_val = + LLVMBuildLoad2(builder, i64, struct_gep_1, "field_1_val"); - LLVMBuildRetVoid(builder); + LLVMBuildRetVoid(builder); - LLVMDisposeBuilder(builder); + LLVMDisposeBuilder(builder); - // Verify module - char *error = nullptr; - if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { - fprintf(stderr, "; Verification failed: %s\n", error); - LLVMDisposeMessage(error); - LLVMDisposeModule(mod); - LLVMContextDispose(ctx); - return 1; - } + // Verify module + char *error = nullptr; + if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { + fprintf(stderr, "; Verification failed: %s\n", error); LLVMDisposeMessage(error); - - // Print diagnostic comments - printf("; Test: test_builder_memory\n"); - printf(";\n"); - printf("; Memory operations demonstrated:\n"); - printf("; alloca (i32, i64 with alignment, dynamic array, static array, struct)\n"); - printf("; store (basic, volatile)\n"); - printf("; load (basic, volatile, aligned)\n"); - printf("; GEP (array indexing, inbounds)\n"); - printf("; struct GEP (field access)\n"); - printf(";\n"); - printf("; Alignment checks:\n"); - printf("; alloca_aligned alignment: %u\n", LLVMGetAlignment(alloca_aligned)); - printf("; aligned_load alignment: %u\n", LLVMGetAlignment(aligned_load)); - printf(";\n"); - printf("; Volatile checks:\n"); - printf("; volatile_store is volatile: %s\n", LLVMGetVolatile(volatile_store) ? "yes" : "no"); - printf("; volatile_load is volatile: %s\n", LLVMGetVolatile(volatile_load) ? "yes" : "no"); - printf("; regular store is volatile: %s\n", LLVMGetVolatile(store) ? "yes" : "no"); - printf("\n"); - - // Print module IR - char *ir = LLVMPrintModuleToString(mod); - printf("%s", ir); - LLVMDisposeMessage(ir); - - // Cleanup LLVMDisposeModule(mod); LLVMContextDispose(ctx); + return 1; + } + LLVMDisposeMessage(error); - return 0; + // Print diagnostic comments + printf("; Test: test_builder_memory\n"); + printf(";\n"); + printf("; Memory operations demonstrated:\n"); + printf("; alloca (i32, i64 with alignment, dynamic array, static array, " + "struct)\n"); + printf("; store (basic, volatile)\n"); + printf("; load (basic, volatile, aligned)\n"); + printf("; GEP (array indexing, inbounds)\n"); + printf("; struct GEP (field access)\n"); + printf(";\n"); + printf("; Alignment checks:\n"); + printf("; alloca_aligned alignment: %u\n", + LLVMGetAlignment(alloca_aligned)); + printf("; aligned_load alignment: %u\n", LLVMGetAlignment(aligned_load)); + printf(";\n"); + printf("; Volatile checks:\n"); + printf("; volatile_store is volatile: %s\n", + LLVMGetVolatile(volatile_store) ? "yes" : "no"); + printf("; volatile_load is volatile: %s\n", + LLVMGetVolatile(volatile_load) ? "yes" : "no"); + printf("; regular store is volatile: %s\n", + LLVMGetVolatile(store) ? "yes" : "no"); + printf("\n"); + + // Print module IR + char *ir = LLVMPrintModuleToString(mod); + printf("%s", ir); + LLVMDisposeMessage(ir); + + // Cleanup + LLVMDisposeModule(mod); + LLVMContextDispose(ctx); + + return 0; } diff --git a/tests/test_constants.cpp b/tests/test_constants.cpp index 962b850..2ef2316 100644 --- a/tests/test_constants.cpp +++ b/tests/test_constants.cpp @@ -9,220 +9,220 @@ * - LLVMGetUndef(), LLVMGetPoison() * - LLVMConstPointerNull() * - LLVMConstStringInContext2() - * - LLVMConstArray2(), LLVMConstStructInContext(), LLVMConstNamedStruct(), LLVMConstVector() + * - LLVMConstArray2(), LLVMConstStructInContext(), LLVMConstNamedStruct(), + * LLVMConstVector() * - LLVMConstIntGetZExtValue(), LLVMConstIntGetSExtValue() * - LLVMIsConstant(), LLVMIsNull(), LLVMIsUndef(), LLVMIsPoison() */ -#include -#include #include #include +#include +#include int main() { - LLVMContextRef ctx = LLVMContextCreate(); - LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_constants", ctx); + LLVMContextRef ctx = LLVMContextCreate(); + LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_constants", ctx); - LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx); - LLVMTypeRef i8 = LLVMInt8TypeInContext(ctx); - LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); - LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx); - LLVMTypeRef i128 = LLVMInt128TypeInContext(ctx); - LLVMTypeRef f32 = LLVMFloatTypeInContext(ctx); - LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx); - LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0); + LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx); + LLVMTypeRef i8 = LLVMInt8TypeInContext(ctx); + LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); + LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx); + LLVMTypeRef i128 = LLVMInt128TypeInContext(ctx); + LLVMTypeRef f32 = LLVMFloatTypeInContext(ctx); + LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx); + LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0); - // ========================================== - // Integer constants - // ========================================== - LLVMValueRef const_0 = LLVMConstInt(i32, 0, 0); - LLVMValueRef const_42 = LLVMConstInt(i32, 42, 0); - LLVMValueRef const_neg1 = LLVMConstInt(i32, -1, 1); // Sign extend - LLVMValueRef const_max_u32 = LLVMConstInt(i32, 0xFFFFFFFF, 0); - LLVMValueRef const_i64 = LLVMConstInt(i64, 0x123456789ABCDEF0ULL, 0); + // ========================================== + // Integer constants + // ========================================== + LLVMValueRef const_0 = LLVMConstInt(i32, 0, 0); + LLVMValueRef const_42 = LLVMConstInt(i32, 42, 0); + LLVMValueRef const_neg1 = LLVMConstInt(i32, -1, 1); // Sign extend + LLVMValueRef const_max_u32 = LLVMConstInt(i32, 0xFFFFFFFF, 0); + LLVMValueRef const_i64 = LLVMConstInt(i64, 0x123456789ABCDEF0ULL, 0); - // Arbitrary precision integer (128-bit) - uint64_t words[] = {0xFFFFFFFFFFFFFFFFULL, 0x0000000000000001ULL}; - LLVMValueRef const_i128 = LLVMConstIntOfArbitraryPrecision(i128, 2, words); + // Arbitrary precision integer (128-bit) + uint64_t words[] = {0xFFFFFFFFFFFFFFFFULL, 0x0000000000000001ULL}; + LLVMValueRef const_i128 = LLVMConstIntOfArbitraryPrecision(i128, 2, words); - // ========================================== - // Floating point constants - // ========================================== - LLVMValueRef const_pi = LLVMConstReal(f64, 3.14159265358979323846); - LLVMValueRef const_e = LLVMConstReal(f64, 2.71828182845904523536); - LLVMValueRef const_f32 = LLVMConstReal(f32, 1.5f); + // ========================================== + // Floating point constants + // ========================================== + LLVMValueRef const_pi = LLVMConstReal(f64, 3.14159265358979323846); + LLVMValueRef const_e = LLVMConstReal(f64, 2.71828182845904523536); + LLVMValueRef const_f32 = LLVMConstReal(f32, 1.5f); - // From string - LLVMValueRef const_from_str = LLVMConstRealOfString(f64, "1.234567890123456789"); + // From string + LLVMValueRef const_from_str = + LLVMConstRealOfString(f64, "1.234567890123456789"); - // ========================================== - // Special values - // ========================================== - LLVMValueRef null_i32 = LLVMConstNull(i32); - LLVMValueRef null_ptr = LLVMConstPointerNull(ptr); - LLVMValueRef all_ones = LLVMConstAllOnes(i32); - LLVMValueRef undef_i32 = LLVMGetUndef(i32); - LLVMValueRef poison_i32 = LLVMGetPoison(i32); + // ========================================== + // Special values + // ========================================== + LLVMValueRef null_i32 = LLVMConstNull(i32); + LLVMValueRef null_ptr = LLVMConstPointerNull(ptr); + LLVMValueRef all_ones = LLVMConstAllOnes(i32); + LLVMValueRef undef_i32 = LLVMGetUndef(i32); + LLVMValueRef poison_i32 = LLVMGetPoison(i32); - // ========================================== - // String constant - // ========================================== - const char *str = "Hello, LLVM!"; - LLVMValueRef const_string = LLVMConstStringInContext2(ctx, str, strlen(str), 0); // null terminated - LLVMValueRef const_string_no_null = LLVMConstStringInContext2(ctx, str, strlen(str), 1); // not null terminated + // ========================================== + // String constant + // ========================================== + const char *str = "Hello, LLVM!"; + LLVMValueRef const_string = + LLVMConstStringInContext2(ctx, str, strlen(str), 0); // null terminated + LLVMValueRef const_string_no_null = LLVMConstStringInContext2( + ctx, str, strlen(str), 1); // not null terminated - // ========================================== - // Array constant - // ========================================== - LLVMValueRef arr_elems[] = { - LLVMConstInt(i32, 1, 0), - LLVMConstInt(i32, 2, 0), - LLVMConstInt(i32, 3, 0), - LLVMConstInt(i32, 4, 0), - LLVMConstInt(i32, 5, 0) - }; - LLVMValueRef const_array = LLVMConstArray2(i32, arr_elems, 5); + // ========================================== + // Array constant + // ========================================== + LLVMValueRef arr_elems[] = {LLVMConstInt(i32, 1, 0), LLVMConstInt(i32, 2, 0), + LLVMConstInt(i32, 3, 0), LLVMConstInt(i32, 4, 0), + LLVMConstInt(i32, 5, 0)}; + LLVMValueRef const_array = LLVMConstArray2(i32, arr_elems, 5); - // ========================================== - // Anonymous struct constant - // ========================================== - LLVMValueRef struct_elems[] = { - LLVMConstInt(i32, 100, 0), - LLVMConstReal(f64, 3.14), - LLVMConstInt(i64, 999, 0) - }; - LLVMValueRef const_struct = LLVMConstStructInContext(ctx, struct_elems, 3, 0); - LLVMValueRef const_packed_struct = LLVMConstStructInContext(ctx, struct_elems, 3, 1); + // ========================================== + // Anonymous struct constant + // ========================================== + LLVMValueRef struct_elems[] = {LLVMConstInt(i32, 100, 0), + LLVMConstReal(f64, 3.14), + LLVMConstInt(i64, 999, 0)}; + LLVMValueRef const_struct = LLVMConstStructInContext(ctx, struct_elems, 3, 0); + LLVMValueRef const_packed_struct = + LLVMConstStructInContext(ctx, struct_elems, 3, 1); - // ========================================== - // Named struct constant - // ========================================== - LLVMTypeRef named_struct_ty = LLVMStructCreateNamed(ctx, "Point"); - LLVMTypeRef point_elems[] = {i32, i32}; - LLVMStructSetBody(named_struct_ty, point_elems, 2, 0); + // ========================================== + // Named struct constant + // ========================================== + LLVMTypeRef named_struct_ty = LLVMStructCreateNamed(ctx, "Point"); + LLVMTypeRef point_elems[] = {i32, i32}; + LLVMStructSetBody(named_struct_ty, point_elems, 2, 0); - LLVMValueRef point_vals[] = { - LLVMConstInt(i32, 10, 0), - LLVMConstInt(i32, 20, 0) - }; - LLVMValueRef const_named_struct = LLVMConstNamedStruct(named_struct_ty, point_vals, 2); + LLVMValueRef point_vals[] = {LLVMConstInt(i32, 10, 0), + LLVMConstInt(i32, 20, 0)}; + LLVMValueRef const_named_struct = + LLVMConstNamedStruct(named_struct_ty, point_vals, 2); - // ========================================== - // Vector constant - // ========================================== - LLVMValueRef vec_elems[] = { - LLVMConstInt(i32, 1, 0), - LLVMConstInt(i32, 2, 0), - LLVMConstInt(i32, 3, 0), - LLVMConstInt(i32, 4, 0) - }; - LLVMValueRef const_vector = LLVMConstVector(vec_elems, 4); + // ========================================== + // Vector constant + // ========================================== + LLVMValueRef vec_elems[] = {LLVMConstInt(i32, 1, 0), LLVMConstInt(i32, 2, 0), + LLVMConstInt(i32, 3, 0), LLVMConstInt(i32, 4, 0)}; + LLVMValueRef const_vector = LLVMConstVector(vec_elems, 4); - // ========================================== - // Add globals to expose constants in output - // ========================================== - LLVMValueRef g; + // ========================================== + // Add globals to expose constants in output + // ========================================== + LLVMValueRef g; - g = LLVMAddGlobal(mod, i32, "const_42"); - LLVMSetInitializer(g, const_42); - LLVMSetGlobalConstant(g, 1); + g = LLVMAddGlobal(mod, i32, "const_42"); + LLVMSetInitializer(g, const_42); + LLVMSetGlobalConstant(g, 1); - g = LLVMAddGlobal(mod, i32, "const_neg1"); - LLVMSetInitializer(g, const_neg1); - LLVMSetGlobalConstant(g, 1); + g = LLVMAddGlobal(mod, i32, "const_neg1"); + LLVMSetInitializer(g, const_neg1); + LLVMSetGlobalConstant(g, 1); - g = LLVMAddGlobal(mod, i64, "const_i64"); - LLVMSetInitializer(g, const_i64); - LLVMSetGlobalConstant(g, 1); + g = LLVMAddGlobal(mod, i64, "const_i64"); + LLVMSetInitializer(g, const_i64); + LLVMSetGlobalConstant(g, 1); - g = LLVMAddGlobal(mod, i128, "const_i128"); - LLVMSetInitializer(g, const_i128); - LLVMSetGlobalConstant(g, 1); + g = LLVMAddGlobal(mod, i128, "const_i128"); + LLVMSetInitializer(g, const_i128); + LLVMSetGlobalConstant(g, 1); - g = LLVMAddGlobal(mod, f64, "const_pi"); - LLVMSetInitializer(g, const_pi); - LLVMSetGlobalConstant(g, 1); + g = LLVMAddGlobal(mod, f64, "const_pi"); + LLVMSetInitializer(g, const_pi); + LLVMSetGlobalConstant(g, 1); - g = LLVMAddGlobal(mod, i32, "all_ones"); - LLVMSetInitializer(g, all_ones); - LLVMSetGlobalConstant(g, 1); + g = LLVMAddGlobal(mod, i32, "all_ones"); + LLVMSetInitializer(g, all_ones); + LLVMSetGlobalConstant(g, 1); - g = LLVMAddGlobal(mod, i32, "undef_val"); - LLVMSetInitializer(g, undef_i32); + g = LLVMAddGlobal(mod, i32, "undef_val"); + LLVMSetInitializer(g, undef_i32); - g = LLVMAddGlobal(mod, i32, "poison_val"); - LLVMSetInitializer(g, poison_i32); + g = LLVMAddGlobal(mod, i32, "poison_val"); + LLVMSetInitializer(g, poison_i32); - // Get array type for const_string - LLVMTypeRef str_arr_ty = LLVMArrayType2(i8, strlen(str) + 1); - g = LLVMAddGlobal(mod, str_arr_ty, "hello_string"); - LLVMSetInitializer(g, const_string); - LLVMSetGlobalConstant(g, 1); + // Get array type for const_string + LLVMTypeRef str_arr_ty = LLVMArrayType2(i8, strlen(str) + 1); + g = LLVMAddGlobal(mod, str_arr_ty, "hello_string"); + LLVMSetInitializer(g, const_string); + LLVMSetGlobalConstant(g, 1); - LLVMTypeRef arr_ty = LLVMArrayType2(i32, 5); - g = LLVMAddGlobal(mod, arr_ty, "const_array"); - LLVMSetInitializer(g, const_array); - LLVMSetGlobalConstant(g, 1); + LLVMTypeRef arr_ty = LLVMArrayType2(i32, 5); + g = LLVMAddGlobal(mod, arr_ty, "const_array"); + LLVMSetInitializer(g, const_array); + LLVMSetGlobalConstant(g, 1); - // Struct types for globals - LLVMTypeRef anon_struct_elems[] = {i32, f64, i64}; - LLVMTypeRef anon_struct_ty = LLVMStructTypeInContext(ctx, anon_struct_elems, 3, 0); - g = LLVMAddGlobal(mod, anon_struct_ty, "const_struct"); - LLVMSetInitializer(g, const_struct); - LLVMSetGlobalConstant(g, 1); + // Struct types for globals + LLVMTypeRef anon_struct_elems[] = {i32, f64, i64}; + LLVMTypeRef anon_struct_ty = + LLVMStructTypeInContext(ctx, anon_struct_elems, 3, 0); + g = LLVMAddGlobal(mod, anon_struct_ty, "const_struct"); + LLVMSetInitializer(g, const_struct); + LLVMSetGlobalConstant(g, 1); - g = LLVMAddGlobal(mod, named_struct_ty, "const_point"); - LLVMSetInitializer(g, const_named_struct); - LLVMSetGlobalConstant(g, 1); + g = LLVMAddGlobal(mod, named_struct_ty, "const_point"); + LLVMSetInitializer(g, const_named_struct); + LLVMSetGlobalConstant(g, 1); - LLVMTypeRef vec_ty = LLVMVectorType(i32, 4); - g = LLVMAddGlobal(mod, vec_ty, "const_vector"); - LLVMSetInitializer(g, const_vector); - LLVMSetGlobalConstant(g, 1); + LLVMTypeRef vec_ty = LLVMVectorType(i32, 4); + g = LLVMAddGlobal(mod, vec_ty, "const_vector"); + LLVMSetInitializer(g, const_vector); + LLVMSetGlobalConstant(g, 1); - // Verify module - char *error = nullptr; - if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { - fprintf(stderr, "; Verification failed: %s\n", error); - LLVMDisposeMessage(error); - LLVMDisposeModule(mod); - LLVMContextDispose(ctx); - return 1; - } + // Verify module + char *error = nullptr; + if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { + fprintf(stderr, "; Verification failed: %s\n", error); LLVMDisposeMessage(error); - - // Print diagnostic comments - printf("; Test: test_constants\n"); - printf(";\n"); - printf("; Integer constants:\n"); - printf("; const_0 value (zext): %llu\n", LLVMConstIntGetZExtValue(const_0)); - printf("; const_42 value (zext): %llu\n", LLVMConstIntGetZExtValue(const_42)); - printf("; const_neg1 value (sext): %lld\n", LLVMConstIntGetSExtValue(const_neg1)); - printf("; const_max_u32 value (zext): %llu\n", LLVMConstIntGetZExtValue(const_max_u32)); - printf(";\n"); - printf("; Value checks:\n"); - printf("; const_42 is constant: %s\n", LLVMIsConstant(const_42) ? "yes" : "no"); - printf("; null_i32 is null: %s\n", LLVMIsNull(null_i32) ? "yes" : "no"); - printf("; null_ptr is null: %s\n", LLVMIsNull(null_ptr) ? "yes" : "no"); - printf("; undef_i32 is undef: %s\n", LLVMIsUndef(undef_i32) ? "yes" : "no"); - printf("; poison_i32 is poison: %s\n", LLVMIsPoison(poison_i32) ? "yes" : "no"); - printf("; const_42 is undef: %s\n", LLVMIsUndef(const_42) ? "yes" : "no"); - printf(";\n"); - printf("; Aggregate constants:\n"); - printf("; array with 5 i32 elements\n"); - printf("; struct with {i32, f64, i64}\n"); - printf("; named struct Point with {i32, i32}\n"); - printf("; vector with 4 x i32\n"); - printf("\n"); - - // Print module IR - char *ir = LLVMPrintModuleToString(mod); - printf("%s", ir); - LLVMDisposeMessage(ir); - - // Cleanup LLVMDisposeModule(mod); LLVMContextDispose(ctx); + return 1; + } + LLVMDisposeMessage(error); - return 0; + // Print diagnostic comments + printf("; Test: test_constants\n"); + printf(";\n"); + printf("; Integer constants:\n"); + printf("; const_0 value (zext): %llu\n", LLVMConstIntGetZExtValue(const_0)); + printf("; const_42 value (zext): %llu\n", + LLVMConstIntGetZExtValue(const_42)); + printf("; const_neg1 value (sext): %lld\n", + LLVMConstIntGetSExtValue(const_neg1)); + printf("; const_max_u32 value (zext): %llu\n", + LLVMConstIntGetZExtValue(const_max_u32)); + printf(";\n"); + printf("; Value checks:\n"); + printf("; const_42 is constant: %s\n", + LLVMIsConstant(const_42) ? "yes" : "no"); + printf("; null_i32 is null: %s\n", LLVMIsNull(null_i32) ? "yes" : "no"); + printf("; null_ptr is null: %s\n", LLVMIsNull(null_ptr) ? "yes" : "no"); + printf("; undef_i32 is undef: %s\n", LLVMIsUndef(undef_i32) ? "yes" : "no"); + printf("; poison_i32 is poison: %s\n", + LLVMIsPoison(poison_i32) ? "yes" : "no"); + printf("; const_42 is undef: %s\n", LLVMIsUndef(const_42) ? "yes" : "no"); + printf(";\n"); + printf("; Aggregate constants:\n"); + printf("; array with 5 i32 elements\n"); + printf("; struct with {i32, f64, i64}\n"); + printf("; named struct Point with {i32, i32}\n"); + printf("; vector with 4 x i32\n"); + printf("\n"); + + // Print module IR + char *ir = LLVMPrintModuleToString(mod); + printf("%s", ir); + LLVMDisposeMessage(ir); + + // Cleanup + LLVMDisposeModule(mod); + LLVMContextDispose(ctx); + + return 0; } diff --git a/tests/test_factorial.cpp b/tests/test_factorial.cpp index d2c9c87..ec4a465 100644 --- a/tests/test_factorial.cpp +++ b/tests/test_factorial.cpp @@ -10,164 +10,182 @@ * - PHI nodes alternative: using alloca/load/store pattern */ -#include -#include #include +#include +#include int main() { - LLVMContextRef ctx = LLVMContextCreate(); - LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_factorial", ctx); + LLVMContextRef ctx = LLVMContextCreate(); + LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_factorial", ctx); - // Set target for more realistic output - LLVMSetTarget(mod, "x86_64-unknown-linux-gnu"); + // Set target for more realistic output + LLVMSetTarget(mod, "x86_64-unknown-linux-gnu"); - LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx); - LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx); + LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx); + LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx); - LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); + LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); - // ========================================== - // Function: i64 factorial(i64 n) - // Iterative implementation using alloca/load/store - // ========================================== - LLVMTypeRef fact_params[] = {i64}; - LLVMTypeRef fact_ty = LLVMFunctionType(i64, fact_params, 1, 0); - LLVMValueRef fact_func = LLVMAddFunction(mod, "factorial", fact_ty); + // ========================================== + // Function: i64 factorial(i64 n) + // Iterative implementation using alloca/load/store + // ========================================== + LLVMTypeRef fact_params[] = {i64}; + LLVMTypeRef fact_ty = LLVMFunctionType(i64, fact_params, 1, 0); + LLVMValueRef fact_func = LLVMAddFunction(mod, "factorial", fact_ty); - LLVMValueRef n = LLVMGetParam(fact_func, 0); - LLVMSetValueName2(n, "n", 1); + LLVMValueRef n = LLVMGetParam(fact_func, 0); + LLVMSetValueName2(n, "n", 1); - // Basic blocks - LLVMBasicBlockRef entry = LLVMAppendBasicBlockInContext(ctx, fact_func, "entry"); - LLVMBasicBlockRef loop_cond = LLVMAppendBasicBlockInContext(ctx, fact_func, "loop_cond"); - LLVMBasicBlockRef loop_body = LLVMAppendBasicBlockInContext(ctx, fact_func, "loop_body"); - LLVMBasicBlockRef exit_bb = LLVMAppendBasicBlockInContext(ctx, fact_func, "exit"); + // Basic blocks + LLVMBasicBlockRef entry = + LLVMAppendBasicBlockInContext(ctx, fact_func, "entry"); + LLVMBasicBlockRef loop_cond = + LLVMAppendBasicBlockInContext(ctx, fact_func, "loop_cond"); + LLVMBasicBlockRef loop_body = + LLVMAppendBasicBlockInContext(ctx, fact_func, "loop_body"); + LLVMBasicBlockRef exit_bb = + LLVMAppendBasicBlockInContext(ctx, fact_func, "exit"); - // Entry block: initialize result=1, i=1 - LLVMPositionBuilderAtEnd(builder, entry); - LLVMValueRef result_ptr = LLVMBuildAlloca(builder, i64, "result"); - LLVMValueRef i_ptr = LLVMBuildAlloca(builder, i64, "i"); + // Entry block: initialize result=1, i=1 + LLVMPositionBuilderAtEnd(builder, entry); + LLVMValueRef result_ptr = LLVMBuildAlloca(builder, i64, "result"); + LLVMValueRef i_ptr = LLVMBuildAlloca(builder, i64, "i"); - LLVMBuildStore(builder, LLVMConstInt(i64, 1, 0), result_ptr); - LLVMBuildStore(builder, LLVMConstInt(i64, 1, 0), i_ptr); - LLVMBuildBr(builder, loop_cond); + LLVMBuildStore(builder, LLVMConstInt(i64, 1, 0), result_ptr); + LLVMBuildStore(builder, LLVMConstInt(i64, 1, 0), i_ptr); + LLVMBuildBr(builder, loop_cond); - // Loop condition: while (i <= n) - LLVMPositionBuilderAtEnd(builder, loop_cond); - LLVMValueRef i_val = LLVMBuildLoad2(builder, i64, i_ptr, "i_val"); - LLVMValueRef cmp = LLVMBuildICmp(builder, LLVMIntSLE, i_val, n, "cmp"); - LLVMBuildCondBr(builder, cmp, loop_body, exit_bb); + // Loop condition: while (i <= n) + LLVMPositionBuilderAtEnd(builder, loop_cond); + LLVMValueRef i_val = LLVMBuildLoad2(builder, i64, i_ptr, "i_val"); + LLVMValueRef cmp = LLVMBuildICmp(builder, LLVMIntSLE, i_val, n, "cmp"); + LLVMBuildCondBr(builder, cmp, loop_body, exit_bb); - // Loop body: result *= i; i++ - LLVMPositionBuilderAtEnd(builder, loop_body); - LLVMValueRef result_val = LLVMBuildLoad2(builder, i64, result_ptr, "result_val"); - LLVMValueRef i_val2 = LLVMBuildLoad2(builder, i64, i_ptr, "i_val2"); + // Loop body: result *= i; i++ + LLVMPositionBuilderAtEnd(builder, loop_body); + LLVMValueRef result_val = + LLVMBuildLoad2(builder, i64, result_ptr, "result_val"); + LLVMValueRef i_val2 = LLVMBuildLoad2(builder, i64, i_ptr, "i_val2"); - LLVMValueRef new_result = LLVMBuildMul(builder, result_val, i_val2, "new_result"); - LLVMBuildStore(builder, new_result, result_ptr); + LLVMValueRef new_result = + LLVMBuildMul(builder, result_val, i_val2, "new_result"); + LLVMBuildStore(builder, new_result, result_ptr); - LLVMValueRef new_i = LLVMBuildAdd(builder, i_val2, LLVMConstInt(i64, 1, 0), "new_i"); - LLVMBuildStore(builder, new_i, i_ptr); + LLVMValueRef new_i = + LLVMBuildAdd(builder, i_val2, LLVMConstInt(i64, 1, 0), "new_i"); + LLVMBuildStore(builder, new_i, i_ptr); - LLVMBuildBr(builder, loop_cond); + LLVMBuildBr(builder, loop_cond); - // Exit: return result - LLVMPositionBuilderAtEnd(builder, exit_bb); - LLVMValueRef final_result = LLVMBuildLoad2(builder, i64, result_ptr, "final_result"); - LLVMBuildRet(builder, final_result); + // Exit: return result + LLVMPositionBuilderAtEnd(builder, exit_bb); + LLVMValueRef final_result = + LLVMBuildLoad2(builder, i64, result_ptr, "final_result"); + LLVMBuildRet(builder, final_result); - // ========================================== - // Function: i64 factorial_recursive(i64 n) - // Recursive implementation for comparison - // ========================================== - LLVMValueRef fact_rec_func = LLVMAddFunction(mod, "factorial_recursive", fact_ty); - LLVMValueRef n_rec = LLVMGetParam(fact_rec_func, 0); - LLVMSetValueName2(n_rec, "n", 1); + // ========================================== + // Function: i64 factorial_recursive(i64 n) + // Recursive implementation for comparison + // ========================================== + LLVMValueRef fact_rec_func = + LLVMAddFunction(mod, "factorial_recursive", fact_ty); + LLVMValueRef n_rec = LLVMGetParam(fact_rec_func, 0); + LLVMSetValueName2(n_rec, "n", 1); - LLVMBasicBlockRef rec_entry = LLVMAppendBasicBlockInContext(ctx, fact_rec_func, "entry"); - LLVMBasicBlockRef base_case = LLVMAppendBasicBlockInContext(ctx, fact_rec_func, "base_case"); - LLVMBasicBlockRef recursive = LLVMAppendBasicBlockInContext(ctx, fact_rec_func, "recursive"); + LLVMBasicBlockRef rec_entry = + LLVMAppendBasicBlockInContext(ctx, fact_rec_func, "entry"); + LLVMBasicBlockRef base_case = + LLVMAppendBasicBlockInContext(ctx, fact_rec_func, "base_case"); + LLVMBasicBlockRef recursive = + LLVMAppendBasicBlockInContext(ctx, fact_rec_func, "recursive"); - // Entry: if n <= 1 goto base_case else goto recursive - LLVMPositionBuilderAtEnd(builder, rec_entry); - LLVMValueRef is_base = LLVMBuildICmp(builder, LLVMIntSLE, n_rec, - LLVMConstInt(i64, 1, 0), "is_base"); - LLVMBuildCondBr(builder, is_base, base_case, recursive); + // Entry: if n <= 1 goto base_case else goto recursive + LLVMPositionBuilderAtEnd(builder, rec_entry); + LLVMValueRef is_base = LLVMBuildICmp(builder, LLVMIntSLE, n_rec, + LLVMConstInt(i64, 1, 0), "is_base"); + LLVMBuildCondBr(builder, is_base, base_case, recursive); - // Base case: return 1 - LLVMPositionBuilderAtEnd(builder, base_case); - LLVMBuildRet(builder, LLVMConstInt(i64, 1, 0)); + // Base case: return 1 + LLVMPositionBuilderAtEnd(builder, base_case); + LLVMBuildRet(builder, LLVMConstInt(i64, 1, 0)); - // Recursive: return n * factorial_recursive(n-1) - LLVMPositionBuilderAtEnd(builder, recursive); - LLVMValueRef n_minus_1 = LLVMBuildSub(builder, n_rec, LLVMConstInt(i64, 1, 0), "n_minus_1"); - LLVMValueRef rec_args[] = {n_minus_1}; - LLVMValueRef rec_result = LLVMBuildCall2(builder, fact_ty, fact_rec_func, rec_args, 1, "rec_result"); - LLVMValueRef final_rec = LLVMBuildMul(builder, n_rec, rec_result, "final_rec"); - LLVMBuildRet(builder, final_rec); + // Recursive: return n * factorial_recursive(n-1) + LLVMPositionBuilderAtEnd(builder, recursive); + LLVMValueRef n_minus_1 = + LLVMBuildSub(builder, n_rec, LLVMConstInt(i64, 1, 0), "n_minus_1"); + LLVMValueRef rec_args[] = {n_minus_1}; + LLVMValueRef rec_result = LLVMBuildCall2(builder, fact_ty, fact_rec_func, + rec_args, 1, "rec_result"); + LLVMValueRef final_rec = + LLVMBuildMul(builder, n_rec, rec_result, "final_rec"); + LLVMBuildRet(builder, final_rec); - // ========================================== - // Function: i64 main() - // Calls factorial(5) and returns the result - // ========================================== - LLVMTypeRef main_ty = LLVMFunctionType(i64, nullptr, 0, 0); - LLVMValueRef main_func = LLVMAddFunction(mod, "main", main_ty); + // ========================================== + // Function: i64 main() + // Calls factorial(5) and returns the result + // ========================================== + LLVMTypeRef main_ty = LLVMFunctionType(i64, nullptr, 0, 0); + LLVMValueRef main_func = LLVMAddFunction(mod, "main", main_ty); - LLVMBasicBlockRef main_entry = LLVMAppendBasicBlockInContext(ctx, main_func, "entry"); - LLVMPositionBuilderAtEnd(builder, main_entry); + LLVMBasicBlockRef main_entry = + LLVMAppendBasicBlockInContext(ctx, main_func, "entry"); + LLVMPositionBuilderAtEnd(builder, main_entry); - LLVMValueRef main_args[] = {LLVMConstInt(i64, 5, 0)}; - LLVMValueRef fact_result = LLVMBuildCall2(builder, fact_ty, fact_func, main_args, 1, "fact_result"); - LLVMBuildRet(builder, fact_result); + LLVMValueRef main_args[] = {LLVMConstInt(i64, 5, 0)}; + LLVMValueRef fact_result = + LLVMBuildCall2(builder, fact_ty, fact_func, main_args, 1, "fact_result"); + LLVMBuildRet(builder, fact_result); - LLVMDisposeBuilder(builder); + LLVMDisposeBuilder(builder); - // Verify module - char *error = nullptr; - if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { - fprintf(stderr, "; Verification failed: %s\n", error); - LLVMDisposeMessage(error); - LLVMDisposeModule(mod); - LLVMContextDispose(ctx); - return 1; - } + // Verify module + char *error = nullptr; + if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { + fprintf(stderr, "; Verification failed: %s\n", error); LLVMDisposeMessage(error); - - // Print diagnostic comments - printf("; Test: test_factorial\n"); - printf("; Integration test: Iterative and recursive factorial\n"); - printf(";\n"); - printf("; factorial(i64 n) -> i64:\n"); - printf("; Iterative implementation using alloca/load/store\n"); - printf("; Blocks: entry -> loop_cond -> loop_body -> exit\n"); - printf(";\n"); - printf("; factorial_recursive(i64 n) -> i64:\n"); - printf("; Recursive implementation\n"); - printf("; Blocks: entry -> base_case / recursive\n"); - printf(";\n"); - printf("; main() -> i64:\n"); - printf("; Calls factorial(5), expected result: 120\n"); - printf(";\n"); - printf("; Function info:\n"); - - size_t len; - for (LLVMValueRef fn = LLVMGetFirstFunction(mod); fn; fn = LLVMGetNextFunction(fn)) { - const char *name = LLVMGetValueName2(fn, &len); - unsigned bb_count = LLVMCountBasicBlocks(fn); - unsigned param_count = LLVMCountParams(fn); - printf("; %s: %u params, %u blocks\n", name, param_count, bb_count); - } - - printf("\n"); - - // Print module IR - char *ir = LLVMPrintModuleToString(mod); - printf("%s", ir); - LLVMDisposeMessage(ir); - - // Cleanup LLVMDisposeModule(mod); LLVMContextDispose(ctx); + return 1; + } + LLVMDisposeMessage(error); - return 0; + // Print diagnostic comments + printf("; Test: test_factorial\n"); + printf("; Integration test: Iterative and recursive factorial\n"); + printf(";\n"); + printf("; factorial(i64 n) -> i64:\n"); + printf("; Iterative implementation using alloca/load/store\n"); + printf("; Blocks: entry -> loop_cond -> loop_body -> exit\n"); + printf(";\n"); + printf("; factorial_recursive(i64 n) -> i64:\n"); + printf("; Recursive implementation\n"); + printf("; Blocks: entry -> base_case / recursive\n"); + printf(";\n"); + printf("; main() -> i64:\n"); + printf("; Calls factorial(5), expected result: 120\n"); + printf(";\n"); + printf("; Function info:\n"); + + size_t len; + for (LLVMValueRef fn = LLVMGetFirstFunction(mod); fn; + fn = LLVMGetNextFunction(fn)) { + const char *name = LLVMGetValueName2(fn, &len); + unsigned bb_count = LLVMCountBasicBlocks(fn); + unsigned param_count = LLVMCountParams(fn); + printf("; %s: %u params, %u blocks\n", name, param_count, bb_count); + } + + printf("\n"); + + // Print module IR + char *ir = LLVMPrintModuleToString(mod); + printf("%s", ir); + LLVMDisposeMessage(ir); + + // Cleanup + LLVMDisposeModule(mod); + LLVMContextDispose(ctx); + + return 0; } diff --git a/tests/test_function.cpp b/tests/test_function.cpp index 6c1b2fd..31c4f1e 100644 --- a/tests/test_function.cpp +++ b/tests/test_function.cpp @@ -14,177 +14,194 @@ * - LLVMGetReturnType(), LLVMCountParamTypes() */ -#include -#include #include #include +#include +#include -const char* linkage_name(LLVMLinkage linkage) { - switch (linkage) { - case LLVMExternalLinkage: return "external"; - case LLVMAvailableExternallyLinkage: return "available_externally"; - case LLVMLinkOnceAnyLinkage: return "linkonce"; - case LLVMLinkOnceODRLinkage: return "linkonce_odr"; - case LLVMWeakAnyLinkage: return "weak"; - case LLVMWeakODRLinkage: return "weak_odr"; - case LLVMAppendingLinkage: return "appending"; - case LLVMInternalLinkage: return "internal"; - case LLVMPrivateLinkage: return "private"; - case LLVMExternalWeakLinkage: return "extern_weak"; - case LLVMCommonLinkage: return "common"; - default: return "unknown"; - } +const char *linkage_name(LLVMLinkage linkage) { + switch (linkage) { + case LLVMExternalLinkage: + return "external"; + case LLVMAvailableExternallyLinkage: + return "available_externally"; + case LLVMLinkOnceAnyLinkage: + return "linkonce"; + case LLVMLinkOnceODRLinkage: + return "linkonce_odr"; + case LLVMWeakAnyLinkage: + return "weak"; + case LLVMWeakODRLinkage: + return "weak_odr"; + case LLVMAppendingLinkage: + return "appending"; + case LLVMInternalLinkage: + return "internal"; + case LLVMPrivateLinkage: + return "private"; + case LLVMExternalWeakLinkage: + return "extern_weak"; + case LLVMCommonLinkage: + return "common"; + default: + return "unknown"; + } } int main() { - LLVMContextRef ctx = LLVMContextCreate(); - LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_function", ctx); + LLVMContextRef ctx = LLVMContextCreate(); + LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_function", ctx); - LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); - LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx); - LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx); - LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0); + LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); + LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx); + LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx); + LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0); - // Function 1: void foo() - LLVMTypeRef foo_ty = LLVMFunctionType(void_ty, nullptr, 0, 0); - LLVMValueRef foo = LLVMAddFunction(mod, "foo", foo_ty); + // Function 1: void foo() + LLVMTypeRef foo_ty = LLVMFunctionType(void_ty, nullptr, 0, 0); + LLVMValueRef foo = LLVMAddFunction(mod, "foo", foo_ty); - // Function 2: i32 bar(i32, i32) - LLVMTypeRef bar_params[] = {i32, i32}; - LLVMTypeRef bar_ty = LLVMFunctionType(i32, bar_params, 2, 0); - LLVMValueRef bar = LLVMAddFunction(mod, "bar", bar_ty); + // Function 2: i32 bar(i32, i32) + LLVMTypeRef bar_params[] = {i32, i32}; + LLVMTypeRef bar_ty = LLVMFunctionType(i32, bar_params, 2, 0); + LLVMValueRef bar = LLVMAddFunction(mod, "bar", bar_ty); - // Set parameter names - LLVMValueRef bar_param0 = LLVMGetParam(bar, 0); - LLVMValueRef bar_param1 = LLVMGetParam(bar, 1); - LLVMSetValueName2(bar_param0, "x", 1); - LLVMSetValueName2(bar_param1, "y", 1); + // Set parameter names + LLVMValueRef bar_param0 = LLVMGetParam(bar, 0); + LLVMValueRef bar_param1 = LLVMGetParam(bar, 1); + LLVMSetValueName2(bar_param0, "x", 1); + LLVMSetValueName2(bar_param1, "y", 1); - // Function 3: i64 baz(ptr, i32, i64) with internal linkage - // Internal linkage requires a body, so we add a simple one - LLVMTypeRef baz_params[] = {ptr, i32, i64}; - LLVMTypeRef baz_ty = LLVMFunctionType(i64, baz_params, 3, 0); - LLVMValueRef baz = LLVMAddFunction(mod, "baz", baz_ty); - LLVMSetLinkage(baz, LLVMInternalLinkage); - - // Add a basic block with return to make it a valid definition - LLVMBasicBlockRef baz_entry = LLVMAppendBasicBlockInContext(ctx, baz, "entry"); - LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); - LLVMPositionBuilderAtEnd(builder, baz_entry); - LLVMBuildRet(builder, LLVMConstInt(i64, 0, 0)); - LLVMDisposeBuilder(builder); + // Function 3: i64 baz(ptr, i32, i64) with internal linkage + // Internal linkage requires a body, so we add a simple one + LLVMTypeRef baz_params[] = {ptr, i32, i64}; + LLVMTypeRef baz_ty = LLVMFunctionType(i64, baz_params, 3, 0); + LLVMValueRef baz = LLVMAddFunction(mod, "baz", baz_ty); + LLVMSetLinkage(baz, LLVMInternalLinkage); - // Function 4: varargs function - i32 printf(ptr, ...) - LLVMTypeRef printf_params[] = {ptr}; - LLVMTypeRef printf_ty = LLVMFunctionType(i32, printf_params, 1, 1); - LLVMValueRef printf_fn = LLVMAddFunction(mod, "printf", printf_ty); + // Add a basic block with return to make it a valid definition + LLVMBasicBlockRef baz_entry = + LLVMAppendBasicBlockInContext(ctx, baz, "entry"); + LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); + LLVMPositionBuilderAtEnd(builder, baz_entry); + LLVMBuildRet(builder, LLVMConstInt(i64, 0, 0)); + LLVMDisposeBuilder(builder); - // Function 5: Function with fastcc calling convention - LLVMTypeRef fastcc_params[] = {i32}; - LLVMTypeRef fastcc_ty = LLVMFunctionType(i32, fastcc_params, 1, 0); - LLVMValueRef fastcc_fn = LLVMAddFunction(mod, "fastcc_func", fastcc_ty); - LLVMSetFunctionCallConv(fastcc_fn, LLVMFastCallConv); + // Function 4: varargs function - i32 printf(ptr, ...) + LLVMTypeRef printf_params[] = {ptr}; + LLVMTypeRef printf_ty = LLVMFunctionType(i32, printf_params, 1, 1); + LLVMValueRef printf_fn = LLVMAddFunction(mod, "printf", printf_ty); - // Function 6: Will be deleted - LLVMTypeRef delete_ty = LLVMFunctionType(void_ty, nullptr, 0, 0); - LLVMValueRef delete_fn = LLVMAddFunction(mod, "to_be_deleted", delete_ty); + // Function 5: Function with fastcc calling convention + LLVMTypeRef fastcc_params[] = {i32}; + LLVMTypeRef fastcc_ty = LLVMFunctionType(i32, fastcc_params, 1, 0); + LLVMValueRef fastcc_fn = LLVMAddFunction(mod, "fastcc_func", fastcc_ty); + LLVMSetFunctionCallConv(fastcc_fn, LLVMFastCallConv); - // Get function by name - LLVMValueRef found_bar = LLVMGetNamedFunction(mod, "bar"); + // Function 6: Will be deleted + LLVMTypeRef delete_ty = LLVMFunctionType(void_ty, nullptr, 0, 0); + LLVMValueRef delete_fn = LLVMAddFunction(mod, "to_be_deleted", delete_ty); - // Count functions before deletion - int count_before = 0; - for (LLVMValueRef fn = LLVMGetFirstFunction(mod); fn; fn = LLVMGetNextFunction(fn)) { - count_before++; - } + // Get function by name + LLVMValueRef found_bar = LLVMGetNamedFunction(mod, "bar"); - // Delete the function - LLVMDeleteFunction(delete_fn); + // Count functions before deletion + int count_before = 0; + for (LLVMValueRef fn = LLVMGetFirstFunction(mod); fn; + fn = LLVMGetNextFunction(fn)) { + count_before++; + } - // Count functions after deletion - int count_after = 0; - for (LLVMValueRef fn = LLVMGetFirstFunction(mod); fn; fn = LLVMGetNextFunction(fn)) { - count_after++; - } + // Delete the function + LLVMDeleteFunction(delete_fn); - // Verify module - char *error = nullptr; - if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { - fprintf(stderr, "; Verification failed: %s\n", error); - LLVMDisposeMessage(error); - LLVMDisposeModule(mod); - LLVMContextDispose(ctx); - return 1; - } + // Count functions after deletion + int count_after = 0; + for (LLVMValueRef fn = LLVMGetFirstFunction(mod); fn; + fn = LLVMGetNextFunction(fn)) { + count_after++; + } + + // Verify module + char *error = nullptr; + if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { + fprintf(stderr, "; Verification failed: %s\n", error); LLVMDisposeMessage(error); - - // Print diagnostic comments - printf("; Test: test_function\n"); - printf(";\n"); - - // foo info - size_t name_len; - const char *foo_name = LLVMGetValueName2(foo, &name_len); - printf("; Function 'foo':\n"); - printf("; name: %s\n", foo_name); - printf("; param count: %u\n", LLVMCountParams(foo)); - printf("; linkage: %s\n", linkage_name(LLVMGetLinkage(foo))); - printf("; calling conv: %u (C=0)\n", LLVMGetFunctionCallConv(foo)); - - // bar info - const char *bar_name = LLVMGetValueName2(bar, &name_len); - printf(";\n"); - printf("; Function 'bar':\n"); - printf("; name: %s\n", bar_name); - printf("; param count: %u\n", LLVMCountParams(bar)); - printf("; found by name: %s\n", found_bar == bar ? "yes" : "no"); - - // Get param names - const char *p0_name = LLVMGetValueName2(bar_param0, &name_len); - const char *p1_name = LLVMGetValueName2(bar_param1, &name_len); - printf("; param 0 name: %s\n", p0_name); - printf("; param 1 name: %s\n", p1_name); - - // baz info - printf(";\n"); - printf("; Function 'baz':\n"); - printf("; param count: %u\n", LLVMCountParams(baz)); - printf("; linkage: %s\n", linkage_name(LLVMGetLinkage(baz))); - - // printf info - printf(";\n"); - printf("; Function 'printf':\n"); - printf("; param count: %u\n", LLVMCountParams(printf_fn)); - printf("; is vararg: %s\n", LLVMIsFunctionVarArg(printf_ty) ? "yes" : "no"); - - // fastcc info - printf(";\n"); - printf("; Function 'fastcc_func':\n"); - printf("; calling conv: %u (FastCall=8)\n", LLVMGetFunctionCallConv(fastcc_fn)); - - // Function counts - printf(";\n"); - printf("; Function count before deletion: %d\n", count_before); - printf("; Function count after deletion: %d\n", count_after); - - // List all functions - printf(";\n"); - printf("; All functions:\n"); - for (LLVMValueRef fn = LLVMGetFirstFunction(mod); fn; fn = LLVMGetNextFunction(fn)) { - const char *fn_name = LLVMGetValueName2(fn, &name_len); - printf("; - %s\n", fn_name); - } - - printf("\n"); - - // Print module IR - char *ir = LLVMPrintModuleToString(mod); - printf("%s", ir); - LLVMDisposeMessage(ir); - - // Cleanup LLVMDisposeModule(mod); LLVMContextDispose(ctx); + return 1; + } + LLVMDisposeMessage(error); - return 0; + // Print diagnostic comments + printf("; Test: test_function\n"); + printf(";\n"); + + // foo info + size_t name_len; + const char *foo_name = LLVMGetValueName2(foo, &name_len); + printf("; Function 'foo':\n"); + printf("; name: %s\n", foo_name); + printf("; param count: %u\n", LLVMCountParams(foo)); + printf("; linkage: %s\n", linkage_name(LLVMGetLinkage(foo))); + printf("; calling conv: %u (C=0)\n", LLVMGetFunctionCallConv(foo)); + + // bar info + const char *bar_name = LLVMGetValueName2(bar, &name_len); + printf(";\n"); + printf("; Function 'bar':\n"); + printf("; name: %s\n", bar_name); + printf("; param count: %u\n", LLVMCountParams(bar)); + printf("; found by name: %s\n", found_bar == bar ? "yes" : "no"); + + // Get param names + const char *p0_name = LLVMGetValueName2(bar_param0, &name_len); + const char *p1_name = LLVMGetValueName2(bar_param1, &name_len); + printf("; param 0 name: %s\n", p0_name); + printf("; param 1 name: %s\n", p1_name); + + // baz info + printf(";\n"); + printf("; Function 'baz':\n"); + printf("; param count: %u\n", LLVMCountParams(baz)); + printf("; linkage: %s\n", linkage_name(LLVMGetLinkage(baz))); + + // printf info + printf(";\n"); + printf("; Function 'printf':\n"); + printf("; param count: %u\n", LLVMCountParams(printf_fn)); + printf("; is vararg: %s\n", LLVMIsFunctionVarArg(printf_ty) ? "yes" : "no"); + + // fastcc info + printf(";\n"); + printf("; Function 'fastcc_func':\n"); + printf("; calling conv: %u (FastCall=8)\n", + LLVMGetFunctionCallConv(fastcc_fn)); + + // Function counts + printf(";\n"); + printf("; Function count before deletion: %d\n", count_before); + printf("; Function count after deletion: %d\n", count_after); + + // List all functions + printf(";\n"); + printf("; All functions:\n"); + for (LLVMValueRef fn = LLVMGetFirstFunction(mod); fn; + fn = LLVMGetNextFunction(fn)) { + const char *fn_name = LLVMGetValueName2(fn, &name_len); + printf("; - %s\n", fn_name); + } + + printf("\n"); + + // Print module IR + char *ir = LLVMPrintModuleToString(mod); + printf("%s", ir); + LLVMDisposeMessage(ir); + + // Cleanup + LLVMDisposeModule(mod); + LLVMContextDispose(ctx); + + return 0; } diff --git a/tests/test_globals.cpp b/tests/test_globals.cpp index 21dbb0e..319e9d9 100644 --- a/tests/test_globals.cpp +++ b/tests/test_globals.cpp @@ -17,209 +17,232 @@ * - LLVMSetExternallyInitialized(), LLVMIsExternallyInitialized() */ -#include -#include #include +#include +#include -const char* linkage_name(LLVMLinkage linkage) { - switch (linkage) { - case LLVMExternalLinkage: return "external"; - case LLVMAvailableExternallyLinkage: return "available_externally"; - case LLVMLinkOnceAnyLinkage: return "linkonce"; - case LLVMLinkOnceODRLinkage: return "linkonce_odr"; - case LLVMWeakAnyLinkage: return "weak"; - case LLVMWeakODRLinkage: return "weak_odr"; - case LLVMAppendingLinkage: return "appending"; - case LLVMInternalLinkage: return "internal"; - case LLVMPrivateLinkage: return "private"; - case LLVMExternalWeakLinkage: return "extern_weak"; - case LLVMCommonLinkage: return "common"; - default: return "unknown"; - } +const char *linkage_name(LLVMLinkage linkage) { + switch (linkage) { + case LLVMExternalLinkage: + return "external"; + case LLVMAvailableExternallyLinkage: + return "available_externally"; + case LLVMLinkOnceAnyLinkage: + return "linkonce"; + case LLVMLinkOnceODRLinkage: + return "linkonce_odr"; + case LLVMWeakAnyLinkage: + return "weak"; + case LLVMWeakODRLinkage: + return "weak_odr"; + case LLVMAppendingLinkage: + return "appending"; + case LLVMInternalLinkage: + return "internal"; + case LLVMPrivateLinkage: + return "private"; + case LLVMExternalWeakLinkage: + return "extern_weak"; + case LLVMCommonLinkage: + return "common"; + default: + return "unknown"; + } } -const char* visibility_name(LLVMVisibility vis) { - switch (vis) { - case LLVMDefaultVisibility: return "default"; - case LLVMHiddenVisibility: return "hidden"; - case LLVMProtectedVisibility: return "protected"; - default: return "unknown"; - } +const char *visibility_name(LLVMVisibility vis) { + switch (vis) { + case LLVMDefaultVisibility: + return "default"; + case LLVMHiddenVisibility: + return "hidden"; + case LLVMProtectedVisibility: + return "protected"; + default: + return "unknown"; + } } int main() { - LLVMContextRef ctx = LLVMContextCreate(); - LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_globals", ctx); + LLVMContextRef ctx = LLVMContextCreate(); + LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_globals", ctx); - LLVMTypeRef i8 = LLVMInt8TypeInContext(ctx); - LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); - LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx); - LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx); - LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0); + LLVMTypeRef i8 = LLVMInt8TypeInContext(ctx); + LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); + LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx); + LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx); + LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0); - // ========================================== - // Basic global variable - // ========================================== - LLVMValueRef global_counter = LLVMAddGlobal(mod, i32, "counter"); - LLVMSetInitializer(global_counter, LLVMConstInt(i32, 0, 0)); + // ========================================== + // Basic global variable + // ========================================== + LLVMValueRef global_counter = LLVMAddGlobal(mod, i32, "counter"); + LLVMSetInitializer(global_counter, LLVMConstInt(i32, 0, 0)); - // ========================================== - // Constant global - // ========================================== - LLVMValueRef global_const = LLVMAddGlobal(mod, i32, "magic_number"); - LLVMSetInitializer(global_const, LLVMConstInt(i32, 42, 0)); - LLVMSetGlobalConstant(global_const, 1); + // ========================================== + // Constant global + // ========================================== + LLVMValueRef global_const = LLVMAddGlobal(mod, i32, "magic_number"); + LLVMSetInitializer(global_const, LLVMConstInt(i32, 42, 0)); + LLVMSetGlobalConstant(global_const, 1); - // ========================================== - // Global with alignment - // ========================================== - LLVMValueRef global_aligned = LLVMAddGlobal(mod, i64, "aligned_var"); - LLVMSetInitializer(global_aligned, LLVMConstInt(i64, 0, 0)); - LLVMSetAlignment(global_aligned, 16); + // ========================================== + // Global with alignment + // ========================================== + LLVMValueRef global_aligned = LLVMAddGlobal(mod, i64, "aligned_var"); + LLVMSetInitializer(global_aligned, LLVMConstInt(i64, 0, 0)); + LLVMSetAlignment(global_aligned, 16); - // ========================================== - // Global with linkage - // ========================================== - LLVMValueRef global_internal = LLVMAddGlobal(mod, i32, "internal_var"); - LLVMSetInitializer(global_internal, LLVMConstInt(i32, 100, 0)); - LLVMSetLinkage(global_internal, LLVMInternalLinkage); + // ========================================== + // Global with linkage + // ========================================== + LLVMValueRef global_internal = LLVMAddGlobal(mod, i32, "internal_var"); + LLVMSetInitializer(global_internal, LLVMConstInt(i32, 100, 0)); + LLVMSetLinkage(global_internal, LLVMInternalLinkage); - LLVMValueRef global_private = LLVMAddGlobal(mod, i32, "private_var"); - LLVMSetInitializer(global_private, LLVMConstInt(i32, 200, 0)); - LLVMSetLinkage(global_private, LLVMPrivateLinkage); + LLVMValueRef global_private = LLVMAddGlobal(mod, i32, "private_var"); + LLVMSetInitializer(global_private, LLVMConstInt(i32, 200, 0)); + LLVMSetLinkage(global_private, LLVMPrivateLinkage); - LLVMValueRef global_weak = LLVMAddGlobal(mod, i32, "weak_var"); - LLVMSetInitializer(global_weak, LLVMConstInt(i32, 300, 0)); - LLVMSetLinkage(global_weak, LLVMWeakAnyLinkage); + LLVMValueRef global_weak = LLVMAddGlobal(mod, i32, "weak_var"); + LLVMSetInitializer(global_weak, LLVMConstInt(i32, 300, 0)); + LLVMSetLinkage(global_weak, LLVMWeakAnyLinkage); - // ========================================== - // Global with visibility - // ========================================== - LLVMValueRef global_hidden = LLVMAddGlobal(mod, i32, "hidden_var"); - LLVMSetInitializer(global_hidden, LLVMConstInt(i32, 0, 0)); - LLVMSetVisibility(global_hidden, LLVMHiddenVisibility); + // ========================================== + // Global with visibility + // ========================================== + LLVMValueRef global_hidden = LLVMAddGlobal(mod, i32, "hidden_var"); + LLVMSetInitializer(global_hidden, LLVMConstInt(i32, 0, 0)); + LLVMSetVisibility(global_hidden, LLVMHiddenVisibility); - // ========================================== - // Global with section - // ========================================== - LLVMValueRef global_section = LLVMAddGlobal(mod, i32, "section_var"); - LLVMSetInitializer(global_section, LLVMConstInt(i32, 0, 0)); - LLVMSetSection(global_section, ".mydata"); + // ========================================== + // Global with section + // ========================================== + LLVMValueRef global_section = LLVMAddGlobal(mod, i32, "section_var"); + LLVMSetInitializer(global_section, LLVMConstInt(i32, 0, 0)); + LLVMSetSection(global_section, ".mydata"); - // ========================================== - // Thread-local global - // ========================================== - LLVMValueRef global_tls = LLVMAddGlobal(mod, i32, "tls_var"); - LLVMSetInitializer(global_tls, LLVMConstInt(i32, 0, 0)); - LLVMSetThreadLocal(global_tls, 1); + // ========================================== + // Thread-local global + // ========================================== + LLVMValueRef global_tls = LLVMAddGlobal(mod, i32, "tls_var"); + LLVMSetInitializer(global_tls, LLVMConstInt(i32, 0, 0)); + LLVMSetThreadLocal(global_tls, 1); - // ========================================== - // Externally initialized global (no initializer) - // ========================================== - LLVMValueRef global_extern = LLVMAddGlobal(mod, i32, "extern_var"); - LLVMSetExternallyInitialized(global_extern, 1); + // ========================================== + // Externally initialized global (no initializer) + // ========================================== + LLVMValueRef global_extern = LLVMAddGlobal(mod, i32, "extern_var"); + LLVMSetExternallyInitialized(global_extern, 1); - // ========================================== - // Global in address space - // ========================================== - LLVMValueRef global_addrspace = LLVMAddGlobalInAddressSpace(mod, i32, "addrspace_var", 1); - LLVMSetInitializer(global_addrspace, LLVMConstInt(i32, 0, 0)); + // ========================================== + // Global in address space + // ========================================== + LLVMValueRef global_addrspace = + LLVMAddGlobalInAddressSpace(mod, i32, "addrspace_var", 1); + LLVMSetInitializer(global_addrspace, LLVMConstInt(i32, 0, 0)); - // ========================================== - // Global to be deleted - // ========================================== - LLVMValueRef global_delete = LLVMAddGlobal(mod, i32, "to_be_deleted"); - LLVMSetInitializer(global_delete, LLVMConstInt(i32, 999, 0)); + // ========================================== + // Global to be deleted + // ========================================== + LLVMValueRef global_delete = LLVMAddGlobal(mod, i32, "to_be_deleted"); + LLVMSetInitializer(global_delete, LLVMConstInt(i32, 999, 0)); - // Count globals before deletion - int count_before = 0; - for (LLVMValueRef g = LLVMGetFirstGlobal(mod); g; g = LLVMGetNextGlobal(g)) { - count_before++; - } + // Count globals before deletion + int count_before = 0; + for (LLVMValueRef g = LLVMGetFirstGlobal(mod); g; g = LLVMGetNextGlobal(g)) { + count_before++; + } - // Delete the global - LLVMDeleteGlobal(global_delete); + // Delete the global + LLVMDeleteGlobal(global_delete); - // Count globals after deletion - int count_after = 0; - for (LLVMValueRef g = LLVMGetFirstGlobal(mod); g; g = LLVMGetNextGlobal(g)) { - count_after++; - } + // Count globals after deletion + int count_after = 0; + for (LLVMValueRef g = LLVMGetFirstGlobal(mod); g; g = LLVMGetNextGlobal(g)) { + count_after++; + } - // Get global by name - LLVMValueRef found_counter = LLVMGetNamedGlobal(mod, "counter"); - LLVMValueRef found_nonexist = LLVMGetNamedGlobal(mod, "nonexistent"); + // Get global by name + LLVMValueRef found_counter = LLVMGetNamedGlobal(mod, "counter"); + LLVMValueRef found_nonexist = LLVMGetNamedGlobal(mod, "nonexistent"); - // Get initializer - LLVMValueRef init = LLVMGetInitializer(global_const); + // Get initializer + LLVMValueRef init = LLVMGetInitializer(global_const); - // Verify module - char *error = nullptr; - if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { - fprintf(stderr, "; Verification failed: %s\n", error); - LLVMDisposeMessage(error); - LLVMDisposeModule(mod); - LLVMContextDispose(ctx); - return 1; - } + // Verify module + char *error = nullptr; + if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { + fprintf(stderr, "; Verification failed: %s\n", error); LLVMDisposeMessage(error); - - // Print diagnostic comments - printf("; Test: test_globals\n"); - printf(";\n"); - printf("; Global variable properties:\n"); - printf(";\n"); - printf("; counter:\n"); - printf("; is constant: %s\n", LLVMIsGlobalConstant(global_counter) ? "yes" : "no"); - printf("; linkage: %s\n", linkage_name(LLVMGetLinkage(global_counter))); - printf(";\n"); - printf("; magic_number:\n"); - printf("; is constant: %s\n", LLVMIsGlobalConstant(global_const) ? "yes" : "no"); - printf("; has initializer: %s\n", init != nullptr ? "yes" : "no"); - printf("; initializer value: %llu\n", LLVMConstIntGetZExtValue(init)); - printf(";\n"); - printf("; aligned_var:\n"); - printf("; alignment: %u\n", LLVMGetAlignment(global_aligned)); - printf(";\n"); - printf("; internal_var:\n"); - printf("; linkage: %s\n", linkage_name(LLVMGetLinkage(global_internal))); - printf(";\n"); - printf("; hidden_var:\n"); - printf("; visibility: %s\n", visibility_name(LLVMGetVisibility(global_hidden))); - printf(";\n"); - printf("; section_var:\n"); - printf("; section: %s\n", LLVMGetSection(global_section)); - printf(";\n"); - printf("; tls_var:\n"); - printf("; is thread local: %s\n", LLVMIsThreadLocal(global_tls) ? "yes" : "no"); - printf(";\n"); - printf("; extern_var:\n"); - printf("; is externally initialized: %s\n", LLVMIsExternallyInitialized(global_extern) ? "yes" : "no"); - printf(";\n"); - printf("; Lookup tests:\n"); - printf("; found 'counter': %s\n", found_counter != nullptr ? "yes" : "no"); - printf("; found 'nonexistent': %s\n", found_nonexist != nullptr ? "yes" : "no"); - printf(";\n"); - printf("; Global counts:\n"); - printf("; before deletion: %d\n", count_before); - printf("; after deletion: %d\n", count_after); - printf(";\n"); - printf("; All globals:\n"); - for (LLVMValueRef g = LLVMGetFirstGlobal(mod); g; g = LLVMGetNextGlobal(g)) { - size_t len; - const char *name = LLVMGetValueName2(g, &len); - printf("; - %s\n", name); - } - printf("\n"); - - // Print module IR - char *ir = LLVMPrintModuleToString(mod); - printf("%s", ir); - LLVMDisposeMessage(ir); - - // Cleanup LLVMDisposeModule(mod); LLVMContextDispose(ctx); + return 1; + } + LLVMDisposeMessage(error); - return 0; + // Print diagnostic comments + printf("; Test: test_globals\n"); + printf(";\n"); + printf("; Global variable properties:\n"); + printf(";\n"); + printf("; counter:\n"); + printf("; is constant: %s\n", + LLVMIsGlobalConstant(global_counter) ? "yes" : "no"); + printf("; linkage: %s\n", linkage_name(LLVMGetLinkage(global_counter))); + printf(";\n"); + printf("; magic_number:\n"); + printf("; is constant: %s\n", + LLVMIsGlobalConstant(global_const) ? "yes" : "no"); + printf("; has initializer: %s\n", init != nullptr ? "yes" : "no"); + printf("; initializer value: %llu\n", LLVMConstIntGetZExtValue(init)); + printf(";\n"); + printf("; aligned_var:\n"); + printf("; alignment: %u\n", LLVMGetAlignment(global_aligned)); + printf(";\n"); + printf("; internal_var:\n"); + printf("; linkage: %s\n", linkage_name(LLVMGetLinkage(global_internal))); + printf(";\n"); + printf("; hidden_var:\n"); + printf("; visibility: %s\n", + visibility_name(LLVMGetVisibility(global_hidden))); + printf(";\n"); + printf("; section_var:\n"); + printf("; section: %s\n", LLVMGetSection(global_section)); + printf(";\n"); + printf("; tls_var:\n"); + printf("; is thread local: %s\n", + LLVMIsThreadLocal(global_tls) ? "yes" : "no"); + printf(";\n"); + printf("; extern_var:\n"); + printf("; is externally initialized: %s\n", + LLVMIsExternallyInitialized(global_extern) ? "yes" : "no"); + printf(";\n"); + printf("; Lookup tests:\n"); + printf("; found 'counter': %s\n", found_counter != nullptr ? "yes" : "no"); + printf("; found 'nonexistent': %s\n", + found_nonexist != nullptr ? "yes" : "no"); + printf(";\n"); + printf("; Global counts:\n"); + printf("; before deletion: %d\n", count_before); + printf("; after deletion: %d\n", count_after); + printf(";\n"); + printf("; All globals:\n"); + for (LLVMValueRef g = LLVMGetFirstGlobal(mod); g; g = LLVMGetNextGlobal(g)) { + size_t len; + const char *name = LLVMGetValueName2(g, &len); + printf("; - %s\n", name); + } + printf("\n"); + + // Print module IR + char *ir = LLVMPrintModuleToString(mod); + printf("%s", ir); + LLVMDisposeMessage(ir); + + // Cleanup + LLVMDisposeModule(mod); + LLVMContextDispose(ctx); + + return 0; } diff --git a/tests/test_module.cpp b/tests/test_module.cpp index aaf9efb..40eb856 100644 --- a/tests/test_module.cpp +++ b/tests/test_module.cpp @@ -13,85 +13,89 @@ * - LLVMDisposeModule() */ -#include -#include #include #include +#include +#include #include int main() { - LLVMContextRef ctx = LLVMContextCreate(); + LLVMContextRef ctx = LLVMContextCreate(); - // Create module - LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_module", ctx); + // Create module + LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_module", ctx); - // Get initial module identifier (copy to string before modifying) - size_t id_len; - const char *id_ptr = LLVMGetModuleIdentifier(mod, &id_len); - std::string initial_id(id_ptr, id_len); + // Get initial module identifier (copy to string before modifying) + size_t id_len; + const char *id_ptr = LLVMGetModuleIdentifier(mod, &id_len); + std::string initial_id(id_ptr, id_len); - // Set new module identifier - LLVMSetModuleIdentifier(mod, "renamed_module", strlen("renamed_module")); - id_ptr = LLVMGetModuleIdentifier(mod, &id_len); - std::string new_id(id_ptr, id_len); + // Set new module identifier + LLVMSetModuleIdentifier(mod, "renamed_module", strlen("renamed_module")); + id_ptr = LLVMGetModuleIdentifier(mod, &id_len); + std::string new_id(id_ptr, id_len); - // Get/set source filename (copy to string before modifying) - size_t src_len; - const char *src_ptr = LLVMGetSourceFileName(mod, &src_len); - std::string initial_src(src_ptr, src_len); - LLVMSetSourceFileName(mod, "test_source.c", strlen("test_source.c")); - src_ptr = LLVMGetSourceFileName(mod, &src_len); - std::string new_src(src_ptr, src_len); + // Get/set source filename (copy to string before modifying) + size_t src_len; + const char *src_ptr = LLVMGetSourceFileName(mod, &src_len); + std::string initial_src(src_ptr, src_len); + LLVMSetSourceFileName(mod, "test_source.c", strlen("test_source.c")); + src_ptr = LLVMGetSourceFileName(mod, &src_len); + std::string new_src(src_ptr, src_len); - // Get/set data layout (copy to string before modifying) - std::string initial_layout = LLVMGetDataLayoutStr(mod); - LLVMSetDataLayout(mod, "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"); - std::string new_layout = LLVMGetDataLayoutStr(mod); + // Get/set data layout (copy to string before modifying) + std::string initial_layout = LLVMGetDataLayoutStr(mod); + LLVMSetDataLayout( + mod, + "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"); + std::string new_layout = LLVMGetDataLayoutStr(mod); - // Get/set target triple (copy to string before modifying) - std::string initial_target = LLVMGetTarget(mod); - LLVMSetTarget(mod, "x86_64-unknown-linux-gnu"); - std::string new_target = LLVMGetTarget(mod); + // Get/set target triple (copy to string before modifying) + std::string initial_target = LLVMGetTarget(mod); + LLVMSetTarget(mod, "x86_64-unknown-linux-gnu"); + std::string new_target = LLVMGetTarget(mod); - // Clone module - LLVMModuleRef cloned = LLVMCloneModule(mod); - id_ptr = LLVMGetModuleIdentifier(cloned, &id_len); - std::string cloned_id(id_ptr, id_len); + // Clone module + LLVMModuleRef cloned = LLVMCloneModule(mod); + id_ptr = LLVMGetModuleIdentifier(cloned, &id_len); + std::string cloned_id(id_ptr, id_len); - // Verify module - char *error = nullptr; - if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { - fprintf(stderr, "; Verification failed: %s\n", error); - LLVMDisposeMessage(error); - LLVMDisposeModule(cloned); - LLVMDisposeModule(mod); - LLVMContextDispose(ctx); - return 1; - } + // Verify module + char *error = nullptr; + if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { + fprintf(stderr, "; Verification failed: %s\n", error); LLVMDisposeMessage(error); - - // Print diagnostic comments - printf("; Test: test_module\n"); - printf("; Initial module ID: %s\n", initial_id.c_str()); - printf("; New module ID: %s\n", new_id.c_str()); - printf("; Initial source filename: %s\n", initial_src.c_str()); - printf("; New source filename: %s\n", new_src.c_str()); - printf("; Initial data layout: %s\n", initial_layout.empty() ? "(empty)" : initial_layout.c_str()); - printf("; New data layout: %s\n", new_layout.c_str()); - printf("; Initial target: %s\n", initial_target.empty() ? "(empty)" : initial_target.c_str()); - printf("; New target: %s\n", new_target.c_str()); - printf("; Cloned module ID: %s\n", cloned_id.c_str()); - printf("\n"); - - // Print module IR - char *ir = LLVMPrintModuleToString(mod); - printf("%s", ir); - LLVMDisposeMessage(ir); - - // Cleanup LLVMDisposeModule(cloned); LLVMDisposeModule(mod); LLVMContextDispose(ctx); + return 1; + } + LLVMDisposeMessage(error); - return 0; + // Print diagnostic comments + printf("; Test: test_module\n"); + printf("; Initial module ID: %s\n", initial_id.c_str()); + printf("; New module ID: %s\n", new_id.c_str()); + printf("; Initial source filename: %s\n", initial_src.c_str()); + printf("; New source filename: %s\n", new_src.c_str()); + printf("; Initial data layout: %s\n", + initial_layout.empty() ? "(empty)" : initial_layout.c_str()); + printf("; New data layout: %s\n", new_layout.c_str()); + printf("; Initial target: %s\n", + initial_target.empty() ? "(empty)" : initial_target.c_str()); + printf("; New target: %s\n", new_target.c_str()); + printf("; Cloned module ID: %s\n", cloned_id.c_str()); + printf("\n"); + + // Print module IR + char *ir = LLVMPrintModuleToString(mod); + printf("%s", ir); + LLVMDisposeMessage(ir); + + // Cleanup + LLVMDisposeModule(cloned); + LLVMDisposeModule(mod); + LLVMContextDispose(ctx); + + return 0; } diff --git a/tests/test_phi.cpp b/tests/test_phi.cpp index d89b8bc..909ef03 100644 --- a/tests/test_phi.cpp +++ b/tests/test_phi.cpp @@ -8,154 +8,164 @@ * - LLVMCountIncoming(), LLVMGetIncomingValue(), LLVMGetIncomingBlock() */ -#include -#include #include +#include +#include int main() { - LLVMContextRef ctx = LLVMContextCreate(); - LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_phi", ctx); + LLVMContextRef ctx = LLVMContextCreate(); + LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_phi", ctx); - LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx); - LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); + LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx); + LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); - LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); + LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); - // ========================================== - // Function: simple diamond pattern with PHI - // i32 diamond(i1 cond, i32 a, i32 b) - // ========================================== - LLVMTypeRef diamond_params[] = {i1, i32, i32}; - LLVMTypeRef diamond_ty = LLVMFunctionType(i32, diamond_params, 3, 0); - LLVMValueRef diamond_func = LLVMAddFunction(mod, "diamond", diamond_ty); + // ========================================== + // Function: simple diamond pattern with PHI + // i32 diamond(i1 cond, i32 a, i32 b) + // ========================================== + LLVMTypeRef diamond_params[] = {i1, i32, i32}; + LLVMTypeRef diamond_ty = LLVMFunctionType(i32, diamond_params, 3, 0); + LLVMValueRef diamond_func = LLVMAddFunction(mod, "diamond", diamond_ty); - LLVMValueRef cond = LLVMGetParam(diamond_func, 0); - LLVMValueRef a = LLVMGetParam(diamond_func, 1); - LLVMValueRef b = LLVMGetParam(diamond_func, 2); - LLVMSetValueName2(cond, "cond", 4); - LLVMSetValueName2(a, "a", 1); - LLVMSetValueName2(b, "b", 1); + LLVMValueRef cond = LLVMGetParam(diamond_func, 0); + LLVMValueRef a = LLVMGetParam(diamond_func, 1); + LLVMValueRef b = LLVMGetParam(diamond_func, 2); + LLVMSetValueName2(cond, "cond", 4); + LLVMSetValueName2(a, "a", 1); + LLVMSetValueName2(b, "b", 1); - LLVMBasicBlockRef entry = LLVMAppendBasicBlockInContext(ctx, diamond_func, "entry"); - LLVMBasicBlockRef if_true = LLVMAppendBasicBlockInContext(ctx, diamond_func, "if_true"); - LLVMBasicBlockRef if_false = LLVMAppendBasicBlockInContext(ctx, diamond_func, "if_false"); - LLVMBasicBlockRef merge = LLVMAppendBasicBlockInContext(ctx, diamond_func, "merge"); + LLVMBasicBlockRef entry = + LLVMAppendBasicBlockInContext(ctx, diamond_func, "entry"); + LLVMBasicBlockRef if_true = + LLVMAppendBasicBlockInContext(ctx, diamond_func, "if_true"); + LLVMBasicBlockRef if_false = + LLVMAppendBasicBlockInContext(ctx, diamond_func, "if_false"); + LLVMBasicBlockRef merge = + LLVMAppendBasicBlockInContext(ctx, diamond_func, "merge"); - // Entry: conditional branch - LLVMPositionBuilderAtEnd(builder, entry); - LLVMBuildCondBr(builder, cond, if_true, if_false); + // Entry: conditional branch + LLVMPositionBuilderAtEnd(builder, entry); + LLVMBuildCondBr(builder, cond, if_true, if_false); - // True branch: compute a * 2 - LLVMPositionBuilderAtEnd(builder, if_true); - LLVMValueRef a_doubled = LLVMBuildMul(builder, a, LLVMConstInt(i32, 2, 0), "a_doubled"); - LLVMBuildBr(builder, merge); + // True branch: compute a * 2 + LLVMPositionBuilderAtEnd(builder, if_true); + LLVMValueRef a_doubled = + LLVMBuildMul(builder, a, LLVMConstInt(i32, 2, 0), "a_doubled"); + LLVMBuildBr(builder, merge); - // False branch: compute b + 1 - LLVMPositionBuilderAtEnd(builder, if_false); - LLVMValueRef b_inc = LLVMBuildAdd(builder, b, LLVMConstInt(i32, 1, 0), "b_inc"); - LLVMBuildBr(builder, merge); + // False branch: compute b + 1 + LLVMPositionBuilderAtEnd(builder, if_false); + LLVMValueRef b_inc = + LLVMBuildAdd(builder, b, LLVMConstInt(i32, 1, 0), "b_inc"); + LLVMBuildBr(builder, merge); - // Merge: PHI node to select result - LLVMPositionBuilderAtEnd(builder, merge); - LLVMValueRef phi = LLVMBuildPhi(builder, i32, "result"); + // Merge: PHI node to select result + LLVMPositionBuilderAtEnd(builder, merge); + LLVMValueRef phi = LLVMBuildPhi(builder, i32, "result"); - // Add incoming values - LLVMValueRef incoming_vals[] = {a_doubled, b_inc}; - LLVMBasicBlockRef incoming_blocks[] = {if_true, if_false}; - LLVMAddIncoming(phi, incoming_vals, incoming_blocks, 2); + // Add incoming values + LLVMValueRef incoming_vals[] = {a_doubled, b_inc}; + LLVMBasicBlockRef incoming_blocks[] = {if_true, if_false}; + LLVMAddIncoming(phi, incoming_vals, incoming_blocks, 2); - LLVMBuildRet(builder, phi); + LLVMBuildRet(builder, phi); - // ========================================== - // Function: loop with PHI (sum 1 to n) - // i32 sum_to_n(i32 n) - // ========================================== - LLVMTypeRef sum_params[] = {i32}; - LLVMTypeRef sum_ty = LLVMFunctionType(i32, sum_params, 1, 0); - LLVMValueRef sum_func = LLVMAddFunction(mod, "sum_to_n", sum_ty); + // ========================================== + // Function: loop with PHI (sum 1 to n) + // i32 sum_to_n(i32 n) + // ========================================== + LLVMTypeRef sum_params[] = {i32}; + LLVMTypeRef sum_ty = LLVMFunctionType(i32, sum_params, 1, 0); + LLVMValueRef sum_func = LLVMAddFunction(mod, "sum_to_n", sum_ty); - LLVMValueRef n = LLVMGetParam(sum_func, 0); - LLVMSetValueName2(n, "n", 1); + LLVMValueRef n = LLVMGetParam(sum_func, 0); + LLVMSetValueName2(n, "n", 1); - LLVMBasicBlockRef sum_entry = LLVMAppendBasicBlockInContext(ctx, sum_func, "entry"); - LLVMBasicBlockRef loop = LLVMAppendBasicBlockInContext(ctx, sum_func, "loop"); - LLVMBasicBlockRef exit_bb = LLVMAppendBasicBlockInContext(ctx, sum_func, "exit"); + LLVMBasicBlockRef sum_entry = + LLVMAppendBasicBlockInContext(ctx, sum_func, "entry"); + LLVMBasicBlockRef loop = LLVMAppendBasicBlockInContext(ctx, sum_func, "loop"); + LLVMBasicBlockRef exit_bb = + LLVMAppendBasicBlockInContext(ctx, sum_func, "exit"); - // Entry: branch to loop - LLVMPositionBuilderAtEnd(builder, sum_entry); - LLVMBuildBr(builder, loop); + // Entry: branch to loop + LLVMPositionBuilderAtEnd(builder, sum_entry); + LLVMBuildBr(builder, loop); - // Loop header with PHIs - LLVMPositionBuilderAtEnd(builder, loop); - LLVMValueRef i_phi = LLVMBuildPhi(builder, i32, "i"); - LLVMValueRef sum_phi = LLVMBuildPhi(builder, i32, "sum"); + // Loop header with PHIs + LLVMPositionBuilderAtEnd(builder, loop); + LLVMValueRef i_phi = LLVMBuildPhi(builder, i32, "i"); + LLVMValueRef sum_phi = LLVMBuildPhi(builder, i32, "sum"); - // Loop body: sum += i; i++ - LLVMValueRef new_sum = LLVMBuildAdd(builder, sum_phi, i_phi, "new_sum"); - LLVMValueRef new_i = LLVMBuildAdd(builder, i_phi, LLVMConstInt(i32, 1, 0), "new_i"); + // Loop body: sum += i; i++ + LLVMValueRef new_sum = LLVMBuildAdd(builder, sum_phi, i_phi, "new_sum"); + LLVMValueRef new_i = + LLVMBuildAdd(builder, i_phi, LLVMConstInt(i32, 1, 0), "new_i"); - // Loop condition: i <= n - LLVMValueRef loop_cond = LLVMBuildICmp(builder, LLVMIntSLE, new_i, n, "loop_cond"); - LLVMBuildCondBr(builder, loop_cond, loop, exit_bb); + // Loop condition: i <= n + LLVMValueRef loop_cond = + LLVMBuildICmp(builder, LLVMIntSLE, new_i, n, "loop_cond"); + LLVMBuildCondBr(builder, loop_cond, loop, exit_bb); - // Add incoming values to PHIs - // From entry: i=1, sum=0 - LLVMValueRef i_incoming_vals[] = {LLVMConstInt(i32, 1, 0), new_i}; - LLVMBasicBlockRef i_incoming_blocks[] = {sum_entry, loop}; - LLVMAddIncoming(i_phi, i_incoming_vals, i_incoming_blocks, 2); + // Add incoming values to PHIs + // From entry: i=1, sum=0 + LLVMValueRef i_incoming_vals[] = {LLVMConstInt(i32, 1, 0), new_i}; + LLVMBasicBlockRef i_incoming_blocks[] = {sum_entry, loop}; + LLVMAddIncoming(i_phi, i_incoming_vals, i_incoming_blocks, 2); - LLVMValueRef sum_incoming_vals[] = {LLVMConstInt(i32, 0, 0), new_sum}; - LLVMBasicBlockRef sum_incoming_blocks[] = {sum_entry, loop}; - LLVMAddIncoming(sum_phi, sum_incoming_vals, sum_incoming_blocks, 2); + LLVMValueRef sum_incoming_vals[] = {LLVMConstInt(i32, 0, 0), new_sum}; + LLVMBasicBlockRef sum_incoming_blocks[] = {sum_entry, loop}; + LLVMAddIncoming(sum_phi, sum_incoming_vals, sum_incoming_blocks, 2); - // Exit: return sum - LLVMPositionBuilderAtEnd(builder, exit_bb); - LLVMBuildRet(builder, new_sum); + // Exit: return sum + LLVMPositionBuilderAtEnd(builder, exit_bb); + LLVMBuildRet(builder, new_sum); - LLVMDisposeBuilder(builder); + LLVMDisposeBuilder(builder); - // Verify module - char *error = nullptr; - if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { - fprintf(stderr, "; Verification failed: %s\n", error); - LLVMDisposeMessage(error); - LLVMDisposeModule(mod); - LLVMContextDispose(ctx); - return 1; - } + // Verify module + char *error = nullptr; + if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { + fprintf(stderr, "; Verification failed: %s\n", error); LLVMDisposeMessage(error); - - // Print diagnostic comments - printf("; Test: test_phi\n"); - printf(";\n"); - printf("; Diamond pattern PHI:\n"); - printf("; phi incoming count: %u\n", LLVMCountIncoming(phi)); - - // Get incoming values and blocks - for (unsigned i = 0; i < LLVMCountIncoming(phi); i++) { - LLVMValueRef val = LLVMGetIncomingValue(phi, i); - LLVMBasicBlockRef blk = LLVMGetIncomingBlock(phi, i); - size_t len; - const char *val_name = LLVMGetValueName2(val, &len); - const char *blk_name = LLVMGetBasicBlockName(blk); - printf("; incoming[%u]: value=%s, block=%s\n", i, val_name, blk_name); - } - - printf(";\n"); - printf("; Loop PHIs:\n"); - printf("; i_phi incoming count: %u\n", LLVMCountIncoming(i_phi)); - printf("; sum_phi incoming count: %u\n", LLVMCountIncoming(sum_phi)); - - printf("\n"); - - // Print module IR - char *ir = LLVMPrintModuleToString(mod); - printf("%s", ir); - LLVMDisposeMessage(ir); - - // Cleanup LLVMDisposeModule(mod); LLVMContextDispose(ctx); + return 1; + } + LLVMDisposeMessage(error); - return 0; + // Print diagnostic comments + printf("; Test: test_phi\n"); + printf(";\n"); + printf("; Diamond pattern PHI:\n"); + printf("; phi incoming count: %u\n", LLVMCountIncoming(phi)); + + // Get incoming values and blocks + for (unsigned i = 0; i < LLVMCountIncoming(phi); i++) { + LLVMValueRef val = LLVMGetIncomingValue(phi, i); + LLVMBasicBlockRef blk = LLVMGetIncomingBlock(phi, i); + size_t len; + const char *val_name = LLVMGetValueName2(val, &len); + const char *blk_name = LLVMGetBasicBlockName(blk); + printf("; incoming[%u]: value=%s, block=%s\n", i, val_name, blk_name); + } + + printf(";\n"); + printf("; Loop PHIs:\n"); + printf("; i_phi incoming count: %u\n", LLVMCountIncoming(i_phi)); + printf("; sum_phi incoming count: %u\n", LLVMCountIncoming(sum_phi)); + + printf("\n"); + + // Print module IR + char *ir = LLVMPrintModuleToString(mod); + printf("%s", ir); + LLVMDisposeMessage(ir); + + // Cleanup + LLVMDisposeModule(mod); + LLVMContextDispose(ctx); + + return 0; } diff --git a/tests/test_struct.cpp b/tests/test_struct.cpp index fd66f76..3a2250f 100644 --- a/tests/test_struct.cpp +++ b/tests/test_struct.cpp @@ -9,205 +9,221 @@ * - A complete point_add function */ -#include -#include #include +#include +#include int main() { - LLVMContextRef ctx = LLVMContextCreate(); - LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_struct", ctx); + LLVMContextRef ctx = LLVMContextCreate(); + LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_struct", ctx); - LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); - LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx); - LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0); + LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); + LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx); + LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0); - LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); + LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx); - // ========================================== - // Define Point struct: { i32 x, i32 y } - // ========================================== - LLVMTypeRef point_ty = LLVMStructCreateNamed(ctx, "Point"); - LLVMTypeRef point_fields[] = {i32, i32}; - LLVMStructSetBody(point_ty, point_fields, 2, 0); + // ========================================== + // Define Point struct: { i32 x, i32 y } + // ========================================== + LLVMTypeRef point_ty = LLVMStructCreateNamed(ctx, "Point"); + LLVMTypeRef point_fields[] = {i32, i32}; + LLVMStructSetBody(point_ty, point_fields, 2, 0); - // ========================================== - // Function: void point_init(Point* p, i32 x, i32 y) - // ========================================== - LLVMTypeRef init_params[] = {ptr, i32, i32}; - LLVMTypeRef init_ty = LLVMFunctionType(void_ty, init_params, 3, 0); - LLVMValueRef init_func = LLVMAddFunction(mod, "point_init", init_ty); + // ========================================== + // Function: void point_init(Point* p, i32 x, i32 y) + // ========================================== + LLVMTypeRef init_params[] = {ptr, i32, i32}; + LLVMTypeRef init_ty = LLVMFunctionType(void_ty, init_params, 3, 0); + LLVMValueRef init_func = LLVMAddFunction(mod, "point_init", init_ty); - LLVMValueRef p = LLVMGetParam(init_func, 0); - LLVMValueRef x = LLVMGetParam(init_func, 1); - LLVMValueRef y = LLVMGetParam(init_func, 2); - LLVMSetValueName2(p, "p", 1); - LLVMSetValueName2(x, "x", 1); - LLVMSetValueName2(y, "y", 1); + LLVMValueRef p = LLVMGetParam(init_func, 0); + LLVMValueRef x = LLVMGetParam(init_func, 1); + LLVMValueRef y = LLVMGetParam(init_func, 2); + LLVMSetValueName2(p, "p", 1); + LLVMSetValueName2(x, "x", 1); + LLVMSetValueName2(y, "y", 1); - LLVMBasicBlockRef init_entry = LLVMAppendBasicBlockInContext(ctx, init_func, "entry"); - LLVMPositionBuilderAtEnd(builder, init_entry); + LLVMBasicBlockRef init_entry = + LLVMAppendBasicBlockInContext(ctx, init_func, "entry"); + LLVMPositionBuilderAtEnd(builder, init_entry); - // Store x to p->x (field 0) - LLVMValueRef x_ptr = LLVMBuildStructGEP2(builder, point_ty, p, 0, "x_ptr"); - LLVMBuildStore(builder, x, x_ptr); + // Store x to p->x (field 0) + LLVMValueRef x_ptr = LLVMBuildStructGEP2(builder, point_ty, p, 0, "x_ptr"); + LLVMBuildStore(builder, x, x_ptr); - // Store y to p->y (field 1) - LLVMValueRef y_ptr = LLVMBuildStructGEP2(builder, point_ty, p, 1, "y_ptr"); - LLVMBuildStore(builder, y, y_ptr); + // Store y to p->y (field 1) + LLVMValueRef y_ptr = LLVMBuildStructGEP2(builder, point_ty, p, 1, "y_ptr"); + LLVMBuildStore(builder, y, y_ptr); - LLVMBuildRetVoid(builder); + LLVMBuildRetVoid(builder); - // ========================================== - // Function: void point_add(Point* a, Point* b, Point* result) - // ========================================== - LLVMTypeRef add_params[] = {ptr, ptr, ptr}; - LLVMTypeRef add_ty = LLVMFunctionType(void_ty, add_params, 3, 0); - LLVMValueRef add_func = LLVMAddFunction(mod, "point_add", add_ty); + // ========================================== + // Function: void point_add(Point* a, Point* b, Point* result) + // ========================================== + LLVMTypeRef add_params[] = {ptr, ptr, ptr}; + LLVMTypeRef add_ty = LLVMFunctionType(void_ty, add_params, 3, 0); + LLVMValueRef add_func = LLVMAddFunction(mod, "point_add", add_ty); - LLVMValueRef a = LLVMGetParam(add_func, 0); - LLVMValueRef b = LLVMGetParam(add_func, 1); - LLVMValueRef result = LLVMGetParam(add_func, 2); - LLVMSetValueName2(a, "a", 1); - LLVMSetValueName2(b, "b", 1); - LLVMSetValueName2(result, "result", 6); + LLVMValueRef a = LLVMGetParam(add_func, 0); + LLVMValueRef b = LLVMGetParam(add_func, 1); + LLVMValueRef result = LLVMGetParam(add_func, 2); + LLVMSetValueName2(a, "a", 1); + LLVMSetValueName2(b, "b", 1); + LLVMSetValueName2(result, "result", 6); - LLVMBasicBlockRef add_entry = LLVMAppendBasicBlockInContext(ctx, add_func, "entry"); - LLVMPositionBuilderAtEnd(builder, add_entry); + LLVMBasicBlockRef add_entry = + LLVMAppendBasicBlockInContext(ctx, add_func, "entry"); + LLVMPositionBuilderAtEnd(builder, add_entry); - // Load a->x and a->y - LLVMValueRef a_x_ptr = LLVMBuildStructGEP2(builder, point_ty, a, 0, "a_x_ptr"); - LLVMValueRef a_y_ptr = LLVMBuildStructGEP2(builder, point_ty, a, 1, "a_y_ptr"); - LLVMValueRef a_x = LLVMBuildLoad2(builder, i32, a_x_ptr, "a_x"); - LLVMValueRef a_y = LLVMBuildLoad2(builder, i32, a_y_ptr, "a_y"); + // Load a->x and a->y + LLVMValueRef a_x_ptr = + LLVMBuildStructGEP2(builder, point_ty, a, 0, "a_x_ptr"); + LLVMValueRef a_y_ptr = + LLVMBuildStructGEP2(builder, point_ty, a, 1, "a_y_ptr"); + LLVMValueRef a_x = LLVMBuildLoad2(builder, i32, a_x_ptr, "a_x"); + LLVMValueRef a_y = LLVMBuildLoad2(builder, i32, a_y_ptr, "a_y"); - // Load b->x and b->y - LLVMValueRef b_x_ptr = LLVMBuildStructGEP2(builder, point_ty, b, 0, "b_x_ptr"); - LLVMValueRef b_y_ptr = LLVMBuildStructGEP2(builder, point_ty, b, 1, "b_y_ptr"); - LLVMValueRef b_x = LLVMBuildLoad2(builder, i32, b_x_ptr, "b_x"); - LLVMValueRef b_y = LLVMBuildLoad2(builder, i32, b_y_ptr, "b_y"); + // Load b->x and b->y + LLVMValueRef b_x_ptr = + LLVMBuildStructGEP2(builder, point_ty, b, 0, "b_x_ptr"); + LLVMValueRef b_y_ptr = + LLVMBuildStructGEP2(builder, point_ty, b, 1, "b_y_ptr"); + LLVMValueRef b_x = LLVMBuildLoad2(builder, i32, b_x_ptr, "b_x"); + LLVMValueRef b_y = LLVMBuildLoad2(builder, i32, b_y_ptr, "b_y"); - // Compute sum - LLVMValueRef sum_x = LLVMBuildAdd(builder, a_x, b_x, "sum_x"); - LLVMValueRef sum_y = LLVMBuildAdd(builder, a_y, b_y, "sum_y"); + // Compute sum + LLVMValueRef sum_x = LLVMBuildAdd(builder, a_x, b_x, "sum_x"); + LLVMValueRef sum_y = LLVMBuildAdd(builder, a_y, b_y, "sum_y"); - // Store to result - LLVMValueRef result_x_ptr = LLVMBuildStructGEP2(builder, point_ty, result, 0, "result_x_ptr"); - LLVMValueRef result_y_ptr = LLVMBuildStructGEP2(builder, point_ty, result, 1, "result_y_ptr"); - LLVMBuildStore(builder, sum_x, result_x_ptr); - LLVMBuildStore(builder, sum_y, result_y_ptr); + // Store to result + LLVMValueRef result_x_ptr = + LLVMBuildStructGEP2(builder, point_ty, result, 0, "result_x_ptr"); + LLVMValueRef result_y_ptr = + LLVMBuildStructGEP2(builder, point_ty, result, 1, "result_y_ptr"); + LLVMBuildStore(builder, sum_x, result_x_ptr); + LLVMBuildStore(builder, sum_y, result_y_ptr); - LLVMBuildRetVoid(builder); + LLVMBuildRetVoid(builder); - // ========================================== - // Function: i32 point_manhattan_distance(Point* p) - // Returns |x| + |y| (simplified: just x + y for demo) - // ========================================== - LLVMTypeRef dist_params[] = {ptr}; - LLVMTypeRef dist_ty = LLVMFunctionType(i32, dist_params, 1, 0); - LLVMValueRef dist_func = LLVMAddFunction(mod, "point_manhattan", dist_ty); + // ========================================== + // Function: i32 point_manhattan_distance(Point* p) + // Returns |x| + |y| (simplified: just x + y for demo) + // ========================================== + LLVMTypeRef dist_params[] = {ptr}; + LLVMTypeRef dist_ty = LLVMFunctionType(i32, dist_params, 1, 0); + LLVMValueRef dist_func = LLVMAddFunction(mod, "point_manhattan", dist_ty); - LLVMValueRef dist_p = LLVMGetParam(dist_func, 0); - LLVMSetValueName2(dist_p, "p", 1); + LLVMValueRef dist_p = LLVMGetParam(dist_func, 0); + LLVMSetValueName2(dist_p, "p", 1); - LLVMBasicBlockRef dist_entry = LLVMAppendBasicBlockInContext(ctx, dist_func, "entry"); - LLVMPositionBuilderAtEnd(builder, dist_entry); + LLVMBasicBlockRef dist_entry = + LLVMAppendBasicBlockInContext(ctx, dist_func, "entry"); + LLVMPositionBuilderAtEnd(builder, dist_entry); - LLVMValueRef px_ptr = LLVMBuildStructGEP2(builder, point_ty, dist_p, 0, "px_ptr"); - LLVMValueRef py_ptr = LLVMBuildStructGEP2(builder, point_ty, dist_p, 1, "py_ptr"); - LLVMValueRef px = LLVMBuildLoad2(builder, i32, px_ptr, "px"); - LLVMValueRef py = LLVMBuildLoad2(builder, i32, py_ptr, "py"); - LLVMValueRef dist = LLVMBuildAdd(builder, px, py, "dist"); - LLVMBuildRet(builder, dist); + LLVMValueRef px_ptr = + LLVMBuildStructGEP2(builder, point_ty, dist_p, 0, "px_ptr"); + LLVMValueRef py_ptr = + LLVMBuildStructGEP2(builder, point_ty, dist_p, 1, "py_ptr"); + LLVMValueRef px = LLVMBuildLoad2(builder, i32, px_ptr, "px"); + LLVMValueRef py = LLVMBuildLoad2(builder, i32, py_ptr, "py"); + LLVMValueRef dist = LLVMBuildAdd(builder, px, py, "dist"); + LLVMBuildRet(builder, dist); - // ========================================== - // Function: i32 test_points() - // Creates two points, adds them, returns manhattan distance - // ========================================== - LLVMTypeRef test_ty = LLVMFunctionType(i32, nullptr, 0, 0); - LLVMValueRef test_func = LLVMAddFunction(mod, "test_points", test_ty); + // ========================================== + // Function: i32 test_points() + // Creates two points, adds them, returns manhattan distance + // ========================================== + LLVMTypeRef test_ty = LLVMFunctionType(i32, nullptr, 0, 0); + LLVMValueRef test_func = LLVMAddFunction(mod, "test_points", test_ty); - LLVMBasicBlockRef test_entry = LLVMAppendBasicBlockInContext(ctx, test_func, "entry"); - LLVMPositionBuilderAtEnd(builder, test_entry); + LLVMBasicBlockRef test_entry = + LLVMAppendBasicBlockInContext(ctx, test_func, "entry"); + LLVMPositionBuilderAtEnd(builder, test_entry); - // Allocate three Points - LLVMValueRef p1 = LLVMBuildAlloca(builder, point_ty, "p1"); - LLVMValueRef p2 = LLVMBuildAlloca(builder, point_ty, "p2"); - LLVMValueRef p3 = LLVMBuildAlloca(builder, point_ty, "p3"); + // Allocate three Points + LLVMValueRef p1 = LLVMBuildAlloca(builder, point_ty, "p1"); + LLVMValueRef p2 = LLVMBuildAlloca(builder, point_ty, "p2"); + LLVMValueRef p3 = LLVMBuildAlloca(builder, point_ty, "p3"); - // Initialize p1 = (3, 4) - LLVMValueRef init_args1[] = {p1, LLVMConstInt(i32, 3, 0), LLVMConstInt(i32, 4, 0)}; - LLVMBuildCall2(builder, init_ty, init_func, init_args1, 3, ""); + // Initialize p1 = (3, 4) + LLVMValueRef init_args1[] = {p1, LLVMConstInt(i32, 3, 0), + LLVMConstInt(i32, 4, 0)}; + LLVMBuildCall2(builder, init_ty, init_func, init_args1, 3, ""); - // Initialize p2 = (1, 2) - LLVMValueRef init_args2[] = {p2, LLVMConstInt(i32, 1, 0), LLVMConstInt(i32, 2, 0)}; - LLVMBuildCall2(builder, init_ty, init_func, init_args2, 3, ""); + // Initialize p2 = (1, 2) + LLVMValueRef init_args2[] = {p2, LLVMConstInt(i32, 1, 0), + LLVMConstInt(i32, 2, 0)}; + LLVMBuildCall2(builder, init_ty, init_func, init_args2, 3, ""); - // Add p1 + p2 -> p3 - LLVMValueRef add_args[] = {p1, p2, p3}; - LLVMBuildCall2(builder, add_ty, add_func, add_args, 3, ""); + // Add p1 + p2 -> p3 + LLVMValueRef add_args[] = {p1, p2, p3}; + LLVMBuildCall2(builder, add_ty, add_func, add_args, 3, ""); - // Get manhattan distance of p3 - LLVMValueRef dist_args[] = {p3}; - LLVMValueRef final_dist = LLVMBuildCall2(builder, dist_ty, dist_func, dist_args, 1, "final_dist"); + // Get manhattan distance of p3 + LLVMValueRef dist_args[] = {p3}; + LLVMValueRef final_dist = + LLVMBuildCall2(builder, dist_ty, dist_func, dist_args, 1, "final_dist"); - LLVMBuildRet(builder, final_dist); + LLVMBuildRet(builder, final_dist); - // ========================================== - // Global constant Point - // ========================================== - LLVMValueRef origin_vals[] = {LLVMConstInt(i32, 0, 0), LLVMConstInt(i32, 0, 0)}; - LLVMValueRef origin_const = LLVMConstNamedStruct(point_ty, origin_vals, 2); - LLVMValueRef origin_global = LLVMAddGlobal(mod, point_ty, "origin"); - LLVMSetInitializer(origin_global, origin_const); - LLVMSetGlobalConstant(origin_global, 1); + // ========================================== + // Global constant Point + // ========================================== + LLVMValueRef origin_vals[] = {LLVMConstInt(i32, 0, 0), + LLVMConstInt(i32, 0, 0)}; + LLVMValueRef origin_const = LLVMConstNamedStruct(point_ty, origin_vals, 2); + LLVMValueRef origin_global = LLVMAddGlobal(mod, point_ty, "origin"); + LLVMSetInitializer(origin_global, origin_const); + LLVMSetGlobalConstant(origin_global, 1); - LLVMDisposeBuilder(builder); + LLVMDisposeBuilder(builder); - // Verify module - char *error = nullptr; - if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { - fprintf(stderr, "; Verification failed: %s\n", error); - LLVMDisposeMessage(error); - LLVMDisposeModule(mod); - LLVMContextDispose(ctx); - return 1; - } + // Verify module + char *error = nullptr; + if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { + fprintf(stderr, "; Verification failed: %s\n", error); LLVMDisposeMessage(error); - - // Print diagnostic comments - printf("; Test: test_struct\n"); - printf("; Integration test: Point struct manipulation\n"); - printf(";\n"); - printf("; Struct definition:\n"); - printf("; %%Point = type { i32, i32 } ; x, y fields\n"); - printf(";\n"); - printf("; Functions:\n"); - printf("; point_init(Point*, i32, i32) -> void\n"); - printf("; point_add(Point*, Point*, Point*) -> void\n"); - printf("; point_manhattan(Point*) -> i32\n"); - printf("; test_points() -> i32\n"); - printf(";\n"); - printf("; test_points creates:\n"); - printf("; p1 = (3, 4)\n"); - printf("; p2 = (1, 2)\n"); - printf("; p3 = p1 + p2 = (4, 6)\n"); - printf("; returns manhattan(p3) = 4 + 6 = 10\n"); - printf(";\n"); - printf("; Struct type info:\n"); - printf("; name: %s\n", LLVMGetStructName(point_ty)); - printf("; num elements: %u\n", LLVMCountStructElementTypes(point_ty)); - printf("; is packed: %s\n", LLVMIsPackedStruct(point_ty) ? "yes" : "no"); - printf("; is opaque: %s\n", LLVMIsOpaqueStruct(point_ty) ? "yes" : "no"); - printf("\n"); - - // Print module IR - char *ir = LLVMPrintModuleToString(mod); - printf("%s", ir); - LLVMDisposeMessage(ir); - - // Cleanup LLVMDisposeModule(mod); LLVMContextDispose(ctx); + return 1; + } + LLVMDisposeMessage(error); - return 0; + // Print diagnostic comments + printf("; Test: test_struct\n"); + printf("; Integration test: Point struct manipulation\n"); + printf(";\n"); + printf("; Struct definition:\n"); + printf("; %%Point = type { i32, i32 } ; x, y fields\n"); + printf(";\n"); + printf("; Functions:\n"); + printf("; point_init(Point*, i32, i32) -> void\n"); + printf("; point_add(Point*, Point*, Point*) -> void\n"); + printf("; point_manhattan(Point*) -> i32\n"); + printf("; test_points() -> i32\n"); + printf(";\n"); + printf("; test_points creates:\n"); + printf("; p1 = (3, 4)\n"); + printf("; p2 = (1, 2)\n"); + printf("; p3 = p1 + p2 = (4, 6)\n"); + printf("; returns manhattan(p3) = 4 + 6 = 10\n"); + printf(";\n"); + printf("; Struct type info:\n"); + printf("; name: %s\n", LLVMGetStructName(point_ty)); + printf("; num elements: %u\n", LLVMCountStructElementTypes(point_ty)); + printf("; is packed: %s\n", LLVMIsPackedStruct(point_ty) ? "yes" : "no"); + printf("; is opaque: %s\n", LLVMIsOpaqueStruct(point_ty) ? "yes" : "no"); + printf("\n"); + + // Print module IR + char *ir = LLVMPrintModuleToString(mod); + printf("%s", ir); + LLVMDisposeMessage(ir); + + // Cleanup + LLVMDisposeModule(mod); + LLVMContextDispose(ctx); + + return 0; } diff --git a/tests/test_types.cpp b/tests/test_types.cpp index a5bd704..e353669 100644 --- a/tests/test_types.cpp +++ b/tests/test_types.cpp @@ -4,9 +4,11 @@ * * LLVM-C APIs covered: * - LLVMInt1TypeInContext(), LLVMInt8TypeInContext(), LLVMInt16TypeInContext() - * - LLVMInt32TypeInContext(), LLVMInt64TypeInContext(), LLVMInt128TypeInContext() + * - LLVMInt32TypeInContext(), LLVMInt64TypeInContext(), + * LLVMInt128TypeInContext() * - LLVMIntTypeInContext() - * - LLVMHalfTypeInContext(), LLVMFloatTypeInContext(), LLVMDoubleTypeInContext() + * - LLVMHalfTypeInContext(), LLVMFloatTypeInContext(), + * LLVMDoubleTypeInContext() * - LLVMVoidTypeInContext() * - LLVMPointerTypeInContext() * - LLVMArrayType2() @@ -18,174 +20,218 @@ * - LLVMTypeIsSized() */ -#include -#include #include +#include +#include -const char* type_kind_name(LLVMTypeKind kind) { - switch (kind) { - case LLVMVoidTypeKind: return "void"; - case LLVMHalfTypeKind: return "half"; - case LLVMFloatTypeKind: return "float"; - case LLVMDoubleTypeKind: return "double"; - case LLVMX86_FP80TypeKind: return "x86_fp80"; - case LLVMFP128TypeKind: return "fp128"; - case LLVMPPC_FP128TypeKind: return "ppc_fp128"; - case LLVMLabelTypeKind: return "label"; - case LLVMIntegerTypeKind: return "integer"; - case LLVMFunctionTypeKind: return "function"; - case LLVMStructTypeKind: return "struct"; - case LLVMArrayTypeKind: return "array"; - case LLVMPointerTypeKind: return "pointer"; - case LLVMVectorTypeKind: return "vector"; - case LLVMMetadataTypeKind: return "metadata"; - case LLVMTokenTypeKind: return "token"; - case LLVMScalableVectorTypeKind: return "scalable_vector"; - case LLVMBFloatTypeKind: return "bfloat"; - case LLVMX86_AMXTypeKind: return "x86_amx"; - case LLVMTargetExtTypeKind: return "target_ext"; - default: return "unknown"; - } +const char *type_kind_name(LLVMTypeKind kind) { + switch (kind) { + case LLVMVoidTypeKind: + return "void"; + case LLVMHalfTypeKind: + return "half"; + case LLVMFloatTypeKind: + return "float"; + case LLVMDoubleTypeKind: + return "double"; + case LLVMX86_FP80TypeKind: + return "x86_fp80"; + case LLVMFP128TypeKind: + return "fp128"; + case LLVMPPC_FP128TypeKind: + return "ppc_fp128"; + case LLVMLabelTypeKind: + return "label"; + case LLVMIntegerTypeKind: + return "integer"; + case LLVMFunctionTypeKind: + return "function"; + case LLVMStructTypeKind: + return "struct"; + case LLVMArrayTypeKind: + return "array"; + case LLVMPointerTypeKind: + return "pointer"; + case LLVMVectorTypeKind: + return "vector"; + case LLVMMetadataTypeKind: + return "metadata"; + case LLVMTokenTypeKind: + return "token"; + case LLVMScalableVectorTypeKind: + return "scalable_vector"; + case LLVMBFloatTypeKind: + return "bfloat"; + case LLVMX86_AMXTypeKind: + return "x86_amx"; + case LLVMTargetExtTypeKind: + return "target_ext"; + default: + return "unknown"; + } } int main() { - LLVMContextRef ctx = LLVMContextCreate(); - LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_types", ctx); + LLVMContextRef ctx = LLVMContextCreate(); + LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_types", ctx); - // Integer types - LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx); - LLVMTypeRef i8 = LLVMInt8TypeInContext(ctx); - LLVMTypeRef i16 = LLVMInt16TypeInContext(ctx); - LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); - LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx); - LLVMTypeRef i128 = LLVMInt128TypeInContext(ctx); - LLVMTypeRef i256 = LLVMIntTypeInContext(ctx, 256); + // Integer types + LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx); + LLVMTypeRef i8 = LLVMInt8TypeInContext(ctx); + LLVMTypeRef i16 = LLVMInt16TypeInContext(ctx); + LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx); + LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx); + LLVMTypeRef i128 = LLVMInt128TypeInContext(ctx); + LLVMTypeRef i256 = LLVMIntTypeInContext(ctx, 256); - // Floating point types - LLVMTypeRef f16 = LLVMHalfTypeInContext(ctx); - LLVMTypeRef bf16 = LLVMBFloatTypeInContext(ctx); - LLVMTypeRef f32 = LLVMFloatTypeInContext(ctx); - LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx); + // Floating point types + LLVMTypeRef f16 = LLVMHalfTypeInContext(ctx); + LLVMTypeRef bf16 = LLVMBFloatTypeInContext(ctx); + LLVMTypeRef f32 = LLVMFloatTypeInContext(ctx); + LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx); - // Void type - LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx); + // Void type + LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx); - // Pointer type (opaque pointer) - LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0); + // Pointer type (opaque pointer) + LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0); - // Array type - LLVMTypeRef arr_i32_10 = LLVMArrayType2(i32, 10); + // Array type + LLVMTypeRef arr_i32_10 = LLVMArrayType2(i32, 10); - // Vector type - LLVMTypeRef vec_i32_4 = LLVMVectorType(i32, 4); + // Vector type + LLVMTypeRef vec_i32_4 = LLVMVectorType(i32, 4); - // Function type: i32(i32, i32) - LLVMTypeRef func_params[] = {i32, i32}; - LLVMTypeRef func_ty = LLVMFunctionType(i32, func_params, 2, 0); + // Function type: i32(i32, i32) + LLVMTypeRef func_params[] = {i32, i32}; + LLVMTypeRef func_ty = LLVMFunctionType(i32, func_params, 2, 0); - // Function type with varargs: i32(i32, ...) - LLVMTypeRef vararg_params[] = {i32}; - LLVMTypeRef vararg_func_ty = LLVMFunctionType(i32, vararg_params, 1, 1); + // Function type with varargs: i32(i32, ...) + LLVMTypeRef vararg_params[] = {i32}; + LLVMTypeRef vararg_func_ty = LLVMFunctionType(i32, vararg_params, 1, 1); - // Anonymous struct type: {i32, f64} - LLVMTypeRef struct_elems[] = {i32, f64}; - LLVMTypeRef anon_struct = LLVMStructTypeInContext(ctx, struct_elems, 2, 0); + // Anonymous struct type: {i32, f64} + LLVMTypeRef struct_elems[] = {i32, f64}; + LLVMTypeRef anon_struct = LLVMStructTypeInContext(ctx, struct_elems, 2, 0); - // Packed anonymous struct type: <{i8, i32}> - LLVMTypeRef packed_elems[] = {i8, i32}; - LLVMTypeRef packed_struct = LLVMStructTypeInContext(ctx, packed_elems, 2, 1); + // Packed anonymous struct type: <{i8, i32}> + LLVMTypeRef packed_elems[] = {i8, i32}; + LLVMTypeRef packed_struct = LLVMStructTypeInContext(ctx, packed_elems, 2, 1); - // Named struct type - LLVMTypeRef named_struct = LLVMStructCreateNamed(ctx, "MyStruct"); - LLVMTypeRef named_elems[] = {i32, ptr, f64}; - LLVMStructSetBody(named_struct, named_elems, 3, 0); + // Named struct type + LLVMTypeRef named_struct = LLVMStructCreateNamed(ctx, "MyStruct"); + LLVMTypeRef named_elems[] = {i32, ptr, f64}; + LLVMStructSetBody(named_struct, named_elems, 3, 0); - // Opaque struct (no body set) - LLVMTypeRef opaque_struct = LLVMStructCreateNamed(ctx, "OpaqueStruct"); + // Opaque struct (no body set) + LLVMTypeRef opaque_struct = LLVMStructCreateNamed(ctx, "OpaqueStruct"); - // Add global variables to make types visible in output - LLVMAddGlobal(mod, i32, "global_i32"); - LLVMAddGlobal(mod, arr_i32_10, "global_arr"); - LLVMAddGlobal(mod, vec_i32_4, "global_vec"); - LLVMAddGlobal(mod, anon_struct, "global_anon_struct"); - LLVMAddGlobal(mod, packed_struct, "global_packed_struct"); - LLVMAddGlobal(mod, named_struct, "global_named_struct"); + // Add global variables to make types visible in output + LLVMAddGlobal(mod, i32, "global_i32"); + LLVMAddGlobal(mod, arr_i32_10, "global_arr"); + LLVMAddGlobal(mod, vec_i32_4, "global_vec"); + LLVMAddGlobal(mod, anon_struct, "global_anon_struct"); + LLVMAddGlobal(mod, packed_struct, "global_packed_struct"); + LLVMAddGlobal(mod, named_struct, "global_named_struct"); - // Add a function declaration to show function type - LLVMAddFunction(mod, "example_func", func_ty); - LLVMAddFunction(mod, "example_vararg_func", vararg_func_ty); + // Add a function declaration to show function type + LLVMAddFunction(mod, "example_func", func_ty); + LLVMAddFunction(mod, "example_vararg_func", vararg_func_ty); - // Verify module - char *error = nullptr; - if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { - fprintf(stderr, "; Verification failed: %s\n", error); - LLVMDisposeMessage(error); - LLVMDisposeModule(mod); - LLVMContextDispose(ctx); - return 1; - } + // Verify module + char *error = nullptr; + if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) { + fprintf(stderr, "; Verification failed: %s\n", error); LLVMDisposeMessage(error); - - // Print diagnostic comments - printf("; Test: test_types\n"); - printf(";\n"); - printf("; Integer types:\n"); - printf("; i1 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i1), type_kind_name(LLVMGetTypeKind(i1))); - printf("; i8 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i8), type_kind_name(LLVMGetTypeKind(i8))); - printf("; i16 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i16), type_kind_name(LLVMGetTypeKind(i16))); - printf("; i32 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i32), type_kind_name(LLVMGetTypeKind(i32))); - printf("; i64 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i64), type_kind_name(LLVMGetTypeKind(i64))); - printf("; i128 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i128), type_kind_name(LLVMGetTypeKind(i128))); - printf("; i256 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i256), type_kind_name(LLVMGetTypeKind(i256))); - printf(";\n"); - printf("; Floating point types:\n"); - printf("; half kind: %s\n", type_kind_name(LLVMGetTypeKind(f16))); - printf("; bfloat kind: %s\n", type_kind_name(LLVMGetTypeKind(bf16))); - printf("; float kind: %s\n", type_kind_name(LLVMGetTypeKind(f32))); - printf("; double kind: %s\n", type_kind_name(LLVMGetTypeKind(f64))); - printf(";\n"); - printf("; Other types:\n"); - printf("; void kind: %s, sized: %s\n", type_kind_name(LLVMGetTypeKind(void_ty)), LLVMTypeIsSized(void_ty) ? "yes" : "no"); - printf("; pointer kind: %s, sized: %s\n", type_kind_name(LLVMGetTypeKind(ptr)), LLVMTypeIsSized(ptr) ? "yes" : "no"); - printf("; array kind: %s, sized: %s\n", type_kind_name(LLVMGetTypeKind(arr_i32_10)), LLVMTypeIsSized(arr_i32_10) ? "yes" : "no"); - printf("; vector kind: %s, sized: %s\n", type_kind_name(LLVMGetTypeKind(vec_i32_4)), LLVMTypeIsSized(vec_i32_4) ? "yes" : "no"); - printf("; function kind: %s, sized: %s\n", type_kind_name(LLVMGetTypeKind(func_ty)), LLVMTypeIsSized(func_ty) ? "yes" : "no"); - printf(";\n"); - printf("; Struct types:\n"); - printf("; anon_struct kind: %s, packed: %s\n", type_kind_name(LLVMGetTypeKind(anon_struct)), LLVMIsPackedStruct(anon_struct) ? "yes" : "no"); - printf("; packed_struct kind: %s, packed: %s\n", type_kind_name(LLVMGetTypeKind(packed_struct)), LLVMIsPackedStruct(packed_struct) ? "yes" : "no"); - - const char *named_struct_name = LLVMGetStructName(named_struct); - printf("; named_struct name: %s, opaque: %s\n", named_struct_name, LLVMIsOpaqueStruct(named_struct) ? "yes" : "no"); - - const char *opaque_struct_name = LLVMGetStructName(opaque_struct); - printf("; opaque_struct name: %s, opaque: %s\n", opaque_struct_name, LLVMIsOpaqueStruct(opaque_struct) ? "yes" : "no"); - - // Print type strings - printf(";\n"); - printf("; Type strings:\n"); - char *i32_str = LLVMPrintTypeToString(i32); - printf("; i32: %s\n", i32_str); - LLVMDisposeMessage(i32_str); - - char *arr_str = LLVMPrintTypeToString(arr_i32_10); - printf("; [10 x i32]: %s\n", arr_str); - LLVMDisposeMessage(arr_str); - - char *func_str = LLVMPrintTypeToString(func_ty); - printf("; func type: %s\n", func_str); - LLVMDisposeMessage(func_str); - - printf("\n"); - - // Print module IR - char *ir = LLVMPrintModuleToString(mod); - printf("%s", ir); - LLVMDisposeMessage(ir); - - // Cleanup LLVMDisposeModule(mod); LLVMContextDispose(ctx); + return 1; + } + LLVMDisposeMessage(error); - return 0; + // Print diagnostic comments + printf("; Test: test_types\n"); + printf(";\n"); + printf("; Integer types:\n"); + printf("; i1 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i1), + type_kind_name(LLVMGetTypeKind(i1))); + printf("; i8 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i8), + type_kind_name(LLVMGetTypeKind(i8))); + printf("; i16 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i16), + type_kind_name(LLVMGetTypeKind(i16))); + printf("; i32 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i32), + type_kind_name(LLVMGetTypeKind(i32))); + printf("; i64 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i64), + type_kind_name(LLVMGetTypeKind(i64))); + printf("; i128 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i128), + type_kind_name(LLVMGetTypeKind(i128))); + printf("; i256 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i256), + type_kind_name(LLVMGetTypeKind(i256))); + printf(";\n"); + printf("; Floating point types:\n"); + printf("; half kind: %s\n", type_kind_name(LLVMGetTypeKind(f16))); + printf("; bfloat kind: %s\n", type_kind_name(LLVMGetTypeKind(bf16))); + printf("; float kind: %s\n", type_kind_name(LLVMGetTypeKind(f32))); + printf("; double kind: %s\n", type_kind_name(LLVMGetTypeKind(f64))); + printf(";\n"); + printf("; Other types:\n"); + printf("; void kind: %s, sized: %s\n", + type_kind_name(LLVMGetTypeKind(void_ty)), + LLVMTypeIsSized(void_ty) ? "yes" : "no"); + printf("; pointer kind: %s, sized: %s\n", + type_kind_name(LLVMGetTypeKind(ptr)), + LLVMTypeIsSized(ptr) ? "yes" : "no"); + printf("; array kind: %s, sized: %s\n", + type_kind_name(LLVMGetTypeKind(arr_i32_10)), + LLVMTypeIsSized(arr_i32_10) ? "yes" : "no"); + printf("; vector kind: %s, sized: %s\n", + type_kind_name(LLVMGetTypeKind(vec_i32_4)), + LLVMTypeIsSized(vec_i32_4) ? "yes" : "no"); + printf("; function kind: %s, sized: %s\n", + type_kind_name(LLVMGetTypeKind(func_ty)), + LLVMTypeIsSized(func_ty) ? "yes" : "no"); + printf(";\n"); + printf("; Struct types:\n"); + printf("; anon_struct kind: %s, packed: %s\n", + type_kind_name(LLVMGetTypeKind(anon_struct)), + LLVMIsPackedStruct(anon_struct) ? "yes" : "no"); + printf("; packed_struct kind: %s, packed: %s\n", + type_kind_name(LLVMGetTypeKind(packed_struct)), + LLVMIsPackedStruct(packed_struct) ? "yes" : "no"); + + const char *named_struct_name = LLVMGetStructName(named_struct); + printf("; named_struct name: %s, opaque: %s\n", named_struct_name, + LLVMIsOpaqueStruct(named_struct) ? "yes" : "no"); + + const char *opaque_struct_name = LLVMGetStructName(opaque_struct); + printf("; opaque_struct name: %s, opaque: %s\n", opaque_struct_name, + LLVMIsOpaqueStruct(opaque_struct) ? "yes" : "no"); + + // Print type strings + printf(";\n"); + printf("; Type strings:\n"); + char *i32_str = LLVMPrintTypeToString(i32); + printf("; i32: %s\n", i32_str); + LLVMDisposeMessage(i32_str); + + char *arr_str = LLVMPrintTypeToString(arr_i32_10); + printf("; [10 x i32]: %s\n", arr_str); + LLVMDisposeMessage(arr_str); + + char *func_str = LLVMPrintTypeToString(func_ty); + printf("; func type: %s\n", func_str); + LLVMDisposeMessage(func_str); + + printf("\n"); + + // Print module IR + char *ir = LLVMPrintModuleToString(mod); + printf("%s", ir); + LLVMDisposeMessage(ir); + + // Cleanup + LLVMDisposeModule(mod); + LLVMContextDispose(ctx); + + return 0; }