00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "comma/typecheck/TypeCheck.h"
00010 #include "comma/ast/Decl.h"
00011 #include "TypeEqual.h"
00012
00013 using namespace comma;
00014 using llvm::dyn_cast;
00015 using llvm::isa;
00016
00017 TypeCheck::TypeCheck(Diagnostic &diag,
00018 AstResource &resource,
00019 CompilationUnit *cunit)
00020 : diagnostic(diag),
00021 resource(resource),
00022 compUnit(cunit),
00023 errorCount(0)
00024 {
00025 topScope = new Scope();
00026 currentScope = topScope;
00027 }
00028
00029 TypeCheck::~TypeCheck()
00030 {
00031 delete topScope;
00032 }
00033
00034 void TypeCheck::deleteNode(Node node)
00035 {
00036 Ast *ast = Node::lift<Ast>(node);
00037 if (ast && ast->isDeletable()) delete ast;
00038 }
00039
00040 void TypeCheck::beginSignatureDefinition(IdentifierInfo *name,
00041 Location loc)
00042 {
00043 currentModelInfo = new ModelInfo(Ast::AST_SignatureDecl, name, loc);
00044 pushModelScope();
00045 }
00046
00047 void TypeCheck::beginDomainDefinition(IdentifierInfo *name,
00048 Location loc)
00049 {
00050 currentModelInfo = new ModelInfo(Ast::AST_DomainDecl, name, loc);
00051 pushModelScope();
00052 }
00053
00054 void TypeCheck::endModelDefinition()
00055 {
00056 ModelDecl *result = getCurrentModel();
00057 popModelScope();
00058 addType(result->getType());
00059 }
00060
00061 Node TypeCheck::acceptModelParameter(IdentifierInfo *formal,
00062 Node typeNode,
00063 Location loc)
00064 {
00065 ModelType *type = lift<ModelType>(typeNode);
00066
00067 assert(currentScopeKind() == Scope::MODEL_SCOPE);
00068 assert(type && "Bad node kind!");
00069
00070
00071
00072
00073
00074 if (SignatureType *sig = dyn_cast<SignatureType>(type)) {
00075
00076
00077
00078 if (lookupType(formal, false)) {
00079 report(loc, diag::DUPLICATE_FORMAL_PARAM) << formal->getString();
00080 return Node::getInvalidNode();
00081 }
00082 AbstractDomainType *dom = new AbstractDomainType(formal, sig);
00083 addType(dom);
00084 return Node(dom);
00085 }
00086 else {
00087 report(loc, diag::NOT_A_SIGNATURE) << formal->getString();
00088 getCurrentModel()->markInvalid();
00089 return Node::getInvalidNode();
00090 }
00091 }
00092
00093
00094 void TypeCheck::acceptModelParameterList(Node *params,
00095 Location *paramLocs,
00096 unsigned arity)
00097 {
00098 llvm::SmallVector<AbstractDomainType*, 4> domains;
00099
00100
00101 for (unsigned i = 0; i < arity; ++i) {
00102 AbstractDomainType *domain = lift<AbstractDomainType>(params[i]);
00103 assert(domain && "Bad Node kind!");
00104 domains.push_back(domain);
00105 }
00106
00107
00108 assert(currentModelInfo->decl == 0);
00109 ModelDecl *modelDecl;
00110 IdentifierPool &idPool = resource.getIdentifierPool();
00111 IdentifierInfo *percent = &idPool.getIdentifierInfo("%");
00112 IdentifierInfo *name = currentModelInfo->name;
00113 Location loc = currentModelInfo->location;
00114 if (domains.empty()) {
00115 switch (currentModelInfo->kind) {
00116
00117 case Ast::AST_SignatureDecl:
00118 modelDecl = new SignatureDecl(percent, name, loc);
00119 break;
00120
00121 case Ast::AST_DomainDecl:
00122 modelDecl = new DomainDecl(percent, name, loc);
00123 break;
00124
00125 default:
00126 assert(false && "Corruption of currentModelInfo->kind!");
00127 }
00128 }
00129 else {
00130 AbstractDomainType **formals = &domains[0];
00131 switch (currentModelInfo->kind) {
00132
00133 case Ast::AST_SignatureDecl:
00134 currentModelInfo->kind = Ast::AST_VarietyDecl;
00135 modelDecl = new VarietyDecl(percent, name, loc, formals, arity);
00136 break;
00137
00138 case Ast::AST_DomainDecl:
00139 currentModelInfo->kind = Ast::AST_FunctorDecl;
00140 modelDecl = new FunctorDecl(percent, name, loc, formals, arity);
00141 break;
00142
00143 default:
00144 assert(false && "Corruption of currentModelInfo->kind!");
00145 }
00146 }
00147 currentModelInfo->decl = modelDecl;
00148 }
00149
00150 Node TypeCheck::acceptModelSupersignature(Node typeNode,
00151 Location loc)
00152 {
00153 ModelType *type = lift<ModelType>(typeNode);
00154 SignatureType *superSig;
00155 Sigoid *currentSig;
00156
00157 assert(type && "Bad node kind!");
00158
00159
00160 superSig = dyn_cast<SignatureType>(type);
00161 if (!superSig) {
00162 const char *name = type->getString();
00163 report(loc, diag::NOT_A_SIGNATURE) << name;
00164 delete type;
00165 return Node::getInvalidNode();
00166 }
00167
00168
00169 currentSig = getCurrentSignature();
00170 currentSig->addSupersignature(superSig);
00171
00172 return typeNode;
00173 }
00174
00175 void TypeCheck::acceptModelSupersignatureList(Node *sigs,
00176 unsigned numSigs)
00177 {
00178
00179 }
00180
00181 Node TypeCheck::acceptPercent(Location loc)
00182 {
00183 ModelDecl *model = getCurrentModel();
00184
00185 if (model == 0) {
00186 report(loc, diag::TYPE_NOT_VISIBLE) << "%";
00187 return Node::getInvalidNode();
00188 }
00189
00190 return Node(model->getPercent());
00191 }
00192
00193 Node TypeCheck::acceptTypeIdentifier(IdentifierInfo *id,
00194 Location loc)
00195 {
00196 ModelType *type = lookupType(id);
00197 const char *name = id->getString();
00198
00199 if (type == 0) {
00200 report(loc, diag::TYPE_NOT_VISIBLE) << name;
00201 return Node::getInvalidNode();
00202 }
00203 else if (isa<SignatureType>(type) || isa<DomainType>(type))
00204 return Node(type);
00205 else {
00206
00207 report(loc, diag::WRONG_NUM_ARGS_FOR_TYPE) << name;
00208 return Node::getInvalidNode();
00209 }
00210 }
00211
00212 Node TypeCheck::acceptTypeApplication(IdentifierInfo *connective,
00213 Node *argumentNodes,
00214 Location *argumentLocs,
00215 unsigned numArgs,
00216 IdentifierInfo **selectors,
00217 Location *selectorLocs,
00218 unsigned numSelectors,
00219 Location loc)
00220 {
00221 assert(numSelectors <= numArgs && "More selectors that arguments!");
00222
00223 ModelType *type = lookupType(connective);
00224 const char *name = connective->getString();
00225
00226 if (type == 0) {
00227 report(loc, diag::TYPE_NOT_VISIBLE) << name;
00228 return Node();
00229 }
00230
00231 ParameterizedType *candidate = dyn_cast<ParameterizedType>(type);
00232
00233 if (!candidate) {
00234 report(loc, diag::WRONG_NUM_ARGS_FOR_TYPE) << name;
00235 return Node::getInvalidNode();
00236 }
00237
00238 if (candidate->getArity() != numArgs) {
00239 report(loc, diag::WRONG_NUM_ARGS_FOR_TYPE) << name;
00240 return Node::getInvalidNode();
00241 }
00242
00243 unsigned numPositional = numArgs - numSelectors;
00244 llvm::SmallVector<DomainType*, 4> arguments(numArgs);
00245
00246
00247 for (unsigned i = 0; i < numPositional; ++i)
00248 arguments[i] = lift<DomainType>(argumentNodes[i]);
00249
00250
00251 for (unsigned i = 0; i < numSelectors; ++i) {
00252 IdentifierInfo *selector = selectors[i];
00253 Location selectorLoc = selectorLocs[i];
00254 int selectorIdx = candidate->getSelectorIndex(selector);
00255
00256
00257 if (selectorIdx < 0) {
00258 report(selectorLoc, diag::TYPE_HAS_NO_SUCH_SELECTOR)
00259 << selector->getString() << candidate->getString();
00260 return Node::getInvalidNode();
00261 }
00262
00263
00264
00265
00266 if ((unsigned)selectorIdx < numPositional) {
00267 report(selectorLoc, diag::SELECTED_PARAM_PROVIDED_POSITIONALLY)
00268 << selector->getString();
00269 return Node::getInvalidNode();
00270 }
00271
00272
00273
00274 for (unsigned j = 0; j < i; ++j) {
00275 if (selectors[j] == selector) {
00276 report(selectorLoc, diag::DUPLICATE_SELECTOR)
00277 << selector->getString();
00278 return Node::getInvalidNode();
00279 }
00280 }
00281
00282
00283
00284 DomainType *argument =
00285 lift<DomainType>(argumentNodes[i + numPositional]);
00286 arguments[selectorIdx] = argument;
00287 }
00288
00289
00290 for (unsigned i = 0; i < numArgs; ++i) {
00291 DomainType *argument = arguments[i];
00292 Location argLoc = argumentLocs[i];
00293 SignatureType *target =
00294 resolveArgumentType(candidate, &arguments[0], i);
00295
00296 if (!argument) {
00297 ModelType *model = lift<ModelType>(argumentNodes[i]);
00298 report(argLoc, diag::NOT_A_DOMAIN) << model->getString();
00299 return Node::getInvalidNode();
00300 }
00301
00302 if (!has(argument, target)) {
00303 report(argLoc, diag::DOES_NOT_SATISFY)
00304 << argument->getString() << target->getString();
00305 return Node::getInvalidNode();
00306 }
00307 }
00308
00309
00310 Node node;
00311 if (VarietyType *variety = dyn_cast<VarietyType>(candidate)) {
00312 VarietyDecl *decl = variety->getVarietyDecl();
00313 node = Node(decl->getCorrespondingType(&arguments[0], numArgs));
00314 }
00315 else {
00316 FunctorType *functor = dyn_cast<FunctorType>(candidate);
00317 assert(functor && "Corrupt hierarchy?");
00318 FunctorDecl *decl = functor->getFunctorDecl();
00319 node = Node(decl->getCorrespondingType(&arguments[0], numArgs));
00320 }
00321 return node;
00322 }
00323
00324 Node TypeCheck::acceptFunctionType(IdentifierInfo **formals,
00325 Location *formalLocations,
00326 Node *types,
00327 Location *typeLocations,
00328 unsigned arity,
00329 Node returnType,
00330 Location returnLocation)
00331 {
00332 llvm::SmallVector<DomainType*, 4> argumentTypes;
00333 DomainType *targetType;
00334 bool allOK = true;
00335
00336 for (unsigned i = 0; i < arity; ++i) {
00337 IdentifierInfo *formal = formals[i];
00338 Location formalLoc = formalLocations[i];
00339
00340
00341
00342 for (unsigned j = 0; j < i; ++j)
00343 if (formal == formals[j]) {
00344 allOK = false;
00345 report(formalLoc, diag::DUPLICATE_FORMAL_PARAM)
00346 << formal->getString();
00347 }
00348
00349
00350 DomainType *argumentType = ensureDomainType(types[i], typeLocations[i]);
00351 if (argumentType && allOK)
00352 argumentTypes.push_back(argumentType);
00353 }
00354
00355
00356 targetType = ensureDomainType(returnType, returnLocation);
00357
00358 if (targetType && allOK) {
00359 FunctionType *ftype =
00360 new FunctionType(&formals[0], &argumentTypes[0], arity, targetType);
00361 return Node(ftype);
00362 }
00363 return Node::getInvalidNode();
00364 }
00365
00366 Node TypeCheck::acceptSignatureComponent(IdentifierInfo *name,
00367 Node typeNode,
00368 Location loc)
00369 {
00370 Sigoid *sig = getCurrentSignature();
00371 FunctionType *ftype = lift<FunctionType>(typeNode);
00372
00373 assert(ftype && "Only function decls currently supported!");
00374
00375
00376 FunctionDecl *extantDecl = sig->findDirectComponent(name, ftype);
00377 if (extantDecl) {
00378 report(loc, diag::FUNCTION_REDECLARATION) << name->getString();
00379 return Node::getInvalidNode();
00380 }
00381
00382 PercentType *percent = sig->getPercent();
00383 FunctionDecl *fdecl = new FunctionDecl(name, ftype, percent, loc);
00384 sig->addComponent(fdecl);
00385 return Node(fdecl);
00386 }
00387
00388 void TypeCheck::acceptSignatureComponentList(Node *components,
00389 unsigned numComponents)
00390 {
00391
00392
00393 ensureNecessaryRedeclarations(getCurrentSignature());
00394 }
00395
00396
00397
00398
00399
00400 SignatureType *TypeCheck::resolveArgumentType(ParameterizedType *type,
00401 DomainType **actuals,
00402 unsigned numActuals)
00403 {
00404 AstRewriter rewriter;
00405
00406
00407
00408 for (unsigned i = 0; i < numActuals; ++i) {
00409 AbstractDomainType *formal = type->getFormalDomain(i);
00410 DomainType *actual = actuals[i];
00411 rewriter.addRewrite(formal, actual);
00412 }
00413
00414 SignatureType *target = type->getFormalType(numActuals);
00415 return rewriter.rewrite(target);
00416 }
00417
00418 Sigoid *TypeCheck::getCurrentSignature() const {
00419 Sigoid *result = dyn_cast<Sigoid>(getCurrentModel());
00420 if (result == 0) {
00421 Domoid *dom = dyn_cast<Domoid>(getCurrentModel());
00422 result = dom->getPrincipleSignature();
00423 }
00424 return result;
00425 }
00426
00427 DomainType *TypeCheck::ensureDomainType(Node node,
00428 Location loc) const
00429 {
00430 DomainType *dom = lift<DomainType>(node);
00431 if (!dom) {
00432 ModelType *model = lift<ModelType>(node);
00433 assert(model && "Bad node kind!");
00434 report(loc, diag::NOT_A_DOMAIN) << model->getString();
00435 return 0;
00436 }
00437 return dom;
00438 }
00439
00440 namespace {
00441
00442
00443
00444
00445
00446 FunctionDecl *findComponent(const AstRewriter &rewrites,
00447 Sigoid *sig,
00448 FunctionDecl *fdecl)
00449 {
00450 IdentifierInfo *name = fdecl->getIdInfo();
00451 FunctionType *targetType = fdecl->getFunctionType();
00452
00453 Sigoid::ComponentRange range = sig->findComponents(name);
00454 Sigoid::ComponentIter iter = range.first;
00455 for ( ; iter != range.second; ++iter) {
00456 FunctionType *sourceType = iter->second->getFunctionType();
00457 if (compareTypesUsingRewrites(rewrites, sourceType, targetType))
00458 return iter->second;
00459 }
00460 return 0;
00461 }
00462
00463 }
00464
00465 void TypeCheck::ensureNecessaryRedeclarations(Sigoid *sig)
00466 {
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476 typedef llvm::SmallPtrSet<FunctionDecl*, 4> BadDeclSet;
00477 BadDeclSet badDecls;
00478
00479 Sigoid::sig_iterator superIter = sig->beginDirectSupers();
00480 Sigoid::sig_iterator endSuperIter = sig->endDirectSupers();
00481 for ( ; superIter != endSuperIter; ++superIter) {
00482 SignatureType *super = *superIter;
00483 Sigoid *sigdecl = super->getDeclaration();
00484 AstRewriter rewrites;
00485
00486 rewrites[sigdecl->getPercent()] = sig->getPercent();
00487 rewrites.installRewrites(super);
00488
00489 Sigoid::ComponentIter iter = sigdecl->beginComponents();
00490 Sigoid::ComponentIter endIter = sigdecl->endComponents();
00491 for ( ; iter != endIter; ++iter) {
00492 IdentifierInfo *name = iter->first;
00493 FunctionDecl *fdecl = iter->second;
00494 FunctionType *ftype = fdecl->getFunctionType();
00495 FunctionDecl *component = findComponent(rewrites, sig, fdecl);
00496
00497 if (component) {
00498 FunctionType *componentType = component->getFunctionType();
00499
00500
00501
00502
00503 if (!component->isTypeContext(sig->getPercent()) &&
00504 !componentType->selectorsMatch(ftype)) {
00505 Location loc = component->getLocation();
00506 report(loc, diag::MISSING_REDECLARATION)
00507 << component->getString();
00508 badDecls.insert(component);
00509 }
00510 }
00511 else {
00512
00513 FunctionType *rewriteType = rewrites.rewrite(ftype);
00514 FunctionDecl *rewriteDecl =
00515 new FunctionDecl(name, rewriteType, super, 0);
00516 sig->addComponent(rewriteDecl);
00517 }
00518 }
00519
00520
00521
00522 for (BadDeclSet::iterator iter = badDecls.begin();
00523 iter != badDecls.end();
00524 ++iter) {
00525 FunctionDecl *badDecl = *iter;
00526 sig->removeComponent(badDecl);
00527 delete badDecl;
00528 }
00529 }
00530 }