00001 //===-- typecheck/IdentifierResolver.h ------------------------ -*- 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 #ifndef COMMA_TYPECHECK_IDENTIFIERRESOLVER_HDR_GUARD 00010 #define COMMA_TYPECHECK_IDENTIFIERRESOLVER_HDR_GUARD 00011 00012 #include "comma/ast/Homonym.h" 00013 #include "llvm/ADT/SmallVector.h" 00014 00015 namespace comma { 00016 00017 class IdentifierResolver { 00018 00019 typedef llvm::SmallVector<Decl*, 4> DeclVector; 00020 typedef llvm::SmallVector<ValueDecl*, 4> ValueVector; 00021 00022 // Do not implement. 00023 IdentifierResolver(const IdentifierResolver &); 00024 IdentifierResolver &operator=(const IdentifierResolver &); 00025 00026 public: 00027 IdentifierResolver() : directValue(0) { } 00028 00031 bool resolve(IdentifierInfo *idInfo); 00032 00034 void clear(); 00035 00038 bool filterOverloadsWRTArity(unsigned arity); 00039 00042 bool filterProcedures(); 00043 00047 bool filterFunctionals(); 00048 00052 bool filterNullaryOverloads(); 00053 00055 unsigned numDirectOverloads() const { return directOverloads.size(); } 00056 00058 unsigned numIndirectValues() const { return indirectValues.size(); } 00059 00061 unsigned numIndirectOverloads() const { return indirectOverloads.size(); } 00062 00064 unsigned numResolvedDecls() const; 00065 00067 unsigned numOverloads() const { 00068 return numDirectOverloads() + numIndirectOverloads(); 00069 } 00070 00072 bool hasDirectValue() const { return directValue != 0; } 00073 00075 bool hasDirectOverloads() const { return numDirectOverloads() != 0; } 00076 00078 bool hasIndirectValues() const { return numIndirectValues() != 0; } 00079 00081 bool hasIndirectOverloads() const { return numIndirectOverloads() != 0; } 00082 00085 ValueDecl *getDirectValue() const { return directValue; } 00086 00088 Decl *getDirectOverload(unsigned i) const { 00089 assert(i < numDirectOverloads() && "Index out of range!"); 00090 return directOverloads[i]; 00091 } 00092 00094 ValueDecl *getIndirectValue(unsigned i) const { 00095 assert(i < numIndirectValues() && "Index out of range!"); 00096 return indirectValues[i]; 00097 } 00098 00100 Decl *getIndirectOverload(unsigned i) const { 00101 assert(i < numIndirectOverloads() && "Index out of range!"); 00102 return indirectOverloads[i]; 00103 } 00104 00105 typedef DeclVector::iterator DirectOverloadIter; 00106 typedef DeclVector::iterator IndirectOverloadIter; 00107 typedef ValueVector::iterator IndirectValueIter; 00108 00109 DirectOverloadIter beginDirectOverloads() { 00110 return directOverloads.begin(); 00111 } 00112 DirectOverloadIter endDirectOverloads() { 00113 return directOverloads.end(); 00114 } 00115 00116 IndirectOverloadIter beginIndirectOverloads() { 00117 return indirectOverloads.begin(); 00118 } 00119 IndirectOverloadIter endIndirectOverloads() { 00120 return indirectOverloads.end(); 00121 } 00122 00123 IndirectValueIter beginIndirectValues() { 00124 return indirectValues.begin(); 00125 } 00126 00127 IndirectValueIter endIndirectValues() { 00128 return indirectValues.end(); 00129 } 00130 00131 private: 00132 ValueDecl *directValue; 00133 DeclVector directOverloads; 00134 ValueVector indirectValues; 00135 DeclVector indirectOverloads; 00136 00137 struct ArityPred { 00138 unsigned arity; 00139 ArityPred(unsigned arity) : arity(arity) { } 00140 bool operator()(const Decl* decl) const; 00141 }; 00142 00143 struct NullaryPred { 00144 bool operator()(const Decl* decl) const; 00145 }; 00146 00147 template <typename T> 00148 struct TypePred { 00149 bool operator()(const Decl* decl) const { 00150 return llvm::isa<T>(decl); 00151 } 00152 }; 00153 00154 template <typename Pred> 00155 bool filterOverloads(const Pred &pred); 00156 }; 00157 00158 template <typename Pred> 00159 bool IdentifierResolver::filterOverloads(const Pred &pred) 00160 { 00161 DirectOverloadIter directEnd = 00162 std::remove_if(beginDirectOverloads(), endDirectOverloads(), pred); 00163 00164 IndirectOverloadIter indirectEnd = 00165 std::remove_if(beginIndirectOverloads(), endIndirectOverloads(), pred); 00166 00167 bool result = ((directEnd != endDirectOverloads()) || 00168 (indirectEnd != endIndirectOverloads())); 00169 00170 directOverloads.erase(directEnd, endDirectOverloads()); 00171 indirectOverloads.erase(indirectEnd, endIndirectOverloads()); 00172 00173 return result; 00174 } 00175 00176 } // End comma namespace. 00177 00178 #endif