Пример #1
0
// For debugging: there are missing cases: user-defined types, symbols inside of quantifiers, etc.
void VCCmd::printSymbols(Expr e, ExprMap<bool>& cache)
{
  if (cache.find(e) != cache.end()) return;
  switch (e.getKind()) {
    case SKOLEM_VAR:
    case UCONST: {
      cout << e << " : ";
      ExprStream os(d_vc->getEM());
      os.dagFlag(false);
      os << e.getType().getExpr();
      cout << ";" << endl;
      break;
    }
    case APPLY: {
      Expr op = e.getOpExpr();
      if ((op.getKind() == UFUNC) && (cache.find(op) == cache.end())) {
        cout << op << " : ";
        ExprStream os(d_vc->getEM());
        os.dagFlag(false);
        os << op.getType().getExpr();
        cout << ";" << endl;
        cache[op] = true;
      }
      // fall through
    }
    default: {
      Expr::iterator i = e.begin(), iend = e.end();
      for (; i != iend; ++i) {
        printSymbols(*i, cache);
      }
      break;
    }
  }
  cache[e] = true;
}
Пример #2
0
/// Adjust the given return statements so that they formally return
/// the given type.  It should require, at most, an IntegralCast.
static void adjustBlockReturnsToEnum(Sema &S, ArrayRef<ReturnStmt*> returns,
                                     QualType returnType) {
  for (ArrayRef<ReturnStmt*>::iterator
         i = returns.begin(), e = returns.end(); i != e; ++i) {
    ReturnStmt *ret = *i;
    Expr *retValue = ret->getRetValue();
    if (S.Context.hasSameType(retValue->getType(), returnType))
      continue;

    // Right now we only support integral fixup casts.
    assert(returnType->isIntegralOrUnscopedEnumerationType());
    assert(retValue->getType()->isIntegralOrUnscopedEnumerationType());

    ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(retValue);

    Expr *E = (cleanups ? cleanups->getSubExpr() : retValue);
    E = ImplicitCastExpr::Create(S.Context, returnType, CK_IntegralCast,
                                 E, /*base path*/ 0, VK_RValue);
    if (cleanups) {
      cleanups->setSubExpr(E);
    } else {
      ret->setRetValue(E);
    }
  }
}
Пример #3
0
bool IndexSwiftASTWalker::reportRef(ValueDecl *D, SourceLoc Loc) {
  if (startEntityRef(D, Loc)) {
    // Report the accessors that were utilized.
    if (isa<AbstractStorageDecl>(D) && getParentExpr()) {
      bool UsesGetter = false;
      bool UsesSetter = false;
      Expr *CurrE = ExprStack.back();
      Expr *Parent = getParentExpr();
      bool isLValue = !CurrE->getType().isNull() &&
                      CurrE->getType()->is<LValueType>();
      if (isa<LoadExpr>(Parent) || !isLValue) {
        UsesGetter = true;
      } else if (isa<AssignExpr>(Parent)) {
        UsesSetter = true;
      } else {
        UsesGetter = UsesSetter = true;
      }

      AbstractStorageDecl *ASD = cast<AbstractStorageDecl>(D);
      if (UsesGetter)
        if (!reportPseudoAccessor(ASD, AccessorKind::IsGetter, /*IsRef=*/true, Loc))
          return false;
      if (UsesSetter)
        if (!reportPseudoAccessor(ASD, AccessorKind::IsSetter, /*IsRef=*/true, Loc))
          return false;
    }

    assert(EntitiesStack.back().D == D);
    return finishCurrentEntity();
  }

  return !Cancelled;
}
Пример #4
0
nsresult
txXPathOptimizer::optimizePath(Expr* aInExpr, Expr** aOutExpr)
{
    PathExpr* path = static_cast<PathExpr*>(aInExpr);

    uint32_t i;
    Expr* subExpr;
    // look for steps like "//foo" that can be turned into "/descendant::foo"
    // and "//." that can be turned into "/descendant-or-self::node()"
    for (i = 0; (subExpr = path->getSubExprAt(i)); ++i) {
        if (path->getPathOpAt(i) == PathExpr::DESCENDANT_OP &&
            subExpr->getType() == Expr::LOCATIONSTEP_EXPR &&
            !subExpr->getSubExprAt(0)) {
            LocationStep* step = static_cast<LocationStep*>(subExpr);
            if (step->getAxisIdentifier() == LocationStep::CHILD_AXIS) {
                step->setAxisIdentifier(LocationStep::DESCENDANT_AXIS);
                path->setPathOpAt(i, PathExpr::RELATIVE_OP);
            }
            else if (step->getAxisIdentifier() == LocationStep::SELF_AXIS) {
                step->setAxisIdentifier(LocationStep::DESCENDANT_OR_SELF_AXIS);
                path->setPathOpAt(i, PathExpr::RELATIVE_OP);
            }
        }
    }

    // look for expressions that start with a "./"
    subExpr = path->getSubExprAt(0);
    LocationStep* step;
    if (subExpr->getType() == Expr::LOCATIONSTEP_EXPR &&
        path->getSubExprAt(1) &&
        path->getPathOpAt(1) != PathExpr::DESCENDANT_OP) {
        step = static_cast<LocationStep*>(subExpr);
        if (step->getAxisIdentifier() == LocationStep::SELF_AXIS &&
            !step->getSubExprAt(0)) {
            txNodeTest* test = step->getNodeTest();
            txNodeTypeTest* typeTest;
            if (test->getType() == txNodeTest::NODETYPE_TEST &&
                (typeTest = static_cast<txNodeTypeTest*>(test))->
                  getNodeTestType() == txNodeTypeTest::NODE_TYPE) {
                // We have a '.' as first step followed by a single '/'.

                // Check if there are only two steps. If so, return the second
                // as resulting expression.
                if (!path->getSubExprAt(2)) {
                    *aOutExpr = path->getSubExprAt(1);
                    path->setSubExprAt(1, nullptr);

                    return NS_OK;
                }

                // Just delete the '.' step and leave the rest of the PathExpr
                path->deleteExprAt(0);
            }
        }
    }

    return NS_OK;
}
Пример #5
0
CXXRecordDecl *CXXMemberCallExpr::getRecordDecl() {
  Expr* ThisArg = getImplicitObjectArgument();
  if (!ThisArg)
    return 0;

  if (ThisArg->getType()->isAnyPointerType())
    return ThisArg->getType()->getPointeeType()->getAsCXXRecordDecl();

  return ThisArg->getType()->getAsCXXRecordDecl();
}
Пример #6
0
Action::OwningExprResult
Sema::ActOnSelectorExpr(ExprArg BaseExpr, SourceLocation OpLoc,
                        SourceLocation IILoc, IdentifierInfo *II) {
  Expr *Base = BaseExpr.takeAs<Expr>();
  // Note: This will fail for all ExprEmpty()s getting passed in (atm for all
  // numeric literals etc)
  assert(Base && "no base expression");

  // If base is a var, this is a lookup into its type (struct or interface)
  // If base is a type, this could be a MethodExpr.

  LookupResult R(*this, II, IILoc, LookupMemberName);
  OwningExprResult BaseResult = Owned(Base);
  OwningExprResult Result = LookupMemberExpr(R, *Base, OpLoc);
  if (BaseResult.isInvalid())
    return ExprError();
  Base = BaseResult.takeAs<Expr>();

  if (Result.isInvalid()) {
    Owned(Base);
    return ExprError();
  }

  if (Result.get()) {
    return Result;
  }

  Result = BuildMemberReferenceExpr(Base, Base->getType(), OpLoc, R);
  return Result;
}
Пример #7
0
void Tptp::makeApplication(Expr& expr, std::string& name,
                           std::vector<Expr>& args, bool term) {
  if (args.empty()) {        // Its a constant
    if (isDeclared(name)) {  // already appeared
      expr = getVariable(name);
    } else {
      Type t = term ? d_unsorted : getExprManager()->booleanType();
      expr = mkVar(name, t, ExprManager::VAR_FLAG_GLOBAL);  // levelZero
      preemptCommand(new DeclareFunctionCommand(name, expr, t));
    }
  } else {                   // Its an application
    if (isDeclared(name)) {  // already appeared
      expr = getVariable(name);
    } else {
      std::vector<Type> sorts(args.size(), d_unsorted);
      Type t = term ? d_unsorted : getExprManager()->booleanType();
      t = getExprManager()->mkFunctionType(sorts, t);
      expr = mkVar(name, t, ExprManager::VAR_FLAG_GLOBAL);  // levelZero
      preemptCommand(new DeclareFunctionCommand(name, expr, t));
    }
    // args might be rationals, in which case we need to create
    // distinct constants of the "unsorted" sort to represent them
    for (size_t i = 0; i < args.size(); ++i) {
      if (args[i].getType().isReal() &&
          FunctionType(expr.getType()).getArgTypes()[i] == d_unsorted) {
        args[i] = convertRatToUnsorted(args[i]);
      }
    }
    expr = getExprManager()->mkExpr(kind::APPLY_UF, expr, args);
  }
}
Пример #8
0
unsigned compute_degree(ExprManager& exprManager, const Expr& term) {
  unsigned n = term.getNumChildren();    
  unsigned degree = 0;

  // boolean stuff
  if (term.getType() == exprManager.booleanType()) {
    for (unsigned i = 0; i < n; ++ i) {
      degree = std::max(degree, compute_degree(exprManager, term[i]));
    }
    return degree;
  }

  // terms
  if (n == 0) {
    if (term.getKind() == kind::CONST_RATIONAL) {
      return 0;
    } else {
      return 1;
    }
  } else {
    unsigned degree = 0;  
    if (term.getKind() == kind::MULT) {
      for (unsigned i = 0; i < n; ++ i) {
        degree += std::max(degree, compute_degree(exprManager, term[i]));
      }
    } else {
      for (unsigned i = 0; i < n; ++ i) {
        degree = std::max(degree, compute_degree(exprManager, term[i]));
      }
    }    
    return degree;    
  }
}
Пример #9
0
void Tptp::checkLetBinding(const std::vector<Expr>& bvlist, Expr lhs, Expr rhs,
                           bool formula) {
  if (lhs.getKind() != CVC4::kind::APPLY_UF) {
    parseError("malformed let: LHS must be a flat function application");
  }
  const std::multiset<CVC4::Expr> vars{lhs.begin(), lhs.end()};
  if(formula && !lhs.getType().isBoolean()) {
    parseError("malformed let: LHS must be formula");
  }
  for (const CVC4::Expr& var : vars) {
    if (var.hasOperator()) {
      parseError("malformed let: LHS must be flat, illegal child: " +
                 var.toString());
    }
  }

  // ensure all let-bound variables appear on the LHS, and appear only once
  for (const Expr& bound_var : bvlist) {
    const size_t count = vars.count(bound_var);
    if (count == 0) {
      parseError(
          "malformed let: LHS must make use of all quantified variables, "
          "missing `" +
          bound_var.toString() + "'");
    } else if (count >= 2) {
      parseError("malformed let: LHS cannot use same bound variable twice: " +
                 bound_var.toString());
    }
  }
}
Пример #10
0
Stmt *TransformVector::VisitWhileStmt(WhileStmt *Node) {
  DeclVector DeclVec;

  // Cond
  Expr *Cond = Node->getCond();
  if (Cond->getType()->isVectorType()) {
    Node->setCond(ConvertVecLiteralInExpr(DeclVec, Cond));
    if (DeclVec.size() > 0) {
      PushBackDeclStmts(*CurStmtVec, DeclVec);
    }
  } else {
    Node->setCond(TransformExpr(Cond));
  }
  
  // Body
  Stmt *Body = Node->getBody();
  CompoundStmt *CS = dyn_cast<CompoundStmt>(Body);
  if (!CS) {
    // Convert a single stmt Body into a compound stmt.
    SourceLocation loc;
    CS = new (ASTCtx) CompoundStmt(ASTCtx, &Body, 1, loc, loc);
  }
  Node->setBody(TransformStmt(CS));

  // Check if there was a vector literal code motion.
  if (DeclVec.size() > 0) {
    // Add vector literal assignment stmts at the end of the body.
    Node->setBody(MergeBodyAndDecls(Node->getBody(), DeclVec));
  }

  return Node;
}
Пример #11
0
Stmt *TransformVector::VisitDoStmt(DoStmt *Node) {
  // Body
  Stmt *Body = Node->getBody();
  CompoundStmt *CS = dyn_cast<CompoundStmt>(Body);
  if (!CS) {
    // Convert a single stmt Body into a compound stmt.
    SourceLocation loc;
    CS = new (ASTCtx) CompoundStmt(ASTCtx, &Body, 1, loc, loc);
  }
  Node->setBody(TransformStmt(CS));

  // Cond
  Expr *Cond = Node->getCond();
  if (Cond->getType()->isVectorType()) {
    DeclVector DeclVec;
    Node->setCond(ConvertVecLiteralInExpr(DeclVec, Cond));

    if (DeclVec.size() > 0) {
      CS = dyn_cast<CompoundStmt>(Node->getBody());

      StmtVector StmtVec;
      CompoundStmt::body_iterator I, E;
      for (I = CS->body_begin(), E = CS->body_end(); I != E; ++I) {
        StmtVec.push_back(*I);
      }
      PushBackDeclStmts(StmtVec, DeclVec);

      CS->setStmts(ASTCtx, StmtVec.data(), StmtVec.size());
    }
  } else {
    Node->setCond(TransformExpr(Cond));
  }

  return Node;
}
Пример #12
0
Stmt *TransformVector::VisitConditionalOperator(ConditionalOperator *Node) {
  Expr *Cond = Node->getCond();
  QualType CondTy = Cond->getType();
  Expr *LHS = Node->getLHS();
  Expr *RHS = Node->getRHS();

  if (CondTy->isVectorType()) {
    // If the type of Cond is a vector type, change this expr to select().
    DeclVector DeclVec;
    Cond = ConvertVecLiteralInExpr(DeclVec, Cond);
    LHS = ConvertVecLiteralInExpr(DeclVec, LHS);
    RHS = ConvertVecLiteralInExpr(DeclVec, RHS);

    if (DeclVec.size() > 0) {
      PushBackDeclStmts(*CurStmtVec, DeclVec);
    }

    QualType NodeTy = Node->getType();

    ASTCtx.Deallocate(Node);

    Expr *Args[3] = { RHS, LHS, Cond };
    return new (ASTCtx) CallExpr(ASTCtx, 
        CLExprs.getExpr(CLExpressions::SELECT), Args, 3, NodeTy, 
        VK_RValue, SourceLocation());
  } else {
    Node->setCond(TransformExpr(Cond));
    Node->setLHS(TransformExpr(LHS));
    Node->setRHS(TransformExpr(RHS));
  }
  return Node;
}
Пример #13
0
void TransformVector::MakeElementExprs(DeclVector &DeclVec, 
                                       ExprVector &ExprVec,
                                       ExtVectorElementExpr *E) {
  llvm::SmallVector<unsigned, 4> Indices;
  E->getEncodedElementAccess(Indices);
  Expr *BE = E->getBase();

  // If E is an arrow expression, the base pointer expression needs to be 
  // converted into a vector value expression.
  if (E->isArrow()) {
    QualType BaseTy = BE->getType();
    const PointerType *PTy = BaseTy->getAs<PointerType>();
    assert(PTy && "Not a pointer type");
    BE = new (ASTCtx) UnaryOperator(BE, UO_Deref, PTy->getPointeeType(),
                                    VK_RValue, OK_Ordinary, SourceLocation());
    BE = new (ASTCtx) ParenExpr(SourceLocation(), SourceLocation(), BE);
  }

  if (ExtVectorElementExpr *BP = dyn_cast<ExtVectorElementExpr>(BE)) {
    ExprVector BaseExprVec;
    MakeElementExprs(DeclVec, BaseExprVec, BP);
    for (unsigned i = 0, e = Indices.size(); i < e; i++) {
      ExprVec.push_back(BaseExprVec[Indices[i]]);
    }
  } else if (CompoundLiteralExpr *BP = dyn_cast<CompoundLiteralExpr>(BE)) {
    for (unsigned i = 0, e = Indices.size(); i < e; i++) {
      Expr *ElemE = GetSingleValueOfVecLiteral(DeclVec, BP, Indices[i]);
      ExprVec.push_back(ElemE);
    }
  } else {
    Expr *NewBE = ConvertVecLiteralInExpr(DeclVec, BE);
    const ExtVectorType *VecTy = NewBE->getType()->getAs<ExtVectorType>();
    assert(VecTy && "The type of BaseExpr is not a vector type.");

    QualType ElemTy = VecTy->getElementType();
    SourceLocation loc;

    for (unsigned i = 0, e = Indices.size(); i < e; i++) {
      unsigned Kind = CLExpressions::ZERO + Indices[i];
      ArraySubscriptExpr *ElemE = new (ASTCtx) ArraySubscriptExpr(
          NewBE,
          CLExprs.getExpr((CLExpressions::ExprKind)(Kind)), 
          ElemTy, VK_RValue, OK_Ordinary, loc);
      ExprVec.push_back(ElemE);
    }
  }
}
Пример #14
0
llvm::Value * CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) {
  QualType Ty = E->getType();
  const llvm::Type *LTy = ConvertType(Ty)->getPointerTo();
  if (E->isTypeOperand()) {
    Ty = E->getTypeOperand();
    CanQualType CanTy = CGM.getContext().getCanonicalType(Ty);
    Ty = CanTy.getUnqualifiedType().getNonReferenceType();
    if (const RecordType *RT = Ty->getAs<RecordType>()) {
      const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
      if (RD->isPolymorphic())
        return Builder.CreateBitCast(CGM.GenerateRttiRef(RD), LTy);
      return Builder.CreateBitCast(CGM.GenerateRtti(RD), LTy);
    }
    return Builder.CreateBitCast(CGM.GenerateRttiNonClass(Ty), LTy);
  }
  Expr *subE = E->getExprOperand();
  Ty = subE->getType();
  CanQualType CanTy = CGM.getContext().getCanonicalType(Ty);
  Ty = CanTy.getUnqualifiedType().getNonReferenceType();
  if (const RecordType *RT = Ty->getAs<RecordType>()) {
    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
    if (RD->isPolymorphic()) {
      // FIXME: if subE is an lvalue do
      LValue Obj = EmitLValue(subE);
      llvm::Value *This = Obj.getAddress();
      LTy = LTy->getPointerTo()->getPointerTo();
      llvm::Value *V = Builder.CreateBitCast(This, LTy);
      // We need to do a zero check for *p, unless it has NonNullAttr.
      // FIXME: PointerType->hasAttr<NonNullAttr>()
      bool CanBeZero = false;
      if (UnaryOperator *UO = dyn_cast<UnaryOperator>(subE->IgnoreParens()))
        if (UO->getOpcode() == UnaryOperator::Deref)
          CanBeZero = true;
      if (CanBeZero) {
        llvm::BasicBlock *NonZeroBlock = createBasicBlock();
        llvm::BasicBlock *ZeroBlock = createBasicBlock();
        
        llvm::Value *Zero = llvm::Constant::getNullValue(LTy);
        Builder.CreateCondBr(Builder.CreateICmpNE(V, Zero),
                             NonZeroBlock, ZeroBlock);
        EmitBlock(ZeroBlock);
        /// Call __cxa_bad_typeid
        const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext);
        const llvm::FunctionType *FTy;
        FTy = llvm::FunctionType::get(ResultType, false);
        llvm::Value *F = CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid");
        Builder.CreateCall(F)->setDoesNotReturn();
        Builder.CreateUnreachable();
        EmitBlock(NonZeroBlock);
      }
      V = Builder.CreateLoad(V, "vtable");
      V = Builder.CreateConstInBoundsGEP1_64(V, -1ULL);
      V = Builder.CreateLoad(V);
      return V;
    }      
    return Builder.CreateBitCast(CGM.GenerateRtti(RD), LTy);
  }
  return Builder.CreateBitCast(CGM.GenerateRttiNonClass(Ty), LTy);
}
Пример #15
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;

}
Пример #16
0
  void ReturnSynthesizer::Transform() {
    if (!getTransaction()->getCompilationOpts().ResultEvaluation)
      return;

    FunctionDecl* FD = getTransaction()->getWrapperFD();

    int foundAtPos = -1;
    Expr* lastExpr = utils::Analyze::GetOrCreateLastExpr(FD, &foundAtPos, 
                                                         /*omitDS*/false,
                                                         m_Sema);
    if (lastExpr) {
      QualType RetTy = lastExpr->getType();
      if (!RetTy->isVoidType() && RetTy.isTriviallyCopyableType(*m_Context)) {
        // Change the void function's return type
        // We can't PushDeclContext, because we don't have scope.
        Sema::ContextRAII pushedDC(*m_Sema, FD);
        FunctionProtoType::ExtProtoInfo EPI;
        QualType FnTy
          = m_Context->getFunctionType(RetTy, llvm::ArrayRef<QualType>(), EPI);
        FD->setType(FnTy);
        CompoundStmt* CS = cast<CompoundStmt>(FD->getBody());
        assert(CS && "Missing body?");
        // Change it to a return stmt (Avoid dealloc/alloc of all el.)
        *(CS->body_begin() + foundAtPos)
          = m_Sema->ActOnReturnStmt(lastExpr->getExprLoc(), 
                                    lastExpr).take();
      }
    } else if (foundAtPos >= 0) {
      // check for non-void return statement
      CompoundStmt* CS = cast<CompoundStmt>(FD->getBody());
      Stmt* CSS = *(CS->body_begin() + foundAtPos);
      if (ReturnStmt* RS = dyn_cast<ReturnStmt>(CSS)) {
        if (Expr* RetV = RS->getRetValue()) {
          QualType RetTy = RetV->getType();
          // Any return statement will have been "healed" by Sema
          // to correspond to the original void return type of the
          // wrapper, using a ImplicitCastExpr 'void' <ToVoid>.
          // Remove that.
          if (RetTy->isVoidType()) {
            ImplicitCastExpr* VoidCast = dyn_cast<ImplicitCastExpr>(RetV);
            if (VoidCast) {
              RS->setRetValue(VoidCast->getSubExpr());
              RetTy = VoidCast->getSubExpr()->getType();
            }
          }

          if (!RetTy->isVoidType()
              && RetTy.isTriviallyCopyableType(*m_Context)) {
            Sema::ContextRAII pushedDC(*m_Sema, FD);
            FunctionProtoType::ExtProtoInfo EPI;
            QualType FnTy
              = m_Context->getFunctionType(RetTy, llvm::ArrayRef<QualType>(),
                                           EPI);
            FD->setType(FnTy);
          } // not returning void
        } // have return value
      } // is a return statement
    } // have a statement
  }
 bool VisitUnaryOperator(UnaryOperator* UnOp) {
   Expr* SubExpr = UnOp->getSubExpr();
   VisitStmt(SubExpr);
   if (UnOp->getOpcode() == UO_Deref
       && !llvm::isa<clang::CXXThisExpr>(SubExpr)
       && SubExpr->getType().getTypePtr()->isPointerType())
       UnOp->setSubExpr(SynthesizeCheck(SubExpr));
   return true;
 }
