14b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//===--- ASTUnit.cpp - ASTUnit utility ------------------------------------===// 24b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// 34b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// The LLVM Compiler Infrastructure 44b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// 54b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 64b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// License. See LICENSE.TXT for details. 74b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// 84b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 94b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// 104b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// ASTUnit Implementation. 114b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// 124b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 134b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis 140853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Frontend/ASTUnit.h" 15521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/AST/ASTConsumer.h" 1655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/ASTContext.h" 170853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/AST/DeclVisitor.h" 180853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/AST/StmtVisitor.h" 1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/TypeOrdering.h" 2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/Diagnostic.h" 2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/TargetInfo.h" 2255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/TargetOptions.h" 23521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/CompilerInstance.h" 24521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/FrontendActions.h" 257b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Frontend/FrontendDiagnostic.h" 26521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/FrontendOptions.h" 276f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis#include "clang/Frontend/MultiplexConsumer.h" 2832be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor#include "clang/Frontend/Utils.h" 290853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Lex/HeaderSearch.h" 300853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Lex/Preprocessor.h" 3136a16498ff911a218f26c7955376bbe99ddb16dfDouglas Gregor#include "clang/Lex/PreprocessorOptions.h" 3255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Serialization/ASTReader.h" 3355fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Serialization/ASTWriter.h" 347f9fc3f7ce076645cb6aefc99c64d9446caf13d6Chris Lattner#include "llvm/ADT/ArrayRef.h" 359b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor#include "llvm/ADT/StringExtras.h" 36349d38cef04ddf8938047c1b542a799aa82dfe84Douglas Gregor#include "llvm/ADT/StringSet.h" 371fd9e0def66fbd50e99be5ff87c9fd1c91c428abDouglas Gregor#include "llvm/Support/Atomic.h" 3855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/CrashRecoveryContext.h" 399cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis#include "llvm/Support/FileSystem.h" 4055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/Host.h" 4155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/MemoryBuffer.h" 42a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis#include "llvm/Support/Mutex.h" 43e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek#include "llvm/Support/MutexGuard.h" 4455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/Path.h" 4555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/Timer.h" 4655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/raw_ostream.h" 47ad23ebe22b7e52e3875981eeb46a1fd61a7554fbZhongxing Xu#include <cstdio> 4855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include <cstdlib> 49cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor#include <sys/stat.h> 500853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisusing namespace clang; 510853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 52213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregorusing llvm::TimeRecord; 53213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 54213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregornamespace { 55213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor class SimpleTimer { 56213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor bool WantTiming; 57213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor TimeRecord Start; 58213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor std::string Output; 59213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 60edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer public: 619dba61a1e46099b77adf15de224aaa16037a7fffDouglas Gregor explicit SimpleTimer(bool WantTiming) : WantTiming(WantTiming) { 62213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor if (WantTiming) 63edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer Start = TimeRecord::getCurrentTime(); 64213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor } 65213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner void setOutput(const Twine &Output) { 67213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor if (WantTiming) 68edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer this->Output = Output.str(); 69213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor } 70213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 71213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor ~SimpleTimer() { 72213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor if (WantTiming) { 73213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor TimeRecord Elapsed = TimeRecord::getCurrentTime(); 74213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor Elapsed -= Start; 75213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor llvm::errs() << Output << ':'; 76213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor Elapsed.print(Elapsed, llvm::errs()); 77213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor llvm::errs() << '\n'; 78213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor } 79213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor } 80213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor }; 811872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 821872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek struct OnDiskData { 831872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek /// \brief The file in which the precompiled preamble is stored. 841872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek std::string PreambleFile; 851872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 86b804cb315cfeebc4d1c4d2d023ffb08440f77254Rafael Espindola /// \brief Temporary files that should be removed when the ASTUnit is 871872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek /// destroyed. 88b804cb315cfeebc4d1c4d2d023ffb08440f77254Rafael Espindola SmallVector<std::string, 4> TemporaryFiles; 89b804cb315cfeebc4d1c4d2d023ffb08440f77254Rafael Espindola 901872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek /// \brief Erase temporary files. 911872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek void CleanTemporaryFiles(); 921872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 931872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek /// \brief Erase the preamble file. 941872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek void CleanPreambleFile(); 951872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 961872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek /// \brief Erase temporary files and the preamble file. 971872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek void Cleanup(); 981872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek }; 991872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek} 1001872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 101e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenekstatic llvm::sys::SmartMutex<false> &getOnDiskMutex() { 102e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek static llvm::sys::SmartMutex<false> M(/* recursive = */ true); 103e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek return M; 104e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek} 105e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek 106c4a77906c259cba58c147d8468c406a430ecdcbbDmitri Gribenkostatic void cleanupOnDiskMapAtExit(); 1071872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 1081872b3153a388b3a548c9f699cbc348128059be9Ted Kremenektypedef llvm::DenseMap<const ASTUnit *, OnDiskData *> OnDiskDataMap; 1091872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekstatic OnDiskDataMap &getOnDiskDataMap() { 1101872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek static OnDiskDataMap M; 1111872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek static bool hasRegisteredAtExit = false; 1121872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek if (!hasRegisteredAtExit) { 1131872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek hasRegisteredAtExit = true; 1141872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek atexit(cleanupOnDiskMapAtExit); 1151872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek } 1161872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek return M; 1171872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek} 1181872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 119c4a77906c259cba58c147d8468c406a430ecdcbbDmitri Gribenkostatic void cleanupOnDiskMapAtExit() { 120817881376e3a40ca54376547dd1cb9ca5def7190Argyrios Kyrtzidis // Use the mutex because there can be an alive thread destroying an ASTUnit. 121817881376e3a40ca54376547dd1cb9ca5def7190Argyrios Kyrtzidis llvm::MutexGuard Guard(getOnDiskMutex()); 1221872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek OnDiskDataMap &M = getOnDiskDataMap(); 1231872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek for (OnDiskDataMap::iterator I = M.begin(), E = M.end(); I != E; ++I) { 1241872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek // We don't worry about freeing the memory associated with OnDiskDataMap. 1251872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek // All we care about is erasing stale files. 1261872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek I->second->Cleanup(); 1271872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek } 1281872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek} 1291872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 1301872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekstatic OnDiskData &getOnDiskData(const ASTUnit *AU) { 131e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek // We require the mutex since we are modifying the structure of the 132e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek // DenseMap. 133e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek llvm::MutexGuard Guard(getOnDiskMutex()); 1341872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek OnDiskDataMap &M = getOnDiskDataMap(); 1351872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek OnDiskData *&D = M[AU]; 1361872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek if (!D) 1371872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek D = new OnDiskData(); 1381872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek return *D; 1391872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek} 1401872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 1411872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekstatic void erasePreambleFile(const ASTUnit *AU) { 1421872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek getOnDiskData(AU).CleanPreambleFile(); 1431872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek} 1441872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 1451872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekstatic void removeOnDiskEntry(const ASTUnit *AU) { 146e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek // We require the mutex since we are modifying the structure of the 147e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek // DenseMap. 148e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek llvm::MutexGuard Guard(getOnDiskMutex()); 1491872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek OnDiskDataMap &M = getOnDiskDataMap(); 1501872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek OnDiskDataMap::iterator I = M.find(AU); 1511872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek if (I != M.end()) { 1521872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek I->second->Cleanup(); 1531872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek delete I->second; 1541872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek M.erase(AU); 1551872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek } 1561872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek} 1571872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 158cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenkostatic void setPreambleFile(const ASTUnit *AU, StringRef preambleFile) { 1591872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek getOnDiskData(AU).PreambleFile = preambleFile; 1601872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek} 1611872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 1621872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekstatic const std::string &getPreambleFile(const ASTUnit *AU) { 1631872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek return getOnDiskData(AU).PreambleFile; 1641872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek} 1651872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 1661872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekvoid OnDiskData::CleanTemporaryFiles() { 1671872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I) 168b804cb315cfeebc4d1c4d2d023ffb08440f77254Rafael Espindola llvm::sys::fs::remove(TemporaryFiles[I]); 169b804cb315cfeebc4d1c4d2d023ffb08440f77254Rafael Espindola TemporaryFiles.clear(); 1701872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek} 1711872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 1721872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekvoid OnDiskData::CleanPreambleFile() { 1731872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek if (!PreambleFile.empty()) { 17485d28486b781f4e69dbff2d0b0239edc5a31ae16Rafael Espindola llvm::sys::fs::remove(PreambleFile); 1751872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek PreambleFile.clear(); 1761872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek } 1771872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek} 1781872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 1791872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekvoid OnDiskData::Cleanup() { 1801872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek CleanTemporaryFiles(); 1811872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek CleanPreambleFile(); 1821872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek} 1831872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 184900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidisstruct ASTUnit::ASTWriterData { 185900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis SmallString<128> Buffer; 186900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis llvm::BitstreamWriter Stream; 187900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis ASTWriter Writer; 188900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis 189900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis ASTWriterData() : Stream(Buffer), Writer(Stream) { } 190900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis}; 191900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis 192332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidisvoid ASTUnit::clearFileLevelDecls() { 193332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis for (FileDeclsTy::iterator 194332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis I = FileDecls.begin(), E = FileDecls.end(); I != E; ++I) 195332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis delete I->second; 196332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis FileDecls.clear(); 197332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis} 198332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 1991872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekvoid ASTUnit::CleanTemporaryFiles() { 2001872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek getOnDiskData(this).CleanTemporaryFiles(); 2011872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek} 2021872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 203b804cb315cfeebc4d1c4d2d023ffb08440f77254Rafael Espindolavoid ASTUnit::addTemporaryFile(StringRef TempFile) { 2041872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek getOnDiskData(this).TemporaryFiles.push_back(TempFile); 205213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor} 206213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 207eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// \brief After failing to build a precompiled preamble (due to 208eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// errors in the source that occurs in the preamble), the number of 209eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// reparses during which we'll skip even trying to precompile the 210eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// preamble. 211eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregorconst unsigned DefaultPreambleRebuildInterval = 5; 212eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 213e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor/// \brief Tracks the number of ASTUnit objects that are currently active. 214e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor/// 215e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor/// Used for debugging purposes only. 2161fd9e0def66fbd50e99be5ff87c9fd1c91c428abDouglas Gregorstatic llvm::sys::cas_flag ActiveASTUnitObjects; 217e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor 2183687e9d3a5dbfa9963af02a49a2b139d91310813Douglas GregorASTUnit::ASTUnit(bool _MainFileIsAST) 2193b7deda7137e62810a810ce25b062927a9fc7c71Argyrios Kyrtzidis : Reader(0), HadModuleLoaderFatalFailure(false), 2203b7deda7137e62810a810ce25b062927a9fc7c71Argyrios Kyrtzidis OnlyLocalDecls(false), CaptureDiagnostics(false), 221b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis MainFileIsAST(_MainFileIsAST), 222467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor TUKind(TU_Complete), WantTiming(getenv("LIBCLANG_TIMING")), 22315727ddb11405c45372150b5bfb07dbfa4c9960bArgyrios Kyrtzidis OwnsRemappedFileBuffers(true), 224213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor NumStoredDiagnosticsFromDriver(0), 225671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreambleRebuildCounter(0), SavedMainFileBuffer(0), PreambleBuffer(0), 2269870401105660efb1c393829e08eae44e0583b3dArgyrios Kyrtzidis NumWarningsInPreamble(0), 227727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor ShouldCacheCodeCompletionResults(false), 228ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis IncludeBriefCommentsInCodeCompletion(false), UserFilesAreVolatile(false), 2299b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CompletionCacheTopLevelHashValue(0), 2309b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor PreambleTopLevelHashValue(0), 2319b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CurrentTopLevelHashValue(0), 2328b1540c159093e0e627ebf6542d0c0b7aba99eafDouglas Gregor UnsafeToFree(false) { 233e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor if (getenv("LIBCLANG_OBJTRACKING")) { 2341fd9e0def66fbd50e99be5ff87c9fd1c91c428abDouglas Gregor llvm::sys::AtomicIncrement(&ActiveASTUnitObjects); 235e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor fprintf(stderr, "+++ %d translation units\n", ActiveASTUnitObjects); 236e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor } 237385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor} 2383687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor 239521bf9c529e653ab28896d027352d3e16e2672d5Daniel DunbarASTUnit::~ASTUnit() { 240a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor // If we loaded from an AST file, balance out the BeginSourceFile call. 241a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor if (MainFileIsAST && getDiagnostics().getClient()) { 242a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor getDiagnostics().getClient()->EndSourceFile(); 243a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor } 244a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor 245332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis clearFileLevelDecls(); 246332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 2471872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek // Clean up the temporary files and the preamble file. 2481872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek removeOnDiskEntry(this); 2491872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek 250f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // Free the buffers associated with remapped files. We are required to 251f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // perform this operation here because we explicitly request that the 252f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // compiler instance *not* free these buffers for each invocation of the 253f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // parser. 2544f32786ac45210143654390177105eb749b614e9Ted Kremenek if (Invocation.getPtr() && OwnsRemappedFileBuffers) { 255f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 256f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 257f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor FB = PPOpts.remapped_file_buffer_begin(), 258f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor FBEnd = PPOpts.remapped_file_buffer_end(); 259f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor FB != FBEnd; 260f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor ++FB) 261f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor delete FB->second; 262f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor } 26328233428da1ebec20c893d6297ae3191318940ddDouglas Gregor 26428233428da1ebec20c893d6297ae3191318940ddDouglas Gregor delete SavedMainFileBuffer; 265671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete PreambleBuffer; 266671947b18dba342f9aba022ee992babef325a833Douglas Gregor 267213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor ClearCachedCompletionResults(); 268e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor 269e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor if (getenv("LIBCLANG_OBJTRACKING")) { 2701fd9e0def66fbd50e99be5ff87c9fd1c91c428abDouglas Gregor llvm::sys::AtomicDecrement(&ActiveASTUnitObjects); 271e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor fprintf(stderr, "--- %d translation units\n", ActiveASTUnitObjects); 272e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor } 273abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 274abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 2757fe90f3bfa6bd7f779ecfd4ba201a296a3a1c8cbArgyrios Kyrtzidisvoid ASTUnit::setPreprocessor(Preprocessor *pp) { PP = pp; } 2767fe90f3bfa6bd7f779ecfd4ba201a296a3a1c8cbArgyrios Kyrtzidis 2778071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor/// \brief Determine the set of code-completion contexts in which this 2788071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor/// declaration should be shown. 27989cf425f1136f8d24a64ed94450e488b6794dfa4Dmitri Gribenkostatic unsigned getDeclShowContexts(const NamedDecl *ND, 280a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor const LangOptions &LangOpts, 281a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor bool &IsNestedNameSpecifier) { 282a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = false; 283a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor 2848071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (isa<UsingShadowDecl>(ND)) 2858071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor ND = dyn_cast<NamedDecl>(ND->getUnderlyingDecl()); 2868071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (!ND) 2878071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor return 0; 2888071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 289026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith uint64_t Contexts = 0; 2908071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND) || 2918071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND)) { 2928071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // Types can appear in these contexts. 2938071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus || !isa<TagDecl>(ND)) 294026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith Contexts |= (1LL << CodeCompletionContext::CCC_TopLevel) 295026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ObjCIvarList) 296026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ClassStructUnion) 297026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_Statement) 298026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_Type) 299026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression); 3008071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 3018071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // In C++, types can appear in expressions contexts (for functional casts). 3028071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus) 303026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith Contexts |= (1LL << CodeCompletionContext::CCC_Expression); 3048071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 3058071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // In Objective-C, message sends can send interfaces. In Objective-C++, 3068071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // all types are available due to functional casts. 3078071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus || isa<ObjCInterfaceDecl>(ND)) 308026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith Contexts |= (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver); 3093da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor 3103da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor // In Objective-C, you can only be a subclass of another Objective-C class 3113da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor if (isa<ObjCInterfaceDecl>(ND)) 312026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith Contexts |= (1LL << CodeCompletionContext::CCC_ObjCInterfaceName); 3138071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 3148071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // Deal with tag names. 3158071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (isa<EnumDecl>(ND)) { 316026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith Contexts |= (1LL << CodeCompletionContext::CCC_EnumTag); 3178071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 318a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // Part of the nested-name-specifier in C++0x. 31980ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith if (LangOpts.CPlusPlus11) 320a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = true; 32189cf425f1136f8d24a64ed94450e488b6794dfa4Dmitri Gribenko } else if (const RecordDecl *Record = dyn_cast<RecordDecl>(ND)) { 3228071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (Record->isUnion()) 323026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith Contexts |= (1LL << CodeCompletionContext::CCC_UnionTag); 3248071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor else 325026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith Contexts |= (1LL << CodeCompletionContext::CCC_ClassOrStructTag); 3268071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 3278071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus) 328a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = true; 32952779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor } else if (isa<ClassTemplateDecl>(ND)) 330a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = true; 3318071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } else if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) { 3328071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // Values can appear in these contexts. 333026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith Contexts = (1LL << CodeCompletionContext::CCC_Statement) 334026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_Expression) 335026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression) 336026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver); 3378071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } else if (isa<ObjCProtocolDecl>(ND)) { 338026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith Contexts = (1LL << CodeCompletionContext::CCC_ObjCProtocolName); 3393da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor } else if (isa<ObjCCategoryDecl>(ND)) { 340026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith Contexts = (1LL << CodeCompletionContext::CCC_ObjCCategoryName); 3418071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } else if (isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) { 342026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith Contexts = (1LL << CodeCompletionContext::CCC_Namespace); 3438071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 3448071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // Part of the nested-name-specifier. 345a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = true; 3468071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } 3478071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 3488071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor return Contexts; 3498071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor} 3508071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 35187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregorvoid ASTUnit::CacheCodeCompletionResults() { 35287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor if (!TheSema) 35387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor return; 35487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 355213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer Timer(WantTiming); 356edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer Timer.setOutput("Cache global code completions for " + getMainFileName()); 35787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 35887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Clear out the previous results. 35987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor ClearCachedCompletionResults(); 36087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 36187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Gather the set of global code completions. 3620a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall typedef CodeCompletionResult Result; 3635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Result, 8> Results; 36448601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor CachedCompletionAllocator = new GlobalCodeCompletionAllocator; 3657fdc8fdbfe0d2b4bc0f1a22b2560ca6d86a72c94Argyrios Kyrtzidis CodeCompletionTUInfo CCTUInfo(CachedCompletionAllocator); 36628a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis TheSema->GatherGlobalCodeCompletions(*CachedCompletionAllocator, 3677fdc8fdbfe0d2b4bc0f1a22b2560ca6d86a72c94Argyrios Kyrtzidis CCTUInfo, Results); 36887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 36987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Translate global code completions into cached completions. 370f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor llvm::DenseMap<CanQualType, unsigned> CompletionTypes; 371f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 37287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor for (unsigned I = 0, N = Results.size(); I != N; ++I) { 37387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor switch (Results[I].Kind) { 3748071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor case Result::RK_Declaration: { 375a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor bool IsNestedNameSpecifier = false; 3768071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedCodeCompletionResult CachedResult; 377218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema, 37828a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis *CachedCompletionAllocator, 3797fdc8fdbfe0d2b4bc0f1a22b2560ca6d86a72c94Argyrios Kyrtzidis CCTUInfo, 380d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko IncludeBriefCommentsInCodeCompletion); 3818071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedResult.ShowInContexts = getDeclShowContexts(Results[I].Declaration, 3824e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie Ctx->getLangOpts(), 383a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier); 3848071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedResult.Priority = Results[I].Priority; 3858071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedResult.Kind = Results[I].CursorKind; 38658ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor CachedResult.Availability = Results[I].Availability; 387c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor 388f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // Keep track of the type of this completion in an ASTContext-agnostic 389f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // way. 390c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor QualType UsageType = getDeclUsageType(*Ctx, Results[I].Declaration); 391f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor if (UsageType.isNull()) { 392c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor CachedResult.TypeClass = STC_Void; 393f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedResult.Type = 0; 394f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor } else { 395f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CanQualType CanUsageType 396f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor = Ctx->getCanonicalType(UsageType.getUnqualifiedType()); 397f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedResult.TypeClass = getSimplifiedTypeClass(CanUsageType); 398f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 399f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // Determine whether we have already seen this type. If so, we save 400f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // ourselves the work of formatting the type string by using the 401f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // temporary, CanQualType-based hash table to find the associated value. 402f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor unsigned &TypeValue = CompletionTypes[CanUsageType]; 403f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor if (TypeValue == 0) { 404f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor TypeValue = CompletionTypes.size(); 405f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedCompletionTypes[QualType(CanUsageType).getAsString()] 406f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor = TypeValue; 407f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor } 408f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 409f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedResult.Type = TypeValue; 410c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor } 411f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 4128071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedCompletionResults.push_back(CachedResult); 413a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor 414a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor /// Handle nested-name-specifiers in C++. 4154e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (TheSema->Context.getLangOpts().CPlusPlus && 416a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier && !Results[I].StartsNestedNameSpecifier) { 417a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // The contexts in which a nested-name-specifier can appear in C++. 418026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith uint64_t NNSContexts 419026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith = (1LL << CodeCompletionContext::CCC_TopLevel) 420026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ObjCIvarList) 421026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ClassStructUnion) 422026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_Statement) 423026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_Expression) 424026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver) 425026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_EnumTag) 426026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_UnionTag) 427026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ClassOrStructTag) 428026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_Type) 429026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_PotentiallyQualifiedName) 430026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression); 431a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor 432a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor if (isa<NamespaceDecl>(Results[I].Declaration) || 433a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor isa<NamespaceAliasDecl>(Results[I].Declaration)) 434026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith NNSContexts |= (1LL << CodeCompletionContext::CCC_Namespace); 435a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor 436a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor if (unsigned RemainingContexts 437a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor = NNSContexts & ~CachedResult.ShowInContexts) { 438a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // If there any contexts where this completion can be a 439a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // nested-name-specifier but isn't already an option, create a 440a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // nested-name-specifier completion. 441a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Results[I].StartsNestedNameSpecifier = true; 442218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor CachedResult.Completion 443218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor = Results[I].CreateCodeCompletionString(*TheSema, 44428a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis *CachedCompletionAllocator, 4457fdc8fdbfe0d2b4bc0f1a22b2560ca6d86a72c94Argyrios Kyrtzidis CCTUInfo, 446d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko IncludeBriefCommentsInCodeCompletion); 447a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedResult.ShowInContexts = RemainingContexts; 448a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedResult.Priority = CCP_NestedNameSpecifier; 449a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedResult.TypeClass = STC_Void; 450a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedResult.Type = 0; 451a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedCompletionResults.push_back(CachedResult); 452a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor } 453a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor } 45487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor break; 4558071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } 4568071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 45787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor case Result::RK_Keyword: 45887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor case Result::RK_Pattern: 45987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Ignore keywords and patterns; we don't care, since they are so 46087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // easily regenerated. 46187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor break; 46287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 46387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor case Result::RK_Macro: { 46487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedCodeCompletionResult CachedResult; 465218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor CachedResult.Completion 466218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor = Results[I].CreateCodeCompletionString(*TheSema, 46728a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis *CachedCompletionAllocator, 4687fdc8fdbfe0d2b4bc0f1a22b2560ca6d86a72c94Argyrios Kyrtzidis CCTUInfo, 469d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko IncludeBriefCommentsInCodeCompletion); 47087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedResult.ShowInContexts 471026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith = (1LL << CodeCompletionContext::CCC_TopLevel) 472026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ObjCInterface) 473026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ObjCImplementation) 474026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ObjCIvarList) 475026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ClassStructUnion) 476026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_Statement) 477026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_Expression) 478026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver) 479026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_MacroNameUse) 480026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_PreprocessorExpression) 481026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression) 482026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_OtherWithMacros); 4832ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor 48487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedResult.Priority = Results[I].Priority; 48587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedResult.Kind = Results[I].CursorKind; 48658ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor CachedResult.Availability = Results[I].Availability; 4871827e10051638770ad9ccf3e285caf95f995afd1Douglas Gregor CachedResult.TypeClass = STC_Void; 488f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedResult.Type = 0; 48987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedCompletionResults.push_back(CachedResult); 49087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor break; 49187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 49287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 49387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 4949b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 4959b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor // Save the current top-level hash value. 4969b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CompletionCacheTopLevelHashValue = CurrentTopLevelHashValue; 49787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor} 49887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 49987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregorvoid ASTUnit::ClearCachedCompletionResults() { 50087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedCompletionResults.clear(); 501f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedCompletionTypes.clear(); 50248601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor CachedCompletionAllocator = 0; 50387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor} 50487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 5050853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisnamespace { 5060853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 507c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl/// \brief Gathers information from ASTReader that will be used to initialize 5080853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis/// a Preprocessor. 5093c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redlclass ASTInfoCollector : public ASTReaderListener { 510998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor Preprocessor &PP; 511bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor ASTContext &Context; 5120853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis LangOptions &LangOpt; 51357016dda61498294120b1a881d9e6606337b29d9Douglas Gregor IntrusiveRefCntPtr<TargetOptions> &TargetOpts; 514c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<TargetInfo> &Target; 5150853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned &Counter; 5161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 517bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor bool InitializedLanguage; 5180853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidispublic: 519bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor ASTInfoCollector(Preprocessor &PP, ASTContext &Context, LangOptions &LangOpt, 52057016dda61498294120b1a881d9e6606337b29d9Douglas Gregor IntrusiveRefCntPtr<TargetOptions> &TargetOpts, 521c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<TargetInfo> &Target, 5220853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned &Counter) 523f9ba851c9b5db8ea30846215e737702a1cc2c194Argyrios Kyrtzidis : PP(PP), Context(Context), LangOpt(LangOpt), 5249a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor TargetOpts(TargetOpts), Target(Target), 525f9ba851c9b5db8ea30846215e737702a1cc2c194Argyrios Kyrtzidis Counter(Counter), 526bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor InitializedLanguage(false) {} 5271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 52827ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor virtual bool ReadLanguageOptions(const LangOptions &LangOpts, 52938295beb73db5f90bfcf31625fb81dbc3b96290aDouglas Gregor bool Complain) { 530900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis if (InitializedLanguage) 531998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor return false; 532998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor 5330853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis LangOpt = LangOpts; 534bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor InitializedLanguage = true; 535900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis 536900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis updated(); 5370853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return false; 5380853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 5391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 54027ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor virtual bool ReadTargetOptions(const TargetOptions &TargetOpts, 54138295beb73db5f90bfcf31625fb81dbc3b96290aDouglas Gregor bool Complain) { 542998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor // If we've already initialized the target, don't do it again. 543900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis if (Target) 544998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor return false; 545998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor 54657016dda61498294120b1a881d9e6606337b29d9Douglas Gregor this->TargetOpts = new TargetOptions(TargetOpts); 54749a87549f4dc95ecb3d8a593b71df7c167a51f85Douglas Gregor Target = TargetInfo::CreateTargetInfo(PP.getDiagnostics(), 54849a87549f4dc95ecb3d8a593b71df7c167a51f85Douglas Gregor &*this->TargetOpts); 5497f1863326488813e7648845f3cec5225770b1a0bArgyrios Kyrtzidis 550900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis updated(); 5510853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return false; 5520853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 5531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 55462288edde26ff4af9fc079c979a0e1bdc577ce9dArgyrios Kyrtzidis virtual void ReadCounter(const serialization::ModuleFile &M, unsigned Value) { 5550853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Counter = Value; 5560853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 5577f1863326488813e7648845f3cec5225770b1a0bArgyrios Kyrtzidis 5587f1863326488813e7648845f3cec5225770b1a0bArgyrios Kyrtzidisprivate: 559900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis void updated() { 560900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis if (!Target || !InitializedLanguage) 561900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis return; 562900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis 563900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis // Inform the target of the language options. 564900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis // 565900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis // FIXME: We shouldn't need to do this, the target should be immutable once 566900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis // created. This complexity should be lifted elsewhere. 567900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis Target->setForcedLangOptions(LangOpt); 568900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis 569900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis // Initialize the preprocessor. 570900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis PP.Initialize(*Target); 571900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis 572900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis // Initialize the ASTContext 573900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis Context.InitBuiltinTypes(*Target); 5746ebf09130479bc7605aa09a3e6c4dc2ba3513495Dmitri Gribenko 5756ebf09130479bc7605aa09a3e6c4dc2ba3513495Dmitri Gribenko // We didn't have access to the comment options when the ASTContext was 5766ebf09130479bc7605aa09a3e6c4dc2ba3513495Dmitri Gribenko // constructed, so register them now. 5776ebf09130479bc7605aa09a3e6c4dc2ba3513495Dmitri Gribenko Context.getCommentCommandTraits().registerCommentOptions( 5786ebf09130479bc7605aa09a3e6c4dc2ba3513495Dmitri Gribenko LangOpt.CommentOpts); 5797f1863326488813e7648845f3cec5225770b1a0bArgyrios Kyrtzidis } 5800853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis}; 5810853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 582a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor /// \brief Diagnostic consumer that saves each diagnostic it is given. 58326e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikieclass StoredDiagnosticConsumer : public DiagnosticConsumer { 5845f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<StoredDiagnostic> &StoredDiags; 585a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor SourceManager *SourceMgr; 586a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor 587a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorpublic: 58826e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikie explicit StoredDiagnosticConsumer( 5895f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<StoredDiagnostic> &StoredDiags) 590a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor : StoredDiags(StoredDiags), SourceMgr(0) { } 591a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor 592a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor virtual void BeginSourceFile(const LangOptions &LangOpts, 593a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor const Preprocessor *PP = 0) { 594a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor if (PP) 595a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor SourceMgr = &PP->getSourceManager(); 596a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor } 597a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor 598d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie virtual void HandleDiagnostic(DiagnosticsEngine::Level Level, 59940847cfb58acc3cac7d68727df9455ac45f2e118David Blaikie const Diagnostic &Info); 600a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}; 601a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 602a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor/// \brief RAII object that optionally captures diagnostics, if 603a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor/// there is no diagnostic client to capture them already. 604a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorclass CaptureDroppedDiagnostics { 605d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie DiagnosticsEngine &Diags; 60626e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikie StoredDiagnosticConsumer Client; 60778ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie DiagnosticConsumer *PreviousClient; 608a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 609a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorpublic: 610d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie CaptureDroppedDiagnostics(bool RequestCapture, DiagnosticsEngine &Diags, 6115f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<StoredDiagnostic> &StoredDiags) 612bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor : Diags(Diags), Client(StoredDiags), PreviousClient(0) 613a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor { 614bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor if (RequestCapture || Diags.getClient() == 0) { 615bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor PreviousClient = Diags.takeClient(); 616a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor Diags.setClient(&Client); 617bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor } 618a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor } 619a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 620a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor ~CaptureDroppedDiagnostics() { 621bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor if (Diags.getClient() == &Client) { 622bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor Diags.takeClient(); 623bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor Diags.setClient(PreviousClient); 624bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor } 625a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor } 626a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}; 627a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 6280853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis} // anonymous namespace 6290853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 63026e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikievoid StoredDiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level Level, 63140847cfb58acc3cac7d68727df9455ac45f2e118David Blaikie const Diagnostic &Info) { 632f2224d89a6ae65a3839529e26d0f6d025d83d6bbArgyrios Kyrtzidis // Default implementation (Warnings/errors count). 63378ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie DiagnosticConsumer::HandleDiagnostic(Level, Info); 634f2224d89a6ae65a3839529e26d0f6d025d83d6bbArgyrios Kyrtzidis 635a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor // Only record the diagnostic if it's part of the source manager we know 636a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor // about. This effectively drops diagnostics from modules we're building. 637a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor // FIXME: In the long run, ee don't want to drop source managers from modules. 638a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor if (!Info.hasSourceManager() || &Info.getSourceManager() == SourceMgr) 639a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor StoredDiags.push_back(StoredDiagnostic(Level, Info)); 640a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor} 641a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 6427eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios KyrtzidisASTMutationListener *ASTUnit::getASTMutationListener() { 6437eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis if (WriterData) 6447eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis return &WriterData->Writer; 6457eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis return 0; 6467eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis} 6477eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis 648900ab95e12bb7483971640a91075699eec391804Argyrios KyrtzidisASTDeserializationListener *ASTUnit::getDeserializationListener() { 649900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis if (WriterData) 650900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis return &WriterData->Writer; 651900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis return 0; 652900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis} 653900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis 6545f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerllvm::MemoryBuffer *ASTUnit::getBufferForFile(StringRef Filename, 65575dfb65c38d51772df9a00ce2d2feeefd55667adChris Lattner std::string *ErrorStr) { 65639b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner assert(FileMgr); 65775dfb65c38d51772df9a00ce2d2feeefd55667adChris Lattner return FileMgr->getBufferForFile(Filename, ErrorStr); 658389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis} 659389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis 660e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor/// \brief Configure the diagnostics object for use with ASTUnit. 661c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmithvoid ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> &Diags, 6620b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor const char **ArgBegin, const char **ArgEnd, 663e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor ASTUnit &AST, bool CaptureDiagnostics) { 664e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor if (!Diags.getPtr()) { 665e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor // No diagnostics engine was provided, so create our own diagnostics object 666e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor // with the default options. 66778ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie DiagnosticConsumer *Client = 0; 668e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor if (CaptureDiagnostics) 66926e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikie Client = new StoredDiagnosticConsumer(AST.StoredDiagnostics); 67002c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions(), 671d47afb96a3f988e6d21a92fe4dfe875ab227c7c0Sean Silva Client, 672cc2b653c319599f502425d2c3de29865d47bb9e4Douglas Gregor /*ShouldOwnClient=*/true); 673e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor } else if (CaptureDiagnostics) { 67426e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikie Diags->setClient(new StoredDiagnosticConsumer(AST.StoredDiagnostics)); 675e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor } 676e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor} 677e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor 6783c7f4134603d04b44f997b43c0a9def270f25386Sebastian RedlASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, 679c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 680389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis const FileSystemOptions &FileSystemOpts, 6815cf48766d626ff6b223acc9d4b7e415ca8480836Ted Kremenek bool OnlyLocalDecls, 6824db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFile *RemappedFiles, 683a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor unsigned NumRemappedFiles, 684bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis bool CaptureDiagnostics, 685ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis bool AllowPCHWithCompilerErrors, 686ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis bool UserFilesAreVolatile) { 6876f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<ASTUnit> AST(new ASTUnit(true)); 688b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek 689b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek // Recover resources if we crash before exiting this method. 69025a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> 69125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek ASTUnitCleanup(AST.get()); 692d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, 693d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > 69425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek DiagCleanup(Diags.getPtr()); 695b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek 6960b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics); 697abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 6987d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor AST->OnlyLocalDecls = OnlyLocalDecls; 699e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor AST->CaptureDiagnostics = CaptureDiagnostics; 70028019772db70d4547be05a042eb950bc910f134fDouglas Gregor AST->Diagnostics = Diags; 7014f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->FileMgr = new FileManager(FileSystemOpts); 702ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis AST->UserFilesAreVolatile = UserFilesAreVolatile; 7034f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->SourceMgr = new SourceManager(AST->getDiagnostics(), 704ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis AST->getFileManager(), 705ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis UserFilesAreVolatile); 706c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregor AST->HSOpts = new HeaderSearchOptions(); 707c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregor 708c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregor AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts, 709c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregor AST->getFileManager(), 71051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor AST->getDiagnostics(), 711dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor AST->ASTFileLangOpts, 712dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor /*Target=*/0)); 713914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor 7144db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor for (unsigned I = 0; I != NumRemappedFiles; ++I) { 715b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; 716b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (const llvm::MemoryBuffer * 717b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { 718b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // Create the file entry for the file that we're mapping from. 719b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *FromFile 720b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis = AST->getFileManager().getVirtualFile(RemappedFiles[I].first, 721b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf->getBufferSize(), 722b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 0); 723b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (!FromFile) { 724b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file) 725b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis << RemappedFiles[I].first; 726b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis delete memBuf; 727b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis continue; 728b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 729b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 730b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // Override the contents of the "from" file with the contents of 731b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // the "to" file. 732b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis AST->getSourceManager().overrideFileContents(FromFile, memBuf); 733b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 734b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } else { 735b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const char *fname = fileOrBuf.get<const char *>(); 736b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *ToFile = AST->FileMgr->getFile(fname); 737b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (!ToFile) { 738b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis AST->getDiagnostics().Report(diag::err_fe_remap_missing_to_file) 739b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis << RemappedFiles[I].first << fname; 740b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis continue; 741b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 742b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 743b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // Create the file entry for the file that we're mapping from. 744b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *FromFile 745b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis = AST->getFileManager().getVirtualFile(RemappedFiles[I].first, 746b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis ToFile->getSize(), 747b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 0); 748b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (!FromFile) { 749b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file) 750b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis << RemappedFiles[I].first; 751b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis delete memBuf; 752b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis continue; 753b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 754b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 755b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // Override the contents of the "from" file with the contents of 756b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // the "to" file. 757b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis AST->getSourceManager().overrideFileContents(FromFile, ToFile); 7584db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 7594db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 7604db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 7610853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // Gather Info for preprocessor construction later on. 7621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7630853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis HeaderSearch &HeaderInfo = *AST->HeaderInfo.get(); 7640853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned Counter; 7650853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 7666f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<ASTReader> Reader; 7670853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 76836a16498ff911a218f26c7955376bbe99ddb16dfDouglas Gregor AST->PP = new Preprocessor(new PreprocessorOptions(), 76936a16498ff911a218f26c7955376bbe99ddb16dfDouglas Gregor AST->getDiagnostics(), AST->ASTFileLangOpts, 770998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor /*Target=*/0, AST->getSourceManager(), HeaderInfo, 771998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor *AST, 772998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor /*IILookup=*/0, 773998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor /*OwnsHeaderSearch=*/false, 774998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor /*DelayInitialization=*/true); 775bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Preprocessor &PP = *AST->PP; 776bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor 777bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor AST->Ctx = new ASTContext(AST->ASTFileLangOpts, 778bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor AST->getSourceManager(), 779bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor /*Target=*/0, 780bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor PP.getIdentifierTable(), 781bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor PP.getSelectorTable(), 782bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor PP.getBuiltinInfo(), 783bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor /* size_reserve = */0, 784bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor /*DelayInitialization=*/true); 785bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor ASTContext &Context = *AST->Ctx; 786998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor 78798e95bf1c84560684356088af7f4878bdacb5856Argyrios Kyrtzidis bool disableValid = false; 78898e95bf1c84560684356088af7f4878bdacb5856Argyrios Kyrtzidis if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION")) 78998e95bf1c84560684356088af7f4878bdacb5856Argyrios Kyrtzidis disableValid = true; 790bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis Reader.reset(new ASTReader(PP, Context, 791bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis /*isysroot=*/"", 79298e95bf1c84560684356088af7f4878bdacb5856Argyrios Kyrtzidis /*DisableValidation=*/disableValid, 793bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis AllowPCHWithCompilerErrors)); 7948c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek 7958c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek // Recover resources if we crash before exiting this method. 7968c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<ASTReader> 7978c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek ReaderCleanup(Reader.get()); 7988c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek 799bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Reader->setListener(new ASTInfoCollector(*AST->PP, Context, 800f9ba851c9b5db8ea30846215e737702a1cc2c194Argyrios Kyrtzidis AST->ASTFileLangOpts, 8019a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor AST->TargetOpts, AST->Target, 8024399890d385171eff39927a26823426046d33456Douglas Gregor Counter)); 803cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar 80438295beb73db5f90bfcf31625fb81dbc3b96290aDouglas Gregor switch (Reader->ReadAST(Filename, serialization::MK_MainFile, 805958bcaf3d4e0c1ae46de3e84e7c2a7638c3c5286Argyrios Kyrtzidis SourceLocation(), ASTReader::ARR_None)) { 806c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl case ASTReader::Success: 8070853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis break; 8081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 809c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl case ASTReader::Failure: 810677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor case ASTReader::Missing: 8114825fd7fbb3fe87cdf8da9bccc1361fac45bdf2dDouglas Gregor case ASTReader::OutOfDate: 8124825fd7fbb3fe87cdf8da9bccc1361fac45bdf2dDouglas Gregor case ASTReader::VersionMismatch: 8134825fd7fbb3fe87cdf8da9bccc1361fac45bdf2dDouglas Gregor case ASTReader::ConfigurationMismatch: 8144825fd7fbb3fe87cdf8da9bccc1361fac45bdf2dDouglas Gregor case ASTReader::HadErrors: 8153687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch); 8160853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return NULL; 8170853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 8181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 81968d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar AST->OriginalSourceFile = Reader->getOriginalSourceFile(); 82068d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar 8210853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis PP.setCounterValue(Counter); 8221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 823c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl // Attach the AST reader to the AST context as an external AST 8240853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // source, so that declarations will be deserialized from the 8253c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl // AST file as needed. 826c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl ASTReader *ReaderPtr = Reader.get(); 8276f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<ExternalASTSource> Source(Reader.take()); 8288c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek 8298c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek // Unregister the cleanup for ASTReader. It will get cleaned up 8308c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek // by the ASTUnit cleanup. 8318c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek ReaderCleanup.unregister(); 8328c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek 8330853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Context.setExternalSource(Source); 8340853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 835914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor // Create an AST consumer, even though it isn't used. 836914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor AST->Consumer.reset(new ASTConsumer); 837914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor 838c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl // Create a semantic analysis object and tell the AST reader about it. 839914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor AST->TheSema.reset(new Sema(PP, Context, *AST->Consumer)); 840914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor AST->TheSema->Initialize(); 841914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor ReaderPtr->InitializeSema(*AST->TheSema); 84262ba9f61af6177992d8cd2e3306257e1213b1bd3Argyrios Kyrtzidis AST->Reader = ReaderPtr; 843914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor 844a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor // Tell the diagnostic client that we have started a source file. 845a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor AST->getDiagnostics().getClient()->BeginSourceFile(Context.getLangOpts(),&PP); 846a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor 8471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return AST.take(); 8480853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis} 849521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 850521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarnamespace { 851521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 8529b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor/// \brief Preprocessor callback class that updates a hash value with the names 8539b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor/// of all macros that have been defined by the translation unit. 8549b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregorclass MacroDefinitionTrackerPPCallbacks : public PPCallbacks { 8559b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor unsigned &Hash; 8569b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 8579b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregorpublic: 8589b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor explicit MacroDefinitionTrackerPPCallbacks(unsigned &Hash) : Hash(Hash) { } 8599b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 860c515978bd3a703aa733f846a0094ffa84d149074Argyrios Kyrtzidis virtual void MacroDefined(const Token &MacroNameTok, 861c515978bd3a703aa733f846a0094ffa84d149074Argyrios Kyrtzidis const MacroDirective *MD) { 8629b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Hash = llvm::HashString(MacroNameTok.getIdentifierInfo()->getName(), Hash); 8639b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 8649b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor}; 8659b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 8669b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor/// \brief Add the given declaration to the hash of all top-level entities. 8679b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregorvoid AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) { 8689b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (!D) 8699b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return; 8709b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 8719b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor DeclContext *DC = D->getDeclContext(); 8729b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (!DC) 8739b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return; 8749b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 8759b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (!(DC->isTranslationUnit() || DC->getLookupParent()->isTranslationUnit())) 8769b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return; 8779b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 8789b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 8799b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (ND->getIdentifier()) 8809b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Hash = llvm::HashString(ND->getIdentifier()->getName(), Hash); 8819b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor else if (DeclarationName Name = ND->getDeclName()) { 8829b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor std::string NameStr = Name.getAsString(); 8839b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Hash = llvm::HashString(NameStr, Hash); 8849b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 8859b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return; 8861f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis } 8871f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis 8881f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis if (ImportDecl *ImportD = dyn_cast<ImportDecl>(D)) { 8891f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis if (Module *Mod = ImportD->getImportedModule()) { 8901f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis std::string ModName = Mod->getFullModuleName(); 8911f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis Hash = llvm::HashString(ModName, Hash); 8921f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis } 8931f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis return; 8941f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis } 8959b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor} 8969b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 897f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerConsumer : public ASTConsumer { 898f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar ASTUnit &Unit; 8999b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor unsigned &Hash; 9009b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 901f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic: 9029b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor TopLevelDeclTrackerConsumer(ASTUnit &_Unit, unsigned &Hash) 9039b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor : Unit(_Unit), Hash(Hash) { 9049b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Hash = 0; 9059b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 9069b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 907332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis void handleTopLevelDecl(Decl *D) { 90835593a9add85353532519f8eba5ec513a611aac5Argyrios Kyrtzidis if (!D) 90935593a9add85353532519f8eba5ec513a611aac5Argyrios Kyrtzidis return; 91035593a9add85353532519f8eba5ec513a611aac5Argyrios Kyrtzidis 911332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis // FIXME: Currently ObjC method declarations are incorrectly being 912332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis // reported as top-level declarations, even though their DeclContext 913332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis // is the containing ObjC @interface/@implementation. This is a 914332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis // fundamental problem in the parser right now. 915332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis if (isa<ObjCMethodDecl>(D)) 916332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis return; 917332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 918332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis AddTopLevelDeclarationToHash(D, Hash); 919332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis Unit.addTopLevelDecl(D); 920332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 921332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis handleFileLevelDecl(D); 922332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis } 923332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 924332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis void handleFileLevelDecl(Decl *D) { 925332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis Unit.addFileLevelDecl(D); 926332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis if (NamespaceDecl *NSD = dyn_cast<NamespaceDecl>(D)) { 927332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis for (NamespaceDecl::decl_iterator 928332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis I = NSD->decls_begin(), E = NSD->decls_end(); I != E; ++I) 929332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis handleFileLevelDecl(*I); 930da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek } 931f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar } 93227372b4f1f402e95dd479ecf40c39ca71c15619fSebastian Redl 93388c2596edc8eb475e20f6033de1ea01669695a0cArgyrios Kyrtzidis bool HandleTopLevelDecl(DeclGroupRef D) { 934332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) 935332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis handleTopLevelDecl(*it); 93688c2596edc8eb475e20f6033de1ea01669695a0cArgyrios Kyrtzidis return true; 937332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis } 938332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 93927372b4f1f402e95dd479ecf40c39ca71c15619fSebastian Redl // We're not interested in "interesting" decls. 94027372b4f1f402e95dd479ecf40c39ca71c15619fSebastian Redl void HandleInterestingDecl(DeclGroupRef) {} 941332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 942332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) { 943332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) 944332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis handleTopLevelDecl(*it); 945332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis } 946900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis 9477eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis virtual ASTMutationListener *GetASTMutationListener() { 9487eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis return Unit.getASTMutationListener(); 9497eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis } 9507eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis 951900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis virtual ASTDeserializationListener *GetASTDeserializationListener() { 952900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis return Unit.getDeserializationListener(); 953900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis } 954f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar}; 955f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 956f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerAction : public ASTFrontendAction { 957f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic: 958f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar ASTUnit &Unit; 959f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 960521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 9615f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef InFile) { 9629b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CI.getPreprocessor().addPPCallbacks( 9639b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor new MacroDefinitionTrackerPPCallbacks(Unit.getCurrentTopLevelHashValue())); 9649b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return new TopLevelDeclTrackerConsumer(Unit, 9659b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Unit.getCurrentTopLevelHashValue()); 966521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar } 967521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 968521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarpublic: 969f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {} 970f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 971521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar virtual bool hasCodeCompletionSupport() const { return false; } 972467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor virtual TranslationUnitKind getTranslationUnitKind() { 973467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor return Unit.getTranslationUnitKind(); 974df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 975521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar}; 976521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 977b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramerclass PrecompilePreambleAction : public ASTFrontendAction { 978b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer ASTUnit &Unit; 979b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer bool HasEmittedPreamblePCH; 980b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer 981b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramerpublic: 982b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer explicit PrecompilePreambleAction(ASTUnit &Unit) 983b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer : Unit(Unit), HasEmittedPreamblePCH(false) {} 984b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer 985b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 986b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer StringRef InFile); 987b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer bool hasEmittedPreamblePCH() const { return HasEmittedPreamblePCH; } 988b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer void setHasEmittedPreamblePCH() { HasEmittedPreamblePCH = true; } 989b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer virtual bool shouldEraseOutputFiles() { return !hasEmittedPreamblePCH(); } 990b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer 991b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer virtual bool hasCodeCompletionSupport() const { return false; } 992b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer virtual bool hasASTFileSupport() const { return false; } 993b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer virtual TranslationUnitKind getTranslationUnitKind() { return TU_Prefix; } 994b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer}; 995b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer 99692ddef1bf843e1e18c040d69f48a6bf0bc7c776aArgyrios Kyrtzidisclass PrecompilePreambleConsumer : public PCHGenerator { 9971d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor ASTUnit &Unit; 998b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer unsigned &Hash; 999eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor std::vector<Decl *> TopLevelDecls; 1000b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer PrecompilePreambleAction *Action; 1001b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer 10021d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorpublic: 1003b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer PrecompilePreambleConsumer(ASTUnit &Unit, PrecompilePreambleAction *Action, 1004b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer const Preprocessor &PP, StringRef isysroot, 1005b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer raw_ostream *Out) 10061f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis : PCHGenerator(PP, "", 0, isysroot, Out, /*AllowASTWithErrors=*/true), 1007b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer Unit(Unit), Hash(Unit.getCurrentTopLevelHashValue()), Action(Action) { 10089b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Hash = 0; 10099b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 10101d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 101188c2596edc8eb475e20f6033de1ea01669695a0cArgyrios Kyrtzidis virtual bool HandleTopLevelDecl(DeclGroupRef D) { 10121d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) { 10131d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor Decl *D = *it; 10141d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // FIXME: Currently ObjC method declarations are incorrectly being 10151d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // reported as top-level declarations, even though their DeclContext 10161d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // is the containing ObjC @interface/@implementation. This is a 10171d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // fundamental problem in the parser right now. 10181d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor if (isa<ObjCMethodDecl>(D)) 10191d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor continue; 10209b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor AddTopLevelDeclarationToHash(D, Hash); 1021eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDecls.push_back(D); 1022eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 102388c2596edc8eb475e20f6033de1ea01669695a0cArgyrios Kyrtzidis return true; 1024eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 1025eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 1026eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor virtual void HandleTranslationUnit(ASTContext &Ctx) { 1027eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor PCHGenerator::HandleTranslationUnit(Ctx); 10281f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis if (hasEmittedPCH()) { 1029eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // Translate the top-level declarations we captured during 1030eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // parsing into declaration IDs in the precompiled 1031eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // preamble. This will allow us to deserialize those top-level 1032eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // declarations when requested. 103351e75aecf4fb303b91c9e54fd88e3509e5acc7a6Argyrios Kyrtzidis for (unsigned I = 0, N = TopLevelDecls.size(); I != N; ++I) { 103451e75aecf4fb303b91c9e54fd88e3509e5acc7a6Argyrios Kyrtzidis Decl *D = TopLevelDecls[I]; 103551e75aecf4fb303b91c9e54fd88e3509e5acc7a6Argyrios Kyrtzidis // Invalid top-level decls may not have been serialized. 103651e75aecf4fb303b91c9e54fd88e3509e5acc7a6Argyrios Kyrtzidis if (D->isInvalidDecl()) 103751e75aecf4fb303b91c9e54fd88e3509e5acc7a6Argyrios Kyrtzidis continue; 103851e75aecf4fb303b91c9e54fd88e3509e5acc7a6Argyrios Kyrtzidis Unit.addTopLevelDeclFromPreamble(getWriter().getDeclID(D)); 103951e75aecf4fb303b91c9e54fd88e3509e5acc7a6Argyrios Kyrtzidis } 1040b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer 1041b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer Action->setHasEmittedPreamblePCH(); 10421d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor } 10431d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor } 10441d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor}; 10451d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 1046b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer} 10471d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 1048b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin KramerASTConsumer *PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI, 1049b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer StringRef InFile) { 1050b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer std::string Sysroot; 1051b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer std::string OutputFile; 1052b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer raw_ostream *OS = 0; 1053b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer if (GeneratePCHAction::ComputeASTConsumerArguments(CI, InFile, Sysroot, 1054b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer OutputFile, OS)) 1055b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer return 0; 10561f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis 1057b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer if (!CI.getFrontendOpts().RelocatablePCH) 1058b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer Sysroot.clear(); 10591d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 1060b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer CI.getPreprocessor().addPPCallbacks(new MacroDefinitionTrackerPPCallbacks( 1061b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer Unit.getCurrentTopLevelHashValue())); 1062b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer return new PrecompilePreambleConsumer(Unit, this, CI.getPreprocessor(), 1063b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer Sysroot, OS); 1064521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar} 1065521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 1066fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin Kramerstatic bool isNonDriverDiag(const StoredDiagnostic &StoredDiag) { 1067fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin Kramer return StoredDiag.getLocation().isValid(); 1068fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin Kramer} 1069fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin Kramer 1070fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin Kramerstatic void 1071fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin KramercheckAndRemoveNonDriverDiags(SmallVectorImpl<StoredDiagnostic> &StoredDiags) { 10727f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis // Get rid of stored diagnostics except the ones from the driver which do not 10737f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis // have a source location. 1074fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin Kramer StoredDiags.erase( 1075fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin Kramer std::remove_if(StoredDiags.begin(), StoredDiags.end(), isNonDriverDiag), 1076fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin Kramer StoredDiags.end()); 10777f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis} 10787f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis 10797f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidisstatic void checkAndSanitizeDiags(SmallVectorImpl<StoredDiagnostic> & 10807f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis StoredDiagnostics, 10817f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis SourceManager &SM) { 10827f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis // The stored diagnostic has the old source manager in it; update 10837f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis // the locations to refer into the new source manager. Since we've 10847f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis // been careful to make sure that the source manager's state 10857f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis // before and after are identical, so that we can reuse the source 10867f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis // location itself. 10877f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis for (unsigned I = 0, N = StoredDiagnostics.size(); I < N; ++I) { 10887f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis if (StoredDiagnostics[I].getLocation().isValid()) { 10897f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis FullSourceLoc Loc(StoredDiagnostics[I].getLocation(), SM); 10907f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis StoredDiagnostics[I].setLocation(Loc); 10917f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis } 10927f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis } 10937f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis} 10947f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis 1095abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// Parse the source file into a translation unit using the given compiler 1096abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// invocation, replacing the current translation unit. 1097abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// 1098abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// \returns True if a failure occurred that causes the ASTUnit not to 1099abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// contain any translation-unit information, false otherwise. 1100754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregorbool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { 110128233428da1ebec20c893d6297ae3191318940ddDouglas Gregor delete SavedMainFileBuffer; 110228233428da1ebec20c893d6297ae3191318940ddDouglas Gregor SavedMainFileBuffer = 0; 110328233428da1ebec20c893d6297ae3191318940ddDouglas Gregor 11044f32786ac45210143654390177105eb749b614e9Ted Kremenek if (!Invocation) { 1105671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete OverrideMainBuffer; 1106abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 1107671947b18dba342f9aba022ee992babef325a833Douglas Gregor } 1108abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1109521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the compiler instance to use for building the AST. 11106f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<CompilerInstance> Clang(new CompilerInstance()); 111103201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 111203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek // Recover resources if we crash before exiting this method. 111325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> 111425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek CICleanup(Clang.get()); 111503201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 1116c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<CompilerInvocation> 111726d43cd3a088d4f1f1645328db3b73afbc7eaa61Argyrios Kyrtzidis CCInvocation(new CompilerInvocation(*Invocation)); 111826d43cd3a088d4f1f1645328db3b73afbc7eaa61Argyrios Kyrtzidis 111926d43cd3a088d4f1f1645328db3b73afbc7eaa61Argyrios Kyrtzidis Clang->setInvocation(CCInvocation.getPtr()); 11208616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile(); 1121abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 11221abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set up diagnostics, capturing any diagnostics that would 11231abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // otherwise be dropped. 112403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setDiagnostics(&getDiagnostics()); 11253687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor 1126521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the target instance. 112703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), 112849a87549f4dc95ecb3d8a593b71df7c167a51f85Douglas Gregor &Clang->getTargetOpts())); 112903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek if (!Clang->hasTarget()) { 1130671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete OverrideMainBuffer; 1131abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 1132671947b18dba342f9aba022ee992babef325a833Douglas Gregor } 1133671947b18dba342f9aba022ee992babef325a833Douglas Gregor 1134521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Inform the target of the language options. 1135521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // 1136521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // FIXME: We shouldn't need to do this, the target should be immutable once 1137521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // created. This complexity should be lifted elsewhere. 113803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); 1139abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 114003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs.size() == 1 && 1141521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar "Invocation must have exactly one source file!"); 11428616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis assert(Clang->getFrontendOpts().Inputs[0].getKind() != IK_AST && 1143521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar "FIXME: AST inputs not yet supported here!"); 11448616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis assert(Clang->getFrontendOpts().Inputs[0].getKind() != IK_LLVM_IR && 1145faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar "IR inputs not support here!"); 1146521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 1147abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Configure the various subsystems. 1148abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // FIXME: Should we retain the previous file manager? 1149d3b74d9ca4f239a7a90ad193378c494306c57352Ted Kremenek LangOpts = &Clang->getLangOpts(); 115003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek FileSystemOpts = Clang->getFileSystemOpts(); 11514f32786ac45210143654390177105eb749b614e9Ted Kremenek FileMgr = new FileManager(FileSystemOpts); 1152ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis SourceMgr = new SourceManager(getDiagnostics(), *FileMgr, 1153ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis UserFilesAreVolatile); 1154914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor TheSema.reset(); 11554f32786ac45210143654390177105eb749b614e9Ted Kremenek Ctx = 0; 11564f32786ac45210143654390177105eb749b614e9Ted Kremenek PP = 0; 115762ba9f61af6177992d8cd2e3306257e1213b1bd3Argyrios Kyrtzidis Reader = 0; 1158abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1159abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Clear out old caches and data. 1160abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor TopLevelDecls.clear(); 1161332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis clearFileLevelDecls(); 1162abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor CleanTemporaryFiles(); 1163c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 1164f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor if (!OverrideMainBuffer) { 11657f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis checkAndRemoveNonDriverDiags(StoredDiagnostics); 1166f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor TopLevelDeclsInPreamble.clear(); 1167f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor } 1168f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor 1169521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create a file manager object to provide access to and cache the filesystem. 117003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setFileManager(&getFileManager()); 1171abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1172521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the source manager. 117303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setSourceManager(&getSourceManager()); 1174abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1175f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // If the main file has been overridden due to the use of a preamble, 1176f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // make that override happen and introduce the preamble. 117703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek PreprocessorOptions &PreprocessorOpts = Clang->getPreprocessorOpts(); 1178f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (OverrideMainBuffer) { 1179f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); 1180f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size(); 1181f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second 1182f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor = PreambleEndsAtStartOfLine; 11831872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek PreprocessorOpts.ImplicitPCHInclude = getPreambleFile(this); 1184fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor PreprocessorOpts.DisablePCHValidation = true; 118528233428da1ebec20c893d6297ae3191318940ddDouglas Gregor 1186c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // The stored diagnostic has the old source manager in it; update 1187c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // the locations to refer into the new source manager. Since we've 1188c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // been careful to make sure that the source manager's state 1189c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // before and after are identical, so that we can reuse the source 1190c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // location itself. 11917f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis checkAndSanitizeDiags(StoredDiagnostics, getSourceManager()); 11924cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 11934cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor // Keep track of the override buffer; 11944cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor SavedMainFileBuffer = OverrideMainBuffer; 1195f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor } 1196f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 11976f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<TopLevelDeclTrackerAction> Act( 119825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek new TopLevelDeclTrackerAction(*this)); 119925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek 120025a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek // Recover resources if we crash before exiting this method. 120125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction> 120225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek ActCleanup(Act.get()); 120325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek 12041f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) 1205521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar goto error; 1206f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 1207f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (OverrideMainBuffer) { 12081872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek std::string ModName = getPreambleFile(this); 1209f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateStoredDiagnostics(Clang->getModuleManager(), ModName, 1210f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor getSourceManager(), PreambleDiagnostics, 1211f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor StoredDiagnostics); 1212f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 1213f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 1214374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis if (!Act->Execute()) 1215374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis goto error; 1216e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis 1217e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis transferASTDataFromCompilerInstance(*Clang); 1218abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1219f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar Act->EndSourceFile(); 1220f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 1221e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis FailedParseDiagnostics.clear(); 1222e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis 1223abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return false; 12244f32786ac45210143654390177105eb749b614e9Ted Kremenek 1225521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarerror: 1226f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // Remove the overridden buffer we used for the preamble. 1227fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor if (OverrideMainBuffer) { 1228671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete OverrideMainBuffer; 122937cf66350cb5a2bb68b0b7c7cca552f7a4867348Douglas Gregor SavedMainFileBuffer = 0; 1230fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor } 1231e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis 1232e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis // Keep the ownership of the data in the ASTUnit because the client may 1233e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis // want to see the diagnostics. 1234e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis transferASTDataFromCompilerInstance(*Clang); 1235e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis FailedParseDiagnostics.swap(StoredDiagnostics); 1236d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor StoredDiagnostics.clear(); 12373e9d32656a8a3a787f64f9beeef66d2d700eb85dArgyrios Kyrtzidis NumStoredDiagnosticsFromDriver = 0; 1238abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 1239abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 1240abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 124144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor/// \brief Simple function to retrieve a path for a preamble precompiled header. 124244c181aec37789f25f6c15543c164416f72e562aDouglas Gregorstatic std::string GetPreamblePCHPath() { 1243424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor // FIXME: This is a hack so that we can override the preamble file during 1244424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor // crash-recovery testing, which is the only case where the preamble files 124585d28486b781f4e69dbff2d0b0239edc5a31ae16Rafael Espindola // are not necessarily cleaned up. 1246424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor const char *TmpFile = ::getenv("CINDEXTEST_PREAMBLE_FILE"); 1247424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor if (TmpFile) 1248424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor return TmpFile; 124985d28486b781f4e69dbff2d0b0239edc5a31ae16Rafael Espindola 125085d28486b781f4e69dbff2d0b0239edc5a31ae16Rafael Espindola SmallString<128> Path; 12511ec4a86a867fc04f35d13bc9e33b04cf2171fe41Rafael Espindola llvm::sys::fs::createTemporaryFile("preamble", "pch", Path); 125285d28486b781f4e69dbff2d0b0239edc5a31ae16Rafael Espindola 125385d28486b781f4e69dbff2d0b0239edc5a31ae16Rafael Espindola return Path.str(); 125444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor} 125544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 1256f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// \brief Compute the preamble for the main file, providing the source buffer 1257f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// that corresponds to the main file along with a pair (bytes, start-of-line) 1258f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// that describes the preamble. 1259f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregorstd::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > 1260df95a13ec73d2cdaea79555cb412d767f4963120Douglas GregorASTUnit::ComputePreamble(CompilerInvocation &Invocation, 1261df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor unsigned MaxLines, bool &CreatedBuffer) { 1262175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor FrontendOptions &FrontendOpts = Invocation.getFrontendOpts(); 126339b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner PreprocessorOptions &PreprocessorOpts = Invocation.getPreprocessorOpts(); 1264175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = false; 1265175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 126644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Try to determine if the main file has been remapped, either from the 126744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // command line (to another file) or directly through the compiler invocation 126844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // (to a memory buffer). 1269175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::MemoryBuffer *Buffer = 0; 1270105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola std::string MainFilePath(FrontendOpts.Inputs[0].getFile()); 12714488835d1c78221553909447cf87d7e4ff7f99fbRafael Espindola llvm::sys::fs::UniqueID MainFileID; 1272da4cb0cf401bb546574a7db46e50cda8b9d9c048Rafael Espindola if (!llvm::sys::fs::getUniqueID(MainFilePath, MainFileID)) { 127344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Check whether there is a file-file remapping of the main file 127444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor for (PreprocessorOptions::remapped_file_iterator 1275175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor M = PreprocessorOpts.remapped_file_begin(), 1276175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor E = PreprocessorOpts.remapped_file_end(); 127744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor M != E; 127844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor ++M) { 1279105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola std::string MPath(M->first); 12804488835d1c78221553909447cf87d7e4ff7f99fbRafael Espindola llvm::sys::fs::UniqueID MID; 1281da4cb0cf401bb546574a7db46e50cda8b9d9c048Rafael Espindola if (!llvm::sys::fs::getUniqueID(MPath, MID)) { 1282105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola if (MainFileID == MID) { 128344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // We found a remapping. Try to load the resulting, remapped source. 1284175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (CreatedBuffer) { 128544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor delete Buffer; 1286175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = false; 1287175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 1288175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1289389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis Buffer = getBufferForFile(M->second); 129044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Buffer) 1291f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor return std::make_pair((llvm::MemoryBuffer*)0, 1292f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor std::make_pair(0, true)); 1293175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = true; 129444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 129544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 129644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 129744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 129844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Check whether there is a file-buffer remapping. It supercedes the 129944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // file-file remapping. 130044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 130144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor M = PreprocessorOpts.remapped_file_buffer_begin(), 130244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor E = PreprocessorOpts.remapped_file_buffer_end(); 130344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor M != E; 130444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor ++M) { 1305105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola std::string MPath(M->first); 13064488835d1c78221553909447cf87d7e4ff7f99fbRafael Espindola llvm::sys::fs::UniqueID MID; 1307da4cb0cf401bb546574a7db46e50cda8b9d9c048Rafael Espindola if (!llvm::sys::fs::getUniqueID(MPath, MID)) { 1308105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola if (MainFileID == MID) { 1309105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola // We found a remapping. 1310175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (CreatedBuffer) { 131144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor delete Buffer; 1312175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = false; 1313175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 131444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 1315175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Buffer = const_cast<llvm::MemoryBuffer *>(M->second); 131644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 131744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 1318175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 131944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 132044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 132144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // If the main source file was not remapped, load it now. 132244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Buffer) { 13238616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis Buffer = getBufferForFile(FrontendOpts.Inputs[0].getFile()); 132444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Buffer) 1325f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor return std::make_pair((llvm::MemoryBuffer*)0, std::make_pair(0, true)); 1326175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1327175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = true; 1328175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 1329175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 133003c107a42fae79e89d0016999a1a04c07d65591aArgyrios Kyrtzidis return std::make_pair(Buffer, Lexer::ComputePreamble(Buffer, 1331d3b74d9ca4f239a7a90ad193378c494306c57352Ted Kremenek *Invocation.getLangOpts(), 133203c107a42fae79e89d0016999a1a04c07d65591aArgyrios Kyrtzidis MaxLines)); 1333175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor} 1334175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1335754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregorstatic llvm::MemoryBuffer *CreatePaddedMainFileBuffer(llvm::MemoryBuffer *Old, 1336754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor unsigned NewSize, 13375f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef NewName) { 1338754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor llvm::MemoryBuffer *Result 1339754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor = llvm::MemoryBuffer::getNewUninitMemBuffer(NewSize, NewName); 1340754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor memcpy(const_cast<char*>(Result->getBufferStart()), 1341754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor Old->getBufferStart(), Old->getBufferSize()); 1342754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor memset(const_cast<char*>(Result->getBufferStart()) + Old->getBufferSize(), 1343f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor ' ', NewSize - Old->getBufferSize() - 1); 1344f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor const_cast<char*>(Result->getBufferEnd())[-1] = '\n'; 1345754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor 1346754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return Result; 1347754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor} 1348754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor 1349175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// \brief Attempt to build or re-use a precompiled preamble when (re-)parsing 1350175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// the source file. 1351175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// 1352175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// This routine will compute the preamble of the main source file. If a 1353175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// non-trivial preamble is found, it will precompile that preamble into a 1354175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// precompiled header so that the precompiled preamble can be used to reduce 1355175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// reparsing time. If a precompiled preamble has already been constructed, 1356175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// this routine will determine if it is still valid and, if so, avoid 1357175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// rebuilding the precompiled preamble. 1358175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// 1359df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// \param AllowRebuild When true (the default), this routine is 1360df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// allowed to rebuild the precompiled preamble if it is found to be 1361df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// out-of-date. 1362df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// 1363df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// \param MaxLines When non-zero, the maximum number of lines that 1364df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// can occur within the preamble. 1365df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// 1366754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// \returns If the precompiled preamble can be used, returns a newly-allocated 1367754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// buffer that should be used in place of the main file when doing so. 1368754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// Otherwise, returns a NULL pointer. 1369df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregorllvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( 137001b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor const CompilerInvocation &PreambleInvocationIn, 1371df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool AllowRebuild, 1372df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor unsigned MaxLines) { 137301b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor 1374c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<CompilerInvocation> 137501b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor PreambleInvocation(new CompilerInvocation(PreambleInvocationIn)); 137601b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor FrontendOptions &FrontendOpts = PreambleInvocation->getFrontendOpts(); 1377175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreprocessorOptions &PreprocessorOpts 137801b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor = PreambleInvocation->getPreprocessorOpts(); 1379175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1380175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor bool CreatedPreambleBuffer = false; 1381f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > NewPreamble 138201b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor = ComputePreamble(*PreambleInvocation, MaxLines, CreatedPreambleBuffer); 1383175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1384f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // If ComputePreamble() Take ownership of the preamble buffer. 13856f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<llvm::MemoryBuffer> OwnedPreambleBuffer; 138673fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor if (CreatedPreambleBuffer) 138773fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor OwnedPreambleBuffer.reset(NewPreamble.first); 138873fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor 1389f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (!NewPreamble.second.first) { 1390175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We couldn't find a preamble in the main source. Clear out the current 1391175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // preamble, if we have one. It's obviously no good any more. 1392175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 13931872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek erasePreambleFile(this); 1394eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 1395eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // The next time we actually see a preamble, precompile it. 1396eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = 1; 1397754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 139844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 139944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 1400175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (!Preamble.empty()) { 1401175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We've previously computed a preamble. Check whether we have the same 1402175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // preamble now that we did before, and that there's enough space in 1403175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // the main-file buffer within the precompiled preamble to fit the 1404175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // new main file. 1405f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (Preamble.size() == NewPreamble.second.first && 1406f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreambleEndsAtStartOfLine == NewPreamble.second.second && 1407592508ed997e52207cf380f9b6eb9943994ad7aeDouglas Gregor NewPreamble.first->getBufferSize() < PreambleReservedSize-2 && 1408507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis memcmp(Preamble.getBufferStart(), NewPreamble.first->getBufferStart(), 1409f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor NewPreamble.second.first) == 0) { 1410175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // The preamble has not changed. We may be able to re-use the precompiled 1411175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // preamble. 1412c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 1413cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Check that none of the files used by the preamble have changed. 1414cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor bool AnyFileChanged = false; 1415cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1416cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // First, make a record of those files that have been overridden via 1417cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // remapping or unsaved_files. 1418cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor llvm::StringMap<std::pair<off_t, time_t> > OverriddenFiles; 1419cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (PreprocessorOptions::remapped_file_iterator 1420cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor R = PreprocessorOpts.remapped_file_begin(), 1421cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor REnd = PreprocessorOpts.remapped_file_end(); 1422cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor !AnyFileChanged && R != REnd; 1423cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++R) { 1424aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola llvm::sys::fs::file_status Status; 1425aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola if (FileMgr->getNoncachedStatValue(R->second, Status)) { 1426cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // If we can't stat the file we're remapping to, assume that something 1427cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // horrible happened. 1428cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 1429cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor break; 1430cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1431aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola 1432aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola OverriddenFiles[R->first] = std::make_pair( 1433aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola Status.getSize(), Status.getLastModificationTime().toEpochTime()); 1434cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1435cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 1436cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor R = PreprocessorOpts.remapped_file_buffer_begin(), 1437cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor REnd = PreprocessorOpts.remapped_file_buffer_end(); 1438cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor !AnyFileChanged && R != REnd; 1439cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++R) { 1440cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // FIXME: Should we actually compare the contents of file->buffer 1441cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // remappings? 1442cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor OverriddenFiles[R->first] = std::make_pair(R->second->getBufferSize(), 1443cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 0); 1444cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1445cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1446cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Check whether anything has changed. 1447cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (llvm::StringMap<std::pair<off_t, time_t> >::iterator 1448cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor F = FilesInPreamble.begin(), FEnd = FilesInPreamble.end(); 1449cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor !AnyFileChanged && F != FEnd; 1450cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++F) { 1451cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor llvm::StringMap<std::pair<off_t, time_t> >::iterator Overridden 1452cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor = OverriddenFiles.find(F->first()); 1453cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (Overridden != OverriddenFiles.end()) { 1454cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // This file was remapped; check whether the newly-mapped file 1455cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // matches up with the previous mapping. 1456cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (Overridden->second != F->second) 1457cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 1458cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor continue; 1459cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1460cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1461cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // The file was not remapped; check whether it has changed on disk. 1462aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola llvm::sys::fs::file_status Status; 1463aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola if (FileMgr->getNoncachedStatValue(F->first(), Status)) { 1464cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // If we can't stat the file, assume that something horrible happened. 1465cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 1466aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola } else if (Status.getSize() != uint64_t(F->second.first) || 1467aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola Status.getLastModificationTime().toEpochTime() != 1468aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola uint64_t(F->second.second)) 1469cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 1470cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1471cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1472cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (!AnyFileChanged) { 1473c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Okay! We can re-use the precompiled preamble. 1474c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 1475c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Set the state of the diagnostic object to mimic its state 1476c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // after parsing the preamble. 1477c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getDiagnostics().Reset(); 147832be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor ProcessWarningOptions(getDiagnostics(), 147901b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor PreambleInvocation->getDiagnosticOpts()); 1480c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getDiagnostics().setNumWarnings(NumWarningsInPreamble); 1481c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 1482c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Create a version of the main file buffer that is padded to 1483c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // buffer size we reserved when creating the preamble. 1484cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor return CreatePaddedMainFileBuffer(NewPreamble.first, 1485cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor PreambleReservedSize, 14868616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis FrontendOpts.Inputs[0].getFile()); 1487cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1488175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 1489df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 1490df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // If we aren't allowed to rebuild the precompiled preamble, just 1491df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // return now. 1492df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (!AllowRebuild) 1493df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor return 0; 1494aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor 1495175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We can't reuse the previously-computed preamble. Build a new one. 1496175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1497f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor PreambleDiagnostics.clear(); 14981872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek erasePreambleFile(this); 1499eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = 1; 1500df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } else if (!AllowRebuild) { 1501df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // We aren't allowed to rebuild the precompiled preamble; just 1502df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // return now. 1503df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor return 0; 1504df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 1505eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 1506eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // If the preamble rebuild counter > 1, it's because we previously 1507eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // failed to build a preamble and we're not yet ready to try 1508eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // again. Decrement the counter and return a failure. 1509eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor if (PreambleRebuildCounter > 1) { 1510eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor --PreambleRebuildCounter; 1511eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor return 0; 1512eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor } 1513eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 15142cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor // Create a temporary file for the precompiled preamble. In rare 15152cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor // circumstances, this can fail. 15162cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor std::string PreamblePCHPath = GetPreamblePCHPath(); 15172cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor if (PreamblePCHPath.empty()) { 15182cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor // Try again next time. 15192cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor PreambleRebuildCounter = 1; 15202cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor return 0; 15212cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor } 15222cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor 1523175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We did not previously compute a preamble, or it can't be reused anyway. 1524213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer PreambleTimer(WantTiming); 1525edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer PreambleTimer.setOutput("Precompiling preamble"); 152644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 152744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create a new buffer that stores the preamble. The buffer also contains 152844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // extra space for the original contents of the file (which will be present 152944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // when we actually parse the file) along with more room in case the file 1530175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // grows. 1531175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleReservedSize = NewPreamble.first->getBufferSize(); 1532175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (PreambleReservedSize < 4096) 1533f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreambleReservedSize = 8191; 153444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor else 1535175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleReservedSize *= 2; 1536175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1537c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Save the preamble text for later; we'll need to compare against it for 1538c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // subsequent reparses. 15398616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis StringRef MainFilename = PreambleInvocation->getFrontendOpts().Inputs[0].getFile(); 1540507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis Preamble.assign(FileMgr->getFile(MainFilename), 1541507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis NewPreamble.first->getBufferStart(), 1542c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor NewPreamble.first->getBufferStart() 1543c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor + NewPreamble.second.first); 1544c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor PreambleEndsAtStartOfLine = NewPreamble.second.second; 1545c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 1546671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete PreambleBuffer; 1547671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreambleBuffer 1548175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor = llvm::MemoryBuffer::getNewUninitMemBuffer(PreambleReservedSize, 15498616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis FrontendOpts.Inputs[0].getFile()); 155044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor memcpy(const_cast<char*>(PreambleBuffer->getBufferStart()), 1551175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor NewPreamble.first->getBufferStart(), Preamble.size()); 1552175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor memset(const_cast<char*>(PreambleBuffer->getBufferStart()) + Preamble.size(), 1553f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor ' ', PreambleReservedSize - Preamble.size() - 1); 1554f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor const_cast<char*>(PreambleBuffer->getBufferEnd())[-1] = '\n'; 15551cd7df45ac8909a92a80af4be7ec1bbdcb3a84e7Rafael Espindola 155644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Remap the main source file to the preamble buffer. 15571cd7df45ac8909a92a80af4be7ec1bbdcb3a84e7Rafael Espindola StringRef MainFilePath = FrontendOpts.Inputs[0].getFile(); 15581cd7df45ac8909a92a80af4be7ec1bbdcb3a84e7Rafael Espindola PreprocessorOpts.addRemappedFile(MainFilePath, PreambleBuffer); 15591cd7df45ac8909a92a80af4be7ec1bbdcb3a84e7Rafael Espindola 156044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Tell the compiler invocation to generate a temporary precompiled header. 156144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor FrontendOpts.ProgramAction = frontend::GeneratePCH; 156244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: Generate the precompiled header into memory? 15632cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor FrontendOpts.OutputFile = PreamblePCHPath; 1564aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = 0; 1565aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second = false; 156644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 156744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create the compiler instance to use for building the precompiled preamble. 15686f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<CompilerInstance> Clang(new CompilerInstance()); 156903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 157003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek // Recover resources if we crash before exiting this method. 157125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> 157225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek CICleanup(Clang.get()); 157303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 157401b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor Clang->setInvocation(&*PreambleInvocation); 15758616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile(); 157644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 15771abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set up diagnostics, capturing all of the diagnostics produced. 157803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setDiagnostics(&getDiagnostics()); 157944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 158044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create the target instance. 158103201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), 158249a87549f4dc95ecb3d8a593b71df7c167a51f85Douglas Gregor &Clang->getTargetOpts())); 158303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek if (!Clang->hasTarget()) { 158421b1824304076325a72239a4446e5f7e97370cfdRafael Espindola llvm::sys::fs::remove(FrontendOpts.OutputFile); 1585175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1586eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = DefaultPreambleRebuildInterval; 1587671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1588671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 1589754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 159044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 159144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 159244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Inform the target of the language options. 159344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // 159444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: We shouldn't need to do this, the target should be immutable once 159544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // created. This complexity should be lifted elsewhere. 159603201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); 159744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 159803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs.size() == 1 && 159944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor "Invocation must have exactly one source file!"); 16008616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis assert(Clang->getFrontendOpts().Inputs[0].getKind() != IK_AST && 160144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor "FIXME: AST inputs not yet supported here!"); 16028616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis assert(Clang->getFrontendOpts().Inputs[0].getKind() != IK_LLVM_IR && 160344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor "IR inputs not support here!"); 160444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 160544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Clear out old caches and data. 1606aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor getDiagnostics().Reset(); 160703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek ProcessWarningOptions(getDiagnostics(), Clang->getDiagnosticOpts()); 16087f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis checkAndRemoveNonDriverDiags(StoredDiagnostics); 1609eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDecls.clear(); 1610eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDeclsInPreamble.clear(); 161144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 161244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create a file manager object to provide access to and cache the filesystem. 161303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setFileManager(new FileManager(Clang->getFileSystemOpts())); 161444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 161544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create the source manager. 161603201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setSourceManager(new SourceManager(getDiagnostics(), 16174f32786ac45210143654390177105eb749b614e9Ted Kremenek Clang->getFileManager())); 161844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 16196f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<PrecompilePreambleAction> Act; 16201d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor Act.reset(new PrecompilePreambleAction(*this)); 16211f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) { 162221b1824304076325a72239a4446e5f7e97370cfdRafael Espindola llvm::sys::fs::remove(FrontendOpts.OutputFile); 1623175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1624eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = DefaultPreambleRebuildInterval; 1625671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1626671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 1627754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 162844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 162944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 163044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Act->Execute(); 163144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Act->EndSourceFile(); 16324f32786ac45210143654390177105eb749b614e9Ted Kremenek 16331f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis if (!Act->hasEmittedPreamblePCH()) { 1634739f9e575cfa3ade546b3845eeea86eabd67357fArgyrios Kyrtzidis // The preamble PCH failed (e.g. there was a module loading fatal error), 1635739f9e575cfa3ade546b3845eeea86eabd67357fArgyrios Kyrtzidis // so no precompiled header was generated. Forget that we even tried. 163606e504462014b0506a70c7730ea45c551a103364Douglas Gregor // FIXME: Should we leave a note for ourselves to try again? 163721b1824304076325a72239a4446e5f7e97370cfdRafael Espindola llvm::sys::fs::remove(FrontendOpts.OutputFile); 1638175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1639eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDeclsInPreamble.clear(); 1640eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = DefaultPreambleRebuildInterval; 1641671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1642671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 1643754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 1644175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 1645175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1646f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Transfer any diagnostics generated when parsing the preamble into the set 1647f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // of preamble diagnostics. 1648f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor PreambleDiagnostics.clear(); 1649f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor PreambleDiagnostics.insert(PreambleDiagnostics.end(), 16503e9d32656a8a3a787f64f9beeef66d2d700eb85dArgyrios Kyrtzidis stored_diag_afterDriver_begin(), stored_diag_end()); 16517f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis checkAndRemoveNonDriverDiags(StoredDiagnostics); 1652f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 1653175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // Keep track of the preamble we precompiled. 16541872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek setPreambleFile(this, FrontendOpts.OutputFile); 1655c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor NumWarningsInPreamble = getDiagnostics().getNumWarnings(); 1656cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1657cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Keep track of all of the files that the source manager knows about, 1658cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // so we can verify whether they have changed or not. 1659cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FilesInPreamble.clear(); 166003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek SourceManager &SourceMgr = Clang->getSourceManager(); 1661cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor const llvm::MemoryBuffer *MainFileBuffer 1662cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor = SourceMgr.getBuffer(SourceMgr.getMainFileID()); 1663cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (SourceManager::fileinfo_iterator F = SourceMgr.fileinfo_begin(), 1664cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FEnd = SourceMgr.fileinfo_end(); 1665cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor F != FEnd; 1666cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++F) { 1667b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *File = F->second->OrigEntry; 1668cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (!File || F->second->getRawBuffer() == MainFileBuffer) 1669cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor continue; 1670cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1671cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FilesInPreamble[File->getName()] 1672cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor = std::make_pair(F->second->getSize(), File->getModificationTime()); 1673cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1674cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1675eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = 1; 1676671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1677671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 16789b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 16799b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor // If the hash of top-level entities differs from the hash of the top-level 16809b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor // entities the last time we rebuilt the preamble, clear out the completion 16819b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor // cache. 16829b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (CurrentTopLevelHashValue != PreambleTopLevelHashValue) { 16839b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CompletionCacheTopLevelHashValue = 0; 16849b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor PreambleTopLevelHashValue = CurrentTopLevelHashValue; 16859b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 16869b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 1687754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return CreatePaddedMainFileBuffer(NewPreamble.first, 1688754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor PreambleReservedSize, 16898616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis FrontendOpts.Inputs[0].getFile()); 169044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor} 1691abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1692eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregorvoid ASTUnit::RealizeTopLevelDeclsFromPreamble() { 1693eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor std::vector<Decl *> Resolved; 1694eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Resolved.reserve(TopLevelDeclsInPreamble.size()); 1695eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor ExternalASTSource &Source = *getASTContext().getExternalSource(); 1696eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor for (unsigned I = 0, N = TopLevelDeclsInPreamble.size(); I != N; ++I) { 1697eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // Resolve the declaration ID to an actual declaration, possibly 1698eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // deserializing the declaration in the process. 1699eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Decl *D = Source.GetExternalDecl(TopLevelDeclsInPreamble[I]); 1700eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (D) 1701eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Resolved.push_back(D); 1702eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 1703eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDeclsInPreamble.clear(); 1704eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end()); 1705eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor} 1706eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 1707e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidisvoid ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) { 1708e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis // Steal the created target, context, and preprocessor. 1709e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis TheSema.reset(CI.takeSema()); 1710e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis Consumer.reset(CI.takeASTConsumer()); 1711e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis Ctx = &CI.getASTContext(); 1712e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis PP = &CI.getPreprocessor(); 1713e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis CI.setSourceManager(0); 1714e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis CI.setFileManager(0); 1715e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis Target = &CI.getTarget(); 1716e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis Reader = CI.getModuleManager(); 17173b7deda7137e62810a810ce25b062927a9fc7c71Argyrios Kyrtzidis HadModuleLoaderFatalFailure = CI.hadModuleLoaderFatalFailure(); 1718e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis} 1719e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis 17205f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerStringRef ASTUnit::getMainFileName() const { 1721814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis if (Invocation && !Invocation->getFrontendOpts().Inputs.empty()) { 1722814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis const FrontendInputFile &Input = Invocation->getFrontendOpts().Inputs[0]; 1723814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis if (Input.isFile()) 1724814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis return Input.getFile(); 1725814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis else 1726814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis return Input.getBuffer()->getBufferIdentifier(); 1727814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis } 1728814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis 1729814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis if (SourceMgr) { 1730814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis if (const FileEntry * 1731814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis FE = SourceMgr->getFileEntryForID(SourceMgr->getMainFileID())) 1732814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis return FE->getName(); 1733814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis } 1734814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis 1735814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis return StringRef(); 1736213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor} 1737213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 173844f65a587ee39c20e715c9df411c864d328c71b5Argyrios KyrtzidisStringRef ASTUnit::getASTFileName() const { 173944f65a587ee39c20e715c9df411c864d328c71b5Argyrios Kyrtzidis if (!isMainFileAST()) 174044f65a587ee39c20e715c9df411c864d328c71b5Argyrios Kyrtzidis return StringRef(); 174144f65a587ee39c20e715c9df411c864d328c71b5Argyrios Kyrtzidis 174244f65a587ee39c20e715c9df411c864d328c71b5Argyrios Kyrtzidis serialization::ModuleFile & 174344f65a587ee39c20e715c9df411c864d328c71b5Argyrios Kyrtzidis Mod = Reader->getModuleManager().getPrimaryModule(); 174444f65a587ee39c20e715c9df411c864d328c71b5Argyrios Kyrtzidis return Mod.FileName; 174544f65a587ee39c20e715c9df411c864d328c71b5Argyrios Kyrtzidis} 174644f65a587ee39c20e715c9df411c864d328c71b5Argyrios Kyrtzidis 1747b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios KyrtzidisASTUnit *ASTUnit::create(CompilerInvocation *CI, 1748c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 1749ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis bool CaptureDiagnostics, 1750ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis bool UserFilesAreVolatile) { 17516f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<ASTUnit> AST; 1752b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis AST.reset(new ASTUnit(false)); 1753991bf49f68e8caeb900dd9738712b861073363d9Argyrios Kyrtzidis ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics); 1754b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis AST->Diagnostics = Diags; 17554f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->Invocation = CI; 17560d8d7e6067f9093e7d5abc45c9639ab977aab692Anders Carlsson AST->FileSystemOpts = CI->getFileSystemOpts(); 17574f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->FileMgr = new FileManager(AST->FileSystemOpts); 1758ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis AST->UserFilesAreVolatile = UserFilesAreVolatile; 1759ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr, 1760ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis UserFilesAreVolatile); 1761b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 1762b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis return AST.take(); 1763b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis} 1764b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 1765d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios KyrtzidisASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI, 1766c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 1767abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis ASTFrontendAction *Action, 17686f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis ASTUnit *Unit, 17696f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis bool Persistent, 17706f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis StringRef ResourceFilesPath, 17716f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis bool OnlyLocalDecls, 17726f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis bool CaptureDiagnostics, 17736f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis bool PrecompilePreamble, 1774e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis bool CacheCodeCompletionResults, 1775d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko bool IncludeBriefCommentsInCodeCompletion, 1776ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis bool UserFilesAreVolatile, 1777e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis OwningPtr<ASTUnit> *ErrAST) { 1778d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis assert(CI && "A CompilerInvocation is required"); 1779d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 17806f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<ASTUnit> OwnAST; 1781abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis ASTUnit *AST = Unit; 1782abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis if (!AST) { 1783abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis // Create the AST unit. 1784ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis OwnAST.reset(create(CI, Diags, CaptureDiagnostics, UserFilesAreVolatile)); 1785abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis AST = OwnAST.get(); 1786abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis } 1787abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis 17886f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis if (!ResourceFilesPath.empty()) { 17896f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis // Override the resources path. 17906f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath; 17916f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis } 17926f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis AST->OnlyLocalDecls = OnlyLocalDecls; 17936f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis AST->CaptureDiagnostics = CaptureDiagnostics; 17946f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis if (PrecompilePreamble) 17956f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis AST->PreambleRebuildCounter = 2; 1796467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete; 17976f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults; 1798d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko AST->IncludeBriefCommentsInCodeCompletion 1799d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko = IncludeBriefCommentsInCodeCompletion; 1800d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1801d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Recover resources if we crash before exiting this method. 1802d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> 1803abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis ASTUnitCleanup(OwnAST.get()); 1804d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, 1805d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > 1806d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis DiagCleanup(Diags.getPtr()); 1807d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1808d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // We'll manage file buffers ourselves. 1809d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis CI->getPreprocessorOpts().RetainRemappedFileBuffers = true; 1810d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis CI->getFrontendOpts().DisableFree = false; 1811d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts()); 1812d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1813d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Create the compiler instance to use for building the AST. 18146f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<CompilerInstance> Clang(new CompilerInstance()); 1815d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1816d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Recover resources if we crash before exiting this method. 1817d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> 1818d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis CICleanup(Clang.get()); 1819d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1820d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setInvocation(CI); 18218616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis AST->OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile(); 1822d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1823d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Set up diagnostics, capturing any diagnostics that would 1824d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // otherwise be dropped. 1825d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setDiagnostics(&AST->getDiagnostics()); 1826d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1827d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Create the target instance. 1828d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), 182949a87549f4dc95ecb3d8a593b71df7c167a51f85Douglas Gregor &Clang->getTargetOpts())); 1830d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis if (!Clang->hasTarget()) 1831d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis return 0; 1832d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1833d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Inform the target of the language options. 1834d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // 1835d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // FIXME: We shouldn't need to do this, the target should be immutable once 1836d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // created. This complexity should be lifted elsewhere. 1837d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); 1838d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1839d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis assert(Clang->getFrontendOpts().Inputs.size() == 1 && 1840d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis "Invocation must have exactly one source file!"); 18418616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis assert(Clang->getFrontendOpts().Inputs[0].getKind() != IK_AST && 1842d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis "FIXME: AST inputs not yet supported here!"); 18438616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis assert(Clang->getFrontendOpts().Inputs[0].getKind() != IK_LLVM_IR && 1844d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis "IR inputs not supported here!"); 1845d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1846d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Configure the various subsystems. 1847d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->TheSema.reset(); 1848d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->Ctx = 0; 1849d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->PP = 0; 185062ba9f61af6177992d8cd2e3306257e1213b1bd3Argyrios Kyrtzidis AST->Reader = 0; 1851d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1852d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Create a file manager object to provide access to and cache the filesystem. 1853d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setFileManager(&AST->getFileManager()); 1854d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1855d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Create the source manager. 1856d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setSourceManager(&AST->getSourceManager()); 1857d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1858d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis ASTFrontendAction *Act = Action; 1859d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 18606f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<TopLevelDeclTrackerAction> TrackerAct; 1861d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis if (!Act) { 1862d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis TrackerAct.reset(new TopLevelDeclTrackerAction(*AST)); 1863d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Act = TrackerAct.get(); 1864d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis } 1865d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1866d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Recover resources if we crash before exiting this method. 1867d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction> 1868d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis ActCleanup(TrackerAct.get()); 1869d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1870e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) { 1871e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis AST->transferASTDataFromCompilerInstance(*Clang); 1872e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis if (OwnAST && ErrAST) 1873e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis ErrAST->swap(OwnAST); 1874e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis 1875d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis return 0; 1876e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis } 18776f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis 18786f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis if (Persistent && !TrackerAct) { 18796f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis Clang->getPreprocessor().addPPCallbacks( 18806f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis new MacroDefinitionTrackerPPCallbacks(AST->getCurrentTopLevelHashValue())); 18816f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis std::vector<ASTConsumer*> Consumers; 18826f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis if (Clang->hasASTConsumer()) 18836f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis Consumers.push_back(Clang->takeASTConsumer()); 18846f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis Consumers.push_back(new TopLevelDeclTrackerConsumer(*AST, 18856f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis AST->getCurrentTopLevelHashValue())); 18866f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis Clang->setASTConsumer(new MultiplexConsumer(Consumers)); 18876f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis } 1888374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis if (!Act->Execute()) { 1889374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis AST->transferASTDataFromCompilerInstance(*Clang); 1890374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis if (OwnAST && ErrAST) 1891374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis ErrAST->swap(OwnAST); 1892374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis 1893374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis return 0; 1894374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis } 1895e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis 1896d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Steal the created target, context, and preprocessor. 1897e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis AST->transferASTDataFromCompilerInstance(*Clang); 1898d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1899d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Act->EndSourceFile(); 1900d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1901abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis if (OwnAST) 1902abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis return OwnAST.take(); 1903abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis else 1904abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis return AST; 1905d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis} 1906d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 19074cd912aa94656697a44c3ebb159f05060300524eDouglas Gregorbool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) { 19084cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor if (!Invocation) 19094cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor return true; 19104cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 19114cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor // We'll manage file buffers ourselves. 19124cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor Invocation->getPreprocessorOpts().RetainRemappedFileBuffers = true; 19134cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor Invocation->getFrontendOpts().DisableFree = false; 19140b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts()); 19154cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 19164cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor llvm::MemoryBuffer *OverrideMainBuffer = 0; 191799ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor if (PrecompilePreamble) { 191808bb4c622d0b79c33b4ac78ce1bec79398953daaDouglas Gregor PreambleRebuildCounter = 2; 19194cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor OverrideMainBuffer 19204cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor = getMainBufferWithPrecompiledPreamble(*Invocation); 19214cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor } 19224cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 1923213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer ParsingTimer(WantTiming); 1924edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer ParsingTimer.setOutput("Parsing " + getMainFileName()); 19254cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 192625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek // Recover resources if we crash before exiting this method. 192725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer> 192825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek MemBufferCleanup(OverrideMainBuffer); 192925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek 1930213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor return Parse(OverrideMainBuffer); 19314cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor} 19324cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 1933abc563f554951259bbe0315055cad92ee14d87e4Douglas GregorASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, 1934c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 1935abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor bool OnlyLocalDecls, 193644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor bool CaptureDiagnostics, 1937df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool PrecompilePreamble, 1938467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor TranslationUnitKind TUKind, 1939d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko bool CacheCodeCompletionResults, 1940ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis bool IncludeBriefCommentsInCodeCompletion, 1941ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis bool UserFilesAreVolatile) { 1942abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Create the AST unit. 19436f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<ASTUnit> AST; 1944abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST.reset(new ASTUnit(false)); 19450b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics); 1946abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST->Diagnostics = Diags; 1947abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST->OnlyLocalDecls = OnlyLocalDecls; 1948e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor AST->CaptureDiagnostics = CaptureDiagnostics; 1949467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor AST->TUKind = TUKind; 195087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults; 1951d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko AST->IncludeBriefCommentsInCodeCompletion 1952d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko = IncludeBriefCommentsInCodeCompletion; 19534f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->Invocation = CI; 1954eb8fc58241e1781a77c958764e16a4c402e4d707Argyrios Kyrtzidis AST->FileSystemOpts = CI->getFileSystemOpts(); 1955eb8fc58241e1781a77c958764e16a4c402e4d707Argyrios Kyrtzidis AST->FileMgr = new FileManager(AST->FileSystemOpts); 1956ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis AST->UserFilesAreVolatile = UserFilesAreVolatile; 1957385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor 1958b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek // Recover resources if we crash before exiting this method. 195925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> 196025a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek ASTUnitCleanup(AST.get()); 1961d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, 1962d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > 196325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek DiagCleanup(Diags.getPtr()); 1964b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek 19654cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor return AST->LoadFromCompilerInvocation(PrecompilePreamble)? 0 : AST.take(); 1966521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar} 19677b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 19687b55668db7618334cc40011d3c1e128524d89462Daniel DunbarASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, 19697b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar const char **ArgEnd, 1970c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 19715f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef ResourceFilesPath, 19727b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar bool OnlyLocalDecls, 1973e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor bool CaptureDiagnostics, 19744db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFile *RemappedFiles, 1975a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor unsigned NumRemappedFiles, 1976299a4a967b02c9f0d0d94ad8560e3ced893f9116Argyrios Kyrtzidis bool RemappedFilesKeepOriginalName, 1977df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool PrecompilePreamble, 1978467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor TranslationUnitKind TUKind, 1979bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis bool CacheCodeCompletionResults, 1980d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko bool IncludeBriefCommentsInCodeCompletion, 1981e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis bool AllowPCHWithCompilerErrors, 19826a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen bool SkipFunctionBodies, 1983ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis bool UserFilesAreVolatile, 1984900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis bool ForSerialization, 1985e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis OwningPtr<ASTUnit> *ErrAST) { 198628019772db70d4547be05a042eb950bc910f134fDouglas Gregor if (!Diags.getPtr()) { 19873687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor // No diagnostics engine was provided, so create our own diagnostics object 19883687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor // with the default options. 1989d47afb96a3f988e6d21a92fe4dfe875ab227c7c0Sean Silva Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions()); 19903687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor } 19917b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 19925f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<StoredDiagnostic, 4> StoredDiagnostics; 19934cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 1994c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<CompilerInvocation> CI; 1995e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor 19964cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor { 1997f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 1998e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags, 19994cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics); 20004cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 2001832316e9a04242972f4b57281dccb8e4cf5894eaArgyrios Kyrtzidis CI = clang::createInvocationFromCommandLine( 2002e9c0265d6e6b5bf865f4a0c2c00d00ac251e6437Frits van Bommel llvm::makeArrayRef(ArgBegin, ArgEnd), 2003e9c0265d6e6b5bf865f4a0c2c00d00ac251e6437Frits van Bommel Diags); 2004054e4f50e2f1995e91b0cd3c3258aa252785fe3fArgyrios Kyrtzidis if (!CI) 20054e03c2b9d735063a60cd0623423f4814178857efArgyrios Kyrtzidis return 0; 20067b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar } 2007e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor 20084db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor // Override any files that need remapping 2009b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis for (unsigned I = 0; I != NumRemappedFiles; ++I) { 2010b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; 2011b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (const llvm::MemoryBuffer * 2012b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { 2013b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, memBuf); 2014b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } else { 2015b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const char *fname = fileOrBuf.get<const char *>(); 2016b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, fname); 2017b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 2018b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 2019bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis PreprocessorOptions &PPOpts = CI->getPreprocessorOpts(); 2020bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName; 2021bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors; 20224db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 20238b9adfea5e834eaee0f45d8cc7fb052d68df4a46Daniel Dunbar // Override the resources path. 2024807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath; 20257b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 20266a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen CI->getFrontendOpts().SkipFunctionBodies = SkipFunctionBodies; 20276a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen 20284cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor // Create the AST unit. 20296f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<ASTUnit> AST; 20304cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST.reset(new ASTUnit(false)); 20310b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor ConfigureDiags(Diags, ArgBegin, ArgEnd, *AST, CaptureDiagnostics); 20324cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->Diagnostics = Diags; 2033d04a982d3472d98e58f58dfc327ca11e236980f5Ted Kremenek Diags = 0; // Zero out now to ease cleanup during crash recovery. 20340d8d7e6067f9093e7d5abc45c9639ab977aab692Anders Carlsson AST->FileSystemOpts = CI->getFileSystemOpts(); 20354f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->FileMgr = new FileManager(AST->FileSystemOpts); 20364cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->OnlyLocalDecls = OnlyLocalDecls; 2037e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor AST->CaptureDiagnostics = CaptureDiagnostics; 2038467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor AST->TUKind = TUKind; 20394cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults; 2040d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko AST->IncludeBriefCommentsInCodeCompletion 2041d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko = IncludeBriefCommentsInCodeCompletion; 2042ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis AST->UserFilesAreVolatile = UserFilesAreVolatile; 20434cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size(); 20444cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->StoredDiagnostics.swap(StoredDiagnostics); 20454f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->Invocation = CI; 2046900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis if (ForSerialization) 2047900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis AST->WriterData.reset(new ASTWriterData()); 2048d04a982d3472d98e58f58dfc327ca11e236980f5Ted Kremenek CI = 0; // Zero out now to ease cleanup during crash recovery. 2049b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek 2050b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek // Recover resources if we crash before exiting this method. 205125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> 205225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek ASTUnitCleanup(AST.get()); 2053b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek 2054e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis if (AST->LoadFromCompilerInvocation(PrecompilePreamble)) { 2055e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis // Some error occurred, if caller wants to examine diagnostics, pass it the 2056e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis // ASTUnit. 2057e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis if (ErrAST) { 2058e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics); 2059e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis ErrAST->swap(AST); 2060e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis } 2061e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis return 0; 2062e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis } 2063e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis 2064e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis return AST.take(); 20657b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar} 2066abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 2067abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregorbool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) { 20684f32786ac45210143654390177105eb749b614e9Ted Kremenek if (!Invocation) 2069abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 2070332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 2071332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis clearFileLevelDecls(); 2072abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 2073213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer ParsingTimer(WantTiming); 2074edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer ParsingTimer.setOutput("Reparsing " + getMainFileName()); 2075213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 2076cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Remap files. 2077f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 2078f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 2079f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor R = PPOpts.remapped_file_buffer_begin(), 2080f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor REnd = PPOpts.remapped_file_buffer_end(); 2081f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor R != REnd; 2082f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor ++R) { 2083f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor delete R->second; 2084f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor } 2085cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor Invocation->getPreprocessorOpts().clearRemappedFiles(); 2086b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis for (unsigned I = 0; I != NumRemappedFiles; ++I) { 2087b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; 2088b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (const llvm::MemoryBuffer * 2089b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { 2090b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, 2091b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf); 2092b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } else { 2093b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const char *fname = fileOrBuf.get<const char *>(); 2094b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, 2095b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis fname); 2096b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 2097b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 2098cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 2099eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // If we have a preamble file lying around, or if we might try to 2100eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // build a precompiled preamble, do so now. 2101754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor llvm::MemoryBuffer *OverrideMainBuffer = 0; 21021872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek if (!getPreambleFile(this).empty() || PreambleRebuildCounter > 0) 21032283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation); 2104175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 2105abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Clear out the diagnostics state. 2106e6825d39e89362105171c013f4018c4d1134ad6fArgyrios Kyrtzidis getDiagnostics().Reset(); 2107e6825d39e89362105171c013f4018c4d1134ad6fArgyrios Kyrtzidis ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts()); 210827368f9f1942a42b668cd1d9426859566c4f8540Argyrios Kyrtzidis if (OverrideMainBuffer) 210927368f9f1942a42b668cd1d9426859566c4f8540Argyrios Kyrtzidis getDiagnostics().setNumWarnings(NumWarningsInPreamble); 2110e6825d39e89362105171c013f4018c4d1134ad6fArgyrios Kyrtzidis 2111175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // Parse the sources 21129b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor bool Result = Parse(OverrideMainBuffer); 21132fe17fc5ead5e42ef195618228bca53c79e0e50dArgyrios Kyrtzidis 21142fe17fc5ead5e42ef195618228bca53c79e0e50dArgyrios Kyrtzidis // If we're caching global code-completion results, and the top-level 21152fe17fc5ead5e42ef195618228bca53c79e0e50dArgyrios Kyrtzidis // declarations have changed, clear out the code-completion cache. 21162fe17fc5ead5e42ef195618228bca53c79e0e50dArgyrios Kyrtzidis if (!Result && ShouldCacheCodeCompletionResults && 21172fe17fc5ead5e42ef195618228bca53c79e0e50dArgyrios Kyrtzidis CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue) 21182fe17fc5ead5e42ef195618228bca53c79e0e50dArgyrios Kyrtzidis CacheCodeCompletionResults(); 21199b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 212028a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis // We now need to clear out the completion info related to this translation 212128a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis // unit; it'll be recreated if necessary. 212228a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis CCTUInfo.reset(); 21238fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor 2124175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor return Result; 2125abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 21261abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 212787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor//----------------------------------------------------------------------------// 212887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor// Code completion 212987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor//----------------------------------------------------------------------------// 213087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 213187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregornamespace { 213287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor /// \brief Code completion consumer that combines the cached code-completion 213387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor /// results from an ASTUnit with the code-completion results provided to it, 213487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor /// then passes the result on to 213587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer { 2136026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith uint64_t NormalContexts; 213787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor ASTUnit &AST; 213887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CodeCompleteConsumer &Next; 213987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 214087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor public: 214187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next, 2142d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko const CodeCompleteOptions &CodeCompleteOpts) 2143d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko : CodeCompleteConsumer(CodeCompleteOpts, Next.isOutputBinary()), 2144d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko AST(AST), Next(Next) 214587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor { 214687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Compute the set of contexts in which we will look when we don't have 214787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // any information about the specific context. 214887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor NormalContexts 2149026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith = (1LL << CodeCompletionContext::CCC_TopLevel) 2150026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ObjCInterface) 2151026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ObjCImplementation) 2152026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ObjCIvarList) 2153026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_Statement) 2154026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_Expression) 2155026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver) 2156026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_DotMemberAccess) 2157026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ArrowMemberAccess) 2158026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ObjCPropertyAccess) 2159026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ObjCProtocolName) 2160026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression) 2161026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_Recovery); 21620268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor 21634e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (AST.getASTContext().getLangOpts().CPlusPlus) 2164026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith NormalContexts |= (1LL << CodeCompletionContext::CCC_EnumTag) 2165026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_UnionTag) 2166026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith | (1LL << CodeCompletionContext::CCC_ClassOrStructTag); 216787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 216887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 216987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor virtual void ProcessCodeCompleteResults(Sema &S, 217087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CodeCompletionContext Context, 21710a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall CodeCompletionResult *Results, 2172697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor unsigned NumResults); 217387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 217487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, 217587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor OverloadCandidate *Candidates, 217687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor unsigned NumCandidates) { 217787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates); 217887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 2179218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor 2180dae687575010c9c49a4b552f5eef82cd6279d9acDouglas Gregor virtual CodeCompletionAllocator &getAllocator() { 2181218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor return Next.getAllocator(); 2182218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor } 218328a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis 218428a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() { 218528a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis return Next.getCodeCompletionTUInfo(); 218628a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis } 218787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor }; 218887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor} 2189697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 21905f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor/// \brief Helper function that computes which global names are hidden by the 21915f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor/// local code-completion results. 2192c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenekstatic void CalculateHiddenNames(const CodeCompletionContext &Context, 2193c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek CodeCompletionResult *Results, 2194c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek unsigned NumResults, 2195c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek ASTContext &Ctx, 2196c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek llvm::StringSet<llvm::BumpPtrAllocator> &HiddenNames){ 21975f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor bool OnlyTagNames = false; 21985f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor switch (Context.getKind()) { 219952779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor case CodeCompletionContext::CCC_Recovery: 22005f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_TopLevel: 22015f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCInterface: 22025f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCImplementation: 22035f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCIvarList: 22045f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ClassStructUnion: 22055f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_Statement: 22065f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_Expression: 22075f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCMessageReceiver: 22083da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_DotMemberAccess: 22093da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_ArrowMemberAccess: 22103da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_ObjCPropertyAccess: 22115f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_Namespace: 22125f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_Type: 22132ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor case CodeCompletionContext::CCC_Name: 22142ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor case CodeCompletionContext::CCC_PotentiallyQualifiedName: 22150268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor case CodeCompletionContext::CCC_ParenthesizedExpression: 22160f91c8ccb398be2bd40dc402309bd79737542396Douglas Gregor case CodeCompletionContext::CCC_ObjCInterfaceName: 22175f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor break; 22185f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 22195f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_EnumTag: 22205f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_UnionTag: 22215f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ClassOrStructTag: 22225f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor OnlyTagNames = true; 22235f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor break; 22245f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 22255f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCProtocolName: 22261fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor case CodeCompletionContext::CCC_MacroName: 22271fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor case CodeCompletionContext::CCC_MacroNameUse: 2228f29c5233085a5af795c3c01b94d319e5b3235d56Douglas Gregor case CodeCompletionContext::CCC_PreprocessorExpression: 2229721f359a350059a81945baa08f63b2e5feceb044Douglas Gregor case CodeCompletionContext::CCC_PreprocessorDirective: 223059a66946aa7723c7b14831aa50902d533baaa957Douglas Gregor case CodeCompletionContext::CCC_NaturalLanguage: 2231458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor case CodeCompletionContext::CCC_SelectorName: 22321a480c403a3b141ab89c9c59cf7b681102a1bfabDouglas Gregor case CodeCompletionContext::CCC_TypeQualifiers: 223352779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor case CodeCompletionContext::CCC_Other: 22345c722c7020b33da57090422b854072258a50b3f0Douglas Gregor case CodeCompletionContext::CCC_OtherWithMacros: 22353da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_ObjCInstanceMessage: 22363da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_ObjCClassMessage: 22373da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_ObjCCategoryName: 2238721f359a350059a81945baa08f63b2e5feceb044Douglas Gregor // We're looking for nothing, or we're looking for names that cannot 2239721f359a350059a81945baa08f63b2e5feceb044Douglas Gregor // be hidden. 22405f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor return; 22415f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor } 22425f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 22430a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall typedef CodeCompletionResult Result; 22445f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor for (unsigned I = 0; I != NumResults; ++I) { 22455f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (Results[I].Kind != Result::RK_Declaration) 22465f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor continue; 22475f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 22485f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor unsigned IDNS 22495f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor = Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace(); 22505f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 22515f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor bool Hiding = false; 22525f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (OnlyTagNames) 22535f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor Hiding = (IDNS & Decl::IDNS_Tag); 22545f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor else { 22555f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member | 2256a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Decl::IDNS_Namespace | Decl::IDNS_Ordinary | 2257a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Decl::IDNS_NonMemberOperator); 22584e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Ctx.getLangOpts().CPlusPlus) 22595f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenIDNS |= Decl::IDNS_Tag; 22605f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor Hiding = (IDNS & HiddenIDNS); 22615f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor } 22625f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 22635f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (!Hiding) 22645f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor continue; 22655f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 22665f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor DeclarationName Name = Results[I].Declaration->getDeclName(); 22675f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (IdentifierInfo *Identifier = Name.getAsIdentifierInfo()) 22685f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenNames.insert(Identifier->getName()); 22695f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor else 22705f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenNames.insert(Name.getAsString()); 22715f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor } 22725f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor} 22735f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 22745f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 2275697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregorvoid AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S, 2276697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor CodeCompletionContext Context, 22770a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall CodeCompletionResult *Results, 2278697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor unsigned NumResults) { 2279697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // Merge the results we were given with the results we cached. 2280697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor bool AddedResult = false; 2281026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith uint64_t InContexts = 2282026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith Context.getKind() == CodeCompletionContext::CCC_Recovery 2283026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith ? NormalContexts : (1LL << Context.getKind()); 22845f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor // Contains the set of names that are hidden by "local" completion results. 2285c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames; 22860a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall typedef CodeCompletionResult Result; 22875f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Result, 8> AllResults; 2288697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor for (ASTUnit::cached_completion_iterator 22895535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor C = AST.cached_completion_begin(), 22905535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor CEnd = AST.cached_completion_end(); 2291697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor C != CEnd; ++C) { 2292697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // If the context we are in matches any of the contexts we are 2293697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // interested in, we'll add this result. 2294697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if ((C->ShowInContexts & InContexts) == 0) 2295697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor continue; 2296697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 2297697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // If we haven't added any results previously, do so now. 2298697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (!AddedResult) { 22995f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor CalculateHiddenNames(Context, Results, NumResults, S.Context, 23005f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenNames); 2301697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor AllResults.insert(AllResults.end(), Results, Results + NumResults); 2302697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor AddedResult = true; 2303697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 2304697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 23055f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor // Determine whether this global completion result is hidden by a local 23065f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor // completion result. If so, skip it. 23075f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (C->Kind != CXCursor_MacroDefinition && 23085f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenNames.count(C->Completion->getTypedText())) 23095f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor continue; 23105f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 2311697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // Adjust priority based on similar type classes. 2312697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor unsigned Priority = C->Priority; 23131fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor CodeCompletionString *Completion = C->Completion; 2314697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (!Context.getPreferredType().isNull()) { 2315697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (C->Kind == CXCursor_MacroDefinition) { 2316697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Priority = getMacroUsagePriority(C->Completion->getTypedText(), 23174e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie S.getLangOpts(), 23181fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor Context.getPreferredType()->isAnyPointerType()); 2319697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } else if (C->Type) { 2320697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor CanQualType Expected 23215535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor = S.Context.getCanonicalType( 2322697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Context.getPreferredType().getUnqualifiedType()); 2323697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor SimplifiedTypeClass ExpectedSTC = getSimplifiedTypeClass(Expected); 2324697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (ExpectedSTC == C->TypeClass) { 2325697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // We know this type is similar; check for an exact match. 2326697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor llvm::StringMap<unsigned> &CachedCompletionTypes 23275535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor = AST.getCachedCompletionTypes(); 2328697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor llvm::StringMap<unsigned>::iterator Pos 23295535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor = CachedCompletionTypes.find(QualType(Expected).getAsString()); 2330697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type) 2331697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Priority /= CCF_ExactTypeMatch; 2332697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor else 2333697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Priority /= CCF_SimilarTypeMatch; 2334697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 2335697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 2336697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 2337697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 23381fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor // Adjust the completion string, if required. 23391fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor if (C->Kind == CXCursor_MacroDefinition && 23401fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) { 23411fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor // Create a new code-completion string that just contains the 23421fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor // macro name, without its arguments. 234328a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis CodeCompletionBuilder Builder(getAllocator(), getCodeCompletionTUInfo(), 234428a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis CCP_CodePattern, C->Availability); 2345218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor Builder.AddTypedTextChunk(C->Completion->getTypedText()); 23464125c37c71c6c8475019497de837204f0ee4370fDouglas Gregor Priority = CCP_CodePattern; 2347218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor Completion = Builder.TakeString(); 23481fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor } 23491fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor 2350c04bb926ef693c94560da254e87926e93bb9c92fArgyrios Kyrtzidis AllResults.push_back(Result(Completion, Priority, C->Kind, 235158ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor C->Availability)); 2352697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 2353697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 2354697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // If we did not add any cached completion results, just forward the 2355697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // results we were given to the next consumer. 2356697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (!AddedResult) { 2357697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Next.ProcessCodeCompleteResults(S, Context, Results, NumResults); 2358697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor return; 2359697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 23601e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor 2361697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Next.ProcessCodeCompleteResults(S, Context, AllResults.data(), 2362697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor AllResults.size()); 2363697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor} 2364697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 2365697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 2366697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 23675f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, 23681abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor RemappedFile *RemappedFiles, 23691abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor unsigned NumRemappedFiles, 2370cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor bool IncludeMacros, 2371cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor bool IncludeCodePatterns, 2372d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko bool IncludeBriefComments, 23731abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor CodeCompleteConsumer &Consumer, 2374d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie DiagnosticsEngine &Diag, LangOptions &LangOpts, 23751abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor SourceManager &SourceMgr, FileManager &FileMgr, 23765f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics, 23775f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers) { 23784f32786ac45210143654390177105eb749b614e9Ted Kremenek if (!Invocation) 23791abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor return; 23801abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 2381213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer CompletionTimer(WantTiming); 2382edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer CompletionTimer.setOutput("Code completion @ " + File + ":" + 23835f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner Twine(Line) + ":" + Twine(Column)); 2384df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 2385c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<CompilerInvocation> 23864f32786ac45210143654390177105eb749b614e9Ted Kremenek CCInvocation(new CompilerInvocation(*Invocation)); 23874f32786ac45210143654390177105eb749b614e9Ted Kremenek 23884f32786ac45210143654390177105eb749b614e9Ted Kremenek FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts(); 2389d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko CodeCompleteOptions &CodeCompleteOpts = FrontendOpts.CodeCompleteOpts; 23904f32786ac45210143654390177105eb749b614e9Ted Kremenek PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts(); 2391cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor 2392d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko CodeCompleteOpts.IncludeMacros = IncludeMacros && 2393d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko CachedCompletionResults.empty(); 2394d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko CodeCompleteOpts.IncludeCodePatterns = IncludeCodePatterns; 2395d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko CodeCompleteOpts.IncludeGlobals = CachedCompletionResults.empty(); 2396d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko CodeCompleteOpts.IncludeBriefComments = IncludeBriefComments; 2397d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko 2398d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion); 2399d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko 24001abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor FrontendOpts.CodeCompletionAt.FileName = File; 24011abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor FrontendOpts.CodeCompletionAt.Line = Line; 24021abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor FrontendOpts.CodeCompletionAt.Column = Column; 24031abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 24041abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set the language options appropriately. 2405d3b74d9ca4f239a7a90ad193378c494306c57352Ted Kremenek LangOpts = *CCInvocation->getLangOpts(); 24061abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 24076f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<CompilerInstance> Clang(new CompilerInstance()); 240803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 240903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek // Recover resources if we crash before exiting this method. 241025a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> 241125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek CICleanup(Clang.get()); 241203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 24134f32786ac45210143654390177105eb749b614e9Ted Kremenek Clang->setInvocation(&*CCInvocation); 24148616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile(); 24151abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 24161abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set up diagnostics, capturing any diagnostics produced. 241703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setDiagnostics(&Diag); 24181abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor CaptureDroppedDiagnostics Capture(true, 241903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getDiagnostics(), 24201abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor StoredDiagnostics); 2421f0c06a3fa424a7bf858d95f6e83c392dbb31ea43Manuel Klimek ProcessWarningOptions(Diag, CCInvocation->getDiagnosticOpts()); 24221abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 24231abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Create the target instance. 242403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), 242549a87549f4dc95ecb3d8a593b71df7c167a51f85Douglas Gregor &Clang->getTargetOpts())); 242603201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek if (!Clang->hasTarget()) { 24274f32786ac45210143654390177105eb749b614e9Ted Kremenek Clang->setInvocation(0); 2428bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor return; 24291abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor } 24301abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 24311abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Inform the target of the language options. 24321abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // 24331abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // FIXME: We shouldn't need to do this, the target should be immutable once 24341abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // created. This complexity should be lifted elsewhere. 243503201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); 24361abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 243703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs.size() == 1 && 24381abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor "Invocation must have exactly one source file!"); 24398616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis assert(Clang->getFrontendOpts().Inputs[0].getKind() != IK_AST && 24401abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor "FIXME: AST inputs not yet supported here!"); 24418616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis assert(Clang->getFrontendOpts().Inputs[0].getKind() != IK_LLVM_IR && 24421abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor "IR inputs not support here!"); 24431abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 24441abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 24451abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Use the source and file managers that we were given. 244603201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setFileManager(&FileMgr); 244703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setSourceManager(&SourceMgr); 24481abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 24491abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Remap files. 24501abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PreprocessorOpts.clearRemappedFiles(); 2451b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor PreprocessorOpts.RetainRemappedFileBuffers = true; 24522283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor for (unsigned I = 0; I != NumRemappedFiles; ++I) { 2453b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; 2454b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (const llvm::MemoryBuffer * 2455b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { 2456b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, memBuf); 2457b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis OwnedBuffers.push_back(memBuf); 2458b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } else { 2459b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const char *fname = fileOrBuf.get<const char *>(); 2460b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, fname); 2461b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 24622283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor } 24631abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 246487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Use the code completion consumer we were given, but adding any cached 246587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // code-completion results. 24667f946ad40877df749ad05392cc4b80dc4189d28fDouglas Gregor AugmentedCodeCompleteConsumer *AugmentedConsumer 2467d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko = new AugmentedCodeCompleteConsumer(*this, Consumer, CodeCompleteOpts); 246803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setCodeCompletionConsumer(AugmentedConsumer); 24691abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 2470df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // If we have a precompiled preamble, try to use it. We only allow 2471df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // the use of the precompiled preamble if we're if the completion 2472df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // point is within the main file, after the end of the precompiled 2473df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // preamble. 2474df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor llvm::MemoryBuffer *OverrideMainBuffer = 0; 24751872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek if (!getPreambleFile(this).empty()) { 2476105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola std::string CompleteFilePath(File); 24774488835d1c78221553909447cf87d7e4ff7f99fbRafael Espindola llvm::sys::fs::UniqueID CompleteFileID; 2478105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola 2479da4cb0cf401bb546574a7db46e50cda8b9d9c048Rafael Espindola if (!llvm::sys::fs::getUniqueID(CompleteFilePath, CompleteFileID)) { 2480105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola std::string MainPath(OriginalSourceFile); 24814488835d1c78221553909447cf87d7e4ff7f99fbRafael Espindola llvm::sys::fs::UniqueID MainID; 2482da4cb0cf401bb546574a7db46e50cda8b9d9c048Rafael Espindola if (!llvm::sys::fs::getUniqueID(MainPath, MainID)) { 2483105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola if (CompleteFileID == MainID && Line > 1) 24842283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor OverrideMainBuffer 24854f32786ac45210143654390177105eb749b614e9Ted Kremenek = getMainBufferWithPrecompiledPreamble(*CCInvocation, false, 2486c9c29a8d7a0f78ddf2b393dd92f77c7f2046179cDouglas Gregor Line - 1); 2487105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola } 2488105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola } 2489df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 2490df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 2491df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // If the main file has been overridden due to the use of a preamble, 2492df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // make that override happen and introduce the preamble. 2493df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (OverrideMainBuffer) { 2494df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); 2495df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size(); 2496df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second 2497df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor = PreambleEndsAtStartOfLine; 24981872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek PreprocessorOpts.ImplicitPCHInclude = getPreambleFile(this); 2499df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.DisablePCHValidation = true; 2500df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 25012283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor OwnedBuffers.push_back(OverrideMainBuffer); 2502f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor } else { 2503f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = 0; 2504f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second = false; 2505df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 2506df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 2507e50904f83b1b09bff487185dd823dfc8415cb300Argyrios Kyrtzidis // Disable the preprocessing record if modules are not enabled. 2508e50904f83b1b09bff487185dd823dfc8415cb300Argyrios Kyrtzidis if (!Clang->getLangOpts().Modules) 2509e50904f83b1b09bff487185dd823dfc8415cb300Argyrios Kyrtzidis PreprocessorOpts.DetailedRecord = false; 2510dca8ee8b7bc86076916a3a80f553f7a4e98c14afDouglas Gregor 25116f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<SyntaxOnlyAction> Act; 25121abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Act.reset(new SyntaxOnlyAction); 25131f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor if (Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) { 25141abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Act->Execute(); 25151abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Act->EndSourceFile(); 25161abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor } 25171abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor} 25187ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor 2519e6d22027bc22d3767a2acdc80299c76b91159867Argyrios Kyrtzidisbool ASTUnit::Save(StringRef File) { 25203b7deda7137e62810a810ce25b062927a9fc7c71Argyrios Kyrtzidis if (HadModuleLoaderFatalFailure) 25213b7deda7137e62810a810ce25b062927a9fc7c71Argyrios Kyrtzidis return true; 25223b7deda7137e62810a810ce25b062927a9fc7c71Argyrios Kyrtzidis 25239cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis // Write to a temporary file and later rename it to the actual file, to avoid 25249cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis // possible race conditions. 2525f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> TempPath; 25267e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis TempPath = File; 25277e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis TempPath += "-%%%%%%%%"; 25287e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis int fd; 252970e7aeccbf5856a84f81366c6c1a0c0c01e70063Rafael Espindola if (llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath)) 2530e6d22027bc22d3767a2acdc80299c76b91159867Argyrios Kyrtzidis return true; 25319cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis 25327ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor // FIXME: Can we somehow regenerate the stat cache here, or do we need to 25337ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor // unconditionally create a stat cache when we parse the file? 25347e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis llvm::raw_fd_ostream Out(fd, /*shouldClose=*/true); 2535b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 2536b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis serialize(Out); 2537b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis Out.close(); 25384bd265468cb115efd5c87c59d5a5b6af5d24d48cArgyrios Kyrtzidis if (Out.has_error()) { 25394bd265468cb115efd5c87c59d5a5b6af5d24d48cArgyrios Kyrtzidis Out.clear_error(); 2540e6d22027bc22d3767a2acdc80299c76b91159867Argyrios Kyrtzidis return true; 25414bd265468cb115efd5c87c59d5a5b6af5d24d48cArgyrios Kyrtzidis } 25429cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis 25438d2a701734f6e0aa778f6be4e6b6d561d8ba6fdbRafael Espindola if (llvm::sys::fs::rename(TempPath.str(), File)) { 25449cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis bool exists; 25459cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis llvm::sys::fs::remove(TempPath.str(), exists); 2546e6d22027bc22d3767a2acdc80299c76b91159867Argyrios Kyrtzidis return true; 25479cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis } 25489cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis 2549e6d22027bc22d3767a2acdc80299c76b91159867Argyrios Kyrtzidis return false; 2550b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis} 2551b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 2552900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidisstatic bool serializeUnit(ASTWriter &Writer, 2553900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis SmallVectorImpl<char> &Buffer, 2554900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis Sema &S, 2555900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis bool hasErrors, 2556900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis raw_ostream &OS) { 25574182ed686283b72736b287cbe28583cb641f8934Argyrios Kyrtzidis Writer.WriteAST(S, std::string(), 0, "", hasErrors); 2558900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis 2559900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis // Write the generated bitstream to "Out". 2560900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis if (!Buffer.empty()) 2561900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis OS.write(Buffer.data(), Buffer.size()); 2562900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis 2563900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis return false; 2564900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis} 2565900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis 25665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerbool ASTUnit::serialize(raw_ostream &OS) { 2567bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis bool hasErrors = getDiagnostics().hasErrorOccurred(); 2568b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 2569900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis if (WriterData) 2570900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis return serializeUnit(WriterData->Writer, WriterData->Buffer, 2571900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis getSema(), hasErrors, OS); 2572900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis 25738d6ff02cb78c67c615125782967b44d1b37e5815Daniel Dunbar SmallString<128> Buffer; 25747ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor llvm::BitstreamWriter Stream(Buffer); 2575a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl ASTWriter Writer(Stream); 2576900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis return serializeUnit(Writer, Buffer, getSema(), hasErrors, OS); 25777ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor} 2578f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 2579f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregortypedef ContinuousRangeMap<unsigned, int, 2> SLocRemap; 2580f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 2581f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregorstatic void TranslateSLoc(SourceLocation &L, SLocRemap &Remap) { 2582f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned Raw = L.getRawEncoding(); 2583f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const unsigned MacroBit = 1U << 31; 2584f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor L = SourceLocation::getFromRawEncoding((Raw & MacroBit) | 2585f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor ((Raw & ~MacroBit) + Remap.find(Raw & ~MacroBit)->second)); 2586f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor} 2587f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 2588f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregorvoid ASTUnit::TranslateStoredDiagnostics( 2589f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor ASTReader *MMan, 25905f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef ModName, 2591f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceManager &SrcMgr, 25925f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner const SmallVectorImpl<StoredDiagnostic> &Diags, 25935f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<StoredDiagnostic> &Out) { 2594f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // The stored diagnostic has the old source manager in it; update 2595f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // the locations to refer into the new source manager. We also need to remap 2596f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // all the locations to the new view. This includes the diag location, any 2597f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // associated source ranges, and the source ranges of associated fix-its. 2598f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // FIXME: There should be a cleaner way to do this. 2599f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 26005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<StoredDiagnostic, 4> Result; 2601f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Result.reserve(Diags.size()); 2602f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(MMan && "Don't have a module manager"); 26031a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor serialization::ModuleFile *Mod = MMan->ModuleMgr.lookup(ModName); 2604f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(Mod && "Don't have preamble module"); 2605f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SLocRemap &Remap = Mod->SLocRemap; 2606f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (unsigned I = 0, N = Diags.size(); I != N; ++I) { 2607f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Rebuild the StoredDiagnostic. 2608f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const StoredDiagnostic &SD = Diags[I]; 2609f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceLocation L = SD.getLocation(); 2610f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateSLoc(L, Remap); 2611f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FullSourceLoc Loc(L, SrcMgr); 2612f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 26135f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CharSourceRange, 4> Ranges; 2614f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Ranges.reserve(SD.range_size()); 2615f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (StoredDiagnostic::range_iterator I = SD.range_begin(), 2616f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor E = SD.range_end(); 2617f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor I != E; ++I) { 2618f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceLocation BL = I->getBegin(); 2619f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateSLoc(BL, Remap); 2620f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceLocation EL = I->getEnd(); 2621f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateSLoc(EL, Remap); 2622f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Ranges.push_back(CharSourceRange(SourceRange(BL, EL), I->isTokenRange())); 2623f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 2624f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 26255f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<FixItHint, 2> FixIts; 2626f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FixIts.reserve(SD.fixit_size()); 2627f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (StoredDiagnostic::fixit_iterator I = SD.fixit_begin(), 2628f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor E = SD.fixit_end(); 2629f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor I != E; ++I) { 2630f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FixIts.push_back(FixItHint()); 2631f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FixItHint &FH = FixIts.back(); 2632f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FH.CodeToInsert = I->CodeToInsert; 2633f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceLocation BL = I->RemoveRange.getBegin(); 2634f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateSLoc(BL, Remap); 2635f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceLocation EL = I->RemoveRange.getEnd(); 2636f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateSLoc(EL, Remap); 2637f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FH.RemoveRange = CharSourceRange(SourceRange(BL, EL), 2638f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor I->RemoveRange.isTokenRange()); 2639f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 2640f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 2641f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Result.push_back(StoredDiagnostic(SD.getLevel(), SD.getID(), 2642f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SD.getMessage(), Loc, Ranges, FixIts)); 2643f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 2644f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Result.swap(Out); 2645f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor} 2646507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis 2647332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidisstatic inline bool compLocDecl(std::pair<unsigned, Decl *> L, 2648332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis std::pair<unsigned, Decl *> R) { 2649332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis return L.first < R.first; 2650332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis} 2651332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 2652332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidisvoid ASTUnit::addFileLevelDecl(Decl *D) { 2653332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis assert(D); 265466e870029fdc1a36e79e62fd64430b527a318868Douglas Gregor 265566e870029fdc1a36e79e62fd64430b527a318868Douglas Gregor // We only care about local declarations. 265666e870029fdc1a36e79e62fd64430b527a318868Douglas Gregor if (D->isFromASTFile()) 265766e870029fdc1a36e79e62fd64430b527a318868Douglas Gregor return; 2658332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 2659332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis SourceManager &SM = *SourceMgr; 2660332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis SourceLocation Loc = D->getLocation(); 2661332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis if (Loc.isInvalid() || !SM.isLocalSourceLocation(Loc)) 2662332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis return; 2663332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 2664332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis // We only keep track of the file-level declarations of each file. 2665332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis if (!D->getLexicalDeclContext()->isFileContext()) 2666332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis return; 2667332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 2668332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis SourceLocation FileLoc = SM.getFileLoc(Loc); 2669332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis assert(SM.isLocalSourceLocation(FileLoc)); 2670332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis FileID FID; 2671332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis unsigned Offset; 2672332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis llvm::tie(FID, Offset) = SM.getDecomposedLoc(FileLoc); 2673332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis if (FID.isInvalid()) 2674332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis return; 2675332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 2676332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis LocDeclsTy *&Decls = FileDecls[FID]; 2677332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis if (!Decls) 2678332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis Decls = new LocDeclsTy(); 2679332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 2680332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis std::pair<unsigned, Decl *> LocDecl(Offset, D); 2681332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 2682332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis if (Decls->empty() || Decls->back().first <= Offset) { 2683332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis Decls->push_back(LocDecl); 2684332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis return; 2685332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis } 2686332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 2687332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis LocDeclsTy::iterator 2688332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis I = std::upper_bound(Decls->begin(), Decls->end(), LocDecl, compLocDecl); 2689332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 2690332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis Decls->insert(I, LocDecl); 2691332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis} 2692332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis 2693dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidisvoid ASTUnit::findFileRegionDecls(FileID File, unsigned Offset, unsigned Length, 2694dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis SmallVectorImpl<Decl *> &Decls) { 2695dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis if (File.isInvalid()) 2696dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis return; 2697dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis 2698dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis if (SourceMgr->isLoadedFileID(File)) { 2699dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis assert(Ctx->getExternalSource() && "No external source!"); 2700dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis return Ctx->getExternalSource()->FindFileRegionDecls(File, Offset, Length, 2701dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis Decls); 2702dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis } 2703dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis 2704dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis FileDeclsTy::iterator I = FileDecls.find(File); 2705dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis if (I == FileDecls.end()) 2706dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis return; 2707dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis 2708dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis LocDeclsTy &LocDecls = *I->second; 2709dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis if (LocDecls.empty()) 2710dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis return; 2711dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis 2712dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis LocDeclsTy::iterator 2713dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis BeginIt = std::lower_bound(LocDecls.begin(), LocDecls.end(), 2714dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis std::make_pair(Offset, (Decl*)0), compLocDecl); 2715dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis if (BeginIt != LocDecls.begin()) 2716dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis --BeginIt; 2717dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis 2718c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis // If we are pointing at a top-level decl inside an objc container, we need 2719c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis // to backtrack until we find it otherwise we will fail to report that the 2720c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis // region overlaps with an objc container. 2721c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis while (BeginIt != LocDecls.begin() && 2722c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis BeginIt->second->isTopLevelDeclInObjCContainer()) 2723c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis --BeginIt; 2724c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis 2725dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis LocDeclsTy::iterator 2726dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis EndIt = std::upper_bound(LocDecls.begin(), LocDecls.end(), 2727dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis std::make_pair(Offset+Length, (Decl*)0), 2728dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis compLocDecl); 2729dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis if (EndIt != LocDecls.end()) 2730dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis ++EndIt; 2731dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis 2732dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis for (LocDeclsTy::iterator DIt = BeginIt; DIt != EndIt; ++DIt) 2733dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis Decls.push_back(DIt->second); 2734dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis} 2735dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis 2736507097ec40105ed927cb5a744fad98f5875aacacArgyrios KyrtzidisSourceLocation ASTUnit::getLocation(const FileEntry *File, 2737507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis unsigned Line, unsigned Col) const { 2738507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis const SourceManager &SM = getSourceManager(); 2739ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis SourceLocation Loc = SM.translateFileLineCol(File, Line, Col); 2740507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis return SM.getMacroArgExpandedLocation(Loc); 2741507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis} 2742507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis 2743507097ec40105ed927cb5a744fad98f5875aacacArgyrios KyrtzidisSourceLocation ASTUnit::getLocation(const FileEntry *File, 2744507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis unsigned Offset) const { 2745507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis const SourceManager &SM = getSourceManager(); 2746ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis SourceLocation FileLoc = SM.translateFileLineCol(File, 1, 1); 2747507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis return SM.getMacroArgExpandedLocation(FileLoc.getLocWithOffset(Offset)); 2748507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis} 2749507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis 2750ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// \brief If \arg Loc is a loaded location from the preamble, returns 2751ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// the corresponding local location of the main file, otherwise it returns 2752ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// \arg Loc. 2753ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios KyrtzidisSourceLocation ASTUnit::mapLocationFromPreamble(SourceLocation Loc) { 2754ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis FileID PreambleID; 2755ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis if (SourceMgr) 2756ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis PreambleID = SourceMgr->getPreambleFileID(); 2757ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis 2758ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis if (Loc.isInvalid() || Preamble.empty() || PreambleID.isInvalid()) 2759ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis return Loc; 2760ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis 2761ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis unsigned Offs; 2762ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis if (SourceMgr->isInFileID(Loc, PreambleID, &Offs) && Offs < Preamble.size()) { 2763ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis SourceLocation FileLoc 2764ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis = SourceMgr->getLocForStartOfFile(SourceMgr->getMainFileID()); 2765ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis return FileLoc.getLocWithOffset(Offs); 2766ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis } 2767ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis 2768ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis return Loc; 2769ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis} 2770ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis 2771ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// \brief If \arg Loc is a local location of the main file but inside the 2772ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// preamble chunk, returns the corresponding loaded location from the 2773ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// preamble, otherwise it returns \arg Loc. 2774ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios KyrtzidisSourceLocation ASTUnit::mapLocationToPreamble(SourceLocation Loc) { 2775ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis FileID PreambleID; 2776ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis if (SourceMgr) 2777ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis PreambleID = SourceMgr->getPreambleFileID(); 2778ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis 2779ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis if (Loc.isInvalid() || Preamble.empty() || PreambleID.isInvalid()) 2780ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis return Loc; 2781ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis 2782ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis unsigned Offs; 2783ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis if (SourceMgr->isInFileID(Loc, SourceMgr->getMainFileID(), &Offs) && 2784ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis Offs < Preamble.size()) { 2785ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis SourceLocation FileLoc = SourceMgr->getLocForStartOfFile(PreambleID); 2786ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis return FileLoc.getLocWithOffset(Offs); 2787ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis } 2788ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis 2789ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis return Loc; 2790ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis} 2791ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis 2792f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidisbool ASTUnit::isInPreambleFileID(SourceLocation Loc) { 2793f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis FileID FID; 2794f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis if (SourceMgr) 2795f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis FID = SourceMgr->getPreambleFileID(); 2796f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis 2797f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis if (Loc.isInvalid() || FID.isInvalid()) 2798f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis return false; 2799f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis 2800f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis return SourceMgr->isInFileID(Loc, FID); 2801f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis} 2802f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis 2803f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidisbool ASTUnit::isInMainFileID(SourceLocation Loc) { 2804f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis FileID FID; 2805f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis if (SourceMgr) 2806f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis FID = SourceMgr->getMainFileID(); 2807f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis 2808f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis if (Loc.isInvalid() || FID.isInvalid()) 2809f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis return false; 2810f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis 2811f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis return SourceMgr->isInFileID(Loc, FID); 2812f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis} 2813f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis 2814f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios KyrtzidisSourceLocation ASTUnit::getEndOfPreambleFileID() { 2815f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis FileID FID; 2816f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis if (SourceMgr) 2817f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis FID = SourceMgr->getPreambleFileID(); 2818f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis 2819f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis if (FID.isInvalid()) 2820f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis return SourceLocation(); 2821f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis 2822f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis return SourceMgr->getLocForEndOfFile(FID); 2823f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis} 2824f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis 2825f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios KyrtzidisSourceLocation ASTUnit::getStartOfMainFileID() { 2826f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis FileID FID; 2827f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis if (SourceMgr) 2828f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis FID = SourceMgr->getMainFileID(); 2829f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis 2830f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis if (FID.isInvalid()) 2831f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis return SourceLocation(); 2832f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis 2833f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis return SourceMgr->getLocForStartOfFile(FID); 2834f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis} 2835f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis 2836632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidisstd::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> 2837632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios KyrtzidisASTUnit::getLocalPreprocessingEntities() const { 2838632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis if (isMainFileAST()) { 2839632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis serialization::ModuleFile & 2840632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis Mod = Reader->getModuleManager().getPrimaryModule(); 2841632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis return Reader->getModulePreprocessedEntities(Mod); 2842632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis } 2843632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis 2844632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis if (PreprocessingRecord *PPRec = PP->getPreprocessingRecord()) 2845632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis return std::make_pair(PPRec->local_begin(), PPRec->local_end()); 2846632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis 2847632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis return std::make_pair(PreprocessingRecord::iterator(), 2848632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis PreprocessingRecord::iterator()); 2849632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis} 2850632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis 285195c579cae01118eadd311d445ff7f491d0011fb0Argyrios Kyrtzidisbool ASTUnit::visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn) { 28522093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis if (isMainFileAST()) { 28532093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis serialization::ModuleFile & 28542093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis Mod = Reader->getModuleManager().getPrimaryModule(); 28552093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis ASTReader::ModuleDeclIterator MDI, MDE; 28562093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis llvm::tie(MDI, MDE) = Reader->getModuleFileLevelDecls(Mod); 28572093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis for (; MDI != MDE; ++MDI) { 28582093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis if (!Fn(context, *MDI)) 28592093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis return false; 28602093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis } 28612093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis 28622093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis return true; 28632093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis } 28642093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis 28652093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis for (ASTUnit::top_level_iterator TL = top_level_begin(), 28662093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis TLEnd = top_level_end(); 28672093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis TL != TLEnd; ++TL) { 28682093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis if (!Fn(context, *TL)) 28692093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis return false; 28702093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis } 28712093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis 28722093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis return true; 28732093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis} 28742093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis 28753da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidisnamespace { 28763da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidisstruct PCHLocatorInfo { 28773da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis serialization::ModuleFile *Mod; 28783da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis PCHLocatorInfo() : Mod(0) {} 28793da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis}; 28803da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis} 28813da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis 28823da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidisstatic bool PCHLocator(serialization::ModuleFile &M, void *UserData) { 28833da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis PCHLocatorInfo &Info = *static_cast<PCHLocatorInfo*>(UserData); 28843da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis switch (M.Kind) { 28853da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis case serialization::MK_Module: 28863da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis return true; // skip dependencies. 28873da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis case serialization::MK_PCH: 28883da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis Info.Mod = &M; 28893da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis return true; // found it. 28903da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis case serialization::MK_Preamble: 28913da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis return false; // look in dependencies. 28923da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis case serialization::MK_MainFile: 28933da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis return false; // look in dependencies. 28943da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis } 28953da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis 28963da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis return true; 28973da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis} 28983da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis 28993da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidisconst FileEntry *ASTUnit::getPCHFile() { 29003da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis if (!Reader) 29013da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis return 0; 29023da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis 29033da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis PCHLocatorInfo Info; 29043da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis Reader->getModuleManager().visit(PCHLocator, &Info); 29053da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis if (Info.Mod) 29063da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis return Info.Mod->File; 29073da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis 29083da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis return 0; 29093da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis} 29103da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis 291162288edde26ff4af9fc079c979a0e1bdc577ce9dArgyrios Kyrtzidisbool ASTUnit::isModuleFile() { 291262288edde26ff4af9fc079c979a0e1bdc577ce9dArgyrios Kyrtzidis return isMainFileAST() && !ASTFileLangOpts.CurrentModule.empty(); 291362288edde26ff4af9fc079c979a0e1bdc577ce9dArgyrios Kyrtzidis} 291462288edde26ff4af9fc079c979a0e1bdc577ce9dArgyrios Kyrtzidis 2915507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidisvoid ASTUnit::PreambleData::countLines() const { 2916507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis NumLines = 0; 2917507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis if (empty()) 2918507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis return; 2919507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis 2920507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis for (std::vector<char>::const_iterator 2921507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis I = Buffer.begin(), E = Buffer.end(); I != E; ++I) { 2922507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis if (*I == '\n') 2923507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis ++NumLines; 2924507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis } 2925507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis if (Buffer.back() != '\n') 2926507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis ++NumLines; 2927507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis} 2928a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis 2929a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis#ifndef NDEBUG 2930a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios KyrtzidisASTUnit::ConcurrencyState::ConcurrencyState() { 2931a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis Mutex = new llvm::sys::MutexImpl(/*recursive=*/true); 2932a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis} 2933a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis 2934a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios KyrtzidisASTUnit::ConcurrencyState::~ConcurrencyState() { 2935a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis delete static_cast<llvm::sys::MutexImpl *>(Mutex); 2936a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis} 2937a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis 2938a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidisvoid ASTUnit::ConcurrencyState::start() { 2939a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis bool acquired = static_cast<llvm::sys::MutexImpl *>(Mutex)->tryacquire(); 2940a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis assert(acquired && "Concurrent access to ASTUnit!"); 2941a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis} 2942a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis 2943a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidisvoid ASTUnit::ConcurrencyState::finish() { 2944a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis static_cast<llvm::sys::MutexImpl *>(Mutex)->release(); 2945a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis} 2946a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis 2947a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis#else // NDEBUG 2948a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis 2949a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios KyrtzidisASTUnit::ConcurrencyState::ConcurrencyState() {} 2950a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios KyrtzidisASTUnit::ConcurrencyState::~ConcurrencyState() {} 2951a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidisvoid ASTUnit::ConcurrencyState::start() {} 2952a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidisvoid ASTUnit::ConcurrencyState::finish() {} 2953a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis 2954a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis#endif 2955