Index: test/modularize/ProblemsDuplicate.cpp
===================================================================
--- test/modularize/ProblemsDuplicate.cpp	(revision 0)
+++ test/modularize/ProblemsDuplicate.cpp	(revision 0)
@@ -0,0 +1,6 @@
+# RUN: modularize %s -x c++ 2>&1 | FileCheck %s
+
+InputProblemsDuplicate/Header1.h
+InputProblemsDuplicate/Header2.h
+
+# CHECK: error: 'TypeInt' defined at both {{.*}}{{[/\\]}}InputProblemsDuplicate{{[/\\]}}Header1.h:2:13 and {{.*}}{{[/\\]}}InputProblemsDuplicate{{[/\\]}}Header2.h:2:13
Index: test/modularize/InputNoProblems/SomeDecls.h
===================================================================
--- test/modularize/InputNoProblems/SomeDecls.h	(revision 0)
+++ test/modularize/InputNoProblems/SomeDecls.h	(revision 0)
@@ -0,0 +1,5 @@
+// Declare a couple of functions - no modules problems.
+
+void FuncOne();
+
+int FuncTwo(int arg);
Index: test/modularize/InputNoProblems/SomeTypes.h
===================================================================
--- test/modularize/InputNoProblems/SomeTypes.h	(revision 0)
+++ test/modularize/InputNoProblems/SomeTypes.h	(revision 0)
@@ -0,0 +1,16 @@
+// Define a few different kinds of types - no modules problems.
+
+typedef int TypeInt;
+
+typedef TypeInt NestedTypeInt;
+
+struct TypeStruct {
+  int Member;
+};
+
+class TypeClass {
+public:
+  TypeClass() : Member(0) {}
+private:
+  int Member;
+};
Index: test/modularize/NoProblems.cpp
===================================================================
--- test/modularize/NoProblems.cpp	(revision 0)
+++ test/modularize/NoProblems.cpp	(revision 0)
@@ -0,0 +1,5 @@
+# RUN: modularize %s -x c++
+# RUN: modularize -prefix=%p %s -x c++
+
+InputNoProblems/SomeTypes.h
+InputNoProblems/SomeDecls.h
Index: test/modularize/InputProblemsInconsistent/Header1.h
===================================================================
--- test/modularize/InputProblemsInconsistent/Header1.h	(revision 0)
+++ test/modularize/InputProblemsInconsistent/Header1.h	(revision 0)
@@ -0,0 +1,4 @@
+// Define symbol such that a declaration exists when this header
+// is included, but not when Header2.h is included.
+#define SYMBOL1 1
+#include "SubHeader.h"
Index: test/modularize/InputProblemsInconsistent/Header2.h
===================================================================
--- test/modularize/InputProblemsInconsistent/Header2.h	(revision 0)
+++ test/modularize/InputProblemsInconsistent/Header2.h	(revision 0)
@@ -0,0 +1,3 @@
+// Set up so the declaration in SubHeader.h is not defined.
+#define SYMBOL2 1
+#include "SubHeader.h"
Index: test/modularize/InputProblemsInconsistent/SubHeader.h
===================================================================
--- test/modularize/InputProblemsInconsistent/SubHeader.h	(revision 0)
+++ test/modularize/InputProblemsInconsistent/SubHeader.h	(revision 0)
@@ -0,0 +1,11 @@
+// Set up so TypeInt only defined during Header1.h include.
+#ifdef SYMBOL1
+#define SYMBOL 1
+#endif
+#ifdef SYMBOL2
+#define SYMBOL 2
+#endif
+
+#if SYMBOL == 1
+typedef int TypeInt;
+#endif
Index: test/modularize/ProblemsInconsistent.cpp
===================================================================
--- test/modularize/ProblemsInconsistent.cpp	(revision 0)
+++ test/modularize/ProblemsInconsistent.cpp	(revision 0)
@@ -0,0 +1,10 @@
+# RUN: modularize %s -x c++ 2>&1 | FileCheck %s
+
+InputProblemsInconsistent/Header1.h
+InputProblemsInconsistent/Header2.h
+
+# CHECK: error: 'SYMBOL' defined at both {{.*}}{{[/\\]}}InputProblemsInconsistent{{[/\\]}}SubHeader.h:3:9 and {{.*}}{{[/\\]}}InputProblemsInconsistent/SubHeader.h:6:9
+# CHECK-NEXT: error: header '{{.*}}{{[/\\]}}InputProblemsInconsistent{{[/\\]}}SubHeader.h' has different contents dependening on how it was included
+# CHECK-NEXT: note: 'SYMBOL' in {{.*}}{{[/\\]}}InputProblemsInconsistent{{[/\\]}}SubHeader.h at 3:9 not always provided
+# CHECK-NEXT: note: 'SYMBOL' in {{.*}}{{[/\\]}}InputProblemsInconsistent{{[/\\]}}SubHeader.h at 6:9 not always provided
+# CHECK-NEXT: note: 'TypeInt' in {{.*}}{{[/\\]}}InputProblemsInconsistent{{[/\\]}}SubHeader.h at 10:13 not always provided
Index: test/modularize/InputProblemsDuplicate/Header1.h
===================================================================
--- test/modularize/InputProblemsDuplicate/Header1.h	(revision 0)
+++ test/modularize/InputProblemsDuplicate/Header1.h	(revision 0)
@@ -0,0 +1,2 @@
+// Same decl as in Header2.h.
+typedef int TypeInt;
Index: test/modularize/InputProblemsDuplicate/Header2.h
===================================================================
--- test/modularize/InputProblemsDuplicate/Header2.h	(revision 0)
+++ test/modularize/InputProblemsDuplicate/Header2.h	(revision 0)
@@ -0,0 +1,2 @@
+// Same decl as in Header1.h.
+typedef int TypeInt;
Index: test/CMakeLists.txt
===================================================================
--- test/CMakeLists.txt	(revision 177770)
+++ test/CMakeLists.txt	(working copy)
@@ -22,7 +22,7 @@
   clang clang-headers FileCheck count not
 
   # Individual tools we test.
