From 312a8b726e24078d3bd3b2328f9f895d1407cdb7 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Wed, 9 Jun 2010 18:49:38 +0000 Subject: [PATCH] Driver: Add an explicit offset to JoinedArg and JoinedAndSeparateArg, so that they can be independent of the exact option that created them. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105739 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Driver/Arg.h | 11 +++++++++-- include/clang/Driver/ArgList.h | 5 +++++ lib/Driver/Arg.cpp | 20 +++++++++++--------- lib/Driver/ArgList.cpp | 13 ++++++++++++- lib/Driver/Option.cpp | 9 +++++---- 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())); } -- 2.49.0