r256611 - [ptr-traits] Switch the Redeclarable template to using a void pointer in

Chandler Carruth via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 29 19:09:25 PST 2015


Author: chandlerc
Date: Tue Dec 29 21:09:25 2015
New Revision: 256611

URL: http://llvm.org/viewvc/llvm-project?rev=256611&view=rev
Log:
[ptr-traits] Switch the Redeclarable template to using a void pointer in
its PointerUnion rather than an ASTContext pointer.

Using pointers with PointerUnion really should be checking the pointee
type's alignment, and we can't do this without the complete type. The
Redeclarable template inherently can't know the complete type of
ASTContext because of its layering, and because it is a template its
methods can't reasonably be out-of-line the way we traditionally solve
circular references within the AST library.

After discussing this with Richard Smith, his suggestion which I have
implemented here was to just drop to a void* for the PointerUnion. This
essentially documents that we're going to completely ignore the type
(including its potential alignment consequences) for this code. There
are still of course dynamic guards that this ended up working correctly,
and because of the way the code is factored this doesn't leak outside of
the very narrow implementation guts of Redeclarable.

This is part of a series of patches to allow LLVM to check for complete
pointee types when computing its pointer traits. This is absolutely
necessary to get correct (or reproducible) results for things like how
many low bits are guaranteed to be zero.

Modified:
    cfe/trunk/include/clang/AST/Redeclarable.h

Modified: cfe/trunk/include/clang/AST/Redeclarable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Redeclarable.h?rev=256611&r1=256610&r2=256611&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Redeclarable.h (original)
+++ cfe/trunk/include/clang/AST/Redeclarable.h Tue Dec 29 21:09:25 2015
@@ -20,6 +20,7 @@
 #include <iterator>
 
 namespace clang {
+class ASTContext;
 
 /// \brief Provides common interface for the Decls that can be redeclared.
 template<typename decl_type>
@@ -32,7 +33,11 @@ protected:
                                       &ExternalASTSource::CompleteRedeclChain>
                                           KnownLatest;
 
-    typedef const ASTContext *UninitializedLatest;
+    /// We store a pointer to the ASTContext in the UninitializedLatest
+    /// pointer, but to avoid circular type dependencies when we steal the low
+    /// bits of this pointer, we use a raw void* here.
+    typedef const void *UninitializedLatest;
+
     typedef Decl *Previous;
 
     /// A pointer to either an uninitialized latest declaration (where either
@@ -47,7 +52,7 @@ protected:
     enum LatestTag { LatestLink };
 
     DeclLink(LatestTag, const ASTContext &Ctx)
-        : Next(NotKnownLatest(&Ctx)) {}
+        : Next(NotKnownLatest(reinterpret_cast<UninitializedLatest>(&Ctx))) {}
     DeclLink(PreviousTag, decl_type *D)
         : Next(NotKnownLatest(Previous(D))) {}
 
@@ -67,7 +72,8 @@ protected:
           return static_cast<decl_type*>(NKL.get<Previous>());
 
         // Allocate the generational 'most recent' cache now, if needed.
-        Next = KnownLatest(*NKL.get<UninitializedLatest>(),
+        Next = KnownLatest(*reinterpret_cast<const ASTContext *>(
+                               NKL.get<UninitializedLatest>()),
                            const_cast<decl_type *>(D));
       }
 
@@ -83,7 +89,9 @@ protected:
       assert(NextIsLatest() && "decl became canonical unexpectedly");
       if (Next.is<NotKnownLatest>()) {
         NotKnownLatest NKL = Next.get<NotKnownLatest>();
-        Next = KnownLatest(*NKL.get<UninitializedLatest>(), D);
+        Next = KnownLatest(*reinterpret_cast<const ASTContext *>(
+                               NKL.get<UninitializedLatest>()),
+                           D);
       } else {
         auto Latest = Next.get<KnownLatest>();
         Latest.set(D);




More information about the cfe-commits mailing list