Exemplo n.º 1
0
  virtual void HandleTranslationUnit(TranslationUnit& tu) {
    // called when everything is done

    UsageMap uses;
    for (int i = 0; i < globals.size(); ++i) {
      uses[globals[i]] = vector<DeclRefExpr*>();
    }

    FindUsages fu(uses);
    for (int i = 0; i < functions.size(); ++i) {
      fu.process(functions[i]);
    }

    for (int i = 0; i < globals.size(); ++i) {
      VarDecl* VD = globals[i];
      FullSourceLoc loc(VD->getLocation(), *sm);
      bool isStatic = VD->getStorageClass() == VarDecl::Static;

      cout << "<span class=\"global\">" << loc.getSourceName() << ": "
           << (isStatic?"static ":"") << VD->getName()
           << "  (" << uses[VD].size() << " local uses)"
           << "\n</span>";

      cout << "<span class=\"uses\">";
      for (int j = 0; j < uses[VD].size(); ++j) {
        DeclRefExpr* dre = uses[VD][j];
        FunctionDecl* fd = enclosing[dre];
        FullSourceLoc loc(dre->getLocStart(), *sm);
        cout << "  " << fd->getName() << ":"
             << loc.getLogicalLineNumber() << "\n";
      }
      cout << "</span>";
    }
  }
 bool VisitBinAssign(const BinaryOperator *assign) {
     DeclRefExpr *lhs = llvm::dyn_cast<DeclRefExpr>(assign->getLHS());
     if (lhs && lhs->getDecl() == _Decl) {
         _Set.insert(assign->getRHS()->IgnoreParenImpCasts());
     }
     return true;
 }
Exemplo n.º 3
0
static CallExpr *create_call_once_funcptr_call(ASTContext &C, ASTMaker M,
                                               const ParmVarDecl *Callback,
                                               ArrayRef<Expr *> CallArgs) {

  QualType Ty = Callback->getType();
  DeclRefExpr *Call = M.makeDeclRefExpr(Callback);
  Expr *SubExpr;
  if (Ty->isRValueReferenceType()) {
    SubExpr = M.makeImplicitCast(
        Call, Ty.getNonReferenceType(), CK_LValueToRValue);
  } else if (Ty->isLValueReferenceType() &&
             Call->getType()->isFunctionType()) {
    Ty = C.getPointerType(Ty.getNonReferenceType());
    SubExpr = M.makeImplicitCast(Call, Ty, CK_FunctionToPointerDecay);
  } else if (Ty->isLValueReferenceType()
             && Call->getType()->isPointerType()
             && Call->getType()->getPointeeType()->isFunctionType()){
    SubExpr = Call;
  } else {
    llvm_unreachable("Unexpected state");
  }

  return CallExpr::Create(C, SubExpr, CallArgs, C.VoidTy, VK_RValue,
                          SourceLocation());
}
Exemplo n.º 4
0
bool VarCollector::VisitBinaryOperator(BinaryOperator *e)  {

  CompilerInstance &CI = FullDirectives->GetCI(e->getLocStart());

  // If it's not an assignment, no contamination can occur
  if (!e->isAssignmentOp()) {
    return true;
  }
  
  // If we're not changing a pointer, no contamination can occur
  if (!e->getLHS()->getType()->isPointerType()) {
    return true;
  }
  
  assert(!e->getLHS()->getType()->isArrayType());
  
  // Get Dominant LHS DeclRef and its expr
  DeclRefExpr * LDominantRef = NULL;
  Expr * LDominantExpr = NULL;

  VarTraverser lvt(e->getLHS(), LDominantRef, LDominantExpr, CI);
  lvt.TraverseStmt(e->getLHS());
  
  // Shouldn't get this!!
  // But if there isn't a dominant variable being written to just return
  // Where on earth is it writing to!?
  // TODO: Convert to actual error!
  if (!LDominantRef) {
    llvm::errs() << "Warning: Found a pointer being modified that we have no "
                 << "idea where came from. Can't determine if private or not!\n";
    return true;
  }
  
  // Get Dominant RHS DeclRef and its expr
  DeclRefExpr * RDominantRef = NULL;
  Expr * RDominantExpr = NULL;

  VarTraverser rvt(e->getRHS(), RDominantRef, RDominantExpr, CI);
  rvt.TraverseStmt(e->getRHS());

  // If there isn't a dominant variable now being pointed to, just return
  if (!RDominantRef) {
    llvm::errs() << "No dominant right ref\n";
    return true;
  }

  VarDecl * VDLHS = dyn_cast<VarDecl>(LDominantRef->getDecl());
  VarDecl * VDRHS = dyn_cast<VarDecl>(RDominantRef->getDecl());

  const Type * T = LDominantExpr->getType().getTypePtr();

  string LT = GetType(LDominantExpr);
  string RT = GetType(RDominantExpr);

  maybeContaminated(VDLHS, LT, VDRHS, RT, T, e->getLocStart());

  return true;

}
  void NetworkDriverRewriteVisitor::InstrumentEntryPoints(FunctionDecl* funcDecl, string fdFile)
  {
    if (funcDecl->getStorageClass() == SC_Static)
      RW.RemoveText(funcDecl->getInnerLocStart(), 7);

    if (DI->getInstance().GetInitFunction() == funcDecl->getNameInfo().getName().getAsString())
      return;

    if (funcDecl->getParamDecl(0)->getOriginalType().getAsString() != "struct device *" &&
      funcDecl->getParamDecl(0)->getOriginalType().getAsString() != "struct pci_dev *")
      return;

    SourceRange sr = funcDecl->getParamDecl(0)->getSourceRange();

    RW.InsertTextBefore(sr.getBegin(), "struct net_device *dev, ");

    Stmt *body = funcDecl->getBody();
    list<DeclStmt*> stmtsToRewrite;

    for (auto i = body->child_begin(), e = body->child_end(); i != e; ++i)
    {
      if (!isa<DeclStmt>(*i))
        continue;

      DeclStmt *declStmt = cast<DeclStmt>(*i);
      if (!declStmt->isSingleDecl() && !isa<VarDecl>(declStmt->getSingleDecl()))
        continue;

      VarDecl *var = cast<VarDecl>(declStmt->getSingleDecl());
      if (!var->hasInit())
        continue;

      Expr *expr = var->getInit();
      if (!isa<ImplicitCastExpr>(expr))
        continue;

      ImplicitCastExpr *implicit = cast<ImplicitCastExpr>(expr);
      if (!isa<CallExpr>(implicit->getSubExpr()))
       continue;

      CallExpr *call = cast<CallExpr>(implicit->getSubExpr());
      DeclRefExpr *callee = cast<DeclRefExpr>(cast<ImplicitCastExpr>(call->getCallee())->getSubExpr());

      if (callee->getNameInfo().getName().getAsString() == "to_pci_dev" ||
          callee->getNameInfo().getName().getAsString() == "pci_get_drvdata")
      {
        stmtsToRewrite.push_back(declStmt);
      }
    }

    while (!stmtsToRewrite.empty())
    {
      DeclStmt *stmt = stmtsToRewrite.back();
      RW.RemoveText(stmt->getSourceRange());
      stmtsToRewrite.pop_back();
    }
  }
