00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef COMMA_AST_TYPE_HDR_GUARD
00010 #define COMMA_AST_TYPE_HDR_GUARD
00011
00012 #include "comma/ast/AstBase.h"
00013 #include "comma/ast/AstRewriter.h"
00014 #include "llvm/ADT/FoldingSet.h"
00015 #include "llvm/ADT/SmallPtrSet.h"
00016 #include "llvm/Support/Casting.h"
00017
00018 namespace comma {
00019
00020
00021
00022
00023 class Type : public Ast {
00024
00025 public:
00026 virtual ~Type() { }
00027
00028 static bool classof(const Type *node) { return true; }
00029 static bool classof(const Ast *node) {
00030 return node->denotesType();
00031 }
00032
00033 protected:
00034 Type(AstKind kind) : Ast(kind) {
00035 assert(this->denotesType());
00036 }
00037 };
00038
00039
00040
00041
00042 class ModelType : public Type {
00043
00044 public:
00045 virtual ~ModelType() { }
00046
00047 IdentifierInfo *getIdInfo() const { return idInfo; }
00048
00049
00050
00051 const char *getString() const {
00052 return getIdInfo()->getString();
00053 }
00054
00055
00056 static bool classof(const ModelType *node) { return true; }
00057 static bool classof(const Ast *node) {
00058 return node->denotesModelType();
00059 }
00060
00061 protected:
00062 ModelType(AstKind kind, IdentifierInfo *idInfo)
00063 : Type(kind),
00064 idInfo(idInfo) { assert(this->denotesModelType()); }
00065
00066 IdentifierInfo *idInfo;
00067 };
00068
00069
00070
00071
00072 class SignatureType : public ModelType, public llvm::FoldingSetNode {
00073
00074 public:
00075 Sigoid *getDeclaration() const;
00076
00077 SignatureDecl *getSignature() const;
00078
00079 VarietyDecl *getVariety() const;
00080
00081
00082 bool isParameterized() const { return getVariety() != 0; }
00083
00084
00085
00086 unsigned getArity() const;
00087
00088
00089
00090 DomainType *getActualParameter(unsigned n) const;
00091
00092 typedef DomainType **arg_iterator;
00093 arg_iterator beginArguments() const { return arguments; }
00094 arg_iterator endArguments() const { return &arguments[getArity()]; }
00095
00096 void Profile(llvm::FoldingSetNodeID &id) {
00097 Profile(id, &arguments[0], getArity());
00098 }
00099
00100
00101 static void
00102 Profile(llvm::FoldingSetNodeID &id, DomainType **args, unsigned numArgs);
00103
00104 static bool classof(const SignatureType *node) { return true; }
00105 static bool classof(const Ast *node) {
00106 return node->getKind() == AST_SignatureType;
00107 }
00108
00109 private:
00110 friend class SignatureDecl;
00111 friend class VarietyDecl;
00112
00113 SignatureType(SignatureDecl *decl);
00114
00115 SignatureType(VarietyDecl *decl, DomainType **args, unsigned numArgs);
00116
00117
00118 Sigoid *sigoid;
00119
00120
00121
00122 DomainType **arguments;
00123 };
00124
00125
00126
00127
00128
00129
00130 class ParameterizedType : public ModelType {
00131
00132 public:
00133 virtual ~ParameterizedType() { }
00134
00135 unsigned getArity() const { return numFormals; }
00136
00137
00138 AbstractDomainType *getFormalDomain(unsigned i) const;
00139
00140
00141
00142 SignatureType *getFormalType(unsigned i) const;
00143
00144
00145 IdentifierInfo *getFormalIdInfo(unsigned i) const;
00146
00147
00148
00149 int getSelectorIndex(IdentifierInfo *selector) const;
00150
00151 static bool classof(const ParameterizedType *node) { return true; }
00152 static bool classof(const Ast *node) {
00153 AstKind kind = node->getKind();
00154 return kind == AST_VarietyType || kind == AST_FunctorType;
00155 }
00156
00157 protected:
00158 ParameterizedType(AstKind kind,
00159 IdentifierInfo *idInfo,
00160 AbstractDomainType **formalArguments,
00161 unsigned arity);
00162
00163 AbstractDomainType **formals;
00164 unsigned numFormals;
00165 };
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 class VarietyType : public ParameterizedType {
00177
00178 public:
00179 VarietyType(AbstractDomainType **formalArguments,
00180 VarietyDecl *variety, unsigned arity);
00181
00182 ~VarietyType();
00183
00184 VarietyDecl *getVarietyDecl() const { return variety; }
00185
00186 static bool classof(const VarietyType *node) { return true; }
00187 static bool classof(const Ast *node) {
00188 return node->getKind() == AST_VarietyType;
00189 }
00190
00191 private:
00192 friend class VarietyDecl;
00193
00194 VarietyDecl *variety;
00195 };
00196
00197
00198
00199
00200
00201
00202
00203
00204 class FunctorType : public ParameterizedType {
00205
00206 public:
00207 FunctorType(AbstractDomainType **formalArguments,
00208 FunctorDecl *functor, unsigned arity);
00209
00210 ~FunctorType();
00211
00212 FunctorDecl *getFunctorDecl() const { return functor; }
00213
00214 static bool classof(const FunctorType *node) { return true; }
00215 static bool classof(const Ast *node) {
00216 return node->getKind() == AST_FunctorType;
00217 }
00218
00219 private:
00220 FunctorDecl *functor;
00221 };
00222
00223
00224
00225
00226
00227
00228
00229
00230 class DomainType : public ModelType {
00231
00232 public:
00233 virtual ~DomainType() { }
00234
00235
00236
00237 ModelDecl *getDeclaration() const;
00238
00239
00240
00241 Domoid *getDomoid() const;
00242
00243
00244
00245 DomainDecl *getDomain() const;
00246
00247
00248
00249 FunctorDecl *getFunctor() const;
00250
00251
00252
00253
00254 bool isAbstract() const;
00255
00256
00257 bool isConcrete() const { return !isAbstract(); }
00258
00259 ConcreteDomainType *getConcreteType();
00260
00261
00262 static bool classof(const DomainType *node) { return true; }
00263 static bool classof(const Ast *node) {
00264 return node->denotesDomainType();
00265 }
00266
00267 protected:
00268 DomainType(AstKind kind, IdentifierInfo *idInfo, ModelDecl *decl);
00269 DomainType(AstKind kind, IdentifierInfo *idInfo, SignatureType *sig);
00270
00271 union {
00272 Ast *astNode;
00273 ModelDecl *modelDecl;
00274 SignatureType *signatureType;
00275 };
00276 };
00277
00278
00279
00280
00281
00282 class ConcreteDomainType : public DomainType, public llvm::FoldingSetNode {
00283
00284 public:
00285
00286
00287
00288
00289 unsigned getArity() const;
00290
00291
00292
00293 DomainType *getActualParameter(unsigned n) const;
00294
00295
00296 bool isParameterized() const { return arguments != 0; }
00297
00298 typedef DomainType **arg_iterator;
00299 arg_iterator beginArguments() const { return arguments; }
00300 arg_iterator endArguments() const { return &arguments[getArity()]; }
00301
00302 void Profile(llvm::FoldingSetNodeID &id) {
00303 Profile(id, &arguments[0], getArity());
00304 }
00305
00306
00307 static void
00308 Profile(llvm::FoldingSetNodeID &id, DomainType **args, unsigned numArgs);
00309
00310
00311 static bool classof(const ConcreteDomainType *node) { return true; }
00312 static bool classof(const Ast *node) {
00313 return node->getKind() == AST_ConcreteDomainType;
00314 }
00315
00316 private:
00317 friend class DomainDecl;
00318 friend class FunctorDecl;
00319
00320
00321 ConcreteDomainType(DomainDecl *decl);
00322
00323
00324
00325 ConcreteDomainType(FunctorDecl *decl, DomainType **args, unsigned numArgs);
00326
00327
00328
00329 DomainType **arguments;
00330 };
00331
00332
00333
00334 class AbstractDomainType : public DomainType {
00335
00336 public:
00337
00338 AbstractDomainType(IdentifierInfo *name, SignatureType *signature)
00339 : DomainType(AST_AbstractDomainType, name, signature),
00340 idInfo(name) { };
00341
00342
00343 SignatureType *getSignature() const { return signatureType; }
00344
00345
00346 static bool classof(const AbstractDomainType *node) { return true; }
00347 static bool classof(const Ast *node) {
00348 return node->getKind() == AST_AbstractDomainType;
00349 }
00350
00351 private:
00352 IdentifierInfo *idInfo;
00353 };
00354
00355
00356
00357 class PercentType : public DomainType {
00358
00359 public:
00360 PercentType(IdentifierInfo *idInfo, ModelDecl *decl)
00361 : DomainType(AST_PercentType, idInfo, decl) { }
00362
00363 static bool classof(const PercentType *node) { return true; }
00364 static bool classof(const Ast *node) {
00365 return node->getKind() == AST_PercentType;
00366 }
00367 };
00368
00369
00370 inline ConcreteDomainType *DomainType::getConcreteType()
00371 {
00372 return llvm::dyn_cast<ConcreteDomainType>(this);
00373 }
00374
00375
00376
00377
00378 class FunctionType : public Type {
00379
00380 public:
00381 FunctionType(IdentifierInfo **formals,
00382 DomainType **argTypes,
00383 unsigned numArgs,
00384 DomainType *returnType);
00385
00386
00387 unsigned getArity() const { return numArgs; }
00388
00389
00390 DomainType *getReturnType() const { return returnType; }
00391
00392
00393 DomainType *getArgType(unsigned i) const {
00394 assert(i < getArity() && "Index out of range!");
00395 return argumentTypes[i];
00396 }
00397
00398
00399 IdentifierInfo *getSelector(unsigned i) const {
00400 assert(i < getArity() && "Index out of range!");
00401 return selectors[i];
00402 }
00403
00404
00405
00406
00407 bool selectorsMatch(const FunctionType *ftype) const;
00408
00409
00410
00411
00412 bool equals(const FunctionType *ftype) const;
00413
00414 private:
00415 IdentifierInfo **selectors;
00416 DomainType **argumentTypes;
00417 DomainType *returnType;
00418 unsigned numArgs;
00419 };
00420
00421 }
00422
00423 #endif