1+ #include " AST/Exprs.hpp"
12#include " AST/Types.hpp"
23#include " ASTVisitor.hpp"
34#include " TypePrinter.hpp"
@@ -37,17 +38,8 @@ class CodePrinter : public ASTVisitor<CodePrinter> {
3738 {
3839 // Print each top-level declaration in the module
3940 for (auto *decl : node->getDecls ()) {
40- if (auto *funcDecl = llvm::dyn_cast<FunctionDecl>(decl)) {
41- visit (funcDecl);
42- _out << " \n " ;
43- } else if (auto *structDecl = llvm::dyn_cast<StructDecl>(decl)) {
44- visit (structDecl);
45- _out << " \n " ;
46- } else if (auto *enumDecl = llvm::dyn_cast<EnumDecl>(decl)) {
47- visit (enumDecl);
48- _out << " \n " ;
49- }
50- // Skip other declaration types as they're not supported
41+ visit (decl);
42+ _out << " \n " ;
5143 }
5244 }
5345
@@ -56,15 +48,13 @@ class CodePrinter : public ASTVisitor<CodePrinter> {
5648 void visitFunctionDecl (FunctionDecl *node)
5749 {
5850 printIndent ();
59-
60- printVisibility (node->getVisibility ());
51+ printDeclPrefix (node);
6152
6253 _out << " func " << node->getName ();
6354
6455 printFunctionParameters (node->getParams ());
6556
66- if (auto *funcType
67- = llvm::dyn_cast<glu::types::FunctionTy>(node->getType ())) {
57+ if (auto *funcType = node->getType ()) {
6858 auto *returnType = funcType->getReturnType ();
6959 if (!llvm::isa<glu::types::VoidTy>(returnType)) {
7060 _out << " -> " ;
@@ -80,8 +70,7 @@ class CodePrinter : public ASTVisitor<CodePrinter> {
8070 void visitStructDecl (StructDecl *node)
8171 {
8272 printIndent ();
83-
84- printVisibility (node->getVisibility ());
73+ printDeclPrefix (node);
8574
8675 _out << " struct " << node->getName () << " {\n " ;
8776
@@ -104,8 +93,7 @@ class CodePrinter : public ASTVisitor<CodePrinter> {
10493 void visitEnumDecl (EnumDecl *node)
10594 {
10695 printIndent ();
107-
108- printVisibility (node->getVisibility ());
96+ printDeclPrefix (node);
10997
11098 _out << " enum " << node->getName () << " {\n " ;
11199
@@ -128,14 +116,16 @@ class CodePrinter : public ASTVisitor<CodePrinter> {
128116 void visitFieldDecl (FieldDecl *node)
129117 {
130118 printIndent ();
131- _out << node->getName () << " : " ;
132- printType (node->getType ());
119+ _out << node->getName ();
133120
134- bool isFieldInStructOrEnum
135- = llvm::isa_and_nonnull<StructDecl>(node->getParent ())
136- || llvm::isa_and_nonnull<EnumDecl>(node->getParent ());
121+ // For enum fields, we don't print the type (just the name)
122+ // For struct fields, we print "name: type"
123+ if (!llvm::isa_and_nonnull<EnumDecl>(node->getParent ())) {
124+ _out << " : " ;
125+ printType (node->getType ());
126+ }
137127
138- _out << (isFieldInStructOrEnum ? " ," : " ; " ) ;
128+ _out << " ," ;
139129 }
140130
141131 // / @brief Visit a ParamDecl and print its declaration
@@ -146,6 +136,29 @@ class CodePrinter : public ASTVisitor<CodePrinter> {
146136 printType (node->getType ());
147137 }
148138
139+ // / @brief Visit a LiteralExpr and print its value for attribute parameters
140+ // / @param node The LiteralExpr node to print
141+ void visitLiteralExpr (LiteralExpr *node)
142+ {
143+ std::visit (
144+ [this ](auto &&val) {
145+ using T = std::decay_t <decltype (val)>;
146+ if constexpr (std::is_same_v<T, llvm::APInt>) {
147+ _out << val;
148+ } else if constexpr (std::is_same_v<T, llvm::APFloat>) {
149+ _out << val.convertToDouble ();
150+ } else if constexpr (std::is_same_v<T, llvm::StringRef>) {
151+ _out << " \" " << val.str () << " \" " ;
152+ } else if constexpr (std::is_same_v<T, bool >) {
153+ _out << (val ? " true" : " false" );
154+ } else if constexpr (std::is_same_v<T, std::nullptr_t >) {
155+ _out << " null" ;
156+ }
157+ },
158+ node->getValue ()
159+ );
160+ }
161+
149162 // / @brief Default handler for nodes that shouldn't be printed
150163 // / @param node The AST node
151164 void beforeVisitNode ([[maybe_unused]] ASTNode *node)
@@ -175,6 +188,35 @@ class CodePrinter : public ASTVisitor<CodePrinter> {
175188 }
176189 }
177190
191+ // / @brief Print attributes and visibility prefix for declarations
192+ // / @param decl The declaration to print prefix for
193+ void printDeclPrefix (DeclBase *decl)
194+ {
195+ printAttributes (decl);
196+ printVisibility (decl->getVisibility ());
197+ }
198+
199+ // / @brief Print attributes if present
200+ // / @param decl The declaration with potential attributes
201+ void printAttributes (DeclBase *decl)
202+ {
203+ if (!decl->getAttributes ()) {
204+ return ;
205+ }
206+
207+ for (auto *attr : decl->getAttributes ()->getAttributes ()) {
208+ _out << " @" << attr->getAttributeKindSpelling ();
209+
210+ if (attr->getParameter ()) {
211+ _out << " (" ;
212+ visit (attr->getParameter ());
213+ _out << " )" ;
214+ }
215+
216+ _out << " " ;
217+ }
218+ }
219+
178220 // / @brief Print function parameters
179221 // / @param params The parameter list
180222 void printFunctionParameters (llvm::ArrayRef<ParamDecl *> params)
@@ -195,9 +237,7 @@ class CodePrinter : public ASTVisitor<CodePrinter> {
195237 {
196238 switch (visibility) {
197239 case Visibility::Public: _out << " public " ; break ;
198- case Visibility::Private:
199- // Private is the default, don't print anything
200- break ;
240+ case Visibility::Private: _out << " private " ; break ;
201241 }
202242 }
203243};
0 commit comments