simon_tatham created this revision.
simon_tatham added reviewers: rsmith, lebedev.ri, akyrtzi.
simon_tatham requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This is part of a patch series working towards the ability to make
SourceLocation into a 64-bit type to handle larger translation units.

The `void *Data1` field in ProgramPoint is sometimes used to store a
SourceLocation in pointer encoding, and sometimes used to store other
pointer data. If SourceLocation becomes 64-bit when clang is compiled
for a 32-bit platform, then this won't fit any more. Hence, we change
the type of `Data1` to a union storing either an actual SourceLocation
or a pointer.

Patch originally by Mikhail Maltsev.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D105494

Files:
  clang/include/clang/Analysis/ProgramPoint.h

Index: clang/include/clang/Analysis/ProgramPoint.h
===================================================================
--- clang/include/clang/Analysis/ProgramPoint.h
+++ clang/include/clang/Analysis/ProgramPoint.h
@@ -21,6 +21,7 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/AlignOf.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/DataTypes.h"
 #include <cassert>
@@ -85,9 +86,31 @@
               MaxImplicitCallKind = PostImplicitCallKind,
               LoopExitKind,
               EpsilonKind};
-
 private:
-  const void *Data1;
+  union PtrOrSLoc {
+    PtrOrSLoc() {}
+    PtrOrSLoc(const void *P) {
+      memset(Raw.buffer, 0, sizeof(Raw.buffer));
+      Ptr = P;
+    }
+    PtrOrSLoc(SourceLocation L) {
+      memset(Raw.buffer, 0, sizeof(Raw.buffer));
+      new (&SLoc) SourceLocation(L);
+    }
+    bool operator==(const PtrOrSLoc &RHS) const {
+      return memcmp(this, &RHS, sizeof(PtrOrSLoc)) == 0;
+    }
+    bool operator!=(const PtrOrSLoc &RHS) const { return !(*this == RHS); }
+    StringRef AsBuffer() const {
+      const char *c = (const char *)this;
+      return StringRef(c, sizeof(PtrOrSLoc));
+    }
+    const void *Ptr;
+    SourceLocation SLoc;
+    llvm::AlignedCharArrayUnion<void *, SourceLocation> Raw;
+  };
+
+  PtrOrSLoc Data1;
   llvm::PointerIntPair<const void *, 2, unsigned> Data2;
 
   // The LocationContext could be NULL to allow ProgramPoint to be used in
@@ -108,30 +131,38 @@
       Tag(tag, (((unsigned) k) >> 4) & 0x3) {
         assert(getKind() == k);
         assert(getLocationContext() == l);
-        assert(getData1() == P);
+        assert(getData1Ptr() == P);
       }
 
