cishida created this revision.
cishida added reviewers: dexonsmith, ributzka.
cishida requested review of this revision.
Herald added a project: clang.

When building frameworks, headermaps responsible for mapping angle-included 
headers to their source file location are passed via
`-I` and not `-index-header-map`. However, `-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


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D111468

Files:
  clang/lib/Lex/HeaderSearch.cpp
  clang/unittests/Lex/HeaderSearchTest.cpp


Index: clang/unittests/Lex/HeaderSearchTest.cpp
===================================================================
--- clang/unittests/Lex/HeaderSearchTest.cpp
+++ clang/unittests/Lex/HeaderSearchTest.cpp
@@ -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 {
@@ -47,7 +48,8 @@
   }
 
   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);
@@ -56,9 +58,10 @@
     // Test class supports only one HMap at a time.
     assert(!HMap);
     HMap = HeaderMap::Create(*FE, FileMgr);
+    HMap->dump();
     auto DL =
         DirectoryLookup(HMap.get(), SrcMgr::C_User, /*isFramework=*/false);
-    Search.AddSearchPath(DL, /*isAngled=*/false);
+    Search.AddSearchPath(DL, isAngled);
   }
 
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> VFS;
@@ -179,5 +182,38 @@
             "d.h");
 }
 
+TEST_F(HeaderSearchTest, HeaderMapFrameworkLookup) {
+  typedef NullTerminatedFile<test::HMapFileMock<4, 128>, char> FileTy;
+  FileTy File;
+  File.init();
+
+  test::HMapFileMockMaker<FileTy> Maker(File);
+  auto a = Maker.addString("Foo/Foo.h");
+  auto b = Maker.addString("/tmp/Sources/Foo/Headers/");
+  auto c = Maker.addString("Foo.h");
+  Maker.addBucket("Foo/Foo.h", a, b, c);
+  addHeaderMap("product-headers.hmap", File.getBuffer(), /*isAngled=*/true);
+
+  StringRef HeaderName = "/tmp/Sources/Foo/Headers/Foo.h";
+  VFS->addFile(
+      HeaderName, 0, llvm::MemoryBuffer::getMemBufferCopy("", HeaderName),
+      /*User=*/None, /*Group=*/None, llvm::sys::fs::file_type::regular_file);
+
+  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=*/nullptr,
+      /*IsFrameworkFound=*/nullptr);
+
+  EXPECT_TRUE(FoundFile.hasValue());
+  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
Index: clang/lib/Lex/HeaderSearch.cpp
===================================================================
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -964,13 +964,13 @@
 
     // 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,


Index: clang/unittests/Lex/HeaderSearchTest.cpp
===================================================================
--- clang/unittests/Lex/HeaderSearchTest.cpp
+++ clang/unittests/Lex/HeaderSearchTest.cpp
@@ -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 {
@@ -47,7 +48,8 @@
   }
 
   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);
@@ -56,9 +58,10 @@
     // Test class supports only one HMap at a time.
     assert(!HMap);
     HMap = HeaderMap::Create(*FE, FileMgr);
+    HMap->dump();
     auto DL =
         DirectoryLookup(HMap.get(), SrcMgr::C_User, /*isFramework=*/false);
-    Search.AddSearchPath(DL, /*isAngled=*/false);
+    Search.AddSearchPath(DL, isAngled);
   }
 
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> VFS;
@@ -179,5 +182,38 @@
             "d.h");
 }
 
+TEST_F(HeaderSearchTest, HeaderMapFrameworkLookup) {
+  typedef NullTerminatedFile<test::HMapFileMock<4, 128>, char> FileTy;
+  FileTy File;
+  File.init();
+
+  test::HMapFileMockMaker<FileTy> Maker(File);
+  auto a = Maker.addString("Foo/Foo.h");
+  auto b = Maker.addString("/tmp/Sources/Foo/Headers/");
+  auto c = Maker.addString("Foo.h");
+  Maker.addBucket("Foo/Foo.h", a, b, c);
+  addHeaderMap("product-headers.hmap", File.getBuffer(), /*isAngled=*/true);
+
+  StringRef HeaderName = "/tmp/Sources/Foo/Headers/Foo.h";
+  VFS->addFile(
+      HeaderName, 0, llvm::MemoryBuffer::getMemBufferCopy("", HeaderName),
+      /*User=*/None, /*Group=*/None, llvm::sys::fs::file_type::regular_file);
+
+  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=*/nullptr,
+      /*IsFrameworkFound=*/nullptr);
+
+  EXPECT_TRUE(FoundFile.hasValue());
+  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
Index: clang/lib/Lex/HeaderSearch.cpp
===================================================================
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -964,13 +964,13 @@
 
     // 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,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to