00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef COMMA_TYPECHECK_TYPECHECK_HDR_GUARD
00010 #define COMMA_TYPECHECK_TYPECHECK_HDR_GUARD
00011
00012 #include "comma/basic/Diagnostic.h"
00013 #include "comma/basic/TextProvider.h"
00014 #include "comma/parser/Bridge.h"
00015 #include "comma/ast/AstBase.h"
00016 #include "comma/ast/Cunit.h"
00017 #include "comma/ast/Scope.h"
00018 #include "comma/ast/AstResource.h"
00019 #include "llvm/Support/Casting.h"
00020 #include <iosfwd>
00021
00022 namespace comma {
00023
00024 class TypeCheck : public Bridge {
00025
00026 public:
00027 TypeCheck(Diagnostic &diag,
00028 AstResource &resource,
00029 CompilationUnit *cunit);
00030
00031 ~TypeCheck();
00032
00033 void beginSignatureDefinition(IdentifierInfo *name, Location location);
00034 void beginDomainDefinition(IdentifierInfo *name, Location location);
00035 void endModelDefinition();
00036
00037
00038
00039
00040 Node acceptModelParameter(IdentifierInfo *formal, Node type, Location loc);
00041
00042
00043
00044 void acceptModelParameterList(Node *params, Location *locs, unsigned arity);
00045
00046
00047
00048 Node acceptModelSupersignature(Node typeNode, Location loc);
00049
00050
00051
00052 void acceptModelSupersignatureList(Node *sigs, unsigned numSigs);
00053
00054 Node acceptSignatureComponent(IdentifierInfo *name,
00055 Node typeNode, Location loc);
00056
00057 void acceptSignatureComponentList(Node *components,
00058 unsigned numComponents);
00059
00060 Node acceptPercent(Location loc);
00061
00062 Node acceptTypeIdentifier(IdentifierInfo *info, Location loc);
00063
00064 Node acceptTypeApplication(IdentifierInfo *connective,
00065 Node *arguments,
00066 Location *argumentLocs,
00067 unsigned numArgs,
00068 IdentifierInfo **selectors,
00069 Location *selectorLocs,
00070 unsigned numSelectors,
00071 Location loc);
00072
00073 Node acceptFunctionType(IdentifierInfo **formals,
00074 Location *formalLocations,
00075 Node *types,
00076 Location *typeLocations,
00077 unsigned arity,
00078 Node returnType,
00079 Location returnLocation);
00080
00081
00082 void deleteNode(Node node);
00083
00084 private:
00085 Diagnostic &diagnostic;
00086 AstResource &resource;
00087 CompilationUnit *compUnit;
00088
00089
00090
00091 template <class T>
00092 static T *lift(Node &node) {
00093 return llvm::dyn_cast_or_null<T>(Node::lift<Ast>(node));
00094 }
00095
00096 struct ModelInfo {
00097 Ast::AstKind kind;
00098 IdentifierInfo *name;
00099 Location location;
00100 ModelDecl *decl;
00101
00102 ModelInfo(Ast::AstKind kind, IdentifierInfo *name, Location loc)
00103 : kind(kind), name(name), location(loc), decl(0) { }
00104 };
00105
00106 ModelInfo *currentModelInfo;
00107
00108 ModelDecl *getCurrentModel() const {
00109 return currentModelInfo->decl;
00110 }
00111
00112 Sigoid *getCurrentSignature() const;
00113
00114
00115
00116
00117 Scope *topScope;
00118 Scope *currentScope;
00119
00120 unsigned errorCount;
00121
00122 CompilationUnit *currentCompUnit() const { return compUnit; }
00123
00124 Scope::ScopeKind currentScopeKind() const {
00125 return currentScope->getKind();
00126 }
00127
00128 void pushModelScope() {
00129 currentScope = currentScope->pushScope(Scope::MODEL_SCOPE);
00130 }
00131
00132 void popModelScope() {
00133 popScope();
00134 }
00135
00136 void popScope() {
00137
00138
00139 Scope *parent = currentScope->popScope();
00140 delete currentScope;
00141 currentScope = parent;
00142 }
00143
00144
00145
00146
00147
00148 void addType(ModelType *type) {
00149 currentScope->addType(type);
00150 }
00151
00152 ModelType *lookupType(IdentifierInfo *info, bool traverse = true) {
00153 return currentScope->lookupType(info, traverse);
00154 }
00155
00156
00157
00158
00159
00160 void ensureNecessaryRedeclarations(Sigoid *sig);
00161
00162 DomainType *ensureDomainType(Node typeNode, Location loc) const;
00163
00164 static SignatureType *resolveArgumentType(ParameterizedType *target,
00165 DomainType **actuals,
00166 unsigned numActuals);
00167
00168 bool has(DomainType *source, SignatureType *target);
00169 bool has(ConcreteDomainType *source, SignatureType *target);
00170 bool has(AbstractDomainType *source, SignatureType *target);
00171 bool has(PercentType *source, SignatureType *target);
00172
00173 DiagnosticStream &report(Location loc, diag::Kind kind) const {
00174 SourceLocation sloc = resource.getTextProvider().getSourceLocation(loc);
00175 return diagnostic.report(sloc, kind);
00176 }
00177 };
00178
00179 }
00180
00181 #endif