Fixes issue in DeclUnloader: do not unload templates intantiated in the PCH
This commit is contained in:
parent
ed3b079e93
commit
13485246a7
@ -29,6 +29,20 @@
|
||||
namespace cling {
|
||||
using namespace clang;
|
||||
|
||||
///\brief Return whether `D' is a template that was first instantiated non-
|
||||
/// locally, i.e. in a PCH/module. If `D' is not an instantiation, return false.
|
||||
bool DeclUnloader::isInstantiatedInPCH(const Decl *D) {
|
||||
SourceManager &SM = D->getASTContext().getSourceManager();
|
||||
if (const auto FD = dyn_cast<FunctionDecl>(D))
|
||||
return FD->isTemplateInstantiation() &&
|
||||
!SM.isLocalSourceLocation(FD->getPointOfInstantiation());
|
||||
else if (const auto CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))
|
||||
return !SM.isLocalSourceLocation(CTSD->getPointOfInstantiation());
|
||||
else if (const auto VTSD = dyn_cast<VarTemplateSpecializationDecl>(D))
|
||||
return !SM.isLocalSourceLocation(VTSD->getPointOfInstantiation());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeclUnloader::isDefinition(TagDecl* R) {
|
||||
return R->isCompleteDefinition() && isa<CXXRecordDecl>(R);
|
||||
}
|
||||
|
@ -54,13 +54,13 @@ namespace cling {
|
||||
: m_Sema(S), m_CodeGen(CG), m_CurTransaction(T) { }
|
||||
~DeclUnloader();
|
||||
|
||||
///\brief Interface with nice name, forwarding to Visit.
|
||||
///
|
||||
///\param[in] D - The declaration to forward.
|
||||
///\brief Forwards to Visit(), excluding PCH declarations (known to cause
|
||||
/// problems). If unsure, call this function instead of plain `Visit()'.
|
||||
///\param[in] D - The declaration to unload
|
||||
///\returns true on success.
|
||||
///
|
||||
bool UnloadDecl(clang::Decl* D) {
|
||||
if (D->isFromASTFile())
|
||||
if (D->isFromASTFile() || isInstantiatedInPCH(D))
|
||||
return true;
|
||||
return Visit(D);
|
||||
}
|
||||
@ -264,6 +264,8 @@ namespace cling {
|
||||
///
|
||||
void CollectFilesToUncache(clang::SourceLocation Loc);
|
||||
|
||||
bool isInstantiatedInPCH(const clang::Decl *D);
|
||||
|
||||
constexpr static bool isDefinition(void*) { return false; }
|
||||
static bool isDefinition(clang::TagDecl* R);
|
||||
|
||||
|
@ -85,10 +85,9 @@ namespace cling {
|
||||
const DeclGroupRef& DGR = (*I).m_DGR;
|
||||
for (DeclGroupRef::const_iterator
|
||||
Di = DGR.end() - 1, E = DGR.begin() - 1; Di != E; --Di) {
|
||||
// We only want to revert all that came through parseForModule, and
|
||||
// not the PCH.
|
||||
if (!(*Di)->isFromASTFile())
|
||||
Successful = DeclU.UnloadDecl(*Di) && Successful;
|
||||
// UnloadDecl() shall unload decls that came through `parseForModule()',
|
||||
// but not those that came from the PCH.
|
||||
Successful = DeclU.UnloadDecl(*Di) && Successful;
|
||||
#ifndef NDEBUG
|
||||
assert(Successful && "Cannot handle that yet!");
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user