/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * 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"bodynotinblock.hxx"
namespace loplugin
{
/* This is a compile check.
Check for two statements that are both indented to look like a body of if/while/for but are not inside a compound statement and thus the second one is unrelated.
For example:
if( a != 0 ) b = 2; c = 3;
Here either both statements should be inside {} or the second statement in indented wrong.
*/
BodyNotInBlock::BodyNotInBlock( const InstantiationData& data )
: Plugin( data )
{
}
void BodyNotInBlock::checkBody( const Stmt* body, SourceLocation stmtLocation, int stmtType, bool dontGoUp )
{ if( body == NULL ) return; // TODO: If the if/else/while/for comes from a macro expansion, ignore it completely for // now. The code below could assume everything is in the same place (and thus also column) // and give a false warning. Moreover some macros are rather loosely written and would // result in poor formatting. To be evaluated later, maybe this could be handled // including macro expansion. if( stmtLocation.isMacroID()) return; if( dyn_cast< CompoundStmt >( body )) return; // if body is a compound statement, then it is in {} const Stmt* previousParent = parentStmt( body ); // Here the statement itself. // Find the next statement (in source position) after 'body'. for(;;)
{ const Stmt* parent = parentStmt( previousParent ); if( parent == NULL ) break; for( ConstStmtIterator it = parent->child_begin();
it != parent->child_end();
)
{ if( *it == previousParent ) // found grand(grand...)parent
{ // get next statement after our (grand...)parent
++it; while( it != parent->child_end() && *it == NULL )
++it; // skip empty ones (missing 'else' bodies for example) if( it != parent->child_end())
{ bool invalid1, invalid2; unsigned bodyColumn = compiler.getSourceManager()
.getPresumedColumnNumber( body->getLocStart(), &invalid1 ); unsigned nextStatementColumn = compiler.getSourceManager()
.getPresumedColumnNumber( (*it)->getLocStart(), &invalid2 ); if( invalid1 || invalid2 ) return; if( bodyColumn == nextStatementColumn )
{
report( DiagnosticsEngine::Warning, "statement aligned as second statement in %select{if|while|for}0 body but not in a statement block",
(*it)->getLocStart()) << stmtType;
report( DiagnosticsEngine::Note, "%select{if|while|for}0 body statement is here",
body->getLocStart()) << stmtType;
} return;
} // else we need to go higher to find the next statement
} else
++it;
} // If going up would mean leaving a {} block, stop, because the } should // make it visible the two statements are not in the same body. if( dyn_cast< CompoundStmt >( parent )) return; // If the body to be checked is a body of an if statement that has also // an else part, don't go up, the else is after the body and should make // it clear the body does not continue there. if( dontGoUp ) return;
previousParent = parent;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.