Extract two more methods from the unary type trait checking. These

provide re-usable forms of the rest of the custom validation done here.
Still no functionality changed here.

With this it should be possible to have an expression-centric code path
and a type-centric code path which don't duplicate logic.

llvm-svn: 132118
This commit is contained in:
Chandler Carruth 2011-05-26 08:53:16 +00:00
parent 98e017b5df
commit cea1aacf40
1 changed files with 41 additions and 19 deletions

View File

@ -3072,6 +3072,42 @@ static bool CheckVecStepTraitOperandType(Sema &S, QualType T,
return false;
}
static bool CheckExtensionTraitOperandType(Sema &S, QualType T,
SourceLocation Loc,
SourceRange ArgRange,
UnaryExprOrTypeTrait TraitKind) {
// C99 6.5.3.4p1:
if (T->isFunctionType()) {
// alignof(function) is allowed as an extension.
if (TraitKind == UETT_SizeOf)
S.Diag(Loc, diag::ext_sizeof_function_type) << ArgRange;
return false;
}
// Allow sizeof(void)/alignof(void) as an extension.
if (T->isVoidType()) {
S.Diag(Loc, diag::ext_sizeof_void_type) << TraitKind << ArgRange;
return false;
}
return true;
}
static bool CheckObjCTraitOperandConstraints(Sema &S, QualType T,
SourceLocation Loc,
SourceRange ArgRange,
UnaryExprOrTypeTrait TraitKind) {
// Reject sizeof(interface) and sizeof(interface<proto>) in 64-bit mode.
if (S.LangOpts.ObjCNonFragileABI && T->isObjCObjectType()) {
S.Diag(Loc, diag::err_sizeof_nonfragile_interface)
<< T << (TraitKind == UETT_SizeOf)
<< ArgRange;
return true;
}
return false;
}
/// \brief Check the constrains on expression operands to unary type expression
/// and type traits.
///
@ -3117,33 +3153,19 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType exprType,
if (ExprKind == UETT_VecStep)
return CheckVecStepTraitOperandType(*this, exprType, OpLoc, ExprRange);
// C99 6.5.3.4p1:
if (exprType->isFunctionType()) {
// alignof(function) is allowed as an extension.
if (ExprKind == UETT_SizeOf)
Diag(OpLoc, diag::ext_sizeof_function_type)
<< ExprRange;
// Whitelist some types as extensions
if (!CheckExtensionTraitOperandType(*this, exprType, OpLoc, ExprRange,
ExprKind))
return false;
}
// Allow sizeof(void)/alignof(void) as an extension.
if (exprType->isVoidType()) {
Diag(OpLoc, diag::ext_sizeof_void_type) << ExprKind << ExprRange;
return false;
}
if (RequireCompleteType(OpLoc, exprType,
PDiag(diag::err_sizeof_alignof_incomplete_type)
<< ExprKind << ExprRange))
return true;
// Reject sizeof(interface) and sizeof(interface<proto>) in 64-bit mode.
if (LangOpts.ObjCNonFragileABI && exprType->isObjCObjectType()) {
Diag(OpLoc, diag::err_sizeof_nonfragile_interface)
<< exprType << (ExprKind == UETT_SizeOf)
<< ExprRange;
if (CheckObjCTraitOperandConstraints(*this, exprType, OpLoc, ExprRange,
ExprKind))
return true;
}
return false;
}