[cfe-commits] [patch] __has_trivial_* type traits

Douglas Gregor dgregor at apple.com
Thu Jul 23 11:44:54 PDT 2009


On Jul 23, 2009, at 1:03 AM, John McCall wrote:

> This patch fixes the implementations of the __has_trivial_destructor  
> and __has_trivial_constructor builtin pseudo-functions and  
> additionally implements __has_trivial_copy and __has_trivial_assign.

Cool.

> Index: include/clang/AST/Type.h
> ===================================================================
> --- include/clang/AST/Type.h	(revision 76866)
> +++ include/clang/AST/Type.h	(working copy)
> @@ -473,6 +473,11 @@ public:
>   /// element type of the array, potentially with type qualifiers  
> missing.
>   /// This method should never be used when type qualifiers are  
> meaningful.
>   const Type *getArrayElementTypeNoTypeQual() const;
> +
> +  /// getBaseElementTypeNoTypeQual - Recursively strip qualifiers and
> +  /// array types off this type.  This method should never be used  
> when
> +  /// type qualifiers are meaningful.
> +  const Type *getBaseElementTypeNoTypeQual() const;

Why does this operation strip off the qualifiers? Most of the callers  
of this routine don't mind if the result type is qualified, and the  
UTT_HasTrivialAssign computation would be far easier if this routine  
maintained the qualifiers.

> +  case UTT_HasTrivialAssign:
> +    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
> +    //   If type is const qualified or is a reference type then the
> +    //   trait is false. Otherwise if __is_pod (type) is true then  
> the
> +    //   trait is true, else if type is a cv class or union type with
> +    //   a trivial copy assignment ([class.copy]) then the trait is
> +    //   true, else it is false.
> +    // Note: the const and reference restrictions are interesting,
> +    // given that const and reference members don't prevent a class
> +    // from having a trivial copy assignment operator (but do cause
> +    // errors if the copy assignment operator is actually used, q.v.
> +    // [class.copy]p12).
> +
> +    // Arrays make this const check really annoying, especially since
> +    // we don't have an ASTContext right now.
> +    {
> +      QualType QT = QueriedType;
> +      while (true) {
> +        if (QT.isConstQualified())
> +          return false;
> +
> +        QT = QT->getDesugaredType();
> +        if (QT.isConstQualified())
> +          return false;
> +
> +        if (const ArrayType* AT = dyn_cast<ArrayType>(QT)) {
> +          QT = AT->getElementType();
> +        }else if (const ExtQualType* EQT = dyn_cast<ExtQualType> 
> (QT)) {
> +          QT = QualType(EQT->getBaseType(), 0);
> +        }else {
> +          break;
> +        }
> +      }
> +    }

This is definitely more complicated than it needs to be.

> Index: lib/AST/Type.cpp
> ===================================================================
> --- lib/AST/Type.cpp	(revision 76866)
> +++ lib/AST/Type.cpp	(working copy)
> @@ -92,6 +92,23 @@ const Type *Type::getArrayElementTypeNoT
>   return cast<ArrayType>(getDesugaredType())->getElementType 
> ().getTypePtr();
> }
>
> +/// getBaseElementTypeNoTypeQual - Recursively strip qualifiers and
> +/// array types off this type.  This method should never be used when
> +/// type qualifiers are meaningful.
> +const Type *Type::getBaseElementTypeNoTypeQual() const {
> +  const Type* Ty = this;
> +  while (true) {
> +    const Type* DTy = Ty->getDesugaredType().getTypePtr();
> +    if (const ArrayType* ATy = dyn_cast<ArrayType>(DTy)) {
> +      Ty = ATy->getElementType().getTypePtr();
> +    }else if (const ExtQualType* EQTy = dyn_cast<ExtQualType>(DTy)) {
> +      Ty = EQTy->getBaseType();
> +    }else {
> +      return Ty; // the sugared type
> +    }
> +  }
> +}
> +

The logic here looks file. It seems to me like it would be relatively  
easy to drill down to the base element type, keeping around the union  
of the qualifiers that have been added at each stage. Then, return a  
QualType with the base element type and those accumulated qualifiers.  
Clients that want the unqualified version can just  
use .getUnqualifiedType() on the result.

	- Doug



More information about the cfe-commits mailing list