Exemplo n.º 6
0
Stmt *TransformWCR::VisitWhileStmt(WhileStmt *S) {
  StmtVector OuterBody;
  StmtVector BodyStmts;
  StmtVector WCRBody;

  // Declaration of condition variable
  VarDecl *CondVD = NewCondVarDecl(S->getCond()->getType());
  CondDecls.push_back(NewDeclStmt(CondVD));

  // Computation of condition
  DeclRefExpr *LHS = new (ASTCtx) DeclRefExpr(CondVD,
      CondVD->getType(), VK_RValue, SourceLocation());
  BinaryOperator *CondBinOp = new (ASTCtx) BinaryOperator(
      LHS, S->getCond(), BO_Assign, LHS->getType(), 
      VK_RValue, OK_Ordinary, SourceLocation());

  // Cond WCR
  MergeBodyAndCond(BodyStmts, CondBinOp);

  // Exit condition
  DeclRefExpr *CondRef = new (ASTCtx) DeclRefExpr(CondVD,
      CondVD->getType(), VK_RValue, SourceLocation());
  UnaryOperator *NotCond = new (ASTCtx) UnaryOperator(
      CondRef, UO_LNot, CondVD->getType(), VK_RValue, OK_Ordinary,
      SourceLocation());
  BreakStmt *ThenStmt = new (ASTCtx) BreakStmt(SourceLocation());
  IfStmt *ExitStmt = new (ASTCtx) IfStmt(ASTCtx, SourceLocation(), 
                                         NULL, NotCond, ThenStmt);
  BodyStmts.push_back(ExitStmt);
  
  // Body
  Stmt *Body = S->getBody();
  CompoundStmt *CS = dyn_cast<CompoundStmt>(Body);
  assert(CS && "Not a CompoundStmt");

  // Identify each WCR
  VisitRawCompoundStmt(CS, BodyStmts, WCRBody);
  MergeBodyAndWCR(BodyStmts, WCRBody);

  ASTCtx.Deallocate(S);
  ASTCtx.Deallocate(CS);

  // Outer WhileStmt 
  Expr *Cond = CLExprs.getExpr(CLExpressions::ONE);
  Body = MergeWCRsAndMakeCompoundStmt(BodyStmts);
  WhileStmt *WS = new (ASTCtx) WhileStmt(ASTCtx, NULL, Cond, Body,
                                         SourceLocation());
  OuterBody.push_back(WS);

  // Landing pad - empty WCR
  OuterBody.push_back(NewLandingPad(WS));

  return NewStmtList(OuterBody);
}
Exemplo n.º 7
0
void VarCollector::HandleArrayInitList(VarDecl *VDLHS,
                                       string TLHS,
                                       InitListExpr * Inits,
                                       SourceLocation StmtLoc) {

  CompilerInstance &CI = FullDirectives->GetCI(Inits->getLocStart());


  for (unsigned i = 0; i < Inits->getNumInits(); i++) {
  
    Expr * Current = Inits->getInit(i);
  
    InitListExpr * InitList = dyn_cast<InitListExpr>(Current);
    
    if (InitList) {
    
      HandleArrayInitList(VDLHS, TLHS, InitList, StmtLoc);
      
    } else {

      // Get Dominant RHS DeclRef and its expr
      DeclRefExpr * RDominantRef = NULL;
      Expr * RDominantExpr = NULL;

      VarTraverser rvt(Current, RDominantRef, RDominantExpr, CI);
      rvt.TraverseStmt(Current);

      // If there isn't a dominant variable now being pointed to, just return
      if (!RDominantRef) {
        continue;
      }

      // DEBUG:
      // Print out the dominant LHS and RHS
      
/*      llvm::errs() << "Found init of a pointer:\n";
      llvm::errs() << "RHS Ref " << RDominantRef->getDecl()->getName()
                   << " -> " << GetStmtString(RDominantExpr)
                   << " ("
                   << RDominantExpr->getType().getAsString()
                   << ")\n";*/

      VarDecl * VDRHS = dyn_cast<VarDecl>(RDominantRef->getDecl());
      string TRHS = GetType(RDominantExpr);

      const Type * T = RDominantExpr->getType()->getUnqualifiedDesugaredType();

      maybeContaminated(VDLHS, TLHS, VDRHS, TRHS, T, StmtLoc);
    
    }
  
  }

}
Exemplo n.º 8
0
OMPThreadPrivateDecl *Sema::CheckOMPThreadPrivateDecl(
                                 SourceLocation Loc,
                                 ArrayRef<Expr *> VarList) {
  SmallVector<Expr *, 8> Vars;
  for (ArrayRef<Expr *>::iterator I = VarList.begin(),
                                         E = VarList.end();
       I != E; ++I) {
    DeclRefExpr *DE = cast<DeclRefExpr>(*I);
    VarDecl *VD = cast<VarDecl>(DE->getDecl());
    SourceLocation ILoc = DE->getExprLoc();

    // OpenMP [2.9.2, Restrictions, C/C++, p.10]
    //   A threadprivate variable must not have an incomplete type.
    if (RequireCompleteType(ILoc, VD->getType(),
                            diag::err_omp_threadprivate_incomplete_type)) {
      continue;
    }

    // OpenMP [2.9.2, Restrictions, C/C++, p.10]
    //   A threadprivate variable must not have a reference type.
    if (VD->getType()->isReferenceType()) {
      Diag(ILoc, diag::err_omp_ref_type_arg)
        << getOpenMPDirectiveName(OMPD_threadprivate)
        << VD->getType();
      bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
                    VarDecl::DeclarationOnly;
      Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
                                       diag::note_defined_here) << VD;
      continue;
    }

    // Check if this is a TLS variable.
    if (VD->getTLSKind()) {
      Diag(ILoc, diag::err_omp_var_thread_local) << VD;
      bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
                    VarDecl::DeclarationOnly;
      Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
                                       diag::note_defined_here) << VD;
      continue;
    }

    Vars.push_back(*I);
  }
  OMPThreadPrivateDecl *D = 0;
  if (!Vars.empty()) {
    D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
                                     Vars);
    D->setAccess(AS_public);
  }
  return D;
}
Exemplo n.º 9
0
 ValueDecl *valueDeclFromIncExpr(Expr *incExpr)
 {
     UnaryOperator *unaryOperator = dyn_cast_or_null<UnaryOperator>(incExpr);
     if (unaryOperator)
     {
         Expr *unaryOpSubExpr = unaryOperator->getSubExpr();
         if (unaryOpSubExpr && isa<DeclRefExpr>(unaryOpSubExpr))
         {
             DeclRefExpr *declRefExpr = dyn_cast<DeclRefExpr>(unaryOpSubExpr);
             return declRefExpr->getDecl();
         }
     }
     return nullptr;
 }
Exemplo n.º 10
0
NamedDecl* RedundantLocalVariableRule::extractFromReturnStmt(Stmt *stmt) {
  ReturnStmt *returnStmt = dyn_cast<ReturnStmt>(stmt);
  if (returnStmt) {
    Expr *returnValue = returnStmt->getRetValue();
    if (returnValue) {
      ImplicitCastExpr *implicitCastExpr = dyn_cast<ImplicitCastExpr>(returnValue);
      if (implicitCastExpr) {
        DeclRefExpr *returnExpr = dyn_cast<DeclRefExpr>(implicitCastExpr->getSubExpr());
        if (returnExpr) {
          return returnExpr->getFoundDecl();
        }
      }
    }
  }
  return NULL;
}
Exemplo n.º 11
0
//--------------------------------------------------------- 
FunctionDecl* findFunctionDecl(CallExpr* expr)
{
  if (CXXMemberCallExpr* CMC = dyn_cast<CXXMemberCallExpr>(expr))
  {
    return CMC->getMethodDecl();
  }
  
  CastExpr* castExpr;
  Expr* calleeExpr = expr->getCallee();
  while ((castExpr = dyn_cast<CastExpr>(calleeExpr)) != NULL) 
  {
    calleeExpr = castExpr->getSubExpr();
  }

  DeclRefExpr* fnRef = dyn_cast<DeclRefExpr>(calleeExpr);
  return fnRef ? dyn_cast<FunctionDecl>(fnRef->getDecl()) : NULL;
}
Exemplo n.º 12
0
 bool VisitBinaryOperator(BinaryOperator *binaryOperator)
 {
     Expr *leftExpr = binaryOperator->getLHS();
     if (binaryOperator->getOpcode() == BO_Assign && leftExpr && isa<DeclRefExpr>(leftExpr))
     {
         DeclRefExpr *declRefExpr = dyn_cast<DeclRefExpr>(leftExpr);
         for (const auto& name : _names)
         {
             if (declRefExpr->getFoundDecl()->getNameAsString() == name)
             {
                 _binaryOperators.push_back(binaryOperator);
                 break;
             }
         }
     }
     return true;
 }
