Changeset ffec1bf for src


Ignore:
Timestamp:
Jul 25, 2022, 2:23:28 PM (3 years ago)
Author:
Fangren Yu <f37yu@…>
Branches:
ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
Children:
4c48be0, 5cf1228, def751f
Parents:
9e23b446 (diff), 1f950c3b (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
Files:
15 added
52 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    r9e23b446 rffec1bf  
    168168                auto attr = get<Attribute>().acceptL( node->attributes );
    169169
     170                // This field can be unset very early on (Pre-FixReturnTypes).
     171                auto newType = (type) ? type->clone() : nullptr;
     172
    170173                auto decl = new ObjectDecl(
    171174                        node->name,
     
    173176                        LinkageSpec::Spec( node->linkage.val ),
    174177                        bfwd,
    175                         type->clone(),
     178                        newType,
    176179                        nullptr, // prevent infinite loop
    177180                        attr,
     
    15791582
    15801583        virtual void visit( const ObjectDecl * old ) override final {
     1584                if ( inCache( old ) ) {
     1585                        return;
     1586                }
    15811587                auto&& type = GET_ACCEPT_1(type, Type);
    15821588                auto&& init = GET_ACCEPT_1(init, Init);
    15831589                auto&& bfwd = GET_ACCEPT_1(bitfieldWidth, Expr);
    15841590                auto&& attr = GET_ACCEPT_V(attributes, Attribute);
    1585                 if ( inCache( old ) ) {
    1586                         return;
    1587                 }
     1591
    15881592                auto decl = new ast::ObjectDecl(
    15891593                        old->location,
  • src/AST/Decl.hpp

    r9e23b446 rffec1bf  
    315315
    316316        EnumDecl( const CodeLocation& loc, const std::string& name,
    317                 std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall, Type * base = nullptr,
    318                  std::unordered_map< std::string, long long > enumValues = std::unordered_map< std::string, long long >() )
     317                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall, Type const * base = nullptr,
     318                std::unordered_map< std::string, long long > enumValues = std::unordered_map< std::string, long long >() )
    319319        : AggregateDecl( loc, name, std::move(attrs), linkage ), base(base), enumValues(enumValues) {}
    320320
  • src/AST/Expr.cpp

    r9e23b446 rffec1bf  
    272272        // Adjust the length of the string for the terminator.
    273273        const Expr * strSize = from_ulong( loc, str.size() + 1 );
    274         const Type * strType = new ArrayType( charType, strSize, FixedLen, StaticDim );
     274        const Type * strType = new ArrayType( charType, strSize, FixedLen, DynamicDim );
    275275        const std::string strValue = "\"" + str + "\"";
    276276        return new ConstantExpr( loc, strType, strValue, std::nullopt );
  • src/AST/Pass.impl.hpp

    r9e23b446 rffec1bf  
    681681        if ( __visit_children() ) {
    682682                // unlike structs, traits, and unions, enums inject their members into the global scope
     683                maybe_accept( node, &EnumDecl::base );
    683684                maybe_accept( node, &EnumDecl::params     );
    684685                maybe_accept( node, &EnumDecl::members    );
  • src/AST/module.mk

    r9e23b446 rffec1bf  
    3737        AST/Init.cpp \
    3838        AST/Init.hpp \
     39        AST/Inspect.cpp \
     40        AST/Inspect.hpp \
    3941        AST/Label.hpp \
    4042        AST/LinkageSpec.cpp \
  • src/CodeGen/CodeGenerator.cc

    r9e23b446 rffec1bf  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Feb  2 20:30:30 2022
    13 // Update Count     : 541
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Jun 29 14:34:00 2022
     13// Update Count     : 542
    1414//
    1515#include "CodeGenerator.h"
     
    1818#include <list>                      // for _List_iterator, list, list<>::it...
    1919
     20#include "AST/Decl.hpp"              // for DeclWithType
    2021#include "Common/UniqueName.h"       // for UniqueName
    2122#include "Common/utility.h"          // for CodeLocation, toString
     
    294295                                } else {
    295296                                        if ( obj->get_init() ) {
    296                                                 obj->get_init()->accept( *visitor ); 
     297                                                obj->get_init()->accept( *visitor );
    297298                                        } else {
    298299                                                // Should not reach here!
     
    683684                extension( variableExpr );
    684685                const OperatorInfo * opInfo;
    685                 if ( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && (opInfo = operatorLookup( variableExpr->get_var()->get_name() )) && opInfo->type == OT_CONSTANT ) {
     686                if( dynamic_cast<ZeroType*>( variableExpr->get_var()->get_type() ) ) {
     687                        output << "0";
     688                } else if ( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && (opInfo = operatorLookup( variableExpr->get_var()->get_name() )) && opInfo->type == OT_CONSTANT ) {
    686689                        output << opInfo->symbol;
    687690                } else {
    688                         // if (dynamic_cast<EnumInstType *>(variableExpr->get_var()->get_type()) 
     691                        // if (dynamic_cast<EnumInstType *>(variableExpr->get_var()->get_type())
    689692                        // && dynamic_cast<EnumInstType *>(variableExpr->get_var()->get_type())->baseEnum->base) {
    690693                        //      output << '(' <<genType(dynamic_cast<EnumInstType *>(variableExpr->get_var()->get_type())->baseEnum->base, "", options) << ')';
     
    12361239                } // if
    12371240        }
     1241
     1242std::string genName( ast::DeclWithType const * decl ) {
     1243        if ( const OperatorInfo * opInfo = operatorLookup( decl->name ) ) {
     1244                return opInfo->outputName;
     1245        } else {
     1246                return decl->name;
     1247        }
     1248}
     1249
    12381250} // namespace CodeGen
    12391251
  • src/CodeGen/CodeGenerator.h

    r9e23b446 rffec1bf  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  1 09:23:21 2022
    13 // Update Count     : 64
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Jun 29 14:32:00 2022
     13// Update Count     : 65
    1414//
    1515
     
    2626#include "SynTree/Visitor.h"      // for Visitor
    2727#include "SynTree/SynTree.h"      // for Visitor Nodes
     28
     29namespace ast {
     30        class DeclWithType;
     31}
    2832
    2933namespace CodeGen {
     
    182186        /// returns C-compatible name of declaration
    183187        std::string genName( DeclarationWithType * decl );
     188        std::string genName( ast::DeclWithType const * decl );
    184189
    185190        inline std::ostream & operator<<( std::ostream & os, const CodeGenerator::LineEnder & endl ) {
  • src/CodeGen/FixNames.cc

    r9e23b446 rffec1bf  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // FixNames.cc --
     7// FixNames.cc -- Adjustments to typed declarations.
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Oct 29 15:49:00 2021
    13 // Update Count     : 23
     12// Last Modified On : Wed Jul 20 11:49:00 2022
     13// Update Count     : 24
    1414//
    1515
     
    8787
    8888/// Does work with the main function and scopeLevels.
    89 class FixNames_new : public ast::WithGuards {
     89class FixNames_new final {
    9090        int scopeLevel = 1;
    9191
     
    103103
    104104        const ast::FunctionDecl *postvisit( const ast::FunctionDecl *functionDecl ) {
    105                 // This store is used to ensure a maximum of one call to mutate.
    106                 ast::FunctionDecl * mutDecl = nullptr;
     105                if ( FixMain::isMain( functionDecl ) ) {
     106                        auto mutDecl = ast::mutate( functionDecl );
    107107
    108                 if ( shouldSetScopeLevel( functionDecl ) ) {
    109                         mutDecl = ast::mutate( functionDecl );
    110                         mutDecl->scopeLevel = scopeLevel;
    111                 }
    112 
    113                 if ( FixMain::isMain( functionDecl ) ) {
    114                         if ( !mutDecl ) { mutDecl = ast::mutate( functionDecl ); }
     108                        if ( shouldSetScopeLevel( mutDecl ) ) {
     109                                mutDecl->scopeLevel = scopeLevel;
     110                        }
    115111
    116112                        int nargs = mutDecl->params.size();
     
    124120                                )
    125121                        );
     122
     123                        return mutDecl;
     124                } else if ( shouldSetScopeLevel( functionDecl ) ) {
     125                        return ast::mutate_field( functionDecl, &ast::FunctionDecl::scopeLevel, scopeLevel );
     126                } else {
     127                        return functionDecl;
    126128                }
    127                 return mutDecl ? mutDecl : functionDecl;
    128129        }
    129130
    130131        void previsit( const ast::CompoundStmt * ) {
    131                 GuardValue( scopeLevel ) += 1;
     132                scopeLevel += 1;
     133        }
     134
     135        void postvisit( const ast::CompoundStmt * ) {
     136                scopeLevel -= 1;
    132137        }
    133138};
  • src/CodeGen/FixNames.h

    r9e23b446 rffec1bf  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // FixNames.h --
     7// FixNames.h -- Adjustments to typed declarations.
    88//
    99// Author           : Richard C. Bilson
     
    2626        /// mangles object and function names
    2727        void fixNames( std::list< Declaration* > & translationUnit );
    28         void fixNames( ast::TranslationUnit & translationUnit );
     28/// Sets scope levels and fills in main's default return.
     29void fixNames( ast::TranslationUnit & translationUnit );
    2930} // namespace CodeGen
    3031
  • src/CodeGen/GenType.cc

    r9e23b446 rffec1bf  
    254254
    255255        void GenType::postvisit( EnumInstType * enumInst ) {
    256                 if ( enumInst->baseEnum->base ) {
     256                if ( enumInst->baseEnum && enumInst->baseEnum->base ) {
    257257                        typeString = genType(enumInst->baseEnum->base, "", options) + typeString;
    258258                } else {
  • src/Common/Eval.cc

    r9e23b446 rffec1bf  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 24 15:09:06 2019
    13 // Update Count     : 64
     12// Last Modified On : Fri Jul  1 08:41:03 2022
     13// Update Count     : 117
    1414//
    1515
     
    1717
    1818#include "Common/PassVisitor.h"
     19#include "CodeGen/OperatorTable.h"                                              // access: OperatorInfo
    1920#include "AST/Pass.hpp"
    2021#include "InitTweak/InitTweak.h"
     
    2425// Old AST
    2526struct EvalOld : public WithShortCircuiting {
    26         long long int value = 0;
    27         bool valid = true;
     27        long long int value = 0;                                                        // compose the result of the constant expression
     28        bool valid = true;                                                                      // true => constant expression and value is the result
     29                                                                                                                // false => not constant expression, e.g., ++i
     30        bool cfavalid = true;                                                           // true => constant expression and value computable
     31                                                                                                                // false => constant expression but value not computable, e.g., sizeof(int)
    2832
    2933        void previsit( const BaseSyntaxNode * ) { visit_children = false; }
     
    8993// New AST
    9094struct EvalNew : public ast::WithShortCircuiting {
    91         long long int value = 0;
    92         bool valid = true;
     95        long long int value = 0;                                                        // compose the result of the constant expression
     96        bool valid = true;                                                                      // true => constant expression and value is the result
     97                                                                                                                // false => not constant expression, e.g., ++i
     98        bool cfavalid = true;                                                           // true => constant expression and value computable
     99                                                                                                                // false => constant expression but value not computable, e.g., sizeof(int)
    93100
    94101        void previsit( const ast::Node * ) { visit_children = false; }
    95         void postvisit( const ast::Node * ) { valid = false; }
    96 
    97         void postvisit( const ast::ConstantExpr * expr ) {
     102        void postvisit( const ast::Node * ) { cfavalid = valid = false; }
     103
     104        void postvisit( const ast::UntypedExpr * ) {
     105                assertf( false, "UntypedExpr in constant expression evaluation" ); // FIX ME, resolve variable
     106        }
     107
     108        void postvisit( const ast::ConstantExpr * expr ) {      // only handle int constants
    98109                value = expr->intValue();
    99110        }
    100111
    101         void postvisit( const ast::SizeofExpr * expr ) {
    102                 if ( expr->expr ) value = eval(expr->expr).first;
    103                 else if ( expr->type ) value = eval(expr->expr).first;
    104                 else SemanticError( expr->location, ::toString( "Internal error: SizeofExpr has no expression or type value" ) );
    105         }
    106 
    107         void postvisit( const ast::CastExpr * expr ) {
     112        void postvisit( const ast::SizeofExpr * ) {
     113                // do not change valid or value => let C figure it out
     114                cfavalid = false;
     115        }
     116
     117        void postvisit( const ast::AlignofExpr * ) {
     118                // do not change valid or value => let C figure it out
     119                cfavalid = false;
     120        }
     121
     122        void postvisit( const ast::OffsetofExpr * ) {
     123                // do not change valid or value => let C figure it out
     124                cfavalid = false;
     125        }
     126
     127        void postvisit( const ast::LogicalExpr * expr ) {
     128                std::pair<long long int, bool> arg1, arg2;
     129                arg1 = eval( expr->arg1 );
     130                valid &= arg1.second;
     131                if ( ! valid ) return;
     132                arg2 = eval( expr->arg2 );
     133                valid &= arg2.second;
     134                if ( ! valid ) return;
     135
     136                if ( expr->isAnd ) {
     137                        value = arg1.first && arg2.first;
     138                } else {
     139                        value = arg1.first || arg2.first;
     140                } // if
     141        }
     142
     143        void postvisit( const ast::ConditionalExpr * expr ) {
     144                std::pair<long long int, bool> arg1, arg2, arg3;
     145                arg1 = eval( expr->arg1 );
     146                valid &= arg1.second;
     147                if ( ! valid ) return;
     148                arg2 = eval( expr->arg2 );
     149                valid &= arg2.second;
     150                if ( ! valid ) return;
     151                arg3 = eval( expr->arg3 );
     152                valid &= arg3.second;
     153                if ( ! valid ) return;
     154
     155                value = arg1.first ? arg2.first : arg3.first;
     156        }
     157
     158        void postvisit( const ast::CastExpr * expr ) {         
     159                // cfa-cc generates a cast before every constant and many other places, e.g., (int)3, so the cast argument must
     160                // be evaluated to get the constant value.
    108161                auto arg = eval(expr->arg);
    109162                valid = arg.second;
    110163                value = arg.first;
    111                 // TODO: perform type conversion on value if valid
    112         }
    113 
    114         void postvisit( const ast::VariableExpr * expr ) { // No hit
     164                cfavalid = false;
     165        }
     166
     167        void postvisit( const ast::VariableExpr * expr ) {
    115168                if ( const ast::EnumInstType * inst = dynamic_cast<const ast::EnumInstType *>(expr->result.get()) ) {
    116169                        if ( const ast::EnumDecl * decl = inst->base ) {
     
    128181                const std::string & fname = function->name;
    129182                assertf( expr->args.size() == 1 || expr->args.size() == 2, "Intrinsic function with %zd arguments: %s", expr->args.size(), fname.c_str() );
    130                 std::pair<long long int, bool> arg1, arg2;
    131                 arg1 = eval(expr->args.front());
    132                 valid = valid && arg1.second;
    133                 if ( ! valid ) return;
    134                 if ( expr->args.size() == 2 ) {
     183
     184                if ( expr->args.size() == 1 ) {
     185                        // pre/postfix operators ++ and -- => assignment, which is not constant
     186                        std::pair<long long int, bool> arg1;
     187                        arg1 = eval(expr->args.front());
     188                        valid &= arg1.second;
     189                        if ( ! valid ) return;
     190
     191                        if (fname == "+?") {
     192                                value = arg1.first;
     193                        } else if (fname == "-?") {
     194                                value = -arg1.first;
     195                        } else if (fname == "~?") {
     196                                value = ~arg1.first;
     197                        } else if (fname == "!?") {
     198                                value = ! arg1.first;
     199                        } else {
     200                                valid = false;
     201                        } // if
     202                } else { // => expr->args.size() == 2
     203                        // infix assignment operators => assignment, which is not constant
     204                        std::pair<long long int, bool> arg1, arg2;
     205                        arg1 = eval(expr->args.front());
     206                        valid &= arg1.second;
     207                        if ( ! valid ) return;
    135208                        arg2 = eval(expr->args.back());
    136                         valid = valid && arg2.second;
    137                         if ( ! valid ) return;
    138                 }
    139                 if (fname == "?+?") {
    140                         value = arg1.first + arg2.first;
    141                 } else if (fname == "?-?") {
    142                         value = arg1.first - arg2.first;
    143                 } else if (fname == "?*?") {
    144                         value = arg1.first * arg2.first;
    145                 } else if (fname == "?/?") {
    146                         value = arg1.first / arg2.first;
    147                 } else if (fname == "?%?") {
    148                         value = arg1.first % arg2.first;
    149                 } else {
    150                         valid = false;
    151                 }
     209                        valid &= arg2.second;
     210                        if ( ! valid ) return;
     211
     212                        if (fname == "?+?") {
     213                                value = arg1.first + arg2.first;
     214                        } else if (fname == "?-?") {
     215                                value = arg1.first - arg2.first;
     216                        } else if (fname == "?*?") {
     217                                value = arg1.first * arg2.first;
     218                        } else if (fname == "?/?") {
     219                                value = arg1.first / arg2.first;
     220                        } else if (fname == "?%?") {
     221                                value = arg1.first % arg2.first;
     222                        } else if (fname == "?<<?") {
     223                                value = arg1.first << arg2.first;
     224                        } else if (fname == "?>>?") {
     225                                value = arg1.first >> arg2.first;
     226                        } else if (fname == "?<?") {
     227                                value = arg1.first < arg2.first;
     228                        } else if (fname == "?>?") {
     229                                value = arg1.first > arg2.first;
     230                        } else if (fname == "?<=?") {
     231                                value = arg1.first <= arg2.first;
     232                        } else if (fname == "?>=?") {
     233                                value = arg1.first >= arg2.first;
     234                        } else if (fname == "?==?") {
     235                                value = arg1.first == arg2.first;
     236                        } else if (fname == "?!=?") {
     237                                value = arg1.first != arg2.first;
     238                        } else if (fname == "?&?") {
     239                                value = arg1.first & arg2.first;
     240                        } else if (fname == "?^?") {
     241                                value = arg1.first ^ arg2.first;
     242                        } else if (fname == "?|?") {
     243                                value = arg1.first | arg2.first;
     244                        } else {
     245                                valid = false;
     246                        }
     247                } // if
    152248                // TODO: implement other intrinsic functions
    153249        }
    154250};
    155251
    156 std::pair<long long int, bool> eval( const Expression * expr) {
     252std::pair<long long int, bool> eval( const Expression * expr ) {
    157253        PassVisitor<EvalOld> ev;
    158         if (expr) {
    159                 expr->accept(ev);
    160                 return std::make_pair(ev.pass.value, ev.pass.valid);
     254        if ( expr ) {
     255                expr->accept( ev );
     256                return std::make_pair( ev.pass.value, ev.pass.valid );
    161257        } else {
    162                 return std::make_pair(0, false);
     258                return std::make_pair( 0, false );
    163259        }
    164260}
    165261
    166 std::pair<long long int, bool> eval(const ast::Expr * expr) {
     262std::pair<long long int, bool> eval( const ast::Expr * expr ) {
    167263        ast::Pass<EvalNew> ev;
    168         if (expr) {
    169                 expr->accept(ev);
    170                 return std::make_pair(ev.core.value, ev.core.valid);
     264        if ( expr ) {
     265                expr->accept( ev );
     266                return std::make_pair( ev.core.value, ev.core.valid );
    171267        } else {
    172                 return std::make_pair(0, false);
     268                return std::make_pair( 0, false );
    173269        }
    174270}
  • src/Common/ResolvProtoDump.cpp

    r9e23b446 rffec1bf  
    227227        }
    228228
    229         void previsit( const ast::EnumInstType * enumInst) {
     229        void previsit( const ast::EnumInstType * ) {
    230230                // TODO: Add the meaningful text representation of typed enum
    231231                ss << (int)ast::BasicType::SignedInt;
  • src/Concurrency/Keywords.h

    r9e23b446 rffec1bf  
    2828        void implementThreadStarter( std::list< Declaration * > & translationUnit );
    2929
    30 /// Implement the sue-like keywords and the suspend keyword.
     30/// Implement the sue-like keywords and the suspend keyword. Pre-Autogen
    3131void implementKeywords( ast::TranslationUnit & translationUnit );
    32 /// Implement the mutex parameters and mutex statement.
     32/// Implement the mutex parameters and mutex statement. Post-Autogen
    3333void implementMutex( ast::TranslationUnit & translationUnit );
    34 /// Add the thread starter code to constructors.
     34/// Add the thread starter code to constructors. Post-Autogen
    3535void implementThreadStarter( ast::TranslationUnit & translationUnit );
    3636};
  • src/ControlStruct/ExceptDecl.cc

    r9e23b446 rffec1bf  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // ExceptDecl.cc --
     7// ExceptDecl.cc -- Handles declarations of exception types.
    88//
    99// Author           : Henry Xue
  • src/ControlStruct/ExceptDecl.h

    r9e23b446 rffec1bf  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // ExceptDecl.h --
     7// ExceptDecl.h -- Handles declarations of exception types.
    88//
    99// Author           : Henry Xue
    1010// Created On       : Tue Jul 20 04:10:50 2021
    11 // Last Modified By : Henry Xue
    12 // Last Modified On : Tue Jul 20 04:10:50 2021
    13 // Update Count     : 1
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Jul 12 15:49:00 2022
     13// Update Count     : 2
    1414//
    1515
     
    2020class Declaration;
    2121
     22namespace ast {
     23        class TranslationUnit;
     24}
     25
    2226namespace ControlStruct {
    23         void translateExcept( std::list< Declaration *> & translationUnit );
     27/// Unfold exception declarations into raw structure declarations.
     28/// Also builds vtable declarations and converts vtable types.
     29void translateExcept( std::list< Declaration *> & translationUnit );
     30void translateExcept( ast::TranslationUnit & translationUnit );
    2431}
  • src/ControlStruct/HoistControlDecls.hpp

    r9e23b446 rffec1bf  
    2121
    2222namespace ControlStruct {
    23 // Hoist declarations out of control flow statements into compound statement.
     23/// Hoist declarations out of control flow statements into compound statement.
     24/// Must happen before auto-gen routines are added.
    2425void hoistControlDecls( ast::TranslationUnit & translationUnit );
    2526} // namespace ControlStruct
  • src/ControlStruct/MultiLevelExit.cpp

    r9e23b446 rffec1bf  
    149149};
    150150
    151 NullStmt * labelledNullStmt(
    152         const CodeLocation & cl, const Label & label ) {
     151NullStmt * labelledNullStmt( const CodeLocation & cl, const Label & label ) {
    153152        return new NullStmt( cl, vector<Label>{ label } );
    154153}
     
    164163
    165164const CompoundStmt * MultiLevelExitCore::previsit(
    166         const CompoundStmt * stmt ) {
     165                const CompoundStmt * stmt ) {
    167166        visit_children = false;
    168167
     
    189188}
    190189
    191 size_t getUnusedIndex(
    192         const Stmt * stmt, const Label & originalTarget ) {
     190size_t getUnusedIndex( const Stmt * stmt, const Label & originalTarget ) {
    193191        const size_t size = stmt->labels.size();
    194192
     
    210208}
    211209
    212 const Stmt * addUnused(
    213         const Stmt * stmt, const Label & originalTarget ) {
     210const Stmt * addUnused( const Stmt * stmt, const Label & originalTarget ) {
    214211        size_t i = getUnusedIndex( stmt, originalTarget );
    215212        if ( i == stmt->labels.size() ) {
     
    356353
    357354// Mimic what the built-in push_front would do anyways. It is O(n).
    358 void push_front(
    359         vector<ptr<Stmt>> & vec, const Stmt * element ) {
     355void push_front( vector<ptr<Stmt>> & vec, const Stmt * element ) {
    360356        vec.emplace_back( nullptr );
    361357        for ( size_t i = vec.size() - 1 ; 0 < i ; --i ) {
     
    590586
    591587                ptr<Stmt> else_stmt = nullptr;
    592                 Stmt * loop_kid = nullptr;
     588                const Stmt * loop_kid = nullptr;
    593589                // check if loop node and if so add else clause if it exists
    594                 const WhileDoStmt * whilePtr = dynamic_cast<const WhileDoStmt *>(kid.get());
    595                 if ( whilePtr && whilePtr->else_) {
     590                const WhileDoStmt * whilePtr = kid.as<WhileDoStmt>();
     591                if ( whilePtr && whilePtr->else_ ) {
    596592                        else_stmt = whilePtr->else_;
    597                         WhileDoStmt * mutate_ptr = mutate(whilePtr);
    598                         mutate_ptr->else_ = nullptr;
    599                         loop_kid = mutate_ptr;
    600                 }
    601                 const ForStmt * forPtr = dynamic_cast<const ForStmt *>(kid.get());
    602                 if ( forPtr && forPtr->else_) {
     593                        loop_kid = mutate_field( whilePtr, &WhileDoStmt::else_, nullptr );
     594                }
     595                const ForStmt * forPtr = kid.as<ForStmt>();
     596                if ( forPtr && forPtr->else_ ) {
    603597                        else_stmt = forPtr->else_;
    604                         ForStmt * mutate_ptr = mutate(forPtr);
    605                         mutate_ptr->else_ = nullptr;
    606                         loop_kid = mutate_ptr;
     598                        loop_kid = mutate_field( forPtr, &ForStmt::else_, nullptr );
    607599                }
    608600
  • src/ControlStruct/module.mk

    r9e23b446 rffec1bf  
    1717SRC += \
    1818        ControlStruct/ExceptDecl.cc \
     19        ControlStruct/ExceptDeclNew.cpp \
    1920        ControlStruct/ExceptDecl.h \
    2021        ControlStruct/ExceptTranslateNew.cpp \
  • src/GenPoly/Box.cc

    r9e23b446 rffec1bf  
    189189                        /// Enters a new scope for type-variables, adding the type variables from ty
    190190                        void beginTypeScope( Type *ty );
    191                         /// Exits the type-variable scope
    192                         void endTypeScope();
    193191                        /// Enters a new scope for knowLayouts and knownOffsets and queues exit calls
    194192                        void beginGenericScope();
     
    198196                        UniqueName bufNamer;                           ///< Namer for VLA buffers
    199197                        Expression * addrMember = nullptr;             ///< AddressExpr argument is MemberExpr?
     198                        bool expect_func_type = false;                 ///< used to avoid recursing too deep in type decls
    200199                };
    201200
     
    12771276                        FunctionType * ftype = functionDecl->type;
    12781277                        if ( ! ftype->returnVals.empty() && functionDecl->statements ) {
    1279                                 if ( ! isPrefix( functionDecl->name, "_thunk" ) && ! isPrefix( functionDecl->name, "_adapter" ) ) { // xxx - remove check for prefix once thunks properly use ctor/dtors
     1278                                // intrinsic functions won't be using the _retval so no need to generate it.
     1279                                if ( functionDecl->linkage != LinkageSpec::Intrinsic && !isPrefix( functionDecl->name, "_thunk" ) && ! isPrefix( functionDecl->name, "_adapter" ) ) { // xxx - remove check for prefix once thunks properly use ctor/dtors
    12801280                                        assert( ftype->returnVals.size() == 1 );
    12811281                                        DeclarationWithType * retval = ftype->returnVals.front();
     
    14181418                void PolyGenericCalculator::beginGenericScope() {
    14191419                        GuardScope( *this );
     1420                        // We expect the first function type see to be the type relating to this scope
     1421                        // but any further type is probably some unrelated function pointer
     1422                        // keep track of which is the first
     1423                        GuardValue( expect_func_type );
     1424                        expect_func_type = true;
    14201425                }
    14211426
     
    14671472                void PolyGenericCalculator::premutate( FunctionType *funcType ) {
    14681473                        beginTypeScope( funcType );
     1474
     1475                        GuardValue( expect_func_type );
     1476
     1477                        if(!expect_func_type) {
     1478                                GuardAction( [this]() {
     1479                                        knownLayouts.endScope();
     1480                                        knownOffsets.endScope();
     1481                                });
     1482                                // If this is the first function type we see
     1483                                // Then it's the type of the declaration and we care about it
     1484                                knownLayouts.beginScope();
     1485                                knownOffsets.beginScope();
     1486                        }
     1487
     1488                        // The other functions type we will see in this scope are probably functions parameters
     1489                        // they don't help us with the layout and offsets so don't mark them as known in this scope
     1490                        expect_func_type = false;
    14691491
    14701492                        // make sure that any type information passed into the function is accounted for
     
    17451767                                }
    17461768
     1769                                // std::cout << "TRUE 2" << std::endl;
     1770
    17471771                                return true;
    17481772                        } else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) {
  • src/GenPoly/GenPoly.cc

    r9e23b446 rffec1bf  
    6464                }
    6565
    66                 __attribute__((ununsed))
     66                __attribute__((unused))
    6767                bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap & tyVars, const ast::TypeSubstitution * env) {
    6868                        for (auto &param : params) {
  • src/InitTweak/GenInit.cc

    r9e23b446 rffec1bf  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // GenInit.cc --
     7// GenInit.cc -- Generate initializers, and other stuff.
    88//
    99// Author           : Rob Schluntz
     
    642642
    643643ast::ConstructorInit * genCtorInit( const CodeLocation & loc, const ast::ObjectDecl * objDecl ) {
    644         // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor for each 
     644        // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor for each
    645645        // constructable object
    646646        InitExpander_new srcParam{ objDecl->init }, nullParam{ (const ast::Init *)nullptr };
    647647        ast::ptr< ast::Expr > dstParam = new ast::VariableExpr(loc, objDecl);
    648        
    649         ast::ptr< ast::Stmt > ctor = SymTab::genImplicitCall( 
     648
     649        ast::ptr< ast::Stmt > ctor = SymTab::genImplicitCall(
    650650                srcParam, dstParam, loc, "?{}", objDecl );
    651         ast::ptr< ast::Stmt > dtor = SymTab::genImplicitCall( 
    652                 nullParam, dstParam, loc, "^?{}", objDecl, 
     651        ast::ptr< ast::Stmt > dtor = SymTab::genImplicitCall(
     652                nullParam, dstParam, loc, "^?{}", objDecl,
    653653                SymTab::LoopBackward );
    654        
     654
    655655        // check that either both ctor and dtor are present, or neither
    656656        assert( (bool)ctor == (bool)dtor );
    657657
    658658        if ( ctor ) {
    659                 // need to remember init expression, in case no ctors exist. If ctor does exist, want to 
     659                // need to remember init expression, in case no ctors exist. If ctor does exist, want to
    660660                // use ctor expression instead of init.
    661                 ctor.strict_as< ast::ImplicitCtorDtorStmt >(); 
     661                ctor.strict_as< ast::ImplicitCtorDtorStmt >();
    662662                dtor.strict_as< ast::ImplicitCtorDtorStmt >();
    663663
  • src/InitTweak/GenInit.h

    r9e23b446 rffec1bf  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // GenInit.h --
     7// GenInit.h -- Generate initializers, and other stuff.
    88//
    99// Author           : Rodolfo G. Esteves
     
    2929        void genInit( ast::TranslationUnit & translationUnit );
    3030
    31         /// Converts return statements into copy constructor calls on the hidden return variable
     31        /// Converts return statements into copy constructor calls on the hidden return variable.
     32        /// This pass must happen before auto-gen.
    3233        void fixReturnStatements( std::list< Declaration * > & translationUnit );
    3334        void fixReturnStatements( ast::TranslationUnit & translationUnit );
  • src/Parser/lex.ll

    r9e23b446 rffec1bf  
    8282// Stop warning due to incorrectly generated flex code.
    8383#pragma GCC diagnostic ignored "-Wsign-compare"
     84
     85// lex uses __null in a boolean context, it's fine.
     86#pragma GCC diagnostic ignored "-Wnull-conversion"
    8487%}
    8588
  • src/Parser/parser.yy

    r9e23b446 rffec1bf  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat May 14 09:16:22 2022
    13 // Update Count     : 5401
     12// Last Modified On : Fri Jul  1 15:35:08 2022
     13// Update Count     : 5405
    1414//
    1515
     
    5656
    5757#include "SynTree/Attribute.h"     // for Attribute
     58
     59// lex uses __null in a boolean context, it's fine.
     60#pragma GCC diagnostic ignored "-Wparentheses-equality"
    5861
    5962extern DeclarationNode * parseTree;
     
    12401243                {
    12411244                        $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) );
    1242                         SemanticWarning( yylloc, Warning::SuperfluousElse );
     1245                        SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
    12431246                }
    12441247        | WHILE '(' conditional_declaration ')' statement       %prec THEN
     
    12511254                {
    12521255                        $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) );
    1253                         SemanticWarning( yylloc, Warning::SuperfluousElse );
     1256                        SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
    12541257                }
    12551258        | DO statement WHILE '(' comma_expression ')' ';'
     
    12621265                {
    12631266                        $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) );
    1264                         SemanticWarning( yylloc, Warning::SuperfluousElse );
     1267                        SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
    12651268                }
    12661269        | FOR '(' for_control_expression_list ')' statement     %prec THEN
     
    23942397        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'
    23952398                {
    2396                         if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) 
     2399                        if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 )
    23972400                        { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
    23982401
     
    24382441        // empty
    24392442                { $$ = nullptr; }
    2440         // | '=' constant_expression
    2441         //      { $$ = $2; }
    2442         | simple_assignment_operator initializer
    2443                 { $$ = $1 == OperKinds::Assign ? $2 : $2->set_maybeConstructed( false ); }
     2443        | '=' constant_expression                                       { $$ = new InitializerNode( $2 ); }
     2444        | '=' '{' initializer_list_opt comma_opt '}' { $$ = new InitializerNode( $3, true ); }
     2445        // | simple_assignment_operator initializer
     2446        //      { $$ = $1 == OperKinds::Assign ? $2 : $2->set_maybeConstructed( false ); }
    24442447        ;
    24452448
     
    28412844                        linkage = LinkageSpec::update( yylloc, linkage, $2 );
    28422845                }
    2843           up external_definition down 
     2846          up external_definition down
    28442847                {
    28452848                        linkage = linkageStack.top();
  • src/ResolvExpr/CandidateFinder.cpp

    r9e23b446 rffec1bf  
    4141#include "Common/utility.h"       // for move, copy
    4242#include "SymTab/Mangler.h"
    43 #include "SymTab/Validate.h"      // for validateType
    4443#include "Tuples/Tuples.h"        // for handleTupleAssignment
    4544#include "InitTweak/InitTweak.h"  // for getPointerBase
     
    10911090                        assert( toType );
    10921091                        toType = resolveTypeof( toType, context );
    1093                         // toType = SymTab::validateType( castExpr->location, toType, symtab );
    10941092                        toType = adjustExprType( toType, tenv, symtab );
    10951093
     
    15901588                                // calculate target type
    15911589                                const ast::Type * toType = resolveTypeof( initAlt.type, context );
    1592                                 // toType = SymTab::validateType( initExpr->location, toType, symtab );
    15931590                                toType = adjustExprType( toType, tenv, symtab );
    15941591                                // The call to find must occur inside this loop, otherwise polymorphic return
  • src/ResolvExpr/CurrentObject.cc

    r9e23b446 rffec1bf  
    99// Author           : Rob Schluntz
    1010// Created On       : Tue Jun 13 15:28:32 2017
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Jun 13 15:28:44 2017
    13 // Update Count     : 2
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Jul  1 09:16:01 2022
     13// Update Count     : 15
    1414//
    1515
     
    7373                virtual void setPosition( std::list< Expression * > & designators ) = 0;
    7474
    75                 /// retrieve the list of possible Type/Designaton pairs for the current position in the currect object
     75                /// retrieve the list of possible Type/Designation pairs for the current position in the currect object
    7676                virtual std::list<InitAlternative> operator*() const = 0;
    7777
     
    158158
    159159        private:
    160                 void setSize( Expression * expr ) { // replace this logic with an eval call
    161                         auto res = eval(expr);
     160                void setSize( Expression * expr ) {
     161                        auto res = eval( expr );
    162162                        if (res.second) {
    163163                                size = res.first;
     
    170170                void setPosition( Expression * expr ) {
    171171                        // need to permit integer-constant-expressions, including: integer constants, enumeration constants, character constants, sizeof expressions, _Alignof expressions, cast expressions
    172                         if ( ConstantExpr * constExpr = dynamic_cast< ConstantExpr * >( expr ) ) {
    173                                 try {
    174                                         index = constExpr->intValue();
    175                                 } catch( SemanticErrorException & ) {
    176                                         SemanticError( expr, "Constant expression of non-integral type in array designator: " );
    177                                 }
    178                         } else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
    179                                 setPosition( castExpr->get_arg() );
    180                         } else if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( expr ) ) {
    181                                 EnumInstType * inst = dynamic_cast<EnumInstType *>( varExpr->get_result() );
    182                                 assertf( inst, "ArrayIterator given variable that isn't an enum constant : %s", toString( expr ).c_str() );
    183                                 long long int value;
    184                                 if ( inst->baseEnum->valueOf( varExpr->var, value ) ) {
    185                                         index = value;
    186                                 }
    187                         } else if ( dynamic_cast< SizeofExpr * >( expr ) || dynamic_cast< AlignofExpr * >( expr ) ) {
    188                                 index = 0; // xxx - get actual sizeof/alignof value?
    189                         } else {
    190                                 assertf( false, "bad designator given to ArrayIterator: %s", toString( expr ).c_str() );
    191                         }
     172                        auto arg = eval( expr );
     173                        index = arg.first;
     174                        return;
     175
     176                        // if ( ConstantExpr * constExpr = dynamic_cast< ConstantExpr * >( expr ) ) {
     177                        //      try {
     178                        //              index = constExpr->intValue();
     179                        //      } catch( SemanticErrorException & ) {
     180                        //              SemanticError( expr, "Constant expression of non-integral type in array designator: " );
     181                        //      }
     182                        // } else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
     183                        //      setPosition( castExpr->get_arg() );
     184                        // } else if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( expr ) ) {
     185                        //      EnumInstType * inst = dynamic_cast<EnumInstType *>( varExpr->get_result() );
     186                        //      assertf( inst, "ArrayIterator given variable that isn't an enum constant : %s", toString( expr ).c_str() );
     187                        //      long long int value;
     188                        //      if ( inst->baseEnum->valueOf( varExpr->var, value ) ) {
     189                        //              index = value;
     190                        //      }
     191                        // } else if ( dynamic_cast< SizeofExpr * >( expr ) || dynamic_cast< AlignofExpr * >( expr ) ) {
     192                        //      index = 0; // xxx - get actual sizeof/alignof value?
     193                        // } else {
     194                        //      assertf( false, "4 bad designator given to ArrayIterator: %s", toString( expr ).c_str() );
     195                        // }
    192196                }
    193197
     
    329333                                        assertf( false, "could not find member in %s: %s", kind.c_str(), toString( varExpr ).c_str() );
    330334                                } else {
    331                                         assertf( false, "bad designator given to %s: %s", kind.c_str(), toString( designators.front() ).c_str() );
     335                                        assertf( false, "3 bad designator given to %s: %s", kind.c_str(), toString( designators.front() ).c_str() );
    332336                                } // if
    333337                        } // if
     
    637641
    638642                void setSize( const Expr * expr ) {
    639                         auto res = eval(expr);
     643                        auto res = eval( expr );
    640644                        if ( ! res.second ) {
    641                                 SemanticError( location,
    642                                         toString("Array designator must be a constant expression: ", expr ) );
     645                                SemanticError( location, toString( "Array designator must be a constant expression: ", expr ) );
    643646                        }
    644647                        size = res.first;
     
    646649
    647650        public:
    648                 ArrayIterator( const CodeLocation & loc, const ArrayType * at )
    649                 : location( loc ), array( at ), base( at->base ) {
     651                ArrayIterator( const CodeLocation & loc, const ArrayType * at ) : location( loc ), array( at ), base( at->base ) {
    650652                        PRINT( std::cerr << "Creating array iterator: " << at << std::endl; )
    651653                        memberIter.reset( createMemberIterator( loc, base ) );
     
    660662                        // enumeration constants, character constants, sizeof expressions, alignof expressions,
    661663                        // cast expressions
    662                         if ( auto constExpr = dynamic_cast< const ConstantExpr * >( expr ) ) {
    663                                 try {
    664                                         index = constExpr->intValue();
    665                                 } catch ( SemanticErrorException & ) {
    666                                         SemanticError( expr,
    667                                                 "Constant expression of non-integral type in array designator: " );
    668                                 }
    669                         } else if ( auto castExpr = dynamic_cast< const CastExpr * >( expr ) ) {
    670                                 setPosition( castExpr->arg );
    671                         } else if (
    672                                 dynamic_cast< const SizeofExpr * >( expr )
    673                                 || dynamic_cast< const AlignofExpr * >( expr )
    674                         ) {
    675                                 index = 0;
    676                         } else {
    677                                 assertf( false,
    678                                         "bad designator given to ArrayIterator: %s", toString( expr ).c_str() );
    679                         }
     664
     665                        auto arg = eval( expr );
     666                        index = arg.first;
     667                        return;
     668
     669                        // if ( auto constExpr = dynamic_cast< const ConstantExpr * >( expr ) ) {
     670                        //      try {
     671                        //              index = constExpr->intValue();
     672                        //      } catch ( SemanticErrorException & ) {
     673                        //              SemanticError( expr, "Constant expression of non-integral type in array designator: " );
     674                        //      }
     675                        // } else if ( auto castExpr = dynamic_cast< const CastExpr * >( expr ) ) {
     676                        //      setPosition( castExpr->arg );
     677                        // } else if ( dynamic_cast< const SizeofExpr * >( expr ) || dynamic_cast< const AlignofExpr * >( expr ) ) {
     678                        //      index = 0;
     679                        // } else {
     680                        //      assertf( false, "2 bad designator given to ArrayIterator: %s", toString( expr ).c_str() );
     681                        // }
    680682                }
    681683
     
    723725                                std::deque< InitAlternative > ret = memberIter->first();
    724726                                for ( InitAlternative & alt : ret ) {
    725                                         alt.designation.get_and_mutate()->designators.emplace_front(
    726                                                 ConstantExpr::from_ulong( location, index ) );
     727                                        alt.designation.get_and_mutate()->designators.emplace_front( ConstantExpr::from_ulong( location, index ) );
    727728                                }
    728729                                return ret;
     
    788789                                        return;
    789790                                }
    790                                 assertf( false,
    791                                         "could not find member in %s: %s", kind.c_str(), toString( varExpr ).c_str() );
     791                                assertf( false, "could not find member in %s: %s", kind.c_str(), toString( varExpr ).c_str() );
    792792                        } else {
    793                                 assertf( false,
    794                                         "bad designator given to %s: %s", kind.c_str(), toString( *begin ).c_str() );
     793                                assertf( false, "1 bad designator given to %s: %s", kind.c_str(), toString( *begin ).c_str() );
    795794                        }
    796795                }
  • src/SymTab/FixFunction.cc

    r9e23b446 rffec1bf  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 16:19:49 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Mar  6 23:36:59 2017
    13 // Update Count     : 6
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Jul 12 14:28:00 2022
     13// Update Count     : 7
    1414//
    1515
     
    122122                }
    123123
     124                void previsit( const ast::FunctionType * ) { visit_children = false; }
     125
     126                const ast::Type * postvisit( const ast::FunctionType * type ) {
     127                        return new ast::PointerType( type );
     128                }
     129
    124130                void previsit( const ast::VoidType * ) { isVoid = true; }
    125131
     
    145151}
    146152
     153const ast::Type * fixFunction( const ast::Type * type, bool & isVoid ) {
     154        ast::Pass< FixFunction_new > fixer;
     155        type = type->accept( fixer );
     156        isVoid |= fixer.core.isVoid;
     157        return type;
     158}
     159
    147160} // namespace SymTab
    148161
  • src/SymTab/FixFunction.h

    r9e23b446 rffec1bf  
    1010// Created On       : Sun May 17 17:02:08 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:45:55 2017
    13 // Update Count     : 4
     12// Last Modified On : Tue Jul 12 14:19:00 2022
     13// Update Count     : 5
    1414//
    1515
     
    2121namespace ast {
    2222        class DeclWithType;
     23        class Type;
    2324}
    2425
     
    3132        /// Sets isVoid to true if type is void
    3233        const ast::DeclWithType * fixFunction( const ast::DeclWithType * dwt, bool & isVoid );
     34        const ast::Type * fixFunction( const ast::Type * type, bool & isVoid );
    3335} // namespace SymTab
    3436
  • src/SymTab/Mangler.cc

    r9e23b446 rffec1bf  
    537537                }
    538538
     539                __attribute__((unused))
    539540                inline std::vector< ast::ptr< ast::Type > > getTypes( const std::vector< ast::ptr< ast::DeclWithType > > & decls ) {
    540541                        std::vector< ast::ptr< ast::Type > > ret;
  • src/SymTab/Validate.cc

    r9e23b446 rffec1bf  
    1010// Created On       : Sun May 17 21:50:04 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue May 17 14:36:00 2022
    13 // Update Count     : 366
     12// Last Modified On : Tue Jul 12 15:00:00 2022
     13// Update Count     : 367
    1414//
    1515
     
    294294        };
    295295
    296         void validate_A( std::list< Declaration * > & translationUnit ) {
     296        void validate( std::list< Declaration * > &translationUnit, __attribute__((unused)) bool doDebug ) {
    297297                PassVisitor<HoistTypeDecls> hoistDecls;
    298298                {
     
    305305                        decayEnumsAndPointers( translationUnit ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes_old because it is an indexer and needs correct types for mangling
    306306                }
    307         }
    308 
    309         void validate_B( std::list< Declaration * > & translationUnit ) {
    310307                PassVisitor<FixQualifiedTypes> fixQual;
    311308                {
    312309                        Stats::Heap::newPass("validate-B");
    313310                        Stats::Time::BlockGuard guard("validate-B");
    314                         //linkReferenceToTypes( translationUnit );
     311                        linkReferenceToTypes( translationUnit ); // Must happen before auto-gen, because it uses the sized flag.
    315312                        mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes_old, because aggregate members are accessed
    316313                        HoistStruct::hoistStruct( translationUnit );
    317314                        EliminateTypedef::eliminateTypedef( translationUnit );
    318315                }
    319         }
    320 
    321         void validate_C( std::list< Declaration * > & translationUnit ) {
    322316                PassVisitor<ValidateGenericParameters> genericParams;
    323317                PassVisitor<ResolveEnumInitializers> rei( nullptr );
     
    343337                        });
    344338                }
    345         }
    346 
    347         void validate_D( std::list< Declaration * > & translationUnit ) {
    348339                {
    349340                        Stats::Heap::newPass("validate-D");
     
    362353                        });
    363354                }
    364         }
    365 
    366         void validate_E( std::list< Declaration * > & translationUnit ) {
    367355                PassVisitor<CompoundLiteral> compoundliteral;
    368356                {
     
    384372                        }
    385373                }
    386         }
    387 
    388         void validate_F( std::list< Declaration * > & translationUnit ) {
    389374                PassVisitor<LabelAddressFixer> labelAddrFixer;
    390375                {
     
    410395                        }
    411396                }
    412         }
    413 
    414         void validate( std::list< Declaration * > &translationUnit, __attribute__((unused)) bool doDebug ) {
    415                 validate_A( translationUnit );
    416                 validate_B( translationUnit );
    417                 validate_C( translationUnit );
    418                 validate_D( translationUnit );
    419                 validate_E( translationUnit );
    420                 validate_F( translationUnit );
    421397        }
    422398
  • src/SymTab/Validate.h

    r9e23b446 rffec1bf  
    1111// Created On       : Sun May 17 21:53:34 2015
    1212// Last Modified By : Andrew Beach
    13 // Last Modified On : Tue May 17 14:35:00 2022
    14 // Update Count     : 5
     13// Last Modified On : Tue Jul 12 15:30:00 2022
     14// Update Count     : 6
    1515//
    1616
     
    1919#include <list>  // for list
    2020
    21 struct CodeLocation;
    22 class  Declaration;
    23 class  Type;
    24 
    25 namespace ast {
    26         class Type;
    27         class SymbolTable;
    28 }
     21class Declaration;
    2922
    3023namespace SymTab {
    31         class Indexer;
    32 
    3324        /// Normalizes struct and function declarations
    3425        void validate( std::list< Declaration * > &translationUnit, bool doDebug = false );
    35 
    36         // Sub-passes of validate.
    37         void validate_A( std::list< Declaration * > &translationUnit );
    38         void validate_B( std::list< Declaration * > &translationUnit );
    39         void validate_C( std::list< Declaration * > &translationUnit );
    40         void validate_D( std::list< Declaration * > &translationUnit );
    41         void validate_E( std::list< Declaration * > &translationUnit );
    42         void validate_F( std::list< Declaration * > &translationUnit );
    4326} // namespace SymTab
    4427
  • src/SymTab/ValidateType.cc

    r9e23b446 rffec1bf  
    222222        // visit enum members first so that the types of self-referencing members are updated properly
    223223        // Replace the enum base; right now it works only for StructEnum
    224         if ( enumDecl->base && dynamic_cast<TypeInstType*>(enumDecl->base) ) {
    225                 std::string baseName = static_cast<TypeInstType*>(enumDecl->base)->name;
    226                 const StructDecl * st = local_indexer->lookupStruct( baseName );
    227                 if ( st ) {
    228                         enumDecl->base = new StructInstType(Type::Qualifiers(),const_cast<StructDecl *>(st)); // Just linking in the node
     224        if ( enumDecl->base ) {
     225                if ( const TypeInstType * base = dynamic_cast< TypeInstType * >(enumDecl->base) ) {
     226                        if ( const StructDecl * decl = local_indexer->lookupStruct( base->name ) ) {
     227                                enumDecl->base = new StructInstType( Type::Qualifiers(), const_cast< StructDecl * >( decl ) ); // Just linking in the node
     228                        }
     229                } else if ( const PointerType * ptr = dynamic_cast< PointerType * >(enumDecl->base) ) {
     230                        if ( const TypeInstType * ptrBase = dynamic_cast< TypeInstType * >( ptr->base ) ) {
     231                                if ( const StructDecl * decl = local_indexer->lookupStruct( ptrBase->name ) ) {
     232                                        enumDecl->base = new PointerType( Type::Qualifiers(),
     233                                                new StructInstType( Type::Qualifiers(), const_cast< StructDecl * >( decl ) ) );
     234                                }
     235                        }
    229236                }
    230237        }
     238       
    231239        if ( enumDecl->body ) {
    232240                ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl->name );
  • src/SynTree/AggregateDecl.cc

    r9e23b446 rffec1bf  
    1010// Created On       : Sun May 17 23:56:39 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Dec 16 15:07:20 2019
    13 // Update Count     : 31
     12// Last Modified On : Fri Jul  1 09:12:33 2022
     13// Update Count     : 32
    1414//
    1515
     
    125125                                SingleInit * init = strict_dynamic_cast< SingleInit * >( field->init );
    126126                                auto result = eval( init->value );
    127                                 if ( ! result.second ) SemanticError( init->location, toString( "Non-constexpr in initialization of enumerator: ", field ) );
     127                                if ( ! result.second ) SemanticError( init->location, toString( "Enumerator value for '", field, "' is not an integer constant" ) );
    128128                                currentValue = result.first;
    129129                        }
  • src/SynTree/Type.h

    r9e23b446 rffec1bf  
    274274class PointerType : public Type {
    275275  public:
    276         Type *base;
     276        Type * base;
    277277
    278278        // In C99, pointer types can be qualified in many ways e.g., int f( int a[ static 3 ] )
     
    516516        typedef ReferenceToType Parent;
    517517  public:
    518         // this decl is not "owned" by the union inst; it is merely a pointer to elsewhere in the tree,
    519         // where the union used in this type is actually defined
     518        // this decl is not "owned" by the enum inst; it is merely a pointer to elsewhere in the tree,
     519        // where the enum used in this type is actually defined
    520520        EnumDecl *baseEnum = nullptr;
    521521
  • src/Tuples/Tuples.cc

    r9e23b446 rffec1bf  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Tuples.h --
     7// Tuples.cc -- A collection of tuple operations.
    88//
    99// Author           : Andrew Beach
  • src/Tuples/Tuples.h

    r9e23b446 rffec1bf  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Tuples.h --
     7// Tuples.h -- A collection of tuple operations.
    88//
    99// Author           : Rodolfo G. Esteves
  • src/Validate/Autogen.cpp

    r9e23b446 rffec1bf  
    2828#include "AST/DeclReplacer.hpp"
    2929#include "AST/Expr.hpp"
     30#include "AST/Inspect.hpp"
    3031#include "AST/Pass.hpp"
    3132#include "AST/Stmt.hpp"
     
    121122
    122123        // Built-ins do not use autogeneration.
    123         bool shouldAutogen() const final { return !decl->linkage.is_builtin; }
     124        bool shouldAutogen() const final { return !decl->linkage.is_builtin && !structHasFlexibleArray(decl); }
    124125private:
    125126        void genFuncBody( ast::FunctionDecl * decl ) final;
     
    183184        {
    184185                // TODO: These functions are somewhere between instrinsic and autogen,
    185                 // could possibly use a new linkage type. For now we just make them
    186                 // intrinsic to code-gen them as C assignments.
    187                 proto_linkage = ast::Linkage::Intrinsic;
     186                // could possibly use a new linkage type. For now we just make the
     187                // basic ones intrinsic to code-gen them as C assignments.
     188                const auto & real_type = decl->base;
     189                const auto & basic = real_type.as<ast::BasicType>();
     190                if(!real_type || (basic && basic->isInteger())) proto_linkage = ast::Linkage::Intrinsic;
    188191        }
    189192
     
    402405        auto retval = srcParam();
    403406        retval->name = "_ret";
    404         // xxx - Adding this unused attribute can slience unused variable warning
    405         // However, some code might not be compiled as expected
    406         // Temporarily disabled
    407         // retval->attributes.push_back(new ast::Attribute("unused"));
    408407        return genProto( "?=?", { dstParam(), srcParam() }, { retval } );
    409408}
  • src/Validate/Autogen.hpp

    r9e23b446 rffec1bf  
    2222namespace Validate {
    2323
     24/// Generate routines for all data types in the translation unit.
     25/// A lot of passes have to happen either before or after this pass.
    2426void autogenerateRoutines( ast::TranslationUnit & translationUnit );
    2527
  • src/Validate/CompoundLiteral.hpp

    r9e23b446 rffec1bf  
    2323
    2424/// Use variables to implement compound literals.
     25/// Must happen after auto-gen routines are added.
    2526void handleCompoundLiterals( ast::TranslationUnit & translationUnit );
    2627
  • src/Validate/EliminateTypedef.cpp

    r9e23b446 rffec1bf  
    1010// Created On       : Wed Apr 20 16:37:00 2022
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Apr 25 14:26:00 2022
    13 // Update Count     : 0
     12// Last Modified On : Mon Jul 11 16:30:00 2022
     13// Update Count     : 1
    1414//
    1515
     
    2828
    2929struct EliminateTypedefCore {
     30        // Remove typedefs from inside aggregates.
    3031        ast::StructDecl const * previsit( ast::StructDecl const * decl );
    3132        ast::UnionDecl const * previsit( ast::UnionDecl const * decl );
     33        // Remove typedefs from statement lists.
    3234        ast::CompoundStmt const * previsit( ast::CompoundStmt const * stmt );
     35        // Remove typedefs from control structure initializers.
     36        ast::IfStmt const * previsit( ast::IfStmt const * stmt );
     37        ast::ForStmt const * previsit( ast::ForStmt const * stmt );
     38        ast::WhileDoStmt const * previsit( ast::WhileDoStmt const * stmt );
    3339};
    3440
     
    6369}
    6470
     71ast::IfStmt const * EliminateTypedefCore::previsit( ast::IfStmt const * stmt ) {
     72        return field_erase_if( stmt, &ast::IfStmt::inits, isTypedefStmt );
     73}
     74
     75ast::ForStmt const * EliminateTypedefCore::previsit( ast::ForStmt const * stmt ) {
     76        return field_erase_if( stmt, &ast::ForStmt::inits, isTypedefStmt );
     77}
     78
     79ast::WhileDoStmt const * EliminateTypedefCore::previsit( ast::WhileDoStmt const * stmt ) {
     80        return field_erase_if( stmt, &ast::WhileDoStmt::inits, isTypedefStmt );
     81}
     82
    6583} // namespace
    6684
  • src/Validate/FindSpecialDecls.h

    r9e23b446 rffec1bf  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // FindSpecialDeclarations.h --
     7// FindSpecialDeclarations.h -- Find special declarations used in the compiler.
    88//
    99// Author           : Rob Schluntz
     
    4343        void findSpecialDecls( std::list< Declaration * > & translationUnit );
    4444
    45 /// find and remember some of the special declarations that are useful for
     45/// Find and remember some of the special declarations that are useful for
    4646/// generating code, so that they do not have to be discovered multiple times.
    4747void findGlobalDecls( ast::TranslationUnit & translationUnit );
  • src/Validate/FixQualifiedTypes.cpp

    r9e23b446 rffec1bf  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // FixQualifiedTypes.cpp --
     7// FixQualifiedTypes.cpp -- Replace the qualified type with a direct type.
    88//
    99// Author           : Andrew Beach
     
    7676                                                        ret->qualifiers = type->qualifiers;
    7777                                                        ast::TypeSubstitution sub( aggr->params, instp->params );
    78                                                         // = parent->genericSubstitution();
    7978                                                        auto result = sub.apply(ret);
    8079                                                        return result.node.release();
  • src/Validate/FixQualifiedTypes.hpp

    r9e23b446 rffec1bf  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // FixQualifiedTypes.hpp --
     7// FixQualifiedTypes.hpp -- Replace the qualified type with a direct type.
    88//
    99// Author           : Andrew Beach
     
    2222namespace Validate {
    2323
     24/// Replaces qualified types with an unqualified NamedTypeDecl.
     25/// Must happen after Link References To Types,
     26/// because aggregate members are accessed.
    2427void fixQualifiedTypes( ast::TranslationUnit & translationUnit );
    2528
  • src/Validate/ForallPointerDecay.hpp

    r9e23b446 rffec1bf  
    2929/// Also checks that operator names are used properly on functions and
    3030/// assigns unique IDs. This is a "legacy" pass.
     31/// Must be after implement concurrent keywords; because uniqueIds must be
     32/// set on declaration before resolution.
     33/// Must happen before auto-gen routines are added.
    3134void decayForallPointers( ast::TranslationUnit & transUnit );
    3235
  • src/Validate/GenericParameter.cpp

    r9e23b446 rffec1bf  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // GenericParameter.hpp --
     7// GenericParameter.hpp -- Generic parameter related passes.
    88//
    99// Author           : Andrew Beach
  • src/Validate/GenericParameter.hpp

    r9e23b446 rffec1bf  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // GenericParameter.hpp --
     7// GenericParameter.hpp -- Generic parameter related passes.
    88//
    99// Author           : Andrew Beach
     
    2323
    2424/// Perform substutions for generic parameters and fill in defaults.
     25/// Check as early as possible, but it can't happen before Link References to
     26/// Types and observed failing when attempted before eliminate typedef.
    2527void fillGenericParameters( ast::TranslationUnit & translationUnit );
    2628
  • src/Validate/HoistStruct.hpp

    r9e23b446 rffec1bf  
    2222namespace Validate {
    2323
    24 /// Flattens nested type declarations.
     24/// Flattens nested type declarations. (Run right after Fix Qualified Types.)
    2525void hoistStruct( ast::TranslationUnit & translationUnit );
    2626
  • src/Validate/LabelAddressFixer.cpp

    r9e23b446 rffec1bf  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // LabelAddressFixer.cpp --
     7// LabelAddressFixer.cpp -- Create label address expressions.
    88//
    99// Author           : Andrew Beach
  • src/Validate/LabelAddressFixer.hpp

    r9e23b446 rffec1bf  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // LabelAddressFixer.hpp --
     7// LabelAddressFixer.hpp -- Create label address expressions.
    88//
    99// Author           : Andrew Beach
     
    2020namespace Validate {
    2121
     22/// Label addresses are not actually created in the parser, this pass finds
     23/// the patterns that represent the label address expression.
    2224void fixLabelAddresses( ast::TranslationUnit & translationUnit );
    2325
  • src/Validate/module.mk

    r9e23b446 rffec1bf  
    2626        Validate/EliminateTypedef.cpp \
    2727        Validate/EliminateTypedef.hpp \
     28        Validate/EnumAndPointerDecay.cpp \
     29        Validate/EnumAndPointerDecay.hpp \
    2830        Validate/FindSpecialDeclsNew.cpp \
    2931        Validate/FixQualifiedTypes.cpp \
    3032        Validate/FixQualifiedTypes.hpp \
     33        Validate/FixReturnTypes.cpp \
     34        Validate/FixReturnTypes.hpp \
    3135        Validate/ForallPointerDecay.cpp \
    3236        Validate/ForallPointerDecay.hpp \
     
    3741        Validate/HoistStruct.cpp \
    3842        Validate/HoistStruct.hpp \
     43        Validate/HoistTypeDecls.cpp \
     44        Validate/HoistTypeDecls.hpp \
    3945        Validate/InitializerLength.cpp \
    4046        Validate/InitializerLength.hpp \
    4147        Validate/LabelAddressFixer.cpp \
    4248        Validate/LabelAddressFixer.hpp \
     49        Validate/LinkReferenceToTypes.cpp \
     50        Validate/LinkReferenceToTypes.hpp \
    4351        Validate/NoIdSymbolTable.hpp \
     52        Validate/ReplaceTypedef.cpp \
     53        Validate/ReplaceTypedef.hpp \
    4454        Validate/ReturnCheck.cpp \
    45         Validate/ReturnCheck.hpp
     55        Validate/ReturnCheck.hpp \
     56        Validate/VerifyCtorDtorAssign.cpp \
     57        Validate/VerifyCtorDtorAssign.hpp
    4658
    4759SRCDEMANGLE += $(SRC_VALIDATE)
  • src/Virtual/Tables.h

    r9e23b446 rffec1bf  
    1919#include "AST/Fwd.hpp"
    2020class Declaration;
     21class Expression;
     22class FunctionDecl;
     23class Initializer;
     24class ObjectDecl;
    2125class StructDecl;
    22 class Expression;
     26class StructInstType;
     27class Type;
    2328
    2429namespace Virtual {
  • src/main.cc

    r9e23b446 rffec1bf  
    1010// Created On       : Fri May 15 23:12:02 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Jun  7 13:29:00 2022
    13 // Update Count     : 674
     12// Last Modified On : Mon Jul 18 11:08:00 2022
     13// Update Count     : 676
    1414//
    1515
     
    7878#include "Validate/CompoundLiteral.hpp"     // for handleCompoundLiterals
    7979#include "Validate/EliminateTypedef.hpp"    // for eliminateTypedef
     80#include "Validate/EnumAndPointerDecay.hpp" // for decayEnumsAndPointers
    8081#include "Validate/FindSpecialDecls.h"      // for findGlobalDecls
    8182#include "Validate/FixQualifiedTypes.hpp"   // for fixQualifiedTypes
     83#include "Validate/FixReturnTypes.hpp"      // for fixReturnTypes
    8284#include "Validate/ForallPointerDecay.hpp"  // for decayForallPointers
    8385#include "Validate/GenericParameter.hpp"    // for fillGenericParameters, tr...
    8486#include "Validate/HoistStruct.hpp"         // for hoistStruct
     87#include "Validate/HoistTypeDecls.hpp"      // for hoistTypeDecls
    8588#include "Validate/InitializerLength.hpp"   // for setLengthFromInitializer
    8689#include "Validate/LabelAddressFixer.hpp"   // for fixLabelAddresses
     90#include "Validate/LinkReferenceToTypes.hpp" // for linkReferenceToTypes
     91#include "Validate/ReplaceTypedef.hpp"      // for replaceTypedef
    8792#include "Validate/ReturnCheck.hpp"         // for checkReturnStatements
     93#include "Validate/VerifyCtorDtorAssign.hpp" // for verifyCtorDtorAssign
    8894#include "Virtual/ExpandCasts.h"            // for expandCasts
    8995
     
    324330                Stats::Time::StopBlock();
    325331
    326                 PASS( "Translate Exception Declarations", ControlStruct::translateExcept( translationUnit ) );
    327                 if ( exdeclp ) {
    328                         dump( translationUnit );
    329                         return EXIT_SUCCESS;
    330                 } // if
    331 
    332                 // add the assignment statement after the initialization of a type parameter
    333                 PASS( "Validate-A", SymTab::validate_A( translationUnit ) );
    334 
    335                 // Must happen before auto-gen, because it uses the sized flag.
    336                 PASS( "Link Reference To Types", SymTab::linkReferenceToTypes( translationUnit ) );
    337 
    338                 CodeTools::fillLocations( translationUnit );
    339 
    340332                if( useNewAST ) {
    341                         CodeTools::fillLocations( translationUnit );
    342 
    343333                        if (Stats::Counters::enabled) {
    344334                                ast::pass_visitor_stats.avg = Stats::Counters::build<Stats::Counters::AverageCounter<double>>("Average Depth - New");
     
    349339                        forceFillCodeLocations( transUnit );
    350340
    351                         // Must happen after Link References To Types,
    352                         // because aggregate members are accessed.
     341                        PASS( "Translate Exception Declarations", ControlStruct::translateExcept( transUnit ) );
     342                        if ( exdeclp ) {
     343                                dump( move( transUnit ) );
     344                                return EXIT_SUCCESS;
     345                        }
     346
     347                        PASS( "Verify Ctor, Dtor & Assign", Validate::verifyCtorDtorAssign( transUnit ) );
     348                        PASS( "Hoist Type Decls", Validate::hoistTypeDecls( transUnit ) );
     349                        // Hoist Type Decls pulls some declarations out of contexts where
     350                        // locations are not tracked. Perhaps they should be, but for now
     351                        // the full fill solves it.
     352                        forceFillCodeLocations( transUnit );
     353
     354                        PASS( "Replace Typedefs", Validate::replaceTypedef( transUnit ) );
     355                        PASS( "Fix Return Types", Validate::fixReturnTypes( transUnit ) );
     356                        PASS( "Enum and Pointer Decay", Validate::decayEnumsAndPointers( transUnit ) );
     357
     358                        PASS( "Link Reference To Types", Validate::linkReferenceToTypes( transUnit ) );
     359
    353360                        PASS( "Fix Qualified Types", Validate::fixQualifiedTypes( transUnit ) );
    354 
    355361                        PASS( "Hoist Struct", Validate::hoistStruct( transUnit ) );
    356362                        PASS( "Eliminate Typedef", Validate::eliminateTypedef( transUnit ) );
    357 
    358                         // Check as early as possible. Can't happen before
    359                         // LinkReferenceToType, observed failing when attempted
    360                         // before eliminateTypedef
    361363                        PASS( "Validate Generic Parameters", Validate::fillGenericParameters( transUnit ) );
    362 
    363364                        PASS( "Translate Dimensions", Validate::translateDimensionParameters( transUnit ) );
    364365                        PASS( "Check Function Returns", Validate::checkReturnStatements( transUnit ) );
    365 
    366                         // Must happen before Autogen.
    367366                        PASS( "Fix Return Statements", InitTweak::fixReturnStatements( transUnit ) );
    368 
    369367                        PASS( "Implement Concurrent Keywords", Concurrency::implementKeywords( transUnit ) );
    370 
    371                         // Must be after implement concurrent keywords; because uniqueIds
    372                         //   must be set on declaration before resolution.
    373                         // Must happen before autogen routines are added.
    374368                        PASS( "Forall Pointer Decay", Validate::decayForallPointers( transUnit ) );
    375 
    376                         // Must happen before autogen routines are added.
    377369                        PASS( "Hoist Control Declarations", ControlStruct::hoistControlDecls( transUnit ) );
    378370
    379                         // Must be after enum and pointer decay.
    380                         // Must be before compound literals.
    381371                        PASS( "Generate Autogen Routines", Validate::autogenerateRoutines( transUnit ) );
    382372
     
    454444                        translationUnit = convert( move( transUnit ) );
    455445                } else {
    456                         PASS( "Validate-B", SymTab::validate_B( translationUnit ) );
    457                         PASS( "Validate-C", SymTab::validate_C( translationUnit ) );
    458                         PASS( "Validate-D", SymTab::validate_D( translationUnit ) );
    459                         PASS( "Validate-E", SymTab::validate_E( translationUnit ) );
    460                         PASS( "Validate-F", SymTab::validate_F( translationUnit ) );
     446                        PASS( "Translate Exception Declarations", ControlStruct::translateExcept( translationUnit ) );
     447                        if ( exdeclp ) {
     448                                dump( translationUnit );
     449                                return EXIT_SUCCESS;
     450                        } // if
     451
     452                        // add the assignment statement after the initialization of a type parameter
     453                        PASS( "Validate", SymTab::validate( translationUnit ) );
    461454
    462455                        if ( symtabp ) {
Note: See TracChangeset for help on using the changeset viewer.