aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--test/Bindings/llvm-c/calc.test15
-rw-r--r--test/Bindings/llvm-c/disassemble.test29
-rw-r--r--test/Bindings/llvm-c/functions.ll31
-rw-r--r--test/Bindings/llvm-c/globals.ll7
-rw-r--r--test/Bindings/llvm-c/lit.local.cfg3
-rw-r--r--test/lit.cfg1
-rw-r--r--tools/CMakeLists.txt6
-rw-r--r--tools/Makefile2
-rw-r--r--tools/llvm-c-test/CMakeLists.txt16
-rw-r--r--tools/llvm-c-test/Makefile29
-rw-r--r--tools/llvm-c-test/calc.c143
-rw-r--r--tools/llvm-c-test/disassemble.c85
-rw-r--r--tools/llvm-c-test/helpers.c40
-rw-r--r--tools/llvm-c-test/include-all.c33
-rw-r--r--tools/llvm-c-test/llvm-c-test.h37
-rw-r--r--tools/llvm-c-test/main.c73
-rw-r--r--tools/llvm-c-test/module.c112
-rw-r--r--tools/llvm-c-test/object.c85
-rw-r--r--tools/llvm-c-test/targets.c29
19 files changed, 775 insertions, 1 deletions
diff --git a/test/Bindings/llvm-c/calc.test b/test/Bindings/llvm-c/calc.test
new file mode 100644
index 0000000..36a76e6
--- /dev/null
+++ b/test/Bindings/llvm-c/calc.test
@@ -0,0 +1,15 @@
+; RUN: llvm-c-test --calc <%s | FileCheck %s
+
+; constant folding
+test 100 200 +
+;CHECK: ModuleID = 'test'
+;CHECK: define i64 @test
+;CHECK: {
+;CHECK: ret i64 300
+;CHECK: }
+
+arg1 0 @ 0 @ * 1 @ 1 @ * +
+;CHECK: ModuleID = 'arg1'
+;CHECK: getelementptr
+;CHECK: load
+;CHECK: ret
diff --git a/test/Bindings/llvm-c/disassemble.test b/test/Bindings/llvm-c/disassemble.test
new file mode 100644
index 0000000..201e914
--- /dev/null
+++ b/test/Bindings/llvm-c/disassemble.test
@@ -0,0 +1,29 @@
+; RUN: llvm-c-test --disassemble < %s | FileCheck %s
+
+
+arm-linux-android 44 26 1f e5 0c 10 4b e2 02 20 81 e0
+;CHECK: triple: arm-linux-android
+;CHECK: ldr r2, [pc, #-1604]
+;CHECK: sub r1, r11, #12
+;CHECK: 02 20 81 e0
+;CHECK: add r2, r1, r2
+
+x86_64-linux-unknown 48 83 c4 38 5b 5d 41 5c 41 5d 41 5e 41 5f c3
+;CHECK: triple: x86_64-linux-unknown
+;CHECK: addq $56, %rsp
+;CHECK: popq %rbx
+;CHECK: popq %rbp
+;CHECK: popq %r12
+;CHECK: popq %r13
+;CHECK: popq %r14
+;CHECK: popq %r15
+;CHECK: ret
+
+i686-apple-darwin 0f b7 4c 24 0a e8 29 ce ff ff
+;CHECK: movzwl 10(%esp), %ecx
+;CHECK: calll -12759
+
+i686-linux-unknown dd 44 24 04 d9 e1 c3
+;CHECK: fldl 4(%esp)
+;CHECK: fabs
+;CHECK: ret
diff --git a/test/Bindings/llvm-c/functions.ll b/test/Bindings/llvm-c/functions.ll
new file mode 100644
index 0000000..4503fb1
--- /dev/null
+++ b/test/Bindings/llvm-c/functions.ll
@@ -0,0 +1,31 @@
+; RUN: llvm-as < %s | llvm-c-test --module-list-functions | FileCheck %s
+
+define i32 @X() {
+entry:
+ br label %l1
+
+l1:
+ br label %l2
+
+l2:
+ br label %l3
+
+l3:
+ ret i32 1234
+}
+;CHECK: FunctionDefinition: X [#bb=4]
+
+
+define i32 @Z(i32 %a) {
+entry:
+ %0 = tail call i32 @Y(i32 %a)
+ ret i32 %0
+}
+
+;CHECK: FunctionDefinition: Z [#bb=1]
+;CHECK: calls: Y
+;CHECK: #isn: 2
+
+declare i32 @Y(i32)
+;CHECK: FunctionDeclaration: Y
+
diff --git a/test/Bindings/llvm-c/globals.ll b/test/Bindings/llvm-c/globals.ll
new file mode 100644
index 0000000..a38f08b
--- /dev/null
+++ b/test/Bindings/llvm-c/globals.ll
@@ -0,0 +1,7 @@
+; RUN: llvm-as < %s | llvm-c-test --module-list-globals | FileCheck %s
+
+@foo = constant [7 x i8] c"foobar\00", align 1
+;CHECK: GlobalDefinition: foo [7 x i8]*
+
+@bar = common global i32 0, align 4
+;CHECK: GlobalDefinition: bar i32*
diff --git a/test/Bindings/llvm-c/lit.local.cfg b/test/Bindings/llvm-c/lit.local.cfg
new file mode 100644
index 0000000..270a7f2
--- /dev/null
+++ b/test/Bindings/llvm-c/lit.local.cfg
@@ -0,0 +1,3 @@
+targets = set(config.root.targets_to_build.split())
+if not (targets & set(["X86", "ARM"])):
+ config.unsupported = True
diff --git a/test/lit.cfg b/test/lit.cfg
index 9e590a8..1b6fa54 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -232,6 +232,7 @@ for pattern in [r"\bbugpoint\b(?!-)",
r"\bllvm-shlib\b",
r"\bllvm-size\b",
r"\bllvm-tblgen\b",
+ r"\bllvm-c-test\b",
# Match llvmc but not -llvmc
NOHYPHEN + r"\bllvmc\b",
# Match lto but not -lto
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 69c4050..54f849c 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -39,6 +39,12 @@ add_llvm_tool_subdirectory(llvm-mcmarkup)
add_llvm_tool_subdirectory(llvm-symbolizer)
+if( NOT MSVC )
+ add_llvm_tool_subdirectory(llvm-c-test)
+else()
+ ignore_llvm_tool_subdirectory(llvm-c-test)
+endif( NOT MSVC )
+
add_llvm_tool_subdirectory(obj2yaml)
add_llvm_tool_subdirectory(yaml2obj)
diff --git a/tools/Makefile b/tools/Makefile
index 5fa5bf2..be87254 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -31,7 +31,7 @@ PARALLEL_DIRS := opt llvm-as llvm-dis llc llvm-ar llvm-nm llvm-link \
lli llvm-extract llvm-mc bugpoint llvm-bcanalyzer llvm-diff \
macho-dump llvm-objdump llvm-readobj llvm-rtdyld \
llvm-dwarfdump llvm-cov llvm-size llvm-stress llvm-mcmarkup \
- llvm-symbolizer obj2yaml yaml2obj
+ llvm-symbolizer obj2yaml yaml2obj llvm-c-test
# If Intel JIT Events support is configured, build an extra tool to test it.
ifeq ($(USE_INTEL_JITEVENTS), 1)
diff --git a/tools/llvm-c-test/CMakeLists.txt b/tools/llvm-c-test/CMakeLists.txt
new file mode 100644
index 0000000..2926d9d
--- /dev/null
+++ b/tools/llvm-c-test/CMakeLists.txt
@@ -0,0 +1,16 @@
+set(LLVM_LINK_COMPONENTS all)
+
+if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wstrict-prototypes")
+endif ()
+
+add_llvm_tool(llvm-c-test
+ calc.c
+ disassemble.c
+ helpers.c
+ include-all.c
+ main.c
+ module.c
+ object.c
+ targets.c
+ )
diff --git a/tools/llvm-c-test/Makefile b/tools/llvm-c-test/Makefile
new file mode 100644
index 0000000..08be7c3
--- /dev/null
+++ b/tools/llvm-c-test/Makefile
@@ -0,0 +1,29 @@
+##===- tools/llvm-c-test -----------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TOOLNAME = llvm-c-test
+
+TOOL_NO_EXPORTS = 1
+NO_INSTALL = 1
+
+
+# If there is no shared lib, link all components...
+ifneq ($(ENABLE_SHARED),1)
+LINK_COMPONENTS = all
+endif
+
+include $(LEVEL)/Makefile.common
+
+CFLAGS += -std=c99 -Wall -Wstrict-prototypes
+
+# ...but if it is built - use it
+ifeq ($(ENABLE_SHARED),1)
+LIBS = -lLLVM-$(LLVMVersion)
+endif
diff --git a/tools/llvm-c-test/calc.c b/tools/llvm-c-test/calc.c
new file mode 100644
index 0000000..c34ff7b
--- /dev/null
+++ b/tools/llvm-c-test/calc.c
@@ -0,0 +1,143 @@
+/*===-- calc.c - tool for testing libLLVM and llvm-c API ------------------===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This file implements the --calc command in llvm-c-test. --calc reads lines *|
+|* from stdin, parses them as a name and an expression in reverse polish *|
+|* notation and prints a module with a function with the expression. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#include "llvm-c-test.h"
+#include "llvm-c/Core.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+typedef LLVMValueRef (*binop_func_t)(LLVMBuilderRef, LLVMValueRef LHS,
+ LLVMValueRef RHS, const char *Name);
+
+static LLVMOpcode op_to_opcode(char op) {
+ switch (op) {
+ case '+': return LLVMAdd;
+ case '-': return LLVMSub;
+ case '*': return LLVMMul;
+ case '/': return LLVMSDiv;
+ case '&': return LLVMAnd;
+ case '|': return LLVMOr;
+ case '^': return LLVMXor;
+ }
+ assert(0 && "unknown operation");
+ return 0;
+}
+
+#define MAX_DEPTH 32
+
+static LLVMValueRef build_from_tokens(char **tokens, int ntokens,
+ LLVMBuilderRef builder,
+ LLVMValueRef param) {
+ LLVMValueRef stack[MAX_DEPTH];
+ int depth = 0;
+
+ for (int i = 0; i < ntokens; i++) {
+ char tok = tokens[i][0];
+ switch (tok) {
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '&':
+ case '|':
+ case '^':
+ if (depth < 2) {
+ printf("stack underflow\n");
+ return NULL;
+ }
+
+ stack[depth - 2] = LLVMBuildBinOp(builder, op_to_opcode(tok),
+ stack[depth - 1], stack[depth - 2], "");
+ depth--;
+
+ break;
+
+ case '@':
+ if (depth < 1) {
+ printf("stack underflow\n");
+ return NULL;
+ }
+
+ LLVMValueRef off = LLVMBuildGEP(builder, param, &stack[depth - 1], 1, "");
+ stack[depth - 1] = LLVMBuildLoad(builder, off, "");
+
+ break;
+
+ default: {
+ char *end;
+ long val = strtol(tokens[i], &end, 0);
+ if (end[0] != '\0') {
+ printf("error parsing number\n");
+ return NULL;
+ }
+
+ if (depth >= MAX_DEPTH) {
+ printf("stack overflow\n");
+ return NULL;
+ }
+
+ stack[depth++] = LLVMConstInt(LLVMInt64Type(), val, 1);
+ break;
+ }
+ }
+ }
+
+ if (depth < 1) {
+ printf("stack underflow at return\n");
+ return NULL;
+ }
+
+ LLVMBuildRet(builder, stack[depth - 1]);
+
+ return stack[depth - 1];
+}
+
+static void handle_line(char **tokens, int ntokens) {
+ char *name = tokens[0];
+
+ LLVMModuleRef M = LLVMModuleCreateWithName(name);
+
+ LLVMTypeRef I64ty = LLVMInt64Type();
+ LLVMTypeRef I64Ptrty = LLVMPointerType(I64ty, 0);
+ LLVMTypeRef Fty = LLVMFunctionType(I64ty, &I64Ptrty, 1, 0);
+
+ LLVMValueRef F = LLVMAddFunction(M, name, Fty);
+ LLVMBuilderRef builder = LLVMCreateBuilder();
+ LLVMPositionBuilderAtEnd(builder, LLVMAppendBasicBlock(F, "entry"));
+
+ LLVMValueRef param;
+ LLVMGetParams(F, &param);
+ LLVMSetValueName(param, "in");
+
+ LLVMValueRef res = build_from_tokens(tokens + 1, ntokens - 1, builder, param);
+ if (res) {
+ char *irstr = LLVMPrintModuleToString(M);
+ puts(irstr);
+ LLVMDisposeMessage(irstr);
+ }
+
+ LLVMDisposeBuilder(builder);
+
+ LLVMDisposeModule(M);
+}
+
+int calc(void) {
+
+ tokenize_stdin(handle_line);
+
+ return 0;
+}
diff --git a/tools/llvm-c-test/disassemble.c b/tools/llvm-c-test/disassemble.c
new file mode 100644
index 0000000..4b3d37b
--- /dev/null
+++ b/tools/llvm-c-test/disassemble.c
@@ -0,0 +1,85 @@
+/*===-- disassemble.c - tool for testing libLLVM and llvm-c API -----------===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This file implements the --disassemble command in llvm-c-test. *|
+|* --disassemble reads lines from stdin, parses them as a triple and hex *|
+|* machine code, and prints disassembly of the machine code. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#include "llvm-c-test.h"
+#include "llvm-c/Disassembler.h"
+#include "llvm-c/Target.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+static void pprint(int pos, unsigned char *buf, int len, const char *disasm) {
+ printf("%04x: ", pos);
+ for (int i = 0; i < 8; i++) {
+ if (i < len) {
+ printf("%02x ", buf[i]);
+ } else {
+ printf(" ");
+ }
+ }
+
+ printf(" %s\n", disasm);
+}
+
+static void do_disassemble(const char *triple, unsigned char *buf, int siz) {
+ LLVMDisasmContextRef D = LLVMCreateDisasm(triple, NULL, 0, NULL, NULL);
+
+ if (!D) {
+ printf("ERROR: Couldn't create disassebler for triple %s\n", triple);
+ return;
+ }
+
+ char outline[1024];
+ int pos = 0;
+ while (pos < siz) {
+ size_t l = LLVMDisasmInstruction(D, buf + pos, siz - pos, 0, outline,
+ sizeof(outline));
+ if (!l) {
+ pprint(pos, buf + pos, 1, "\t???");
+ pos++;
+ } else {
+ pprint(pos, buf + pos, l, outline);
+ pos += l;
+ }
+ }
+
+ LLVMDisasmDispose(D);
+}
+
+static void handle_line(char **tokens, int ntokens) {
+ unsigned char disbuf[128];
+ size_t disbuflen = 0;
+ char *triple = tokens[0];
+
+ printf("triple: %s\n", triple);
+
+ for (int i = 1; i < ntokens; i++) {
+ disbuf[disbuflen++] = strtol(tokens[i], NULL, 16);
+ if (disbuflen >= sizeof(disbuf)) {
+ fprintf(stderr, "Warning: Too long line, truncating\n");
+ break;
+ }
+ }
+ do_disassemble(triple, disbuf, disbuflen);
+}
+
+int disassemble(void) {
+ LLVMInitializeAllTargetInfos();
+ LLVMInitializeAllTargetMCs();
+ LLVMInitializeAllDisassemblers();
+
+ tokenize_stdin(handle_line);
+
+ return 0;
+}
diff --git a/tools/llvm-c-test/helpers.c b/tools/llvm-c-test/helpers.c
new file mode 100644
index 0000000..1ea8a4f
--- /dev/null
+++ b/tools/llvm-c-test/helpers.c
@@ -0,0 +1,40 @@
+/*===-- helpers.c - tool for testing libLLVM and llvm-c API ---------------===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* Helper functions *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#include "llvm-c-test.h"
+#include <stdio.h>
+#include <string.h>
+
+#define MAX_TOKENS 512
+#define MAX_LINE_LEN 1024
+
+void tokenize_stdin(void (*cb)(char **tokens, int ntokens)) {
+ char line[MAX_LINE_LEN];
+ char *tokbuf[MAX_TOKENS];
+
+ while (fgets(line, sizeof(line), stdin)) {
+ int c = 0;
+
+ if (line[0] == ';' || line[0] == '\n')
+ continue;
+
+ while (c < MAX_TOKENS) {
+ tokbuf[c] = strtok(c ? NULL : line, " \n");
+ if (!tokbuf[c])
+ break;
+ c++;
+ }
+ if (c)
+ cb(tokbuf, c);
+ }
+}
diff --git a/tools/llvm-c-test/include-all.c b/tools/llvm-c-test/include-all.c
new file mode 100644
index 0000000..17b9917
--- /dev/null
+++ b/tools/llvm-c-test/include-all.c
@@ -0,0 +1,33 @@
+/*===-- include-all.c - tool for testing libLLVM and llvm-c API -----------===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This file doesn't have any actual code. It just make sure that all *|
+|* the llvm-c include files are good and doesn't generate any warnings *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+// FIXME: Autogenerate this list
+
+#include "llvm-c/Analysis.h"
+#include "llvm-c/BitReader.h"
+#include "llvm-c/BitWriter.h"
+#include "llvm-c/Core.h"
+#include "llvm-c/Disassembler.h"
+#include "llvm-c/ExecutionEngine.h"
+#include "llvm-c/Initialization.h"
+#include "llvm-c/LinkTimeOptimizer.h"
+#include "llvm-c/Linker.h"
+#include "llvm-c/Object.h"
+#include "llvm-c/Target.h"
+#include "llvm-c/TargetMachine.h"
+#include "llvm-c/Transforms/IPO.h"
+#include "llvm-c/Transforms/PassManagerBuilder.h"
+#include "llvm-c/Transforms/Scalar.h"
+#include "llvm-c/Transforms/Vectorize.h"
+#include "llvm-c/lto.h"
diff --git a/tools/llvm-c-test/llvm-c-test.h b/tools/llvm-c-test/llvm-c-test.h
new file mode 100644
index 0000000..0a25aa6
--- /dev/null
+++ b/tools/llvm-c-test/llvm-c-test.h
@@ -0,0 +1,37 @@
+/*===-- llvm-c-test.h - tool for testing libLLVM and llvm-c API -----------===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* Header file for llvm-c-test *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+#ifndef LLVM_C_TEST_H
+#define LLVM_C_TEST_H
+
+// helpers.c
+void tokenize_stdin(void (*cb)(char **tokens, int ntokens));
+
+// module.c
+int module_dump(void);
+int module_list_functions(void);
+int module_list_globals(void);
+
+// calc.c
+int calc(void);
+
+// disassemble.c
+int disassemble(void);
+
+// object.c
+int object_list_sections(void);
+int object_list_symbols(void);
+
+// targets.c
+int targets_list(void);
+
+#endif
diff --git a/tools/llvm-c-test/main.c b/tools/llvm-c-test/main.c
new file mode 100644
index 0000000..72f8b04
--- /dev/null
+++ b/tools/llvm-c-test/main.c
@@ -0,0 +1,73 @@
+/*===-- main.c - tool for testing libLLVM and llvm-c API ------------------===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* Main file for llvm-c-tests. "Parses" arguments and dispatches. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#include "llvm-c-test.h"
+#include "llvm-c/BitReader.h"
+#include "llvm-c/Core.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void print_usage(void) {
+ fprintf(stderr, "llvm-c-test command\n\n");
+ fprintf(stderr, " Commands:\n");
+ fprintf(stderr, " * --module-dump\n");
+ fprintf(stderr, " Read bytecode from stdin - print disassembly\n\n");
+ fprintf(stderr, " * --module-list-functions\n");
+ fprintf(stderr,
+ " Read bytecode from stdin - list summary of functions\n\n");
+ fprintf(stderr, " * --module-list-globals\n");
+ fprintf(stderr, " Read bytecode from stdin - list summary of globals\n\n");
+ fprintf(stderr, " * --targets-list\n");
+ fprintf(stderr, " List available targets\n\n");
+ fprintf(stderr, " * --object-list-sections\n");
+ fprintf(stderr, " Read object file form stdin - list sections\n\n");
+ fprintf(stderr, " * --object-list-symbols\n");
+ fprintf(stderr,
+ " Read object file form stdin - list symbols (like nm)\n\n");
+ fprintf(stderr, " * --disassemble\n");
+ fprintf(stderr, " Read lines of triple, hex ascii machine code from stdin "
+ "- print disassembly\n\n");
+ fprintf(stderr, " * --calc\n");
+ fprintf(
+ stderr,
+ " Read lines of name, rpn from stdin - print generated module\n\n");
+}
+
+int main(int argc, char **argv) {
+ LLVMPassRegistryRef pr = LLVMGetGlobalPassRegistry();
+
+ LLVMInitializeCore(pr);
+
+ if (argc == 2 && !strcmp(argv[1], "--module-dump")) {
+ return module_dump();
+ } else if (argc == 2 && !strcmp(argv[1], "--module-list-functions")) {
+ return module_list_functions();
+ } else if (argc == 2 && !strcmp(argv[1], "--module-list-globals")) {
+ return module_list_globals();
+ } else if (argc == 2 && !strcmp(argv[1], "--targets-list")) {
+ return targets_list();
+ } else if (argc == 2 && !strcmp(argv[1], "--object-list-sections")) {
+ return object_list_sections();
+ } else if (argc == 2 && !strcmp(argv[1], "--object-list-symbols")) {
+ return object_list_symbols();
+ } else if (argc == 2 && !strcmp(argv[1], "--disassemble")) {
+ return disassemble();
+ } else if (argc == 2 && !strcmp(argv[1], "--calc")) {
+ return calc();
+ } else {
+ print_usage();
+ }
+
+ return 1;
+}
diff --git a/tools/llvm-c-test/module.c b/tools/llvm-c-test/module.c
new file mode 100644
index 0000000..50e6e9c
--- /dev/null
+++ b/tools/llvm-c-test/module.c
@@ -0,0 +1,112 @@
+/*===-- module.c - tool for testing libLLVM and llvm-c API ----------------===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This file implements the --module-dump, --module-list-functions and *|
+|* --module-list-globals commands in llvm-c-test. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#include "llvm-c-test.h"
+#include "llvm-c/BitReader.h"
+#include "llvm-c/Core.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static LLVMModuleRef load_module(void) {
+ LLVMMemoryBufferRef MB;
+ LLVMModuleRef M;
+ char *msg = NULL;
+
+ if (LLVMCreateMemoryBufferWithSTDIN(&MB, &msg)) {
+ fprintf(stderr, "Error reading file: %s\n", msg);
+ exit(1);
+ }
+
+ if (LLVMParseBitcode(MB, &M, &msg)) {
+ fprintf(stderr, "Error parsing bitcode: %s\n", msg);
+ exit(1);
+ }
+
+ return M;
+}
+
+int module_dump(void) {
+ LLVMModuleRef M = load_module();
+
+ char *irstr = LLVMPrintModuleToString(M);
+ puts(irstr);
+ LLVMDisposeMessage(irstr);
+
+ LLVMDisposeModule(M);
+
+ return 0;
+}
+
+int module_list_functions(void) {
+ LLVMModuleRef M = load_module();
+ LLVMValueRef f;
+
+ f = LLVMGetFirstFunction(M);
+ while (f) {
+ if (LLVMIsDeclaration(f)) {
+ printf("FunctionDeclaration: %s\n", LLVMGetValueName(f));
+ } else {
+ unsigned nisn = 0;
+ unsigned nbb = 0;
+
+ printf("FunctionDefinition: %s [#bb=%u]\n", LLVMGetValueName(f),
+ LLVMCountBasicBlocks(f));
+
+ for (LLVMBasicBlockRef bb = LLVMGetFirstBasicBlock(f); bb;
+ bb = LLVMGetNextBasicBlock(bb)) {
+ nbb++;
+ for (LLVMValueRef isn = LLVMGetFirstInstruction(bb); isn;
+ isn = LLVMGetNextInstruction(isn)) {
+ nisn++;
+ if (LLVMIsACallInst(isn)) {
+ LLVMValueRef callee =
+ LLVMGetOperand(isn, LLVMGetNumOperands(isn) - 1);
+ printf(" calls: %s\n", LLVMGetValueName(callee));
+ }
+ }
+ }
+ printf(" #isn: %u\n", nisn);
+ printf(" #bb: %u\n\n", nbb);
+ }
+ f = LLVMGetNextFunction(f);
+ }
+
+ LLVMDisposeModule(M);
+
+ return 0;
+}
+
+int module_list_globals(void) {
+ LLVMModuleRef M = load_module();
+ LLVMValueRef g;
+
+ g = LLVMGetFirstGlobal(M);
+ while (g) {
+ LLVMTypeRef T = LLVMTypeOf(g);
+ char *s = LLVMPrintTypeToString(T);
+
+ printf("Global%s: %s %s\n",
+ LLVMIsDeclaration(g) ? "Declaration" : "Definition",
+ LLVMGetValueName(g), s);
+
+ LLVMDisposeMessage(s);
+
+ g = LLVMGetNextGlobal(g);
+ }
+
+ LLVMDisposeModule(M);
+
+ return 0;
+}
diff --git a/tools/llvm-c-test/object.c b/tools/llvm-c-test/object.c
new file mode 100644
index 0000000..c94e3af
--- /dev/null
+++ b/tools/llvm-c-test/object.c
@@ -0,0 +1,85 @@
+/*===-- object.c - tool for testing libLLVM and llvm-c API ----------------===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This file implements the --object-list-sections and --object-list-symbols *|
+|* commands in llvm-c-test. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#include "llvm-c-test.h"
+#include "llvm-c/Object.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+int object_list_sections(void) {
+ LLVMMemoryBufferRef MB;
+ LLVMObjectFileRef O;
+ char *msg = NULL;
+
+ if (LLVMCreateMemoryBufferWithSTDIN(&MB, &msg)) {
+ fprintf(stderr, "Error reading file: %s\n", msg);
+ exit(1);
+ }
+
+ O = LLVMCreateObjectFile(MB);
+ if (!O) {
+ fprintf(stderr, "Error reading object\n");
+ exit(1);
+ }
+
+ LLVMSectionIteratorRef sect = LLVMGetSections(O);
+ while (!LLVMIsSectionIteratorAtEnd(O, sect)) {
+ printf("'%s': @0x%08" PRIx64 " +%" PRIu64 "\n", LLVMGetSectionName(sect),
+ LLVMGetSectionAddress(sect), LLVMGetSectionSize(sect));
+
+ LLVMMoveToNextSection(sect);
+ }
+
+ LLVMDisposeSectionIterator(sect);
+
+ LLVMDisposeObjectFile(O);
+
+ return 0;
+}
+
+int object_list_symbols(void) {
+ LLVMMemoryBufferRef MB;
+ LLVMObjectFileRef O;
+ char *msg = NULL;
+
+ if (LLVMCreateMemoryBufferWithSTDIN(&MB, &msg)) {
+ fprintf(stderr, "Error reading file: %s\n", msg);
+ exit(1);
+ }
+
+ O = LLVMCreateObjectFile(MB);
+ if (!O) {
+ fprintf(stderr, "Error reading object\n");
+ exit(1);
+ }
+
+ LLVMSectionIteratorRef sect = LLVMGetSections(O);
+ LLVMSymbolIteratorRef sym = LLVMGetSymbols(O);
+ while (!LLVMIsSymbolIteratorAtEnd(O, sym)) {
+
+ LLVMMoveToContainingSection(sect, sym);
+ printf("%s @0x%08" PRIx64 "/0x%08" PRIx64 " +%" PRIu64 " (%s)\n",
+ LLVMGetSymbolName(sym), LLVMGetSymbolAddress(sym),
+ LLVMGetSymbolFileOffset(sym), LLVMGetSymbolSize(sym),
+ LLVMGetSectionName(sect));
+
+ LLVMMoveToNextSymbol(sym);
+ }
+
+ LLVMDisposeSymbolIterator(sym);
+
+ LLVMDisposeObjectFile(O);
+
+ return 0;
+}
diff --git a/tools/llvm-c-test/targets.c b/tools/llvm-c-test/targets.c
new file mode 100644
index 0000000..fccea09
--- /dev/null
+++ b/tools/llvm-c-test/targets.c
@@ -0,0 +1,29 @@
+/*===-- targets.c - tool for testing libLLVM and llvm-c API ---------------===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This file implements the --targets command in llvm-c-test. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#include "llvm-c/TargetMachine.h"
+#include <stdio.h>
+
+int targets_list(void) {
+ LLVMInitializeAllTargetInfos();
+ LLVMInitializeAllTargets();
+
+ for (LLVMTargetRef t = LLVMGetFirstTarget(); t; t = LLVMGetNextTarget(t)) {
+ printf("%s", LLVMGetTargetName(t));
+ if (LLVMTargetHasJIT(t))
+ printf(" (+jit)");
+ printf("\n - %s\n", LLVMGetTargetDescription(t));
+ }
+
+ return 0;
+}