00001 
00002 
00003 
00004 
00005 
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     
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     
00118     
00119     
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     
00151     if (hasDirectValue())
00152         return false;
00153 
00154     unsigned numEntries = srDecls.size();
00155 
00156     
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     
00163     if (hasIndirectValues())
00164         return numEntries != srDecls.size();
00165 
00166     
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 }