]> granicus.if.org Git - clang/commitdiff
Driver: Fix a parsing bug where some options were matched
authorDaniel Dunbar <daniel@zuster.org>
Tue, 7 Apr 2009 18:21:47 +0000 (18:21 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Tue, 7 Apr 2009 18:21:47 +0000 (18:21 +0000)
incorrectly. I'm blanking on the smartest way to write this search,
but we should just do the right thing when we move to TableGen.
 - <rdar://problem/6761194> [driver] -Wextra-tokens isn't parsed
   correctly

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68525 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Driver/OptTable.cpp
test/Driver/parsing.c

index 15b121c45b1bc0ec361dc78b580e3621bbaeff44..cbbeea1974cbcf0925db6062f0384cb150ced244 100644 (file)
@@ -230,19 +230,26 @@ Arg *OptTable::ParseOneArg(const InputArgList &Args, unsigned &Index) const {
   struct Info *Start = OptionInfos + FirstSearchableOption - 1;
   struct Info *End = OptionInfos + LastOption - 1;
 
-  // Find the first option which could be a prefix.
+  // Search for the first next option which could be a prefix.
   Start = std::lower_bound(Start, End, Str);
 
-  // Scan for first option which is a proper prefix.
-  for (; Start != End; ++Start)
-    if (memcmp(Str, Start->Name, strlen(Start->Name)) == 0)
-      break;
-
-  // Look for a match until we don't have a prefix.
+  // Options are stored in sorted order, with '\0' at the end of the
+  // alphabet. Since the only options which can accept a string must
+  // prefix it, we iteratively search for the next option which could
+  // be a prefix.
+  //
+  // FIXME: This is searching much more than necessary, but I am
+  // blanking on the simplest way to make it fast. We can solve this
+  // problem when we move to TableGen.
   for (; Start != End; ++Start) {
-    if (memcmp(Start->Name, Str, strlen(Start->Name)) != 0)
+    // Scan for first option which is a proper prefix.
+    for (; Start != End; ++Start)
+      if (memcmp(Str, Start->Name, strlen(Start->Name)) == 0)
+        break;
+    if (Start == End)
       break;
 
+    // See if this option matches.
     options::ID id = (options::ID) (Start - OptionInfos + 1);
     if (Arg *A = getOption(id)->accept(Args, Index))
       return A;
index ed70949a01a02f3096dee42e25a22c80b354f66d..7b6444050d7d3ca66e554fff0ebeb5064686a5c6 100644 (file)
 // RUN: not clang -sectalign 1 2 2> %t &&
 // RUN: grep "error: argument to '-sectalign' is missing (expected 3 values)" %t &&
 
+// Verify that search continues after find the first option.
+// RUN: clang -ccc-print-options -Wally 2> %t &&
+// RUN: grep 'Option 0 - Name: "-W", Values: {"ally"}' %t &&
+
 // RUN: true