00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef COMMA_TYPECHECK_RESOLVER_HDR_GUARD
00010 #define COMMA_TYPECHECK_RESOLVER_HDR_GUARD
00011
00012 #include "comma/ast/Decl.h"
00013
00014 namespace comma {
00015
00016 class Homonym;
00017 class Scope;
00018
00019 class Resolver {
00020 typedef llvm::SmallVector<Decl*, 4> DeclVector;
00021 typedef llvm::SmallVector<ValueDecl*, 4> ValueVector;
00022 typedef llvm::SmallVector<TypeDecl*, 4> TypeVector;
00023 typedef llvm::SmallVector<ExceptionDecl*, 4> ExceptionVector;
00024
00025
00026 Resolver(const Resolver &);
00027 Resolver &operator=(const Resolver &);
00028
00029
00030 Resolver() : directDecl(0) { };
00031
00034 void clear();
00035
00036 friend class Scope;
00037
00038 public:
00041 bool resolve(IdentifierInfo *idInfo);
00042
00046 bool filterOverloadsWRTArity(unsigned arity);
00047
00050 bool filterProcedures();
00051
00055 bool filterFunctionals();
00056
00060 bool filterNullaryOverloads();
00061
00063 IdentifierInfo *getIdInfo() const { return idInfo; }
00064
00066 unsigned numDirectOverloads() const { return directOverloads.size(); }
00067
00069 unsigned numIndirectValues() const { return indirectValues.size(); }
00070
00072 unsigned numIndirectTypes() const { return indirectTypes.size(); }
00073
00075 unsigned numIndirectExceptions() const { return indirectExceptions.size(); }
00076
00078 unsigned numIndirectOverloads() const {
00079 return indirectOverloads.size();
00080 }
00081
00083 unsigned numResolvedDecls() const;
00084
00086 unsigned numOverloads() const {
00087 return numDirectOverloads() + numIndirectOverloads();
00088 }
00089
00091 bool hasDirectValue() const {
00092 return directDecl && llvm::isa<ValueDecl>(directDecl);
00093 }
00094
00096 bool hasDirectType() const {
00097 return directDecl && llvm::isa<TypeDecl>(directDecl);
00098 }
00099
00101 bool hasDirectCapsule() const {
00102 return directDecl && llvm::isa<ModelDecl>(directDecl);
00103 }
00104
00106 bool hasDirectException() const {
00107 return directDecl && llvm::isa<ExceptionDecl>(directDecl);
00108 }
00109
00111 bool hasDirectOverloads() const { return numDirectOverloads() != 0; }
00112
00114 bool hasIndirectValues() const { return numIndirectValues() != 0; }
00115
00117 bool hasIndirectTypes() const { return numIndirectTypes() != 0; }
00118
00120 bool hasIndirectExceptions() const { return numIndirectExceptions() != 0; }
00121
00123 bool hasIndirectOverloads() const {
00124 return numIndirectOverloads() != 0;
00125 }
00126
00128 bool hasVisibleIndirectValue() const {
00129 return (numIndirectValues() == 1 &&
00130 (!hasIndirectOverloads() && !hasIndirectTypes()));
00131 }
00132
00134 bool hasVisibleIndirectType() const {
00135 return (numIndirectTypes() == 1 &&
00136 (!hasIndirectValues() && !hasIndirectOverloads()));
00137 }
00138
00140 bool hasVisibleIndirectOverloads() const {
00141 return (hasIndirectOverloads() &&
00142 (!hasIndirectValues() && !hasIndirectTypes()));
00143 }
00144
00147 ValueDecl *getDirectValue() const {
00148 return hasDirectValue() ? llvm::cast<ValueDecl>(directDecl) : 0;
00149 }
00150
00153 TypeDecl *getDirectType() const {
00154 return hasDirectType() ? llvm::cast<TypeDecl>(directDecl) : 0;
00155 }
00156
00159 ModelDecl *getDirectCapsule() const {
00160 return hasDirectCapsule() ? llvm::cast<ModelDecl>(directDecl) : 0;
00161 }
00162
00165 ExceptionDecl *getDirectException() const {
00166 return hasDirectException() ? llvm::cast<ExceptionDecl>(directDecl) : 0;
00167 }
00168
00170 Decl *getDirectOverload(unsigned i) const {
00171 assert(i < numDirectOverloads() && "Index out of range!");
00172 return directOverloads[i];
00173 }
00174
00176 ValueDecl *getIndirectValue(unsigned i) const {
00177 assert(i < numIndirectValues() && "Index out of range!");
00178 return indirectValues[i];
00179 }
00180
00182 TypeDecl *getIndirectType(unsigned i) const {
00183 assert(i < numIndirectTypes() && "Index out of range!");
00184 return indirectTypes[i];
00185 }
00186
00188 ExceptionDecl *getIndirectException(unsigned i) const {
00189 assert(i < numIndirectExceptions() && "Index out of range!");
00190 return indirectExceptions[i];
00191 }
00192
00194 Decl *getIndirectOverload(unsigned i) const {
00195 assert(i < numIndirectOverloads() && "Index out of range!");
00196 return indirectOverloads[i];
00197 }
00198
00201 bool getVisibleSubroutines(
00202 llvm::SmallVectorImpl<SubroutineDecl*> &srDecls);
00203
00204 typedef DeclVector::iterator direct_overload_iter;
00205 typedef DeclVector::iterator indirect_overload_iter;
00206 typedef ValueVector::iterator indirect_value_iter;
00207 typedef TypeVector::iterator indirect_type_iter;
00208
00209 direct_overload_iter begin_direct_overloads() {
00210 return directOverloads.begin();
00211 }
00212 direct_overload_iter end_direct_overloads() {
00213 return directOverloads.end();
00214 }
00215
00216 indirect_overload_iter begin_indirect_overloads() {
00217 return indirectOverloads.begin();
00218 }
00219 indirect_overload_iter end_indirect_overloads() {
00220 return indirectOverloads.end();
00221 }
00222
00223 indirect_value_iter begin_indirect_values() {
00224 return indirectValues.begin();
00225 }
00226
00227 indirect_value_iter end_indirect_values() {
00228 return indirectValues.end();
00229 }
00230
00231 indirect_type_iter begin_indirect_types() {
00232 return indirectTypes.begin();
00233 }
00234
00235 indirect_type_iter end_indirect_types() {
00236 return indirectTypes.end();
00237 }
00238
00239 private:
00240 IdentifierInfo *idInfo;
00241 Decl *directDecl;
00242 DeclVector directOverloads;
00243 ValueVector indirectValues;
00244 TypeVector indirectTypes;
00245 DeclVector indirectOverloads;
00246 ExceptionVector indirectExceptions;
00247
00250 bool resolveDirectDecls(Homonym *homonym);
00251
00254 bool resolveIndirectDecls(Homonym *homonym);
00255
00256 struct ArityPred {
00257 unsigned arity;
00258 ArityPred(unsigned arity) : arity(arity) { }
00259 bool operator()(const Decl* decl) const;
00260 };
00261
00262 struct NullaryPred {
00263 bool operator()(const Decl* decl) const;
00264 };
00265
00266 template <typename T>
00267 struct TypePred {
00268 bool operator()(const Decl* decl) const {
00269 return llvm::isa<T>(decl);
00270 }
00271 };
00272
00273 template <typename Pred>
00274 bool filterOverloads(const Pred &pred) {
00275 direct_overload_iter directEnd = end_direct_overloads();
00276 direct_overload_iter directFilterEnd =
00277 std::remove_if(begin_direct_overloads(), directEnd, pred);
00278
00279 indirect_overload_iter indirectEnd = end_indirect_overloads();
00280 indirect_overload_iter indirectFilterEnd =
00281 std::remove_if(begin_indirect_overloads(), indirectEnd, pred);
00282
00283 directOverloads.erase(directFilterEnd, directEnd);
00284 indirectOverloads.erase(indirectFilterEnd, indirectEnd);
00285
00286 return ((directEnd != directFilterEnd) ||
00287 (indirectEnd != indirectFilterEnd));
00288 }
00289 };
00290
00291
00292
00293 }
00294
00295 #endif