Пример #18
0
void ArgumentSource::rewriteType(CanType newType) & {
  assert(!isLValue());
  if (isRValue()) {
    Storage.TheRV.Value.rewriteType(newType);
  } else {
    Expr *expr = Storage.TheExpr;
    if (expr->getType()->isEqual(newType)) return;
    llvm_unreachable("unimplemented! hope it doesn't happen");
  }
}
Пример #19
0
Theorem CNF_Manager::replaceITErec(const Expr& e, Var v, bool translateOnly)
{
  // Quick exit for atomic expressions
  if (e.isAtomic()) return d_commonRules->reflexivityRule(e);

  // Check cache
  Theorem thm;
  bool foundInCache = false;
  ExprHashMap<Theorem>::iterator iMap = d_iteMap.find(e);
  if (iMap != d_iteMap.end()) {
    thm = (*iMap).second;
    foundInCache = true;
  }

  if (e.getKind() == ITE) {
    // Replace non-Bool ITE expressions
    DebugAssert(!e.getType().isBool(), "Expected non-Bool ITE");
    // generate e = x for new x
    if (!foundInCache) thm = d_commonRules->varIntroSkolem(e);
    Theorem thm2 = d_commonRules->symmetryRule(thm);
    thm2 = d_commonRules->iffMP(thm2, d_rules->ifLiftRule(thm2.getExpr(), 1));
    d_translateQueueVars.push_back(v);
    d_translateQueueThms.push_back(thm2);
    d_translateQueueFlags.push_back(translateOnly);
  }
  else {
    // Recursively traverse, replacing ITE's
    vector<Theorem> thms;
    vector<unsigned> changed;
    unsigned index = 0;
    Expr::iterator i, iend;
    if (foundInCache) {
      for(i = e.begin(), iend = e.end(); i!=iend; ++i, ++index) {
        replaceITErec(*i, v, translateOnly);
      }
    }
    else {
      for(i = e.begin(), iend = e.end(); i!=iend; ++i, ++index) {
        thm = replaceITErec(*i, v, translateOnly);
        if (!thm.isRefl()) {
          thms.push_back(thm);
          changed.push_back(index);
        }
      }
      if(changed.size() > 0) {
        thm = d_commonRules->substitutivityRule(e, changed, thms);
      }
      else thm = d_commonRules->reflexivityRule(e);
    }
  }

  // Update cache and return
  if (!foundInCache) d_iteMap[e] = thm;
  return thm;
}
Пример #20
0
Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
  Expr *SubExpr = Importer.Import(E->getSubExpr());
  if (!SubExpr)
    return 0;
  
  return new (Importer.getToContext()) 
                                  ParenExpr(Importer.Import(E->getLParen()),
                                            Importer.Import(E->getRParen()),
                                            SubExpr, SubExpr->getType(),
                                            SubExpr->getValueKind());
}
Пример #21
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);
    
    }
  
  }

}
Пример #22
0
CXXRecordDecl * Utils::namedCastInnerDecl(CXXNamedCastExpr *staticOrDynamicCast)
{
    Expr *e = staticOrDynamicCast->getSubExpr();
    if (!e) return nullptr;
    QualType qt = e->getType();
    const Type *t = qt.getTypePtrOrNull();
    if (!t) return nullptr;
    QualType qt2 = t->getPointeeType();
    const Type *t2 = qt2.getTypePtrOrNull();
    if (!t2) return nullptr;
    return t2->getAsCXXRecordDecl();
}
Пример #23
0
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);
}
Пример #24
0
Type* TypeOfExprType::CreateImpl(ASTContext& Context, Deserializer& D) {
  Expr* E = D.ReadOwnedPtr<Expr>(Context);
  
  std::vector<Type*>& Types = 
    const_cast<std::vector<Type*>&>(Context.getTypes());

  TypeOfExprType* T 
    = new TypeOfExprType(E, Context.getCanonicalType(E->getType()));
  Types.push_back(T);

  return T;
}
Пример #25
0
/// \brief Figure out if an expression could be turned into a call.
///
/// Use this when trying to recover from an error where the programmer may have
/// written just the name of a function instead of actually calling it.
///
/// \param E - The expression to examine.
/// \param ZeroArgCallReturnTy - If the expression can be turned into a call
///  with no arguments, this parameter is set to the type returned by such a
///  call; otherwise, it is set to an empty QualType.
/// \param NonTemplateOverloads - If the expression is an overloaded function
///  name, this parameter is populated with the decls of the various overloads.
bool Sema::isExprCallable(const Expr &E, QualType &ZeroArgCallReturnTy,
                          UnresolvedSetImpl &NonTemplateOverloads) {
  ZeroArgCallReturnTy = QualType();
  NonTemplateOverloads.clear();
  if (const OverloadExpr *Overloads = dyn_cast<OverloadExpr>(&E)) {
    for (OverloadExpr::decls_iterator it = Overloads->decls_begin(),
         DeclsEnd = Overloads->decls_end(); it != DeclsEnd; ++it) {
      // Our overload set may include TemplateDecls, which we'll ignore for our
      // present purpose.
      if (const FunctionDecl *OverloadDecl = dyn_cast<FunctionDecl>(*it)) {
        NonTemplateOverloads.addDecl(*it);
        if (OverloadDecl->getMinRequiredArguments() == 0)
          ZeroArgCallReturnTy = OverloadDecl->getResultType();
      }
    }
    return true;
  }

  if (const DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(&E)) {
    if (const FunctionDecl *Fun = dyn_cast<FunctionDecl>(DeclRef->getDecl())) {
      if (Fun->getMinRequiredArguments() == 0)
        ZeroArgCallReturnTy = Fun->getResultType();
      return true;
    }
  }

  // We don't have an expression that's convenient to get a FunctionDecl from,
  // but we can at least check if the type is "function of 0 arguments".
  QualType ExprTy = E.getType();
  const FunctionType *FunTy = NULL;
  QualType PointeeTy = ExprTy->getPointeeType();
  if (!PointeeTy.isNull())
    FunTy = PointeeTy->getAs<FunctionType>();
  if (!FunTy)
    FunTy = ExprTy->getAs<FunctionType>();
  if (!FunTy && ExprTy == Context.BoundMemberTy) {
    // Look for the bound-member type.  If it's still overloaded, give up,
    // although we probably should have fallen into the OverloadExpr case above
    // if we actually have an overloaded bound member.
    QualType BoundMemberTy = Expr::findBoundMemberType(&E);
    if (!BoundMemberTy.isNull())
      FunTy = BoundMemberTy->castAs<FunctionType>();
  }

  if (const FunctionProtoType *FPT =
      dyn_cast_or_null<FunctionProtoType>(FunTy)) {
    if (FPT->getNumArgs() == 0)
      ZeroArgCallReturnTy = FunTy->getResultType();
    return true;
  }
  return false;
}
Пример #26
0
void TransformVector::TransformVectorLiteralExpr(
    CompoundLiteralExpr *E, Expr **Args, unsigned StartPos) {
  InitListExpr *ILE = dyn_cast<InitListExpr>(E->getInitializer());
  assert(ILE && "ERROR: Vector literal is not an InitListExpr");

  QualType ETy = E->getType();
  const ExtVectorType *EVT = ETy->getAs<ExtVectorType>();
  unsigned NumElems = EVT->getNumElements();
  unsigned VecPos   = 0;
  bool HasOneInitElem = (ILE->getNumInits() == 1);

  for (unsigned i = StartPos; i < StartPos + NumElems; i++) {
    Expr *InitExpr = ILE->getInit(VecPos);
    if (!HasOneInitElem) VecPos++;
    if (InitExpr == NULL) {
      // zero
      Args[i] = CLExprs.getExpr(CLExpressions::ZERO);
      continue;
    }

    QualType InitType = InitExpr->getType();
    if (!InitType->isVectorType()) {
      // scalar element
      Args[i] = TransformExpr(InitExpr);
      continue;
    }

    // vector element
    const ExtVectorType *InitVec = InitType->getAs<ExtVectorType>();
    unsigned InitNumElems = InitVec->getNumElements();

    // Strip off any ParenExpr or CastExprs
    InitExpr = InitExpr->IgnoreParenCasts();
    if (CompoundLiteralExpr *CE = dyn_cast<CompoundLiteralExpr>(InitExpr)) {
      TransformVectorLiteralExpr(CE, Args, i);
      i += (InitNumElems - 1);
    } else {
      CLExpressions::ExprKind kind;
      for (unsigned t = 0; t < InitNumElems; ++t, ++i) {
        // ArraySubscriptExpr
        kind = (CLExpressions::ExprKind)(CLExpressions::ZERO + t);
        Args[i] = new (ASTCtx) ArraySubscriptExpr(
            InitExpr, CLExprs.getExpr(kind), 
            InitType, VK_RValue, OK_Ordinary, SourceLocation());
      }
      --i;
    }
  }

  ASTCtx.Deallocate(ILE);
  ASTCtx.Deallocate(E);
}
Пример #27
0
 Expr collectSortsExpr(Expr e)
 {
   if(substitutions.find(e) != substitutions.end()) {
     return substitutions[e];
   }
   ++depth;
   Expr old_e = e;
   for(unsigned i = 0; i < e.getNumChildren(); ++i) {
     collectSortsExpr(e[i]);
   }
   e = e.substitute(substitutions);
   // cout << "[debug] " << e << " " << e.getKind() << " " << theory::kindToTheoryId(e.getKind()) << endl;
   if(theory::kindToTheoryId(e.getKind()) == theory::THEORY_SETS) {
     SetType t = SetType(e.getType().isBoolean() ? e[1].getType() : e.getType());
     substitutions[e] = add(t, e);
     e = e.substitute(substitutions);
   }
   substitutions[old_e] = e;
   // cout << ";"; for(int i = 0; i < depth; ++i) cout << " "; cout << old_e << " => " << e << endl;
   --depth;
   return e;
 }
