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 }