diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index d7c9227cb1c49..a2d1d91f14ce7 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -188,6 +188,8 @@ class TargetProperties : public Properties { bool GetSwiftAllowExplicitModules() const; + AutoBool GetSwiftPCMValidation() const; + Args GetSwiftPluginServerForPath() const; bool GetSwiftAutoImportFrameworks() const; diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index 9211db9c185e2..b66b2d2814434 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -57,7 +57,9 @@ #include "clang/Basic/TargetOptions.h" #include "clang/Driver/Driver.h" #include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Lex/PreprocessorOptions.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" @@ -9210,6 +9212,38 @@ bool SwiftASTContext::GetCompileUnitImportsImpl( if (cu_imports.size() == 0) return true; + // Set PCM validation. This is not a great place to do this, but it + // needs to happen after ClangImporter was created and + // m_has_explicit_modules has been initialized. + { + // Read the setting. + AutoBool validate_pcm_setting = AutoBool::Auto; + TargetSP target_sp = GetTargetWP().lock(); + if (target_sp) + validate_pcm_setting = target_sp->GetSwiftPCMValidation(); + + // If the setting is explicit, honor it. + bool validate_pcm = validate_pcm_setting != AutoBool::False; + if (validate_pcm_setting == AutoBool::Auto) { + // Disable validation for explicit modules. + validate_pcm = m_has_explicit_modules ? false : true; + // Enable validation in asserts builds. +#ifndef NDEBUG + validate_pcm = true; +#endif + } + + auto &pp_opts = m_clangimporter->getClangPreprocessor() + .getPreprocessorOpts(); + pp_opts.DisablePCHOrModuleValidation = + validate_pcm ? clang::DisableValidationForModuleKind::None + : clang::DisableValidationForModuleKind::All; + pp_opts.ModulesCheckRelocated = validate_pcm; + + LOG_PRINTF(GetLog(LLDBLog::Types), "PCM validation is %s", + validate_pcm ? "disabled" : "enabled"); + } + LOG_PRINTF(GetLog(LLDBLog::Types), "Importing dependencies of current CU"); // Turn off implicit clang modules while importing CU dependencies. diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index f4df89d6c450e..bcb3151eb48f8 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -4688,6 +4688,13 @@ static constexpr OptionEnumValueElement g_memory_module_load_level_values[] = { }, }; +static constexpr OptionEnumValueElement g_swift_pcm_validation_values[] = { + {llvm::to_underlying(AutoBool::Auto), "auto", + "Turned on when explicit modules are enabled"}, + {llvm::to_underlying(AutoBool::True), "true", "Enable validation."}, + {llvm::to_underlying(AutoBool::False), "false", "Disable validation."}, +}; + #define LLDB_PROPERTIES_target #include "TargetProperties.inc" @@ -4927,6 +4934,19 @@ bool TargetProperties::GetSwiftAllowExplicitModules() const { return true; } +AutoBool TargetProperties::GetSwiftPCMValidation() const { + const Property *exp_property = + m_collection_sp->GetPropertyAtIndex(ePropertyExperimental); + OptionValueProperties *exp_values = + exp_property->GetValue()->GetAsProperties(); + if (exp_values) + return exp_values + ->GetPropertyAtIndexAs(ePropertySwiftPCMValidation) + .value_or(AutoBool::Auto); + + return AutoBool::Auto; +} + Args TargetProperties::GetSwiftPluginServerForPath() const { const uint32_t idx = ePropertySwiftPluginServerForPath; diff --git a/lldb/source/Target/TargetProperties.td b/lldb/source/Target/TargetProperties.td index 19ae2ed1c1526..31879a85c7f3b 100644 --- a/lldb/source/Target/TargetProperties.td +++ b/lldb/source/Target/TargetProperties.td @@ -26,6 +26,11 @@ let Definition = "target_experimental" in { def SwiftAllowExplicitModules: Property<"swift-allow-explicit-modules", "Boolean">, DefaultTrue, Desc<"Allows explicit module flags to be passed through to ClangImporter.">; + def SwiftPCMValidation: Property<"swift-pcm-validation", "Enum">, + Global, + DefaultEnumValue<"llvm::to_underlying(AutoBool::Auto)">, + EnumValues<"OptionEnumValues(g_swift_pcm_validation_values)">, + Desc<"Enable validation when loading Clang PCM files (-fvalidate-pch, -fmodules-check-relocated).">; } let Definition = "target" in { diff --git a/lldb/test/API/lang/swift/clangimporter/fmodule_flags/TestSwiftFModuleFlags.py b/lldb/test/API/lang/swift/clangimporter/fmodule_flags/TestSwiftFModuleFlags.py index 7673e760f985e..15b9f2d315d4f 100644 --- a/lldb/test/API/lang/swift/clangimporter/fmodule_flags/TestSwiftFModuleFlags.py +++ b/lldb/test/API/lang/swift/clangimporter/fmodule_flags/TestSwiftFModuleFlags.py @@ -24,3 +24,4 @@ def test(self): # CHECK-NOT: -fno-implicit-modules # CHECK-NOT: -fno-implicit-module-maps # CHECK: -DMARKER2 +# CHECK: PCM validation is