]> granicus.if.org Git - clang/commitdiff
Type::isObjectType now implements the (more sensible) C++ definition
authorDouglas Gregor <dgregor@apple.com>
Tue, 24 Mar 2009 20:32:41 +0000 (20:32 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 24 Mar 2009 20:32:41 +0000 (20:32 +0000)
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
lib/AST/Type.cpp
lib/Sema/SemaOverload.cpp
lib/Sema/SemaTemplate.cpp
lib/Sema/SemaType.cpp

index 580f78c2972911c18dc2618afcc4d4f78782f043..3453cb09dfc09b301360656a5bf203b0b1e39993 100644 (file)
@@ -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.
index 77d006e644980ffd027ac1df277a3bf847f27149..19a3f144234a20d31ca5c97983f619054b4a448d 100644 (file)
@@ -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 {
index 9f88a87474048ff5742a3ab0059c95e9212c398d..025a245c6ca6518c6041c021acb84a9d0472d54d 100644 (file)
@@ -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] = { 
index c7899d1ecc534ea9cbbd9d7643512fc8d040176d..fd39a9150f983097cf93f04a22d1b6dceda48d69 100644 (file)
@@ -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)) {
index fdd6ff91fe65de04774f2d439dbcd2eb4b0c8bae..196a30642b50e45cddf0d0833c2bed1c1398ed55 100644 (file)
@@ -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(),