source: src/Virtual/Tables.cc@ 5936244

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 5936244 was 69c5c00, checked in by Andrew Beach <ajbeach@…>, 5 years ago

Rework exceptions mark_exception -> get_exception_vtable and the needed follow up.

  • Property mode set to 100644
File size: 4.2 KB
RevLine 
[1c01c58]1//
2// Cforall Version 1.0.0 Copyright (C) 2016 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// Tables.cc --
8//
9// Author : Andrew Beach
10// Created On : Mon Aug 31 11:11:00 2020
11// Last Modified By : Andrew Beach
12// Last Modified On : Tue Sep 3 14:56:00 2020
13// Update Count : 0
14//
15
[69c5c00]16#include <SynTree/Attribute.h>
[1c01c58]17#include <SynTree/Declaration.h>
18#include <SynTree/Expression.h>
[69c5c00]19#include <SynTree/Statement.h>
[1c01c58]20#include <SynTree/Type.h>
21
22namespace Virtual {
23
24std::string vtableTypeName( std::string const & name ) {
25 return name + "_vtable";
26}
27
28std::string instanceName( std::string const & name ) {
29 return std::string("_") + name + "_instance";
30}
31
32std::string vtableInstanceName( std::string const & name ) {
33 return instanceName( vtableTypeName( name ) );
34}
35
36bool isVTableInstanceName( std::string const & name ) {
37 // There are some delicate length calculations here.
38 return 17 < name.size() && '_' == name[0] &&
39 std::string("_vtable_instance") == name.substr(1, name.size() - 17);
40}
41
42static ObjectDecl * makeVtableDeclaration(
43 StructInstType * type, Initializer * init ) {
44 std::string const & name = instanceName( type->name );
45 Type::StorageClasses storage = noStorageClasses;
46 if ( nullptr == init ) {
47 storage.is_extern = true;
48 }
49 return new ObjectDecl(
50 name,
51 storage,
52 LinkageSpec::Cforall,
53 nullptr,
54 type,
55 init
56 );
57}
58
59ObjectDecl * makeVtableForward( StructInstType * type ) {
[69c5c00]60 assert( type );
[1c01c58]61 return makeVtableDeclaration( type, nullptr );
62}
63
64ObjectDecl * makeVtableInstance(
[69c5c00]65 StructInstType * vtableType, Type * objectType, Initializer * init ) {
66 assert( vtableType );
67 assert( objectType );
[1c01c58]68 StructDecl * vtableStruct = vtableType->baseStruct;
69 // Build the initialization
70 if ( nullptr == init ) {
71 std::list< Initializer * > inits;
72
73 // This is going to have to be run before the resolver to connect expressions.
74 for ( auto field : vtableStruct->members ) {
75 if ( std::string( "parent" ) == field->name ) {
76 // This will not work with polymorphic state.
77 auto oField = strict_dynamic_cast< ObjectDecl * >( field );
78 auto fieldType = strict_dynamic_cast< PointerType * >( oField->type );
79 auto parentType = strict_dynamic_cast< StructInstType * >( fieldType->base );
80 std::string const & parentInstance = instanceName( parentType->name );
81 inits.push_back(
82 new SingleInit( new AddressExpr( new NameExpr( parentInstance ) ) ) );
83 } else if ( std::string( "size" ) == field->name ) {
[69c5c00]84 inits.push_back( new SingleInit( new SizeofExpr( objectType->clone() ) ) );
[1c01c58]85 } else if ( std::string( "align" ) == field->name ) {
[69c5c00]86 inits.push_back( new SingleInit( new AlignofExpr( objectType->clone() ) ) );
[1c01c58]87 } else {
88 inits.push_back( new SingleInit( new NameExpr( field->name ) ) );
89 }
90 }
91 init = new ListInit( inits );
92 // This should initialize everything except the parent pointer, the
93 // size-of and align-of fields. These should be inserted.
94 } else {
95 assert(false);
96 }
97 return makeVtableDeclaration( vtableType, init );
98}
99
[69c5c00]100namespace {
101 std::string const functionName = "get_exception_vtable";
102}
103
104FunctionDecl * makeGetExceptionForward(
105 Type * vtableType, Type * exceptType ) {
106 assert( vtableType );
107 assert( exceptType );
108 FunctionType * type = new FunctionType( noQualifiers, false );
109 vtableType->tq.is_const = true;
110 type->returnVals.push_back( new ObjectDecl(
111 "_retvalue",
112 noStorageClasses,
113 LinkageSpec::Cforall,
114 nullptr,
115 new ReferenceType( noQualifiers, vtableType ),
116 nullptr,
117 { new Attribute("unused") }
118 ) );
119 type->parameters.push_back( new ObjectDecl(
120 "__unused",
121 noStorageClasses,
122 LinkageSpec::Cforall,
123 nullptr,
124 new PointerType( noQualifiers, exceptType ),
125 nullptr,
126 { new Attribute("unused") }
127 ) );
128 return new FunctionDecl(
129 functionName,
130 noStorageClasses,
131 LinkageSpec::Cforall,
132 type,
133 nullptr
134 );
135}
136
137FunctionDecl * makeGetExceptionFunction(
138 ObjectDecl * vtableInstance, Type * exceptType ) {
139 assert( vtableInstance );
140 assert( exceptType );
141 FunctionDecl * func = makeGetExceptionForward(
142 vtableInstance->type->clone(), exceptType );
143 func->statements = new CompoundStmt( {
144 new ReturnStmt( new VariableExpr( vtableInstance ) ),
145 } );
146 return func;
[1c01c58]147}
148
149}
Note: See TracBrowser for help on using the repository browser.