Commit 1ff8269e7921a072fceaf40d05240f3ccba094b4

Authored by Austin Sun
Exists in master

Merge branch 'master' of git.ucsd.edu:acs008/cse131-pa4

Showing 4 changed files Inline Diff

/* File: ast_decl.cc 1 1 /* File: ast_decl.cc
* ----------------- 2 2 * -----------------
* Implementation of Decl node classes. 3 3 * Implementation of Decl node classes.
*/ 4 4 */
#include "ast_decl.h" 5 5 #include "ast_decl.h"
#include "ast_type.h" 6 6 #include "ast_type.h"
#include "ast_stmt.h" 7 7 #include "ast_stmt.h"
#include "symtable.h" 8 8 #include "symtable.h"
9 9
Decl::Decl(Identifier *n) : Node(*n->GetLocation()) { 10 10 Decl::Decl(Identifier *n) : Node(*n->GetLocation()) {
Assert(n != NULL); 11 11 Assert(n != NULL);
(id=n)->SetParent(this); 12 12 (id=n)->SetParent(this);
} 13 13 }
14 14
VarDecl::VarDecl(Identifier *n, Type *t, Expr *e) : Decl(n) { 15 15 VarDecl::VarDecl(Identifier *n, Type *t, Expr *e) : Decl(n) {
Assert(n != NULL && t != NULL); 16 16 Assert(n != NULL && t != NULL);
(type=t)->SetParent(this); 17 17 (type=t)->SetParent(this);
if (e) (assignTo=e)->SetParent(this); 18 18 if (e) (assignTo=e)->SetParent(this);
typeq = NULL; 19 19 typeq = NULL;
} 20 20 }
21 21
VarDecl::VarDecl(Identifier *n, TypeQualifier *tq, Expr *e) : Decl(n) { 22 22 VarDecl::VarDecl(Identifier *n, TypeQualifier *tq, Expr *e) : Decl(n) {
Assert(n != NULL && tq != NULL); 23 23 Assert(n != NULL && tq != NULL);
(typeq=tq)->SetParent(this); 24 24 (typeq=tq)->SetParent(this);
if (e) (assignTo=e)->SetParent(this); 25 25 if (e) (assignTo=e)->SetParent(this);
type = NULL; 26 26 type = NULL;
} 27 27 }
28 28
VarDecl::VarDecl(Identifier *n, Type *t, TypeQualifier *tq, Expr *e) : Decl(n) { 29 29 VarDecl::VarDecl(Identifier *n, Type *t, TypeQualifier *tq, Expr *e) : Decl(n) {
Assert(n != NULL && t != NULL && tq != NULL); 30 30 Assert(n != NULL && t != NULL && tq != NULL);
(type=t)->SetParent(this); 31 31 (type=t)->SetParent(this);
(typeq=tq)->SetParent(this); 32 32 (typeq=tq)->SetParent(this);
if (e) (assignTo=e)->SetParent(this); 33 33 if (e) (assignTo=e)->SetParent(this);
} 34 34 }
35 35
void VarDecl::PrintChildren(int indentLevel) { 36 36 void VarDecl::PrintChildren(int indentLevel) {
if (typeq) typeq->Print(indentLevel+1); 37 37 if (typeq) typeq->Print(indentLevel+1);
if (type) type->Print(indentLevel+1); 38 38 if (type) type->Print(indentLevel+1);
if (id) id->Print(indentLevel+1); 39 39 if (id) id->Print(indentLevel+1);
if (assignTo) assignTo->Print(indentLevel+1, "(initializer) "); 40 40 if (assignTo) assignTo->Print(indentLevel+1, "(initializer) ");
} 41 41 }
42 42
FnDecl::FnDecl(Identifier *n, Type *r, List<VarDecl*> *d) : Decl(n) { 43 43 FnDecl::FnDecl(Identifier *n, Type *r, List<VarDecl*> *d) : Decl(n) {
Assert(n != NULL && r!= NULL && d != NULL); 44 44 Assert(n != NULL && r!= NULL && d != NULL);
(returnType=r)->SetParent(this); 45 45 (returnType=r)->SetParent(this);
(formals=d)->SetParentAll(this); 46 46 (formals=d)->SetParentAll(this);
body = NULL; 47 47 body = NULL;
returnTypeq = NULL; 48 48 returnTypeq = NULL;
} 49 49 }
50 50
FnDecl::FnDecl(Identifier *n, Type *r, TypeQualifier *rq, List<VarDecl*> *d) : Decl(n) { 51 51 FnDecl::FnDecl(Identifier *n, Type *r, TypeQualifier *rq, List<VarDecl*> *d) : Decl(n) {
Assert(n != NULL && r != NULL && rq != NULL&& d != NULL); 52 52 Assert(n != NULL && r != NULL && rq != NULL&& d != NULL);
(returnType=r)->SetParent(this); 53 53 (returnType=r)->SetParent(this);
(returnTypeq=rq)->SetParent(this); 54 54 (returnTypeq=rq)->SetParent(this);
(formals=d)->SetParentAll(this); 55 55 (formals=d)->SetParentAll(this);
body = NULL; 56 56 body = NULL;
} 57 57 }
58 58
void FnDecl::SetFunctionBody(Stmt *b) { 59 59 void FnDecl::SetFunctionBody(Stmt *b) {
(body=b)->SetParent(this); 60 60 (body=b)->SetParent(this);
} 61 61 }
62 62
void FnDecl::PrintChildren(int indentLevel) { 63 63 void FnDecl::PrintChildren(int indentLevel) {
if (returnType) returnType->Print(indentLevel+1, "(return type) "); 64 64 if (returnType) returnType->Print(indentLevel+1, "(return type) ");
if (id) id->Print(indentLevel+1); 65 65 if (id) id->Print(indentLevel+1);
if (formals) formals->PrintAll(indentLevel+1, "(formals) "); 66 66 if (formals) formals->PrintAll(indentLevel+1, "(formals) ");
if (body) body->Print(indentLevel+1, "(body) "); 67 67 if (body) body->Print(indentLevel+1, "(body) ");
} 68 68 }
69
70 llvm::Value* VarDecl::Emit() {
71 llvm::Value* val;
72 if(type == Type::intType || type == Type::uintType)
73 val = new llvm::AllocaInst(llvm::Type::getInt32Ty(*irgen.GetContext()), id->GetName(), irgen.GetBasicBlock());
74 if(type == Type::boolType)
75 val = new llvm::AllocaInst(llvm::Type::getInt1Ty(*irgen.GetContext()), id->GetName(), irgen.GetBasicBlock());
76 else if(type == Type::voidType)
77 val = new llvm::AllocaInst(llvm::Type::getInt32Ty(*irgen.GetContext()), id->GetName(), irgen.GetBasicBlock());
78 else if(type == Type::floatType)
79 val = new llvm::AllocaInst(llvm::Type::getVoidTy(*irgen.GetContext()), id->GetName(), irgen.GetBasicBlock());
80 if(assignTo) val = new llvm::StoreInst(val, assignTo->Emit(), NULL, irgen.GetBasicBlock());
81 return val;
82 }
83
84 llvm::Value* FnDecl::Emit() {
85 llvm::LLVMContext* context = irgen.GetContext();
86 llvm::BasicBlock::Create(*context, "funcBlock", irgen.GetBasicBlock());
87 pushScope();
/* File: ast_decl.h 1 1 /* File: ast_decl.h
* ---------------- 2 2 * ----------------
* In our parse tree, Decl nodes are used to represent and 3 3 * In our parse tree, Decl nodes are used to represent and
* manage declarations. There are 4 subclasses of the base class, 4 4 * manage declarations. There are 4 subclasses of the base class,
* specialized for declarations of variables, functions, classes, 5 5 * specialized for declarations of variables, functions, classes,
* and interfaces. 6 6 * and interfaces.
* 7 7 *
* pp3: You will need to extend the Decl classes to implement 8 8 * pp3: You will need to extend the Decl classes to implement
* semantic processing including detection of declaration conflicts 9 9 * semantic processing including detection of declaration conflicts
* and managing scoping issues. 10 10 * and managing scoping issues.
*/ 11 11 */
12 12
#ifndef _H_ast_decl 13 13 #ifndef _H_ast_decl
#define _H_ast_decl 14 14 #define _H_ast_decl
15 15
#include "ast.h" 16 16 #include "ast.h"
#include "list.h" 17 17 #include "list.h"
#include "ast_expr.h" 18 18 #include "ast_expr.h"
19 19
class Type; 20 20 class Type;
class TypeQualifier; 21 21 class TypeQualifier;
class NamedType; 22 22 class NamedType;
class Identifier; 23 23 class Identifier;
class Stmt; 24 24 class Stmt;
25 25
void yyerror(const char *msg); 26 26 void yyerror(const char *msg);
27 27
class Decl : public Node 28 28 class Decl : public Node
{ 29 29 {
protected: 30 30 protected:
Identifier *id; 31 31 Identifier *id;
32 32
public: 33 33 public:
Decl() : id(NULL) {} 34 34 Decl() : id(NULL) {}
Decl(Identifier *name); 35 35 Decl(Identifier *name);
Identifier *GetIdentifier() const { return id; } 36 36 Identifier *GetIdentifier() const { return id; }
friend ostream& operator<<(ostream& out, Decl *d) { return out << d->id; } 37 37 friend ostream& operator<<(ostream& out, Decl *d) { return out << d->id; }
38 38
}; 39 39 };
40 40
class VarDecl : public Decl 41 41 class VarDecl : public Decl
{ 42 42 {
protected: 43 43 protected:
Type *type; 44 44 Type *type;
TypeQualifier *typeq; 45 45 TypeQualifier *typeq;
Expr *assignTo; 46 46 Expr *assignTo;
47 47
public: 48 48 public:
VarDecl() : type(NULL), typeq(NULL), assignTo(NULL) {} 49 49 VarDecl() : type(NULL), typeq(NULL), assignTo(NULL) {}
VarDecl(Identifier *name, Type *type, Expr *assignTo = NULL); 50 50 VarDecl(Identifier *name, Type *type, Expr *assignTo = NULL);
VarDecl(Identifier *name, TypeQualifier *typeq, Expr *assignTo = NULL); 51 51 VarDecl(Identifier *name, TypeQualifier *typeq, Expr *assignTo = NULL);
VarDecl(Identifier *name, Type *type, TypeQualifier *typeq, Expr *assignTo = NULL); 52 52 VarDecl(Identifier *name, Type *type, TypeQualifier *typeq, Expr *assignTo = NULL);
const char *GetPrintNameForNode() { return "VarDecl"; } 53 53 const char *GetPrintNameForNode() { return "VarDecl"; }
void PrintChildren(int indentLevel); 54 54 void PrintChildren(int indentLevel);
Type *GetType() const { return type; } 55 55 Type *GetType() const { return type; }
56 llvm::Value* Emit();
}; 56 57 };
57 58
class VarDeclError : public VarDecl 58 59 class VarDeclError : public VarDecl
{ 59 60 {
public: 60 61 public:
VarDeclError() : VarDecl() { yyerror(this->GetPrintNameForNode()); }; 61 62 VarDeclError() : VarDecl() { yyerror(this->GetPrintNameForNode()); };
const char *GetPrintNameForNode() { return "VarDeclError"; } 62 63 const char *GetPrintNameForNode() { return "VarDeclError"; }
}; 63 64 };
64 65
class FnDecl : public Decl 65 66 class FnDecl : public Decl
{ 66 67 {
protected: 67 68 protected:
List<VarDecl*> *formals; 68 69 List<VarDecl*> *formals;
Type *returnType; 69 70 Type *returnType;
TypeQualifier *returnTypeq; 70 71 TypeQualifier *returnTypeq;
Stmt *body; 71 72 Stmt *body;
72 73
public: 73 74 public:
FnDecl() : Decl(), formals(NULL), returnType(NULL), returnTypeq(NULL), body(NULL) {} 74 75 FnDecl() : Decl(), formals(NULL), returnType(NULL), returnTypeq(NULL), body(NULL) {}
FnDecl(Identifier *name, Type *returnType, List<VarDecl*> *formals); 75 76 FnDecl(Identifier *name, Type *returnType, List<VarDecl*> *formals);
FnDecl(Identifier *name, Type *returnType, TypeQualifier *returnTypeq, List<VarDecl*> *formals); 76 77 FnDecl(Identifier *name, Type *returnType, TypeQualifier *returnTypeq, List<VarDecl*> *formals);
void SetFunctionBody(Stmt *b); 77 78 void SetFunctionBody(Stmt *b);
const char *GetPrintNameForNode() { return "FnDecl"; } 78 79 const char *GetPrintNameForNode() { return "FnDecl"; }
/* File: ast_type.cc 1 1 /* File: ast_type.cc
* ----------------- 2 2 * -----------------
* Implementation of type node classes. 3 3 * Implementation of type node classes.
*/ 4 4 */
5 5
#include <string.h> 6 6 #include <string.h>
#include "ast_type.h" 7 7 #include "ast_type.h"
#include "ast_decl.h" 8 8 #include "ast_decl.h"
9 9
/* Class constants 10 10 /* Class constants
* --------------- 11 11 * ---------------
* These are public constants for the built-in base types (int, double, etc.) 12 12 * These are public constants for the built-in base types (int, double, etc.)
* They can be accessed with the syntax Type::intType. This allows you to 13 13 * They can be accessed with the syntax Type::intType. This allows you to
* directly access them and share the built-in types where needed rather that 14 14 * directly access them and share the built-in types where needed rather that
* creates lots of copies. 15 15 * creates lots of copies.
*/ 16 16 */
17 17
Type *Type::intType = new Type("int"); 18 18 Type *Type::intType = new Type("int");
Type *Type::floatType = new Type("float"); 19 19 Type *Type::floatType = new Type("float");
Type *Type::voidType = new Type("void"); 20 20 Type *Type::voidType = new Type("void");
Type *Type::boolType = new Type("bool"); 21 21 Type *Type::boolType = new Type("bool");
Type *Type::mat2Type = new Type("mat2"); 22 22 Type *Type::mat2Type = new Type("mat2");
Type *Type::mat3Type = new Type("mat3"); 23 23 Type *Type::mat3Type = new Type("mat3");
Type *Type::mat4Type = new Type("mat4"); 24 24 Type *Type::mat4Type = new Type("mat4");
Type *Type::vec2Type = new Type("vec2"); 25 25 Type *Type::vec2Type = new Type("vec2");
Type *Type::vec3Type = new Type("vec3"); 26 26 Type *Type::vec3Type = new Type("vec3");
Type *Type::vec4Type = new Type("vec4"); 27 27 Type *Type::vec4Type = new Type("vec4");
Type *Type::ivec2Type = new Type("ivec2"); 28 28 Type *Type::ivec2Type = new Type("ivec2");
Type *Type::ivec3Type = new Type("ivec3"); 29 29 Type *Type::ivec3Type = new Type("ivec3");
Type *Type::ivec4Type = new Type("ivec4"); 30 30 Type *Type::ivec4Type = new Type("ivec4");
Type *Type::bvec2Type = new Type("bvec2"); 31 31 Type *Type::bvec2Type = new Type("bvec2");
Type *Type::bvec3Type = new Type("bvec3"); 32 32 Type *Type::bvec3Type = new Type("bvec3");
Type *Type::bvec4Type = new Type("bvec4"); 33 33 Type *Type::bvec4Type = new Type("bvec4");
Type *Type::uintType = new Type("uint"); 34 34 Type *Type::uintType = new Type("uint");
Type *Type::uvec2Type = new Type("uvec2"); 35 35 Type *Type::uvec2Type = new Type("uvec2");
Type *Type::uvec3Type = new Type("uvec3"); 36 36 Type *Type::uvec3Type = new Type("uvec3");
Type *Type::uvec4Type = new Type("uvec4"); 37 37 Type *Type::uvec4Type = new Type("uvec4");
Type *Type::errorType = new Type("error"); 38 38 Type *Type::errorType = new Type("error");
39 39
TypeQualifier *TypeQualifier::inTypeQualifier = new TypeQualifier("in"); 40 40 TypeQualifier *TypeQualifier::inTypeQualifier = new TypeQualifier("in");
TypeQualifier *TypeQualifier::outTypeQualifier = new TypeQualifier("out"); 41 41 TypeQualifier *TypeQualifier::outTypeQualifier = new TypeQualifier("out");
TypeQualifier *TypeQualifier::constTypeQualifier = new TypeQualifier("const"); 42 42 TypeQualifier *TypeQualifier::constTypeQualifier = new TypeQualifier("const");
TypeQualifier *TypeQualifier::uniformTypeQualifier = new TypeQualifier("uniform"); 43 43 TypeQualifier *TypeQualifier::uniformTypeQualifier = new TypeQualifier("uniform");
44 44
Type::Type(const char *n) { 45 45 Type::Type(const char *n) {
Assert(n); 46 46 Assert(n);
typeName = strdup(n); 47 47 typeName = strdup(n);
} 48 48 }
49 49
void Type::PrintChildren(int indentLevel) { 50 50 void Type::PrintChildren(int indentLevel) {
printf("%s", typeName); 51 51 printf("%s", typeName);
} 52 52 }
53 53
TypeQualifier::TypeQualifier(const char *n) { 54 54 TypeQualifier::TypeQualifier(const char *n) {
Assert(n); 55 55 Assert(n);
typeQualifierName = strdup(n); 56 56 typeQualifierName = strdup(n);
} 57 57 }
58 58
void TypeQualifier::PrintChildren(int indentLevel) { 59 59 void TypeQualifier::PrintChildren(int indentLevel) {
printf("%s", typeQualifierName); 60 60 printf("%s", typeQualifierName);
} 61 61 }
62 62
bool Type::IsNumeric() { 63 63 bool Type::IsNumeric() {
return this->IsEquivalentTo(Type::intType) || this->IsEquivalentTo(Type::floatType); 64 64 return this->IsEquivalentTo(Type::intType) || this->IsEquivalentTo(Type::floatType);
} 65 65 }
66 66
bool Type::IsVector() { 67 67 bool Type::IsVector() {
return this->IsEquivalentTo(Type::vec2Type) || 68 68 return this->IsEquivalentTo(Type::vec2Type) ||
this->IsEquivalentTo(Type::vec3Type) || 69 69 this->IsEquivalentTo(Type::vec3Type) ||
this->IsEquivalentTo(Type::vec4Type); 70 70 this->IsEquivalentTo(Type::vec4Type);
} 71 71 }
72 72
bool Type::IsMatrix() { 73 73 bool Type::IsMatrix() {
return this->IsEquivalentTo(Type::mat2Type) || 74 74 return this->IsEquivalentTo(Type::mat2Type) ||
this->IsEquivalentTo(Type::mat3Type) || 75 75 this->IsEquivalentTo(Type::mat3Type) ||
this->IsEquivalentTo(Type::mat4Type); 76 76 this->IsEquivalentTo(Type::mat4Type);
} 77 77 }
78 78
bool Type::IsError() { 79 79 bool Type::IsError() {
return this->IsEquivalentTo(Type::errorType); 80 80 return this->IsEquivalentTo(Type::errorType);
} 81 81 }
82 82
NamedType::NamedType(Identifier *i) : Type(*i->GetLocation()) { 83 83 NamedType::NamedType(Identifier *i) : Type(*i->GetLocation()) {
Assert(i != NULL); 84 84 Assert(i != NULL);
(id=i)->SetParent(this); 85 85 (id=i)->SetParent(this);
} 86 86 }
87 87
void NamedType::PrintChildren(int indentLevel) { 88 88 void NamedType::PrintChildren(int indentLevel) {
id->Print(indentLevel+1); 89 89 id->Print(indentLevel+1);
} 90 90 }
91 91
ArrayType::ArrayType(yyltype loc, Type *et, int ec) : Type(loc) { 92 92 ArrayType::ArrayType(yyltype loc, Type *et, int ec) : Type(loc) {
Assert(et != NULL); 93 93 Assert(et != NULL);
(elemType=et)->SetParent(this); 94 94 (elemType=et)->SetParent(this);
elemCount=ec; 95 95 elemCount=ec;
} 96 96 }
void ArrayType::PrintChildren(int indentLevel) { 97 97 void ArrayType::PrintChildren(int indentLevel) {
elemType->Print(indentLevel+1); 98 98 elemType->Print(indentLevel+1);
} 99 99 }
100
/* File: ast_type.h 1 1 /* File: ast_type.h
* ---------------- 2 2 * ----------------
* In our parse tree, Type nodes are used to represent and 3 3 * In our parse tree, Type nodes are used to represent and
* store type information. The base Type class is used 4 4 * store type information. The base Type class is used
* for built-in types, the NamedType for classes and interfaces, 5 5 * for built-in types, the NamedType for classes and interfaces,
* and the ArrayType for arrays of other types. 6 6 * and the ArrayType for arrays of other types.
* 7 7 *
* pp3: You will need to extend the Type classes to implement 8 8 * pp3: You will need to extend the Type classes to implement
* the type system and rules for type equivalency and compatibility. 9 9 * the type system and rules for type equivalency and compatibility.
*/ 10 10 */
11 11
#ifndef _H_ast_type 12 12 #ifndef _H_ast_type
#define _H_ast_type 13 13 #define _H_ast_type
14 14
#include "ast.h" 15 15 #include "ast.h"
#include "list.h" 16 16 #include "list.h"
#include <iostream> 17 17 #include <iostream>
18 18
using namespace std; 19 19 using namespace std;
20 20
class TypeQualifier : public Node 21 21 class TypeQualifier : public Node
{ 22 22 {
protected: 23 23 protected:
char *typeQualifierName; 24 24 char *typeQualifierName;
25 25
public : 26 26 public :
static TypeQualifier *inTypeQualifier, *outTypeQualifier, *constTypeQualifier, *uniformTypeQualifier; 27 27 static TypeQualifier *inTypeQualifier, *outTypeQualifier, *constTypeQualifier, *uniformTypeQualifier;
28 28
TypeQualifier(yyltype loc) : Node(loc) {} 29 29 TypeQualifier(yyltype loc) : Node(loc) {}
TypeQualifier(const char *str); 30 30 TypeQualifier(const char *str);
31 31
const char *GetPrintNameForNode() { return "TypeQualifier"; } 32 32 const char *GetPrintNameForNode() { return "TypeQualifier"; }
void PrintChildren(int indentLevel); 33 33 void PrintChildren(int indentLevel);
}; 34 34 };
35 35
class Type : public Node 36 36 class Type : public Node
{ 37 37 {
protected: 38 38 protected:
char *typeName; 39 39 char *typeName;
40 40
public : 41 41 public :
static Type *intType, *uintType,*floatType, *boolType, *voidType, 42 42 static Type *intType, *uintType,*floatType, *boolType, *voidType,
*vec2Type, *vec3Type, *vec4Type, 43 43 *vec2Type, *vec3Type, *vec4Type,
*mat2Type, *mat3Type, *mat4Type, 44 44 *mat2Type, *mat3Type, *mat4Type,
*ivec2Type, *ivec3Type, *ivec4Type, 45 45 *ivec2Type, *ivec3Type, *ivec4Type,
*bvec2Type, *bvec3Type, *bvec4Type, 46 46 *bvec2Type, *bvec3Type, *bvec4Type,
*uvec2Type, *uvec3Type,*uvec4Type, 47 47 *uvec2Type, *uvec3Type,*uvec4Type,
*errorType; 48 48 *errorType;
49 49
Type(yyltype loc) : Node(loc) {} 50 50 Type(yyltype loc) : Node(loc) {}
Type(const char *str); 51 51 Type(const char *str);
52 52
const char *GetPrintNameForNode() { return "Type"; } 53 53 const char *GetPrintNameForNode() { return "Type"; }
void PrintChildren(int indentLevel); 54 54 void PrintChildren(int indentLevel);
55 55
virtual void PrintToStream(ostream& out) { out << typeName; } 56 56 virtual void PrintToStream(ostream& out) { out << typeName; }
friend ostream& operator<<(ostream& out, Type *t) { t->PrintToStream(out); return out; } 57 57 friend ostream& operator<<(ostream& out, Type *t) { t->PrintToStream(out); return out; }
virtual bool IsEquivalentTo(Type *other) { return (this == other); } 58 58 virtual bool IsEquivalentTo(Type *other) { return (this == other); }
virtual bool IsConvertibleTo(Type *other) { return (this == other || this == errorType); } 59 59 virtual bool IsConvertibleTo(Type *other) { return (this == other || this == errorType); }
bool IsNumeric(); 60 60 bool IsNumeric();
bool IsVector(); 61 61 bool IsVector();
bool IsMatrix(); 62 62 bool IsMatrix();
bool IsError(); 63 63 bool IsError();
}; 64 64 };
65 65
66 66
class NamedType : public Type 67 67 class NamedType : public Type
{ 68 68 {
protected: 69 69 protected:
Identifier *id; 70 70 Identifier *id;
71 71
public: 72 72 public:
NamedType(Identifier *i); 73 73 NamedType(Identifier *i);
74 74
const char *GetPrintNameForNode() { return "NamedType"; } 75 75 const char *GetPrintNameForNode() { return "NamedType"; }
void PrintChildren(int indentLevel); 76 76 void PrintChildren(int indentLevel);
void PrintToStream(ostream& out) { out << id; } 77 77 void PrintToStream(ostream& out) { out << id; }