00001 //===-- typecheck/Has.cpp ------------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2008, Stephen Wilson 00006 // 00007 //===----------------------------------------------------------------------===// 00008 00009 00010 #include "TypeCheck.h" 00011 #include "comma/ast/AstRewriter.h" 00012 #include "comma/ast/Decl.h" 00013 #include "comma/ast/Type.h" 00014 00015 using namespace comma; 00016 using llvm::dyn_cast; 00017 using llvm::dyn_cast_or_null; 00018 using llvm::cast; 00019 using llvm::isa; 00020 00021 namespace { 00022 00023 bool percentHas(PercentDecl *source, SigInstanceDecl *target) 00024 { 00025 if (Sigoid *sigoid = dyn_cast<Sigoid>(source->getDefinition())) { 00026 // This % node corresponds to a signature declaration. If the 00027 // declaration is not parameterized, check if the target matches the 00028 // source declaration. That is to say, in the context of some signature 00029 // S, % certainly has S. 00030 if (SignatureDecl *signature = dyn_cast<SignatureDecl>(sigoid)) { 00031 if (signature == target->getSignature()) 00032 return true; 00033 } 00034 else { 00035 // When % is defined in the context of some variety V (X1 : T1, .., 00036 // Xn : Tn), check if the target corresponds to V(X1, .., Xn). 00037 VarietyDecl *variety = cast<VarietyDecl>(sigoid); 00038 if (variety == target->getVariety()) { 00039 bool matchFound = true; 00040 unsigned arity = variety->getArity(); 00041 for (unsigned i = 0; i < arity; ++i) { 00042 Type *actual = target->getActualParamType(i); 00043 DomainType *formal = variety->getFormalType(i); 00044 if (actual != formal) { 00045 matchFound = false; 00046 break; 00047 } 00048 } 00049 if (matchFound) return true; 00050 } 00051 } 00052 // Otherwise, an exact match on the target is sought against the set of 00053 // super signatures. No rewrites are needed since this test is wrt the 00054 // internal view of the signature. 00055 return sigoid->getSignatureSet().contains(target); 00056 } 00057 00058 // We do not have a signature, so we must have a domain. Since we are 00059 // asking if % has the given signature, we are working with the 'internal 00060 // view' of the domain and the super signature set does not require a 00061 // rewrite. 00062 Domoid *domoid = cast<Domoid>(source->getDefinition()); 00063 return domoid->getSignatureSet().contains(target); 00064 } 00065 00066 } // End anonymous namespace. 00067 00068 bool TypeCheck::has(DomainType *source, SigInstanceDecl *target) 00069 { 00070 if (PercentDecl *percent = source->getPercentDecl()) { 00071 return percentHas(percent, target); 00072 } 00073 00074 DomainTypeDecl *dom = source->getDomainTypeDecl(); 00075 const SignatureSet &sigset = dom->getSignatureSet(); 00076 SignatureSet::const_iterator iter = sigset.begin(); 00077 SignatureSet::const_iterator endIter = sigset.end(); 00078 00079 for ( ; iter != endIter; ++iter) { 00080 SigInstanceDecl *candidate = *iter; 00081 if (candidate == target) 00082 return true; 00083 } 00084 return false; 00085 } 00086 00087 bool TypeCheck::has(const AstRewriter &rewrites, 00088 DomainType *source, AbstractDomainDecl *target) 00089 { 00090 // If the target does not have a principle signature, the source domain 00091 // trivialy satisfies. 00092 if (!target->hasPrincipleSignature()) 00093 return true; 00094 00095 // Otherwise, the source domain must implement the principle signature of 00096 // the target. 00097 SigInstanceDecl *targetSig = target->getPrincipleSignature(); 00098 return has(source, rewrites.rewriteSigInstance(targetSig)); 00099 }