Пример #1
0
    void TraverseFunctionBody(Stmt *S, Method *m) {
        // perform depth first traversal of all children
        for (Stmt::child_iterator CI = S->child_begin(),
                E = S->child_end(); CI != E; ++CI) {
            if (*CI) TraverseFunctionBody(*CI, m);
        }

        // if it's a function call, register it
        if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
            FunctionDecl *fd = CE->getDirectCallee();
            if (fd != 0) {
                QualType type = fd->getResultType();
                std::string rtype = type.getAsString();
                std::string qname = fd->getQualifiedNameAsString();
                std::string param = "";
                param += "(";

                for (FunctionDecl::param_iterator I = fd->param_begin(),
                        E = fd->param_end(); I != E; ++I) {
                    if(ParmVarDecl *PD = dyn_cast<ParmVarDecl>(*I)) {
                        QualType type = PD->getType();
                        param += type.getAsString() + ",";
                    }
                    else assert(0); // case of interest!
                }

                if (param != "(") param.erase(param.end() - 1); // remove the last comma
                param += ")";
                std::string callee = rtype + " " + qname + param;
                m->callexprs.insert(callee);
            }
        }
    }
Пример #2
0
void ReplaceCallExpr::getParmPosVector(ParameterPosVector &PosVector,
                                       ReturnStmt *RS, CallExpr *CE)
{
  DenseMap<ReturnStmt *, ParmRefsVector *>::iterator RI =
    ReturnStmtToParmRefs.find(RS);
  if (RI == ReturnStmtToParmRefs.end())
    return;

  ParmRefsVector *PVector = (*RI).second;

  FunctionDecl *FD = CE->getDirectCallee();
  for (ParmRefsVector::const_iterator PI = PVector->begin(),
       PE = PVector->end(); PI != PE; ++PI) {

    const ValueDecl *OrigDecl = (*PI)->getDecl();
    const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(OrigDecl);
    unsigned int Pos = 0;
    for(FunctionDecl::param_const_iterator I = FD->param_begin(),
        E = FD->param_end(); I != E; ++I) {
      if (PD == (*I))
        break;
      Pos++;
    }
    PosVector.push_back(Pos);
  }
}
Пример #3
0
void ReplaceCallExpr::getNewParmRefStr(const DeclRefExpr *DE,
                                       std::string &ParmRefStr)
{
  const ValueDecl *OrigDecl = DE->getDecl();
  const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(OrigDecl);
  TransAssert(PD && "Bad ParmVarDecl!");

  FunctionDecl *FD = TheCallExpr->getDirectCallee();

  unsigned int Pos = 0;
  for(FunctionDecl::param_const_iterator I = FD->param_begin(),
      E = FD->param_end(); I != E; ++I) {
    TransAssert((Pos < TheCallExpr->getNumArgs()) &&
                "Unmatched Parm and Arg!");
    if (PD != (*I)) {
      Pos++;
      continue;
    }

    const Expr *Arg = TheCallExpr->getArg(Pos)->IgnoreParenImpCasts();
    RewriteHelper->getExprString(Arg, ParmRefStr);
    ParmRefStr = "(" + ParmRefStr + ")";

    const Type *ParmT = PD->getType().getTypePtr();
    const Type *CanParmT = Context->getCanonicalType(ParmT);
    const Type *ArgT = Arg->getType().getTypePtr();
    const Type *CanArgT = Context->getCanonicalType(ArgT);
    if (CanParmT != CanArgT) {
      std::string TypeCastStr = PD->getType().getAsString();
      ParmRefStr = "(" + TypeCastStr + ")" + ParmRefStr;
    }
    return;
  }
  TransAssert(0 && "Unreachable Code!");
}
Пример #4
0
void FunctionArgsByRef::VisitDecl(Decl *decl)
{
    FunctionDecl *functionDecl = dyn_cast<FunctionDecl>(decl);
    if (functionDecl == nullptr || !functionDecl->hasBody() || shouldIgnoreFunction(functionDecl->getNameAsString())
            || !functionDecl->isThisDeclarationADefinition()) return;

    Stmt *body = functionDecl->getBody();

    for (auto it = functionDecl->param_begin(), end = functionDecl->param_end(); it != end; ++it) {
        const ParmVarDecl *param = *it;
        QualType paramQt = param->getType();
        const Type *paramType = paramQt.getTypePtrOrNull();
        if (paramType == nullptr || paramType->isDependentType())
            continue;

        const int size_of_T = m_ci.getASTContext().getTypeSize(paramQt) / 8;
        const bool isSmall = size_of_T <= 16; // TODO: What about arm ?
        CXXRecordDecl *recordDecl = paramType->getAsCXXRecordDecl();
        const bool isUserNonTrivial = recordDecl && (recordDecl->hasUserDeclaredCopyConstructor() || recordDecl->hasUserDeclaredDestructor());
        const bool isReference = paramType->isLValueReferenceType();
        const bool isConst = paramQt.isConstQualified();
        if (recordDecl && shouldIgnoreClass(recordDecl->getQualifiedNameAsString()))
            continue;

        std::string error;
        if (isConst && !isReference) {
            if (!isSmall) {
                error += warningMsgForSmallType(size_of_T, paramQt.getAsString());
            } else if (isUserNonTrivial) {
                error += "Missing reference on non-trivial type " + recordDecl->getQualifiedNameAsString();
            }
        } else if (isConst && isReference && !isUserNonTrivial && isSmall) {
            //error += "Don't use by-ref on small trivial type";
        } else if (!isConst && !isReference && (!isSmall || isUserNonTrivial)) {
            if (Utils::containsNonConstMemberCall(body, param) || Utils::containsCallByRef(body, param))
                continue;
            if (!isSmall) {
                error += warningMsgForSmallType(size_of_T, paramQt.getAsString());
            } else if (isUserNonTrivial) {
                error += "Missing reference on non-trivial type " + recordDecl->getQualifiedNameAsString();
            }
        }

        if (!error.empty()) {
            emitWarning(param->getLocStart(), error.c_str());
        }
    }
}
Пример #5
0
void
NSErrorChecker::CheckSignature(const FunctionDecl& F, QualType& ResultTy,
                             llvm::SmallVectorImpl<VarDecl*>& ErrorParams) {

  ResultTy = F.getResultType();

  for (FunctionDecl::param_const_iterator I = F.param_begin(),
                                          E = F.param_end(); I != E; ++I)  {

    QualType T = (*I)->getType();

    if (isNSErrorWarning) {
      if (CheckNSErrorArgument(T)) ErrorParams.push_back(*I);
    }
    else if (CheckCFErrorArgument(T))
      ErrorParams.push_back(*I);
  }
}