Add Clang driver-support for directory-style precompiled headers

When passed -include foo we will check if foo.pch is a directory,
and if so try to look up a precompiled header matching the current
input language in that directory.

GCC will actually search every file in this directory, regardless of
naming, and choose the first one that matches the language.

---

Comments? Is it okey to do this kind of simple transparent GCC-compatibility-trick or do we have to do what GCC does and actually parse each header in that directory and check if it's valid for the language?

Side-note about the code: There's a condition where we "Ignore the PCH if not first on command line and emit warning.", but we don't actually ignore the argument, it's claimed and rendered as a normal -include. Is this intentional? In my case I chose to actually ignore the whole argument, does that makes sense?

Thanks!

Tor Arne

  include/clang/Basic/DiagnosticDriverKinds.td |    2 ++
  lib/Driver/Tools.cpp                         |   10 ++++++++++
test/Driver/pch.c | 25 +++++++++++++++++++++++++
  test/Driver/pth.c                            |   12 ++++++++++++
  4 files changed, 49 insertions(+), 0 deletions(-)
  create mode 100644 test/Driver/pch.c



>From c81d9e3c34b0d7be5d0cac7d2add3ce6396ab23f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <[email protected]>
Date: Fri, 15 Oct 2010 11:32:54 +0200
Subject: [PATCH] Add Clang driver-support for directory-style precompiled 
headers

When passed -include foo we will check if foo.pch is a directory,
and if so try to look up a precompiled header matching the current
input language in that directory.

GCC will actually search every file in this directory, regardless of
naming, and choose the first one that matches the language.
---
 include/clang/Basic/DiagnosticDriverKinds.td |    2 ++
 lib/Driver/Tools.cpp                         |   10 ++++++++++
 test/Driver/pch.c                            |   25 +++++++++++++++++++++++++
 test/Driver/pth.c                            |   12 ++++++++++++
 4 files changed, 49 insertions(+), 0 deletions(-)
 create mode 100644 test/Driver/pch.c

diff --git a/include/clang/Basic/DiagnosticDriverKinds.td 
b/include/clang/Basic/DiagnosticDriverKinds.td
index 748a3db..4265ec8 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -104,5 +104,7 @@ def warn_drv_objc_gc_unsupported : Warning<
   "Objective-C garbage collection is not supported on this platform, ignoring 
'%0'">;
 def warn_drv_pch_not_first_include : Warning<
   "precompiled header '%0' was ignored because '%1' is not first '-include'">;
+def warn_drv_pch_missing_language : Warning<
+  "ignoring argument '%0' due to missing precompiled header '%1' for language 
'%2'">;
 
 }
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 31f9c08..5f0bbb7 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -260,6 +260,16 @@ void Clang::AddPreprocessingOptions(const Driver &D,
             CmdArgs.push_back("-include-pch");
           else
             CmdArgs.push_back("-include-pth");
+          if (P.isDirectory()) {
+            // Expect to find a precompiled header matching the current input 
type
+            P.appendComponent(types::getTypeName(Inputs[0].getType()));
+            if (!P.exists()) {
+              D.Diag(clang::diag::warn_drv_pch_missing_language)
+                  << A->getAsString(Args) << P.str()
+                  << types::getTypeName(Inputs[0].getType());
+              continue;
+            }
+          }
           CmdArgs.push_back(Args.MakeArgString(P.str()));
           continue;
         } else {
diff --git a/test/Driver/pch.c b/test/Driver/pch.c
new file mode 100644
index 0000000..03d1ad4
--- /dev/null
+++ b/test/Driver/pch.c
@@ -0,0 +1,25 @@
+// Test transparent PCH support.
+
+// RUN: %clang -x c-header %s -o %t.h.pch -### 2> %t.log
+// RUN: FileCheck -check-prefix CHECK1 -input-file %t.log %s
+
+// CHECK1: "{{.*}}/clang{{.*}}" "-cc1" {{.*}} "-o" "{{.*}}.h.pch" "-x" 
"c-header" "{{.*}}pch.c"
+
+// RUN: touch %t.h.pch
+// RUN: %clang -E -include %t.h %s -### 2> %t.log
+// RUN: FileCheck -check-prefix CHECK2 -input-file %t.log %s
+
+// CHECK2: "{{.*}}/clang{{.*}}" "-cc1" {{.*}}"-include-pch" "{{.*}}.h.pch" 
{{.*}}"-x" "c" "{{.*}}pch.c"
+
+// RUN: mkdir -p %t.pch
+// RUN: %clang -x c-header %s -o %t.pch/c -### 2> %t.log
+// RUN: FileCheck -check-prefix CHECK3 -input-file %t.log %s
+
+// CHECK3: "{{.*}}/clang{{.*}}" "-cc1" {{.*}} "-o" "{{.*}}.pch/c" "-x" 
"c-header" "{{.*}}pch.c"
+
+// RUN: touch %t.pch/c
+// RUN: %clang -E -include %t %s -### 2> %t.log
+// RUN: FileCheck -check-prefix CHECK4 -input-file %t.log %s
+
+// CHECK4: "{{.*}}/clang{{.*}}" "-cc1" {{.*}}"-include-pch" "{{.*}}.pch/c" 
{{.*}}"-x" "c" "{{.*}}pch.c"
+
diff --git a/test/Driver/pth.c b/test/Driver/pth.c
index 9c47c55..496e65c 100644
--- a/test/Driver/pth.c
+++ b/test/Driver/pth.c
@@ -10,3 +10,15 @@
 // RUN: FileCheck -check-prefix CHECK2 -input-file %t.log %s
 
 // CHECK2: "{{.*}}/clang{{.*}}" "-cc1" {{.*}}"-include-pth" "{{.*}}.h.pth" 
{{.*}}"-x" "c" "{{.*}}pth.c"
+
+// RUN: mkdir -p %t.pth
+// RUN: %clang -ccc-pch-is-pth -x c-header %s -o %t.pth/c -### 2> %t.log
+// RUN: FileCheck -check-prefix CHECK3 -input-file %t.log %s
+
+// CHECK3: "{{.*}}/clang{{.*}}" "-cc1" {{.*}} "-o" "{{.*}}.pth/c" "-x" 
"c-header" "{{.*}}pth.c"
+
+// RUN: touch %t.pth/c
+// RUN: %clang -ccc-pch-is-pth -E -include %t %s -### 2> %t.log
+// RUN: FileCheck -check-prefix CHECK4 -input-file %t.log %s
+
+// CHECK4: "{{.*}}/clang{{.*}}" "-cc1" {{.*}}"-include-pth" "{{.*}}.pth/c" 
{{.*}}"-x" "c" "{{.*}}pth.c"
-- 
1.7.2.1


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to