00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "comma/typecheck/TypeCheck.h"
00010 #include "comma/ast/Type.h"
00011 #include "comma/ast/Decl.h"
00012 #include "TypeEqual.h"
00013 #include <map>
00014
00015 using namespace comma;
00016 using llvm::dyn_cast;
00017 using llvm::isa;
00018
00019 namespace {
00020
00021
00022
00023 bool hasExactSignature(Sigoid *source, SignatureType *target)
00024 {
00025 Sigoid::sig_iterator iter = source->beginSupers();
00026 Sigoid::sig_iterator endIter = source->endSupers();
00027
00028 for ( ; iter != endIter; ++iter)
00029 if (*iter == target) return true;
00030 return false;
00031 }
00032
00033 }
00034
00035 bool TypeCheck::has(ConcreteDomainType *source, SignatureType *target)
00036 {
00037 Domoid *domoid = source->getDomoid();
00038 SignatureDecl *principleSignature = domoid->getPrincipleSignature();
00039
00040 SignatureDecl::sig_iterator iter = principleSignature->beginSupers();
00041 SignatureDecl::sig_iterator endIter = principleSignature->endSupers();
00042 AstRewriter rewrites;
00043
00044 rewrites.installRewrites(source);
00045 for ( ; iter != endIter; ++iter) {
00046 SignatureType *candidate = *iter;
00047 if (compareTypesUsingRewrites(rewrites, candidate, target))
00048 return true;
00049 }
00050 return false;
00051 }
00052
00053 bool TypeCheck::has(AbstractDomainType *source, SignatureType *target)
00054 {
00055 AstRewriter rewrites;
00056 SignatureType *signature = source->getSignature();
00057 Sigoid *sigoid = signature->getDeclaration();
00058
00059 if (signature == target) return true;
00060
00061
00062
00063
00064
00065
00066
00067 rewrites.installRewrites(source);
00068 rewrites.installRewrites(signature);
00069
00070 Sigoid::sig_iterator iter = sigoid->beginSupers();
00071 Sigoid::sig_iterator endIter = sigoid->endSupers();
00072 for ( ; iter != endIter; ++iter) {
00073 SignatureType *candidate = *iter;
00074 if (compareTypesUsingRewrites(rewrites, candidate, target))
00075 return true;
00076 }
00077 return false;
00078 }
00079
00080 bool TypeCheck::has(PercentType *source, SignatureType *target)
00081 {
00082 ModelDecl *model = source->getDeclaration();
00083
00084 if (Sigoid *sigoid = dyn_cast<Sigoid>(model)) {
00085
00086
00087
00088
00089 if (SignatureDecl *signature = dyn_cast<SignatureDecl>(sigoid)) {
00090 if (signature == target->getDeclaration())
00091 return true;
00092 }
00093 else {
00094
00095
00096 VarietyDecl *variety = dyn_cast<VarietyDecl>(sigoid);
00097 if (variety == target->getDeclaration()) {
00098 bool matchFound = true;
00099 unsigned arity = variety->getArity();
00100 for (unsigned i = 0; i < arity; ++i) {
00101 DomainType *actual = target->getActualParameter(i);
00102 DomainType *formal = variety->getFormalDomain(i);
00103 if (actual != formal) {
00104 matchFound = false;
00105 break;
00106 }
00107 }
00108 if (matchFound) return true;
00109 }
00110 }
00111
00112
00113
00114 return hasExactSignature(sigoid, target);
00115 }
00116
00117
00118
00119 Domoid *domoid = source->getDomoid();
00120 SignatureDecl *principleSig = domoid->getPrincipleSignature();
00121 return hasExactSignature(principleSig, target);
00122 }
00123
00124 bool TypeCheck::has(DomainType *source, SignatureType *target)
00125 {
00126 if (ConcreteDomainType *domain = dyn_cast<ConcreteDomainType>(source))
00127 return has(domain, target);
00128
00129 if (AbstractDomainType *domain = dyn_cast<AbstractDomainType>(source))
00130 return has(domain, target);
00131
00132 return has(dyn_cast<PercentType>(source), target);
00133 }