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 @@ -1037,8 +1037,9 @@ } } - // If this file is found in a header map and uses the framework style of - // includes, then this header is part of a framework we're building. + // Set the `Framework` info if this file is in a header map with framework + // style include spelling or found in a framework dir. The header map case + // is possible when building frameworks which use header maps. if (CurDir->isHeaderMap() && isAngled) { size_t SlashPos = Filename.find('/'); if (SlashPos != StringRef::npos) @@ -1046,6 +1047,11 @@ getUniqueFrameworkName(StringRef(Filename.begin(), SlashPos)); if (CurDir->isIndexHeaderMap()) HFI.IndexHeaderMapHeader = 1; + } else if (CurDir->isFramework()) { + size_t SlashPos = Filename.find('/'); + if (SlashPos != StringRef::npos) + HFI.Framework = + getUniqueFrameworkName(StringRef(Filename.begin(), SlashPos)); } if (checkMSVCHeaderSearch(Diags, MSFE ? &MSFE->getFileEntry() : nullptr, diff --git a/clang/unittests/Lex/HeaderSearchTest.cpp b/clang/unittests/Lex/HeaderSearchTest.cpp --- a/clang/unittests/Lex/HeaderSearchTest.cpp +++ b/clang/unittests/Lex/HeaderSearchTest.cpp @@ -186,6 +186,29 @@ "Sub/Sub.h"); } +TEST_F(HeaderSearchTest, HeaderFrameworkLookup) { + std::string HeaderPath = "/tmp/Frameworks/Foo.framework/Headers/Foo.h"; + addSystemFrameworkSearchDir("/tmp/Frameworks"); + VFS->addFile( + HeaderPath, 0, llvm::MemoryBuffer::getMemBufferCopy("", HeaderPath), + /*User=*/None, /*Group=*/None, llvm::sys::fs::file_type::regular_file); + + bool IsFrameworkFound = false; + auto FoundFile = Search.LookupFile( + "Foo/Foo.h", SourceLocation(), /*isAngled=*/true, /*FromDir=*/nullptr, + /*CurDir=*/nullptr, /*Includers=*/{}, /*SearchPath=*/nullptr, + /*RelativePath=*/nullptr, /*RequestingModule=*/nullptr, + /*SuggestedModule=*/nullptr, /*IsMapped=*/nullptr, &IsFrameworkFound); + + EXPECT_TRUE(FoundFile.hasValue()); + EXPECT_TRUE(IsFrameworkFound); + auto &FE = FoundFile.getValue(); + auto FI = Search.getExistingFileInfo(FE); + EXPECT_TRUE(FI); + EXPECT_TRUE(FI->IsValid); + EXPECT_EQ(FI->Framework.str(), "Foo"); +} + // Helper struct with null terminator character to make MemoryBuffer happy. template struct NullTerminatedFile : public FileTy {