source: src/ResolvExpr/CastCost.cc@ c93bc28

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since c93bc28 was 89be1c68, checked in by Rob Schluntz <rschlunt@…>, 8 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.