diff options
author | Carlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au> | 2012-10-15 17:10:06 +1100 |
---|---|---|
committer | Carlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au> | 2012-10-15 17:10:06 +1100 |
commit | be1de4be954c80875ad4108e0a33e8e131b2f2c0 (patch) | |
tree | 1fbbecf276bf7c7bdcbb4dd446099d6d90eaa516 /clang/lib/Driver/ArgList.cpp | |
parent | c4626a62754862d20b41e8a46a3574264ea80e6d (diff) | |
parent | f1bd2e48c5324d3f7cda4090c87f8a5b6f463ce2 (diff) |
Merge branch 'master' of ssh://bitbucket.org/czan/honours
Diffstat (limited to 'clang/lib/Driver/ArgList.cpp')
-rw-r--r-- | clang/lib/Driver/ArgList.cpp | 333 |
1 files changed, 333 insertions, 0 deletions
diff --git a/clang/lib/Driver/ArgList.cpp b/clang/lib/Driver/ArgList.cpp new file mode 100644 index 0000000..55a0ddf --- /dev/null +++ b/clang/lib/Driver/ArgList.cpp @@ -0,0 +1,333 @@ +//===--- ArgList.cpp - Argument List Management ---------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Driver/ArgList.h" +#include "clang/Driver/Arg.h" +#include "clang/Driver/DriverDiagnostic.h" +#include "clang/Driver/Option.h" + +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/raw_ostream.h" + +using namespace clang; +using namespace clang::driver; + +void arg_iterator::SkipToNextArg() { + for (; Current != Args.end(); ++Current) { + // Done if there are no filters. + if (!Id0.isValid()) + break; + + // Otherwise require a match. + const Option &O = (*Current)->getOption(); + if (O.matches(Id0) || + (Id1.isValid() && O.matches(Id1)) || + (Id2.isValid() && O.matches(Id2))) + break; + } +} + +// + +ArgList::ArgList() { +} + +ArgList::~ArgList() { +} + +void ArgList::append(Arg *A) { + Args.push_back(A); +} + +void ArgList::eraseArg(OptSpecifier Id) { + for (iterator it = begin(), ie = end(); it != ie; ) { + if ((*it)->getOption().matches(Id)) { + it = Args.erase(it); + ie = end(); + } else { + ++it; + } + } +} + +Arg *ArgList::getLastArgNoClaim(OptSpecifier Id) const { + // FIXME: Make search efficient? + for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it) + if ((*it)->getOption().matches(Id)) + return *it; + return 0; +} + +Arg *ArgList::getLastArg(OptSpecifier Id) const { + Arg *Res = 0; + for (const_iterator it = begin(), ie = end(); it != ie; ++it) { + if ((*it)->getOption().matches(Id)) { + Res = *it; + Res->claim(); + } + } + + return Res; +} + +Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1) const { + Arg *Res = 0; + for (const_iterator it = begin(), ie = end(); it != ie; ++it) { + if ((*it)->getOption().matches(Id0) || + (*it)->getOption().matches(Id1)) { + Res = *it; + Res->claim(); + + } + } + + return Res; +} + +Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, + OptSpecifier Id2) const { + Arg *Res = 0; + for (const_iterator it = begin(), ie = end(); it != ie; ++it) { + if ((*it)->getOption().matches(Id0) || + (*it)->getOption().matches(Id1) || + (*it)->getOption().matches(Id2)) { + Res = *it; + Res->claim(); + } + } + + return Res; +} + +Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, + OptSpecifier Id2, OptSpecifier Id3) const { + Arg *Res = 0; + for (const_iterator it = begin(), ie = end(); it != ie; ++it) { + if ((*it)->getOption().matches(Id0) || + (*it)->getOption().matches(Id1) || + (*it)->getOption().matches(Id2) || + (*it)->getOption().matches(Id3)) { + Res = *it; + Res->claim(); + } + } + + return Res; +} + +Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, + OptSpecifier Id2, OptSpecifier Id3, + OptSpecifier Id4) const { + Arg *Res = 0; + for (const_iterator it = begin(), ie = end(); it != ie; ++it) { + if ((*it)->getOption().matches(Id0) || + (*it)->getOption().matches(Id1) || + (*it)->getOption().matches(Id2) || + (*it)->getOption().matches(Id3) || + (*it)->getOption().matches(Id4)) { + Res = *it; + Res->claim(); + } + } + + return Res; +} + +bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const { + if (Arg *A = getLastArg(Pos, Neg)) + return A->getOption().matches(Pos); + return Default; +} + +StringRef ArgList::getLastArgValue(OptSpecifier Id, + StringRef Default) const { + if (Arg *A = getLastArg(Id)) + return A->getValue(*this); + return Default; +} + +int ArgList::getLastArgIntValue(OptSpecifier Id, int Default, + clang::DiagnosticsEngine *Diags) const { + int Res = Default; + + if (Arg *A = getLastArg(Id)) { + if (StringRef(A->getValue(*this)).getAsInteger(10, Res)) { + if (Diags) + Diags->Report(diag::err_drv_invalid_int_value) + << A->getAsString(*this) << A->getValue(*this); + } + } + + return Res; +} + +std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const { + SmallVector<const char *, 16> Values; + AddAllArgValues(Values, Id); + return std::vector<std::string>(Values.begin(), Values.end()); +} + +void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const { + if (Arg *A = getLastArg(Id)) { + A->claim(); + A->render(*this, Output); + } +} + +void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0, + OptSpecifier Id1, OptSpecifier Id2) const { + for (arg_iterator it = filtered_begin(Id0, Id1, Id2), + ie = filtered_end(); it != ie; ++it) { + (*it)->claim(); + (*it)->render(*this, Output); + } +} + +void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0, + OptSpecifier Id1, OptSpecifier Id2) const { + for (arg_iterator it = filtered_begin(Id0, Id1, Id2), + ie = filtered_end(); it != ie; ++it) { + (*it)->claim(); + for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i) + Output.push_back((*it)->getValue(*this, i)); + } +} + +void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0, + const char *Translation, + bool Joined) const { + for (arg_iterator it = filtered_begin(Id0), + ie = filtered_end(); it != ie; ++it) { + (*it)->claim(); + + if (Joined) { + Output.push_back(MakeArgString(StringRef(Translation) + + (*it)->getValue(*this, 0))); + } else { + Output.push_back(Translation); + Output.push_back((*it)->getValue(*this, 0)); + } + } +} + +void ArgList::ClaimAllArgs(OptSpecifier Id0) const { + for (arg_iterator it = filtered_begin(Id0), + ie = filtered_end(); it != ie; ++it) + (*it)->claim(); +} + +void ArgList::ClaimAllArgs() const { + for (const_iterator it = begin(), ie = end(); it != ie; ++it) + if (!(*it)->isClaimed()) + (*it)->claim(); +} + +const char *ArgList::MakeArgString(const Twine &T) const { + SmallString<256> Str; + T.toVector(Str); + return MakeArgString(Str.str()); +} + +const char *ArgList::GetOrMakeJoinedArgString(unsigned Index, + StringRef LHS, + StringRef RHS) const { + 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* const *ArgBegin, + const char* const *ArgEnd) + : 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(StringRef 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(StringRef String0, + StringRef 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(StringRef Str) const { + return getArgString(MakeIndex(Str)); +} + +// + +DerivedArgList::DerivedArgList(const InputArgList &_BaseArgs) + : BaseArgs(_BaseArgs) { +} + +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(StringRef Str) const { + return BaseArgs.MakeArgString(Str); +} + +Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option *Opt) const { + Arg *A = new Arg(Opt, BaseArgs.MakeIndex(Opt->getName()), BaseArg); + SynthesizedArgs.push_back(A); + return A; +} + +Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option *Opt, + StringRef Value) const { + unsigned Index = BaseArgs.MakeIndex(Value); + Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index), BaseArg); + SynthesizedArgs.push_back(A); + return A; +} + +Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option *Opt, + StringRef Value) const { + unsigned Index = BaseArgs.MakeIndex(Opt->getName(), Value); + Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index + 1), BaseArg); + SynthesizedArgs.push_back(A); + return A; +} + +Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option *Opt, + StringRef Value) const { + unsigned Index = BaseArgs.MakeIndex(Opt->getName().str() + Value.str()); + Arg *A = new Arg(Opt, Index, + BaseArgs.getArgString(Index) + Opt->getName().size(), + BaseArg); + SynthesizedArgs.push_back(A); + return A; +} |