summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bindings/go/llvm/ir.go52
-rw-r--r--include/llvm-c/Comdat.h75
-rw-r--r--include/llvm-c/Types.h5
-rw-r--r--include/llvm/IR/Comdat.h6
-rw-r--r--lib/IR/Comdat.cpp58
5 files changed, 186 insertions, 10 deletions
diff --git a/bindings/go/llvm/ir.go b/bindings/go/llvm/ir.go
index 71b11a6668e..0a379e47dc6 100644
--- a/bindings/go/llvm/ir.go
+++ b/bindings/go/llvm/ir.go
@@ -15,6 +15,7 @@ package llvm
/*
#include "llvm-c/Core.h"
+#include "llvm-c/Comdat.h"
#include "IRBindings.h"
#include <stdlib.h>
*/
@@ -37,6 +38,9 @@ type (
Value struct {
C C.LLVMValueRef
}
+ Comdat struct {
+ C C.LLVMComdatRef
+ }
BasicBlock struct {
C C.LLVMBasicBlockRef
}
@@ -61,14 +65,15 @@ type (
Attribute struct {
C C.LLVMAttributeRef
}
- Opcode C.LLVMOpcode
- TypeKind C.LLVMTypeKind
- Linkage C.LLVMLinkage
- Visibility C.LLVMVisibility
- CallConv C.LLVMCallConv
- IntPredicate C.LLVMIntPredicate
- FloatPredicate C.LLVMRealPredicate
- LandingPadClause C.LLVMLandingPadClauseTy
+ Opcode C.LLVMOpcode
+ TypeKind C.LLVMTypeKind
+ Linkage C.LLVMLinkage
+ Visibility C.LLVMVisibility
+ CallConv C.LLVMCallConv
+ ComdatSelectionKind C.LLVMComdatSelectionKind
+ IntPredicate C.LLVMIntPredicate
+ FloatPredicate C.LLVMRealPredicate
+ LandingPadClause C.LLVMLandingPadClauseTy
)
func (c Context) IsNil() bool { return c.C == nil }
@@ -249,6 +254,18 @@ const (
)
//-------------------------------------------------------------------------
+// llvm.ComdatSelectionKind
+//-------------------------------------------------------------------------
+
+const (
+ AnyComdatSelectionKind ComdatSelectionKind = C.LLVMAnyComdatSelectionKind
+ ExactMatchComdatSelectionKind ComdatSelectionKind = C.LLVMExactMatchComdatSelectionKind
+ LargestComdatSelectionKind ComdatSelectionKind = C.LLVMLargestComdatSelectionKind
+ NoDuplicatesComdatSelectionKind ComdatSelectionKind = C.LLVMNoDuplicatesComdatSelectionKind
+ SameSizeComdatSelectionKind ComdatSelectionKind = C.LLVMSameSizeComdatSelectionKind
+)
+
+//-------------------------------------------------------------------------
// llvm.IntPredicate
//-------------------------------------------------------------------------
@@ -1029,6 +1046,25 @@ func AddAlias(m Module, t Type, aliasee Value, name string) (v Value) {
return
}
+// Operations on comdat
+func (m Module) Comdat(name string) (c Comdat) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ c.C = C.LLVMGetOrInsertComdat(m.C, cname)
+ return
+}
+
+func (v Value) Comdat() (c Comdat) { c.C = C.LLVMGetComdat(v.C); return }
+func (v Value) SetComdat(c Comdat) { C.LLVMSetComdat(v.C, c.C) }
+
+func (c Comdat) SelectionKind() ComdatSelectionKind {
+ return ComdatSelectionKind(C.LLVMGetComdatSelectionKind(c.C))
+}
+
+func (c Comdat) SetSelectionKind(k ComdatSelectionKind) {
+ C.LLVMSetComdatSelectionKind(c.C, (C.LLVMComdatSelectionKind)(k))
+}
+
// Operations on functions
func AddFunction(m Module, name string, ft Type) (v Value) {
cname := C.CString(name)
diff --git a/include/llvm-c/Comdat.h b/include/llvm-c/Comdat.h
new file mode 100644
index 00000000000..499996d68a5
--- /dev/null
+++ b/include/llvm-c/Comdat.h
@@ -0,0 +1,75 @@
+/*===-- llvm-c/Comdat.h - Module Comdat C Interface -------------*- C++ -*-===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This file defines the C interface to COMDAT. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_COMDAT_H
+#define LLVM_C_COMDAT_H
+
+#include "llvm-c/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ LLVMAnyComdatSelectionKind, ///< The linker may choose any COMDAT.
+ LLVMExactMatchComdatSelectionKind, ///< The data referenced by the COMDAT must
+ ///< be the same.
+ LLVMLargestComdatSelectionKind, ///< The linker will choose the largest
+ ///< COMDAT.
+ LLVMNoDuplicatesComdatSelectionKind, ///< No other Module may specify this
+ ///< COMDAT.
+ LLVMSameSizeComdatSelectionKind ///< The data referenced by the COMDAT must be
+ ///< the same size.
+} LLVMComdatSelectionKind;
+
+/**
+ * Return the Comdat in the module with the specified name. It is created
+ * if it didn't already exist.
+ *
+ * @see llvm::Module::getOrInsertComdat()
+ */
+LLVMComdatRef LLVMGetOrInsertComdat(LLVMModuleRef M, const char *Name);
+
+/**
+ * Get the Comdat assigned to the given global object.
+ *
+ * @see llvm::GlobalObject::getComdat()
+ */
+LLVMComdatRef LLVMGetComdat(LLVMValueRef V);
+
+/**
+ * Assign the Comdat to the given global object.
+ *
+ * @see llvm::GlobalObject::setComdat()
+ */
+void LLVMSetComdat(LLVMValueRef V, LLVMComdatRef C);
+
+/*
+ * Get the conflict resolution selection kind for the Comdat.
+ *
+ * @see llvm::Comdat::getSelectionKind()
+ */
+LLVMComdatSelectionKind LLVMGetComdatSelectionKind(LLVMComdatRef C);
+
+/*
+ * Set the conflict resolution selection kind for the Comdat.
+ *
+ * @see llvm::Comdat::setSelectionKind()
+ */
+void LLVMSetComdatSelectionKind(LLVMComdatRef C, LLVMComdatSelectionKind Kind);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/llvm-c/Types.h b/include/llvm-c/Types.h
index 970980b1f23..f08610e5c90 100644
--- a/include/llvm-c/Types.h
+++ b/include/llvm-c/Types.h
@@ -135,6 +135,11 @@ typedef struct LLVMOpaqueAttributeRef *LLVMAttributeRef;
typedef struct LLVMOpaqueDiagnosticInfo *LLVMDiagnosticInfoRef;
/**
+ * @see llvm::Comdat
+ */
+typedef struct LLVMComdat *LLVMComdatRef;
+
+/**
* @}
*/
diff --git a/include/llvm/IR/Comdat.h b/include/llvm/IR/Comdat.h
index fa87093ca50..555121e928f 100644
--- a/include/llvm/IR/Comdat.h
+++ b/include/llvm/IR/Comdat.h
@@ -16,6 +16,9 @@
#ifndef LLVM_IR_COMDAT_H
#define LLVM_IR_COMDAT_H
+#include "llvm-c/Types.h"
+#include "llvm/Support/CBindingWrapping.h"
+
namespace llvm {
class raw_ostream;
@@ -55,6 +58,9 @@ private:
SelectionKind SK = Any;
};
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Comdat, LLVMComdatRef)
+
inline raw_ostream &operator<<(raw_ostream &OS, const Comdat &C) {
C.print(OS);
return OS;
diff --git a/lib/IR/Comdat.cpp b/lib/IR/Comdat.cpp
index c735f9b2eb1..3b1f7d62cda 100644
--- a/lib/IR/Comdat.cpp
+++ b/lib/IR/Comdat.cpp
@@ -7,13 +7,16 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements the Comdat class.
+// This file implements the Comdat class (including the C bindings).
//
//===----------------------------------------------------------------------===//
-#include "llvm/IR/Comdat.h"
+#include "llvm-c/Comdat.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/Comdat.h"
+#include "llvm/IR/GlobalObject.h"
+#include "llvm/IR/Module.h"
using namespace llvm;
@@ -22,3 +25,54 @@ Comdat::Comdat(Comdat &&C) : Name(C.Name), SK(C.SK) {}
Comdat::Comdat() = default;
StringRef Comdat::getName() const { return Name->first(); }
+
+LLVMComdatRef LLVMGetOrInsertComdat(LLVMModuleRef M, const char *Name) {
+ return wrap(unwrap(M)->getOrInsertComdat(Name));
+}
+
+LLVMComdatRef LLVMGetComdat(LLVMValueRef V) {
+ GlobalObject *G = unwrap<GlobalObject>(V);
+ return wrap(G->getComdat());
+}
+
+void LLVMSetComdat(LLVMValueRef V, LLVMComdatRef C) {
+ GlobalObject *G = unwrap<GlobalObject>(V);
+ G->setComdat(unwrap(C));
+}
+
+LLVMComdatSelectionKind LLVMGetComdatSelectionKind(LLVMComdatRef C) {
+ switch (unwrap(C)->getSelectionKind()) {
+ case Comdat::Any:
+ return LLVMAnyComdatSelectionKind;
+ case Comdat::ExactMatch:
+ return LLVMExactMatchComdatSelectionKind;
+ case Comdat::Largest:
+ return LLVMLargestComdatSelectionKind;
+ case Comdat::NoDuplicates:
+ return LLVMNoDuplicatesComdatSelectionKind;
+ case Comdat::SameSize:
+ return LLVMSameSizeComdatSelectionKind;
+ }
+ llvm_unreachable("Invalid Comdat SelectionKind!");
+}
+
+void LLVMSetComdatSelectionKind(LLVMComdatRef C, LLVMComdatSelectionKind kind) {
+ Comdat *Cd = unwrap(C);
+ switch (kind) {
+ case LLVMAnyComdatSelectionKind:
+ Cd->setSelectionKind(Comdat::Any);
+ break;
+ case LLVMExactMatchComdatSelectionKind:
+ Cd->setSelectionKind(Comdat::ExactMatch);
+ break;
+ case LLVMLargestComdatSelectionKind:
+ Cd->setSelectionKind(Comdat::Largest);
+ break;
+ case LLVMNoDuplicatesComdatSelectionKind:
+ Cd->setSelectionKind(Comdat::NoDuplicates);
+ break;
+ case LLVMSameSizeComdatSelectionKind:
+ Cd->setSelectionKind(Comdat::SameSize);
+ break;
+ }
+}