00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #ifndef COMMA_TYPECHECK_TYPECHECK_HDR_GUARD
00010 #define COMMA_TYPECHECK_TYPECHECK_HDR_GUARD
00011 
00012 
00013 #include "Scope.h"
00014 #include "Stencil.h"
00015 #include "comma/ast/AstBase.h"
00016 #include "comma/ast/AstResource.h"
00017 #include "comma/ast/Cunit.h"
00018 #include "comma/ast/Type.h"
00019 #include "comma/basic/Diagnostic.h"
00020 #include "comma/basic/TextProvider.h"
00021 #include "comma/typecheck/Checker.h"
00022 
00023 #include "llvm/Support/Casting.h"
00024 
00025 #include <stack>
00026 
00027 namespace llvm {
00028 
00029 class APInt;
00030 
00031 } 
00032 
00033 namespace comma {
00034 
00035 class TypeCheck : public Checker {
00036 
00037 public:
00038     TypeCheck(Diagnostic      &diag,
00039               AstResource     &resource,
00040               CompilationUnit *cunit);
00041 
00042     ~TypeCheck();
00043 
00049 
00050     void beginCapsule();
00051     void endCapsule();
00052 
00053     void beginGenericFormals();
00054     void endGenericFormals();
00055 
00056     void acceptFormalDomain(IdentifierInfo *name, Location loc, Node sig);
00057 
00058     void beginDomainDecl(IdentifierInfo *name, Location loc);
00059     void beginSignatureDecl(IdentifierInfo *name, Location loc);
00060 
00061     void beginSignatureProfile();
00062     void endSignatureProfile();
00063 
00064     void acceptSupersignature(Node typeNode);
00065 
00066     void beginAddExpression();
00067     void endAddExpression();
00068 
00069     void acceptCarrier(IdentifierInfo *name, Location loc, Node typeNode);
00070 
00071     void beginFunctionDeclaration(IdentifierInfo *name, Location loc);
00072     void beginProcedureDeclaration(IdentifierInfo *name, Location loc);
00073 
00074 
00075     void acceptSubroutineParameter(IdentifierInfo *formal, Location loc,
00076                                    Node typeNode, PM::ParameterMode mode);
00077 
00078     void acceptFunctionReturnType(Node typeNode);
00079 
00080     Node endSubroutineDeclaration(bool definitionFollows);
00081 
00082     Node beginSubroutineDefinition(Node declarationNode);
00083     void endSubroutineBody(Node contextNode);
00084     void endSubroutineDefinition();
00085 
00086     Node acceptDirectName(IdentifierInfo *name, Location loc,
00087                           bool forStatement);
00088 
00089     Node acceptCharacterLiteral(IdentifierInfo *lit, Location loc);
00090 
00091     Node acceptSelectedComponent(Node prefix,
00092                                  IdentifierInfo *name,
00093                                  Location loc,
00094                                  bool forStatement);
00095 
00096     Node acceptParameterAssociation(IdentifierInfo *key,
00097                                     Location loc, Node rhs);
00098 
00099     Node acceptApplication(Node prefix, NodeVector &argNodes);
00100 
00101     Node acceptAttribute(Node prefix, IdentifierInfo *name, Location loc);
00102 
00103     Node finishName(Node name);
00104 
00105     void beginAggregate(Location loc);
00106     void acceptPositionalAggregateComponent(Node component);
00107     Node acceptAggregateKey(Node lower, Node upper);
00108     Node acceptAggregateKey(IdentifierInfo *name, Location loc);
00109     Node acceptAggregateKey(Node key);
00110     void acceptKeyedAggregateComponent(NodeVector &keys,
00111                                        Node expr, Location loc);
00112     void acceptAggregateOthers(Location loc, Node component);
00113     Node endAggregate();
00114 
00115     Node beginForStmt(Location loc, IdentifierInfo *iterName, Location iterLoc,
00116                       Node control, bool isReversed);
00117     Node endForStmt(Node forNode, NodeVector &bodyNodes);
00118 
00119     Node acceptDSTDefinition(Node name, Node lower, Node upper);
00120     Node acceptDSTDefinition(Node nameOrAttribute, bool isUnconstrained);
00121     Node acceptDSTDefinition(Node lower, Node upper);
00122 
00123     bool acceptObjectDeclaration(Location loc, IdentifierInfo *name,
00124                                  Node type, Node initializer);
00125 
00126     bool acceptRenamedObjectDeclaration(Location loc, IdentifierInfo *name,
00127                                         Node type, Node target);
00128 
00129     void acceptDeclarationInitializer(Node declNode, Node initializer);
00130 
00131     Node acceptPercent(Location loc);
00132 
00133     bool acceptImportDeclaration(Node importedType);
00134 
00135     Node acceptProcedureCall(Node name);
00136 
00137     Node acceptInj(Location loc, Node expr);
00138 
00139     Node acceptPrj(Location loc, Node expr);
00140 
00141     Node acceptIntegerLiteral(llvm::APInt &value, Location loc);
00142 
00143     Node acceptStringLiteral(const char *string, unsigned len, Location loc);
00144 
00145     Node acceptNullExpr(Location loc);
00146 
00147     Node acceptAllocatorExpr(Node operand, Location loc);
00148 
00149     Node acceptQualifiedExpr(Node qualifier, Node operand);
00150 
00151     Node acceptDereference(Node prefix, Location loc);
00152 
00153     Node acceptIfStmt(Location loc, Node condition, NodeVector &consequents);
00154 
00155     Node acceptElseStmt(Location loc, Node ifNode, NodeVector &alternates);
00156 
00157     Node acceptElsifStmt(Location loc, Node ifNode, Node condition,
00158                          NodeVector &consequents);
00159 
00160     Node acceptEmptyReturnStmt(Location loc);
00161 
00162     Node acceptReturnStmt(Location loc, Node retNode);
00163 
00164     Node acceptAssignmentStmt(Node target, Node value);
00165 
00166     Node beginBlockStmt(Location loc, IdentifierInfo *label = 0);
00167     void endBlockStmt(Node block);
00168 
00169     Node beginHandlerStmt(Location loc, NodeVector &choices);
00170     void endHandlerStmt(Node context, Node handler);
00171 
00172     Node acceptNullStmt(Location loc);
00173 
00174     bool acceptStmt(Node context, Node stmt);
00175 
00176     Node acceptWhileStmt(Location loc, Node condition, NodeVector &stmtNodes);
00177 
00178     Node acceptLoopStmt(Location loc, NodeVector &stmtNodes);
00179 
00180     Node acceptRaiseStmt(Location loc, Node exception, Node message);
00181 
00182     Node acceptPragmaStmt(IdentifierInfo *name, Location loc, NodeVector &args);
00183 
00184     void acceptPragmaImport(Location pragmaLoc,
00185                             IdentifierInfo *convention, Location conventionLoc,
00186                             IdentifierInfo *entity, Location entityLoc,
00187                             Node externalNameNode);
00188 
00189     void beginEnumeration(IdentifierInfo *name, Location loc);
00190     void acceptEnumerationIdentifier(IdentifierInfo *name, Location loc);
00191     void acceptEnumerationCharacter(IdentifierInfo *name, Location loc);
00192     void endEnumeration();
00193 
00194     void acceptIntegerTypeDecl(IdentifierInfo *name, Location loc,
00195                                Node low, Node high);
00196 
00197     void acceptRangedSubtypeDecl(IdentifierInfo *name, Location loc,
00198                                  Node subtype, Node low, Node high);
00199 
00200     void acceptSubtypeDecl(IdentifierInfo *name, Location loc, Node subtype);
00201     void acceptIncompleteTypeDecl(IdentifierInfo *name, Location loc);
00202     void acceptAccessTypeDecl(IdentifierInfo *name, Location loc, Node subtype);
00203 
00204     void acceptArrayDecl(IdentifierInfo *name, Location loc,
00205                          NodeVector indices, Node component);
00206 
00207     void beginRecord(IdentifierInfo *name, Location loc);
00208     void acceptRecordComponent(IdentifierInfo *name, Location loc, Node type);
00209     void endRecord();
00210 
00211     
00212     void deleteNode(Node &node);
00214 
00217 
00218 
00221     bool checkSuccessful() const { return diagnostic.numErrors() == 0; }
00222 
00225     CompilationUnit *getCompilationUnit() const { return compUnit; }
00226 
00228     Diagnostic &getDiagnostic() { return diagnostic; }
00229 
00231     AstResource &getAstResource() { return resource; }
00233 
00235 
00236 
00239     static bool conversionRequired(Type *source, Type *target);
00240 
00242     static Expr *convertIfNeeded(Expr *expr, Type *target);
00243 
00246     Type *getCoveringDereference(Type *source, Type *target);
00247 
00250     Type *getCoveringDereference(Type *source, Type::Classification ID);
00251 
00257     Expr *implicitlyDereference(Expr *expr, Type *target);
00258 
00264     Expr *implicitlyDereference(Expr *expr, Type::Classification ID);
00265 
00271     Expr *checkExprInContext(Expr *expr, Type *context);
00272 
00276     bool checkExprInContext(Expr *expr, Type::Classification ID);
00277 
00283     Expr *checkExprAndDereferenceInContext(Expr *expr, Type *context);
00284 
00288     bool ensureStaticIntegerExpr(Expr *expr, llvm::APInt &result);
00289 
00292     bool ensureStaticIntegerExpr(Expr *expr);
00293 
00296     Expr *ensureExpr(Node node);
00297 
00300     Expr *ensureExpr(Ast *node);
00301 
00310     Ast *checkDirectName(IdentifierInfo *name, Location loc, bool forStatement);
00311 
00313     static bool covers(Type *A, Type *B);
00315 
00316 private:
00317     Diagnostic      &diagnostic;
00318     AstResource     &resource;
00319     CompilationUnit *compUnit;
00320     DeclRegion      *declarativeRegion;
00321     ModelDecl       *currentModel;
00322     Scope            scope;
00323 
00326     llvm::SmallVector<AbstractDomainDecl *, 8> GenericFormalDecls;
00327 
00329     EnumDeclStencil enumStencil;
00330     SRDeclStencil routineStencil;
00331 
00334     std::stack<AggregateExpr*> aggregateStack;
00335 
00338     template <class T>
00339     struct SVImpl {
00340         typedef llvm::SmallVectorImpl<T> Type;
00341     };
00342 
00343     
00344     
00345     
00346 
00347     
00348     
00349     template <class T>
00350     static T *lift_node(Node &node) {
00351         return llvm::dyn_cast_or_null<T>(Node::lift<Ast>(node));
00352     }
00353 
00354     
00355     
00356     template <class T>
00357     static T *cast_node(Node &node) {
00358         return llvm::cast<T>(Node::lift<Ast>(node));
00359     }
00360 
00361     
00362     template <class T>
00363     struct NodeLifter : public std::unary_function<Node&, T*> {
00364         T* operator ()(Node &node) const { return lift_node<T>(node); }
00365     };
00366 
00367     
00368     template <class T>
00369     struct NodeCaster : public std::unary_function<Node&, T*> {
00370         T* operator ()(Node &node) const { return cast_node<T>(node); }
00371     };
00372 
00373     DeclRegion *currentDeclarativeRegion() const {
00374         return declarativeRegion;
00375     }
00376 
00377     void pushDeclarativeRegion(DeclRegion *region) {
00378         declarativeRegion = region;
00379     }
00380 
00381     DeclRegion *popDeclarativeRegion() {
00382         DeclRegion *res = declarativeRegion;
00383         declarativeRegion = res->getParent();
00384         return res;
00385     }
00386 
00387     CompilationUnit *currentCompUnit() const { return compUnit; }
00388 
00389     ModelDecl *getCurrentModel() const {
00390         return currentModel;
00391     }
00392 
00393     
00394     
00395     Sigoid *getCurrentSigoid() const;
00396 
00397     
00398     
00399     SignatureDecl *getCurrentSignature() const;
00400 
00401     
00402     
00403     VarietyDecl *getCurrentVariety() const;
00404 
00405     
00406     
00407     Domoid *getCurrentDomoid() const;
00408 
00409     
00410     
00411     DomainDecl *getCurrentDomain() const;
00412 
00413     
00414     
00415     FunctorDecl *getCurrentFunctor() const;
00416 
00417     
00418     
00419     SubroutineDecl *getCurrentSubroutine() const;
00420 
00421     
00422     
00423     ProcedureDecl *getCurrentProcedure() const;
00424 
00425     
00426     FunctionDecl *getCurrentFunction() const;
00427 
00428     
00429     
00430     DomainType *getCurrentPercentType() const;
00431 
00432     
00433     
00434     PercentDecl *getCurrentPercent() const;
00435 
00436     
00437     bool checkingDomain() const { return getCurrentDomain() != 0; }
00438 
00439     
00440     bool checkingFunctor() const { return getCurrentFunctor() != 0; }
00441 
00442     
00443     bool checkingSignature() const { return getCurrentSignature() != 0; }
00444 
00445     
00446     bool checkingVariety() const { return getCurrentVariety() != 0; }
00447 
00448     
00449     bool checkingProcedure() const { return getCurrentProcedure() != 0; }
00450 
00451     
00452     bool checkingFunction() const { return getCurrentFunction() != 0; }
00453 
00454     
00455     
00456     
00457     void populateInitialEnvironment();
00458 
00463     void initializeForModelDeclaration();
00464 
00477     bool compatibleSubroutineDecls(SubroutineDecl *X, SubroutineDecl *Y);
00478 
00483     bool ensureNonRecursiveInstance(FunctorDecl *decl,
00484                                     DomainTypeDecl **args, unsigned numArgs,
00485                                     Location loc);
00486 
00488     void acquireImplicitDeclarations(Decl *decl);
00489 
00496     void acquireSignatureDeclarations(SigInstanceDecl *sig, Location loc);
00497 
00501     TypeDecl *ensureCompleteTypeDecl(Node refNode, bool report = true);
00502 
00514     TypeDecl *ensureCompleteTypeDecl(Decl *decl, Location loc,
00515                                      bool report = true);
00516 
00521     TypeDecl *ensureTypeDecl(Decl *decl, Location loc, bool report = true);
00522 
00526     TypeDecl *ensureTypeDecl(Node refNode, bool report = true);
00527 
00529     Type *resolveType(Type *type) const;
00530 
00532     Type *resolveType(Expr *expr) const { return resolveType(expr->getType()); }
00533 
00534     
00535     
00536     
00537     
00538     
00539     Expr *resolveIntegerLiteral(IntegerLiteral *intLit, Type *context);
00540 
00541     
00542     
00543     
00544     
00545     bool resolveIntegerLiteral(IntegerLiteral *intLit, Type::Classification ID);
00546 
00547     
00548     
00549     
00550     
00551     
00552     Expr *resolveStringLiteral(StringLiteral *strLit, Type *context);
00553 
00554     
00555     
00556     
00557     
00558     Expr *resolveAggregateExpr(AggregateExpr *agg, Type *context);
00559 
00560     
00561     
00562     
00563     Expr *resolveNullExpr(NullExpr *expr, Type *context);
00564 
00565     
00566     
00567     Expr *resolveAllocatorExpr(AllocatorExpr *alloc, Type *context);
00568 
00569     
00570     
00571     Expr *resolveSelectedExpr(SelectedExpr *select, Type *context);
00572 
00573     
00574     Expr *resolveDiamondExpr(DiamondExpr *diamond, Type *context);
00575 
00576     
00577     
00578     
00579     
00580     Expr *resolveFunctionCall(FunctionCallExpr *call, Type *type);
00581 
00582     
00583     
00584     
00585     bool resolveFunctionCall(FunctionCallExpr *call, Type::Classification ID);
00586 
00587     
00588     
00589     
00590     
00591     
00592     Expr *resolveFunctionCall(FunctionCallExpr *call, IdentifierInfo *selector,
00593                               Type *targetType);
00594 
00595     
00596     
00597     FunctionDecl *resolvePreferredConnective(FunctionCallExpr *Call,
00598                                              Type *targetType);
00599 
00600     
00601     
00602     
00603     FunctionDecl *resolvePreferredOperator(SVImpl<FunctionDecl*>::Type &decls);
00604 
00611     Ast *acceptSubroutineApplication(SubroutineRef *ref,
00612                                      NodeVector &argNodes);
00613 
00623     bool checkSubroutineArgumentNodes(NodeVector &argNodes,
00624                                       SVImpl<Expr*>::Type &positional,
00625                                       SVImpl<KeywordSelector*>::Type &keyed);
00626 
00631     Expr *checkSubroutineArgument(Expr *arg, Type *targetType,
00632                                   PM::ParameterMode targetMode);
00633 
00636     bool checkSubroutineCallArguments(SubroutineCall *call);
00637 
00647     bool checkSubroutineArguments(SubroutineDecl *decl,
00648                                   SVImpl<Expr*>::Type &posArgs,
00649                                   SVImpl<KeywordSelector*>::Type &keyArgs);
00650 
00653     bool routineAcceptsArgs(SubroutineDecl *decl,
00654                             SVImpl<Expr*>::Type &args);
00655 
00658     bool routineAcceptsArgs(SubroutineDecl *decl,
00659                             SVImpl<KeywordSelector*>::Type &args);
00660 
00667     Ast *acceptSubroutineCall(SubroutineRef *ref,
00668                               SVImpl<Expr*>::Type &positionalArgs,
00669                               SVImpl<KeywordSelector*>::Type &keyedArgs);
00670 
00677     SubroutineCall *
00678     checkSubroutineCall(SubroutineRef *ref,
00679                         SVImpl<Expr*>::Type &positionalArgs,
00680                         SVImpl<KeywordSelector*>::Type &keyArgs);
00681 
00683 
00689     bool checkApplicableArgument(Expr *expr, Type *targetType);
00690 
00691     
00692     
00693     
00694     
00695     
00696     
00697     bool checkSignatureProfile(const AstRewriter &rewrites, Type *source,
00698                                AbstractDomainDecl *target, Location loc);
00699 
00700     
00701     
00702     
00703     bool ensureExportConstraints(AddDecl *add);
00704 
00705     
00706     
00707     bool denotesDomainPercent(const Decl *decl);
00708 
00709     
00710     
00711     
00712     
00713     
00714     
00715     
00716     
00717     
00718     
00719     
00720     
00721     
00722     
00723     bool denotesFunctorPercent(const FunctorDecl *functor,
00724                                DomainTypeDecl **args, unsigned numArgs);
00725 
00733     SigInstanceDecl *resolveFormalSignature(ModelDecl *parameterizedModel,
00734                                             Type **arguments,
00735                                             unsigned numArguments);
00736 
00740     bool checkFunctionParameter(ParamValueDecl *param);
00741 
00745     bool acceptEnumerationLiteral(IdentifierInfo *name, Location loc);
00746 
00752     void introduceImplicitDecls(DeclRegion *region);
00753 
00755     TypeRef *buildTypeRefForModel(Location loc, ModelDecl *mdecl);
00756 
00759     Ast *checkIndirectName(Location loc, Resolver &resolver);
00760 
00765     TypeRef *acceptTypeApplication(TypeRef *ref, NodeVector &argNodes);
00766 
00771     TypeRef *acceptTypeApplication(TypeRef *ref,
00772                                    SVImpl<TypeRef *>::Type &posArgs,
00773                                    SVImpl<KeywordSelector *>::Type &keyedArgs);
00774 
00784     bool checkTypeArgumentNodes(NodeVector &argNodes,
00785                                 SVImpl<TypeRef*>::Type &positional,
00786                                 SVImpl<KeywordSelector*>::Type &keyed);
00787 
00793     DomainTypeDecl *ensureValidModelParam(TypeRef *ref);
00794 
00805     bool checkModelKeywordArgs(ModelDecl *model, unsigned numPositional,
00806                                SVImpl<KeywordSelector*>::Type &keyedArgs);
00807 
00815     bool checkModelArgs(ModelDecl *model,
00816                         SVImpl<DomainTypeDecl*>::Type &args,
00817                         SVImpl<Location>::Type &argLocs);
00818 
00831     bool introduceTypeDeclaration(TypeDecl *decl);
00832 
00840     IndexedArrayExpr *acceptIndexedArray(Expr *ref, NodeVector &argNodes);
00841 
00847     bool checkArrayIndexNodes(NodeVector &argNodes,
00848                               SVImpl<Expr*>::Type &indices);
00849 
00853     IndexedArrayExpr *acceptIndexedArray(Expr *ref,
00854                                          SVImpl<Expr*>::Type &indices);
00855 
00870     ObjectDecl *acceptArrayObjectDeclaration(Location loc, IdentifierInfo *name,
00871                                              ArrayDecl *arrDecl, Expr *init);
00872 
00875     ArrayType *getConstrainedArraySubtype(ArrayType *arrTy, Expr *init);
00876 
00880     Ast *finishSubroutineRef(SubroutineRef *ref);
00881 
00886     bool finishTypeRef(TypeRef *ref);
00887 
00890     Ast *processExpandedName(TypeRef *ref, IdentifierInfo *name, Location loc,
00891                              bool forStatement);
00892 
00895     Ast *processSelectedComponent(Expr *expr, IdentifierInfo *name,
00896                                   Location loc, bool forStatement);
00897 
00899     PragmaAssert *acceptPragmaAssert(Location loc, NodeVector &args);
00900 
00901     Ast *checkAttribute(attrib::AttributeID, Ast *prefix, Location loc);
00902 
00904     static Location getNodeLoc(Node node);
00905 
00906     bool has(DomainType *source, SigInstanceDecl *target);
00907     bool has(const AstRewriter &rewrites,
00908              DomainType *source, AbstractDomainDecl *target);
00909 
00910     SourceLocation getSourceLoc(Location loc) const {
00911         return resource.getTextProvider().getSourceLocation(loc);
00912     }
00913 
00914     DiagnosticStream &report(Location loc, diag::Kind kind) {
00915         return diagnostic.report(getSourceLoc(loc), kind);
00916     }
00917 };
00918 
00919 } 
00920 
00921 #endif