Changeset aba20d2 for src/AST


Ignore:
Timestamp:
Jun 17, 2019, 1:09:41 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
800bae1, 9d5089e
Parents:
8b34df0 (diff), b4d34fa (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/AST
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    r8b34df0 raba20d2  
    734734        const ast::Expr * visit( const ast::VariableExpr * node ) override final {
    735735                auto expr = new VariableExpr();
     736                expr->var = get<DeclarationWithType>().accept1(node->var);
    736737                visitBaseExpr( node, expr );
    737                 expr->var = get<DeclarationWithType>().accept1(node->var);
    738                 Type * type = expr->var->get_type()->clone();
    739                 if(FunctionType * ft = dynamic_cast<FunctionType*>(type)) {
    740                         if(node->result.as<ast::PointerType>()) {
    741                                 type = new PointerType({}, ft);
    742                         }
    743                 }
    744 
    745                 type->set_lvalue( true );
    746                 expr->result = type ;
    747738                this->node = expr;
    748739                return nullptr;
     
    750741
    751742        const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
    752                 ConstantExpr *rslt = nullptr;
    753                 switch ( node->kind ) {
    754                 case ast::ConstantExpr::Integer:
    755                         rslt = new ConstantExpr{Constant{
    756                                 get<Type>().accept1( node->result ),
    757                                 node->rep,
    758                                 (unsigned long long) node->intValue()
    759                         }};
    760                         break;
    761                 case ast::ConstantExpr::FloatingPoint:
    762                         rslt = new ConstantExpr{Constant{
    763                                 get<Type>().accept1(node->result),
    764                                 node->rep,
    765                                 (double) node->floatValue()
    766                         }};
    767                         break;
    768                 case ast::ConstantExpr::String:
    769                         rslt = new ConstantExpr{Constant{
    770                                 get<Type>().accept1( node->result ),
    771                                 node->rep,
    772                                 (long long unsigned int)0
    773                         }};
    774                         break;
    775                 }
    776                 assert(rslt);
     743                // Old world:   two types: rslt->constant.type, rslt->result
     744                // New workd:   one public type: node->result, plus node->underlyer only to support roundtrip conversion
     745                //              preserving underlyer because the correct type for string literals is complicated to construct,
     746            //              and distinguishing a string from other literals using the type is hard to do accurately
     747                // Both worlds: the outer, expression-level type can change during resolution
     748                //              for a string, that's char[k] before-resolve and char * after
     749                // Old world:   the inner Constant type stays what it was built with
     750                //              for a string, that's char[k] always
     751                // Both worlds: the "rep" field of a constant is the C source file fragment that compiles to the desired value
     752        //              for a string, that includes outer quotes, backslashes, et al cases from the Literals test
     753                ConstantExpr *rslt = new ConstantExpr(Constant(
     754                        get<Type>().accept1(node->underlyer),
     755                        node->rep,
     756                        node->ival));
    777757                auto expr = visitBaseExpr( node, rslt );
    778758                this->node = expr;
     
    21532133                );
    21542134
    2155                 visitBaseExpr_SkipResultType( old,
    2156                         expr
    2157                 );
    2158 
    21592135                expr->var = GET_ACCEPT_1(var, DeclWithType);
    2160                 expr->result = expr->var->get_type();
    2161                 if(const ast::FunctionType * ft = expr->result.as<ast::FunctionType>()) {
    2162                         if(dynamic_cast<PointerType *>(old->result)) {
    2163                                 expr->result = new ast::PointerType(ft);
    2164                         }
    2165                 }
    2166                 add_qualifiers( expr->result, ast::CV::Lvalue );
    2167                 this->node = expr;
    2168         }
    2169 
    2170         bool isIntlikeConstantType(const Type *t) {
    2171                 if ( const BasicType * basicType = dynamic_cast< const BasicType * >( t ) ) {
    2172                         if ( basicType->isInteger() ) {
    2173                                 return true;
    2174                         }
    2175                 } else if ( dynamic_cast< const OneType * >( t ) ) {
    2176                         return true;
    2177                 } else if ( dynamic_cast< const ZeroType * >( t ) ) {
    2178                         return true;
    2179                 } else if ( dynamic_cast< const PointerType * >( t ) ) {
    2180                         // null pointer constants, with zero int-values
    2181                         return true;
    2182                 }
    2183                 return false;
    2184         }
    2185 
    2186         int isFloatlikeConstantType(const Type *t) {
    2187                 if ( const BasicType * bty = dynamic_cast< const BasicType * >( t ) ) {
    2188                         if ( ! bty->isInteger() ) {
    2189                                 return true;
    2190                         }
    2191                 }
    2192                 return false;
    2193         }
    2194 
    2195         int isStringlikeConstantType(const Type *t) {
    2196                 const Type *referentType = nullptr;
    2197                 if ( const ArrayType * aty = dynamic_cast< const ArrayType * >( t ) ) {
    2198                         referentType = aty->base;
    2199                 } else if ( const PointerType * pty = dynamic_cast< const PointerType * >( t ) ) {
    2200                         referentType = pty->base;
    2201                 }
    2202                 if (referentType) {
    2203                         if ( const BasicType * bty = dynamic_cast< const BasicType * >( referentType ) ) {
    2204                            if ( bty->kind == BasicType::Kind::Char ) {
    2205                                    return true;
    2206                            }
    2207                         }
    2208                 }
    2209                 return false;
     2136                visitBaseExpr( old, expr );
     2137
     2138                this->node = expr;
    22102139        }
    22112140
    22122141        virtual void visit( ConstantExpr * old ) override final {
    2213                 ast::ConstantExpr *rslt = nullptr;
    2214                 if (isStringlikeConstantType(old->result)) {
    2215                         rslt = new ast::ConstantExpr(
    2216                                 old->location,
    2217                                 GET_ACCEPT_1(result, Type),
    2218                                 old->constant.get_value(),
    2219                                 0,
    2220                                 ast::ConstantExpr::Kind::String
    2221                         );
    2222                 } else if (isIntlikeConstantType(old->result)) {
    2223                         rslt = new ast::ConstantExpr(
    2224                                 old->location,
    2225                                 GET_ACCEPT_1(result, Type),
    2226                                 old->constant.get_value(),
    2227                                 (unsigned long long) old->intValue(),
    2228                                 ast::ConstantExpr::Kind::Integer
    2229                         );
    2230                 } else if (isFloatlikeConstantType(old->result)) {
    2231                         rslt = new ast::ConstantExpr(
    2232                                 old->location,
    2233                                 GET_ACCEPT_1(result, Type),
    2234                                 old->constant.get_value(),
    2235                                 (double) old->constant.get_dval()
    2236                         );
    2237                 }
    2238                 assert(rslt);
     2142                ast::ConstantExpr *rslt = new ast::ConstantExpr(
     2143                        old->location,
     2144                        GET_ACCEPT_1(result, Type),
     2145                        old->constant.get_value(),
     2146                        old->constant.ival
     2147                );
     2148                rslt->underlyer = getAccept1< ast::Type, Type* >( old->constant.get_type() );
    22392149                this->node = visitBaseExpr( old, rslt );
    22402150        }
  • src/AST/Expr.cpp

    r8b34df0 raba20d2  
    99// Author           : Aaron B. Moss
    1010// Created On       : Wed May 15 17:00:00 2019
    11 // Last Modified By : Aaron B. Moss
    12 // Created On       : Wed May 15 17:00:00 2019
    13 // Update Count     : 1
     11// Last Modified By : Andrew Beach
     12// Created On       : Thr Jun 13 13:38:00 2019
     13// Update Count     : 2
    1414//
    1515
     
    194194        if ( const BasicType * bty = result.as< BasicType >() ) {
    195195                if ( bty->isInteger() ) {
    196                         return val.ival;
     196                        assert(ival);
     197                        return ival.value();
    197198                }
    198199        } else if ( result.as< ZeroType >() ) {
     
    204205}
    205206
    206 double ConstantExpr::floatValue() const {
    207         if ( const BasicType * bty = result.as< BasicType >() ) {
    208                 if ( ! bty->isInteger() ) {
    209                         return val.dval;
    210                 }
    211         }
    212         SemanticError( this, "Constant expression of non-floating-point type " );
    213 }
    214 
    215207ConstantExpr * ConstantExpr::from_bool( const CodeLocation & loc, bool b ) {
    216208        return new ConstantExpr{
    217209                loc, new BasicType{ BasicType::Bool }, b ? "1" : "0", (unsigned long long)b };
    218 }
    219 
    220 ConstantExpr * ConstantExpr::from_char( const CodeLocation & loc, char c ) {
    221         return new ConstantExpr{
    222                 loc, new BasicType{ BasicType::Char }, std::to_string( c ), (unsigned long long)c };
    223210}
    224211
     
    232219                loc, new BasicType{ BasicType::LongUnsignedInt }, std::to_string( i ),
    233220                (unsigned long long)i };
    234 }
    235 
    236 ConstantExpr * ConstantExpr::from_double( const CodeLocation & loc, double d ) {
    237         return new ConstantExpr{ loc, new BasicType{ BasicType::Double }, std::to_string( d ), d };
    238 }
    239 
    240 ConstantExpr * ConstantExpr::from_string( const CodeLocation & loc, const std::string & s ) {
    241         return new ConstantExpr{
    242                 loc,
    243                 new ArrayType{
    244                         new BasicType{ BasicType::Char, CV::Const },
    245                         ConstantExpr::from_int( loc, s.size() + 1 /* null terminator */ ),
    246                         FixedLen, DynamicDim },
    247                 std::string{"\""} + s + "\"",
    248                 (unsigned long long)0,
    249                 ConstantExpr::String };
    250221}
    251222
     
    382353
    383354UniqueExpr::UniqueExpr( const CodeLocation & loc, const Expr * e, unsigned long long i )
    384 : Expr( loc, e->result ), id( i ) {
     355: Expr( loc, e->result ), expr( e ), id( i ) {
    385356        assert( expr );
    386357        if ( id == -1ull ) {
  • src/AST/Expr.hpp

    r8b34df0 raba20d2  
    2222#include <utility>        // for move
    2323#include <vector>
     24#include <optional>
    2425
    2526#include "Fwd.hpp"        // for UniqueId
     
    3233
    3334class ConverterOldToNew;
     35class ConverterNewToOld;
    3436
    3537namespace ast {
     
    346348};
    347349
    348 /// A compile-time constant
     350/// A compile-time constant.
     351/// Mostly carries C-source text from parse to code-gen, without interpretation.  E.g. strings keep their outer quotes and never have backslashes interpreted.
     352/// Integer constants get special treatment, e.g. for verifying array operations, when an integer constant occurs as the length of an array.
    349353class ConstantExpr final : public Expr {
    350         union Val {
    351                 unsigned long long ival;
    352                 double dval;
    353 
    354                 Val( unsigned long long i ) : ival( i ) {}
    355                 Val( double d ) : dval( d ) {}
    356         } val;
    357 public:
     354public:
     355        // Representation of this constant, as it occurs in .cfa source and .cfa.cc result.
    358356        std::string rep;
    359         enum Kind { Integer, FloatingPoint, String } kind;
    360357
    361358        ConstantExpr(
    362                 const CodeLocation & loc, const Type * ty, const std::string & r, unsigned long long v,
    363                 Kind k = Integer )
    364         : Expr( loc, ty ), val( v ), rep( r ), kind( k ) {}
    365         ConstantExpr( const CodeLocation & loc, const Type * ty, const std::string & r, double v )
    366         : Expr( loc, ty ), val( v ), rep( r ), kind( FloatingPoint ) {}
    367 
    368         /// Gets the value of this constant as an integer
     359                const CodeLocation & loc, const Type * ty, const std::string & r,
     360                        std::optional<unsigned long long> i )
     361        : Expr( loc, ty ), rep( r ), ival( i ) {}
     362
     363        /// Gets the integer value of this constant, if one is appropriate to its type.
     364        /// Throws a SemanticError if the type is not appropriate for value-as-integer.
     365        /// Suffers an assertion failure the type is appropriate but no integer value was supplied to the constructor.
    369366        long long int intValue() const;
    370         /// Gets the value of this constant as floating point
    371         double floatValue() const;
    372367
    373368        /// generates a boolean constant of the given bool
    374369        static ConstantExpr * from_bool( const CodeLocation & loc, bool b );
    375         /// generates a char constant of the given char
    376         static ConstantExpr * from_char( const CodeLocation & loc, char c );
    377370        /// generates an integer constant of the given int
    378371        static ConstantExpr * from_int( const CodeLocation & loc, int i );
    379372        /// generates an integer constant of the given unsigned long int
    380373        static ConstantExpr * from_ulong( const CodeLocation & loc, unsigned long i );
    381         /// generates a floating point constant of the given double
    382         static ConstantExpr * from_double( const CodeLocation & loc, double d );
    383         /// generates an array of chars constant of the given string
    384         static ConstantExpr * from_string( const CodeLocation & loc, const std::string & s );
    385374        /// generates a null pointer value for the given type. void * if omitted.
    386375        static ConstantExpr * null( const CodeLocation & loc, const Type * ptrType = nullptr );
     
    390379        ConstantExpr * clone() const override { return new ConstantExpr{ *this }; }
    391380        MUTATE_FRIEND
     381
     382        std::optional<unsigned long long> ival;
     383
     384        // Intended only for legacy support of roundtripping the old AST.
     385        // Captures the very-locally inferred type, before the resolver modifies the type of this ConstantExpression.
     386        // In the old AST it's constExpr->constant.type
     387        ptr<Type> underlyer;
     388        friend class ::ConverterOldToNew;
     389        friend class ::ConverterNewToOld;
    392390};
    393391
     
    693691        unsigned long long id;
    694692
    695         UniqueExpr( const CodeLocation & loc, const Expr * e, unsigned long long i = -1 );
     693        UniqueExpr( const CodeLocation & loc, const Expr * e, unsigned long long i = -1ull );
    696694
    697695        const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
Note: See TracChangeset for help on using the changeset viewer.