r220943 - [modules] When a .pcm file is explicitly built separately from the translation

Richard Smith richard-llvm at metafoo.co.uk
Thu Oct 30 19:28:59 PDT 2014


Author: rsmith
Date: Thu Oct 30 21:28:58 2014
New Revision: 220943

URL: http://llvm.org/viewvc/llvm-project?rev=220943&view=rev
Log:
[modules] When a .pcm file is explicitly built separately from the translation
unit, allow the -O settings of the two compilations to differ.

Modified:
    cfe/trunk/include/clang/Basic/LangOptions.def
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/Frontend/ASTUnit.cpp
    cfe/trunk/lib/Frontend/FrontendActions.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/test/Modules/explicit-build-flags.cpp

Modified: cfe/trunk/include/clang/Basic/LangOptions.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.def?rev=220943&r1=220942&r2=220943&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/LangOptions.def (original)
+++ cfe/trunk/include/clang/Basic/LangOptions.def Thu Oct 30 21:28:58 2014
@@ -9,26 +9,40 @@
 //
 // This file defines the language options. Users of this file must
 // define the LANGOPT macro to make use of this information.
-// Optionally, the user may also define BENIGN_LANGOPT
-// (for options that don't affect the construction of the AST in an
-// incompatible way), ENUM_LANGOPT (for options that have enumeration,
-// rather than unsigned, type), BENIGN_ENUM_LANGOPT (for benign
-// options that have enumeration type), and VALUE_LANGOPT is a language option
-// that describes a value rather than a flag.
 //
+// Optionally, the user may also define:
+//
+// BENIGN_LANGOPT: for options that don't affect the construction of the AST in
+//     any way (that is, the value can be different between an implicit module
+//     and the user of that module).
+//
+// COMPATIBLE_LANGOPT: for options that affect the construction of the AST in
+//     a way that doesn't prevent interoperability (that is, the value can be
+//     different between an explicit module and the user of that module).
+//
+// ENUM_LANGOPT: for options that have enumeration, rather than unsigned, type.
+//
+// VALUE_LANGOPT: for options that describe a value rather than a flag.
+//
+// BENIGN_ENUM_LANGOPT, COMPATIBLE_ENUM_LANGOPT: combinations of the above.
+//
+// FIXME: Clients should be able to more easily select whether they want
+// different levels of compatibility versus how to handle different kinds
+// of option.
 //===----------------------------------------------------------------------===//
+
 #ifndef LANGOPT
 #  error Define the LANGOPT macro to handle language options
 #endif
 
-#ifndef VALUE_LANGOPT
-#  define VALUE_LANGOPT(Name, Bits, Default, Description) \
+#ifndef COMPATIBLE_LANGOPT
+#  define COMPATIBLE_LANGOPT(Name, Bits, Default, Description) \
      LANGOPT(Name, Bits, Default, Description)
 #endif
 
 #ifndef BENIGN_LANGOPT
 #  define BENIGN_LANGOPT(Name, Bits, Default, Description) \
-     LANGOPT(Name, Bits, Default, Description)
+     COMPATIBLE_LANGOPT(Name, Bits, Default, Description)
 #endif
 
 #ifndef ENUM_LANGOPT
@@ -36,11 +50,22 @@
      LANGOPT(Name, Bits, Default, Description)
 #endif
 
+#ifndef COMPATIBLE_ENUM_LANGOPT
+#  define COMPATIBLE_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
+     ENUM_LANGOPT(Name, Type, Bits, Default, Description)
+#endif
+
 #ifndef BENIGN_ENUM_LANGOPT
 #  define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
-     ENUM_LANGOPT(Name, Type, Bits, Default, Description)
+     COMPATIBLE_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
+#endif
+
+#ifndef VALUE_LANGOPT
+#  define VALUE_LANGOPT(Name, Bits, Default, Description) \
+     LANGOPT(Name, Bits, Default, Description)
 #endif
 
