static DeclRefExpr* EvalAddr(Expr *E) {
// We should only be called for evaluating pointer expressions.
- assert (E->getType()->isPointerType() && "EvalAddr only works on pointers");
+ assert ((E->getType()->isPointerType() ||
+ E->getType()->isObjcQualifiedIdType())
+ && "EvalAddr only works on pointers");
// Our "symbolic interpreter" is just a dispatch off the currently
// viewed AST node. We then recursively traverse the AST by calling
ImplicitCastExpr *IE = cast<ImplicitCastExpr>(E);
Expr* SubExpr = IE->getSubExpr();
- if (SubExpr->getType()->isPointerType())
+ if (SubExpr->getType()->isPointerType() ||
+ SubExpr->getType()->isObjcQualifiedIdType())
return EvalAddr(SubExpr);
else
return EvalVal(SubExpr);
promoteExprToType(rex, lType); // promote the pointer to pointer
return Context.IntTy;
}
+ if ((lType->isObjcQualifiedIdType() || rType->isObjcQualifiedIdType())
+ && Context.ObjcQualifiedIdTypesAreCompatible(lType, rType)) {
+ promoteExprToType(rex, lType);
+ return Context.IntTy;
+ }
if (lType->isPointerType() && rType->isIntegerType()) {
if (!RHSIsNull)
Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer,
return isa<FunctionType>(CanonicalType);
}
inline bool Type::isPointerType() const {
- return isa<PointerType>(CanonicalType) ||
- isa<ObjcQualifiedIdType>(CanonicalType);
+ return isa<PointerType>(CanonicalType);
}
inline bool Type::isFunctionPointerType() const {
if (const PointerType* T = getAsPointerType())