17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//===- PositionalOptions.cpp ----------------------------------------------===//
27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//                     The MCLinker Project
47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// License. See LICENSE.TXT for details.
77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//===----------------------------------------------------------------------===//
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <mcld/PositionalOptions.h>
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <mcld/LinkerConfig.h>
117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <mcld/LinkerScript.h>
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <mcld/MC/InputAction.h>
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <mcld/MC/CommandAction.h>
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <mcld/MC/FileAction.h>
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <mcld/Support/MsgHandling.h>
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace {
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//===----------------------------------------------------------------------===//
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Normal input files
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//===----------------------------------------------------------------------===//
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)llvm::cl::list<mcld::sys::fs::Path> ArgInputObjectFiles(llvm::cl::Positional,
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::desc("[input object files]"),
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::ZeroOrMore);
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// --script is an alias, but cl::alias doesn't work correctly with cl::list.
273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)llvm::cl::list<std::string> ArgLinkerScript("T",
283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  llvm::cl::ZeroOrMore,
293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  llvm::cl::desc("Linker script"),
303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  llvm::cl::value_desc("file"));
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//===----------------------------------------------------------------------===//
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Namespecs
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//===----------------------------------------------------------------------===//
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)llvm::cl::list<std::string> ArgNameSpecList("l",
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::ZeroOrMore,
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::desc("Add the archive or object file specified by namespec to\n"
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 "the list of files to link."),
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::value_desc("namespec"),
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::Prefix);
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)llvm::cl::alias ArgNameSpecListAlias("library",
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::desc("alias for -l"),
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::aliasopt(ArgNameSpecList));
45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)//===----------------------------------------------------------------------===//
47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Attributes
48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)//===----------------------------------------------------------------------===//
49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)llvm::cl::list<bool> ArgWholeArchiveList("whole-archive",
50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  llvm::cl::ValueDisallowed,
517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  llvm::cl::desc("For each archive mentioned on the command line after\n"
527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 "the --whole-archive option, include all object files\n"
537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 "in the archive."));
547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochllvm::cl::list<bool> ArgNoWholeArchiveList("no-whole-archive",
567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  llvm::cl::ValueDisallowed,
577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  llvm::cl::desc("Turn off the effect of the --whole-archive option for\n"
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 "subsequent archive files."));
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)llvm::cl::list<bool> ArgAsNeededList("as-needed",
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::ValueDisallowed,
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::desc("This option affects ELF DT_NEEDED tags for dynamic\n"
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 "libraries mentioned on the command line after the\n"
647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 "--as-needed option."));
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)llvm::cl::list<bool> ArgNoAsNeededList("no-as-needed",
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::ValueDisallowed,
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::desc("Turn off the effect of the --as-needed option for\n"
697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 "subsequent dynamic libraries"));
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)llvm::cl::list<bool> ArgAddNeededList("add-needed",
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::ValueDisallowed,
737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  llvm::cl::desc("--add-needed causes DT_NEEDED tags are always\n"
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 "emitted for those libraries from DT_NEEDED tags.\n"
757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 "This is the default behavior."));
767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochllvm::cl::list<bool> ArgNoAddNeededList("no-add-needed",
787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  llvm::cl::ValueDisallowed,
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  llvm::cl::desc("--no-add-needed causes DT_NEEDED tags will never be\n"
80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 "emitted for those libraries from DT_NEEDED tags"));
81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)llvm::cl::list<bool> ArgBDynamicList("Bdynamic",
837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  llvm::cl::ValueDisallowed,
847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  llvm::cl::desc("Link against dynamic library"));
857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)llvm::cl::alias ArgBDynamicListAlias1("dy",
877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  llvm::cl::desc("alias for --Bdynamic"),
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::aliasopt(ArgBDynamicList));
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)llvm::cl::alias ArgBDynamicListAlias2("call_shared",
917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::desc("alias for --Bdynamic"),
927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::aliasopt(ArgBDynamicList));
937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochllvm::cl::list<bool> ArgBStaticList("Bstatic",
957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  llvm::cl::ValueDisallowed,
967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  llvm::cl::desc("Link against static library"));
977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochllvm::cl::alias ArgBStaticListAlias1("dn",
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::desc("alias for --Bstatic"),
1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  llvm::cl::aliasopt(ArgBStaticList));
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)llvm::cl::alias ArgBStaticListAlias2("static",
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  llvm::cl::desc("alias for --Bstatic"),
1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  llvm::cl::aliasopt(ArgBStaticList));
105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)llvm::cl::alias ArgBStaticListAlias3("non_shared",
1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::desc("alias for --Bstatic"),
1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::aliasopt(ArgBStaticList));
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//===----------------------------------------------------------------------===//
111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Groups
112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)//===----------------------------------------------------------------------===//
113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)llvm::cl::list<bool> ArgStartGroupList("start-group",
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::ValueDisallowed,
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::desc("start to record a group of archives"));
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)llvm::cl::alias ArgStartGroupListAlias("(",
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::desc("alias for --start-group"),
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::aliasopt(ArgStartGroupList));
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)llvm::cl::list<bool> ArgEndGroupList("end-group",
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::ValueDisallowed,
1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::desc("stop recording a group of archives"));
1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochllvm::cl::alias ArgEndGroupListAlias(")",
1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  llvm::cl::desc("alias for --end-group"),
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  llvm::cl::aliasopt(ArgEndGroupList));
1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//===----------------------------------------------------------------------===//
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// --defsym
1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//===----------------------------------------------------------------------===//
1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)llvm::cl::list<std::string> ArgDefSymList("defsym",
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  llvm::cl::ZeroOrMore,
1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::desc("Define a symbol"),
1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::cl::value_desc("symbol=expression"));
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//===----------------------------------------------------------------------===//
1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Help Functions
1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//===----------------------------------------------------------------------===//
1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)inline bool
1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CompareAction(const mcld::InputAction* X, const mcld::InputAction* Y)
1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles){
1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return (X->position() < Y->position());
144}
145
146} // anonymous namespace
147
148using namespace mcld;
149
150//===----------------------------------------------------------------------===//
151// PositionalOptions
152//===----------------------------------------------------------------------===//
153PositionalOptions::PositionalOptions()
154  : m_InputObjectFiles(ArgInputObjectFiles),
155    m_LinkerScript(ArgLinkerScript),
156    m_NameSpecList(ArgNameSpecList),
157    m_WholeArchiveList(ArgWholeArchiveList),
158    m_NoWholeArchiveList(ArgNoWholeArchiveList),
159    m_AsNeededList(ArgAsNeededList),
160    m_NoAsNeededList(ArgNoAsNeededList),
161    m_AddNeededList(ArgAddNeededList),
162    m_NoAddNeededList(ArgNoAddNeededList),
163    m_BDynamicList(ArgBDynamicList),
164    m_BStaticList(ArgBStaticList),
165    m_StartGroupList(ArgStartGroupList),
166    m_EndGroupList(ArgEndGroupList),
167    m_DefSymList(ArgDefSymList) {
168}
169
170size_t PositionalOptions::numOfActions() const
171{
172  return m_InputObjectFiles.size() +
173         m_LinkerScript.size() +
174         m_NameSpecList.size() +
175         m_WholeArchiveList.size() +
176         m_NoWholeArchiveList.size() +
177         m_AsNeededList.size() +
178         m_NoAsNeededList.size() +
179         m_AddNeededList.size() +
180         m_NoAddNeededList.size() +
181         m_BDynamicList.size() +
182         m_BStaticList.size() +
183         m_StartGroupList.size() +
184         m_EndGroupList.size() +
185         m_DefSymList.size();
186}
187
188size_t PositionalOptions::numOfInputs() const
189{
190  return (m_InputObjectFiles.size() +
191          m_LinkerScript.size() +
192          m_NameSpecList.size());
193}
194
195bool PositionalOptions::parse(std::vector<InputAction*>& pActions,
196                              const LinkerConfig& pConfig,
197                              const LinkerScript& pScript)
198{
199  if (0 == numOfInputs()) {
200    fatal(diag::err_no_inputs);
201    return false;
202  }
203
204  pActions.reserve(numOfActions());
205
206  // -T/--script
207  // FIXME:
208  llvm::cl::list<std::string>::iterator sp;
209  llvm::cl::list<std::string>::iterator spEnd = m_LinkerScript.end();
210  for (sp = m_LinkerScript.begin(); sp != spEnd; ++sp) {
211    pActions.push_back(new ScriptAction(0x0,
212                                       *sp,
213                                       ScriptFile::LDScript,
214                                       pScript.directories()));
215    pActions.push_back(new ContextAction(0x0));
216    pActions.push_back(new MemoryAreaAction(0x0, FileHandle::ReadOnly));
217  }
218
219  // --defsym
220  llvm::cl::list<std::string>::iterator defsym, dsBegin, dsEnd;
221  dsBegin = m_DefSymList.begin();
222  dsEnd = m_DefSymList.end();
223  for (defsym = dsBegin; defsym != dsEnd; ++defsym) {
224    unsigned int pos = m_DefSymList.getPosition(defsym - dsBegin);
225    pActions.push_back(new DefSymAction(pos, *defsym));
226  }
227
228  // set input
229  llvm::cl::list<mcld::sys::fs::Path>::iterator input, inBegin, inEnd;
230  inBegin = m_InputObjectFiles.begin();
231  inEnd = m_InputObjectFiles.end();
232  for (input = inBegin; input != inEnd; ++input) {
233    unsigned int pos = m_InputObjectFiles.getPosition(input - inBegin);
234    pActions.push_back(new InputFileAction(pos, *input));
235    pActions.push_back(new ContextAction(pos));
236    pActions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly));
237  }
238
239  // set -l[namespec]
240  llvm::cl::list<std::string>::iterator namespec, nsBegin, nsEnd;
241  nsBegin = m_NameSpecList.begin();
242  nsEnd = m_NameSpecList.end();
243  for (namespec = nsBegin; namespec != nsEnd; ++namespec) {
244    unsigned int pos = m_NameSpecList.getPosition(namespec - nsBegin);
245    pActions.push_back(new NamespecAction(pos, *namespec,
246                                          pScript.directories()));
247    pActions.push_back(new ContextAction(pos));
248    pActions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly));
249  }
250
251  // set --whole-archive
252  llvm::cl::list<bool>::iterator attr, attrBegin, attrEnd;
253  attrBegin = m_WholeArchiveList.begin();
254  attrEnd   = m_WholeArchiveList.end();
255  for (attr = attrBegin; attr != attrEnd; ++attr) {
256    unsigned int pos = m_WholeArchiveList.getPosition(attr - attrBegin);
257    pActions.push_back(new WholeArchiveAction(pos));
258  }
259
260  // set --no-whole-archive
261  attrBegin = m_NoWholeArchiveList.begin();
262  attrEnd   = m_NoWholeArchiveList.end();
263  for (attr = attrBegin; attr != attrEnd; ++attr) {
264    unsigned int pos = m_NoWholeArchiveList.getPosition(attr - attrBegin);
265    pActions.push_back(new NoWholeArchiveAction(pos));
266  }
267
268  // set --as-needed
269  attrBegin = m_AsNeededList.begin();
270  attrEnd   = m_AsNeededList.end();
271  for (attr = attrBegin; attr != attrEnd; ++attr) {
272    unsigned int pos = m_AsNeededList.getPosition(attr - attrBegin);
273    pActions.push_back(new AsNeededAction(pos));
274  }
275
276  // set --no-as-needed
277  attrBegin = m_NoAsNeededList.begin();
278  attrEnd   = m_NoAsNeededList.end();
279  for (attr = attrBegin; attr != attrEnd; ++attr) {
280    unsigned int pos = m_NoAsNeededList.getPosition(attr - attrBegin);
281    pActions.push_back(new NoAsNeededAction(pos));
282  }
283
284  // set --add--needed
285  attrBegin = m_AddNeededList.begin();
286  attrEnd   = m_AddNeededList.end();
287  for (attr = attrBegin; attr != attrEnd; ++attr) {
288    unsigned int pos = m_AddNeededList.getPosition(attr - attrBegin);
289    pActions.push_back(new AddNeededAction(pos));
290  }
291
292  // set --no-add--needed
293  attrBegin = m_NoAddNeededList.begin();
294  attrEnd   = m_NoAddNeededList.end();
295  for (attr = attrBegin; attr != attrEnd; ++attr) {
296    unsigned int pos = m_NoAddNeededList.getPosition(attr - attrBegin);
297    pActions.push_back(new NoAddNeededAction(pos));
298  }
299
300  // set --Bdynamic
301  attrBegin = m_BDynamicList.begin();
302  attrEnd   = m_BDynamicList.end();
303  for (attr = attrBegin; attr != attrEnd; ++attr) {
304    unsigned int pos = m_BDynamicList.getPosition(attr - attrBegin);
305    pActions.push_back(new BDynamicAction(pos));
306  }
307
308  // set --Bstatic
309  attrBegin = m_BStaticList.begin();
310  attrEnd   = m_BStaticList.end();
311  for (attr = attrBegin; attr != attrEnd; ++attr) {
312    unsigned int pos = m_BStaticList.getPosition(attr - attrBegin);
313    pActions.push_back(new BStaticAction(pos));
314  }
315
316  // set --start-group
317  llvm::cl::list<bool>::iterator group, gsBegin, gsEnd;
318  gsBegin = m_StartGroupList.begin();
319  gsEnd   = m_StartGroupList.end();
320  for (group = gsBegin; group != gsEnd; ++group) {
321    unsigned int pos = m_StartGroupList.getPosition(group - gsBegin);
322    pActions.push_back(new StartGroupAction(pos));
323  }
324
325  // set --end-group
326  gsBegin = m_EndGroupList.begin();
327  gsEnd   = m_EndGroupList.end();
328  for (group = gsBegin; group != gsEnd; ++group) {
329    unsigned int pos = m_EndGroupList.getPosition(group - gsBegin);
330    pActions.push_back(new EndGroupAction(pos));
331  }
332
333  // stable sort
334  std::stable_sort(pActions.begin(), pActions.end(), CompareAction);
335
336  return true;
337}
338
339