<div dir="ltr">Hi,<br><br>I use <font face="courier new, monospace">clang_reparseTranslationUnit</font> with <font face="courier new, monospace">CXTranslationUnit_PrecompiledPreamble </font>flag on windows.<div><br></div><div>

I investigated why libclang.dll fails to delete old pch files on windows.</div><div><br></div><div>Modules keep an active file mapping on file until they are destroyed.  Later on, this still active mapping will cause <span style="font-family:'courier new',monospace">DeleteFileW </span>to fail (silently..) . </div>

<div><br></div><div><br></div><div>There is at least two cases when it happens:<br></div><div><br></div><div>The first one is when some preamble has changed and a new pch needs to replace the current one,  <font face="courier new, monospace" color="#000000" style="background-color:rgb(213,166,189)">CleanPreambleFile</font><font face="arial, helvetica, sans-serif"> </font><span style="font-family:arial,helvetica,sans-serif">, </span><span style="font-family:arial,helvetica,sans-serif">which purpose is to destroy the now old pch file </span><span style="font-family:arial,helvetica,sans-serif">will be called <b>before </b>the corresponding module is destroyed when the mapping will be recycled in </span><span style="font-family:'courier new',monospace"><font color="#000000" style="background-color:rgb(180,167,214)">ASTUnit::Parse</font><font color="#8e7cc3">.</font></span></div>

<div><br></div><div><div><font face="arial, helvetica, sans-serif">The second one is when we destroy the translation unit with </font><font color="#000000"><span style="font-family:'courier new',monospace">clang_</span><span style="font-family:'courier new',monospace">disposeTranslationUnit</span></font><font face="arial, helvetica, sans-serif">, </font><font face="courier new, monospace" style="background-color:rgb(246,178,107)" color="#000000">CleanPreambleFile</font><font face="arial, helvetica, sans-serif"> </font><span style="font-family:arial,helvetica,sans-serif">which purpose is to destroy the pch file, is called <b>before</b> the corresponding module is destroyed in </span><span style="color:rgb(61,133,198);font-family:'courier new',monospace">~</span><span style="font-family:'courier new',monospace;background-color:rgb(159,197,232)"><font color="#000000">ModuleFile</font></span><span style="font-family:arial,helvetica,sans-serif">. </span></div>

</div><div><span style="font-family:arial,helvetica,sans-serif"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif">Below are the corresponding callstacks.</span></div><div><br></div><div><ol><li><font color="#000000" style="background-color:rgb(213,166,189)"><font face="courier new, monospace">  libclang.dll!`anonymous namespace'::OnDiskData::<b>CleanPreambleFile</b>() Line 175<span class="" style="white-space:pre">    </span>C++</font><br>

</font></li><li style="font-family:arial,helvetica,sans-serif"><font color="#000000" style="background-color:rgb(213,166,189)"><span style="font-family:'courier new',monospace">  libclang.dll!</span><span style="font-family:'courier new',monospace">erasePreambleFile</span><span style="font-family:'courier new',monospace">(const clang::ASTUnit * AU) Line 144 C++</span><br>

</font></li><li style="font-family:arial,helvetica,sans-serif"><font color="#000000" style="background-color:rgb(213,166,189)"><span style="font-family:'courier new',monospace">  libclang.dll!clang::ASTUnit::getMainBufferWithPrecompiledPreamble(const clang::CompilerInvocation & PreambleInvocationIn, bool AllowRebuild, unsigned int MaxLines) Line 1511 C++</span><br>

</font></li><li style="font-family:arial,helvetica,sans-serif"><font color="#000000" style="background-color:rgb(213,166,189)"><span style="font-family:'courier new',monospace">  libclang.dll!clang::ASTUnit::Reparse(std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,llvm::PointerUnion<char const *,llvm::MemoryBuffer const *> > * RemappedFiles, unsigned int NumRemappedFiles) Line 2116 C++</span><br>

</font></li><li style="font-family:arial,helvetica,sans-serif"><span style="font-family:'courier new',monospace;background-color:rgb(213,166,189)"><font color="#000000">  libclang.dll!clang_reparseTranslationUnit_Impl(void * UserData) Line 3008 C++</font></span></li>

