summaryrefslogtreecommitdiffstats
path: root/clang/lib/Lex
diff options
context:
space:
mode:
authorIsmail Pazarbasi <ismail.pazarbasi@gmail.com>2013-10-12 23:17:37 +0000
committerIsmail Pazarbasi <ismail.pazarbasi@gmail.com>2013-10-12 23:17:37 +0000
commit8d0f2f3ae3bc24a7847ce0984612653e60dcfb09 (patch)
tree4003a5400c97b102d0c78c350fc8c7cd2e0f7f0c /clang/lib/Lex
parent96bb15f464cfe957bdf816c76de3059eefc5d572 (diff)
downloadbcm5719-llvm-8d0f2f3ae3bc24a7847ce0984612653e60dcfb09.tar.gz
bcm5719-llvm-8d0f2f3ae3bc24a7847ce0984612653e60dcfb09.zip
Relax header guard mismatch warning with edit distance heuristic.
If the edit distance between the two macros is more than 50%, DefinedMacro may not be header guard or can be header guard of another header file or it might be defining something completely different set by the build environment. llvm-svn: 192547
Diffstat (limited to 'clang/lib/Lex')
-rw-r--r--clang/lib/Lex/PPLexerChange.cpp39
1 files changed, 26 insertions, 13 deletions
diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp
index 1193c3ce4ec..1f970a4450d 100644
--- a/clang/lib/Lex/PPLexerChange.cpp
+++ b/clang/lib/Lex/PPLexerChange.cpp
@@ -264,19 +264,32 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
if (!ControllingMacro->hasMacroDefinition() &&
DefinedMacro != ControllingMacro &&
HeaderInfo.FirstTimeLexingFile(FE)) {
- // Emit a warning for a bad header guard.
- Diag(CurPPLexer->MIOpt.GetMacroLocation(),
- diag::warn_header_guard)
- << CurPPLexer->MIOpt.GetMacroLocation()
- << ControllingMacro;
- Diag(CurPPLexer->MIOpt.GetDefinedLocation(),
- diag::note_header_guard)
- << CurPPLexer->MIOpt.GetDefinedLocation()
- << DefinedMacro
- << ControllingMacro
- << FixItHint::CreateReplacement(
- CurPPLexer->MIOpt.GetDefinedLocation(),
- ControllingMacro->getName());
+
+ // If the edit distance between the two macros is more than 50%,
+ // DefinedMacro may not be header guard, or can be header guard of
+ // another header file. Therefore, it maybe defining something
+ // completely different. This can be observed in the wild when
+ // handling feature macros or header guards in different files.
+
+ const StringRef ControllingMacroName = ControllingMacro->getName();
+ const StringRef DefinedMacroName = DefinedMacro->getName();
+ const size_t MaxHalfLength = std::max(ControllingMacroName.size(),
+ DefinedMacroName.size()) / 2;
+ const unsigned ED = ControllingMacroName.edit_distance(
+ DefinedMacroName, true, MaxHalfLength);
+ if (ED <= MaxHalfLength) {
+ // Emit a warning for a bad header guard.
+ Diag(CurPPLexer->MIOpt.GetMacroLocation(),
+ diag::warn_header_guard)
+ << CurPPLexer->MIOpt.GetMacroLocation() << ControllingMacro;
+ Diag(CurPPLexer->MIOpt.GetDefinedLocation(),
+ diag::note_header_guard)
+ << CurPPLexer->MIOpt.GetDefinedLocation() << DefinedMacro
+ << ControllingMacro
+ << FixItHint::CreateReplacement(
+ CurPPLexer->MIOpt.GetDefinedLocation(),
+ ControllingMacro->getName());
+ }
}
}
}
OpenPOWER on IntegriCloud