コード例 #1
0
ファイル: MultilibTest.cpp プロジェクト: 4ntoine/clang
TEST(MultilibTest, SetSelection2) {
  MultilibSet MS2 = MultilibSet()
    .Maybe(Multilib("el").flag("+EL"))
    .Maybe(Multilib("sf").flag("+SF"));

  for (unsigned I = 0; I < 4; ++I) {
    bool IsEL = I & 0x1;
    bool IsSF = I & 0x2;
    Multilib::flags_list Flags;
    if (IsEL)
      Flags.push_back("+EL");
    else
      Flags.push_back("-EL");

    if (IsSF)
      Flags.push_back("+SF");
    else
      Flags.push_back("-SF");

    Multilib Selection;
    ASSERT_TRUE(MS2.select(Flags, Selection)) << "Selection failed for "
                                              << (IsEL ? "+EL" : "-EL") << " "
                                              << (IsSF ? "+SF" : "-SF");

    std::string Suffix;
    if (IsEL)
      Suffix += "/el";
    if (IsSF)
      Suffix += "/sf";

    ASSERT_EQ(Selection.gccSuffix(), Suffix) << "Selection picked " << Selection
                                             << " which was not expected ";
  }
}
コード例 #2
0
ファイル: Multilib.cpp プロジェクト: C0deZLee/llvm-dsa
MultilibSet &MultilibSet::Maybe(const Multilib &M) {
  Multilib Opposite;
  // Negate any '+' flags
  for (StringRef Flag : M.flags()) {
    if (Flag.front() == '+')
      Opposite.flags().push_back(("-" + Flag.substr(1)).str());
  }
  return Either(M, Opposite);
}
コード例 #3
0
ファイル: MultilibTest.cpp プロジェクト: 4ntoine/clang
TEST(MultilibTest, Construction3) {
  Multilib M = Multilib().flag("+f1").flag("+f2").flag("-f3");
  for (Multilib::flags_list::const_iterator I = M.flags().begin(),
                                            E = M.flags().end();
       I != E; ++I) {
    ASSERT_TRUE(llvm::StringSwitch<bool>(*I)
                    .Cases("+f1", "+f2", "-f3", true)
                    .Default(false));
  }
}
コード例 #4
0
ファイル: MultilibTest.cpp プロジェクト: 4ntoine/clang
static bool hasFlag(const Multilib &M, StringRef Flag) {
  for (Multilib::flags_list::const_iterator I = M.flags().begin(),
                                            E = M.flags().end();
       I != E; ++I) {
    if (*I == Flag)
      return true;
    else if (StringRef(*I).substr(1) == Flag.substr(1))
      return false;
  }
  return false;
}
コード例 #5
0
ファイル: Multilib.cpp プロジェクト: C0deZLee/llvm-dsa
bool MultilibSet::select(const Multilib::flags_list &Flags, Multilib &M) const {
  llvm::StringMap<bool> FlagSet;

  // Stuff all of the flags into the FlagSet such that a true mappend indicates
  // the flag was enabled, and a false mappend indicates the flag was disabled.
  for (StringRef Flag : Flags)
    FlagSet[Flag.substr(1)] = isFlagEnabled(Flag);

  multilib_list Filtered = filterCopy([&FlagSet](const Multilib &M) {
    for (StringRef Flag : M.flags()) {
      llvm::StringMap<bool>::const_iterator SI = FlagSet.find(Flag.substr(1));
      if (SI != FlagSet.end())
        if (SI->getValue() != isFlagEnabled(Flag))
          return true;
    }
    return false;
  }, Multilibs);

  if (Filtered.size() == 0) {
    return false;
  } else if (Filtered.size() == 1) {
    M = Filtered[0];
    return true;
  }

  // TODO: pick the "best" multlib when more than one is suitable
  assert(false);

  return false;
}
コード例 #6
0
ファイル: Multilib.cpp プロジェクト: C0deZLee/llvm-dsa
static Multilib compose(const Multilib &Base, const Multilib &New) {
  SmallString<128> GCCSuffix;
  llvm::sys::path::append(GCCSuffix, "/", Base.gccSuffix(), New.gccSuffix());
  SmallString<128> OSSuffix;
  llvm::sys::path::append(OSSuffix, "/", Base.osSuffix(), New.osSuffix());
  SmallString<128> IncludeSuffix;
  llvm::sys::path::append(IncludeSuffix, "/", Base.includeSuffix(),
                          New.includeSuffix());

  Multilib Composed(GCCSuffix, OSSuffix, IncludeSuffix);

  Multilib::flags_list &Flags = Composed.flags();

  Flags.insert(Flags.end(), Base.flags().begin(), Base.flags().end());
  Flags.insert(Flags.end(), New.flags().begin(), New.flags().end());

  return Composed;
}
コード例 #7
0
ファイル: Multilib.cpp プロジェクト: ADonut/LLVM-GPGPU
 bool operator()(const Multilib &M) const override {
   for (StringRef Flag : M.flags()) {
     llvm::StringMap<bool>::const_iterator SI = FlagSet.find(Flag.substr(1));
     if (SI != FlagSet.end())
       if (SI->getValue() != isFlagEnabled(Flag))
         return true;
   }
   return false;
 }
