void QDeleteAll::VisitStmt(clang::Stmt *stmt) { // Find a call to QMap/QSet/QHash::values CXXMemberCallExpr *valuesCall = dyn_cast<CXXMemberCallExpr>(stmt); if (valuesCall && valuesCall->getDirectCallee() && valuesCall->getDirectCallee()->getNameAsString() == "values") { const std::string valuesClassName = valuesCall->getMethodDecl()->getParent()->getNameAsString(); if (valuesClassName == "QMap" || valuesClassName == "QSet" || valuesClassName == "QHash") { // QMultiHash and QMultiMap automatically supported // Once found see if the first parent call is qDeleteAll int i = 1; Stmt *p = Utils::parent(m_parentMap, stmt, i); while (p) { CallExpr *pc = dyn_cast<CallExpr>(p); if (pc) { if (pc->getDirectCallee() && pc->getDirectCallee()->getNameAsString() == "qDeleteAll") { emitWarning(p->getLocStart(), "Calling qDeleteAll with " + valuesClassName + "::values, call qDeleteAll on the container itself"); } break; } ++i; p = Utils::parent(m_parentMap, stmt, i); } } } }
bool CursorHelper::isCursorDeclaredInCurrentFile(CXCursor node) { FileID fileId; Decl *decl = CursorHelper::getDecl(node); Stmt *stmt = CursorHelper::getStmt(node); if (decl) { fileId = CursorHelper::getASTContext(node) .getSourceManager() .getFileID(decl->getLocation()); } else if (stmt) { fileId = CursorHelper::getASTContext(node) .getSourceManager() .getFileID(stmt->getLocStart()); } else { return false; } SourceLocation sourceLocation = CursorHelper::getASTContext(node).getSourceManager().getIncludeLoc(fileId); return sourceLocation.isInvalid(); }
/*! Visit Statement \p s. */ bool VisitStmt(Stmt *s) { // Only care about If statements. if (isa<IfStmt>(s)) { IfStmt *IfStatement = cast<IfStmt>(s); Stmt *Then = IfStatement->getThen(); m_rw.InsertText(Then->getLocStart(), "// the 'if' part\n", true, true); Stmt *Else = IfStatement->getElse(); if (Else) m_rw.InsertText(Else->getLocStart(), "// the 'else' part\n", true, true); } return true; }
void FakeDirectiveHandler::InsertAccess(Expr * Current, DeclRefExpr * Original, bool Write, vector<LocalStmtPair> WritePairs, bool ActualVar, string Struct) { if (!ActualVar) return; const Type * T = Current->getType().getTypePtr(); if (FullDirectives->IsPrivate(Original, Struct, T, Original->getLocStart())) { return; } vector<LocalStmtPair>::iterator it; CompilerInstance &CI = FullDirectives->GetCI(Current->getLocStart()); for (it = WritePairs.begin(); it != WritePairs.end(); it++) { bool insertAfter = it->insertAfter; Stmt * curStmt = it->stmt; bool isBracket = false; SourceLocation start = curStmt->getLocStart(); SourceLocation end = FindSemiAfterLocation(curStmt->getLocEnd(), CI.getASTContext()); if (end.isInvalid()) { end = curStmt->getLocEnd(); isBracket = true; } SourceLocation loc; if (insertAfter) { if (isBracket) { loc = end; } else { loc = end.getLocWithOffset(1); } } else { loc = start; } loc = tools::UnpackMacroLoc(loc, CI); if (GetOrSetAccessed(loc, Current, Write)) { continue; } FullDirectives->InsertDeclAccess(Original->getFoundDecl(), Write); } }
/// VerifyJumps - Verify each element of the Jumps array to see if they are /// valid, emitting diagnostics if not. void JumpScopeChecker::VerifyJumps() { while (!Jumps.empty()) { Stmt *Jump = Jumps.pop_back_val(); // With a goto, if (GotoStmt *GS = dyn_cast<GotoStmt>(Jump)) { CheckJump(GS, GS->getLabel(), GS->getGotoLoc(), diag::err_goto_into_protected_scope); continue; } if (SwitchStmt *SS = dyn_cast<SwitchStmt>(Jump)) { for (SwitchCase *SC = SS->getSwitchCaseList(); SC; SC = SC->getNextSwitchCase()) { assert(LabelAndGotoScopes.count(SC) && "Case not visited?"); CheckJump(SS, SC, SC->getLocStart(), diag::err_switch_into_protected_scope); } continue; } unsigned DiagnosticScope; // We don't know where an indirect goto goes, require that it be at the // top level of scoping. if (IndirectGotoStmt *IG = dyn_cast<IndirectGotoStmt>(Jump)) { assert(LabelAndGotoScopes.count(Jump) && "Jump didn't get added to scopes?"); unsigned GotoScope = LabelAndGotoScopes[IG]; if (GotoScope == 0) continue; // indirect jump is ok. S.Diag(IG->getGotoLoc(), diag::err_indirect_goto_in_protected_scope); DiagnosticScope = GotoScope; } else { // We model &&Label as a jump for purposes of scope tracking. We actually // don't care *where* the address of label is, but we require the *label // itself* to be in scope 0. If it is nested inside of a VLA scope, then // it is possible for an indirect goto to illegally enter the VLA scope by // indirectly jumping to the label. assert(isa<AddrLabelExpr>(Jump) && "Unknown jump type"); LabelStmt *TheLabel = cast<AddrLabelExpr>(Jump)->getLabel(); assert(LabelAndGotoScopes.count(TheLabel) && "Referenced label didn't get added to scopes?"); unsigned LabelScope = LabelAndGotoScopes[TheLabel]; if (LabelScope == 0) continue; // Addr of label is ok. S.Diag(Jump->getLocStart(), diag::err_addr_of_label_in_protected_scope); DiagnosticScope = LabelScope; } // Report all the things that would be skipped over by this &&label or // indirect goto. while (DiagnosticScope != 0) { S.Diag(Scopes[DiagnosticScope].Loc, Scopes[DiagnosticScope].Diag); DiagnosticScope = Scopes[DiagnosticScope].ParentScope; } } }
bool ReserveCandidates::isInComplexLoop(clang::Stmt *s, SourceLocation declLocation, bool isMemberVariable) const { if (!s || declLocation.isInvalid()) return false; int forCount = 0; int foreachCount = 0; static vector<unsigned int> nonComplexOnesCache; static vector<unsigned int> complexOnesCache; auto rawLoc = s->getLocStart().getRawEncoding(); // For some reason we generate two warnings on some foreaches, so cache the ones we processed // and return true so we don't trigger a warning if (clazy_std::contains(nonComplexOnesCache, rawLoc) || clazy_std::contains(complexOnesCache, rawLoc)) return true; Stmt *parent = s; PresumedLoc lastForeachForStm; while ((parent = HierarchyUtils::parent(m_parentMap, parent))) { const SourceLocation parentStart = parent->getLocStart(); if (!isMemberVariable && sm().isBeforeInSLocAddrSpace(parentStart, declLocation)) { nonComplexOnesCache.push_back(rawLoc); return false; } bool isLoop = false; if (loopIsComplex(parent, isLoop)) { complexOnesCache.push_back(rawLoc); return true; } if (QtUtils::isInForeach(m_ci, parentStart)) { auto ploc = sm().getPresumedLoc(parentStart); if (Utils::presumedLocationsEqual(ploc, lastForeachForStm)) { // Q_FOREACH comes in pairs, because each has two for statements inside, so ignore one when counting } else { foreachCount++; lastForeachForStm = ploc; } } else { if (isLoop) forCount++; } if (foreachCount > 1 || forCount > 1) { // two foreaches are almost always a false-positve complexOnesCache.push_back(rawLoc); return true; } } nonComplexOnesCache.push_back(rawLoc); return false; }
void SimpleInliner::copyFunctionBody(void) { Stmt *Body = CurrentFD->getBody(); TransAssert(Body && "NULL Body!"); std::string FuncBodyStr(""); RewriteHelper->getStmtString(Body, FuncBodyStr); TransAssert(FuncBodyStr[0] == '{'); SourceLocation StartLoc = Body->getLocStart(); const char *StartBuf = SrcManager->getCharacterData(StartLoc); std::vector< std::pair<ReturnStmt *, int> > SortedReturnStmts; sortReturnStmtsByOffs(StartBuf, SortedReturnStmts); // Now we start rewriting int Delta = 1; // skip the first { symbol FuncBodyStr.insert(Delta, "\n"); ++Delta; for(SmallVector<std::string, 10>::iterator I = ParmStrings.begin(), E = ParmStrings.end(); I != E; ++I) { std::string PStr = (*I); FuncBodyStr.insert(Delta, PStr); Delta += PStr.size(); } // restore the effect of { Delta--; int ReturnSZ = 6; std::string TmpVarStr = TmpVarName + " = "; int TmpVarNameSize = static_cast<int>(TmpVarStr.size()); for(std::vector< std::pair<ReturnStmt *, int> >::iterator I = SortedReturnStmts.begin(), E = SortedReturnStmts.end(); I != E; ++I) { ReturnStmt *RS = (*I).first; int Off = (*I).second + Delta; Expr *Exp = RS->getRetValue(); if (Exp) { const Type *T = Exp->getType().getTypePtr(); if (!T->isVoidType()) { FuncBodyStr.replace(Off, ReturnSZ, TmpVarStr); Delta += (TmpVarNameSize - ReturnSZ); continue; } } FuncBodyStr.replace(Off, ReturnSZ, ""); Delta -= ReturnSZ; } RewriteHelper->addStringBeforeStmt(TheStmt, FuncBodyStr, NeedParen); }
bool RewriteUtils::addLocalVarToFunc(const std::string &VarStr, FunctionDecl *FD) { Stmt *Body = FD->getBody(); TransAssert(Body && "NULL body for a function definition!"); std::string IndentStr; StmtIterator I = Body->child_begin(); if (I == Body->child_end()) IndentStr = DefaultIndentStr; else IndentStr = getStmtIndentString((*I), SrcManager); std::string NewVarStr = "\n" + IndentStr + VarStr; SourceLocation StartLoc = Body->getLocStart(); return !(TheRewriter->InsertTextAfterToken(StartLoc, NewVarStr)); }
// TODO: Handle call expr? Still need this for reads of params etc. bool FakeDirectiveHandler::VisitDeclRefExpr(DeclRefExpr *S) { if (WaitingHeader && IsChild(S, WaitingHeader)) { return true; } FunctionDecl * F = dyn_cast<FunctionDecl>(S->getDecl()); if (F) { return true; } SourceManager &SM = FullDirectives->GetCI(S->getLocStart()).getSourceManager(); // TODO: Replace with presumed loc stuff SourceLocation Loc = tools::GetNearestValidLoc(S, SM, PM); if (FullDirectives->IsCompletelyPrivate(S, Loc)) { return true; } Expr * Var = getVar(S); Stmt * Base = getBase(S); Stmt * Parent = getParent(Base); Stmt * Top; if (!Parent || FullDirectives->IsLocDirectlyAfterPragma(Parent->getLocStart())) { Top = FullDirectives->GetHeader(S->getLocStart()); } else { Top = Parent; } vector<LocalStmtPair> WritePairs = GenerateWritePairs(Base, Parent, Top); WalkUpExpr(S, Var, WritePairs, true, string()); return true; }
virtual bool VisitFunctionDecl(FunctionDecl *func) { NameCodeMap::const_iterator iterator; for (iterator = functionsMap.begin(); iterator != functionsMap.end(); ++iterator) { string currentFunctionName = func->getNameInfo().getName().getAsString(); // TODO: additional checkups if(func->isThisDeclarationADefinition() && iterator->first.compare(currentFunctionName)==0){ // std::cout<<"current function: "<<currentFunctionName<<" lookedup func: "<<iterator->first<<std::endl; SourceLocation currentLocation; Stmt * definition = func->getBody(); for (StmtRange range = definition->children(); range; ++range){ Stmt * fs = *range; currentLocation = fs->getLocStart(); break; } rewriter.InsertTextBefore(currentLocation,functionsMap[iterator->first]); } } return true; }
bool AnalysisDeclContext::isBodyAutosynthesizedFromModelFile() const { bool Tmp; Stmt *Body = getBody(Tmp); return Tmp && Body->getLocStart().isValid(); }