Index: llvm/trunk/bindings/go/llvm/ir.go =================================================================== --- llvm/trunk/bindings/go/llvm/ir.go +++ llvm/trunk/bindings/go/llvm/ir.go @@ -15,6 +15,7 @@ /* #include "llvm-c/Core.h" +#include "llvm-c/Comdat.h" #include "IRBindings.h" #include */ @@ -37,6 +38,9 @@ Value struct { C C.LLVMValueRef } + Comdat struct { + C C.LLVMComdatRef + } BasicBlock struct { C C.LLVMBasicBlockRef } @@ -61,14 +65,15 @@ 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 @@ ) //------------------------------------------------------------------------- +// 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 @@ 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) Index: llvm/trunk/include/llvm-c/Comdat.h =================================================================== --- llvm/trunk/include/llvm-c/Comdat.h +++ llvm/trunk/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 Index: llvm/trunk/include/llvm-c/Types.h =================================================================== --- llvm/trunk/include/llvm-c/Types.h +++ llvm/trunk/include/llvm-c/Types.h @@ -135,6 +135,11 @@ typedef struct LLVMOpaqueDiagnosticInfo *LLVMDiagnosticInfoRef; /** + * @see llvm::Comdat + */ +typedef struct LLVMComdat *LLVMComdatRef; + +/** * @} */ Index: llvm/trunk/include/llvm/IR/Comdat.h =================================================================== --- llvm/trunk/include/llvm/IR/Comdat.h +++ llvm/trunk/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 @@ 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: llvm/trunk/lib/IR/Comdat.cpp =================================================================== --- llvm/trunk/lib/IR/Comdat.cpp +++ llvm/trunk/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() = 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(V); + return wrap(G->getComdat()); +} + +void LLVMSetComdat(LLVMValueRef V, LLVMComdatRef C) { + GlobalObject *G = unwrap(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; + } +}