コード例 #8
0
ファイル: Multilib.cpp プロジェクト: ADonut/LLVM-GPGPU
 bool operator()(const Multilib &M) const override {
   std::string Error;
   if (!R.isValid(Error)) {
     llvm::errs() << Error;
     assert(false);
     return false;
   }
   return R.match(M.gccSuffix());
 }
コード例 #9
0
ファイル: Multilib.cpp プロジェクト: C0deZLee/llvm-dsa
MultilibSet &MultilibSet::Either(ArrayRef<Multilib> MultilibSegments) {
  multilib_list Composed;

  if (Multilibs.empty())
    Multilibs.insert(Multilibs.end(), MultilibSegments.begin(),
                     MultilibSegments.end());
  else {
    for (const Multilib &New : MultilibSegments) {
      for (const Multilib &Base : *this) {
        Multilib MO = compose(Base, New);
        if (MO.isValid())
          Composed.push_back(MO);
      }
    }

    Multilibs = Composed;
  }

  return *this;
}
コード例 #10
0
ファイル: Multilib.cpp プロジェクト: C0deZLee/llvm-dsa
bool Multilib::operator==(const Multilib &Other) const {
  // Check whether the flags sets match
  // allowing for the match to be order invariant
  llvm::StringSet<> MyFlags;
  for (const auto &Flag : Flags)
    MyFlags.insert(Flag);

  for (const auto &Flag : Other.Flags)
    if (MyFlags.find(Flag) == MyFlags.end())
      return false;

  if (osSuffix() != Other.osSuffix())
    return false;

  if (gccSuffix() != Other.gccSuffix())
    return false;

  if (includeSuffix() != Other.includeSuffix())
    return false;

  return true;
}
コード例 #11
0
ファイル: Linux.cpp プロジェクト: bgabor666/clang
Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
    : Generic_ELF(D, Triple, Args) {
  GCCInstallation.init(Triple, Args);
  Multilibs = GCCInstallation.getMultilibs();
  llvm::Triple::ArchType Arch = Triple.getArch();
  std::string SysRoot = computeSysRoot();

  // Cross-compiling binutils and GCC installations (vanilla and openSUSE at
  // least) put various tools in a triple-prefixed directory off of the parent
  // of the GCC installation. We use the GCC triple here to ensure that we end
  // up with tools that support the same amount of cross compiling as the
  // detected GCC installation. For example, if we find a GCC installation
  // targeting x86_64, but it is a bi-arch GCC installation, it can also be
  // used to target i386.
  // FIXME: This seems unlikely to be Linux-specific.
  ToolChain::path_list &PPaths = getProgramPaths();
  PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
                         GCCInstallation.getTriple().str() + "/bin")
                       .str());

  Distro Distro(D.getVFS());

  if (Distro.IsOpenSUSE() || Distro.IsUbuntu()) {
    ExtraOpts.push_back("-z");
    ExtraOpts.push_back("relro");
  }

  if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)
    ExtraOpts.push_back("-X");

  const bool IsAndroid = Triple.isAndroid();
  const bool IsMips = tools::isMipsArch(Arch);
  const bool IsHexagon = Arch == llvm::Triple::hexagon;

  if (IsMips && !SysRoot.empty())
    ExtraOpts.push_back("--sysroot=" + SysRoot);

  // Do not use 'gnu' hash style for Mips targets because .gnu.hash
  // and the MIPS ABI require .dynsym to be sorted in different ways.
  // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS
  // ABI requires a mapping between the GOT and the symbol table.
  // Android loader does not support .gnu.hash.
  // Hexagon linker/loader does not support .gnu.hash
  if (!IsMips && !IsAndroid && !IsHexagon) {
    if (Distro.IsRedhat() || Distro.IsOpenSUSE() ||
        (Distro.IsUbuntu() && Distro >= Distro::UbuntuMaverick))
      ExtraOpts.push_back("--hash-style=gnu");

    if (Distro.IsDebian() || Distro.IsOpenSUSE() || Distro == Distro::UbuntuLucid ||
        Distro == Distro::UbuntuJaunty || Distro == Distro::UbuntuKarmic)
      ExtraOpts.push_back("--hash-style=both");
  }

  if (Distro.IsRedhat() && Distro != Distro::RHEL5 && Distro != Distro::RHEL6)
    ExtraOpts.push_back("--no-add-needed");

#ifdef ENABLE_LINKER_BUILD_ID
  ExtraOpts.push_back("--build-id");
