diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 5c5c893ea5db..391438248e52 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -356,7 +356,13 @@ namespace clang { HEADER_SEARCH_TABLE = 40, /// \brief The directory that the PCH was originally created in. - ORIGINAL_PCH_DIR = 41 + ORIGINAL_PCH_DIR = 41, + + /// \brief Record code for floating point #pragma options. + FP_PRAGMA_OPTIONS = 42, + + /// \brief Record code for enabled OpenCL extensions. + OPENCL_EXTENSIONS = 43 }; /// \brief Record types used within a source manager block. diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 8cb0206fd717..94bfd1635308 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -600,6 +600,12 @@ private: /// directly. llvm::SmallVector CUDASpecialDeclRefs; + /// \brief The floating point pragma option settings. + llvm::SmallVector FPPragmaOptions; + + /// \brief The OpenCL extension settings. + llvm::SmallVector OpenCLExtensions; + //@} /// \brief Diagnostic IDs and their mappings that the user changed. diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index 7da0dfea8322..f9a49973e14e 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -42,10 +42,12 @@ class ASTSerializationListener; class NestedNameSpecifier; class CXXBaseSpecifier; class CXXCtorInitializer; +class FPOptions; class HeaderSearch; class LabelStmt; class MacroDefinition; class MemorizeStatCalls; +class OpenCLOptions; class ASTReader; class PreprocessedEntity; class PreprocessingRecord; @@ -331,6 +333,8 @@ private: void WriteDeclUpdatesBlocks(); void WriteDeclReplacementsBlock(); void WriteDeclContextVisibleUpdate(const DeclContext *DC); + void WriteFPPragmaOptions(const FPOptions &Opts); + void WriteOpenCLExtensions(Sema &SemaRef); unsigned ParmVarDeclAbbrev; unsigned DeclContextLexicalAbbrev; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 3dcc62ebc1bc..fcf09b7bd566 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -142,6 +142,7 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) { PARSE_LANGOPT_BENIGN(CatchUndefined); PARSE_LANGOPT_IMPORTANT(ElideConstructors, diag::warn_pch_elide_constructors); PARSE_LANGOPT_BENIGN(SpellChecking); + PARSE_LANGOPT_BENIGN(DefaultFPContract); #undef PARSE_LANGOPT_IMPORTANT #undef PARSE_LANGOPT_BENIGN @@ -2304,6 +2305,16 @@ ASTReader::ReadASTBlock(PerFileData &F) { PP->getHeaderSearchInfo().SetExternalSource(this); } break; + + case FP_PRAGMA_OPTIONS: + // Later tables overwrite earlier ones. + FPPragmaOptions.swap(Record); + break; + + case OPENCL_EXTENSIONS: + // Later tables overwrite earlier ones. + OpenCLExtensions.swap(Record); + break; } First = false; } @@ -2818,6 +2829,7 @@ bool ASTReader::ParseLanguageOptions( PARSE_LANGOPT(OpenCL); PARSE_LANGOPT(CUDA); PARSE_LANGOPT(CatchUndefined); + PARSE_LANGOPT(DefaultFPContract); // FIXME: Missing ElideConstructors?! #undef PARSE_LANGOPT @@ -4106,6 +4118,19 @@ void ASTReader::InitializeSema(Sema &S) { SemaObj->VTablesUsed[Class] = DefinitionRequired; } } + + if (!FPPragmaOptions.empty()) { + assert(FPPragmaOptions.size() == 1 && "Wrong number of FP_PRAGMA_OPTIONS"); + SemaObj->FPFeatures.fp_contract = FPPragmaOptions[0]; + } + + if (!OpenCLExtensions.empty()) { + unsigned I = 0; +#define OPENCLEXT(nm) SemaObj->OpenCLFeatures.nm = OpenCLExtensions[I++]; +#include "clang/Basic/OpenCLExtensions.def" + + assert(OpenCLExtensions.size() == I && "Wrong number of OPENCL_EXTENSIONS"); + } } IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) { diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index cb2997310528..d46ddf8f2f8f 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -740,7 +740,10 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(DECL_UPDATES); RECORD(CXX_BASE_SPECIFIER_OFFSETS); RECORD(DIAG_PRAGMA_MAPPINGS); + RECORD(CUDA_SPECIAL_DECL_REFS); RECORD(HEADER_SEARCH_TABLE); + RECORD(FP_PRAGMA_OPTIONS); + RECORD(OPENCL_EXTENSIONS); // SourceManager Block. BLOCK(SOURCE_MANAGER_BLOCK); @@ -1056,6 +1059,7 @@ void ASTWriter::WriteLanguageOptions(const LangOptions &LangOpts) { Record.push_back(LangOpts.OpenCL); Record.push_back(LangOpts.CUDA); Record.push_back(LangOpts.CatchUndefined); + Record.push_back(LangOpts.DefaultFPContract); Record.push_back(LangOpts.ElideConstructors); Record.push_back(LangOpts.SpellChecking); Stream.EmitRecord(LANGUAGE_OPTIONS, Record); @@ -2528,6 +2532,25 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable.str()); } +/// \brief Write an FP_PRAGMA_OPTIONS block for the given FPOptions. +void ASTWriter::WriteFPPragmaOptions(const FPOptions &Opts) { + RecordData Record; + Record.push_back(Opts.fp_contract); + Stream.EmitRecord(FP_PRAGMA_OPTIONS, Record); +} + +/// \brief Write an OPENCL_EXTENSIONS block for the given OpenCLOptions. +void ASTWriter::WriteOpenCLExtensions(Sema &SemaRef) { + if (!SemaRef.Context.getLangOptions().OpenCL) + return; + + const OpenCLOptions &Opts = SemaRef.getOpenCLOptions(); + RecordData Record; +#define OPENCLEXT(nm) Record.push_back(Opts.nm); +#include "clang/Basic/OpenCLExtensions.def" + Stream.EmitRecord(OPENCL_EXTENSIONS, Record); +} + //===----------------------------------------------------------------------===// // General Serialization Routines //===----------------------------------------------------------------------===// @@ -2758,6 +2781,8 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, WriteSelectors(SemaRef); WriteReferencedSelectorsPool(SemaRef); WriteIdentifierTable(PP); + WriteFPPragmaOptions(SemaRef.getFPOptions()); + WriteOpenCLExtensions(SemaRef); WriteTypeDeclOffsets(); WritePragmaDiagnosticMappings(Context.getDiagnostics()); @@ -2997,6 +3022,9 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, WriteSelectors(SemaRef); WriteReferencedSelectorsPool(SemaRef); WriteIdentifierTable(PP); + WriteFPPragmaOptions(SemaRef.getFPOptions()); + WriteOpenCLExtensions(SemaRef); + WriteTypeDeclOffsets(); // FIXME: For chained PCH only write the new mappings (we currently // write all of them again). diff --git a/clang/test/PCH/opencl-extensions.cl b/clang/test/PCH/opencl-extensions.cl new file mode 100644 index 000000000000..a22b007f9d54 --- /dev/null +++ b/clang/test/PCH/opencl-extensions.cl @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -emit-pch -o %t %s +// RUN: %clang_cc1 -include-pch %t -fsyntax-only %s + +#ifndef HEADER +#define HEADER +// Header. + +#pragma OPENCL EXTENSION cl_khr_fp64 : enable + +#else +// Using the header. + +void test(void) { + double d; +} + +#endif