summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorBen Boeckel <ben.boeckel@kitware.com>2010-08-24 16:50:15 -0400
committerBen Boeckel <ben.boeckel@kitware.com>2010-09-01 13:08:14 -0400
commite141bc950a1970c6bc96fa5f55fd60c6aedbb2d0 (patch)
tree0b6b9931c33a5de02a82f444925bfeabe9700160 /Source
parentd3e8eb504137dde90a73f1b46f97f889af46db18 (diff)
downloadcmake-e141bc950a1970c6bc96fa5f55fd60c6aedbb2d0.tar.gz
Detect unused variables
Diffstat (limited to 'Source')
-rw-r--r--Source/cmMakefile.cxx65
-rw-r--r--Source/cmMakefile.h6
2 files changed, 69 insertions, 2 deletions
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index d89168df07..e4973cb5bf 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -44,6 +44,7 @@ class cmMakefile::Internals
public:
std::stack<cmDefinitions, std::list<cmDefinitions> > VarStack;
std::stack<std::set<cmStdString> > VarInitStack;
+ std::stack<std::set<cmStdString> > VarUsageStack;
std::set<cmStdString> VarRemoved;
};
@@ -91,6 +92,8 @@ cmMakefile::cmMakefile(): Internal(new Internals)
this->AddDefaultDefinitions();
this->Initialize();
this->PreOrder = false;
+ this->FindUnused = false;
+ this->DefaultToUsed = false;
}
cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals)
@@ -133,6 +136,8 @@ cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals)
this->SubDirectoryOrder = mf.SubDirectoryOrder;
this->Properties = mf.Properties;
this->PreOrder = mf.PreOrder;
+ this->FindUnused = mf.FindUnused;
+ this->DefaultToUsed = mf.DefaultToUsed;
this->ListFileStack = mf.ListFileStack;
this->Initialize();
}
@@ -757,6 +762,21 @@ void cmMakefile::SetLocalGenerator(cmLocalGenerator* lg)
this->AddSourceGroup("Resources", "\\.plist$");
#endif
+ if (this->Internal->VarUsageStack.empty())
+ {
+ const cmDefinitions& defs = cmDefinitions();
+ const std::set<cmStdString> globalKeys = defs.LocalKeys();
+ this->FindUnused = this->GetCMakeInstance()->GetFindUnused();
+ this->DefaultToUsed = this->GetCMakeInstance()->GetDefaultToUsed();
+ if (this->FindUnused)
+ {
+ this->Internal->VarUsageStack.push(globalKeys);
+ }
+ else
+ {
+ this->Internal->VarUsageStack.push(std::set<cmStdString>());
+ }
+ }
}
bool cmMakefile::NeedBackwardsCompatibility(unsigned int major,
@@ -1690,6 +1710,10 @@ void cmMakefile::AddDefinition(const char* name, bool value)
{
this->Internal->VarStack.top().Set(name, value? "ON" : "OFF");
this->Internal->VarInitStack.top().insert(name);
+ if (this->FindUnused && this->DefaultToUsed)
+ {
+ this->Internal->VarUsageStack.top().insert(name);
+ }
#ifdef CMAKE_BUILD_WITH_CMAKE
cmVariableWatch* vv = this->GetVariableWatch();
if ( vv )
@@ -1709,6 +1733,15 @@ bool cmMakefile::VariableInitialized(const char* var) const
return false;
}
+bool cmMakefile::VariableUsed(const char* var) const
+{
+ if(this->Internal->VarUsageStack.top().find(var) != this->Internal->VarUsageStack.top().end())
+ {
+ return true;
+ }
+ return false;
+}
+
bool cmMakefile::VariableCleared(const char* var) const
{
if(this->Internal->VarRemoved.find(var) != this->Internal->VarRemoved.end())
@@ -1723,6 +1756,10 @@ void cmMakefile::RemoveDefinition(const char* name)
this->Internal->VarStack.top().Set(name, 0);
this->Internal->VarRemoved.insert(name);
this->Internal->VarInitStack.top().insert(name);
+ if (this->FindUnused)
+ {
+ this->Internal->VarUsageStack.top().insert(name);
+ }
#ifdef CMAKE_BUILD_WITH_CMAKE
cmVariableWatch* vv = this->GetVariableWatch();
if ( vv )
@@ -2101,6 +2138,10 @@ const char* cmMakefile::GetDefinition(const char* name) const
RecordPropertyAccess(name,cmProperty::VARIABLE);
}
#endif
+ if (this->FindUnused)
+ {
+ this->Internal->VarUsageStack.top().insert(name);
+ }
const char* def = this->Internal->VarStack.top().Get(name);
if(!def)
{
@@ -3332,29 +3373,49 @@ void cmMakefile::PushScope()
{
cmDefinitions* parent = &this->Internal->VarStack.top();
const std::set<cmStdString>& init = this->Internal->VarInitStack.top();
+ const std::set<cmStdString>& usage = this->Internal->VarUsageStack.top();
this->Internal->VarStack.push(cmDefinitions(parent));
this->Internal->VarInitStack.push(init);
+ this->Internal->VarUsageStack.push(usage);
}
void cmMakefile::PopScope()
{
cmDefinitions* current = &this->Internal->VarStack.top();
std::set<cmStdString> init = this->Internal->VarInitStack.top();
+ std::set<cmStdString> usage = this->Internal->VarUsageStack.top();
const std::set<cmStdString>& locals = current->LocalKeys();
- // Remove initialization information for variables in the local scope.
+ // Remove initialization and usage information for variables in the local
+ // scope.
std::set<cmStdString>::const_iterator it = locals.begin();
for (; it != locals.end(); ++it)
{
init.erase(*it);
+ if (this->FindUnused && usage.find(*it) == usage.end())
+ {
+ cmOStringStream m;
+ m << "unused variable \'" << *it << "\'";
+ this->IssueMessage(cmake::AUTHOR_WARNING, m.str());
+ }
+ else
+ {
+ usage.erase(*it);
+ }
}
this->Internal->VarStack.pop();
this->Internal->VarInitStack.pop();
- // Push initialization up to the parent scope.
+ this->Internal->VarUsageStack.pop();
+ // Push initialization and usage up to the parent scope.
it = init.begin();
for (; it != init.end(); ++it)
{
this->Internal->VarInitStack.top().insert(*it);
}
+ it = usage.begin();
+ for (; it != usage.end(); ++it)
+ {
+ this->Internal->VarUsageStack.top().insert(*it);
+ }
}
void cmMakefile::RaiseScope(const char *var, const char *varDef)
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index cec273805b..184253a660 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -63,6 +63,8 @@ public:
/* return true if a variable has been initialized */
bool VariableInitialized(const char* ) const;
+ /* return true if a variable has been used */
+ bool VariableUsed(const char* ) const;
/* return true if a variable has been set with
set(foo )
*/
@@ -931,6 +933,10 @@ private:
// should this makefile be processed before or after processing the parent
bool PreOrder;
+ // Unused variable flags
+ bool FindUnused;
+ bool DefaultToUsed;
+
// stack of list files being read
std::deque<cmStdString> ListFileStack;