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 //===-- ast/Expr.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_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 // Expr 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 // Support isa/dyn_cast. 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 // DeclRefExpr 00153 // 00154 // Represents references to declarations in the source code. 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 // Support isa/dyn_cast. 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 // FunctionCallExpr 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 // Support isa and dyn_cast. 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 // IndexedArrayExpr 00280 // 00281 // Represents the indexing into an array expression. 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 // Support isa and dyn_cast. 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 // SelectedExpr 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 // Support isa/dyn_cast. 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 // InjExpr 00407 // 00408 // Represents "inj" expressions, mapping domain types to their carrier types. 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 // PrjExpr 00430 // 00431 // Represents "prj" expressions, mapping carrier types to their domains. 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 // IntegerLiteral 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 // Suppport isa/dyn_cast. 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 // StringLiteral 00493 // 00494 // Initially, strings are constructed without a known type, as they are 00495 // overloaded objects. 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 // Support isa and dyn_cast. 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 // NullExpr 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 // Support isa/dyn_cast; 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 // QualifiedExpr 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 // Support isa/dyn_cast. 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 // DereferenceExpr 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 // Support isa/dyn_cast. 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 // ConversionExpr 00741 // 00742 // These nodes represent type conversions. 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 // Support isa and dyn_cast. 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 // AllocatorExpr 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 // Support isa/dyn_cast. 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 // DiamondExpr 00846 // 00852 class DiamondExpr : public Expr { 00853 00854 public: 00855 DiamondExpr(Location loc, Type *type = 0) 00856 : Expr(AST_DiamondExpr, type, loc) { } 00857 00858 // Support isa/dyn_cast. 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 } // End comma namespace. 00866 00867 #endif