@@ -103,14 +103,14 @@ ToolChain::ToolChain(const Driver &D, const llvm::Triple &T,
103
103
for (const auto &Path : getArchSpecificLibPaths ())
104
104
addIfExists (getFilePaths (), Path);
105
105
106
- #if 0
107
- if (D.IsFlangMode()) {
108
- getIntrinsicModulePaths().append(getDefaultIntrinsicModulePaths());
109
- }
110
- #endif
106
+ #if 0
107
+ if (std::optional<std::string> Path = getDefaultIntrinsicModuleDir())
108
+ getIntrinsicModulePaths().push_back(*Path);
109
+ #endif
111
110
}
112
111
113
112
113
+
114
114
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
115
115
ToolChain::executeToolChainProgram (StringRef Executable) const {
116
116
llvm::SmallString<64 > OutputFile;
@@ -874,8 +874,52 @@ void ToolChain::addFlangRTLibPath(const ArgList &Args,
874
874
// Android target triples contain a target version. If we don't have libraries
875
875
// for the exact target version, we should fall back to the next newest version
876
876
// or a versionless path, if any.
877
+ static
878
+ std::optional<std::string>
879
+ getFallbackAndroidTargetPath (StringRef BaseDir, const llvm::Triple &T, llvm::vfs::FileSystem &VFS, DiagnosticsEngine *Diags) {
880
+ llvm::Triple TripleWithoutLevel (T);
881
+ TripleWithoutLevel.setEnvironmentName (" android" ); // remove any version number
882
+ const std::string &TripleWithoutLevelStr = TripleWithoutLevel.str ();
883
+ unsigned TripleVersion = T.getEnvironmentVersion ().getMajor ();
884
+ unsigned BestVersion = 0 ;
885
+
886
+ SmallString<32 > TripleDir;
887
+ bool UsingUnversionedDir = false ;
888
+ std::error_code EC;
889
+ for (llvm::vfs::directory_iterator LI = VFS.dir_begin (BaseDir, EC), LE;
890
+ !EC && LI != LE; LI = LI.increment (EC)) {
891
+ StringRef DirName = llvm::sys::path::filename (LI->path ());
892
+ StringRef DirNameSuffix = DirName;
893
+ if (DirNameSuffix.consume_front (TripleWithoutLevelStr)) {
894
+ if (DirNameSuffix.empty () && TripleDir.empty ()) {
895
+ TripleDir = DirName;
896
+ UsingUnversionedDir = true ;
897
+ } else {
898
+ unsigned Version;
899
+ if (!DirNameSuffix.getAsInteger (10 , Version) && Version > BestVersion &&
900
+ Version < TripleVersion) {
901
+ BestVersion = Version;
902
+ TripleDir = DirName;
903
+ UsingUnversionedDir = false ;
904
+ }
905
+ }
906
+ }
907
+ }
908
+
909
+ if (TripleDir.empty ())
910
+ return {};
911
+
912
+ SmallString<128 > P (BaseDir);
913
+ llvm::sys::path::append (P, TripleDir);
914
+ if (UsingUnversionedDir && Diags)
915
+ Diags->Report (diag::warn_android_unversioned_fallback) << P << T.getTriple ();
916
+ return std::string (P);
917
+ }
918
+
877
919
std::optional<std::string>
878
920
ToolChain::getFallbackAndroidTargetPath (StringRef BaseDir) const {
921
+ return ::getFallbackAndroidTargetPath (BaseDir, getTriple (), getVFS (), &D.getDiags ());
922
+ #if 0
879
923
llvm::Triple TripleWithoutLevel(getTriple());
880
924
TripleWithoutLevel.setEnvironmentName("android"); // remove any version number
881
925
const std::string &TripleWithoutLevelStr = TripleWithoutLevel.str();
@@ -913,9 +957,10 @@ ToolChain::getFallbackAndroidTargetPath(StringRef BaseDir) const {
913
957
if (UsingUnversionedDir)
914
958
D.Diag(diag::warn_android_unversioned_fallback) << P << getTripleString();
915
959
return std::string(P);
960
+ #endif
916
961
}
917
962
918
- llvm::Triple ToolChain::getTripleWithoutOSVersion () const {
963
+ llvm::Triple ToolChain::getTripleWithoutOSVersion (const llvm::Triple &Triple) {
919
964
return (Triple.hasEnvironment ()
920
965
? llvm::Triple (Triple.getArchName (), Triple.getVendorName (),
921
966
llvm::Triple::getOSTypeName (Triple.getOS ()),
@@ -925,8 +970,74 @@ llvm::Triple ToolChain::getTripleWithoutOSVersion() const {
925
970
llvm::Triple::getOSTypeName (Triple.getOS ())));
926
971
}
927
972
973
+ static std::optional<std::string> getTargetSubDirPath (StringRef BaseDir, const llvm::Triple &T ,llvm::vfs::FileSystem &VFS, clang::DiagnosticsEngine *Diags ) {
974
+ auto getPathForTriple = [&](const llvm::Triple &Triple) -> std::optional<std::string> {
975
+ SmallString<128 > P (BaseDir);
976
+ llvm::sys::path::append (P, Triple.str ());
977
+ if (VFS.exists (P))
978
+ return std::string (P);
979
+ return {};
980
+ };
981
+
982
+
983
+ if (auto Path = getPathForTriple (T))
984
+ return *Path;
985
+
986
+ if (T.isOSAIX ()) {
987
+ llvm::Triple AIXTriple;
988
+ if (T.getEnvironment () == Triple::UnknownEnvironment) {
989
+ // Strip unknown environment and the OS version from the triple.
990
+ AIXTriple = llvm::Triple (T.getArchName (), T.getVendorName (),
991
+ llvm::Triple::getOSTypeName (T.getOS ()));
992
+ } else {
993
+ // Strip the OS version from the triple.
994
+ AIXTriple =ToolChain:: getTripleWithoutOSVersion (T);
995
+ }
996
+ if (auto Path = getPathForTriple (AIXTriple))
997
+ return *Path;
998
+ }
999
+
1000
+ if (T.isOSzOS () &&
1001
+ (!T.getOSVersion ().empty () || !T.getEnvironmentVersion ().empty ())) {
1002
+ // Build the triple without version information
1003
+ const llvm::Triple &TripleWithoutVersion =ToolChain:: getTripleWithoutOSVersion (T);
1004
+ if (auto Path = getPathForTriple (TripleWithoutVersion))
1005
+ return *Path;
1006
+ }
1007
+
1008
+ // When building with per target runtime directories, various ways of naming
1009
+ // the Arm architecture may have been normalised to simply "arm".
1010
+ // For example "armv8l" (Armv8 AArch32 little endian) is replaced with "arm".
1011
+ // Since an armv8l system can use libraries built for earlier architecture
1012
+ // versions assuming endian and float ABI match.
1013
+ //
1014
+ // Original triple: armv8l-unknown-linux-gnueabihf
1015
+ // Runtime triple: arm-unknown-linux-gnueabihf
1016
+ //
1017
+ // We do not do this for armeb (big endian) because doing so could make us
1018
+ // select little endian libraries. In addition, all known armeb triples only
1019
+ // use the "armeb" architecture name.
1020
+ //
1021
+ // M profile Arm is bare metal and we know they will not be using the per
1022
+ // target runtime directory layout.
1023
+ if (T.getArch () == Triple::arm && !T.isArmMClass ()) {
1024
+ llvm::Triple ArmTriple = T;
1025
+ ArmTriple.setArch (Triple::arm);
1026
+ if (auto Path = getPathForTriple (ArmTriple))
1027
+ return *Path;
1028
+ }
1029
+
1030
+ if (T.isAndroid ())
1031
+ return :: getFallbackAndroidTargetPath (BaseDir, T, VFS, Diags);
1032
+
1033
+ return {};
1034
+ }
1035
+
1036
+
928
1037
std::optional<std::string>
929
1038
ToolChain::getTargetSubDirPath (StringRef BaseDir) const {
1039
+ return ::getTargetSubDirPath (BaseDir, getTriple (), getVFS (),& D.getDiags () );
1040
+ #if 0
930
1041
auto getPathForTriple =
931
1042
[&](const llvm::Triple &Triple) -> std::optional<std::string> {
932
1043
SmallString<128> P(BaseDir);
@@ -988,6 +1099,19 @@ ToolChain::getTargetSubDirPath(StringRef BaseDir) const {
988
1099
return getFallbackAndroidTargetPath(BaseDir);
989
1100
990
1101
return {};
1102
+ #endif
1103
+ }
1104
+
1105
+ std::optional< std::string> ToolChain::getDefaultIntrinsicModuleDir (StringRef ResourceDir, const llvm::Triple &T ,llvm::vfs::FileSystem &VFS, clang::DiagnosticsEngine *Diags ) {
1106
+ SmallString<128 > P (ResourceDir);
1107
+ llvm::sys::path::append (P, " finclude" );
1108
+ return ::getTargetSubDirPath (P, T, VFS, Diags );
1109
+ // llvm::sys::path::append(instrinsicsDir, "finclude", triple.str());
1110
+ // return instrinsicsDir.str().str();
1111
+ }
1112
+
1113
+ std::optional< std::string> ToolChain::getDefaultIntrinsicModuleDir ( ) const {
1114
+ return ToolChain::getDefaultIntrinsicModuleDir (D.ResourceDir , getTriple (), getVFS (),& D.getDiags () );
991
1115
}
992
1116
993
1117
std::optional<std::string> ToolChain::getRuntimePath () const {
@@ -1015,24 +1139,6 @@ std::optional<std::string> ToolChain::getStdlibIncludePath() const {
1015
1139
return getTargetSubDirPath (P);
1016
1140
}
1017
1141
1018
- ToolChain:: path_list ToolChain:: getDefaultIntrinsicModulePaths() const {
1019
- SmallString<128 > P (D.ResourceDir );
1020
- llvm::sys::path::append (P, " finclude" );
1021
-
1022
- // TODO: If there are multiple valid names for the target triple, prefer to add all of them instead probing which are existing.
1023
- ToolChain:: path_list Result;
1024
- if (std::optional<std::string> PerTargetPath = getTargetSubDirPath (P))
1025
- Result.push_back (*PerTargetPath);
1026
-
1027
- // flang used this in the past, keep for compatibility
1028
- SmallString<128 > CompatIntrModPath (D.Dir );
1029
- llvm::sys::path::append (CompatIntrModPath, " .." , " include" , " flang" );
1030
- Result.push_back (std::string (CompatIntrModPath));
1031
-
1032
- return Result;
1033
- }
1034
-
1035
-
1036
1142
ToolChain::path_list ToolChain::getArchSpecificLibPaths () const {
1037
1143
path_list Paths;
1038
1144
0 commit comments