-  remove-cstr-calls cpp11-migrate clang-format
+  remove-cstr-calls cpp11-migrate clang-format modularize
   )
 
 add_lit_testsuite(check-clang-tools "Running the Clang extra tools' regression tests"
Index: modularize/Modularize.cpp
===================================================================
--- modularize/Modularize.cpp	(revision 177770)
+++ modularize/Modularize.cpp	(working copy)
@@ -19,8 +19,14 @@
 // newline-separated list of headers to check with respect to each other.
 // Modularize also accepts regular front-end arguments.
 //
-// Usage:   modularize (include-files_list) [(front-end-options) ...]
+// Usage:   modularize [-prefix (optional header path prefix)] \
+//   (include-files_list) [(front-end-options) ...]
 //
+// Note that unless a "-prefex (header path)" option is specified,
+// non-absolute file paths in the header list file will be relative
+// to the header list file directory.  Use -prefix to specify a different
+// directory.
+//
 // Modularize will do normal parsing, reporting normal errors and warnings,
 // but will also report special error messages like the following:
 //
@@ -60,7 +66,9 @@
 //===----------------------------------------------------------------------===//
  
 #include "llvm/Config/config.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 #include "llvm/ADT/StringRef.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Preprocessor.h"
@@ -79,7 +87,7 @@
 
 using namespace clang::tooling;
 using namespace clang;
-using llvm::StringRef;
+using namespace llvm;
 
 // FIXME: The Location class seems to be something that we might
 // want to design to be applicable to a wider range of tools, and stick it
@@ -331,42 +339,65 @@
   EntityMap &Entities;  
 };
 
+// Option to specify a file name for a list of header files to check.
+cl::opt<std::string> ListFileName(cl::Positional,
+  cl::desc("<name of file containing list of headers to check>"));
+
+// Collect all other arguments, which will be passed to the front end.
+cl::list<std::string>  CC1Arguments(cl::ConsumeAfter,
+  cl::desc("<arguments to be passed to front end>..."));
+
+// Option to specify a prefix to be prepended to the header names.
+cl::opt<std::string> HeaderPrefix("prefix", cl::init(""),
+  cl::desc("Prepend header file paths with this prefix."
+    " If not specified,"
+    " the files are considered to be relative to the header list file."));
+
 int main(int argc, const char **argv) {
-  // Figure out command-line arguments.
-  if (argc < 2) {
-    llvm::errs() << "Usage: modularize <file containing header names> <arguments>\n";
-    return 1;
+
+  // This causes options to be parsed.
+  cl::ParseCommandLineOptions(argc, argv, "modularize.\n");
+
+  // No go if we have no header list file.
+  if (ListFileName.size() == 0) {
+    cl::PrintHelpMessage();
+    return -1;
   }
+
+  // By default, use the path component of the list file name.
+  SmallString<256> HeaderDirectory(ListFileName.c_str());
+  sys::path::remove_filename(HeaderDirectory);
   
+  // Get the prefix if we have one.
+  if (HeaderPrefix.size() != 0)
+    HeaderDirectory = HeaderPrefix;
+
   // Load the list of headers.
-  std::string File = argv[1];
   llvm::SmallVector<std::string, 8> Headers;
   {
-    std::ifstream In(File.c_str());
+    std::ifstream In(ListFileName.c_str());
     if (!In) {
-      llvm::errs() << "Unable to open header list file \"" << File.c_str() << "\"\n";
+      llvm::errs() << "Unable to open header list file \"" << ListFileName.c_str() << "\"\n";
       return 2;
     }
-    
     std::string Line;
     while (std::getline(In, Line)) {
       if (Line.empty() || Line[0] == '#')
         continue;
-      
-      Headers.push_back(Line);
+      SmallString<256> headerFileName;
+      if (sys::path::is_absolute(Line))
+          headerFileName = Line;
+      else {
+          headerFileName = HeaderDirectory;
+          sys::path::append(headerFileName, Line);
+      }
+      Headers.push_back(headerFileName.c_str());
     }
   }
-  
+
   // Create the compilation database.
   llvm::OwningPtr<CompilationDatabase> Compilations;
-  {
-    std::vector<std::string> Arguments;
-    for (int I = 2; I < argc; ++I)
-      Arguments.push_back(argv[I]);
-    SmallString<256> PathBuf;
-    llvm::sys::fs::current_path(PathBuf);
-    Compilations.reset(new FixedCompilationDatabase(Twine(PathBuf), Arguments));
-  }
+  Compilations.reset(new FixedCompilationDatabase(Twine(HeaderDirectory), CC1Arguments));
   
   // Parse all of the headers, detecting duplicates.
   EntityMap Entities;
