1/*===-- module.c - tool for testing libLLVM and llvm-c API ----------------===*\
2|*                                                                            *|
3|*                     The LLVM Compiler Infrastructure                       *|
4|*                                                                            *|
5|* This file is distributed under the University of Illinois Open Source      *|
6|* License. See LICENSE.TXT for details.                                      *|
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 "llvm-c/Core.h"
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21
22static void diagnosticHandler(LLVMDiagnosticInfoRef DI, void *C) {
23  char *CErr = LLVMGetDiagInfoDescription(DI);
24  fprintf(stderr, "Error with new bitcode parser: %s\n", CErr);
25  LLVMDisposeMessage(CErr);
26  exit(1);
27}
28
29static LLVMModuleRef load_module(bool Lazy, bool New) {
30  LLVMMemoryBufferRef MB;
31  LLVMModuleRef M;
32  char *msg = NULL;
33
34  if (LLVMCreateMemoryBufferWithSTDIN(&MB, &msg)) {
35    fprintf(stderr, "Error reading file: %s\n", msg);
36    exit(1);
37  }
38
39  LLVMBool Ret;
40  if (New) {
41    LLVMContextRef C = LLVMGetGlobalContext();
42    LLVMContextSetDiagnosticHandler(C, diagnosticHandler, NULL);
43    if (Lazy)
44      Ret = LLVMGetBitcodeModule2(MB, &M);
45    else
46      Ret = LLVMParseBitcode2(MB, &M);
47  } else {
48    if (Lazy)
49      Ret = LLVMGetBitcodeModule(MB, &M, &msg);
50    else
51      Ret = LLVMParseBitcode(MB, &M, &msg);
52  }
53
54  if (Ret) {
55    fprintf(stderr, "Error parsing bitcode: %s\n", msg);
56    LLVMDisposeMemoryBuffer(MB);
57    exit(1);
58  }
59
60  if (!Lazy)
61    LLVMDisposeMemoryBuffer(MB);
62
63  return M;
64}
65
66int module_dump(bool Lazy, bool New) {
67  LLVMModuleRef M = load_module(Lazy, New);
68
69  char *irstr = LLVMPrintModuleToString(M);
70  puts(irstr);
71  LLVMDisposeMessage(irstr);
72
73  LLVMDisposeModule(M);
74
75  return 0;
76}
77
78int module_list_functions(void) {
79  LLVMModuleRef M = load_module(false, false);
80  LLVMValueRef f;
81
82  f = LLVMGetFirstFunction(M);
83  while (f) {
84    if (LLVMIsDeclaration(f)) {
85      printf("FunctionDeclaration: %s\n", LLVMGetValueName(f));
86    } else {
87      LLVMBasicBlockRef bb;
88      LLVMValueRef isn;
89      unsigned nisn = 0;
90      unsigned nbb = 0;
91
92      printf("FunctionDefinition: %s [#bb=%u]\n", LLVMGetValueName(f),
93             LLVMCountBasicBlocks(f));
94
95      for (bb = LLVMGetFirstBasicBlock(f); bb;
96           bb = LLVMGetNextBasicBlock(bb)) {
97        nbb++;
98        for (isn = LLVMGetFirstInstruction(bb); isn;
99             isn = LLVMGetNextInstruction(isn)) {
100          nisn++;
101          if (LLVMIsACallInst(isn)) {
102            LLVMValueRef callee =
103                LLVMGetOperand(isn, LLVMGetNumOperands(isn) - 1);
104            printf(" calls: %s\n", LLVMGetValueName(callee));
105          }
106        }
107      }
108      printf(" #isn: %u\n", nisn);
109      printf(" #bb: %u\n\n", nbb);
110    }
111    f = LLVMGetNextFunction(f);
112  }
113
114  LLVMDisposeModule(M);
115
116  return 0;
117}
118
119int module_list_globals(void) {
120  LLVMModuleRef M = load_module(false, false);
121  LLVMValueRef g;
122
123  g = LLVMGetFirstGlobal(M);
124  while (g) {
125    LLVMTypeRef T = LLVMTypeOf(g);
126    char *s = LLVMPrintTypeToString(T);
127
128    printf("Global%s: %s %s\n",
129           LLVMIsDeclaration(g) ? "Declaration" : "Definition",
130           LLVMGetValueName(g), s);
131
132    LLVMDisposeMessage(s);
133
134    g = LLVMGetNextGlobal(g);
135  }
136
137  LLVMDisposeModule(M);
138
139  return 0;
140}
141