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, format: "Error with new bitcode parser: %s\n", CErr);
23 LLVMDisposeMessage(Message: CErr);
24 exit(status: 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(OutMemBuf: &MB, OutMessage: &msg)) {
33 fprintf(stderr, format: "Error reading file: %s\n", msg);
34 exit(status: 1);
35 }
36
37 LLVMBool Ret;
38 if (New) {
39 LLVMContextRef C = LLVMGetGlobalContext();
40 LLVMContextSetDiagnosticHandler(C, Handler: diagnosticHandler, NULL);
41 if (Lazy)
42 Ret = LLVMGetBitcodeModule2(MemBuf: MB, OutM: &M);
43 else
44 Ret = LLVMParseBitcode2(MemBuf: MB, OutModule: &M);
45 } else {
46 if (Lazy)
47 Ret = LLVMGetBitcodeModule(MemBuf: MB, OutM: &M, OutMessage: &msg);
48 else
49 Ret = LLVMParseBitcode(MemBuf: MB, OutModule: &M, OutMessage: &msg);
50 }
51
52 if (Ret) {
53 fprintf(stderr, format: "Error parsing bitcode: %s\n", msg);
54 LLVMDisposeMemoryBuffer(MemBuf: MB);
55 exit(status: 1);
56 }
57
58 if (!Lazy)
59 LLVMDisposeMemoryBuffer(MemBuf: 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(s: irstr);
69 LLVMDisposeMessage(Message: 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(Global: f)) {
83 printf(format: "FunctionDeclaration: %s\n", LLVMGetValueName(Val: f));
84 } else {
85 LLVMBasicBlockRef bb;
86 LLVMValueRef isn;
87 unsigned nisn = 0;
88 unsigned nbb = 0;
89
90 printf(format: "FunctionDefinition: %s [#bb=%u]\n", LLVMGetValueName(Val: f),
91 LLVMCountBasicBlocks(Fn: f));
92
93 for (bb = LLVMGetFirstBasicBlock(Fn: f); bb;
94 bb = LLVMGetNextBasicBlock(BB: bb)) {
95 nbb++;
96 for (isn = LLVMGetFirstInstruction(BB: bb); isn;
97 isn = LLVMGetNextInstruction(Inst: isn)) {
98 nisn++;
99 if (LLVMIsACallInst(Val: isn)) {
100 LLVMValueRef callee =
101 LLVMGetOperand(Val: isn, Index: LLVMGetNumOperands(Val: isn) - 1);
102 printf(format: " calls: %s\n", LLVMGetValueName(Val: callee));
103 }
104 }
105 }
106 printf(format: " #isn: %u\n", nisn);
107 printf(format: " #bb: %u\n\n", nbb);
108 }
109 f = LLVMGetNextFunction(Fn: 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(Val: g);
124 char *s = LLVMPrintTypeToString(Val: T);
125
126 printf(format: "Global%s: %s %s\n",
127 LLVMIsDeclaration(Global: g) ? "Declaration" : "Definition",
128 LLVMGetValueName(Val: g), s);
129
130 LLVMDisposeMessage(Message: s);
131
132 g = LLVMGetNextGlobal(GlobalVar: g);
133 }
134
135 LLVMDisposeModule(M);
136
137 return 0;
138}
139