diff options
-rw-r--r-- | examples/testrun.log | 16 | ||||
-rw-r--r-- | examples/“ | 24 | ||||
-rw-r--r-- | include/chillAST/chillASTs.hh | 2 | ||||
-rwxr-xr-x | include/ir_clang.hh | 2 | ||||
-rw-r--r-- | src/chillASTs.cc | 11 | ||||
-rw-r--r-- | src/chillmodule.cc | 17 | ||||
-rwxr-xr-x | src/ir_clang.cc | 169 | ||||
-rw-r--r-- | src/irtools.cc | 2 | ||||
-rw-r--r-- | src/printer/cfamily.cpp | 18 | ||||
-rw-r--r-- | src/printer/dump.cpp | 4 | ||||
-rw-r--r-- | src/printer/generic.cpp | 2 |
11 files changed, 139 insertions, 128 deletions
diff --git a/examples/testrun.log b/examples/testrun.log deleted file mode 100644 index 7611517..0000000 --- a/examples/testrun.log +++ /dev/null @@ -1,16 +0,0 @@ -Test Run By bobw on Mon Sep 21 12:59:26 2015 -Native configuration is x86_64-unknown-linux-gnu - - === tests === - -Schedule of variations: - unix - -Running target unix -Using /usr/local/share/dejagnu/baseboards/unix.exp as board description file for target. -Using /usr/local/share/dejagnu/config/unix.exp as generic interface file for target. -WARNING: Couldn't find tool config file for unix, using default. - - === Summary === - -runtest completed at Mon Sep 21 12:59:26 2015 diff --git a/examples/“ b/examples/“ new file mode 100644 index 0000000..985ecaa --- /dev/null +++ b/examples/“ @@ -0,0 +1,24 @@ +// this source is derived from CHILL AST originally from file 'mm.c' as parsed by frontend compiler clang + +void mm(float **A, float **B, float **C, int ambn, int an, int bm) { + int t6; + int t4; + int t2; + int over1; + over1 = 0; + for (t2 = 0; t2 <= an - 1; t2 += 1) + for (t4 = 0; t4 <= bm - 1; t4 += 1) + C[t2][t4] = 0.0f; + for (t2 = 0; t2 <= an - 1; t2 += 1) + for (t4 = 0; t4 <= bm - 1; t4 += 1) { + over1 = ambn % 4; + for (t6 = 0; t6 <= -over1 + ambn - 1; t6 += 4) { + C[t2][t4] += A[t2][t6] * B[t6][t4]; + C[t2][t4] += A[t2][t6 + 1] * B[t6 + 1][t4]; + C[t2][t4] += A[t2][t6 + 2] * B[t6 + 2][t4]; + C[t2][t4] += A[t2][t6 + 3] * B[t6 + 3][t4]; + } + for (t6 = 0 < ambn - over1 ? ambn - over1 : 0; t6 <= ambn - 1; t6 += 1) + C[t2][t4] += A[t2][t6] * B[t6][t4]; + } +} diff --git a/include/chillAST/chillASTs.hh b/include/chillAST/chillASTs.hh index 93b4420..f49cf6f 100644 --- a/include/chillAST/chillASTs.hh +++ b/include/chillAST/chillASTs.hh @@ -916,6 +916,8 @@ public: // required methods that I can't seem to get to inherit chillAST_Node *clone(); + chillAST_Node* constantFold(); + //void replaceVarDecls( chillAST_VarDecl *olddecl, chillAST_VarDecl *newdecl); bool findLoopIndexesToReplace(chillAST_SymbolTable *symtab, bool forcesync = false) { return false; }; // no loops under here diff --git a/include/ir_clang.hh b/include/ir_clang.hh index 14def21..3e4e7d6 100755 --- a/include/ir_clang.hh +++ b/include/ir_clang.hh @@ -446,6 +446,7 @@ protected: // char *filename; char *procedurename; + char *outfilename; chillAST_Node *entire_file_AST; @@ -471,6 +472,7 @@ public: clang::SourceManager *getASTSourceManager() { return sourceManager; }; IR_clangCode(const char *filename, const char *proc_name); + IR_clangCode(const char *filename, const char *proc_name, const char *dest_name); ~IR_clangCode(); diff --git a/src/chillASTs.cc b/src/chillASTs.cc index 701832e..6f9f845 100644 --- a/src/chillASTs.cc +++ b/src/chillASTs.cc @@ -22,8 +22,10 @@ char *parseUnderlyingType(const char *sometype) { while (p > underlying) if (*p == ' ' || *p == '*') --p; - else if (*p == ']') + else if (*p == ']') { while (*p != '[') --p; + --p; + } else break; *(p + 1) = '\0'; @@ -1751,6 +1753,11 @@ chillAST_ImplicitCastExpr::chillAST_ImplicitCastExpr() { children.push_back(NULL); } +chillAST_Node* chillAST_ImplicitCastExpr::constantFold() { + chillAST_Node::constantFold(); + return getSubExpr(); +} + chillAST_ImplicitCastExpr::chillAST_ImplicitCastExpr(chillAST_Node *sub) : chillAST_ImplicitCastExpr() { setSubExpr(sub); } @@ -1908,7 +1915,7 @@ class chillAST_Node *chillAST_ReturnStmt::clone() { } chillAST_CallExpr::chillAST_CallExpr() { - addChild(NULL); + children.push_back(NULL); } chillAST_CallExpr::chillAST_CallExpr(chillAST_Node *c) : chillAST_CallExpr() { diff --git a/src/chillmodule.cc b/src/chillmodule.cc index 591b77e..e59fc79 100644 --- a/src/chillmodule.cc +++ b/src/chillmodule.cc @@ -21,6 +21,7 @@ extern bool is_interactive; std::string procedure_name; std::string source_filename; +std::string dest_filename; int loop_start_num; int loop_end_num; @@ -80,7 +81,10 @@ static void init_loop(int loop_num_start, int loop_num_end) { exit(2); } else { if (ir_code == NULL) { - ir_code = new IR_clangCode(source_filename.c_str(), procedure_name.c_str()); + if (dest_filename != "") + ir_code = new IR_clangCode(source_filename.c_str(), procedure_name.c_str(), dest_filename.c_str()); + else + ir_code = new IR_clangCode(source_filename.c_str(), procedure_name.c_str()); IR_Block *block = ir_code->GetCode(); ir_controls = ir_code->FindOneLevelControlStructure(block); for (int i = 0; i < ir_controls.size(); i++) { @@ -268,6 +272,13 @@ static PyObject *chill_source(PyObject *self, PyObject *args) { Py_RETURN_NONE; } +static PyObject * +chill_dest(PyObject *self, PyObject* args) { + strict_arg_num(args, 1, "destination"); + dest_filename = strArg(args, 0); + Py_RETURN_NONE; +} + static PyObject *chill_procedure(PyObject *self, PyObject *args) { if (!procedure_name.empty()) { CHILL_ERROR("only one procedure can be handled in a script"); @@ -706,9 +717,7 @@ static PyObject *chill_distribute(PyObject *self, PyObject *args) { static PyObject * chill_num_statements(PyObject *self, PyObject *args) { - //DEBUG_PRINT("\nC chill_num_statements() called from python\n"); int num = myloop->stmt.size(); - //DEBUG_PRINT("C num_statement() = %d\n", num); return Py_BuildValue("i", num); // BEWARE "d" is DOUBLE, not int } @@ -716,6 +725,7 @@ static PyMethodDef ChillMethods[] = { //python name C routine parameter passing comment {"source", chill_source, METH_VARARGS, "set source file for chill script"}, + {"destination", chill_dest, METH_VARARGS, "set destination file for generated source"}, {"procedure", chill_procedure, METH_VARARGS, "set the name of the procedure"}, {"loop", chill_loop, METH_VARARGS, "indicate which loop to optimize"}, {"print_code", chill_print_code, METH_VARARGS, "print generated code"}, @@ -767,5 +777,6 @@ initchill(void) // pass C methods to python { CHILL_DEBUG_PRINT("set up C methods to be called from python\n"); PyObject *m = Py_InitModule("chill", ChillMethods); + dest_filename = ""; register_globals(m); } diff --git a/src/ir_clang.cc b/src/ir_clang.cc index 51e5388..b5db954 100755 --- a/src/ir_clang.cc +++ b/src/ir_clang.cc @@ -141,7 +141,9 @@ SourceManager *globalSRCMAN; // ugly. shame. char *splitTypeInfo(char *underlyingtype); chillAST_Node* unwrap(chillAST_NodeList* nl){ - chillAST_Node* n = (*nl)[0]; + chillAST_Node* n; + if (!nl || !nl->size()) n = NULL; + else n = (*nl)[0]; delete nl; return n; } @@ -340,9 +342,7 @@ chillAST_NodeList* ConvertDeclStmt(DeclStmt *clangDS) { chillAST_NodeList* ConvertCompoundStmt(CompoundStmt *clangCS) { - //fprintf(stderr, "ConvertCompoundStmt( )\n"); int numchildren = clangCS->size(); - //fprintf(stderr, "clang CompoundStmt has %d children\n", numchildren); // make an empty CHILL compound statement chillAST_CompoundStmt *chillCS = new chillAST_CompoundStmt; @@ -363,15 +363,12 @@ chillAST_NodeList* ConvertCompoundStmt(CompoundStmt *clangCS) { chillAST_NodeList* ConvertFunctionDecl(FunctionDecl *D) { - //fprintf(stderr, "\nConvertFunctionDecl( )\n"); QualType QT = D->getReturnType(); string ReturnTypeStr = QT.getAsString(); // Function name DeclarationName DeclName = D->getNameInfo().getName(); string FuncName = DeclName.getAsString(); - //fprintf(stderr, "function %s has type %s ", FuncName.c_str(), ReturnTypeStr.c_str()); - //fprintf(stderr, "\n%s %s()\n", ReturnTypeStr.c_str(), FuncName.c_str()); chillAST_FunctionDecl *chillFD = new chillAST_FunctionDecl(ReturnTypeStr.c_str(), FuncName.c_str(), D); @@ -672,19 +669,12 @@ chillAST_NodeList* ConvertImplicitCastExpr(ImplicitCastExpr *clangICE) { chillAST_NodeList* ConvertCStyleCastExpr(CStyleCastExpr *clangCSCE) { - //fprintf(stderr, "ConvertCStyleCastExpr()\n"); - //fprintf(stderr, "C Style cast of kind "); CastExpr *CE = dyn_cast<CastExpr>(clangCSCE); - //fprintf(stderr, "%s\n", CE->getCastKindName()); - //clangCSCE->getTypeAsWritten().getAsString(Policy) const char *towhat = strdup(clangCSCE->getTypeAsWritten().getAsString().c_str()); - //fprintf(stderr, "before sub towhat (%s)\n", towhat); chillAST_Node *sub = unwrap(ConvertGenericClangAST(clangCSCE->getSubExprAsWritten())); - //fprintf(stderr, "after sub towhat (%s)\n", towhat); chillAST_CStyleCastExpr *chillCSCE = new chillAST_CStyleCastExpr(towhat, sub); - //fprintf(stderr, "after CSCE towhat (%s)\n", towhat); NL_RET(chillCSCE); } @@ -1601,12 +1591,17 @@ IR_clangCode_Global_Init::~IR_clangCode_Global_Init() { // Class: IR_clangCode // ---------------------------------------------------------------------------- +IR_clangCode::IR_clangCode(const char *filename, const char *proc_name, const char *dest_name) : IR_clangCode(filename, + proc_name) { + outfilename = strdup(dest_name); +} IR_clangCode::IR_clangCode(const char *fname, const char *proc_name) : IR_Code() { CHILL_DEBUG_PRINT("IR_xxxxCode::IR_xxxxCode()\n"); //fprintf(stderr, "IR_clangCode::IR_clangCode( filename %s, procedure %s )\n", filename, proc_name); filename = strdup(fname); // filename is internal to IR_clangCode procedurename = strdup(proc_name); + outfilename = NULL; int argc = 2; char *argv[2]; @@ -1666,17 +1661,15 @@ IR_clangCode::~IR_clangCode() { CHILL_DEBUG_BEGIN src->dump(); CHILL_DEBUG_END - if (src->isSourceFile()) src->printToFile(); + if (src->isSourceFile()) src->printToFile(outfilename); } } //TODO IR_ScalarSymbol *IR_clangCode::CreateScalarSymbol(const IR_Symbol *sym, int i) { - //fprintf(stderr, "IR_clangCode::CreateScalarSymbol()\n"); if (typeid(*sym) == typeid(IR_chillScalarSymbol)) { // should be the case ??? fprintf(stderr, "IR_xxxxCode::CreateScalarSymbol() from a scalar symbol\n"); - //fprintf(stderr, "(typeid(*sym) == typeid( IR_chillScalarSymbol )\n"); const IR_chillScalarSymbol *CSS = (IR_chillScalarSymbol *) sym; chillAST_VarDecl *vd = CSS->chillvd; @@ -1688,19 +1681,11 @@ IR_ScalarSymbol *IR_clangCode::CreateScalarSymbol(const IR_Symbol *sym, int i) { return new IR_chillScalarSymbol(this, CSS->chillvd); // CSS->clone(); } - // ?? if (typeid(*sym) == typeid(IR_chillArraySymbol)) { fprintf(stderr, "IR_xxxxCode::CreateScalarSymbol() from an array symbol?\n"); const IR_chillArraySymbol *CAS = (IR_chillArraySymbol *) sym; - //fprintf(stderr, "CAS 0x%x chillvd = 0x%x\n", CAS, CAS->chillvd); - //fprintf(stderr, "\nthis is the SYMBOL?: \n"); - //CAS->print(); - //CAS->dump(); chillAST_VarDecl *vd = CAS->chillvd; - //fprintf(stderr, "\nthis is the var decl?: "); - //vd->print(); printf("\n"); - //vd->dump(); printf("\n\n"); fflush(stdout); // figure out the base type (probably float) of the array @@ -1959,6 +1944,7 @@ std::vector<IR_Control *> IR_clangCode::FindOneLevelControlStructure(const IR_Bl chillAST_Node *blockast = NULL; int numstmts = CB->statements.size(); + bool unwrap = false; CHILL_DEBUG_PRINT("%d statements\n", numstmts); if (numstmts == 0) return controls; @@ -1969,86 +1955,66 @@ std::vector<IR_Control *> IR_clangCode::FindOneLevelControlStructure(const IR_Bl for (int i = 0; i < CB->statements.size(); ++i) { fprintf(stderr, "block's AST is of type %s\n", CB->statements[i]->getTypeString()); CB->statements[i]->print(); - printf("\n"); - fflush(stdout); } CHILL_DEBUG_END - - //vector<chillAST_Node *> funcchildren = chillfunc->getChildren(); - //fprintf(stderr, "%d children of clangcode\n", funcchildren.size()); // includes parameters - // build up a vector of "controls". // a run of straight-line code (statements that can't cause branching) will be // bundled up into an IR_Block // ifs and loops will get their own entry - - std::vector<chillAST_Node *> *children; - - - if (blockast->getType() == CHILLAST_NODE_FORSTMT) { - CHILL_DEBUG_BEGIN - fflush(stdout); - fprintf(stderr, "found a top level For statement (Loop)\n"); - fprintf(stderr, "For Stmt (loop) is:\n"); - blockast->print(); - fprintf(stderr, "pushing the loop at TOP\n"); - CHILL_DEBUG_END - - controls.push_back(new IR_chillLoop(this, (chillAST_ForStmt *) blockast)); - } - else if (blockast->getType() == CHILLAST_NODE_COMPOUNDSTMT || - blockast->getType() == CHILLAST_NODE_FUNCTIONDECL) { - - if (blockast->getType() == CHILLAST_NODE_FUNCTIONDECL) { + const std::vector<chillAST_Node *> *children = NULL; + if (blockast) { + if (blockast->isFunctionDecl()) { chillAST_FunctionDecl *FD = (chillAST_FunctionDecl *) blockast; chillAST_Node *bod = FD->getBody(); children = bod->getChildren(); - } else /* CompoundStmt */ { + unwrap = true; + } + if (blockast->isCompoundStmt()) { children = blockast->getChildren(); + unwrap = true; } + if (blockast->isForStmt()) { + controls.push_back(new IR_chillLoop(this, (chillAST_ForStmt *) blockast)); + return controls; + } + } + if (!children) + children = &(CB->statements); + + int numchildren = children->size(); + int ns; + IR_chillBlock *basicblock = new IR_chillBlock(this); // no statements + for (int i = 0; i < numchildren; i++) { + CHILLAST_NODE_TYPE typ = (*children)[i]->getType(); + if (typ == CHILLAST_NODE_LOOP) { + CHILL_DEBUG_PRINT("found a For statement (Loop) at %d within a Basic Block\n", i); + + ns = basicblock->numstatements(); + if (ns) { + CHILL_DEBUG_PRINT("pushing a run of statements as a block\n"); + controls.push_back(basicblock); + basicblock = new IR_chillBlock(this); // start a new one + } - int numchildren = children->size(); - int ns; - IR_chillBlock *basicblock = new IR_chillBlock(this); // no statements - for (int i = 0; i < numchildren; i++) { - CHILLAST_NODE_TYPE typ = (*children)[i]->getType(); - if (typ == CHILLAST_NODE_LOOP) { - if (numchildren == 1) { - CHILL_DEBUG_PRINT("found a For statement (Loop)\n"); - } else { - CHILL_DEBUG_PRINT("found a For statement (Loop) at %d within a Basic Block\n", i); - } - - ns = basicblock->numstatements(); - if (ns) { - CHILL_DEBUG_PRINT("pushing a run of statements as a block\n"); - controls.push_back(basicblock); - basicblock = new IR_chillBlock(this); // start a new one - } - - CHILL_DEBUG_PRINT("pushing the loop at %d\n", i); - controls.push_back(new IR_chillLoop(this, (chillAST_ForStmt *) (*children)[i])); + CHILL_DEBUG_PRINT("pushing the loop at %d\n", i); + controls.push_back(new IR_chillLoop(this, (chillAST_ForStmt *) (*children)[i])); - } - //else if (typ == CHILLAST_NODE_IFSTMT ) // TODO - else { // straight line code - basicblock->addStatement((*children)[i]); - CHILL_DEBUG_BEGIN - fprintf(stderr, "straight line code\n"); - fprintf(stderr, "child %d = \n", i); - (*children)[i]->print(); - printf("\n"); - fflush(stdout); - fprintf(stderr, "child %d is part of a basic block\n", i); - CHILL_DEBUG_END - } - } // for each child - ns = basicblock->numstatements(); - if (ns!=0) - controls.push_back(basicblock); - } else - CHILL_DEBUG_PRINT("Single statement block of type %s\n", blockast->getTypeString()); + } + //else if (typ == CHILLAST_NODE_IFSTMT ) // TODO + else { // straight line code + basicblock->addStatement((*children)[i]); + CHILL_DEBUG_BEGIN + fprintf(stderr, "straight line code\n"); + fprintf(stderr, "child %d = \n", i); + (*children)[i]->print(); + fprintf(stderr, "child %d is part of a basic block\n", i); + CHILL_DEBUG_END + } + } // for each child + ns = basicblock->numstatements(); + if (ns != 0 && (unwrap || ns != numchildren)) + controls.push_back(basicblock); CHILL_DEBUG_PRINT("returning vector of %d controls\n", controls.size()); return controls; @@ -2171,10 +2137,9 @@ void IR_clangCode::ReplaceCode(IR_Control *old, omega::CG_outputRepr *repr) { std::vector<chillAST_Node *> *oldparentcode = par->getChildren(); // probably only works for compoundstmts // find loop in the parent - int index = -1; int numstatements = oldparentcode->size(); - for (int i = 0; i < numstatements; i++) if ((*oldparentcode)[i] == forstmt) { index = i; } - if (index == -1) { + int index = par->findChild(forstmt); + if (index < 0) { CHILL_ERROR("can't find the loop in its parent\n"); exit(-1); } @@ -2200,10 +2165,24 @@ void IR_clangCode::ReplaceCode(IR_Control *old, omega::CG_outputRepr *repr) { fflush(stdout); } break; - case IR_CONTROL_BLOCK: + case IR_CONTROL_BLOCK: { CHILL_ERROR("old is IR_CONTROL_BLOCK\n"); - exit(-1); + par = ((IR_chillBlock*)old)->statements[0]->parent; + if (!par) { + CHILL_ERROR("old parent was NULL\n"); + CHILL_ERROR("ir_clang.cc that will not work very well.\n"); + exit(-1); + } + IR_chillBlock *cblock = (struct IR_chillBlock *) old; + std::vector<chillAST_Node *> *oldparentcode = par->getChildren(); // probably only works for compoundstmts + int index = par->findChild(cblock->statements[0]); + for (int i = 0;i<cblock->numstatements();++i) // delete all current statements + par->removeChild(par->findChild(cblock->statements[i])); + for (int i = 0; i < numnew; i++) + par->insertChild(index + i, newcode[i]); // insert New child + // TODO add in (insert) variable declarations that go with the new loops break; + } default: throw chill::error::ir("control structure to be replaced not supported"); break; diff --git a/src/irtools.cc b/src/irtools.cc index abe6c43..784f6e4 100644 --- a/src/irtools.cc +++ b/src/irtools.cc @@ -376,7 +376,7 @@ test_data_dependences(IR_Code *ir, fprintf(stderr, "\nirtools.cc ij %d %d SYMBOL A == SYMBOL B and one is a write\n", i, j); Relation *helper = new Relation(r); fprintf(stderr, "r "); - helper->print(); + helper->print(stderr); fflush(stdout); CHILL_DEBUG_END std::pair<std::vector<DependenceVector>, diff --git a/src/printer/cfamily.cpp b/src/printer/cfamily.cpp index 488c884..c328c67 100644 --- a/src/printer/cfamily.cpp +++ b/src/printer/cfamily.cpp @@ -59,7 +59,7 @@ void CFamily::printS(std::string ident, chillAST_BinaryOperator *n, std::ostream if (n->getLHS()) printPrec(ident, n->getLHS(), o, prec); else o << "(NULL)"; o << " " << n->op << " "; - if (n->getRHS()) printPrec(ident, n->getRHS(), o, prec); + if (n->getRHS()) printPrec(ident, n->getRHS(), o, prec-1); else o << "(NULL)"; } @@ -83,32 +83,32 @@ void CFamily::printS(std::string ident, chillAST_CallExpr *n, std::ostream &o) { FD = (chillAST_FunctionDecl *) n->getCallee(); else if (n->getCallee()->isMacroDefinition()) MD = (chillAST_MacroDefinition *) n->getCallee(); - if (FD) { - o << FD->functionName; + if (MD && n->getNumChildren()-1) + o << "("; + else { + print(ident,n->getCallee(),o); if (n->grid && n->block) o << "<<<" << n->grid->varname << "," << n->block->varname << ">>>"; o << "("; } - if (MD && n->getNumChildren()-1) - o << "("; for (int i = 1; i < n->getNumChildren(); ++i) { - if (i != 0) o << ", "; + if (i != 1) o << ", "; print(ident, n->getChild(i), o); } - if (FD || n->getNumChildren()-1) + if (!MD || n->getNumChildren()-1) o << ")"; } void CFamily::printS(std::string ident, chillAST_CompoundStmt *n, std::ostream &o) { chillAST_NodeList *c = n->getChildren(); string nid = ident + identSpace; - if (c->size() > 1) o << "{"; + if (c->size() > 1 || n->getParent()->isFunctionDecl()) o << "{"; for (int i = 0; i < c->size(); ++i) { o << "\n" << nid; print(nid, c->at(i), o); if (!ifSemicolonFree(c->at(i)->getType())) o << ";"; } - if (c->size() > 1) o << "\n" << ident << "}"; + if (c->size() > 1 || n->getParent()->isFunctionDecl()) o << "\n" << ident << "}"; } int CFamily::getPrecS(chillAST_CStyleAddressOf *n) { diff --git a/src/printer/dump.cpp b/src/printer/dump.cpp index cd4c316..ca208ab 100644 --- a/src/printer/dump.cpp +++ b/src/printer/dump.cpp @@ -24,6 +24,7 @@ void dumpVector(GenericPrinter *p, string ident, chillAST_TypedefTable *n, ostre } void Dump::print(string ident, chillAST_Node *n, ostream &o) { + if (!n) return; o << "(" << n->getTypeString() << " "; if (n->getParameters()) { o << "(Params: "; @@ -70,8 +71,7 @@ void Dump::printS(std::string ident, chillAST_BinaryOperator *n, std::ostream &o } void Dump::printS(std::string ident, chillAST_CallExpr *n, std::ostream &o) { - if (n->getCallee()) - print(ident, n->getCallee(), o); + dumpVector(this,ident,n->getChildren(),o); } void Dump::printS(std::string ident, chillAST_CompoundStmt *n, std::ostream &o) { diff --git a/src/printer/generic.cpp b/src/printer/generic.cpp index 79ee312..dcd5498 100644 --- a/src/printer/generic.cpp +++ b/src/printer/generic.cpp @@ -7,6 +7,7 @@ using namespace chill::printer; void GenericPrinter::print(std::string ident, chillAST_Node *n, std::ostream &o) { + if (!n) return; switch (n->getType()) { case CHILLAST_NODE_ARRAYSUBSCRIPTEXPR: printS(ident, dynamic_cast<chillAST_ArraySubscriptExpr *>(n), o); @@ -120,6 +121,7 @@ void GenericPrinter::print(std::string ident, chillAST_Node *n, std::ostream &o) } int GenericPrinter::getPrec(chillAST_Node *n) { + if (!n) return defGetPrecS(); switch (n->getType()) { case CHILLAST_NODE_ARRAYSUBSCRIPTEXPR: return getPrecS(dynamic_cast<chillAST_ArraySubscriptExpr *>(n)); |