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