2424#include < cxx/ast.h>
2525#include < cxx/control.h>
2626#include < cxx/external_name_encoder.h>
27+ #include < cxx/names.h>
2728#include < cxx/symbols.h>
2829#include < cxx/translation_unit.h>
2930#include < cxx/types.h>
3738
3839namespace cxx {
3940
41+ namespace {
42+
43+ [[nodiscard]] auto is_global_namespace (Symbol* symbol) -> bool {
44+ if (!symbol) return false ;
45+ if (!symbol->isNamespace ()) return false ;
46+ if (symbol->parent ()) return false ;
47+ return true ;
48+ }
49+
50+ } // namespace
51+
4052struct Codegen ::DeclarationVisitor {
4153 Codegen& gen;
4254
@@ -205,8 +217,8 @@ auto Codegen::DeclarationVisitor::operator()(SimpleDeclarationAST* ast)
205217
206218 const auto elementType = gen.convertType (var->type ());
207219
208- gen. builder_ . create < mlir::cxx::StoreOp>( loc, expressionResult.value ,
209- local.value ());
220+ mlir::cxx::StoreOp::create (gen. builder_ , loc, expressionResult.value ,
221+ local.value ());
210222 }
211223
212224 return {};
@@ -365,7 +377,17 @@ auto Codegen::DeclarationVisitor::operator()(FunctionDefinitionAST* ast)
365377 gen.getLocation (ast->functionBody ->firstSourceLocation ());
366378 auto exitValueType = gen.convertType (returnType);
367379 auto ptrType = gen.builder_ .getType <mlir::cxx::PointerType>(exitValueType);
368- exitValue = gen.builder_ .create <mlir::cxx::AllocaOp>(exitValueLoc, ptrType);
380+ exitValue =
381+ mlir::cxx::AllocaOp::create (gen.builder_ , exitValueLoc, ptrType);
382+
383+ auto id = name_cast<Identifier>(functionSymbol->name ());
384+ if (id && id->name () == " main" &&
385+ is_global_namespace (functionSymbol->parent ())) {
386+ auto zeroOp = mlir::cxx::IntConstantOp::create (
387+ gen.builder_ , loc, gen.convertType (gen.control ()->getIntType ()), 0 );
388+
389+ mlir::cxx::StoreOp::create (gen.builder_ , exitValueLoc, zeroOp, exitValue);
390+ }
369391 }
370392
371393 std::unordered_map<Symbol*, mlir::Value> locals;
@@ -389,8 +411,8 @@ auto Codegen::DeclarationVisitor::operator()(FunctionDefinitionAST* ast)
389411 thisValue = gen.newTemp (classSymbol->type (), ast->firstSourceLocation ());
390412
391413 // store the `this` pointer in the entry block
392- gen. builder_ . create < mlir::cxx::StoreOp>(
393- loc, gen.entryBlock_ ->getArgument (0 ), thisValue);
414+ mlir::cxx::StoreOp::create (gen. builder_ , loc,
415+ gen.entryBlock_ ->getArgument (0 ), thisValue);
394416 }
395417
396418 FunctionParametersSymbol* params = nullptr ;
@@ -408,11 +430,11 @@ auto Codegen::DeclarationVisitor::operator()(FunctionDefinitionAST* ast)
408430 auto ptrType = gen.builder_ .getType <mlir::cxx::PointerType>(type);
409431
410432 auto loc = gen.getLocation (arg->location ());
411- auto allocaOp = gen. builder_ . create < mlir::cxx::AllocaOp>( loc, ptrType);
433+ auto allocaOp = mlir::cxx::AllocaOp::create (gen. builder_ , loc, ptrType);
412434
413435 auto value = args[argc];
414436 ++argc;
415- gen. builder_ . create < mlir::cxx::StoreOp>( loc, value, allocaOp);
437+ mlir::cxx::StoreOp::create (gen. builder_ , loc, value, allocaOp);
416438
417439 gen.locals_ .emplace (arg, allocaOp);
418440 }
@@ -430,7 +452,7 @@ auto Codegen::DeclarationVisitor::operator()(FunctionDefinitionAST* ast)
430452 const auto endLoc = gen.getLocation (ast->lastSourceLocation ());
431453
432454 if (!gen.builder_ .getBlock ()->mightHaveTerminator ()) {
433- gen. builder_ . create < mlir::cf::BranchOp>( endLoc, gen.exitBlock_ );
455+ mlir::cf::BranchOp::create (gen. builder_ , endLoc, gen.exitBlock_ );
434456 }
435457
436458 gen.builder_ .setInsertionPointToEnd (gen.exitBlock_ );
@@ -439,13 +461,13 @@ auto Codegen::DeclarationVisitor::operator()(FunctionDefinitionAST* ast)
439461 // We need to return a value of the correct type.
440462 auto elementType = gen.exitValue_ .getType ().getElementType ();
441463
442- auto value = gen. builder_ . create < mlir::cxx::LoadOp>( endLoc, elementType,
443- gen.exitValue_ );
464+ auto value = mlir::cxx::LoadOp::create (gen. builder_ , endLoc, elementType,
465+ gen.exitValue_ );
444466
445- gen. builder_ . create < mlir::cxx::ReturnOp>( endLoc, value->getResults ());
467+ mlir::cxx::ReturnOp::create (gen. builder_ , endLoc, value->getResults ());
446468 } else {
447469 // If the function returns void, we don't need to return anything.
448- gen. builder_ . create < mlir::cxx::ReturnOp>( endLoc);
470+ mlir::cxx::ReturnOp::create (gen. builder_ , endLoc);
449471 }
450472
451473 // restore the state
0 commit comments