void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts) { llvm::Triple::OSType os = triple.getOS(); switch (os) { case llvm::Triple::FreeBSD: case llvm::Triple::NetBSD: break; default: // FIXME: temporary hack: hard-coded paths. AddPath("/usr/local/include", System, true, false, false); break; } // Builtin includes use #include_next directives and should be positioned // just prior C include dirs. if (HSOpts.UseBuiltinIncludes) { // Ignore the sys root, we *always* look for clang headers relative to // supplied path. llvm::sys::Path P(HSOpts.ResourceDir); P.appendComponent("include"); AddPath(P.str(), System, false, false, false, /*IgnoreSysRoot=*/ true); } // Add dirs specified via 'configure --with-c-include-dirs'. StringRef CIncludeDirs(C_INCLUDE_DIRS); if (CIncludeDirs != "") { SmallVector<StringRef, 5> dirs; CIncludeDirs.split(dirs, ":"); for (SmallVectorImpl<StringRef>::iterator i = dirs.begin(); i != dirs.end(); ++i) AddPath(*i, System, false, false, false); return; } switch (os) { case llvm::Triple::Win32: { std::string VSDir; std::string WindowsSDKDir; if (getVisualStudioDir(VSDir)) { AddPath(VSDir + "\\VC\\include", System, false, false, false); if (getWindowsSDKDir(WindowsSDKDir)) AddPath(WindowsSDKDir + "\\include", System, false, false, false); else AddPath(VSDir + "\\VC\\PlatformSDK\\Include", System, false, false, false); } else { // Default install paths. AddPath("C:/Program Files/Microsoft Visual Studio 10.0/VC/include", System, false, false, false); AddPath("C:/Program Files/Microsoft Visual Studio 9.0/VC/include", System, false, false, false); AddPath( "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include", System, false, false, false); AddPath("C:/Program Files/Microsoft Visual Studio 8/VC/include", System, false, false, false); AddPath( "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include", System, false, false, false); } break; } case llvm::Triple::Haiku: AddPath("/boot/common/include", System, true, false, false); AddPath("/boot/develop/headers/os", System, true, false, false); AddPath("/boot/develop/headers/os/app", System, true, false, false); AddPath("/boot/develop/headers/os/arch", System, true, false, false); AddPath("/boot/develop/headers/os/device", System, true, false, false); AddPath("/boot/develop/headers/os/drivers", System, true, false, false); AddPath("/boot/develop/headers/os/game", System, true, false, false); AddPath("/boot/develop/headers/os/interface", System, true, false, false); AddPath("/boot/develop/headers/os/kernel", System, true, false, false); AddPath("/boot/develop/headers/os/locale", System, true, false, false); AddPath("/boot/develop/headers/os/mail", System, true, false, false); AddPath("/boot/develop/headers/os/media", System, true, false, false); AddPath("/boot/develop/headers/os/midi", System, true, false, false); AddPath("/boot/develop/headers/os/midi2", System, true, false, false); AddPath("/boot/develop/headers/os/net", System, true, false, false); AddPath("/boot/develop/headers/os/storage", System, true, false, false); AddPath("/boot/develop/headers/os/support", System, true, false, false); AddPath("/boot/develop/headers/os/translation", System, true, false, false); AddPath("/boot/develop/headers/os/add-ons/graphics", System, true, false, false); AddPath("/boot/develop/headers/os/add-ons/input_server", System, true, false, false); AddPath("/boot/develop/headers/os/add-ons/screen_saver", System, true, false, false); AddPath("/boot/develop/headers/os/add-ons/tracker", System, true, false, false); AddPath("/boot/develop/headers/os/be_apps/Deskbar", System, true, false, false); AddPath("/boot/develop/headers/os/be_apps/NetPositive", System, true, false, false); AddPath("/boot/develop/headers/os/be_apps/Tracker", System, true, false, false); AddPath("/boot/develop/headers/cpp", System, true, false, false); AddPath("/boot/develop/headers/cpp/i586-pc-haiku", System, true, false, false); AddPath("/boot/develop/headers/3rdparty", System, true, false, false); AddPath("/boot/develop/headers/bsd", System, true, false, false); AddPath("/boot/develop/headers/glibc", System, true, false, false); AddPath("/boot/develop/headers/posix", System, true, false, false); AddPath("/boot/develop/headers", System, true, false, false); break; case llvm::Triple::RTEMS: break; case llvm::Triple::Cygwin: AddPath("/usr/include/w32api", System, true, false, false); break; case llvm::Triple::MinGW32: { // mingw-w64 crt include paths llvm::sys::Path P(HSOpts.ResourceDir); P.appendComponent("../../../i686-w64-mingw32/include"); // <sysroot>/i686-w64-mingw32/include AddPath(P.str(), System, true, false, false); P = llvm::sys::Path(HSOpts.ResourceDir); P.appendComponent("../../../x86_64-w64-mingw32/include"); // <sysroot>/x86_64-w64-mingw32/include AddPath(P.str(), System, true, false, false); // mingw.org crt include paths P = llvm::sys::Path(HSOpts.ResourceDir); P.appendComponent("../../../include"); // <sysroot>/include AddPath(P.str(), System, true, false, false); AddPath("/mingw/include", System, true, false, false); AddPath("c:/mingw/include", System, true, false, false); } break; case llvm::Triple::Linux: // Generic Debian multiarch support: if (triple.getArch() == llvm::Triple::x86_64) { AddPath("/usr/include/x86_64-linux-gnu", System, false, false, false); AddPath("/usr/include/i686-linux-gnu/64", System, false, false, false); AddPath("/usr/include/i486-linux-gnu/64", System, false, false, false); } else if (triple.getArch() == llvm::Triple::x86) { AddPath("/usr/include/x86_64-linux-gnu/32", System, false, false, false); AddPath("/usr/include/i686-linux-gnu", System, false, false, false); AddPath("/usr/include/i486-linux-gnu", System, false, false, false); } else if (triple.getArch() == llvm::Triple::arm) { AddPath("/usr/include/arm-linux-gnueabi", System, false, false, false); } default: break; } if ( os != llvm::Triple::RTEMS ) AddPath("/usr/include", System, false, false, false); }
ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0), HW_FP(0) { bool IsOpenBSD = Triple.isOSOpenBSD(); bool IsNetBSD = Triple.isOSNetBSD(); // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like // environment where size_t is `unsigned long` rather than `unsigned int` PtrDiffType = IntPtrType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD || IsNetBSD) ? SignedLong : SignedInt; SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD || IsNetBSD) ? UnsignedLong : UnsignedInt; // ptrdiff_t is inconsistent on Darwin if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) && !Triple.isWatchABI()) PtrDiffType = SignedInt; // Cache arch related info. setArchInfo(); // {} in inline assembly are neon specifiers, not assembly variant // specifiers. NoAsmVariants = true; // FIXME: This duplicates code from the driver that sets the -target-abi // option - this code is used if -target-abi isn't passed and should // be unified in some way. if (Triple.isOSBinFormatMachO()) { // The backend is hardwired to assume AAPCS for M-class processors, ensure // the frontend matches that. if (Triple.getEnvironment() == llvm::Triple::EABI || Triple.getOS() == llvm::Triple::UnknownOS || ArchProfile == llvm::ARM::ProfileKind::M) { setABI("aapcs"); } else if (Triple.isWatchABI()) { setABI("aapcs16"); } else { setABI("apcs-gnu"); } } else if (Triple.isOSWindows()) { // FIXME: this is invalid for WindowsCE setABI("aapcs"); } else { // Select the default based on the platform. switch (Triple.getEnvironment()) { case llvm::Triple::Android: case llvm::Triple::GNUEABI: case llvm::Triple::GNUEABIHF: case llvm::Triple::MuslEABI: case llvm::Triple::MuslEABIHF: setABI("aapcs-linux"); break; case llvm::Triple::EABIHF: case llvm::Triple::EABI: setABI("aapcs"); break; case llvm::Triple::GNU: setABI("apcs-gnu"); break; default: if (IsNetBSD) setABI("apcs-gnu"); else if (IsOpenBSD) setABI("aapcs-linux"); else setABI("aapcs"); break; } } // ARM targets default to using the ARM C++ ABI. TheCXXABI.set(TargetCXXABI::GenericARM); // ARM has atomics up to 8 bytes setAtomic(); // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS) if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android)) MaxVectorAlign = 64; // Do force alignment of members that follow zero length bitfields. If // the alignment of the zero-length bitfield is greater than the member // that follows it, `bar', `bar' will be aligned as the type of the // zero length bitfield. UseZeroLengthBitfieldAlignment = true; if (Triple.getOS() == llvm::Triple::Linux || Triple.getOS() == llvm::Triple::UnknownOS) this->MCountName = Opts.EABIVersion == llvm::EABI::GNU ? "\01__gnu_mcount_nc" : "\01mcount"; }
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); }
void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts) { llvm::Triple::OSType os = triple.getOS(); if (HSOpts.UseStandardSystemIncludes) { switch (os) { case llvm::Triple::CloudABI: case llvm::Triple::FreeBSD: case llvm::Triple::NetBSD: case llvm::Triple::OpenBSD: case llvm::Triple::NaCl: case llvm::Triple::PS4: case llvm::Triple::ELFIAMCU: break; case llvm::Triple::Win32: if (triple.getEnvironment() != llvm::Triple::Cygnus) break; LLVM_FALLTHROUGH; default: // FIXME: temporary hack: hard-coded paths. AddPath("/usr/local/include", System, false); break; } } // Builtin includes use #include_next directives and should be positioned // just prior C include dirs. if (HSOpts.UseBuiltinIncludes) { // Ignore the sys root, we *always* look for clang headers relative to // supplied path. SmallString<128> P = StringRef(HSOpts.ResourceDir); llvm::sys::path::append(P, "include"); AddUnmappedPath(P, ExternCSystem, false); } // All remaining additions are for system include directories, early exit if // we aren't using them. if (!HSOpts.UseStandardSystemIncludes) return; // Add dirs specified via 'configure --with-c-include-dirs'. StringRef CIncludeDirs(C_INCLUDE_DIRS); if (CIncludeDirs != "") { SmallVector<StringRef, 5> dirs; CIncludeDirs.split(dirs, ":"); for (StringRef dir : dirs) AddPath(dir, ExternCSystem, false); return; } switch (os) { case llvm::Triple::Linux: case llvm::Triple::Solaris: llvm_unreachable("Include management is handled in the driver."); case llvm::Triple::CloudABI: { // <sysroot>/<triple>/include SmallString<128> P = StringRef(HSOpts.ResourceDir); llvm::sys::path::append(P, "../../..", triple.str(), "include"); AddPath(P, System, false); break; } case llvm::Triple::Haiku: AddPath("/boot/system/non-packaged/develop/headers", System, false); AddPath("/boot/system/develop/headers/os", System, false); AddPath("/boot/system/develop/headers/os/app", System, false); AddPath("/boot/system/develop/headers/os/arch", System, false); AddPath("/boot/system/develop/headers/os/device", System, false); AddPath("/boot/system/develop/headers/os/drivers", System, false); AddPath("/boot/system/develop/headers/os/game", System, false); AddPath("/boot/system/develop/headers/os/interface", System, false); AddPath("/boot/system/develop/headers/os/kernel", System, false); AddPath("/boot/system/develop/headers/os/locale", System, false); AddPath("/boot/system/develop/headers/os/mail", System, false); AddPath("/boot/system/develop/headers/os/media", System, false); AddPath("/boot/system/develop/headers/os/midi", System, false); AddPath("/boot/system/develop/headers/os/midi2", System, false); AddPath("/boot/system/develop/headers/os/net", System, false); AddPath("/boot/system/develop/headers/os/opengl", System, false); AddPath("/boot/system/develop/headers/os/storage", System, false); AddPath("/boot/system/develop/headers/os/support", System, false); AddPath("/boot/system/develop/headers/os/translation", System, false); AddPath("/boot/system/develop/headers/os/add-ons/graphics", System, false); AddPath("/boot/system/develop/headers/os/add-ons/input_server", System, false); AddPath("/boot/system/develop/headers/os/add-ons/mail_daemon", System, false); AddPath("/boot/system/develop/headers/os/add-ons/registrar", System, false); AddPath("/boot/system/develop/headers/os/add-ons/screen_saver", System, false); AddPath("/boot/system/develop/headers/os/add-ons/tracker", System, false); AddPath("/boot/system/develop/headers/os/be_apps/Deskbar", System, false); AddPath("/boot/system/develop/headers/os/be_apps/NetPositive", System, false); AddPath("/boot/system/develop/headers/os/be_apps/Tracker", System, false); AddPath("/boot/system/develop/headers/3rdparty", System, false); AddPath("/boot/system/develop/headers/bsd", System, false); AddPath("/boot/system/develop/headers/glibc", System, false); AddPath("/boot/system/develop/headers/posix", System, false); AddPath("/boot/system/develop/headers", System, false); break; case llvm::Triple::RTEMS: break; case llvm::Triple::Win32: switch (triple.getEnvironment()) { default: llvm_unreachable("Include management is handled in the driver."); case llvm::Triple::Cygnus: AddPath("/usr/include/w32api", System, false); break; case llvm::Triple::GNU: break; } break; default: break; } switch (os) { case llvm::Triple::CloudABI: case llvm::Triple::RTEMS: case llvm::Triple::NaCl: case llvm::Triple::ELFIAMCU: break; case llvm::Triple::PS4: { // <isysroot> gets prepended later in AddPath(). std::string BaseSDKPath = ""; if (!HasSysroot) { const char *envValue = getenv("SCE_ORBIS_SDK_DIR"); if (envValue) BaseSDKPath = envValue; else { // HSOpts.ResourceDir variable contains the location of Clang's // resource files. // Assuming that Clang is configured for PS4 without // --with-clang-resource-dir option, the location of Clang's resource // files is <SDK_DIR>/host_tools/lib/clang SmallString<128> P = StringRef(HSOpts.ResourceDir); llvm::sys::path::append(P, "../../.."); BaseSDKPath = P.str(); } } AddPath(BaseSDKPath + "/target/include", System, false); if (triple.isPS4CPU()) AddPath(BaseSDKPath + "/target/include_common", System, false); LLVM_FALLTHROUGH; } default: AddPath("/usr/include", ExternCSystem, false); break; } }
std::pair<bool, bool> LangOptions::setTarget(llvm::Triple triple) { clearAllPlatformConditionValues(); if (triple.getOS() == llvm::Triple::Darwin && triple.getVendor() == llvm::Triple::Apple) { // Rewrite darwinX.Y triples to macosx10.X'.Y ones. // It affects code generation on our platform. llvm::SmallString<16> osxBuf; llvm::raw_svector_ostream osx(osxBuf); osx << llvm::Triple::getOSTypeName(llvm::Triple::MacOSX); unsigned major, minor, micro; triple.getMacOSXVersion(major, minor, micro); osx << major << "." << minor; if (micro != 0) osx << "." << micro; triple.setOSName(osx.str()); } Target = std::move(triple); bool UnsupportedOS = false; // Set the "os" platform condition. if (Target.isMacOSX()) addPlatformConditionValue(PlatformConditionKind::OS, "OSX"); else if (triple.isTvOS()) addPlatformConditionValue(PlatformConditionKind::OS, "tvOS"); else if (triple.isWatchOS()) addPlatformConditionValue(PlatformConditionKind::OS, "watchOS"); else if (triple.isiOS()) addPlatformConditionValue(PlatformConditionKind::OS, "iOS"); else if (triple.isAndroid()) addPlatformConditionValue(PlatformConditionKind::OS, "Android"); else if (triple.isOSLinux()) addPlatformConditionValue(PlatformConditionKind::OS, "Linux"); else if (triple.isOSFreeBSD()) addPlatformConditionValue(PlatformConditionKind::OS, "FreeBSD"); else if (triple.isOSWindows()) addPlatformConditionValue(PlatformConditionKind::OS, "Windows"); else if (triple.isWindowsCygwinEnvironment()) addPlatformConditionValue(PlatformConditionKind::OS, "Cygwin"); else if (triple.isPS4()) addPlatformConditionValue(PlatformConditionKind::OS, "PS4"); else UnsupportedOS = true; bool UnsupportedArch = false; // Set the "arch" platform condition. switch (Target.getArch()) { case llvm::Triple::ArchType::arm: case llvm::Triple::ArchType::thumb: addPlatformConditionValue(PlatformConditionKind::Arch, "arm"); break; case llvm::Triple::ArchType::aarch64: addPlatformConditionValue(PlatformConditionKind::Arch, "arm64"); break; case llvm::Triple::ArchType::ppc64: addPlatformConditionValue(PlatformConditionKind::Arch, "powerpc64"); break; case llvm::Triple::ArchType::ppc64le: addPlatformConditionValue(PlatformConditionKind::Arch, "powerpc64le"); break; case llvm::Triple::ArchType::x86: addPlatformConditionValue(PlatformConditionKind::Arch, "i386"); break; case llvm::Triple::ArchType::x86_64: addPlatformConditionValue(PlatformConditionKind::Arch, "x86_64"); break; case llvm::Triple::ArchType::systemz: addPlatformConditionValue(PlatformConditionKind::Arch, "s390x"); break; default: UnsupportedArch = true; } if (UnsupportedOS || UnsupportedArch) return { UnsupportedOS, UnsupportedArch }; // Set the "_endian" platform condition. switch (Target.getArch()) { case llvm::Triple::ArchType::arm: case llvm::Triple::ArchType::thumb: addPlatformConditionValue(PlatformConditionKind::Endianness, "little"); break; case llvm::Triple::ArchType::aarch64: addPlatformConditionValue(PlatformConditionKind::Endianness, "little"); break; case llvm::Triple::ArchType::ppc64: addPlatformConditionValue(PlatformConditionKind::Endianness, "big"); break; case llvm::Triple::ArchType::ppc64le: addPlatformConditionValue(PlatformConditionKind::Endianness, "little"); break; case llvm::Triple::ArchType::x86: addPlatformConditionValue(PlatformConditionKind::Endianness, "little"); break; case llvm::Triple::ArchType::x86_64: addPlatformConditionValue(PlatformConditionKind::Endianness, "little"); break; case llvm::Triple::ArchType::systemz: addPlatformConditionValue(PlatformConditionKind::Endianness, "big"); break; default: llvm_unreachable("undefined architecture endianness"); } // Set the "runtime" platform condition. if (EnableObjCInterop) addPlatformConditionValue(PlatformConditionKind::Runtime, "_ObjC"); else addPlatformConditionValue(PlatformConditionKind::Runtime, "_Native"); // If you add anything to this list, change the default size of // PlatformConditionValues to not require an extra allocation // in the common case. return { false, false }; }
void InitHeaderSearch:: AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts) { llvm::Triple::OSType os = triple.getOS(); // FIXME: temporary hack: hard-coded paths. if (triple.isOSDarwin()) { switch (triple.getArch()) { default: break; case llvm::Triple::ppc: case llvm::Triple::ppc64: AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "powerpc-apple-darwin10", "", "ppc64", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0", "powerpc-apple-darwin10", "", "ppc64", triple); break; case llvm::Triple::x86: case llvm::Triple::x86_64: AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "i686-apple-darwin10", "", "x86_64", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0", "i686-apple-darwin8", "", "", triple); break; case llvm::Triple::arm: case llvm::Triple::thumb: AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "arm-apple-darwin10", "v7", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "arm-apple-darwin10", "v6", "", triple); break; } return; } switch (os) { case llvm::Triple::Linux: case llvm::Triple::Win32: llvm_unreachable("Include management is handled in the driver."); case llvm::Triple::Cygwin: // Cygwin-1.7 AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.5.3"); AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.4"); // g++-4 / Cygwin-1.5 AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.2"); break; case llvm::Triple::MinGW32: // mingw-w64 C++ include paths (i686-w64-mingw32 and x86_64-w64-mingw32) AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.0"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.1"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.2"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.3"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.4"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.0"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.1"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.2"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.3"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.7.0"); // mingw.org C++ include paths AddMinGWCPlusPlusIncludePaths("/mingw/lib/gcc", "mingw32", "4.5.2"); //MSYS #if defined(_WIN32) AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.6.2"); AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.6.1"); AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.2"); AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.0"); AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.4.0"); AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.3.0"); #endif break; case llvm::Triple::DragonFly: if (llvm::sys::fs::exists("/usr/lib/gcc47")) AddPath("/usr/include/c++/4.7", CXXSystem, false); else AddPath("/usr/include/c++/4.4", CXXSystem, false); break; case llvm::Triple::FreeBSD: // FreeBSD 8.0 // FreeBSD 7.3 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2", "", "", "", triple); break; case llvm::Triple::OpenBSD: { std::string t = triple.getTriple(); if (t.substr(0, 6) == "x86_64") t.replace(0, 6, "amd64"); AddGnuCPlusPlusIncludePaths("/usr/include/g++", t, "", "", triple); break; } case llvm::Triple::Minix: AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3", "", "", "", triple); break; case llvm::Triple::Solaris: AddGnuCPlusPlusIncludePaths("/usr/gcc/4.5/include/c++/4.5.2/", "i386-pc-solaris2.11", "", "", triple); // Solaris - Fall though.. case llvm::Triple::AuroraUX: // AuroraUX AddGnuCPlusPlusIncludePaths("/opt/gcc4/include/c++/4.2.4", "i386-pc-solaris2.11", "", "", triple); break; default: break; } }
CudaInstallationDetector::CudaInstallationDetector( const Driver &D, const llvm::Triple &HostTriple, const llvm::opt::ArgList &Args) : D(D) { struct Candidate { std::string Path; bool StrictChecking; Candidate(std::string Path, bool StrictChecking = false) : Path(Path), StrictChecking(StrictChecking) {} }; SmallVector<Candidate, 4> Candidates; // In decreasing order so we prefer newer versions to older versions. std::initializer_list<const char *> Versions = {"8.0", "7.5", "7.0"}; if (Args.hasArg(clang::driver::options::OPT_cuda_path_EQ)) { Candidates.emplace_back( Args.getLastArgValue(clang::driver::options::OPT_cuda_path_EQ).str()); } else if (HostTriple.isOSWindows()) { for (const char *Ver : Versions) Candidates.emplace_back( D.SysRoot + "/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v" + Ver); } else { if (!Args.hasArg(clang::driver::options::OPT_cuda_path_ignore_env)) { // Try to find ptxas binary. If the executable is located in a directory // called 'bin/', its parent directory might be a good guess for a valid // CUDA installation. // However, some distributions might installs 'ptxas' to /usr/bin. In that // case the candidate would be '/usr' which passes the following checks // because '/usr/include' exists as well. To avoid this case, we always // check for the directory potentially containing files for libdevice, // even if the user passes -nocudalib. if (llvm::ErrorOr<std::string> ptxas = llvm::sys::findProgramByName("ptxas")) { SmallString<256> ptxasAbsolutePath; llvm::sys::fs::real_path(*ptxas, ptxasAbsolutePath); StringRef ptxasDir = llvm::sys::path::parent_path(ptxasAbsolutePath); if (llvm::sys::path::filename(ptxasDir) == "bin") Candidates.emplace_back(llvm::sys::path::parent_path(ptxasDir), /*StrictChecking=*/true); } } Candidates.emplace_back(D.SysRoot + "/usr/local/cuda"); for (const char *Ver : Versions) Candidates.emplace_back(D.SysRoot + "/usr/local/cuda-" + Ver); if (Distro(D.getVFS()).IsDebian()) // Special case for Debian to have nvidia-cuda-toolkit work // out of the box. More info on http://bugs.debian.org/882505 Candidates.emplace_back(D.SysRoot + "/usr/lib/cuda"); } bool NoCudaLib = Args.hasArg(options::OPT_nocudalib); for (const auto &Candidate : Candidates) { InstallPath = Candidate.Path; if (InstallPath.empty() || !D.getVFS().exists(InstallPath)) continue; BinPath = InstallPath + "/bin"; IncludePath = InstallPath + "/include"; LibDevicePath = InstallPath + "/nvvm/libdevice"; auto &FS = D.getVFS(); if (!(FS.exists(IncludePath) && FS.exists(BinPath))) continue; bool CheckLibDevice = (!NoCudaLib || Candidate.StrictChecking); if (CheckLibDevice && !FS.exists(LibDevicePath)) continue; // On Linux, we have both lib and lib64 directories, and we need to choose // based on our triple. On MacOS, we have only a lib directory. // // It's sufficient for our purposes to be flexible: If both lib and lib64 // exist, we choose whichever one matches our triple. Otherwise, if only // lib exists, we use it. if (HostTriple.isArch64Bit() && FS.exists(InstallPath + "/lib64")) LibPath = InstallPath + "/lib64"; else if (FS.exists(InstallPath + "/lib")) LibPath = InstallPath + "/lib"; else continue; llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> VersionFile = FS.getBufferForFile(InstallPath + "/version.txt"); if (!VersionFile) { // CUDA 7.0 doesn't have a version.txt, so guess that's our version if // version.txt isn't present. Version = CudaVersion::CUDA_70; } else { Version = ParseCudaVersionFile((*VersionFile)->getBuffer()); } if (Version >= CudaVersion::CUDA_90) { // CUDA-9+ uses single libdevice file for all GPU variants. std::string FilePath = LibDevicePath + "/libdevice.10.bc"; if (FS.exists(FilePath)) { for (const char *GpuArchName : {"sm_20", "sm_30", "sm_32", "sm_35", "sm_50", "sm_52", "sm_53", "sm_60", "sm_61", "sm_62", "sm_70", "sm_72"}) { const CudaArch GpuArch = StringToCudaArch(GpuArchName); if (Version >= MinVersionForCudaArch(GpuArch) && Version <= MaxVersionForCudaArch(GpuArch)) LibDeviceMap[GpuArchName] = FilePath; } } } else { std::error_code EC; for (llvm::sys::fs::directory_iterator LI(LibDevicePath, EC), LE; !EC && LI != LE; LI = LI.increment(EC)) { StringRef FilePath = LI->path(); StringRef FileName = llvm::sys::path::filename(FilePath); // Process all bitcode filenames that look like // libdevice.compute_XX.YY.bc const StringRef LibDeviceName = "libdevice."; if (!(FileName.startswith(LibDeviceName) && FileName.endswith(".bc"))) continue; StringRef GpuArch = FileName.slice( LibDeviceName.size(), FileName.find('.', LibDeviceName.size())); LibDeviceMap[GpuArch] = FilePath.str(); // Insert map entries for specifc devices with this compute // capability. NVCC's choice of the libdevice library version is // rather peculiar and depends on the CUDA version. if (GpuArch == "compute_20") { LibDeviceMap["sm_20"] = FilePath; LibDeviceMap["sm_21"] = FilePath; LibDeviceMap["sm_32"] = FilePath; } else if (GpuArch == "compute_30") { LibDeviceMap["sm_30"] = FilePath; if (Version < CudaVersion::CUDA_80) { LibDeviceMap["sm_50"] = FilePath; LibDeviceMap["sm_52"] = FilePath; LibDeviceMap["sm_53"] = FilePath; } LibDeviceMap["sm_60"] = FilePath; LibDeviceMap["sm_61"] = FilePath; LibDeviceMap["sm_62"] = FilePath; } else if (GpuArch == "compute_35") { LibDeviceMap["sm_35"] = FilePath; LibDeviceMap["sm_37"] = FilePath; } else if (GpuArch == "compute_50") { if (Version >= CudaVersion::CUDA_80) { LibDeviceMap["sm_50"] = FilePath; LibDeviceMap["sm_52"] = FilePath; LibDeviceMap["sm_53"] = FilePath; } } } } // Check that we have found at least one libdevice that we can link in if // -nocudalib hasn't been specified. if (LibDeviceMap.empty() && !NoCudaLib) continue; IsValid = true; break; } }
bool swift::irgen::useDllStorage(const llvm::Triple &triple) { return triple.isOSBinFormatCOFF() && !triple.isOSCygMing(); }
UniversalLinkageInfo::UniversalLinkageInfo(const llvm::Triple &triple, bool hasMultipleIGMs, bool isWholeModule) : IsELFObject(triple.isOSBinFormatELF()), UseDLLStorage(useDllStorage(triple)), HasMultipleIGMs(hasMultipleIGMs), IsWholeModule(isWholeModule) {}
// Get CPU and ABI names. They are not independent // so we have to calculate them together. void mips::getMipsCPUAndABI(const ArgList &Args, const llvm::Triple &Triple, StringRef &CPUName, StringRef &ABIName) { const char *DefMips32CPU = "mips32r2"; const char *DefMips64CPU = "mips64r2"; // MIPS32r6 is the default for mips(el)?-img-linux-gnu and MIPS64r6 is the // default for mips64(el)?-img-linux-gnu. if (Triple.getVendor() == llvm::Triple::ImaginationTechnologies && Triple.getEnvironment() == llvm::Triple::GNU) { DefMips32CPU = "mips32r6"; DefMips64CPU = "mips64r6"; } // MIPS64r6 is the default for Android MIPS64 (mips64el-linux-android). if (Triple.isAndroid()) { DefMips32CPU = "mips32"; DefMips64CPU = "mips64r6"; } // MIPS3 is the default for mips64*-unknown-openbsd. if (Triple.getOS() == llvm::Triple::OpenBSD) DefMips64CPU = "mips3"; if (Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ, options::OPT_mcpu_EQ)) CPUName = A->getValue(); if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { ABIName = A->getValue(); // Convert a GNU style Mips ABI name to the name // accepted by LLVM Mips backend. ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName) .Case("32", "o32") .Case("64", "n64") .Default(ABIName); } // Setup default CPU and ABI names. if (CPUName.empty() && ABIName.empty()) { switch (Triple.getArch()) { default: llvm_unreachable("Unexpected triple arch name"); case llvm::Triple::mips: case llvm::Triple::mipsel: CPUName = DefMips32CPU; break; case llvm::Triple::mips64: case llvm::Triple::mips64el: CPUName = DefMips64CPU; break; } } if (ABIName.empty() && (Triple.getVendor() == llvm::Triple::MipsTechnologies || Triple.getVendor() == llvm::Triple::ImaginationTechnologies)) { ABIName = llvm::StringSwitch<const char *>(CPUName) .Case("mips1", "o32") .Case("mips2", "o32") .Case("mips3", "n64") .Case("mips4", "n64") .Case("mips5", "n64") .Case("mips32", "o32") .Case("mips32r2", "o32") .Case("mips32r3", "o32") .Case("mips32r5", "o32") .Case("mips32r6", "o32") .Case("mips64", "n64") .Case("mips64r2", "n64") .Case("mips64r3", "n64") .Case("mips64r5", "n64") .Case("mips64r6", "n64") .Case("octeon", "n64") .Case("p5600", "o32") .Default(""); } if (ABIName.empty()) { // Deduce ABI name from the target triple. if (Triple.getArch() == llvm::Triple::mips || Triple.getArch() == llvm::Triple::mipsel) ABIName = "o32"; else ABIName = "n64"; } if (CPUName.empty()) { // Deduce CPU name from ABI name. CPUName = llvm::StringSwitch<const char *>(ABIName) .Case("o32", DefMips32CPU) .Cases("n32", "n64", DefMips64CPU) .Default(""); } // FIXME: Warn on inconsistent use of -march and -mabi. }
void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, const llvm::Triple &Triple, StringRef &PlatformName, VersionTuple &PlatformMinVersion) { Builder.defineMacro("__APPLE_CC__", "6000"); Builder.defineMacro("__APPLE__"); Builder.defineMacro("__STDC_NO_THREADS__"); Builder.defineMacro("OBJC_NEW_PROPERTIES"); // AddressSanitizer doesn't play well with source fortification, which is on // by default on Darwin. if (Opts.Sanitize.has(SanitizerKind::Address)) Builder.defineMacro("_FORTIFY_SOURCE", "0"); // Darwin defines __weak, __strong, and __unsafe_unretained even in C mode. if (!Opts.ObjC) { // __weak is always defined, for use in blocks and with objc pointers. Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))"); Builder.defineMacro("__strong", ""); Builder.defineMacro("__unsafe_unretained", ""); } if (Opts.Static) Builder.defineMacro("__STATIC__"); else Builder.defineMacro("__DYNAMIC__"); if (Opts.POSIXThreads) Builder.defineMacro("_REENTRANT"); // Get the platform type and version number from the triple. unsigned Maj, Min, Rev; if (Triple.isMacOSX()) { Triple.getMacOSXVersion(Maj, Min, Rev); PlatformName = "macos"; } else { Triple.getOSVersion(Maj, Min, Rev); PlatformName = llvm::Triple::getOSTypeName(Triple.getOS()); } // If -target arch-pc-win32-macho option specified, we're // generating code for Win32 ABI. No need to emit // __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__. if (PlatformName == "win32") { PlatformMinVersion = VersionTuple(Maj, Min, Rev); return; } // Set the appropriate OS version define. if (Triple.isiOS()) { assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!"); char Str[7]; if (Maj < 10) { Str[0] = '0' + Maj; Str[1] = '0' + (Min / 10); Str[2] = '0' + (Min % 10); Str[3] = '0' + (Rev / 10); Str[4] = '0' + (Rev % 10); Str[5] = '\0'; } else { // Handle versions >= 10. Str[0] = '0' + (Maj / 10); Str[1] = '0' + (Maj % 10); Str[2] = '0' + (Min / 10); Str[3] = '0' + (Min % 10); Str[4] = '0' + (Rev / 10); Str[5] = '0' + (Rev % 10); Str[6] = '\0'; } if (Triple.isTvOS()) Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str); else Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str); } else if (Triple.isWatchOS()) { assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!"); char Str[6]; Str[0] = '0' + Maj; Str[1] = '0' + (Min / 10); Str[2] = '0' + (Min % 10); Str[3] = '0' + (Rev / 10); Str[4] = '0' + (Rev % 10); Str[5] = '\0'; Builder.defineMacro("__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__", Str); } else if (Triple.isMacOSX()) { // Note that the Driver allows versions which aren't representable in the // define (because we only get a single digit for the minor and micro // revision numbers). So, we limit them to the maximum representable // version. assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!"); char Str[7]; if (Maj < 10 || (Maj == 10 && Min < 10)) { Str[0] = '0' + (Maj / 10); Str[1] = '0' + (Maj % 10); Str[2] = '0' + std::min(Min, 9U); Str[3] = '0' + std::min(Rev, 9U); Str[4] = '\0'; } else { // Handle versions > 10.9. Str[0] = '0' + (Maj / 10); Str[1] = '0' + (Maj % 10); Str[2] = '0' + (Min / 10); Str[3] = '0' + (Min % 10); Str[4] = '0' + (Rev / 10); Str[5] = '0' + (Rev % 10); Str[6] = '\0'; } Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str); } // Tell users about the kernel if there is one. if (Triple.isOSDarwin()) Builder.defineMacro("__MACH__"); PlatformMinVersion = VersionTuple(Maj, Min, Rev); }
// TargetInfo Constructor. TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { // Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or // SPARC. These should be overridden by concrete targets as needed. BigEndian = !T.isLittleEndian(); TLSSupported = true; NoAsmVariants = false; HasFloat128 = false; PointerWidth = PointerAlign = 32; BoolWidth = BoolAlign = 8; IntWidth = IntAlign = 32; LongWidth = LongAlign = 32; LongLongWidth = LongLongAlign = 64; SuitableAlign = 64; DefaultAlignForAttributeAligned = 128; MinGlobalAlign = 0; // From the glibc documentation, on GNU systems, malloc guarantees 16-byte // alignment on 64-bit systems and 8-byte alignment on 32-bit systems. See // https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html if (T.isGNUEnvironment()) NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0; else NewAlign = 0; // Infer from basic type alignment. HalfWidth = 16; HalfAlign = 16; FloatWidth = 32; FloatAlign = 32; DoubleWidth = 64; DoubleAlign = 64; LongDoubleWidth = 64; LongDoubleAlign = 64; Float128Align = 128; LargeArrayMinWidth = 0; LargeArrayAlign = 0; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0; MaxVectorAlign = 0; MaxTLSAlign = 0; SimdDefaultAlign = 0; SizeType = UnsignedLong; PtrDiffType = SignedLong; IntMaxType = SignedLongLong; IntPtrType = SignedLong; WCharType = SignedInt; WIntType = SignedInt; Char16Type = UnsignedShort; Char32Type = UnsignedInt; Int64Type = SignedLongLong; SigAtomicType = SignedInt; ProcessIDType = SignedInt; UseSignedCharForObjCBool = true; UseBitFieldTypeAlignment = true; UseZeroLengthBitfieldAlignment = false; UseExplicitBitFieldAlignment = true; ZeroLengthBitfieldBoundary = 0; HalfFormat = &llvm::APFloat::IEEEhalf(); FloatFormat = &llvm::APFloat::IEEEsingle(); DoubleFormat = &llvm::APFloat::IEEEdouble(); LongDoubleFormat = &llvm::APFloat::IEEEdouble(); Float128Format = &llvm::APFloat::IEEEquad(); MCountName = "mcount"; RegParmMax = 0; SSERegParmMax = 0; HasAlignMac68kSupport = false; HasBuiltinMSVaList = false; IsRenderScriptTarget = false; // Default to no types using fpret. RealTypeUsesObjCFPRet = 0; // Default to not using fp2ret for __Complex long double ComplexLongDoubleUsesFP2Ret = false; // Set the C++ ABI based on the triple. TheCXXABI.set(Triple.isKnownWindowsMSVCEnvironment() ? TargetCXXABI::Microsoft : TargetCXXABI::GenericItanium); // Default to an empty address space map. AddrSpaceMap = &DefaultAddrSpaceMap; UseAddrSpaceMapMangling = false; // Default to an unknown platform name. PlatformName = "unknown"; PlatformMinVersion = VersionTuple(); }
std::unique_ptr<ELFLinkingContext> elf::createX86LinkingContext(llvm::Triple triple) { if (triple.getArch() == llvm::Triple::x86) return llvm::make_unique<X86LinkingContext>(triple); return nullptr; }
void InitHeaderSearch:: AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts) { llvm::Triple::OSType os = triple.getOS(); StringRef CxxIncludeRoot(CXX_INCLUDE_ROOT); if (CxxIncludeRoot != "") { StringRef CxxIncludeArch(CXX_INCLUDE_ARCH); if (CxxIncludeArch == "") AddGnuCPlusPlusIncludePaths(CxxIncludeRoot, triple.str().c_str(), CXX_INCLUDE_32BIT_DIR, CXX_INCLUDE_64BIT_DIR, triple); else AddGnuCPlusPlusIncludePaths(CxxIncludeRoot, CXX_INCLUDE_ARCH, CXX_INCLUDE_32BIT_DIR, CXX_INCLUDE_64BIT_DIR, triple); return; } // FIXME: temporary hack: hard-coded paths. if (triple.isOSDarwin()) { switch (triple.getArch()) { default: break; case llvm::Triple::ppc: case llvm::Triple::ppc64: AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "powerpc-apple-darwin10", "", "ppc64", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0", "powerpc-apple-darwin10", "", "ppc64", triple); break; case llvm::Triple::x86: case llvm::Triple::x86_64: AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "i686-apple-darwin10", "", "x86_64", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0", "i686-apple-darwin8", "", "", triple); break; case llvm::Triple::arm: case llvm::Triple::thumb: AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "arm-apple-darwin10", "v7", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "arm-apple-darwin10", "v6", "", triple); break; } return; } switch (os) { case llvm::Triple::Cygwin: // Cygwin-1.7 AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.4"); // g++-4 / Cygwin-1.5 AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.2"); // FIXME: Do we support g++-3.4.4? AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "3.4.4"); break; case llvm::Triple::MinGW32: // mingw-w64 C++ include paths (i686-w64-mingw32 and x86_64-w64-mingw32) AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.0"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.1"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.2"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.3"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.0"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.1"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.2"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.7.0"); // mingw.org C++ include paths AddMinGWCPlusPlusIncludePaths("/mingw/lib/gcc", "mingw32", "4.5.2"); //MSYS AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.0"); AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.4.0"); AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.3.0"); break; case llvm::Triple::DragonFly: AddPath("/usr/include/c++/4.1", CXXSystem, true, false, false); break; case llvm::Triple::Linux: //===------------------------------------------------------------------===// // Debian based distros. // Note: these distros symlink /usr/include/c++/X.Y.Z -> X.Y //===------------------------------------------------------------------===// // Ubuntu 11.11 "Oneiric Ocelot" -- gcc-4.6.0 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6", "x86_64-linux-gnu", "32", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6", "i686-linux-gnu", "", "64", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6", "i486-linux-gnu", "", "64", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6", "arm-linux-gnueabi", "", "", triple); // Ubuntu 11.04 "Natty Narwhal" -- gcc-4.5.2 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5", "x86_64-linux-gnu", "32", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5", "i686-linux-gnu", "", "64", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5", "i486-linux-gnu", "", "64", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5", "arm-linux-gnueabi", "", "", triple); // Ubuntu 10.10 "Maverick Meerkat" -- gcc-4.4.5 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4", "i686-linux-gnu", "", "64", triple); // The rest of 10.10 is the same as previous versions. // Ubuntu 10.04 LTS "Lucid Lynx" -- gcc-4.4.3 // Ubuntu 9.10 "Karmic Koala" -- gcc-4.4.1 // Debian 6.0 "squeeze" -- gcc-4.4.2 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4", "x86_64-linux-gnu", "32", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4", "i486-linux-gnu", "", "64", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4", "arm-linux-gnueabi", "", "", triple); // Ubuntu 9.04 "Jaunty Jackalope" -- gcc-4.3.3 // Ubuntu 8.10 "Intrepid Ibex" -- gcc-4.3.2 // Debian 5.0 "lenny" -- gcc-4.3.2 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3", "x86_64-linux-gnu", "32", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3", "i486-linux-gnu", "", "64", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3", "arm-linux-gnueabi", "", "", triple); // Ubuntu 8.04.4 LTS "Hardy Heron" -- gcc-4.2.4 // Ubuntu 8.04.[0-3] LTS "Hardy Heron" -- gcc-4.2.3 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2", "x86_64-linux-gnu", "32", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2", "i486-linux-gnu", "", "64", triple); // Ubuntu 7.10 "Gutsy Gibbon" -- gcc-4.1.3 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1", "x86_64-linux-gnu", "32", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1", "i486-linux-gnu", "", "64", triple); //===------------------------------------------------------------------===// // Redhat based distros. //===------------------------------------------------------------------===// // Fedora 15 (GCC 4.6.1) AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.1", "x86_64-redhat-linux", "32", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.1", "i686-redhat-linux", "", "", triple); // Fedora 15 (GCC 4.6.0) AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.0", "x86_64-redhat-linux", "32", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.0", "i686-redhat-linux", "", "", triple); // Fedora 14 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.1", "x86_64-redhat-linux", "32", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.1", "i686-redhat-linux", "", "", triple); // RHEL5(gcc44) AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.4", "x86_64-redhat-linux6E", "32", "", triple); // Fedora 13 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.4", "x86_64-redhat-linux", "32", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.4", "i686-redhat-linux","", "", triple); // Fedora 12 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3", "x86_64-redhat-linux", "32", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3", "i686-redhat-linux","", "", triple); // Fedora 12 (pre-FEB-2010) AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2", "x86_64-redhat-linux", "32", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2", "i686-redhat-linux","", "", triple); // Fedora 11 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1", "x86_64-redhat-linux", "32", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1", "i586-redhat-linux","", "", triple); // Fedora 10 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.2", "x86_64-redhat-linux", "32", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.2", "i386-redhat-linux","", "", triple); // Fedora 9 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.0", "x86_64-redhat-linux", "32", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.0", "i386-redhat-linux", "", "", triple); // Fedora 8 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.2", "x86_64-redhat-linux", "", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.2", "i386-redhat-linux", "", "", triple); // RHEL 5 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.1", "x86_64-redhat-linux", "32", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.1", "i386-redhat-linux", "", "", triple); //===------------------------------------------------------------------===// // Exherbo (2010-01-25) AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3", "x86_64-pc-linux-gnu", "32", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3", "i686-pc-linux-gnu", "", "", triple); // openSUSE 11.1 32 bit AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3", "i586-suse-linux", "", "", triple); // openSUSE 11.1 64 bit AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3", "x86_64-suse-linux", "32", "", triple); // openSUSE 11.2 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4", "i586-suse-linux", "", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4", "x86_64-suse-linux", "", "", triple); // openSUSE 11.4 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5", "i586-suse-linux", "", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5", "x86_64-suse-linux", "", "", triple); // openSUSE 12.1 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6", "i586-suse-linux", "", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6", "x86_64-suse-linux", "", "", triple); // Arch Linux 2008-06-24 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.1", "i686-pc-linux-gnu", "", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.1", "x86_64-unknown-linux-gnu", "", "", triple); // Arch Linux gcc 4.6 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.1", "i686-pc-linux-gnu", "", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.1", "x86_64-unknown-linux-gnu", "", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.0", "i686-pc-linux-gnu", "", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.0", "x86_64-unknown-linux-gnu", "", "", triple); // Slackware gcc 4.5.2 (13.37) AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.2", "i486-slackware-linux", "", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.2", "x86_64-slackware-linux", "", "", triple); // Slackware gcc 4.5.3 (-current) AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.3", "i486-slackware-linux", "", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.3", "x86_64-slackware-linux", "", "", triple); // Gentoo x86 gcc 4.5.2 AddGnuCPlusPlusIncludePaths( "/usr/lib/gcc/i686-pc-linux-gnu/4.5.2/include/g++-v4", "i686-pc-linux-gnu", "", "", triple); // Gentoo x86 gcc 4.4.5 AddGnuCPlusPlusIncludePaths( "/usr/lib/gcc/i686-pc-linux-gnu/4.4.5/include/g++-v4", "i686-pc-linux-gnu", "", "", triple); // Gentoo x86 gcc 4.4.4 AddGnuCPlusPlusIncludePaths( "/usr/lib/gcc/i686-pc-linux-gnu/4.4.4/include/g++-v4", "i686-pc-linux-gnu", "", "", triple); // Gentoo x86 2010.0 stable AddGnuCPlusPlusIncludePaths( "/usr/lib/gcc/i686-pc-linux-gnu/4.4.3/include/g++-v4", "i686-pc-linux-gnu", "", "", triple); // Gentoo x86 2009.1 stable AddGnuCPlusPlusIncludePaths( "/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4", "i686-pc-linux-gnu", "", "", triple); // Gentoo x86 2009.0 stable AddGnuCPlusPlusIncludePaths( "/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4", "i686-pc-linux-gnu", "", "", triple); // Gentoo x86 2008.0 stable AddGnuCPlusPlusIncludePaths( "/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include/g++-v4", "i686-pc-linux-gnu", "", "", triple); // Gentoo x86 llvm-gcc trunk AddGnuCPlusPlusIncludePaths( "/usr/lib/llvm-gcc-4.2-9999/include/c++/4.2.1", "i686-pc-linux-gnu", "", "", triple); // Gentoo amd64 gcc 4.5.2 AddGnuCPlusPlusIncludePaths( "/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.2/include/g++-v4", "x86_64-pc-linux-gnu", "32", "", triple); // Gentoo amd64 gcc 4.4.5 AddGnuCPlusPlusIncludePaths( "/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.5/include/g++-v4", "x86_64-pc-linux-gnu", "32", "", triple); // Gentoo amd64 gcc 4.4.4 AddGnuCPlusPlusIncludePaths( "/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.4/include/g++-v4", "x86_64-pc-linux-gnu", "32", "", triple); // Gentoo amd64 gcc 4.4.3 AddGnuCPlusPlusIncludePaths( "/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3/include/g++-v4", "x86_64-pc-linux-gnu", "32", "", triple); // Gentoo amd64 gcc 4.3.4 AddGnuCPlusPlusIncludePaths( "/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/include/g++-v4", "x86_64-pc-linux-gnu", "", "", triple); // Gentoo amd64 gcc 4.3.2 AddGnuCPlusPlusIncludePaths( "/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.2/include/g++-v4", "x86_64-pc-linux-gnu", "", "", triple); // Gentoo amd64 stable AddGnuCPlusPlusIncludePaths( "/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include/g++-v4", "x86_64-pc-linux-gnu", "", "", triple); // Gentoo amd64 llvm-gcc trunk AddGnuCPlusPlusIncludePaths( "/usr/lib/llvm-gcc-4.2-9999/include/c++/4.2.1", "x86_64-pc-linux-gnu", "", "", triple); break; case llvm::Triple::FreeBSD: // FreeBSD 8.0 // FreeBSD 7.3 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2", "", "", "", triple); break; case llvm::Triple::NetBSD: AddGnuCPlusPlusIncludePaths("/usr/include/g++", "", "", "", triple); break; case llvm::Triple::OpenBSD: { std::string t = triple.getTriple(); if (t.substr(0, 6) == "x86_64") t.replace(0, 6, "amd64"); AddGnuCPlusPlusIncludePaths("/usr/include/g++", t, "", "", triple); break; } case llvm::Triple::Minix: AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3", "", "", "", triple); break; case llvm::Triple::Solaris: // Solaris - Fall though.. case llvm::Triple::AuroraUX: // AuroraUX AddGnuCPlusPlusIncludePaths("/opt/gcc4/include/c++/4.2.4", "i386-pc-solaris2.11", "", "", triple); break; default: break; } }
IRGenModule::IRGenModule(IRGenModuleDispatcher &dispatcher, SourceFile *SF, ASTContext &Context, llvm::LLVMContext &LLVMContext, IRGenOptions &Opts, StringRef ModuleName, const llvm::DataLayout &DataLayout, const llvm::Triple &Triple, llvm::TargetMachine *TargetMachine, SILModule *SILMod, StringRef OutputFilename) : Context(Context), Opts(Opts), ClangCodeGen(createClangCodeGenerator(Context, LLVMContext, Opts, ModuleName)), Module(*ClangCodeGen->GetModule()), LLVMContext(Module.getContext()), DataLayout(DataLayout), Triple(Triple), TargetMachine(TargetMachine), SILMod(SILMod), OutputFilename(OutputFilename), dispatcher(dispatcher), TargetInfo(SwiftTargetInfo::get(*this)), DebugInfo(0), ModuleHash(nullptr), ObjCInterop(Context.LangOpts.EnableObjCInterop), Types(*new TypeConverter(*this)) { dispatcher.addGenModule(SF, this); // If the command line contains an explicit request about whether to add // LLVM value names, honor it. Otherwise, add value names only if the // final result is textual LLVM assembly. if (Opts.HasValueNamesSetting) { EnableValueNames = Opts.ValueNames; } else { EnableValueNames = (Opts.OutputKind == IRGenOutputKind::LLVMAssembly); } VoidTy = llvm::Type::getVoidTy(getLLVMContext()); Int1Ty = llvm::Type::getInt1Ty(getLLVMContext()); Int8Ty = llvm::Type::getInt8Ty(getLLVMContext()); Int16Ty = llvm::Type::getInt16Ty(getLLVMContext()); Int32Ty = llvm::Type::getInt32Ty(getLLVMContext()); Int64Ty = llvm::Type::getInt64Ty(getLLVMContext()); Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext()); Int8PtrPtrTy = Int8PtrTy->getPointerTo(0); SizeTy = DataLayout.getIntPtrType(getLLVMContext(), /*addrspace*/ 0); auto CI = static_cast<ClangImporter*>(&*Context.getClangModuleLoader()); assert(CI && "no clang module loader"); auto &clangASTContext = CI->getClangASTContext(); ObjCBoolTy = Int1Ty; if (clangASTContext.getTargetInfo().useSignedCharForObjCBool()) ObjCBoolTy = Int8Ty; RefCountedStructTy = llvm::StructType::create(getLLVMContext(), "swift.refcounted"); RefCountedPtrTy = RefCountedStructTy->getPointerTo(/*addrspace*/ 0); RefCountedNull = llvm::ConstantPointerNull::get(RefCountedPtrTy); // For now, native weak references are just a pointer. WeakReferencePtrTy = createStructPointerType(*this, "swift.weak", { RefCountedPtrTy }); // Native unowned references are just a pointer. UnownedReferencePtrTy = createStructPointerType(*this, "swift.unowned", { RefCountedPtrTy }); // A type metadata record is the structure pointed to by the canonical // address point of a type metadata. This is at least one word, and // potentially more than that, past the start of the actual global // structure. TypeMetadataStructTy = createStructType(*this, "swift.type", { MetadataKindTy // MetadataKind Kind; }); TypeMetadataPtrTy = TypeMetadataStructTy->getPointerTo(DefaultAS); // A protocol descriptor describes a protocol. It is not type metadata in // and of itself, but is referenced in the structure of existential type // metadata records. ProtocolDescriptorStructTy = createStructType(*this, "swift.protocol", { Int8PtrTy, // objc isa Int8PtrTy, // name Int8PtrTy, // inherited protocols Int8PtrTy, // required objc instance methods Int8PtrTy, // required objc class methods Int8PtrTy, // optional objc instance methods Int8PtrTy, // optional objc class methods Int8PtrTy, // objc properties Int32Ty, // size Int32Ty, // flags Int16Ty, // minimum witness count Int16Ty, // default witness count Int32Ty // padding }); ProtocolDescriptorPtrTy = ProtocolDescriptorStructTy->getPointerTo(); // A tuple type metadata record has a couple extra fields. auto tupleElementTy = createStructType(*this, "swift.tuple_element_type", { TypeMetadataPtrTy, // Metadata *Type; SizeTy // size_t Offset; }); TupleTypeMetadataPtrTy = createStructPointerType(*this, "swift.tuple_type", { TypeMetadataStructTy, // (base) SizeTy, // size_t NumElements; Int8PtrTy, // const char *Labels; llvm::ArrayType::get(tupleElementTy, 0) // Element Elements[]; }); // A full type metadata record is basically just an adjustment to the // address point of a type metadata. Resilience may cause // additional data to be laid out prior to this address point. FullTypeMetadataStructTy = createStructType(*this, "swift.full_type", { WitnessTablePtrTy, TypeMetadataStructTy }); FullTypeMetadataPtrTy = FullTypeMetadataStructTy->getPointerTo(DefaultAS); // A metadata pattern is a structure from which generic type // metadata are allocated. We leave this struct type intentionally // opaque, because the compiler basically never needs to access // anything from one. TypeMetadataPatternStructTy = llvm::StructType::create(getLLVMContext(), "swift.type_pattern"); TypeMetadataPatternPtrTy = TypeMetadataPatternStructTy->getPointerTo(DefaultAS); DeallocatingDtorTy = llvm::FunctionType::get(VoidTy, RefCountedPtrTy, false); llvm::Type *dtorPtrTy = DeallocatingDtorTy->getPointerTo(); // A full heap metadata is basically just an additional small prefix // on a full metadata, used for metadata corresponding to heap // allocations. FullHeapMetadataStructTy = createStructType(*this, "swift.full_heapmetadata", { dtorPtrTy, WitnessTablePtrTy, TypeMetadataStructTy }); FullHeapMetadataPtrTy = FullHeapMetadataStructTy->getPointerTo(DefaultAS); // A full box metadata is non-type heap metadata for a heap allocation of a // single value. The box tracks the offset to the value inside the box. FullBoxMetadataStructTy = createStructType(*this, "swift.full_boxmetadata", { dtorPtrTy, WitnessTablePtrTy, TypeMetadataStructTy, Int32Ty, }); FullBoxMetadataPtrTy = FullBoxMetadataStructTy->getPointerTo(DefaultAS); llvm::Type *refCountedElts[] = { TypeMetadataPtrTy, Int32Ty, Int32Ty }; RefCountedStructTy->setBody(refCountedElts); PtrSize = Size(DataLayout.getPointerSize(DefaultAS)); FunctionPairTy = createStructType(*this, "swift.function", { FunctionPtrTy, RefCountedPtrTy, }); OpaquePtrTy = llvm::StructType::create(LLVMContext, "swift.opaque") ->getPointerTo(DefaultAS); ProtocolConformanceRecordTy = createStructType(*this, "swift.protocol_conformance", { RelativeAddressTy, RelativeAddressTy, RelativeAddressTy, Int32Ty }); ProtocolConformanceRecordPtrTy = ProtocolConformanceRecordTy->getPointerTo(DefaultAS); NominalTypeDescriptorTy = llvm::StructType::create(LLVMContext, "swift.type_descriptor"); NominalTypeDescriptorPtrTy = NominalTypeDescriptorTy->getPointerTo(DefaultAS); TypeMetadataRecordTy = createStructType(*this, "swift.type_metadata_record", { RelativeAddressTy, Int32Ty }); TypeMetadataRecordPtrTy = TypeMetadataRecordTy->getPointerTo(DefaultAS); FieldDescriptorTy = llvm::StructType::create(LLVMContext, "swift.field_descriptor"); FieldDescriptorPtrTy = FieldDescriptorTy->getPointerTo(DefaultAS); FixedBufferTy = nullptr; for (unsigned i = 0; i != MaxNumValueWitnesses; ++i) ValueWitnessTys[i] = nullptr; ObjCPtrTy = llvm::StructType::create(getLLVMContext(), "objc_object") ->getPointerTo(DefaultAS); BridgeObjectPtrTy = llvm::StructType::create(getLLVMContext(), "swift.bridge") ->getPointerTo(DefaultAS); ObjCClassStructTy = llvm::StructType::create(LLVMContext, "objc_class"); ObjCClassPtrTy = ObjCClassStructTy->getPointerTo(DefaultAS); llvm::Type *objcClassElts[] = { ObjCClassPtrTy, ObjCClassPtrTy, OpaquePtrTy, OpaquePtrTy, IntPtrTy }; ObjCClassStructTy->setBody(objcClassElts); ObjCSuperStructTy = llvm::StructType::create(LLVMContext, "objc_super"); ObjCSuperPtrTy = ObjCSuperStructTy->getPointerTo(DefaultAS); llvm::Type *objcSuperElts[] = { ObjCPtrTy, ObjCClassPtrTy }; ObjCSuperStructTy->setBody(objcSuperElts); ObjCBlockStructTy = llvm::StructType::create(LLVMContext, "objc_block"); ObjCBlockPtrTy = ObjCBlockStructTy->getPointerTo(DefaultAS); llvm::Type *objcBlockElts[] = { ObjCClassPtrTy, // isa Int32Ty, // flags Int32Ty, // reserved FunctionPtrTy, // invoke function pointer Int8PtrTy, // TODO: block descriptor pointer. // We will probably need a struct type for that at some // point too. }; ObjCBlockStructTy->setBody(objcBlockElts); auto ErrorStructTy = llvm::StructType::create(LLVMContext, "swift.error"); // ErrorStruct is currently opaque to the compiler. ErrorPtrTy = ErrorStructTy->getPointerTo(DefaultAS); llvm::Type *openedErrorTriple[] = { OpaquePtrTy, TypeMetadataPtrTy, WitnessTablePtrTy, }; OpenedErrorTripleTy = llvm::StructType::get(getLLVMContext(), openedErrorTriple, /*packed*/ false); OpenedErrorTriplePtrTy = OpenedErrorTripleTy->getPointerTo(DefaultAS); InvariantMetadataID = LLVMContext.getMDKindID("invariant.load"); InvariantNode = llvm::MDNode::get(LLVMContext, {}); DereferenceableID = LLVMContext.getMDKindID("dereferenceable"); C_CC = llvm::CallingConv::C; // TODO: use "tinycc" on platforms that support it DefaultCC = SWIFT_LLVM_CC(DefaultCC); // If it is an interpreter, don't use try to use any // advanced calling conventions and use instead a // more conservative C calling convention. This // makes sure that none of the registers eventually // used by the dynamic linker are used by generated code. // TODO: Check that the deployment target supports the new // calling convention. Older versions of the runtime library // may not contain the entries using the new calling convention. // Only use the new calling conventions on platforms that support it. auto Arch = Triple.getArch(); if (SWIFT_RT_USE_RegisterPreservingCC && Arch == llvm::Triple::ArchType::aarch64) { RegisterPreservingCC = SWIFT_LLVM_CC(RegisterPreservingCC); } else { RegisterPreservingCC = DefaultCC; } ABITypes = new CodeGenABITypes(clangASTContext, Module); if (Opts.DebugInfoKind != IRGenDebugInfoKind::None) { DebugInfo = new IRGenDebugInfo(Opts, *CI, *this, Module, SF); } initClangTypeConverter(); }
std::unique_ptr<lld::ELFLinkingContext> elf::createHexagonLinkingContext(llvm::Triple triple) { if (triple.getArch() == llvm::Triple::hexagon) return llvm::make_unique<HexagonLinkingContext>(triple); return nullptr; }
void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts) { llvm::Triple::OSType os = triple.getOS(); if (HSOpts.UseStandardSystemIncludes) { switch (os) { case llvm::Triple::FreeBSD: case llvm::Triple::NetBSD: case llvm::Triple::OpenBSD: case llvm::Triple::Bitrig: break; default: // FIXME: temporary hack: hard-coded paths. AddPath("/usr/local/include", System, false); break; } } // Builtin includes use #include_next directives and should be positioned // just prior C include dirs. if (HSOpts.UseBuiltinIncludes) { // Ignore the sys root, we *always* look for clang headers relative to // supplied path. llvm::sys::Path P(HSOpts.ResourceDir); P.appendComponent("include"); AddUnmappedPath(P.str(), ExternCSystem, false); } // All remaining additions are for system include directories, early exit if // we aren't using them. if (!HSOpts.UseStandardSystemIncludes) return; // Add dirs specified via 'configure --with-c-include-dirs'. StringRef CIncludeDirs(C_INCLUDE_DIRS); if (CIncludeDirs != "") { SmallVector<StringRef, 5> dirs; CIncludeDirs.split(dirs, ":"); for (SmallVectorImpl<StringRef>::iterator i = dirs.begin(); i != dirs.end(); ++i) AddPath(*i, ExternCSystem, false); return; } switch (os) { case llvm::Triple::Linux: case llvm::Triple::Win32: llvm_unreachable("Include management is handled in the driver."); case llvm::Triple::Haiku: AddPath("/boot/common/include", System, false); AddPath("/boot/develop/headers/os", System, false); AddPath("/boot/develop/headers/os/app", System, false); AddPath("/boot/develop/headers/os/arch", System, false); AddPath("/boot/develop/headers/os/device", System, false); AddPath("/boot/develop/headers/os/drivers", System, false); AddPath("/boot/develop/headers/os/game", System, false); AddPath("/boot/develop/headers/os/interface", System, false); AddPath("/boot/develop/headers/os/kernel", System, false); AddPath("/boot/develop/headers/os/locale", System, false); AddPath("/boot/develop/headers/os/mail", System, false); AddPath("/boot/develop/headers/os/media", System, false); AddPath("/boot/develop/headers/os/midi", System, false); AddPath("/boot/develop/headers/os/midi2", System, false); AddPath("/boot/develop/headers/os/net", System, false); AddPath("/boot/develop/headers/os/storage", System, false); AddPath("/boot/develop/headers/os/support", System, false); AddPath("/boot/develop/headers/os/translation", System, false); AddPath("/boot/develop/headers/os/add-ons/graphics", System, false); AddPath("/boot/develop/headers/os/add-ons/input_server", System, false); AddPath("/boot/develop/headers/os/add-ons/screen_saver", System, false); AddPath("/boot/develop/headers/os/add-ons/tracker", System, false); AddPath("/boot/develop/headers/os/be_apps/Deskbar", System, false); AddPath("/boot/develop/headers/os/be_apps/NetPositive", System, false); AddPath("/boot/develop/headers/os/be_apps/Tracker", System, false); AddPath("/boot/develop/headers/cpp", System, false); AddPath("/boot/develop/headers/cpp/i586-pc-haiku", System, false); AddPath("/boot/develop/headers/3rdparty", System, false); AddPath("/boot/develop/headers/bsd", System, false); AddPath("/boot/develop/headers/glibc", System, false); AddPath("/boot/develop/headers/posix", System, false); AddPath("/boot/develop/headers", System, false); break; case llvm::Triple::RTEMS: break; case llvm::Triple::Cygwin: AddPath("/usr/include/w32api", System, false); break; case llvm::Triple::MinGW32: { // mingw-w64 crt include paths llvm::sys::Path P(HSOpts.ResourceDir); P.appendComponent("../../../i686-w64-mingw32/include"); // <sysroot>/i686-w64-mingw32/include AddPath(P.str(), System, false); P = llvm::sys::Path(HSOpts.ResourceDir); P.appendComponent("../../../x86_64-w64-mingw32/include"); // <sysroot>/x86_64-w64-mingw32/include AddPath(P.str(), System, false); // mingw.org crt include paths P = llvm::sys::Path(HSOpts.ResourceDir); P.appendComponent("../../../include"); // <sysroot>/include AddPath(P.str(), System, false); AddPath("/mingw/include", System, false); #if defined(_WIN32) AddPath("c:/mingw/include", System, false); #endif } break; default: break; } if ( os != llvm::Triple::RTEMS ) AddPath("/usr/include", ExternCSystem, false); }
static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args, DiagnosticEngine &Diags, const FrontendOptions &FrontendOpts, const SILOptions &SILOpts, StringRef SDKPath, StringRef ResourceDir, const llvm::Triple &Triple) { using namespace options; if (!SILOpts.SILOutputFileNameForDebugging.empty()) { Opts.DebugInfoLevel = IRGenDebugInfoLevel::LineTables; } else if (const Arg *A = Args.getLastArg(OPT_g_Group)) { if (A->getOption().matches(OPT_g)) Opts.DebugInfoLevel = IRGenDebugInfoLevel::Normal; else if (A->getOption().matches(options::OPT_gline_tables_only)) Opts.DebugInfoLevel = IRGenDebugInfoLevel::LineTables; else if (A->getOption().matches(options::OPT_gdwarf_types)) Opts.DebugInfoLevel = IRGenDebugInfoLevel::DwarfTypes; else assert(A->getOption().matches(options::OPT_gnone) && "unknown -g<kind> option"); if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::LineTables) { if (Args.hasArg(options::OPT_debug_info_store_invocation)) { ArgStringList RenderedArgs; for (auto A : Args) A->render(Args, RenderedArgs); CompilerInvocation::buildDebugFlags(Opts.DebugFlags, RenderedArgs, SDKPath, ResourceDir); } // TODO: Should we support -fdebug-compilation-dir? llvm::SmallString<256> cwd; llvm::sys::fs::current_path(cwd); Opts.DebugCompilationDir = cwd.str(); } } if (const Arg *A = Args.getLastArg(options::OPT_debug_info_format)) { if (A->containsValue("dwarf")) Opts.DebugInfoFormat = IRGenDebugInfoFormat::DWARF; else if (A->containsValue("codeview")) Opts.DebugInfoFormat = IRGenDebugInfoFormat::CodeView; else Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, A->getAsString(Args), A->getValue()); } else if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::None) { // If -g was specified but not -debug-info-format, DWARF is assumed. Opts.DebugInfoFormat = IRGenDebugInfoFormat::DWARF; } if (Args.hasArg(options::OPT_debug_info_format) && !Args.hasArg(options::OPT_g_Group)) { const Arg *debugFormatArg = Args.getLastArg(options::OPT_debug_info_format); Diags.diagnose(SourceLoc(), diag::error_option_missing_required_argument, debugFormatArg->getAsString(Args), "-g"); } if (Opts.DebugInfoFormat == IRGenDebugInfoFormat::CodeView && (Opts.DebugInfoLevel == IRGenDebugInfoLevel::LineTables || Opts.DebugInfoLevel == IRGenDebugInfoLevel::DwarfTypes)) { const Arg *debugFormatArg = Args.getLastArg(options::OPT_debug_info_format); Diags.diagnose(SourceLoc(), diag::error_argument_not_allowed_with, debugFormatArg->getAsString(Args), Opts.DebugInfoLevel == IRGenDebugInfoLevel::LineTables ? "-gline-tables-only" : "-gdwarf_types"); } for (auto A : Args.getAllArgValues(options::OPT_debug_prefix_map)) { auto SplitMap = StringRef(A).split('='); Opts.DebugPrefixMap.addMapping(SplitMap.first, SplitMap.second); } for (const Arg *A : Args.filtered(OPT_Xcc)) { StringRef Opt = A->getValue(); if (Opt.startswith("-D") || Opt.startswith("-U")) Opts.ClangDefines.push_back(Opt); } for (const Arg *A : Args.filtered(OPT_l, OPT_framework)) { LibraryKind Kind; if (A->getOption().matches(OPT_l)) { Kind = LibraryKind::Library; } else if (A->getOption().matches(OPT_framework)) { Kind = LibraryKind::Framework; } else { llvm_unreachable("Unknown LinkLibrary option kind"); } Opts.LinkLibraries.push_back(LinkLibrary(A->getValue(), Kind)); } if (auto valueNames = Args.getLastArg(OPT_disable_llvm_value_names, OPT_enable_llvm_value_names)) { Opts.HasValueNamesSetting = true; Opts.ValueNames = valueNames->getOption().matches(OPT_enable_llvm_value_names); } Opts.DisableLLVMOptzns |= Args.hasArg(OPT_disable_llvm_optzns); Opts.DisableSwiftSpecificLLVMOptzns |= Args.hasArg(OPT_disable_swift_specific_llvm_optzns); Opts.DisableLLVMSLPVectorizer |= Args.hasArg(OPT_disable_llvm_slp_vectorizer); if (Args.hasArg(OPT_disable_llvm_verify)) Opts.Verify = false; Opts.EmitStackPromotionChecks |= Args.hasArg(OPT_stack_promotion_checks); if (const Arg *A = Args.getLastArg(OPT_stack_promotion_limit)) { unsigned limit; if (StringRef(A->getValue()).getAsInteger(10, limit)) { Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, A->getAsString(Args), A->getValue()); return true; } Opts.StackPromotionSizeLimit = limit; } if (Args.hasArg(OPT_autolink_force_load)) Opts.ForceLoadSymbolName = Args.getLastArgValue(OPT_module_link_name); Opts.ModuleName = FrontendOpts.ModuleName; if (Args.hasArg(OPT_use_jit)) Opts.UseJIT = true; for (const Arg *A : Args.filtered(OPT_verify_type_layout)) { Opts.VerifyTypeLayoutNames.push_back(A->getValue()); } for (const Arg *A : Args.filtered(OPT_disable_autolink_framework)) { Opts.DisableAutolinkFrameworks.push_back(A->getValue()); } Opts.GenerateProfile |= Args.hasArg(OPT_profile_generate); const Arg *ProfileUse = Args.getLastArg(OPT_profile_use); Opts.UseProfile = ProfileUse ? ProfileUse->getValue() : ""; Opts.PrintInlineTree |= Args.hasArg(OPT_print_llvm_inline_tree); Opts.EnableDynamicReplacementChaining |= Args.hasArg(OPT_enable_dynamic_replacement_chaining); Opts.UseSwiftCall = Args.hasArg(OPT_enable_swiftcall); // This is set to true by default. Opts.UseIncrementalLLVMCodeGen &= !Args.hasArg(OPT_disable_incremental_llvm_codegeneration); if (Args.hasArg(OPT_embed_bitcode)) Opts.EmbedMode = IRGenEmbedMode::EmbedBitcode; else if (Args.hasArg(OPT_embed_bitcode_marker)) Opts.EmbedMode = IRGenEmbedMode::EmbedMarker; if (Opts.EmbedMode == IRGenEmbedMode::EmbedBitcode) { // Keep track of backend options so we can embed them in a separate data // section and use them when building from the bitcode. This can be removed // when all the backend options are recorded in the IR. for (const Arg *A : Args) { // Do not encode output and input. if (A->getOption().getID() == options::OPT_o || A->getOption().getID() == options::OPT_INPUT || A->getOption().getID() == options::OPT_primary_file || A->getOption().getID() == options::OPT_embed_bitcode) continue; ArgStringList ASL; A->render(Args, ASL); for (ArgStringList::iterator it = ASL.begin(), ie = ASL.end(); it != ie; ++ it) { StringRef ArgStr(*it); Opts.CmdArgs.insert(Opts.CmdArgs.end(), ArgStr.begin(), ArgStr.end()); // using \00 to terminate to avoid problem decoding. Opts.CmdArgs.push_back('\0'); } } } if (const Arg *A = Args.getLastArg(options::OPT_sanitize_coverage_EQ)) { Opts.SanitizeCoverage = parseSanitizerCoverageArgValue(A, Triple, Diags, Opts.Sanitizers); } else if (Opts.Sanitizers & SanitizerKind::Fuzzer) { // Automatically set coverage flags, unless coverage type was explicitly // requested. Opts.SanitizeCoverage.IndirectCalls = true; Opts.SanitizeCoverage.TraceCmp = true; Opts.SanitizeCoverage.TracePCGuard = true; Opts.SanitizeCoverage.CoverageType = llvm::SanitizerCoverageOptions::SCK_Edge; } if (Args.hasArg(OPT_disable_reflection_metadata)) { Opts.EnableReflectionMetadata = false; Opts.EnableReflectionNames = false; } if (Args.hasArg(OPT_disable_reflection_names)) { Opts.EnableReflectionNames = false; } if (Args.hasArg(OPT_enable_class_resilience)) { Opts.EnableClassResilience = true; } if (Args.hasArg(OPT_enable_resilience_bypass)) { Opts.EnableResilienceBypass = true; } // PE/COFF cannot deal with the cross-module reference to the metadata parent // (e.g. NativeObject). Force the lazy initialization of the VWT always. Opts.LazyInitializeClassMetadata = Triple.isOSBinFormatCOFF(); if (const Arg *A = Args.getLastArg(OPT_read_type_info_path_EQ)) { Opts.ReadTypeInfoPath = A->getValue(); } for (const auto &Lib : Args.getAllArgValues(options::OPT_autolink_library)) Opts.LinkLibraries.push_back(LinkLibrary(Lib, LibraryKind::Library)); if (const Arg *A = Args.getLastArg(OPT_type_info_dump_filter_EQ)) { StringRef mode(A->getValue()); if (mode == "all") Opts.TypeInfoFilter = IRGenOptions::TypeInfoDumpFilter::All; else if (mode == "resilient") Opts.TypeInfoFilter = IRGenOptions::TypeInfoDumpFilter::Resilient; else if (mode == "fragile") Opts.TypeInfoFilter = IRGenOptions::TypeInfoDumpFilter::Fragile; else { Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, A->getAsString(Args), A->getValue()); } } return false; }
// Scatter sections in all directions! // Remaps section addresses for -verify mode. The following command line options // can be used to customize the layout of the memory within the phony target's // address space: // -target-addr-start <s> -- Specify where the phony target addres range starts. // -target-addr-end <e> -- Specify where the phony target address range ends. // -target-section-sep <d> -- Specify how big a gap should be left between the // end of one section and the start of the next. // Defaults to zero. Set to something big // (e.g. 1 << 32) to stress-test stubs, GOTs, etc. // static void remapSectionsAndSymbols(const llvm::Triple &TargetTriple, TrivialMemoryManager &MemMgr, RuntimeDyldChecker &Checker) { // Set up a work list (section addr/size pairs). typedef std::list<std::pair<void*, uint64_t>> WorklistT; WorklistT Worklist; for (const auto& CodeSection : MemMgr.FunctionMemory) Worklist.push_back(std::make_pair(CodeSection.base(), CodeSection.size())); for (const auto& DataSection : MemMgr.DataMemory) Worklist.push_back(std::make_pair(DataSection.base(), DataSection.size())); // Apply any section-specific mappings that were requested on the command // line. typedef std::map<void*, uint64_t> AppliedMappingsT; AppliedMappingsT AppliedMappings = applySpecificSectionMappings(Checker); // Keep an "already allocated" mapping of section target addresses to sizes. // Sections whose address mappings aren't specified on the command line will // allocated around the explicitly mapped sections while maintaining the // minimum separation. std::map<uint64_t, uint64_t> AlreadyAllocated; // Move the previously applied mappings into the already-allocated map. for (WorklistT::iterator I = Worklist.begin(), E = Worklist.end(); I != E;) { WorklistT::iterator Tmp = I; ++I; AppliedMappingsT::iterator AI = AppliedMappings.find(Tmp->first); if (AI != AppliedMappings.end()) { AlreadyAllocated[AI->second] = Tmp->second; Worklist.erase(Tmp); } } // If the -target-addr-end option wasn't explicitly passed, then set it to a // sensible default based on the target triple. if (TargetAddrEnd.getNumOccurrences() == 0) { if (TargetTriple.isArch16Bit()) TargetAddrEnd = (1ULL << 16) - 1; else if (TargetTriple.isArch32Bit()) TargetAddrEnd = (1ULL << 32) - 1; // TargetAddrEnd already has a sensible default for 64-bit systems, so // there's nothing to do in the 64-bit case. } // Process any elements remaining in the worklist. while (!Worklist.empty()) { std::pair<void*, uint64_t> CurEntry = Worklist.front(); Worklist.pop_front(); uint64_t NextSectionAddr = TargetAddrStart; for (const auto &Alloc : AlreadyAllocated) if (NextSectionAddr + CurEntry.second + TargetSectionSep <= Alloc.first) break; else NextSectionAddr = Alloc.first + Alloc.second + TargetSectionSep; AlreadyAllocated[NextSectionAddr] = CurEntry.second; Checker.getRTDyld().mapSectionAddress(CurEntry.first, NextSectionAddr); } // Add dummy symbols to the memory manager. for (const auto &Mapping : DummySymbolMappings) { size_t EqualsIdx = Mapping.find_first_of("="); if (EqualsIdx == StringRef::npos) report_fatal_error("Invalid dummy symbol specification '" + Mapping + "'. Should be '<symbol name>=<addr>'"); std::string Symbol = Mapping.substr(0, EqualsIdx); std::string AddrStr = Mapping.substr(EqualsIdx + 1); uint64_t Addr; if (StringRef(AddrStr).getAsInteger(0, Addr)) report_fatal_error("Invalid symbol mapping '" + Mapping + "'."); MemMgr.addDummySymbol(Symbol, Addr); } }
std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T, bool FromAs) { Arg *A; switch (T.getArch()) { default: return ""; case llvm::Triple::aarch64: case llvm::Triple::aarch64_be: return aarch64::getAArch64TargetCPU(Args, A); case llvm::Triple::arm: case llvm::Triple::armeb: case llvm::Triple::thumb: case llvm::Triple::thumbeb: { StringRef MArch, MCPU; arm::getARMArchCPUFromArgs(Args, MArch, MCPU, FromAs); return arm::getARMTargetCPU(MCPU, MArch, T); } case llvm::Triple::avr: if (const Arg *A = Args.getLastArg(options::OPT_mmcu_EQ)) return A->getValue(); return ""; case llvm::Triple::nios2: { return getNios2TargetCPU(Args); } case llvm::Triple::mips: case llvm::Triple::mipsel: case llvm::Triple::mips64: case llvm::Triple::mips64el: { StringRef CPUName; StringRef ABIName; mips::getMipsCPUAndABI(Args, T, CPUName, ABIName); return CPUName; } case llvm::Triple::nvptx: case llvm::Triple::nvptx64: if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) return A->getValue(); return ""; case llvm::Triple::ppc: case llvm::Triple::ppc64: case llvm::Triple::ppc64le: { std::string TargetCPUName = ppc::getPPCTargetCPU(Args); // LLVM may default to generating code for the native CPU, // but, like gcc, we default to a more generic option for // each architecture. (except on Darwin) if (TargetCPUName.empty() && !T.isOSDarwin()) { if (T.getArch() == llvm::Triple::ppc64) TargetCPUName = "ppc64"; else if (T.getArch() == llvm::Triple::ppc64le) TargetCPUName = "ppc64le"; else TargetCPUName = "ppc"; } return TargetCPUName; } case llvm::Triple::bpfel: case llvm::Triple::bpfeb: case llvm::Triple::sparc: case llvm::Triple::sparcel: case llvm::Triple::sparcv9: if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) return A->getValue(); return ""; case llvm::Triple::x86: case llvm::Triple::x86_64: return x86::getX86TargetCPU(Args, T); case llvm::Triple::hexagon: return "hexagon" + toolchains::HexagonToolChain::GetTargetCPUVersion(Args).str(); case llvm::Triple::lanai: return getLanaiTargetCPU(Args); case llvm::Triple::systemz: return systemz::getSystemZTargetCPU(Args); case llvm::Triple::r600: case llvm::Triple::amdgcn: return getR600TargetGPU(Args); case llvm::Triple::wasm32: case llvm::Triple::wasm64: return getWebAssemblyTargetCPU(Args); case llvm::Triple::z80: case llvm::Triple::ez80: return getZ80TargetCPU(Args, T); } }
static bool supportsNilWithFloatRet(const llvm::Triple &triple) { return (triple.getVendor() == llvm::Triple::Apple && (triple.isiOS() || !triple.isMacOSXVersionLT(10,5))); }
// CloudABI and WebAssembly use -ffunction-sections and -fdata-sections by // default. bool tools::isUseSeparateSections(const llvm::Triple &Triple) { return Triple.getOS() == llvm::Triple::CloudABI || Triple.getArch() == llvm::Triple::wasm32 || Triple.getArch() == llvm::Triple::wasm64; }
void InitHeaderSearch:: AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts) { llvm::Triple::OSType os = triple.getOS(); // FIXME: temporary hack: hard-coded paths. if (triple.isOSDarwin()) { switch (triple.getArch()) { default: break; case llvm::Triple::ppc: case llvm::Triple::ppc64: AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "powerpc-apple-darwin10", "", "ppc64", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0", "powerpc-apple-darwin10", "", "ppc64", triple); break; case llvm::Triple::x86: case llvm::Triple::x86_64: AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "i686-apple-darwin10", "", "x86_64", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0", "i686-apple-darwin8", "", "", triple); break; case llvm::Triple::arm: case llvm::Triple::thumb: AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "arm-apple-darwin10", "v7", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "arm-apple-darwin10", "v6", "", triple); break; case llvm::Triple::aarch64: AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "arm64-apple-darwin10", "", "", triple); break; } return; } switch (os) { case llvm::Triple::Linux: case llvm::Triple::Solaris: llvm_unreachable("Include management is handled in the driver."); break; case llvm::Triple::Win32: switch (triple.getEnvironment()) { default: llvm_unreachable("Include management is handled in the driver."); case llvm::Triple::Cygnus: // Cygwin-1.7 AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.7.3"); AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.5.3"); AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.4"); // g++-4 / Cygwin-1.5 AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.2"); break; } break; case llvm::Triple::DragonFly: AddPath("/usr/include/c++/5.0", CXXSystem, false); break; case llvm::Triple::OpenBSD: { std::string t = triple.getTriple(); if (t.substr(0, 6) == "x86_64") t.replace(0, 6, "amd64"); AddGnuCPlusPlusIncludePaths("/usr/include/g++", t, "", "", triple); break; } case llvm::Triple::Minix: AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3", "", "", "", triple); break; default: break; } }
std::unique_ptr<ELFLinkingContext> elf::createExampleLinkingContext(llvm::Triple triple) { if (triple.getVendorName() == "example") return llvm::make_unique<ExampleLinkingContext>(triple); return nullptr; }
std::unique_ptr<ELFLinkingContext> createARMLinkingContext(llvm::Triple triple) { if (triple.getArch() == llvm::Triple::arm) return llvm::make_unique<ARMLinkingContext>(triple); return nullptr; }
CudaInstallationDetector::CudaInstallationDetector( const Driver &D, const llvm::Triple &HostTriple, const llvm::opt::ArgList &Args) : D(D) { SmallVector<std::string, 4> CudaPathCandidates; // In decreasing order so we prefer newer versions to older versions. std::initializer_list<const char *> Versions = {"8.0", "7.5", "7.0"}; if (Args.hasArg(clang::driver::options::OPT_cuda_path_EQ)) { CudaPathCandidates.push_back( Args.getLastArgValue(clang::driver::options::OPT_cuda_path_EQ)); } else if (HostTriple.isOSWindows()) { for (const char *Ver : Versions) CudaPathCandidates.push_back( D.SysRoot + "/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v" + Ver); } else { CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda"); for (const char *Ver : Versions) CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-" + Ver); } for (const auto &CudaPath : CudaPathCandidates) { if (CudaPath.empty() || !D.getVFS().exists(CudaPath)) continue; InstallPath = CudaPath; BinPath = CudaPath + "/bin"; IncludePath = InstallPath + "/include"; LibDevicePath = InstallPath + "/nvvm/libdevice"; auto &FS = D.getVFS(); if (!(FS.exists(IncludePath) && FS.exists(BinPath) && FS.exists(LibDevicePath))) continue; // On Linux, we have both lib and lib64 directories, and we need to choose // based on our triple. On MacOS, we have only a lib directory. // // It's sufficient for our purposes to be flexible: If both lib and lib64 // exist, we choose whichever one matches our triple. Otherwise, if only // lib exists, we use it. if (HostTriple.isArch64Bit() && FS.exists(InstallPath + "/lib64")) LibPath = InstallPath + "/lib64"; else if (FS.exists(InstallPath + "/lib")) LibPath = InstallPath + "/lib"; else continue; llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> VersionFile = FS.getBufferForFile(InstallPath + "/version.txt"); if (!VersionFile) { // CUDA 7.0 doesn't have a version.txt, so guess that's our version if // version.txt isn't present. Version = CudaVersion::CUDA_70; } else { Version = ParseCudaVersionFile((*VersionFile)->getBuffer()); } std::error_code EC; for (llvm::sys::fs::directory_iterator LI(LibDevicePath, EC), LE; !EC && LI != LE; LI = LI.increment(EC)) { StringRef FilePath = LI->path(); StringRef FileName = llvm::sys::path::filename(FilePath); // Process all bitcode filenames that look like libdevice.compute_XX.YY.bc const StringRef LibDeviceName = "libdevice."; if (!(FileName.startswith(LibDeviceName) && FileName.endswith(".bc"))) continue; StringRef GpuArch = FileName.slice( LibDeviceName.size(), FileName.find('.', LibDeviceName.size())); LibDeviceMap[GpuArch] = FilePath.str(); // Insert map entries for specifc devices with this compute // capability. NVCC's choice of the libdevice library version is // rather peculiar and depends on the CUDA version. if (GpuArch == "compute_20") { LibDeviceMap["sm_20"] = FilePath; LibDeviceMap["sm_21"] = FilePath; LibDeviceMap["sm_32"] = FilePath; } else if (GpuArch == "compute_30") { LibDeviceMap["sm_30"] = FilePath; if (Version < CudaVersion::CUDA_80) { LibDeviceMap["sm_50"] = FilePath; LibDeviceMap["sm_52"] = FilePath; LibDeviceMap["sm_53"] = FilePath; } LibDeviceMap["sm_60"] = FilePath; LibDeviceMap["sm_61"] = FilePath; LibDeviceMap["sm_62"] = FilePath; } else if (GpuArch == "compute_35") { LibDeviceMap["sm_35"] = FilePath; LibDeviceMap["sm_37"] = FilePath; } else if (GpuArch == "compute_50") { if (Version >= CudaVersion::CUDA_80) { LibDeviceMap["sm_50"] = FilePath; LibDeviceMap["sm_52"] = FilePath; LibDeviceMap["sm_53"] = FilePath; } } } IsValid = true; break; } }
static bool supportsNilWithFloatRet(const llvm::Triple &triple) { return triple.getVendor() == llvm::Triple::Apple && (!triple.isMacOSXVersionLT(10,5) || triple.getArch() == llvm::Triple::arm || triple.getArch() == llvm::Triple::thumb); }
bool swift::tripleIsWatchSimulator(const llvm::Triple &triple) { llvm::Triple::ArchType arch = triple.getArch(); return (triple.isWatchOS() && (arch == llvm::Triple::x86 || arch == llvm::Triple::x86_64)); }
/// \brief Get our best guess at the multiarch triple for a target. /// /// Debian-based systems are starting to use a multiarch setup where they use /// a target-triple directory in the library and header search paths. /// Unfortunately, this triple does not align with the vanilla target triple, /// so we provide a rough mapping here. static std::string getMultiarchTriple(const Driver &D, const llvm::Triple &TargetTriple, StringRef SysRoot) { llvm::Triple::EnvironmentType TargetEnvironment = TargetTriple.getEnvironment(); // For most architectures, just use whatever we have rather than trying to be // clever. switch (TargetTriple.getArch()) { default: break; // We use the existence of '/lib/<triple>' as a directory to detect some // common linux triples that don't quite match the Clang triple for both // 32-bit and 64-bit targets. Multiarch fixes its install triples to these // regardless of what the actual target triple is. case llvm::Triple::arm: case llvm::Triple::thumb: if (TargetEnvironment == llvm::Triple::GNUEABIHF) { if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabihf")) return "arm-linux-gnueabihf"; } else { if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabi")) return "arm-linux-gnueabi"; } break; case llvm::Triple::armeb: case llvm::Triple::thumbeb: if (TargetEnvironment == llvm::Triple::GNUEABIHF) { if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabihf")) return "armeb-linux-gnueabihf"; } else { if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabi")) return "armeb-linux-gnueabi"; } break; case llvm::Triple::x86: if (D.getVFS().exists(SysRoot + "/lib/i386-linux-gnu")) return "i386-linux-gnu"; break; case llvm::Triple::x86_64: // We don't want this for x32, otherwise it will match x86_64 libs if (TargetEnvironment != llvm::Triple::GNUX32 && D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnu")) return "x86_64-linux-gnu"; break; case llvm::Triple::aarch64: if (D.getVFS().exists(SysRoot + "/lib/aarch64-linux-gnu")) return "aarch64-linux-gnu"; break; case llvm::Triple::aarch64_be: if (D.getVFS().exists(SysRoot + "/lib/aarch64_be-linux-gnu")) return "aarch64_be-linux-gnu"; break; case llvm::Triple::mips: if (D.getVFS().exists(SysRoot + "/lib/mips-linux-gnu")) return "mips-linux-gnu"; break; case llvm::Triple::mipsel: if (D.getVFS().exists(SysRoot + "/lib/mipsel-linux-gnu")) return "mipsel-linux-gnu"; break; case llvm::Triple::mips64: if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnu")) return "mips64-linux-gnu"; if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnuabi64")) return "mips64-linux-gnuabi64"; break; case llvm::Triple::mips64el: if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnu")) return "mips64el-linux-gnu"; if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnuabi64")) return "mips64el-linux-gnuabi64"; break; case llvm::Triple::ppc: if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnuspe")) return "powerpc-linux-gnuspe"; if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnu")) return "powerpc-linux-gnu"; break; case llvm::Triple::ppc64: if (D.getVFS().exists(SysRoot + "/lib/powerpc64-linux-gnu")) return "powerpc64-linux-gnu"; break; case llvm::Triple::ppc64le: if (D.getVFS().exists(SysRoot + "/lib/powerpc64le-linux-gnu")) return "powerpc64le-linux-gnu"; break; case llvm::Triple::sparc: if (D.getVFS().exists(SysRoot + "/lib/sparc-linux-gnu")) return "sparc-linux-gnu"; break; case llvm::Triple::sparcv9: if (D.getVFS().exists(SysRoot + "/lib/sparc64-linux-gnu")) return "sparc64-linux-gnu"; break; case llvm::Triple::systemz: if (D.getVFS().exists(SysRoot + "/lib/s390x-linux-gnu")) return "s390x-linux-gnu"; break; } return TargetTriple.str(); }
OptionSet<SanitizerKind> swift::parseSanitizerArgValues( const llvm::opt::ArgList &Args, const llvm::opt::Arg *A, const llvm::Triple &Triple, DiagnosticEngine &Diags, llvm::function_ref<bool(llvm::StringRef, bool)> sanitizerRuntimeLibExists) { OptionSet<SanitizerKind> sanitizerSet; // Find the sanitizer kind. for (int i = 0, n = A->getNumValues(); i != n; ++i) { auto kind = llvm::StringSwitch<Optional<SanitizerKind>>(A->getValue(i)) .Case("address", SanitizerKind::Address) .Case("thread", SanitizerKind::Thread) .Case("fuzzer", SanitizerKind::Fuzzer) .Default(None); bool isShared = kind && *kind != SanitizerKind::Fuzzer; if (!kind) { Diags.diagnose(SourceLoc(), diag::error_unsupported_option_argument, A->getOption().getPrefixedName(), A->getValue(i)); } else { // Support is determined by existance of the sanitizer library. bool sanitizerSupported = sanitizerRuntimeLibExists(toFileName(*kind), isShared); // TSan is explicitly not supported for 32 bits. if (*kind == SanitizerKind::Thread && !Triple.isArch64Bit()) sanitizerSupported = false; if (!sanitizerSupported) { SmallString<128> b; Diags.diagnose(SourceLoc(), diag::error_unsupported_opt_for_target, (A->getOption().getPrefixedName() + toStringRef(*kind)) .toStringRef(b), Triple.getTriple()); } else { sanitizerSet |= *kind; } } } // Check that we're one of the known supported targets for sanitizers. if (!(Triple.isOSDarwin() || Triple.isOSLinux() || Triple.isOSWindows())) { SmallString<128> b; Diags.diagnose(SourceLoc(), diag::error_unsupported_opt_for_target, (A->getOption().getPrefixedName() + StringRef(A->getAsString(Args))).toStringRef(b), Triple.getTriple()); } // Address and thread sanitizers can not be enabled concurrently. if ((sanitizerSet & SanitizerKind::Thread) && (sanitizerSet & SanitizerKind::Address)) { SmallString<128> b1; SmallString<128> b2; Diags.diagnose(SourceLoc(), diag::error_argument_not_allowed_with, (A->getOption().getPrefixedName() + toStringRef(SanitizerKind::Address)).toStringRef(b1), (A->getOption().getPrefixedName() + toStringRef(SanitizerKind::Thread)).toStringRef(b2)); } return sanitizerSet; }