-  ProgramPoint(const void *P1,
-               const void *P2,
-               Kind k,
-               const LocationContext *l,
-               const ProgramPointTag *tag = nullptr)
-    : Data1(P1),
-      Data2(P2, (((unsigned) k) >> 0) & 0x3),
-      L(l, (((unsigned) k) >> 2) & 0x3),
-      Tag(tag, (((unsigned) k) >> 4) & 0x3) {}
-
-protected:
-  const void *getData1() const { return Data1; }
-  const void *getData2() const { return Data2.getPointer(); }
-  void setData2(const void *d) { Data2.setPointer(d); }
-
-public:
-  /// Create a new ProgramPoint object that is the same as the original
-  /// except for using the specified tag value.
-  ProgramPoint withTag(const ProgramPointTag *tag) const {
-    return ProgramPoint(getData1(), getData2(), getKind(),
-                        getLocationContext(), tag);
+      ProgramPoint(PtrOrSLoc D1, const void *P2, Kind k,
+                   const LocationContext *l,
+                   const ProgramPointTag *tag = nullptr)
+          : Data1(D1), Data2(P2, (((unsigned)k) >> 0) & 0x3),
+            L(l, (((unsigned)k) >> 2) & 0x3),
+            Tag(tag, (((unsigned)k) >> 4) & 0x3) {}
+
+      ProgramPoint(const void *P1, const void *P2, Kind k,
+                   const LocationContext *l,
+                   const ProgramPointTag *tag = nullptr)
+          : ProgramPoint(PtrOrSLoc(P1), P2, k, l, tag) {}
+
+      ProgramPoint(SourceLocation Loc, const void *P2, Kind k,
+                   const LocationContext *l,
+                   const ProgramPointTag *tag = nullptr)
+          : ProgramPoint(PtrOrSLoc(Loc), P2, k, l, tag) {}
+
+    protected:
+      const PtrOrSLoc &getData1() const { return Data1; }
+      const void *getData1Ptr() const { return Data1.Ptr; }
+      const void *getData2() const { return Data2.getPointer(); }
+      void setData2(const void *d) { Data2.setPointer(d); }
+
+    public:
+      /// Create a new ProgramPoint object that is the same as the original
+      /// except for using the specified tag value.
+      ProgramPoint withTag(const ProgramPointTag *tag) const {
+        return ProgramPoint(getData1(), getData2(), getKind(),
+                            getLocationContext(), tag);
   }
 
   /// Convert to the specified ProgramPoint type, asserting that this
@@ -207,7 +238,7 @@
 
   void Profile(llvm::FoldingSetNodeID& ID) const {
     ID.AddInteger((unsigned) getKind());
-    ID.AddPointer(getData1());
+    ID.AddString(getData1().AsBuffer());
     ID.AddPointer(getData2());
     ID.AddPointer(getLocationContext());
     ID.AddPointer(getTag());
@@ -231,7 +262,7 @@
   }
 
   const CFGBlock *getBlock() const {
-    return reinterpret_cast<const CFGBlock*>(getData1());
+    return reinterpret_cast<const CFGBlock *>(getData1Ptr());
   }
 
   Optional<CFGElement> getFirstElement() const {
@@ -253,7 +284,7 @@
     : ProgramPoint(B, BlockExitKind, L) {}
 
   const CFGBlock *getBlock() const {
-    return reinterpret_cast<const CFGBlock*>(getData1());
+    return reinterpret_cast<const CFGBlock *>(getData1Ptr());
   }
 
   const Stmt *getTerminator() const {
@@ -276,7 +307,7 @@
     assert(S);
   }
 
-  const Stmt *getStmt() const { return (const Stmt*) getData1(); }
+  const Stmt *getStmt() const { return (const Stmt *)getData1Ptr(); }
 
   template <typename T>
   const T* getStmtAs() const { return dyn_cast<T>(getStmt()); }
@@ -344,7 +375,7 @@
   }
 
   const ReturnStmt *getStmt() const {
-    return reinterpret_cast<const ReturnStmt *>(getData1());
+    return reinterpret_cast<const ReturnStmt *>(getData1Ptr());
   }
 
 private:
@@ -509,7 +540,7 @@
   }
 
   const CFGBlock *getSrc() const {
-    return static_cast<const CFGBlock*>(getData1());
+    return static_cast<const CFGBlock *>(getData1Ptr());
   }
 
   const CFGBlock *getDst() const {
@@ -537,7 +568,7 @@
     : ProgramPoint(I, Loc, PostInitializerKind, L) {}
 
   const CXXCtorInitializer *getInitializer() const {
-    return static_cast<const CXXCtorInitializer *>(getData1());
+    return static_cast<const CXXCtorInitializer *>(getData1Ptr());
   }
 
   /// Returns the location of the field.
@@ -560,12 +591,10 @@
 public:
   ImplicitCallPoint(const Decl *D, SourceLocation Loc, Kind K,
                     const LocationContext *L, const ProgramPointTag *Tag)
-    : ProgramPoint(Loc.getPtrEncoding(), D, K, L, Tag) {}
+      : ProgramPoint(Loc, D, K, L, Tag) {}
 
   const Decl *getDecl() const { return static_cast<const Decl *>(getData2()); }
-  SourceLocation getLocation() const {
-    return SourceLocation::getFromPtrEncoding(getData1());
-  }
+  SourceLocation getLocation() const { return getData1().SLoc; }
 
 protected:
   ImplicitCallPoint() = default;
@@ -634,7 +663,7 @@
     : ProgramPoint(stmt, calleeCtx, CallEnterKind, callerCtx, nullptr) {}
 
   const Stmt *getCallExpr() const {
-    return static_cast<const Stmt *>(getData1());
+    return static_cast<const Stmt *>(getData1Ptr());
   }
 
   const StackFrameContext *getCalleeContext() const {
@@ -672,7 +701,7 @@
     : ProgramPoint(RS, CallExitBeginKind, L, nullptr) { }
 
   const ReturnStmt *getReturnStmt() const {
-    return static_cast<const ReturnStmt *>(getData1());
+    return static_cast<const ReturnStmt *>(getData1Ptr());
   }
 
 private:
@@ -693,7 +722,7 @@
     : ProgramPoint(CalleeCtx, CallExitEndKind, CallerCtx, nullptr) {}
 
   const StackFrameContext *getCalleeContext() const {
-    return static_cast<const StackFrameContext *>(getData1());
+    return static_cast<const StackFrameContext *>(getData1Ptr());
   }
 
 private:
@@ -716,7 +745,7 @@
             : ProgramPoint(LoopStmt, nullptr, LoopExitKind, LC) {}
 
     const Stmt *getLoopStmt() const {
-      return static_cast<const Stmt *>(getData1());
+      return static_cast<const Stmt *>(getData1Ptr());
     }
 
 private:
@@ -736,7 +765,7 @@
                const ProgramPointTag *tag = nullptr)
     : ProgramPoint(Data1, Data2, EpsilonKind, L, tag) {}
 
-  const void *getData() const { return getData1(); }
+  const void *getData() const { return getData1Ptr(); }
 
 private:
   friend class ProgramPoint;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to