forked from OSchip/llvm-project
[clang] Track how headers get included generally during lookup time
tapi & clang-extractapi both attempt to construct then check against how a header was included to determine api information when working against multiple search paths, headermap, and vfsoverlay mechanisms. Validating this against what the preprocessor sees during lookup time makes this check more reliable. Reviewed By: zixuw, jansvoboda11 Differential Revision: https://reviews.llvm.org/D124638
This commit is contained in:
parent
94d36fdbd7
commit
b6c67c3c67
|
@ -20,6 +20,7 @@
|
|||
#include "clang/Lex/ModuleMap.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/StringSet.h"
|
||||
|
@ -314,6 +315,9 @@ class HeaderSearch {
|
|||
/// whether they were valid or not.
|
||||
llvm::DenseMap<const FileEntry *, bool> LoadedModuleMaps;
|
||||
|
||||
// A map of discovered headers with their associated include file name.
|
||||
llvm::DenseMap<const FileEntry *, llvm::SmallString<64>> IncludeNames;
|
||||
|
||||
/// Uniqued set of framework names, which is used to track which
|
||||
/// headers were included as framework headers.
|
||||
llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
|
||||
|
@ -823,6 +827,13 @@ public:
|
|||
/// Retrieve a uniqued framework name.
|
||||
StringRef getUniqueFrameworkName(StringRef Framework);
|
||||
|
||||
/// Retrieve the include name for the header.
|
||||
///
|
||||
/// \param File The entry for a given header.
|
||||
/// \returns The name of how the file was included when the header's location
|
||||
/// was resolved.
|
||||
StringRef getIncludeNameForHeader(const FileEntry *File) const;
|
||||
|
||||
/// Suggest a path by which the specified file could be found, for use in
|
||||
/// diagnostics to suggest a #include. Returned path will only contain forward
|
||||
/// slashes as separators. MainFile is the absolute path of the file that we
|
||||
|
|
|
@ -1030,8 +1030,11 @@ Optional<FileEntryRef> HeaderSearch::LookupFile(
|
|||
|
||||
CurDir = It;
|
||||
|
||||
const auto FE = &File->getFileEntry();
|
||||
IncludeNames[FE] = Filename;
|
||||
|
||||
// This file is a system header or C++ unfriendly if the dir is.
|
||||
HeaderFileInfo &HFI = getFileInfo(&File->getFileEntry());
|
||||
HeaderFileInfo &HFI = getFileInfo(FE);
|
||||
HFI.DirInfo = CurDir->getDirCharacteristic();
|
||||
|
||||
// If the directory characteristic is User but this framework was
|
||||
|
@ -1460,6 +1463,13 @@ StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) {
|
|||
return FrameworkNames.insert(Framework).first->first();
|
||||
}
|
||||
|
||||
StringRef HeaderSearch::getIncludeNameForHeader(const FileEntry *File) const {
|
||||
auto It = IncludeNames.find(File);
|
||||
if (It == IncludeNames.end())
|
||||
return {};
|
||||
return It->second;
|
||||
}
|
||||
|
||||
bool HeaderSearch::hasModuleMap(StringRef FileName,
|
||||
const DirectoryEntry *Root,
|
||||
bool IsSystem) {
|
||||
|
|
|
@ -207,6 +207,7 @@ TEST_F(HeaderSearchTest, HeaderFrameworkLookup) {
|
|||
EXPECT_TRUE(FI);
|
||||
EXPECT_TRUE(FI->IsValid);
|
||||
EXPECT_EQ(FI->Framework.str(), "Foo");
|
||||
EXPECT_EQ(Search.getIncludeNameForHeader(FE), "Foo/Foo.h");
|
||||
}
|
||||
|
||||
// Helper struct with null terminator character to make MemoryBuffer happy.
|
||||
|
@ -275,6 +276,7 @@ TEST_F(HeaderSearchTest, HeaderMapFrameworkLookup) {
|
|||
EXPECT_TRUE(FI);
|
||||
EXPECT_TRUE(FI->IsValid);
|
||||
EXPECT_EQ(FI->Framework.str(), "Foo");
|
||||
EXPECT_EQ(Search.getIncludeNameForHeader(FE), "Foo/Foo.h");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
Loading…
Reference in New Issue