</ol></div><ol><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!llvm::sys::fs::mapped_file_region::~mapped_file_region() Line 833 C++<br></font></li><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!`anonymous namespace'::MemoryBufferMMapFile::~MemoryBufferMMapFile() C++<br>

</font></li><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!`anonymous namespace'::MemoryBufferMMapFile::`scalar deleting destructor'(unsigned int) C++<br></font></li>

<li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!llvm::OwningPtr<llvm::MemoryBuffer>::~OwningPtr<llvm::MemoryBuffer>() Line 45 C++<br></font></li><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!clang::serialization::ModuleFile::~ModuleFile() Line 58 C++<br>

</font></li><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!clang::serialization::ModuleFile::`scalar deleting destructor'(unsigned int) C++<br></font></li><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!clang::serialization::ModuleManager::~ModuleManager() Line 230 C++<br>

</font></li><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!clang::ASTReader::~ASTReader() Line 7638 C++<br></font></li><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!clang::ASTReader::`scalar deleting destructor'(unsigned int) C++<br>

</font></li><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!llvm::OwningPtr<clang::ExternalASTSource>::~OwningPtr<clang::ExternalASTSource>() Line 45 C++<br></font></li>

<li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!clang::ASTContext::~ASTContext() Line 790 C++<br></font></li><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!clang::ASTContext::`scalar deleting destructor'(unsigned int) C++<br>

</font></li><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!llvm::RefCountedBase<clang::ASTContext>::Release() Line 54 C++<br></font></li><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!llvm::IntrusiveRefCntPtrInfo<clang::ASTContext>::release(clang::ASTContext * obj) Line 89 C++<br>

</font></li><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!llvm::IntrusiveRefCntPtr<clang::ASTContext>::release() Line 178 C++<br></font></li><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!llvm::IntrusiveRefCntPtr<clang::ASTContext>::~IntrusiveRefCntPtr<clang::ASTContext>() Line 148 C++<br>

</font></li><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!llvm::IntrusiveRefCntPtr<clang::ASTContext>::operator=(llvm::IntrusiveRefCntPtr<clang::ASTContext> S) Line 145 C++<br>

</font></li><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!clang::ASTUnit::Parse(llvm::MemoryBuffer * OverrideMainBuffer) Line 1169 C++<br></font></li><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!clang::ASTUnit::Reparse(std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,llvm::PointerUnion<char const *,llvm::MemoryBuffer const *> > * RemappedFiles, unsigned int NumRemappedFiles) Line 2125 C++<br>

</font></li><li><font face="courier new, monospace" style="background-color:rgb(180,167,214)">  libclang.dll!clang_reparseTranslationUnit_Impl(void * UserData) Line 3008 C++</font><span style="background-color:rgb(246,178,107)"><font color="#000000"><br>

</font></span></li></ol><div><div><ol><li><font style="background-color:rgb(246,178,107)" color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!`anonymous namespace'::OnDiskData::</span><span style="font-family:'courier new',monospace"><b>CleanPreambleFile</b></span><span style="font-family:'courier new',monospace">() Line 175</span><span style="font-family:'courier new',monospace;white-space:pre-wrap">  </span><span style="font-family:'courier new',monospace">C++</span><br>

</font></li><li><font style="background-color:rgb(246,178,107)" color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!`anonymous namespace'::OnDiskData::</span><span style="font-family:'courier new',monospace">Cleanup() Line 183</span><span style="font-family:'courier new',monospace;white-space:pre-wrap">      </span><span style="font-family:'courier new',monospace">C++</span><br>

</font></li><li><font style="background-color:rgb(246,178,107)" color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!</span><span style="font-family:'courier new',monospace">removeOnDiskEntry(const clang::ASTUnit * AU) Line 154</span><span style="font-family:'courier new',monospace;white-space:pre-wrap">  </span><span style="font-family:'courier new',monospace">C++</span><br>

</font></li><li><font style="background-color:rgb(246,178,107)" color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!clang::ASTUnit::~</span><span style="font-family:'courier new',monospace">ASTUnit() Line 249</span><span style="font-family:'courier new',monospace;white-space:pre-wrap">    </span><span style="font-family:'courier new',monospace">C++</span><br>

</font></li><li><font style="background-color:rgb(246,178,107)" color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!clang::ASTUnit::`</span><span style="font-family:'courier new',monospace">scalar deleting destructor'(unsigned int)</span><span style="font-family:'courier new',monospace;white-space:pre-wrap"> </span><span style="font-family:'courier new',monospace">C++</span><br>

