138 lines · c
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(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 else43 Ret = LLVMParseBitcodeInContext2(C, MB, &M);44 } else {45 if (Lazy)46 Ret = LLVMGetBitcodeModuleInContext(C, MB, &M, &msg);47 else48 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 63int 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 75int 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 116int 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