Exemplo n.º 13
0
Arquivo: Utils.cpp Projeto: KDE/clazy
static bool isArgOfFunc(T expr, FunctionDecl *fDecl, const VarDecl *varDecl, bool byRefOrPtrOnly)
{
    unsigned int param = -1;
    for (auto arg : expr->arguments()) {
        ++param;
        DeclRefExpr *refExpr = dyn_cast<DeclRefExpr>(arg);
        if (!refExpr)  {
            if (clazy_std::hasChildren(arg)) {
                Stmt* firstChild = *(arg->child_begin()); // Can be null (bug #362236)
                refExpr = firstChild ? dyn_cast<DeclRefExpr>(firstChild) : nullptr;
                if (!refExpr)
                    continue;
            } else {
                continue;
            }
        }

        if (refExpr->getDecl() != varDecl) // It's our variable ?
            continue;

        if (!byRefOrPtrOnly) {
            // We found it
            return true;
        }

        // It is, lets see if the callee takes our variable by const-ref
        if (param >= fDecl->param_size())
            continue;

        ParmVarDecl *paramDecl = fDecl->getParamDecl(param);
        if (!paramDecl)
            continue;

        QualType qt = paramDecl->getType();
        const Type *t = qt.getTypePtrOrNull();
        if (!t)
            continue;

        if ((t->isReferenceType() || t->isPointerType()) && !t->getPointeeType().isConstQualified())
            return true; // function receives non-const ref, so our foreach variable cant be const-ref
    }

    return false;
}
Exemplo n.º 14
0
void TransferFunctions::VisitObjCForCollectionStmt(ObjCForCollectionStmt *OS) {
  // Kill the iteration variable.
  DeclRefExpr *DR = nullptr;
  const VarDecl *VD = nullptr;

  Stmt *element = OS->getElement();
  if (DeclStmt *DS = dyn_cast<DeclStmt>(element)) {
    VD = cast<VarDecl>(DS->getSingleDecl());
  }
  else if ((DR = dyn_cast<DeclRefExpr>(cast<Expr>(element)->IgnoreParens()))) {
    VD = cast<VarDecl>(DR->getDecl());
  }
  
  if (VD) {
    val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD);
    if (observer && DR)
      observer->observerKill(DR);
  }
}
Exemplo n.º 15
0
  string NetworkDriverRewriteVisitor::GetSharedStructStr(CallExpr *callExpr)
  {
    string shared_struct_str = "";

    Expr *callee = callExpr->getCallee();
    if (!isa<ImplicitCastExpr>(callee))
      return shared_struct_str;

    ImplicitCastExpr *calleeImplExpr = cast<ImplicitCastExpr>(callee);
    if (!isa<DeclRefExpr>(calleeImplExpr->getSubExpr()))
      return shared_struct_str;

    DeclRefExpr *calleeDeclExpr = cast<DeclRefExpr>(calleeImplExpr->getSubExpr());
    Stmt *body = callExpr->getCalleeDecl()->getBody();

    if (calleeDeclExpr->getNameInfo().getAsString() != "alloc_etherdev")
      shared_struct_str = GetSharedStructStrInFunctionBody(body, false);
    if (calleeDeclExpr->getNameInfo().getAsString() != "alloc_etherdev")
      return shared_struct_str;

    for (auto i = callExpr->arg_begin(), e = callExpr->arg_end(); i != e; ++i)
    {
      if (!isa<ImplicitCastExpr>(*i))
        continue;

      ImplicitCastExpr *argImplExpr = cast<ImplicitCastExpr>(*i);
      if (!isa<UnaryExprOrTypeTraitExpr>(argImplExpr->getSubExpr()))
        continue;

      UnaryExprOrTypeTraitExpr *argExpr = cast<UnaryExprOrTypeTraitExpr>(argImplExpr->getSubExpr());
      ParenExpr *parenExpr = cast<ParenExpr>(argExpr->getArgumentExpr());
      UnaryOperator *uop = cast<UnaryOperator>(parenExpr->getSubExpr());
      ImplicitCastExpr *implExpr = cast<ImplicitCastExpr>(uop->getSubExpr());
      DeclRefExpr *declExpr = cast<DeclRefExpr>(implExpr->getSubExpr());
      ValueDecl *valueDecl = cast<ValueDecl>(declExpr->getDecl());

      shared_struct_str = valueDecl->getType().getAsString(Context->getPrintingPolicy());
      break;
    }

    return shared_struct_str;
  }
void UnnecessaryValueParamCheck::handleMoveFix(const ParmVarDecl &Var,
                                               const DeclRefExpr &CopyArgument,
                                               const ASTContext &Context) {
  auto Diag = diag(CopyArgument.getLocStart(),
                   "parameter %0 is passed by value and only copied once; "
                   "consider moving it to avoid unnecessary copies")
              << &Var;
  // Do not propose fixes in macros since we cannot place them correctly.
  if (CopyArgument.getLocStart().isMacroID())
    return;
  const auto &SM = Context.getSourceManager();
  auto EndLoc = Lexer::getLocForEndOfToken(CopyArgument.getLocation(), 0, SM,
                                           Context.getLangOpts());
  Diag << FixItHint::CreateInsertion(CopyArgument.getLocStart(), "std::move(")
       << FixItHint::CreateInsertion(EndLoc, ")");
  if (auto IncludeFixit = Inserter->CreateIncludeInsertion(
          SM.getFileID(CopyArgument.getLocStart()), "utility",
          /*IsAngled=*/true))
    Diag << *IncludeFixit;
}
Exemplo n.º 17
0
 void Fix(CompoundStmt* CS) {
   if (!CS->size())
     return;
   typedef llvm::SmallVector<Stmt*, 32> Statements;
   Statements Stmts;
   Stmts.append(CS->body_begin(), CS->body_end());
   for (Statements::iterator I = Stmts.begin(); I != Stmts.end(); ++I) {
     if (!TraverseStmt(*I) && !m_HandledDecls.count(m_FoundDRE->getDecl())) {
       Sema::DeclGroupPtrTy VDPtrTy 
         = m_Sema->ConvertDeclToDeclGroup(m_FoundDRE->getDecl());
       StmtResult DS = m_Sema->ActOnDeclStmt(VDPtrTy, 
                                             m_FoundDRE->getLocStart(), 
                                             m_FoundDRE->getLocEnd());
       assert(!DS.isInvalid() && "Invalid DeclStmt.");
       I = Stmts.insert(I, DS.take());
       m_HandledDecls.insert(m_FoundDRE->getDecl());
     }
   }
   CS->setStmts(m_Sema->getASTContext(), Stmts.data(), Stmts.size());
 }
