This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
00001 //===-- typecheck/Resolver.cpp -------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2009, Stephen Wilson 00006 // 00007 //===----------------------------------------------------------------------===// 00008 00009 #include "Homonym.h" 00010 #include "Resolver.h" 00011 00012 using namespace comma; 00013 using llvm::dyn_cast; 00014 using llvm::cast; 00015 using llvm::isa; 00016 00017 void Resolver::clear() 00018 { 00019 idInfo = 0; 00020 directDecl = 0; 00021 directOverloads.clear(); 00022 indirectValues.clear(); 00023 indirectTypes.clear(); 00024 indirectOverloads.clear(); 00025 indirectExceptions.clear(); 00026 } 00027 00028 bool Resolver::ArityPred::operator()(const Decl* decl) const { 00029 if (const SubroutineDecl *sdecl = dyn_cast<SubroutineDecl>(decl)) 00030 return sdecl->getArity() != arity; 00031 if (arity == 0) 00032 return !isa<EnumLiteral>(decl); 00033 return false; 00034 } 00035 00036 bool Resolver::NullaryPred::operator()(const Decl* decl) const { 00037 if (const SubroutineDecl *sdecl = dyn_cast<SubroutineDecl>(decl)) 00038 return sdecl->getArity() == 0; 00039 return true; 00040 } 00041 00042 unsigned Resolver::numResolvedDecls() const { 00043 unsigned result = 0; 00044 result += hasDirectValue(); 00045 result += hasDirectType(); 00046 result += numDirectOverloads(); 00047 result += numIndirectValues(); 00048 result += numIndirectTypes(); 00049 result += numIndirectOverloads(); 00050 result += numIndirectExceptions(); 00051 return result; 00052 } 00053 00054 bool Resolver::filterOverloadsWRTArity(unsigned arity) 00055 { 00056 return filterOverloads(ArityPred(arity)); 00057 } 00058 00059 bool Resolver::filterProcedures() 00060 { 00061 return filterOverloads(TypePred<ProcedureDecl>()); 00062 } 00063 00064 bool Resolver::filterFunctionals() 00065 { 00066 // FIXME: We should probably do this more efficiently. 00067 return filterOverloads(TypePred<FunctionDecl>()) || 00068 filterOverloads(TypePred<EnumLiteral>()); 00069 } 00070 00071 bool Resolver::filterNullaryOverloads() 00072 { 00073 return filterOverloads(NullaryPred()); 00074 } 00075 00076 bool Resolver::resolveDirectDecls(Homonym *homonym) 00077 { 00078 for (Homonym::DirectIterator iter = homonym->beginDirectDecls(); 00079 iter != homonym->endDirectDecls(); ++iter) { 00080 Decl *candidate = *iter; 00081 if (SubroutineDecl *sdecl = dyn_cast<SubroutineDecl>(candidate)) { 00082 SubroutineType *stype = sdecl->getType(); 00083 bool duplicated = false; 00084 for (unsigned i = 0; i < directOverloads.size(); ++i) { 00085 if (SubroutineDecl *targetDecl = 00086 dyn_cast<SubroutineDecl>(directOverloads[i])) { 00087 SubroutineType *targetType = targetDecl->getType(); 00088 if (!(duplicated = stype == targetType)) 00089 break; 00090 } 00091 } 00092 if (!duplicated) 00093 directOverloads.push_back(sdecl); 00094 } 00095 else { 00096 assert((isa<ValueDecl>(candidate) || 00097 isa<TypeDecl>(candidate) || 00098 isa<ModelDecl>(candidate) || 00099 isa<ExceptionDecl>(candidate) || 00100 isa<ComponentDecl>(candidate)) && 00101 "Bad type of direct declaration!"); 00102 if (directOverloads.empty()) { 00103 directDecl = candidate; 00104 return true; 00105 } 00106 break; 00107 } 00108 } 00109 return !directOverloads.empty(); 00110 } 00111 00112 bool Resolver::resolveIndirectDecls(Homonym *homonym) 00113 { 00114 if (!homonym->hasImportDecls()) 00115 return false; 00116 00117 // Scan the set of indirect declarations associcated with the homonym and 00118 // partition them into four sets corresponding to the accessible values, 00119 // subroutines, types, and exceptions. 00120 for (Homonym::ImportIterator iter = homonym->beginImportDecls(); 00121 iter != homonym->endImportDecls(); ++iter) { 00122 Decl *candidate = *iter; 00123 if (SubroutineDecl *sdecl = dyn_cast<SubroutineDecl>(candidate)) 00124 indirectOverloads.push_back(sdecl); 00125 else if (ValueDecl *vdecl = dyn_cast<ValueDecl>(candidate)) 00126 indirectValues.push_back(vdecl); 00127 else if (TypeDecl *tdecl = dyn_cast<TypeDecl>(candidate)) 00128 indirectTypes.push_back(tdecl); 00129 else if (ExceptionDecl *edecl = dyn_cast<ExceptionDecl>(candidate)) 00130 indirectExceptions.push_back(edecl); 00131 else 00132 assert(false && "Bad type of indirect declaration!"); 00133 } 00134 return true; 00135 } 00136 00137 bool Resolver::resolve(IdentifierInfo *idInfo) 00138 { 00139 Homonym *homonym = idInfo->getMetadata<Homonym>(); 00140 00141 this->idInfo = idInfo; 00142 if (!homonym || homonym->empty()) 00143 return false; 00144 return resolveDirectDecls(homonym) | resolveIndirectDecls(homonym); 00145 } 00146 00147 bool Resolver::getVisibleSubroutines( 00148 llvm::SmallVectorImpl<SubroutineDecl*> &srDecls) 00149 { 00150 // If there are any direct values, no subroutines are visible. 00151 if (hasDirectValue()) 00152 return false; 00153 00154 unsigned numEntries = srDecls.size(); 00155 00156 // Resolve all direct subroutines. 00157 direct_overload_iter DE = end_direct_overloads(); 00158 for (direct_overload_iter I = begin_direct_overloads(); I != DE; ++I) 00159 if (SubroutineDecl *SR = dyn_cast<SubroutineDecl>(*I)) 00160 srDecls.push_back(SR); 00161 00162 // If there are any indirect values, we are done. 00163 if (hasIndirectValues()) 00164 return numEntries != srDecls.size(); 00165 00166 // Resolve all indirect subroutines. 00167 indirect_overload_iter IE = end_indirect_overloads(); 00168 for (indirect_overload_iter I = begin_indirect_overloads(); I != IE; ++I) 00169 if (SubroutineDecl *SR = dyn_cast<SubroutineDecl>(*I)) 00170 srDecls.push_back(SR); 00171 00172 return numEntries != srDecls.size(); 00173 }