summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorKadir Cetinkaya <kadircet@google.com>2019-07-03 07:47:19 +0000
committerKadir Cetinkaya <kadircet@google.com>2019-07-03 07:47:19 +0000
commit1f6d9845d8f2e0e664b0b03488588010adf39b3f (patch)
treed6cac219b4e8686f740c72c3f0fd33fe059ba278 /clang/lib
parent09a0d3d1a256900def51534184ed8c30169cd382 (diff)
downloadbcm5719-llvm-1f6d9845d8f2e0e664b0b03488588010adf39b3f.tar.gz
bcm5719-llvm-1f6d9845d8f2e0e664b0b03488588010adf39b3f.zip
[clang][HeaderSearch] Shorten paths for includes in mainfile's directory
Summary: Currently HeaderSearch only looks at SearchDir's passed into it, but in addition to those paths headers can be relative to including file's directory. This patch makes sure that is taken into account. Reviewers: gribozavr Subscribers: jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D63295 llvm-svn: 365005
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Lex/HeaderSearch.cpp44
-rw-r--r--clang/lib/Sema/SemaLookup.cpp21
2 files changed, 42 insertions, 23 deletions
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index 3ad0e1e5e83..ca94883ebec 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -1665,28 +1665,25 @@ void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
SearchDir.setSearchedAllModuleMaps(true);
}
-std::string HeaderSearch::suggestPathToFileForDiagnostics(const FileEntry *File,
- bool *IsSystem) {
+std::string HeaderSearch::suggestPathToFileForDiagnostics(
+ const FileEntry *File, llvm::StringRef MainFile, bool *IsSystem) {
// FIXME: We assume that the path name currently cached in the FileEntry is
// the most appropriate one for this analysis (and that it's spelled the
// same way as the corresponding header search path).
- return suggestPathToFileForDiagnostics(File->getName(), /*BuildDir=*/"",
- IsSystem);
+ return suggestPathToFileForDiagnostics(File->getName(), /*WorkingDir=*/"",
+ MainFile, IsSystem);
}
std::string HeaderSearch::suggestPathToFileForDiagnostics(
- llvm::StringRef File, llvm::StringRef WorkingDir, bool *IsSystem) {
+ llvm::StringRef File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
+ bool *IsSystem) {
using namespace llvm::sys;
unsigned BestPrefixLength = 0;
- unsigned BestSearchDir;
-
- for (unsigned I = 0; I != SearchDirs.size(); ++I) {
- // FIXME: Support this search within frameworks and header maps.
- if (!SearchDirs[I].isNormalDir())
- continue;
-
- StringRef Dir = SearchDirs[I].getDir()->getName();
+ // Checks whether Dir and File shares a common prefix, if they do and that's
+ // the longest prefix we've seen so for it returns true and updates the
+ // BestPrefixLength accordingly.
+ auto CheckDir = [&](llvm::StringRef Dir) -> bool {
llvm::SmallString<32> DirPath(Dir.begin(), Dir.end());
if (!WorkingDir.empty() && !path::is_absolute(Dir))
fs::make_absolute(WorkingDir, DirPath);
@@ -1710,7 +1707,7 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics(
unsigned PrefixLength = NI - path::begin(File);
if (PrefixLength > BestPrefixLength) {
BestPrefixLength = PrefixLength;
- BestSearchDir = I;
+ return true;
}
break;
}
@@ -1723,9 +1720,24 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics(
if (*NI != *DI)
break;
}
+ return false;
+ };
+
+ for (unsigned I = 0; I != SearchDirs.size(); ++I) {
+ // FIXME: Support this search within frameworks and header maps.
+ if (!SearchDirs[I].isNormalDir())
+ continue;
+
+ StringRef Dir = SearchDirs[I].getDir()->getName();
+ if (CheckDir(Dir) && IsSystem)
+ *IsSystem = BestPrefixLength ? I >= SystemDirIdx : false;
}
- if (IsSystem)
- *IsSystem = BestPrefixLength ? BestSearchDir >= SystemDirIdx : false;
+ // Try to shorten include path using TUs directory, if we couldn't find any
+ // suitable prefix in include search paths.
+ if (!BestPrefixLength && CheckDir(path::parent_path(MainFile)) && IsSystem)
+ *IsSystem = false;
+
+
return path::convert_to_slash(File.drop_front(BestPrefixLength));
}
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 086f90f5e93..c50592c4ff8 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -21,6 +21,7 @@
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/Basic/Builtins.h"
+#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/ModuleLoader.h"
@@ -5195,10 +5196,11 @@ void Sema::diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl,
/// Get a "quoted.h" or <angled.h> include path to use in a diagnostic
/// suggesting the addition of a #include of the specified file.
static std::string getIncludeStringForHeader(Preprocessor &PP,
- const FileEntry *E) {
- bool IsSystem;
- auto Path =
- PP.getHeaderSearchInfo().suggestPathToFileForDiagnostics(E, &IsSystem);
+ const FileEntry *E,
+ llvm::StringRef IncludingFile) {
+ bool IsSystem = false;
+ auto Path = PP.getHeaderSearchInfo().suggestPathToFileForDiagnostics(
+ E, IncludingFile, &IsSystem);
return (IsSystem ? '<' : '"') + Path + (IsSystem ? '>' : '"');
}
@@ -5240,6 +5242,11 @@ void Sema::diagnoseMissingImport(SourceLocation UseLoc, NamedDecl *Decl,
UniqueModules.push_back(M);
}
+ llvm::StringRef IncludingFile;
+ if (const FileEntry *FE =
+ SourceMgr.getFileEntryForID(SourceMgr.getFileID(UseLoc)))
+ IncludingFile = FE->tryGetRealPathName();
+
if (UniqueModules.empty()) {
// All candidates were global module fragments. Try to suggest a #include.
const FileEntry *E =
@@ -5248,7 +5255,7 @@ void Sema::diagnoseMissingImport(SourceLocation UseLoc, NamedDecl *Decl,
// a FixItHint there.
Diag(UseLoc, diag::err_module_unimported_use_global_module_fragment)
<< (int)MIK << Decl << !!E
- << (E ? getIncludeStringForHeader(PP, E) : "");
+ << (E ? getIncludeStringForHeader(PP, E, IncludingFile) : "");
// Produce a "previous" note if it will point to a header rather than some
// random global module fragment.
// FIXME: Suppress the note backtrace even under
@@ -5284,8 +5291,8 @@ void Sema::diagnoseMissingImport(SourceLocation UseLoc, NamedDecl *Decl,
// FIXME: Find a smart place to suggest inserting a #include, and add
// a FixItHint there.
Diag(UseLoc, diag::err_module_unimported_use_header)
- << (int)MIK << Decl << Modules[0]->getFullModuleName()
- << getIncludeStringForHeader(PP, E);
+ << (int)MIK << Decl << Modules[0]->getFullModuleName()
+ << getIncludeStringForHeader(PP, E, IncludingFile);
} else {
// FIXME: Add a FixItHint that imports the corresponding module.
Diag(UseLoc, diag::err_module_unimported_use)
OpenPOWER on IntegriCloud