[cfe-commits] r49100 - in /cfe/trunk: include/clang/AST/Type.h lib/AST/ASTContext.cpp lib/AST/Type.cpp lib/CodeGen/CGExprScalar.cpp lib/CodeGen/CodeGenTypes.cpp lib/Sema/SemaType.cpp

Chris Lattner sabre at nondot.org
Wed Apr 2 10:35:07 PDT 2008


Author: lattner
Date: Wed Apr  2 12:35:06 2008
New Revision: 49100

URL: http://llvm.org/viewvc/llvm-project?rev=49100&view=rev
Log:
add a common base class "PointerLikeType" for PointerType and ReferenceType,
allowing them to be treated the same in some contexts.  A suggestion for a
better name is welcome :)

Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
    cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=49100&r1=49099&r2=49100&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Apr  2 12:35:06 2008
@@ -38,6 +38,7 @@
   class ObjCMethodDecl;
   class Expr;
   class SourceLocation;
+  class PointerLikeType;
   class PointerType;
   class ReferenceType;
   class VectorType;
@@ -303,9 +304,10 @@
   // Type Predicates: Check to see if this type is structurally the specified
   // type, ignoring typedefs and qualifiers.
   bool isFunctionType() const;
+  bool isPointerLikeType() const; // Pointer or Reference.
   bool isPointerType() const;
-  bool isFunctionPointerType() const;
   bool isReferenceType() const;
+  bool isFunctionPointerType() const;
   bool isArrayType() const;
   bool isRecordType() const;
   bool isStructureType() const;   
@@ -321,6 +323,7 @@
   // the best type we can.
   const BuiltinType *getAsBuiltinType() const;   
   const FunctionType *getAsFunctionType() const;   
+  const PointerLikeType *getAsPointerLikeType() const; // Pointer or Reference.
   const PointerType *getAsPointerType() const;
   const ReferenceType *getAsReferenceType() const;
   const ArrayType *getAsArrayType() const;
@@ -488,22 +491,35 @@
   friend class Type;
 };
 
+/// PointerLikeType - Common base class for pointers and references.
+///
+class PointerLikeType : public Type {
+  QualType PointeeType;
+protected:
+  PointerLikeType(TypeClass K, QualType Pointee, QualType CanonicalPtr) :
+    Type(K, CanonicalPtr), PointeeType(Pointee) {
+  }
+public:
+  
+  QualType getPointeeType() const { return PointeeType; }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == Pointer || T->getTypeClass() == Reference;
+  }
+  static bool classof(const PointerLikeType *) { return true; }
+};
 
 /// PointerType - C99 6.7.5.1 - Pointer Declarators.
 ///