+// FIXME: A lot of the BENIGN_ options should be COMPATIBLE_ instead.
 LANGOPT(C99               , 1, 0, "C99")
 LANGOPT(C11               , 1, 0, "C11")
 LANGOPT(MSVCCompat        , 1, 0, "Microsoft Visual C++ full compatibility mode")
@@ -102,8 +127,8 @@ LANGOPT(ModulesDeclUse    , 1, 0, "requi
 LANGOPT(ModulesSearchAll  , 1, 1, "search even non-imported modules to find unresolved references")
 LANGOPT(ModulesStrictDeclUse, 1, 0, "require declaration of module uses and all headers to be in modules")
 LANGOPT(ModulesErrorRecovery, 1, 1, "automatically import modules as needed when performing error recovery")
-LANGOPT(Optimize          , 1, 0, "__OPTIMIZE__ predefined macro")
-LANGOPT(OptimizeSize      , 1, 0, "__OPTIMIZE_SIZE__ predefined macro")
+COMPATIBLE_LANGOPT(Optimize          , 1, 0, "__OPTIMIZE__ predefined macro")
+COMPATIBLE_LANGOPT(OptimizeSize      , 1, 0, "__OPTIMIZE_SIZE__ predefined macro")
 LANGOPT(Static            , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)")
 VALUE_LANGOPT(PackStruct  , 32, 0,
               "default struct packing maximum alignment")
@@ -112,8 +137,8 @@ VALUE_LANGOPT(MaxTypeAlign  , 32, 0,
 VALUE_LANGOPT(PICLevel    , 2, 0, "__PIC__ level")
 VALUE_LANGOPT(PIELevel    , 2, 0, "__PIE__ level")
 LANGOPT(GNUInline         , 1, 0, "GNU inline semantics")
-LANGOPT(NoInlineDefine    , 1, 0, "__NO_INLINE__ predefined macro")
-LANGOPT(Deprecated        , 1, 0, "__DEPRECATED predefined macro")
+COMPATIBLE_LANGOPT(NoInlineDefine    , 1, 0, "__NO_INLINE__ predefined macro")
+COMPATIBLE_LANGOPT(Deprecated        , 1, 0, "__DEPRECATED predefined macro")
 LANGOPT(FastMath          , 1, 0, "__FAST_MATH__ predefined macro")
 LANGOPT(FiniteMathOnly    , 1, 0, "__FINITE_MATH_ONLY__ predefined macro")
 
@@ -192,8 +217,10 @@ LANGOPT(ApplePragmaPack, 1, 0, "Apple gc
 LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")
 
 #undef LANGOPT
-#undef VALUE_LANGOPT
+#undef COMPATIBLE_LANGOPT
 #undef BENIGN_LANGOPT
 #undef ENUM_LANGOPT
+#undef COMPATIBLE_ENUM_LANGOPT
 #undef BENIGN_ENUM_LANGOPT
+#undef VALUE_LANGOPT
 

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=220943&r1=220942&r2=220943&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Thu Oct 30 21:28:58 2014
@@ -115,7 +115,8 @@ public:
   ///
   /// \returns true to indicate the options are invalid or false otherwise.
   virtual bool ReadLanguageOptions(const LangOptions &LangOpts,
-                                   bool Complain) {
+                                   bool Complain,
+                                   bool AllowCompatibleDifferences) {
     return false;
   }
 
@@ -219,7 +220,8 @@ public:
   bool ReadFullVersionInformation(StringRef FullVersion) override;
   void ReadModuleName(StringRef ModuleName) override;
   void ReadModuleMapFile(StringRef ModuleMapPath) override;
-  bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain) override;
+  bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
+                           bool AllowCompatibleDifferences) override;
   bool ReadTargetOptions(const TargetOptions &TargetOpts,
                          bool Complain) override;
   bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
@@ -251,8 +253,8 @@ public:
   PCHValidator(Preprocessor &PP, ASTReader &Reader)
     : PP(PP), Reader(Reader) {}
 
-  bool ReadLanguageOptions(const LangOptions &LangOpts,
-                           bool Complain) override;
+  bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
+                           bool AllowCompatibleDifferences) override;
   bool ReadTargetOptions(const TargetOptions &TargetOpts,
                          bool Complain) override;
   bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
