diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -1167,12 +1167,12 @@ HeaderFileInfo *HFI = &FileInfo[FE->getUID()]; // FIXME: Use a generation count to check whether this is really up to date. if (ExternalSource && !HFI->Resolved) { - HFI->Resolved = true; auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE); - - HFI = &FileInfo[FE->getUID()]; - if (ExternalHFI.External) - mergeHeaderFileInfo(*HFI, ExternalHFI); + if (ExternalHFI.IsValid) { + HFI->Resolved = true; + if (ExternalHFI.External) + mergeHeaderFileInfo(*HFI, ExternalHFI); + } } HFI->IsValid = true; @@ -1199,12 +1199,12 @@ if (!WantExternal && (!HFI->IsValid || HFI->External)) return nullptr; if (!HFI->Resolved) { - HFI->Resolved = true; auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE); - - HFI = &FileInfo[FE->getUID()]; - if (ExternalHFI.External) - mergeHeaderFileInfo(*HFI, ExternalHFI); + if (ExternalHFI.IsValid) { + HFI->Resolved = true; + if (ExternalHFI.External) + mergeHeaderFileInfo(*HFI, ExternalHFI); + } } } else if (FE->getUID() >= FileInfo.size()) { return nullptr; diff --git a/clang/test/Modules/Inputs/import-once/ImportOnce.framework/Headers/ImportOnce.h b/clang/test/Modules/Inputs/import-once/ImportOnce.framework/Headers/ImportOnce.h new file mode 100644 --- /dev/null +++ b/clang/test/Modules/Inputs/import-once/ImportOnce.framework/Headers/ImportOnce.h @@ -0,0 +1,5 @@ +// No header guards on purpose. + +enum SomeSimpleEnum { + SomeSimpleEnumCase, +}; diff --git a/clang/test/Modules/Inputs/import-once/ImportOnce.framework/Modules/module.modulemap b/clang/test/Modules/Inputs/import-once/ImportOnce.framework/Modules/module.modulemap new file mode 100644 --- /dev/null +++ b/clang/test/Modules/Inputs/import-once/ImportOnce.framework/Modules/module.modulemap @@ -0,0 +1,4 @@ +framework module ImportOnce { + umbrella header "ImportOnce.h" + export * +} diff --git a/clang/test/Modules/Inputs/import-once/IndirectImporter.framework/Headers/IndirectImporter.h b/clang/test/Modules/Inputs/import-once/IndirectImporter.framework/Headers/IndirectImporter.h new file mode 100644 --- /dev/null +++ b/clang/test/Modules/Inputs/import-once/IndirectImporter.framework/Headers/IndirectImporter.h @@ -0,0 +1,2 @@ +#import +#import diff --git a/clang/test/Modules/Inputs/import-once/IndirectImporter.framework/Modules/module.modulemap b/clang/test/Modules/Inputs/import-once/IndirectImporter.framework/Modules/module.modulemap new file mode 100644 --- /dev/null +++ b/clang/test/Modules/Inputs/import-once/IndirectImporter.framework/Modules/module.modulemap @@ -0,0 +1,4 @@ +framework module IndirectImporter { + umbrella header "IndirectImporter.h" + export * +} diff --git a/clang/test/Modules/Inputs/import-once/Unrelated.framework/Headers/Unrelated.h b/clang/test/Modules/Inputs/import-once/Unrelated.framework/Headers/Unrelated.h new file mode 100644 --- /dev/null +++ b/clang/test/Modules/Inputs/import-once/Unrelated.framework/Headers/Unrelated.h @@ -0,0 +1 @@ +void foo(void); diff --git a/clang/test/Modules/Inputs/import-once/Unrelated.framework/Modules/module.modulemap b/clang/test/Modules/Inputs/import-once/Unrelated.framework/Modules/module.modulemap new file mode 100644 --- /dev/null +++ b/clang/test/Modules/Inputs/import-once/Unrelated.framework/Modules/module.modulemap @@ -0,0 +1,4 @@ +framework module Unrelated { + umbrella header "Unrelated.h" + export * +} diff --git a/clang/test/Modules/import-once.m b/clang/test/Modules/import-once.m new file mode 100644 --- /dev/null +++ b/clang/test/Modules/import-once.m @@ -0,0 +1,15 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fmodule-name=ImportOnce -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/import-once %s + +// Test #import-ed headers are processed only once, even without header guards. +// Dependency graph is +// +// Unrelated ImportOnce +// ^ ^ ^ +// \ / | +// IndirectImporter | +// ^ | +// \ | +// import-once.m +#import +#import