source: src/AST/Decl.cpp@ 9e72bae3

Last change on this file since 9e72bae3 was 90be0cf, checked in by Andrew Beach <ajbeach@…>, 11 months ago

Moved some methods out of EnumDecl. These were calculations and the ast types are supposed to be data focused so they should either go with utility functions or to their use site. I tried the use site.

  • Property mode set to 100644
File size: 6.7 KB
RevLine 
[2bb4a01]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// Decl.cpp --
8//
9// Author : Aaron B. Moss
10// Created On : Thu May 9 10:00:00 2019
[4c2fe47]11// Last Modified By : Peter A. Buhr
12// Last Modified On : Sat Dec 9 16:28:51 2023
13// Update Count : 31
[2bb4a01]14//
15
16#include "Decl.hpp"
17
[360b2e13]18#include <cassert> // for assert, strict_dynamic_cast
[d76c588]19#include <iostream>
[360b2e13]20#include <unordered_map>
21
[c92bdcc]22#include "Common/Eval.hpp" // for eval
23#include "Common/SemanticError.hpp"
[87701b6]24
[360b2e13]25#include "Fwd.hpp" // for UniqueId
[a300e4a]26#include "Init.hpp"
[360b2e13]27#include "Node.hpp" // for readonly
[87701b6]28#include "Type.hpp" // for readonly
[a4a6802]29#include "Expr.hpp"
[2bb4a01]30
31namespace ast {
[a300e4a]32
[2bb4a01]33// To canonicalize declarations
34static UniqueId lastUniqueId = 0;
35
36void Decl::fixUniqueId() {
37 if ( uniqueId ) return; // ensure only set once
38 uniqueId = ++lastUniqueId;
39}
[a300e4a]40
[8a5530c]41// --- FunctionDecl
42
[7edd5c1]43FunctionDecl::FunctionDecl( const CodeLocation & loc, const std::string & name,
[3e5dd913]44 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
45 CompoundStmt * stmts, Storage::Classes storage, Linkage::Spec linkage,
[3e94a23]46 std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, ArgumentFlag isVarArgs )
[37273c8]47: FunctionDecl( loc, name, {}, {}, std::move(params), std::move(returns),
48 stmts, storage, linkage, std::move(attrs), fs, isVarArgs ) {
[3e5dd913]49}
[490fb92e]50
[7edd5c1]51FunctionDecl::FunctionDecl( const CodeLocation & location, const std::string & name,
52 std::vector<ptr<TypeDecl>>&& forall, std::vector<ptr<DeclWithType>>&& assertions,
53 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
54 CompoundStmt * stmts, Storage::Classes storage, Linkage::Spec linkage,
[3e94a23]55 std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, ArgumentFlag isVarArgs )
[7edd5c1]56: DeclWithType( location, name, storage, linkage, std::move(attrs), fs ),
57 type_params( std::move( forall) ), assertions( std::move( assertions ) ),
[b859f59]58 params( std::move(params) ), returns( std::move(returns) ),
[7edd5c1]59 type( nullptr ), stmts( stmts ) {
[3e94a23]60 FunctionType * type = new FunctionType( isVarArgs );
[7edd5c1]61 for ( auto & param : this->params ) {
62 type->params.emplace_back( param->get_type() );
63 }
64 for ( auto & ret : this->returns ) {
65 type->returns.emplace_back( ret->get_type() );
66 }
67 for ( auto & param : this->type_params ) {
68 type->forall.emplace_back( new TypeInstType( param ) );
69 }
70 for ( auto & assertion : this->assertions ) {
71 type->assertions.emplace_back(
72 new VariableExpr( assertion->location, assertion ) );
73 }
74 this->type = type;
75}
76
[490fb92e]77
[87701b6]78const Type * FunctionDecl::get_type() const { return type.get(); }
[e0e9a0b]79void FunctionDecl::set_type( const Type * t ) {
80 type = strict_dynamic_cast< const FunctionType * >( t );
81}
[8a5530c]82
[360b2e13]83// --- TypeDecl
84
[312029a]85const char * TypeDecl::typeString() const {
[6e50a6b]86 static const char * kindNames[] = { "sized data type", "sized data type", "sized object type", "sized function type", "sized tuple type", "sized length value" };
[b66d14a]87 static_assert( sizeof(kindNames) / sizeof(kindNames[0]) == TypeDecl::NUMBER_OF_KINDS, "typeString: kindNames is out of sync." );
[07de76b]88 assertf( kind < TypeDecl::NUMBER_OF_KINDS, "TypeDecl kind is out of bounds." );
[97b47ec]89 // sizeof("sized") includes '\0' and gives the offset to remove "sized ".
90 return sized ? kindNames[ kind ] : &kindNames[ kind ][ sizeof("sized") ];
[360b2e13]91}
92
[312029a]93const char * TypeDecl::genTypeString() const {
[b66d14a]94 static const char * kindNames[] = { "T &", "T *", "T", "(*)", "T ...", "[T]" };
95 static_assert( sizeof(kindNames) / sizeof(kindNames[0]) == TypeDecl::NUMBER_OF_KINDS, "genTypeString: kindNames is out of sync." );
[07de76b]96 assertf( kind < TypeDecl::NUMBER_OF_KINDS, "TypeDecl kind is out of bounds." );
[360b2e13]97 return kindNames[ kind ];
98}
99
[93c10de]100std::ostream & operator<< ( std::ostream & out, const TypeData & data ) {
[d76c588]101 return out << data.kind << ", " << data.isComplete;
102}
103
[312029a]104// --- AggregateDecl
105
106// These must harmonize with the corresponding AggregateDecl::Aggregate enumerations.
107static const char * aggregateNames[] = { "struct", "union", "enum", "exception", "trait", "generator", "coroutine", "monitor", "thread", "NoAggregateName" };
108
109const char * AggregateDecl::aggrString( AggregateDecl::Aggregate aggr ) {
110 return aggregateNames[aggr];
111}
112
[a300e4a]113// --- EnumDecl
114
[4c2fe47]115bool EnumDecl::valueOf( const Decl * enumerator, long long & value ) const {
[a300e4a]116 if ( enumValues.empty() ) {
[8f557161]117 Evaluation crntVal = {0, true, true}; // until expression is given, we know to start counting from 0
[9d6e7fa9]118 for ( const Decl * member : members ) {
[4c2fe47]119 const ObjectDecl * field = strict_dynamic_cast< const ObjectDecl * >( member );
[a300e4a]120 if ( field->init ) {
[4c2fe47]121 const SingleInit * init = strict_dynamic_cast< const SingleInit * >( field->init.get() );
[8f557161]122 crntVal = eval( init->value );
123 if ( ! crntVal.isEvaluableInGCC ) {
[4c2fe47]124 SemanticError( init->location, "Non-constexpr in initialization of enumerator %s", field->name.c_str() );
[a300e4a]125 }
126 }
127 if ( enumValues.count( field->name ) != 0 ) {
[4c2fe47]128 SemanticError( location, "Enum %s has multiple members with %s", name.c_str(), field->name.c_str() );
[a300e4a]129 }
[8f557161]130 if (crntVal.hasKnownValue) {
131 enumValues[ field->name ] = crntVal.knownValue;
132 }
133 ++crntVal.knownValue;
[a300e4a]134 }
135 }
136
137 auto it = enumValues.find( enumerator->name );
[b859f59]138
[a300e4a]139 if ( it != enumValues.end() ) {
[b859f59]140
[f135b50]141 // Handle typed enum by casting the value in (C++) compiler
[3e54399]142 // if ( base ) { // A typed enum
143 // if ( const BasicType * bt = dynamic_cast<const BasicType *>(base) ) {
144 // switch( bt->kind ) {
145 // case BasicType::Kind::Bool: value = (bool) it->second; break;
146 // case BasicType::Kind::Char: value = (char) it->second; break;
147 // case BasicType::Kind::SignedChar: value = (signed char) it->second; break;
148 // case BasicType::Kind::UnsignedChar: value = (unsigned char) it->second; break;
149 // case BasicType::Kind::ShortSignedInt: value = (short signed int) it->second; break;
150 // case BasicType::Kind::SignedInt: value = (signed int) it->second; break;
151 // case BasicType::Kind::UnsignedInt: value = (unsigned int) it->second; break;
152 // case BasicType::Kind::LongSignedInt: value = (long signed int) it->second; break;
153 // case BasicType::Kind::LongUnsignedInt: value = (long unsigned int) it->second; break;
154 // case BasicType::Kind::LongLongSignedInt: value = (long long signed int) it->second; break;
[b859f59]155 // case BasicType::Kind::LongLongUnsignedInt: value = (long long unsigned int) it->second; break;
[3e54399]156 // // TODO: value should be able to handle long long unsigned int
157
158 // default:
159 // value = it->second;
160 // }
161 // }
162 // } else {
[f135b50]163 value = it->second;
[3e54399]164 //}
[f135b50]165
[a300e4a]166 return true;
167 }
168 return false;
169}
170
[f8f298c]171bool EnumDecl::isTyped() const { return base; }
[5ccc733]172
[8c55d34]173bool EnumDecl::isOpaque() const { return isCfa && !isTyped(); }
174
[2bb4a01]175}
176
177// Local Variables: //
178// tab-width: 4 //
179// mode: c++ //
180// compile-command: "make install" //
181// End: //
Note: See TracBrowser for help on using the repository browser.