source: src/Validate/FixReturnTypes.cpp @ af75a87

ADTast-experimentalpthread-emulationqualifiedEnum
Last change on this file since af75a87 was 1931bb01, checked in by Andrew Beach <ajbeach@…>, 22 months ago

Converted 'Validate A' to the new AST. There some utility changes as well.

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