This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
00001 //===-- parser/ParseClient.h ---------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2008-2010, Stephen Wilson 00006 // 00007 //===----------------------------------------------------------------------===// 00008 00009 #ifndef COMMA_PARSECLIENT_HDR_GUARD 00010 #define COMMA_PARSECLIENT_HDR_GUARD 00011 00012 #include "comma/basic/ParameterModes.h" 00013 #include "comma/basic/IdentifierInfo.h" 00014 00015 #include "llvm/ADT/SmallVector.h" 00016 #include "llvm/ADT/PointerIntPair.h" 00017 00018 namespace llvm { 00019 00020 class APInt; 00021 00022 } // end llvm namespace 00023 00024 namespace comma { 00025 00026 class ParseClient; 00027 00028 //===----------------------------------------------------------------------===// 00029 // Node 00030 // 00031 // This class encapsulates (in a non-type-safe manner) the internal data 00032 // structures produced by a ParseClient, and provides automatic memory 00033 // management of that data by way of a reference counting mechanism. 00034 // 00035 // When a ParseClient returns data to the parser, it wraps it up in a Node 00036 // instance. This provides a uniform, opaque handle on the data which the 00037 // parser can collect and submit back to the ParseClient. 00038 // 00039 // A Node provides automatic memory management using a reference counting 00040 // mechanism. Nodes can be freely copied and assigned to. Each Node contains a 00041 // pointer to the ParseClient which produced its associated data. When the 00042 // reference count drops to zero, ParseClient::deleteNode is called with the 00043 // Node about to be freed, giving the ParseClient the opportunity to manage to 00044 // allocation of its data. 00045 // 00046 // In general, automatic reclamation of nodes occurs when an error is 00047 // encountered during parsing, or during the analysis performed by the 00048 // ParseClient itself. When the ParseClient accepts a particular construct that 00049 // the parser produces, the associated Node's are typically released, thereby 00050 // inhibiting the automatic reclamation that would otherwise occur. 00051 // 00052 // A Node can be marked as "invalid", meaning that the data which is associated 00053 // with the Node is malformed in some respect. A ParseClient can return invalid 00054 // nodes to indicate that it could not handle a construct produced by the 00055 // parser. The parser in turn never submits an invalid Node back to the client. 00056 class Node { 00057 00058 // This simple structure is used to maintain the ParseClient and reference 00059 // count associated with each node. 00060 struct NodeState { 00061 00062 // Disjoint properties associated with each node, recorded in the low 00063 // order bits of NodeState::client. 00064 enum Property { 00065 None = 0, 00066 Invalid = 1, 00067 Released = 2 00068 }; 00069 00070 // The ParseClient associated with this node. We encode the 00071 // NodePropertys associated with this node in the low order bits of this 00072 // field as it is expected to be accessed relatively infrequently. 00073 llvm::PointerIntPair<ParseClient *, 2> client; 00074 00075 // The reference count. 00076 unsigned rc; 00077 00078 // The payload associated with this node. 00079 void *payload; 00080 00081 // NOTE: Constructor initializes the reference count to 1. 00082 NodeState(ParseClient *client, 00083 void *ptr = 0, Property prop = None) 00084 : client(client, prop), 00085 rc(1), 00086 payload(ptr) { } 00087 00088 private: 00089 // Do not implement. 00090 NodeState(const NodeState &state); 00091 NodeState &operator=(const NodeState &state); 00092 }; 00093 00094 // Construction of nodes is prohibited except by the ParseClient producing 00095 // them. Thus, all direct constructors are private and we define the 00096 // ParseClient as a friend. 00097 Node(ParseClient *client, void *ptr, NodeState::Property prop) 00098 : state(new NodeState(client, ptr, prop)) { } 00099 00100 Node(ParseClient *client, void *ptr = 0) 00101 : state(new NodeState(client, ptr)) { } 00102 00103 static Node getInvalidNode(ParseClient *client) { 00104 return Node(client, 0, NodeState::Invalid); 00105 } 00106 00107 static Node getNullNode(ParseClient *client) { 00108 return Node(client); 00109 } 00110 00111 friend class ParseClient; 00112 00113 public: 00114 Node(const Node &node) 00115 : state(node.state) { 00116 ++state->rc; 00117 } 00118 00119 ~Node() { dispose(); } 00120 00121 Node &operator=(const Node &node); 00122 00123 00124 // Returns true if this node is invalid. 00125 bool isInvalid() const { 00126 return state->client.getInt() & NodeState::Invalid; 00127 } 00128 00129 // Returns true if this Node is valid. 00130 bool isValid() const { return !isInvalid(); } 00131 00132 // Marks this node as invalid. 00133 void markInvalid(); 00134 00135 // Returns true if this Node is not associated with any data. 00136 bool isNull() const { 00137 return state->payload == 0; 00138 } 00139 00140 // Releases ownership of this node (and all copies). 00141 void release(); 00142 00143 // Returns true if this Node owns the associated pointer. 00144 bool isOwning(); 00145 00146 // Returns the reference count associated with this node. 00147 unsigned getRC() { return state->rc; } 00148 00149 // Returns the pointer associated with this node cast to the supplied type. 00150 template <class T> static T *lift(Node &node) { 00151 return reinterpret_cast<T*>(node.state->payload); 00152 } 00153 00154 private: 00155 void dispose(); 00156 00157 // Heap-allocated state associated with this node (and all copies). 00158 NodeState *state; 00159 }; 00160 00161 //===----------------------------------------------------------------------===// 00162 // NodeVector 00163 // 00164 // A simple vector type which manages a collection of Node's. This type 00165 // provides a release method which releases all of the Node's associated with 00166 // the vector. 00167 class NodeVector : public llvm::SmallVector<Node, 16> { 00168 public: 00169 void release(); 00170 }; 00171 00172 class ParseClient { 00173 00174 public: 00179 Node getNullNode() { return Node::getNullNode(this); } 00180 00185 Node getInvalidNode() { return Node::getInvalidNode(this); } 00186 00191 virtual void deleteNode(Node &node) = 0; 00192 00200 00201 virtual void beginCapsule() = 0; 00202 virtual void endCapsule() = 0; 00204 00210 00211 00212 00213 00214 00215 00216 00217 00218 00219 virtual void beginGenericFormals() = 0; 00220 virtual void endGenericFormals() = 0; 00222 00232 virtual void acceptFormalDomain(IdentifierInfo *name, Location loc, 00233 Node sig) = 0; 00234 00242 00243 virtual void beginDomainDecl(IdentifierInfo *name, Location loc) = 0; 00244 virtual void beginSignatureDecl(IdentifierInfo *name, Location loc) = 0; 00246 00249 00250 00251 00252 00253 00254 00255 00256 00257 00258 00259 virtual void beginSignatureProfile() = 0; 00260 virtual void endSignatureProfile() = 0; 00262 00264 virtual void acceptSupersignature(Node typeNode) = 0; 00266 00270 virtual void beginAddExpression() = 0; 00271 00273 virtual void endAddExpression() = 0; 00274 00276 virtual void acceptCarrier(IdentifierInfo *name, Location loc, 00277 Node typeNode) = 0; 00278 00287 00288 virtual void beginFunctionDeclaration(IdentifierInfo *name, 00289 Location loc) = 0; 00290 virtual void beginProcedureDeclaration(IdentifierInfo *name, 00291 Location loc) = 0; 00292 00300 virtual void acceptFunctionReturnType(Node typeNode) = 0; 00301 00315 virtual void acceptSubroutineParameter(IdentifierInfo *formal, Location loc, 00316 Node typeNode, 00317 PM::ParameterMode mode) = 0; 00318 00326 virtual Node endSubroutineDeclaration(bool definitionFollows) = 0; 00328 00331 00332 00339 virtual Node beginSubroutineDefinition(Node declarationNode) = 0; 00340 00344 virtual void endSubroutineBody(Node context) = 0; 00345 00349 virtual void endSubroutineDefinition() = 0; 00351 00355 00356 virtual Node acceptDirectName(IdentifierInfo *name, Location loc, 00357 bool forStatement) = 0; 00358 00359 virtual Node acceptCharacterLiteral(IdentifierInfo *lit, Location loc) = 0; 00360 00361 virtual Node acceptSelectedComponent(Node prefix, 00362 IdentifierInfo *name, 00363 Location loc, 00364 bool forStatement) = 0; 00365 00366 virtual Node acceptParameterAssociation(IdentifierInfo *key, 00367 Location loc, Node rhs) = 0; 00368 00369 virtual Node acceptApplication(Node prefix, NodeVector &argumentNodes) = 0; 00370 00371 virtual Node acceptAttribute(Node prefix, 00372 IdentifierInfo *name, Location loc) = 0; 00373 00374 virtual Node finishName(Node name) = 0; 00376 00392 00397 00398 00402 virtual void beginAggregate(Location loc) = 0; 00403 00405 virtual void acceptPositionalAggregateComponent(Node component) = 0; 00406 00408 virtual Node acceptAggregateKey(Node lower, Node upper) = 0; 00409 00412 virtual Node acceptAggregateKey(Node key) = 0; 00413 00423 virtual Node acceptAggregateKey(IdentifierInfo *name, Location loc) = 0; 00424 00440 virtual void acceptKeyedAggregateComponent(NodeVector &keys, 00441 Node expr, Location loc) = 0; 00442 00450 virtual void acceptAggregateOthers(Location loc, Node component) = 0; 00451 00455 virtual Node endAggregate() = 0; 00457 00458 00464 00465 00483 virtual Node beginForStmt(Location loc, 00484 IdentifierInfo *iterName, Location iterLoc, 00485 Node control, bool isReversed) = 0; 00486 00495 virtual Node endForStmt(Node forNode, NodeVector &bodyNodes) = 0; 00497 00503 00504 00513 virtual Node acceptDSTDefinition(Node name, Node lower, Node upper) = 0; 00514 00519 virtual Node acceptDSTDefinition(Node nameOrAttribute, 00520 bool isUnconstrained) = 0; 00521 00524 virtual Node acceptDSTDefinition(Node lower, Node upper) = 0; 00526 00534 00535 00537 virtual Node beginBlockStmt(Location loc, IdentifierInfo *label = 0) = 0; 00538 00542 virtual void endBlockStmt(Node block) = 0; 00544 00547 00548 00559 virtual Node beginHandlerStmt(Location loc, NodeVector &choices) = 0; 00560 00568 virtual void endHandlerStmt(Node context, Node handler) = 0; 00570 00572 virtual Node acceptNullStmt(Location loc) = 0; 00573 00583 virtual bool acceptStmt(Node context, Node stmt) = 0; 00584 00585 virtual bool acceptObjectDeclaration(Location loc, IdentifierInfo *name, 00586 Node type, Node initializer) = 0; 00587 00588 virtual bool acceptRenamedObjectDeclaration(Location loc, 00589 IdentifierInfo *name, 00590 Node type, Node target) = 0; 00591 00592 virtual Node acceptPercent(Location loc) = 0; 00593 00594 virtual Node acceptProcedureCall(Node name) = 0; 00595 00598 virtual Node acceptInj(Location loc, Node expr) = 0; 00599 00602 virtual Node acceptPrj(Location loc, Node expr) = 0; 00603 00604 virtual Node acceptIntegerLiteral(llvm::APInt &value, Location loc) = 0; 00605 00615 virtual Node acceptStringLiteral(const char *string, unsigned len, 00616 Location loc) = 0; 00617 00620 virtual Node acceptNullExpr(Location loc) = 0; 00621 00628 virtual Node acceptAllocatorExpr(Node operand, Location loc) = 0; 00629 00635 virtual Node acceptQualifiedExpr(Node qualifier, Node operand) = 0; 00636 00642 virtual Node acceptDereference(Node prefix, Location loc) = 0; 00643 00645 virtual bool acceptImportDeclaration(Node importedType) = 0; 00646 00647 virtual Node acceptIfStmt(Location loc, Node condition, 00648 NodeVector &consequents) = 0; 00649 00650 virtual Node acceptElseStmt(Location loc, Node ifNode, 00651 NodeVector &alternates) = 0; 00652 00653 virtual Node acceptElsifStmt(Location loc, Node ifNode, Node condition, 00654 NodeVector &consequents) = 0; 00655 00656 virtual Node acceptEmptyReturnStmt(Location loc) = 0; 00657 00658 virtual Node acceptReturnStmt(Location loc, Node retNode) = 0; 00659 00660 virtual Node acceptAssignmentStmt(Node target, Node value) = 0; 00661 00663 virtual Node acceptWhileStmt(Location loc, Node condition, 00664 NodeVector &stmtNodes) = 0; 00665 00667 virtual Node acceptLoopStmt(Location loc, NodeVector &stmtNodes) = 0; 00668 00678 virtual Node acceptRaiseStmt(Location loc, Node exception, 00679 Node message) = 0; 00680 00682 virtual Node acceptPragmaStmt(IdentifierInfo *name, Location loc, 00683 NodeVector &pragmaArgs) = 0; 00684 00700 virtual void 00701 acceptPragmaImport(Location pragmaLoc, 00702 IdentifierInfo *convention, Location conventionLoc, 00703 IdentifierInfo *enity, Location entityLoc, 00704 Node externalNameNode) = 0; 00705 00714 00715 00716 00717 00718 00719 00720 00721 00722 virtual void beginEnumeration(IdentifierInfo *name, Location loc) = 0; 00723 00730 virtual void acceptEnumerationIdentifier(IdentifierInfo *name, 00731 Location loc) = 0; 00732 00743 virtual void acceptEnumerationCharacter(IdentifierInfo *name, 00744 Location loc) = 0; 00745 00748 virtual void endEnumeration() = 0; 00750 00757 virtual void acceptIntegerTypeDecl(IdentifierInfo *name, Location loc, 00758 Node low, Node high) = 0; 00759 00767 virtual void acceptRangedSubtypeDecl(IdentifierInfo *name, Location loc, 00768 Node subtype, 00769 Node low, Node high) = 0; 00770 00777 virtual void acceptSubtypeDecl(IdentifierInfo *name, Location loc, 00778 Node subtype) = 0; 00779 00784 virtual void acceptIncompleteTypeDecl(IdentifierInfo *name, 00785 Location loc) = 0; 00786 00788 virtual void acceptAccessTypeDecl(IdentifierInfo *name, Location loc, 00789 Node subtype) = 0; 00790 00801 virtual void acceptArrayDecl(IdentifierInfo *name, Location loc, 00802 NodeVector indices, Node component) = 0; 00803 00809 00810 00816 virtual void beginRecord(IdentifierInfo *name, Location loc) = 0; 00817 00825 virtual void acceptRecordComponent(IdentifierInfo *name, Location loc, 00826 Node type) = 0; 00827 00829 virtual void endRecord() = 0; 00831 00832 protected: 00834 Node getNode(void *ptr) { return Node(this, ptr); } 00835 00838 Node getReleasedNode(void *ptr) { 00839 Node node(this, ptr); 00840 node.release(); 00841 return node; 00842 } 00843 }; 00844 00845 //===----------------------------------------------------------------------===// 00846 // Inline methods. 00847 00848 inline void Node::dispose() 00849 { 00850 assert(state->rc != 0); 00851 if (--state->rc == 0) { 00852 if (isOwning()) 00853 state->client.getPointer()->deleteNode(*this); 00854 delete state; 00855 } 00856 } 00857 00858 inline Node &Node::operator=(const Node &node) 00859 { 00860 if (state != node.state) { 00861 ++node.state->rc; 00862 dispose(); 00863 state = node.state; 00864 } 00865 return *this; 00866 } 00867 00868 inline void Node::release() 00869 { 00870 unsigned prop = state->client.getInt(); 00871 state->client.setInt(prop | NodeState::Released); 00872 } 00873 00874 inline bool Node::isOwning() 00875 { 00876 return !(state->client.getInt() & NodeState::Released); 00877 } 00878 00879 inline void Node::markInvalid() 00880 { 00881 unsigned prop = state->client.getInt(); 00882 state->client.setInt(prop | NodeState::Invalid); 00883 } 00884 00885 inline void NodeVector::release() 00886 { 00887 for (iterator iter = begin(); iter != end(); ++iter) 00888 iter->release(); 00889 } 00890 00891 } // End comma namespace. 00892 00893 #endif