Driver: Prep for tool chain specific argument translation.
- Lift ArgList to a base class for InputArgList and DerivedArgList.
- This is not a great decomposition, but it does embed the
translation into the type system, and keep things efficient for
tool chains that don't want to do any translation.
- No intended functionality change.
Eventually I hope to get rid of tool chain specific translation and
have each tool do the right thing, but for now this is the easiest way
to match gcc precisely (which is good for testing).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67676 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Driver/ArgList.cpp b/lib/Driver/ArgList.cpp
index d74e3bd..bd3aab3 100644
--- a/lib/Driver/ArgList.cpp
+++ b/lib/Driver/ArgList.cpp
@@ -13,22 +13,13 @@
using namespace clang::driver;
-ArgList::ArgList(const char **ArgBegin, const char **ArgEnd)
- : NumInputArgStrings(ArgEnd - ArgBegin)
-{
- ArgStrings.append(ArgBegin, ArgEnd);
+ArgList::ArgList(arglist_type &_Args) : Args(_Args) {
}
ArgList::~ArgList() {
- for (iterator it = begin(), ie = end(); it != ie; ++it)
- delete *it;
}
void ArgList::append(Arg *A) {
- if (A->getOption().isUnsupported()) {
- assert(0 && "FIXME: unsupported unsupported.");
- }
-
Args.push_back(A);
}
@@ -68,46 +59,6 @@
return Default;
}
-unsigned ArgList::MakeIndex(const char *String0) const {
- unsigned Index = ArgStrings.size();
-
- // Tuck away so we have a reliable const char *.
- SynthesizedStrings.push_back(String0);
- ArgStrings.push_back(SynthesizedStrings.back().c_str());
-
- return Index;
-}
-
-unsigned ArgList::MakeIndex(const char *String0, const char *String1) const {
- unsigned Index0 = MakeIndex(String0);
- unsigned Index1 = MakeIndex(String1);
- assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
- (void) Index1;
- return Index0;
-}
-
-const char *ArgList::MakeArgString(const char *Str) const {
- return getArgString(MakeIndex(Str));
-}
-
-Arg *ArgList::MakeFlagArg(const Option *Opt) const {
- return new FlagArg(Opt, MakeIndex(Opt->getName()));
-}
-
-Arg *ArgList::MakePositionalArg(const Option *Opt, const char *Value) const {
- return new PositionalArg(Opt, MakeIndex(Value));
-}
-
-Arg *ArgList::MakeSeparateArg(const Option *Opt, const char *Value) const {
- return new SeparateArg(Opt, MakeIndex(Opt->getName(), Value), 1);
-}
-
-Arg *ArgList::MakeJoinedArg(const Option *Opt, const char *Value) const {
- std::string Joined(Opt->getName());
- Joined += Value;
- return new JoinedArg(Opt, MakeIndex(Joined.c_str()));
-}
-
void ArgList::AddLastArg(ArgStringList &Output, options::ID Id) const {
if (Arg *A = getLastArg(Id)) {
A->claim();
@@ -175,3 +126,80 @@
}
}
}
+
+//
+
+InputArgList::InputArgList(const char **ArgBegin, const char **ArgEnd)
+ : ArgList(ActualArgs), NumInputArgStrings(ArgEnd - ArgBegin)
+{
+ ArgStrings.append(ArgBegin, ArgEnd);
+}
+
+InputArgList::~InputArgList() {
+ // An InputArgList always owns its arguments.
+ for (iterator it = begin(), ie = end(); it != ie; ++it)
+ delete *it;
+}
+
+unsigned InputArgList::MakeIndex(const char *String0) const {
+ unsigned Index = ArgStrings.size();
+
+ // Tuck away so we have a reliable const char *.
+ SynthesizedStrings.push_back(String0);
+ ArgStrings.push_back(SynthesizedStrings.back().c_str());
+
+ return Index;
+}
+
+unsigned InputArgList::MakeIndex(const char *String0,
+ const char *String1) const {
+ unsigned Index0 = MakeIndex(String0);
+ unsigned Index1 = MakeIndex(String1);
+ assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
+ (void) Index1;
+ return Index0;
+}
+
+const char *InputArgList::MakeArgString(const char *Str) const {
+ return getArgString(MakeIndex(Str));
+}
+
+//
+
+DerivedArgList::DerivedArgList(InputArgList &_BaseArgs, bool _OnlyProxy)
+ : ArgList(_OnlyProxy ? _BaseArgs.getArgs() : ActualArgs),
+ BaseArgs(_BaseArgs), OnlyProxy(_OnlyProxy)
+{
+}
+
+DerivedArgList::~DerivedArgList() {
+ // We only own the arguments we explicitly synthesized.
+ for (iterator it = SynthesizedArgs.begin(), ie = SynthesizedArgs.end();
+ it != ie; ++it)
+ delete *it;
+}
+
+const char *DerivedArgList::MakeArgString(const char *Str) const {
+ return BaseArgs.MakeArgString(Str);
+}
+
+Arg *DerivedArgList::MakeFlagArg(const Option *Opt) const {
+ return new FlagArg(Opt, BaseArgs.MakeIndex(Opt->getName()));
+}
+
+Arg *DerivedArgList::MakePositionalArg(const Option *Opt,
+ const char *Value) const {
+ return new PositionalArg(Opt, BaseArgs.MakeIndex(Value));
+}
+
+Arg *DerivedArgList::MakeSeparateArg(const Option *Opt,
+ const char *Value) const {
+ return new SeparateArg(Opt, BaseArgs.MakeIndex(Opt->getName(), Value), 1);
+}
+
+Arg *DerivedArgList::MakeJoinedArg(const Option *Opt,
+ const char *Value) const {
+ std::string Joined(Opt->getName());
+ Joined += Value;
+ return new JoinedArg(Opt, BaseArgs.MakeIndex(Joined.c_str()));
+}
diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp
index 2165bb7..1e044c6 100644
--- a/lib/Driver/Compilation.cpp
+++ b/lib/Driver/Compilation.cpp
@@ -23,7 +23,7 @@
Compilation::Compilation(Driver &D,
ToolChain &_DefaultToolChain,
- ArgList *_Args)
+ InputArgList *_Args)
: TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args) {
}
@@ -31,12 +31,9 @@
delete Args;
// Free any derived arg lists.
- for (llvm::DenseMap<const ToolChain*, ArgList*>::iterator
- it = TCArgs.begin(), ie = TCArgs.end(); it != ie; ++it) {
- ArgList *A = it->second;
- if (A != Args)
- delete Args;
- }
+ for (llvm::DenseMap<const ToolChain*, DerivedArgList*>::iterator
+ it = TCArgs.begin(), ie = TCArgs.end(); it != ie; ++it)
+ delete it->second;
// Free the actions, if built.
for (ActionList::iterator it = Actions.begin(), ie = Actions.end();
@@ -44,11 +41,11 @@
delete *it;
}
-const ArgList &Compilation::getArgsForToolChain(const ToolChain *TC) {
+const DerivedArgList &Compilation::getArgsForToolChain(const ToolChain *TC) {
if (!TC)
TC = &DefaultToolChain;
- ArgList *&Entry = TCArgs[TC];
+ DerivedArgList *&Entry = TCArgs[TC];
if (!Entry)
Entry = TC->TranslateArgs(*Args);
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 2ffd641..85d76c8 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -56,9 +56,10 @@
delete Host;
}
-ArgList *Driver::ParseArgStrings(const char **ArgBegin, const char **ArgEnd) {
+InputArgList *Driver::ParseArgStrings(const char **ArgBegin,
+ const char **ArgEnd) {
llvm::PrettyStackTraceString CrashInfo("Command line argument parsing");
- ArgList *Args = new ArgList(ArgBegin, ArgEnd);
+ InputArgList *Args = new InputArgList(ArgBegin, ArgEnd);
// FIXME: Handle '@' args (or at least error on them).
@@ -171,7 +172,7 @@
}
}
- ArgList *Args = ParseArgStrings(Start, End);
+ InputArgList *Args = ParseArgStrings(Start, End);
Host = GetHostInfo(HostTriple);
@@ -851,8 +852,8 @@
}
llvm::errs() << "], output: " << Result.getAsString() << "\n";
} else {
- const ArgList &TCArgs = C.getArgsForToolChain(TC);
- T.ConstructJob(C, *JA, *Dest, Result, InputInfos, TCArgs, LinkingOutput);
+ T.ConstructJob(C, *JA, *Dest, Result, InputInfos,
+ C.getArgsForToolChain(TC), LinkingOutput);
}
}
diff --git a/lib/Driver/OptTable.cpp b/lib/Driver/OptTable.cpp
index 4524ece..baaa886 100644
--- a/lib/Driver/OptTable.cpp
+++ b/lib/Driver/OptTable.cpp
@@ -208,7 +208,7 @@
return StrCmpOptionName(Name, I.Name) == -1;
}
-Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index) const {
+Arg *OptTable::ParseOneArg(const InputArgList &Args, unsigned &Index) const {
unsigned Prev = Index;
const char *Str = Args.getArgString(Index);
diff --git a/lib/Driver/Option.cpp b/lib/Driver/Option.cpp
index dc681c7..6ea02aa 100644
--- a/lib/Driver/Option.cpp
+++ b/lib/Driver/Option.cpp
@@ -107,7 +107,7 @@
: Option(Option::GroupClass, ID, Name, Group, 0) {
}
-Arg *OptionGroup::accept(const ArgList &Args, unsigned &Index) const {
+Arg *OptionGroup::accept(const InputArgList &Args, unsigned &Index) const {
assert(0 && "accept() should never be called on an OptionGroup");
return 0;
}
@@ -116,7 +116,7 @@
: Option(Option::InputClass, options::OPT_INPUT, "<input>", 0, 0) {
}
-Arg *InputOption::accept(const ArgList &Args, unsigned &Index) const {
+Arg *InputOption::accept(const InputArgList &Args, unsigned &Index) const {
assert(0 && "accept() should never be called on an InputOption");
return 0;
}
@@ -125,7 +125,7 @@
: Option(Option::UnknownClass, options::OPT_UNKNOWN, "<unknown>", 0, 0) {
}
-Arg *UnknownOption::accept(const ArgList &Args, unsigned &Index) const {
+Arg *UnknownOption::accept(const InputArgList &Args, unsigned &Index) const {
assert(0 && "accept() should never be called on an UnknownOption");
return 0;
}
@@ -135,7 +135,7 @@
: Option(Option::FlagClass, ID, Name, Group, Alias) {
}
-Arg *FlagOption::accept(const ArgList &Args, unsigned &Index) const {
+Arg *FlagOption::accept(const InputArgList &Args, unsigned &Index) const {
// Matches iff this is an exact match.
// FIXME: Avoid strlen.
if (strlen(getName()) != strlen(Args.getArgString(Index)))
@@ -149,7 +149,7 @@
: Option(Option::JoinedClass, ID, Name, Group, Alias) {
}
-Arg *JoinedOption::accept(const ArgList &Args, unsigned &Index) const {
+Arg *JoinedOption::accept(const InputArgList &Args, unsigned &Index) const {
// Always matches.
return new JoinedArg(this, Index++);
}
@@ -160,7 +160,8 @@
: Option(Option::CommaJoinedClass, ID, Name, Group, Alias) {
}
-Arg *CommaJoinedOption::accept(const ArgList &Args, unsigned &Index) const {
+Arg *CommaJoinedOption::accept(const InputArgList &Args,
+ unsigned &Index) const {
// Always matches. We count the commas now so we can answer
// getNumValues easily.
@@ -175,7 +176,7 @@
: Option(Option::SeparateClass, ID, Name, Group, Alias) {
}
-Arg *SeparateOption::accept(const ArgList &Args, unsigned &Index) const {
+Arg *SeparateOption::accept(const InputArgList &Args, unsigned &Index) const {
// Matches iff this is an exact match.
// FIXME: Avoid strlen.
if (strlen(getName()) != strlen(Args.getArgString(Index)))
@@ -195,7 +196,7 @@
assert(NumArgs > 1 && "Invalid MultiArgOption!");
}
-Arg *MultiArgOption::accept(const ArgList &Args, unsigned &Index) const {
+Arg *MultiArgOption::accept(const InputArgList &Args, unsigned &Index) const {
// Matches iff this is an exact match.
// FIXME: Avoid strlen.
if (strlen(getName()) != strlen(Args.getArgString(Index)))
@@ -214,7 +215,7 @@
: Option(Option::JoinedOrSeparateClass, ID, Name, Group, Alias) {
}
-Arg *JoinedOrSeparateOption::accept(const ArgList &Args,
+Arg *JoinedOrSeparateOption::accept(const InputArgList &Args,
unsigned &Index) const {
// If this is not an exact match, it is a joined arg.
// FIXME: Avoid strlen.
@@ -236,7 +237,7 @@
: Option(Option::JoinedAndSeparateClass, ID, Name, Group, Alias) {
}
-Arg *JoinedAndSeparateOption::accept(const ArgList &Args,
+Arg *JoinedAndSeparateOption::accept(const InputArgList &Args,
unsigned &Index) const {
// Always matches.
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index c8df6c0..898f12e 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -9,6 +9,8 @@
#include "ToolChains.h"
+#include "clang/Driver/Arg.h"
+#include "clang/Driver/ArgList.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/HostInfo.h"
@@ -122,9 +124,9 @@
return *T;
}
-ArgList *Darwin_X86::TranslateArgs(ArgList &Args) const {
+DerivedArgList *Darwin_X86::TranslateArgs(InputArgList &Args) const {
// FIXME: Implement!
- return &Args;
+ return new DerivedArgList(Args, true);
}
bool Darwin_X86::IsMathErrnoDefault() const {
@@ -223,3 +225,7 @@
const char *Generic_GCC::GetForcedPicModel() const {
return 0;
}
+
+DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args) const {
+ return new DerivedArgList(Args, true);
+}
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index ea1661a..305737b 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -33,7 +33,7 @@
const char *OS);
~Generic_GCC();
- virtual ArgList *TranslateArgs(ArgList &Args) const { return &Args; }
+ virtual DerivedArgList *TranslateArgs(InputArgList &Args) const;
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
@@ -62,7 +62,7 @@
const unsigned (&GCCVersion)[3]);
~Darwin_X86();
- virtual ArgList *TranslateArgs(ArgList &Args) const;
+ virtual DerivedArgList *TranslateArgs(InputArgList &Args) const;
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;