parent
cbd6d3e0ed
commit
13044d942d
|
@ -352,16 +352,14 @@ const FileEntry *Preprocessor::LookupFile(const std::string &Filename,
|
||||||
bool Preprocessor::isInPrimaryFile() const {
|
bool Preprocessor::isInPrimaryFile() const {
|
||||||
unsigned NumLexersFound = 0;
|
unsigned NumLexersFound = 0;
|
||||||
if (CurLexer && !CurLexer->Is_PragmaLexer)
|
if (CurLexer && !CurLexer->Is_PragmaLexer)
|
||||||
++NumLexersFound;
|
return CurLexer->isMainFile();
|
||||||
|
|
||||||
/// If there are any stacked lexers, we're in a #include.
|
// If there are any stacked lexers, we're in a #include.
|
||||||
for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i)
|
for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i)
|
||||||
if (IncludeMacroStack[i].TheLexer) {
|
if (IncludeMacroStack[i].TheLexer &&
|
||||||
if (!IncludeMacroStack[i].TheLexer->Is_PragmaLexer)
|
!IncludeMacroStack[i].TheLexer->Is_PragmaLexer)
|
||||||
if (++NumLexersFound > 1)
|
return IncludeMacroStack[i].TheLexer->isMainFile();
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
return NumLexersFound < 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getCurrentLexer - Return the current file lexer being lexed from. Note
|
/// getCurrentLexer - Return the current file lexer being lexed from. Note
|
||||||
|
@ -384,7 +382,8 @@ Lexer *Preprocessor::getCurrentFileLexer() const {
|
||||||
/// start lexing tokens from it instead of the current buffer. Return true
|
/// start lexing tokens from it instead of the current buffer. Return true
|
||||||
/// on failure.
|
/// on failure.
|
||||||
void Preprocessor::EnterSourceFile(unsigned FileID,
|
void Preprocessor::EnterSourceFile(unsigned FileID,
|
||||||
const DirectoryLookup *CurDir) {
|
const DirectoryLookup *CurDir,
|
||||||
|
bool isMainFile) {
|
||||||
assert(CurMacroExpander == 0 && "Cannot #include a file inside a macro!");
|
assert(CurMacroExpander == 0 && "Cannot #include a file inside a macro!");
|
||||||
++NumEnteredSourceFiles;
|
++NumEnteredSourceFiles;
|
||||||
|
|
||||||
|
@ -393,6 +392,7 @@ void Preprocessor::EnterSourceFile(unsigned FileID,
|
||||||
|
|
||||||
const SourceBuffer *Buffer = SourceMgr.getBuffer(FileID);
|
const SourceBuffer *Buffer = SourceMgr.getBuffer(FileID);
|
||||||
Lexer *TheLexer = new Lexer(Buffer, FileID, *this);
|
Lexer *TheLexer = new Lexer(Buffer, FileID, *this);
|
||||||
|
if (isMainFile) TheLexer->setIsMainFile();
|
||||||
EnterSourceFileWithLexer(TheLexer, CurDir);
|
EnterSourceFileWithLexer(TheLexer, CurDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,6 +490,9 @@ void Preprocessor::RegisterBuiltinMacros() {
|
||||||
void Preprocessor::HandleMacroExpandedIdentifier(LexerToken &Identifier,
|
void Preprocessor::HandleMacroExpandedIdentifier(LexerToken &Identifier,
|
||||||
MacroInfo *MI) {
|
MacroInfo *MI) {
|
||||||
++NumMacroExpanded;
|
++NumMacroExpanded;
|
||||||
|
|
||||||
|
// Notice that this macro has been used.
|
||||||
|
MI->setIsUsed(true);
|
||||||
|
|
||||||
// If this is a builtin macro, like __LINE__ or _Pragma, handle it specially.
|
// If this is a builtin macro, like __LINE__ or _Pragma, handle it specially.
|
||||||
if (MI->isBuiltinMacro())
|
if (MI->isBuiltinMacro())
|
||||||
|
@ -689,6 +692,18 @@ void Preprocessor::ExpandBuiltinMacro(LexerToken &Tok) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
struct UnusedIdentifierReporter : public IdentifierVisitor {
|
||||||
|
Preprocessor &PP;
|
||||||
|
UnusedIdentifierReporter(Preprocessor &pp) : PP(pp) {}
|
||||||
|
|
||||||
|
void VisitIdentifier(IdentifierTokenInfo &ITI) const {
|
||||||
|
if (ITI.getMacroInfo() && !ITI.getMacroInfo()->isUsed())
|
||||||
|
PP.Diag(ITI.getMacroInfo()->getDefinitionLoc(), diag::pp_macro_not_used);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Lexer Event Handling.
|
// Lexer Event Handling.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -775,6 +790,9 @@ void Preprocessor::HandleEndOfFile(LexerToken &Result, bool isEndOfMacro) {
|
||||||
// We're done with the #included file.
|
// We're done with the #included file.
|
||||||
delete CurLexer;
|
delete CurLexer;
|
||||||
CurLexer = 0;
|
CurLexer = 0;
|
||||||
|
|
||||||
|
// This is the end of the top-level file.
|
||||||
|
IdentifierInfo.VisitIdentifiers(UnusedIdentifierReporter(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// HandleEndOfMacro - This callback is invoked when the lexer hits the end of
|
/// HandleEndOfMacro - This callback is invoked when the lexer hits the end of
|
||||||
|
@ -1302,10 +1320,17 @@ void Preprocessor::HandleDefineDirective(LexerToken &DefineTok) {
|
||||||
LexUnexpandedToken(Tok);
|
LexUnexpandedToken(Tok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is the primary source file, remember that this macro hasn't been
|
||||||
|
// used yet.
|
||||||
|
if (isInPrimaryFile())
|
||||||
|
MI->setIsUsed(false);
|
||||||
|
|
||||||
// Finally, if this identifier already had a macro defined for it, verify that
|
// Finally, if this identifier already had a macro defined for it, verify that
|
||||||
// the macro bodies are identical and free the old definition.
|
// the macro bodies are identical and free the old definition.
|
||||||
if (MacroInfo *OtherMI = MacroNameTok.getIdentifierInfo()->getMacroInfo()) {
|
if (MacroInfo *OtherMI = MacroNameTok.getIdentifierInfo()->getMacroInfo()) {
|
||||||
|
if (!OtherMI->isUsed())
|
||||||
|
Diag(OtherMI->getDefinitionLoc(), diag::pp_macro_not_used);
|
||||||
|
|
||||||
// FIXME: Verify the definition is the same.
|
// FIXME: Verify the definition is the same.
|
||||||
// Macros must be identical. This means all tokes and whitespace separation
|
// Macros must be identical. This means all tokes and whitespace separation
|
||||||
// must be the same.
|
// must be the same.
|
||||||
|
@ -1336,10 +1361,8 @@ void Preprocessor::HandleUndefDirective(LexerToken &UndefTok) {
|
||||||
// If the macro is not defined, this is a noop undef, just return.
|
// If the macro is not defined, this is a noop undef, just return.
|
||||||
if (MI == 0) return;
|
if (MI == 0) return;
|
||||||
|
|
||||||
#if 0 // FIXME: implement warn_unused_macros.
|
if (!MI->isUsed())
|
||||||
if (CPP_OPTION (pfile, warn_unused_macros))
|
Diag(MI->getDefinitionLoc(), diag::pp_macro_not_used);
|
||||||
_cpp_warn_if_unused_macro (pfile, node, NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Free macro definition.
|
// Free macro definition.
|
||||||
delete MI;
|
delete MI;
|
||||||
|
|
|
@ -98,6 +98,8 @@ DIAG(pp_undef_builtin_macro, WARNING,
|
||||||
"undefining builtin macro")
|
"undefining builtin macro")
|
||||||
DIAG(pp_redef_builtin_macro, WARNING,
|
DIAG(pp_redef_builtin_macro, WARNING,
|
||||||
"redefining builtin macro")
|
"redefining builtin macro")
|
||||||
|
DIAG(pp_macro_not_used, WARNING, // -Wunused-macros
|
||||||
|
"macro is not used")
|
||||||
|
|
||||||
DIAG(ext_pp_import_directive, EXTENSION,
|
DIAG(ext_pp_import_directive, EXTENSION,
|
||||||
"#import is a language extension")
|
"#import is a language extension")
|
||||||
|
|
|
@ -33,30 +33,50 @@ class MacroInfo {
|
||||||
/// to.
|
/// to.
|
||||||
std::vector<LexerToken> ReplacementTokens;
|
std::vector<LexerToken> ReplacementTokens;
|
||||||
|
|
||||||
/// isDisabled - True if we have started an expansion of this macro already.
|
/// IsDisabled - True if we have started an expansion of this macro already.
|
||||||
/// This disbles recursive expansion, which would be quite bad for things like
|
/// This disbles recursive expansion, which would be quite bad for things like
|
||||||
/// #define A A.
|
/// #define A A.
|
||||||
bool IsDisabled : 1;
|
bool IsDisabled : 1;
|
||||||
|
|
||||||
/// isBuiltinMacro - True if this is a builtin macro, such as __LINE__, and if
|
/// IsBuiltinMacro - True if this is a builtin macro, such as __LINE__, and if
|
||||||
/// it has not yet been redefined or undefined.
|
/// it has not yet been redefined or undefined.
|
||||||
bool IsBuiltinMacro : 1;
|
bool IsBuiltinMacro : 1;
|
||||||
|
|
||||||
|
/// IsUsed - True if this macro is either defined in the main file and has
|
||||||
|
/// been used, or if it is not defined in the main file. This is used to
|
||||||
|
/// emit -Wunused-macros diagnostics.
|
||||||
|
bool IsUsed : 1;
|
||||||
public:
|
public:
|
||||||
MacroInfo(SourceLocation DefLoc) : Location(DefLoc) {
|
MacroInfo(SourceLocation DefLoc) : Location(DefLoc) {
|
||||||
IsDisabled = false;
|
IsDisabled = false;
|
||||||
IsBuiltinMacro = false;
|
IsBuiltinMacro = false;
|
||||||
|
IsUsed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getDefinitionLoc - Return the location that the macro was defined at.
|
||||||
|
///
|
||||||
|
SourceLocation getDefinitionLoc() const { return Location; }
|
||||||
|
|
||||||
/// setIsBuiltinMacro - Set or clear the isBuiltinMacro flag.
|
/// setIsBuiltinMacro - Set or clear the isBuiltinMacro flag.
|
||||||
///
|
///
|
||||||
void setIsBuiltinMacro(bool Val = true) {
|
void setIsBuiltinMacro(bool Val = true) {
|
||||||
IsBuiltinMacro = Val;
|
IsBuiltinMacro = Val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// setIsUsed - Set the value of the IsUsed flag.
|
||||||
|
///
|
||||||
|
void setIsUsed(bool Val) {
|
||||||
|
IsUsed = Val;
|
||||||
|
}
|
||||||
|
|
||||||
/// isBuiltinMacro - Return true if this macro is a builtin macro, such as
|
/// isBuiltinMacro - Return true if this macro is a builtin macro, such as
|
||||||
/// __LINE__, which requires processing before expansion.
|
/// __LINE__, which requires processing before expansion.
|
||||||
bool isBuiltinMacro() const { return IsBuiltinMacro; }
|
bool isBuiltinMacro() const { return IsBuiltinMacro; }
|
||||||
|
|
||||||
|
/// isUsed - Return false if this macro is defined in the main file and has
|
||||||
|
/// not yet been used.
|
||||||
|
bool isUsed() const { return IsUsed; }
|
||||||
|
|
||||||
/// getNumTokens - Return the number of tokens that this macro expands to.
|
/// getNumTokens - Return the number of tokens that this macro expands to.
|
||||||
///
|
///
|
||||||
unsigned getNumTokens() const {
|
unsigned getNumTokens() const {
|
||||||
|
|
|
@ -297,8 +297,10 @@ public:
|
||||||
const DirectoryLookup *&CurDir);
|
const DirectoryLookup *&CurDir);
|
||||||
|
|
||||||
/// EnterSourceFile - Add a source file to the top of the include stack and
|
/// EnterSourceFile - Add a source file to the top of the include stack and
|
||||||
/// start lexing tokens from it instead of the current buffer.
|
/// start lexing tokens from it instead of the current buffer. If isMainFile
|
||||||
void EnterSourceFile(unsigned CurFileID, const DirectoryLookup *Dir);
|
/// is true, this is the main file for the translation unit.
|
||||||
|
void EnterSourceFile(unsigned CurFileID, const DirectoryLookup *Dir,
|
||||||
|
bool isMainFile = false);
|
||||||
|
|
||||||
/// EnterMacro - Add a Macro to the top of the include stack and start lexing
|
/// EnterMacro - Add a Macro to the top of the include stack and start lexing
|
||||||
/// tokens from it instead of the current buffer.
|
/// tokens from it instead of the current buffer.
|
||||||
|
@ -440,7 +442,7 @@ private:
|
||||||
void Handle_Pragma(LexerToken &Tok);
|
void Handle_Pragma(LexerToken &Tok);
|
||||||
|
|
||||||
|
|
||||||
/// EnterSourceFile - Add a source file to the top of the include stack and
|
/// EnterSourceFileWithLexer - Add a lexer to the top of the include stack and
|
||||||
/// start lexing tokens from it instead of the current buffer.
|
/// start lexing tokens from it instead of the current buffer.
|
||||||
void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);
|
void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue