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