Smart pointers for canonical types

Hello all,

Last week a few of us discussed potential improvements to Clang's use of canonical types. At issue is our continuing concern that it is too easy to accidentally compare non-canonical QualTypes, and each place we've made this mistake will only be exposed when some poor user has a typedef where we haven't yet seen one.

The attached patch introduces a new class template CanQual<T>, which is a smart pointer that refers to a canonical type whose dynamic type is T or some subclass thereof. T will often be Type, but we also expect that, e.g., CanQual<PointerType> will be used rather than const PointerType*.

ASTContext's getCanonicalType() now returns a CanQual<Type> (also named CanQualType). CanQual<T> provides the appropriate conversions to QualType and const T* so that existing code continues to work. We can gradually move type-checking code over toward CanQual<T> to improve safety. The design is such that, once complete, accessing members of PointerType through CanQual<PointerType> will always return *canonical* types (e.g., a CanQual<Type>) so that it's easy to stay within the static canonical-types system.

Comments and questions greatly appreciated!

  - Doug

type-traits.patch (1.2 KB)

can-qual-ptr.patch (18.8 KB)

Go static type checking! :slight_smile:

Douglas Gregor wrote:

The attached patch introduces a new class template CanQual<T>, which is a smart pointer that refers to a canonical type whose dynamic type is T or some subclass thereof. T will often be Type, but we also expect that, e.g., CanQual<PointerType> will be used rather than const PointerType*.

I love the idea. I'll have to look at the patch in detail.

Sebastian

Here's an updated patch, which contains all of the canonical type proxies and converts the template argument deduction code over to use the canonical-type smart pointer. Unless there are complaints, I plan to introduce this code early next week.

  - Doug

can-qual-ptr.patch (49.2 KB)

Douglas Gregor wrote:

The attached patch introduces a new class template CanQual<T>, which
is a smart pointer that refers to a canonical type whose dynamic type
is T or some subclass thereof. T will often be Type, but we also
expect that, e.g., CanQual<PointerType> will be used rather than
const PointerType*.

Here's an updated patch, which contains all of the canonical type
proxies and converts the template argument deduction code over to use
the canonical-type smart pointer. Unless there are complaints, I plan
to introduce this code early next week.

Looks very good. Just one nit: CanQual::getNonReferenceType has an
incomplete comment.

Sebastian

Canonical types have finally been committed here:

  http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20090803/020009.html

(With a follow-up commit to fix the incomplete comment Sebastian noted)

  - Doug