INTERFACE: #include #include // OpenC++ interfaces #include #include #include "ptree_nodes.h" #include "source.h" #include "downcast.h" class Source; /** Base class for visitors of a PTree hierarchy. This class template serves as an adapter to OpenC++'s Walker hierarchy, which is already supported by PTree and friends. Currently, this class recursively traverses a parse tree. Users can overload the visit() functions to add their own node-specific code, and call this class' visit() to do the recursion. */ template class Ptree_visitor : private Opencxx::Walker { // TYPES typedef Walker Super; // DATA Source* _s; Returntype _saved; public: using Super::operator delete; using Super::operator new; Source* get_source() const { return _s; } }; IMPLEMENTATION: PUBLIC template explicit Ptree_visitor::Ptree_visitor (Source* s) : Opencxx::Walker (s->parser()), _s (s) { } PUBLIC template virtual Ptree_visitor::~Ptree_visitor () { } PUBLIC template Returntype Ptree_visitor::visit () { _s->translate(this); // XXX Source::translate returns Ptree -- why? return _saved; } PUBLIC template virtual Returntype Ptree_visitor::visit (Ptree *p) { if (! p) return visit_null (); Returntype saved = _saved; Super::Translate (p); std::swap (_saved, saved); return saved; } /** Recursively visit nested nodes. (You should not overload this function. If you want to change the default action, overload default() instead.) @param p parse subtree @returns result of visitation of last subtree of p */ PROTECTED template Returntype Ptree_visitor::recurse (Ptree* p) { assert (p); if (p->IsLeaf()) return Returntype(0); Returntype r(0); do { r = visit (p->Car()); p = p->Cdr(); if (p && p->IsLeaf()) { r = visit (p); break; } } while (p); return r; } /** Default action taken when a visit_*() function has not been overloaded. Overload this function to change the default action. The standard default action is to call recurse() on the argument. @param p parse subtree @returns result of default action */ PROTECTED template virtual Returntype Ptree_visitor::default_action (Ptree* p) { if (p) return recurse (p); return Returntype (0); } PUBLIC template virtual Returntype Ptree_visitor::visit_null () { return default_action (0); } // // Type switch // /** Visit a parse-tree leaf: Leaf, LeafReserved, and all subclasses of LeafReserved: LeafNAMESPACE etc. */ PUBLIC template virtual Returntype Ptree_visitor::visit_leaf (Leaf *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_nonleaf (NonLeaf *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_declarator (PtreeDeclarator *p) { return default_action(p); } /** @param p ["typedef", Ptree(type), Ptree(newtypename)] */ PUBLIC template virtual Returntype Ptree_visitor::visit_typedef (PtreeTypedef *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_templatedecl (PtreeTemplateDecl *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_templateinstantiation (PtreeTemplateInstantiation *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_externtemplate (PtreeExternTemplate *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_linkagespec (PtreeLinkageSpec *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_namespacespec (PtreeNamespaceSpec *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_using (PtreeUsing *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_declaration (PtreeDeclaration *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_brace (PtreeBrace *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_block (PtreeBlock *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_classbody (PtreeClassBody *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_classspec (PtreeClassSpec *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_enumspec (PtreeEnumSpec *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_accessspec (PtreeAccessSpec *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_accessdecl (PtreeAccessDecl *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_useraccessspec (PtreeUserAccessSpec *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_if (PtreeIfStatement *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_switch (PtreeSwitchStatement *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_while (PtreeWhileStatement *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_do (PtreeDoStatement *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_for (PtreeForStatement *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_try (PtreeTryStatement *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_break (PtreeBreakStatement *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_continue (PtreeContinueStatement *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_return (PtreeReturnStatement *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_goto (PtreeGotoStatement *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_case (PtreeCaseStatement *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_default (PtreeDefaultStatement *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_label (PtreeLabelStatement *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_comma (PtreeCommaExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_assign (PtreeAssignExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_cond (PtreeCondExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_infix (PtreeInfixExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_pm (PtreePmExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_cast (PtreeCastExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_unary (PtreeUnaryExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_throw (PtreeThrowExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_sizeof (PtreeSizeofExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_typeid (PtreeTypeidExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_new (PtreeNewExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_delete (PtreeDeleteExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_array (PtreeArrayExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_funcall (PtreeFuncallExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_postfix (PtreePostfixExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_userstatement (PtreeUserStatementExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_dotmember (PtreeDotMemberExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_arrowmember (PtreeArrowMemberExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_paren (PtreeParenExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_staticuserstatement (PtreeStaticUserStatementExpr *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_exprstatement (PtreeExprStatement *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_fstylecastexpr (PtreeFstyleCastExpr *p) { return default_action(p); } /** @param p Can be PtreeName or LeafName */ PUBLIC template virtual Returntype Ptree_visitor::visit_name (Ptree *p) { return default_action(p); } PUBLIC template virtual Returntype Ptree_visitor::visit_this (LeafThis *p) { return default_action(p); } PROTECTED template virtual void Ptree_visitor::runtime_error () { assert (!"This should never be called."); } // // Override OpenC++'s Walker functions // // Define those functions called by subclass implementations of // Ptree::Translate(). template virtual Ptree* Ptree_visitor::TranslatePtree (Ptree *p) { // Hack: Do some type deduction for types that do not support // visitation if (p->IsLeaf()) _saved = visit_leaf (downcast(p)); else if (PtreeDeclarator* d = dynamic_cast(p)) _saved = visit_declarator (d); else _saved = visit_nonleaf (downcast(p)); // This barfs if p is not a nonleaf, which is what we want. return 0; } template virtual Ptree* Ptree_visitor::TranslateTypedef (Ptree *p) { _saved = visit_typedef (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateTemplateDecl (Ptree *p) { _saved = visit_templatedecl (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateTemplateInstantiation (Ptree *p) { _saved = visit_templateinstantiation (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateExternTemplate (Ptree *p) { _saved = visit_externtemplate (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateLinkageSpec (Ptree *p) { _saved = visit_linkagespec (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateNamespaceSpec (Ptree *p) { _saved = visit_namespacespec (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateUsing (Ptree *p) { _saved = visit_using (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateDeclaration (Ptree *p) { _saved = visit_declaration (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateBrace (Ptree *p) { _saved = visit_brace (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateBlock (Ptree *p) { _saved = visit_block (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateClassBody (Ptree *p, Ptree *, Opencxx::Class *) { _saved = visit_classbody (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateClassSpec (Ptree *p) { _saved = visit_classspec (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateEnumSpec (Ptree *p) { _saved = visit_enumspec (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateAccessSpec (Ptree *p) { _saved = visit_accessspec (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateAccessDecl (Ptree *p) { _saved = visit_accessdecl (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateUserAccessSpec (Ptree *p) { _saved = visit_useraccessspec (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateIf (Ptree *p) { _saved = visit_if (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateSwitch (Ptree *p) { _saved = visit_switch (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateWhile (Ptree *p) { _saved = visit_while (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateDo (Ptree *p) { _saved = visit_do (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateFor (Ptree *p) { _saved = visit_for (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateTry (Ptree *p) { _saved = visit_try (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateBreak (Ptree *p) { _saved = visit_break (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateContinue (Ptree *p) { _saved = visit_continue (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateReturn (Ptree *p) { _saved = visit_return (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateGoto (Ptree *p) { _saved = visit_goto (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateCase (Ptree *p) { _saved = visit_case (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateDefault (Ptree *p) { _saved = visit_default (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateLabel (Ptree *p) { _saved = visit_label (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateExprStatement (Ptree *p) { _saved = visit_exprstatement (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateComma (Ptree *p) { _saved = visit_comma (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateAssign (Ptree *p) { _saved = visit_assign (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateCond (Ptree *p) { _saved = visit_cond (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateInfix (Ptree *p) { _saved = visit_infix (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslatePm (Ptree *p) { _saved = visit_pm (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateCast (Ptree *p) { _saved = visit_cast (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateUnary (Ptree *p) { _saved = visit_unary (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateThrow (Ptree *p) { _saved = visit_throw (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateSizeof (Ptree *p) { _saved = visit_sizeof (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateTypeid (Ptree *p) { _saved = visit_typeid (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateNew (Ptree *p) { _saved = visit_new (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateDelete (Ptree *p) { _saved = visit_delete (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateArray (Ptree *p) { _saved = visit_array (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateFuncall (Ptree *p) { _saved = visit_funcall (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslatePostfix (Ptree *p) { _saved = visit_postfix (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateUserStatement (Ptree *p) { _saved = visit_userstatement (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateDotMember (Ptree *p) { _saved = visit_dotmember (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateArrowMember (Ptree *p) { _saved = visit_arrowmember (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateParen (Ptree *p) { _saved = visit_paren (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateStaticUserStatement (Ptree *p) { _saved = visit_staticuserstatement (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateFstyleCast (Ptree *p) { _saved = visit_fstylecastexpr (downcast(p)); return 0; } template virtual Ptree* Ptree_visitor::TranslateVariable (Ptree *p) { // no downcast here -- p can be LeafName or PtreeName _saved = visit_name (p); return 0; } template virtual Ptree* Ptree_visitor::TranslateThis (Ptree *p) { _saved = visit_this (downcast(p)); return 0; } // Wire all other virtual functions of Walker to runtime errors. They // should never be called. template virtual bool Ptree_visitor::IsClassWalker () { runtime_error(); return 0; } template virtual void Ptree_visitor::TypeofPtree (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual Ptree* Ptree_visitor::TranslateTemplateInstantiation (Ptree *, Ptree *, Ptree *, Opencxx::Class *) { runtime_error(); return 0; } template virtual Ptree* Ptree_visitor::TranslateTemplateClass (Ptree *, Ptree *) { runtime_error(); return 0; } template virtual Ptree* Ptree_visitor::TranslateTemplateFunction (Ptree *, Ptree *) { runtime_error(); return 0; } template virtual Ptree* Ptree_visitor::TranslateStorageSpecifiers (Ptree *) { runtime_error(); return 0; } template virtual Ptree* Ptree_visitor::TranslateDeclarators (Ptree *) { runtime_error(); return 0; } template virtual Ptree* Ptree_visitor::TranslateDeclarator (bool, PtreeDeclarator *) { runtime_error(); return 0; } template virtual Ptree* Ptree_visitor::TranslateArgDeclList (bool, Ptree *, Ptree *) { runtime_error(); return 0; } template virtual Ptree* Ptree_visitor::TranslateInitializeArgs (PtreeDeclarator *, Ptree *) { runtime_error(); return 0; } template virtual Ptree* Ptree_visitor::TranslateAssignInitializer (PtreeDeclarator *, Ptree *) { runtime_error(); return 0; } template virtual Ptree* Ptree_visitor::TranslateFunctionImplementation (Ptree *) { runtime_error(); return 0; } template virtual Ptree* Ptree_visitor::RecordArgsAndTranslateFbody (Opencxx::Class *, Ptree *args, Ptree *body) { runtime_error(); return 0; } template virtual Ptree* Ptree_visitor::TranslateFunctionBody (Ptree *) { runtime_error(); return 0; } template virtual Ptree* Ptree_visitor::TranslateClassSpec (Ptree *, Ptree *, Ptree *, Opencxx::Class *) { runtime_error(); return 0; } template virtual Ptree* Ptree_visitor::TranslateTypespecifier (Ptree *) { runtime_error(); return 0; } template virtual Ptree* Ptree_visitor::TranslateNew2 (Ptree *, Ptree *, Ptree *, Ptree *, Ptree *, Ptree *, Ptree *) { runtime_error(); return 0; } template virtual Ptree* Ptree_visitor::TranslateNew3 (Ptree *type) { runtime_error(); return 0; } // Metaclass stuff template virtual Opencxx::Class* Ptree_visitor::MakeTemplateInstantiationMetaobject (Ptree *full_class_spec, Ptree *userkey, Ptree *class_spec) { runtime_error(); return 0; } template virtual Opencxx::Class* Ptree_visitor::MakeTemplateClassMetaobject (Ptree *, Ptree *, Ptree *) { runtime_error(); return 0; } template virtual Opencxx::Class* Ptree_visitor::MakeClassMetaobject (Ptree *, Ptree *, Ptree *) { runtime_error(); return 0; } // Typeof stuff template virtual void Ptree_visitor::TypeofComma (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofAssign (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofCond (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofInfix (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofPm (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofCast (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofUnary (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofThrow (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofSizeof (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofTypeid (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofNew (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofDelete (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofThis (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofVariable (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofFstyleCast (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofArray (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofFuncall (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofPostfix (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofUserStatement (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofDotMember (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofArrowMember (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofParen (Ptree *, Opencxx::TypeInfo &) { runtime_error(); } template virtual void Ptree_visitor::TypeofStaticUserStatement (Ptree *, Opencxx::TypeInfo &) { runtime_error(); }