本文整理汇总了C++中QualType::isIntegerType方法的典型用法代码示例。如果您正苦于以下问题:C++ QualType::isIntegerType方法的具体用法?C++ QualType::isIntegerType怎么用?C++ QualType::isIntegerType使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类QualType
的用法示例。
在下文中一共展示了QualType::isIntegerType方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: VisitImplicitCastExpr
void ICEVisitor::VisitImplicitCastExpr(ImplicitCastExpr *CE) {
const NamedDecl *ACD = dyn_cast<NamedDecl>(AC->getDecl());
VisitChildren(CE);
const Expr *SE = CE->getSubExprAsWritten();
std::string sename = SE->getType().getAsString();
const clang::Expr *E = CE->getSubExpr();
if (!(sename == "EventNumber_t"))
return;
QualType OTy = BR.getContext().getCanonicalType(E->getType());
QualType TTy = BR.getContext().getCanonicalType(CE->getType());
QualType ToTy = TTy.getUnqualifiedType();
QualType OrigTy = OTy.getUnqualifiedType();
if (!(ToTy->isIntegerType() || ToTy->isFloatingType()))
return;
if (ToTy->isBooleanType())
return;
CharUnits size_otype = BR.getContext().getTypeSizeInChars(OrigTy);
CharUnits size_ttype = BR.getContext().getTypeSizeInChars(ToTy);
std::string oname = OrigTy.getAsString();
std::string tname = ToTy.getAsString();
if (ToTy->isFloatingType()) {
llvm::SmallString<100> buf;
llvm::raw_svector_ostream os(buf);
os << "Cast-to type, " << tname << ". Cast-from type, " << oname << " . " << support::getQualifiedName(*(ACD));
clang::ento::PathDiagnosticLocation CELoc =
clang::ento::PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
BR.EmitBasicReport(ACD,
CheckName(),
"implicit cast of int type to float type",
"CMS code rules",
os.str(),
CELoc,
CE->getSourceRange());
}
if ((size_otype > size_ttype)) {
llvm::SmallString<100> buf;
llvm::raw_svector_ostream os(buf);
os << "Cast-to type, " << tname << ". Cast-from type, " << oname << ". Cast may result in truncation. "
<< support::getQualifiedName(*(ACD));
clang::ento::PathDiagnosticLocation CELoc =
clang::ento::PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
BR.EmitBasicReport(ACD,
CheckName(),
"implicit cast of int type to smaller int type could truncate",
"CMS code rules",
os.str(),
CELoc,
CE->getSourceRange());
}
if (ToTy->hasSignedIntegerRepresentation() && OrigTy->hasUnsignedIntegerRepresentation() ||
ToTy->hasUnsignedIntegerRepresentation() && OrigTy->hasSignedIntegerRepresentation()) {
llvm::SmallString<100> buf;
llvm::raw_svector_ostream os(buf);
os << "Cast-to type, " << tname << ". Cast-from type, " << oname << ". Changes int sign type. "
<< support::getQualifiedName(*(ACD));
clang::ento::PathDiagnosticLocation CELoc =
clang::ento::PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
BR.EmitBasicReport(ACD,
CheckName(),
"implicit cast changes int sign type",
"CMS code rules",
os.str(),
CELoc,
CE->getSourceRange());
}
return;
}
示例2: evalCast
// FIXME: should rewrite according to the cast kind.
SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
castTy = Context.getCanonicalType(castTy);
originalTy = Context.getCanonicalType(originalTy);
if (val.isUnknownOrUndef() || castTy == originalTy)
return val;
// For const casts, just propagate the value.
if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType())
if (haveSimilarTypes(Context, Context.getPointerType(castTy),
Context.getPointerType(originalTy)))
return val;
// Check for casts from pointers to integers.
if (castTy->isIntegerType() && Loc::isLocType(originalTy))
return evalCastFromLoc(cast<Loc>(val), castTy);
// Check for casts from integers to pointers.
if (Loc::isLocType(castTy) && originalTy->isIntegerType()) {
if (nonloc::LocAsInteger *LV = dyn_cast<nonloc::LocAsInteger>(&val)) {
if (const MemRegion *R = LV->getLoc().getAsRegion()) {
StoreManager &storeMgr = StateMgr.getStoreManager();
R = storeMgr.castRegion(R, castTy);
return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
}
return LV->getLoc();
}
return dispatchCast(val, castTy);
}
// Just pass through function and block pointers.
if (originalTy->isBlockPointerType() || originalTy->isFunctionPointerType()) {
assert(Loc::isLocType(castTy));
return val;
}
// Check for casts from array type to another type.
if (originalTy->isArrayType()) {
// We will always decay to a pointer.
val = StateMgr.ArrayToPointer(cast<Loc>(val));
// Are we casting from an array to a pointer? If so just pass on
// the decayed value.
if (castTy->isPointerType())
return val;
// Are we casting from an array to an integer? If so, cast the decayed
// pointer value to an integer.
assert(castTy->isIntegerType());
// FIXME: Keep these here for now in case we decide soon that we
// need the original decayed type.
// QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
// QualType pointerTy = C.getPointerType(elemTy);
return evalCastFromLoc(cast<Loc>(val), castTy);
}
// Check for casts from a region to a specific type.
if (const MemRegion *R = val.getAsRegion()) {
// FIXME: We should handle the case where we strip off view layers to get
// to a desugared type.
if (!Loc::isLocType(castTy)) {
// FIXME: There can be gross cases where one casts the result of a function
// (that returns a pointer) to some other value that happens to fit
// within that pointer value. We currently have no good way to
// model such operations. When this happens, the underlying operation
// is that the caller is reasoning about bits. Conceptually we are
// layering a "view" of a location on top of those bits. Perhaps
// we need to be more lazy about mutual possible views, even on an
// SVal? This may be necessary for bit-level reasoning as well.
return UnknownVal();
}
// We get a symbolic function pointer for a dereference of a function
// pointer, but it is of function type. Example:
// struct FPRec {
// void (*my_func)(int * x);
// };
//
// int bar(int x);
//
// int f1_a(struct FPRec* foo) {
// int x;
// (*foo->my_func)(&x);
// return bar(x)+1; // no-warning
// }
assert(Loc::isLocType(originalTy) || originalTy->isFunctionType() ||
originalTy->isBlockPointerType() || castTy->isReferenceType());
StoreManager &storeMgr = StateMgr.getStoreManager();
// Delegate to store manager to get the result of casting a region to a
// different type. If the MemRegion* returned is NULL, this expression
// Evaluates to UnknownVal.
R = storeMgr.castRegion(R, castTy);
return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
}
//.........这里部分代码省略.........
示例3: M
/// Create a fake body for dispatch_once.
static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
// Check if we have at least two parameters.
if (D->param_size() != 2)
return 0;
// Check if the first parameter is a pointer to integer type.
const ParmVarDecl *Predicate = D->getParamDecl(0);
QualType PredicateQPtrTy = Predicate->getType();
const PointerType *PredicatePtrTy = PredicateQPtrTy->getAs<PointerType>();
if (!PredicatePtrTy)
return 0;
QualType PredicateTy = PredicatePtrTy->getPointeeType();
if (!PredicateTy->isIntegerType())
return 0;
// Check if the second parameter is the proper block type.
const ParmVarDecl *Block = D->getParamDecl(1);
QualType Ty = Block->getType();
if (!isDispatchBlock(Ty))
return 0;
// Everything checks out. Create a fakse body that checks the predicate,
// sets it, and calls the block. Basically, an AST dump of:
//
// void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) {
// if (!*predicate) {
// *predicate = 1;
// block();
// }
// }
ASTMaker M(C);
// (1) Create the call.
DeclRefExpr *DR = M.makeDeclRefExpr(Block);
ImplicitCastExpr *ICE = M.makeLvalueToRvalue(DR, Ty);
CallExpr *CE = new (C) CallExpr(C, ICE, None, C.VoidTy, VK_RValue,
SourceLocation());
// (2) Create the assignment to the predicate.
IntegerLiteral *IL =
IntegerLiteral::Create(C, llvm::APInt(C.getTypeSize(C.IntTy), (uint64_t) 1),
C.IntTy, SourceLocation());
BinaryOperator *B =
M.makeAssignment(
M.makeDereference(
M.makeLvalueToRvalue(
M.makeDeclRefExpr(Predicate), PredicateQPtrTy),
PredicateTy),
M.makeIntegralCast(IL, PredicateTy),
PredicateTy);
// (3) Create the compound statement.
Stmt *Stmts[2];
Stmts[0] = B;
Stmts[1] = CE;
CompoundStmt *CS = M.makeCompound(ArrayRef<Stmt*>(Stmts, 2));
// (4) Create the 'if' condition.
ImplicitCastExpr *LValToRval =
M.makeLvalueToRvalue(
M.makeDereference(
M.makeLvalueToRvalue(
M.makeDeclRefExpr(Predicate),
PredicateQPtrTy),
PredicateTy),
PredicateTy);
UnaryOperator *UO = new (C) UnaryOperator(LValToRval, UO_LNot, C.IntTy,
VK_RValue, OK_Ordinary,
SourceLocation());
// (5) Create the 'if' statement.
IfStmt *If = new (C) IfStmt(C, SourceLocation(), 0, UO, CS);
return If;
}
示例4: ConvertedInt
const GRState *SimpleConstraintManager::AssumeSymRel(const GRState *state,
const SymExpr *LHS,
BinaryOperator::Opcode op,
const llvm::APSInt& Int) {
assert(BinaryOperator::isComparisonOp(op) &&
"Non-comparison ops should be rewritten as comparisons to zero.");
// We only handle simple comparisons of the form "$sym == constant"
// or "($sym+constant1) == constant2".
// The adjustment is "constant1" in the above expression. It's used to
// "slide" the solution range around for modular arithmetic. For example,
// x < 4 has the solution [0, 3]. x+2 < 4 has the solution [0-2, 3-2], which
// in modular arithmetic is [0, 1] U [UINT_MAX-1, UINT_MAX]. It's up to
// the subclasses of SimpleConstraintManager to handle the adjustment.
llvm::APSInt Adjustment;
// First check if the LHS is a simple symbol reference.
SymbolRef Sym = dyn_cast<SymbolData>(LHS);
if (Sym) {
Adjustment = 0;
} else {
// Next, see if it's a "($sym+constant1)" expression.
const SymIntExpr *SE = dyn_cast<SymIntExpr>(LHS);
// We don't handle "($sym1+$sym2)".
// Give up and assume the constraint is feasible.
if (!SE)
return state;
// We don't handle "(<expr>+constant1)".
// Give up and assume the constraint is feasible.
Sym = dyn_cast<SymbolData>(SE->getLHS());
if (!Sym)
return state;
// Get the constant out of the expression "($sym+constant1)".
switch (SE->getOpcode()) {
case BO_Add:
Adjustment = SE->getRHS();
break;
case BO_Sub:
Adjustment = -SE->getRHS();
break;
default:
// We don't handle non-additive operators.
// Give up and assume the constraint is feasible.
return state;
}
}
// FIXME: This next section is a hack. It silently converts the integers to
// be of the same type as the symbol, which is not always correct. Really the
// comparisons should be performed using the Int's type, then mapped back to
// the symbol's range of values.
GRStateManager &StateMgr = state->getStateManager();
ASTContext &Ctx = StateMgr.getContext();
QualType T = Sym->getType(Ctx);
assert(T->isIntegerType() || Loc::IsLocType(T));
unsigned bitwidth = Ctx.getTypeSize(T);
bool isSymUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T);
// Convert the adjustment.
Adjustment.setIsUnsigned(isSymUnsigned);
Adjustment.extOrTrunc(bitwidth);
// Convert the right-hand side integer.
llvm::APSInt ConvertedInt(Int, isSymUnsigned);
ConvertedInt.extOrTrunc(bitwidth);
switch (op) {
default:
// No logic yet for other operators. Assume the constraint is feasible.
return state;
case BO_EQ:
return AssumeSymEQ(state, Sym, ConvertedInt, Adjustment);
case BO_NE:
return AssumeSymNE(state, Sym, ConvertedInt, Adjustment);
case BO_GT:
return AssumeSymGT(state, Sym, ConvertedInt, Adjustment);
case BO_GE:
return AssumeSymGE(state, Sym, ConvertedInt, Adjustment);
case BO_LT:
return AssumeSymLT(state, Sym, ConvertedInt, Adjustment);
case BO_LE:
return AssumeSymLE(state, Sym, ConvertedInt, Adjustment);
} // end switch
}
示例5: CheckOpen
void UnixAPIChecker::CheckOpen(CheckerContext &C, const CallExpr *CE) const {
ProgramStateRef state = C.getState();
if (CE->getNumArgs() < 2) {
// The frontend should issue a warning for this case, so this is a sanity
// check.
return;
} else if (CE->getNumArgs() == 3) {
const Expr *Arg = CE->getArg(2);
QualType QT = Arg->getType();
if (!QT->isIntegerType()) {
ReportOpenBug(C, state,
"Third argument to 'open' is not an integer",
Arg->getSourceRange());
return;
}
} else if (CE->getNumArgs() > 3) {
ReportOpenBug(C, state,
"Call to 'open' with more than three arguments",
CE->getArg(3)->getSourceRange());
return;
}
// The definition of O_CREAT is platform specific. We need a better way
// of querying this information from the checking environment.
if (!Val_O_CREAT.hasValue()) {
if (C.getASTContext().getTargetInfo().getTriple().getVendor()
== llvm::Triple::Apple)
Val_O_CREAT = 0x0200;
else {
// FIXME: We need a more general way of getting the O_CREAT value.
// We could possibly grovel through the preprocessor state, but
// that would require passing the Preprocessor object to the ExprEngine.
// See also: MallocChecker.cpp / M_ZERO.
return;
}
}
// Now check if oflags has O_CREAT set.
const Expr *oflagsEx = CE->getArg(1);
const SVal V = state->getSVal(oflagsEx, C.getLocationContext());
if (!V.getAs<NonLoc>()) {
// The case where 'V' can be a location can only be due to a bad header,
// so in this case bail out.
return;
}
NonLoc oflags = V.castAs<NonLoc>();
NonLoc ocreateFlag = C.getSValBuilder()
.makeIntVal(Val_O_CREAT.getValue(), oflagsEx->getType()).castAs<NonLoc>();
SVal maskedFlagsUC = C.getSValBuilder().evalBinOpNN(state, BO_And,
oflags, ocreateFlag,
oflagsEx->getType());
if (maskedFlagsUC.isUnknownOrUndef())
return;
DefinedSVal maskedFlags = maskedFlagsUC.castAs<DefinedSVal>();
// Check if maskedFlags is non-zero.
ProgramStateRef trueState, falseState;
std::tie(trueState, falseState) = state->assume(maskedFlags);
// Only emit an error if the value of 'maskedFlags' is properly
// constrained;
if (!(trueState && !falseState))
return;
if (CE->getNumArgs() < 3) {
ReportOpenBug(C, trueState,
"Call to 'open' requires a third argument when "
"the 'O_CREAT' flag is set",
oflagsEx->getSourceRange());
}
}
示例6: Audit
bool AuditCFNumberCreate::Audit(ExplodedNode* N,GRStateManager&){
const CallExpr* CE =
cast<CallExpr>(cast<PostStmt>(N->getLocation()).getStmt());
const Expr* Callee = CE->getCallee();
SVal CallV = N->getState()->getSVal(Callee);
const FunctionDecl* FD = CallV.getAsFunctionDecl();
if (!FD || FD->getIdentifier() != II || CE->getNumArgs()!=3)
return false;
// Get the value of the "theType" argument.
SVal TheTypeVal = N->getState()->getSVal(CE->getArg(1));
// FIXME: We really should allow ranges of valid theType values, and
// bifurcate the state appropriately.
nonloc::ConcreteInt* V = dyn_cast<nonloc::ConcreteInt>(&TheTypeVal);
if (!V)
return false;
uint64_t NumberKind = V->getValue().getLimitedValue();
Optional<uint64_t> TargetSize = GetCFNumberSize(Ctx, NumberKind);
// FIXME: In some cases we can emit an error.
if (!TargetSize.isKnown())
return false;
// Look at the value of the integer being passed by reference. Essentially
// we want to catch cases where the value passed in is not equal to the
// size of the type being created.
SVal TheValueExpr = N->getState()->getSVal(CE->getArg(2));
// FIXME: Eventually we should handle arbitrary locations. We can do this
// by having an enhanced memory model that does low-level typing.
loc::MemRegionVal* LV = dyn_cast<loc::MemRegionVal>(&TheValueExpr);
if (!LV)
return false;
const TypedRegion* R = dyn_cast<TypedRegion>(LV->StripCasts());
if (!R)
return false;
QualType T = Ctx.getCanonicalType(R->getValueType(Ctx));
// FIXME: If the pointee isn't an integer type, should we flag a warning?
// People can do weird stuff with pointers.
if (!T->isIntegerType())
return false;
uint64_t SourceSize = Ctx.getTypeSize(T);
// CHECK: is SourceSize == TargetSize
if (SourceSize == TargetSize)
return false;
AddError(R, CE->getArg(2), N, SourceSize, TargetSize, NumberKind);
// FIXME: We can actually create an abstract "CFNumber" object that has
// the bits initialized to the provided values.
return SourceSize < TargetSize;
}
示例7: eval_rexpr
// caller must free returned value
const EmuVal* eval_rexpr(const Expr* e){
errs() << "\nDEBUG: about to eval rexpr:\n";
e->dump();
if(isa<IntegerLiteral>(e)){
const IntegerLiteral *obj = (const IntegerLiteral*)e;
APInt i = obj->getValue();
if(i.slt(EMU_MIN_INT) || i.sgt(EMU_MAX_INT)){
e->dump();
cant_handle();
}
return new EmuNum<NUM_TYPE_INT>(i);
} else if(isa<CharacterLiteral>(e)){
const CharacterLiteral *obj = (const CharacterLiteral*)e;
unsigned int i = obj->getValue();
if(i > 127){
e->dump();
cant_handle();
}
return new EmuNum<NUM_TYPE_CHAR>(new APInt(8, i, true));
} else if(isa<UnaryOperator>(e)){
const UnaryOperator *obj = (const UnaryOperator*)e;
const Expr* sub = obj->getSubExpr();
const auto op = obj->getOpcode();
switch(op){
case UO_AddrOf:
{
lvalue arg = eval_lexpr(sub);
return new EmuPtr(arg.ptr, e->getType());
}
case UO_LNot:
case UO_Minus:
{
const EmuVal* arg = eval_rexpr(sub);
if(!arg->obj_type->isIntegerType()){
cant_cast();
}
if(op == UO_LNot){
return ((const EmuNumGeneric*)arg)->lnot();
} else if (op == UO_Minus){
return ((const EmuNumGeneric*)arg)->neg();
}
}
case UO_Deref:
case UO_Extension:
case UO_Imag:
case UO_Real:
case UO_Not:
case UO_PostInc:
case UO_PostDec:
case UO_PreInc:
case UO_PreDec:
case UO_Plus:
default:
llvm::errs() << "Got opcode " << obj->getOpcode() << "\n";
cant_handle();
}
} else if(isa<BinaryOperator>(e)){
const BinaryOperator* ex = (const BinaryOperator*)e;
BinaryOperatorKind op = ex->getOpcode();
// right always an rexpr
const EmuVal *right = eval_rexpr(ex->getRHS());
switch(op){
case BO_Assign:
{
lvalue left = eval_lexpr(ex->getLHS());
const EmuVal* ans = right->cast_to(left.type);
delete right;
left.ptr.block->write(ans, left.ptr.offset);
return ans;
}
case BO_LT:
case BO_GT:
case BO_LE:
case BO_GE:
case BO_EQ:
case BO_NE:
{
const EmuVal *left = eval_rexpr(ex->getLHS());
QualType tl = left->obj_type.getCanonicalType();
QualType tr = right->obj_type.getCanonicalType();
if(tl != IntType || tr != IntType){
left->obj_type.dump();
right->obj_type.dump();
cant_handle();
}
const llvm::APInt* lval = &((const EmuNum<NUM_TYPE_INT>*)left)->val;
llvm::APInt rval = ((const EmuNum<NUM_TYPE_INT>*)right)->val;
int ans;
if(lval->isNegative()){
if(op == BO_LT) ans = (lval->slt(rval))?1:0;
else if(op==BO_GT) ans = (lval->sgt(rval))?1:0;
else if(op==BO_LE) ans = (lval->sle(rval))?1:0;
else if(op==BO_GE) ans = (lval->sge(rval))?1:0;
else if(op==BO_EQ) ans = (lval->eq( rval))?1:0;
else if(op==BO_NE) ans = (lval->ne( rval))?1:0;
} else if(rval.isNegative()){
//.........这里部分代码省略.........
示例8: checkPreStmt
void CFNumberCreateChecker::checkPreStmt(const CallExpr *CE,
CheckerContext &C) const {
ProgramStateRef state = C.getState();
const FunctionDecl *FD = C.getCalleeDecl(CE);
if (!FD)
return;
ASTContext &Ctx = C.getASTContext();
if (!II)
II = &Ctx.Idents.get("CFNumberCreate");
if (FD->getIdentifier() != II || CE->getNumArgs() != 3)
return;
// Get the value of the "theType" argument.
const LocationContext *LCtx = C.getLocationContext();
SVal TheTypeVal = state->getSVal(CE->getArg(1), LCtx);
// FIXME: We really should allow ranges of valid theType values, and
// bifurcate the state appropriately.
nonloc::ConcreteInt* V = dyn_cast<nonloc::ConcreteInt>(&TheTypeVal);
if (!V)
return;
uint64_t NumberKind = V->getValue().getLimitedValue();
Optional<uint64_t> TargetSize = GetCFNumberSize(Ctx, NumberKind);
// FIXME: In some cases we can emit an error.
if (!TargetSize.isKnown())
return;
// Look at the value of the integer being passed by reference. Essentially
// we want to catch cases where the value passed in is not equal to the
// size of the type being created.
SVal TheValueExpr = state->getSVal(CE->getArg(2), LCtx);
// FIXME: Eventually we should handle arbitrary locations. We can do this
// by having an enhanced memory model that does low-level typing.
loc::MemRegionVal* LV = dyn_cast<loc::MemRegionVal>(&TheValueExpr);
if (!LV)
return;
const TypedValueRegion* R = dyn_cast<TypedValueRegion>(LV->stripCasts());
if (!R)
return;
QualType T = Ctx.getCanonicalType(R->getValueType());
// FIXME: If the pointee isn't an integer type, should we flag a warning?
// People can do weird stuff with pointers.
if (!T->isIntegerType())
return;
uint64_t SourceSize = Ctx.getTypeSize(T);
// CHECK: is SourceSize == TargetSize
if (SourceSize == TargetSize)
return;
// Generate an error. Only generate a sink if 'SourceSize < TargetSize';
// otherwise generate a regular node.
//
// FIXME: We can actually create an abstract "CFNumber" object that has
// the bits initialized to the provided values.
//
if (ExplodedNode *N = SourceSize < TargetSize ? C.generateSink()
: C.addTransition()) {
SmallString<128> sbuf;
llvm::raw_svector_ostream os(sbuf);
os << (SourceSize == 8 ? "An " : "A ")
<< SourceSize << " bit integer is used to initialize a CFNumber "
"object that represents "
<< (TargetSize == 8 ? "an " : "a ")
<< TargetSize << " bit integer. ";
if (SourceSize < TargetSize)
os << (TargetSize - SourceSize)
<< " bits of the CFNumber value will be garbage." ;
else
os << (SourceSize - TargetSize)
<< " bits of the input integer will be lost.";
if (!BT)
BT.reset(new APIMisuse("Bad use of CFNumberCreate"));
BugReport *report = new BugReport(*BT, os.str(), N);
report->addRange(CE->getArg(2)->getSourceRange());
C.EmitReport(report);
}
}
示例9: evalBinOpNN
//.........这里部分代码省略.........
// If both the LHS and the current expression are additive,
// fold their constants.
if (BinaryOperator::isAdditiveOp(op)) {
BinaryOperator::Opcode lop = symIntExpr->getOpcode();
if (BinaryOperator::isAdditiveOp(lop)) {
// resultTy may not be the best type to convert to, but it's
// probably the best choice in expressions with mixed type
// (such as x+1U+2LL). The rules for implicit conversions should
// choose a reasonable type to preserve the expression, and will
// at least match how the value is going to be used.
const llvm::APSInt &first =
BasicVals.Convert(resultTy, symIntExpr->getRHS());
const llvm::APSInt &second =
BasicVals.Convert(resultTy, rhsInt->getValue());
const llvm::APSInt *newRHS;
if (lop == op)
newRHS = BasicVals.evalAPSInt(BO_Add, first, second);
else
newRHS = BasicVals.evalAPSInt(BO_Sub, first, second);
return MakeSymIntVal(symIntExpr->getLHS(), lop, *newRHS, resultTy);
}
}
// Otherwise, make a SymExprVal out of the expression.
return MakeSymIntVal(symIntExpr, op, rhsInt->getValue(), resultTy);
}
case nonloc::ConcreteIntKind: {
const nonloc::ConcreteInt& lhsInt = cast<nonloc::ConcreteInt>(lhs);
// Is the RHS a symbol we can simplify?
// FIXME: This was mostly copy/pasted from the LHS-is-a-symbol case.
if (const nonloc::SymbolVal *srhs = dyn_cast<nonloc::SymbolVal>(&rhs)) {
SymbolRef RSym = srhs->getSymbol();
if (RSym->getType(Context)->isIntegerType()) {
if (const llvm::APSInt *Constant = state->getSymVal(RSym)) {
// The symbol evaluates to a constant.
const llvm::APSInt *rhs_I;
if (BinaryOperator::isRelationalOp(op))
rhs_I = &BasicVals.Convert(lhsInt.getValue(), *Constant);
else
rhs_I = &BasicVals.Convert(resultTy, *Constant);
rhs = nonloc::ConcreteInt(*rhs_I);
}
}
}
if (isa<nonloc::ConcreteInt>(rhs)) {
return lhsInt.evalBinOp(*this, op, cast<nonloc::ConcreteInt>(rhs));
} else {
const llvm::APSInt& lhsValue = lhsInt.getValue();
// Swap the left and right sides and flip the operator if doing so
// allows us to better reason about the expression (this is a form
// of expression canonicalization).
// While we're at it, catch some special cases for non-commutative ops.
NonLoc tmp = rhs;
rhs = lhs;
lhs = tmp;
switch (op) {
case BO_LT:
case BO_GT:
case BO_LE:
case BO_GE:
op = ReverseComparison(op);
示例10: M
/// Create a fake body for dispatch_once.
static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
// Check if we have at least two parameters.
if (D->param_size() != 2)
return nullptr;
// Check if the first parameter is a pointer to integer type.
const ParmVarDecl *Predicate = D->getParamDecl(0);
QualType PredicateQPtrTy = Predicate->getType();
const PointerType *PredicatePtrTy = PredicateQPtrTy->getAs<PointerType>();
if (!PredicatePtrTy)
return nullptr;
QualType PredicateTy = PredicatePtrTy->getPointeeType();
if (!PredicateTy->isIntegerType())
return nullptr;
// Check if the second parameter is the proper block type.
const ParmVarDecl *Block = D->getParamDecl(1);
QualType Ty = Block->getType();
if (!isDispatchBlock(Ty))
return nullptr;
// Everything checks out. Create a fakse body that checks the predicate,
// sets it, and calls the block. Basically, an AST dump of:
//
// void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) {
// if (*predicate != ~0l) {
// *predicate = ~0l;
// block();
// }
// }
ASTMaker M(C);
// (1) Create the call.
CallExpr *CE = CallExpr::Create(
/*ASTContext=*/C,
/*StmtClass=*/M.makeLvalueToRvalue(/*Expr=*/Block),
/*args=*/None,
/*QualType=*/C.VoidTy,
/*ExprValueType=*/VK_RValue,
/*SourceLocation=*/SourceLocation());
// (2) Create the assignment to the predicate.
Expr *DoneValue =
new (C) UnaryOperator(M.makeIntegerLiteral(0, C.LongTy), UO_Not, C.LongTy,
VK_RValue, OK_Ordinary, SourceLocation(),
/*CanOverflow*/false);
BinaryOperator *B =
M.makeAssignment(
M.makeDereference(
M.makeLvalueToRvalue(
M.makeDeclRefExpr(Predicate), PredicateQPtrTy),
PredicateTy),
M.makeIntegralCast(DoneValue, PredicateTy),
PredicateTy);
// (3) Create the compound statement.
Stmt *Stmts[] = { B, CE };
CompoundStmt *CS = M.makeCompound(Stmts);
// (4) Create the 'if' condition.
ImplicitCastExpr *LValToRval =
M.makeLvalueToRvalue(
M.makeDereference(
M.makeLvalueToRvalue(
M.makeDeclRefExpr(Predicate),
PredicateQPtrTy),
PredicateTy),
PredicateTy);
Expr *GuardCondition = M.makeComparison(LValToRval, DoneValue, BO_NE);
// (5) Create the 'if' statement.
auto *If = IfStmt::Create(C, SourceLocation(),
/* IsConstexpr=*/false,
/* init=*/nullptr,
/* var=*/nullptr,
/* cond=*/GuardCondition,
/* then=*/CS);
return If;
}
示例11: BuildInstanceMessage
//.........这里部分代码省略.........
} else if (const ObjCObjectPointerType *OCIType
= ReceiverType->getAsObjCInterfacePointerType()) {
// We allow sending a message to a pointer to an interface (an object).
ClassDecl = OCIType->getInterfaceDecl();
// FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
// faster than the following method (which can do *many* linear searches).
// The idea is to add class info to MethodPool.
Method = ClassDecl->lookupInstanceMethod(Sel);
if (!Method) {
// Search protocol qualifiers.
for (ObjCObjectPointerType::qual_iterator QI = OCIType->qual_begin(),
E = OCIType->qual_end(); QI != E; ++QI) {
if ((Method = (*QI)->lookupInstanceMethod(Sel)))
break;
}
}
if (!Method) {
// If we have implementations in scope, check "private" methods.
Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
if (!Method && (!Receiver || !isSelfExpr(Receiver))) {
// If we still haven't found a method, look in the global pool. This
// behavior isn't very desirable, however we need it for GCC
// compatibility. FIXME: should we deviate??
if (OCIType->qual_empty()) {
Method = LookupInstanceMethodInGlobalPool(Sel,
SourceRange(LBracLoc, RBracLoc));
if (Method && !OCIType->getInterfaceDecl()->isForwardDecl())
Diag(Loc, diag::warn_maynot_respond)
<< OCIType->getInterfaceDecl()->getIdentifier() << Sel;
}
}
}
if (Method && DiagnoseUseOfDecl(Method, Loc))
return ExprError();
} else if (!Context.getObjCIdType().isNull() &&
(ReceiverType->isPointerType() ||
ReceiverType->isIntegerType())) {
// Implicitly convert integers and pointers to 'id' but emit a warning.
Diag(Loc, diag::warn_bad_receiver_type)
<< ReceiverType
<< Receiver->getSourceRange();
if (ReceiverType->isPointerType())
ImpCastExprToType(Receiver, Context.getObjCIdType(),
CastExpr::CK_BitCast);
else
ImpCastExprToType(Receiver, Context.getObjCIdType(),
CastExpr::CK_IntegralToPointer);
ReceiverType = Receiver->getType();
}
else if (getLangOptions().CPlusPlus &&
!PerformContextuallyConvertToObjCId(Receiver)) {
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Receiver)) {
Receiver = ICE->getSubExpr();
ReceiverType = Receiver->getType();
}
return BuildInstanceMessage(Owned(Receiver),
ReceiverType,
SuperLoc,
Sel,
Method,
LBracLoc,
RBracLoc,
move(ArgsIn));
} else {
// Reject other random receiver types (e.g. structs).
Diag(Loc, diag::err_bad_receiver_type)
<< ReceiverType << Receiver->getSourceRange();
return ExprError();
}
}
}
// Check the message arguments.
unsigned NumArgs = ArgsIn.size();
Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release());
QualType ReturnType;
if (CheckMessageArgumentTypes(Args, NumArgs, Sel, Method, false,
LBracLoc, RBracLoc, ReturnType))
return ExprError();
if (!ReturnType->isVoidType()) {
if (RequireCompleteType(LBracLoc, ReturnType,
diag::err_illegal_message_expr_incomplete_type))
return ExprError();
}
// Construct the appropriate ObjCMessageExpr instance.
Expr *Result;
if (SuperLoc.isValid())
Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc,
SuperLoc, /*IsInstanceSuper=*/true,
ReceiverType, Sel, Method,
Args, NumArgs, RBracLoc);
else
Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, Receiver,
Sel, Method, Args, NumArgs, RBracLoc);
return MaybeBindToTemporary(Result);
}