blob: a09ba095f119d32ec0d4f969f272b4839d4a3b26 [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
Mike Stump1eb44332009-09-09 15:08:12 +000017Arg::Arg(ArgClass _Kind, const Option *_Opt, unsigned _Index,
18 const Arg *_BaseArg)
19 : Kind(_Kind), Opt(_Opt), BaseArg(_BaseArg), Index(_Index), Claimed(false) {
Daniel Dunbarfb36cae2009-03-04 22:37:52 +000020}
21
22Arg::~Arg() { }
23
Daniel Dunbarf781c412009-03-04 23:02:50 +000024void Arg::dump() const {
25 llvm::errs() << "<";
26 switch (Kind) {
27 default:
28 assert(0 && "Invalid kind");
29#define P(N) case N: llvm::errs() << #N; break
Daniel Dunbar06482622009-03-05 06:38:47 +000030 P(FlagClass);
Daniel Dunbarf781c412009-03-04 23:02:50 +000031 P(PositionalClass);
32 P(JoinedClass);
33 P(SeparateClass);
34 P(CommaJoinedClass);
35 P(JoinedAndSeparateClass);
36#undef P
37 }
38
39 llvm::errs() << " Opt:";
40 Opt->dump();
41
42 llvm::errs() << " Index:" << Index;
43
Daniel Dunbarbbf842b2009-03-04 23:22:02 +000044 if (isa<CommaJoinedArg>(this) || isa<SeparateArg>(this))
45 llvm::errs() << " NumValues:" << getNumValues();
Daniel Dunbarf781c412009-03-04 23:02:50 +000046
47 llvm::errs() << ">\n";
Daniel Dunbarf781c412009-03-04 23:02:50 +000048}
49
Daniel Dunbar38dd3d52009-03-20 06:14:23 +000050std::string Arg::getAsString(const ArgList &Args) const {
51 std::string Res;
52 llvm::raw_string_ostream OS(Res);
53
54 ArgStringList ASL;
55 render(Args, ASL);
Mike Stump1eb44332009-09-09 15:08:12 +000056 for (ArgStringList::iterator
Daniel Dunbar38dd3d52009-03-20 06:14:23 +000057 it = ASL.begin(), ie = ASL.end(); it != ie; ++it) {
58 if (it != ASL.begin())
59 OS << ' ';
60 OS << *it;
61 }
62
63 return OS.str();
64}
65
Daniel Dunbar42f7fc22009-03-19 07:22:40 +000066void Arg::renderAsInput(const ArgList &Args, ArgStringList &Output) const {
67 if (!getOption().hasNoOptAsInput()) {
68 render(Args, Output);
69 return;
70 }
71
72 for (unsigned i = 0, e = getNumValues(); i != e; ++i)
73 Output.push_back(getValue(Args, i));
74}
75
Daniel Dunbar478edc22009-03-29 22:29:05 +000076FlagArg::FlagArg(const Option *Opt, unsigned Index, const Arg *BaseArg)
77 : Arg(FlagClass, Opt, Index, BaseArg) {
Daniel Dunbar06482622009-03-05 06:38:47 +000078}
79
80void FlagArg::render(const ArgList &Args, ArgStringList &Output) const {
Daniel Dunbar21fd6ac2009-03-18 08:01:48 +000081 Output.push_back(Args.getArgString(getIndex()));
Daniel Dunbar06482622009-03-05 06:38:47 +000082}
83
84const char *FlagArg::getValue(const ArgList &Args, unsigned N) const {
85 assert(0 && "Invalid index.");
86 return 0;
87}
88
Mike Stump1eb44332009-09-09 15:08:12 +000089PositionalArg::PositionalArg(const Option *Opt, unsigned Index,
Daniel Dunbar478edc22009-03-29 22:29:05 +000090 const Arg *BaseArg)
91 : Arg(PositionalClass, Opt, Index, BaseArg) {
Daniel Dunbarfb36cae2009-03-04 22:37:52 +000092}
93
94void PositionalArg::render(const ArgList &Args, ArgStringList &Output) const {
Daniel Dunbar21fd6ac2009-03-18 08:01:48 +000095 Output.push_back(Args.getArgString(getIndex()));
Daniel Dunbarfb36cae2009-03-04 22:37:52 +000096}
97
98const char *PositionalArg::getValue(const ArgList &Args, unsigned N) const {
Daniel Dunbar06482622009-03-05 06:38:47 +000099 assert(N < getNumValues() && "Invalid index.");
100 return Args.getArgString(getIndex());
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000101}
102
Daniel Dunbar478edc22009-03-29 22:29:05 +0000103JoinedArg::JoinedArg(const Option *Opt, unsigned Index, const Arg *BaseArg)
104 : Arg(JoinedClass, Opt, Index, BaseArg) {
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000105}
106
107void JoinedArg::render(const ArgList &Args, ArgStringList &Output) const {
Daniel Dunbar21fd6ac2009-03-18 08:01:48 +0000108 if (getOption().hasForceSeparateRender()) {
109 Output.push_back(getOption().getName());
110 Output.push_back(getValue(Args, 0));
111 } else {
112 Output.push_back(Args.getArgString(getIndex()));
113 }
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000114}
115
116const char *JoinedArg::getValue(const ArgList &Args, unsigned N) const {
Daniel Dunbar06482622009-03-05 06:38:47 +0000117 assert(N < getNumValues() && "Invalid index.");
118 // FIXME: Avoid strlen.
119 return Args.getArgString(getIndex()) + strlen(getOption().getName());
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000120}
121
Mike Stump1eb44332009-09-09 15:08:12 +0000122CommaJoinedArg::CommaJoinedArg(const Option *Opt, unsigned Index,
Daniel Dunbar478edc22009-03-29 22:29:05 +0000123 const char *Str, const Arg *BaseArg)
124 : Arg(CommaJoinedClass, Opt, Index, BaseArg) {
Mike Stump1eb44332009-09-09 15:08:12 +0000125 const char *Prev = Str;
Daniel Dunbar06482622009-03-05 06:38:47 +0000126 for (;; ++Str) {
127 char c = *Str;
128
129 if (!c) {
130 if (Prev != Str)
131 Values.push_back(std::string(Prev, Str));
132 break;
133 } else if (c == ',') {
134 if (Prev != Str)
135 Values.push_back(std::string(Prev, Str));
136 Prev = Str + 1;
137 }
138 }
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000139}
140
141void CommaJoinedArg::render(const ArgList &Args, ArgStringList &Output) const {
Daniel Dunbar21fd6ac2009-03-18 08:01:48 +0000142 Output.push_back(Args.getArgString(getIndex()));
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000143}
144
145const char *CommaJoinedArg::getValue(const ArgList &Args, unsigned N) const {
Daniel Dunbar06482622009-03-05 06:38:47 +0000146 assert(N < getNumValues() && "Invalid index.");
147 return Values[N].c_str();
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000148}
149
Daniel Dunbar478edc22009-03-29 22:29:05 +0000150SeparateArg::SeparateArg(const Option *Opt, unsigned Index, unsigned _NumValues,
151 const Arg *BaseArg)
152 : Arg(SeparateClass, Opt, Index, BaseArg), NumValues(_NumValues) {
Daniel Dunbarf781c412009-03-04 23:02:50 +0000153}
154
155void SeparateArg::render(const ArgList &Args, ArgStringList &Output) const {
Daniel Dunbar21fd6ac2009-03-18 08:01:48 +0000156 if (getOption().hasForceJoinedRender()) {
157 assert(getNumValues() == 1 && "Cannot force joined render with > 1 args.");
158 // FIXME: Avoid std::string.
159 std::string Joined(getOption().getName());
160 Joined += Args.getArgString(getIndex());
161 Output.push_back(Args.MakeArgString(Joined.c_str()));
162 } else {
163 Output.push_back(Args.getArgString(getIndex()));
Daniel Dunbar3fe51c42009-03-22 23:50:14 +0000164 for (unsigned i = 0; i < NumValues; ++i)
165 Output.push_back(Args.getArgString(getIndex() + 1 + i));
Daniel Dunbar21fd6ac2009-03-18 08:01:48 +0000166 }
Daniel Dunbarf781c412009-03-04 23:02:50 +0000167}
168
Mike Stump1eb44332009-09-09 15:08:12 +0000169const char *SeparateArg::getValue(const ArgList &Args, unsigned N) const {
Daniel Dunbar06482622009-03-05 06:38:47 +0000170 assert(N < getNumValues() && "Invalid index.");
171 return Args.getArgString(getIndex() + 1 + N);
Daniel Dunbarf781c412009-03-04 23:02:50 +0000172}
173
Mike Stump1eb44332009-09-09 15:08:12 +0000174JoinedAndSeparateArg::JoinedAndSeparateArg(const Option *Opt, unsigned Index,
Daniel Dunbar478edc22009-03-29 22:29:05 +0000175 const Arg *BaseArg)
176 : Arg(JoinedAndSeparateClass, Opt, Index, BaseArg) {
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000177}
178
Mike Stump1eb44332009-09-09 15:08:12 +0000179void JoinedAndSeparateArg::render(const ArgList &Args,
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000180 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
Mike Stump1eb44332009-09-09 15:08:12 +0000185const char *JoinedAndSeparateArg::getValue(const ArgList &Args,
Daniel Dunbarfb36cae2009-03-04 22:37:52 +0000186 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}