Exemplo n.º 18
0
//--------------------------------------------------------- 
VarDecl* isFortranLoop(ForStmt* Node, const char*& errMsg)
{
  // cond must be of form "x >/</!=/ expr":
  BinaryOperator* condCmp = dyn_cast_or_null<BinaryOperator>(Node->getCond());
  if (condCmp == 0 || 
      ((!condCmp->isRelationalOp()) && condCmp->getOpcode() != BO_NE))
  {
    errMsg = "for-cond not fortran-like (must be x rel expr)";  
    return 0;
  }
  DeclRefExpr* condVar = dyn_cast<DeclRefExpr>(stripParenCasts(condCmp->getLHS()));
  if (condVar == 0 || !condVar->getType()->isIntegerType())
  {
    errMsg = "no integer for-init variable";  
    return 0;
  }
  VarDecl* VD = dyn_cast<VarDecl>(condVar->getDecl());
  if (VD == 0)
  {
    errMsg = "strange unrecognized lhs in for-condition";  
    return 0;
  }

  // inc must be of form "++x/x++":
  UnaryOperator* incStmt = dyn_cast_or_null<UnaryOperator>(Node->getInc());
  if (incStmt == 0 || (!incStmt->isIncrementOp()))
  {
    errMsg = "for-inc not fortran-like (must be ++x/x++)";  
    return 0;
  }
  DeclRefExpr* incVar = dyn_cast<DeclRefExpr>(incStmt->getSubExpr());
  if (incVar == 0 || incVar->getDecl() != VD)
  {
    errMsg = "for-inc doesn't refer to for-cond variable";
    return 0;
  }
  return VD;
}
Exemplo n.º 19
0
Stmt *TransformWCR::VisitIfStmt(IfStmt *S) {
  StmtVector OuterBody;

  // Declaration of the condition variable
  VarDecl *CondVD = NewCondVarDecl(S->getCond()->getType());
  CondDecls.push_back(NewDeclStmt(CondVD));
  
  // Computation of the condition
  DeclRefExpr *LHS = new (ASTCtx) DeclRefExpr(CondVD,
      CondVD->getType(), VK_RValue, SourceLocation());
  BinaryOperator *CondBinOp = new (ASTCtx) BinaryOperator(
      LHS, S->getCond(), BO_Assign, LHS->getType(), 
      VK_RValue, OK_Ordinary, SourceLocation());
  MergeBodyAndCond(OuterBody, CondBinOp);

  // Cond
  DeclRefExpr *CondRef = new (ASTCtx) DeclRefExpr(CondVD,
      CondVD->getType(), VK_RValue, SourceLocation());
  S->setCond(CondRef);

  // Then
  Stmt *Then = S->getThen();
  CompoundStmt *ThenCS = dyn_cast<CompoundStmt>(Then);
  assert(ThenCS && "Not a CompoundStmt");
  S->setThen(VisitCompoundStmt(ThenCS));
  
  // Else
  if (Stmt *Else = S->getElse()) {
    CompoundStmt *ElseCS = dyn_cast<CompoundStmt>(Else);
    assert(ElseCS && "Not a CompoundStmt");
    S->setElse(VisitCompoundStmt(ElseCS));
  }

  OuterBody.push_back(S);

  return NewStmtList(OuterBody);
}
Exemplo n.º 20
0
void VarCollector::HandlePointerInit(VarDecl *VDLHS,
                                     string TLHS,
                                     SourceLocation StmtLoc) {

  CompilerInstance &CI = FullDirectives->GetCI(StmtLoc);

  // Get Dominant RHS DeclRef and its expr
  DeclRefExpr * RDominantRef = NULL;
  Expr * RDominantExpr = NULL;

  VarTraverser rvt(VDLHS->getInit(), RDominantRef, RDominantExpr, CI);
  rvt.TraverseStmt(VDLHS->getInit());

  // If there isn't a dominant variable now being pointed to, just return
  if (!RDominantRef) {
    return;
  }

  // DEBUG:
  // Print out the dominant LHS and RHS
  
  /*llvm::errs() << "Found init of a pointer:\n";
  llvm::errs() << "RHS Ref " << RDominantRef->getDecl()->getName()
               << " -> " << GetStmtString(RDominantExpr)
               << " ("
               << RDominantExpr->getType().getAsString()
               << ")\n";*/

  VarDecl * VDRHS = dyn_cast<VarDecl>(RDominantRef->getDecl());

  string TRHS = GetType(RDominantExpr);

  const Type * T = RDominantExpr->getType()->getUnqualifiedDesugaredType();

  maybeContaminated(VDLHS, TLHS, VDRHS, TRHS, T, StmtLoc);

}
Exemplo n.º 21
0
void TransferFunctions::VisitBinaryOperator(BinaryOperator *E) {
  DeclRefExpr *DRE = nullptr;

  switch (E->getOpcode()) {
    case BO_PtrMemD:
    case BO_PtrMemI:
    default:
      KS.num_ops++;
      if (checkImageAccess(E->getLHS(), READ_WRITE) ||
          checkImageAccess(E->getRHS(), READ_WRITE)) {
        // not supported on image objects
        KS.Diags.Report(E->getOperatorLoc(), KS.DiagIDUnsupportedBO) <<
          E->getOpcodeStr();
        exit(EXIT_FAILURE);
      }
    case BO_Mul:
    case BO_Div:
    case BO_Rem:
    case BO_Add:
    case BO_Sub:
    case BO_Shl:
    case BO_Shr:
    case BO_LT:
    case BO_GT:
    case BO_LE:
    case BO_GE:
    case BO_EQ:
    case BO_NE:
    case BO_And:
    case BO_Xor:
    case BO_Or:
    case BO_LAnd:
    case BO_LOr:
      KS.num_ops++;
      if (checkImageAccess(E->getLHS(), READ_ONLY)) {
        KS.curStmtVectorize = (VectorInfo) (KS.curStmtVectorize|VECTORIZE);
      }
      if (checkImageAccess(E->getRHS(), READ_ONLY)) {
        KS.curStmtVectorize = (VectorInfo) (KS.curStmtVectorize|VECTORIZE);
      }
      break;
    case BO_Assign:
      KS.num_ops++;
      if (checkImageAccess(E->getRHS(), READ_ONLY)) {
        KS.curStmtVectorize = (VectorInfo) (KS.curStmtVectorize|VECTORIZE);
      } else {
        if (isa<DeclRefExpr>(E->getRHS()->IgnoreParenImpCasts())) {
          DRE = dyn_cast<DeclRefExpr>(E->getRHS()->IgnoreParenImpCasts());

          if (isa<VarDecl>(DRE->getDecl())) {
            VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());

            KS.declsToVector[VD] = (VectorInfo)
              (KS.curStmtVectorize|KS.declsToVector[VD]);
          }
        }
      }
      if (!checkImageAccess(E->getLHS(), WRITE_ONLY)) {
        if (isa<DeclRefExpr>(E->getLHS())) {
          DRE = dyn_cast<DeclRefExpr>(E->getLHS());

          if (isa<VarDecl>(DRE->getDecl())) {
            VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());

            KS.declsToVector[VD] = (VectorInfo)
              (KS.curStmtVectorize|KS.declsToVector[VD]);
          }
        } else {
          #ifdef DEBUG_ANALYSIS
          llvm::errs() << "==DEBUG==: is not a DRE (LHS):\n";
          E->getLHS()->dump();
          llvm::errs() << "\n";
          #endif
        }
      }
      // reset vectorization status for next statement
      KS.curStmtVectorize = SCALAR;

      break;
    case BO_MulAssign:
    case BO_DivAssign:
    case BO_RemAssign:
    case BO_AddAssign:
    case BO_SubAssign:
    case BO_ShlAssign:
    case BO_ShrAssign:
    case BO_AndAssign:
    case BO_XorAssign:
    case BO_OrAssign:
      KS.num_ops+=2;
      if (checkImageAccess(E->getRHS(), READ_ONLY)) {
        KS.curStmtVectorize = (VectorInfo) (KS.curStmtVectorize|VECTORIZE);
      } else {
        if (isa<DeclRefExpr>(E->getRHS()->IgnoreParenImpCasts())) {
          DRE = dyn_cast<DeclRefExpr>(E->getRHS()->IgnoreParenImpCasts());

          if (isa<VarDecl>(DRE->getDecl())) {
            VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());

            KS.declsToVector[VD] = (VectorInfo)
              (KS.curStmtVectorize|KS.declsToVector[VD]);
          }
        }
      }
      if (!checkImageAccess(E->getLHS(), READ_WRITE)) {
        if (isa<DeclRefExpr>(E->getLHS())) {
          DRE = dyn_cast<DeclRefExpr>(E->getLHS());

          if (isa<VarDecl>(DRE->getDecl())) {
            VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());

            KS.declsToVector[VD] = (VectorInfo)
              (KS.curStmtVectorize|KS.declsToVector[VD]);
          }
        } else {
          #ifdef DEBUG_ANALYSIS
          llvm::errs() << "==DEBUG==: is not a DRE (LHS):\n";
          E->getLHS()->dump();
          llvm::errs() << "\n";
          #endif
        }
      }
      // reset vectorization status for next statement
      KS.curStmtVectorize = SCALAR;

      break;
    case BO_Comma:
      break;
  }
}
Exemplo n.º 22
0
OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
                                               SourceLocation StartLoc,
                                               SourceLocation LParenLoc,
                                               SourceLocation EndLoc) {
  SmallVector<Expr *, 8> Vars;
  for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end();
       I != E; ++I) {
    assert(*I && "NULL expr in OpenMP firstprivate clause.");
    if (isa<DependentScopeDeclRefExpr>(*I)) {
      // It will be analyzed later.
      Vars.push_back(*I);
      continue;
    }

    SourceLocation ELoc = (*I)->getExprLoc();
    // OpenMP [2.1, C/C++]
    //  A list item is a variable name.
    // OpenMP  [2.9.3.3, Restrictions, p.1]
    //  A variable that is part of another variable (as an array or
    //  structure element) cannot appear in a private clause.
    DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(*I);
    if (!DE || !isa<VarDecl>(DE->getDecl())) {
      Diag(ELoc, diag::err_omp_expected_var_name)
        << (*I)->getSourceRange();
      continue;
    }
    Decl *D = DE->getDecl();
    VarDecl *VD = cast<VarDecl>(D);

    QualType Type = VD->getType();
    if (Type->isDependentType() || Type->isInstantiationDependentType()) {
      // It will be analyzed later.
      Vars.push_back(DE);
      continue;
    }

    // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
    //  A variable that appears in a private clause must not have an incomplete
    //  type or a reference type.
    if (RequireCompleteType(ELoc, Type,
                            diag::err_omp_firstprivate_incomplete_type)) {
      continue;
    }
    if (Type->isReferenceType()) {
      Diag(ELoc, diag::err_omp_clause_ref_type_arg)
        << getOpenMPClauseName(OMPC_firstprivate) << Type;
      bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
                    VarDecl::DeclarationOnly;
      Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
                                       diag::note_defined_here) << VD;
      continue;
    }

    // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
    //  A variable of class type (or array thereof) that appears in a private
    //  clause requires an accesible, unambiguous copy constructor for the
    //  class type.
    Type = Context.getBaseElementType(Type);
    CXXRecordDecl *RD = getLangOpts().CPlusPlus ?
                          Type.getNonReferenceType()->getAsCXXRecordDecl() : 0;
    if (RD) {
      CXXConstructorDecl *CD = LookupCopyingConstructor(RD, 0);
      PartialDiagnostic PD =
        PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
      if (!CD ||
          CheckConstructorAccess(ELoc, CD,
                                 InitializedEntity::InitializeTemporary(Type),
                                 CD->getAccess(), PD) == AR_inaccessible ||
          CD->isDeleted()) {
        Diag(ELoc, diag::err_omp_required_method)
             << getOpenMPClauseName(OMPC_firstprivate) << 1;
        bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
                      VarDecl::DeclarationOnly;
        Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
                                         diag::note_defined_here) << VD;
        Diag(RD->getLocation(), diag::note_previous_decl) << RD;
        continue;
      }
      MarkFunctionReferenced(ELoc, CD);
      DiagnoseUseOfDecl(CD, ELoc);

      CXXDestructorDecl *DD = RD->getDestructor();
      if (DD) {
        if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible ||
            DD->isDeleted()) {
          Diag(ELoc, diag::err_omp_required_method)
               << getOpenMPClauseName(OMPC_firstprivate) << 4;
          bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
                        VarDecl::DeclarationOnly;
          Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
                                           diag::note_defined_here) << VD;
          Diag(RD->getLocation(), diag::note_previous_decl) << RD;
          continue;
        }
        MarkFunctionReferenced(ELoc, DD);
        DiagnoseUseOfDecl(DD, ELoc);
      }
    }

    // If StartLoc and EndLoc are invalid - this is an implicit firstprivate
    // variable and it was checked already.
    if (StartLoc.isValid() && EndLoc.isValid()) {
      DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
      Type = Type.getNonReferenceType().getCanonicalType();
      bool IsConstant = Type.isConstant(Context);
      Type = Context.getBaseElementType(Type);
      // OpenMP [2.4.13, Data-sharing Attribute Clauses]
      //  A list item that specifies a given variable may not appear in more
      // than one clause on the same directive, except that a variable may be
      //  specified in both firstprivate and lastprivate clauses.
      //  TODO: add processing for lastprivate.
      if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
          DVar.RefExpr) {
        Diag(ELoc, diag::err_omp_wrong_dsa)
           << getOpenMPClauseName(DVar.CKind)
           << getOpenMPClauseName(OMPC_firstprivate);
        Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
           << getOpenMPClauseName(DVar.CKind);
        continue;
      }

      // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
      // in a Construct]
      //  Variables with the predetermined data-sharing attributes may not be
      //  listed in data-sharing attributes clauses, except for the cases
      //  listed below. For these exceptions only, listing a predetermined
      //  variable in a data-sharing attribute clause is allowed and overrides
      //  the variable's predetermined data-sharing attributes.
      // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
      // in a Construct, C/C++, p.2]
      //  Variables with const-qualified type having no mutable member may be
      //  listed in a firstprivate clause, even if they are static data members.
      if (!(IsConstant || VD->isStaticDataMember()) && !DVar.RefExpr &&
          DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
        Diag(ELoc, diag::err_omp_wrong_dsa)
           << getOpenMPClauseName(DVar.CKind)
           << getOpenMPClauseName(OMPC_firstprivate);
        Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)
           << getOpenMPClauseName(DVar.CKind);
        continue;
      }

      // OpenMP [2.9.3.4, Restrictions, p.2]
      //  A list item that is private within a parallel region must not appear
      //  in a firstprivate clause on a worksharing construct if any of the
      //  worksharing regions arising from the worksharing construct ever bind
      //  to any of the parallel regions arising from the parallel construct.
      // OpenMP [2.9.3.4, Restrictions, p.3]
      //  A list item that appears in a reduction clause of a parallel construct
      //  must not appear in a firstprivate clause on a worksharing or task
      //  construct if any of the worksharing or task regions arising from the
      //  worksharing or task construct ever bind to any of the parallel regions
      //  arising from the parallel construct.
      // OpenMP [2.9.3.4, Restrictions, p.4]
      //  A list item that appears in a reduction clause in worksharing
      //  construct must not appear in a firstprivate clause in a task construct
      //  encountered during execution of any of the worksharing regions arising
      //  from the worksharing construct.
      // TODO:
    }

    DSAStack->addDSA(VD, DE, OMPC_firstprivate);
    Vars.push_back(DE);
  }

  if (Vars.empty()) return 0;

  return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
                                       Vars);
}
Exemplo n.º 23
0
OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
                                          SourceLocation StartLoc,
                                          SourceLocation LParenLoc,
                                          SourceLocation EndLoc) {
  SmallVector<Expr *, 8> Vars;
  for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end();
       I != E; ++I) {
    assert(*I && "NULL expr in OpenMP private clause.");
    if (isa<DependentScopeDeclRefExpr>(*I)) {
      // It will be analyzed later.
      Vars.push_back(*I);
      continue;
    }

    SourceLocation ELoc = (*I)->getExprLoc();
    // OpenMP [2.1, C/C++]
    //  A list item is a variable name.
    // OpenMP  [2.9.3.3, Restrictions, p.1]
    //  A variable that is part of another variable (as an array or
    //  structure element) cannot appear in a private clause.
    DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(*I);
    if (!DE || !isa<VarDecl>(DE->getDecl())) {
      Diag(ELoc, diag::err_omp_expected_var_name)
        << (*I)->getSourceRange();
      continue;
    }
    Decl *D = DE->getDecl();
    VarDecl *VD = cast<VarDecl>(D);

    QualType Type = VD->getType();
    if (Type->isDependentType() || Type->isInstantiationDependentType()) {
      // It will be analyzed later.
      Vars.push_back(DE);
      continue;
    }

    // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
    //  A variable that appears in a private clause must not have an incomplete
    //  type or a reference type.
    if (RequireCompleteType(ELoc, Type,
                            diag::err_omp_private_incomplete_type)) {
      continue;
    }
    if (Type->isReferenceType()) {
      Diag(ELoc, diag::err_omp_clause_ref_type_arg)
        << getOpenMPClauseName(OMPC_private) << Type;
      bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
                    VarDecl::DeclarationOnly;
      Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
                                       diag::note_defined_here) << VD;
      continue;
    }

    // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
    //  A variable of class type (or array thereof) that appears in a private
    //  clause requires an accesible, unambiguous default constructor for the
    //  class type.
    while (Type.getNonReferenceType()->isArrayType()) {
      Type = cast<ArrayType>(
                 Type.getNonReferenceType().getTypePtr())->getElementType();
    }
    CXXRecordDecl *RD = getLangOpts().CPlusPlus ?
                          Type.getNonReferenceType()->getAsCXXRecordDecl() : 0;
    if (RD) {
      CXXConstructorDecl *CD = LookupDefaultConstructor(RD);
      PartialDiagnostic PD =
        PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
      if (!CD ||
          CheckConstructorAccess(ELoc, CD,
                                 InitializedEntity::InitializeTemporary(Type),
                                 CD->getAccess(), PD) == AR_inaccessible ||
          CD->isDeleted()) {
        Diag(ELoc, diag::err_omp_required_method)
             << getOpenMPClauseName(OMPC_private) << 0;
        bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
                      VarDecl::DeclarationOnly;
        Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
                                         diag::note_defined_here) << VD;
        Diag(RD->getLocation(), diag::note_previous_decl) << RD;
        continue;
      }
      MarkFunctionReferenced(ELoc, CD);
      DiagnoseUseOfDecl(CD, ELoc);

      CXXDestructorDecl *DD = RD->getDestructor();
      if (DD) {
        if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible ||
            DD->isDeleted()) {
          Diag(ELoc, diag::err_omp_required_method)
               << getOpenMPClauseName(OMPC_private) << 4;
          bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
                        VarDecl::DeclarationOnly;
          Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
                                           diag::note_defined_here) << VD;
          Diag(RD->getLocation(), diag::note_previous_decl) << RD;
          continue;
        }
        MarkFunctionReferenced(ELoc, DD);
        DiagnoseUseOfDecl(DD, ELoc);
      }
    }

    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
    // in a Construct]
    //  Variables with the predetermined data-sharing attributes may not be
    //  listed in data-sharing attributes clauses, except for the cases
    //  listed below. For these exceptions only, listing a predetermined
    //  variable in a data-sharing attribute clause is allowed and overrides
    //  the variable's predetermined data-sharing attributes.
    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
      Diag(ELoc, diag::err_omp_wrong_dsa)
         << getOpenMPClauseName(DVar.CKind)
         << getOpenMPClauseName(OMPC_private);
      if (DVar.RefExpr) {
        Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
             << getOpenMPClauseName(DVar.CKind);
      } else {
        Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)
             << getOpenMPClauseName(DVar.CKind);
      }
      continue;
    }

    DSAStack->addDSA(VD, DE, OMPC_private);
    Vars.push_back(DE);
  }

  if (Vars.empty()) return 0;

  return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
}
Exemplo n.º 24
0
		/*
		   this helper function is called when the traversal reaches a node of type Stmt
		 */
		void StmtHelper(Stmt *x){
			//variable used for <cond> </cond>
			//bool condition = false;
			bool isElse = false;
			if(x != NULL){
				string output = "";
				//find current level and next level
				int intLevel = getLevelStmt(x); int intNextLevel = intLevel+1;
				//convert them both to strings to use for output
				string level; string nextLevel;
				stringstream ss;
				ss << intLevel;
				level = ss.str();
				stringstream ss2;
				ss2 << intNextLevel;
				nextLevel = ss2.str();

				const Stmt* parent = getStmtParent(x, Context);
				//PROBLEM
				if(x->getStmtClassName() != std::string("ForStmt") && isFlowControl(x, Context)){
					//return;
				}

				//if the parent is calling any type of funciton then this node should be enclosed in <args> </args>
				string filename;
				if(callStackDebug && !callStack.empty()){
					cerr << "stmt: call stack top: " << callStack.top()->getStmtClassName() << endl;
				}

				while(!callStack.empty() && numClosingArgsNeeded > 0
						&& !isParentStmt(parent, callStack.top()->getStmtClassName())){

					if(debugPrint){
						cerr << "adding args" << endl;
					}
					numClosingArgsNeeded--;
					output += "</args,1>\n";

					callStack.pop();

					if(callStackDebug){
						cerr << "popping" << endl;
						printCallStack();
					}
				}

				if(isParentStmtInCurFile(x,"CXXConstructExpr") && isParentStmt(x, "CXXConstructExpr")){

					if(debugPrint){
						cerr << "setting previousConstructorCall to true" << endl;
					}

				}else if(isParentStmtInCurFile(x,"CXXTemporaryObjectExpr") && isParentStmt(x, "CXXTemporaryObjectExpr")){

					if(debugPrint){
						cerr << "setting previousTempConstructorCallArg" << endl;
					}


				}else if(isParentStmt(x, "CallExpr")){

					if(debugPrint){
						cerr << "setting previousCallArgs to true" << endl;
					}


				}else if(isParentStmt(x, "CXXMemberCallExpr")){

					if(debugPrint){
						cerr << "setting previousMemberCallArgs to true" << endl;
					}

				}

				//if the parent is a variable declaration then this node should be encolsed in <decl> </decl>
				if(isParentStmt(x, "Var")){
					previousRhsDecl = true;
					if(debugPrint){
						cout << "setting prev var to true" << endl;
					}

				}else if(previousRhsDecl && numClosingVarsNeeded > 0){
					//if the current node is not a child of a variable declaration 
					//but the previous node was a child of a variable declation 
					//then we know to print a </decl>
					output +="</variableDecl,1>\n";
					numClosingVarsNeeded--;
					previousRhsDecl = false;
				}


				if(parent != NULL && strcmp(parent->getStmtClassName(), "IfStmt") == 0){
					if(debugPrint){
						cerr << "possibly an if statement" << endl;
					}
					//find the first child of the if statemt
					const Stmt* firstChild = NULL;
					auto children = parent->children();
					for(const Stmt* child : children){
						if(child != NULL){
							firstChild = child;
							break;
						}
					}

					//if the first child is the current node, then we know it is part of the condition
					if(firstChild != NULL  && x->getLocStart() == firstChild->getLocStart()){
						if(debugPrint){
							cerr << "part of the condition" << endl;
						}
						prevCondition = true;
					}else if(prevCondition){
						output +="</cond,1>\n";
						prevCondition = false;
					}


					//find if else
					const IfStmt* ifstmt = (IfStmt*) parent;
					const Stmt* elseStmt = ifstmt->getElse();
					if(elseStmt != NULL){
						if(debugPrint){
							cout << "checking if " << x->getLocStart().printToString(Context->getSourceManager());
							cout << " == " << elseStmt->getLocStart().printToString(Context->getSourceManager());
							cout << " : " << (x->getLocStart() == elseStmt->getLocStart()) << endl;
						}
						if(x->getLocStart() == elseStmt->getLocStart()){
							isElse = true;
						}
					}

				}

				string node = x->getStmtClassName();
				if(node == "ReturnStmt"){
					output += "<return";
				}else if(node == "ForStmt"){
					output += "<forLoop";
				}else if(node == "WhileStmt"){
					output += "<whileLoop";
				}else if(node == "DoStmt"){
					output += "<do";		
				}else if(node == "IfStmt"){
                                        if(parent->getStmtClassName() != std::string("IfStmt")){
						stringstream ssminus;
						ssminus << (intLevel-1);
						output += "<ifBlock," + ssminus.str() + ">\n";
						intLevel += 1;
						stringstream ssif;
						ssif << intLevel;
						level = ssif.str();
					}
					output += "<ifStatement";
				}else if(node == "SwitchStmt"){
					output += "<switch";
				}else if(node == "CaseStmt"){
					output += "<case";
				}else if(node == "CXXMemberCallExpr"){
					CXXMemberCallExpr* ce = (CXXMemberCallExpr*) x;
					Expr* obj = ce->getImplicitObjectArgument();
					CallExpr* expr = (CallExpr*) x;
					output += "<object: ";
					QualType qt = obj->getType();
					output += qt.getBaseTypeIdentifier()->getName().str();
					output += "; calling func: ";
					output += expr->getDirectCallee()->getNameInfo().getAsString();
					output += ", " + level + ">\n";
					output += "<args";
					numClosingArgsNeeded++;
					callStack.push(x);

					if(callStackDebug){
						cerr << "pushing" << endl;
						printCallStack();								
					}

				}else if(node == "CallExpr"){
					CallExpr* expr = (CallExpr*) x;
					output += "<calling func: ";
					output += expr->getDirectCallee()->getNameInfo().getAsString();
					output += ", " + level + ">\n";
					output += "<args";
					numClosingArgsNeeded++;
					callStack.push(x);
					if(callStackDebug){
						cerr << "pushing" << endl;
						printCallStack();								
					}

				}else if(node == "CXXConstructExpr"){
					CXXConstructExpr* ce = (CXXConstructExpr*) x;
					//Decl* CD = ce->getConstructor();

					string filename;
					//if(isInCurFile(Context, CD, filename)){
						CXXMethodDecl* MD =  ce->getConstructor();
						output += "<calling func: ";
						output += MD->getNameInfo().getAsString();
						output += "," + level + ">\n";
						output += "<args";
						numClosingArgsNeeded++;
						callStack.push(x);
						if(callStackDebug){
							cerr << "pushing" << endl;
							printCallStack();								
						}

					//}

				}else if(node == "BinaryOperator"){
					BinaryOperator* binaryOp = (BinaryOperator*) x;
					if(binaryOp->isAssignmentOp()){
						output += "<assignment";
					}else if(binaryOp->isComparisonOp()){
						output += "<comparison";
					}else{
						output += "<binaryOp";
					}
				}else if(node == "UnaryOperator"){
					UnaryOperator* uo = (UnaryOperator*) x;
					string op = uo->getOpcodeStr(uo->getOpcode()).str();
					if(op != "-"){
						output += "<unaryOp";
					}
				}else if(node == "CompoundAssignOperator"){
					output += "<augAssign";
				}else if(node == "CompoundStmt"){
					if(isElse){
						output += "<elseStatement";
					}else{
						output += "<compoundStmt";
					}
				}else if(node == "CXXThrowExpr"){
					output += "<raisingException";
				}else if(node == "CXXTryStmt"){
					output += "<try";
				}else if(node == "CXXCatchStmt"){
					output += "<except";
				}else if(node == "CXXOperatorCallExpr"){
					CXXOperatorCallExpr* ce = (CXXOperatorCallExpr*) x;
					if(ce->isAssignmentOp()){
						output += "<assignment";
					}
				}else if(node == "CXXTemporaryObjectExpr"){
					CXXTemporaryObjectExpr* ce = (CXXTemporaryObjectExpr*) x;
					Decl* CD = ce->getConstructor();



					string filename;
					if(isInCurFile(Context, CD, filename)){
						CXXMethodDecl* MD =  ce->getConstructor();
						output += "<calling func: ";
						output += MD->getNameInfo().getAsString();
						output += "," + level + ">\n";
						output += "<args";
						numClosingArgsNeeded++;
						callStack.push(x);
						if(callStackDebug){
							cerr << "pushing" << endl;
							printCallStack();								
						}


					}

				}else if(node == "DeclRefExpr"){
                                        if(parent != NULL && parent->getStmtClassName() == std::string("ImplicitCastExpr")){
						DeclRefExpr* dr = (DeclRefExpr*) x;
						ValueDecl* d = (ValueDecl*) dr->getDecl();
						//cout << d->getQualType().getAsString() << endl;
						if(d != NULL){
							QualType qt = d->getType();
							//cout << qt.getAsString() << endl;
							if(qt.getAsString() == "std::vector<int, class std::allocator<int> >::const_reference (std::vector::size_type) const noexcept"){
								//string type = io->getName().str();
								//cout << type << endl;

								//if(type == "vector"){
								output += "<expr";
								//}
							}
						}
					}
				}else{
					if(allNodes){
						output += "<";
						output += node;
						output += ">";

					}
				}


				if(output.size() != 0 && !endsIn(output, "</cond,1>\n") && 
						!endsIn(output,"</variableDecl,1>\n") && !endsIn(output,"</args,1>\n") 
						&& !endsIn(output,">") && !endsIn(output, ">\n")){

					output += ", " + level + ">";
					cout << output << endl;
					output = "";
				}else if(output.size() != 0){
					cout << output << endl;
					output = "";
					if(debugPrint){
						cerr << "printing output" << endl;
					}
				}	


			}
		}
