1651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===--- Multilib.h ---------------------------------------------*- C++ -*-===//
2651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//
3651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//                     The LLVM Compiler Infrastructure
4651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//
5651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// This file is distributed under the University of Illinois Open Source
6651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// License. See LICENSE.TXT for details.
7651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//
8651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===----------------------------------------------------------------------===//
9651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
10651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#ifndef CLANG_LIB_DRIVER_MULTILIB_H_
11651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#define CLANG_LIB_DRIVER_MULTILIB_H_
12651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
13651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/Basic/LLVM.h"
14651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/ADT/Triple.h"
15651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/Option/Option.h"
16651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <string>
17651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <vector>
18651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
19651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace clang {
20651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace driver {
21651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
22651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// This corresponds to a single GCC Multilib, or a segment of one controlled
23651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// by a command line flag
24651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass Multilib {
25651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic:
26651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef std::vector<std::string> flags_list;
27651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
28651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesprivate:
29651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::string GCCSuffix;
30651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::string OSSuffix;
31651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::string IncludeSuffix;
32651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  flags_list Flags;
33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic:
35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Multilib(StringRef GCCSuffix = "", StringRef OSSuffix = "",
36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines           StringRef IncludeSuffix = "");
37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief Get the detected GCC installation path suffix for the multi-arch
39651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// target variant. Always starts with a '/', unless empty
40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const std::string &gccSuffix() const {
41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    assert(GCCSuffix.empty() ||
42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines           (StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1));
43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return GCCSuffix;
44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Set the GCC installation path suffix.
46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Multilib &gccSuffix(StringRef S);
47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief Get the detected os path suffix for the multi-arch
49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// target variant. Always starts with a '/', unless empty
50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const std::string &osSuffix() const {
51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    assert(OSSuffix.empty() ||
52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines           (StringRef(OSSuffix).front() == '/' && OSSuffix.size() > 1));
53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return OSSuffix;
54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Set the os path suffix.
56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Multilib &osSuffix(StringRef S);
57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief Get the include directory suffix. Always starts with a '/', unless
59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// empty
60651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const std::string &includeSuffix() const {
61651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    assert(IncludeSuffix.empty() ||
62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines           (StringRef(IncludeSuffix).front() == '/' && IncludeSuffix.size() > 1));
63651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return IncludeSuffix;
64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Set the include directory suffix
66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Multilib &includeSuffix(StringRef S);
67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief Get the flags that indicate or contraindicate this multilib's use
69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// All elements begin with either '+' or '-'
70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const flags_list &flags() const { return Flags; }
71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  flags_list &flags() { return Flags; }
72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Add a flag to the flags list
73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Multilib &flag(StringRef F) {
74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    assert(F.front() == '+' || F.front() == '-');
75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Flags.push_back(F);
76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return *this;
77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
78651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
79651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief print summary of the Multilib
80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void print(raw_ostream &OS) const;
81651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Check whether any of the 'against' flags contradict the 'for' flags.
83651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool isValid() const;
84651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
85651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Check whether the default is selected
86651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool isDefault() const
87651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  { return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty(); }
88651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
89651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool operator==(const Multilib &Other) const;
90651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
92651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesraw_ostream &operator<<(raw_ostream &OS, const Multilib &M);
93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass MultilibSet {
95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic:
96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef std::vector<Multilib> multilib_list;
97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef multilib_list::iterator iterator;
98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef multilib_list::const_iterator const_iterator;
99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  struct FilterCallback {
101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    virtual ~FilterCallback() {};
102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// \return true iff the filter should remove the Multilib from the set
103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    virtual bool operator()(const Multilib &M) const = 0;
104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesprivate:
107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  multilib_list Multilibs;
108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic:
110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  MultilibSet() {}
111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Add an optional Multilib segment
113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  MultilibSet &Maybe(const Multilib &M);
114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Add a set of mutually incompatible Multilib segments
116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  MultilibSet &Either(const Multilib &M1, const Multilib &M2);
117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  MultilibSet &Either(const Multilib &M1, const Multilib &M2,
118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      const Multilib &M3);
119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  MultilibSet &Either(const Multilib &M1, const Multilib &M2,
120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      const Multilib &M3, const Multilib &M4);
121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  MultilibSet &Either(const Multilib &M1, const Multilib &M2,
122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      const Multilib &M3, const Multilib &M4,
123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      const Multilib &M5);
124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  MultilibSet &Either(const std::vector<Multilib> &Ms);
125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Filter out some subset of the Multilibs using a user defined callback
127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  MultilibSet &FilterOut(const FilterCallback &F);
128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Filter out those Multilibs whose gccSuffix matches the given expression
129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  MultilibSet &FilterOut(std::string Regex);
130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Add a completed Multilib to the set
132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void push_back(const Multilib &M);
133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Union this set of multilibs with another
135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void combineWith(const MultilibSet &MS);
136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Remove all of thie multilibs from the set
138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void clear() { Multilibs.clear(); }
139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  iterator begin() { return Multilibs.begin(); }
141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const_iterator begin() const { return Multilibs.begin(); }
142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  iterator end() { return Multilibs.end(); }
144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const_iterator end() const { return Multilibs.end(); }
145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Pick the best multilib in the set, \returns false if none are compatible
147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool select(const Multilib::flags_list &Flags, Multilib &M) const;
148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned size() const { return Multilibs.size(); }
150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void print(raw_ostream &OS) const;
152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesprivate:
154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Apply the filter to Multilibs and return the subset that remains
155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  static multilib_list filterCopy(const FilterCallback &F,
156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                  const multilib_list &Ms);
157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Apply the filter to the multilib_list, removing those that don't match
159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  static void filterInPlace(const FilterCallback &F, multilib_list &Ms);
160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesraw_ostream &operator<<(raw_ostream &OS, const MultilibSet &MS);
163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif
167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
168