Пример #28
0
static Cl::Kinds ClassifyConditional(ASTContext &Ctx,
                                     const ConditionalOperator *E) {
  assert(Ctx.getLangOptions().CPlusPlus &&
         "This is only relevant for C++.");

  Expr *True = E->getTrueExpr();
  Expr *False = E->getFalseExpr();
  // C++ [expr.cond]p2
  //   If either the second or the third operand has type (cv) void, [...]
  //   the result [...] is a prvalue.
  if (True->getType()->isVoidType() || False->getType()->isVoidType())
    return Cl::CL_PRValue;

  // Note that at this point, we have already performed all conversions
  // according to [expr.cond]p3.
  // C++ [expr.cond]p4: If the second and third operands are glvalues of the
  //   same value category [...], the result is of that [...] value category.
  // C++ [expr.cond]p5: Otherwise, the result is a prvalue.
  Cl::Kinds LCl = ClassifyInternal(Ctx, True),
            RCl = ClassifyInternal(Ctx, False);
  return LCl == RCl ? LCl : Cl::CL_PRValue;
}
Пример #29
0
llvm::Value *CodeGenFunction::EmitUPCPointerArithmetic(
    llvm::Value *Pointer, llvm::Value *Index, QualType PtrTy, const Expr *E, bool IsSubtraction) {
  
  const BinaryOperator *expr = cast<BinaryOperator>(E);
  Expr *pointerOperand = expr->getLHS();
  Expr *indexOperand = expr->getRHS();

  if (!IsSubtraction && !Index->getType()->isIntegerTy()) {
    std::swap(Pointer, Index);
    std::swap(pointerOperand, indexOperand);
  }
  return EmitUPCPointerArithmetic(Pointer, Index, PtrTy, indexOperand->getType(), IsSubtraction);
}
Пример #30
0
Stmt *TransformVector::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
  Expr *Target = Node->getTarget();
  if (Target->getType()->isVectorType()) {
    DeclVector DeclVec;
    Node->setTarget(ConvertVecLiteralInExpr(DeclVec, Target));
    if (DeclVec.size() > 0) {
      PushBackDeclStmts(*CurStmtVec, DeclVec);
    }
  } else {
    Node->setTarget(TransformExpr(Node->getTarget()));
  }

  return Node;
}