/*If Statement*/ void SyntaxAnalysis::ifStmt() { Tree::Tree * tempTree = subTree; setAndAdvance(IFSTRING); eat(Token::IF); eat(Token::OPEN); operationsExp(); eat(Token::CLOSE); eat(Token::THEN); compoundStmt(); if (vecToken[0].getTokenType() == Token::OTHERWISE) { Tree::Tree * newTempTree = subTree; setAndAdvance(OTHERSTRING); eat(Token::OTHERWISE); compoundStmt(); eat(Token::END); subTree = newTempTree; } else eat(Token::END); subTree = tempTree; }
void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) { // FIXME: Support continue, break and throw. Finder->addMatcher( compoundStmt( forEach(ifStmt(hasThen(stmt(anyOf(returnStmt(), compoundStmt(has(returnStmt()))))), hasElse(stmt().bind("else"))) .bind("if"))), this); }
void FunctionSizeCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( functionDecl( unless(isInstantiated()), forEachDescendant( stmt(unless(compoundStmt()), hasParent(stmt(anyOf(compoundStmt(), ifStmt(), anyOf(whileStmt(), doStmt(), forRangeStmt(), forStmt()))))) .bind("stmt"))).bind("func"), this); }
namespace EffectiveCPP { StatementMatcher ctorCallVtlMatcherEC = compoundStmt( hasParent(constructorDecl().bind("cDecl")), hasDescendant(callExpr(callee(methodDecl(isVirtual())))) ); StatementMatcher dtorCallVtlMatcherEC = compoundStmt( hasParent(destructorDecl().bind("dDecl")), hasDescendant(callExpr(callee(methodDecl(isVirtual())))) ); }
void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) { const auto ControlFlowInterruptorMatcher = stmt(anyOf(returnStmt().bind("return"), continueStmt().bind("continue"), breakStmt().bind("break"), expr(ignoringImplicit(cxxThrowExpr().bind("throw"))))); Finder->addMatcher( compoundStmt(forEach( ifStmt(hasThen(stmt( anyOf(ControlFlowInterruptorMatcher, compoundStmt(has(ControlFlowInterruptorMatcher))))), hasElse(stmt().bind("else"))) .bind("if"))), this); }
void MisleadingIndentationCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher(ifStmt(hasElse(stmt())).bind("if"), this); Finder->addMatcher( compoundStmt(has(stmt(anyOf(ifStmt(), forStmt(), whileStmt())))) .bind("compound"), this); }
void DeleteNullPointerCheck::registerMatchers(MatchFinder *Finder) { const auto DeleteExpr = cxxDeleteExpr(has(castExpr(has(declRefExpr( to(decl(equalsBoundNode("deletedPointer")))))))) .bind("deleteExpr"); const auto DeleteMemberExpr = cxxDeleteExpr(has(castExpr(has(memberExpr(hasDeclaration( fieldDecl(equalsBoundNode("deletedMemberPointer")))))))) .bind("deleteMemberExpr"); const auto PointerExpr = ignoringImpCasts(anyOf( declRefExpr(to(decl().bind("deletedPointer"))), memberExpr(hasDeclaration(fieldDecl().bind("deletedMemberPointer"))))); const auto PointerCondition = castExpr(hasCastKind(CK_PointerToBoolean), hasSourceExpression(PointerExpr)); const auto BinaryPointerCheckCondition = binaryOperator(hasEitherOperand(castExpr(hasCastKind(CK_NullToPointer))), hasEitherOperand(PointerExpr)); Finder->addMatcher( ifStmt(hasCondition(anyOf(PointerCondition, BinaryPointerCheckCondition)), hasThen(anyOf( DeleteExpr, DeleteMemberExpr, compoundStmt(anyOf(has(DeleteExpr), has(DeleteMemberExpr)), statementCountIs(1)) .bind("compound")))) .bind("ifWithDelete"), this); }
void MustUseChecker::registerMatchers(MatchFinder *AstMatcher) { AstMatcher->addMatcher(switchCase().bind("switchcase"), this); AstMatcher->addMatcher(compoundStmt().bind("compound"), this); AstMatcher->addMatcher(ifStmt().bind("if"), this); AstMatcher->addMatcher(whileStmt().bind("while"), this); AstMatcher->addMatcher(doStmt().bind("do"), this); AstMatcher->addMatcher(forStmt().bind("for"), this); AstMatcher->addMatcher(binaryOperator(binaryCommaOperator()).bind("bin"), this); }
/*Laço de Repetição*/ void SyntaxAnalysis::whileStmt() { Tree::Tree * tempTree = subTree; setAndAdvance(WHILESTRING); eat(Token::REPEAT); compoundStmt(); eat(Token::UNTIL); eat(Token::OPEN); operationsExp(); eat(Token::CLOSE); subTree = tempTree; }
void SyntaxAnalysis::compoundStmt() { Token::Token tokenTemp = targetAdvance(); Tree::Tree * tempTree = subTree; if (tokenTemp.getTokenType() != Token::END && tokenTemp.getTokenType() != Token::OTHERWISE && tokenTemp.getTokenType() != Token::UNTIL) { setAndAdvance(COMPSTMTSTRING); expression(); compoundStmt(); } subTree = tempTree; }
// }}} // {{{ stmt std::unique_ptr<Stmt> FlowParser::stmt() { FNTRACE(); switch (token()) { case FlowToken::If: return ifStmt(); case FlowToken::Begin: return compoundStmt(); case FlowToken::Ident: return callStmt(); case FlowToken::Semicolon: { FlowLocation sloc(location()); nextToken(); return std::make_unique<CompoundStmt>(sloc.update(end())); } default: reportError("Unexpected token '%s'. Expected a statement instead.", token().c_str()); return nullptr; } }
void SyntaxAnalysis::functionDecStmt() { Tree::Tree * tempTree = subTree; setAndAdvance(FUNCDECSTRING); type(vecToken[0]); subTree->setChild(vecToken[0]); switch (vecToken[0].getTokenType()) { case(Token::IDENTIFIER): eat(Token::IDENTIFIER); prototypeDefStmt(); compoundStmt(); eat(Token::END); break; default: error.functionDeclarationError(vecToken[0]); } subTree = tempTree; }
void UndelegatedConstructorCheck::registerMatchers(MatchFinder *Finder) { // We look for calls to constructors of the same type in constructors. To do // this we have to look through a variety of nodes that occur in the path, // depending on the type's destructor and the number of arguments on the // constructor call, this is handled by ignoringTemporaryExpr. Ignore template // instantiations to reduce the number of duplicated warnings. // // Only register the matchers for C++11; the functionality currently does not // provide any benefit to other languages, despite being benign. if (!getLangOpts().CPlusPlus11) return; Finder->addMatcher( compoundStmt( hasParent( cxxConstructorDecl(ofClass(cxxRecordDecl().bind("parent")))), forEach(ignoringTemporaryExpr( cxxConstructExpr(hasDeclaration(cxxConstructorDecl(ofClass( cxxRecordDecl(baseOfBoundNode("parent")))))) .bind("construct"))), unless(isInTemplateInstantiation())), this); }
// primaryExpr ::= NUMBER // | STRING // | variable // | function '(' exprList ')' // | '(' expr ')' std::unique_ptr<Expr> FlowParser::primaryExpr() { FNTRACE(); static struct { const char* ident; long long nominator; long long denominator; } units[] = { { "byte", 1, 1 }, { "kbyte", 1024llu, 1 }, { "mbyte", 1024llu * 1024, 1 }, { "gbyte", 1024llu * 1024 * 1024, 1 }, { "tbyte", 1024llu * 1024 * 1024 * 1024, 1 }, { "bit", 1, 8 }, { "kbit", 1024llu, 8 }, { "mbit", 1024llu * 1024, 8 }, { "gbit", 1024llu * 1024 * 1024, 8 }, { "tbit", 1024llu * 1024 * 1024 * 1024, 8 }, { "sec", 1, 1 }, { "min", 60llu, 1 }, { "hour", 60llu * 60, 1 }, { "day", 60llu * 60 * 24, 1 }, { "week", 60llu * 60 * 24 * 7, 1 }, { "month", 60llu * 60 * 24 * 30, 1 }, { "year", 60llu * 60 * 24 * 365, 1 }, { nullptr, 1, 1 } }; FlowLocation loc(location()); switch (token()) { case FlowToken::Ident: { std::string name = stringValue(); nextToken(); Symbol* symbol = scope()->lookup(name, Lookup::All); if (!symbol) { // XXX assume that given symbol is a auto forward-declared handler. Handler* href = (Handler*) globalScope()->appendSymbol(std::make_unique<Handler>(name, loc)); return std::make_unique<HandlerRefExpr>(href, loc); } if (auto variable = dynamic_cast<Variable*>(symbol)) return std::make_unique<VariableExpr>(variable, loc); if (auto handler = dynamic_cast<Handler*>(symbol)) return std::make_unique<HandlerRefExpr>(handler, loc); if (symbol->type() == Symbol::BuiltinFunction) { if (token() != FlowToken::RndOpen) return std::make_unique<FunctionCallExpr>((BuiltinFunction*) symbol, ExprList()/*args*/, loc); nextToken(); ExprList args; bool rv = listExpr(args); consume(FlowToken::RndClose); if (!rv) return nullptr; return std::make_unique<FunctionCallExpr>((BuiltinFunction*) symbol, std::move(args), loc); } reportError("Unsupported symbol type of '%s' in expression.", name.c_str()); return nullptr; } case FlowToken::Boolean: { std::unique_ptr<BoolExpr> e = std::make_unique<BoolExpr>(booleanValue(), loc); nextToken(); return std::move(e); } case FlowToken::RegExp: { std::unique_ptr<RegExpExpr> e = std::make_unique<RegExpExpr>(RegExp(stringValue()), loc); nextToken(); return std::move(e); } case FlowToken::InterpolatedStringFragment: return interpolatedStr(); case FlowToken::String: case FlowToken::RawString: { std::unique_ptr<StringExpr> e = std::make_unique<StringExpr>(stringValue(), loc); nextToken(); return std::move(e); } case FlowToken::Number: { // NUMBER [UNIT] auto number = numberValue(); nextToken(); if (token() == FlowToken::Ident) { std::string sv(stringValue()); for (size_t i = 0; units[i].ident; ++i) { if (sv == units[i].ident || (sv[sv.size() - 1] == 's' && sv.substr(0, sv.size() - 1) == units[i].ident)) { nextToken(); // UNIT number = number * units[i].nominator / units[i].denominator; loc.update(end()); break; } } } return std::make_unique<NumberExpr>(number, loc); } case FlowToken::IP: { std::unique_ptr<IPAddressExpr> e = std::make_unique<IPAddressExpr>(lexer_->ipValue(), loc); nextToken(); return std::move(e); } case FlowToken::Cidr: { std::unique_ptr<CidrExpr> e = std::make_unique<CidrExpr>(lexer_->cidr(), loc); nextToken(); return std::move(e); } case FlowToken::StringType: case FlowToken::NumberType: case FlowToken::BoolType: return castExpr(); case FlowToken::Begin: { // lambda-like inline function ref char name[64]; static unsigned long i = 0; ++i; snprintf(name, sizeof(name), "__lambda_%lu", i); FlowLocation loc = location(); auto st = std::make_unique<SymbolTable>(scope(), name); enter(st.get()); std::unique_ptr<Stmt> body = compoundStmt(); leave(); if (!body) return nullptr; loc.update(body->location().end); Handler* handler = new Handler(name, std::move(st), std::move(body), loc); // TODO (memory leak): add handler to unit's global scope, i.e. via: // - scope()->rootScope()->insert(handler); // - unit_->scope()->insert(handler); // to get free'd return std::make_unique<HandlerRefExpr>(handler, loc); } case FlowToken::RndOpen: { nextToken(); std::unique_ptr<Expr> e = expr(); consume(FlowToken::RndClose); e->setLocation(loc.update(end())); return e; } default: TRACE(1, "Expected primary expression. Got something... else."); reportUnexpectedToken(); return nullptr; } }
#include "ASTUtility.h" StatementMatcher FuncStmtMatcher = compoundStmt( hasParent(functionDecl(returns(pointerType())).bind("functiondecl")), hasDescendant(returnStmt( hasDescendant(declRefExpr().bind("decl")))) ).bind("funcstmt"); class ReturnChecker : public MatchFinder::MatchCallback { public: virtual void run(const MatchFinder::MatchResult &Result) { clang::ASTContext *Context = Result.Context; const clang::CompoundStmt *cs = Result.Nodes.getNodeAs<clang::CompoundStmt>("funcstmt"); const clang::FunctionDecl *fd = Result.Nodes.getNodeAs<clang::FunctionDecl>("functiondecl"); const clang::DeclRefExpr *decl = Result.Nodes.getNodeAs<clang::DeclRefExpr>("decl"); if(!cs || !fd || !decl || ASTUtility::IsStmtInSTDFile(cs, Context)) return; if (!clang::VarDecl::classof(decl -> getDecl())) return; const clang::VarDecl *var = static_cast<const clang::VarDecl*>(decl -> getDecl()); if (var -> hasLocalStorage()) ASTUtility::Print(decl, Context, "Rule65"); } }; //@TestNeed static llvm::cl::OptionCategory MyToolCategory("options");
#include "ASTUtility.h" StatementMatcher funcMatcher = compoundStmt( hasParent(functionDecl().bind("function")) ).bind("functionBody"); class FunctionPrinter : public MatchFinder::MatchCallback { public: virtual void run(const MatchFinder::MatchResult &Result) { //get the node clang::ASTContext *Context = Result.Context; const clang::CompoundStmt *FS = Result.Nodes.getNodeAs<clang::CompoundStmt>("functionBody"); const clang::FunctionDecl *FD = Result.Nodes.getNodeAs<clang::FunctionDecl>("function"); if(!FD || ASTUtility::IsDeclInSTDFile(FD, Context)) return; if(FD -> isVariadic()) ASTUtility::Print(FD, Context, "Rule041"); } }; //"My tool options" is the name. static llvm::cl::OptionCategory MyToolCategory("My tool options"); int main(int argc, const char **argv) { //CommonOptionsParser constructor will parse arguments and create a //CompilationDatabase. In case of error it will terminate the program. CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
bool parserCls::doStmt(void){ bool bb1=true,bb2=true,foundControlVar=false; tokenContainCls tcs1=getCurToken();exprContainCls *ce0,*ce1,*ce2,*ce3; int a1=noSourceLine,a2=0,a3=0; EtokenType tt2 ; EinstructionWord tt1 =ErrorInstr; getToken(); noLoop ++ ; switch(getTokenType()){ case While : tt1 = DoWhileInstr; bb1 = exprShould(tt1) ; break ; case Until: tt1=DoUntilInstr; bb1=exprShould(tt1); break ; case ForEver: tt1=DoForEverInstr ; getToken(); break ; case For: tt1=DoForInstr; bb1 = exprShould(tt1) ; break ; case Semicolon : case EndOfLine : tt1 = DoInstr ; noLoop --; break ; default: tt1=DoToInstr; tt2=getTokenType(); tokenContainCls tcs2=getCurToken() ; if((tt2==Array)||(tt2==Name)) { addControlVar(tcs2 );foundControlVar=true; ce0=new exprContainCls(1);ce0->push(tcs2);getToken(); if(getTokenType() == Eq) { bb2 = exprShould(DoToInstr); ce1 = getNewExpr(); } else { bb2= false ; errorDo(1, tcs1, tcs2 ); foundControlVar=false; popControlVar(); } } else { errorDo(2,tcs1,tcs2); bb2=false; } if(bb2) if(getTokenType() == To ) { bb2 = exprShould(DoToInstr); ce2 = getNewExpr(); } else { errorDo(2 , tcs1 , tcs2 ) ; bb2 = false ; } if(bb2) if(getTokenType() == By) { bb2=exprShould(DoToByInstr); tt1=DoToByInstr; ce3=getNewExpr(); } } if((tt1 == DoWhileInstr) || (tt1 == DoForInstr)||(tt1 == DoUntilInstr) ) ce0=getNewExpr(); bb1 = bb1 && bb2 ; bool bb3=true ; if(bb1) endWhiteLine(); else bb3 = syncStmtError(); if(!bb3) return false ; compoundStmt(tcs1,a2 ) ;/// if error not found show the error a3 = stmtNo ; if(foundControlVar) popControlVar(); noLoop--; initEiwCss(tt1) ; if((tt1==DoWhileInstr)||(tt1==DoUntilInstr)||(tt1==DoForInstr)) addExprToStmt(ce0,0); else if((tt1 == DoInstr)||(tt1==DoForEverInstr)) {if(tt1 == DoInstr ) noLoop ++ ;} else if( (tt1 == DoToInstr ) || (tt1 == DoToByInstr) ) {addExprToStmt(ce0,0); addExprToStmt(ce1,1);addExprToStmt(ce2,2); if(tt1 == DoToByInstr ) addExprToStmt(ce3,3); } valInt[0] = a1 ;valInt[1] = a2 -1;valInt[2] = a3;noOfValInt=3; return bb1 ; }