source: src/Virtual/ExpandCasts.cc@ cd7ef0b

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 cd7ef0b was cbce272, checked in by Andrew Beach <ajbeach@…>, 8 years ago

Structure based exception handling.

  • Property mode set to 100644
File size: 4.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// ExpandCasts.cc --
8//
9// Author : Andrew Beach
10// Created On : Mon Jul 24 13:59:00 2017
11// Last Modified By : Andrew Beach
12// Last Modified On : Tus Aug 2 14:59:00 2017
13// Update Count : 1
14//
15
16#include "ExpandCasts.h"
17#include "Common/PassVisitor.h"
18
19namespace Virtual {
20
21 /* Currently virtual depends on the rather brittle name matching between
22 * a (strict/explicate) virtual type, its vtable type and the vtable
23 * instance.
24 * A stronger implementation, would probably keep track of those triads
25 * and use that information to create better error messages.
26 */
27
28 std::string get_vtable_name( std::string const & name ) {
29 return name + "_vtable";
30 }
31
32 std::string get_vtable_inst_name( std::string const & name ) {
33 return std::string("_") + get_vtable_name( name ) + "_instance";
34 }
35
36 std::string get_vtable_name_root( std::string const & name ) {
37 return name.substr(0, name.size() - 7 );
38 }
39
40 std::string get_vtable_inst_name_root( std::string const & name ) {
41 return get_vtable_name_root( name.substr(1, name.size() - 10 ) );
42 }
43
44 bool is_vtable_name( std::string const & name ) {
45 return (name.substr( name.size() - 7 ) == "_vtable" );
46 }
47
48 bool is_vtable_inst_name( std::string const & name ) {
49 return 17 < name.size() &&
50 name == get_vtable_inst_name( get_vtable_inst_name_root( name ) );
51 }
52
53 class VirtualCastCore {
54 std::map<std::string, ObjectDecl *> vtable_instances;
55 FunctionDecl *vcast_decl;
56 StructDecl *pvt_decl;
57
58 Type * pointer_to_pvt(int level_of_indirection) {
59 Type * type = new StructInstType(
60 Type::Qualifiers( Type::Const ), pvt_decl );
61 for (int i = 0 ; i < level_of_indirection ; ++i) {
62 type = new PointerType( noQualifiers, type );
63 }
64 return type;
65 }
66
67 public:
68 VirtualCastCore() :
69 vtable_instances(), vcast_decl( nullptr ), pvt_decl( nullptr )
70 {}
71
72 void premutate( FunctionDecl * functionDecl );
73 void premutate( StructDecl * structDecl );
74 void premutate( ObjectDecl * objectDecl );
75
76 Expression * postmutate( VirtualCastExpr * castExpr );
77 };
78
79 void VirtualCastCore::premutate( FunctionDecl * functionDecl ) {
80 if ( (! vcast_decl) &&
81 functionDecl->get_name() == "__cfa__virtual_cast" ) {
82 vcast_decl = functionDecl;
83 }
84 }
85
86 void VirtualCastCore::premutate( StructDecl * structDecl ) {
87 if ( pvt_decl || ! structDecl->has_body() ) {
88 return;
89 } else if ( structDecl->get_name() == "__cfa__parent_vtable" ) {
90 pvt_decl = structDecl;
91 }
92 }
93
94 void VirtualCastCore::premutate( ObjectDecl * objectDecl ) {
95 if ( is_vtable_inst_name( objectDecl->get_name() ) ) {
96 vtable_instances[objectDecl->get_name()] = objectDecl;
97 }
98 }
99
100 Expression * VirtualCastCore::postmutate( VirtualCastExpr * castExpr ) {
101 assertf( castExpr->get_result(), "Virtual Cast target not found before expansion." );
102
103 assert( vcast_decl );
104 assert( pvt_decl );
105
106 // May only cast to a pointer or reference type.
107 // A earlier validation should give a syntax error, this is
108 // just to make sure errors don't creep during translation.
109 // Move to helper with more detailed error messages.
110 PointerType * target_type =
111 dynamic_cast<PointerType *>( castExpr->get_result() );
112 assert( target_type );
113
114 StructInstType * target_struct =
115 dynamic_cast<StructInstType *>( target_type->get_base() );
116 assert( target_struct );
117
118 StructDecl * target_decl = target_struct->get_baseStruct();
119
120 std::map<std::string, ObjectDecl *>::iterator found =
121 vtable_instances.find(
122 get_vtable_inst_name( target_decl->get_name() ) );
123 if ( vtable_instances.end() == found ) {
124 assertf( false, "virtual table instance not found." );
125 }
126 ObjectDecl * table = found->second;
127
128 Expression * result = new CastExpr(
129 //new ApplicationExpr(
130 //new AddressExpr( new VariableExpr( vcast_decl ) ),
131 //new CastExpr( new VariableExpr( vcast_decl ),
132 // new PointerType( noQualifiers,
133 // vcast_decl->get_type()->clone()
134 // )
135 // ),
136 new UntypedExpr( new NameExpr( "__cfa__virtual_cast" ), {
137 new CastExpr(
138 new AddressExpr( new VariableExpr( table ) ),
139 pointer_to_pvt(1)
140 ),
141 new CastExpr(
142 castExpr->get_arg(),
143 pointer_to_pvt(2)
144 )
145 } ),
146 castExpr->get_result()->clone()
147 );
148
149 castExpr->set_arg( nullptr );
150 castExpr->set_result( nullptr );
151 delete castExpr;
152 return result;
153 }
154
155 void expandCasts( std::list< Declaration * > & translationUnit ) {
156 PassVisitor<VirtualCastCore> translator;
157 mutateAll( translationUnit, translator );
158 }
159}
Note: See TracBrowser for help on using the repository browser.