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