Пример #1
0
void SimpleInliner::doAnalysis(void)
{
  getValidFunctionDecls();

  for (SmallVector<CallExpr *, 10>::iterator CI = AllCallExprs.begin(),
       CE = AllCallExprs.end(); CI != CE; ++CI) {

    FunctionDecl *CalleeDecl = (*CI)->getDirectCallee(); 
    TransAssert(CalleeDecl && "Bad CalleeDecl!");
    FunctionDecl *CanonicalDecl = CalleeDecl->getCanonicalDecl();
    if (!ValidFunctionDecls.count(CanonicalDecl))
      continue;

    if (!hasValidArgExprs(*CI))
      continue;

    ValidInstanceNum++;
    if (TransformationCounter == ValidInstanceNum) {
      // It's possible the direct callee is not a definition
      if (!CalleeDecl->isThisDeclarationADefinition()) {
        CalleeDecl = CalleeDecl->getFirstDeclaration();
        for(FunctionDecl::redecl_iterator RI = CalleeDecl->redecls_begin(),
            RE = CalleeDecl->redecls_end(); RI != RE; ++RI) {
          if ((*RI)->isThisDeclarationADefinition()) {
            CalleeDecl = (*RI);
            break;
          }
        }
      }
      TransAssert(CalleeDecl->isThisDeclarationADefinition() && 
                  "Bad CalleeDecl!");
      CurrentFD = CalleeDecl;
      TheCaller = CalleeToCallerMap[(*CI)];
      TransAssert(TheCaller && "NULL TheCaller!");
      TheCallExpr = (*CI);
    }
  }
}
Пример #2
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());
        }
    }
}
Пример #3
0
bool RemoveAddrTaken::HandleTopLevelDecl(DeclGroupRef D) 
{
  TransAssert(CollectionVisitor && "NULL CollectionVisitor!");
  if (TransformationManager::isCXXLangOpt()) {
    ValidInstanceNum = 0;
    return true;
  }

  for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
    FunctionDecl *FD = dyn_cast<FunctionDecl>(*I);
    if (!FD || !FD->isThisDeclarationADefinition())
      continue;
    CollectionVisitor->TraverseDecl(*I); 
  }

  return true;
}
Пример #4
0
void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
  prettyPrintPragmas(D->getTemplatedDecl());
  VisitRedeclarableTemplateDecl(D);

  if (PrintInstantiation) {
    FunctionDecl *PrevDecl = D->getTemplatedDecl();
    const FunctionDecl *Def;
    if (PrevDecl->isDefined(Def) && Def != PrevDecl)
      return;
    for (auto *I : D->specializations())
      if (I->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) {
        if (!PrevDecl->isThisDeclarationADefinition())
          Out << ";\n";
        Indent();
        prettyPrintPragmas(I);
        Visit(I);
      }
  }
}
Пример #5
0
bool MoveFunctionBody::HandleTopLevelDecl(DeclGroupRef D) 
{
  for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
    FunctionDecl *FD = dyn_cast<FunctionDecl>(*I);
    if (!FD) {
      PrevFunctionDecl = NULL;
      continue;
    }

    FunctionDecl *CanonicalFD = FD->getCanonicalDecl();
    if (FD->isThisDeclarationADefinition()) {
      FunctionDecl *FDDecl = AllValidFunctionDecls[CanonicalFD];
      if (!FDDecl) {
        PrevFunctionDecl = NULL;
        continue;
      }

      // Declaration and Definition are next to each other
      if (PrevFunctionDecl) {
        FunctionDecl *CanonicalPrevFD = PrevFunctionDecl->getCanonicalDecl();
        if (CanonicalFD == CanonicalPrevFD) {
          PrevFunctionDecl = NULL;
          continue;
        }
      }

      FuncDeclToFuncDef[FDDecl] = FD;
    }

    PrevFunctionDecl = FD;
    // We only need the first FunctionDecl
    if (AllValidFunctionDecls[CanonicalFD])
      continue;

    AllValidFunctionDecls[CanonicalFD] = FD;
  }
  return true;
}
Пример #6
0
void SimpleInliner::doAnalysis(void)
{
#ifdef DEBUGCL
  std::cerr << "SimpleInliner::doAnalysis" << std::endl;
  std::cerr << "Size of AllCallExprs = " << AllCallExprs.size() << std::endl;
#endif
  getValidFunctionDecls();

  for (SmallVector<CallExpr *, 10>::iterator CI = AllCallExprs.begin(),
       CE = AllCallExprs.end(); CI != CE; ++CI) {

    FunctionDecl *CalleeDecl = (*CI)->getDirectCallee(); 
    TransAssert(CalleeDecl && "Bad CalleeDecl!");
    FunctionDecl *CanonicalDecl = CalleeDecl->getCanonicalDecl();
#ifdef DEBUGCL
    std::cerr << "CanonicalDecl = " << CanonicalDecl->getName().str()
      << std::endl;
#endif
    if (!ValidFunctionDecls.count(CanonicalDecl)) {
#ifdef DEBUGCL
      std::cerr << "!ValidFunctionDecls.count" << std::endl;
#endif
      continue;
    }

    if (!hasValidArgExprs(*CI)) {
#ifdef DEBUGCL
      std::cerr << "!hasValidArgExprs" << std::endl;
#endif
      continue;
    }

    ValidInstanceNum++;
#ifdef DEBUGCL
    std::cerr << "TransformationCounter = " << TransformationCounter
      << " and ValidInstanceNum = " << ValidInstanceNum << std::endl;
#endif
    if (TransformationCounter == ValidInstanceNum) {
#ifdef DEBUGCL
      std::cerr << "TransformationCounter == ValidInstanceNum" << std::endl;
#endif
      // It's possible the direct callee is not a definition
      if (!CalleeDecl->isThisDeclarationADefinition()) {
        CalleeDecl = CalleeDecl->getFirstDeclaration();
        for(FunctionDecl::redecl_iterator RI = CalleeDecl->redecls_begin(),
            RE = CalleeDecl->redecls_end(); RI != RE; ++RI) {
          if ((*RI)->isThisDeclarationADefinition()) {
            CalleeDecl = (*RI);
            break;
          }
        }
      }
      TransAssert(CalleeDecl->isThisDeclarationADefinition() && 
                  "Bad CalleeDecl!");
      CurrentFD = CalleeDecl;
      TheCaller = CalleeToCallerMap[(*CI)];
      TransAssert(TheCaller && "NULL TheCaller!");
#ifdef DEBUGCL
      std::cerr << "Assigning TheCallExpr" << std::endl;
#endif
      TheCallExpr = (*CI);
    }
  }
}