00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef COMMA_PARSER_DESCRIPTORS_HDR_GUARD
00010 #define COMMA_PARSER_DESCRIPTORS_HDR_GUARD
00011
00012 #include "comma/basic/IdentifierInfo.h"
00013 #include "comma/basic/Location.h"
00014 #include "llvm/ADT/SmallVector.h"
00015 #include "llvm/ADT/PointerIntPair.h"
00016
00017 namespace comma {
00018
00019 class ParseClient;
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 class Node {
00050
00051
00052
00053 struct NodeState {
00054
00055
00056
00057 enum Property {
00058 None = 0,
00059 Invalid = 1,
00060 Released = 2
00061 };
00062
00063
00064
00065
00066 llvm::PointerIntPair<ParseClient *, 2> client;
00067
00068
00069 unsigned rc;
00070
00071
00072 void *payload;
00073
00074
00075 NodeState(ParseClient *client,
00076 void *ptr = 0, Property prop = None)
00077 : client(client, prop),
00078 rc(1),
00079 payload(ptr) { }
00080
00081 private:
00082
00083 NodeState(const NodeState &state);
00084 NodeState &operator=(const NodeState &state);
00085 };
00086
00087
00088
00089
00090 Node(ParseClient *client, void *ptr, NodeState::Property prop)
00091 : state(new NodeState(client, ptr, prop)) { }
00092
00093 Node(ParseClient *client, void *ptr = 0)
00094 : state(new NodeState(client, ptr)) { }
00095
00096 static Node getInvalidNode(ParseClient *client) {
00097 return Node(client, 0, NodeState::Invalid);
00098 }
00099
00100 static Node getNullNode(ParseClient *client) {
00101 return Node(client);
00102 }
00103
00104 friend class ParseClient;
00105
00106 public:
00107 Node(const Node &node)
00108 : state(node.state) {
00109 ++state->rc;
00110 }
00111
00112 ~Node() { dispose(); }
00113
00114 Node &operator=(const Node &node);
00115
00116
00117
00118 bool isInvalid() const {
00119 return state->client.getInt() & NodeState::Invalid;
00120 }
00121
00122
00123 bool isValid() const { return !isInvalid(); }
00124
00125
00126 void markInvalid();
00127
00128
00129 bool isNull() const {
00130 return state->payload == 0;
00131 }
00132
00133
00134 void release();
00135
00136
00137 bool isOwning();
00138
00139
00140 unsigned getRC() { return state->rc; }
00141
00142
00143 template <class T> static T *lift(Node &node) {
00144 return reinterpret_cast<T*>(node.state->payload);
00145 }
00146
00147 private:
00148 void dispose();
00149
00150
00151 NodeState *state;
00152 };
00153
00154
00155
00156
00157
00158
00159
00160 class NodeVector : public llvm::SmallVector<Node, 16> {
00161 public:
00162 void release();
00163 };
00164
00165
00166 class Descriptor {
00167
00170 typedef NodeVector paramVector;
00171
00172 public:
00173
00174 enum DescriptorKind {
00175 DESC_Empty,
00176 DESC_Signature,
00177 DESC_Domain,
00178 DESC_Function,
00179 DESC_Procedure
00180 };
00181
00185 Descriptor(ParseClient *client, DescriptorKind kind = DESC_Empty);
00186
00190 void clear();
00191
00194 void initialize(DescriptorKind descKind) {
00195 clear();
00196 kind = descKind;
00197 }
00198
00200 void release();
00201
00203 void setIdentifier(IdentifierInfo *id, Location loc) {
00204 idInfo = id;
00205 location = loc;
00206 }
00207
00209 DescriptorKind getKind() const { return kind; }
00210
00212 bool isFunctionDescriptor() const { return kind == DESC_Function; }
00213 bool isProcedureDescriptor() const { return kind == DESC_Procedure; }
00214 bool isSignatureDescriptor() const { return kind == DESC_Signature; }
00215 bool isDomainDescriptor() const { return kind == DESC_Domain; }
00216
00218 IdentifierInfo *getIdInfo() const { return idInfo; }
00219
00221 Location getLocation() const { return location; }
00222
00223 bool isValid() const { return !invalidFlag; }
00224 bool isInvalid() const { return invalidFlag; }
00225 void setInvalid() { invalidFlag = true; }
00226
00229 void addParam(Node param) { params.push_back(param); }
00230
00233 unsigned numParams() const { return params.size(); }
00234
00236 bool hasParams() const { return numParams() > 0; }
00237
00238 typedef paramVector::iterator paramIterator;
00239 paramIterator beginParams() { return params.begin(); }
00240 paramIterator endParams() { return params.end(); }
00241
00245 void setReturnType(Node node);
00246
00250 Node getReturnType();
00251
00252 private:
00253 DescriptorKind kind : 8;
00254 bool invalidFlag : 1;
00255 bool hasReturn : 1;
00256 ParseClient *client;
00257 IdentifierInfo *idInfo;
00258 Location location;
00259 paramVector params;
00260 Node returnType;
00261 };
00262
00263 }
00264
00265 #endif