forked from OSchip/llvm-project
rename some variables, no functionality change.
llvm-svn: 64884
This commit is contained in:
parent
b694533a54
commit
432cff5bf4
|
@ -2219,74 +2219,75 @@ Sema::ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
|
||||||
/// Note that lex is not null here, even if this is the gnu "x ?: y" extension.
|
/// Note that lex is not null here, even if this is the gnu "x ?: y" extension.
|
||||||
/// In that case, lex = cond.
|
/// In that case, lex = cond.
|
||||||
inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
|
inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
|
||||||
Expr *&cond, Expr *&lex, Expr *&rex, SourceLocation questionLoc) {
|
Expr *&Cond, Expr *&LHS, Expr *&RHS, SourceLocation QuestionLoc) {
|
||||||
UsualUnaryConversions(cond);
|
UsualUnaryConversions(Cond);
|
||||||
UsualUnaryConversions(lex);
|
UsualUnaryConversions(LHS);
|
||||||
UsualUnaryConversions(rex);
|
UsualUnaryConversions(RHS);
|
||||||
QualType condT = cond->getType();
|
QualType CondTy = Cond->getType();
|
||||||
QualType lexT = lex->getType();
|
QualType LHSTy = LHS->getType();
|
||||||
QualType rexT = rex->getType();
|
QualType RHSTy = RHS->getType();
|
||||||
|
|
||||||
// first, check the condition.
|
// first, check the condition.
|
||||||
if (!cond->isTypeDependent()) {
|
if (!Cond->isTypeDependent()) {
|
||||||
if (!condT->isScalarType()) { // C99 6.5.15p2
|
if (!CondTy->isScalarType()) { // C99 6.5.15p2
|
||||||
Diag(cond->getLocStart(), diag::err_typecheck_cond_expect_scalar) << condT;
|
Diag(Cond->getLocStart(), diag::err_typecheck_cond_expect_scalar)
|
||||||
|
<< CondTy;
|
||||||
return QualType();
|
return QualType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now check the two expressions.
|
// Now check the two expressions.
|
||||||
if ((lex && lex->isTypeDependent()) || (rex && rex->isTypeDependent()))
|
if ((LHS && LHS->isTypeDependent()) || (RHS && RHS->isTypeDependent()))
|
||||||
return Context.DependentTy;
|
return Context.DependentTy;
|
||||||
|
|
||||||
// If both operands have arithmetic type, do the usual arithmetic conversions
|
// If both operands have arithmetic type, do the usual arithmetic conversions
|
||||||
// to find a common type: C99 6.5.15p3,5.
|
// to find a common type: C99 6.5.15p3,5.
|
||||||
if (lexT->isArithmeticType() && rexT->isArithmeticType()) {
|
if (LHSTy->isArithmeticType() && RHSTy->isArithmeticType()) {
|
||||||
UsualArithmeticConversions(lex, rex);
|
UsualArithmeticConversions(LHS, RHS);
|
||||||
return lex->getType();
|
return LHS->getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If both operands are the same structure or union type, the result is that
|
// If both operands are the same structure or union type, the result is that
|
||||||
// type.
|
// type.
|
||||||
if (const RecordType *LHSRT = lexT->getAsRecordType()) { // C99 6.5.15p3
|
if (const RecordType *LHSRT = LHSTy->getAsRecordType()) { // C99 6.5.15p3
|
||||||
if (const RecordType *RHSRT = rexT->getAsRecordType())
|
if (const RecordType *RHSRT = RHSTy->getAsRecordType())
|
||||||
if (LHSRT->getDecl() == RHSRT->getDecl())
|
if (LHSRT->getDecl() == RHSRT->getDecl())
|
||||||
// "If both the operands have structure or union type, the result has
|
// "If both the operands have structure or union type, the result has
|
||||||
// that type." This implies that CV qualifiers are dropped.
|
// that type." This implies that CV qualifiers are dropped.
|
||||||
return lexT.getUnqualifiedType();
|
return LHSTy.getUnqualifiedType();
|
||||||
}
|
}
|
||||||
|
|
||||||
// C99 6.5.15p5: "If both operands have void type, the result has void type."
|
// C99 6.5.15p5: "If both operands have void type, the result has void type."
|
||||||
// The following || allows only one side to be void (a GCC-ism).
|
// The following || allows only one side to be void (a GCC-ism).
|
||||||
if (lexT->isVoidType() || rexT->isVoidType()) {
|
if (LHSTy->isVoidType() || RHSTy->isVoidType()) {
|
||||||
if (!lexT->isVoidType())
|
if (!LHSTy->isVoidType())
|
||||||
Diag(rex->getLocStart(), diag::ext_typecheck_cond_one_void)
|
Diag(RHS->getLocStart(), diag::ext_typecheck_cond_one_void)
|
||||||
<< rex->getSourceRange();
|
<< RHS->getSourceRange();
|
||||||
if (!rexT->isVoidType())
|
if (!RHSTy->isVoidType())
|
||||||
Diag(lex->getLocStart(), diag::ext_typecheck_cond_one_void)
|
Diag(LHS->getLocStart(), diag::ext_typecheck_cond_one_void)
|
||||||
<< lex->getSourceRange();
|
<< LHS->getSourceRange();
|
||||||
ImpCastExprToType(lex, Context.VoidTy);
|
ImpCastExprToType(LHS, Context.VoidTy);
|
||||||
ImpCastExprToType(rex, Context.VoidTy);
|
ImpCastExprToType(RHS, Context.VoidTy);
|
||||||
return Context.VoidTy;
|
return Context.VoidTy;
|
||||||
}
|
}
|
||||||
// C99 6.5.15p6 - "if one operand is a null pointer constant, the result has
|
// C99 6.5.15p6 - "if one operand is a null pointer constant, the result has
|
||||||
// the type of the other operand."
|
// the type of the other operand."
|
||||||
if ((lexT->isPointerType() || lexT->isBlockPointerType() ||
|
if ((LHSTy->isPointerType() || LHSTy->isBlockPointerType() ||
|
||||||
Context.isObjCObjectPointerType(lexT)) &&
|
Context.isObjCObjectPointerType(LHSTy)) &&
|
||||||
rex->isNullPointerConstant(Context)) {
|
RHS->isNullPointerConstant(Context)) {
|
||||||
ImpCastExprToType(rex, lexT); // promote the null to a pointer.
|
ImpCastExprToType(RHS, LHSTy); // promote the null to a pointer.
|
||||||
return lexT;
|
return LHSTy;
|
||||||
}
|
}
|
||||||
if ((rexT->isPointerType() || rexT->isBlockPointerType() ||
|
if ((RHSTy->isPointerType() || RHSTy->isBlockPointerType() ||
|
||||||
Context.isObjCObjectPointerType(rexT)) &&
|
Context.isObjCObjectPointerType(RHSTy)) &&
|
||||||
lex->isNullPointerConstant(Context)) {
|
LHS->isNullPointerConstant(Context)) {
|
||||||
ImpCastExprToType(lex, rexT); // promote the null to a pointer.
|
ImpCastExprToType(LHS, RHSTy); // promote the null to a pointer.
|
||||||
return rexT;
|
return RHSTy;
|
||||||
}
|
}
|
||||||
// Handle the case where both operands are pointers before we handle null
|
// Handle the case where both operands are pointers before we handle null
|
||||||
// pointer constants in case both operands are null pointer constants.
|
// pointer constants in case both operands are null pointer constants.
|
||||||
if (const PointerType *LHSPT = lexT->getAsPointerType()) { // C99 6.5.15p3,6
|
if (const PointerType *LHSPT = LHSTy->getAsPointerType()) { // C99 6.5.15p3,6
|
||||||
if (const PointerType *RHSPT = rexT->getAsPointerType()) {
|
if (const PointerType *RHSPT = RHSTy->getAsPointerType()) {
|
||||||
// get the "pointed to" types
|
// get the "pointed to" types
|
||||||
QualType lhptee = LHSPT->getPointeeType();
|
QualType lhptee = LHSPT->getPointeeType();
|
||||||
QualType rhptee = RHSPT->getPointeeType();
|
QualType rhptee = RHSPT->getPointeeType();
|
||||||
|
@ -2297,24 +2298,24 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
|
||||||
// Figure out necessary qualifiers (C99 6.5.15p6)
|
// Figure out necessary qualifiers (C99 6.5.15p6)
|
||||||
QualType destPointee=lhptee.getQualifiedType(rhptee.getCVRQualifiers());
|
QualType destPointee=lhptee.getQualifiedType(rhptee.getCVRQualifiers());
|
||||||
QualType destType = Context.getPointerType(destPointee);
|
QualType destType = Context.getPointerType(destPointee);
|
||||||
ImpCastExprToType(lex, destType); // add qualifiers if necessary
|
ImpCastExprToType(LHS, destType); // add qualifiers if necessary
|
||||||
ImpCastExprToType(rex, destType); // promote to void*
|
ImpCastExprToType(RHS, destType); // promote to void*
|
||||||
return destType;
|
return destType;
|
||||||
}
|
}
|
||||||
if (rhptee->isVoidType() && lhptee->isIncompleteOrObjectType()) {
|
if (rhptee->isVoidType() && lhptee->isIncompleteOrObjectType()) {
|
||||||
QualType destPointee=rhptee.getQualifiedType(lhptee.getCVRQualifiers());
|
QualType destPointee=rhptee.getQualifiedType(lhptee.getCVRQualifiers());
|
||||||
QualType destType = Context.getPointerType(destPointee);
|
QualType destType = Context.getPointerType(destPointee);
|
||||||
ImpCastExprToType(lex, destType); // add qualifiers if necessary
|
ImpCastExprToType(LHS, destType); // add qualifiers if necessary
|
||||||
ImpCastExprToType(rex, destType); // promote to void*
|
ImpCastExprToType(RHS, destType); // promote to void*
|
||||||
return destType;
|
return destType;
|
||||||
}
|
}
|
||||||
|
|
||||||
QualType compositeType = lexT;
|
QualType compositeType = LHSTy;
|
||||||
|
|
||||||
// If either type is an Objective-C object type then check
|
// If either type is an Objective-C object type then check
|
||||||
// compatibility according to Objective-C.
|
// compatibility according to Objective-C.
|
||||||
if (Context.isObjCObjectPointerType(lexT) ||
|
if (Context.isObjCObjectPointerType(LHSTy) ||
|
||||||
Context.isObjCObjectPointerType(rexT)) {
|
Context.isObjCObjectPointerType(RHSTy)) {
|
||||||
// If both operands are interfaces and either operand can be
|
// If both operands are interfaces and either operand can be
|
||||||
// assigned to the other, use that type as the composite
|
// assigned to the other, use that type as the composite
|
||||||
// type. This allows
|
// type. This allows
|
||||||
|
@ -2332,32 +2333,32 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
|
||||||
const ObjCInterfaceType* RHSIface = rhptee->getAsObjCInterfaceType();
|
const ObjCInterfaceType* RHSIface = rhptee->getAsObjCInterfaceType();
|
||||||
if (LHSIface && RHSIface &&
|
if (LHSIface && RHSIface &&
|
||||||
Context.canAssignObjCInterfaces(LHSIface, RHSIface)) {
|
Context.canAssignObjCInterfaces(LHSIface, RHSIface)) {
|
||||||
compositeType = lexT;
|
compositeType = LHSTy;
|
||||||
} else if (LHSIface && RHSIface &&
|
} else if (LHSIface && RHSIface &&
|
||||||
Context.canAssignObjCInterfaces(RHSIface, LHSIface)) {
|
Context.canAssignObjCInterfaces(RHSIface, LHSIface)) {
|
||||||
compositeType = rexT;
|
compositeType = RHSTy;
|
||||||
} else if (Context.isObjCIdStructType(lhptee) ||
|
} else if (Context.isObjCIdStructType(lhptee) ||
|
||||||
Context.isObjCIdStructType(rhptee)) {
|
Context.isObjCIdStructType(rhptee)) {
|
||||||
compositeType = Context.getObjCIdType();
|
compositeType = Context.getObjCIdType();
|
||||||
} else {
|
} else {
|
||||||
Diag(questionLoc, diag::ext_typecheck_comparison_of_distinct_pointers)
|
Diag(QuestionLoc, diag::ext_typecheck_comparison_of_distinct_pointers)
|
||||||
<< lexT << rexT
|
<< LHSTy << RHSTy
|
||||||
<< lex->getSourceRange() << rex->getSourceRange();
|
<< LHS->getSourceRange() << RHS->getSourceRange();
|
||||||
QualType incompatTy = Context.getObjCIdType();
|
QualType incompatTy = Context.getObjCIdType();
|
||||||
ImpCastExprToType(lex, incompatTy);
|
ImpCastExprToType(LHS, incompatTy);
|
||||||
ImpCastExprToType(rex, incompatTy);
|
ImpCastExprToType(RHS, incompatTy);
|
||||||
return incompatTy;
|
return incompatTy;
|
||||||
}
|
}
|
||||||
} else if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(),
|
} else if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(),
|
||||||
rhptee.getUnqualifiedType())) {
|
rhptee.getUnqualifiedType())) {
|
||||||
Diag(questionLoc, diag::warn_typecheck_cond_incompatible_pointers)
|
Diag(QuestionLoc, diag::warn_typecheck_cond_incompatible_pointers)
|
||||||
<< lexT << rexT << lex->getSourceRange() << rex->getSourceRange();
|
<< LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
|
||||||
// In this situation, we assume void* type. No especially good
|
// In this situation, we assume void* type. No especially good
|
||||||
// reason, but this is what gcc does, and we do have to pick
|
// reason, but this is what gcc does, and we do have to pick
|
||||||
// to get a consistent AST.
|
// to get a consistent AST.
|
||||||
QualType incompatTy = Context.getPointerType(Context.VoidTy);
|
QualType incompatTy = Context.getPointerType(Context.VoidTy);
|
||||||
ImpCastExprToType(lex, incompatTy);
|
ImpCastExprToType(LHS, incompatTy);
|
||||||
ImpCastExprToType(rex, incompatTy);
|
ImpCastExprToType(RHS, incompatTy);
|
||||||
return incompatTy;
|
return incompatTy;
|
||||||
}
|
}
|
||||||
// The pointer types are compatible.
|
// The pointer types are compatible.
|
||||||
|
@ -2367,23 +2368,23 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
|
||||||
// type.
|
// type.
|
||||||
// FIXME: Need to calculate the composite type.
|
// FIXME: Need to calculate the composite type.
|
||||||
// FIXME: Need to add qualifiers
|
// FIXME: Need to add qualifiers
|
||||||
ImpCastExprToType(lex, compositeType);
|
ImpCastExprToType(LHS, compositeType);
|
||||||
ImpCastExprToType(rex, compositeType);
|
ImpCastExprToType(RHS, compositeType);
|
||||||
return compositeType;
|
return compositeType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Need to handle "id<xx>" explicitly. Unlike "id", whose canonical type
|
// Need to handle "id<xx>" explicitly. Unlike "id", whose canonical type
|
||||||
// evaluates to "struct objc_object *" (and is handled above when comparing
|
// evaluates to "struct objc_object *" (and is handled above when comparing
|
||||||
// id with statically typed objects).
|
// id with statically typed objects).
|
||||||
if (lexT->isObjCQualifiedIdType() || rexT->isObjCQualifiedIdType()) {
|
if (LHSTy->isObjCQualifiedIdType() || RHSTy->isObjCQualifiedIdType()) {
|
||||||
// GCC allows qualified id and any Objective-C type to devolve to
|
// GCC allows qualified id and any Objective-C type to devolve to
|
||||||
// id. Currently localizing to here until clear this should be
|
// id. Currently localizing to here until clear this should be
|
||||||
// part of ObjCQualifiedIdTypesAreCompatible.
|
// part of ObjCQualifiedIdTypesAreCompatible.
|
||||||
if (ObjCQualifiedIdTypesAreCompatible(lexT, rexT, true) ||
|
if (ObjCQualifiedIdTypesAreCompatible(LHSTy, RHSTy, true) ||
|
||||||
(lexT->isObjCQualifiedIdType() &&
|
(LHSTy->isObjCQualifiedIdType() &&
|
||||||
Context.isObjCObjectPointerType(rexT)) ||
|
Context.isObjCObjectPointerType(RHSTy)) ||
|
||||||
(rexT->isObjCQualifiedIdType() &&
|
(RHSTy->isObjCQualifiedIdType() &&
|
||||||
Context.isObjCObjectPointerType(lexT))) {
|
Context.isObjCObjectPointerType(LHSTy))) {
|
||||||
// FIXME: This is not the correct composite type. This only
|
// FIXME: This is not the correct composite type. This only
|
||||||
// happens to work because id can more or less be used anywhere,
|
// happens to work because id can more or less be used anywhere,
|
||||||
// however this may change the type of method sends.
|
// however this may change the type of method sends.
|
||||||
|
@ -2391,20 +2392,20 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
|
||||||
// (confusing) incompatible comparison warnings in some
|
// (confusing) incompatible comparison warnings in some
|
||||||
// cases. Investigate.
|
// cases. Investigate.
|
||||||
QualType compositeType = Context.getObjCIdType();
|
QualType compositeType = Context.getObjCIdType();
|
||||||
ImpCastExprToType(lex, compositeType);
|
ImpCastExprToType(LHS, compositeType);
|
||||||
ImpCastExprToType(rex, compositeType);
|
ImpCastExprToType(RHS, compositeType);
|
||||||
return compositeType;
|
return compositeType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Selection between block pointer types is ok as long as they are the same.
|
// Selection between block pointer types is ok as long as they are the same.
|
||||||
if (lexT->isBlockPointerType() && rexT->isBlockPointerType() &&
|
if (LHSTy->isBlockPointerType() && RHSTy->isBlockPointerType() &&
|
||||||
Context.getCanonicalType(lexT) == Context.getCanonicalType(rexT))
|
Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy))
|
||||||
return lexT;
|
return LHSTy;
|
||||||
|
|
||||||
// Otherwise, the operands are not compatible.
|
// Otherwise, the operands are not compatible.
|
||||||
Diag(questionLoc, diag::err_typecheck_cond_incompatible_operands)
|
Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
|
||||||
<< lexT << rexT << lex->getSourceRange() << rex->getSourceRange();
|
<< LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
|
||||||
return QualType();
|
return QualType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue