summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRichard Trieu <rtrieu@google.com>2013-06-12 21:20:57 +0000
committerRichard Trieu <rtrieu@google.com>2013-06-12 21:20:57 +0000
commit33a4b3db0de5fbba06264a46f560220b5f8f11a8 (patch)
treebe7f0fa608cba875aadb51581141eb56cff06290 /clang/lib
parent2bb2aa27bfe729aa6d60b17cfafeaa959c7ea050 (diff)
downloadbcm5719-llvm-33a4b3db0de5fbba06264a46f560220b5f8f11a8.tar.gz
bcm5719-llvm-33a4b3db0de5fbba06264a46f560220b5f8f11a8.zip
Introducing -Wheader-guard, a warning that checks header guards actually work
properly. This warning checks that the #ifndef and #define directives at the beginning of a header refer to the same macro name. Includes a fix-it hint to correct the header guard. llvm-svn: 183867
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Lex/PPDirectives.cpp18
-rw-r--r--clang/lib/Lex/PPLexerChange.cpp23
2 files changed, 36 insertions, 5 deletions
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 947011d7075..0cfdac92d23 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -626,6 +626,10 @@ void Preprocessor::HandleDirective(Token &Result) {
CurPPLexer->ParsingPreprocessorDirective = true;
if (CurLexer) CurLexer->SetKeepWhitespaceMode(false);
+ bool ImmediatelyAfterTopLevelIfndef =
+ CurPPLexer->MIOpt.getImmediatelyAfterTopLevelIfndef();
+ CurPPLexer->MIOpt.resetImmediatelyAfterTopLevelIfndef();
+
++NumDirectives;
// We are about to read a token. For the multiple-include optimization FA to
@@ -713,7 +717,7 @@ void Preprocessor::HandleDirective(Token &Result) {
// C99 6.10.3 - Macro Replacement.
case tok::pp_define:
- return HandleDefineDirective(Result);
+ return HandleDefineDirective(Result, ImmediatelyAfterTopLevelIfndef);
case tok::pp_undef:
return HandleUndefDirective(Result);
@@ -1760,7 +1764,8 @@ bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI, Token &Tok) {
/// HandleDefineDirective - Implements \#define. This consumes the entire macro
/// line then lets the caller lex the next real token.
-void Preprocessor::HandleDefineDirective(Token &DefineTok) {
+void Preprocessor::HandleDefineDirective(Token &DefineTok,
+ bool ImmediatelyAfterHeaderGuard) {
++NumDefined;
Token MacroNameTok;
@@ -1786,6 +1791,11 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) {
// marking each of the identifiers as being used as macro arguments. Also,
// check other constraints on the first token of the macro body.
if (Tok.is(tok::eod)) {
+ if (ImmediatelyAfterHeaderGuard) {
+ // Save this macro information since it may part of a header guard.
+ CurPPLexer->MIOpt.SetDefinedMacro(MacroNameTok.getIdentifierInfo(),
+ MacroNameTok.getLocation());
+ }
// If there is no body to this macro, we have no special handling here.
} else if (Tok.hasLeadingSpace()) {
// This is a normal token with leading space. Clear the leading space
@@ -2076,7 +2086,7 @@ void Preprocessor::HandleIfdefDirective(Token &Result, bool isIfndef,
// handle.
if (!ReadAnyTokensBeforeDirective && MI == 0) {
assert(isIfndef && "#ifdef shouldn't reach here");
- CurPPLexer->MIOpt.EnterTopLevelIFNDEF(MII);
+ CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.getLocation());
} else
CurPPLexer->MIOpt.EnterTopLevelConditional();
}
@@ -2122,7 +2132,7 @@ void Preprocessor::HandleIfDirective(Token &IfToken,
// directive seen, handle it for the multiple-include optimization.
if (CurPPLexer->getConditionalStackDepth() == 0) {
if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
- CurPPLexer->MIOpt.EnterTopLevelIFNDEF(IfNDefMacro);
+ CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, ConditionalBegin);
else
CurPPLexer->MIOpt.EnterTopLevelConditional();
}
diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp
index 64373362461..e521032bca3 100644
--- a/clang/lib/Lex/PPLexerChange.cpp
+++ b/clang/lib/Lex/PPLexerChange.cpp
@@ -244,8 +244,29 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
CurPPLexer->MIOpt.GetControllingMacroAtEndOfFile()) {
// Okay, this has a controlling macro, remember in HeaderFileInfo.
if (const FileEntry *FE =
- SourceMgr.getFileEntryForID(CurPPLexer->getFileID()))
+ SourceMgr.getFileEntryForID(CurPPLexer->getFileID())) {
HeaderInfo.SetFileControllingMacro(FE, ControllingMacro);
+ if (const IdentifierInfo *DefinedMacro =
+ CurPPLexer->MIOpt.GetDefinedMacro()) {
+ 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());
+ }
+ }
+ }
}
}
OpenPOWER on IntegriCloud