aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-03-02 23:58:15 +0000
committerDouglas Gregor <dgregor@apple.com>2010-03-02 23:58:15 +0000
commit7d10b7eb670b821741b4c96f6cf7afbc3bb39abe (patch)
tree6eb946551052737ea82f6a8cc13fee601fb06a71 /lib/AST/ASTContext.cpp
parente97c32f9578861d575ca96bbbae426c76cbc9024 (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.cpp80
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> {