summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticLexKinds.td4
-rw-r--r--clang/lib/Lex/PPDirectives.cpp30
-rw-r--r--clang/test/Preprocessor/empty_file_to_include.h7
-rw-r--r--clang/test/Preprocessor/include-likely-typo.c3
4 files changed, 42 insertions, 2 deletions
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td
index 7e8bea7c249..085648c65d1 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -422,8 +422,10 @@ def warn_pp_hdrstop_filename_ignored : Warning<
"#pragma hdrstop filename not supported, "
"/Fp can be used to specify precompiled header filename">,
InGroup<ClangClPch>;
-def err_pp_file_not_found_not_fatal : Error<
+def err_pp_file_not_found_angled_include_not_fatal : Error<
"'%0' file not found with <angled> include; use \"quotes\" instead">;
+def err_pp_file_not_found_typo_not_fatal
+ : Error<"'%0' file not found, did you mean '%1'?">;
def err_pp_error_opening_file : Error<
"error opening file '%0': %1">, DefaultFatal;
def err_pp_empty_filename : Error<"empty filename">;
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 2bb96c1f15a..ca2b3d5d027 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -1879,12 +1879,40 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
Callbacks ? &RelativePath : nullptr, &SuggestedModule, &IsMapped);
if (File) {
SourceRange Range(FilenameTok.getLocation(), CharEnd);
- Diag(FilenameTok, diag::err_pp_file_not_found_not_fatal) <<
+ Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal) <<
Filename <<
FixItHint::CreateReplacement(Range, "\"" + Filename.str() + "\"");
}
}
+ // Check for likely typos due to leading or trailing non-isAlphanumeric
+ // characters
+ if (!File) {
+ StringRef OriginalFilename = Filename;
+ while (!isAlphanumeric(Filename.front())) {
+ Filename = Filename.drop_front();
+ }
+ while (!isAlphanumeric(Filename.back())) {
+ Filename = Filename.drop_back();
+ }
+
+ File = LookupFile(
+ FilenameLoc,
+ LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, isAngled,
+ LookupFrom, LookupFromFile, CurDir,
+ Callbacks ? &SearchPath : nullptr,
+ Callbacks ? &RelativePath : nullptr, &SuggestedModule, &IsMapped);
+ if (File) {
+ SourceRange Range(FilenameTok.getLocation(), CharEnd);
+ auto Hint = isAngled ? FixItHint::CreateReplacement(
+ Range, "<" + Filename.str() + ">")
+ : FixItHint::CreateReplacement(
+ Range, "\"" + Filename.str() + "\"");
+ Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
+ << OriginalFilename << Filename << Hint;
+ }
+ }
+
// If the file is still not found, just go with the vanilla diagnostic
if (!File)
Diag(FilenameTok, diag::err_pp_file_not_found) << Filename
diff --git a/clang/test/Preprocessor/empty_file_to_include.h b/clang/test/Preprocessor/empty_file_to_include.h
new file mode 100644
index 00000000000..48ffc751538
--- /dev/null
+++ b/clang/test/Preprocessor/empty_file_to_include.h
@@ -0,0 +1,7 @@
+
+#ifndef EMPTY_FILE_TO_INCLUDE_H
+#define EMPTY_FILE_TO_INCLUDE_H
+
+// empty file
+
+#endif
diff --git a/clang/test/Preprocessor/include-likely-typo.c b/clang/test/Preprocessor/include-likely-typo.c
new file mode 100644
index 00000000000..88942ae6f89
--- /dev/null
+++ b/clang/test/Preprocessor/include-likely-typo.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 %s -verify
+
+#include "<empty_file_to_include.h>" // expected-error {{'<empty_file_to_include.h>' file not found, did you mean 'empty_file_to_include.h'?}}
OpenPOWER on IntegriCloud