[PATCH] D19815: Support '#pragma once' in headers when using PCH

Warren Ristow via cfe-commits cfe-commits at lists.llvm.org
Mon May 2 10:35:29 PDT 2016


wristow created this revision.
wristow added a reviewer: rsmith.
wristow added a subscriber: cfe-commits.

The '#pragma once' directive was erroneously ignored when encountered
in the header-file specified in generate-PCH-mode.  This resulted in
compile-time errors in some cases with legal code, and also a misleading
warning being produced.

This fixes PR24387.

http://reviews.llvm.org/D19815

Files:
  include/clang/Lex/PreprocessorOptions.h
  lib/Frontend/InitPreprocessor.cpp
  lib/Lex/Pragma.cpp
  test/PCH/pragma-once.c
  test/PCH/pragma-once.h

Index: test/PCH/pragma-once.h
===================================================================
--- /dev/null
+++ test/PCH/pragma-once.h
@@ -0,0 +1,5 @@
+#pragma once
+
+/* For use with the pragma-once.c test */
+
+int x = 3;
Index: test/PCH/pragma-once.c
===================================================================
--- /dev/null
+++ test/PCH/pragma-once.c
@@ -0,0 +1,13 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/pragma-once.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t %S/pragma-once.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s
+
+// expected-no-diagnostics
+
+// Including "pragma-once.h" twice, to verify the 'once' aspect is honored.
+#include "pragma-once.h"
+#include "pragma-once.h"
+int foo(void) { return 0; }
Index: lib/Lex/Pragma.cpp
===================================================================
--- lib/Lex/Pragma.cpp
+++ lib/Lex/Pragma.cpp
@@ -19,6 +19,7 @@
 #include "clang/Lex/LexDiagnostic.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/PreprocessorOptions.h"
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringSwitch.h"
@@ -354,7 +355,9 @@
 /// HandlePragmaOnce - Handle \#pragma once.  OnceTok is the 'once'.
 ///
 void Preprocessor::HandlePragmaOnce(Token &OnceTok) {
-  if (isInPrimaryFile()) {
+  // Don't honor the 'once' when handling the primary source file, unless
+  // we're generating a PCH file.
+  if (isInPrimaryFile() && !getPreprocessorOpts().GeneratePCHMode) {
     Diag(OnceTok, diag::pp_pragma_once_in_main_file);
     return;
   }
Index: lib/Frontend/InitPreprocessor.cpp
===================================================================
--- lib/Frontend/InitPreprocessor.cpp
+++ lib/Frontend/InitPreprocessor.cpp
@@ -1021,6 +1021,10 @@
   if (!InitOpts.ImplicitPTHInclude.empty())
     AddImplicitIncludePTH(Builder, PP, InitOpts.ImplicitPTHInclude);
 
+  // Instruct the preprocessor that we're generating a PCH file.
+  if (FEOpts.ProgramAction == frontend::GeneratePCH)
+    PP.getPreprocessorOpts().GeneratePCHMode = true;
+
   // Process -include directives.
   for (unsigned i = 0, e = InitOpts.Includes.size(); i != e; ++i) {
     const std::string &Path = InitOpts.Includes[i];
Index: include/clang/Lex/PreprocessorOptions.h
===================================================================
--- include/clang/Lex/PreprocessorOptions.h
+++ include/clang/Lex/PreprocessorOptions.h
@@ -61,6 +61,9 @@
   /// \brief Headers that will be converted to chained PCHs in memory.
   std::vector<std::string> ChainedIncludes;
 
+  /// \brief When true, we are generating a pre-compiled header.
+  bool GeneratePCHMode;
+
   /// \brief When true, disables most of the normal validation performed on
   /// precompiled headers.
   bool DisablePCHValidation;
@@ -141,6 +144,7 @@
 
 public:
   PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
+                          GeneratePCHMode(false),
                           DisablePCHValidation(false),
                           AllowPCHWithCompilerErrors(false),
                           DumpDeserializedPCHDecls(false),


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D19815.55841.patch
Type: text/x-patch
Size: 3214 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160502/c8350148/attachment.bin>


More information about the cfe-commits mailing list