Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- Ownership.h - Parser ownership helpers -------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. //  This file contains classes for managing ownership of Stmt and Expr nodes.
  10. //
  11. //===----------------------------------------------------------------------===//
  12.  
  13. #ifndef LLVM_CLANG_SEMA_OWNERSHIP_H
  14. #define LLVM_CLANG_SEMA_OWNERSHIP_H
  15.  
  16. #include "clang/AST/Expr.h"
  17. #include "clang/Basic/LLVM.h"
  18. #include "llvm/ADT/ArrayRef.h"
  19. #include "llvm/Support/PointerLikeTypeTraits.h"
  20. #include "llvm/Support/type_traits.h"
  21. #include <cassert>
  22. #include <cstddef>
  23. #include <cstdint>
  24.  
  25. //===----------------------------------------------------------------------===//
  26. // OpaquePtr
  27. //===----------------------------------------------------------------------===//
  28.  
  29. namespace clang {
  30.  
  31. class CXXBaseSpecifier;
  32. class CXXCtorInitializer;
  33. class Decl;
  34. class Expr;
  35. class ParsedTemplateArgument;
  36. class QualType;
  37. class Stmt;
  38. class TemplateName;
  39. class TemplateParameterList;
  40.  
  41.   /// Wrapper for void* pointer.
  42.   /// \tparam PtrTy Either a pointer type like 'T*' or a type that behaves like
  43.   ///               a pointer.
  44.   ///
  45.   /// This is a very simple POD type that wraps a pointer that the Parser
  46.   /// doesn't know about but that Sema or another client does.  The PtrTy
  47.   /// template argument is used to make sure that "Decl" pointers are not
  48.   /// compatible with "Type" pointers for example.
  49.   template <class PtrTy>
  50.   class OpaquePtr {
  51.     void *Ptr = nullptr;
  52.  
  53.     explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {}
  54.  
  55.     using Traits = llvm::PointerLikeTypeTraits<PtrTy>;
  56.  
  57.   public:
  58.     OpaquePtr(std::nullptr_t = nullptr) {}
  59.  
  60.     static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; }
  61.  
  62.     /// Returns plain pointer to the entity pointed by this wrapper.
  63.     /// \tparam PointeeT Type of pointed entity.
  64.     ///
  65.     /// It is identical to getPtrAs<PointeeT*>.
  66.     template <typename PointeeT> PointeeT* getPtrTo() const {
  67.       return get();
  68.     }
  69.  
  70.     /// Returns pointer converted to the specified type.
  71.     /// \tparam PtrT Result pointer type.  There must be implicit conversion
  72.     ///              from PtrTy to PtrT.
  73.     ///
  74.     /// In contrast to getPtrTo, this method allows the return type to be
  75.     /// a smart pointer.
  76.     template <typename PtrT> PtrT getPtrAs() const {
  77.       return get();
  78.     }
  79.  
  80.     PtrTy get() const {
  81.       return Traits::getFromVoidPointer(Ptr);
  82.     }
  83.  
  84.     void set(PtrTy P) {
  85.       Ptr = Traits::getAsVoidPointer(P);
  86.     }
  87.  
  88.     explicit operator bool() const { return Ptr != nullptr; }
  89.  
  90.     void *getAsOpaquePtr() const { return Ptr; }
  91.     static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); }
  92.   };
  93.  
  94.   /// UnionOpaquePtr - A version of OpaquePtr suitable for membership
  95.   /// in a union.
  96.   template <class T> struct UnionOpaquePtr {
  97.     void *Ptr;
  98.  
  99.     static UnionOpaquePtr make(OpaquePtr<T> P) {
  100.       UnionOpaquePtr OP = { P.getAsOpaquePtr() };
  101.       return OP;
  102.     }
  103.  
  104.     OpaquePtr<T> get() const { return OpaquePtr<T>::getFromOpaquePtr(Ptr); }
  105.     operator OpaquePtr<T>() const { return get(); }
  106.  
  107.     UnionOpaquePtr &operator=(OpaquePtr<T> P) {
  108.       Ptr = P.getAsOpaquePtr();
  109.       return *this;
  110.     }
  111.   };
  112.  
  113. } // namespace clang
  114.  
  115. namespace llvm {
  116.  
  117.   template <class T>
  118.   struct PointerLikeTypeTraits<clang::OpaquePtr<T>> {
  119.     static constexpr int NumLowBitsAvailable = 0;
  120.  
  121.     static inline void *getAsVoidPointer(clang::OpaquePtr<T> P) {
  122.       // FIXME: Doesn't work? return P.getAs< void >();
  123.       return P.getAsOpaquePtr();
  124.     }
  125.  
  126.     static inline clang::OpaquePtr<T> getFromVoidPointer(void *P) {
  127.       return clang::OpaquePtr<T>::getFromOpaquePtr(P);
  128.     }
  129.   };
  130.  
  131. } // namespace llvm
  132.  
  133. namespace clang {
  134.  
  135.   // Basic
  136. class StreamingDiagnostic;
  137.  
  138. // Determines whether the low bit of the result pointer for the
  139. // given UID is always zero. If so, ActionResult will use that bit
  140. // for it's "invalid" flag.
  141. template <class Ptr> struct IsResultPtrLowBitFree {
  142.   static const bool value = false;
  143.   };
  144.  
  145.   /// ActionResult - This structure is used while parsing/acting on
  146.   /// expressions, stmts, etc.  It encapsulates both the object returned by
  147.   /// the action, plus a sense of whether or not it is valid.
  148.   /// When CompressInvalid is true, the "invalid" flag will be
  149.   /// stored in the low bit of the Val pointer.
  150.   template<class PtrTy,
  151.            bool CompressInvalid = IsResultPtrLowBitFree<PtrTy>::value>
  152.   class ActionResult {
  153.     PtrTy Val;
  154.     bool Invalid;
  155.  
  156.   public:
  157.     ActionResult(bool Invalid = false) : Val(PtrTy()), Invalid(Invalid) {}
  158.     ActionResult(PtrTy val) : Val(val), Invalid(false) {}
  159.     ActionResult(const DiagnosticBuilder &) : Val(PtrTy()), Invalid(true) {}
  160.  
  161.     // These two overloads prevent void* -> bool conversions.
  162.     ActionResult(const void *) = delete;
  163.     ActionResult(volatile void *) = delete;
  164.  
  165.     bool isInvalid() const { return Invalid; }
  166.     bool isUsable() const { return !Invalid && Val; }
  167.     bool isUnset() const { return !Invalid && !Val; }
  168.  
  169.     PtrTy get() const { return Val; }
  170.     template <typename T> T *getAs() { return static_cast<T*>(get()); }
  171.  
  172.     void set(PtrTy V) { Val = V; }
  173.  
  174.     const ActionResult &operator=(PtrTy RHS) {
  175.       Val = RHS;
  176.       Invalid = false;
  177.       return *this;
  178.     }
  179.   };
  180.  
  181.   // This ActionResult partial specialization places the "invalid"
  182.   // flag into the low bit of the pointer.
  183.   template<typename PtrTy>
  184.   class ActionResult<PtrTy, true> {
  185.     // A pointer whose low bit is 1 if this result is invalid, 0
  186.     // otherwise.
  187.     uintptr_t PtrWithInvalid;
  188.  
  189.     using PtrTraits = llvm::PointerLikeTypeTraits<PtrTy>;
  190.  
  191.   public:
  192.     ActionResult(bool Invalid = false)
  193.         : PtrWithInvalid(static_cast<uintptr_t>(Invalid)) {}
  194.  
  195.     ActionResult(PtrTy V) {
  196.       void *VP = PtrTraits::getAsVoidPointer(V);
  197.       PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
  198.       assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
  199.     }
  200.  
  201.     ActionResult(const DiagnosticBuilder &) : PtrWithInvalid(0x01) {}
  202.  
  203.     // These two overloads prevent void* -> bool conversions.
  204.     ActionResult(const void *) = delete;
  205.     ActionResult(volatile void *) = delete;
  206.  
  207.     bool isInvalid() const { return PtrWithInvalid & 0x01; }
  208.     bool isUsable() const { return PtrWithInvalid > 0x01; }
  209.     bool isUnset() const { return PtrWithInvalid == 0; }
  210.  
  211.     PtrTy get() const {
  212.       void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01);
  213.       return PtrTraits::getFromVoidPointer(VP);
  214.     }
  215.  
  216.     template <typename T> T *getAs() { return static_cast<T*>(get()); }
  217.  
  218.     void set(PtrTy V) {
  219.       void *VP = PtrTraits::getAsVoidPointer(V);
  220.       PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
  221.       assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
  222.     }
  223.  
  224.     const ActionResult &operator=(PtrTy RHS) {
  225.       void *VP = PtrTraits::getAsVoidPointer(RHS);
  226.       PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
  227.       assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
  228.       return *this;
  229.     }
  230.  
  231.     // For types where we can fit a flag in with the pointer, provide
  232.     // conversions to/from pointer type.
  233.     static ActionResult getFromOpaquePointer(void *P) {
  234.       ActionResult Result;
  235.       Result.PtrWithInvalid = (uintptr_t)P;
  236.       return Result;
  237.     }
  238.     void *getAsOpaquePointer() const { return (void*)PtrWithInvalid; }
  239.   };
  240.  
  241.   /// An opaque type for threading parsed type information through the
  242.   /// parser.
  243.   using ParsedType = OpaquePtr<QualType>;
  244.   using UnionParsedType = UnionOpaquePtr<QualType>;
  245.  
  246.   // We can re-use the low bit of expression, statement, base, and
  247.   // member-initializer pointers for the "invalid" flag of
  248.   // ActionResult.
  249.   template<> struct IsResultPtrLowBitFree<Expr*> {
  250.     static const bool value = true;
  251.   };
  252.   template<> struct IsResultPtrLowBitFree<Stmt*> {
  253.     static const bool value = true;
  254.   };
  255.   template<> struct IsResultPtrLowBitFree<CXXBaseSpecifier*> {
  256.     static const bool value = true;
  257.   };
  258.   template<> struct IsResultPtrLowBitFree<CXXCtorInitializer*> {
  259.     static const bool value = true;
  260.   };
  261.  
  262.   using ExprResult = ActionResult<Expr *>;
  263.   using StmtResult = ActionResult<Stmt *>;
  264.   using TypeResult = ActionResult<ParsedType>;
  265.   using BaseResult = ActionResult<CXXBaseSpecifier *>;
  266.   using MemInitResult = ActionResult<CXXCtorInitializer *>;
  267.  
  268.   using DeclResult = ActionResult<Decl *>;
  269.   using ParsedTemplateTy = OpaquePtr<TemplateName>;
  270.   using UnionParsedTemplateTy = UnionOpaquePtr<TemplateName>;
  271.  
  272.   using MultiExprArg = MutableArrayRef<Expr *>;
  273.   using MultiStmtArg = MutableArrayRef<Stmt *>;
  274.   using ASTTemplateArgsPtr = MutableArrayRef<ParsedTemplateArgument>;
  275.   using MultiTypeArg = MutableArrayRef<ParsedType>;
  276.   using MultiTemplateParamsArg = MutableArrayRef<TemplateParameterList *>;
  277.  
  278.   inline ExprResult ExprError() { return ExprResult(true); }
  279.   inline StmtResult StmtError() { return StmtResult(true); }
  280.   inline TypeResult TypeError() { return TypeResult(true); }
  281.  
  282.   inline ExprResult ExprError(const StreamingDiagnostic &) {
  283.     return ExprError();
  284.   }
  285.   inline StmtResult StmtError(const StreamingDiagnostic &) {
  286.     return StmtError();
  287.   }
  288.  
  289.   inline ExprResult ExprEmpty() { return ExprResult(false); }
  290.   inline StmtResult StmtEmpty() { return StmtResult(false); }
  291.  
  292.   inline Expr *AssertSuccess(ExprResult R) {
  293.     assert(!R.isInvalid() && "operation was asserted to never fail!");
  294.     return R.get();
  295.   }
  296.  
  297.   inline Stmt *AssertSuccess(StmtResult R) {
  298.     assert(!R.isInvalid() && "operation was asserted to never fail!");
  299.     return R.get();
  300.   }
  301.  
  302. } // namespace clang
  303.  
  304. #endif // LLVM_CLANG_SEMA_OWNERSHIP_H
  305.