forked from OSchip/llvm-project
Type::isObjectType now implements the (more sensible) C++ definition
of "object type" rather than the C definition of "object type". The difference is that C's "object type" excludes incomplete types such as struct X; However, C's definition also makes it far too easy to use isObjectType as a means to detect incomplete types when in fact we should use other means (e.g., Sema::RequireCompleteType) that cope with C++ semantics, including template instantiation. I've already audited every use of isObjectType and isIncompleteType to ensure that they are doing the right thing for both C and C++, so this is patch does not change any functionality. llvm-svn: 67648
This commit is contained in:
parent
24e02b1043
commit
64259f5143
|
@ -288,8 +288,12 @@ public:
|
|||
/// Types are partitioned into 3 broad categories (C99 6.2.5p1):
|
||||
/// object types, function types, and incomplete types.
|
||||
|
||||
/// isObjectType - types that fully describe objects. An object is a region
|
||||
/// of memory that can be examined and stored into (H&S).
|
||||
/// \brief Determines whether the type describes an object in memory.
|
||||
///
|
||||
/// Note that this definition of object type corresponds to the C++
|
||||
/// definition of object type, which includes incomplete types, as
|
||||
/// opposed to the C definition (which does not include incomplete
|
||||
/// types).
|
||||
bool isObjectType() const;
|
||||
|
||||
/// isIncompleteType - Return true if this is an incomplete type.
|
||||
|
|
|
@ -113,11 +113,12 @@ bool Type::isVoidType() const {
|
|||
}
|
||||
|
||||
bool Type::isObjectType() const {
|
||||
if (isa<FunctionType>(CanonicalType) || isa<ReferenceType>(CanonicalType))
|
||||
if (isa<FunctionType>(CanonicalType) || isa<ReferenceType>(CanonicalType) ||
|
||||
isa<IncompleteArrayType>(CanonicalType) || isVoidType())
|
||||
return false;
|
||||
if (const ExtQualType *AS = dyn_cast<ExtQualType>(CanonicalType))
|
||||
return AS->getBaseType()->isObjectType();
|
||||
return !CanonicalType->isIncompleteType();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Type::isDerivedType() const {
|
||||
|
|
|
@ -916,8 +916,7 @@ bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
|
|||
// An rvalue of type "pointer to cv T," where T is an object type,
|
||||
// can be converted to an rvalue of type "pointer to cv void" (C++
|
||||
// 4.10p2).
|
||||
if (FromPointeeType->isIncompleteOrObjectType() &&
|
||||
ToPointeeType->isVoidType()) {
|
||||
if (FromPointeeType->isObjectType() && ToPointeeType->isVoidType()) {
|
||||
ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
|
||||
ToPointeeType,
|
||||
ToType, Context);
|
||||
|
@ -2776,7 +2775,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
|
|||
for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin();
|
||||
Ptr != CandidateTypes.pointer_end(); ++Ptr) {
|
||||
// Skip pointer types that aren't pointers to object types.
|
||||
if (!(*Ptr)->getAsPointerType()->getPointeeType()->isIncompleteOrObjectType())
|
||||
if (!(*Ptr)->getAsPointerType()->getPointeeType()->isObjectType())
|
||||
continue;
|
||||
|
||||
QualType ParamTypes[2] = {
|
||||
|
|
|
@ -1395,8 +1395,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
|
|||
// -- for a non-type template-parameter of type pointer to
|
||||
// object, qualification conversions (4.4) and the
|
||||
// array-to-pointer conversion (4.2) are applied.
|
||||
assert(ParamType->getAsPointerType()->getPointeeType()
|
||||
->isIncompleteOrObjectType() &&
|
||||
assert(ParamType->getAsPointerType()->getPointeeType()->isObjectType() &&
|
||||
"Only object pointers allowed here");
|
||||
|
||||
if (ArgType->isArrayType()) {
|
||||
|
@ -1435,7 +1434,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
|
|||
// identical) type of the template-argument. The
|
||||
// template-parameter is bound directly to the
|
||||
// template-argument, which must be an lvalue.
|
||||
assert(ParamRefType->getPointeeType()->isIncompleteOrObjectType() &&
|
||||
assert(ParamRefType->getPointeeType()->isObjectType() &&
|
||||
"Only object references allowed here");
|
||||
|
||||
if (!Context.hasSameUnqualifiedType(ParamRefType->getPointeeType(), ArgType)) {
|
||||
|
|
|
@ -235,7 +235,7 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) {
|
|||
Result->getAsPointerType()->getPointeeType() :
|
||||
Result->getAsReferenceType()->getPointeeType();
|
||||
|
||||
// If we have a pointer or reference, the pointee must have an object or
|
||||
// If we have a pointer or reference, the pointee must have an object
|
||||
// incomplete type.
|
||||
if (!EltTy->isIncompleteOrObjectType()) {
|
||||
Diag(DS.getRestrictSpecLoc(),
|
||||
|
|
Loading…
Reference in New Issue