source: src/Validate/FixReturnTypes.cpp

Last change on this file was 83fd57d, checked in by Andrew Beach <ajbeach@…>, 5 months ago

Removed 'New' suffixes, they are no longer needed for disambiguation.

  • Property mode set to 100644
File size: 3.1 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2018 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// FixReturnTypes.cpp -- Unifies the representation of return types.
8//
9// Author           : Andrew Beach
10// Created On       : Tue Jun 29 11:06:00 2022
11// Last Modified By : Andrew Beach
12// Last Modified On : Tue Jul 12 14:04:00 2022
13// Update Count     : 0
14//
15
16#include "FixReturnTypes.hpp"
17
18#include "AST/Decl.hpp"
19#include "AST/Pass.hpp"
20#include "AST/Type.hpp"
21#include "CodeGen/CodeGenerator.hpp"
22#include "ResolvExpr/Unify.h"
23
24namespace Validate {
25
26namespace {
27
28struct ReturnTypeFixer final {
29        ast::FunctionDecl const * postvisit( ast::FunctionDecl const * decl );
30        ast::FunctionType const * postvisit( ast::FunctionType const * type );
31};
32
33ast::FunctionDecl const * ReturnTypeFixer::postvisit(
34                ast::FunctionDecl const * decl ) {
35        // TODO: It does not handle return values. This information needs to be
36        // saved if resolution is to use it. (But does it currently?)
37        if ( 1 < decl->returns.size() ) {
38                auto mut = ast::mutate( decl );
39                // Generate a single return value which is the tuple of all return values.
40                auto resultType = ResolvExpr::extractResultType( mut->type );
41                ast::TupleType const * tupleType = resultType.strict_as<ast::TupleType>();
42                // Ensure return values are not destructed by explicitly creating
43                // an empty ListInit node wherein the ConstructFlag is NoConstruct.
44                ast::ObjectDecl * newRet = new ast::ObjectDecl(
45                        decl->location, "", tupleType,
46                        new ast::ListInit( decl->location, {}, {}, ast::NoConstruct ),
47                        ast::Storage::Classes(), ast::Linkage::Cforall );
48                mut->returns.clear();
49                mut->returns.push_back( newRet );
50                decl = mut;
51        }
52
53        assertf( decl->returns.size() < 2,
54                "Function %s has too many return values: %zu",
55                decl->name.c_str(), decl->returns.size() );
56        if ( 0 == decl->returns.size() ) {
57                return decl;
58        }
59        // Ensure that all function return values have a name.
60        // The function name is used to disambiguate the name (and provide
61        // debugging information) from other return values.
62        auto mut = ast::mutate( decl );
63        ast::ptr<ast::DeclWithType> & ret = mut->returns.front();
64        if ( "" == ret->name ) {
65                ret.get_and_mutate()->name = "_retval_" + CodeGen::genName( decl );
66        }
67        ret.get_and_mutate()->attributes.push_back( new ast::Attribute( "unused" ) );
68        return mut;
69}
70
71ast::FunctionType const * ReturnTypeFixer::postvisit(
72                ast::FunctionType const * type ) {
73        if ( 1 < type->returns.size() ) {
74                auto mut = ast::mutate( type );
75                // Generate a single return type which is the tuple of all return types.
76                auto resultType = ResolvExpr::extractResultType( mut );
77                ast::TupleType const * tupleType = resultType.strict_as<ast::TupleType>();
78                mut->returns.clear();
79                mut->returns.push_back( tupleType );
80                return mut;
81        }
82        return type;
83}
84
85} // namespace
86
87void fixReturnTypes( ast::TranslationUnit & translationUnit ) {
88        ast::Pass<ReturnTypeFixer>::run( translationUnit );
89}
90
91} // namespace Validate
92
93// Local Variables: //
94// tab-width: 4 //
95// mode: c++ //
96// compile-command: "make install" //
97// End: //
Note: See TracBrowser for help on using the repository browser.