00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef COMMA_AST_EXPR_HDR_GUARD
00010 #define COMMA_AST_EXPR_HDR_GUARD
00011
00012 #include "comma/ast/AstBase.h"
00013 #include "comma/ast/Decl.h"
00014 #include "comma/ast/SubroutineCall.h"
00015 #include "comma/ast/SubroutineRef.h"
00016 #include "comma/ast/Type.h"
00017
00018 #include "llvm/ADT/APInt.h"
00019 #include "llvm/ADT/SmallPtrSet.h"
00020 #include "llvm/ADT/StringRef.h"
00021 #include "llvm/Support/DataTypes.h"
00022
00023 namespace comma {
00024
00025
00026
00027
00031 class Expr : public Ast {
00032
00033 public:
00034 Expr(AstKind kind, Type *type, Location loc = 0)
00035 : Ast(kind), type(type), location(loc) {
00036 assert(this->denotesExpr());
00037 }
00038
00039 Expr(AstKind kind, Location loc = 0)
00040 : Ast(kind), type(0), location(loc) {
00041 assert(this->denotesExpr());
00042 }
00043
00044 virtual ~Expr() { }
00045
00047 Location getLocation() const { return location; }
00048
00050 bool hasType() const { return type != 0; }
00051
00061 Type *getType() const {
00062 assert(hasType() && "Expr does not have an associated type!");
00063 return type;
00064 }
00065
00070 void setType(Type *type) { this->type = type; }
00071
00076 bool hasResolvedType() const {
00077 return hasType() && !getType()->isUniversalType();
00078 }
00079
00082 bool isStaticDiscreteExpr() const;
00083
00095 bool staticDiscreteValue(llvm::APInt &result) const;
00096
00105 bool staticStringValue(std::string &result) const;
00106
00109 bool isStaticStringExpr() const;
00110
00130 bool isMutable(Expr *&immutable);
00131
00134 Expr *ignoreInjPrj();
00135
00138 bool denotesName() const;
00139
00140
00141 static bool classof(const Expr *node) { return true; }
00142 static bool classof(const Ast *node) {
00143 return node->denotesExpr();
00144 }
00145
00146 private:
00147 Type *type;
00148 Location location;
00149 };
00150
00151
00152
00153
00154
00155 class DeclRefExpr : public Expr {
00156
00157 public:
00158 DeclRefExpr(ValueDecl *decl, Location loc)
00159 : Expr(AST_DeclRefExpr, decl->getType(), loc),
00160 declaration(decl) { }
00161
00164 IdentifierInfo *getIdInfo() const { return declaration->getIdInfo(); }
00165
00167 const char *getString() const { return declaration->getString(); }
00168
00170
00171 const ValueDecl *getDeclaration() const { return declaration; }
00172 ValueDecl *getDeclaration() { return declaration; }
00174 void setDeclaration(ValueDecl *decl) { declaration = decl; }
00175
00176
00177 static bool classof(const DeclRefExpr *node) { return true; }
00178 static bool classof(const Ast *node) {
00179 return node->getKind() == AST_DeclRefExpr;
00180 }
00181
00182 private:
00183 ValueDecl *declaration;
00184 };
00185
00186
00187
00188
00189 class FunctionCallExpr : public Expr, public SubroutineCall {
00190
00191 public:
00199 FunctionCallExpr(SubroutineRef *connective,
00200 Expr **positionalArgs, unsigned numPositional,
00201 KeywordSelector **keyedArgs, unsigned numKeys);
00202
00205 FunctionCallExpr(FunctionDecl *connective, Location loc,
00206 Expr **positionalArgs, unsigned numPositional,
00207 KeywordSelector **keyedArgs, unsigned numKeys);
00208
00211 FunctionCallExpr(SubroutineRef *connective);
00212
00215 FunctionCallExpr(FunctionDecl *connective, Location loc);
00216
00220 Location getLocation() const { return Expr::getLocation(); }
00221
00223
00224
00225 FunctionDecl *getConnective() {
00226 return llvm::cast<FunctionDecl>(SubroutineCall::getConnective());
00227 };
00228
00229 const FunctionDecl *getConnective() const {
00230 return llvm::cast<FunctionDecl>(SubroutineCall::getConnective());
00231 }
00233
00235 void resolveConnective(FunctionDecl *connective);
00236
00238
00239
00240 const FunctionDecl *getConnective(unsigned i) const {
00241 return llvm::cast<FunctionDecl>(SubroutineCall::getConnective(i));
00242 }
00243 FunctionDecl *getConnective(unsigned i) {
00244 return llvm::cast<FunctionDecl>(SubroutineCall::getConnective(i));
00245 }
00247
00249
00250
00251 typedef SubroutineRef::fun_iterator fun_iterator;
00252 fun_iterator begin_functions() {
00253 return connective->begin_functions();
00254 }
00255 fun_iterator end_functions() {
00256 return connective->end_functions();
00257 }
00258
00259 typedef SubroutineRef::const_fun_iterator const_fun_iterator;
00260 const_fun_iterator begin_functions() const {
00261 return connective->begin_functions();
00262 }
00263 const_fun_iterator end_functions() const {
00264 return connective->end_functions();
00265 }
00267
00268
00269 static bool classof(const FunctionCallExpr *node) { return true; }
00270 static bool classof(const Ast *node) {
00271 return node->getKind() == AST_FunctionCallExpr;
00272 }
00273
00274 private:
00275 void setTypeForConnective();
00276 };
00277
00278
00279
00280
00281
00282 class IndexedArrayExpr : public Expr {
00283
00284 public:
00285 IndexedArrayExpr(Expr *arrExpr, Expr **indices, unsigned numIndices);
00286
00289 Expr *getPrefix() { return indexedArray; }
00290 const Expr *getPrefix() const { return indexedArray; }
00292
00294 unsigned getNumIndices() const { return numIndices; }
00295
00298 Expr *getIndex(unsigned i) {
00299 assert(i < numIndices && "Index out of range!");
00300 return indexExprs[i];
00301 }
00302
00303 const Expr *getIndex(unsigned i) const {
00304 assert(i < numIndices && "Index out of range!");
00305 return indexExprs[i];
00306 }
00308
00312 typedef Expr **index_iterator;
00313 index_iterator begin_indices() { return &indexExprs[0]; }
00314 index_iterator end_indices() { return &indexExprs[numIndices]; }
00315
00316 typedef Expr *const *const_index_iterator;
00317 const_index_iterator begin_indices() const { return &indexExprs[0]; }
00318 const_index_iterator end_indices() const { return &indexExprs[numIndices]; }
00320
00321
00322 static bool classof(const IndexedArrayExpr *node) { return true; }
00323 static bool classof(const Ast *node) {
00324 return node->getKind() == AST_IndexedArrayExpr;
00325 }
00326
00327 private:
00331 Expr *indexedArray;
00332 unsigned numIndices;
00333 Expr **indexExprs;
00334 };
00335
00336
00337
00338
00340 class SelectedExpr : public Expr {
00341
00342 public:
00347 SelectedExpr(Expr *prefix, Decl *component, Location loc, Type *type)
00348 : Expr(AST_SelectedExpr, type, prefix->getLocation()),
00349 prefix(prefix), component(component), componentLoc(loc) { }
00350
00353 SelectedExpr(Expr *prefix, IdentifierInfo *component, Location loc)
00354 : Expr(AST_SelectedExpr, prefix->getLocation()),
00355 prefix(prefix), component(component), componentLoc(loc) { }
00356
00358 bool isAmbiguous() const { return component.is<IdentifierInfo*>(); }
00359
00361 void resolve(Decl *component, Type *type) {
00362 assert(isAmbiguous() && "SelectedExpr already resolved!");
00363 this->component = component;
00364 setType(type);
00365 }
00366
00368
00369 const Expr *getPrefix() const { return prefix; }
00370 Expr *getPrefix() { return prefix; }
00372
00374
00375
00376 const Decl *getSelectorDecl() const { return component.get<Decl*>(); }
00377 Decl *getSelectorDecl() { return component.get<Decl*>(); }
00379
00381 IdentifierInfo *getSelectorIdInfo() const {
00382 if (component.is<IdentifierInfo*>())
00383 return component.get<IdentifierInfo*>();
00384 else
00385 return component.get<Decl*>()->getIdInfo();
00386 }
00387
00389 Location getSelectorLoc() const { return componentLoc; }
00390
00391
00392 static bool classof(const SelectedExpr *node) { return true; }
00393 static bool classof(const Ast *node) {
00394 return node->getKind() == AST_SelectedExpr;
00395 }
00396
00397 private:
00398 typedef llvm::PointerUnion<Decl*, IdentifierInfo*> ComponentUnion;
00399
00400 Expr *prefix;
00401 ComponentUnion component;
00402 Location componentLoc;
00403 };
00404
00405
00406
00407
00408
00409 class InjExpr : public Expr {
00410
00411 public:
00412 InjExpr(Expr *argument, Type *resultType, Location loc)
00413 : Expr(AST_InjExpr, resultType, loc),
00414 operand(argument) { }
00415
00416 Expr *getOperand() { return operand; }
00417 const Expr *getOperand() const { return operand; }
00418
00419 static bool classof(const InjExpr *node) { return true; }
00420 static bool classof(const Ast *node) {
00421 return node->getKind() == AST_InjExpr;
00422 }
00423
00424 private:
00425 Expr *operand;
00426 };
00427
00428
00429
00430
00431
00432 class PrjExpr : public Expr {
00433
00434 public:
00435 PrjExpr(Expr *argument, DomainType *resultType, Location loc)
00436 : Expr(AST_PrjExpr, resultType, loc),
00437 operand(argument) { }
00438
00439 Expr *getOperand() { return operand; }
00440 const Expr *getOperand() const { return operand; }
00441
00442 static bool classof(const PrjExpr *node) { return true; }
00443 static bool classof(const Ast *node) {
00444 return node->getKind() == AST_PrjExpr;
00445 }
00446
00447 private:
00448 Expr *operand;
00449 };
00450
00451
00452
00453
00454 class IntegerLiteral : public Expr
00455 {
00456 public:
00459 IntegerLiteral(const llvm::APInt &value, Location loc)
00460 : Expr(AST_IntegerLiteral, UniversalType::getUniversalInteger(), loc),
00461 value(value) { }
00462
00464 IntegerLiteral(const llvm::APInt &value, IntegerType *type, Location loc)
00465 : Expr(AST_IntegerLiteral, type, loc), value(value) { }
00466
00468 bool isUniversalInteger() const {
00469 return llvm::isa<UniversalType>(getType());
00470 }
00471
00473
00474 const llvm::APInt &getValue() const { return value; }
00475 llvm::APInt &getValue() { return value; }
00477
00479 void setValue(const llvm::APInt &V) { value = V; }
00480
00481
00482 static bool classof(const IntegerLiteral *node) { return true; }
00483 static bool classof(const Ast *node) {
00484 return node->getKind() == AST_IntegerLiteral;
00485 }
00486
00487 private:
00488 llvm::APInt value;
00489 };
00490
00491
00492
00493
00494
00495
00496 class StringLiteral : public Expr
00497 {
00498 typedef llvm::SmallPtrSet<EnumerationDecl*, 4> InterpSet;
00499
00500 public:
00504 StringLiteral(const char *string, unsigned len, Location loc)
00505 : Expr(AST_StringLiteral, loc) {
00506 init(string, len);
00507 }
00508
00510 StringLiteral(const char *start, const char *end, Location loc)
00511 : Expr(AST_StringLiteral, loc) {
00512 init(start, end - start);
00513 }
00514
00516 ArrayType *getType() const {
00517 return llvm::cast<ArrayType>(Expr::getType());
00518 }
00519
00521 llvm::StringRef getString() const { return llvm::StringRef(rep, len); }
00522
00524 unsigned length() const { return len; }
00525
00532 bool addComponentType(EnumerationDecl *decl) {
00533 return interps.insert(decl);
00534 }
00535
00537 template <class I>
00538 void addComponentTypes(I start, I end) { interps.insert(start, end); }
00539
00546 bool removeComponentType(EnumerationDecl *decl) {
00547 return interps.erase(decl);
00548 }
00549
00557
00558 bool containsComponentType(EnumerationDecl *decl) const {
00559 return interps.count(decl);
00560 }
00561 bool containsComponentType(EnumerationType *type) const {
00562 return findComponent(type->getRootType()) != end_component_types();
00563 }
00565
00570
00571 bool resolveComponentType(EnumerationType *type);
00573
00575 unsigned numComponentTypes() const { return interps.size(); }
00576
00578 bool zeroComponentTypes() const { return numComponentTypes() == 0; }
00579
00581 const EnumerationDecl *getComponentType() const {
00582 if (numComponentTypes() != 1)
00583 return 0;
00584 return *begin_component_types();
00585 }
00586
00587
00589
00590 typedef InterpSet::iterator component_iterator;
00591 component_iterator begin_component_types() { return interps.begin(); }
00592 component_iterator end_component_types() { return interps.end(); }
00593
00594 typedef InterpSet::const_iterator const_component_iterator;
00595 const_component_iterator begin_component_types() const {
00596 return interps.begin();
00597 }
00598 const_component_iterator end_component_types() const {
00599 return interps.end();
00600 }
00602
00603
00604 static bool classof(const StringLiteral *node) { return true; }
00605 static bool classof(const Ast *node) {
00606 return node->getKind() == AST_StringLiteral;
00607 }
00608
00609 private:
00610 char *rep;
00611 unsigned len;
00612 InterpSet interps;
00613
00615 void init(const char *string, unsigned len);
00616
00619 const_component_iterator findComponent(EnumerationType *type) const;
00620 component_iterator findComponent(EnumerationType *type);
00621 };
00622
00623
00624
00625
00635 class NullExpr : public Expr {
00636
00637 public:
00638 NullExpr(Location loc, AccessType *target = 0)
00639 : Expr(AST_NullExpr, target, loc) { }
00640
00642
00643 const AccessType *getType() const {
00644 return llvm::cast<AccessType>(Expr::getType());
00645 }
00646 AccessType *getType() {
00647 return llvm::cast<AccessType>(Expr::getType());
00648 }
00650
00651
00652 static bool classof(const NullExpr *node) { return true; }
00653 static bool classof(const Ast *node) {
00654 return node->getKind() == AST_NullExpr;
00655 }
00656 };
00657
00658
00659
00660
00664 class QualifiedExpr : public Expr {
00665
00666 public:
00667 QualifiedExpr(TypeDecl *qualifier, Expr *operand, Location loc)
00668 : Expr(AST_QualifiedExpr, qualifier->getType(), loc),
00669 prefix(qualifier), operand(operand) { }
00670
00671 ~QualifiedExpr() { delete operand; }
00672
00674
00675 const TypeDecl *getPrefix() const { return prefix; }
00676 TypeDecl *getPrefix() { return prefix; }
00678
00680
00681 const Expr *getOperand() const { return operand; }
00682 Expr *getOperand() { return operand; }
00684
00685
00686 static bool classof(const QualifiedExpr *node) { return true; }
00687 static bool classof(const Ast *node) {
00688 return node->getKind() == AST_QualifiedExpr;
00689 }
00690
00691 private:
00692 TypeDecl *prefix;
00693 Expr *operand;
00694 };
00695
00696
00697
00698
00702 class DereferenceExpr : public Expr {
00703
00704 public:
00705 DereferenceExpr(Expr *prefix, Location loc, bool isImplicit = false);
00706
00707 ~DereferenceExpr() { delete prefix; }
00708
00710
00711 const Expr *getPrefix() const { return prefix; }
00712 Expr *getPrefix() { return prefix; }
00714
00716
00717 const AccessType *getPrefixType() const {
00718 return llvm::cast<AccessType>(prefix->getType());
00719 }
00720 AccessType *getPrefixType() {
00721 return llvm::cast<AccessType>(prefix->getType());
00722 }
00724
00727 bool isImplicit() const { return bits != 0; }
00728
00729
00730 static bool classof(const DereferenceExpr *node) { return true; }
00731 static bool classof(const Ast *node) {
00732 return node->getKind() == AST_DereferenceExpr;
00733 }
00734
00735 private:
00736 Expr *prefix;
00737 };
00738
00739
00740
00741
00742
00743 class ConversionExpr : public Expr
00744 {
00745 public:
00746 ConversionExpr(Expr *operand, Type *target, Location loc = 0)
00747 : Expr(AST_ConversionExpr, target, loc),
00748 operand(operand) { }
00749
00751 const Expr *getOperand() const { return operand; }
00752 Expr *getOperand() { return operand; }
00753
00754
00755 static bool classof(const ConversionExpr *node) { return true; }
00756 static bool classof(const Ast *node) {
00757 return node->getKind() == AST_ConversionExpr;
00758 }
00759
00760 private:
00761 Expr *operand;
00762 };
00763
00764
00765
00766
00779 class AllocatorExpr : public Expr {
00780
00781 public:
00783 AllocatorExpr(QualifiedExpr *operand, Location loc)
00784 : Expr(AST_AllocatorExpr, loc),
00785 operand(operand) { }
00786
00788 AllocatorExpr(PrimaryType *operand, Location loc)
00789 : Expr(AST_AllocatorExpr, loc),
00790 operand(operand) { }
00791
00793 bool isInitialized() const { return operand.is<Expr*>(); }
00794
00796 bool isUninitialized() const { return operand.is<PrimaryType*>(); }
00797
00799
00800
00801 const Expr *getInitializer() const { return operand.dyn_cast<Expr*>(); }
00802 Expr *getInitializer() { return operand.dyn_cast<Expr*>(); }
00804
00806
00807 const PrimaryType *getAllocatedType() const {
00808 return const_cast<AllocatorExpr*>(this)->getAllocatedType();
00809 }
00810 PrimaryType *getAllocatedType() {
00811 if (isInitialized())
00812 return llvm::cast<PrimaryType>(operand.get<Expr*>()->getType());
00813 else
00814 return operand.get<PrimaryType*>();
00815 }
00817
00819 void setInitializer(Expr *expr) { operand = expr; }
00820
00822
00823 const AccessType *getType() const {
00824 return llvm::cast<AccessType>(Expr::getType());
00825 }
00826 AccessType *getType() {
00827 return llvm::cast<AccessType>(Expr::getType());
00828 }
00830
00831
00832 static bool classof(const AllocatorExpr *node) { return true; }
00833 static bool classof(const Ast *node) {
00834 return node->getKind() == AST_AllocatorExpr;
00835 }
00836
00837 private:
00840 typedef llvm::PointerUnion<PrimaryType*, Expr*> OperandUnion;
00841 OperandUnion operand;
00842 };
00843
00844
00845
00846
00852 class DiamondExpr : public Expr {
00853
00854 public:
00855 DiamondExpr(Location loc, Type *type = 0)
00856 : Expr(AST_DiamondExpr, type, loc) { }
00857
00858
00859 static bool classof(const DiamondExpr *node) { return true; }
00860 static bool classof(const Ast *node) {
00861 return node->getKind() == AST_DiamondExpr;
00862 }
00863 };
00864
00865 }
00866
00867 #endif