xref: /llvm-project/llvm/tools/llvm-c-test/module.c (revision eb7d535199d7fc3de763276093b97141a041d3d6)
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 
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 
27 LLVMModuleRef 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     else
43       Ret = LLVMParseBitcodeInContext2(C, MB, &M);
44   } else {
45     if (Lazy)
46       Ret = LLVMGetBitcodeModuleInContext(C, MB, &M, &msg);
47     else
48       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 
63 int 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 
75 int 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 
116 int 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