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