From bad0e656c3732e3539a9cd6525de721d7e47408b Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 24 Mar 2009 20:32:41 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67648 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Type.h | 8 ++++++-- lib/AST/Type.cpp | 5 +++-- lib/Sema/SemaOverload.cpp | 5 ++--- lib/Sema/SemaTemplate.cpp | 5 ++--- lib/Sema/SemaType.cpp | 2 +- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 580f78c297..3453cb09df 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -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. diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 77d006e644..19a3f14423 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -113,11 +113,12 @@ bool Type::isVoidType() const { } bool Type::isObjectType() const { - if (isa(CanonicalType) || isa(CanonicalType)) + if (isa(CanonicalType) || isa(CanonicalType) || + isa(CanonicalType) || isVoidType()) return false; if (const ExtQualType *AS = dyn_cast(CanonicalType)) return AS->getBaseType()->isObjectType(); - return !CanonicalType->isIncompleteType(); + return true; } bool Type::isDerivedType() const { diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 9f88a87474..025a245c6c 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -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] = { diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index c7899d1ecc..fd39a9150f 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -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)) { diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index fdd6ff91fe..196a30642b 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -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(), -- 2.40.0