Kaydet (Commit) 1e313e75 authored tarafından Luboš Luňák's avatar Luboš Luňák

compiler check to compare SAL_WARN/LOG areas against sal/inc/sal/log-areas.dox

Some of the areas are guesses I've added after seeing them, whoever feels reponsible
for whichever part of the code feel free to adjust them.

Change-Id: I2192de84d51cc2bc7c28fa84019d38b465985d15
üst e3418e9a
......@@ -11,6 +11,7 @@
# The list of source files.
CLANGSRC=compileplugin.cxx \
bodynotinblock.cxx \
sallogareas.cxx \
unusedvariablecheck.cxx \
......@@ -52,7 +53,7 @@ CLANGOBJS=
define clangbuildsrc
$(3): $(2) $(SRCDIR)/compilerplugins/Makefile-clang.mk $(CLANGOUTDIR)/clang-timestamp
@echo [build CXX] $(subst $(SRCDIR)/,,$(2))
$(CXX) $(CLANGCXXFLAGS) $(CLANGDEFS) $(CLANGINCLUDES) $(2) -fPIC -c -o $(3) -MMD -MT $(3) -MP -MF $(CLANGOUTDIR)/$(1).d
$(CXX) $(CLANGCXXFLAGS) $(CLANGDEFS) $(CLANGINCLUDES) -DSRCDIR=$(SRCDIR) $(2) -fPIC -c -o $(3) -MMD -MT $(3) -MP -MF $(CLANGOUTDIR)/$(1).d
-include $(CLANGOUTDIR)/$(1).d
......
......@@ -18,6 +18,7 @@
#include <clang/Rewrite/Rewriter.h>
#include "bodynotinblock.hxx"
#include "sallogareas.hxx"
#include "unusedvariablecheck.hxx"
using namespace clang;
......@@ -40,7 +41,10 @@ DiagnosticBuilder Plugin::report( DiagnosticsEngine::Level level, StringRef mess
if( level == DiagnosticsEngine::Error && diag.getErrorsAsFatal())
level = DiagnosticsEngine::Fatal;
#endif
return diag.Report( loc, diag.getCustomDiagID( level, message ));
if( loc.isValid())
return diag.Report( loc, diag.getCustomDiagID( level, message ));
else
return diag.Report( diag.getCustomDiagID( level, message ));
}
bool Plugin::ignoreLocation( SourceLocation loc )
......@@ -58,6 +62,7 @@ class PluginHandler
explicit PluginHandler( ASTContext& context )
: rewriter( context.getSourceManager(), context.getLangOpts())
, bodyNotInBlock( context )
, salLogAreas( context )
, unusedVariableCheck( context )
{
}
......@@ -66,6 +71,7 @@ class PluginHandler
if( context.getDiagnostics().hasErrorOccurred())
return;
bodyNotInBlock.run();
salLogAreas.run();
unusedVariableCheck.run();
// TODO also LO header files? or a subdir?
if( const RewriteBuffer* buf = rewriter.getRewriteBufferFor( context.getSourceManager().getMainFileID()))
......@@ -75,6 +81,7 @@ class PluginHandler
private:
Rewriter rewriter;
BodyNotInBlock bodyNotInBlock;
SalLogAreas salLogAreas;
UnusedVariableCheck unusedVariableCheck;
};
......
......@@ -23,7 +23,7 @@ class Plugin
public:
explicit Plugin( ASTContext& context );
protected:
DiagnosticBuilder report( DiagnosticsEngine::Level level, StringRef message, SourceLocation loc );
DiagnosticBuilder report( DiagnosticsEngine::Level level, StringRef message, SourceLocation loc = SourceLocation());
bool ignoreLocation( SourceLocation loc );
bool ignoreLocation( const Decl* decl );
bool ignoreLocation( const Stmt* stmt );
......
/*
* This file is part of the LibreOffice project.
*
* Based on LLVM/Clang.
*
* This file is distributed under the University of Illinois Open Source
* License. See LICENSE.TXT for details.
*
*/
#include "sallogareas.hxx"
#include <clang/Basic/SourceManager.h>
#include <fstream>
using namespace std;
namespace loplugin
{
/*
Check that areas used in SAL_LOG/SAL_WARN are listed in sal/inc/sal/log-areas.dox .
*/
SalLogAreas::SalLogAreas( ASTContext& context )
: Plugin( context )
{
}
void SalLogAreas::run()
{
inFunction = NULL;
TraverseDecl( context.getTranslationUnitDecl());
}
bool SalLogAreas::VisitFunctionDecl( FunctionDecl* function )
{
inFunction = function;
return true;
}
bool SalLogAreas::VisitCallExpr( CallExpr* call )
{
if( ignoreLocation( call ))
return true;
if( FunctionDecl* func = call->getDirectCallee())
{
// Optimize, getQualifiedNameAsString() is reportedly expensive.
if( func->getNumParams() == 4 && func->getIdentifier() != NULL
&& ( func->getName() == "sal_detail_log" || func->getName() == "log" ))
{
std::string qualifiedName = func->getQualifiedNameAsString();
if( qualifiedName == "sal_detail_log" || qualifiedName == "sal::detail::log" )
{
if( const StringLiteral* area = dyn_cast< StringLiteral >( call->getArg( 1 )->IgnoreParenImpCasts()))
{
if( area->getKind() == StringLiteral::Ascii )
checkArea( area->getBytes(), area->getExprLoc());
else
report( DiagnosticsEngine::Warning, "unsupported string literal kind (plugin needs fixing?) [loplugin] sallog",
area->getLocStart());
return true;
}
if( inFunction->getQualifiedNameAsString() == "sal::detail::log" )
return true; // This function only forwards to sal_detail_log, so ok.
report( DiagnosticsEngine::Warning, "cannot analyse log area argument (plugin needs fixing?) [loplugin] sallog",
call->getLocStart());
}
}
}
return true;
}
void SalLogAreas::checkArea( StringRef area, SourceLocation location )
{
if( logAreas.empty())
readLogAreas();
if( !logAreas.count( area ))
{
report( DiagnosticsEngine::Warning, "unknown log area '%0' (check or extend sal/inc/sal/log-areas.dox) [loplugin] sallog",
location ) << area;
}
}
void SalLogAreas::readLogAreas()
{
#define STRINGIFY2( s ) #s
#define STRINGIFY( s ) STRINGIFY2( s )
ifstream is( STRINGIFY( SRCDIR ) "/sal/inc/sal/log-areas.dox" );
#undef STRINGIFY
#undef STRINGIFY2
while( is.good())
{
string line;
getline( is, line );
size_t pos = line.find( "@li @c " );
if( pos != string::npos )
{
pos += strlen( "@li @c " );
size_t end = line.find( ' ', pos );
if( end == string::npos )
logAreas.insert( line.substr( pos ));
else if( pos != end )
logAreas.insert( line.substr( pos, end - pos ));
}
}
// If you get this error message, you possibly have too old icecream (ICECC_EXTRAFILES is needed).
if( logAreas.empty())
report( DiagnosticsEngine::Warning, "error reading log areas [loplugin] sallog" );
}
} // namespace
/*
* This file is part of the LibreOffice project.
*
* Based on LLVM/Clang.
*
* This file is distributed under the University of Illinois Open Source
* License. See LICENSE.TXT for details.
*
*/
#ifndef SALLOGAREAS_H
#define SALLOGAREAS_H
#include <set>
#include "compileplugin.hxx"
namespace loplugin
{
class SalLogAreas
: public RecursiveASTVisitor< SalLogAreas >
, public Plugin
{
public:
explicit SalLogAreas( ASTContext& context );
void run();
bool VisitFunctionDecl( FunctionDecl* function );
bool VisitCallExpr( CallExpr* call );
private:
void checkArea( StringRef area, SourceLocation location );
void readLogAreas();
const FunctionDecl* inFunction;
std::set< std::string > logAreas;
};
} // namespace
#endif // SALLOGAREAS_H
......@@ -38,13 +38,10 @@ void UnusedVariableCheck::run()
TraverseDecl( context.getTranslationUnitDecl());
}
bool UnusedVariableCheck::VisitNamedDecl( NamedDecl* declaration )
bool UnusedVariableCheck::VisitVarDecl( VarDecl* var )
{
if( ignoreLocation( declaration ))
if( ignoreLocation( var ))
return true;
if( !isa< VarDecl >( declaration ))
return true;
const VarDecl* var = cast< VarDecl >( declaration );
if( var->isReferenced() || var->isUsed())
return true;
if( var->isDefinedOutsideFunctionOrMethod())
......
......@@ -23,7 +23,7 @@ class UnusedVariableCheck
public:
explicit UnusedVariableCheck( ASTContext& context );
void run();
bool VisitNamedDecl( NamedDecl* declaration );
bool VisitVarDecl( VarDecl* var );
};
} // namespace
......
// NOTE: This file is also parsed by a compiler plugin. Make sure all
// areas are marked with '@li @c'.
/**
@page sal_log_areas SAL debug areas
......@@ -22,21 +25,126 @@ certain functionality.
@li @c sal.rtl - SAL RTL library
@li @c sal.textenc - the textencoding SAL library
@section basctl
@li @c basctl.basicide
@section canvas
@li @c canvas
@li @c canvas.cairo
@section connectivity
@li @c connectivity.mork
@section cui
@li @c cui.customize
@li @c cui.dialogs
@li @c cui.factory
@li @c cui.options
@li @c cui.tabpages
@section Calc
@li @c sc.core
@li @c sc.ui - Calc UI
@section desktop
@li @c desktop
@li @c desktop.deployment
@section Draw
@li @c sd.fwk
@li @c sd.sls
@li @c sd.tools
@li @c sd.view
@li @c sdremote
@li @c sdremote.bluetooth
@section editeng
@li @c editeng
@li @c editeng.items
@section extensions
@li @c extensions.scanner
@section Filter
@li @c filter.ms - escher import/export
@li @c oox.xmlstream - XmlStream class
@section formula
@li @c formula.core
@section fpicker
@li @c fpicker.office
@section i18npool
@li @c i18npool.langtag
@section Math
@li @c starmath.rtf
@li @c starmath.ooxml - OOXML import/export
@li @c starmath.wordbase
@section sdext
@li @c sdext.pdfimport
@li @c sdext.presenter
@section sfx2
@li @c sfx2.appl
@li @c sfx2.bastyp
@li @c sfx2.config
@li @c sfx2.dialog
@li @c sfx2.doc
@li @c sfx2.notify
@li @c sfx2.view
@section slideshow
@li @c slideshow.opengl
@section svtools
@li @c svtools.config
@li @c svtools.contnr
@li @c svtools.control
@li @c svtools.dialogs
@li @c svtools.filter
@li @c svtools.misc
@li @c svtools.uno
@section svx
@li @c svx.dialog
@li @c svx.form
@section tools
@li @c tools.debug
@li @c tools.stream - SvStream class
@section ucb
@li @c cmisucp
@li @c ucb.ucp
@section unotools
@li @c unotools.config
@li @c unotools.i18n
@section URE
......@@ -46,9 +154,11 @@ certain functionality.
@section VCL
@li @c vcl.control
@li @c vcl.gdi - the GDI part of VCL, devices, bitmaps, etc.
@li @c vcl.gtk - Gtk+ 2/3 plugin
@li @c vcl.layout - Widget layout
@li @c vcl.sm
@section Writer
......@@ -58,5 +168,37 @@ certain functionality.
@li @c sw.uno - Writer UNO interfaces
@li @c sw.ww8 - .doc/.docx export filter, .doc import filter (not writerfilter)
@section xmloff
@li @c xmloff.core
@li @c xmloff.forms
@li @c xmloff.chart
@li @c xmloff.style
@section other
@li @c accessibility
@li @c avmedia
@li @c basebmp
@li @c basic
@li @c binaryurp
@li @c bridges
@li @c comphelper
@li @c configmgr
@li @c cppcanvas
@li @c cppuhelper
@li @c cppu
@li @c editeng
@li @c helpcompiler
@li @c linguistic
@li @c oox
@li @c rsc
@li @c shell
@li @c stoc
@li @c ucbhelper
@li @c writerfilter
@li @c xmlhelp
@li @c xmlreader
*/
/* vim:set ft=cpp shiftwidth=4 softtabstop=4 expandtab: */
......@@ -55,6 +55,7 @@ define gb_CObject__command
$(call gb_Output_announce,$(2).c,$(true),C ,3)
$(call gb_Helper_abbreviate_dirs,\
mkdir -p $(dir $(1)) $(dir $(4)) && cd $(SRCDIR) && \
$(if $(COMPILER_PLUGINS),$(gb_COMPILER_PLUGINS_SETUP)) \
$(gb_CC) \
$(DEFS) \
$(if $(filter Library,$(TARGETTYPE)),$(gb_Library_LTOFLAGS)) \
......@@ -78,6 +79,7 @@ define gb_CxxObject__command
$(call gb_Output_announce,$(2).cxx,$(true),CXX,3)
$(call gb_Helper_abbreviate_dirs,\
mkdir -p $(dir $(1)) $(dir $(4)) && cd $(SRCDIR) && \
$(if $(COMPILER_PLUGINS),$(gb_COMPILER_PLUGINS_SETUP)) \
$(gb_CXX) \
$(DEFS) \
$(if $(filter Library,$(TARGETTYPE)),$(gb_Library_LTOFLAGS)) \
......
......@@ -155,8 +155,10 @@ gb_LinkTarget_INCLUDE_STL := $(filter %/stl, $(subst -I. , ,$(SOLARINC)))
ifeq ($(COM_GCC_IS_CLANG),TRUE)
gb_COMPILER_PLUGINS :=-Xclang -load -Xclang $(SRCDIR)/compilerplugins/obj/compileplugin.so -Xclang -add-plugin -Xclang loplugin
gb_COMPILER_PLUGINS_SETUP := ICECC_EXTRAFILES=$(SRCDIR)/sal/inc/sal/log-areas.dox
else
gb_COMPILER_PLUGINS :=
gb_COMPILER_PLUGINS_SETUP :=
endif
# Executable class
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment