Skip to content

Commit

Permalink
[clang] Capture Framework when HeaderSearch is resolved via headermap
Browse files Browse the repository at this point in the history
When building frameworks, headermaps responsible for mapping angle-included headers to their source file location are passed via
`-I` and not `-index-header-map`. Also, `-index-header-map` is only used for indexing purposes and not during most builds.
This patch holds on to the framework's name in HeaderFileInfo as this is retrieveable for cases outside of IndexHeaderMaps and
still represents the framework that is being built.

resolves: rdar://84046893

Reviewed By: jansvoboda11

Differential Revision: https://reviews.llvm.org/D111468
  • Loading branch information
cyndyishida committed Oct 15, 2021
1 parent c294715 commit 395e1fe
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 7 deletions.
10 changes: 5 additions & 5 deletions clang/lib/Lex/HeaderSearch.cpp
Expand Up @@ -1005,13 +1005,13 @@ Optional<FileEntryRef> HeaderSearch::LookupFile(

// 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.
if (CurDir->isIndexHeaderMap()) {
if (CurDir->isHeaderMap() && isAngled) {
size_t SlashPos = Filename.find('/');
if (SlashPos != StringRef::npos) {
if (SlashPos != StringRef::npos)
HFI.Framework =
getUniqueFrameworkName(StringRef(Filename.begin(), SlashPos));
if (CurDir->isIndexHeaderMap())
HFI.IndexHeaderMapHeader = 1;
HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(),
SlashPos));
}
}

if (checkMSVCHeaderSearch(Diags, MSFE ? &MSFE->getFileEntry() : nullptr,
Expand Down
49 changes: 47 additions & 2 deletions clang/unittests/Lex/HeaderSearchTest.cpp
Expand Up @@ -18,6 +18,7 @@
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Serialization/InMemoryModuleCache.h"
#include "llvm/Support/MemoryBuffer.h"
#include "gtest/gtest.h"

namespace clang {
Expand Down Expand Up @@ -47,7 +48,8 @@ class HeaderSearchTest : public ::testing::Test {
}

void addHeaderMap(llvm::StringRef Filename,
std::unique_ptr<llvm::MemoryBuffer> Buf) {
std::unique_ptr<llvm::MemoryBuffer> Buf,
bool isAngled = false) {
VFS->addFile(Filename, 0, std::move(Buf), /*User=*/None, /*Group=*/None,
llvm::sys::fs::file_type::regular_file);
auto FE = FileMgr.getFile(Filename, true);
Expand All @@ -58,7 +60,7 @@ class HeaderSearchTest : public ::testing::Test {
HMap = HeaderMap::Create(*FE, FileMgr);
auto DL =
DirectoryLookup(HMap.get(), SrcMgr::C_User, /*isFramework=*/false);
Search.AddSearchPath(DL, /*isAngled=*/false);
Search.AddSearchPath(DL, isAngled);
}

IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> VFS;
Expand Down Expand Up @@ -179,5 +181,48 @@ TEST_F(HeaderSearchTest, HeaderMapReverseLookup) {
"d.h");
}

TEST_F(HeaderSearchTest, HeaderMapFrameworkLookup) {
typedef NullTerminatedFile<test::HMapFileMock<4, 128>, char> FileTy;
FileTy File;
File.init();

std::string HeaderDirName = "/tmp/Sources/Foo/Headers/";
std::string HeaderName = "Foo.h";
#ifdef _WIN32
// Force header path to be absolute on windows.
// As headermap content should represent absolute locations.
HeaderDirName = "C:" + HeaderDirName;
#endif /*_WIN32*/

test::HMapFileMockMaker<FileTy> Maker(File);
auto a = Maker.addString("Foo/Foo.h");
auto b = Maker.addString(HeaderDirName);
auto c = Maker.addString(HeaderName);
Maker.addBucket("Foo/Foo.h", a, b, c);
addHeaderMap("product-headers.hmap", File.getBuffer(), /*isAngled=*/true);

VFS->addFile(
HeaderDirName + HeaderName, 0,
llvm::MemoryBuffer::getMemBufferCopy("", HeaderDirName + HeaderName),
/*User=*/None, /*Group=*/None, llvm::sys::fs::file_type::regular_file);

bool IsMapped = false;
const DirectoryLookup *CurDir = nullptr;
auto FoundFile = Search.LookupFile(
"Foo/Foo.h", SourceLocation(), /*isAngled=*/true, /*FromDir=*/nullptr,
CurDir, /*Includers=*/{}, /*SearchPath=*/nullptr,
/*RelativePath=*/nullptr, /*RequestingModule=*/nullptr,
/*SuggestedModule=*/nullptr, &IsMapped,
/*IsFrameworkFound=*/nullptr);

EXPECT_TRUE(FoundFile.hasValue());
EXPECT_TRUE(IsMapped);
auto &FE = FoundFile.getValue();
auto FI = Search.getExistingFileInfo(FE);
EXPECT_TRUE(FI);
EXPECT_TRUE(FI->IsValid);
EXPECT_EQ(FI->Framework.str(), "Foo");
}

} // namespace
} // namespace clang

0 comments on commit 395e1fe

Please sign in to comment.