aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Lex
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Lex')
-rw-r--r--clang/lib/Lex/HeaderMap.cpp29
-rw-r--r--clang/lib/Lex/HeaderSearch.cpp17
2 files changed, 44 insertions, 2 deletions
diff --git a/clang/lib/Lex/HeaderMap.cpp b/clang/lib/Lex/HeaderMap.cpp
index d44ef29c..4b60cfa 100644
--- a/clang/lib/Lex/HeaderMap.cpp
+++ b/clang/lib/Lex/HeaderMap.cpp
@@ -240,3 +240,32 @@ StringRef HeaderMapImpl::lookupFilename(StringRef Filename,
return StringRef(DestPath.begin(), DestPath.size());
}
}
+
+StringRef HeaderMapImpl::reverseLookupFilename(StringRef DestPath) const {
+ if (!ReverseMap.empty())
+ return ReverseMap.lookup(DestPath);
+
+ const HMapHeader &Hdr = getHeader();
+ unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);
+ StringRef RetKey;
+ for (unsigned i = 0; i != NumBuckets; ++i) {
+ HMapBucket B = getBucket(i);
+ if (B.Key == HMAP_EmptyBucketKey)
+ continue;
+
+ Optional<StringRef> Key = getString(B.Key);
+ Optional<StringRef> Prefix = getString(B.Prefix);
+ Optional<StringRef> Suffix = getString(B.Suffix);
+ if (LLVM_LIKELY(Key && Prefix && Suffix)) {
+ SmallVector<char, 1024> Buf;
+ Buf.append(Prefix->begin(), Prefix->end());
+ Buf.append(Suffix->begin(), Suffix->end());
+ StringRef Value(Buf.begin(), Buf.size());
+ ReverseMap[Value] = *Key;
+
+ if (DestPath == Value)
+ RetKey = *Key;
+ }
+ }
+ return RetKey;
+}
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index 99c92e9..9970c3c 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -1834,7 +1834,7 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics(
};
for (unsigned I = 0; I != SearchDirs.size(); ++I) {
- // FIXME: Support this search within frameworks and header maps.
+ // FIXME: Support this search within frameworks.
if (!SearchDirs[I].isNormalDir())
continue;
@@ -1848,6 +1848,19 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics(
if (!BestPrefixLength && CheckDir(path::parent_path(MainFile)) && IsSystem)
*IsSystem = false;
+ // Try resolving resulting filename via reverse search in header maps,
+ // key from header name is user prefered name for the include file.
+ StringRef Filename = File.drop_front(BestPrefixLength);
+ for (unsigned I = 0; I != SearchDirs.size(); ++I) {
+ if (!SearchDirs[I].isHeaderMap())
+ continue;
- return path::convert_to_slash(File.drop_front(BestPrefixLength));
+ StringRef SpelledFilename =
+ SearchDirs[I].getHeaderMap()->reverseLookupFilename(Filename);
+ if (!SpelledFilename.empty()) {
+ Filename = SpelledFilename;
+ break;
+ }
+ }
+ return path::convert_to_slash(Filename);
}