@@ -929,6 +929,22 @@ static bool searchForFile(SmallVectorImpl<char> &FilePath,
929
929
return false ;
930
930
}
931
931
932
+ static void appendOneArg (InputArgList &Args, const Arg *Opt,
933
+ const Arg *BaseArg) {
934
+ // The args for config files or /clang: flags belong to different InputArgList
935
+ // objects than Args. This copies an Arg from one of those other InputArgLists
936
+ // to the ownership of Args.
937
+ unsigned Index = Args.MakeIndex (Opt->getSpelling ());
938
+ Arg *Copy = new llvm::opt::Arg (Opt->getOption (), Args.getArgString (Index),
939
+ Index, BaseArg);
940
+ Copy->getValues () = Opt->getValues ();
941
+ if (Opt->isClaimed ())
942
+ Copy->claim ();
943
+ Copy->setOwnsValues (Opt->getOwnsValues ());
944
+ Opt->setOwnsValues (false );
945
+ Args.append (Copy);
946
+ }
947
+
932
948
bool Driver::readConfigFile (StringRef FileName) {
933
949
// Try reading the given file.
934
950
SmallVector<const char *, 32 > NewCfgArgs;
@@ -940,31 +956,38 @@ bool Driver::readConfigFile(StringRef FileName) {
940
956
// Read options from config file.
941
957
llvm::SmallString<128 > CfgFileName (FileName);
942
958
llvm::sys::path::native (CfgFileName);
943
- ConfigFile = std::string (CfgFileName);
944
959
bool ContainErrors;
945
- CfgOptions = std::make_unique<InputArgList>(
960
+ std::unique_ptr<InputArgList> NewOptions = std::make_unique<InputArgList>(
946
961
ParseArgStrings (NewCfgArgs, IsCLMode (), ContainErrors));
947
- if (ContainErrors) {
948
- CfgOptions.reset ();
962
+ if (ContainErrors)
949
963
return true ;
950
- }
951
964
952
- if (CfgOptions->hasArg (options::OPT_config)) {
953
- CfgOptions.reset ();
965
+ if (NewOptions->hasArg (options::OPT_config)) {
954
966
Diag (diag::err_drv_nested_config_file);
955
967
return true ;
956
968
}
957
969
958
970
// Claim all arguments that come from a configuration file so that the driver
959
971
// does not warn on any that is unused.
960
- for (Arg *A : *CfgOptions )
972
+ for (Arg *A : *NewOptions )
961
973
A->claim ();
974
+
975
+ if (!CfgOptions)
976
+ CfgOptions = std::move (NewOptions);
977
+ else {
978
+ // If this is a subsequent config file, append options to the previous one.
979
+ for (auto *Opt : *NewOptions) {
980
+ const Arg *BaseArg = &Opt->getBaseArg ();
981
+ if (BaseArg == Opt)
982
+ BaseArg = nullptr ;
983
+ appendOneArg (*CfgOptions, Opt, BaseArg);
984
+ }
985
+ }
986
+ ConfigFiles.push_back (std::string (CfgFileName));
962
987
return false ;
963
988
}
964
989
965
- bool Driver::loadConfigFile () {
966
- std::string CfgFileName;
967
-
990
+ bool Driver::loadConfigFiles () {
968
991
// Process options that change search path for config files.
969
992
if (CLOptions) {
970
993
if (CLOptions->hasArg (options::OPT_config_system_dir_EQ)) {
@@ -990,26 +1013,18 @@ bool Driver::loadConfigFile() {
990
1013
// Prepare list of directories where config file is searched for.
991
1014
StringRef CfgFileSearchDirs[] = {UserConfigDir, SystemConfigDir, Dir};
992
1015
993
- // First try to find config file specified in command line.
1016
+ // First try to load configuration from the default files, return on error.
1017
+ if (loadDefaultConfigFiles (CfgFileSearchDirs))
1018
+ return true ;
1019
+
1020
+ // Then load configuration files specified explicitly.
994
1021
llvm::SmallString<128 > CfgFilePath;
995
1022
if (CLOptions) {
996
- std::vector<std::string> ConfigFiles =
997
- CLOptions->getAllArgValues (options::OPT_config);
998
- if (ConfigFiles.size () > 1 ) {
999
- if (!llvm::all_equal (ConfigFiles)) {
1000
- Diag (diag::err_drv_duplicate_config);
1001
- return true ;
1002
- }
1003
- }
1004
-
1005
- if (!ConfigFiles.empty ()) {
1006
- CfgFileName = ConfigFiles.front ();
1007
- assert (!CfgFileName.empty ());
1008
-
1023
+ for (auto CfgFileName : CLOptions->getAllArgValues (options::OPT_config)) {
1009
1024
// If argument contains directory separator, treat it as a path to
1010
1025
// configuration file.
1011
1026
if (llvm::sys::path::has_parent_path (CfgFileName)) {
1012
- SmallString< 128 > CfgFilePath ( CfgFileName) ;
1027
+ CfgFilePath = CfgFileName;
1013
1028
if (llvm::sys::path::is_relative (CfgFilePath)) {
1014
1029
if (getVFS ().makeAbsolute (CfgFilePath))
1015
1030
return true ;
@@ -1020,35 +1035,37 @@ bool Driver::loadConfigFile() {
1020
1035
return true ;
1021
1036
}
1022
1037
}
1023
- return readConfigFile (CfgFilePath);
1038
+ } else if (!searchForFile (CfgFilePath, CfgFileSearchDirs, CfgFileName,
1039
+ getVFS ())) {
1040
+ // Report an error that the config file could not be found.
1041
+ Diag (diag::err_drv_config_file_not_found) << CfgFileName;
1042
+ for (const StringRef &SearchDir : CfgFileSearchDirs)
1043
+ if (!SearchDir.empty ())
1044
+ Diag (diag::note_drv_config_file_searched_in) << SearchDir;
1045
+ return true ;
1024
1046
}
1025
1047
1026
- // Look for the configuration file in the usual locations.
1027
- if (searchForFile (CfgFilePath, CfgFileSearchDirs, CfgFileName, getVFS ()))
1028
- return readConfigFile (CfgFilePath);
1029
-
1030
- // Report error but only if config file was specified explicitly, by
1031
- // option --config. If it was deduced from executable name, it is not an
1032
- // error.
1033
- Diag (diag::err_drv_config_file_not_found) << CfgFileName;
1034
- for (const StringRef &SearchDir : CfgFileSearchDirs)
1035
- if (!SearchDir.empty ())
1036
- Diag (diag::note_drv_config_file_searched_in) << SearchDir;
1037
- return true ;
1048
+ // Try to read the config file, return on error.
1049
+ if (readConfigFile (CfgFilePath))
1050
+ return true ;
1038
1051
}
1039
1052
}
1040
1053
1041
- if (!(CLOptions && CLOptions->hasArg (options::OPT_no_default_config))) {
1042
- // If config file is not specified explicitly, try to deduce configuration
1043
- // from executable name. For instance, an executable 'armv7l-clang' will
1044
- // search for config file 'armv7l-clang.cfg'.
1045
- if (CfgFileName.empty () && !ClangNameParts.TargetPrefix .empty ())
1046
- CfgFileName =
1047
- ClangNameParts.TargetPrefix + ' -' + ClangNameParts.ModeSuffix ;
1048
- }
1054
+ // No error occurred.
1055
+ return false ;
1056
+ }
1049
1057
1050
- if (CfgFileName.empty ())
1058
+ bool Driver::loadDefaultConfigFiles (ArrayRef<StringRef> CfgFileSearchDirs) {
1059
+ if (CLOptions && CLOptions->hasArg (options::OPT_no_default_config))
1051
1060
return false ;
1061
+ if (ClangNameParts.TargetPrefix .empty ())
1062
+ return false ;
1063
+
1064
+ // If config file is not specified explicitly, try to deduce configuration
1065
+ // from executable name. For instance, an executable 'armv7l-clang' will
1066
+ // search for config file 'armv7l-clang.cfg'.
1067
+ std::string CfgFileName =
1068
+ ClangNameParts.TargetPrefix + ' -' + ClangNameParts.ModeSuffix ;
1052
1069
1053
1070
// Determine architecture part of the file name, if it is present.
1054
1071
StringRef CfgFileArch = CfgFileName;
@@ -1086,6 +1103,7 @@ bool Driver::loadConfigFile() {
1086
1103
}
1087
1104
1088
1105
// Try to find config file. First try file with corrected architecture.
1106
+ llvm::SmallString<128 > CfgFilePath;
1089
1107
if (!FixedConfigFile.empty ()) {
1090
1108
if (searchForFile (CfgFilePath, CfgFileSearchDirs, FixedConfigFile,
1091
1109
getVFS ()))
@@ -1138,36 +1156,21 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
1138
1156
1139
1157
// Try parsing configuration file.
1140
1158
if (!ContainsError)
1141
- ContainsError = loadConfigFile ();
1159
+ ContainsError = loadConfigFiles ();
1142
1160
bool HasConfigFile = !ContainsError && (CfgOptions.get () != nullptr );
1143
1161
1144
1162
// All arguments, from both config file and command line.
1145
1163
InputArgList Args = std::move (HasConfigFile ? std::move (*CfgOptions)
1146
1164
: std::move (*CLOptions));
1147
1165
1148
- // The args for config files or /clang: flags belong to different InputArgList
1149
- // objects than Args. This copies an Arg from one of those other InputArgLists
1150
- // to the ownership of Args.
1151
- auto appendOneArg = [&Args](const Arg *Opt, const Arg *BaseArg) {
1152
- unsigned Index = Args.MakeIndex (Opt->getSpelling ());
1153
- Arg *Copy = new llvm::opt::Arg (Opt->getOption (), Args.getArgString (Index),
1154
- Index, BaseArg);
1155
- Copy->getValues () = Opt->getValues ();
1156
- if (Opt->isClaimed ())
1157
- Copy->claim ();
1158
- Copy->setOwnsValues (Opt->getOwnsValues ());
1159
- Opt->setOwnsValues (false );
1160
- Args.append (Copy);
1161
- };
1162
-
1163
1166
if (HasConfigFile)
1164
1167
for (auto *Opt : *CLOptions) {
1165
1168
if (Opt->getOption ().matches (options::OPT_config))
1166
1169
continue ;
1167
1170
const Arg *BaseArg = &Opt->getBaseArg ();
1168
1171
if (BaseArg == Opt)
1169
1172
BaseArg = nullptr ;
1170
- appendOneArg (Opt, BaseArg);
1173
+ appendOneArg (Args, Opt, BaseArg);
1171
1174
}
1172
1175
1173
1176
// In CL mode, look for any pass-through arguments
@@ -1186,7 +1189,7 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
1186
1189
1187
1190
if (!ContainsError)
1188
1191
for (auto *Opt : *CLModePassThroughOptions) {
1189
- appendOneArg (Opt, nullptr );
1192
+ appendOneArg (Args, Opt, nullptr );
1190
1193
}
1191
1194
}
1192
1195
}
@@ -1880,8 +1883,8 @@ void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const {
1880
1883
// Print out the install directory.
1881
1884
OS << " InstalledDir: " << InstalledDir << ' \n ' ;
1882
1885
1883
- // If configuration file was used, print its path .
1884
- if (! ConfigFile. empty () )
1886
+ // If configuration files were used, print their paths .
1887
+ for ( auto ConfigFile : ConfigFiles )
1885
1888
OS << " Configuration file: " << ConfigFile << ' \n ' ;
1886
1889
}
1887
1890
0 commit comments