[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