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" 150853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/AST/ASTContext.h" 16521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/AST/ASTConsumer.h" 170853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/AST/DeclVisitor.h" 18f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor#include "clang/AST/TypeOrdering.h" 190853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/AST/StmtVisitor.h" 207b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Driver/Compilation.h" 217b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Driver/Driver.h" 227b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Driver/Job.h" 234e03c2b9d735063a60cd0623423f4814178857efArgyrios Kyrtzidis#include "clang/Driver/ArgList.h" 244e03c2b9d735063a60cd0623423f4814178857efArgyrios Kyrtzidis#include "clang/Driver/Options.h" 257b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Driver/Tool.h" 26521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/CompilerInstance.h" 27521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/FrontendActions.h" 287b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Frontend/FrontendDiagnostic.h" 29521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/FrontendOptions.h" 3032be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor#include "clang/Frontend/Utils.h" 316ab7cd853e9c15cf986a8a7c3db1f8d20e275409Sebastian Redl#include "clang/Serialization/ASTReader.h" 327faa2ec03a7ef120ac165bb45b6c70a8b20c9f1cSebastian Redl#include "clang/Serialization/ASTWriter.h" 330853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Lex/HeaderSearch.h" 340853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Lex/Preprocessor.h" 35d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar#include "clang/Basic/TargetOptions.h" 360853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Basic/TargetInfo.h" 370853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Basic/Diagnostic.h" 387f9fc3f7ce076645cb6aefc99c64d9446caf13d6Chris Lattner#include "llvm/ADT/ArrayRef.h" 399b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor#include "llvm/ADT/StringExtras.h" 40349d38cef04ddf8938047c1b542a799aa82dfe84Douglas Gregor#include "llvm/ADT/StringSet.h" 411fd9e0def66fbd50e99be5ff87c9fd1c91c428abDouglas Gregor#include "llvm/Support/Atomic.h" 424db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor#include "llvm/Support/MemoryBuffer.h" 4303013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Host.h" 4403013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Path.h" 45df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor#include "llvm/Support/raw_ostream.h" 46385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor#include "llvm/Support/Timer.h" 479cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis#include "llvm/Support/FileSystem.h" 48a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis#include "llvm/Support/Mutex.h" 49b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek#include "llvm/Support/CrashRecoveryContext.h" 5044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor#include <cstdlib> 51ad23ebe22b7e52e3875981eeb46a1fd61a7554fbZhongxing Xu#include <cstdio> 52cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor#include <sys/stat.h> 530853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisusing namespace clang; 540853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 55213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregorusing llvm::TimeRecord; 56213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 57213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregornamespace { 58213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor class SimpleTimer { 59213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor bool WantTiming; 60213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor TimeRecord Start; 61213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor std::string Output; 62213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 63edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer public: 649dba61a1e46099b77adf15de224aaa16037a7fffDouglas Gregor explicit SimpleTimer(bool WantTiming) : WantTiming(WantTiming) { 65213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor if (WantTiming) 66edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer Start = TimeRecord::getCurrentTime(); 67213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor } 68213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 695f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner void setOutput(const Twine &Output) { 70213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor if (WantTiming) 71edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer this->Output = Output.str(); 72213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor } 73213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 74213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor ~SimpleTimer() { 75213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor if (WantTiming) { 76213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor TimeRecord Elapsed = TimeRecord::getCurrentTime(); 77213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor Elapsed -= Start; 78213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor llvm::errs() << Output << ':'; 79213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor Elapsed.print(Elapsed, llvm::errs()); 80213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor llvm::errs() << '\n'; 81213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor } 82213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor } 83213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor }; 84213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor} 85213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 86eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// \brief After failing to build a precompiled preamble (due to 87eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// errors in the source that occurs in the preamble), the number of 88eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// reparses during which we'll skip even trying to precompile the 89eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// preamble. 90eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregorconst unsigned DefaultPreambleRebuildInterval = 5; 91eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 92e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor/// \brief Tracks the number of ASTUnit objects that are currently active. 93e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor/// 94e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor/// Used for debugging purposes only. 951fd9e0def66fbd50e99be5ff87c9fd1c91c428abDouglas Gregorstatic llvm::sys::cas_flag ActiveASTUnitObjects; 96e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor 973687e9d3a5dbfa9963af02a49a2b139d91310813Douglas GregorASTUnit::ASTUnit(bool _MainFileIsAST) 98b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis : OnlyLocalDecls(false), CaptureDiagnostics(false), 99b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis MainFileIsAST(_MainFileIsAST), 100467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor TUKind(TU_Complete), WantTiming(getenv("LIBCLANG_TIMING")), 10115727ddb11405c45372150b5bfb07dbfa4c9960bArgyrios Kyrtzidis OwnsRemappedFileBuffers(true), 102213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor NumStoredDiagnosticsFromDriver(0), 103671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreambleRebuildCounter(0), SavedMainFileBuffer(0), PreambleBuffer(0), 104727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor ShouldCacheCodeCompletionResults(false), 105ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth NestedMacroExpansions(true), 1069b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CompletionCacheTopLevelHashValue(0), 1079b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor PreambleTopLevelHashValue(0), 1089b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CurrentTopLevelHashValue(0), 1098b1540c159093e0e627ebf6542d0c0b7aba99eafDouglas Gregor UnsafeToFree(false) { 110e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor if (getenv("LIBCLANG_OBJTRACKING")) { 1111fd9e0def66fbd50e99be5ff87c9fd1c91c428abDouglas Gregor llvm::sys::AtomicIncrement(&ActiveASTUnitObjects); 112e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor fprintf(stderr, "+++ %d translation units\n", ActiveASTUnitObjects); 113e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor } 114385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor} 1153687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor 116521bf9c529e653ab28896d027352d3e16e2672d5Daniel DunbarASTUnit::~ASTUnit() { 117abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor CleanTemporaryFiles(); 118175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (!PreambleFile.empty()) 119385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor llvm::sys::Path(PreambleFile).eraseFromDisk(); 120f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 121f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // Free the buffers associated with remapped files. We are required to 122f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // perform this operation here because we explicitly request that the 123f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // compiler instance *not* free these buffers for each invocation of the 124f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // parser. 1254f32786ac45210143654390177105eb749b614e9Ted Kremenek if (Invocation.getPtr() && OwnsRemappedFileBuffers) { 126f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 127f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 128f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor FB = PPOpts.remapped_file_buffer_begin(), 129f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor FBEnd = PPOpts.remapped_file_buffer_end(); 130f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor FB != FBEnd; 131f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor ++FB) 132f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor delete FB->second; 133f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor } 13428233428da1ebec20c893d6297ae3191318940ddDouglas Gregor 13528233428da1ebec20c893d6297ae3191318940ddDouglas Gregor delete SavedMainFileBuffer; 136671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete PreambleBuffer; 137671947b18dba342f9aba022ee992babef325a833Douglas Gregor 138213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor ClearCachedCompletionResults(); 139e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor 140e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor if (getenv("LIBCLANG_OBJTRACKING")) { 1411fd9e0def66fbd50e99be5ff87c9fd1c91c428abDouglas Gregor llvm::sys::AtomicDecrement(&ActiveASTUnitObjects); 142e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor fprintf(stderr, "--- %d translation units\n", ActiveASTUnitObjects); 143e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor } 144abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 145abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 146abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregorvoid ASTUnit::CleanTemporaryFiles() { 147313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I) 148313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor TemporaryFiles[I].eraseFromDisk(); 149abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor TemporaryFiles.clear(); 150e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff} 1510853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 1528071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor/// \brief Determine the set of code-completion contexts in which this 1538071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor/// declaration should be shown. 1548071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregorstatic unsigned getDeclShowContexts(NamedDecl *ND, 155a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor const LangOptions &LangOpts, 156a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor bool &IsNestedNameSpecifier) { 157a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = false; 158a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor 1598071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (isa<UsingShadowDecl>(ND)) 1608071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor ND = dyn_cast<NamedDecl>(ND->getUnderlyingDecl()); 1618071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (!ND) 1628071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor return 0; 1638071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 1648071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor unsigned Contexts = 0; 1658071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND) || 1668071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND)) { 1678071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // Types can appear in these contexts. 1688071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus || !isa<TagDecl>(ND)) 1698071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_TopLevel - 1)) 1708071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1)) 1718071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1)) 1728071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor | (1 << (CodeCompletionContext::CCC_Statement - 1)) 1730268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_Type - 1)) 1740268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)); 1758071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 1768071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // In C++, types can appear in expressions contexts (for functional casts). 1778071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus) 1788071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_Expression - 1)); 1798071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 1808071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // In Objective-C, message sends can send interfaces. In Objective-C++, 1818071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // all types are available due to functional casts. 1828071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus || isa<ObjCInterfaceDecl>(ND)) 1838071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)); 1843da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor 1853da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor // In Objective-C, you can only be a subclass of another Objective-C class 1863da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor if (isa<ObjCInterfaceDecl>(ND)) 1870f91c8ccb398be2bd40dc402309bd79737542396Douglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_ObjCInterfaceName - 1)); 1888071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 1898071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // Deal with tag names. 1908071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (isa<EnumDecl>(ND)) { 1918071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_EnumTag - 1)); 1928071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 193a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // Part of the nested-name-specifier in C++0x. 1948071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus0x) 195a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = true; 1968071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } else if (RecordDecl *Record = dyn_cast<RecordDecl>(ND)) { 1978071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (Record->isUnion()) 1988071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_UnionTag - 1)); 1998071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor else 2008071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1)); 2018071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 2028071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus) 203a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = true; 20452779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor } else if (isa<ClassTemplateDecl>(ND)) 205a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = true; 2068071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } else if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) { 2078071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // Values can appear in these contexts. 2088071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts = (1 << (CodeCompletionContext::CCC_Statement - 1)) 2098071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor | (1 << (CodeCompletionContext::CCC_Expression - 1)) 2100268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)) 2118071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)); 2128071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } else if (isa<ObjCProtocolDecl>(ND)) { 2138071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts = (1 << (CodeCompletionContext::CCC_ObjCProtocolName - 1)); 2143da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor } else if (isa<ObjCCategoryDecl>(ND)) { 2153da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor Contexts = (1 << (CodeCompletionContext::CCC_ObjCCategoryName - 1)); 2168071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } else if (isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) { 217a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Contexts = (1 << (CodeCompletionContext::CCC_Namespace - 1)); 2188071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 2198071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // Part of the nested-name-specifier. 220a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = true; 2218071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } 2228071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 2238071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor return Contexts; 2248071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor} 2258071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 22687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregorvoid ASTUnit::CacheCodeCompletionResults() { 22787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor if (!TheSema) 22887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor return; 22987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 230213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer Timer(WantTiming); 231edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer Timer.setOutput("Cache global code completions for " + getMainFileName()); 23287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 23387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Clear out the previous results. 23487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor ClearCachedCompletionResults(); 23587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 23687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Gather the set of global code completions. 2370a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall typedef CodeCompletionResult Result; 2385f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Result, 8> Results; 23948601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor CachedCompletionAllocator = new GlobalCodeCompletionAllocator; 24048601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor TheSema->GatherGlobalCodeCompletions(*CachedCompletionAllocator, Results); 24187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 24287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Translate global code completions into cached completions. 243f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor llvm::DenseMap<CanQualType, unsigned> CompletionTypes; 244f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 24587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor for (unsigned I = 0, N = Results.size(); I != N; ++I) { 24687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor switch (Results[I].Kind) { 2478071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor case Result::RK_Declaration: { 248a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor bool IsNestedNameSpecifier = false; 2498071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedCodeCompletionResult CachedResult; 250218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema, 25148601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor *CachedCompletionAllocator); 2528071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedResult.ShowInContexts = getDeclShowContexts(Results[I].Declaration, 253a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Ctx->getLangOptions(), 254a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier); 2558071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedResult.Priority = Results[I].Priority; 2568071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedResult.Kind = Results[I].CursorKind; 25758ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor CachedResult.Availability = Results[I].Availability; 258c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor 259f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // Keep track of the type of this completion in an ASTContext-agnostic 260f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // way. 261c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor QualType UsageType = getDeclUsageType(*Ctx, Results[I].Declaration); 262f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor if (UsageType.isNull()) { 263c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor CachedResult.TypeClass = STC_Void; 264f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedResult.Type = 0; 265f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor } else { 266f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CanQualType CanUsageType 267f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor = Ctx->getCanonicalType(UsageType.getUnqualifiedType()); 268f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedResult.TypeClass = getSimplifiedTypeClass(CanUsageType); 269f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 270f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // Determine whether we have already seen this type. If so, we save 271f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // ourselves the work of formatting the type string by using the 272f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // temporary, CanQualType-based hash table to find the associated value. 273f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor unsigned &TypeValue = CompletionTypes[CanUsageType]; 274f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor if (TypeValue == 0) { 275f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor TypeValue = CompletionTypes.size(); 276f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedCompletionTypes[QualType(CanUsageType).getAsString()] 277f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor = TypeValue; 278f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor } 279f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 280f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedResult.Type = TypeValue; 281c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor } 282f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 2838071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedCompletionResults.push_back(CachedResult); 284a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor 285a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor /// Handle nested-name-specifiers in C++. 286a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor if (TheSema->Context.getLangOptions().CPlusPlus && 287a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier && !Results[I].StartsNestedNameSpecifier) { 288a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // The contexts in which a nested-name-specifier can appear in C++. 289a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor unsigned NNSContexts 290a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor = (1 << (CodeCompletionContext::CCC_TopLevel - 1)) 291a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1)) 292a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1)) 293a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_Statement - 1)) 294a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_Expression - 1)) 295a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)) 296a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_EnumTag - 1)) 297a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_UnionTag - 1)) 298a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1)) 2992ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor | (1 << (CodeCompletionContext::CCC_Type - 1)) 3000268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_PotentiallyQualifiedName - 1)) 3010268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)); 302a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor 303a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor if (isa<NamespaceDecl>(Results[I].Declaration) || 304a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor isa<NamespaceAliasDecl>(Results[I].Declaration)) 305a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor NNSContexts |= (1 << (CodeCompletionContext::CCC_Namespace - 1)); 306a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor 307a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor if (unsigned RemainingContexts 308a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor = NNSContexts & ~CachedResult.ShowInContexts) { 309a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // If there any contexts where this completion can be a 310a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // nested-name-specifier but isn't already an option, create a 311a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // nested-name-specifier completion. 312a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Results[I].StartsNestedNameSpecifier = true; 313218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor CachedResult.Completion 314218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor = Results[I].CreateCodeCompletionString(*TheSema, 31548601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor *CachedCompletionAllocator); 316a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedResult.ShowInContexts = RemainingContexts; 317a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedResult.Priority = CCP_NestedNameSpecifier; 318a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedResult.TypeClass = STC_Void; 319a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedResult.Type = 0; 320a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedCompletionResults.push_back(CachedResult); 321a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor } 322a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor } 32387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor break; 3248071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } 3258071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 32687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor case Result::RK_Keyword: 32787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor case Result::RK_Pattern: 32887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Ignore keywords and patterns; we don't care, since they are so 32987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // easily regenerated. 33087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor break; 33187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 33287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor case Result::RK_Macro: { 33387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedCodeCompletionResult CachedResult; 334218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor CachedResult.Completion 335218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor = Results[I].CreateCodeCompletionString(*TheSema, 33648601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor *CachedCompletionAllocator); 33787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedResult.ShowInContexts 33887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor = (1 << (CodeCompletionContext::CCC_TopLevel - 1)) 33987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCInterface - 1)) 34087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCImplementation - 1)) 34187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1)) 34287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1)) 34387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_Statement - 1)) 34487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_Expression - 1)) 3451fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)) 346f29c5233085a5af795c3c01b94d319e5b3235d56Douglas Gregor | (1 << (CodeCompletionContext::CCC_MacroNameUse - 1)) 3470268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_PreprocessorExpression - 1)) 3485c722c7020b33da57090422b854072258a50b3f0Douglas Gregor | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)) 3495c722c7020b33da57090422b854072258a50b3f0Douglas Gregor | (1 << (CodeCompletionContext::CCC_OtherWithMacros - 1)); 3502ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor 35187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedResult.Priority = Results[I].Priority; 35287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedResult.Kind = Results[I].CursorKind; 35358ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor CachedResult.Availability = Results[I].Availability; 3541827e10051638770ad9ccf3e285caf95f995afd1Douglas Gregor CachedResult.TypeClass = STC_Void; 355f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedResult.Type = 0; 35687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedCompletionResults.push_back(CachedResult); 35787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor break; 35887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 35987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 36087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 3619b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 3629b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor // Save the current top-level hash value. 3639b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CompletionCacheTopLevelHashValue = CurrentTopLevelHashValue; 36487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor} 36587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 36687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregorvoid ASTUnit::ClearCachedCompletionResults() { 36787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedCompletionResults.clear(); 368f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedCompletionTypes.clear(); 36948601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor CachedCompletionAllocator = 0; 37087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor} 37187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 3720853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisnamespace { 3730853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 374c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl/// \brief Gathers information from ASTReader that will be used to initialize 3750853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis/// a Preprocessor. 3763c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redlclass ASTInfoCollector : public ASTReaderListener { 377998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor Preprocessor &PP; 378bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor ASTContext &Context; 3790853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis LangOptions &LangOpt; 3800853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis HeaderSearch &HSI; 381998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor llvm::IntrusiveRefCntPtr<TargetInfo> &Target; 3820853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string &Predefines; 3830853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned &Counter; 3841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3850853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned NumHeaderInfos; 3861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 387bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor bool InitializedLanguage; 3880853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidispublic: 389bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor ASTInfoCollector(Preprocessor &PP, ASTContext &Context, LangOptions &LangOpt, 390bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor HeaderSearch &HSI, 391998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor llvm::IntrusiveRefCntPtr<TargetInfo> &Target, 392998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor std::string &Predefines, 3930853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned &Counter) 394bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor : PP(PP), Context(Context), LangOpt(LangOpt), HSI(HSI), Target(Target), 395998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor Predefines(Predefines), Counter(Counter), NumHeaderInfos(0), 396bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor InitializedLanguage(false) {} 3971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3980853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis virtual bool ReadLanguageOptions(const LangOptions &LangOpts) { 399bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (InitializedLanguage) 400998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor return false; 401998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor 4020853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis LangOpt = LangOpts; 403998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor 404998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor // Initialize the preprocessor. 405998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor PP.Initialize(*Target); 406bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor 407bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor // Initialize the ASTContext 408bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Context.InitBuiltinTypes(*Target); 409bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor 410bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor InitializedLanguage = true; 4110853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return false; 4120853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 4131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4145f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner virtual bool ReadTargetTriple(StringRef Triple) { 415998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor // If we've already initialized the target, don't do it again. 416998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor if (Target) 417998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor return false; 418998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor 419998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor // FIXME: This is broken, we should store the TargetOptions in the AST file. 420998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor TargetOptions TargetOpts; 421998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor TargetOpts.ABI = ""; 422998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor TargetOpts.CXXABI = ""; 423998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor TargetOpts.CPU = ""; 424998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor TargetOpts.Features.clear(); 425998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor TargetOpts.Triple = Triple; 426998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor Target = TargetInfo::CreateTargetInfo(PP.getDiagnostics(), TargetOpts); 4270853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return false; 4280853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 4291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 430cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, 4315f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef OriginalFileName, 432277a6e752512cff286190d35cb353ce717e86b18Nick Lewycky std::string &SuggestedPredefines, 433277a6e752512cff286190d35cb353ce717e86b18Nick Lewycky FileManager &FileMgr) { 434cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl Predefines = Buffers[0].Data; 435cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl for (unsigned I = 1, N = Buffers.size(); I != N; ++I) { 436cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl Predefines += Buffers[I].Data; 437cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl } 4380853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return false; 4390853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 4401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 441ec1afbfd8e880d0169aab0ececa2e7e1611f4955Douglas Gregor virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID) { 4420853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis HSI.setHeaderFileInfoForUID(HFI, NumHeaderInfos++); 4430853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 4441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4450853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis virtual void ReadCounter(unsigned Value) { 4460853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Counter = Value; 4470853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 4480853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis}; 4490853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 45026e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikieclass StoredDiagnosticConsumer : public DiagnosticConsumer { 4515f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<StoredDiagnostic> &StoredDiags; 452a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 453a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorpublic: 45426e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikie explicit StoredDiagnosticConsumer( 4555f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<StoredDiagnostic> &StoredDiags) 456a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor : StoredDiags(StoredDiags) { } 457a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 458d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie virtual void HandleDiagnostic(DiagnosticsEngine::Level Level, 45940847cfb58acc3cac7d68727df9455ac45f2e118David Blaikie const Diagnostic &Info); 460aee526e77657afd1600276450e9c346953ad51d7Douglas Gregor 461aee526e77657afd1600276450e9c346953ad51d7Douglas Gregor DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const { 462aee526e77657afd1600276450e9c346953ad51d7Douglas Gregor // Just drop any diagnostics that come from cloned consumers; they'll 463aee526e77657afd1600276450e9c346953ad51d7Douglas Gregor // have different source managers anyway. 464aee526e77657afd1600276450e9c346953ad51d7Douglas Gregor return new IgnoringDiagConsumer(); 465aee526e77657afd1600276450e9c346953ad51d7Douglas Gregor } 466a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}; 467a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 468a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor/// \brief RAII object that optionally captures diagnostics, if 469a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor/// there is no diagnostic client to capture them already. 470a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorclass CaptureDroppedDiagnostics { 471d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie DiagnosticsEngine &Diags; 47226e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikie StoredDiagnosticConsumer Client; 47378ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie DiagnosticConsumer *PreviousClient; 474a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 475a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorpublic: 476d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie CaptureDroppedDiagnostics(bool RequestCapture, DiagnosticsEngine &Diags, 4775f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<StoredDiagnostic> &StoredDiags) 478bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor : Diags(Diags), Client(StoredDiags), PreviousClient(0) 479a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor { 480bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor if (RequestCapture || Diags.getClient() == 0) { 481bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor PreviousClient = Diags.takeClient(); 482a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor Diags.setClient(&Client); 483bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor } 484a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor } 485a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 486a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor ~CaptureDroppedDiagnostics() { 487bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor if (Diags.getClient() == &Client) { 488bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor Diags.takeClient(); 489bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor Diags.setClient(PreviousClient); 490bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor } 491a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor } 492a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}; 493a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 4940853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis} // anonymous namespace 4950853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 49626e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikievoid StoredDiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level Level, 49740847cfb58acc3cac7d68727df9455ac45f2e118David Blaikie const Diagnostic &Info) { 498f2224d89a6ae65a3839529e26d0f6d025d83d6bbArgyrios Kyrtzidis // Default implementation (Warnings/errors count). 49978ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie DiagnosticConsumer::HandleDiagnostic(Level, Info); 500f2224d89a6ae65a3839529e26d0f6d025d83d6bbArgyrios Kyrtzidis 501a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor StoredDiags.push_back(StoredDiagnostic(Level, Info)); 502a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor} 503a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 50477accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroffconst std::string &ASTUnit::getOriginalSourceFileName() { 50568d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar return OriginalSourceFile; 50677accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroff} 5070853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 5085f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerllvm::MemoryBuffer *ASTUnit::getBufferForFile(StringRef Filename, 50975dfb65c38d51772df9a00ce2d2feeefd55667adChris Lattner std::string *ErrorStr) { 51039b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner assert(FileMgr); 51175dfb65c38d51772df9a00ce2d2feeefd55667adChris Lattner return FileMgr->getBufferForFile(Filename, ErrorStr); 512389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis} 513389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis 514e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor/// \brief Configure the diagnostics object for use with ASTUnit. 515d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikievoid ASTUnit::ConfigureDiags(llvm::IntrusiveRefCntPtr<DiagnosticsEngine> &Diags, 5160b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor const char **ArgBegin, const char **ArgEnd, 517e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor ASTUnit &AST, bool CaptureDiagnostics) { 518e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor if (!Diags.getPtr()) { 519e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor // No diagnostics engine was provided, so create our own diagnostics object 520e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor // with the default options. 521e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor DiagnosticOptions DiagOpts; 52278ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie DiagnosticConsumer *Client = 0; 523e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor if (CaptureDiagnostics) 52426e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikie Client = new StoredDiagnosticConsumer(AST.StoredDiagnostics); 5250b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor Diags = CompilerInstance::createDiagnostics(DiagOpts, ArgEnd- ArgBegin, 5260b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor ArgBegin, Client); 527e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor } else if (CaptureDiagnostics) { 52826e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikie Diags->setClient(new StoredDiagnosticConsumer(AST.StoredDiagnostics)); 529e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor } 530e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor} 531e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor 5323c7f4134603d04b44f997b43c0a9def270f25386Sebastian RedlASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, 533d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 534389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis const FileSystemOptions &FileSystemOpts, 5355cf48766d626ff6b223acc9d4b7e415ca8480836Ted Kremenek bool OnlyLocalDecls, 5364db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFile *RemappedFiles, 537a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor unsigned NumRemappedFiles, 538a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor bool CaptureDiagnostics) { 5393687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true)); 540b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek 541b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek // Recover resources if we crash before exiting this method. 54225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> 54325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek ASTUnitCleanup(AST.get()); 544d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, 545d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > 54625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek DiagCleanup(Diags.getPtr()); 547b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek 5480b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics); 549abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 5507d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor AST->OnlyLocalDecls = OnlyLocalDecls; 551e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor AST->CaptureDiagnostics = CaptureDiagnostics; 55228019772db70d4547be05a042eb950bc910f134fDouglas Gregor AST->Diagnostics = Diags; 5534f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->FileMgr = new FileManager(FileSystemOpts); 5544f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->SourceMgr = new SourceManager(AST->getDiagnostics(), 5554f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->getFileManager()); 55639b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager())); 557914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor 5584db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor for (unsigned I = 0; I != NumRemappedFiles; ++I) { 559b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; 560b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (const llvm::MemoryBuffer * 561b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { 562b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // Create the file entry for the file that we're mapping from. 563b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *FromFile 564b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis = AST->getFileManager().getVirtualFile(RemappedFiles[I].first, 565b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf->getBufferSize(), 566b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 0); 567b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (!FromFile) { 568b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file) 569b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis << RemappedFiles[I].first; 570b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis delete memBuf; 571b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis continue; 572b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 573b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 574b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // Override the contents of the "from" file with the contents of 575b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // the "to" file. 576b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis AST->getSourceManager().overrideFileContents(FromFile, memBuf); 577b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 578b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } else { 579b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const char *fname = fileOrBuf.get<const char *>(); 580b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *ToFile = AST->FileMgr->getFile(fname); 581b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (!ToFile) { 582b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis AST->getDiagnostics().Report(diag::err_fe_remap_missing_to_file) 583b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis << RemappedFiles[I].first << fname; 584b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis continue; 585b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 586b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 587b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // Create the file entry for the file that we're mapping from. 588b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *FromFile 589b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis = AST->getFileManager().getVirtualFile(RemappedFiles[I].first, 590b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis ToFile->getSize(), 591b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 0); 592b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (!FromFile) { 593b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file) 594b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis << RemappedFiles[I].first; 595b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis delete memBuf; 596b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis continue; 597b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 598b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 599b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // Override the contents of the "from" file with the contents of 600b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // the "to" file. 601b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis AST->getSourceManager().overrideFileContents(FromFile, ToFile); 6024db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 6034db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 6044db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 6050853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // Gather Info for preprocessor construction later on. 6061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6070853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis HeaderSearch &HeaderInfo = *AST->HeaderInfo.get(); 6080853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string Predefines; 6090853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned Counter; 6100853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 611c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl llvm::OwningPtr<ASTReader> Reader; 6120853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 613998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor AST->PP = new Preprocessor(AST->getDiagnostics(), AST->ASTFileLangOpts, 614998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor /*Target=*/0, AST->getSourceManager(), HeaderInfo, 615998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor *AST, 616998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor /*IILookup=*/0, 617998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor /*OwnsHeaderSearch=*/false, 618998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor /*DelayInitialization=*/true); 619bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Preprocessor &PP = *AST->PP; 620bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor 621bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor AST->Ctx = new ASTContext(AST->ASTFileLangOpts, 622bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor AST->getSourceManager(), 623bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor /*Target=*/0, 624bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor PP.getIdentifierTable(), 625bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor PP.getSelectorTable(), 626bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor PP.getBuiltinInfo(), 627bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor /* size_reserve = */0, 628bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor /*DelayInitialization=*/true); 629bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor ASTContext &Context = *AST->Ctx; 630998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor 631f8a1e51c48761ee1d7803c3fa35ac94f42ebb55eDouglas Gregor Reader.reset(new ASTReader(PP, Context)); 6328c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek 6338c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek // Recover resources if we crash before exiting this method. 6348c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<ASTReader> 6358c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek ReaderCleanup(Reader.get()); 6368c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek 637bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Reader->setListener(new ASTInfoCollector(*AST->PP, Context, 638998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor AST->ASTFileLangOpts, HeaderInfo, 639998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor AST->Target, Predefines, Counter)); 640cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar 64172a9ae18553bf8b6bdad84d2c54f73741a47e275Douglas Gregor switch (Reader->ReadAST(Filename, serialization::MK_MainFile)) { 642c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl case ASTReader::Success: 6430853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis break; 6441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 645c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl case ASTReader::Failure: 646c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl case ASTReader::IgnorePCH: 6473687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch); 6480853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return NULL; 6490853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 6501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 65168d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar AST->OriginalSourceFile = Reader->getOriginalSourceFile(); 65268d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar 653d5b6126389e1e2fd89e498fe17da4bb44ece0302Daniel Dunbar PP.setPredefines(Reader->getSuggestedPredefines()); 6540853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis PP.setCounterValue(Counter); 6551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 656c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl // Attach the AST reader to the AST context as an external AST 6570853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // source, so that declarations will be deserialized from the 6583c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl // AST file as needed. 659c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl ASTReader *ReaderPtr = Reader.get(); 660914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor llvm::OwningPtr<ExternalASTSource> Source(Reader.take()); 6618c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek 6628c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek // Unregister the cleanup for ASTReader. It will get cleaned up 6638c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek // by the ASTUnit cleanup. 6648c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek ReaderCleanup.unregister(); 6658c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek 6660853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Context.setExternalSource(Source); 6670853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 668914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor // Create an AST consumer, even though it isn't used. 669914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor AST->Consumer.reset(new ASTConsumer); 670914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor 671c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl // Create a semantic analysis object and tell the AST reader about it. 672914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor AST->TheSema.reset(new Sema(PP, Context, *AST->Consumer)); 673914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor AST->TheSema->Initialize(); 674914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor ReaderPtr->InitializeSema(*AST->TheSema); 675914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor 6761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return AST.take(); 6770853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis} 678521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 679521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarnamespace { 680521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 6819b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor/// \brief Preprocessor callback class that updates a hash value with the names 6829b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor/// of all macros that have been defined by the translation unit. 6839b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregorclass MacroDefinitionTrackerPPCallbacks : public PPCallbacks { 6849b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor unsigned &Hash; 6859b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 6869b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregorpublic: 6879b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor explicit MacroDefinitionTrackerPPCallbacks(unsigned &Hash) : Hash(Hash) { } 6889b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 6899b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) { 6909b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Hash = llvm::HashString(MacroNameTok.getIdentifierInfo()->getName(), Hash); 6919b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 6929b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor}; 6939b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 6949b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor/// \brief Add the given declaration to the hash of all top-level entities. 6959b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregorvoid AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) { 6969b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (!D) 6979b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return; 6989b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 6999b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor DeclContext *DC = D->getDeclContext(); 7009b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (!DC) 7019b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return; 7029b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 7039b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (!(DC->isTranslationUnit() || DC->getLookupParent()->isTranslationUnit())) 7049b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return; 7059b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 7069b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 7079b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (ND->getIdentifier()) 7089b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Hash = llvm::HashString(ND->getIdentifier()->getName(), Hash); 7099b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor else if (DeclarationName Name = ND->getDeclName()) { 7109b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor std::string NameStr = Name.getAsString(); 7119b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Hash = llvm::HashString(NameStr, Hash); 7129b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 7139b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return; 7149b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 7159b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 7169b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (ObjCForwardProtocolDecl *Forward 7179b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor = dyn_cast<ObjCForwardProtocolDecl>(D)) { 7189b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor for (ObjCForwardProtocolDecl::protocol_iterator 7199b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor P = Forward->protocol_begin(), 7209b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor PEnd = Forward->protocol_end(); 7219b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor P != PEnd; ++P) 7229b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor AddTopLevelDeclarationToHash(*P, Hash); 7239b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return; 7249b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 7259b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 7265f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner if (ObjCClassDecl *Class = dyn_cast<ObjCClassDecl>(D)) { 72795ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian AddTopLevelDeclarationToHash(Class->getForwardInterfaceDecl(), Hash); 7289b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return; 7299b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 7309b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor} 7319b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 732f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerConsumer : public ASTConsumer { 733f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar ASTUnit &Unit; 7349b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor unsigned &Hash; 7359b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 736f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic: 7379b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor TopLevelDeclTrackerConsumer(ASTUnit &_Unit, unsigned &Hash) 7389b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor : Unit(_Unit), Hash(Hash) { 7399b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Hash = 0; 7409b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 7419b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 742f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar void HandleTopLevelDecl(DeclGroupRef D) { 743da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) { 744da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek Decl *D = *it; 745da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek // FIXME: Currently ObjC method declarations are incorrectly being 746da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek // reported as top-level declarations, even though their DeclContext 747da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek // is the containing ObjC @interface/@implementation. This is a 748da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek // fundamental problem in the parser right now. 749da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek if (isa<ObjCMethodDecl>(D)) 750da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek continue; 7519b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 7529b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor AddTopLevelDeclarationToHash(D, Hash); 753eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Unit.addTopLevelDecl(D); 754da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek } 755f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar } 75627372b4f1f402e95dd479ecf40c39ca71c15619fSebastian Redl 75727372b4f1f402e95dd479ecf40c39ca71c15619fSebastian Redl // We're not interested in "interesting" decls. 75827372b4f1f402e95dd479ecf40c39ca71c15619fSebastian Redl void HandleInterestingDecl(DeclGroupRef) {} 759f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar}; 760f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 761f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerAction : public ASTFrontendAction { 762f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic: 763f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar ASTUnit &Unit; 764f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 765521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 7665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef InFile) { 7679b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CI.getPreprocessor().addPPCallbacks( 7689b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor new MacroDefinitionTrackerPPCallbacks(Unit.getCurrentTopLevelHashValue())); 7699b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return new TopLevelDeclTrackerConsumer(Unit, 7709b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Unit.getCurrentTopLevelHashValue()); 771521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar } 772521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 773521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarpublic: 774f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {} 775f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 776521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar virtual bool hasCodeCompletionSupport() const { return false; } 777467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor virtual TranslationUnitKind getTranslationUnitKind() { 778467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor return Unit.getTranslationUnitKind(); 779df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 780521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar}; 781521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 78292ddef1bf843e1e18c040d69f48a6bf0bc7c776aArgyrios Kyrtzidisclass PrecompilePreambleConsumer : public PCHGenerator { 7831d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor ASTUnit &Unit; 7849b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor unsigned &Hash; 785eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor std::vector<Decl *> TopLevelDecls; 78689d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor 7871d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorpublic: 7889293ba8e26fcba18505b273ecc9b66645133fcceDouglas Gregor PrecompilePreambleConsumer(ASTUnit &Unit, const Preprocessor &PP, 7895f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef isysroot, raw_ostream *Out) 7907143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor : PCHGenerator(PP, "", /*IsModule=*/false, isysroot, Out), Unit(Unit), 7919b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Hash(Unit.getCurrentTopLevelHashValue()) { 7929b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Hash = 0; 7939b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 7941d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 795eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor virtual void HandleTopLevelDecl(DeclGroupRef D) { 7961d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) { 7971d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor Decl *D = *it; 7981d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // FIXME: Currently ObjC method declarations are incorrectly being 7991d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // reported as top-level declarations, even though their DeclContext 8001d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // is the containing ObjC @interface/@implementation. This is a 8011d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // fundamental problem in the parser right now. 8021d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor if (isa<ObjCMethodDecl>(D)) 8031d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor continue; 8049b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor AddTopLevelDeclarationToHash(D, Hash); 805eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDecls.push_back(D); 806eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 807eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 808eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 809eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor virtual void HandleTranslationUnit(ASTContext &Ctx) { 810eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor PCHGenerator::HandleTranslationUnit(Ctx); 811eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (!Unit.getDiagnostics().hasErrorOccurred()) { 812eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // Translate the top-level declarations we captured during 813eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // parsing into declaration IDs in the precompiled 814eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // preamble. This will allow us to deserialize those top-level 815eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // declarations when requested. 816eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor for (unsigned I = 0, N = TopLevelDecls.size(); I != N; ++I) 817eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Unit.addTopLevelDeclFromPreamble( 818eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor getWriter().getDeclID(TopLevelDecls[I])); 8191d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor } 8201d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor } 8211d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor}; 8221d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 8231d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorclass PrecompilePreambleAction : public ASTFrontendAction { 8241d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor ASTUnit &Unit; 8251d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 8261d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorpublic: 8271d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor explicit PrecompilePreambleAction(ASTUnit &Unit) : Unit(Unit) {} 8281d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 8291d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 8305f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef InFile) { 8311d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor std::string Sysroot; 8328e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis std::string OutputFile; 8335f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream *OS = 0; 8348e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis if (GeneratePCHAction::ComputeASTConsumerArguments(CI, InFile, Sysroot, 8358e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis OutputFile, 8369293ba8e26fcba18505b273ecc9b66645133fcceDouglas Gregor OS)) 8371d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor return 0; 8381d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 839832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor if (!CI.getFrontendOpts().RelocatablePCH) 840832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor Sysroot.clear(); 841832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor 8429b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CI.getPreprocessor().addPPCallbacks( 8439b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor new MacroDefinitionTrackerPPCallbacks(Unit.getCurrentTopLevelHashValue())); 8449293ba8e26fcba18505b273ecc9b66645133fcceDouglas Gregor return new PrecompilePreambleConsumer(Unit, CI.getPreprocessor(), Sysroot, 8459293ba8e26fcba18505b273ecc9b66645133fcceDouglas Gregor OS); 8461d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor } 8471d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 8481d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor virtual bool hasCodeCompletionSupport() const { return false; } 8491d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor virtual bool hasASTFileSupport() const { return false; } 850467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor virtual TranslationUnitKind getTranslationUnitKind() { return TU_Prefix; } 8511d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor}; 8521d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 853521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar} 854521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 855abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// Parse the source file into a translation unit using the given compiler 856abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// invocation, replacing the current translation unit. 857abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// 858abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// \returns True if a failure occurred that causes the ASTUnit not to 859abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// contain any translation-unit information, false otherwise. 860754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregorbool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { 86128233428da1ebec20c893d6297ae3191318940ddDouglas Gregor delete SavedMainFileBuffer; 86228233428da1ebec20c893d6297ae3191318940ddDouglas Gregor SavedMainFileBuffer = 0; 86328233428da1ebec20c893d6297ae3191318940ddDouglas Gregor 8644f32786ac45210143654390177105eb749b614e9Ted Kremenek if (!Invocation) { 865671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete OverrideMainBuffer; 866abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 867671947b18dba342f9aba022ee992babef325a833Douglas Gregor } 868abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 869521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the compiler instance to use for building the AST. 87003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance()); 87103201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 87203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek // Recover resources if we crash before exiting this method. 87325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> 87425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek CICleanup(Clang.get()); 87503201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 87626d43cd3a088d4f1f1645328db3b73afbc7eaa61Argyrios Kyrtzidis llvm::IntrusiveRefCntPtr<CompilerInvocation> 87726d43cd3a088d4f1f1645328db3b73afbc7eaa61Argyrios Kyrtzidis CCInvocation(new CompilerInvocation(*Invocation)); 87826d43cd3a088d4f1f1645328db3b73afbc7eaa61Argyrios Kyrtzidis 87926d43cd3a088d4f1f1645328db3b73afbc7eaa61Argyrios Kyrtzidis Clang->setInvocation(CCInvocation.getPtr()); 88003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second; 881abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 8821abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set up diagnostics, capturing any diagnostics that would 8831abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // otherwise be dropped. 88403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setDiagnostics(&getDiagnostics()); 8853687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor 886521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the target instance. 88703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTargetOpts().Features = TargetFeatures; 88803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), 8894f32786ac45210143654390177105eb749b614e9Ted Kremenek Clang->getTargetOpts())); 89003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek if (!Clang->hasTarget()) { 891671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete OverrideMainBuffer; 892abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 893671947b18dba342f9aba022ee992babef325a833Douglas Gregor } 894671947b18dba342f9aba022ee992babef325a833Douglas Gregor 895521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Inform the target of the language options. 896521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // 897521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // FIXME: We shouldn't need to do this, the target should be immutable once 898521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // created. This complexity should be lifted elsewhere. 89903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); 900abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 90103201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs.size() == 1 && 902521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar "Invocation must have exactly one source file!"); 90303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs[0].first != IK_AST && 904521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar "FIXME: AST inputs not yet supported here!"); 90503201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs[0].first != IK_LLVM_IR && 906faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar "IR inputs not support here!"); 907521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 908abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Configure the various subsystems. 909abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // FIXME: Should we retain the previous file manager? 91003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek FileSystemOpts = Clang->getFileSystemOpts(); 9114f32786ac45210143654390177105eb749b614e9Ted Kremenek FileMgr = new FileManager(FileSystemOpts); 9124f32786ac45210143654390177105eb749b614e9Ted Kremenek SourceMgr = new SourceManager(getDiagnostics(), *FileMgr); 913914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor TheSema.reset(); 9144f32786ac45210143654390177105eb749b614e9Ted Kremenek Ctx = 0; 9154f32786ac45210143654390177105eb749b614e9Ted Kremenek PP = 0; 916abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 917abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Clear out old caches and data. 918abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor TopLevelDecls.clear(); 919abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor CleanTemporaryFiles(); 920c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 921f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor if (!OverrideMainBuffer) { 9224cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.erase( 9234cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver, 9244cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.end()); 925f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor TopLevelDeclsInPreamble.clear(); 926f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor } 927f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor 928521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create a file manager object to provide access to and cache the filesystem. 92903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setFileManager(&getFileManager()); 930abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 931521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the source manager. 93203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setSourceManager(&getSourceManager()); 933abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 934f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // If the main file has been overridden due to the use of a preamble, 935f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // make that override happen and introduce the preamble. 93603201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek PreprocessorOptions &PreprocessorOpts = Clang->getPreprocessorOpts(); 937ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth PreprocessorOpts.DetailedRecordIncludesNestedMacroExpansions 938ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth = NestedMacroExpansions; 939f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (OverrideMainBuffer) { 940f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); 941f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size(); 942f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second 943f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor = PreambleEndsAtStartOfLine; 944385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor PreprocessorOpts.ImplicitPCHInclude = PreambleFile; 945fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor PreprocessorOpts.DisablePCHValidation = true; 94628233428da1ebec20c893d6297ae3191318940ddDouglas Gregor 947c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // The stored diagnostic has the old source manager in it; update 948c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // the locations to refer into the new source manager. Since we've 949c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // been careful to make sure that the source manager's state 950c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // before and after are identical, so that we can reuse the source 951c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // location itself. 9524cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor for (unsigned I = NumStoredDiagnosticsFromDriver, 9534cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor N = StoredDiagnostics.size(); 9544cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor I < N; ++I) { 955c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor FullSourceLoc Loc(StoredDiagnostics[I].getLocation(), 956c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getSourceManager()); 957c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor StoredDiagnostics[I].setLocation(Loc); 958c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor } 9594cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 9604cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor // Keep track of the override buffer; 9614cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor SavedMainFileBuffer = OverrideMainBuffer; 962f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor } 963f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 96425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::OwningPtr<TopLevelDeclTrackerAction> Act( 96525a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek new TopLevelDeclTrackerAction(*this)); 96625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek 96725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek // Recover resources if we crash before exiting this method. 96825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction> 96925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek ActCleanup(Act.get()); 97025a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek 97103201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0].second, 97203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getFrontendOpts().Inputs[0].first)) 973521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar goto error; 974f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 975f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (OverrideMainBuffer) { 9769461fccd05bde8458710ba367be10b6e4efe2ec7Jonathan D. Turner std::string ModName = PreambleFile; 977f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateStoredDiagnostics(Clang->getModuleManager(), ModName, 978f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor getSourceManager(), PreambleDiagnostics, 979f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor StoredDiagnostics); 980f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 981f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 982f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar Act->Execute(); 983abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 9844f32786ac45210143654390177105eb749b614e9Ted Kremenek // Steal the created target, context, and preprocessor. 98503201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek TheSema.reset(Clang->takeSema()); 98603201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Consumer.reset(Clang->takeASTConsumer()); 9874f32786ac45210143654390177105eb749b614e9Ted Kremenek Ctx = &Clang->getASTContext(); 9884f32786ac45210143654390177105eb749b614e9Ted Kremenek PP = &Clang->getPreprocessor(); 9894f32786ac45210143654390177105eb749b614e9Ted Kremenek Clang->setSourceManager(0); 9904f32786ac45210143654390177105eb749b614e9Ted Kremenek Clang->setFileManager(0); 9914f32786ac45210143654390177105eb749b614e9Ted Kremenek Target = &Clang->getTarget(); 992abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 993f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar Act->EndSourceFile(); 994f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 995abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return false; 9964f32786ac45210143654390177105eb749b614e9Ted Kremenek 997521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarerror: 998f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // Remove the overridden buffer we used for the preamble. 999fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor if (OverrideMainBuffer) { 1000671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete OverrideMainBuffer; 100137cf66350cb5a2bb68b0b7c7cca552f7a4867348Douglas Gregor SavedMainFileBuffer = 0; 1002fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor } 1003f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 1004d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor StoredDiagnostics.clear(); 1005abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 1006abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 1007abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 100844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor/// \brief Simple function to retrieve a path for a preamble precompiled header. 100944c181aec37789f25f6c15543c164416f72e562aDouglas Gregorstatic std::string GetPreamblePCHPath() { 101044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: This is lame; sys::Path should provide this function (in particular, 101144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // it should know how to find the temporary files dir). 101244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: This is really lame. I copied this code from the Driver! 1013424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor // FIXME: This is a hack so that we can override the preamble file during 1014424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor // crash-recovery testing, which is the only case where the preamble files 1015424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor // are not necessarily cleaned up. 1016424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor const char *TmpFile = ::getenv("CINDEXTEST_PREAMBLE_FILE"); 1017424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor if (TmpFile) 1018424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor return TmpFile; 1019424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor 102044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor std::string Error; 102144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor const char *TmpDir = ::getenv("TMPDIR"); 102244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!TmpDir) 102344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor TmpDir = ::getenv("TEMP"); 102444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!TmpDir) 102544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor TmpDir = ::getenv("TMP"); 1026c6cb2b02f0f4b3f162985803df3729b4def32108Douglas Gregor#ifdef LLVM_ON_WIN32 1027c6cb2b02f0f4b3f162985803df3729b4def32108Douglas Gregor if (!TmpDir) 1028c6cb2b02f0f4b3f162985803df3729b4def32108Douglas Gregor TmpDir = ::getenv("USERPROFILE"); 1029c6cb2b02f0f4b3f162985803df3729b4def32108Douglas Gregor#endif 103044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!TmpDir) 103144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor TmpDir = "/tmp"; 103244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor llvm::sys::Path P(TmpDir); 1033c6cb2b02f0f4b3f162985803df3729b4def32108Douglas Gregor P.createDirectoryOnDisk(true); 103444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor P.appendComponent("preamble"); 10356bf1830875673d6bd6c5bfcd65c9dcabfb45958bDouglas Gregor P.appendSuffix("pch"); 1036bc9d5a3ace7cb75e4bff3dd4a3999a3fc04f4d45Argyrios Kyrtzidis if (P.makeUnique(/*reuse_current=*/false, /*ErrMsg*/0)) 103744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor return std::string(); 103844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 103944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor return P.str(); 104044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor} 104144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 1042f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// \brief Compute the preamble for the main file, providing the source buffer 1043f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// that corresponds to the main file along with a pair (bytes, start-of-line) 1044f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// that describes the preamble. 1045f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregorstd::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > 1046df95a13ec73d2cdaea79555cb412d767f4963120Douglas GregorASTUnit::ComputePreamble(CompilerInvocation &Invocation, 1047df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor unsigned MaxLines, bool &CreatedBuffer) { 1048175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor FrontendOptions &FrontendOpts = Invocation.getFrontendOpts(); 104939b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner PreprocessorOptions &PreprocessorOpts = Invocation.getPreprocessorOpts(); 1050175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = false; 1051175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 105244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Try to determine if the main file has been remapped, either from the 105344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // command line (to another file) or directly through the compiler invocation 105444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // (to a memory buffer). 1055175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::MemoryBuffer *Buffer = 0; 105644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].second); 105744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (const llvm::sys::FileStatus *MainFileStatus = MainFilePath.getFileStatus()) { 105844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Check whether there is a file-file remapping of the main file 105944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor for (PreprocessorOptions::remapped_file_iterator 1060175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor M = PreprocessorOpts.remapped_file_begin(), 1061175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor E = PreprocessorOpts.remapped_file_end(); 106244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor M != E; 106344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor ++M) { 106444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor llvm::sys::PathWithStatus MPath(M->first); 106544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (const llvm::sys::FileStatus *MStatus = MPath.getFileStatus()) { 106644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (MainFileStatus->uniqueID == MStatus->uniqueID) { 106744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // We found a remapping. Try to load the resulting, remapped source. 1068175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (CreatedBuffer) { 106944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor delete Buffer; 1070175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = false; 1071175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 1072175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1073389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis Buffer = getBufferForFile(M->second); 107444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Buffer) 1075f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor return std::make_pair((llvm::MemoryBuffer*)0, 1076f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor std::make_pair(0, true)); 1077175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = true; 107844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 107944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 108044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 108144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 108244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Check whether there is a file-buffer remapping. It supercedes the 108344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // file-file remapping. 108444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 108544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor M = PreprocessorOpts.remapped_file_buffer_begin(), 108644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor E = PreprocessorOpts.remapped_file_buffer_end(); 108744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor M != E; 108844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor ++M) { 108944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor llvm::sys::PathWithStatus MPath(M->first); 109044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (const llvm::sys::FileStatus *MStatus = MPath.getFileStatus()) { 109144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (MainFileStatus->uniqueID == MStatus->uniqueID) { 109244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // We found a remapping. 1093175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (CreatedBuffer) { 109444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor delete Buffer; 1095175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = false; 1096175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 109744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 1098175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Buffer = const_cast<llvm::MemoryBuffer *>(M->second); 109944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 110044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 1101175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 110244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 110344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 110444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // If the main source file was not remapped, load it now. 110544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Buffer) { 1106389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis Buffer = getBufferForFile(FrontendOpts.Inputs[0].second); 110744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Buffer) 1108f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor return std::make_pair((llvm::MemoryBuffer*)0, std::make_pair(0, true)); 1109175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1110175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = true; 1111175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 1112175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 111303c107a42fae79e89d0016999a1a04c07d65591aArgyrios Kyrtzidis return std::make_pair(Buffer, Lexer::ComputePreamble(Buffer, 111403c107a42fae79e89d0016999a1a04c07d65591aArgyrios Kyrtzidis Invocation.getLangOpts(), 111503c107a42fae79e89d0016999a1a04c07d65591aArgyrios Kyrtzidis MaxLines)); 1116175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor} 1117175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1118754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregorstatic llvm::MemoryBuffer *CreatePaddedMainFileBuffer(llvm::MemoryBuffer *Old, 1119754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor unsigned NewSize, 11205f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef NewName) { 1121754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor llvm::MemoryBuffer *Result 1122754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor = llvm::MemoryBuffer::getNewUninitMemBuffer(NewSize, NewName); 1123754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor memcpy(const_cast<char*>(Result->getBufferStart()), 1124754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor Old->getBufferStart(), Old->getBufferSize()); 1125754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor memset(const_cast<char*>(Result->getBufferStart()) + Old->getBufferSize(), 1126f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor ' ', NewSize - Old->getBufferSize() - 1); 1127f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor const_cast<char*>(Result->getBufferEnd())[-1] = '\n'; 1128754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor 1129754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return Result; 1130754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor} 1131754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor 1132175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// \brief Attempt to build or re-use a precompiled preamble when (re-)parsing 1133175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// the source file. 1134175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// 1135175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// This routine will compute the preamble of the main source file. If a 1136175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// non-trivial preamble is found, it will precompile that preamble into a 1137175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// precompiled header so that the precompiled preamble can be used to reduce 1138175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// reparsing time. If a precompiled preamble has already been constructed, 1139175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// this routine will determine if it is still valid and, if so, avoid 1140175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// rebuilding the precompiled preamble. 1141175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// 1142df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// \param AllowRebuild When true (the default), this routine is 1143df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// allowed to rebuild the precompiled preamble if it is found to be 1144df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// out-of-date. 1145df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// 1146df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// \param MaxLines When non-zero, the maximum number of lines that 1147df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// can occur within the preamble. 1148df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// 1149754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// \returns If the precompiled preamble can be used, returns a newly-allocated 1150754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// buffer that should be used in place of the main file when doing so. 1151754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// Otherwise, returns a NULL pointer. 1152df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregorllvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( 115301b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor const CompilerInvocation &PreambleInvocationIn, 1154df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool AllowRebuild, 1155df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor unsigned MaxLines) { 115601b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor 115701b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor llvm::IntrusiveRefCntPtr<CompilerInvocation> 115801b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor PreambleInvocation(new CompilerInvocation(PreambleInvocationIn)); 115901b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor FrontendOptions &FrontendOpts = PreambleInvocation->getFrontendOpts(); 1160175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreprocessorOptions &PreprocessorOpts 116101b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor = PreambleInvocation->getPreprocessorOpts(); 1162175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1163175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor bool CreatedPreambleBuffer = false; 1164f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > NewPreamble 116501b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor = ComputePreamble(*PreambleInvocation, MaxLines, CreatedPreambleBuffer); 1166175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1167f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // If ComputePreamble() Take ownership of the preamble buffer. 116873fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor llvm::OwningPtr<llvm::MemoryBuffer> OwnedPreambleBuffer; 116973fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor if (CreatedPreambleBuffer) 117073fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor OwnedPreambleBuffer.reset(NewPreamble.first); 117173fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor 1172f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (!NewPreamble.second.first) { 1173175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We couldn't find a preamble in the main source. Clear out the current 1174175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // preamble, if we have one. It's obviously no good any more. 1175175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1176175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (!PreambleFile.empty()) { 1177385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor llvm::sys::Path(PreambleFile).eraseFromDisk(); 1178175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleFile.clear(); 1179175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 1180eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 1181eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // The next time we actually see a preamble, precompile it. 1182eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = 1; 1183754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 118444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 118544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 1186175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (!Preamble.empty()) { 1187175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We've previously computed a preamble. Check whether we have the same 1188175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // preamble now that we did before, and that there's enough space in 1189175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // the main-file buffer within the precompiled preamble to fit the 1190175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // new main file. 1191f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (Preamble.size() == NewPreamble.second.first && 1192f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreambleEndsAtStartOfLine == NewPreamble.second.second && 1193592508ed997e52207cf380f9b6eb9943994ad7aeDouglas Gregor NewPreamble.first->getBufferSize() < PreambleReservedSize-2 && 1194507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis memcmp(Preamble.getBufferStart(), NewPreamble.first->getBufferStart(), 1195f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor NewPreamble.second.first) == 0) { 1196175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // The preamble has not changed. We may be able to re-use the precompiled 1197175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // preamble. 1198c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 1199cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Check that none of the files used by the preamble have changed. 1200cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor bool AnyFileChanged = false; 1201cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1202cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // First, make a record of those files that have been overridden via 1203cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // remapping or unsaved_files. 1204cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor llvm::StringMap<std::pair<off_t, time_t> > OverriddenFiles; 1205cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (PreprocessorOptions::remapped_file_iterator 1206cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor R = PreprocessorOpts.remapped_file_begin(), 1207cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor REnd = PreprocessorOpts.remapped_file_end(); 1208cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor !AnyFileChanged && R != REnd; 1209cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++R) { 1210cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor struct stat StatBuf; 1211340415c0c7a7fdeb688fe5a0993bdd142cc9f59cAnders Carlsson if (FileMgr->getNoncachedStatValue(R->second, StatBuf)) { 1212cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // If we can't stat the file we're remapping to, assume that something 1213cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // horrible happened. 1214cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 1215cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor break; 1216cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1217754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor 1218cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor OverriddenFiles[R->first] = std::make_pair(StatBuf.st_size, 1219cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor StatBuf.st_mtime); 1220cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1221cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 1222cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor R = PreprocessorOpts.remapped_file_buffer_begin(), 1223cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor REnd = PreprocessorOpts.remapped_file_buffer_end(); 1224cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor !AnyFileChanged && R != REnd; 1225cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++R) { 1226cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // FIXME: Should we actually compare the contents of file->buffer 1227cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // remappings? 1228cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor OverriddenFiles[R->first] = std::make_pair(R->second->getBufferSize(), 1229cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 0); 1230cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1231cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1232cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Check whether anything has changed. 1233cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (llvm::StringMap<std::pair<off_t, time_t> >::iterator 1234cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor F = FilesInPreamble.begin(), FEnd = FilesInPreamble.end(); 1235cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor !AnyFileChanged && F != FEnd; 1236cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++F) { 1237cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor llvm::StringMap<std::pair<off_t, time_t> >::iterator Overridden 1238cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor = OverriddenFiles.find(F->first()); 1239cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (Overridden != OverriddenFiles.end()) { 1240cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // This file was remapped; check whether the newly-mapped file 1241cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // matches up with the previous mapping. 1242cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (Overridden->second != F->second) 1243cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 1244cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor continue; 1245cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1246cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1247cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // The file was not remapped; check whether it has changed on disk. 1248cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor struct stat StatBuf; 1249340415c0c7a7fdeb688fe5a0993bdd142cc9f59cAnders Carlsson if (FileMgr->getNoncachedStatValue(F->first(), StatBuf)) { 1250cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // If we can't stat the file, assume that something horrible happened. 1251cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 1252cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } else if (StatBuf.st_size != F->second.first || 1253cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor StatBuf.st_mtime != F->second.second) 1254cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 1255cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1256cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1257cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (!AnyFileChanged) { 1258c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Okay! We can re-use the precompiled preamble. 1259c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 1260c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Set the state of the diagnostic object to mimic its state 1261c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // after parsing the preamble. 126232be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor // FIXME: This won't catch any #pragma push warning changes that 126332be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor // have occurred in the preamble. 1264c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getDiagnostics().Reset(); 126532be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor ProcessWarningOptions(getDiagnostics(), 126601b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor PreambleInvocation->getDiagnosticOpts()); 1267c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getDiagnostics().setNumWarnings(NumWarningsInPreamble); 1268c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 1269c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Create a version of the main file buffer that is padded to 1270c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // buffer size we reserved when creating the preamble. 1271cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor return CreatePaddedMainFileBuffer(NewPreamble.first, 1272cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor PreambleReservedSize, 1273cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FrontendOpts.Inputs[0].second); 1274cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1275175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 1276df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 1277df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // If we aren't allowed to rebuild the precompiled preamble, just 1278df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // return now. 1279df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (!AllowRebuild) 1280df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor return 0; 1281aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor 1282175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We can't reuse the previously-computed preamble. Build a new one. 1283175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1284f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor PreambleDiagnostics.clear(); 1285385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor llvm::sys::Path(PreambleFile).eraseFromDisk(); 1286eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = 1; 1287df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } else if (!AllowRebuild) { 1288df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // We aren't allowed to rebuild the precompiled preamble; just 1289df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // return now. 1290df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor return 0; 1291df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 1292eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 1293eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // If the preamble rebuild counter > 1, it's because we previously 1294eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // failed to build a preamble and we're not yet ready to try 1295eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // again. Decrement the counter and return a failure. 1296eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor if (PreambleRebuildCounter > 1) { 1297eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor --PreambleRebuildCounter; 1298eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor return 0; 1299eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor } 1300eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 13012cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor // Create a temporary file for the precompiled preamble. In rare 13022cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor // circumstances, this can fail. 13032cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor std::string PreamblePCHPath = GetPreamblePCHPath(); 13042cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor if (PreamblePCHPath.empty()) { 13052cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor // Try again next time. 13062cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor PreambleRebuildCounter = 1; 13072cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor return 0; 13082cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor } 13092cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor 1310175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We did not previously compute a preamble, or it can't be reused anyway. 1311213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer PreambleTimer(WantTiming); 1312edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer PreambleTimer.setOutput("Precompiling preamble"); 131344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 131444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create a new buffer that stores the preamble. The buffer also contains 131544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // extra space for the original contents of the file (which will be present 131644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // when we actually parse the file) along with more room in case the file 1317175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // grows. 1318175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleReservedSize = NewPreamble.first->getBufferSize(); 1319175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (PreambleReservedSize < 4096) 1320f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreambleReservedSize = 8191; 132144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor else 1322175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleReservedSize *= 2; 1323175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1324c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Save the preamble text for later; we'll need to compare against it for 1325c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // subsequent reparses. 1326507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis StringRef MainFilename = PreambleInvocation->getFrontendOpts().Inputs[0].second; 1327507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis Preamble.assign(FileMgr->getFile(MainFilename), 1328507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis NewPreamble.first->getBufferStart(), 1329c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor NewPreamble.first->getBufferStart() 1330c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor + NewPreamble.second.first); 1331c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor PreambleEndsAtStartOfLine = NewPreamble.second.second; 1332c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 1333671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete PreambleBuffer; 1334671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreambleBuffer 1335175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor = llvm::MemoryBuffer::getNewUninitMemBuffer(PreambleReservedSize, 133644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor FrontendOpts.Inputs[0].second); 133744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor memcpy(const_cast<char*>(PreambleBuffer->getBufferStart()), 1338175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor NewPreamble.first->getBufferStart(), Preamble.size()); 1339175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor memset(const_cast<char*>(PreambleBuffer->getBufferStart()) + Preamble.size(), 1340f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor ' ', PreambleReservedSize - Preamble.size() - 1); 1341f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor const_cast<char*>(PreambleBuffer->getBufferEnd())[-1] = '\n'; 134244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 134344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Remap the main source file to the preamble buffer. 1344175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].second); 134544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor PreprocessorOpts.addRemappedFile(MainFilePath.str(), PreambleBuffer); 134644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 134744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Tell the compiler invocation to generate a temporary precompiled header. 134844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor FrontendOpts.ProgramAction = frontend::GeneratePCH; 134944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: Generate the precompiled header into memory? 13502cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor FrontendOpts.OutputFile = PreamblePCHPath; 1351aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = 0; 1352aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second = false; 135344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 135444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create the compiler instance to use for building the precompiled preamble. 135503201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance()); 135603201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 135703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek // Recover resources if we crash before exiting this method. 135825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> 135925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek CICleanup(Clang.get()); 136003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 136101b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor Clang->setInvocation(&*PreambleInvocation); 136203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second; 136344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 13641abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set up diagnostics, capturing all of the diagnostics produced. 136503201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setDiagnostics(&getDiagnostics()); 136644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 136744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create the target instance. 136803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTargetOpts().Features = TargetFeatures; 136903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), 137003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTargetOpts())); 137103201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek if (!Clang->hasTarget()) { 1372175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 1373175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1374eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = DefaultPreambleRebuildInterval; 1375671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1376671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 1377754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 137844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 137944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 138044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Inform the target of the language options. 138144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // 138244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: We shouldn't need to do this, the target should be immutable once 138344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // created. This complexity should be lifted elsewhere. 138403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); 138544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 138603201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs.size() == 1 && 138744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor "Invocation must have exactly one source file!"); 138803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs[0].first != IK_AST && 138944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor "FIXME: AST inputs not yet supported here!"); 139003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs[0].first != IK_LLVM_IR && 139144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor "IR inputs not support here!"); 139244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 139344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Clear out old caches and data. 1394aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor getDiagnostics().Reset(); 139503201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek ProcessWarningOptions(getDiagnostics(), Clang->getDiagnosticOpts()); 13964cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.erase( 13974cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver, 13984cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.end()); 1399eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDecls.clear(); 1400eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDeclsInPreamble.clear(); 140144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 140244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create a file manager object to provide access to and cache the filesystem. 140303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setFileManager(new FileManager(Clang->getFileSystemOpts())); 140444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 140544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create the source manager. 140603201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setSourceManager(new SourceManager(getDiagnostics(), 14074f32786ac45210143654390177105eb749b614e9Ted Kremenek Clang->getFileManager())); 140844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 14091d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor llvm::OwningPtr<PrecompilePreambleAction> Act; 14101d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor Act.reset(new PrecompilePreambleAction(*this)); 141103201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0].second, 141203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getFrontendOpts().Inputs[0].first)) { 1413175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 1414175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1415eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = DefaultPreambleRebuildInterval; 1416671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1417671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 1418754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 141944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 142044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 142144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Act->Execute(); 142244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Act->EndSourceFile(); 14234f32786ac45210143654390177105eb749b614e9Ted Kremenek 1424eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (Diagnostics->hasErrorOccurred()) { 1425175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // There were errors parsing the preamble, so no precompiled header was 1426175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // generated. Forget that we even tried. 142706e504462014b0506a70c7730ea45c551a103364Douglas Gregor // FIXME: Should we leave a note for ourselves to try again? 1428175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 1429175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1430eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDeclsInPreamble.clear(); 1431eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = DefaultPreambleRebuildInterval; 1432671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1433671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 1434754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 1435175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 1436175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1437f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Transfer any diagnostics generated when parsing the preamble into the set 1438f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // of preamble diagnostics. 1439f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor PreambleDiagnostics.clear(); 1440f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor PreambleDiagnostics.insert(PreambleDiagnostics.end(), 1441f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver, 1442f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor StoredDiagnostics.end()); 1443f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor StoredDiagnostics.erase( 1444f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver, 1445f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor StoredDiagnostics.end()); 1446f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 1447175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // Keep track of the preamble we precompiled. 1448175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleFile = FrontendOpts.OutputFile; 1449c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor NumWarningsInPreamble = getDiagnostics().getNumWarnings(); 1450cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1451cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Keep track of all of the files that the source manager knows about, 1452cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // so we can verify whether they have changed or not. 1453cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FilesInPreamble.clear(); 145403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek SourceManager &SourceMgr = Clang->getSourceManager(); 1455cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor const llvm::MemoryBuffer *MainFileBuffer 1456cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor = SourceMgr.getBuffer(SourceMgr.getMainFileID()); 1457cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (SourceManager::fileinfo_iterator F = SourceMgr.fileinfo_begin(), 1458cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FEnd = SourceMgr.fileinfo_end(); 1459cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor F != FEnd; 1460cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++F) { 1461b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *File = F->second->OrigEntry; 1462cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (!File || F->second->getRawBuffer() == MainFileBuffer) 1463cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor continue; 1464cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1465cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FilesInPreamble[File->getName()] 1466cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor = std::make_pair(F->second->getSize(), File->getModificationTime()); 1467cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1468cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1469eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = 1; 1470671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1471671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 14729b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 14739b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor // If the hash of top-level entities differs from the hash of the top-level 14749b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor // entities the last time we rebuilt the preamble, clear out the completion 14759b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor // cache. 14769b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (CurrentTopLevelHashValue != PreambleTopLevelHashValue) { 14779b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CompletionCacheTopLevelHashValue = 0; 14789b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor PreambleTopLevelHashValue = CurrentTopLevelHashValue; 14799b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 14809b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 1481754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return CreatePaddedMainFileBuffer(NewPreamble.first, 1482754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor PreambleReservedSize, 1483754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor FrontendOpts.Inputs[0].second); 148444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor} 1485abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1486eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregorvoid ASTUnit::RealizeTopLevelDeclsFromPreamble() { 1487eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor std::vector<Decl *> Resolved; 1488eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Resolved.reserve(TopLevelDeclsInPreamble.size()); 1489eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor ExternalASTSource &Source = *getASTContext().getExternalSource(); 1490eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor for (unsigned I = 0, N = TopLevelDeclsInPreamble.size(); I != N; ++I) { 1491eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // Resolve the declaration ID to an actual declaration, possibly 1492eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // deserializing the declaration in the process. 1493eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Decl *D = Source.GetExternalDecl(TopLevelDeclsInPreamble[I]); 1494eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (D) 1495eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Resolved.push_back(D); 1496eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 1497eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDeclsInPreamble.clear(); 1498eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end()); 1499eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor} 1500eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 15015f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerStringRef ASTUnit::getMainFileName() const { 1502213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor return Invocation->getFrontendOpts().Inputs[0].second; 1503213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor} 1504213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 1505b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios KyrtzidisASTUnit *ASTUnit::create(CompilerInvocation *CI, 1506d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags) { 1507b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis llvm::OwningPtr<ASTUnit> AST; 1508b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis AST.reset(new ASTUnit(false)); 1509b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis ConfigureDiags(Diags, 0, 0, *AST, /*CaptureDiagnostics=*/false); 1510b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis AST->Diagnostics = Diags; 15114f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->Invocation = CI; 15120d8d7e6067f9093e7d5abc45c9639ab977aab692Anders Carlsson AST->FileSystemOpts = CI->getFileSystemOpts(); 15134f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->FileMgr = new FileManager(AST->FileSystemOpts); 1514abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr); 1515b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 1516b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis return AST.take(); 1517b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis} 1518b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 1519d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios KyrtzidisASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI, 1520d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 1521abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis ASTFrontendAction *Action, 1522abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis ASTUnit *Unit) { 1523d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis assert(CI && "A CompilerInvocation is required"); 1524d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1525abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis llvm::OwningPtr<ASTUnit> OwnAST; 1526abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis ASTUnit *AST = Unit; 1527abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis if (!AST) { 1528abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis // Create the AST unit. 1529abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis OwnAST.reset(create(CI, Diags)); 1530abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis AST = OwnAST.get(); 1531abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis } 1532abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis 1533d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->OnlyLocalDecls = false; 1534d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->CaptureDiagnostics = false; 1535467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete; 1536d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->ShouldCacheCodeCompletionResults = false; 1537d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1538d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Recover resources if we crash before exiting this method. 1539d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> 1540abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis ASTUnitCleanup(OwnAST.get()); 1541d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, 1542d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > 1543d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis DiagCleanup(Diags.getPtr()); 1544d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1545d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // We'll manage file buffers ourselves. 1546d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis CI->getPreprocessorOpts().RetainRemappedFileBuffers = true; 1547d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis CI->getFrontendOpts().DisableFree = false; 1548d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts()); 1549d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1550d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Save the target features. 1551d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->TargetFeatures = CI->getTargetOpts().Features; 1552d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1553d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Create the compiler instance to use for building the AST. 1554d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance()); 1555d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1556d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Recover resources if we crash before exiting this method. 1557d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> 1558d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis CICleanup(Clang.get()); 1559d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1560d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setInvocation(CI); 1561d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second; 1562d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1563d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Set up diagnostics, capturing any diagnostics that would 1564d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // otherwise be dropped. 1565d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setDiagnostics(&AST->getDiagnostics()); 1566d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1567d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Create the target instance. 1568d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->getTargetOpts().Features = AST->TargetFeatures; 1569d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), 1570d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->getTargetOpts())); 1571d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis if (!Clang->hasTarget()) 1572d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis return 0; 1573d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1574d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Inform the target of the language options. 1575d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // 1576d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // FIXME: We shouldn't need to do this, the target should be immutable once 1577d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // created. This complexity should be lifted elsewhere. 1578d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); 1579d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1580d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis assert(Clang->getFrontendOpts().Inputs.size() == 1 && 1581d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis "Invocation must have exactly one source file!"); 1582d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis assert(Clang->getFrontendOpts().Inputs[0].first != IK_AST && 1583d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis "FIXME: AST inputs not yet supported here!"); 1584d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis assert(Clang->getFrontendOpts().Inputs[0].first != IK_LLVM_IR && 1585d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis "IR inputs not supported here!"); 1586d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1587d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Configure the various subsystems. 1588d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->TheSema.reset(); 1589d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->Ctx = 0; 1590d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->PP = 0; 1591d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1592d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Create a file manager object to provide access to and cache the filesystem. 1593d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setFileManager(&AST->getFileManager()); 1594d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1595d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Create the source manager. 1596d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setSourceManager(&AST->getSourceManager()); 1597d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1598d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis ASTFrontendAction *Act = Action; 1599d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1600d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis llvm::OwningPtr<TopLevelDeclTrackerAction> TrackerAct; 1601d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis if (!Act) { 1602d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis TrackerAct.reset(new TopLevelDeclTrackerAction(*AST)); 1603d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Act = TrackerAct.get(); 1604d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis } 1605d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1606d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Recover resources if we crash before exiting this method. 1607d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction> 1608d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis ActCleanup(TrackerAct.get()); 1609d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1610d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis if (!Act->BeginSourceFile(*Clang.get(), 1611d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->getFrontendOpts().Inputs[0].second, 1612d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->getFrontendOpts().Inputs[0].first)) 1613d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis return 0; 1614d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1615d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Act->Execute(); 1616d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1617d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Steal the created target, context, and preprocessor. 1618d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->TheSema.reset(Clang->takeSema()); 1619d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->Consumer.reset(Clang->takeASTConsumer()); 1620d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->Ctx = &Clang->getASTContext(); 1621d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->PP = &Clang->getPreprocessor(); 1622d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setSourceManager(0); 1623d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setFileManager(0); 1624d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->Target = &Clang->getTarget(); 1625d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1626d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Act->EndSourceFile(); 1627d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1628abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis if (OwnAST) 1629abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis return OwnAST.take(); 1630abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis else 1631abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis return AST; 1632d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis} 1633d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 16344cd912aa94656697a44c3ebb159f05060300524eDouglas Gregorbool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) { 16354cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor if (!Invocation) 16364cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor return true; 16374cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 16384cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor // We'll manage file buffers ourselves. 16394cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor Invocation->getPreprocessorOpts().RetainRemappedFileBuffers = true; 16404cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor Invocation->getFrontendOpts().DisableFree = false; 16410b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts()); 16424cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 16431aa27307c462baaa9e5fda14ff6797dd39fe8b84Douglas Gregor // Save the target features. 16441aa27307c462baaa9e5fda14ff6797dd39fe8b84Douglas Gregor TargetFeatures = Invocation->getTargetOpts().Features; 16451aa27307c462baaa9e5fda14ff6797dd39fe8b84Douglas Gregor 16464cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor llvm::MemoryBuffer *OverrideMainBuffer = 0; 164799ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor if (PrecompilePreamble) { 164808bb4c622d0b79c33b4ac78ce1bec79398953daaDouglas Gregor PreambleRebuildCounter = 2; 16494cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor OverrideMainBuffer 16504cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor = getMainBufferWithPrecompiledPreamble(*Invocation); 16514cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor } 16524cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 1653213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer ParsingTimer(WantTiming); 1654edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer ParsingTimer.setOutput("Parsing " + getMainFileName()); 16554cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 165625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek // Recover resources if we crash before exiting this method. 165725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer> 165825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek MemBufferCleanup(OverrideMainBuffer); 165925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek 1660213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor return Parse(OverrideMainBuffer); 16614cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor} 16624cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 1663abc563f554951259bbe0315055cad92ee14d87e4Douglas GregorASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, 1664d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 1665abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor bool OnlyLocalDecls, 166644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor bool CaptureDiagnostics, 1667df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool PrecompilePreamble, 1668467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor TranslationUnitKind TUKind, 1669dca8ee8b7bc86076916a3a80f553f7a4e98c14afDouglas Gregor bool CacheCodeCompletionResults, 1670ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth bool NestedMacroExpansions) { 1671abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Create the AST unit. 1672abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor llvm::OwningPtr<ASTUnit> AST; 1673abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST.reset(new ASTUnit(false)); 16740b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics); 1675abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST->Diagnostics = Diags; 1676abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST->OnlyLocalDecls = OnlyLocalDecls; 1677e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor AST->CaptureDiagnostics = CaptureDiagnostics; 1678467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor AST->TUKind = TUKind; 167987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults; 16804f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->Invocation = CI; 1681ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth AST->NestedMacroExpansions = NestedMacroExpansions; 1682385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor 1683b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek // Recover resources if we crash before exiting this method. 168425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> 168525a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek ASTUnitCleanup(AST.get()); 1686d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, 1687d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > 168825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek DiagCleanup(Diags.getPtr()); 1689b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek 16904cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor return AST->LoadFromCompilerInvocation(PrecompilePreamble)? 0 : AST.take(); 1691521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar} 16927b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 16937b55668db7618334cc40011d3c1e128524d89462Daniel DunbarASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, 16947b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar const char **ArgEnd, 1695d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 16965f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef ResourceFilesPath, 16977b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar bool OnlyLocalDecls, 1698e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor bool CaptureDiagnostics, 16994db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFile *RemappedFiles, 1700a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor unsigned NumRemappedFiles, 1701299a4a967b02c9f0d0d94ad8560e3ced893f9116Argyrios Kyrtzidis bool RemappedFilesKeepOriginalName, 1702df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool PrecompilePreamble, 1703467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor TranslationUnitKind TUKind, 170499ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor bool CacheCodeCompletionResults, 1705ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth bool NestedMacroExpansions) { 170628019772db70d4547be05a042eb950bc910f134fDouglas Gregor if (!Diags.getPtr()) { 17073687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor // No diagnostics engine was provided, so create our own diagnostics object 17083687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor // with the default options. 17093687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor DiagnosticOptions DiagOpts; 17100b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor Diags = CompilerInstance::createDiagnostics(DiagOpts, ArgEnd - ArgBegin, 17110b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor ArgBegin); 17123687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor } 17137b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 17145f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<StoredDiagnostic, 4> StoredDiagnostics; 17154cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 17164f32786ac45210143654390177105eb749b614e9Ted Kremenek llvm::IntrusiveRefCntPtr<CompilerInvocation> CI; 1717e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor 17184cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor { 1719f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 1720e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags, 17214cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics); 17224cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 1723832316e9a04242972f4b57281dccb8e4cf5894eaArgyrios Kyrtzidis CI = clang::createInvocationFromCommandLine( 1724e9c0265d6e6b5bf865f4a0c2c00d00ac251e6437Frits van Bommel llvm::makeArrayRef(ArgBegin, ArgEnd), 1725e9c0265d6e6b5bf865f4a0c2c00d00ac251e6437Frits van Bommel Diags); 1726054e4f50e2f1995e91b0cd3c3258aa252785fe3fArgyrios Kyrtzidis if (!CI) 17274e03c2b9d735063a60cd0623423f4814178857efArgyrios Kyrtzidis return 0; 17287b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar } 1729e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor 17304db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor // Override any files that need remapping 1731b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis for (unsigned I = 0; I != NumRemappedFiles; ++I) { 1732b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; 1733b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (const llvm::MemoryBuffer * 1734b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { 1735b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, memBuf); 1736b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } else { 1737b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const char *fname = fileOrBuf.get<const char *>(); 1738b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, fname); 1739b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 1740b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 1741299a4a967b02c9f0d0d94ad8560e3ced893f9116Argyrios Kyrtzidis CI->getPreprocessorOpts().RemappedFilesKeepOriginalName = 1742299a4a967b02c9f0d0d94ad8560e3ced893f9116Argyrios Kyrtzidis RemappedFilesKeepOriginalName; 17434db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 17448b9adfea5e834eaee0f45d8cc7fb052d68df4a46Daniel Dunbar // Override the resources path. 1745807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath; 17467b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 17474cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor // Create the AST unit. 17484cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor llvm::OwningPtr<ASTUnit> AST; 17494cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST.reset(new ASTUnit(false)); 17500b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor ConfigureDiags(Diags, ArgBegin, ArgEnd, *AST, CaptureDiagnostics); 17514cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->Diagnostics = Diags; 17520d8d7e6067f9093e7d5abc45c9639ab977aab692Anders Carlsson 17530d8d7e6067f9093e7d5abc45c9639ab977aab692Anders Carlsson AST->FileSystemOpts = CI->getFileSystemOpts(); 17544f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->FileMgr = new FileManager(AST->FileSystemOpts); 17554cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->OnlyLocalDecls = OnlyLocalDecls; 1756e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor AST->CaptureDiagnostics = CaptureDiagnostics; 1757467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor AST->TUKind = TUKind; 17584cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults; 17594cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size(); 17604cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->StoredDiagnostics.swap(StoredDiagnostics); 17614f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->Invocation = CI; 1762ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth AST->NestedMacroExpansions = NestedMacroExpansions; 1763b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek 1764b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek // Recover resources if we crash before exiting this method. 176525a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> 176625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek ASTUnitCleanup(AST.get()); 176725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<CompilerInvocation, 176825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextReleaseRefCleanup<CompilerInvocation> > 176925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek CICleanup(CI.getPtr()); 1770d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, 1771d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > 177225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek DiagCleanup(Diags.getPtr()); 1773b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek 177439b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner return AST->LoadFromCompilerInvocation(PrecompilePreamble) ? 0 : AST.take(); 17757b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar} 1776abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1777abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregorbool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) { 17784f32786ac45210143654390177105eb749b614e9Ted Kremenek if (!Invocation) 1779abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 1780abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1781213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer ParsingTimer(WantTiming); 1782edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer ParsingTimer.setOutput("Reparsing " + getMainFileName()); 1783213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 1784cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Remap files. 1785f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 17868ef6c8cb6c5627240e2339fd7062c9873f821d7eDouglas Gregor PPOpts.DisableStatCache = true; 1787f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 1788f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor R = PPOpts.remapped_file_buffer_begin(), 1789f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor REnd = PPOpts.remapped_file_buffer_end(); 1790f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor R != REnd; 1791f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor ++R) { 1792f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor delete R->second; 1793f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor } 1794cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor Invocation->getPreprocessorOpts().clearRemappedFiles(); 1795b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis for (unsigned I = 0; I != NumRemappedFiles; ++I) { 1796b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; 1797b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (const llvm::MemoryBuffer * 1798b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { 1799b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, 1800b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf); 1801b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } else { 1802b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const char *fname = fileOrBuf.get<const char *>(); 1803b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, 1804b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis fname); 1805b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 1806b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 1807cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1808eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // If we have a preamble file lying around, or if we might try to 1809eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // build a precompiled preamble, do so now. 1810754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor llvm::MemoryBuffer *OverrideMainBuffer = 0; 1811eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor if (!PreambleFile.empty() || PreambleRebuildCounter > 0) 18122283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation); 1813175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1814abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Clear out the diagnostics state. 181532be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor if (!OverrideMainBuffer) { 1816c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getDiagnostics().Reset(); 181732be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts()); 181832be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor } 1819abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1820175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // Parse the sources 18219b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor bool Result = Parse(OverrideMainBuffer); 18229b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 18239b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor // If we're caching global code-completion results, and the top-level 18249b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor // declarations have changed, clear out the code-completion cache. 18259b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (!Result && ShouldCacheCodeCompletionResults && 18269b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue) 18279b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CacheCodeCompletionResults(); 18289b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 18298fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor // We now need to clear out the completion allocator for 18308fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor // clang_getCursorCompletionString; it'll be recreated if necessary. 18318fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor CursorCompletionAllocator = 0; 18328fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor 1833175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor return Result; 1834abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 18351abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 183687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor//----------------------------------------------------------------------------// 183787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor// Code completion 183887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor//----------------------------------------------------------------------------// 183987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 184087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregornamespace { 184187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor /// \brief Code completion consumer that combines the cached code-completion 184287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor /// results from an ASTUnit with the code-completion results provided to it, 184387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor /// then passes the result on to 184487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer { 18453da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor unsigned long long NormalContexts; 184687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor ASTUnit &AST; 184787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CodeCompleteConsumer &Next; 184887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 184987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor public: 185087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next, 18518071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor bool IncludeMacros, bool IncludeCodePatterns, 18528071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor bool IncludeGlobals) 18538071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals, 185487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor Next.isOutputBinary()), AST(AST), Next(Next) 185587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor { 185687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Compute the set of contexts in which we will look when we don't have 185787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // any information about the specific context. 185887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor NormalContexts 18593da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor = (1LL << (CodeCompletionContext::CCC_TopLevel - 1)) 18603da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ObjCInterface - 1)) 18613da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ObjCImplementation - 1)) 18623da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ObjCIvarList - 1)) 18633da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_Statement - 1)) 18643da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_Expression - 1)) 18653da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)) 18663da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_DotMemberAccess - 1)) 18673da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ArrowMemberAccess - 1)) 18683da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ObjCPropertyAccess - 1)) 18693da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ObjCProtocolName - 1)) 18703da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)) 18713da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_Recovery - 1)); 18720268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor 187387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor if (AST.getASTContext().getLangOptions().CPlusPlus) 18743da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor NormalContexts |= (1LL << (CodeCompletionContext::CCC_EnumTag - 1)) 18753da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_UnionTag - 1)) 18763da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ClassOrStructTag - 1)); 187787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 187887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 187987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor virtual void ProcessCodeCompleteResults(Sema &S, 188087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CodeCompletionContext Context, 18810a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall CodeCompletionResult *Results, 1882697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor unsigned NumResults); 188387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 188487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, 188587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor OverloadCandidate *Candidates, 188687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor unsigned NumCandidates) { 188787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates); 188887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 1889218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor 1890dae687575010c9c49a4b552f5eef82cd6279d9acDouglas Gregor virtual CodeCompletionAllocator &getAllocator() { 1891218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor return Next.getAllocator(); 1892218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor } 189387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor }; 189487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor} 1895697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 18965f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor/// \brief Helper function that computes which global names are hidden by the 18975f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor/// local code-completion results. 1898c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenekstatic void CalculateHiddenNames(const CodeCompletionContext &Context, 1899c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek CodeCompletionResult *Results, 1900c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek unsigned NumResults, 1901c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek ASTContext &Ctx, 1902c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek llvm::StringSet<llvm::BumpPtrAllocator> &HiddenNames){ 19035f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor bool OnlyTagNames = false; 19045f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor switch (Context.getKind()) { 190552779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor case CodeCompletionContext::CCC_Recovery: 19065f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_TopLevel: 19075f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCInterface: 19085f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCImplementation: 19095f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCIvarList: 19105f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ClassStructUnion: 19115f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_Statement: 19125f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_Expression: 19135f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCMessageReceiver: 19143da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_DotMemberAccess: 19153da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_ArrowMemberAccess: 19163da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_ObjCPropertyAccess: 19175f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_Namespace: 19185f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_Type: 19192ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor case CodeCompletionContext::CCC_Name: 19202ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor case CodeCompletionContext::CCC_PotentiallyQualifiedName: 19210268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor case CodeCompletionContext::CCC_ParenthesizedExpression: 19220f91c8ccb398be2bd40dc402309bd79737542396Douglas Gregor case CodeCompletionContext::CCC_ObjCInterfaceName: 19235f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor break; 19245f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 19255f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_EnumTag: 19265f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_UnionTag: 19275f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ClassOrStructTag: 19285f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor OnlyTagNames = true; 19295f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor break; 19305f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 19315f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCProtocolName: 19321fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor case CodeCompletionContext::CCC_MacroName: 19331fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor case CodeCompletionContext::CCC_MacroNameUse: 1934f29c5233085a5af795c3c01b94d319e5b3235d56Douglas Gregor case CodeCompletionContext::CCC_PreprocessorExpression: 1935721f359a350059a81945baa08f63b2e5feceb044Douglas Gregor case CodeCompletionContext::CCC_PreprocessorDirective: 193659a66946aa7723c7b14831aa50902d533baaa957Douglas Gregor case CodeCompletionContext::CCC_NaturalLanguage: 1937458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor case CodeCompletionContext::CCC_SelectorName: 19381a480c403a3b141ab89c9c59cf7b681102a1bfabDouglas Gregor case CodeCompletionContext::CCC_TypeQualifiers: 193952779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor case CodeCompletionContext::CCC_Other: 19405c722c7020b33da57090422b854072258a50b3f0Douglas Gregor case CodeCompletionContext::CCC_OtherWithMacros: 19413da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_ObjCInstanceMessage: 19423da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_ObjCClassMessage: 19433da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_ObjCCategoryName: 1944721f359a350059a81945baa08f63b2e5feceb044Douglas Gregor // We're looking for nothing, or we're looking for names that cannot 1945721f359a350059a81945baa08f63b2e5feceb044Douglas Gregor // be hidden. 19465f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor return; 19475f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor } 19485f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 19490a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall typedef CodeCompletionResult Result; 19505f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor for (unsigned I = 0; I != NumResults; ++I) { 19515f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (Results[I].Kind != Result::RK_Declaration) 19525f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor continue; 19535f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 19545f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor unsigned IDNS 19555f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor = Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace(); 19565f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 19575f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor bool Hiding = false; 19585f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (OnlyTagNames) 19595f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor Hiding = (IDNS & Decl::IDNS_Tag); 19605f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor else { 19615f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member | 1962a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Decl::IDNS_Namespace | Decl::IDNS_Ordinary | 1963a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Decl::IDNS_NonMemberOperator); 19645f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (Ctx.getLangOptions().CPlusPlus) 19655f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenIDNS |= Decl::IDNS_Tag; 19665f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor Hiding = (IDNS & HiddenIDNS); 19675f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor } 19685f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 19695f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (!Hiding) 19705f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor continue; 19715f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 19725f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor DeclarationName Name = Results[I].Declaration->getDeclName(); 19735f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (IdentifierInfo *Identifier = Name.getAsIdentifierInfo()) 19745f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenNames.insert(Identifier->getName()); 19755f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor else 19765f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenNames.insert(Name.getAsString()); 19775f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor } 19785f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor} 19795f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 19805f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 1981697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregorvoid AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S, 1982697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor CodeCompletionContext Context, 19830a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall CodeCompletionResult *Results, 1984697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor unsigned NumResults) { 1985697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // Merge the results we were given with the results we cached. 1986697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor bool AddedResult = false; 19875f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor unsigned InContexts 198852779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor = (Context.getKind() == CodeCompletionContext::CCC_Recovery? NormalContexts 198901a429a1029dd650ed11cc35160451664f664df3NAKAMURA Takumi : (1ULL << (Context.getKind() - 1))); 19905f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor // Contains the set of names that are hidden by "local" completion results. 1991c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames; 19920a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall typedef CodeCompletionResult Result; 19935f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Result, 8> AllResults; 1994697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor for (ASTUnit::cached_completion_iterator 19955535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor C = AST.cached_completion_begin(), 19965535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor CEnd = AST.cached_completion_end(); 1997697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor C != CEnd; ++C) { 1998697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // If the context we are in matches any of the contexts we are 1999697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // interested in, we'll add this result. 2000697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if ((C->ShowInContexts & InContexts) == 0) 2001697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor continue; 2002697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 2003697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // If we haven't added any results previously, do so now. 2004697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (!AddedResult) { 20055f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor CalculateHiddenNames(Context, Results, NumResults, S.Context, 20065f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenNames); 2007697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor AllResults.insert(AllResults.end(), Results, Results + NumResults); 2008697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor AddedResult = true; 2009697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 2010697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 20115f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor // Determine whether this global completion result is hidden by a local 20125f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor // completion result. If so, skip it. 20135f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (C->Kind != CXCursor_MacroDefinition && 20145f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenNames.count(C->Completion->getTypedText())) 20155f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor continue; 20165f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 2017697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // Adjust priority based on similar type classes. 2018697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor unsigned Priority = C->Priority; 20194125c37c71c6c8475019497de837204f0ee4370fDouglas Gregor CXCursorKind CursorKind = C->Kind; 20201fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor CodeCompletionString *Completion = C->Completion; 2021697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (!Context.getPreferredType().isNull()) { 2022697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (C->Kind == CXCursor_MacroDefinition) { 2023697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Priority = getMacroUsagePriority(C->Completion->getTypedText(), 2024b05496dbd63f03bf474dae2c4d1e2142608780ccDouglas Gregor S.getLangOptions(), 20251fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor Context.getPreferredType()->isAnyPointerType()); 2026697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } else if (C->Type) { 2027697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor CanQualType Expected 20285535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor = S.Context.getCanonicalType( 2029697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Context.getPreferredType().getUnqualifiedType()); 2030697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor SimplifiedTypeClass ExpectedSTC = getSimplifiedTypeClass(Expected); 2031697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (ExpectedSTC == C->TypeClass) { 2032697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // We know this type is similar; check for an exact match. 2033697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor llvm::StringMap<unsigned> &CachedCompletionTypes 20345535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor = AST.getCachedCompletionTypes(); 2035697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor llvm::StringMap<unsigned>::iterator Pos 20365535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor = CachedCompletionTypes.find(QualType(Expected).getAsString()); 2037697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type) 2038697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Priority /= CCF_ExactTypeMatch; 2039697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor else 2040697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Priority /= CCF_SimilarTypeMatch; 2041697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 2042697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 2043697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 2044697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 20451fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor // Adjust the completion string, if required. 20461fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor if (C->Kind == CXCursor_MacroDefinition && 20471fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) { 20481fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor // Create a new code-completion string that just contains the 20491fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor // macro name, without its arguments. 2050218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor CodeCompletionBuilder Builder(getAllocator(), CCP_CodePattern, 2051218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor C->Availability); 2052218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor Builder.AddTypedTextChunk(C->Completion->getTypedText()); 20534125c37c71c6c8475019497de837204f0ee4370fDouglas Gregor CursorKind = CXCursor_NotImplemented; 20544125c37c71c6c8475019497de837204f0ee4370fDouglas Gregor Priority = CCP_CodePattern; 2055218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor Completion = Builder.TakeString(); 20561fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor } 20571fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor 20584125c37c71c6c8475019497de837204f0ee4370fDouglas Gregor AllResults.push_back(Result(Completion, Priority, CursorKind, 205958ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor C->Availability)); 2060697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 2061697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 2062697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // If we did not add any cached completion results, just forward the 2063697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // results we were given to the next consumer. 2064697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (!AddedResult) { 2065697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Next.ProcessCodeCompleteResults(S, Context, Results, NumResults); 2066697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor return; 2067697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 20681e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor 2069697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Next.ProcessCodeCompleteResults(S, Context, AllResults.data(), 2070697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor AllResults.size()); 2071697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor} 2072697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 2073697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 2074697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 20755f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, 20761abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor RemappedFile *RemappedFiles, 20771abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor unsigned NumRemappedFiles, 2078cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor bool IncludeMacros, 2079cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor bool IncludeCodePatterns, 20801abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor CodeCompleteConsumer &Consumer, 2081d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie DiagnosticsEngine &Diag, LangOptions &LangOpts, 20821abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor SourceManager &SourceMgr, FileManager &FileMgr, 20835f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics, 20845f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers) { 20854f32786ac45210143654390177105eb749b614e9Ted Kremenek if (!Invocation) 20861abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor return; 20871abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 2088213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer CompletionTimer(WantTiming); 2089edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer CompletionTimer.setOutput("Code completion @ " + File + ":" + 20905f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner Twine(Line) + ":" + Twine(Column)); 2091df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 20924f32786ac45210143654390177105eb749b614e9Ted Kremenek llvm::IntrusiveRefCntPtr<CompilerInvocation> 20934f32786ac45210143654390177105eb749b614e9Ted Kremenek CCInvocation(new CompilerInvocation(*Invocation)); 20944f32786ac45210143654390177105eb749b614e9Ted Kremenek 20954f32786ac45210143654390177105eb749b614e9Ted Kremenek FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts(); 20964f32786ac45210143654390177105eb749b614e9Ted Kremenek PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts(); 2097cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor 209887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor FrontendOpts.ShowMacrosInCodeCompletion 209987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor = IncludeMacros && CachedCompletionResults.empty(); 2100cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor FrontendOpts.ShowCodePatternsInCodeCompletion = IncludeCodePatterns; 21018071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor FrontendOpts.ShowGlobalSymbolsInCodeCompletion 21028071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor = CachedCompletionResults.empty(); 21031abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor FrontendOpts.CodeCompletionAt.FileName = File; 21041abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor FrontendOpts.CodeCompletionAt.Line = Line; 21051abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor FrontendOpts.CodeCompletionAt.Column = Column; 21061abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 21071abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set the language options appropriately. 21084f32786ac45210143654390177105eb749b614e9Ted Kremenek LangOpts = CCInvocation->getLangOpts(); 21091abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 211003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance()); 211103201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 211203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek // Recover resources if we crash before exiting this method. 211325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> 211425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek CICleanup(Clang.get()); 211503201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 21164f32786ac45210143654390177105eb749b614e9Ted Kremenek Clang->setInvocation(&*CCInvocation); 211703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second; 21181abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 21191abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set up diagnostics, capturing any diagnostics produced. 212003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setDiagnostics(&Diag); 21214f32786ac45210143654390177105eb749b614e9Ted Kremenek ProcessWarningOptions(Diag, CCInvocation->getDiagnosticOpts()); 21221abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor CaptureDroppedDiagnostics Capture(true, 212303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getDiagnostics(), 21241abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor StoredDiagnostics); 21251abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 21261abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Create the target instance. 212703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTargetOpts().Features = TargetFeatures; 212803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), 212903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTargetOpts())); 213003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek if (!Clang->hasTarget()) { 21314f32786ac45210143654390177105eb749b614e9Ted Kremenek Clang->setInvocation(0); 2132bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor return; 21331abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor } 21341abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 21351abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Inform the target of the language options. 21361abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // 21371abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // FIXME: We shouldn't need to do this, the target should be immutable once 21381abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // created. This complexity should be lifted elsewhere. 213903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); 21401abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 214103201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs.size() == 1 && 21421abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor "Invocation must have exactly one source file!"); 214303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs[0].first != IK_AST && 21441abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor "FIXME: AST inputs not yet supported here!"); 214503201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs[0].first != IK_LLVM_IR && 21461abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor "IR inputs not support here!"); 21471abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 21481abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 21491abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Use the source and file managers that we were given. 215003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setFileManager(&FileMgr); 215103201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setSourceManager(&SourceMgr); 21521abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 21531abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Remap files. 21541abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PreprocessorOpts.clearRemappedFiles(); 2155b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor PreprocessorOpts.RetainRemappedFileBuffers = true; 21562283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor for (unsigned I = 0; I != NumRemappedFiles; ++I) { 2157b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; 2158b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (const llvm::MemoryBuffer * 2159b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { 2160b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, memBuf); 2161b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis OwnedBuffers.push_back(memBuf); 2162b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } else { 2163b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const char *fname = fileOrBuf.get<const char *>(); 2164b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, fname); 2165b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 21662283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor } 21671abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 216887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Use the code completion consumer we were given, but adding any cached 216987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // code-completion results. 21707f946ad40877df749ad05392cc4b80dc4189d28fDouglas Gregor AugmentedCodeCompleteConsumer *AugmentedConsumer 21717f946ad40877df749ad05392cc4b80dc4189d28fDouglas Gregor = new AugmentedCodeCompleteConsumer(*this, Consumer, 21727f946ad40877df749ad05392cc4b80dc4189d28fDouglas Gregor FrontendOpts.ShowMacrosInCodeCompletion, 21737f946ad40877df749ad05392cc4b80dc4189d28fDouglas Gregor FrontendOpts.ShowCodePatternsInCodeCompletion, 21747f946ad40877df749ad05392cc4b80dc4189d28fDouglas Gregor FrontendOpts.ShowGlobalSymbolsInCodeCompletion); 217503201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setCodeCompletionConsumer(AugmentedConsumer); 21761abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 2177df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // If we have a precompiled preamble, try to use it. We only allow 2178df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // the use of the precompiled preamble if we're if the completion 2179df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // point is within the main file, after the end of the precompiled 2180df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // preamble. 2181df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor llvm::MemoryBuffer *OverrideMainBuffer = 0; 2182df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (!PreambleFile.empty()) { 2183df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor using llvm::sys::FileStatus; 2184df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor llvm::sys::PathWithStatus CompleteFilePath(File); 2185df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor llvm::sys::PathWithStatus MainPath(OriginalSourceFile); 2186df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (const FileStatus *CompleteFileStatus = CompleteFilePath.getFileStatus()) 2187df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (const FileStatus *MainStatus = MainPath.getFileStatus()) 2188c8c97a03eb0fdeb4f5fc9c4dea308ebbf46c2c93Argyrios Kyrtzidis if (CompleteFileStatus->getUniqueID() == MainStatus->getUniqueID() && 2189c8c97a03eb0fdeb4f5fc9c4dea308ebbf46c2c93Argyrios Kyrtzidis Line > 1) 21902283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor OverrideMainBuffer 21914f32786ac45210143654390177105eb749b614e9Ted Kremenek = getMainBufferWithPrecompiledPreamble(*CCInvocation, false, 2192c9c29a8d7a0f78ddf2b393dd92f77c7f2046179cDouglas Gregor Line - 1); 2193df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 2194df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 2195df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // If the main file has been overridden due to the use of a preamble, 2196df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // make that override happen and introduce the preamble. 21978ef6c8cb6c5627240e2339fd7062c9873f821d7eDouglas Gregor PreprocessorOpts.DisableStatCache = true; 21984cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.insert(StoredDiagnostics.end(), 21994cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor this->StoredDiagnostics.begin(), 22004cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor this->StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver); 2201df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (OverrideMainBuffer) { 2202df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); 2203df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size(); 2204df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second 2205df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor = PreambleEndsAtStartOfLine; 2206df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.ImplicitPCHInclude = PreambleFile; 2207df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.DisablePCHValidation = true; 2208df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 22092283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor OwnedBuffers.push_back(OverrideMainBuffer); 2210f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor } else { 2211f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = 0; 2212f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second = false; 2213df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 2214df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 2215dca8ee8b7bc86076916a3a80f553f7a4e98c14afDouglas Gregor // Disable the preprocessing record 2216dca8ee8b7bc86076916a3a80f553f7a4e98c14afDouglas Gregor PreprocessorOpts.DetailedRecord = false; 2217dca8ee8b7bc86076916a3a80f553f7a4e98c14afDouglas Gregor 22181abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor llvm::OwningPtr<SyntaxOnlyAction> Act; 22191abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Act.reset(new SyntaxOnlyAction); 222003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek if (Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0].second, 222103201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getFrontendOpts().Inputs[0].first)) { 2222f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (OverrideMainBuffer) { 22239461fccd05bde8458710ba367be10b6e4efe2ec7Jonathan D. Turner std::string ModName = PreambleFile; 2224f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateStoredDiagnostics(Clang->getModuleManager(), ModName, 2225f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor getSourceManager(), PreambleDiagnostics, 2226f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor StoredDiagnostics); 2227f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 22281abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Act->Execute(); 22291abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Act->EndSourceFile(); 22301abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor } 22311abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor} 22327ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor 22335f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerCXSaveError ASTUnit::Save(StringRef File) { 223485bea9777d444ccbcc086d98f075fe666c2e865dDouglas Gregor if (getDiagnostics().hasUnrecoverableErrorOccurred()) 223539c411fa229b2a6747b92f945d1702ee674d3470Douglas Gregor return CXSaveError_TranslationErrors; 22369cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis 22379cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis // Write to a temporary file and later rename it to the actual file, to avoid 22389cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis // possible race conditions. 22397e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis llvm::SmallString<128> TempPath; 22407e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis TempPath = File; 22417e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis TempPath += "-%%%%%%%%"; 22427e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis int fd; 22437e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis if (llvm::sys::fs::unique_file(TempPath.str(), fd, TempPath, 22447e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis /*makeAbsolute=*/false)) 22459cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis return CXSaveError_Unknown; 22469cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis 22477ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor // FIXME: Can we somehow regenerate the stat cache here, or do we need to 22487ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor // unconditionally create a stat cache when we parse the file? 22497e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis llvm::raw_fd_ostream Out(fd, /*shouldClose=*/true); 2250b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 2251b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis serialize(Out); 2252b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis Out.close(); 22539cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis if (Out.has_error()) 22549cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis return CXSaveError_Unknown; 22559cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis 22569cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis if (llvm::error_code ec = llvm::sys::fs::rename(TempPath.str(), File)) { 22579cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis bool exists; 22589cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis llvm::sys::fs::remove(TempPath.str(), exists); 22599cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis return CXSaveError_Unknown; 22609cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis } 22619cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis 22629cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis return CXSaveError_None; 2263b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis} 2264b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 22655f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerbool ASTUnit::serialize(raw_ostream &OS) { 2266b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis if (getDiagnostics().hasErrorOccurred()) 2267b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis return true; 2268b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 22697ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor std::vector<unsigned char> Buffer; 22707ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor llvm::BitstreamWriter Stream(Buffer); 2271a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl ASTWriter Writer(Stream); 22727143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor // FIXME: Handle modules 22737143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor Writer.WriteAST(getSema(), 0, std::string(), /*IsModule=*/false, ""); 22747ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor 22757ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor // Write the generated bitstream to "Out". 2276bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor if (!Buffer.empty()) 2277b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis OS.write((char *)&Buffer.front(), Buffer.size()); 2278b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 2279b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis return false; 22807ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor} 2281f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 2282f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregortypedef ContinuousRangeMap<unsigned, int, 2> SLocRemap; 2283f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 2284f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregorstatic void TranslateSLoc(SourceLocation &L, SLocRemap &Remap) { 2285f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned Raw = L.getRawEncoding(); 2286f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const unsigned MacroBit = 1U << 31; 2287f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor L = SourceLocation::getFromRawEncoding((Raw & MacroBit) | 2288f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor ((Raw & ~MacroBit) + Remap.find(Raw & ~MacroBit)->second)); 2289f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor} 2290f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 2291f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregorvoid ASTUnit::TranslateStoredDiagnostics( 2292f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor ASTReader *MMan, 22935f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef ModName, 2294f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceManager &SrcMgr, 22955f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner const SmallVectorImpl<StoredDiagnostic> &Diags, 22965f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<StoredDiagnostic> &Out) { 2297f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // The stored diagnostic has the old source manager in it; update 2298f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // the locations to refer into the new source manager. We also need to remap 2299f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // all the locations to the new view. This includes the diag location, any 2300f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // associated source ranges, and the source ranges of associated fix-its. 2301f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // FIXME: There should be a cleaner way to do this. 2302f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 23035f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<StoredDiagnostic, 4> Result; 2304f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Result.reserve(Diags.size()); 2305f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(MMan && "Don't have a module manager"); 230648d2c3f7c3ca48da05436afdc8426a245294ee65Jonathan D. Turner serialization::Module *Mod = MMan->ModuleMgr.lookup(ModName); 2307f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(Mod && "Don't have preamble module"); 2308f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SLocRemap &Remap = Mod->SLocRemap; 2309f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (unsigned I = 0, N = Diags.size(); I != N; ++I) { 2310f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Rebuild the StoredDiagnostic. 2311f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const StoredDiagnostic &SD = Diags[I]; 2312f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceLocation L = SD.getLocation(); 2313f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateSLoc(L, Remap); 2314f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FullSourceLoc Loc(L, SrcMgr); 2315f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 23165f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CharSourceRange, 4> Ranges; 2317f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Ranges.reserve(SD.range_size()); 2318f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (StoredDiagnostic::range_iterator I = SD.range_begin(), 2319f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor E = SD.range_end(); 2320f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor I != E; ++I) { 2321f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceLocation BL = I->getBegin(); 2322f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateSLoc(BL, Remap); 2323f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceLocation EL = I->getEnd(); 2324f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateSLoc(EL, Remap); 2325f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Ranges.push_back(CharSourceRange(SourceRange(BL, EL), I->isTokenRange())); 2326f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 2327f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 23285f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<FixItHint, 2> FixIts; 2329f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FixIts.reserve(SD.fixit_size()); 2330f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (StoredDiagnostic::fixit_iterator I = SD.fixit_begin(), 2331f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor E = SD.fixit_end(); 2332f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor I != E; ++I) { 2333f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FixIts.push_back(FixItHint()); 2334f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FixItHint &FH = FixIts.back(); 2335f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FH.CodeToInsert = I->CodeToInsert; 2336f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceLocation BL = I->RemoveRange.getBegin(); 2337f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateSLoc(BL, Remap); 2338f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceLocation EL = I->RemoveRange.getEnd(); 2339f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateSLoc(EL, Remap); 2340f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FH.RemoveRange = CharSourceRange(SourceRange(BL, EL), 2341f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor I->RemoveRange.isTokenRange()); 2342f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 2343f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 2344f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Result.push_back(StoredDiagnostic(SD.getLevel(), SD.getID(), 2345f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SD.getMessage(), Loc, Ranges, FixIts)); 2346f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 2347f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Result.swap(Out); 2348f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor} 2349507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis 2350507097ec40105ed927cb5a744fad98f5875aacacArgyrios KyrtzidisSourceLocation ASTUnit::getLocation(const FileEntry *File, 2351507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis unsigned Line, unsigned Col) const { 2352507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis const SourceManager &SM = getSourceManager(); 2353ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis SourceLocation Loc = SM.translateFileLineCol(File, Line, Col); 2354507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis return SM.getMacroArgExpandedLocation(Loc); 2355507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis} 2356507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis 2357507097ec40105ed927cb5a744fad98f5875aacacArgyrios KyrtzidisSourceLocation ASTUnit::getLocation(const FileEntry *File, 2358507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis unsigned Offset) const { 2359507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis const SourceManager &SM = getSourceManager(); 2360ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis SourceLocation FileLoc = SM.translateFileLineCol(File, 1, 1); 2361507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis return SM.getMacroArgExpandedLocation(FileLoc.getLocWithOffset(Offset)); 2362507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis} 2363507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis 2364ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// \brief If \arg Loc is a loaded location from the preamble, returns 2365ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// the corresponding local location of the main file, otherwise it returns 2366ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// \arg Loc. 2367ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios KyrtzidisSourceLocation ASTUnit::mapLocationFromPreamble(SourceLocation Loc) { 2368ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis FileID PreambleID; 2369ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis if (SourceMgr) 2370ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis PreambleID = SourceMgr->getPreambleFileID(); 2371ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis 2372ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis if (Loc.isInvalid() || Preamble.empty() || PreambleID.isInvalid()) 2373ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis return Loc; 2374ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis 2375ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis unsigned Offs; 2376ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis if (SourceMgr->isInFileID(Loc, PreambleID, &Offs) && Offs < Preamble.size()) { 2377ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis SourceLocation FileLoc 2378ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis = SourceMgr->getLocForStartOfFile(SourceMgr->getMainFileID()); 2379ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis return FileLoc.getLocWithOffset(Offs); 2380ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis } 2381ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis 2382ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis return Loc; 2383ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis} 2384ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis 2385ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// \brief If \arg Loc is a local location of the main file but inside the 2386ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// preamble chunk, returns the corresponding loaded location from the 2387ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// preamble, otherwise it returns \arg Loc. 2388ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios KyrtzidisSourceLocation ASTUnit::mapLocationToPreamble(SourceLocation Loc) { 2389ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis FileID PreambleID; 2390ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis if (SourceMgr) 2391ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis PreambleID = SourceMgr->getPreambleFileID(); 2392ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis 2393ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis if (Loc.isInvalid() || Preamble.empty() || PreambleID.isInvalid()) 2394ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis return Loc; 2395ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis 2396ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis unsigned Offs; 2397ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis if (SourceMgr->isInFileID(Loc, SourceMgr->getMainFileID(), &Offs) && 2398ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis Offs < Preamble.size()) { 2399ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis SourceLocation FileLoc = SourceMgr->getLocForStartOfFile(PreambleID); 2400ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis return FileLoc.getLocWithOffset(Offs); 2401ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis } 2402ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis 2403ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis return Loc; 2404ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis} 2405ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis 2406507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidisvoid ASTUnit::PreambleData::countLines() const { 2407507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis NumLines = 0; 2408507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis if (empty()) 2409507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis return; 2410507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis 2411507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis for (std::vector<char>::const_iterator 2412507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis I = Buffer.begin(), E = Buffer.end(); I != E; ++I) { 2413507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis if (*I == '\n') 2414507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis ++NumLines; 2415507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis } 2416507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis if (Buffer.back() != '\n') 2417507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis ++NumLines; 2418507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis} 2419a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis 2420a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis#ifndef NDEBUG 2421a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios KyrtzidisASTUnit::ConcurrencyState::ConcurrencyState() { 2422a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis Mutex = new llvm::sys::MutexImpl(/*recursive=*/true); 2423a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis} 2424a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis 2425a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios KyrtzidisASTUnit::ConcurrencyState::~ConcurrencyState() { 2426a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis delete static_cast<llvm::sys::MutexImpl *>(Mutex); 2427a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis} 2428a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis 2429a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidisvoid ASTUnit::ConcurrencyState::start() { 2430a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis bool acquired = static_cast<llvm::sys::MutexImpl *>(Mutex)->tryacquire(); 2431a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis assert(acquired && "Concurrent access to ASTUnit!"); 2432a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis} 2433a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis 2434a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidisvoid ASTUnit::ConcurrencyState::finish() { 2435a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis static_cast<llvm::sys::MutexImpl *>(Mutex)->release(); 2436a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis} 2437a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis 2438a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis#else // NDEBUG 2439a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis 2440a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios KyrtzidisASTUnit::ConcurrencyState::ConcurrencyState() {} 2441a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios KyrtzidisASTUnit::ConcurrencyState::~ConcurrencyState() {} 2442a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidisvoid ASTUnit::ConcurrencyState::start() {} 2443a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidisvoid ASTUnit::ConcurrencyState::finish() {} 2444a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis 2445a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis#endif 2446