diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-08-29 23:59:27 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-08-29 23:59:27 +0000 |
commit | 676c404dec0c28651b1c568496f8fc1ed7231fa0 (patch) | |
tree | 001269a579f2a01ec6ab2f69b9e6416ffd9a6b89 /clang/lib/AST/RecordLayoutBuilder.cpp | |
parent | b81766ca232cba89ba2c058affadc2220eb19f19 (diff) | |
download | bcm5719-llvm-676c404dec0c28651b1c568496f8fc1ed7231fa0.tar.gz bcm5719-llvm-676c404dec0c28651b1c568496f8fc1ed7231fa0.zip |
Be lazier when loading KeyFunctions from PCH/modules. We don't need to load
these in eagerly if we're not actually processing a translation unit. The added
laziness here also avoids us loading in parts of a CXXRecordDecl earlier than an
upcoming class template specialization merging patch would like.
Ideally, we should mark the vtable as used when we see a definition for the key
function, rather than having a separate pass over dynamic classes at the end of
the TU. The existing approach is pretty bad for PCH/modules, since it forcibly
loads the declarations of all key functions in all imported modules, whether or
not those key functions are defined.
llvm-svn: 189627
Diffstat (limited to 'clang/lib/AST/RecordLayoutBuilder.cpp')
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 5df372639da..e5222c971e3 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -2438,32 +2438,31 @@ const CXXMethodDecl *ASTContext::getCurrentKeyFunction(const CXXRecordDecl *RD) assert(RD->getDefinition() && "Cannot get key function for forward decl!"); RD = cast<CXXRecordDecl>(RD->getDefinition()); - const CXXMethodDecl *&entry = KeyFunctions[RD]; - if (!entry) { - entry = computeKeyFunction(*this, RD); - } + LazyDeclPtr &Entry = KeyFunctions[RD]; + if (!Entry) + Entry = const_cast<CXXMethodDecl*>(computeKeyFunction(*this, RD)); - return entry; + return cast_or_null<CXXMethodDecl>(Entry.get(getExternalSource())); } -void ASTContext::setNonKeyFunction(const CXXMethodDecl *method) { - assert(method == method->getFirstDeclaration() && +void ASTContext::setNonKeyFunction(const CXXMethodDecl *Method) { + assert(Method == Method->getFirstDeclaration() && "not working with method declaration from class definition"); // Look up the cache entry. Since we're working with the first // declaration, its parent must be the class definition, which is // the correct key for the KeyFunctions hash. - llvm::DenseMap<const CXXRecordDecl*, const CXXMethodDecl*>::iterator - i = KeyFunctions.find(method->getParent()); + llvm::DenseMap<const CXXRecordDecl*, LazyDeclPtr>::iterator + I = KeyFunctions.find(Method->getParent()); // If it's not cached, there's nothing to do. - if (i == KeyFunctions.end()) return; + if (I == KeyFunctions.end()) return; // If it is cached, check whether it's the target method, and if so, // remove it from the cache. - if (i->second == method) { + if (I->second.get(getExternalSource()) == Method) { // FIXME: remember that we did this for module / chained PCH state? - KeyFunctions.erase(i); + KeyFunctions.erase(I); } } |