#endif

  if (Distro.IsOpenSUSE())
    ExtraOpts.push_back("--enable-new-dtags");

  // The selection of paths to try here is designed to match the patterns which
  // the GCC driver itself uses, as this is part of the GCC-compatible driver.
  // This was determined by running GCC in a fake filesystem, creating all
  // possible permutations of these directories, and seeing which ones it added
  // to the link paths.
  path_list &Paths = getFilePaths();

  const std::string OSLibDir = getOSLibDir(Triple, Args);
  const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);

  // Add the multilib suffixed paths where they are available.
  if (GCCInstallation.isValid()) {
    const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
    const std::string &LibPath = GCCInstallation.getParentLibPath();
    const Multilib &Multilib = GCCInstallation.getMultilib();
    const MultilibSet &Multilibs = GCCInstallation.getMultilibs();

    // Add toolchain / multilib specific file paths.
    addMultilibsFilePaths(D, Multilibs, Multilib,
                          GCCInstallation.getInstallPath(), Paths);

    // Sourcery CodeBench MIPS toolchain holds some libraries under
    // a biarch-like suffix of the GCC installation.
    addPathIfExists(D, GCCInstallation.getInstallPath() + Multilib.gccSuffix(),
                    Paths);

    // GCC cross compiling toolchains will install target libraries which ship
    // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as
    // any part of the GCC installation in
    // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat
    // debatable, but is the reality today. We need to search this tree even
    // when we have a sysroot somewhere else. It is the responsibility of
    // whomever is doing the cross build targeting a sysroot using a GCC
    // installation that is *not* within the system root to ensure two things:
    //
    //  1) Any DSOs that are linked in from this tree or from the install path
    //     above must be present on the system root and found via an
    //     appropriate rpath.
    //  2) There must not be libraries installed into
    //     <prefix>/<triple>/<libdir> unless they should be preferred over
    //     those within the system root.
    //
    // Note that this matches the GCC behavior. See the below comment for where
    // Clang diverges from GCC's behavior.
    addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib/../" +
                           OSLibDir + Multilib.osSuffix(),
                    Paths);

    // If the GCC installation we found is inside of the sysroot, we want to
    // prefer libraries installed in the parent prefix of the GCC installation.
    // It is important to *not* use these paths when the GCC installation is
    // outside of the system root as that can pick up unintended libraries.
    // This usually happens when there is an external cross compiler on the
    // host system, and a more minimal sysroot available that is the target of
    // the cross. Note that GCC does include some of these directories in some
    // configurations but this seems somewhere between questionable and simply
    // a bug.
    if (StringRef(LibPath).startswith(SysRoot)) {
      addPathIfExists(D, LibPath + "/" + MultiarchTriple, Paths);
      addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths);
    }
  }

  // Similar to the logic for GCC above, if we currently running Clang inside
  // of the requested system root, add its parent library paths to
  // those searched.
  // FIXME: It's not clear whether we should use the driver's installed
  // directory ('Dir' below) or the ResourceDir.
  if (StringRef(D.Dir).startswith(SysRoot)) {
    addPathIfExists(D, D.Dir + "/../lib/" + MultiarchTriple, Paths);
    addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths);
  }

  addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths);
  addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths);
  addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
  addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths);

  // Try walking via the GCC triple path in case of biarch or multiarch GCC
  // installations with strange symlinks.
  if (GCCInstallation.isValid()) {
    addPathIfExists(D,
                    SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
                        "/../../" + OSLibDir,
                    Paths);

    // Add the 'other' biarch variant path
    Multilib BiarchSibling;
    if (GCCInstallation.getBiarchSibling(BiarchSibling)) {
      addPathIfExists(D, GCCInstallation.getInstallPath() +
                             BiarchSibling.gccSuffix(),
                      Paths);
    }

    // See comments above on the multilib variant for details of why this is
    // included even from outside the sysroot.
    const std::string &LibPath = GCCInstallation.getParentLibPath();
    const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
    const Multilib &Multilib = GCCInstallation.getMultilib();
    addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib" +
                           Multilib.osSuffix(),
                    Paths);

    // See comments above on the multilib variant for details of why this is
    // only included from within the sysroot.
    if (StringRef(LibPath).startswith(SysRoot))
      addPathIfExists(D, LibPath, Paths);
  }

  // Similar to the logic for GCC above, if we are currently running Clang
  // inside of the requested system root, add its parent library path to those
  // searched.
  // FIXME: It's not clear whether we should use the driver's installed
  // directory ('Dir' below) or the ResourceDir.
  if (StringRef(D.Dir).startswith(SysRoot))
    addPathIfExists(D, D.Dir + "/../lib", Paths);

  addPathIfExists(D, SysRoot + "/lib", Paths);
  addPathIfExists(D, SysRoot + "/usr/lib", Paths);
}
コード例 #12
0
ファイル: MultilibTest.cpp プロジェクト: 4ntoine/clang
 bool operator()(const Multilib &M) const override {
   return StringRef(M.gccSuffix()).startswith("/p");
 }