#ifndef LLVM_LINKER_LINKER_H
#define LLVM_LINKER_LINKER_H
-#include "llvm/ADT/SmallPtrSet.h"
-#include <string>
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/FunctionInfo.h"
namespace llvm {
-
class Module;
-class StringRef;
class StructType;
+class Type;
/// This class provides the core functionality of linking in LLVM. It keeps a
/// pointer to the merged module so far. It doesn't take ownership of the
/// module since it is assumed that the user of this class will want to do
/// something with it after the linking.
class Linker {
- public:
- enum LinkerMode {
- DestroySource = 0, // Allow source module to be destroyed.
- PreserveSource = 1 // Preserve the source module.
+public:
+ struct StructTypeKeyInfo {
+ struct KeyTy {
+ ArrayRef<Type *> ETypes;
+ bool IsPacked;
+ KeyTy(ArrayRef<Type *> E, bool P);
+ KeyTy(const StructType *ST);
+ bool operator==(const KeyTy &that) const;
+ bool operator!=(const KeyTy &that) const;
};
+ static StructType *getEmptyKey();
+ static StructType *getTombstoneKey();
+ static unsigned getHashValue(const KeyTy &Key);
+ static unsigned getHashValue(const StructType *ST);
+ static bool isEqual(const KeyTy &LHS, const StructType *RHS);
+ static bool isEqual(const StructType *LHS, const StructType *RHS);
+ };
+
+ typedef DenseSet<StructType *, StructTypeKeyInfo> NonOpaqueStructTypeSet;
+ typedef DenseSet<StructType *> OpaqueStructTypeSet;
+
+ struct IdentifiedStructTypeSet {
+ // The set of opaque types is the composite module.
+ OpaqueStructTypeSet OpaqueStructTypes;
+
+ // The set of identified but non opaque structures in the composite module.
+ NonOpaqueStructTypeSet NonOpaqueStructTypes;
+
+ void addNonOpaque(StructType *Ty);
+ void switchToNonOpaque(StructType *Ty);
+ void addOpaque(StructType *Ty);
+ StructType *findNonOpaque(ArrayRef<Type *> ETypes, bool IsPacked);
+ bool hasType(StructType *Ty);
+ };
+
+ enum Flags {
+ None = 0,
+ OverrideFromSrc = (1 << 0),
+ LinkOnlyNeeded = (1 << 1),
+ InternalizeLinkedSymbols = (1 << 2)
+ };
+
+ Linker(Module &M, DiagnosticHandlerFunction DiagnosticHandler);
+ Linker(Module &M);
- Linker(Module *M, bool SuppressWarnings=false);
- ~Linker();
+ /// \brief Link \p Src into the composite. The source is destroyed.
+ ///
+ /// Passing OverrideSymbols as true will have symbols from Src
+ /// shadow those in the Dest.
+ /// For ThinLTO function importing/exporting the \p FunctionInfoIndex
+ /// is passed. If \p FunctionsToImport is provided, only the functions that
+ /// are part of the set will be imported from the source module.
+ ///
+ /// Returns true on error.
+ bool linkInModule(Module &Src, unsigned Flags = Flags::None,
+ const FunctionInfoIndex *Index = nullptr,
+ DenseSet<const GlobalValue *> *FunctionsToImport = nullptr);
- Module *getModule() const { return Composite; }
- void deleteModule();
+ static bool linkModules(Module &Dest, Module &Src,
+ DiagnosticHandlerFunction DiagnosticHandler,
+ unsigned Flags = Flags::None);
- /// \brief Link \p Src into the composite. The source is destroyed if
- /// \p Mode is DestroySource and preserved if it is PreserveSource.
- /// If \p ErrorMsg is not null, information about any error is written
- /// to it.
- /// Returns true on error.
- bool linkInModule(Module *Src, unsigned Mode, std::string *ErrorMsg);
- bool linkInModule(Module *Src, std::string *ErrorMsg) {
- return linkInModule(Src, Linker::DestroySource, ErrorMsg);
- }
+ static bool linkModules(Module &Dest, Module &Src,
+ unsigned Flags = Flags::None);
- static bool LinkModules(Module *Dest, Module *Src, unsigned Mode,
- std::string *ErrorMsg);
+private:
+ Module &Composite;
- private:
- Module *Composite;
- SmallPtrSet<StructType*, 32> IdentifiedStructTypes;
+ IdentifiedStructTypeSet IdentifiedStructTypes;
- bool SuppressWarnings;
+ DiagnosticHandlerFunction DiagnosticHandler;
};
} // End llvm namespace