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 20 static 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 27 LLVMModuleRef llvm_load_module(LLVMContextRef C, 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 LLVMContextSetDiagnosticHandler(C, diagnosticHandler, NULL); 40 if (Lazy) 41 Ret = LLVMGetBitcodeModuleInContext2(C, MB, &M); 42 else 43 Ret = LLVMParseBitcodeInContext2(C, MB, &M); 44 } else { 45 if (Lazy) 46 Ret = LLVMGetBitcodeModuleInContext(C, MB, &M, &msg); 47 else 48 Ret = LLVMParseBitcodeInContext(C, MB, &M, &msg); 49 } 50 51 if (Ret) { 52 fprintf(stderr, "Error parsing bitcode: %s\n", msg); 53 LLVMDisposeMemoryBuffer(MB); 54 exit(1); 55 } 56 57 if (!Lazy) 58 LLVMDisposeMemoryBuffer(MB); 59 60 return M; 61 } 62 63 int llvm_module_dump(bool Lazy, bool New) { 64 LLVMModuleRef M = llvm_load_module(LLVMGetGlobalContext(), Lazy, New); 65 66 char *irstr = LLVMPrintModuleToString(M); 67 puts(irstr); 68 LLVMDisposeMessage(irstr); 69 70 LLVMDisposeModule(M); 71 72 return 0; 73 } 74 75 int llvm_module_list_functions(void) { 76 LLVMModuleRef M = llvm_load_module(LLVMGetGlobalContext(), false, false); 77 LLVMValueRef f; 78 79 f = LLVMGetFirstFunction(M); 80 while (f) { 81 if (LLVMIsDeclaration(f)) { 82 printf("FunctionDeclaration: %s\n", LLVMGetValueName(f)); 83 } else { 84 LLVMBasicBlockRef bb; 85 LLVMValueRef isn; 86 unsigned nisn = 0; 87 unsigned nbb = 0; 88 89 printf("FunctionDefinition: %s [#bb=%u]\n", LLVMGetValueName(f), 90 LLVMCountBasicBlocks(f)); 91 92 for (bb = LLVMGetFirstBasicBlock(f); bb; 93 bb = LLVMGetNextBasicBlock(bb)) { 94 nbb++; 95 for (isn = LLVMGetFirstInstruction(bb); isn; 96 isn = LLVMGetNextInstruction(isn)) { 97 nisn++; 98 if (LLVMIsACallInst(isn)) { 99 LLVMValueRef callee = 100 LLVMGetOperand(isn, LLVMGetNumOperands(isn) - 1); 101 printf(" calls: %s\n", LLVMGetValueName(callee)); 102 } 103 } 104 } 105 printf(" #isn: %u\n", nisn); 106 printf(" #bb: %u\n\n", nbb); 107 } 108 f = LLVMGetNextFunction(f); 109 } 110 111 LLVMDisposeModule(M); 112 113 return 0; 114 } 115 116 int llvm_module_list_globals(void) { 117 LLVMModuleRef M = llvm_load_module(LLVMGetGlobalContext(), false, false); 118 LLVMValueRef g; 119 120 g = LLVMGetFirstGlobal(M); 121 while (g) { 122 LLVMTypeRef T = LLVMTypeOf(g); 123 char *s = LLVMPrintTypeToString(T); 124 125 printf("Global%s: %s %s\n", 126 LLVMIsDeclaration(g) ? "Declaration" : "Definition", 127 LLVMGetValueName(g), s); 128 129 LLVMDisposeMessage(s); 130 131 g = LLVMGetNextGlobal(g); 132 } 133 134 LLVMDisposeModule(M); 135 136 return 0; 137 } 138