blob: 1d8d2497b65ae1eb6b67ace98d95cfe21d3d3383 [file] [log] [blame]
Daniel Dunbarfb36cae2009-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 Dunbar06482622009-03-05 06:38:47 +000011#include "clang/Driver/ArgList.h"
Daniel Dunbarf781c412009-03-04 23:02:50 +000012#include "clang/Driver/Option.h"
13#include "llvm/Support/raw_ostream.h"
Daniel Dunbarfb36cae2009-03-04 22:37:52 +000014
15using namespace clang::driver;
16
17Arg::Arg(ArgClass _Kind, const Option *_Opt, unsigned _Index)
18 : Kind(_Kind),
19 Opt(_Opt),
Daniel Dunbar6d91b042009-03-18 02:57:50 +000020 Index(_Index),
21 Claimed(false)
Daniel Dunbarfb36cae2009-03-04 22:37:52 +000022{
23}
24
25Arg::~Arg() { }
26
Daniel Dunbarf781c412009-03-04 23:02:50 +000027void Arg::dump() const {
28 llvm::errs() << "<";
29 switch (Kind) {
30 default:
31 assert(0 && "Invalid kind");
32#define P(N) case N: llvm::errs() << #N; break
Daniel Dunbar06482622009-03-05 06:38:47 +000033 P(FlagClass);
Daniel Dunbarf781c412009-03-04 23:02:50 +000034 P(PositionalClass);
35 P(JoinedClass);
36 P(SeparateClass);
37 P(CommaJoinedClass);
38 P(JoinedAndSeparateClass);
39#undef P
40 }
41
42 llvm::errs() << " Opt:";
43 Opt->dump();
44
45 llvm::errs() << " Index:" << Index;
46
Daniel Dunbarbbf842b2009-03-04 23:22:02 +000047 if (isa<CommaJoinedArg>(this) || isa<SeparateArg>(this))
48 llvm::errs() << " NumValues:" << getNumValues();
Daniel Dunbarf781c412009-03-04 23:02:50 +000049
50 llvm::errs() << ">\n";
Daniel Dunbarf781c412009-03-04 23:02:50 +000051}
52
Daniel Dunbar38dd3d52009-03-20 06:14:23 +000053std::string Arg::getAsString(const ArgList &Args) const {
54 std::string Res;
55 llvm::raw_string_ostream OS(Res);
56
57 ArgStringList ASL;
58 render(Args, ASL);
59 for (ArgStringList::iterator
60 it = ASL.begin(), ie = ASL.end(); it != ie; ++it) {
61 if (it != ASL.begin())
62 OS << ' ';
63 OS << *it;
64 }
65
66 return OS.str();
67}
68
Daniel Dunbar42f7fc22009-03-19 07:22:40 +000069void Arg::renderAsInput(const ArgList &Args, ArgStringList &Output) const {
70 if (!getOption().hasNoOptAsInput()) {
71 render(Args, Output);
72 return;
73 }
74
75 for (unsigned i = 0, e = getNumValues(); i != e; ++i)
76 Output.push_back(getValue(Args, i));
77}
78
Daniel Dunbar06482622009-03-05 06:38:47 +000079FlagArg::FlagArg(const Option *Opt, unsigned Index)
80 : Arg(FlagClass, Opt, Index) {
81}
82
83void FlagArg::render(const ArgList &Args, ArgStringList &Output) const {
Daniel Dunbar21fd6ac2009-03-18 08:01:48 +000084 Output.push_back(Args.getArgString(getIndex()));
Daniel Dunbar06482622009-03-05 06:38:47 +000085}
86
87const char *FlagArg::getValue(const ArgList &Args, unsigned N) const {
88 assert(0 && "Invalid index.");
89 return 0;
90}
91
Daniel Dunbarfb36cae2009-03-04 22:37:52 +000092PositionalArg::PositionalArg(const Option *Opt, unsigned Index)
93 : Arg(PositionalClass, Opt, Index) {
94}
95
96void PositionalArg::render(const ArgList &Args, ArgStringList &Output) const {
Daniel Dunbar21fd6ac2009-03-18 08:01:48 +000097 Output.push_back(Args.getArgString(getIndex()));
Daniel Dunbarfb36cae2009-03-04 22:37:52 +000098}
99
100const char *PositionalArg::getValue(const ArgList &Args, unsigned N) const {
Daniel Dunbar06482622009-03-05 06:38:47 +0000101 assert(N < getNumValues() && "Invalid index.");
102 return Args.getArgString(getIndex());
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000103}
104
105JoinedArg::JoinedArg(const Option *Opt, unsigned Index)
106 : Arg(JoinedClass, Opt, Index) {
107}
108
109void JoinedArg::render(const ArgList &Args, ArgStringList &Output) const {
Daniel Dunbar21fd6ac2009-03-18 08:01:48 +0000110 if (getOption().hasForceSeparateRender()) {
111 Output.push_back(getOption().getName());
112 Output.push_back(getValue(Args, 0));
113 } else {
114 Output.push_back(Args.getArgString(getIndex()));
115 }
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000116}
117
118const char *JoinedArg::getValue(const ArgList &Args, unsigned N) const {
Daniel Dunbar06482622009-03-05 06:38:47 +0000119 assert(N < getNumValues() && "Invalid index.");
120 // FIXME: Avoid strlen.
121 return Args.getArgString(getIndex()) + strlen(getOption().getName());
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000122}
123
124CommaJoinedArg::CommaJoinedArg(const Option *Opt, unsigned Index,
Daniel Dunbar06482622009-03-05 06:38:47 +0000125 const char *Str)
126 : Arg(CommaJoinedClass, Opt, Index) {
127 const char *Prev = Str;
128 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 Dunbarfb36cae2009-03-04 22:37:52 +0000141}
142
143void CommaJoinedArg::render(const ArgList &Args, ArgStringList &Output) const {
Daniel Dunbar21fd6ac2009-03-18 08:01:48 +0000144 Output.push_back(Args.getArgString(getIndex()));
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000145}
146
147const char *CommaJoinedArg::getValue(const ArgList &Args, unsigned N) const {
Daniel Dunbar06482622009-03-05 06:38:47 +0000148 assert(N < getNumValues() && "Invalid index.");
149 return Values[N].c_str();
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000150}
151
Daniel Dunbarf781c412009-03-04 23:02:50 +0000152SeparateArg::SeparateArg(const Option *Opt, unsigned Index, unsigned _NumValues)
153 : Arg(SeparateClass, Opt, Index), NumValues(_NumValues) {
154}
155
156void SeparateArg::render(const ArgList &Args, ArgStringList &Output) const {
Daniel Dunbar21fd6ac2009-03-18 08:01:48 +0000157 if (getOption().hasForceJoinedRender()) {
158 assert(getNumValues() == 1 && "Cannot force joined render with > 1 args.");
159 // FIXME: Avoid std::string.
160 std::string Joined(getOption().getName());
161 Joined += Args.getArgString(getIndex());
162 Output.push_back(Args.MakeArgString(Joined.c_str()));
163 } else {
164 Output.push_back(Args.getArgString(getIndex()));
Daniel Dunbar3fe51c42009-03-22 23:50:14 +0000165 for (unsigned i = 0; i < NumValues; ++i)
166 Output.push_back(Args.getArgString(getIndex() + 1 + i));
Daniel Dunbar21fd6ac2009-03-18 08:01:48 +0000167 }
Daniel Dunbarf781c412009-03-04 23:02:50 +0000168}
169
170const char *SeparateArg::getValue(const ArgList &Args, unsigned N) const {
Daniel Dunbar06482622009-03-05 06:38:47 +0000171 assert(N < getNumValues() && "Invalid index.");
172 return Args.getArgString(getIndex() + 1 + N);
Daniel Dunbarf781c412009-03-04 23:02:50 +0000173}
174
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000175JoinedAndSeparateArg::JoinedAndSeparateArg(const Option *Opt, unsigned Index)
176 : Arg(JoinedAndSeparateClass, Opt, Index) {
177}
178
179void JoinedAndSeparateArg::render(const ArgList &Args,
180 ArgStringList &Output) const {
Daniel Dunbar21fd6ac2009-03-18 08:01:48 +0000181 Output.push_back(Args.getArgString(getIndex()));
Daniel Dunbarea728ac2009-03-25 05:23:40 +0000182 Output.push_back(Args.getArgString(getIndex() + 1));
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000183}
184
185const char *JoinedAndSeparateArg::getValue(const ArgList &Args,
186 unsigned N) const {
Daniel Dunbar06482622009-03-05 06:38:47 +0000187 assert(N < getNumValues() && "Invalid index.");
Daniel Dunbarec29d362009-03-18 01:48:37 +0000188 if (N == 0)
189 return Args.getArgString(getIndex()) + strlen(getOption().getName());
190 return Args.getArgString(getIndex() + 1);
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000191}