@@ -1042,34 +1042,59 @@ bool Driver::readConfigFile(StringRef FileName,
10421042 }
10431043
10441044 // Try reading the given file.
1045- SmallVector<const char *, 32 > NewCfgArgs ;
1046- if (llvm::Error Err = ExpCtx.readConfigFile (FileName, NewCfgArgs )) {
1045+ SmallVector<const char *, 32 > NewCfgFileArgs ;
1046+ if (llvm::Error Err = ExpCtx.readConfigFile (FileName, NewCfgFileArgs )) {
10471047 Diag (diag::err_drv_cannot_read_config_file)
10481048 << FileName << toString (std::move (Err));
10491049 return true ;
10501050 }
10511051
1052+ // Populate head and tail lists. The tail list is used only when linking.
1053+ SmallVector<const char *, 32 > NewCfgHeadArgs, NewCfgTailArgs;
1054+ for (const char *Opt : NewCfgFileArgs) {
1055+ // An $-prefixed option should go to the tail list.
1056+ if (Opt[0 ] == ' $' && Opt[1 ])
1057+ NewCfgTailArgs.push_back (Opt + 1 );
1058+ else
1059+ NewCfgHeadArgs.push_back (Opt);
1060+ }
1061+
10521062 // Read options from config file.
10531063 llvm::SmallString<128 > CfgFileName (FileName);
10541064 llvm::sys::path::native (CfgFileName);
1055- bool ContainErrors;
1056- auto NewOptions = std::make_unique<InputArgList>(
1057- ParseArgStrings (NewCfgArgs, /* UseDriverMode=*/ true , ContainErrors));
1065+ bool ContainErrors = false ;
1066+ auto NewHeadOptions = std::make_unique<InputArgList>(
1067+ ParseArgStrings (NewCfgHeadArgs, /* UseDriverMode=*/ true , ContainErrors));
1068+ if (ContainErrors)
1069+ return true ;
1070+ auto NewTailOptions = std::make_unique<InputArgList>(
1071+ ParseArgStrings (NewCfgTailArgs, /* UseDriverMode=*/ true , ContainErrors));
10581072 if (ContainErrors)
10591073 return true ;
10601074
10611075 // Claim all arguments that come from a configuration file so that the driver
10621076 // does not warn on any that is unused.
1063- for (Arg *A : *NewOptions )
1077+ for (Arg *A : *NewHeadOptions )
10641078 A->claim ();
1079+ for (Arg *A : *NewTailOptions)
1080+ A->claim ();
1081+
1082+ if (!CfgOptionsHead)
1083+ CfgOptionsHead = std::move (NewHeadOptions);
1084+ else {
1085+ // If this is a subsequent config file, append options to the previous one.
1086+ for (auto *Opt : *NewHeadOptions)
1087+ appendOneArg (*CfgOptionsHead, Opt);
1088+ }
10651089
1066- if (!CfgOptions )
1067- CfgOptions = std::move (NewOptions );
1090+ if (!CfgOptionsTail )
1091+ CfgOptionsTail = std::move (NewTailOptions );
10681092 else {
10691093 // If this is a subsequent config file, append options to the previous one.
1070- for (auto *Opt : *NewOptions )
1071- appendOneArg (*CfgOptions , Opt);
1094+ for (auto *Opt : *NewTailOptions )
1095+ appendOneArg (*CfgOptionsTail , Opt);
10721096 }
1097+
10731098 ConfigFiles.push_back (std::string (CfgFileName));
10741099 return false ;
10751100}
@@ -1100,20 +1125,6 @@ bool Driver::loadConfigFiles() {
11001125 UserConfigDir = static_cast <std::string>(CfgDir);
11011126 }
11021127 }
1103-
1104- // First try to find config file specified in command line.
1105- if (CLOptions) {
1106- std::vector<std::string> ConfigFiles =
1107- CLOptions->getAllArgValues (options::OPT_config);
1108- if (ConfigFiles.size () > 1 ) {
1109- if (!llvm::all_of (ConfigFiles, [ConfigFiles](const std::string &s) {
1110- return s == ConfigFiles[0 ];
1111- })) {
1112- Diag (diag::err_drv_duplicate_config);
1113- return true ;
1114- }
1115- }
1116- }
11171128 // Prepare list of directories where config file is searched for.
11181129 StringRef CfgFileSearchDirs[] = {UserConfigDir, SystemConfigDir, Dir};
11191130 ExpCtx.setSearchDirs (CfgFileSearchDirs);
@@ -1259,13 +1270,14 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
12591270 // Try parsing configuration file.
12601271 if (!ContainsError)
12611272 ContainsError = loadConfigFiles ();
1262- bool HasConfigFile = !ContainsError && (CfgOptions.get () != nullptr );
1273+ bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1274+ bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
12631275
12641276 // All arguments, from both config file and command line.
1265- InputArgList Args = std::move (HasConfigFile ? std::move (*CfgOptions)
1266- : std::move (*CLOptions) );
1277+ InputArgList Args =
1278+ HasConfigFileHead ? std::move (*CfgOptionsHead) : std::move (*CLOptions);
12671279
1268- if (HasConfigFile )
1280+ if (HasConfigFileHead )
12691281 for (auto *Opt : *CLOptions)
12701282 if (!Opt->getOption ().matches (options::OPT_config))
12711283 appendOneArg (Args, Opt);
@@ -1563,6 +1575,15 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
15631575 // Construct the list of inputs.
15641576 InputList Inputs;
15651577 BuildInputs (C->getDefaultToolChain (), *TranslatedArgs, Inputs);
1578+ if (HasConfigFileTail && Inputs.size ()) {
1579+ Arg *FinalPhaseArg;
1580+ if (getFinalPhase (*TranslatedArgs, &FinalPhaseArg) == phases::Link) {
1581+ DerivedArgList TranslatedLinkerIns (*CfgOptionsTail);
1582+ for (Arg *A : *CfgOptionsTail)
1583+ TranslatedLinkerIns.append (A);
1584+ BuildInputs (C->getDefaultToolChain (), TranslatedLinkerIns, Inputs);
1585+ }
1586+ }
15661587
15671588 // Populate the tool chains for the offloading devices, if any.
15681589 CreateOffloadingDeviceToolChains (*C, Inputs);
0 commit comments