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