OSDN Git Service

[LLVM-C] [bindings/go] Add C and Golang bindings for COMDAT
authorReid Kleckner <rnk@google.com>
Wed, 14 Mar 2018 18:33:53 +0000 (18:33 +0000)
committerReid Kleckner <rnk@google.com>
Wed, 14 Mar 2018 18:33:53 +0000 (18:33 +0000)
Patch by Ben Clayton

Differential Revision: https://reviews.llvm.org/D44086

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327551 91177308-0d34-0410-b5e6-96231b3b80d8

bindings/go/llvm/ir.go
include/llvm-c/Comdat.h [new file with mode: 0644]
include/llvm-c/Types.h
include/llvm/IR/Comdat.h
lib/IR/Comdat.cpp

index 71b11a6..0a379e4 100644 (file)
@@ -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 (file)
index 0000000..499996d
--- /dev/null
@@ -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
index 970980b..f08610e 100644 (file)
@@ -135,6 +135,11 @@ typedef struct LLVMOpaqueAttributeRef *LLVMAttributeRef;
 typedef struct LLVMOpaqueDiagnosticInfo *LLVMDiagnosticInfoRef;
 
 /**
+ * @see llvm::Comdat
+ */
+typedef struct LLVMComdat *LLVMComdatRef;
+
+/**
  * @}
  */
 
index fa87093..555121e 100644 (file)
@@ -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;
index c735f9b..3b1f7d6 100644 (file)
@@ -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;
+  }
+}