/* -*-C++-*- */ // AST.h: Definitions for Abstract Syntax Trees #ifndef _AST_H_ #define _AST_H_ #include "ti_config.h" #if USE_LONG_LONG_SUPPORT_H #include "long-long-support.h" #endif /* get intptr_t type */ #include "runtime/gasnet/other/portable_inttypes.h" #include "debug_memory.h" #define __SINST__ // g++ header bug #include #include #include #include #include #include #include "Subst.h" #include "alloccount.h" #include "common.h" #include "gc.h" #include "parse.h" #include "string16.h" #include "utils.h" class AliasInfos; class AllocateNode; class ArrayAccessSet; class Bitset; class Bblock; class Candidate; class CatchListNode; class CfgNode; class CfgExtent; class ClassDecl; class ClassDeclNode; class CompileUnitNode; class CodeContext; class ConstPseudonymDecl; class CfSource; class CodeLiteralNode; class CtType; class Decl; class Defs; class EnactContext; class Environ; class ExprNode; class InferContext; class LocalVars; class LocalEnactContext; class LocalSolver; class MethodStatics; class MIVE; class MIVEcontext; class MonitorFetchNode; class MonitorStats; class NodeStorage; class ObjectNode; class Poly; class PseudonymDecl; class QualSolver; class SharingEnactContext; class SharingSolver; class StatementNode; class StringTable; class Substitutions; class TemplateCheckContext; class TemplateContext; class TemplateParamDecl; class TouchSet; class TreeListNode; class TypeDecl; class TypeDeclNode; class TypeListNode; class TypePseudonymDecl; class TypeNode; class UniqueId; template< class T > class llist; template< class T > class ullist; template< class T, class U = T > class UniqueCons; template< class T > class VectIter; template< class T > class CnstVectIter; template< class T > class SolverInferContext; typedef set< const TreeNode *, less< const TreeNode * > > treeSet; typedef set< CfgNode * > CFGset; typedef UniqueCons< CfgNode *, intptr_t > CFGusetFactory; typedef ullist< CfgNode * > CFGuset; typedef set< const string * > IdentSet; typedef SolverInferContext< LocalSolver > LocalContext; typedef SolverInferContext< SharingSolver > SharingContext; #include "maps.h" #if 0 #include "parse.h" #include "template.h" #endif class TreeNode : public Common, public gc { public: /*****************************************************************/ /* Accessors */ /* The position in the source ascribed to this node. */ inline const SourcePosn &position() const { return where; } /* The parent of this node in the AST. NULL for the root node */ inline TreeNode *parent() const { return _parent; } /* The Ith child (numbering from 0) of *this, 0 <= I < arity(). */ inline TreeNode* child (int i) const { assert ((unsigned int) i < (unsigned int) arity()); return children[i]; } typedef VectIter ChildIter; typedef VectIter TypeIter; typedef CnstVectIter ConstChildIter; typedef CnstVectIter ConstTypeIter; /* An iterator over all children of *THIS. */ ChildIter allChildren(); TypeIter allTypes(); ConstChildIter allChildren() const; ConstTypeIter allTypes() const; /* Print a representation of *this on OS, indenting each line */ /* after the first by INDENT spaces. */ virtual void print (ostream& os, unsigned depth = 0) const; /* Print the attributes of *this on OS, indenting each line */ /* after the first by INDENT spaces. */ virtual void print_attrs (ostream& os, unsigned depth = 0) const; // Print as above, but with a trailing newline and stream flush void print() const { print( cout ); cout << endl; } /* Print a pseudocode representation of *this on OS, indenting each line */ /* after the first by INDENT spaces. */ virtual void pseudoprint (ostream& os, unsigned depth = 0) const; // Serialize a representation of *this. Similar to print(), but // intended for processing by a machine rather than by a human. virtual void dump (ostream &, unsigned depth = 0) const; /* Return true if argument appears to be identical to this. */ /* Implementation of compare() is generated by defnodeimpls.el. */ virtual bool compare (const TreeNode *) const; /* Return a string representing this node suitable for printing */ /* in an error message */ virtual string errorName() const; /* When true, indicates an optional node that is absent (that is, */ /* that the node comes from the static constant omitted, defined */ /* below). */ virtual bool absent() const; /* A TreeNode for which absent() is true. By convention, every */ /* derivate of TreeNode indicating a type of node that may be */ /* missing (i.e., that represents an optional piece of syntax) */ /* also has a static variable of this name which absent() is true. */ static TreeNode* const omitted; /* The printed name of the operator for *this. */ virtual const char* oper_name() const; /* The name of operators, for operator overloading and error messages */ /* (undefined on non-operators) */ virtual const char *operatorName() const; /* The number of children this node possesses. */ virtual int arity() const; /* Make a copy of this node */ virtual TreeNode *clone() const = 0; /* Make a copy of this node and all of its children */ virtual TreeNode *deepClone() const = 0; protected: virtual void deepCloneSpecial (TreeNode* copy) const; public: /* A positive integer identifier unique to THIS. */ int uid () const { return _uid; } /*****************************************************************/ /* Modifying children */ /* Set the Ith child (numbering from 0) of *this to NEWCHILD, 0 <= */ /* I < arity(). The dynamic type of NEWCHILD must be correct for */ /* the type of node. */ void child (int i, TreeNode* newChild) { assert ((unsigned int) i < (unsigned int) arity()); children[i] = newChild; if (newChild) newChild->_parent = this; } /*****************************************************************/ /* Delete this subtree and free some memory. */ virtual void free(); /* Ensure that all derived classes have virtual destructors */ virtual ~TreeNode(); /*****************************************************************/ /* Static semantics */ /* Parsing help */ virtual bool isd() const; virtual TypeNode *asType(); virtual TreeNode *asExpr(); virtual TypeNode *asType2(TypeNode *base); virtual TreeNode *asExpr2(TreeNode *array); virtual bool resolveNewArray(Decl *package, Environ *fileEnv, bool exprOnly, llist **dims, TypeNode **base); virtual bool isArraySpecifier(Decl *package, Environ *fileEnv); /* Static analysis, phase 0: move inner classes to the top level */ class FlattenContext; virtual int incLocalCount(); virtual int incAnonCount(); virtual void flattenClasses (FlattenContext *ctx); class TypeContext; virtual TreeNode *buildTypeEnv(TypeContext *ctx); /* Static analysis, phase 1: build the package environment */ virtual void packageResolution(); /* Static analysis, phase 2: resolveClass: build the class environment resolveInheritance: add inherited members */ class ClassContext; virtual void resolveClass (ClassContext *ctx); virtual void resolveInheritance(); /* Static analysis, phase 3: resolve all names and remove parsing ambiguities */ class NameContext; virtual TreeNode* resolveName (const NameContext &ctx); /* Static analysis, phase 4: (global) verify inheritance circularity */ virtual bool verifyCircularity() const; virtual void reportCircularity() const; /* Static analysis, phase 5: (global) fold constants */ virtual TreeNode *foldConstants(); virtual void foldFields(); /* Static analysis, phase 6: resolve fields, method overloading, and compute types (lazily) */ class FieldContext; class AllocateContext; virtual TreeNode *resolveField(FieldContext *ctx, bool *inAssignment); /* Static analysis, phase 7: simplify string concatenations */ virtual TreeNode *resolveConcat(); /* Static analysis, phase 8: check types */ /* The return value is true if the statement/expression may terminate normally (i.e. doesn't return/throw - break & continue are ignored here because they don't influence whether the whole body of a function may terminate normally) */ virtual bool typecheck(TypeContext *ctx); /* Static analysis, phase 9: check reachability of statements */ class ReachableContext; virtual bool reachability(ReachableContext &); /* Static analysis, phase 10: rewrite some tree nodes for the back end */ virtual TreeNode *rewrite( const FieldContext * ); /* Static analysis, phase 11: Single inference */ class SingleState; class SingleContext; virtual SingleState single(SingleContext *); /* Static analysis, phase 12: Explicitly identify cleanup operations to be performed on scope exit */ virtual void collectCleanups(); /* Static analysis, phase 13: Add widening conversions discovered by the type checker */ virtual void widen(); /* Static analysis, phase 14: Locate interclass dependencies that affect code generation. */ virtual void resolveRequires(ClassDecl *); int fixParent(); TreeNode *cloneSharedSubtrees(); /* Static analysis, phase 15: Introduce temporaries */ virtual TreeNode *lower(llist *&, llist *&); virtual TreeNode * collapseTrivialBlocks(); /** Compute eCFG dominators for code in foreach loops, assuming * that THIS is part of a loop at depth LEVEL. If IGNORENSE, * then don't count non-standard exits from the current loop. */ virtual void computeForeachDominators(bool ignoreNSE, int level); /* Static analysis, phase 16: Control flow */ virtual CfgExtent makeCfg(); virtual CfgExtent getCfgExtent(); virtual CfgExtent getExceptionCfg(); virtual CfgNode *getContinueTarget(); /* Whether this node is a pragma requesting everything in r. */ virtual bool isPragma(Pragma::Request r) const; /* Check that the tree is valid IF (intermediate form) */ /* If serious is true then halt the program with an error message if the check fails. */ virtual bool checkIF(bool serious) const; virtual TreeNode * applyReordering(); /* The type of this node (only makes sense for ExprNodes) */ virtual TypeNode* type(); virtual TypeNode* declaredType() { return type(); } /* The type of constants (needed before typechecking for constant folding). Returns 0 for non-constants */ virtual Common::Kind constantType() const; /* For nodes that represent field accesses (ObjectFieldAccessNode, */ /* ThisFieldAccessNode, SuperFieldAccessNode) the type of the */ /* object that is accessed (e.g., for a node representing FOO.BAR, */ /* the type of FOO. */ virtual TypeNode *accessedObjectType() const; /* Return true if this node is an int constant in the specified range. Assumes constant folding has already been done */ virtual bool isIntConstant(int from, int to) const; /* Report an error if this expression cannto be assigned with 'with' */ virtual void checkAssignable(TreeNode *with, bool ignoreInstanceFinal, bool ignoreStaticFinal, Decl *currentClass); /* Some methods that are type-related but that also appear in TreeNode's (because of TreeListNode, LitNode and NameNode) */ /* Assuming THIS and T1 represent types, true iff they represent */ /* identical types. */ virtual bool typeIdent(const TreeNode* T1) const; /* The same, but ignore type modifiers at the top-level */ virtual bool typeIdentNM(const TreeNode* T1) const; /* The same, but ignore single type modifiers at the top-level (this is getting silly) */ virtual bool typeIdentNS(const TreeNode* T1) const; // Return true if corresponding types in 'this' and 'T1' have the same qualifiers // (requires that this and T1 be TypeListNodes with the same arity) virtual bool singleArgsIdent(const TreeNode* T1) const; /* The JVM signature corresponding to this type. */ virtual string signature() const; /* Signatures for types in method formals */ virtual string formalSignature() const; virtual bool hasFormalSignature() const; /* Return a human readable string for this typename. This string should be unique (i.e. include the package) */ virtual string typeName() const; virtual string unqualifiedTypeName() const; // The type conversions inherent in the xxxAssignNode nodes cannot be // represented by CastNode's. Instead, give a op= b, two functions are provided: // - widenSource: the type to which a should be widened to perform 'a op b' // - castResult: the type to which 'a op b' should be cast before assignment to a // In both cases, NULL is returned if no conversion is necessary. // None of these casts require run-time checks. // widenSource is also the type at which 'op' is computed virtual TypeNode *widenSource(); virtual TypeNode *castResult(); /*****************************************************************/ protected: virtual void reportChange( const string &, const TypeNode & ) const; public: virtual void unshareType(); virtual void unshareTypeTree(); virtual bool isExported() const; virtual bool isInferable() const; virtual void infer( const InferContext & ); virtual void enact( const EnactContext & ); virtual void receiveAssign( const TypeNode &, QualSolver & ) const; virtual void constrainCall( const TypeNode &, QualSolver & ) const; // Local qualification inference void inferLocalTreeExport( const LocalContext & ); virtual void inferLocalTree( const LocalContext & ); virtual void inferLocalChildren( const LocalContext & ) const; virtual void inferLocal( const LocalContext & ); virtual void localReceiveAssign( const TypeNode &, LocalSolver & ) const; virtual void localEnactTree( const LocalEnactContext & ); virtual void localEnactChildren( const LocalEnactContext & ) const; // Sharing qualification inference void inferSharingTreeExport( const SharingContext & ); virtual void inferSharingLateTree( const SharingContext & ); virtual void inferSharingLateChildren( const SharingContext & ) const; virtual void inferSharingLate( const SharingContext & ); virtual void inferSharingEarlyTree( SharingSolver & ) const; virtual void inferSharingEarlyChildren( SharingSolver & ) const; virtual void inferSharingEarly( SharingSolver & ) const; virtual void sharingEnactTree( const SharingEnactContext & ); virtual void sharingEnactChildren( const SharingEnactContext & ) const; virtual void sharingEnact( const SharingEnactContext & ); /*****************************************************************/ // look for a suitable main() method virtual void lookForMain() const; // Mark certain blocks of code as "to be optimized" virtual TreeNode *lazyOptimize(); // simplify or eliminate superfluous monitor operations virtual TreeNode *optimizeMonitors( MonitorStats & ); // t->deleteStmts(s) returns a tree the same as t except that // statements in the set s are gone. ExpressionStmtNodes that // contains exprs in the set s are also gone. virtual TreeNode * deleteStmts(treeSet *s); // Return a set of assignments that have no side-effects and no uses, // and therefore, that can be safely deleted. treeSet * uselessAssignments(); virtual TreeNode * liftInvariantExprs(); virtual TreeNode * strengthReduce(); // Compute whether this is loop invariant with respect to WRTloop. // If it is, call action(this, WRTloop). virtual bool loopInvariant(TreeNode *WRTloop, treeSet *loopContents, void action(TreeNode *, TreeNode *)); // Compute a MIVE for an expression. Call action() if the MIVE is // different from what we'd computed before for this expression. virtual void computeMIVE(TreeNode *WRTloop, void action(TreeNode *, TreeNode *, MIVE *)); // MIVE helper functions, etc. virtual MIVE * defaultMIVE(MIVEcontext *) const; void setMIVE(TreeNode *l, MIVE *p); MIVE * getMIVE(TreeNode *l); void defaultOrSetMIVE(MIVE *m, TreeNode *WRTloop, void action(TreeNode *, TreeNode *, MIVE *)); void elementwiseMIVE(llist < Poly * > *l, TreeNode *WRTloop, void action(TreeNode *, TreeNode *, MIVE *)); // Code generation virtual void codeGen (); // classes virtual void codeGen (CfSource &); // methods virtual void codeGen (CodeContext &); // everything else // selective filtering; implemented by CompileUnitNode and ClassDeclNode virtual bool selectedForCodeGen(bool) const; // Compute the dependencies between static initializers. virtual void findInitDependencies(Decl *, set *, set *); // For ConstructorDeclNodes and MethodDeclNodes, whether the method has // no callee-visible side-effects. For MethodCalls, whether the called // method and all overriders are SEF. virtual bool isSideEffectFree() const; // Whether a method has no callee visible side effects and always // returns the same value for the same arguments. virtual bool isPureFunction() const; // True for ObjectFieldAccessNode's whose object is immutable virtual bool isFieldOfImmutable() const; // Analyze a loop for invariants and induction variables virtual void loopAnal(TreeNode *); // Return invariants for a loop. Defined on ForEachStmtNode only. virtual treeSet *& invariants(); // Return invariants that were lifted. Defined on ForEachStmtNode only. virtual treeSet *& lifted_invariants(); // Emit debug information virtual void emitDebugInfo(ofstream &os, StringTable &st); // implemented by StatementNode and friends typedef llist< TreeNode * > *CleanupList; virtual void unwindSelf( CleanupList & ) const; virtual void unwindTree( CleanupList &, const TreeNode * ) const; // implemented by TryStmtNode /* !!!!! virtual void emitCleanup( CodeContext & ) const; */ virtual const string emitUse( LocalVars &, const ObjectNode & ) const; // implemented by CatchNode virtual void emitCatchTable( ostream & ) const; // implemented by ExprNode virtual const string declareTemporary( LocalVars & ); virtual const string simpleVar( CodeContext & ); virtual const string emitExpression( CodeContext & ); virtual const string getLvalue( CodeContext & ); virtual bool isLocalLvalue(); virtual bool isSimpleLvalue(); // overridden by ArrayAccessNode virtual bool isArrayAccessNode() const; // overridden by ExprNode virtual bool isExprNode() const; // overridden by LitNode virtual bool isLitNode() const; // overridden by TypeNode virtual bool isTypeNode() const; virtual bool isSharedAccess() const; // implemented by ExprNode subclasses virtual void receiveAssign( ostream &, const string &, const string &, AssignKind, const TypeNode * ); // implemented by FieldAccessNode subclasses virtual const string emitMethodCall( CodeContext &, TreeListNode & ); // whether this node is in the StatementNode hierarchy or not virtual bool isStatementNode(void) const { return false; } // Identify objects that have lvals. virtual bool hasLval() const { return false; } // implemented by ObjectNode, FieldAccessNode, and ArrayAccessNode virtual void setDefs(llist *defs) {} virtual llist *getDefs(void) const { return NULL; } // Pass that searches for defs. Argument is where the result is accumulated. virtual void findDefs(Defs *); virtual void findMayMustReadWrite(bool r, bool w); // Return the cached result of defs analysis on this node. virtual Defs * defs (); // implemented by ObjectNode, FieldAccessNode, ArrayAccessNode, and // ParameterNode virtual void setUses(llist *uses) {} virtual llist *getUses(void) const { return NULL; } // Static info about the method/constructor (decl). Valid after alias // analysis. virtual MethodStatics *methodStatics() const; virtual void setMethodStatics(MethodStatics *ms); // implemented by ObjectNode, ObjectFieldAccessNode, // TypeFieldAccessNode, ArrayAccessNode virtual bool handleAssignment(AliasInfos *ai, Bitset* values); // For some ExprNodes which could have aliasable types. The returned // Bitset should be read-only. This computes. virtual Bitset *getValues(AliasInfos *ai); // Caches the above during alias analysis. For ObjectNodes, this can be // used (after alias analysis) to compare object-typed variables. virtual Bitset *getAbstractValues(); virtual void setAbstractValues(Bitset *b); // For nodes that call another procedure, the set of values that it // modifies virtual Bitset *modifiesValues(); virtual void setModifiesValues(Bitset *b); // implemented by ConstructorDeclNode and MethodDeclNode, used during lazy optimization virtual void setBblockRoot(Bblock *bblock) { undefined("setBblockRoot"); } virtual Bblock *getBblockRoot(void) { undefined("getBblockRoot"); return NULL; } virtual void setNodeStorage(NodeStorage *ns) { undefined("setNodeStorage"); } virtual NodeStorage *getNodeStorage(void) { undefined("getNodeStorage"); return NULL; } // implemented by ConstructorDeclNode and MethodDeclNode, used during method inlining virtual void *inlineInfo() const { undefined("inlineInfo"); return NULL; } virtual void inlineInfo(void *ii) { undefined("inlineInfo"); } /*****************************************************************/ /* The definitions of all accessors for all possible children and */ /* attributes. By default, all of these cause runtime errors */ /* when called; they are overridden in classes that define them. */ #include "tree-accessors.h" /* Template instantiatiation on this node, with the specified substitution */ virtual TreeNode *instantiate(Subst *args); // template helpers virtual TreeNode *fixTemplateActual( TreeNode & ) const; virtual TypeNode *fixTemplateActual( const string & ); virtual ExprNode *fixTemplateActual( const string &, TypeNode & ); virtual void checkTemplateFormal( IdentSet &, IdentSet & ) const; virtual void resolveTemplate( const TemplateContext & ); virtual void checkTemplateActual( TemplateCheckContext &, TreeNode & ) const; virtual int templateDepth() const; virtual PseudonymDecl *bindPseudonym( TreeNode & ) const; virtual string mangle(); // resolveClass helper functions virtual bool updateConstructorValidity(); /* Do a DFS and return the first AllocateNode found. */ virtual AllocateNode *findAllocateNode(); protected: /* Set line number from children, if not determined by P. */ void setWhere (SourcePosn p); /* Report that name is undefined and exit. */ void undefined (const string& name) const __attribute__((noreturn)); public: /* Report a fatal error and exit. */ void fatal (const string& msg) const __attribute__((noreturn)); // Issue an error, warning, or message at the node's source position ostream &error() const; ostream &warning(const char *messagename = NULL) const; ostream &message() const; // Debugging feedback on postponed name and template resolution void postpone( const char *ttask, const char *reason ) const; /* Report that a feature is not yet implemented and exit. */ void unimplemented( const string & ) const __attribute__((noreturn)); protected: TreeNode( SourcePosn where = NoSourcePosition, TreeNode **children = 0 ); TreeNode( const TreeNode& ); SourcePosn where; TreeNode *_parent; TreeNode** children; int _uid; // deep cloning helper method void deepCloneChildren( TreeNode & ) const; /* Useful error checking primitives */ /* Report error if a variable of type to cannot be initialised with expression from. Returns false if error reported. Call operatorName() to get a name for this node. */ void assertArithType(TypeNode *type); void assertBooleanType(TypeNode *type); void assertIntegralType(TypeNode *type); void assertPromoteableInt(TypeNode *type); void assertReferenceType(TypeNode *type); void assertDomainOrRectDomainType(TypeNode *type); void assertRectDomainType(TypeNode *type); void assertAssignable(TypeContext *ctx, TreeNode *tree, TreeNode *with); void assertCastable(TypeNode *from, TypeNode *to); void assertComparable(TypeNode *, TypeNode *); // typecheck helper functions virtual bool _typecheck(TypeContext *ctx); void buildAllowedExceptions(TypeContext *ctx); void buildAllowedExceptions(TypeContext *ctx, TreeNode *throws); virtual bool fieldChainParent() const; // widen helper functions virtual void _widen(); TreeNode *typeWiden(TypeNode *to); TreeNode *widenToGlobal(); TreeNode *stringWiden(TreeNode *from); void methodWiden(); void methodWiden(TreeNode *args, Decl *decl); TypeNode *_widenSource(); TypeNode *_castResult(); // packageResolution helper functions virtual void resolvePackage (Decl* package, Environ *fileEnv, Environ *typeEnviron, bool recurse); virtual void resolveImports(CompileUnitNode *file, Environ *fileEnv); virtual TreeNode *resolveTypes(TypeContext *ctx); // resolveName helper functions virtual bool isLoop() const; // resolveField helper functions void resolveAMember (bool thisAccess, bool isSuper, FieldContext *ctx); Decl *resolveAField (TypeDecl &); // resolveOperators helper functions virtual TreeNode *_resolveOperators(); // actually resolve operators on 'this' TreeNode *resolveOverload(bool assign); TreeNode *generalOverload(string op, bool assign, TreeNode *object, TreeListNode *args); TreeNode *overloadArray(); TreeNode *overloadArrayAssign(); // constant folding helper functions virtual TreeNode *_fold(); virtual Common::Kind foldMask(); // single helper functions bool hasGlobalEffects(SingleState s); bool hasSingleEffects(SingleState s); SingleState duplicateState(SingleState s); void discardState(SingleState s); SingleState removeLabel(SingleState s, TreeNode *label); SingleState removeUnlabeledBreak(SingleState s); SingleState removeException(SingleState s, TypeNode *exception); SingleState mergeTerminations(SingleState s, TypeNode *methodType); void validateTerminations(SingleState s); SingleState sequenceState(SingleState s1, SingleState s2, SingleContext *ctx); SingleState merge(SingleState s1, SingleState s2, bool singleSplit, SingleContext *ctx); SingleState loopMerge(SingleState condition, SingleState body, SingleContext *ctx); static SingleState iAmSingle; SingleState singleList(SingleContext *ctx); SingleState singleSequence(SingleContext *ctx); SingleState singleSequence(SingleContext *ctx, SingleState initial); virtual SingleState singleAssign(const SingleState &from, SingleContext *ctx); SingleState singleAssignment(SingleContext *ctx); SingleState singleIf(TreeNode *condition, TreeNode *thenNode, TreeNode *elseNode, SingleContext *ctx); SingleState singleCall(SingleState st, bool explicitConstructorCall, SingleContext *ctx); SingleState singleAllocateArray(SingleState st, SingleContext *ctx); // sglobal inference helper functions public: virtual void sglobalData(); virtual void sglobalCall(); virtual void checkSglobal() const; Bitset *location_set; protected: virtual void sglobalDataAssign(); protected: // Helper functions for dump(). void dumpPrefix( ostream &, unsigned ) const; void dumpSuffix( ostream &, unsigned ) const; // Use/Def info. llist *_uselist, *_deflist; }; /* A TreeListNode wraps around a list of TreeNode*s to make it easy to */ /* give default definitions for the various virtual functions. */ class TreeListNode : public TreeNode { public: TreeListNode (llist *&_children, SourcePosn p = NoSourcePosition) : TreeNode( p ) { initialize( _children ); _children = 0; } ~TreeListNode() { delete [] children; } const char* oper_name() const; void pseudoprint (ostream &, unsigned ) const; void print( ostream &, unsigned ) const; void dump( ostream &, unsigned ) const; bool compare(const TreeNode *) const; int arity() const; bool empty() const { return !children; } TreeListNode *clone() const; TreeListNode *deepClone() const; void emitExpressionList( CodeContext &, vector< string > & ); CfgExtent makeCfg(); TreeListNode *collapseTrivialBlocks(); bool checkIF(bool) const; // Qualification inference void constrainCall( const TypeListNode &, QualSolver & ) const; bool enactDimension( const EnactContext & ); // template helper string mangle(); protected: TreeListNode( SourcePosn posn = NoSourcePosition ) : TreeNode( posn ) { } void initialize( llist * ); size_t _arity; }; llist *appendTreeList(TreeListNode *l1, llist *l2); class OmittedNode : public TreeNode { public: OmittedNode() { children = NULL; where = NoSourcePosition; } void free(); bool absent() const { return true; } void pseudoprint( ostream &, unsigned ) const; void print( ostream &, unsigned ) const; void dump( ostream &, unsigned ) const; int arity() const { return 0; } TypeNode* type(); SingleState single(SingleContext *ctx); const string emitExpression( CodeContext & ); OmittedNode *clone() const { return const_cast(this); } OmittedNode *deepClone() const { return clone(); } void lookForMain() const; void checkSglobal() const; }; /* An ExprNode has a type. */ class ExprNode : public TreeNode { friend class ThisFieldAccessNode; friend class SuperFieldAccessNode; public: ~ExprNode(); TypeNode* type(); void type(TypeNode *); /* For template arguments */ string unqualifiedTypeName() const; bool typeIdentNM(const TreeNode*) const; bool isExprNode() const; // covariant restrictions ExprNode *clone() const = 0; ExprNode *lower(llist *&, llist *&); TreeNode *instantiate(Subst *args); CfgExtent makeCfg(); const string simpleVar( CodeContext & ); MIVE * defaultMIVE(MIVEcontext *) const; void computeMIVE(TreeNode *WRTloop, void action(TreeNode *, TreeNode *, MIVE *)); // void liftInvariants( CodeContext &, TreeNode *WRTloop ); // Supertype resolution. TreeNode *buildTypeEnv(TypeContext*); // Qualification inference void unshareType(); void infer( const InferContext & ); void enact( const EnactContext & ); // cleanups collection void collectCleanups(); bool checkIF(bool) const; // template helpers ExprNode *fixTemplateActual( const string &, TypeNode & ); virtual void checkTemplateActual( TemplateCheckContext &, const string &, TypeNode & ); protected: ExprNode() : _type(NULL), _abstractValues(NULL) {} /* The function type above memoizes the type in the member */ /* _type. The following function does the actual computation */ /* of the type that type() memoizes. */ virtual TypeNode* __type() = 0; TypeNode* _type; /* Some common type checking rules */ void bitwiseTypecheck(); // Should never be called -- fatal error void codeGen( CodeContext & ); protected: // expression code generation helpers const string emitPrefixOp( CodeContext &, const char ); const string emitBinOp( CodeContext &, const char [] ); const string declareTemporary( LocalVars & ); public: static const string getTemporary(); static void resetTemporary(); const static string declareTemporary( LocalVars &, const TypeNode & ); const static string declareTemporary( LocalVars &, const CtType & ); public: virtual Bitset *getAbstractValues(); virtual void setAbstractValues(Bitset *b); /* methods related to deps */ virtual void findMayMustReadWrite(bool r, bool w); inline TouchSet *& mayRead() { return _mayRead; } inline TouchSet *& mustRead() { return _mustRead; } inline TouchSet *& mayWrite() { return _mayWrite; } inline TouchSet *& mustWrite() { return _mustWrite; } protected: Bitset *_abstractValues; private: static UniqueId temporary; TouchSet *_mayRead; TouchSet *_mustRead; TouchSet *_mayWrite; TouchSet *_mustWrite; }; extern void printNode (const TreeNode* t, ostream& os, int indent = 0); #include "ClassDecl.h" #include "MethodDecl.h" #include "c-types/CtType.h" #include "types.h" #include "templates/ConstPseudonymDecl.h" #include "templates/TypePseudonymDecl.h" #include "tree-nodes.h" #include "errors.h" #endif // Local Variables: // c-file-style: "gnu" // End: