diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-03-02 23:58:15 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-03-02 23:58:15 +0000 |
commit | 7d10b7eb670b821741b4c96f6cf7afbc3bb39abe (patch) | |
tree | 6eb946551052737ea82f6a8cc13fee601fb06a71 /lib/AST/ASTContext.cpp | |
parent | e97c32f9578861d575ca96bbbae426c76cbc9024 (diff) |
Eliminate the static map of overridden C++ methods, which was going to
come back to bite us at some point.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97607 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r-- | lib/AST/ASTContext.cpp | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 5cd52396a8..e091bf10b6 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -59,6 +59,12 @@ ASTContext::~ASTContext() { // Release the DenseMaps associated with DeclContext objects. // FIXME: Is this the ideal solution? ReleaseDeclContextMaps(); + + // Release all of the memory associated with overridden C++ methods. + for (llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::iterator + OM = OverriddenMethods.begin(), OMEnd = OverriddenMethods.end(); + OM != OMEnd; ++OM) + OM->second.Destroy(); if (FreeMemory) { // Deallocate all the types. @@ -319,6 +325,80 @@ void ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, InstantiatedFromUnnamedFieldDecl[Inst] = Tmpl; } +CXXMethodVector::iterator CXXMethodVector::begin() const { + if ((Storage & 0x01) == 0) + return reinterpret_cast<iterator>(&Storage); + + vector_type *Vec = reinterpret_cast<vector_type *>(Storage & ~0x01); + return &Vec->front(); +} + +CXXMethodVector::iterator CXXMethodVector::end() const { + if ((Storage & 0x01) == 0) { + if (Storage == 0) + return reinterpret_cast<iterator>(&Storage); + + return reinterpret_cast<iterator>(&Storage) + 1; + } + + vector_type *Vec = reinterpret_cast<vector_type *>(Storage & ~0x01); + return &Vec->front() + Vec->size(); +} + +void CXXMethodVector::push_back(const CXXMethodDecl *Method) { + if (Storage == 0) { + // 0 -> 1 element. + Storage = reinterpret_cast<uintptr_t>(Method); + return; + } + + vector_type *Vec; + if ((Storage & 0x01) == 0) { + // 1 -> 2 elements. Allocate a new vector and push the element into that + // vector. + Vec = new vector_type; + Vec->push_back(reinterpret_cast<const CXXMethodDecl *>(Storage)); + Storage = reinterpret_cast<uintptr_t>(Vec) | 0x01; + } else + Vec = reinterpret_cast<vector_type *>(Storage & ~0x01); + + // Add the new method to the vector. + Vec->push_back(Method); +} + +void CXXMethodVector::Destroy() { + if (Storage & 0x01) + delete reinterpret_cast<vector_type *>(Storage & ~0x01); + + Storage = 0; +} + + +ASTContext::overridden_cxx_method_iterator +ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const { + llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos + = OverriddenMethods.find(Method); + if (Pos == OverriddenMethods.end()) + return 0; + + return Pos->second.begin(); +} + +ASTContext::overridden_cxx_method_iterator +ASTContext::overridden_methods_end(const CXXMethodDecl *Method) const { + llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos + = OverriddenMethods.find(Method); + if (Pos == OverriddenMethods.end()) + return 0; + + return Pos->second.end(); +} + +void ASTContext::addOverriddenMethod(const CXXMethodDecl *Method, + const CXXMethodDecl *Overridden) { + OverriddenMethods[Method].push_back(Overridden); +} + namespace { class BeforeInTranslationUnit : std::binary_function<SourceRange, SourceRange, bool> { |