]> granicus.if.org Git - clang/commitdiff
PR30195: Fix clang-cl attempting to precompile bogus (non-precompilable) input types.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 30 Aug 2016 18:55:16 +0000 (18:55 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 30 Aug 2016 18:55:16 +0000 (18:55 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@280133 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Driver/Types.h
lib/Driver/Driver.cpp
lib/Driver/Types.cpp
test/Driver/cl-pch.c

index 22122c7a8eb993c681216cf04cdd046ba31979dc..c8f0b5664f14f2828d9d147487219d9577668413 100644 (file)
@@ -90,6 +90,10 @@ namespace types {
   /// C type (used for clang++ emulation of g++ behaviour)
   ID lookupCXXTypeForCType(ID Id);
 
+  /// Lookup header file input type that corresponds to given
+  /// source file type (used for clang-cl emulation of \Yc).
+  ID lookupHeaderTypeForSourceType(ID Id);
+
 } // end namespace types
 } // end namespace driver
 } // end namespace clang
index 9871f29eb39c04b47671b407cd8479fe4f7bf0bc..a1adb676a39dd346b93f930121f2bbb3d704a8be 100644 (file)
@@ -1685,12 +1685,14 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
     if (YcArg) {
       // Add a separate precompile phase for the compile phase.
       if (FinalPhase >= phases::Compile) {
+        const types::ID HeaderType = lookupHeaderTypeForSourceType(InputType);
         llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PCHPL;
-        types::getCompilationPhases(types::TY_CXXHeader, PCHPL);
+        types::getCompilationPhases(HeaderType, PCHPL);
         Arg *PchInputArg = MakeInputArg(Args, Opts, YcArg->getValue());
 
         // Build the pipeline for the pch file.
-        Action *ClangClPch = C.MakeAction<InputAction>(*PchInputArg, InputType);
+        Action *ClangClPch =
+            C.MakeAction<InputAction>(*PchInputArg, HeaderType);
         for (phases::ID Phase : PCHPL)
           ClangClPch = ConstructPhaseAction(C, Args, Phase, ClangClPch);
         assert(ClangClPch);
@@ -1812,6 +1814,8 @@ Action *Driver::ConstructPhaseAction(Compilation &C, const ArgList &Args,
     return C.MakeAction<PreprocessJobAction>(Input, OutputTy);
   }
   case phases::Precompile: {
+    assert(onlyPrecompileType(Input->getType()) &&
+           "asked to precompile non-precompilable type");
     types::ID OutputTy = types::TY_PCH;
     if (Args.hasArg(options::OPT_fsyntax_only)) {
       // Syntax checks should not emit a PCH file
index e6072de34e25a713221344e62a60678c793c15d3..1588c94ac7eff670d06d2d4b7250541abdce49ed 100644 (file)
@@ -259,3 +259,21 @@ ID types::lookupCXXTypeForCType(ID Id) {
     return types::TY_PP_CXXHeader;
   }
 }
+
+ID types::lookupHeaderTypeForSourceType(ID Id) {
+  switch (Id) {
+  default:
+    return Id;
+
+  case types::TY_C:
+    return types::TY_CHeader;
+  case types::TY_CXX:
+    return types::TY_CXXHeader;
+  case types::TY_ObjC:
+    return types::TY_ObjCHeader;
+  case types::TY_ObjCXX:
+    return types::TY_ObjCXXHeader;
+  case types::TY_CL:
+    return types::TY_CLHeader;
+  }
+}
index 3372c184bbf32e5423c915879757460fea95fee5..339b7a6efd752ecd8bb0597a57b17714520e578c 100644 (file)
@@ -1,3 +1,6 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+//
 // Note: %s and %S must be preceded by --, otherwise it may be interpreted as a
 // command-line option, e.g. on Mac where %s is commonly under /Users.
 
@@ -5,41 +8,41 @@
 // a few things for .c inputs.
 
 // /Yc with a .c file should build a c pch file.
-// RUN: %clang_cl -Werror /Ycpchfile.h /FIpchfile.h /c -### -- %s 2>&1 \
+// RUN: %clang_cl -Werror /Yc%S/Inputs/pchfile.h /FI%S/Inputs/pchfile.h /c /Fo%t/pchfile.obj /Fp%t/pchfile.pch -v -- %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-YC %s
 // CHECK-YC: cc1
-// CHECK-YC: -emit-pch
-// CHECK-YC: -o
-// CHECK-YC: pchfile.pch
-// CHECK-YC: -x
-// CHECK-YC: "c"
+// CHECK-YC-SAME: -emit-pch
+// CHECK-YC-SAME: -o
+// CHECK-YC-SAME: pchfile.pch
+// CHECK-YC-SAME: -x
+// CHECK-YC-SAME: c-header
 
 // But not if /TP changes the input language to C++.
-// RUN: %clang_cl /TP -Werror /Ycpchfile.h /FIpchfile.h /c -### -- %s 2>&1 \
+// RUN: %clang_cl /TP -Werror /Yc%S/Inputs/pchfile.h /FI%S/Inputs/pchfile.h /c /Fo%t/pchfile.obj /Fp%t/pchfile.pch -v -- %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-YCTP %s
 // CHECK-YCTP: cc1
-// CHECK-YCTP: -emit-pch
-// CHECK-YCTP: -o
-// CHECK-YCTP: pchfile.pch
-// CHECK-YCTP: -x
-// CHECK-YCTP: "c++"
+// CHECK-YCTP-SAME: -emit-pch
+// CHECK-YCTP-SAME: -o
+// CHECK-YCTP-SAME: pchfile.pch
+// CHECK-YCTP-SAME: -x
+// CHECK-YCTP-SAME: c++-header
 
 // Except if a later /TC changes it back.
-// RUN: %clang_cl -Werror /Ycpchfile.h /FIpchfile.h /c -### -- %s 2>&1 \
+// RUN: %clang_cl -Werror /Yc%S/Inputs/pchfile.h /FI%S/Inputs/pchfile.h /c /Fo%t/pchfile.obj /Fp%t/pchfile.pch -v -- %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-YCTPTC %s
 // CHECK-YCTPTC: cc1
-// CHECK-YCTPTC: -emit-pch
-// CHECK-YCTPTC: -o
-// CHECK-YCTPTC: pchfile.pch
-// CHECK-YCTPTC: -x
-// CHECK-YCTPTC: "c"
+// CHECK-YCTPTC-SAME: -emit-pch
+// CHECK-YCTPTC-SAME: -o
+// CHECK-YCTPTC-SAME: pchfile.pch
+// CHECK-YCTPTC-SAME: -x
+// CHECK-YCTPTC-SAME: c-header
 
 // Also check lower-case /Tp flag.
-// RUN: %clang_cl -Werror /Tp%s /Ycpchfile.h /FIpchfile.h /c -### 2>&1 \
+// RUN: %clang_cl -Werror /Tp%s /Yc%S/Inputs/pchfile.h /FI%S/Inputs/pchfile.h /c /Fo%t/pchfile.obj /Fp%t/pchfile.pch -v 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-YCTp %s
 // CHECK-YCTp: cc1
-// CHECK-YCTp: -emit-pch
-// CHECK-YCTp: -o
-// CHECK-YCTp: pchfile.pch
-// CHECK-YCTp: -x
-// CHECK-YCTp: "c++"
+// CHECK-YCTp-SAME: -emit-pch
+// CHECK-YCTp-SAME: -o
+// CHECK-YCTp-SAME: pchfile.pch
+// CHECK-YCTp-SAME: -x
+// CHECK-YCTp-SAME: c++-header