-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[clang] Implement __is_virtual_base_of()
intrinsic
#100393
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
772b5d8
8b0b0c5
da449c9
8913119
46f02b2
60ccd79
8806fdb
47e274d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6030,6 +6030,32 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceI | |
return cast<CXXRecordDecl>(rhsRecord->getDecl()) | ||
->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getDecl())); | ||
} | ||
case BTT_IsVirtualBaseOf: { | ||
const RecordType *BaseRecord = LhsT->getAs<RecordType>(); | ||
const RecordType *DerivedRecord = RhsT->getAs<RecordType>(); | ||
|
||
if (!BaseRecord || !DerivedRecord) { | ||
DiagnoseVLAInCXXTypeTrait(Self, Lhs, | ||
tok::kw___builtin_is_virtual_base_of); | ||
DiagnoseVLAInCXXTypeTrait(Self, Rhs, | ||
tok::kw___builtin_is_virtual_base_of); | ||
return false; | ||
} | ||
|
||
if (BaseRecord->isUnionType() || DerivedRecord->isUnionType()) | ||
return false; | ||
|
||
if (!BaseRecord->isStructureOrClassType() || | ||
!DerivedRecord->isStructureOrClassType()) | ||
return false; | ||
|
||
if (Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does it mean for there to be a complete derived class type but an incomplete base class type? Shouldn't this require a complete type in both cases to give reasonable diagnostic behavior? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The proposal only mentions that the second type has to be complete. My guess is that the reasoning behind this is that in e.g. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I hadn't realized that
I think it would be much kinder to tell the user that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There is no incomplete base type. We are asking whether some type is a base, and if it isn't, we don't care that it is complete. Type traits don't mandate completeness if they don't need to. |
||
diag::err_incomplete_type)) | ||
return false; | ||
|
||
return cast<CXXRecordDecl>(DerivedRecord->getDecl()) | ||
->isVirtuallyDerivedFrom(cast<CXXRecordDecl>(BaseRecord->getDecl())); | ||
} | ||
case BTT_IsSame: | ||
return Self.Context.hasSameType(LhsT, RhsT); | ||
case BTT_TypeCompatible: { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this check necessary? If it’s not a union, it has to be a class type, right? Or am I missing something obvious?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could be an enum (enums can't have an inheritance relationship) - but this check is enough, we don't need the union check above.
I think this is a mismatch between the standard - which treats union as classes, and clang - which treats everything as record.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought a
TagType
was either aRecordType
(struct
/class
/union
) or anEnumType
(enum
). Can aRecordType
really be anenum
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC ObjC interfaces are also
RecordType
s, and I don't think we want to bother with them.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ObjC types don't inherit from
RecordType
, so I don't think this check is needed.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(and I don't think you can have a virtual objective c interface so there is nothing of ObjC to support here)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isStructureOrClassType
is defined as follows:llvm-project/clang/lib/AST/Type.cpp
Lines 657 to 663 in 0ee32c4
So (1) ObjC doesn't have to inherit from
RecordType
to get involved, and (2) the function has a misleading name.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm,
isInterface()
is defined onTagDecl
, so it seems that aRecordType
can still not be an ObjcInterface from what I can tell. Looks likeRD->isInterface()
check in here is just pointless.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It’s also maybe worth noting that the line containing the check is from 2014, so things may have been different back then