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