// 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; }
/// 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); } } }
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; }
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; }
CXXRecordDecl *CXXMemberCallExpr::getRecordDecl() { Expr* ThisArg = getImplicitObjectArgument(); if (!ThisArg) return 0; if (ThisArg->getType()->isAnyPointerType()) return ThisArg->getType()->getPointeeType()->getAsCXXRecordDecl(); return ThisArg->getType()->getAsCXXRecordDecl(); }
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; }
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); } }
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; } }
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()); } } }
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; }
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; }
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; }
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); } } }
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); }
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 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; }
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"); } }
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; }
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()); }
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); } } }
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(); }
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); }
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; }
/// \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; }
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); }
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; }
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; }
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); }
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; }