Skip to content

[clang][lex] Remove HeaderFileInfo::Framework #114460

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 28 additions & 30 deletions clang-tools-extra/clangd/index/SymbolCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,9 +335,10 @@ class SymbolCollector::HeaderFileURICache {
}

struct FrameworkHeaderPath {
// Path to the framework directory containing the Headers/PrivateHeaders
// directories e.g. /Frameworks/Foundation.framework/
llvm::StringRef HeadersParentDir;
// Path to the frameworks directory containing the .framework directory.
llvm::StringRef FrameworkParentDir;
// Name of the framework.
llvm::StringRef FrameworkName;
// Subpath relative to the Headers or PrivateHeaders dir, e.g. NSObject.h
// Note: This is NOT relative to the `HeadersParentDir`.
llvm::StringRef HeaderSubpath;
Expand All @@ -351,19 +352,17 @@ class SymbolCollector::HeaderFileURICache {
path::reverse_iterator I = path::rbegin(Path);
path::reverse_iterator Prev = I;
path::reverse_iterator E = path::rend(Path);
FrameworkHeaderPath HeaderPath;
while (I != E) {
if (*I == "Headers") {
FrameworkHeaderPath HeaderPath;
HeaderPath.HeadersParentDir = Path.substr(0, I - E);
if (*I == "Headers" || *I == "PrivateHeaders") {
HeaderPath.HeaderSubpath = Path.substr(Prev - E);
HeaderPath.IsPrivateHeader = false;
return HeaderPath;
}
if (*I == "PrivateHeaders") {
FrameworkHeaderPath HeaderPath;
HeaderPath.HeadersParentDir = Path.substr(0, I - E);
HeaderPath.HeaderSubpath = Path.substr(Prev - E);
HeaderPath.IsPrivateHeader = true;
HeaderPath.IsPrivateHeader = *I == "PrivateHeaders";
if (++I == E)
break;
HeaderPath.FrameworkName = *I;
if (!HeaderPath.FrameworkName.consume_back(".framework"))
break;
HeaderPath.FrameworkParentDir = Path.substr(0, I - E);
return HeaderPath;
}
Prev = I;
Expand All @@ -379,26 +378,27 @@ class SymbolCollector::HeaderFileURICache {
// <Foundation/NSObject_Private.h> which should be used instead of directly
// importing the header.
std::optional<std::string>
getFrameworkUmbrellaSpelling(llvm::StringRef Framework,
const HeaderSearch &HS,
getFrameworkUmbrellaSpelling(const HeaderSearch &HS,
FrameworkHeaderPath &HeaderPath) {
StringRef Framework = HeaderPath.FrameworkName;
auto Res = CacheFrameworkToUmbrellaHeaderSpelling.try_emplace(Framework);
auto *CachedSpelling = &Res.first->second;
if (!Res.second) {
return HeaderPath.IsPrivateHeader ? CachedSpelling->PrivateHeader
: CachedSpelling->PublicHeader;
}
SmallString<256> UmbrellaPath(HeaderPath.HeadersParentDir);
llvm::sys::path::append(UmbrellaPath, "Headers", Framework + ".h");
SmallString<256> UmbrellaPath(HeaderPath.FrameworkParentDir);
llvm::sys::path::append(UmbrellaPath, Framework + ".framework", "Headers",
Framework + ".h");

llvm::vfs::Status Status;
auto StatErr = HS.getFileMgr().getNoncachedStatValue(UmbrellaPath, Status);
if (!StatErr)
CachedSpelling->PublicHeader = llvm::formatv("<{0}/{0}.h>", Framework);

UmbrellaPath = HeaderPath.HeadersParentDir;
llvm::sys::path::append(UmbrellaPath, "PrivateHeaders",
Framework + "_Private.h");
UmbrellaPath = HeaderPath.FrameworkParentDir;
llvm::sys::path::append(UmbrellaPath, Framework + ".framework",
"PrivateHeaders", Framework + "_Private.h");

StatErr = HS.getFileMgr().getNoncachedStatValue(UmbrellaPath, Status);
if (!StatErr)
Expand All @@ -414,8 +414,7 @@ class SymbolCollector::HeaderFileURICache {
// give <Foundation/Foundation.h> if the umbrella header exists, otherwise
// <Foundation/NSObject.h>.
std::optional<llvm::StringRef>
getFrameworkHeaderIncludeSpelling(FileEntryRef FE, llvm::StringRef Framework,
HeaderSearch &HS) {
getFrameworkHeaderIncludeSpelling(FileEntryRef FE, HeaderSearch &HS) {
auto Res = CachePathToFrameworkSpelling.try_emplace(FE.getName());
auto *CachedHeaderSpelling = &Res.first->second;
if (!Res.second)
Expand All @@ -429,13 +428,15 @@ class SymbolCollector::HeaderFileURICache {
return std::nullopt;
}
if (auto UmbrellaSpelling =
getFrameworkUmbrellaSpelling(Framework, HS, *HeaderPath)) {
getFrameworkUmbrellaSpelling(HS, *HeaderPath)) {
*CachedHeaderSpelling = *UmbrellaSpelling;
return llvm::StringRef(*CachedHeaderSpelling);
}

*CachedHeaderSpelling =
llvm::formatv("<{0}/{1}>", Framework, HeaderPath->HeaderSubpath).str();
llvm::formatv("<{0}/{1}>", HeaderPath->FrameworkName,
HeaderPath->HeaderSubpath)
.str();
return llvm::StringRef(*CachedHeaderSpelling);
}

Expand All @@ -454,11 +455,8 @@ class SymbolCollector::HeaderFileURICache {
// Framework headers are spelled as <FrameworkName/Foo.h>, not
// "path/FrameworkName.framework/Headers/Foo.h".
auto &HS = PP->getHeaderSearchInfo();
if (const auto *HFI = HS.getExistingFileInfo(*FE))
if (!HFI->Framework.empty())
if (auto Spelling =
getFrameworkHeaderIncludeSpelling(*FE, HFI->Framework, HS))
return *Spelling;
if (auto Spelling = getFrameworkHeaderIncludeSpelling(*FE, HS))
return *Spelling;

if (!tooling::isSelfContainedHeader(*FE, PP->getSourceManager(),
PP->getHeaderSearchInfo())) {
Expand Down
6 changes: 2 additions & 4 deletions clang/include/clang/Lex/HeaderSearch.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,6 @@ struct HeaderFileInfo {
/// external storage.
LazyIdentifierInfoPtr LazyControllingMacro;

/// If this header came from a framework include, this is the name
/// of the framework.
StringRef Framework;

HeaderFileInfo()
: IsLocallyIncluded(false), isImport(false), isPragmaOnce(false),
DirInfo(SrcMgr::C_User), External(false), isModuleHeader(false),
Expand All @@ -144,6 +140,8 @@ struct HeaderFileInfo {
void mergeModuleMembership(ModuleMap::ModuleHeaderRole Role);
};

static_assert(sizeof(HeaderFileInfo) <= 16);

/// An external source of header file information, which may supply
/// information about header files already included.
class ExternalHeaderFileInfoSource {
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ namespace serialization {
/// Version 4 of AST files also requires that the version control branch and
/// revision match exactly, since there is no backward compatibility of
/// AST files at this time.
const unsigned VERSION_MAJOR = 32;
const unsigned VERSION_MAJOR = 33;

/// AST file minor version number supported by this version of
/// Clang.
Expand Down
15 changes: 0 additions & 15 deletions clang/lib/Lex/HeaderSearch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -974,11 +974,9 @@ OptionalFileEntryRef HeaderSearch::LookupFile(
const HeaderFileInfo *FromHFI = getExistingFileInfo(*Includer);
assert(FromHFI && "includer without file info");
unsigned DirInfo = FromHFI->DirInfo;
StringRef Framework = FromHFI->Framework;

HeaderFileInfo &ToHFI = getFileInfo(*FE);
ToHFI.DirInfo = DirInfo;
ToHFI.Framework = Framework;

if (SearchPath) {
StringRef SearchPathRef(IncluderAndDir.second.getName());
Expand Down Expand Up @@ -1120,16 +1118,6 @@ OptionalFileEntryRef HeaderSearch::LookupFile(
}
}

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

if (checkMSVCHeaderSearch(Diags, MSFE, &File->getFileEntry(), IncludeLoc)) {
if (SuggestedModule)
*SuggestedModule = MSSuggestedModule;
Expand Down Expand Up @@ -1314,9 +1302,6 @@ static void mergeHeaderFileInfo(HeaderFileInfo &HFI,
HFI.DirInfo = OtherHFI.DirInfo;
HFI.External = (!HFI.IsValid || HFI.External);
HFI.IsValid = true;

if (HFI.Framework.empty())
HFI.Framework = OtherHFI.Framework;
}

HeaderFileInfo &HeaderSearch::getFileInfo(FileEntryRef FE) {
Expand Down
18 changes: 4 additions & 14 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2122,13 +2122,6 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d,
HFI.DirInfo = (Flags >> 1) & 0x07;
HFI.LazyControllingMacro = Reader.getGlobalIdentifierID(
M, endian::readNext<IdentifierID, llvm::endianness::little>(d));
if (unsigned FrameworkOffset =
endian::readNext<uint32_t, llvm::endianness::little>(d)) {
// The framework offset is 1 greater than the actual offset,
// since 0 is used as an indicator for "no framework name".
StringRef FrameworkName(FrameworkStrings + FrameworkOffset - 1);
HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
}

assert((End - d) % 4 == 0 &&
"Wrong data length in HeaderFileInfo deserialization");
Expand Down Expand Up @@ -3902,13 +3895,10 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
F.HeaderFileInfoTableData = Blob.data();
F.LocalNumHeaderFileInfos = Record[1];
if (Record[0]) {
F.HeaderFileInfoTable
= HeaderFileInfoLookupTable::Create(
(const unsigned char *)F.HeaderFileInfoTableData + Record[0],
(const unsigned char *)F.HeaderFileInfoTableData,
HeaderFileInfoTrait(*this, F,
&PP.getHeaderSearchInfo(),
Blob.data() + Record[2]));
F.HeaderFileInfoTable = HeaderFileInfoLookupTable::Create(
(const unsigned char *)F.HeaderFileInfoTableData + Record[0],
(const unsigned char *)F.HeaderFileInfoTableData,
HeaderFileInfoTrait(*this, F));

PP.getHeaderSearchInfo().SetExternalSource(this);
if (!PP.getHeaderSearchInfo().getExternalLookup())
Expand Down
7 changes: 2 additions & 5 deletions clang/lib/Serialization/ASTReaderInternals.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,6 @@ using ASTSelectorLookupTable =
class HeaderFileInfoTrait {
ASTReader &Reader;
ModuleFile &M;
HeaderSearch *HS;
const char *FrameworkStrings;

public:
using external_key_type = FileEntryRef;
Expand All @@ -262,9 +260,8 @@ class HeaderFileInfoTrait {
using hash_value_type = unsigned;
using offset_type = unsigned;

HeaderFileInfoTrait(ASTReader &Reader, ModuleFile &M, HeaderSearch *HS,
const char *FrameworkStrings)
: Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings) {}
HeaderFileInfoTrait(ASTReader &Reader, ModuleFile &M)
: Reader(Reader), M(M) {}

static hash_value_type ComputeHash(internal_key_ref ikey);
internal_key_type GetInternalKey(external_key_type ekey);
Expand Down
26 changes: 1 addition & 25 deletions clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1958,10 +1958,6 @@ namespace {
class HeaderFileInfoTrait {
ASTWriter &Writer;

// Keep track of the framework names we've used during serialization.
SmallString<128> FrameworkStringData;
llvm::StringMap<unsigned> FrameworkNameOffset;

public:
HeaderFileInfoTrait(ASTWriter &Writer) : Writer(Writer) {}

Expand Down Expand Up @@ -2005,7 +2001,7 @@ namespace {
std::pair<unsigned, unsigned>
EmitKeyDataLength(raw_ostream& Out, key_type_ref key, data_type_ref Data) {
unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
unsigned DataLen = 1 + sizeof(IdentifierID) + 4;
unsigned DataLen = 1 + sizeof(IdentifierID);
for (auto ModInfo : Data.KnownHeaders)
if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
DataLen += 4;
Expand Down Expand Up @@ -2045,22 +2041,6 @@ namespace {
LE.write<IdentifierID>(
Writer.getIdentifierRef(Data.HFI.LazyControllingMacro.getPtr()));

unsigned Offset = 0;
if (!Data.HFI.Framework.empty()) {
// If this header refers into a framework, save the framework name.
llvm::StringMap<unsigned>::iterator Pos
= FrameworkNameOffset.find(Data.HFI.Framework);
if (Pos == FrameworkNameOffset.end()) {
Offset = FrameworkStringData.size() + 1;
FrameworkStringData.append(Data.HFI.Framework);
FrameworkStringData.push_back(0);

FrameworkNameOffset[Data.HFI.Framework] = Offset;
} else
Offset = Pos->second;
}
LE.write<uint32_t>(Offset);

auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
uint32_t Value = (ModID << 3) | (unsigned)Role;
Expand All @@ -2076,9 +2056,6 @@ namespace {

assert(Out.tell() - Start == DataLen && "Wrong data length");
}

const char *strings_begin() const { return FrameworkStringData.begin(); }
const char *strings_end() const { return FrameworkStringData.end(); }
};

} // namespace
Expand Down Expand Up @@ -2213,7 +2190,6 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
// Write the header search table
RecordData::value_type Record[] = {HEADER_SEARCH_TABLE, BucketOffset,
NumHeaderSearchEntries, TableData.size()};
TableData.append(GeneratorTrait.strings_begin(),GeneratorTrait.strings_end());
Stream.EmitRecordWithBlob(TableAbbrev, Record, TableData);

// Free all of the strings we had to duplicate.
Expand Down
2 changes: 0 additions & 2 deletions clang/unittests/Lex/HeaderSearchTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,6 @@ TEST_F(HeaderSearchTest, HeaderFrameworkLookup) {
auto FI = Search.getExistingFileInfo(FE);
EXPECT_TRUE(FI);
EXPECT_TRUE(FI->IsValid);
EXPECT_EQ(FI->Framework.str(), "Foo");
EXPECT_EQ(Search.getIncludeNameForHeader(FE), "Foo/Foo.h");
}

Expand Down Expand Up @@ -320,7 +319,6 @@ TEST_F(HeaderSearchTest, HeaderMapFrameworkLookup) {
auto FI = Search.getExistingFileInfo(FE);
EXPECT_TRUE(FI);
EXPECT_TRUE(FI->IsValid);
EXPECT_EQ(FI->Framework.str(), "Foo");
EXPECT_EQ(Search.getIncludeNameForHeader(FE), "Foo/Foo.h");
}

Expand Down
Loading