@@ -1149,7 +1151,8 @@ private:
   ASTReadResult ReadSubmoduleBlock(ModuleFile &F,
                                    unsigned ClientLoadCapabilities);
   static bool ParseLanguageOptions(const RecordData &Record, bool Complain,
-                                   ASTReaderListener &Listener);
+                                   ASTReaderListener &Listener,
+                                   bool AllowCompatibleDifferences);
   static bool ParseTargetOptions(const RecordData &Record, bool Complain,
                                  ASTReaderListener &Listener);
   static bool ParseDiagnosticOptions(const RecordData &Record, bool Complain,

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=220943&r1=220942&r2=220943&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Thu Oct 30 21:28:58 2014
@@ -508,8 +508,8 @@ public:
       : PP(PP), Context(Context), LangOpt(LangOpt), TargetOpts(TargetOpts),
         Target(Target), Counter(Counter), InitializedLanguage(false) {}
 
-  bool ReadLanguageOptions(const LangOptions &LangOpts,
-                           bool Complain) override {
+  bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
+                           bool AllowCompatibleDifferences) override {
     if (InitializedLanguage)
       return false;
     

Modified: cfe/trunk/lib/Frontend/FrontendActions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendActions.cpp?rev=220943&r1=220942&r2=220943&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendActions.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendActions.cpp Thu Oct 30 21:28:58 2014
@@ -431,8 +431,8 @@ namespace {
       Out.indent(2) << "Module map file: " << ModuleMapPath << "\n";
     }
 
-    bool ReadLanguageOptions(const LangOptions &LangOpts,
-                             bool Complain) override {
+    bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
+                             bool AllowCompatibleDifferences) override {
       Out.indent(2) << "Language options:\n";
 #define LANGOPT(Name, Bits, Default, Description) \
       DUMP_BOOLEAN(LangOpts.Name, Description);

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=220943&r1=220942&r2=220943&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Oct 30 21:28:58 2014
@@ -80,10 +80,14 @@ void ChainedASTReaderListener::ReadModul
   First->ReadModuleMapFile(ModuleMapPath);
   Second->ReadModuleMapFile(ModuleMapPath);
 }
-bool ChainedASTReaderListener::ReadLanguageOptions(const LangOptions &LangOpts,
-                                                   bool Complain) {
-  return First->ReadLanguageOptions(LangOpts, Complain) ||
-         Second->ReadLanguageOptions(LangOpts, Complain);
+bool
+ChainedASTReaderListener::ReadLanguageOptions(const LangOptions &LangOpts,
+                                              bool Complain,
+                                              bool AllowCompatibleDifferences) {
+  return First->ReadLanguageOptions(LangOpts, Complain,
+                                    AllowCompatibleDifferences) ||
+         Second->ReadLanguageOptions(LangOpts, Complain,
+                                     AllowCompatibleDifferences);
 }
 bool
 ChainedASTReaderListener::ReadTargetOptions(const TargetOptions &TargetOpts,
@@ -155,11 +159,14 @@ ASTReaderListener::~ASTReaderListener()
 /// language options.
 ///
 /// \param Diags If non-NULL, diagnostics will be emitted via this engine.
+/// \param AllowCompatibleDifferences If true, differences between compatible
+///        language options will be permitted.
 ///
 /// \returns true if the languagae options mis-match, false otherwise.
 static bool checkLanguageOptions(const LangOptions &LangOpts,
                                  const LangOptions &ExistingLangOpts,
-                                 DiagnosticsEngine *Diags) {
+                                 DiagnosticsEngine *Diags,
+                                 bool AllowCompatibleDifferences = true) {
 #define LANGOPT(Name, Bits, Default, Description)                 \
   if (ExistingLangOpts.Name != LangOpts.Name) {                   \
     if (Diags)                                                    \
@@ -184,6 +191,14 @@ static bool checkLanguageOptions(const L
     return true;                                               \
   }
 
+#define COMPATIBLE_LANGOPT(Name, Bits, Default, Description)  \
+  if (!AllowCompatibleDifferences)                            \
+    LANGOPT(Name, Bits, Default, Description)
+
+#define COMPATIBLE_ENUM_LANGOPT(Name, Bits, Default, Description)  \
+  if (!AllowCompatibleDifferences)                                 \
+    ENUM_LANGOPT(Name, Bits, Default, Description)
+
 #define BENIGN_LANGOPT(Name, Bits, Default, Description)
 #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
 #include "clang/Basic/LangOptions.def"
@@ -278,10 +293,12 @@ static bool checkTargetOptions(const Tar
 
 bool
 PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts,
-                                  bool Complain) {
+                                  bool Complain,
+                                  bool AllowCompatibleDifferences) {
   const LangOptions &ExistingLangOpts = PP.getLangOpts();
   return checkLanguageOptions(LangOpts, ExistingLangOpts,
-                              Complain? &Reader.Diags : nullptr);
+                              Complain ? &Reader.Diags : nullptr,
+                              AllowCompatibleDifferences);
 }
 
 bool PCHValidator::ReadTargetOptions(const TargetOptions &TargetOpts,
@@ -2261,6 +2278,12 @@ ASTReader::ReadControlBlock(ModuleFile &
     return Failure;
   }
 
+  // Should we allow the configuration of the module file to differ from the
+  // configuration of the current translation unit in a compatible way?
+  //
+  // FIXME: Allow this for files explicitly specified with -include-pch too.
+  bool AllowCompatibleConfigurationMismatch = F.Kind == MK_ExplicitModule;
+
   // Read all of the records and blocks in the control block.
   RecordData Record;
   unsigned NumInputs = 0;
@@ -2415,8 +2438,10 @@ ASTReader::ReadControlBlock(ModuleFile &
 
     case LANGUAGE_OPTIONS: {
       bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
+      // FIXME: The &F == *ModuleMgr.begin() check is wrong for modules.
       if (Listener && &F == *ModuleMgr.begin() &&
-          ParseLanguageOptions(Record, Complain, *Listener) &&
+          ParseLanguageOptions(Record, Complain, *Listener,
+                               AllowCompatibleConfigurationMismatch) &&
           !DisableValidation && !AllowConfigurationMismatch)
         return ConfigurationMismatch;
       break;
@@ -2434,7 +2459,7 @@ ASTReader::ReadControlBlock(ModuleFile &
     case DIAGNOSTIC_OPTIONS: {
       bool Complain = (ClientLoadCapabilities & ARR_OutOfDate)==0;
       if (Listener && &F == *ModuleMgr.begin() &&
-          F.Kind != MK_ExplicitModule &&
+          !AllowCompatibleConfigurationMismatch &&
           ParseDiagnosticOptions(Record, Complain, *Listener) &&
           !DisableValidation)
         return OutOfDate;
@@ -2444,7 +2469,7 @@ ASTReader::ReadControlBlock(ModuleFile &
     case FILE_SYSTEM_OPTIONS: {
       bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
       if (Listener && &F == *ModuleMgr.begin() &&
-          F.Kind != MK_ExplicitModule &&
+          !AllowCompatibleConfigurationMismatch &&
           ParseFileSystemOptions(Record, Complain, *Listener) &&
           !DisableValidation && !AllowConfigurationMismatch)
         return ConfigurationMismatch;
@@ -2454,7 +2479,7 @@ ASTReader::ReadControlBlock(ModuleFile &
     case HEADER_SEARCH_OPTIONS: {
       bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
       if (Listener && &F == *ModuleMgr.begin() &&
-          F.Kind != MK_ExplicitModule &&
+          !AllowCompatibleConfigurationMismatch &&
           ParseHeaderSearchOptions(Record, Complain, *Listener) &&
           !DisableValidation && !AllowConfigurationMismatch)
         return ConfigurationMismatch;
@@ -2464,7 +2489,7 @@ ASTReader::ReadControlBlock(ModuleFile &
     case PREPROCESSOR_OPTIONS: {
       bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
       if (Listener && &F == *ModuleMgr.begin() &&
-          F.Kind != MK_ExplicitModule &&
+          !AllowCompatibleConfigurationMismatch &&
           ParsePreprocessorOptions(Record, Complain, *Listener,
                                    SuggestedPredefines) &&
           !DisableValidation && !AllowConfigurationMismatch)
@@ -4156,9 +4181,10 @@ namespace {
     {
     }
 
-    bool ReadLanguageOptions(const LangOptions &LangOpts,
-                             bool Complain) override {
-      return checkLanguageOptions(ExistingLangOpts, LangOpts, nullptr);
+    bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
+                             bool AllowCompatibleDifferences) override {
+      return checkLanguageOptions(ExistingLangOpts, LangOpts, nullptr,
+                                  AllowCompatibleDifferences);
     }
     bool ReadTargetOptions(const TargetOptions &TargetOpts,
                            bool Complain) override {
@@ -4256,7 +4282,8 @@ bool ASTReader::readASTFileControlBlock(
       break;
     }
     case LANGUAGE_OPTIONS:
-      if (ParseLanguageOptions(Record, false, Listener))
+      if (ParseLanguageOptions(Record, false, Listener,
+                               /*AllowCompatibleConfigurationMismatch*/false))
         return true;
       break;
 
@@ -4612,7 +4639,8 @@ ASTReader::ReadSubmoduleBlock(ModuleFile
 /// \returns true if the listener deems the file unacceptable, false otherwise.
 bool ASTReader::ParseLanguageOptions(const RecordData &Record,
                                      bool Complain,
-                                     ASTReaderListener &Listener) {
+                                     ASTReaderListener &Listener,
+                                     bool AllowCompatibleDifferences) {
   LangOptions LangOpts;
   unsigned Idx = 0;
 #define LANGOPT(Name, Bits, Default, Description) \
@@ -4640,7 +4668,8 @@ bool ASTReader::ParseLanguageOptions(con
   }
   LangOpts.CommentOpts.ParseAllComments = Record[Idx++];
 
-  return Listener.ReadLanguageOptions(LangOpts, Complain);
+  return Listener.ReadLanguageOptions(LangOpts, Complain,
+                                      AllowCompatibleDifferences);
 }
 
 bool ASTReader::ParseTargetOptions(const RecordData &Record,

Modified: cfe/trunk/test/Modules/explicit-build-flags.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/explicit-build-flags.cpp?rev=220943&r1=220942&r2=220943&view=diff
==============================================================================
--- cfe/trunk/test/Modules/explicit-build-flags.cpp (original)
+++ cfe/trunk/test/Modules/explicit-build-flags.cpp Thu Oct 30 21:28:58 2014
@@ -25,6 +25,13 @@
 // Can use the module if -I flags change.
 // RUN: %clang_cc1 -fmodules -DBAR=2 -I. -x c++ -fmodule-map-file=%t/map -fmodule-file=%t/tmp.pcm -verify -I%t %s
 
+// Can use the module if -O flags change.
+// RUN: %clang_cc1 -fmodules -DBAR=2 -Os -x c++ -fmodule-map-file=%t/map -fmodule-file=%t/tmp.pcm -verify -I%t %s
+//
+// RUN: %clang_cc1 -fmodules -DFOO=1 -O2 -x c++ -fmodule-name=tmp %t/map -emit-module -o %t/tmp-O2.pcm
+// RUN: %clang_cc1 -fmodules -DBAR=2 -O0 -x c++ -fmodule-map-file=%t/map -fmodule-file=%t/tmp-O2.pcm -verify -I%t %s
+// RUN: %clang_cc1 -fmodules -DBAR=2 -Os -x c++ -fmodule-map-file=%t/map -fmodule-file=%t/tmp-O2.pcm -verify -I%t %s
+
 #include "tmp.h" // expected-no-diagnostics
 
 #ifndef BAR





More information about the cfe-commits mailing list