-class PointerType : public Type, public llvm::FoldingSetNode {
-  QualType PointeeType;
+class PointerType : public PointerLikeType, public llvm::FoldingSetNode {
   PointerType(QualType Pointee, QualType CanonicalPtr) :
-    Type(Pointer, CanonicalPtr), PointeeType(Pointee) {
+    PointerLikeType(Pointer, Pointee, CanonicalPtr) {
   }
   friend class ASTContext;  // ASTContext creates these.
 public:
-    
-  QualType getPointeeType() const { return PointeeType; }
   
   virtual void getAsStringInternal(std::string &InnerString) const;
   
-  
   void Profile(llvm::FoldingSetNodeID &ID) {
     Profile(ID, getPointeeType());
   }
@@ -522,19 +538,16 @@
 
 /// ReferenceType - C++ 8.3.2 - Reference Declarators.
 ///
-class ReferenceType : public Type, public llvm::FoldingSetNode {
-  QualType ReferenceeType;
+class ReferenceType : public PointerLikeType, public llvm::FoldingSetNode {
   ReferenceType(QualType Referencee, QualType CanonicalRef) :
-    Type(Reference, CanonicalRef), ReferenceeType(Referencee) {
+    PointerLikeType(Reference, Referencee, CanonicalRef) {
   }
   friend class ASTContext;  // ASTContext creates these.
 public:
   virtual void getAsStringInternal(std::string &InnerString) const;
 
-  QualType getReferenceeType() const { return ReferenceeType; }
-
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, getReferenceeType());
+    Profile(ID, getPointeeType());
   }
   static void Profile(llvm::FoldingSetNodeID &ID, QualType Referencee) {
     ID.AddPointer(Referencee.getAsOpaquePtr());
@@ -1139,15 +1152,18 @@
 inline bool Type::isPointerType() const {
   return isa<PointerType>(CanonicalType.getUnqualifiedType()); 
 }
+inline bool Type::isReferenceType() const {
+  return isa<ReferenceType>(CanonicalType.getUnqualifiedType());
+}
+inline bool Type::isPointerLikeType() const {
+  return isa<PointerLikeType>(CanonicalType.getUnqualifiedType()); 
+}
 inline bool Type::isFunctionPointerType() const {
   if (const PointerType* T = getAsPointerType())
     return T->getPointeeType()->isFunctionType();
   else
     return false;
 }
-inline bool Type::isReferenceType() const {
-  return isa<ReferenceType>(CanonicalType.getUnqualifiedType());
-}
 inline bool Type::isArrayType() const {
   return isa<ArrayType>(CanonicalType.getUnqualifiedType());
 }

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=49100&r1=49099&r2=49100&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Apr  2 12:35:06 2008
@@ -281,7 +281,7 @@
     // of the referenced type." C++98 5.3.3p2: expr.sizeof.
     // FIXME: This is wrong for struct layout: a reference in a struct has
     // pointer size.
-    return getTypeInfo(cast<ReferenceType>(T)->getReferenceeType());
+    return getTypeInfo(cast<ReferenceType>(T)->getPointeeType());
     
   case Type::Complex: {
     // Complex types have the same alignment as their elements, but twice the
@@ -1725,12 +1725,12 @@
   QualType ltype = lhs;
 
   if (lhs->isReferenceType())
-    ltype = cast<ReferenceType>(lhs.getCanonicalType())->getReferenceeType();
+    ltype = cast<ReferenceType>(lhs.getCanonicalType())->getPointeeType();
 
   QualType rtype = rhs;
 
   if (rhs->isReferenceType())
-    rtype = cast<ReferenceType>(rhs.getCanonicalType())->getReferenceeType();
+    rtype = cast<ReferenceType>(rhs.getCanonicalType())->getPointeeType();
 
   return typesAreCompatible(ltype, rtype);
 }
@@ -1817,9 +1817,9 @@
   // designates the object or function denoted by the reference, and the
   // expression is an lvalue.
   if (ReferenceType *RT = dyn_cast<ReferenceType>(lcanon))
-    lcanon = RT->getReferenceeType();
+    lcanon = RT->getPointeeType();
   if (ReferenceType *RT = dyn_cast<ReferenceType>(rcanon))
-    rcanon = RT->getReferenceeType();
+    rcanon = RT->getPointeeType();
   
   Type::TypeClass LHSClass = lcanon->getTypeClass();
   Type::TypeClass RHSClass = rcanon->getTypeClass();

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=49100&r1=49099&r2=49100&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Wed Apr  2 12:35:06 2008
@@ -155,6 +155,24 @@
   return getDesugaredType()->getAsFunctionType();
 }
 
+const PointerLikeType *Type::getAsPointerLikeType() const {
+  // If this is directly a pointer-like type, return it.
+  if (const PointerLikeType *PTy = dyn_cast<PointerLikeType>(this))
+    return PTy;
+  
+  // If the canonical form of this type isn't the right kind, reject it.
+  if (!isa<PointerLikeType>(CanonicalType)) {
+    // Look through type qualifiers
+    if (isa<PointerLikeType>(CanonicalType.getUnqualifiedType()))
+      return CanonicalType.getUnqualifiedType()->getAsPointerLikeType();
+    return 0;
+  }
+  
+  // If this is a typedef for a pointer type, strip the typedef off without
+  // losing all typedef information.
+  return getDesugaredType()->getAsPointerLikeType();
+}
+
 const PointerType *Type::getAsPointerType() const {
   // If this is directly a pointer type, return it.
   if (const PointerType *PTy = dyn_cast<PointerType>(this))
@@ -796,10 +814,10 @@
   
   // Handle things like 'int (*A)[4];' correctly.
   // FIXME: this should include vectors, but vectors use attributes I guess.
-  if (isa<ArrayType>(PointeeType.getTypePtr()))
+  if (isa<ArrayType>(getPointeeType()))
     S = '(' + S + ')';
   
-  PointeeType.getAsStringInternal(S);
+  getPointeeType().getAsStringInternal(S);
 }
 
 void ReferenceType::getAsStringInternal(std::string &S) const {
@@ -807,10 +825,10 @@
   
   // Handle things like 'int (&A)[4];' correctly.
   // FIXME: this should include vectors, but vectors use attributes I guess.
-  if (isa<ArrayType>(ReferenceeType.getTypePtr()))
+  if (isa<ArrayType>(getPointeeType()))
     S = '(' + S + ')';
   
-  ReferenceeType.getAsStringInternal(S);
+  getPointeeType().getAsStringInternal(S);
 }
 
 void ConstantArrayType::getAsStringInternal(std::string &S) const {

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=49100&r1=49099&r2=49100&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Wed Apr  2 12:35:06 2008
@@ -213,7 +213,7 @@
     return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), false);
   }
   Value *EmitSizeAlignOf(QualType TypeToSize, QualType RetType,
-                               bool isSizeOf);
+                         bool isSizeOf);
   Value *VisitUnaryReal     (const UnaryOperator *E);
   Value *VisitUnaryImag     (const UnaryOperator *E);
   Value *VisitUnaryExtension(const UnaryOperator *E) {
@@ -537,7 +537,7 @@
     
   } else if (E->getType()->isReferenceType()) {
     assert(cast<ReferenceType>(E->getType().getCanonicalType())->
-           getReferenceeType() == 
+           getPointeeType() == 
            Op->getType().getCanonicalType() && "Incompatible types!");
     
     return EmitLValue(Op).getAddress();

Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=49100&r1=49099&r2=49100&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Wed Apr  2 12:35:06 2008
@@ -206,15 +206,11 @@
       ConvertType(cast<ComplexType>(Ty).getElementType());
     return llvm::StructType::get(EltTy, EltTy, NULL);
   }
+  case Type::Reference:
   case Type::Pointer: {
-    const PointerType &P = cast<PointerType>(Ty);
-    QualType ETy = P.getPointeeType();
+    QualType ETy = cast<PointerLikeType>(Ty).getPointeeType();
     return llvm::PointerType::get(ConvertType(ETy), ETy.getAddressSpace()); 
   }
-  case Type::Reference: {
-    const ReferenceType &R = cast<ReferenceType>(Ty);
-    return llvm::PointerType::getUnqual(ConvertType(R.getReferenceeType()));
-  }
     
   case Type::VariableArray: {
     const VariableArrayType &A = cast<VariableArrayType>(Ty);

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=49100&r1=49099&r2=49100&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Wed Apr  2 12:35:06 2008
@@ -154,28 +154,23 @@
     // or incomplete types shall not be restrict-qualified."  C++ also allows
     // restrict-qualified references.
     if (TypeQuals & QualType::Restrict) {
-      QualType EltTy;
-      if (const PointerType *PT = Result->getAsPointerType())
-        EltTy = PT->getPointeeType();
-      else if (const ReferenceType *RT = Result->getAsReferenceType())
-        EltTy = RT->getReferenceeType();
-      else {
+      if (const PointerLikeType *PT = Result->getAsPointerLikeType()) {
+        QualType EltTy = PT->getPointeeType();
+      
+        // If we have a pointer or reference, the pointee must have an object or
+        // incomplete type.
+        if (!EltTy->isIncompleteOrObjectType()) {
+          Diag(DS.getRestrictSpecLoc(),
+               diag::err_typecheck_invalid_restrict_invalid_pointee,
+               EltTy.getAsString(), DS.getSourceRange());
+          TypeQuals &= ~QualType::Restrict; // Remove the restrict qualifier.
+        }
+      } else {
         Diag(DS.getRestrictSpecLoc(),
              diag::err_typecheck_invalid_restrict_not_pointer,
              Result.getAsString(), DS.getSourceRange());
+        TypeQuals &= ~QualType::Restrict; // Remove the restrict qualifier.
       }
-
-      // If we have a pointer or reference, the pointee must have an object or
-      // incomplete type.
-      if (!EltTy.isNull() && !EltTy->isIncompleteOrObjectType()) {
-        Diag(DS.getRestrictSpecLoc(),
-             diag::err_typecheck_invalid_restrict_invalid_pointee,
-             EltTy.getAsString(), DS.getSourceRange());
-        EltTy = QualType();
-      }
-      
-      if (EltTy.isNull()) // Invalid restrict: remove the restrict qualifier.
-        TypeQuals &= ~QualType::Restrict;
     }
     
     // Warn about CV qualifiers on functions: C99 6.7.3p8: "If the specification
@@ -249,7 +244,7 @@
         Diag(DeclType.Loc, diag::err_illegal_decl_reference_to_reference,
              D.getIdentifier() ? D.getIdentifier()->getName() : "type name");
         D.setInvalidType(true);
-        T = RT->getReferenceeType();
+        T = RT->getPointeeType();
       }
 
       // Enforce C99 6.7.3p2: "Types other than pointer types derived from
@@ -299,7 +294,7 @@
         // C++ 8.3.2p4: There shall be no ... arrays of references ...
         Diag(D.getIdentifierLoc(), diag::err_illegal_decl_array_of_references,
              D.getIdentifier() ? D.getIdentifier()->getName() : "type name");
-        T = RT->getReferenceeType();
+        T = RT->getPointeeType();
         D.setInvalidType(true);
       } else if (const RecordType *EltTy = T->getAsRecordType()) {
         // If the element type is a struct or union that contains a variadic





More information about the cfe-commits mailing list