</font></li><li><font style="background-color:rgb(246,178,107)" color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!clang_</span><span style="font-family:'courier new',monospace">disposeTranslationUnit(</span><span style="font-family:'courier new',monospace">CXTranslationUnitImpl * CTUnit) Line 2945</span><span style="font-family:'courier new',monospace;white-space:pre-wrap">  </span><span style="font-family:'courier new',monospace">C++</span></font></li>

</ol><ol><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!llvm::sys::fs::</span><span style="font-family:'courier new',monospace">mapped_file_region::~mapped_</span><span style="font-family:'courier new',monospace">file_region() Line 833 C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!`anonymous namespace'::</span><span style="font-family:'courier new',monospace">MemoryBufferMMapFile::~</span><span style="font-family:'courier new',monospace">MemoryBufferMMapFile() C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!`anonymous namespace'::</span><span style="font-family:'courier new',monospace">MemoryBufferMMapFile::`scalar deleting destructor'(unsigned int) C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!llvm::OwningPtr<</span><span style="font-family:'courier new',monospace">llvm::MemoryBuffer>::~</span><span style="font-family:'courier new',monospace">OwningPtr<llvm::MemoryBuffer>(</span><span style="font-family:'courier new',monospace">) Line 45 C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!clang::</span><span style="font-family:'courier new',monospace">serialization::ModuleFile::~</span><span style="font-family:'courier new',monospace">ModuleFile() Line 58 C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!clang::</span><span style="font-family:'courier new',monospace">serialization::ModuleFile::`</span><span style="font-family:'courier new',monospace">scalar deleting destructor'(unsigned int) C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!clang::</span><span style="font-family:'courier new',monospace">serialization::ModuleManager::</span><span style="font-family:'courier new',monospace">~ModuleManager() Line 230 C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!clang::ASTReader:</span><span style="font-family:'courier new',monospace">:~ASTReader() Line 7638 C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!clang::ASTReader:</span><span style="font-family:'courier new',monospace">:`scalar deleting destructor'(unsigned int) C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!llvm::OwningPtr<</span><span style="font-family:'courier new',monospace">clang::ExternalASTSource>::~</span><span style="font-family:'courier new',monospace">OwningPtr<clang::</span><span style="font-family:'courier new',monospace">ExternalASTSource>() Line 45 C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!clang::</span><span style="font-family:'courier new',monospace">ASTContext::~ASTContext() Line 790 C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!clang::</span><span style="font-family:'courier new',monospace">ASTContext::`scalar deleting destructor'(unsigned int) C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!llvm::</span><span style="font-family:'courier new',monospace">RefCountedBase<clang::</span><span style="font-family:'courier new',monospace">ASTContext>::Release() Line 54 C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!llvm::</span><span style="font-family:'courier new',monospace">IntrusiveRefCntPtrInfo<clang::</span><span style="font-family:'courier new',monospace">ASTContext>::release(clang::</span><span style="font-family:'courier new',monospace">ASTContext * obj) Line 89 C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!llvm::</span><span style="font-family:'courier new',monospace">IntrusiveRefCntPtr<clang::</span><span style="font-family:'courier new',monospace">ASTContext>::release() Line 178 C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!llvm::</span><span style="font-family:'courier new',monospace">IntrusiveRefCntPtr<clang::</span><span style="font-family:'courier new',monospace">ASTContext>::~</span><span style="font-family:'courier new',monospace">IntrusiveRefCntPtr<clang::</span><span style="font-family:'courier new',monospace">ASTContext>() Line 148 C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!clang::ASTUnit::~</span><span style="font-family:'courier new',monospace">ASTUnit() Line 274 C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!clang::ASTUnit::`</span><span style="font-family:'courier new',monospace">scalar deleting destructor'(unsigned int) C++</span><br>

</font></span></li><li><span style="background-color:rgb(159,197,232)"><font color="#000000"><span style="font-family:'courier new',monospace">  libclang.dll!clang_</span><span style="font-family:'courier new',monospace">disposeTranslationUnit(</span><span style="font-family:'courier new',monospace">CXTranslationUnitImpl * CTUnit) Line 2945 C++</span></font></span><br>

</li></ol><div><font color="#000000" face="courier new, monospace"><div><br></div><div><span style="color:rgb(34,34,34);font-family:arial,helvetica,sans-serif">To verify this, we made the following dirty fix that solved the problem for our limited usecase.</span><br>

</div><div><br></div><div>ASTUnit.cpp</div><div><br></div><div><span style="background-color:rgb(217,234,211)">static void unmapPreambleFile(const ASTUnit *AU, OnDiskData& D){</span></div><div><span style="background-color:rgb(217,234,211)">  if (!D.PreambleFile.empty()) {</span></div>

<div><span style="background-color:rgb(217,234,211)">    const ASTContext& Context = AU->getASTContext();</span></div><div><span style="background-color:rgb(217,234,211)">    ASTReader& Reader = (ASTReader&)*Context.ExternalSource;</span></div>

<div><span style="background-color:rgb(217,234,211)">    if (&Reader){</span></div><div><span style="background-color:rgb(217,234,211)">      serialization::ModuleManager& ModuleMgr = Reader.getModuleManager();</span></div>

<div><span style="background-color:rgb(217,234,211)">      ModuleMgr.removeModule(D.PreambleFile);</span></div><div><span style="background-color:rgb(217,234,211)">    }</span></div><div><span style="background-color:rgb(217,234,211)">  }</span></div>

<div><span style="background-color:rgb(217,234,211)">}</span></div><div><br></div><div>static void erasePreambleFile(const ASTUnit *AU) {</div><div>  OnDiskData& D = getOnDiskData(AU);</div><div>  <span style="background-color:rgb(217,234,211)">unmapPreambleFile(AU, D);</span></div>

<div>  D.CleanPreambleFile();</div><div>}</div><div><br></div><div>static void removeOnDiskEntry(const ASTUnit *AU) {</div><div>  // We require the mutex since we are modifying the structure of the</div><div>  // DenseMap.</div>

<div>  llvm::MutexGuard Guard(getOnDiskMutex());</div><div>  OnDiskDataMap &M = getOnDiskDataMap();</div><div>  OnDiskDataMap::iterator I = M.find(AU);</div><div>  if (I != M.end()) {</div><div>    OnDiskData* pD = I->second;</div>

<div>    <span style="background-color:rgb(217,234,211)">unmapPreambleFile(AU, *pD);</span></div><div>    pD->Cleanup();</div><div>    delete pD;</div><div>    M.erase(AU);</div><div>  }</div><div>}</div><div><br></div>

<div>ModuleManager.cpp</div><div><br></div><div><span style="background-color:rgb(217,234,211)">void ModuleManager::removeModule(const std::string& FileName){</span></div><div><span style="background-color:rgb(217,234,211)">  for (ModuleIterator M = Chain.begin(), MEnd = Chain.end(); M != MEnd; ++M) {</span></div>

<div><span style="background-color:rgb(217,234,211)">    serialization::ModuleFile* pModuleFile = *M;</span></div><div><span style="background-color:rgb(217,234,211)">    if (pModuleFile->FileName.compare(FileName)==0){</span></div>

<div><span style="background-color:rgb(217,234,211)">      delete pModuleFile;</span></div><div><span style="background-color:rgb(217,234,211)">      Chain.erase(M);</span></div><div><span style="background-color:rgb(217,234,211)">      break;</span></div>

<div><span style="background-color:rgb(217,234,211)">    }</span></div><div><span style="background-color:rgb(217,234,211)">  }</span></div><div><span style="background-color:rgb(217,234,211)">}</span></div><div><br></div>

<div><br></div></font></div></div>


</div></div>