]> granicus.if.org Git - clang/commitdiff
clang-cl: Don't assert on using /Yc with non-source files, PR27450
authorNico Weber <nicolasweber@gmx.de>
Thu, 21 Apr 2016 19:59:10 +0000 (19:59 +0000)
committerNico Weber <nicolasweber@gmx.de>
Thu, 21 Apr 2016 19:59:10 +0000 (19:59 +0000)
Move phase handling after input type validation.

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

lib/Driver/Driver.cpp
test/Driver/cl-pch.cpp

index c7a65fe58552ffc0acf8f48ef0bafd92fa275aab..b855b9c59217d5c64a4964d0102d7366422f79e2 100644 (file)
@@ -1563,25 +1563,6 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
     PL.clear();
     types::getCompilationPhases(InputType, PL);
 
-    if (YcArg) {
-      // Add a separate precompile phase for the compile phase.
-      if (FinalPhase >= phases::Compile) {
-        llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PCHPL;
-        types::getCompilationPhases(types::TY_CXXHeader, PCHPL);
-        Arg *PchInputArg = MakeInputArg(Args, Opts, YcArg->getValue());
-
-        // Build the pipeline for the pch file.
-        Action *ClangClPch = C.MakeAction<InputAction>(*PchInputArg, InputType);
-        for (phases::ID Phase : PCHPL)
-          ClangClPch = ConstructPhaseAction(C, Args, Phase, ClangClPch);
-        assert(ClangClPch);
-        Actions.push_back(ClangClPch);
-        // The driver currently exits after the first failed command.  This
-        // relies on that behavior, to make sure if the pch generation fails,
-        // the main compilation won't run.
-      }
-    }
-
     // If the first step comes after the final phase we are doing as part of
     // this compilation, warn the user about it.
     phases::ID InitialPhase = PL[0];
@@ -1614,6 +1595,25 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
       continue;
     }
 
+    if (YcArg) {
+      // Add a separate precompile phase for the compile phase.
+      if (FinalPhase >= phases::Compile) {
+        llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PCHPL;
+        types::getCompilationPhases(types::TY_CXXHeader, PCHPL);
+        Arg *PchInputArg = MakeInputArg(Args, Opts, YcArg->getValue());
+
+        // Build the pipeline for the pch file.
+        Action *ClangClPch = C.MakeAction<InputAction>(*PchInputArg, InputType);
+        for (phases::ID Phase : PCHPL)
+          ClangClPch = ConstructPhaseAction(C, Args, Phase, ClangClPch);
+        assert(ClangClPch);
+        Actions.push_back(ClangClPch);
+        // The driver currently exits after the first failed command.  This
+        // relies on that behavior, to make sure if the pch generation fails,
+        // the main compilation won't run.
+      }
+    }
+
     phases::ID CudaInjectionPhase =
         (phases::Compile < FinalPhase &&
          llvm::find(PL, phases::Compile) != PL.end())
index 075fe825f66fad1207005a27548639c6e9dd1948..d8b7a660f00c437e7b2d243c87a17720c1542856 100644 (file)
 // CHECK-YCTC: -o
 // CHECK-YCTC: pchfile.pch
 // CHECK-YCTC: -x
-// CHECK-YCTP: "c"
+// CHECK-YCTC: "c"
 
 // Also check lower-case /Tc variant.
 // RUN: %clang_cl -Werror /Ycpchfile.h /FIpchfile.h /c -### /Tc%s 2>&1 \
 // CHECK-YCTc: pchfile.pch
 // CHECK-YCTc: -x
 // CHECK-YCTc: "c"
+
+// Don't crash when a non-source file is passed.
+// RUN: %clang_cl -Werror /Ycpchfile.h /FIpchfile.h /c -### %S/Inputs/file.prof 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-NoSource %s
+// CHECK-NoSource: file.prof:{{.*}}input unused
+
+// ...but if an explicit file turns the file into a source file, handle it:
+// RUN: %clang_cl /TP -Werror /Ycpchfile.h /FIpchfile.h /c -### %S/Inputs/file.prof 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-NoSourceTP %s
+// CHECK-NoSourceTP: cc1
+// CHECK-NoSourceTP: -emit-pch
+// CHECK-NoSourceTP: -o
+// CHECK-NoSourceTP: pchfile.pch
+// CHECK-NoSourceTP: -x
+// CHECK-NoSourceTP: "c++"