Driver: Basic argument parsing.
 - Add Driver::ParseArgStrings.
 - Store values directly in CommaJoinedArg to support simple access.
 - Add FlagArg class.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66142 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Driver/Arg.cpp b/lib/Driver/Arg.cpp
index a4581d0..52437e7 100644
--- a/lib/Driver/Arg.cpp
+++ b/lib/Driver/Arg.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Driver/Arg.h"
+#include "clang/Driver/ArgList.h"
 #include "clang/Driver/Option.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -28,6 +29,7 @@
   default:
     assert(0 && "Invalid kind");
 #define P(N) case N: llvm::errs() << #N; break
+    P(FlagClass);
     P(PositionalClass);
     P(JoinedClass);
     P(SeparateClass);
@@ -49,6 +51,19 @@
   llvm::errs().flush(); // FIXME
 }
 
+FlagArg::FlagArg(const Option *Opt, unsigned Index)
+  : Arg(FlagClass, Opt, Index) {
+}
+
+void FlagArg::render(const ArgList &Args, ArgStringList &Output) const {
+  assert(0 && "FIXME: Implement");
+}
+
+const char *FlagArg::getValue(const ArgList &Args, unsigned N) const {
+  assert(0 && "Invalid index.");
+  return 0;
+}
+
 PositionalArg::PositionalArg(const Option *Opt, unsigned Index)
   : Arg(PositionalClass, Opt, Index) {
 }
@@ -58,7 +73,8 @@
 }
 
 const char *PositionalArg::getValue(const ArgList &Args, unsigned N) const {
-  assert(0 && "FIXME: Implement");
+  assert(N < getNumValues() && "Invalid index.");
+  return Args.getArgString(getIndex());
 }
 
 JoinedArg::JoinedArg(const Option *Opt, unsigned Index)
@@ -70,12 +86,28 @@
 }
 
 const char *JoinedArg::getValue(const ArgList &Args, unsigned N) const {
-  assert(0 && "FIXME: Implement");
+  assert(N < getNumValues() && "Invalid index.");
+  // FIXME: Avoid strlen.
+  return Args.getArgString(getIndex()) + strlen(getOption().getName());
 }
 
 CommaJoinedArg::CommaJoinedArg(const Option *Opt, unsigned Index, 
-                               unsigned _NumValues)
-  : Arg(CommaJoinedClass, Opt, Index), NumValues(_NumValues) {
+                               const char *Str)
+  : Arg(CommaJoinedClass, Opt, Index) {
+  const char *Prev = Str;  
+  for (;; ++Str) {
+    char c = *Str;
+
+    if (!c) {
+      if (Prev != Str)
+        Values.push_back(std::string(Prev, Str));
+      break;
+    } else if (c == ',') {
+      if (Prev != Str)
+        Values.push_back(std::string(Prev, Str));
+      Prev = Str + 1;
+    }
+  }
 }
 
 void CommaJoinedArg::render(const ArgList &Args, ArgStringList &Output) const {
@@ -83,7 +115,8 @@
 }
 
 const char *CommaJoinedArg::getValue(const ArgList &Args, unsigned N) const {
-  assert(0 && "FIXME: Implement");
+  assert(N < getNumValues() && "Invalid index.");
+  return Values[N].c_str();
 }
 
 SeparateArg::SeparateArg(const Option *Opt, unsigned Index, unsigned _NumValues)
@@ -95,7 +128,8 @@
 }
 
 const char *SeparateArg::getValue(const ArgList &Args, unsigned N) const { 
-  assert(0 && "FIXME: Implement");
+  assert(N < getNumValues() && "Invalid index.");
+  return Args.getArgString(getIndex() + 1 + N);
 }
 
 JoinedAndSeparateArg::JoinedAndSeparateArg(const Option *Opt, unsigned Index)
@@ -109,5 +143,6 @@
 
 const char *JoinedAndSeparateArg::getValue(const ArgList &Args, 
                                            unsigned N) const {
+  assert(N < getNumValues() && "Invalid index.");
   assert(0 && "FIXME: Implement");
 }