LCOV - code coverage report
Current view: top level - include/llvm/Support - Casting.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 1557 6945 22.4 %
Date: 2018-10-20 13:21:21 Functions: 79 11516 0.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- llvm/Support/Casting.h - Allow flexible, checked, casts --*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
      11             : // and dyn_cast_or_null<X>() templates.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #ifndef LLVM_SUPPORT_CASTING_H
      16             : #define LLVM_SUPPORT_CASTING_H
      17             : 
      18             : #include "llvm/Support/Compiler.h"
      19             : #include "llvm/Support/type_traits.h"
      20             : #include <cassert>
      21             : #include <memory>
      22             : #include <type_traits>
      23             : 
      24             : namespace llvm {
      25             : 
      26             : //===----------------------------------------------------------------------===//
      27             : //                          isa<x> Support Templates
      28             : //===----------------------------------------------------------------------===//
      29             : 
      30             : // Define a template that can be specialized by smart pointers to reflect the
      31             : // fact that they are automatically dereferenced, and are not involved with the
      32             : // template selection process...  the default implementation is a noop.
      33             : //
      34             : template<typename From> struct simplify_type {
      35             :   using SimpleType = From; // The real type this represents...
      36             : 
      37             :   // An accessor to get the real value...
      38             :   static SimpleType &getSimplifiedValue(From &Val) { return Val; }
      39             : };
      40             : 
      41             : template<typename From> struct simplify_type<const From> {
      42             :   using NonConstSimpleType = typename simplify_type<From>::SimpleType;
      43             :   using SimpleType =
      44             :       typename add_const_past_pointer<NonConstSimpleType>::type;
      45             :   using RetType =
      46             :       typename add_lvalue_reference_if_not_pointer<SimpleType>::type;
      47             : 
      48           0 :   static RetType getSimplifiedValue(const From& Val) {
      49           0 :     return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val));
      50             :   }
      51           0 : };
      52           0 : 
      53             : // The core of the implementation of isa<X> is here; To and From should be
      54           0 : // the names of classes.  This template can be specialized to customize the
      55           0 : // implementation of isa<> without rewriting it from scratch.
      56             : template <typename To, typename From, typename Enabler = void>
      57           0 : struct isa_impl {
      58           0 :   static inline bool doit(const From &Val) {
      59       72754 :     return To::classof(&Val);
      60           0 :   }
      61           0 : };
      62             : 
      63           0 : /// Always allow upcasts, and perform no dynamic check for them.
      64           0 : template <typename To, typename From>
      65     1354738 : struct isa_impl<
      66           0 :     To, From, typename std::enable_if<std::is_base_of<To, From>::value>::type> {
      67           0 :   static inline bool doit(const From &) { return true; }
      68    10415930 : };
      69           0 : 
      70           0 : template <typename To, typename From> struct isa_impl_cl {
      71     6821616 :   static inline bool doit(const From &Val) {
      72           0 :     return isa_impl<To, From>::doit(Val);
      73           0 :   }
      74     6470631 : };
      75           0 : 
      76           0 : template <typename To, typename From> struct isa_impl_cl<To, const From> {
      77     2004703 :   static inline bool doit(const From &Val) {
      78           0 :     return isa_impl<To, From>::doit(Val);
      79           0 :   }
      80      208633 : };
      81           0 : 
      82           0 : template <typename To, typename From>
      83    70992516 : struct isa_impl_cl<To, const std::unique_ptr<From>> {
      84           0 :   static inline bool doit(const std::unique_ptr<From> &Val) {
      85           0 :     assert(Val && "isa<> used on a null pointer");
      86     1825906 :     return isa_impl_cl<To, From>::doit(*Val);
      87           0 :   }
      88           0 : };
      89     1368340 : 
      90           0 : template <typename To, typename From> struct isa_impl_cl<To, From*> {
      91           0 :   static inline bool doit(const From *Val) {
      92        5476 :     assert(Val && "isa<> used on a null pointer");
      93           0 :     return isa_impl<To, From>::doit(*Val);
      94           0 :   }
      95        4810 : };
      96           0 : 
      97           0 : template <typename To, typename From> struct isa_impl_cl<To, From*const> {
      98         281 :   static inline bool doit(const From *Val) {
      99           0 :     assert(Val && "isa<> used on a null pointer");
     100           0 :     return isa_impl<To, From>::doit(*Val);
     101     7945503 :   }
     102           0 : };
     103           0 : 
     104        2170 : template <typename To, typename From> struct isa_impl_cl<To, const From*> {
     105           0 :   static inline bool doit(const From *Val) {
     106           0 :     assert(Val && "isa<> used on a null pointer");
     107           0 :     return isa_impl<To, From>::doit(*Val);
     108           2 :   }
     109           0 : };
     110         497 : 
     111           0 : template <typename To, typename From> struct isa_impl_cl<To, const From*const> {
     112           0 :   static inline bool doit(const From *Val) {
     113          56 :     assert(Val && "isa<> used on a null pointer");
     114           0 :     return isa_impl<To, From>::doit(*Val);
     115           0 :   }
     116     8664315 : };
     117           0 : 
     118           0 : template<typename To, typename From, typename SimpleFrom>
     119    18019147 : struct isa_impl_wrap {
     120           0 :   // When From != SimplifiedType, we can simplify the type some more by using
     121           0 :   // the simplify_type template.
     122        1465 :   static bool doit(const From &Val) {
     123           0 :     return isa_impl_wrap<To, SimpleFrom,
     124           0 :       typename simplify_type<SimpleFrom>::SimpleType>::doit(
     125     4424788 :                           simplify_type<const From>::getSimplifiedValue(Val));
     126           0 :   }
     127           0 : };
     128           0 : 
     129           0 : template<typename To, typename FromTy>
     130           0 : struct isa_impl_wrap<To, FromTy, FromTy> {
     131      297805 :   // When From == SimpleType, we are as simple as we are going to get.
     132           0 :   static bool doit(const FromTy &Val) {
     133           0 :     return isa_impl_cl<To,FromTy>::doit(Val);
     134      297815 :   }
     135           0 : };
     136           4 : 
     137      122235 : // isa<X> - Return true if the parameter to the template is an instance of the
     138           0 : // template type argument.  Used like this:
     139           4 : //
     140      122225 : //  if (isa<Type>(myVal)) { ... }
     141           0 : //
     142        3138 : template <class X, class Y> LLVM_NODISCARD inline bool isa(const Y &Val) {
     143     1960251 :   return isa_impl_wrap<X, const Y,
     144           0 :                        typename simplify_type<const Y>::SimpleType>::doit(Val);
     145        3138 : }
     146    21159395 : 
     147           0 : //===----------------------------------------------------------------------===//
     148           0 : //                          cast<x> Support Templates
     149    19480319 : //===----------------------------------------------------------------------===//
     150           0 : 
     151       29175 : template<class To, class From> struct cast_retty;
     152       69924 : 
     153           0 : // Calculate what type the 'cast' function should return, based on a requested
     154     1946426 : // type of To and a source type of From.
     155       30416 : template<class To, class From> struct cast_retty_impl {
     156           0 :   using ret_type = To &;       // Normal case, return Ty&
     157     1919072 : };
     158           0 : template<class To, class From> struct cast_retty_impl<To, const From> {
     159           0 :   using ret_type = const To &; // Normal case, return Ty&
     160        1821 : };
     161          10 : 
     162    20440886 : template<class To, class From> struct cast_retty_impl<To, From*> {
     163           0 :   using ret_type = To *;       // Pointer arg case, return Ty*
     164           0 : };
     165    20440886 : 
     166           0 : template<class To, class From> struct cast_retty_impl<To, const From*> {
     167           0 :   using ret_type = const To *; // Constant pointer arg case, return const Ty*
     168       19967 : };
     169           2 : 
     170           0 : template<class To, class From> struct cast_retty_impl<To, const From*const> {
     171       19967 :   using ret_type = const To *; // Constant pointer arg case, return const Ty*
     172      101039 : };
     173           0 : 
     174           0 : template <class To, class From>
     175      101037 : struct cast_retty_impl<To, std::unique_ptr<From>> {
     176           0 : private:
     177           0 :   using PointerType = typename cast_retty_impl<To, From *>::ret_type;
     178       26018 :   using ResultType = typename std::remove_pointer<PointerType>::type;
     179      149387 : 
     180           0 : public:
     181       26018 :   using ret_type = std::unique_ptr<ResultType>;
     182      149387 : };
     183     1672599 : 
     184           0 : template<class To, class From, class SimpleFrom>
     185        1050 : struct cast_retty_wrap {
     186     1672599 :   // When the simplified type and the from type are not the same, use the type
     187           0 :   // simplifier to reduce the type, then reuse cast_retty_impl to get the
     188        1050 :   // resultant type.
     189           0 :   using ret_type = typename cast_retty<To, SimpleFrom>::ret_type;
     190           0 : };
     191       29175 : 
     192           0 : template<class To, class FromTy>
     193           0 : struct cast_retty_wrap<To, FromTy, FromTy> {
     194       29175 :   // When the simplified type is equal to the from type, use it directly.
     195           0 :   using ret_type = typename cast_retty_impl<To,FromTy>::ret_type;
     196    19133463 : };
     197           0 : 
     198           0 : template<class To, class From>
     199    19133463 : struct cast_retty {
     200           0 :   using ret_type = typename cast_retty_wrap<
     201           0 :       To, From, typename simplify_type<From>::SimpleType>::ret_type;
     202    20428546 : };
     203           0 : 
     204           0 : // Ensure the non-simple values are converted using the simplify_type template
     205    20428546 : // that may be specialized by smart pointers...
     206           0 : //
     207      301690 : template<class To, class From, class SimpleFrom> struct cast_convert_val {
     208           0 :   // This is not a simple type, use the template to simplify it...
     209           0 :   static typename cast_retty<To, From>::ret_type doit(From &Val) {
     210        3889 :     return cast_convert_val<To, SimpleFrom,
     211           0 :       typename simplify_type<SimpleFrom>::SimpleType>::doit(
     212           0 :                           simplify_type<From>::getSimplifiedValue(Val));
     213           0 :   }
     214       39508 : };
     215           0 : 
     216           0 : template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
     217       39508 :   // This _is_ a simple type, just cast it.
     218           0 :   static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
     219      118912 :     typename cast_retty<To, FromTy>::ret_type Res2
     220           0 :      = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val);
     221           0 :     return Res2;
     222           0 :   }
     223           0 : };
     224           0 : 
     225           0 : template <class X> struct is_simple_type {
     226           0 :   static const bool value =
     227           0 :       std::is_same<X, typename simplify_type<X>::SimpleType>::value;
     228           0 : };
     229           0 : 
     230           0 : // cast<X> - Return the argument parameter cast to the specified type.  This
     231           0 : // casting operator asserts that the type is correct, so it does not return null
     232           0 : // on failure.  It does not allow a null argument (use cast_or_null for that).
     233           0 : // It is typically used like this:
     234           0 : //
     235           0 : //  cast<Instruction>(myVal)->getParent()
     236           0 : //
     237           0 : template <class X, class Y>
     238           0 : inline typename std::enable_if<!is_simple_type<Y>::value,
     239           0 :                                typename cast_retty<X, const Y>::ret_type>::type
     240           0 : cast(const Y &Val) {
     241           0 :   assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
     242           0 :   return cast_convert_val<
     243           8 :       X, const Y, typename simplify_type<const Y>::SimpleType>::doit(Val);
     244           0 : }
     245           0 : 
     246           0 : template <class X, class Y>
     247           0 : inline typename cast_retty<X, Y>::ret_type cast(Y &Val) {
     248           0 :   assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
     249           0 :   return cast_convert_val<X, Y,
     250           2 :                           typename simplify_type<Y>::SimpleType>::doit(Val);
     251           0 : }
     252           0 : 
     253           0 : template <class X, class Y>
     254           0 : inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) {
     255      164614 :   assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
     256           0 :   return cast_convert_val<X, Y*,
     257           0 :                           typename simplify_type<Y*>::SimpleType>::doit(Val);
     258           0 : }
     259           0 : 
     260           0 : template <class X, class Y>
     261          15 : inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type
     262        2184 : cast(std::unique_ptr<Y> &&Val) {
     263           0 :   assert(isa<X>(Val.get()) && "cast<Ty>() argument of incompatible type!");
     264           0 :   using ret_type = typename cast_retty<X, std::unique_ptr<Y>>::ret_type;
     265           0 :   return ret_type(
     266       14161 :       cast_convert_val<X, Y *, typename simplify_type<Y *>::SimpleType>::doit(
     267         199 :           Val.release()));
     268           0 : }
     269           0 : 
     270           0 : // cast_or_null<X> - Functionally identical to cast, except that a null value is
     271           0 : // accepted.
     272           0 : //
     273           0 : template <class X, class Y>
     274           0 : LLVM_NODISCARD inline
     275           0 :     typename std::enable_if<!is_simple_type<Y>::value,
     276           0 :                             typename cast_retty<X, const Y>::ret_type>::type
     277       26018 :     cast_or_null(const Y &Val) {
     278           3 :   if (!Val)
     279         375 :     return nullptr;
     280           0 :   assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
     281           0 :   return cast<X>(Val);
     282           0 : }
     283           0 : 
     284           0 : template <class X, class Y>
     285           0 : LLVM_NODISCARD inline
     286           0 :     typename std::enable_if<!is_simple_type<Y>::value,
     287        2725 :                             typename cast_retty<X, Y>::ret_type>::type
     288           0 :     cast_or_null(Y &Val) {
     289         156 :   if (!Val)
     290           0 :     return nullptr;
     291           0 :   assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
     292           0 :   return cast<X>(Val);
     293           4 : }
     294           0 : 
     295           0 : template <class X, class Y>
     296           0 : LLVM_NODISCARD inline typename cast_retty<X, Y *>::ret_type
     297         182 : cast_or_null(Y *Val) {
     298      655332 :   if (!Val) return nullptr;
     299        6019 :   assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
     300           0 :   return cast<X>(Val);
     301         182 : }
     302       13252 : 
     303         443 : template <class X, class Y>
     304           0 : inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type
     305        5138 : cast_or_null(std::unique_ptr<Y> &&Val) {
     306           0 :   if (!Val)
     307           0 :     return nullptr;
     308      147226 :   return cast<X>(std::move(Val));
     309           0 : }
     310           0 : 
     311        5476 : // dyn_cast<X> - Return the argument parameter cast to the specified type.  This
     312           0 : // casting operator returns null if the argument is of the wrong type, so it can
     313      448182 : // be used to test for a type as well as cast if successful.  This should be
     314      150628 : // used in the context of an if statement like this:
     315           0 : //
     316        9547 : //  if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
     317         519 : //
     318     2162588 : 
     319        9547 : template <class X, class Y>
     320       70983 : LLVM_NODISCARD inline
     321           0 :     typename std::enable_if<!is_simple_type<Y>::value,
     322           0 :                             typename cast_retty<X, const Y>::ret_type>::type
     323      113049 :     dyn_cast(const Y &Val) {
     324      136090 :   return isa<X>(Val) ? cast<X>(Val) : nullptr;
     325           4 : }
     326        1257 : 
     327         165 : template <class X, class Y>
     328    33018341 : LLVM_NODISCARD inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) {
     329      320764 :   return isa<X>(Val) ? cast<X>(Val) : nullptr;
     330           4 : }
     331           0 : 
     332         220 : template <class X, class Y>
     333        1317 : LLVM_NODISCARD inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) {
     334     6393086 :   return isa<X>(Val) ? cast<X>(Val) : nullptr;
     335           0 : }
     336           0 : 
     337         140 : // dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
     338           0 : // value is accepted.
     339      447246 : //
     340         535 : template <class X, class Y>
     341          39 : LLVM_NODISCARD inline
     342     5222869 :     typename std::enable_if<!is_simple_type<Y>::value,
     343        3901 :                             typename cast_retty<X, const Y>::ret_type>::type
     344      140112 :     dyn_cast_or_null(const Y &Val) {
     345     4897488 :   return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
     346         788 : }
     347           0 : 
     348          99 : template <class X, class Y>
     349     9940536 : LLVM_NODISCARD inline
     350       23750 :     typename std::enable_if<!is_simple_type<Y>::value,
     351           0 :                             typename cast_retty<X, Y>::ret_type>::type
     352           0 :     dyn_cast_or_null(Y &Val) {
     353          18 :   return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
     354    76221540 : }
     355       81843 : 
     356           0 : template <class X, class Y>
     357         127 : LLVM_NODISCARD inline typename cast_retty<X, Y *>::ret_type
     358        8683 : dyn_cast_or_null(Y *Val) {
     359      393667 :   return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
     360         131 : }
     361           0 : 
     362        1901 : // unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>,
     363        2000 : // taking ownership of the input pointer iff isa<X>(Val) is true.  If the
     364        1496 : // cast is successful, From refers to nullptr on exit and the casted value
     365          47 : // is returned.  If the cast is unsuccessful, the function returns nullptr
     366        7965 : // and From is unchanged.
     367        3512 : template <class X, class Y>
     368     1709404 : LLVM_NODISCARD inline auto unique_dyn_cast(std::unique_ptr<Y> &Val)
     369     5160715 :     -> decltype(cast<X>(Val)) {
     370         190 :   if (!isa<X>(Val))
     371     4185831 :     return nullptr;
     372      821683 :   return cast<X>(std::move(Val));
     373       68204 : }
     374        2402 : 
     375       30180 : template <class X, class Y>
     376         311 : LLVM_NODISCARD inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val)
     377        1266 :     -> decltype(cast<X>(Val)) {
     378    35968228 :   return unique_dyn_cast<X, Y>(Val);
     379         235 : }
     380      152291 : 
     381     4185984 : // dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast, except that
     382          90 : // a null value is accepted.
     383   120445351 : template <class X, class Y>
     384      933785 : LLVM_NODISCARD inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &Val)
     385   154576490 :     -> decltype(cast<X>(Val)) {
     386       42875 :   if (!Val)
     387         291 :     return nullptr;
     388         190 :   return unique_dyn_cast<X, Y>(Val);
     389       29299 : }
     390     3671306 : 
     391        4835 : template <class X, class Y>
     392       13999 : LLVM_NODISCARD inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val)
     393        3501 :     -> decltype(cast<X>(Val)) {
     394     3186255 :   return unique_dyn_cast_or_null<X, Y>(Val);
     395    11901175 : }
     396      275611 : 
     397      724253 : } // end namespace llvm
     398    51904276 : 
     399     3074805 : #endif // LLVM_SUPPORT_CASTING_H

Generated by: LCOV version 1.13