forked from OSchip/llvm-project
Allow the target field of a CK_ToUnion to be more easily recovered.
llvm-svn: 310963
This commit is contained in:
parent
477b123ead
commit
f1ef796fd9
|
@ -2772,6 +2772,16 @@ public:
|
||||||
path_const_iterator path_begin() const { return path_buffer(); }
|
path_const_iterator path_begin() const { return path_buffer(); }
|
||||||
path_const_iterator path_end() const { return path_buffer() + path_size(); }
|
path_const_iterator path_end() const { return path_buffer() + path_size(); }
|
||||||
|
|
||||||
|
const FieldDecl *getTargetUnionField() const {
|
||||||
|
assert(getCastKind() == CK_ToUnion);
|
||||||
|
return getTargetFieldForToUnionCast(getType(), getSubExpr()->getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
static const FieldDecl *getTargetFieldForToUnionCast(QualType unionType,
|
||||||
|
QualType opType);
|
||||||
|
static const FieldDecl *getTargetFieldForToUnionCast(const RecordDecl *RD,
|
||||||
|
QualType opType);
|
||||||
|
|
||||||
static bool classof(const Stmt *T) {
|
static bool classof(const Stmt *T) {
|
||||||
return T->getStmtClass() >= firstCastExprConstant &&
|
return T->getStmtClass() >= firstCastExprConstant &&
|
||||||
T->getStmtClass() <= lastCastExprConstant;
|
T->getStmtClass() <= lastCastExprConstant;
|
||||||
|
|
|
@ -1695,6 +1695,26 @@ CXXBaseSpecifier **CastExpr::path_buffer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const FieldDecl *CastExpr::getTargetFieldForToUnionCast(QualType unionType,
|
||||||
|
QualType opType) {
|
||||||
|
auto RD = unionType->castAs<RecordType>()->getDecl();
|
||||||
|
return getTargetFieldForToUnionCast(RD, opType);
|
||||||
|
}
|
||||||
|
|
||||||
|
const FieldDecl *CastExpr::getTargetFieldForToUnionCast(const RecordDecl *RD,
|
||||||
|
QualType OpType) {
|
||||||
|
auto &Ctx = RD->getASTContext();
|
||||||
|
RecordDecl::field_iterator Field, FieldEnd;
|
||||||
|
for (Field = RD->field_begin(), FieldEnd = RD->field_end();
|
||||||
|
Field != FieldEnd; ++Field) {
|
||||||
|
if (Ctx.hasSameUnqualifiedType(Field->getType(), OpType) &&
|
||||||
|
!Field->isUnnamedBitfield()) {
|
||||||
|
return *Field;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
ImplicitCastExpr *ImplicitCastExpr::Create(const ASTContext &C, QualType T,
|
ImplicitCastExpr *ImplicitCastExpr::Create(const ASTContext &C, QualType T,
|
||||||
CastKind Kind, Expr *Operand,
|
CastKind Kind, Expr *Operand,
|
||||||
const CXXCastPath *BasePath,
|
const CXXCastPath *BasePath,
|
||||||
|
|
|
@ -2458,24 +2458,17 @@ void CastOperation::CheckCStyleCast() {
|
||||||
// GCC's cast to union extension.
|
// GCC's cast to union extension.
|
||||||
if (DestRecordTy && DestRecordTy->getDecl()->isUnion()) {
|
if (DestRecordTy && DestRecordTy->getDecl()->isUnion()) {
|
||||||
RecordDecl *RD = DestRecordTy->getDecl();
|
RecordDecl *RD = DestRecordTy->getDecl();
|
||||||
RecordDecl::field_iterator Field, FieldEnd;
|
if (CastExpr::getTargetFieldForToUnionCast(RD, SrcType)) {
|
||||||
for (Field = RD->field_begin(), FieldEnd = RD->field_end();
|
Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union)
|
||||||
Field != FieldEnd; ++Field) {
|
<< SrcExpr.get()->getSourceRange();
|
||||||
if (Self.Context.hasSameUnqualifiedType(Field->getType(), SrcType) &&
|
Kind = CK_ToUnion;
|
||||||
!Field->isUnnamedBitfield()) {
|
return;
|
||||||
Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union)
|
} else {
|
||||||
<< SrcExpr.get()->getSourceRange();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Field == FieldEnd) {
|
|
||||||
Self.Diag(OpRange.getBegin(), diag::err_typecheck_cast_to_union_no_type)
|
Self.Diag(OpRange.getBegin(), diag::err_typecheck_cast_to_union_no_type)
|
||||||
<< SrcType << SrcExpr.get()->getSourceRange();
|
<< SrcType << SrcExpr.get()->getSourceRange();
|
||||||
SrcExpr = ExprError();
|
SrcExpr = ExprError();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Kind = CK_ToUnion;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenCL v2.0 s6.13.10 - Allow casts from '0' to event_t type.
|
// OpenCL v2.0 s6.13.10 - Allow casts from '0' to event_t type.
|
||||||
|
|
Loading…
Reference in New Issue