1/*===-- module.c - tool for testing libLLVM and llvm-c API ----------------===*\ 2|* *| 3|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| 4|* Exceptions. *| 5|* See https://llvm.org/LICENSE.txt for license information. *| 6|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| 7|* *| 8|*===----------------------------------------------------------------------===*| 9|* *| 10|* This file implements the --module-dump, --module-list-functions and *| 11|* --module-list-globals commands in llvm-c-test. *| 12|* *| 13\*===----------------------------------------------------------------------===*/ 14 15#include "llvm-c-test.h" 16#include "llvm-c/BitReader.h" 17#include <stdio.h> 18#include <stdlib.h> 19 20static void diagnosticHandler(LLVMDiagnosticInfoRef DI, void *C) { 21 char *CErr = LLVMGetDiagInfoDescription(DI); 22 fprintf(stderr, "Error with new bitcode parser: %s\n", CErr); 23 LLVMDisposeMessage(CErr); 24 exit(1); 25} 26 27LLVMModuleRef llvm_load_module(bool Lazy, bool New) { 28 LLVMMemoryBufferRef MB; 29 LLVMModuleRef M; 30 char *msg = NULL; 31 32 if (LLVMCreateMemoryBufferWithSTDIN(&MB, &msg)) { 33 fprintf(stderr, "Error reading file: %s\n", msg); 34 exit(1); 35 } 36 37 LLVMBool Ret; 38 if (New) { 39 LLVMContextRef C = LLVMGetGlobalContext(); 40 LLVMContextSetDiagnosticHandler(C, diagnosticHandler, NULL); 41 if (Lazy) 42 Ret = LLVMGetBitcodeModule2(MB, &M); 43 else 44 Ret = LLVMParseBitcode2(MB, &M); 45 } else { 46 if (Lazy) 47 Ret = LLVMGetBitcodeModule(MB, &M, &msg); 48 else 49 Ret = LLVMParseBitcode(MB, &M, &msg); 50 } 51 52 if (Ret) { 53 fprintf(stderr, "Error parsing bitcode: %s\n", msg); 54 LLVMDisposeMemoryBuffer(MB); 55 exit(1); 56 } 57 58 if (!Lazy) 59 LLVMDisposeMemoryBuffer(MB); 60 61 return M; 62} 63 64int llvm_module_dump(bool Lazy, bool New) { 65 LLVMModuleRef M = llvm_load_module(Lazy, New); 66 67 char *irstr = LLVMPrintModuleToString(M); 68 puts(irstr); 69 LLVMDisposeMessage(irstr); 70 71 LLVMDisposeModule(M); 72 73 return 0; 74} 75 76int llvm_module_list_functions(void) { 77 LLVMModuleRef M = llvm_load_module(false, false); 78 LLVMValueRef f; 79 80 f = LLVMGetFirstFunction(M); 81 while (f) { 82 if (LLVMIsDeclaration(f)) { 83 printf("FunctionDeclaration: %s\n", LLVMGetValueName(f)); 84 } else { 85 LLVMBasicBlockRef bb; 86 LLVMValueRef isn; 87 unsigned nisn = 0; 88 unsigned nbb = 0; 89 90 printf("FunctionDefinition: %s [#bb=%u]\n", LLVMGetValueName(f), 91 LLVMCountBasicBlocks(f)); 92 93 for (bb = LLVMGetFirstBasicBlock(f); bb; 94 bb = LLVMGetNextBasicBlock(bb)) { 95 nbb++; 96 for (isn = LLVMGetFirstInstruction(bb); isn; 97 isn = LLVMGetNextInstruction(isn)) { 98 nisn++; 99 if (LLVMIsACallInst(isn)) { 100 LLVMValueRef callee = 101 LLVMGetOperand(isn, LLVMGetNumOperands(isn) - 1); 102 printf(" calls: %s\n", LLVMGetValueName(callee)); 103 } 104 } 105 } 106 printf(" #isn: %u\n", nisn); 107 printf(" #bb: %u\n\n", nbb); 108 } 109 f = LLVMGetNextFunction(f); 110 } 111 112 LLVMDisposeModule(M); 113 114 return 0; 115} 116 117int llvm_module_list_globals(void) { 118 LLVMModuleRef M = llvm_load_module(false, false); 119 LLVMValueRef g; 120 121 g = LLVMGetFirstGlobal(M); 122 while (g) { 123 LLVMTypeRef T = LLVMTypeOf(g); 124 char *s = LLVMPrintTypeToString(T); 125 126 printf("Global%s: %s %s\n", 127 LLVMIsDeclaration(g) ? "Declaration" : "Definition", 128 LLVMGetValueName(g), s); 129 130 LLVMDisposeMessage(s); 131 132 g = LLVMGetNextGlobal(g); 133 } 134 135 LLVMDisposeModule(M); 136 137 return 0; 138} 139