Changeset c6b4432 for src/CodeGen


Ignore:
Timestamp:
Nov 8, 2023, 2:01:11 PM (2 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
master
Children:
3e4bf0d, f5ec35a
Parents:
790d835
Message:

Remove BaseSyntaxNode and clean-up.

Location:
src/CodeGen
Files:
2 deleted
9 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/FixMain.cc

    r790d835 rc6b4432  
    2525#include "AST/Type.hpp"
    2626#include "AST/Vector.hpp"
    27 #include "Common/PassVisitor.h"
    2827#include "Common/SemanticError.h"  // for SemanticError
    2928#include "CodeGen/GenType.h"       // for GenType
    30 #include "SynTree/Declaration.h"   // for FunctionDecl, operator<<
    31 #include "SynTree/Type.h"          // for FunctionType
    3229#include "SymTab/Mangler.h"
    3330
     
    3532
    3633namespace {
    37 
    38 struct FindMainCore {
    39         FunctionDecl * main_signature = nullptr;
    40 
    41         void previsit( FunctionDecl * decl ) {
    42                 if ( FixMain::isMain( decl ) ) {
    43                         if ( main_signature ) {
    44                                 SemanticError( decl, "Multiple definition of main routine\n" );
    45                         }
    46                         main_signature = decl;
    47                 }
    48         }
    49 };
    5034
    5135struct FindMainCore_new {
     
    6549        return genType( types[at], "", Options( false, false, false, false ) );
    6650}
    67 
    68 }
    69 
    70         template<typename container>
    71         std::string genTypeAt(const container& p, size_t idx) {
    72                 return genType((*std::next(p.begin(), idx))->get_type(), "");
    73         }
    74 
    75         void FixMain::fix( std::list< Declaration * > & translationUnit,
    76                         std::ostream &os, const char* bootloader_filename ) {
    77                 PassVisitor< FindMainCore > main_finder;
    78                 acceptAll( translationUnit, main_finder );
    79                 FunctionDecl * main_signature = main_finder.pass.main_signature;
    80 
    81                 if( main_signature ) {
    82                         os << "static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return ";
    83                         main_signature->mangleName = SymTab::Mangler::mangle(main_signature);
    84 
    85                         os << main_signature->get_scopedMangleName() << "(";
    86                         const auto& params = main_signature->get_functionType()->get_parameters();
    87                         switch(params.size()) {
    88                                 case 3: os << "(" << genTypeAt(params, 0) << ")argc, (" << genTypeAt(params, 1) << ")argv, (" << genTypeAt(params, 2) << ")envp"; break;
    89                                 case 2: os << "(" << genTypeAt(params, 0) << ")argc, (" << genTypeAt(params, 1) << ")argv"; break;
    90                                 case 0: break;
    91                                 default : assert(false);
    92                         }
    93                         os << "); }\n";
    94 
    95                         std::ifstream bootloader(bootloader_filename, std::ios::in);
    96                         assertf( bootloader.is_open(), "cannot open bootloader.c\n" );
    97                         os << bootloader.rdbuf();
    98                 }
    99         }
    100 
    101 namespace {
    10251
    10352ast::ObjectDecl * makeIntObj(){
     
    159108} // namespace
    160109
    161 bool FixMain::isMain( FunctionDecl * decl ) {
    162         if ( std::string("main") != decl->name ) {
    163                 return false;
    164         }
    165         return is_main( SymTab::Mangler::mangle( decl, true, true ) );
    166 }
    167 
    168110bool FixMain::isMain( const ast::FunctionDecl * decl ) {
    169111        if ( std::string("main") != decl->name ) {
  • src/CodeGen/FixMain.h

    r790d835 rc6b4432  
    2121
    2222#include "AST/LinkageSpec.hpp"
    23 #include "SynTree/LinkageSpec.h"
    2423
    25 class Declaration;
    26 class FunctionDecl;
    2724namespace ast {
    2825        class FunctionDecl;
     
    3431class FixMain {
    3532public :
    36         static inline LinkageSpec::Spec mainLinkage() {
    37                 return replace_main ? LinkageSpec::Cforall : LinkageSpec::C;
    38         }
    3933        static inline ast::Linkage::Spec getMainLinkage() {
    4034                return replace_main ? ast::Linkage::Cforall : ast::Linkage::C;
     
    4539        }
    4640
    47         static bool isMain(FunctionDecl* decl);
    4841        static bool isMain(const ast::FunctionDecl * decl);
    4942
    50         static void fix( std::list< Declaration * > & decls,
    51                         std::ostream &os, const char* bootloader_filename );
    5243        static void fix( ast::TranslationUnit & translationUnit,
    5344                        std::ostream &os, const char * bootloader_filename );
  • src/CodeGen/FixNames.cc

    r790d835 rc6b4432  
    2222#include "AST/Expr.hpp"
    2323#include "AST/Pass.hpp"
    24 #include "Common/PassVisitor.h"
    2524#include "Common/SemanticError.h"  // for SemanticError
    2625#include "FixMain.h"               // for FixMain
    2726#include "SymTab/Mangler.h"        // for Mangler
    28 #include "SynTree/LinkageSpec.h"   // for Cforall, isMangled
    29 #include "SynTree/Constant.h"      // for Constant
    30 #include "SynTree/Declaration.h"   // for FunctionDecl, ObjectDecl, Declarat...
    31 #include "SynTree/Expression.h"    // for ConstantExpr
    32 #include "SynTree/Label.h"         // for Label, noLabels
    33 #include "SynTree/Statement.h"     // for ReturnStmt, CompoundStmt
    34 #include "SynTree/Type.h"          // for Type, BasicType, Type::Qualifiers
    35 #include "SynTree/Visitor.h"       // for Visitor, acceptAll
    3627#include "CompilationState.h"
    3728
    3829namespace CodeGen {
    39         class FixNames : public WithGuards {
    40           public:
    41                 void postvisit( ObjectDecl *objectDecl );
    42                 void postvisit( FunctionDecl *functionDecl );
    43 
    44                 void previsit( CompoundStmt *compoundStmt );
    45           private:
    46                 int scopeLevel = 1;
    47 
    48                 void fixDWT( DeclarationWithType *dwt );
    49         };
    50 
    51         void fixNames( std::list< Declaration* > & translationUnit ) {
    52                 PassVisitor<FixNames> fixer;
    53                 acceptAll( translationUnit, fixer );
    54         }
    55 
    56         void FixNames::fixDWT( DeclarationWithType * dwt ) {
    57                 if ( dwt->get_name() != "" ) {
    58                         if ( LinkageSpec::isMangled( dwt->get_linkage() ) ) {
    59                                 if (!useNewAST) {
    60                                         dwt->set_mangleName( SymTab::Mangler::mangle( dwt ) );
    61                                 }
    62                                 dwt->set_scopeLevel( scopeLevel );
    63                         } // if
    64                 } // if
    65         }
    66 
    67         void FixNames::postvisit( ObjectDecl * objectDecl ) {
    68                 fixDWT( objectDecl );
    69         }
    70 
    71         void FixNames::postvisit( FunctionDecl * functionDecl ) {
    72                 fixDWT( functionDecl );
    73 
    74                 if ( FixMain::isMain( functionDecl ) ) {
    75                         int nargs = functionDecl->get_functionType()->get_parameters().size();
    76                         if( !(nargs == 0 || nargs == 2 || nargs == 3) ) {
    77                                 SemanticError(functionDecl, "Main expected to have 0, 2 or 3 arguments\n");
    78                         }
    79                         functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( new ConstantExpr( Constant::from_int( 0 ) ) ) );
    80                 }
    81         }
    82 
    83         void FixNames::previsit( CompoundStmt * ) {
    84                 scopeLevel++;
    85                 GuardAction( [this](){ scopeLevel--; } );
    86         }
    87 
    8830/// Does work with the main function and scopeLevels.
    8931class FixNames_new final {
  • src/CodeGen/GenType.cc

    r790d835 rc6b4432  
    2121#include "AST/Print.hpp"          // for print
    2222#include "AST/Vector.hpp"         // for vector
    23 #include "CodeGenerator.h"        // for CodeGenerator
    2423#include "CodeGeneratorNew.hpp"   // for CodeGenerator_new
    2524#include "Common/UniqueName.h"    // for UniqueName
    26 #include "SynTree/Declaration.h"  // for DeclarationWithType
    27 #include "SynTree/Expression.h"   // for Expression
    28 #include "SynTree/Type.h"         // for PointerType, Type, FunctionType
    29 #include "SynTree/Visitor.h"      // for Visitor
    3025
    3126namespace CodeGen {
    32         struct GenType : public WithVisitorRef<GenType>, public WithShortCircuiting {
    33                 std::string typeString;
    34                 GenType( const std::string &typeString, const Options &options );
    35 
    36                 void previsit( BaseSyntaxNode * );
    37                 void postvisit( BaseSyntaxNode * );
    38 
    39                 void postvisit( FunctionType * funcType );
    40                 void postvisit( VoidType * voidType );
    41                 void postvisit( BasicType * basicType );
    42                 void postvisit( PointerType * pointerType );
    43                 void postvisit( ArrayType * arrayType );
    44                 void postvisit( ReferenceType * refType );
    45                 void postvisit( StructInstType * structInst );
    46                 void postvisit( UnionInstType * unionInst );
    47                 void postvisit( EnumInstType * enumInst );
    48                 void postvisit( TypeInstType * typeInst );
    49                 void postvisit( TupleType  * tupleType );
    50                 void postvisit( VarArgsType * varArgsType );
    51                 void postvisit( ZeroType * zeroType );
    52                 void postvisit( OneType * oneType );
    53                 void postvisit( GlobalScopeType * globalType );
    54                 void postvisit( TraitInstType * inst );
    55                 void postvisit( TypeofType * typeof );
    56                 void postvisit( VTableType * vtable );
    57                 void postvisit( QualifiedType * qualType );
    58 
    59           private:
    60                 void handleQualifiers( Type *type );
    61                 std::string handleGeneric( ReferenceToType * refType );
    62                 void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
    63 
    64                 Options options;
    65         };
    66 
    67         std::string genType( Type *type, const std::string &baseString, const Options &options ) {
    68                 PassVisitor<GenType> gt( baseString, options );
    69                 std::ostringstream os;
    70 
    71                 if ( ! type->get_attributes().empty() ) {
    72                         PassVisitor<CodeGenerator> cg( os, options );
    73                         cg.pass.genAttributes( type->get_attributes() );
    74                 } // if
    75 
    76                 type->accept( gt );
    77                 return os.str() + gt.pass.typeString;
    78         }
    79 
    80         std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC , bool lineMarks ) {
    81                 return genType( type, baseString, Options(pretty, genC, lineMarks, false ) );
    82         }
    83 
    84         std::string genPrettyType( Type * type, const std::string & baseString ) {
    85                 return genType( type, baseString, true, false );
    86         }
    87 
    88         GenType::GenType( const std::string &typeString, const Options &options ) : typeString( typeString ), options( options ) {}
    89 
    90         // *** BaseSyntaxNode
    91         void GenType::previsit( BaseSyntaxNode * ) {
    92                 // turn off automatic recursion for all nodes, to allow each visitor to
    93                 // precisely control the order in which its children are visited.
    94                 visit_children = false;
    95         }
    96 
    97         void GenType::postvisit( BaseSyntaxNode * node ) {
    98                 std::stringstream ss;
    99                 node->print( ss );
    100                 assertf( false, "Unhandled node reached in GenType: %s", ss.str().c_str() );
    101         }
    102 
    103         void GenType::postvisit( VoidType * voidType ) {
    104                 typeString = "void " + typeString;
    105                 handleQualifiers( voidType );
    106         }
    107 
    108         void GenType::postvisit( BasicType * basicType ) {
    109                 BasicType::Kind kind = basicType->kind;
    110                 assert( 0 <= kind && kind < BasicType::NUMBER_OF_BASIC_TYPES );
    111                 typeString = std::string( BasicType::typeNames[kind] ) + " " + typeString;
    112                 handleQualifiers( basicType );
    113         }
    114 
    115         void GenType::genArray( const Type::Qualifiers & qualifiers, Type * base, Expression *dimension, bool isVarLen, bool isStatic ) {
    116                 std::ostringstream os;
    117                 if ( typeString != "" ) {
    118                         if ( typeString[ 0 ] == '*' ) {
    119                                 os << "(" << typeString << ")";
    120                         } else {
    121                                 os << typeString;
    122                         } // if
    123                 } // if
    124                 os << "[";
    125 
    126                 if ( isStatic ) {
    127                         os << "static ";
    128                 } // if
    129                 if ( qualifiers.is_const ) {
    130                         os << "const ";
    131                 } // if
    132                 if ( qualifiers.is_volatile ) {
    133                         os << "volatile ";
    134                 } // if
    135                 if ( qualifiers.is_restrict ) {
    136                         os << "__restrict ";
    137                 } // if
    138                 if ( qualifiers.is_atomic ) {
    139                         os << "_Atomic ";
    140                 } // if
    141                 if ( dimension != 0 ) {
    142                         PassVisitor<CodeGenerator> cg( os, options );
    143                         dimension->accept( cg );
    144                 } else if ( isVarLen ) {
    145                         // no dimension expression on a VLA means it came in with the * token
    146                         os << "*";
    147                 } // if
    148                 os << "]";
    149 
    150                 typeString = os.str();
    151 
    152                 base->accept( *visitor );
    153         }
    154 
    155         void GenType::postvisit( PointerType * pointerType ) {
    156                 assert( pointerType->base != 0);
    157                 if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->dimension ) {
    158                         genArray( pointerType->get_qualifiers(), pointerType->base, pointerType->dimension, pointerType->get_isVarLen(), pointerType->get_isStatic() );
    159                 } else {
    160                         handleQualifiers( pointerType );
    161                         if ( typeString[ 0 ] == '?' ) {
    162                                 typeString = "* " + typeString;
    163                         } else {
    164                                 typeString = "*" + typeString;
    165                         } // if
    166                         pointerType->base->accept( *visitor );
    167                 } // if
    168         }
    169 
    170         void GenType::postvisit( ArrayType * arrayType ) {
    171                 genArray( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->get_isVarLen(), arrayType->get_isStatic() );
    172         }
    173 
    174         void GenType::postvisit( ReferenceType * refType ) {
    175                 assert( 0 != refType->base );
    176                 assertf( ! options.genC, "Reference types should not reach code generation." );
    177                 handleQualifiers( refType );
    178                 typeString = "&" + typeString;
    179                 refType->base->accept( *visitor );
    180         }
    181 
    182         void GenType::postvisit( FunctionType * funcType ) {
    183                 std::ostringstream os;
    184 
    185                 if ( typeString != "" ) {
    186                         if ( typeString[ 0 ] == '*' ) {
    187                                 os << "(" << typeString << ")";
    188                         } else {
    189                                 os << typeString;
    190                         } // if
    191                 } // if
    192 
    193                 /************* parameters ***************/
    194 
    195                 const std::list<DeclarationWithType *> &pars = funcType->parameters;
    196 
    197                 if ( pars.empty() ) {
    198                         if ( funcType->get_isVarArgs() ) {
    199                                 os << "()";
    200                         } else {
    201                                 os << "(void)";
    202                         } // if
    203                 } else {
    204                         PassVisitor<CodeGenerator> cg( os, options );
    205                         os << "(" ;
    206 
    207                         cg.pass.genCommaList( pars.begin(), pars.end() );
    208 
    209                         if ( funcType->get_isVarArgs() ) {
    210                                 os << ", ...";
    211                         } // if
    212                         os << ")";
    213                 } // if
    214 
    215                 typeString = os.str();
    216 
    217                 if ( funcType->returnVals.size() == 0 ) {
    218                         typeString = "void " + typeString;
    219                 } else {
    220                         funcType->returnVals.front()->get_type()->accept( *visitor );
    221                 } // if
    222 
    223                 // add forall
    224                 if( ! funcType->forall.empty() && ! options.genC ) {
    225                         // assertf( ! genC, "Aggregate type parameters should not reach code generation." );
    226                         std::ostringstream os;
    227                         PassVisitor<CodeGenerator> cg( os, options );
    228                         os << "forall(";
    229                         cg.pass.genCommaList( funcType->forall.begin(), funcType->forall.end() );
    230                         os << ")" << std::endl;
    231                         typeString = os.str() + typeString;
    232                 }
    233         }
    234 
    235         std::string GenType::handleGeneric( ReferenceToType * refType ) {
    236                 if ( ! refType->parameters.empty() ) {
    237                         std::ostringstream os;
    238                         PassVisitor<CodeGenerator> cg( os, options );
    239                         os << "(";
    240                         cg.pass.genCommaList( refType->parameters.begin(), refType->parameters.end() );
    241                         os << ") ";
    242                         return os.str();
    243                 }
    244                 return "";
    245         }
    246 
    247         void GenType::postvisit( StructInstType * structInst )  {
    248                 typeString = structInst->name + handleGeneric( structInst ) + " " + typeString;
    249                 if ( options.genC ) typeString = "struct " + typeString;
    250                 handleQualifiers( structInst );
    251         }
    252 
    253         void GenType::postvisit( UnionInstType * unionInst ) {
    254                 typeString = unionInst->name + handleGeneric( unionInst ) + " " + typeString;
    255                 if ( options.genC ) typeString = "union " + typeString;
    256                 handleQualifiers( unionInst );
    257         }
    258 
    259         void GenType::postvisit( EnumInstType * enumInst ) {
    260                 if ( enumInst->baseEnum && enumInst->baseEnum->base ) {
    261                         typeString = genType(enumInst->baseEnum->base, typeString, options);
    262                 } else {
    263                         typeString = enumInst->name + " " + typeString;
    264                         if ( options.genC ) {
    265                                 typeString = "enum " + typeString;
    266                         }
    267                 }
    268                 handleQualifiers( enumInst );
    269         }
    270 
    271         void GenType::postvisit( TypeInstType * typeInst ) {
    272                 assertf( ! options.genC, "Type instance types should not reach code generation." );
    273                 typeString = typeInst->name + " " + typeString;
    274                 handleQualifiers( typeInst );
    275         }
    276 
    277         void GenType::postvisit( TupleType * tupleType ) {
    278                 assertf( ! options.genC, "Tuple types should not reach code generation." );
    279                 unsigned int i = 0;
    280                 std::ostringstream os;
    281                 os << "[";
    282                 for ( Type * t : *tupleType ) {
    283                         i++;
    284                         os << genType( t, "", options ) << (i == tupleType->size() ? "" : ", ");
    285                 }
    286                 os << "] ";
    287                 typeString = os.str() + typeString;
    288         }
    289 
    290         void GenType::postvisit( VarArgsType * varArgsType ) {
    291                 typeString = "__builtin_va_list " + typeString;
    292                 handleQualifiers( varArgsType );
    293         }
    294 
    295         void GenType::postvisit( ZeroType * zeroType ) {
    296                 // ideally these wouldn't hit codegen at all, but should be safe to make them ints
    297                 typeString = (options.pretty ? "zero_t " : "long int ") + typeString;
    298                 handleQualifiers( zeroType );
    299         }
    300 
    301         void GenType::postvisit( OneType * oneType ) {
    302                 // ideally these wouldn't hit codegen at all, but should be safe to make them ints
    303                 typeString = (options.pretty ? "one_t " : "long int ") + typeString;
    304                 handleQualifiers( oneType );
    305         }
    306 
    307         void GenType::postvisit( GlobalScopeType * globalType ) {
    308                 assertf( ! options.genC, "Global scope type should not reach code generation." );
    309                 handleQualifiers( globalType );
    310         }
    311 
    312         void GenType::postvisit( TraitInstType * inst ) {
    313                 assertf( ! options.genC, "Trait types should not reach code generation." );
    314                 typeString = inst->name + " " + typeString;
    315                 handleQualifiers( inst );
    316         }
    317 
    318         void GenType::postvisit( TypeofType * typeof ) {
    319                 std::ostringstream os;
    320                 PassVisitor<CodeGenerator> cg( os, options );
    321                 os << "typeof(";
    322                 typeof->expr->accept( cg );
    323                 os << ") " << typeString;
    324                 typeString = os.str();
    325                 handleQualifiers( typeof );
    326         }
    327 
    328         void GenType::postvisit( VTableType * vtable ) {
    329                 assertf( ! options.genC, "Virtual table types should not reach code generation." );
    330                 std::ostringstream os;
    331                 os << "vtable(" << genType( vtable->base, "", options ) << ") " << typeString;
    332                 typeString = os.str();
    333                 handleQualifiers( vtable );
    334         }
    335 
    336         void GenType::postvisit( QualifiedType * qualType ) {
    337                 assertf( ! options.genC, "Qualified types should not reach code generation." );
    338                 std::ostringstream os;
    339                 os << genType( qualType->parent, "", options ) << "." << genType( qualType->child, "", options ) << typeString;
    340                 typeString = os.str();
    341                 handleQualifiers( qualType );
    342         }
    343 
    344         void GenType::handleQualifiers( Type * type ) {
    345                 if ( type->get_const() ) {
    346                         typeString = "const " + typeString;
    347                 } // if
    348                 if ( type->get_volatile() ) {
    349                         typeString = "volatile " + typeString;
    350                 } // if
    351                 if ( type->get_restrict() ) {
    352                         typeString = "__restrict " + typeString;
    353                 } // if
    354                 if ( type->get_atomic() ) {
    355                         typeString = "_Atomic " + typeString;
    356                 } // if
    357         }
    35827
    35928namespace {
  • src/CodeGen/Generate.cc

    r790d835 rc6b4432  
    2020
    2121#include "CodeGeneratorNew.hpp"      // for CodeGenerator_new, doSemicolon, ...
    22 #include "CodeGenerator.h"           // for CodeGenerator, doSemicolon, oper...
    2322#include "GenType.h"                 // for genPrettyType
    24 #include "Common/PassVisitor.h"      // for PassVisitor
    25 #include "SynTree/LinkageSpec.h"     // for isBuiltin, isGeneratable
    26 #include "SynTree/BaseSyntaxNode.h"  // for BaseSyntaxNode
    27 #include "SynTree/Declaration.h"     // for Declaration
    28 #include "SynTree/Type.h"            // for Type
    2923
    3024using namespace std;
    3125
    3226namespace CodeGen {
    33         namespace {
    34                 /// Removes misc. nodes that should not exist in CodeGen
    35                 struct TreeCleaner {
    36                         void premutate( CompoundStmt * stmt );
    37                         Statement * postmutate( ImplicitCtorDtorStmt * stmt );
    38 
    39                         static bool shouldClean( Declaration * );
    40                 };
    41 
    42                 void cleanTree( std::list< Declaration * > & translationUnit ) {
    43                         PassVisitor<TreeCleaner> cleaner;
    44                         filter( translationUnit, [](Declaration * decl) { return TreeCleaner::shouldClean(decl); }, false );
    45                         mutateAll( translationUnit, cleaner );
    46                 } // cleanTree
    47         } // namespace
    48 
    49         void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC, bool lineMarks, bool printExprTypes ) {
    50                 cleanTree( translationUnit );
    51 
    52                 PassVisitor<CodeGenerator> cgv( os, pretty, generateC, lineMarks, printExprTypes );
    53                 for ( auto & dcl : translationUnit ) {
    54                         if ( LinkageSpec::isGeneratable( dcl->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( dcl->get_linkage() ) ) ) {
    55                                 cgv.pass.updateLocation( dcl );
    56                                 dcl->accept(cgv);
    57                                 if ( doSemicolon( dcl ) ) {
    58                                         os << ";";
    59                                 } // if
    60                                 os << cgv.pass.endl;
    61                         } // if
    62                 } // for
    63         }
    64 
    65         void generate( BaseSyntaxNode * node, std::ostream & os ) {
    66                 if ( Type * type = dynamic_cast< Type * >( node ) ) {
    67                         os << genPrettyType( type, "" );
    68                 } else {
    69                         PassVisitor<CodeGenerator> cgv( os, true, false, false, false );
    70                         node->accept( cgv );
    71                 }
    72                 os << std::endl;
    73         }
    74 
    75         namespace {
    76                 void TreeCleaner::premutate( CompoundStmt * cstmt ) {
    77                         filter( cstmt->kids, [](Statement * stmt) {
    78                                 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
    79                                         return shouldClean( declStmt->decl );
    80                                 }
    81                                 return false;
    82                         }, false );
    83                 }
    84 
    85                 Statement * TreeCleaner::postmutate( ImplicitCtorDtorStmt * stmt ) {
    86                         Statement * callStmt = nullptr;
    87                         std::swap( stmt->callStmt, callStmt );
    88                         delete stmt;
    89                         return callStmt;
    90                 }
    91 
    92                 bool TreeCleaner::shouldClean( Declaration * decl ) {
    93                         return dynamic_cast< TraitDecl * >( decl );
    94                 }
    95         } // namespace
    9627
    9728namespace {
  • src/CodeGen/Generate.h

    r790d835 rc6b4432  
    2727
    2828namespace CodeGen {
    29         /// Generates code. doIntrinsics determines if intrinsic functions are printed, pretty formats output nicely (e.g., uses unmangled names, etc.), generateC is true when the output must consist only of C code (allows some assertions, etc.)
    30         void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC = false , bool lineMarks = false, bool printTypeExpr = false );
    31 
    32         /// Generate code for a single node -- helpful for debugging in gdb
    33         void generate( BaseSyntaxNode * node, std::ostream & os );
    3429
    3530/// Generates all code in transUnit and writing it to the os.
  • src/CodeGen/LinkOnce.cc

    r790d835 rc6b4432  
    2222#include "AST/Expr.hpp"
    2323#include "AST/Pass.hpp"
    24 #include "Common/PassVisitor.h"       // for PassVisitor, WithShortCircuiting
    2524
    2625namespace CodeGen {
    2726
    2827namespace {
    29 
    30 bool is_cfa_linkonce_old( Attribute const * attr ) {
    31         return std::string("cfa_linkonce") == attr->name;
    32 }
    33 
    34 bool is_section_attribute_old( Attribute const * attr ) {
    35         return std::string("section") == attr->name;
    36 }
    37 
    38 class LinkOnceVisitorCore : public WithShortCircuiting {
    39 public:
    40         void previsit( Declaration * ) {
    41                 visit_children = false;
    42         }
    43 
    44         void previsit( DeclarationWithType * decl ) {
    45                 std::list< Attribute * > & attributes = decl->attributes;
    46                 // See if we can find the element:
    47                 auto found = std::find_if(attributes.begin(), attributes.end(), is_cfa_linkonce_old );
    48                 if ( attributes.end() != found ) {
    49                         // Remove any other sections:
    50                         attributes.remove_if( is_section_attribute_old );
    51                         // Iterator to the cfa_linkonce attribute should still be valid.
    52                         Attribute * attribute = *found;
    53                         assert( attribute->parameters.empty() );
    54                         assert( !decl->mangleName.empty() );
    55                         // Overwrite the attribute in place.
    56                         const std::string section_name = ".gnu.linkonce." + decl->mangleName;
    57                         attribute->name = "section";
    58                         attribute->parameters.push_back(
    59                                 new ConstantExpr( Constant::from_string( section_name ) )
    60                         );
    61 
    62                         // Unconditionnaly add "visibility(default)" to anything with gnu.linkonce
    63                         // visibility is a mess otherwise
    64                         attributes.push_back(new Attribute("visibility", {new ConstantExpr( Constant::from_string( "default" ) )}));
    65 
    66                 }
    67                 visit_children = false;
    68         }
    69 };
    7028
    7129bool is_cfa_linkonce( ast::Attribute const * attr ) {
     
    12280} // namespace
    12381
    124 void translateLinkOnce( std::list< Declaration *> & translationUnit ) {
    125         PassVisitor<LinkOnceVisitorCore> translator;
    126         acceptAll( translationUnit, translator );
    127 }
    128 
    12982void translateLinkOnce( ast::TranslationUnit & translationUnit ) {
    13083        ast::Pass<LinkOnceCore>::run( translationUnit );
  • src/CodeGen/LinkOnce.h

    r790d835 rc6b4432  
    2020// for now its almost the only attribute we handle.
    2121
    22 #include <list>  // for list
    2322
    24 class Declaration;
    2523namespace ast {
    2624        class TranslationUnit;
     
    2927namespace CodeGen {
    3028
    31 void translateLinkOnce( std::list< Declaration *> & translationUnit );
    3229void translateLinkOnce( ast::TranslationUnit & translationUnit );
    3330/* Convert the cfa_linkonce attribute on top level declaration into
  • src/CodeGen/module.mk

    r790d835 rc6b4432  
    1616
    1717SRC_CODEGEN = \
    18         CodeGen/CodeGenerator.cc \
    19         CodeGen/CodeGenerator.h \
    2018        CodeGen/CodeGeneratorNew.cpp \
    2119        CodeGen/CodeGeneratorNew.hpp \
Note: See TracChangeset for help on using the changeset viewer.