summaryrefslogtreecommitdiff
path: root/tools/llvm-c-test
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-c-test')
-rw-r--r--tools/llvm-c-test/CMakeLists.txt3
-rw-r--r--tools/llvm-c-test/Makefile29
-rw-r--r--tools/llvm-c-test/calc.c5
-rw-r--r--tools/llvm-c-test/diagnostic.c89
-rw-r--r--tools/llvm-c-test/disassemble.c4
-rw-r--r--tools/llvm-c-test/echo.cpp958
-rw-r--r--tools/llvm-c-test/helpers.c2
-rw-r--r--tools/llvm-c-test/llvm-c-test.h38
-rw-r--r--tools/llvm-c-test/main.c49
-rw-r--r--tools/llvm-c-test/metadata.c5
-rw-r--r--tools/llvm-c-test/module.c15
-rw-r--r--tools/llvm-c-test/object.c5
-rw-r--r--tools/llvm-c-test/targets.c2
13 files changed, 1123 insertions, 81 deletions
diff --git a/tools/llvm-c-test/CMakeLists.txt b/tools/llvm-c-test/CMakeLists.txt
index f22dffb30e8a4..858f2b07214a1 100644
--- a/tools/llvm-c-test/CMakeLists.txt
+++ b/tools/llvm-c-test/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
Core
MCDisassembler
Object
+ Support
Target
)
@@ -36,7 +37,9 @@ endif ()
add_llvm_tool(llvm-c-test
calc.c
+ diagnostic.c
disassemble.c
+ echo.cpp
helpers.c
include-all.c
main.c
diff --git a/tools/llvm-c-test/Makefile b/tools/llvm-c-test/Makefile
deleted file mode 100644
index 08be7c3619fb2..0000000000000
--- a/tools/llvm-c-test/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-##===- 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
index 3119ccf8e9aa7..4c273cbf70a26 100644
--- a/tools/llvm-c-test/calc.c
+++ b/tools/llvm-c-test/calc.c
@@ -14,7 +14,6 @@
\*===----------------------------------------------------------------------===*/
#include "llvm-c-test.h"
-#include "llvm-c/Core.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -140,9 +139,9 @@ static void handle_line(char **tokens, int ntokens) {
LLVMDisposeModule(M);
}
-int calc(void) {
+int llvm_calc(void) {
- tokenize_stdin(handle_line);
+ llvm_tokenize_stdin(handle_line);
return 0;
}
diff --git a/tools/llvm-c-test/diagnostic.c b/tools/llvm-c-test/diagnostic.c
new file mode 100644
index 0000000000000..16d5174732360
--- /dev/null
+++ b/tools/llvm-c-test/diagnostic.c
@@ -0,0 +1,89 @@
+//===-- diagnostic.cpp - 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 --test-diagnostic-handler command in llvm-c-test.
+//
+// This command uses the C API to read a module with a custom diagnostic
+// handler set to test the diagnostic handler functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm-c-test.h"
+#include "llvm-c/BitReader.h"
+#include "llvm-c/Core.h"
+
+#include <stdio.h>
+
+static void diagnosticHandler(LLVMDiagnosticInfoRef DI, void *C) {
+ fprintf(stderr, "Executing diagnostic handler\n");
+
+ fprintf(stderr, "Diagnostic severity is of type ");
+ switch (LLVMGetDiagInfoSeverity(DI)) {
+ case LLVMDSError:
+ fprintf(stderr, "error");
+ break;
+ case LLVMDSWarning:
+ fprintf(stderr, "warning");
+ break;
+ case LLVMDSRemark:
+ fprintf(stderr, "remark");
+ break;
+ case LLVMDSNote:
+ fprintf(stderr, "note");
+ break;
+ }
+ fprintf(stderr, "\n");
+
+ (*(int *)C) = 1;
+}
+
+static int handlerCalled = 0;
+
+int llvm_test_diagnostic_handler(void) {
+ LLVMContextRef C = LLVMGetGlobalContext();
+ LLVMContextSetDiagnosticHandler(C, diagnosticHandler, &handlerCalled);
+
+ if (LLVMContextGetDiagnosticHandler(C) != diagnosticHandler) {
+ fprintf(stderr, "LLVMContext{Set,Get}DiagnosticHandler failed\n");
+ return 1;
+ }
+
+ int *DC = (int *)LLVMContextGetDiagnosticContext(C);
+ if (DC != &handlerCalled || *DC) {
+ fprintf(stderr, "LLVMContextGetDiagnosticContext failed\n");
+ return 1;
+ }
+
+ LLVMMemoryBufferRef MB;
+ char *msg = NULL;
+ if (LLVMCreateMemoryBufferWithSTDIN(&MB, &msg)) {
+ fprintf(stderr, "Error reading file: %s\n", msg);
+ LLVMDisposeMessage(msg);
+ return 1;
+ }
+
+
+ LLVMModuleRef M;
+ int Ret = LLVMGetBitcodeModule2(MB, &M);
+ if (Ret) {
+ // We do not return if the bitcode was invalid, as we want to test whether
+ // the diagnostic handler was executed.
+ fprintf(stderr, "Error parsing bitcode: %s\n", msg);
+ }
+
+ LLVMDisposeMemoryBuffer(MB);
+
+ if (handlerCalled) {
+ fprintf(stderr, "Diagnostic handler was called while loading module\n");
+ } else {
+ fprintf(stderr, "Diagnostic handler was not called while loading module\n");
+ }
+
+ return 0;
+}
diff --git a/tools/llvm-c-test/disassemble.c b/tools/llvm-c-test/disassemble.c
index 05a9218d014a6..7d6f1783aed9e 100644
--- a/tools/llvm-c-test/disassemble.c
+++ b/tools/llvm-c-test/disassemble.c
@@ -83,12 +83,12 @@ static void handle_line(char **tokens, int ntokens) {
do_disassemble(triple, features, disbuf, disbuflen);
}
-int disassemble(void) {
+int llvm_disassemble(void) {
LLVMInitializeAllTargetInfos();
LLVMInitializeAllTargetMCs();
LLVMInitializeAllDisassemblers();
- tokenize_stdin(handle_line);
+ llvm_tokenize_stdin(handle_line);
return 0;
}
diff --git a/tools/llvm-c-test/echo.cpp b/tools/llvm-c-test/echo.cpp
new file mode 100644
index 0000000000000..72ff138c74e32
--- /dev/null
+++ b/tools/llvm-c-test/echo.cpp
@@ -0,0 +1,958 @@
+//===-- echo.cpp - 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 --echo command in llvm-c-test.
+//
+// This command uses the C API to read a module and output an exact copy of it
+// as output. It is used to check that the resulting module matches the input
+// to validate that the C API can read and write modules properly.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm-c-test.h"
+#include "llvm-c/Target.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/ErrorHandling.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+using namespace llvm;
+
+// Provide DenseMapInfo for C API opaque types.
+template<typename T>
+struct CAPIDenseMap {};
+
+// The default DenseMapInfo require to know about pointer alignement.
+// Because the C API uses opaques pointer types, their alignement is unknown.
+// As a result, we need to roll out our own implementation.
+template<typename T>
+struct CAPIDenseMap<T*> {
+ struct CAPIDenseMapInfo {
+ static inline T* getEmptyKey() {
+ uintptr_t Val = static_cast<uintptr_t>(-1);
+ return reinterpret_cast<T*>(Val);
+ }
+ static inline T* getTombstoneKey() {
+ uintptr_t Val = static_cast<uintptr_t>(-2);
+ return reinterpret_cast<T*>(Val);
+ }
+ static unsigned getHashValue(const T *PtrVal) {
+ return hash_value(PtrVal);
+ }
+ static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
+ };
+
+ typedef DenseMap<T*, T*, CAPIDenseMapInfo> Map;
+};
+
+typedef CAPIDenseMap<LLVMValueRef>::Map ValueMap;
+typedef CAPIDenseMap<LLVMBasicBlockRef>::Map BasicBlockMap;
+
+struct TypeCloner {
+ LLVMModuleRef M;
+ LLVMContextRef Ctx;
+
+ TypeCloner(LLVMModuleRef M): M(M), Ctx(LLVMGetModuleContext(M)) {}
+
+ LLVMTypeRef Clone(LLVMValueRef Src) {
+ return Clone(LLVMTypeOf(Src));
+ }
+
+ LLVMTypeRef Clone(LLVMTypeRef Src) {
+ LLVMTypeKind Kind = LLVMGetTypeKind(Src);
+ switch (Kind) {
+ case LLVMVoidTypeKind:
+ return LLVMVoidTypeInContext(Ctx);
+ case LLVMHalfTypeKind:
+ return LLVMHalfTypeInContext(Ctx);
+ case LLVMFloatTypeKind:
+ return LLVMFloatTypeInContext(Ctx);
+ case LLVMDoubleTypeKind:
+ return LLVMDoubleTypeInContext(Ctx);
+ case LLVMX86_FP80TypeKind:
+ return LLVMX86FP80TypeInContext(Ctx);
+ case LLVMFP128TypeKind:
+ return LLVMFP128TypeInContext(Ctx);
+ case LLVMPPC_FP128TypeKind:
+ return LLVMPPCFP128TypeInContext(Ctx);
+ case LLVMLabelTypeKind:
+ return LLVMLabelTypeInContext(Ctx);
+ case LLVMIntegerTypeKind:
+ return LLVMIntTypeInContext(Ctx, LLVMGetIntTypeWidth(Src));
+ case LLVMFunctionTypeKind: {
+ unsigned ParamCount = LLVMCountParamTypes(Src);
+ LLVMTypeRef* Params = nullptr;
+ if (ParamCount > 0) {
+ Params = (LLVMTypeRef*) malloc(ParamCount * sizeof(LLVMTypeRef));
+ LLVMGetParamTypes(Src, Params);
+ for (unsigned i = 0; i < ParamCount; i++)
+ Params[i] = Clone(Params[i]);
+ }
+
+ LLVMTypeRef FunTy = LLVMFunctionType(Clone(LLVMGetReturnType(Src)),
+ Params, ParamCount,
+ LLVMIsFunctionVarArg(Src));
+ if (ParamCount > 0)
+ free(Params);
+ return FunTy;
+ }
+ case LLVMStructTypeKind: {
+ LLVMTypeRef S = nullptr;
+ const char *Name = LLVMGetStructName(Src);
+ if (Name) {
+ S = LLVMGetTypeByName(M, Name);
+ if (S)
+ return S;
+ S = LLVMStructCreateNamed(Ctx, Name);
+ if (LLVMIsOpaqueStruct(Src))
+ return S;
+ }
+
+ unsigned EltCount = LLVMCountStructElementTypes(Src);
+ SmallVector<LLVMTypeRef, 8> Elts;
+ for (unsigned i = 0; i < EltCount; i++)
+ Elts.push_back(Clone(LLVMStructGetTypeAtIndex(Src, i)));
+ if (Name)
+ LLVMStructSetBody(S, Elts.data(), EltCount, LLVMIsPackedStruct(Src));
+ else
+ S = LLVMStructTypeInContext(Ctx, Elts.data(), EltCount,
+ LLVMIsPackedStruct(Src));
+ return S;
+ }
+ case LLVMArrayTypeKind:
+ return LLVMArrayType(
+ Clone(LLVMGetElementType(Src)),
+ LLVMGetArrayLength(Src)
+ );
+ case LLVMPointerTypeKind:
+ return LLVMPointerType(
+ Clone(LLVMGetElementType(Src)),
+ LLVMGetPointerAddressSpace(Src)
+ );
+ case LLVMVectorTypeKind:
+ return LLVMVectorType(
+ Clone(LLVMGetElementType(Src)),
+ LLVMGetVectorSize(Src)
+ );
+ case LLVMMetadataTypeKind:
+ break;
+ case LLVMX86_MMXTypeKind:
+ return LLVMX86MMXTypeInContext(Ctx);
+ default:
+ break;
+ }
+
+ fprintf(stderr, "%d is not a supported typekind\n", Kind);
+ exit(-1);
+ }
+};
+
+static ValueMap clone_params(LLVMValueRef Src, LLVMValueRef Dst) {
+ unsigned Count = LLVMCountParams(Src);
+ if (Count != LLVMCountParams(Dst))
+ report_fatal_error("Parameter count mismatch");
+
+ ValueMap VMap;
+ if (Count == 0)
+ return VMap;
+
+ LLVMValueRef SrcFirst = LLVMGetFirstParam(Src);
+ LLVMValueRef DstFirst = LLVMGetFirstParam(Dst);
+ LLVMValueRef SrcLast = LLVMGetLastParam(Src);
+ LLVMValueRef DstLast = LLVMGetLastParam(Dst);
+
+ LLVMValueRef SrcCur = SrcFirst;
+ LLVMValueRef DstCur = DstFirst;
+ LLVMValueRef SrcNext = nullptr;
+ LLVMValueRef DstNext = nullptr;
+ while (true) {
+ const char *Name = LLVMGetValueName(SrcCur);
+ LLVMSetValueName(DstCur, Name);
+
+ VMap[SrcCur] = DstCur;
+
+ Count--;
+ SrcNext = LLVMGetNextParam(SrcCur);
+ DstNext = LLVMGetNextParam(DstCur);
+ if (SrcNext == nullptr && DstNext == nullptr) {
+ if (SrcCur != SrcLast)
+ report_fatal_error("SrcLast param does not match End");
+ if (DstCur != DstLast)
+ report_fatal_error("DstLast param does not match End");
+ break;
+ }
+
+ if (SrcNext == nullptr)
+ report_fatal_error("SrcNext was unexpectedly null");
+ if (DstNext == nullptr)
+ report_fatal_error("DstNext was unexpectedly null");
+
+ LLVMValueRef SrcPrev = LLVMGetPreviousParam(SrcNext);
+ if (SrcPrev != SrcCur)
+ report_fatal_error("SrcNext.Previous param is not Current");
+
+ LLVMValueRef DstPrev = LLVMGetPreviousParam(DstNext);
+ if (DstPrev != DstCur)
+ report_fatal_error("DstNext.Previous param is not Current");
+
+ SrcCur = SrcNext;
+ DstCur = DstNext;
+ }
+
+ if (Count != 0)
+ report_fatal_error("Parameter count does not match iteration");
+
+ return VMap;
+}
+
+static void check_value_kind(LLVMValueRef V, LLVMValueKind K) {
+ if (LLVMGetValueKind(V) != K)
+ report_fatal_error("LLVMGetValueKind returned incorrect type");
+}
+
+static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M);
+
+static LLVMValueRef clone_constant(LLVMValueRef Cst, LLVMModuleRef M) {
+ LLVMValueRef Ret = clone_constant_impl(Cst, M);
+ check_value_kind(Ret, LLVMGetValueKind(Cst));
+ return Ret;
+}
+
+static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M) {
+ if (!LLVMIsAConstant(Cst))
+ report_fatal_error("Expected a constant");
+
+ // Maybe it is a symbol
+ if (LLVMIsAGlobalValue(Cst)) {
+ const char *Name = LLVMGetValueName(Cst);
+
+ // Try function
+ if (LLVMIsAFunction(Cst)) {
+ check_value_kind(Cst, LLVMFunctionValueKind);
+ LLVMValueRef Dst = LLVMGetNamedFunction(M, Name);
+ if (Dst)
+ return Dst;
+ report_fatal_error("Could not find function");
+ }
+
+ // Try global variable
+ if (LLVMIsAGlobalVariable(Cst)) {
+ check_value_kind(Cst, LLVMGlobalVariableValueKind);
+ LLVMValueRef Dst = LLVMGetNamedGlobal(M, Name);
+ if (Dst)
+ return Dst;
+ report_fatal_error("Could not find function");
+ }
+
+ fprintf(stderr, "Could not find @%s\n", Name);
+ exit(-1);
+ }
+
+ // Try integer literal
+ if (LLVMIsAConstantInt(Cst)) {
+ check_value_kind(Cst, LLVMConstantIntValueKind);
+ return LLVMConstInt(TypeCloner(M).Clone(Cst),
+ LLVMConstIntGetZExtValue(Cst), false);
+ }
+
+ // Try zeroinitializer
+ if (LLVMIsAConstantAggregateZero(Cst)) {
+ check_value_kind(Cst, LLVMConstantAggregateZeroValueKind);
+ return LLVMConstNull(TypeCloner(M).Clone(Cst));
+ }
+
+ // Try constant array
+ if (LLVMIsAConstantArray(Cst)) {
+ check_value_kind(Cst, LLVMConstantArrayValueKind);
+ LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
+ unsigned EltCount = LLVMGetArrayLength(Ty);
+ SmallVector<LLVMValueRef, 8> Elts;
+ for (unsigned i = 0; i < EltCount; i++)
+ Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M));
+ return LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount);
+ }
+
+ // Try contant data array
+ if (LLVMIsAConstantDataArray(Cst)) {
+ check_value_kind(Cst, LLVMConstantDataArrayValueKind);
+ LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
+ unsigned EltCount = LLVMGetArrayLength(Ty);
+ SmallVector<LLVMValueRef, 8> Elts;
+ for (unsigned i = 0; i < EltCount; i++)
+ Elts.push_back(clone_constant(LLVMGetElementAsConstant(Cst, i), M));
+ return LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount);
+ }
+
+ // Try constant struct
+ if (LLVMIsAConstantStruct(Cst)) {
+ check_value_kind(Cst, LLVMConstantStructValueKind);
+ LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
+ unsigned EltCount = LLVMCountStructElementTypes(Ty);
+ SmallVector<LLVMValueRef, 8> Elts;
+ for (unsigned i = 0; i < EltCount; i++)
+ Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M));
+ if (LLVMGetStructName(Ty))
+ return LLVMConstNamedStruct(Ty, Elts.data(), EltCount);
+ return LLVMConstStructInContext(LLVMGetModuleContext(M), Elts.data(),
+ EltCount, LLVMIsPackedStruct(Ty));
+ }
+
+ // Try undef
+ if (LLVMIsUndef(Cst)) {
+ check_value_kind(Cst, LLVMUndefValueValueKind);
+ return LLVMGetUndef(TypeCloner(M).Clone(Cst));
+ }
+
+ // Try float literal
+ if (LLVMIsAConstantFP(Cst)) {
+ check_value_kind(Cst, LLVMConstantFPValueKind);
+ report_fatal_error("ConstantFP is not supported");
+ }
+
+ // This kind of constant is not supported
+ if (!LLVMIsAConstantExpr(Cst))
+ report_fatal_error("Expected a constant expression");
+
+ // At this point, it must be a constant expression
+ check_value_kind(Cst, LLVMConstantExprValueKind);
+
+ LLVMOpcode Op = LLVMGetConstOpcode(Cst);
+ switch(Op) {
+ case LLVMBitCast:
+ return LLVMConstBitCast(clone_constant(LLVMGetOperand(Cst, 0), M),
+ TypeCloner(M).Clone(Cst));
+ default:
+ fprintf(stderr, "%d is not a supported opcode\n", Op);
+ exit(-1);
+ }
+}
+
+struct FunCloner {
+ LLVMValueRef Fun;
+ LLVMModuleRef M;
+
+ ValueMap VMap;
+ BasicBlockMap BBMap;
+
+ FunCloner(LLVMValueRef Src, LLVMValueRef Dst): Fun(Dst),
+ M(LLVMGetGlobalParent(Fun)), VMap(clone_params(Src, Dst)) {}
+
+ LLVMTypeRef CloneType(LLVMTypeRef Src) {
+ return TypeCloner(M).Clone(Src);
+ }
+
+ LLVMTypeRef CloneType(LLVMValueRef Src) {
+ return TypeCloner(M).Clone(Src);
+ }
+
+ // Try to clone everything in the llvm::Value hierarchy.
+ LLVMValueRef CloneValue(LLVMValueRef Src) {
+ // First, the value may be constant.
+ if (LLVMIsAConstant(Src))
+ return clone_constant(Src, M);
+
+ // Function argument should always be in the map already.
+ auto i = VMap.find(Src);
+ if (i != VMap.end())
+ return i->second;
+
+ if (!LLVMIsAInstruction(Src))
+ report_fatal_error("Expected an instruction");
+
+ auto Ctx = LLVMGetModuleContext(M);
+ auto Builder = LLVMCreateBuilderInContext(Ctx);
+ auto BB = DeclareBB(LLVMGetInstructionParent(Src));
+ LLVMPositionBuilderAtEnd(Builder, BB);
+ auto Dst = CloneInstruction(Src, Builder);
+ LLVMDisposeBuilder(Builder);
+ return Dst;
+ }
+
+ void CloneAttrs(LLVMValueRef Src, LLVMValueRef Dst) {
+ auto Ctx = LLVMGetModuleContext(M);
+ int ArgCount = LLVMGetNumArgOperands(Src);
+ for (int i = LLVMAttributeReturnIndex; i <= ArgCount; i++) {
+ for (unsigned k = 0, e = LLVMGetLastEnumAttributeKind(); k < e; ++k) {
+ if (auto SrcA = LLVMGetCallSiteEnumAttribute(Src, i, k)) {
+ auto Val = LLVMGetEnumAttributeValue(SrcA);
+ auto A = LLVMCreateEnumAttribute(Ctx, k, Val);
+ LLVMAddCallSiteAttribute(Dst, i, A);
+ }
+ }
+ }
+ }
+
+ LLVMValueRef CloneInstruction(LLVMValueRef Src, LLVMBuilderRef Builder) {
+ check_value_kind(Src, LLVMInstructionValueKind);
+ if (!LLVMIsAInstruction(Src))
+ report_fatal_error("Expected an instruction");
+
+ const char *Name = LLVMGetValueName(Src);
+
+ // Check if this is something we already computed.
+ {
+ auto i = VMap.find(Src);
+ if (i != VMap.end()) {
+ // If we have a hit, it means we already generated the instruction
+ // as a dependancy to somethign else. We need to make sure
+ // it is ordered properly.
+ auto I = i->second;
+ LLVMInstructionRemoveFromParent(I);
+ LLVMInsertIntoBuilderWithName(Builder, I, Name);
+ return I;
+ }
+ }
+
+ // We tried everything, it must be an instruction
+ // that hasn't been generated already.
+ LLVMValueRef Dst = nullptr;
+
+ LLVMOpcode Op = LLVMGetInstructionOpcode(Src);
+ switch(Op) {
+ case LLVMRet: {
+ int OpCount = LLVMGetNumOperands(Src);
+ if (OpCount == 0)
+ Dst = LLVMBuildRetVoid(Builder);
+ else
+ Dst = LLVMBuildRet(Builder, CloneValue(LLVMGetOperand(Src, 0)));
+ break;
+ }
+ case LLVMBr: {
+ if (!LLVMIsConditional(Src)) {
+ LLVMValueRef SrcOp = LLVMGetOperand(Src, 0);
+ LLVMBasicBlockRef SrcBB = LLVMValueAsBasicBlock(SrcOp);
+ Dst = LLVMBuildBr(Builder, DeclareBB(SrcBB));
+ break;
+ }
+
+ LLVMValueRef Cond = LLVMGetCondition(Src);
+ LLVMValueRef Else = LLVMGetOperand(Src, 1);
+ LLVMBasicBlockRef ElseBB = DeclareBB(LLVMValueAsBasicBlock(Else));
+ LLVMValueRef Then = LLVMGetOperand(Src, 2);
+ LLVMBasicBlockRef ThenBB = DeclareBB(LLVMValueAsBasicBlock(Then));
+ Dst = LLVMBuildCondBr(Builder, Cond, ThenBB, ElseBB);
+ break;
+ }
+ case LLVMSwitch:
+ case LLVMIndirectBr:
+ break;
+ case LLVMInvoke: {
+ SmallVector<LLVMValueRef, 8> Args;
+ int ArgCount = LLVMGetNumArgOperands(Src);
+ for (int i = 0; i < ArgCount; i++)
+ Args.push_back(CloneValue(LLVMGetOperand(Src, i)));
+ LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src));
+ LLVMBasicBlockRef Then = DeclareBB(LLVMGetNormalDest(Src));
+ LLVMBasicBlockRef Unwind = DeclareBB(LLVMGetUnwindDest(Src));
+ Dst = LLVMBuildInvoke(Builder, Fn, Args.data(), ArgCount,
+ Then, Unwind, Name);
+ CloneAttrs(Src, Dst);
+ break;
+ }
+ case LLVMUnreachable:
+ Dst = LLVMBuildUnreachable(Builder);
+ break;
+ case LLVMAdd: {
+ LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
+ Dst = LLVMBuildAdd(Builder, LHS, RHS, Name);
+ break;
+ }
+ case LLVMSub: {
+ LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
+ Dst = LLVMBuildSub(Builder, LHS, RHS, Name);
+ break;
+ }
+ case LLVMMul: {
+ LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
+ Dst = LLVMBuildMul(Builder, LHS, RHS, Name);
+ break;
+ }
+ case LLVMUDiv: {
+ LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
+ Dst = LLVMBuildUDiv(Builder, LHS, RHS, Name);
+ break;
+ }
+ case LLVMSDiv: {
+ LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
+ Dst = LLVMBuildSDiv(Builder, LHS, RHS, Name);
+ break;
+ }
+ case LLVMURem: {
+ LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
+ Dst = LLVMBuildURem(Builder, LHS, RHS, Name);
+ break;
+ }
+ case LLVMSRem: {
+ LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
+ Dst = LLVMBuildSRem(Builder, LHS, RHS, Name);
+ break;
+ }
+ case LLVMShl: {
+ LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
+ Dst = LLVMBuildShl(Builder, LHS, RHS, Name);
+ break;
+ }
+ case LLVMLShr: {
+ LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
+ Dst = LLVMBuildLShr(Builder, LHS, RHS, Name);
+ break;
+ }
+ case LLVMAShr: {
+ LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
+ Dst = LLVMBuildAShr(Builder, LHS, RHS, Name);
+ break;
+ }
+ case LLVMAnd: {
+ LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
+ Dst = LLVMBuildAnd(Builder, LHS, RHS, Name);
+ break;
+ }
+ case LLVMOr: {
+ LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
+ Dst = LLVMBuildOr(Builder, LHS, RHS, Name);
+ break;
+ }
+ case LLVMXor: {
+ LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
+ Dst = LLVMBuildXor(Builder, LHS, RHS, Name);
+ break;
+ }
+ case LLVMAlloca: {
+ LLVMTypeRef Ty = CloneType(LLVMGetAllocatedType(Src));
+ Dst = LLVMBuildAlloca(Builder, Ty, Name);
+ break;
+ }
+ case LLVMLoad: {
+ LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 0));
+ Dst = LLVMBuildLoad(Builder, Ptr, Name);
+ LLVMSetAlignment(Dst, LLVMGetAlignment(Src));
+ break;
+ }
+ case LLVMStore: {
+ LLVMValueRef Val = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 1));
+ Dst = LLVMBuildStore(Builder, Val, Ptr);
+ LLVMSetAlignment(Dst, LLVMGetAlignment(Src));
+ break;
+ }
+ case LLVMGetElementPtr: {
+ LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 0));
+ SmallVector<LLVMValueRef, 8> Idx;
+ int NumIdx = LLVMGetNumIndices(Src);
+ for (int i = 1; i <= NumIdx; i++)
+ Idx.push_back(CloneValue(LLVMGetOperand(Src, i)));
+ if (LLVMIsInBounds(Src))
+ Dst = LLVMBuildInBoundsGEP(Builder, Ptr, Idx.data(), NumIdx, Name);
+ else
+ Dst = LLVMBuildGEP(Builder, Ptr, Idx.data(), NumIdx, Name);
+ break;
+ }
+ case LLVMAtomicCmpXchg: {
+ LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef Cmp = CloneValue(LLVMGetOperand(Src, 1));
+ LLVMValueRef New = CloneValue(LLVMGetOperand(Src, 2));
+ LLVMAtomicOrdering Succ = LLVMGetCmpXchgSuccessOrdering(Src);
+ LLVMAtomicOrdering Fail = LLVMGetCmpXchgFailureOrdering(Src);
+ LLVMBool SingleThread = LLVMIsAtomicSingleThread(Src);
+
+ Dst = LLVMBuildAtomicCmpXchg(Builder, Ptr, Cmp, New, Succ, Fail,
+ SingleThread);
+ } break;
+ case LLVMBitCast: {
+ LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 0));
+ Dst = LLVMBuildBitCast(Builder, V, CloneType(Src), Name);
+ break;
+ }
+ case LLVMICmp: {
+ LLVMIntPredicate Pred = LLVMGetICmpPredicate(Src);
+ LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
+ Dst = LLVMBuildICmp(Builder, Pred, LHS, RHS, Name);
+ break;
+ }
+ case LLVMPHI: {
+ // We need to agressively set things here because of loops.
+ VMap[Src] = Dst = LLVMBuildPhi(Builder, CloneType(Src), Name);
+
+ SmallVector<LLVMValueRef, 8> Values;
+ SmallVector<LLVMBasicBlockRef, 8> Blocks;
+
+ unsigned IncomingCount = LLVMCountIncoming(Src);
+ for (unsigned i = 0; i < IncomingCount; ++i) {
+ Blocks.push_back(DeclareBB(LLVMGetIncomingBlock(Src, i)));
+ Values.push_back(CloneValue(LLVMGetIncomingValue(Src, i)));
+ }
+
+ LLVMAddIncoming(Dst, Values.data(), Blocks.data(), IncomingCount);
+ return Dst;
+ }
+ case LLVMCall: {
+ SmallVector<LLVMValueRef, 8> Args;
+ int ArgCount = LLVMGetNumArgOperands(Src);
+ for (int i = 0; i < ArgCount; i++)
+ Args.push_back(CloneValue(LLVMGetOperand(Src, i)));
+ LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src));
+ Dst = LLVMBuildCall(Builder, Fn, Args.data(), ArgCount, Name);
+ LLVMSetTailCall(Dst, LLVMIsTailCall(Src));
+ CloneAttrs(Src, Dst);
+ break;
+ }
+ case LLVMResume: {
+ Dst = LLVMBuildResume(Builder, CloneValue(LLVMGetOperand(Src, 0)));
+ break;
+ }
+ case LLVMLandingPad: {
+ // The landing pad API is a bit screwed up for historical reasons.
+ Dst = LLVMBuildLandingPad(Builder, CloneType(Src), nullptr, 0, Name);
+ unsigned NumClauses = LLVMGetNumClauses(Src);
+ for (unsigned i = 0; i < NumClauses; ++i)
+ LLVMAddClause(Dst, CloneValue(LLVMGetClause(Src, i)));
+ LLVMSetCleanup(Dst, LLVMIsCleanup(Src));
+ break;
+ }
+ case LLVMExtractValue: {
+ LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
+ if (LLVMGetNumIndices(Src) != 1)
+ report_fatal_error("Expected only one indice");
+ auto I = LLVMGetIndices(Src)[0];
+ Dst = LLVMBuildExtractValue(Builder, Agg, I, Name);
+ break;
+ }
+ case LLVMInsertValue: {
+ LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 1));
+ if (LLVMGetNumIndices(Src) != 1)
+ report_fatal_error("Expected only one indice");
+ auto I = LLVMGetIndices(Src)[0];
+ Dst = LLVMBuildInsertValue(Builder, Agg, V, I, Name);
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (Dst == nullptr) {
+ fprintf(stderr, "%d is not a supported opcode\n", Op);
+ exit(-1);
+ }
+
+ check_value_kind(Dst, LLVMInstructionValueKind);
+ return VMap[Src] = Dst;
+ }
+
+ LLVMBasicBlockRef DeclareBB(LLVMBasicBlockRef Src) {
+ // Check if this is something we already computed.
+ {
+ auto i = BBMap.find(Src);
+ if (i != BBMap.end()) {
+ return i->second;
+ }
+ }
+
+ LLVMValueRef V = LLVMBasicBlockAsValue(Src);
+ if (!LLVMValueIsBasicBlock(V) || LLVMValueAsBasicBlock(V) != Src)
+ report_fatal_error("Basic block is not a basic block");
+
+ const char *Name = LLVMGetBasicBlockName(Src);
+ const char *VName = LLVMGetValueName(V);
+ if (Name != VName)
+ report_fatal_error("Basic block name mismatch");
+
+ LLVMBasicBlockRef BB = LLVMAppendBasicBlock(Fun, Name);
+ return BBMap[Src] = BB;
+ }
+
+ LLVMBasicBlockRef CloneBB(LLVMBasicBlockRef Src) {
+ LLVMBasicBlockRef BB = DeclareBB(Src);
+
+ // Make sure ordering is correct.
+ LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(Src);
+ if (Prev)
+ LLVMMoveBasicBlockAfter(BB, DeclareBB(Prev));
+
+ LLVMValueRef First = LLVMGetFirstInstruction(Src);
+ LLVMValueRef Last = LLVMGetLastInstruction(Src);
+
+ if (First == nullptr) {
+ if (Last != nullptr)
+ report_fatal_error("Has no first instruction, but last one");
+ return BB;
+ }
+
+ auto Ctx = LLVMGetModuleContext(M);
+ LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Ctx);
+ LLVMPositionBuilderAtEnd(Builder, BB);
+
+ LLVMValueRef Cur = First;
+ LLVMValueRef Next = nullptr;
+ while(true) {
+ CloneInstruction(Cur, Builder);
+ Next = LLVMGetNextInstruction(Cur);
+ if (Next == nullptr) {
+ if (Cur != Last)
+ report_fatal_error("Final instruction does not match Last");
+ break;
+ }
+
+ LLVMValueRef Prev = LLVMGetPreviousInstruction(Next);
+ if (Prev != Cur)
+ report_fatal_error("Next.Previous instruction is not Current");
+
+ Cur = Next;
+ }
+
+ LLVMDisposeBuilder(Builder);
+ return BB;
+ }
+
+ void CloneBBs(LLVMValueRef Src) {
+ unsigned Count = LLVMCountBasicBlocks(Src);
+ if (Count == 0)
+ return;
+
+ LLVMBasicBlockRef First = LLVMGetFirstBasicBlock(Src);
+ LLVMBasicBlockRef Last = LLVMGetLastBasicBlock(Src);
+
+ LLVMBasicBlockRef Cur = First;
+ LLVMBasicBlockRef Next = nullptr;
+ while(true) {
+ CloneBB(Cur);
+ Count--;
+ Next = LLVMGetNextBasicBlock(Cur);
+ if (Next == nullptr) {
+ if (Cur != Last)
+ report_fatal_error("Final basic block does not match Last");
+ break;
+ }
+
+ LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(Next);
+ if (Prev != Cur)
+ report_fatal_error("Next.Previous basic bloc is not Current");
+
+ Cur = Next;
+ }
+
+ if (Count != 0)
+ report_fatal_error("Basic block count does not match iterration");
+ }
+};
+
+static void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
+ LLVMValueRef Begin = LLVMGetFirstGlobal(Src);
+ LLVMValueRef End = LLVMGetLastGlobal(Src);
+
+ LLVMValueRef Cur = Begin;
+ LLVMValueRef Next = nullptr;
+ if (!Begin) {
+ if (End != nullptr)
+ report_fatal_error("Range has an end but no begining");
+ goto FunDecl;
+ }
+
+ while (true) {
+ const char *Name = LLVMGetValueName(Cur);
+ if (LLVMGetNamedGlobal(M, Name))
+ report_fatal_error("GlobalVariable already cloned");
+ LLVMAddGlobal(M, LLVMGetElementType(TypeCloner(M).Clone(Cur)), Name);
+
+ Next = LLVMGetNextGlobal(Cur);
+ if (Next == nullptr) {
+ if (Cur != End)
+ report_fatal_error("");
+ break;
+ }
+
+ LLVMValueRef Prev = LLVMGetPreviousGlobal(Next);
+ if (Prev != Cur)
+ report_fatal_error("Next.Previous global is not Current");
+
+ Cur = Next;
+ }
+
+FunDecl:
+ Begin = LLVMGetFirstFunction(Src);
+ End = LLVMGetLastFunction(Src);
+ if (!Begin) {
+ if (End != nullptr)
+ report_fatal_error("Range has an end but no begining");
+ return;
+ }
+
+ auto Ctx = LLVMGetModuleContext(M);
+
+ Cur = Begin;
+ Next = nullptr;
+ while (true) {
+ const char *Name = LLVMGetValueName(Cur);
+ if (LLVMGetNamedFunction(M, Name))
+ report_fatal_error("Function already cloned");
+ auto Ty = LLVMGetElementType(TypeCloner(M).Clone(Cur));
+ auto F = LLVMAddFunction(M, Name, Ty);
+
+ // Copy attributes
+ for (int i = LLVMAttributeFunctionIndex, c = LLVMCountParams(F);
+ i <= c; ++i) {
+ for (unsigned k = 0, e = LLVMGetLastEnumAttributeKind(); k < e; ++k) {
+ if (auto SrcA = LLVMGetEnumAttributeAtIndex(Cur, i, k)) {
+ auto Val = LLVMGetEnumAttributeValue(SrcA);
+ auto DstA = LLVMCreateEnumAttribute(Ctx, k, Val);
+ LLVMAddAttributeAtIndex(F, i, DstA);
+ }
+ }
+ }
+
+ Next = LLVMGetNextFunction(Cur);
+ if (Next == nullptr) {
+ if (Cur != End)
+ report_fatal_error("Last function does not match End");
+ break;
+ }
+
+ LLVMValueRef Prev = LLVMGetPreviousFunction(Next);
+ if (Prev != Cur)
+ report_fatal_error("Next.Previous function is not Current");
+
+ Cur = Next;
+ }
+}
+
+static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
+ LLVMValueRef Begin = LLVMGetFirstGlobal(Src);
+ LLVMValueRef End = LLVMGetLastGlobal(Src);
+
+ LLVMValueRef Cur = Begin;
+ LLVMValueRef Next = nullptr;
+ if (!Begin) {
+ if (End != nullptr)
+ report_fatal_error("Range has an end but no begining");
+ goto FunClone;
+ }
+
+ while (true) {
+ const char *Name = LLVMGetValueName(Cur);
+ LLVMValueRef G = LLVMGetNamedGlobal(M, Name);
+ if (!G)
+ report_fatal_error("GlobalVariable must have been declared already");
+
+ if (auto I = LLVMGetInitializer(Cur))
+ LLVMSetInitializer(G, clone_constant(I, M));
+
+ LLVMSetGlobalConstant(G, LLVMIsGlobalConstant(Cur));
+ LLVMSetThreadLocal(G, LLVMIsThreadLocal(Cur));
+ LLVMSetExternallyInitialized(G, LLVMIsExternallyInitialized(Cur));
+ LLVMSetLinkage(G, LLVMGetLinkage(Cur));
+ LLVMSetSection(G, LLVMGetSection(Cur));
+ LLVMSetVisibility(G, LLVMGetVisibility(Cur));
+ LLVMSetUnnamedAddr(G, LLVMHasUnnamedAddr(Cur));
+ LLVMSetAlignment(G, LLVMGetAlignment(Cur));
+
+ Next = LLVMGetNextGlobal(Cur);
+ if (Next == nullptr) {
+ if (Cur != End)
+ report_fatal_error("");
+ break;
+ }
+
+ LLVMValueRef Prev = LLVMGetPreviousGlobal(Next);
+ if (Prev != Cur)
+ report_fatal_error("Next.Previous global is not Current");
+
+ Cur = Next;
+ }
+
+FunClone:
+ Begin = LLVMGetFirstFunction(Src);
+ End = LLVMGetLastFunction(Src);
+ if (!Begin) {
+ if (End != nullptr)
+ report_fatal_error("Range has an end but no begining");
+ return;
+ }
+
+ Cur = Begin;
+ Next = nullptr;
+ while (true) {
+ const char *Name = LLVMGetValueName(Cur);
+ LLVMValueRef Fun = LLVMGetNamedFunction(M, Name);
+ if (!Fun)
+ report_fatal_error("Function must have been declared already");
+
+ if (LLVMHasPersonalityFn(Cur)) {
+ const char *FName = LLVMGetValueName(LLVMGetPersonalityFn(Cur));
+ LLVMValueRef P = LLVMGetNamedFunction(M, FName);
+ if (!P)
+ report_fatal_error("Could not find personality function");
+ LLVMSetPersonalityFn(Fun, P);
+ }
+
+ FunCloner FC(Cur, Fun);
+ FC.CloneBBs(Cur);
+
+ Next = LLVMGetNextFunction(Cur);
+ if (Next == nullptr) {
+ if (Cur != End)
+ report_fatal_error("Last function does not match End");
+ break;
+ }
+
+ LLVMValueRef Prev = LLVMGetPreviousFunction(Next);
+ if (Prev != Cur)
+ report_fatal_error("Next.Previous function is not Current");
+
+ Cur = Next;
+ }
+}
+
+int llvm_echo(void) {
+ LLVMEnablePrettyStackTrace();
+
+ LLVMModuleRef Src = llvm_load_module(false, true);
+ size_t Len;
+ const char *ModuleName = LLVMGetModuleIdentifier(Src, &Len);
+ LLVMContextRef Ctx = LLVMContextCreate();
+ LLVMModuleRef M = LLVMModuleCreateWithNameInContext(ModuleName, Ctx);
+
+ // This whole switcharound is done because the C API has no way to
+ // set the source_filename
+ LLVMSetModuleIdentifier(M, "", 0);
+ LLVMGetModuleIdentifier(M, &Len);
+ if (Len != 0)
+ report_fatal_error("LLVM{Set,Get}ModuleIdentifier failed");
+ LLVMSetModuleIdentifier(M, ModuleName, strlen(ModuleName));
+
+ LLVMSetTarget(M, LLVMGetTarget(Src));
+ LLVMSetModuleDataLayout(M, LLVMGetModuleDataLayout(Src));
+ if (strcmp(LLVMGetDataLayoutStr(M), LLVMGetDataLayoutStr(Src)))
+ report_fatal_error("Inconsistent DataLayout string representation");
+
+ declare_symbols(Src, M);
+ clone_symbols(Src, M);
+ char *Str = LLVMPrintModuleToString(M);
+ fputs(Str, stdout);
+
+ LLVMDisposeMessage(Str);
+ LLVMDisposeModule(M);
+ LLVMContextDispose(Ctx);
+
+ return 0;
+}
diff --git a/tools/llvm-c-test/helpers.c b/tools/llvm-c-test/helpers.c
index 1ea8a4f669952..97fbaab6d6c33 100644
--- a/tools/llvm-c-test/helpers.c
+++ b/tools/llvm-c-test/helpers.c
@@ -18,7 +18,7 @@
#define MAX_TOKENS 512
#define MAX_LINE_LEN 1024
-void tokenize_stdin(void (*cb)(char **tokens, int ntokens)) {
+void llvm_tokenize_stdin(void (*cb)(char **tokens, int ntokens)) {
char line[MAX_LINE_LEN];
char *tokbuf[MAX_TOKENS];
diff --git a/tools/llvm-c-test/llvm-c-test.h b/tools/llvm-c-test/llvm-c-test.h
index 7929fc4d19be7..0d1ade093bc7f 100644
--- a/tools/llvm-c-test/llvm-c-test.h
+++ b/tools/llvm-c-test/llvm-c-test.h
@@ -14,30 +14,46 @@
#define LLVM_C_TEST_H
#include <stdbool.h>
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
// helpers.c
-void tokenize_stdin(void (*cb)(char **tokens, int ntokens));
+void llvm_tokenize_stdin(void (*cb)(char **tokens, int ntokens));
// module.c
-int module_dump(bool Lazy, bool New);
-int module_list_functions(void);
-int module_list_globals(void);
+LLVMModuleRef llvm_load_module(bool Lazy, bool New);
+int llvm_module_dump(bool Lazy, bool New);
+int llvm_module_list_functions(void);
+int llvm_module_list_globals(void);
// calc.c
-int calc(void);
+int llvm_calc(void);
// disassemble.c
-int disassemble(void);
+int llvm_disassemble(void);
// metadata.c
-int add_named_metadata_operand(void);
-int set_metadata(void);
+int llvm_add_named_metadata_operand(void);
+int llvm_set_metadata(void);
// object.c
-int object_list_sections(void);
-int object_list_symbols(void);
+int llvm_object_list_sections(void);
+int llvm_object_list_symbols(void);
// targets.c
-int targets_list(void);
+int llvm_targets_list(void);
+
+// echo.c
+int llvm_echo(void);
+
+// diagnostic.c
+int llvm_test_diagnostic_handler(void);
+
+#ifdef __cplusplus
+}
+#endif /* !defined(__cplusplus) */
#endif
diff --git a/tools/llvm-c-test/main.c b/tools/llvm-c-test/main.c
index e6b6e17098b36..90d3501778516 100644
--- a/tools/llvm-c-test/main.c
+++ b/tools/llvm-c-test/main.c
@@ -13,7 +13,6 @@
#include "llvm-c-test.h"
#include "llvm-c/BitReader.h"
-#include "llvm-c/Core.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -22,20 +21,20 @@ 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, " Read bitcode from stdin - print disassembly\n\n");
fprintf(stderr, " * --lazy-module-dump\n");
fprintf(stderr,
- " Lazily read bytecode from stdin - print disassembly\n\n");
+ " Lazily read bitcode from stdin - print disassembly\n\n");
fprintf(stderr, " * --new-module-dump\n");
- fprintf(stderr, " Read bytecode from stdin - print disassembly\n\n");
+ fprintf(stderr, " Read bitcode from stdin - print disassembly\n\n");
fprintf(stderr, " * --lazy-new-module-dump\n");
fprintf(stderr,
- " Lazily read bytecode from stdin - print disassembly\n\n");
+ " Lazily read bitcode from stdin - print disassembly\n\n");
fprintf(stderr, " * --module-list-functions\n");
fprintf(stderr,
- " Read bytecode from stdin - list summary of functions\n\n");
+ " Read bitcode 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, " Read bitcode 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");
@@ -50,6 +49,12 @@ static void print_usage(void) {
fprintf(
stderr,
" Read lines of name, rpn from stdin - print generated module\n\n");
+ fprintf(stderr, " * --echo\n");
+ fprintf(stderr,
+ " Read bitcode file form stdin - print it back out\n\n");
+ fprintf(stderr, " * --test-diagnostic-handler\n");
+ fprintf(stderr,
+ " Read bitcode file form stdin with a diagnostic handler set\n\n");
}
int main(int argc, char **argv) {
@@ -58,31 +63,35 @@ int main(int argc, char **argv) {
LLVMInitializeCore(pr);
if (argc == 2 && !strcmp(argv[1], "--lazy-new-module-dump")) {
- return module_dump(true, true);
+ return llvm_module_dump(true, true);
} else if (argc == 2 && !strcmp(argv[1], "--new-module-dump")) {
- return module_dump(false, true);
+ return llvm_module_dump(false, true);
} else if (argc == 2 && !strcmp(argv[1], "--lazy-module-dump")) {
- return module_dump(true, false);
+ return llvm_module_dump(true, false);
} else if (argc == 2 && !strcmp(argv[1], "--module-dump")) {
- return module_dump(false, false);
+ return llvm_module_dump(false, false);
} else if (argc == 2 && !strcmp(argv[1], "--module-list-functions")) {
- return module_list_functions();
+ return llvm_module_list_functions();
} else if (argc == 2 && !strcmp(argv[1], "--module-list-globals")) {
- return module_list_globals();
+ return llvm_module_list_globals();
} else if (argc == 2 && !strcmp(argv[1], "--targets-list")) {
- return targets_list();
+ return llvm_targets_list();
} else if (argc == 2 && !strcmp(argv[1], "--object-list-sections")) {
- return object_list_sections();
+ return llvm_object_list_sections();
} else if (argc == 2 && !strcmp(argv[1], "--object-list-symbols")) {
- return object_list_symbols();
+ return llvm_object_list_symbols();
} else if (argc == 2 && !strcmp(argv[1], "--disassemble")) {
- return disassemble();
+ return llvm_disassemble();
} else if (argc == 2 && !strcmp(argv[1], "--calc")) {
- return calc();
+ return llvm_calc();
} else if (argc == 2 && !strcmp(argv[1], "--add-named-metadata-operand")) {
- return add_named_metadata_operand();
+ return llvm_add_named_metadata_operand();
} else if (argc == 2 && !strcmp(argv[1], "--set-metadata")) {
- return set_metadata();
+ return llvm_set_metadata();
+ } else if (argc == 2 && !strcmp(argv[1], "--echo")) {
+ return llvm_echo();
+ } else if (argc == 2 && !strcmp(argv[1], "--test-diagnostic-handler")) {
+ return llvm_test_diagnostic_handler();
} else {
print_usage();
}
diff --git a/tools/llvm-c-test/metadata.c b/tools/llvm-c-test/metadata.c
index b64a696c52810..89215b8ebcbd8 100644
--- a/tools/llvm-c-test/metadata.c
+++ b/tools/llvm-c-test/metadata.c
@@ -13,9 +13,8 @@
\*===----------------------------------------------------------------------===*/
#include "llvm-c-test.h"
-#include "llvm-c/Core.h"
-int add_named_metadata_operand(void) {
+int llvm_add_named_metadata_operand(void) {
LLVMModuleRef m = LLVMModuleCreateWithName("Mod");
LLVMValueRef values[] = { LLVMConstInt(LLVMInt32Type(), 0, 0) };
@@ -27,7 +26,7 @@ int add_named_metadata_operand(void) {
return 0;
}
-int set_metadata(void) {
+int llvm_set_metadata(void) {
LLVMBuilderRef b = LLVMCreateBuilder();
LLVMValueRef values[] = { LLVMConstInt(LLVMInt32Type(), 0, 0) };
diff --git a/tools/llvm-c-test/module.c b/tools/llvm-c-test/module.c
index a6c47bf5fa168..c47b55d502949 100644
--- a/tools/llvm-c-test/module.c
+++ b/tools/llvm-c-test/module.c
@@ -14,7 +14,6 @@
#include "llvm-c-test.h"
#include "llvm-c/BitReader.h"
-#include "llvm-c/Core.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -26,7 +25,7 @@ static void diagnosticHandler(LLVMDiagnosticInfoRef DI, void *C) {
exit(1);
}
-static LLVMModuleRef load_module(bool Lazy, bool New) {
+LLVMModuleRef llvm_load_module(bool Lazy, bool New) {
LLVMMemoryBufferRef MB;
LLVMModuleRef M;
char *msg = NULL;
@@ -63,8 +62,8 @@ static LLVMModuleRef load_module(bool Lazy, bool New) {
return M;
}
-int module_dump(bool Lazy, bool New) {
- LLVMModuleRef M = load_module(Lazy, New);
+int llvm_module_dump(bool Lazy, bool New) {
+ LLVMModuleRef M = llvm_load_module(Lazy, New);
char *irstr = LLVMPrintModuleToString(M);
puts(irstr);
@@ -75,8 +74,8 @@ int module_dump(bool Lazy, bool New) {
return 0;
}
-int module_list_functions(void) {
- LLVMModuleRef M = load_module(false, false);
+int llvm_module_list_functions(void) {
+ LLVMModuleRef M = llvm_load_module(false, false);
LLVMValueRef f;
f = LLVMGetFirstFunction(M);
@@ -116,8 +115,8 @@ int module_list_functions(void) {
return 0;
}
-int module_list_globals(void) {
- LLVMModuleRef M = load_module(false, false);
+int llvm_module_list_globals(void) {
+ LLVMModuleRef M = llvm_load_module(false, false);
LLVMValueRef g;
g = LLVMGetFirstGlobal(M);
diff --git a/tools/llvm-c-test/object.c b/tools/llvm-c-test/object.c
index 43521787b6099..809ad54f8721c 100644
--- a/tools/llvm-c-test/object.c
+++ b/tools/llvm-c-test/object.c
@@ -13,12 +13,11 @@
\*===----------------------------------------------------------------------===*/
#include "llvm-c-test.h"
-#include "llvm-c/Core.h"
#include "llvm-c/Object.h"
#include <stdio.h>
#include <stdlib.h>
-int object_list_sections(void) {
+int llvm_object_list_sections(void) {
LLVMMemoryBufferRef MB;
LLVMObjectFileRef O;
LLVMSectionIteratorRef sect;
@@ -50,7 +49,7 @@ int object_list_sections(void) {
return 0;
}
-int object_list_symbols(void) {
+int llvm_object_list_symbols(void) {
LLVMMemoryBufferRef MB;
LLVMObjectFileRef O;
LLVMSectionIteratorRef sect;
diff --git a/tools/llvm-c-test/targets.c b/tools/llvm-c-test/targets.c
index 252c2e02a67ab..f2a9e924a74a3 100644
--- a/tools/llvm-c-test/targets.c
+++ b/tools/llvm-c-test/targets.c
@@ -14,7 +14,7 @@
#include "llvm-c/TargetMachine.h"
#include <stdio.h>
-int targets_list(void) {
+int llvm_targets_list(void) {
LLVMTargetRef t;
LLVMInitializeAllTargetInfos();
LLVMInitializeAllTargets();