source: src/ResolvExpr/CastCost.cc @ 89be1c68

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 89be1c68 was 89be1c68, checked in by Rob Schluntz <rschlunt@…>, 7 years ago

Remove Cost constructors, use only named members

This change makes it easier to read code involving costs, since in almost every case, only a single part of the cost tuple is relevant. Furthermore, this change makes it much simpler to add another dimension to the cost tuple, since only Cost.h needs to be updated, rather than every location using the cost constructor.

  • Property mode set to 100644
File size: 3.6 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// CastCost.cc --
8//
9// Author           : Richard C. Bilson
10// Created On       : Sun May 17 06:57:43 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Tue Feb  2 15:34:36 2016
13// Update Count     : 7
14//
15
16#include "typeops.h"
17#include "Cost.h"
18#include "ConversionCost.h"
19#include "SynTree/Type.h"
20#include "SynTree/Visitor.h"
21#include "SymTab/Indexer.h"
22
23
24namespace ResolvExpr {
25        class CastCost : public ConversionCost {
26          public:
27                CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
28
29                virtual void visit( BasicType *basicType );
30                virtual void visit( PointerType *pointerType );
31        };
32
33        Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
34                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
35                        EqvClass eqvClass;
36                        NamedTypeDecl *namedType;
37                        if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
38                                if ( eqvClass.type ) {
39                                        return castCost( src, eqvClass.type, indexer, env );
40                                } else {
41                                        return Cost::infinity;
42                                }
43                        } else if ( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) {
44                                TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
45                                // all typedefs should be gone by this point
46                                assert( type );
47                                if ( type->get_base() ) {
48                                        return castCost( src, type->get_base(), indexer, env ) + Cost::safe;
49                                } // if
50                        } // if
51                } // if
52                if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) {
53                        return Cost::zero;
54                } else if ( dynamic_cast< VoidType* >( dest ) ) {
55                        return Cost::safe;
56                } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
57                        return convertToReferenceCost( src, refType, indexer, env );
58                } else {
59                        CastCost converter( dest, indexer, env );
60                        src->accept( converter );
61                        if ( converter.get_cost() == Cost::infinity ) {
62                                return Cost::infinity;
63                        } else {
64                                // xxx - why are we adding cost 0 here?
65                                return converter.get_cost() + Cost::zero;
66                        } // if
67                } // if
68        }
69
70        CastCost::CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env )
71                : ConversionCost( dest, indexer, env ) {
72        }
73
74        void CastCost::visit( BasicType *basicType ) {
75                PointerType *destAsPointer = dynamic_cast< PointerType* >( dest );
76                if ( destAsPointer && basicType->isInteger() ) {
77                        // necessary for, e.g. unsigned long => void*
78                        cost = Cost::unsafe;
79                } else {
80                        cost = conversionCost( basicType, dest, indexer, env );
81                } // if
82        }
83
84        void CastCost::visit( PointerType *pointerType ) {
85                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
86                        if ( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) {
87                                cost = Cost::safe;
88                        } else {
89                                TypeEnvironment newEnv( env );
90                                newEnv.add( pointerType->get_forall() );
91                                newEnv.add( pointerType->get_base()->get_forall() );
92                                int castResult = ptrsCastable( pointerType->get_base(), destAsPtr->get_base(), newEnv, indexer );
93                                if ( castResult > 0 ) {
94                                        cost = Cost::safe;
95                                } else if ( castResult < 0 ) {
96                                        cost = Cost::infinity;
97                                } // if
98                        } // if
99                } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
100                        if ( destAsBasic->isInteger() ) {
101                                // necessary for, e.g. void* => unsigned long
102                                cost = Cost::unsafe;
103                        } // if
104                }
105        }
106} // namespace ResolvExpr
107
108// Local Variables: //
109// tab-width: 4 //
110// mode: c++ //
111// compile-command: "make install" //
112// End: //
Note: See TracBrowser for help on using the repository browser.