/// 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;
/// 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;
}
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;
+
/// @}
};
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 {
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,
}
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));
}
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);
}
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)
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;
}
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,
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) {
// 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;
if (Index > Args.getNumInputArgStrings())
return 0;
- return new JoinedAndSeparateArg(this, Index - 2);
+ return new JoinedAndSeparateArg(this, Index - 2, strlen(getName()));
}