summaryrefslogtreecommitdiffstats
path: root/include/llvm/Linker/Linker.h
blob: aac9dcdcb36bb6bc932018f33e27d8980404a21d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//===- Linker.h - Module Linker Interface -----------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LINKER_LINKER_H
#define LLVM_LINKER_LINKER_H

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/IR/DiagnosticInfo.h"

namespace llvm {
class Module;
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:
  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 addOpaque(StructType *Ty);
    StructType *findNonOpaque(ArrayRef<Type *> ETypes, bool IsPacked);
    bool hasType(StructType *Ty);
  };

  Linker(Module *M, DiagnosticHandlerFunction DiagnosticHandler);
  Linker(Module *M);
  ~Linker();

  Module *getModule() const { return Composite; }
  void deleteModule();

  /// \brief Link \p Src into the composite. The source is destroyed.
  /// Returns true on error.
  bool linkInModule(Module *Src);

  /// \brief Set the composite to the passed-in module.
  void setModule(Module *Dst);

  static bool LinkModules(Module *Dest, Module *Src,
                          DiagnosticHandlerFunction DiagnosticHandler);

  static bool LinkModules(Module *Dest, Module *Src);

private:
  void init(Module *M, DiagnosticHandlerFunction DiagnosticHandler);
  Module *Composite;

  IdentifiedStructTypeSet IdentifiedStructTypes;

  DiagnosticHandlerFunction DiagnosticHandler;
};

} // End llvm namespace

#endif