00001
00002
00003
00004
00005
00006
00007
00008
00009
00013
00014
00015 #include "Scope.h"
00016 #include "TypeCheck.h"
00017 #include "comma/ast/Decl.h"
00018 #include "comma/ast/DeclRewriter.h"
00019 #include "comma/ast/TypeRef.h"
00020
00021 #include "llvm/ADT/DenseMap.h"
00022
00023 using namespace comma;
00024 using llvm::dyn_cast;
00025 using llvm::dyn_cast_or_null;
00026 using llvm::cast;
00027 using llvm::isa;
00028
00029 void TypeCheck::beginCapsule()
00030 {
00031 assert(scope.getLevel() == 0 && "Cannot typecheck nested capsules!");
00032
00033
00034 scope.push(MODEL_SCOPE);
00035 GenericFormalDecls.clear();
00036 declarativeRegion = 0;
00037 currentModel = 0;
00038 }
00039
00040 void TypeCheck::endCapsule()
00041 {
00042 if (Domoid *domoid = getCurrentDomoid())
00043 ensureExportConstraints(domoid->getImplementation());
00044
00045 assert(scope.getKind() == MODEL_SCOPE);
00046 scope.pop();
00047
00048 ModelDecl *result = getCurrentModel();
00049 if (Decl *conflict = scope.addDirectDecl(result)) {
00050
00051 report(result->getLocation(), diag::CONFLICTING_DECLARATION)
00052 << result->getIdInfo() << getSourceLoc(conflict->getLocation());
00053 }
00054 else {
00055
00056 if (Domoid *domoid = dyn_cast<Domoid>(result))
00057 domoid->finalize();
00058 compUnit->addDeclaration(result);
00059 }
00060 }
00061
00062 void TypeCheck::beginGenericFormals()
00063 {
00064 assert(GenericFormalDecls.empty() && "Formal decls already present!");
00065 }
00066
00067 void TypeCheck::endGenericFormals() { }
00068
00069 void TypeCheck::acceptFormalDomain(IdentifierInfo *name, Location loc,
00070 Node sigNode)
00071 {
00072 AbstractDomainDecl *decl;
00073
00074 if (sigNode.isNull())
00075 decl = new AbstractDomainDecl(resource, name, loc);
00076 else {
00077 TypeRef *ref = lift_node<TypeRef>(sigNode);
00078
00079 if (!ref || !ref->referencesSigInstance()) {
00080 report(getNodeLoc(sigNode), diag::NOT_A_SIGNATURE);
00081 return;
00082 }
00083
00084 sigNode.release();
00085 delete ref;
00086 SigInstanceDecl *sig = ref->getSigInstanceDecl();
00087 decl = new AbstractDomainDecl(resource, name, loc, sig);
00088 }
00089
00090
00091 if (scope.addDirectDecl(decl)) {
00092
00093
00094 report(loc, diag::DUPLICATE_FORMAL_PARAM) << name;
00095 delete decl;
00096 }
00097 else
00098 GenericFormalDecls.push_back(decl);
00099 }
00100
00101 void TypeCheck::beginDomainDecl(IdentifierInfo *name, Location loc)
00102 {
00103
00104
00105 unsigned arity = GenericFormalDecls.size();
00106
00107 if (arity == 0)
00108 currentModel = new DomainDecl(resource, name, loc);
00109 else
00110 currentModel = new FunctorDecl(resource, name, loc,
00111 &GenericFormalDecls[0], arity);
00112 initializeForModelDeclaration();
00113 }
00114
00115 void TypeCheck::beginSignatureDecl(IdentifierInfo *name, Location loc)
00116 {
00117
00118
00119 unsigned arity = GenericFormalDecls.size();
00120
00121 if (arity == 0)
00122 currentModel = new SignatureDecl(resource, name, loc);
00123 else
00124 currentModel = new VarietyDecl(resource, name, loc,
00125 &GenericFormalDecls[0], arity);
00126 initializeForModelDeclaration();
00127 }
00128
00129 void TypeCheck::initializeForModelDeclaration()
00130 {
00131 assert(scope.getKind() == MODEL_SCOPE);
00132
00133
00134
00135 declarativeRegion = currentModel->getPercent();
00136
00137
00138
00139 unsigned arity = currentModel->getArity();
00140 for (unsigned i = 0; i < arity; ++i) {
00141 AbstractDomainDecl *formal = currentModel->getFormalDecl(i);
00142 formal->setDeclRegion(declarativeRegion);
00143 }
00144
00145
00146
00147 scope.addDirectDeclNoConflicts(currentModel);
00148 }
00149
00150 void TypeCheck::acceptSupersignature(Node typeNode)
00151 {
00152 TypeRef *ref = cast_node<TypeRef>(typeNode);
00153 Location loc = ref->getLocation();
00154 SigInstanceDecl *superSig = ref->getSigInstanceDecl();
00155
00156
00157 if (!superSig) {
00158 report(loc, diag::NOT_A_SIGNATURE);
00159 return;
00160 }
00161
00162 getCurrentModel()->addDirectSignature(superSig);
00163
00164
00165
00166 acquireSignatureDeclarations(superSig, loc);
00167 }
00168
00169 void TypeCheck::beginSignatureProfile()
00170 {
00171
00172
00173
00174 }
00175
00176 void TypeCheck::endSignatureProfile()
00177 {
00178 DomainTypeDecl *domain;
00179
00180
00181
00182 if (ModelDecl *model = getCurrentModel())
00183 domain = model->getPercent();
00184 else
00185 domain = cast<AbstractDomainDecl>(declarativeRegion);
00186 }
00187
00188 void TypeCheck::acquireImplicitDeclarations(Decl *decl)
00189 {
00190 typedef DeclRegion::DeclIter iterator;
00191 DeclRegion *region = 0;
00192
00193
00194
00195 if (EnumerationDecl *eDecl = dyn_cast<EnumerationDecl>(decl))
00196 region = eDecl;
00197 else if (IntegerDecl *iDecl = dyn_cast<IntegerDecl>(decl))
00198 region = iDecl;
00199 else
00200 return;
00201
00202 iterator E = region->endDecls();
00203 for (iterator I = region->beginDecls(); I != E; ++I)
00204 scope.addDirectDeclNoConflicts(*I);
00205 }
00206
00207 void TypeCheck::acquireSignatureDeclarations(SigInstanceDecl *sig, Location loc)
00208 {
00209 typedef DeclRegion::DeclIter iterator;
00210 PercentDecl *sigPercent = sig->getSigoid()->getPercent();
00211 DeclRewriter rewrites(resource, declarativeRegion, sigPercent);
00212
00213
00214
00215
00216 rewrites.installRewrites(sig);
00217 rewrites.addTypeRewrite(sigPercent->getType(), getCurrentPercentType());
00218
00219 iterator E = sigPercent->endDecls();
00220 for (iterator I = sigPercent->beginDecls(); I != E; ++I) {
00221
00222
00223 Decl *candidate = rewrites.rewriteDecl(*I);
00224
00225
00226 if (Decl *conflict = scope.addDirectDecl(candidate)) {
00227
00228
00229
00230
00231 conflict = conflict->resolveOrigin();
00232 candidate = candidate->resolveOrigin();
00233
00234
00235
00236
00237
00238 report(loc, diag::CONFLICTING_SIGNATURE_INCLUSION)
00239 << sig->getIdInfo();
00240
00241
00242 SourceLocation sloc = getSourceLoc(conflict->getLocation());
00243 report(candidate->getLocation(), diag::DECLARATION_CONFLICTS)
00244 << candidate->getIdInfo() << sloc;
00245 }
00246 else {
00247
00248
00249 acquireImplicitDeclarations(candidate);
00250 declarativeRegion->addDecl(candidate);
00251 }
00252 }
00253 }
00254
00255 void TypeCheck::beginAddExpression()
00256 {
00257 Domoid *domoid = getCurrentDomoid();
00258 assert(domoid && "Processing `add' expression outside domain context!");
00259
00260
00261 declarativeRegion = domoid->getImplementation();
00262 assert(declarativeRegion && "Domain missing Add declaration node!");
00263 }
00264
00265 void TypeCheck::endAddExpression()
00266 {
00267
00268
00269 declarativeRegion = declarativeRegion->getParent();
00270 assert(declarativeRegion == getCurrentPercent()->asDeclRegion());
00271 }
00272
00273 void TypeCheck::acceptCarrier(IdentifierInfo *name, Location loc, Node typeNode)
00274 {
00275
00276 AddDecl *add = cast<AddDecl>(declarativeRegion);
00277
00278 if (add->hasCarrier()) {
00279 report(loc, diag::MULTIPLE_CARRIER_DECLARATIONS);
00280 return;
00281 }
00282
00283 TypeDecl *tyDecl = ensureCompleteTypeDecl(typeNode);
00284
00285 if (!tyDecl)
00286 return;
00287
00288 if (tyDecl->getType()->involvesPercent()) {
00289 report(loc, diag::SELF_RECURSIVE_TYPE_DECLARATION);
00290 return;
00291 }
00292
00293 CarrierDecl *carrier;
00294 carrier = new CarrierDecl(resource, name, tyDecl->getType(), loc);
00295 if (Decl *conflict = scope.addDirectDecl(carrier)) {
00296 report(loc, diag::CONFLICTING_DECLARATION)
00297 << name << getSourceLoc(conflict->getLocation());
00298 return;
00299 }
00300 add->setCarrier(carrier);
00301 }
00302
00303 bool TypeCheck::ensureExportConstraints(AddDecl *add)
00304 {
00305 Domoid *domoid = add->getImplementedDomoid();
00306 IdentifierInfo *domainName = domoid->getIdInfo();
00307 PercentDecl *percent = domoid->getPercent();
00308 Location domainLoc = domoid->getLocation();
00309
00310 bool allOK = true;
00311
00312
00313
00314
00315 for (DeclRegion::ConstDeclIter iter = percent->beginDecls();
00316 iter != percent->endDecls(); ++iter) {
00317
00318
00319 if (IncompleteTypeDecl *ITD = dyn_cast<IncompleteTypeDecl>(*iter)) {
00320 if (!ITD->hasCompletion()) {
00321 report(ITD->getLocation(), diag::MISSING_TYPE_COMPLETION)
00322 << ITD->getIdInfo();
00323 allOK=false;
00324 }
00325 continue;
00326 }
00327
00328
00329 SubroutineDecl *decl = dyn_cast<SubroutineDecl>(*iter);
00330
00331 if (!decl)
00332 continue;
00333
00334
00335
00336
00337
00338
00339
00340 if (!decl->getDefiningDeclaration()) {
00341 report(domainLoc, diag::MISSING_EXPORT)
00342 << domainName << decl->getIdInfo();
00343 allOK = false;
00344 }
00345 }
00346 return allOK;
00347 }