Skip to content

Commit ccd7e78

Browse files
committed
Revert "[clang][lex] Keep references to DirectoryLookup objects up-to-date"
This reverts commit 8503c68. This patch causes some issues with `#include_next`: llvm/llvm-project#53161
1 parent 01494c6 commit ccd7e78

File tree

3 files changed

+73
-150
lines changed

3 files changed

+73
-150
lines changed

clang/include/clang/Lex/HeaderSearch.h

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -171,23 +171,22 @@ class HeaderSearch {
171171
/// Header-search options used to initialize this header search.
172172
std::shared_ptr<HeaderSearchOptions> HSOpts;
173173

174+
/// Mapping from SearchDir to HeaderSearchOptions::UserEntries indices.
175+
llvm::DenseMap<unsigned, unsigned> SearchDirToHSEntry;
176+
174177
DiagnosticsEngine &Diags;
175178
FileManager &FileMgr;
176179

177-
/// The allocator owning search directories.
178-
llvm::SpecificBumpPtrAllocator<DirectoryLookup> SearchDirsAlloc;
179180
/// \#include search path information. Requests for \#include "x" search the
180181
/// directory of the \#including file first, then each directory in SearchDirs
181182
/// consecutively. Requests for <x> search the current dir first, then each
182183
/// directory in SearchDirs, starting at AngledDirIdx, consecutively. If
183184
/// NoCurDirSearch is true, then the check for the file in the current
184185
/// directory is suppressed.
185-
std::vector<DirectoryLookup *> SearchDirs;
186-
/// Set of SearchDirs that have been successfully used to lookup a file.
187-
llvm::DenseSet<const DirectoryLookup *> UsedSearchDirs;
188-
/// Mapping from SearchDir to HeaderSearchOptions::UserEntries indices.
189-
llvm::DenseMap<const DirectoryLookup *, unsigned> SearchDirToHSEntry;
190-
186+
std::vector<DirectoryLookup> SearchDirs;
187+
/// Whether the DirectoryLookup at the corresponding index in SearchDirs has
188+
/// been successfully used to lookup a file.
189+
std::vector<bool> SearchDirsUsage;
191190
unsigned AngledDirIdx = 0;
192191
unsigned SystemDirIdx = 0;
193192
bool NoCurDirSearch = false;
@@ -295,7 +294,8 @@ class HeaderSearch {
295294

296295
/// Add an additional system search path.
297296
void AddSystemSearchPath(const DirectoryLookup &dir) {
298-
SearchDirs.push_back(storeSearchDir(dir));
297+
SearchDirs.push_back(dir);
298+
SearchDirsUsage.push_back(false);
299299
}
300300

301301
/// Set the list of system header prefixes.
@@ -499,11 +499,7 @@ class HeaderSearch {
499499

500500
/// Determine which HeaderSearchOptions::UserEntries have been successfully
501501
/// used so far and mark their index with 'true' in the resulting bit vector.
502-
// TODO: Use llvm::BitVector instead.
503502
std::vector<bool> computeUserEntryUsage() const;
504-
/// Return a bit vector of length \c SearchDirs.size() that indicates for each
505-
/// search directory whether it was used.
506-
std::vector<bool> getSearchDirUsage() const;
507503

508504
/// This method returns a HeaderMap for the specified
509505
/// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
@@ -633,11 +629,6 @@ class HeaderSearch {
633629
void loadTopLevelSystemModules();
634630

635631
private:
636-
/// Stores the given search directory and returns a stable pointer.
637-
DirectoryLookup *storeSearchDir(const DirectoryLookup &Dir) {
638-
return new (SearchDirsAlloc.Allocate()) DirectoryLookup(Dir);
639-
}
640-
641632
/// Lookup a module with the given module name and search-name.
642633
///
643634
/// \param ModuleName The name of the module we're looking for.
@@ -724,9 +715,8 @@ class HeaderSearch {
724715
void cacheLookupSuccess(LookupFileCacheInfo &CacheLookup, unsigned HitIdx,
725716
SourceLocation IncludeLoc);
726717
/// Note that a lookup at the given include location was successful using the
727-
/// given search path.
728-
void noteLookupUsage(const DirectoryLookup *SearchDir,
729-
SourceLocation IncludeLoc);
718+
/// search path at index `HitIdx`.
719+
void noteLookupUsage(unsigned HitIdx, SourceLocation IncludeLoc);
730720

731721
public:
732722
/// Retrieve the module map.
@@ -749,8 +739,7 @@ class HeaderSearch {
749739
bool WantExternal = true) const;
750740

751741
// Used by external tools
752-
using search_dir_iterator =
753-
llvm::pointee_iterator<decltype(SearchDirs)::const_iterator>;
742+
using search_dir_iterator = std::vector<DirectoryLookup>::const_iterator;
754743

755744
search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); }
756745
search_dir_iterator search_dir_end() const { return SearchDirs.end(); }
@@ -778,6 +767,9 @@ class HeaderSearch {
778767

779768
search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
780769

770+
/// Get the index of the given search directory.
771+
Optional<unsigned> searchDirIdx(const DirectoryLookup &DL) const;
772+
781773
/// Retrieve a uniqued framework name.
782774
StringRef getUniqueFrameworkName(StringRef Framework);
783775

clang/lib/Lex/HeaderSearch.cpp

Lines changed: 53 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -115,34 +115,30 @@ void HeaderSearch::SetSearchPaths(
115115
llvm::DenseMap<unsigned int, unsigned int> searchDirToHSEntry) {
116116
assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
117117
"Directory indices are unordered");
118-
SearchDirsAlloc.DestroyAll();
119-
SearchDirs.clear();
120-
for (const DirectoryLookup &Dir : dirs)
121-
SearchDirs.push_back(storeSearchDir(Dir));
122-
UsedSearchDirs.clear();
123-
SearchDirToHSEntry.clear();
124-
for (const auto &Entry : searchDirToHSEntry)
125-
SearchDirToHSEntry.insert({SearchDirs[Entry.first], Entry.second});
126-
118+
SearchDirs = std::move(dirs);
119+
SearchDirsUsage.assign(SearchDirs.size(), false);
127120
AngledDirIdx = angledDirIdx;
128121
SystemDirIdx = systemDirIdx;
129122
NoCurDirSearch = noCurDirSearch;
123+
SearchDirToHSEntry = std::move(searchDirToHSEntry);
130124
//LookupFileCache.clear();
131125
}
132126

133127
void HeaderSearch::AddSearchPath(const DirectoryLookup &dir, bool isAngled) {
134128
unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx;
135-
SearchDirs.insert(SearchDirs.begin() + idx, storeSearchDir(dir));
129+
SearchDirs.insert(SearchDirs.begin() + idx, dir);
130+
SearchDirsUsage.insert(SearchDirsUsage.begin() + idx, false);
136131
if (!isAngled)
137132
AngledDirIdx++;
138133
SystemDirIdx++;
139134
}
140135

141136
std::vector<bool> HeaderSearch::computeUserEntryUsage() const {
142137
std::vector<bool> UserEntryUsage(HSOpts->UserEntries.size());
143-
for (const DirectoryLookup *SearchDir : UsedSearchDirs) {
144-
if (UsedSearchDirs.contains(SearchDir)) {
145-
auto UserEntryIdxIt = SearchDirToHSEntry.find(SearchDir);
138+
for (unsigned I = 0, E = SearchDirsUsage.size(); I < E; ++I) {
139+
// Check whether this DirectoryLookup has been successfully used.
140+
if (SearchDirsUsage[I]) {
141+
auto UserEntryIdxIt = SearchDirToHSEntry.find(I);
146142
// Check whether this DirectoryLookup maps to a HeaderSearch::UserEntry.
147143
if (UserEntryIdxIt != SearchDirToHSEntry.end())
148144
UserEntryUsage[UserEntryIdxIt->second] = true;
@@ -151,14 +147,6 @@ std::vector<bool> HeaderSearch::computeUserEntryUsage() const {
151147
return UserEntryUsage;
152148
}
153149

154-
std::vector<bool> HeaderSearch::getSearchDirUsage() const {
155-
std::vector<bool> SearchDirUsage(SearchDirs.size());
156-
for (unsigned I = 0, E = SearchDirs.size(); I < E; ++I)
157-
if (UsedSearchDirs.contains(SearchDirs[I]))
158-
SearchDirUsage[I] = true;
159-
return SearchDirUsage;
160-
}
161-
162150
/// CreateHeaderMap - This method returns a HeaderMap for the specified
163151
/// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
164152
const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) {
@@ -313,23 +301,21 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName,
313301
SourceLocation ImportLoc,
314302
bool AllowExtraModuleMapSearch) {
315303
Module *Module = nullptr;
316-
DirectoryLookup *SearchDir = nullptr;
304+
unsigned Idx;
317305

318306
// Look through the various header search paths to load any available module
319307
// maps, searching for a module map that describes this module.
320-
for (unsigned Idx = 0; Idx != SearchDirs.size(); ++Idx) {
321-
SearchDir = SearchDirs[Idx];
322-
323-
if (SearchDirs[Idx]->isFramework()) {
308+
for (Idx = 0; Idx != SearchDirs.size(); ++Idx) {
309+
if (SearchDirs[Idx].isFramework()) {
324310
// Search for or infer a module map for a framework. Here we use
325311
// SearchName rather than ModuleName, to permit finding private modules
326312
// named FooPrivate in buggy frameworks named Foo.
327313
SmallString<128> FrameworkDirName;
328-
FrameworkDirName += SearchDirs[Idx]->getFrameworkDir()->getName();
314+
FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName();
329315
llvm::sys::path::append(FrameworkDirName, SearchName + ".framework");
330316
if (auto FrameworkDir = FileMgr.getDirectory(FrameworkDirName)) {
331317
bool IsSystem
332-
= SearchDirs[Idx]->getDirCharacteristic() != SrcMgr::C_User;
318+
= SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User;
333319
Module = loadFrameworkModule(ModuleName, *FrameworkDir, IsSystem);
334320
if (Module)
335321
break;
@@ -339,12 +325,12 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName,
339325
// FIXME: Figure out how header maps and module maps will work together.
340326

341327
// Only deal with normal search directories.
342-
if (!SearchDirs[Idx]->isNormalDir())
328+
if (!SearchDirs[Idx].isNormalDir())
343329
continue;
344330

345-
bool IsSystem = SearchDirs[Idx]->isSystemHeaderDirectory();
331+
bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
346332
// Search for a module map file in this directory.
347-
if (loadModuleMapFile(SearchDirs[Idx]->getDir(), IsSystem,
333+
if (loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem,
348334
/*IsFramework*/false) == LMM_NewlyLoaded) {
349335
// We just loaded a module map file; check whether the module is
350336
// available now.
@@ -356,7 +342,7 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName,
356342
// Search for a module map in a subdirectory with the same name as the
357343
// module.
358344
SmallString<128> NestedModuleMapDirName;
359-
NestedModuleMapDirName = SearchDirs[Idx]->getDir()->getName();
345+
NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName();
360346
llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
361347
if (loadModuleMapFile(NestedModuleMapDirName, IsSystem,
362348
/*IsFramework*/false) == LMM_NewlyLoaded){
@@ -368,13 +354,13 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName,
368354

369355
// If we've already performed the exhaustive search for module maps in this
370356
// search directory, don't do it again.
371-
if (SearchDirs[Idx]->haveSearchedAllModuleMaps())
357+
if (SearchDirs[Idx].haveSearchedAllModuleMaps())
372358
continue;
373359

374360
// Load all module maps in the immediate subdirectories of this search
375361
// directory if ModuleName was from @import.
376362
if (AllowExtraModuleMapSearch)
377-
loadSubdirectoryModuleMaps(*SearchDirs[Idx]);
363+
loadSubdirectoryModuleMaps(SearchDirs[Idx]);
378364

379365
// Look again for the module.
380366
Module = ModMap.findModule(ModuleName);
@@ -383,7 +369,7 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName,
383369
}
384370

385371
if (Module)
386-
noteLookupUsage(SearchDir, ImportLoc);
372+
noteLookupUsage(Idx, ImportLoc);
387373

388374
return Module;
389375
}
@@ -509,7 +495,7 @@ Optional<FileEntryRef> DirectoryLookup::LookupFile(
509495
// The case where the target file **exists** is handled by callee of this
510496
// function as part of the regular logic that applies to include search paths.
511497
// The case where the target file **does not exist** is handled here:
512-
HS.noteLookupUsage(this, IncludeLoc);
498+
HS.noteLookupUsage(*HS.searchDirIdx(*this), IncludeLoc);
513499
return None;
514500
}
515501

@@ -717,14 +703,13 @@ Optional<FileEntryRef> DirectoryLookup::DoFrameworkLookup(
717703
void HeaderSearch::cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
718704
unsigned HitIdx, SourceLocation Loc) {
719705
CacheLookup.HitIdx = HitIdx;
720-
noteLookupUsage(SearchDirs[HitIdx], Loc);
706+
noteLookupUsage(HitIdx, Loc);
721707
}
722708

723-
void HeaderSearch::noteLookupUsage(const DirectoryLookup *SearchDir,
724-
SourceLocation Loc) {
725-
UsedSearchDirs.insert(SearchDir);
709+
void HeaderSearch::noteLookupUsage(unsigned HitIdx, SourceLocation Loc) {
710+
SearchDirsUsage[HitIdx] = true;
726711

727-
auto UserEntryIdxIt = SearchDirToHSEntry.find(SearchDir);
712+
auto UserEntryIdxIt = SearchDirToHSEntry.find(HitIdx);
728713
if (UserEntryIdxIt != SearchDirToHSEntry.end())
729714
Diags.Report(Loc, diag::remark_pp_search_path_usage)
730715
<< HSOpts->UserEntries[UserEntryIdxIt->second].Path;
@@ -978,7 +963,7 @@ Optional<FileEntryRef> HeaderSearch::LookupFile(
978963
// If this is a #include_next request, start searching after the directory the
979964
// file was found in.
980965
if (FromDir)
981-
i = std::distance(SearchDirs.begin(), llvm::find(SearchDirs, FromDir));
966+
i = FromDir-&SearchDirs[0];
982967

983968
// Cache all of the lookups performed by this method. Many headers are
984969
// multiply included, and the "pragma once" optimization prevents them from
@@ -1011,7 +996,7 @@ Optional<FileEntryRef> HeaderSearch::LookupFile(
1011996
bool InUserSpecifiedSystemFramework = false;
1012997
bool IsInHeaderMap = false;
1013998
bool IsFrameworkFoundInDir = false;
1014-
Optional<FileEntryRef> File = SearchDirs[i]->LookupFile(
999+
Optional<FileEntryRef> File = SearchDirs[i].LookupFile(
10151000
Filename, *this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
10161001
SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
10171002
IsInHeaderMap, MappedName);
@@ -1033,7 +1018,7 @@ Optional<FileEntryRef> HeaderSearch::LookupFile(
10331018
if (!File)
10341019
continue;
10351020

1036-
CurDir = SearchDirs[i];
1021+
CurDir = &SearchDirs[i];
10371022

10381023
// This file is a system header or C++ unfriendly if the dir is.
10391024
HeaderFileInfo &HFI = getFileInfo(&File->getFileEntry());
@@ -1455,6 +1440,13 @@ size_t HeaderSearch::getTotalMemory() const {
14551440
+ FrameworkMap.getAllocator().getTotalMemory();
14561441
}
14571442

1443+
Optional<unsigned> HeaderSearch::searchDirIdx(const DirectoryLookup &DL) const {
1444+
for (unsigned I = 0; I < SearchDirs.size(); ++I)
1445+
if (&SearchDirs[I] == &DL)
1446+
return I;
1447+
return None;
1448+
}
1449+
14581450
StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) {
14591451
return FrameworkNames.insert(Framework).first->first();
14601452
}
@@ -1782,11 +1774,11 @@ void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) {
17821774
if (HSOpts->ImplicitModuleMaps) {
17831775
// Load module maps for each of the header search directories.
17841776
for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1785-
bool IsSystem = SearchDirs[Idx]->isSystemHeaderDirectory();
1786-
if (SearchDirs[Idx]->isFramework()) {
1777+
bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
1778+
if (SearchDirs[Idx].isFramework()) {
17871779
std::error_code EC;
17881780
SmallString<128> DirNative;
1789-
llvm::sys::path::native(SearchDirs[Idx]->getFrameworkDir()->getName(),
1781+
llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(),
17901782
DirNative);
17911783

17921784
// Search each of the ".framework" directories to load them as modules.
@@ -1810,16 +1802,16 @@ void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) {
18101802
}
18111803

18121804
// FIXME: Deal with header maps.
1813-
if (SearchDirs[Idx]->isHeaderMap())
1805+
if (SearchDirs[Idx].isHeaderMap())
18141806
continue;
18151807

18161808
// Try to load a module map file for the search directory.
1817-
loadModuleMapFile(SearchDirs[Idx]->getDir(), IsSystem,
1809+
loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem,
18181810
/*IsFramework*/ false);
18191811

18201812
// Try to load module map files for immediate subdirectories of this
18211813
// search directory.
1822-
loadSubdirectoryModuleMaps(*SearchDirs[Idx]);
1814+
loadSubdirectoryModuleMaps(SearchDirs[Idx]);
18231815
}
18241816
}
18251817

@@ -1835,13 +1827,14 @@ void HeaderSearch::loadTopLevelSystemModules() {
18351827
// Load module maps for each of the header search directories.
18361828
for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
18371829
// We only care about normal header directories.
1838-
if (!SearchDirs[Idx]->isNormalDir())
1830+
if (!SearchDirs[Idx].isNormalDir()) {
18391831
continue;
1832+
}
18401833

18411834
// Try to load a module map file for the search directory.
1842-
loadModuleMapFile(SearchDirs[Idx]->getDir(),
1843-
SearchDirs[Idx]->isSystemHeaderDirectory(),
1844-
SearchDirs[Idx]->isFramework());
1835+
loadModuleMapFile(SearchDirs[Idx].getDir(),
1836+
SearchDirs[Idx].isSystemHeaderDirectory(),
1837+
SearchDirs[Idx].isFramework());
18451838
}
18461839
}
18471840

@@ -1939,15 +1932,15 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics(
19391932

19401933
bool BestPrefixIsFramework = false;
19411934
for (unsigned I = 0; I != SearchDirs.size(); ++I) {
1942-
if (SearchDirs[I]->isNormalDir()) {
1943-
StringRef Dir = SearchDirs[I]->getDir()->getName();
1935+
if (SearchDirs[I].isNormalDir()) {
1936+
StringRef Dir = SearchDirs[I].getDir()->getName();
19441937
if (CheckDir(Dir)) {
19451938
if (IsSystem)
19461939
*IsSystem = BestPrefixLength ? I >= SystemDirIdx : false;
19471940
BestPrefixIsFramework = false;
19481941
}
1949-
} else if (SearchDirs[I]->isFramework()) {
1950-
StringRef Dir = SearchDirs[I]->getFrameworkDir()->getName();
1942+
} else if (SearchDirs[I].isFramework()) {
1943+
StringRef Dir = SearchDirs[I].getFrameworkDir()->getName();
19511944
if (CheckDir(Dir)) {
19521945
if (IsSystem)
19531946
*IsSystem = BestPrefixLength ? I >= SystemDirIdx : false;
@@ -1968,11 +1961,11 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics(
19681961
// key from header name is user prefered name for the include file.
19691962
StringRef Filename = File.drop_front(BestPrefixLength);
19701963
for (unsigned I = 0; I != SearchDirs.size(); ++I) {
1971-
if (!SearchDirs[I]->isHeaderMap())
1964+
if (!SearchDirs[I].isHeaderMap())
19721965
continue;
19731966

19741967
StringRef SpelledFilename =
1975-
SearchDirs[I]->getHeaderMap()->reverseLookupFilename(Filename);
1968+
SearchDirs[I].getHeaderMap()->reverseLookupFilename(Filename);
19761969
if (!SpelledFilename.empty()) {
19771970
Filename = SpelledFilename;
19781971
BestPrefixIsFramework = false;

0 commit comments

Comments
 (0)