Exemplo n.º 25
0
OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
                                         SourceLocation StartLoc,
                                         SourceLocation LParenLoc,
                                         SourceLocation EndLoc) {
  SmallVector<Expr *, 8> Vars;
  for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end();
       I != E; ++I) {
    assert(*I && "NULL expr in OpenMP shared clause.");
    if (isa<DependentScopeDeclRefExpr>(*I)) {
      // It will be analyzed later.
      Vars.push_back(*I);
      continue;
    }

    SourceLocation ELoc = (*I)->getExprLoc();
    // OpenMP [2.1, C/C++]
    //  A list item is a variable name.
    // OpenMP  [2.9.3.4, Restrictions, p.1]
    //  A variable that is part of another variable (as an array or
    //  structure element) cannot appear in a private clause.
    DeclRefExpr *DE = dyn_cast<DeclRefExpr>(*I);
    if (!DE || !isa<VarDecl>(DE->getDecl())) {
      Diag(ELoc, diag::err_omp_expected_var_name)
        << (*I)->getSourceRange();
      continue;
    }
    Decl *D = DE->getDecl();
    VarDecl *VD = cast<VarDecl>(D);

    QualType Type = VD->getType();
    if (Type->isDependentType() || Type->isInstantiationDependentType()) {
      // It will be analyzed later.
      Vars.push_back(DE);
      continue;
    }

    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
    // in a Construct]
    //  Variables with the predetermined data-sharing attributes may not be
    //  listed in data-sharing attributes clauses, except for the cases
    //  listed below. For these exceptions only, listing a predetermined
    //  variable in a data-sharing attribute clause is allowed and overrides
    //  the variable's predetermined data-sharing attributes.
    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && DVar.RefExpr) {
      Diag(ELoc, diag::err_omp_wrong_dsa)
         << getOpenMPClauseName(DVar.CKind)
         << getOpenMPClauseName(OMPC_shared);
      Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
           << getOpenMPClauseName(DVar.CKind);
      continue;
    }

    DSAStack->addDSA(VD, DE, OMPC_shared);
    Vars.push_back(DE);
  }

  if (Vars.empty()) return 0;

  return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
}
Exemplo n.º 26
0
Stmt *TransformWCR::VisitForStmt(ForStmt *S) {
  StmtVector OuterBody;
  StmtVector BodyStmts;
  StmtVector WCRBody;

  // If Init of ForStmt has a DeclStmt, we make a CompoundStmt that encloses
  // an Init stmt and WhileStmt made from orginal ForStmt.
  bool HasDecl = false;

  // Init
  if (Stmt *Init = S->getInit()) {
    if (DeclStmt *DS = dyn_cast<DeclStmt>(Init)) {
      HasDecl = true;
      StmtVector tmpWCR;
      VisitRawDeclStmt(DS, OuterBody, tmpWCR);
      MergeBodyAndWCR(OuterBody, tmpWCR);
    } else {
      MergeBodyAndCond(OuterBody, Init);
    }
  }

  // Declaration of condition variable
  VarDecl *CondVD = NewCondVarDecl(ASTCtx.IntTy);
  CondDecls.push_back(NewDeclStmt(CondVD));

  // Computation of condition
  DeclRefExpr *LHS = new (ASTCtx) DeclRefExpr(CondVD,
      CondVD->getType(), VK_RValue, SourceLocation());
  Expr *Cond = S->getCond();
  if (!Cond) Cond = CLExprs.getExpr(CLExpressions::ONE);
  BinaryOperator *CondBinOp = new (ASTCtx) BinaryOperator(
      LHS, Cond, BO_Assign, LHS->getType(), 
      VK_RValue, OK_Ordinary, SourceLocation());

  // Cond WCR
  MergeBodyAndCond(BodyStmts, CondBinOp);

  // Exit condition
  DeclRefExpr *CondRef = new (ASTCtx) DeclRefExpr(CondVD,
      CondVD->getType(), VK_RValue, SourceLocation());
  UnaryOperator *NotCond = new (ASTCtx) UnaryOperator(
      CondRef, UO_LNot, CondVD->getType(), VK_RValue, OK_Ordinary,
      SourceLocation());
  BreakStmt *ThenStmt = new (ASTCtx) BreakStmt(SourceLocation());
  IfStmt *ExitStmt = new (ASTCtx) IfStmt(ASTCtx, SourceLocation(), 
                                         NULL, NotCond, ThenStmt);
  BodyStmts.push_back(ExitStmt);
  
  // Body
  Stmt *Body = S->getBody();
  CompoundStmt *CS = dyn_cast<CompoundStmt>(Body);
  assert(CS && "Not a CompoundStmt");

  // Identify each WCR
  VisitRawCompoundStmt(CS, BodyStmts, WCRBody);
  MergeBodyAndWCR(BodyStmts, WCRBody);

  // Inc
  if (Expr *Inc = S->getInc()) MergeBodyAndCond(BodyStmts, Inc);

  ASTCtx.Deallocate(S);
  ASTCtx.Deallocate(CS);

  // Outer WhileStmt 
  Cond = CLExprs.getExpr(CLExpressions::ONE);
  Body = MergeWCRsAndMakeCompoundStmt(BodyStmts);
  WhileStmt *WS = new (ASTCtx) WhileStmt(ASTCtx, NULL, Cond, Body,
                                         SourceLocation());
  OuterBody.push_back(WS);

  // Landing pad - empty WCR
  OuterBody.push_back(NewLandingPad(WS));

  CompoundStmt *Out = NewCompoundStmt(OuterBody);
  if (!HasDecl) Out->setIsStmtList(true);
  return Out;
}
Exemplo n.º 27
0
  string NetworkDriverRewriteVisitor::GetSharedStructStrInFunctionBody(Stmt *body, bool doLog)
  {
    string shared_struct_str = "";

    for (auto i = body->child_begin(), e = body->child_end(); i != e; ++i)
    {
      if (isa<DeclStmt>(*i))
      {
        DeclStmt *declStmt = cast<DeclStmt>(*i);
        if (!declStmt->isSingleDecl() && !isa<VarDecl>(declStmt->getSingleDecl()))
          continue;

        VarDecl *varDecl = cast<VarDecl>(declStmt->getSingleDecl());
        if (!isa<ValueDecl>(varDecl))
          continue;

        ValueDecl *value = cast<ValueDecl>(varDecl);

        if (value->getType().getAsString(Context->getPrintingPolicy()) != "struct net_device *")
          continue;
        if (!isa<NamedDecl>(varDecl))
          continue;

        if (varDecl->getInit() == 0 || !isa<CallExpr>(varDecl->getInit()))
          continue;

        CallExpr *callExpr = cast<CallExpr>(varDecl->getInit());
        shared_struct_str = GetSharedStructStr(callExpr);
        if (shared_struct_str != "")
        {
          if (doLog)
          {
            Expr *callee = callExpr->getCallee();
            ImplicitCastExpr *calleeImplExpr = cast<ImplicitCastExpr>(callee);
            DeclRefExpr *calleeDeclExpr = cast<DeclRefExpr>(calleeImplExpr->getSubExpr());
            DI->getInstance().AddSharedStructInformation("whoop_network_shared_struct",
              calleeDeclExpr->getNameInfo().getAsString());
          }

          break;
        }
      }
      else if (isa<BinaryOperator>(*i))
      {
        BinaryOperator *binOp = cast<BinaryOperator>(*i);
        if (!isa<CallExpr>(binOp->getRHS()))
          continue;

        CallExpr *callExpr = cast<CallExpr>(binOp->getRHS());
        shared_struct_str = GetSharedStructStr(callExpr);
        if (shared_struct_str != "")
        {
          if (doLog)
          {
            Expr *callee = callExpr->getCallee();
            ImplicitCastExpr *calleeImplExpr = cast<ImplicitCastExpr>(callee);
            DeclRefExpr *calleeDeclExpr = cast<DeclRefExpr>(calleeImplExpr->getSubExpr());
            DI->getInstance().AddSharedStructInformation("whoop_network_shared_struct",
              calleeDeclExpr->getNameInfo().getAsString());
          }

          break;
        }
      }
    }

    return shared_struct_str;
  }