blob: 9b02378d15a24389489d44359e3fb54ab86c0ac5 [file] [log] [blame]
Daniel Dunbar9333fc62009-03-04 22:37:52 +00001//===--- Arg.cpp - Argument Implementations -----------------------------*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "clang/Driver/Arg.h"
Daniel Dunbard02cb1d2009-03-05 06:38:47 +000011#include "clang/Driver/ArgList.h"
Daniel Dunbar135837e2009-03-04 23:02:50 +000012#include "clang/Driver/Option.h"
Daniel Dunbar4ea3aea2010-03-20 01:12:00 +000013#include "llvm/ADT/Twine.h"
Daniel Dunbar135837e2009-03-04 23:02:50 +000014#include "llvm/Support/raw_ostream.h"
Daniel Dunbar9333fc62009-03-04 22:37:52 +000015
16using namespace clang::driver;
17
Mike Stump11289f42009-09-09 15:08:12 +000018Arg::Arg(ArgClass _Kind, const Option *_Opt, unsigned _Index,
19 const Arg *_BaseArg)
20 : Kind(_Kind), Opt(_Opt), BaseArg(_BaseArg), Index(_Index), Claimed(false) {
Daniel Dunbar9333fc62009-03-04 22:37:52 +000021}
22
23Arg::~Arg() { }
24
Daniel Dunbar135837e2009-03-04 23:02:50 +000025void Arg::dump() const {
26 llvm::errs() << "<";
27 switch (Kind) {
28 default:
29 assert(0 && "Invalid kind");
30#define P(N) case N: llvm::errs() << #N; break
Daniel Dunbard02cb1d2009-03-05 06:38:47 +000031 P(FlagClass);
Daniel Dunbar135837e2009-03-04 23:02:50 +000032 P(PositionalClass);
33 P(JoinedClass);
34 P(SeparateClass);
35 P(CommaJoinedClass);
36 P(JoinedAndSeparateClass);
37#undef P
38 }
39
40 llvm::errs() << " Opt:";
41 Opt->dump();
42
43 llvm::errs() << " Index:" << Index;
44
Daniel Dunbar458b6982009-03-04 23:22:02 +000045 if (isa<CommaJoinedArg>(this) || isa<SeparateArg>(this))
46 llvm::errs() << " NumValues:" << getNumValues();
Daniel Dunbar135837e2009-03-04 23:02:50 +000047
48 llvm::errs() << ">\n";
Daniel Dunbar135837e2009-03-04 23:02:50 +000049}
50
Daniel Dunbar0e759942009-03-20 06:14:23 +000051std::string Arg::getAsString(const ArgList &Args) const {
52 std::string Res;
53 llvm::raw_string_ostream OS(Res);
54
55 ArgStringList ASL;
56 render(Args, ASL);
Mike Stump11289f42009-09-09 15:08:12 +000057 for (ArgStringList::iterator
Daniel Dunbar0e759942009-03-20 06:14:23 +000058 it = ASL.begin(), ie = ASL.end(); it != ie; ++it) {
59 if (it != ASL.begin())
60 OS << ' ';
61 OS << *it;
62 }
63
64 return OS.str();
65}
66
Daniel Dunbar0e227782009-03-19 07:22:40 +000067void Arg::renderAsInput(const ArgList &Args, ArgStringList &Output) const {
68 if (!getOption().hasNoOptAsInput()) {
69 render(Args, Output);
70 return;
71 }
72
73 for (unsigned i = 0, e = getNumValues(); i != e; ++i)
74 Output.push_back(getValue(Args, i));
75}
76
Daniel Dunbar53b406f2009-03-29 22:29:05 +000077FlagArg::FlagArg(const Option *Opt, unsigned Index, const Arg *BaseArg)
78 : Arg(FlagClass, Opt, Index, BaseArg) {
Daniel Dunbard02cb1d2009-03-05 06:38:47 +000079}
80
81void FlagArg::render(const ArgList &Args, ArgStringList &Output) const {
Daniel Dunbard96e2792010-06-09 18:49:31 +000082 Output.push_back(getOption().getName());
Daniel Dunbard02cb1d2009-03-05 06:38:47 +000083}
84
85const char *FlagArg::getValue(const ArgList &Args, unsigned N) const {
86 assert(0 && "Invalid index.");
87 return 0;
88}
89
Mike Stump11289f42009-09-09 15:08:12 +000090PositionalArg::PositionalArg(const Option *Opt, unsigned Index,
Daniel Dunbar53b406f2009-03-29 22:29:05 +000091 const Arg *BaseArg)
92 : Arg(PositionalClass, Opt, Index, BaseArg) {
Daniel Dunbar9333fc62009-03-04 22:37:52 +000093}
94
95void PositionalArg::render(const ArgList &Args, ArgStringList &Output) const {
Daniel Dunbar8eba3652009-03-18 08:01:48 +000096 Output.push_back(Args.getArgString(getIndex()));
Daniel Dunbar9333fc62009-03-04 22:37:52 +000097}
98
99const char *PositionalArg::getValue(const ArgList &Args, unsigned N) const {
Daniel Dunbard02cb1d2009-03-05 06:38:47 +0000100 assert(N < getNumValues() && "Invalid index.");
101 return Args.getArgString(getIndex());
Daniel Dunbar9333fc62009-03-04 22:37:52 +0000102}
103
Daniel Dunbar26a95c62010-06-09 18:49:38 +0000104JoinedArg::JoinedArg(const Option *Opt, unsigned Index, unsigned _Offset,
105 const Arg *BaseArg)
106 : Arg(JoinedClass, Opt, Index, BaseArg), Offset(_Offset) {
Daniel Dunbar9333fc62009-03-04 22:37:52 +0000107}
108
109void JoinedArg::render(const ArgList &Args, ArgStringList &Output) const {
Daniel Dunbar8eba3652009-03-18 08:01:48 +0000110 if (getOption().hasForceSeparateRender()) {
111 Output.push_back(getOption().getName());
112 Output.push_back(getValue(Args, 0));
113 } else {
Daniel Dunbar26a95c62010-06-09 18:49:38 +0000114 Output.push_back(Args.GetOrMakeJoinedArgString(
115 getIndex(), getOption().getName(), getValue(Args, 0)));
Daniel Dunbar8eba3652009-03-18 08:01:48 +0000116 }
Daniel Dunbar9333fc62009-03-04 22:37:52 +0000117}
118
119const char *JoinedArg::getValue(const ArgList &Args, unsigned N) const {
Daniel Dunbard02cb1d2009-03-05 06:38:47 +0000120 assert(N < getNumValues() && "Invalid index.");
Daniel Dunbar26a95c62010-06-09 18:49:38 +0000121 return Args.getArgString(getIndex()) + Offset;
Daniel Dunbar9333fc62009-03-04 22:37:52 +0000122}
123
Mike Stump11289f42009-09-09 15:08:12 +0000124CommaJoinedArg::CommaJoinedArg(const Option *Opt, unsigned Index,
Daniel Dunbar53b406f2009-03-29 22:29:05 +0000125 const char *Str, const Arg *BaseArg)
126 : Arg(CommaJoinedClass, Opt, Index, BaseArg) {
Mike Stump11289f42009-09-09 15:08:12 +0000127 const char *Prev = Str;
Daniel Dunbard02cb1d2009-03-05 06:38:47 +0000128 for (;; ++Str) {
129 char c = *Str;
130
131 if (!c) {
132 if (Prev != Str)
133 Values.push_back(std::string(Prev, Str));
134 break;
135 } else if (c == ',') {
136 if (Prev != Str)
137 Values.push_back(std::string(Prev, Str));
138 Prev = Str + 1;
139 }
140 }
Daniel Dunbar9333fc62009-03-04 22:37:52 +0000141}
142
143void CommaJoinedArg::render(const ArgList &Args, ArgStringList &Output) const {
Daniel Dunbar8eba3652009-03-18 08:01:48 +0000144 Output.push_back(Args.getArgString(getIndex()));
Daniel Dunbar9333fc62009-03-04 22:37:52 +0000145}
146
147const char *CommaJoinedArg::getValue(const ArgList &Args, unsigned N) const {
Daniel Dunbard02cb1d2009-03-05 06:38:47 +0000148 assert(N < getNumValues() && "Invalid index.");
149 return Values[N].c_str();
Daniel Dunbar9333fc62009-03-04 22:37:52 +0000150}
151
Daniel Dunbar53b406f2009-03-29 22:29:05 +0000152SeparateArg::SeparateArg(const Option *Opt, unsigned Index, unsigned _NumValues,
153 const Arg *BaseArg)
154 : Arg(SeparateClass, Opt, Index, BaseArg), NumValues(_NumValues) {
Daniel Dunbar135837e2009-03-04 23:02:50 +0000155}
156
157void SeparateArg::render(const ArgList &Args, ArgStringList &Output) const {
Daniel Dunbar8eba3652009-03-18 08:01:48 +0000158 if (getOption().hasForceJoinedRender()) {
159 assert(getNumValues() == 1 && "Cannot force joined render with > 1 args.");
Daniel Dunbar4ea3aea2010-03-20 01:12:00 +0000160 Output.push_back(Args.MakeArgString(llvm::StringRef(getOption().getName()) +
161 getValue(Args, 0)));
Daniel Dunbar8eba3652009-03-18 08:01:48 +0000162 } else {
Daniel Dunbard96e2792010-06-09 18:49:31 +0000163 Output.push_back(getOption().getName());
Daniel Dunbara0c89be2009-03-22 23:50:14 +0000164 for (unsigned i = 0; i < NumValues; ++i)
Daniel Dunbar4ea3aea2010-03-20 01:12:00 +0000165 Output.push_back(getValue(Args, i));
Daniel Dunbar8eba3652009-03-18 08:01:48 +0000166 }
Daniel Dunbar135837e2009-03-04 23:02:50 +0000167}
168
Mike Stump11289f42009-09-09 15:08:12 +0000169const char *SeparateArg::getValue(const ArgList &Args, unsigned N) const {
Daniel Dunbard02cb1d2009-03-05 06:38:47 +0000170 assert(N < getNumValues() && "Invalid index.");
171 return Args.getArgString(getIndex() + 1 + N);
Daniel Dunbar135837e2009-03-04 23:02:50 +0000172}
173
Mike Stump11289f42009-09-09 15:08:12 +0000174JoinedAndSeparateArg::JoinedAndSeparateArg(const Option *Opt, unsigned Index,
Daniel Dunbar26a95c62010-06-09 18:49:38 +0000175 unsigned _Offset, const Arg *BaseArg)
176 : Arg(JoinedAndSeparateClass, Opt, Index, BaseArg), Offset(_Offset) {
Daniel Dunbar9333fc62009-03-04 22:37:52 +0000177}
178
Mike Stump11289f42009-09-09 15:08:12 +0000179void JoinedAndSeparateArg::render(const ArgList &Args,
Daniel Dunbar9333fc62009-03-04 22:37:52 +0000180 ArgStringList &Output) const {
Daniel Dunbar26a95c62010-06-09 18:49:38 +0000181 Output.push_back(Args.GetOrMakeJoinedArgString(
182 getIndex(), getOption().getName(), getValue(Args, 0)));
Daniel Dunbarb2304ee2009-03-25 05:23:40 +0000183 Output.push_back(Args.getArgString(getIndex() + 1));
Daniel Dunbar9333fc62009-03-04 22:37:52 +0000184}
185
Mike Stump11289f42009-09-09 15:08:12 +0000186const char *JoinedAndSeparateArg::getValue(const ArgList &Args,
Daniel Dunbar9333fc62009-03-04 22:37:52 +0000187 unsigned N) const {
Daniel Dunbard02cb1d2009-03-05 06:38:47 +0000188 assert(N < getNumValues() && "Invalid index.");
Daniel Dunbar338d7482009-03-18 01:48:37 +0000189 if (N == 0)
Daniel Dunbar26a95c62010-06-09 18:49:38 +0000190 return Args.getArgString(getIndex()) + Offset;
Daniel Dunbar338d7482009-03-18 01:48:37 +0000191 return Args.getArgString(getIndex() + 1);
Daniel Dunbar9333fc62009-03-04 22:37:52 +0000192}