aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Driver/Arg.h11
-rw-r--r--include/clang/Driver/ArgList.h5
-rw-r--r--lib/Driver/Arg.cpp20
-rw-r--r--lib/Driver/ArgList.cpp13
-rw-r--r--lib/Driver/Option.cpp9
5 files changed, 42 insertions, 16 deletions
diff --git a/include/clang/Driver/Arg.h b/include/clang/Driver/Arg.h
index ebf40d45de..9415bae8e5 100644
--- a/include/clang/Driver/Arg.h
+++ b/include/clang/Driver/Arg.h
@@ -149,8 +149,12 @@ namespace driver {
/// JoinedArg - A single value argument where the value is joined
/// (suffixed) to the option.
class JoinedArg : public Arg {
+ /// The offset of the joined argument value.
+ unsigned Offset;
+
public:
- JoinedArg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0);
+ JoinedArg(const Option *Opt, unsigned Index, unsigned Offset,
+ const Arg *BaseArg = 0);
virtual void render(const ArgList &Args, ArgStringList &Output) const;
@@ -210,9 +214,12 @@ namespace driver {
/// JoinedAndSeparateArg - An argument with both joined and separate
/// values.
class JoinedAndSeparateArg : public Arg {
+ /// The offset of the joined argument value.
+ unsigned Offset;
+
public:
JoinedAndSeparateArg(const Option *Opt, unsigned Index,
- const Arg *BaseArg = 0);
+ unsigned Offset, const Arg *BaseArg = 0);
virtual void render(const ArgList &Args, ArgStringList &Output) const;
diff --git a/include/clang/Driver/ArgList.h b/include/clang/Driver/ArgList.h
index 7a14ae84d4..9712c50462 100644
--- a/include/clang/Driver/ArgList.h
+++ b/include/clang/Driver/ArgList.h
@@ -249,6 +249,11 @@ namespace driver {
}
const char *MakeArgString(const llvm::Twine &Str) const;
+ /// \brief Create an arg string for (\arg LHS + \arg RHS), reusing the
+ /// string at \arg Index if possible.
+ const char *GetOrMakeJoinedArgString(unsigned Index, llvm::StringRef LHS,
+ llvm::StringRef RHS) const;
+
/// @}
};
diff --git a/lib/Driver/Arg.cpp b/lib/Driver/Arg.cpp
index 8243caba77..9b02378d15 100644
--- a/lib/Driver/Arg.cpp
+++ b/lib/Driver/Arg.cpp
@@ -101,8 +101,9 @@ const char *PositionalArg::getValue(const ArgList &Args, unsigned N) const {
return Args.getArgString(getIndex());
}
-JoinedArg::JoinedArg(const Option *Opt, unsigned Index, const Arg *BaseArg)
- : Arg(JoinedClass, Opt, Index, BaseArg) {
+JoinedArg::JoinedArg(const Option *Opt, unsigned Index, unsigned _Offset,
+ const Arg *BaseArg)
+ : Arg(JoinedClass, Opt, Index, BaseArg), Offset(_Offset) {
}
void JoinedArg::render(const ArgList &Args, ArgStringList &Output) const {
@@ -110,14 +111,14 @@ void JoinedArg::render(const ArgList &Args, ArgStringList &Output) const {
Output.push_back(getOption().getName());
Output.push_back(getValue(Args, 0));
} else {
- Output.push_back(Args.getArgString(getIndex()));
+ Output.push_back(Args.GetOrMakeJoinedArgString(
+ getIndex(), getOption().getName(), getValue(Args, 0)));
}
}
const char *JoinedArg::getValue(const ArgList &Args, unsigned N) const {
assert(N < getNumValues() && "Invalid index.");
- // FIXME: Avoid strlen.
- return Args.getArgString(getIndex()) + strlen(getOption().getName());
+ return Args.getArgString(getIndex()) + Offset;
}
CommaJoinedArg::CommaJoinedArg(const Option *Opt, unsigned Index,
@@ -171,13 +172,14 @@ const char *SeparateArg::getValue(const ArgList &Args, unsigned N) const {
}
JoinedAndSeparateArg::JoinedAndSeparateArg(const Option *Opt, unsigned Index,
- const Arg *BaseArg)
- : Arg(JoinedAndSeparateClass, Opt, Index, BaseArg) {
+ unsigned _Offset, const Arg *BaseArg)
+ : Arg(JoinedAndSeparateClass, Opt, Index, BaseArg), Offset(_Offset) {
}
void JoinedAndSeparateArg::render(const ArgList &Args,
ArgStringList &Output) const {
- Output.push_back(Args.getArgString(getIndex()));
+ Output.push_back(Args.GetOrMakeJoinedArgString(
+ getIndex(), getOption().getName(), getValue(Args, 0)));
Output.push_back(Args.getArgString(getIndex() + 1));
}
@@ -185,6 +187,6 @@ const char *JoinedAndSeparateArg::getValue(const ArgList &Args,
unsigned N) const {
assert(N < getNumValues() && "Invalid index.");
if (N == 0)
- return Args.getArgString(getIndex()) + strlen(getOption().getName());
+ return Args.getArgString(getIndex()) + Offset;
return Args.getArgString(getIndex() + 1);
}
diff --git a/lib/Driver/ArgList.cpp b/lib/Driver/ArgList.cpp
index 3d07431209..ad067f108e 100644
--- a/lib/Driver/ArgList.cpp
+++ b/lib/Driver/ArgList.cpp
@@ -191,6 +191,17 @@ const char *ArgList::MakeArgString(const llvm::Twine &T) const {
return MakeArgString(Str.str());
}
+const char *ArgList::GetOrMakeJoinedArgString(unsigned Index,
+ llvm::StringRef LHS,
+ llvm::StringRef RHS) const {
+ llvm::StringRef Cur = getArgString(Index);
+ if (Cur.size() == LHS.size() + RHS.size() &&
+ Cur.startswith(LHS) && Cur.endswith(RHS))
+ return Cur.data();
+
+ return MakeArgString(LHS + RHS);
+}
+
//
InputArgList::InputArgList(const char **ArgBegin, const char **ArgEnd)
@@ -269,7 +280,7 @@ Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option *Opt,
Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option *Opt,
llvm::StringRef Value) const {
Arg *A = new JoinedArg(Opt, BaseArgs.MakeIndex(Opt->getName() + Value.str()),
- BaseArg);
+ strlen(Opt->getName()), BaseArg);
SynthesizedArgs.push_back(A);
return A;
}
diff --git a/lib/Driver/Option.cpp b/lib/Driver/Option.cpp
index 17d00f50aa..5a967ea3df 100644
--- a/lib/Driver/Option.cpp
+++ b/lib/Driver/Option.cpp
@@ -133,7 +133,7 @@ JoinedOption::JoinedOption(OptSpecifier ID, const char *Name,
Arg *JoinedOption::accept(const InputArgList &Args, unsigned &Index) const {
// Always matches.
- return new JoinedArg(this, Index++);
+ return new JoinedArg(this, Index++, strlen(getName()));
}
CommaJoinedOption::CommaJoinedOption(OptSpecifier ID, const char *Name,
@@ -191,7 +191,8 @@ Arg *MultiArgOption::accept(const InputArgList &Args, unsigned &Index) const {
return new SeparateArg(this, Index - 1 - NumArgs, NumArgs);
}
-JoinedOrSeparateOption::JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
+JoinedOrSeparateOption::JoinedOrSeparateOption(OptSpecifier ID,
+ const char *Name,
const OptionGroup *Group,
const Option *Alias)
: Option(Option::JoinedOrSeparateClass, ID, Name, Group, Alias) {
@@ -202,7 +203,7 @@ Arg *JoinedOrSeparateOption::accept(const InputArgList &Args,
// If this is not an exact match, it is a joined arg.
// FIXME: Avoid strlen.
if (strlen(getName()) != strlen(Args.getArgString(Index)))
- return new JoinedArg(this, Index++);
+ return new JoinedArg(this, Index++, strlen(getName()));
// Otherwise it must be separate.
Index += 2;
@@ -227,6 +228,6 @@ Arg *JoinedAndSeparateOption::accept(const InputArgList &Args,
if (Index > Args.getNumInputArgStrings())
return 0;
- return new JoinedAndSeparateArg(this, Index - 2);
+ return new JoinedAndSeparateArg(this, Index - 2, strlen(getName()));
}