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