ASTUnit.cpp revision 7e90985df09855dc309ed888a5b16a0ae684f8e3
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" 3289d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor#include "clang/Serialization/ASTSerializationListener.h" 337faa2ec03a7ef120ac165bb45b6c70a8b20c9f1cSebastian Redl#include "clang/Serialization/ASTWriter.h" 340853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Lex/HeaderSearch.h" 350853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Lex/Preprocessor.h" 36d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar#include "clang/Basic/TargetOptions.h" 370853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Basic/TargetInfo.h" 380853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Basic/Diagnostic.h" 397f9fc3f7ce076645cb6aefc99c64d9446caf13d6Chris Lattner#include "llvm/ADT/ArrayRef.h" 409b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor#include "llvm/ADT/StringExtras.h" 41349d38cef04ddf8938047c1b542a799aa82dfe84Douglas Gregor#include "llvm/ADT/StringSet.h" 421fd9e0def66fbd50e99be5ff87c9fd1c91c428abDouglas Gregor#include "llvm/Support/Atomic.h" 434db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor#include "llvm/Support/MemoryBuffer.h" 4403013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Host.h" 4503013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Path.h" 46df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor#include "llvm/Support/raw_ostream.h" 47385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor#include "llvm/Support/Timer.h" 489cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis#include "llvm/Support/FileSystem.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), 100213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor CompleteTranslationUnit(true), WantTiming(getenv("LIBCLANG_TIMING")), 10115727ddb11405c45372150b5bfb07dbfa4c9960bArgyrios Kyrtzidis OwnsRemappedFileBuffers(true), 102213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor NumStoredDiagnosticsFromDriver(0), 1034cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor ConcurrencyCheckValue(CheckUnlocked), 104671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreambleRebuildCounter(0), SavedMainFileBuffer(0), PreambleBuffer(0), 105727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor ShouldCacheCodeCompletionResults(false), 106ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth NestedMacroExpansions(true), 1079b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CompletionCacheTopLevelHashValue(0), 1089b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor PreambleTopLevelHashValue(0), 1099b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CurrentTopLevelHashValue(0), 1108b1540c159093e0e627ebf6542d0c0b7aba99eafDouglas Gregor UnsafeToFree(false) { 111e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor if (getenv("LIBCLANG_OBJTRACKING")) { 1121fd9e0def66fbd50e99be5ff87c9fd1c91c428abDouglas Gregor llvm::sys::AtomicIncrement(&ActiveASTUnitObjects); 113e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor fprintf(stderr, "+++ %d translation units\n", ActiveASTUnitObjects); 114e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor } 115385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor} 1163687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor 117521bf9c529e653ab28896d027352d3e16e2672d5Daniel DunbarASTUnit::~ASTUnit() { 118bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor ConcurrencyCheckValue = CheckLocked; 119abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor CleanTemporaryFiles(); 120175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (!PreambleFile.empty()) 121385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor llvm::sys::Path(PreambleFile).eraseFromDisk(); 122f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 123f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // Free the buffers associated with remapped files. We are required to 124f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // perform this operation here because we explicitly request that the 125f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // compiler instance *not* free these buffers for each invocation of the 126f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // parser. 1274f32786ac45210143654390177105eb749b614e9Ted Kremenek if (Invocation.getPtr() && OwnsRemappedFileBuffers) { 128f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 129f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 130f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor FB = PPOpts.remapped_file_buffer_begin(), 131f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor FBEnd = PPOpts.remapped_file_buffer_end(); 132f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor FB != FBEnd; 133f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor ++FB) 134f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor delete FB->second; 135f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor } 13628233428da1ebec20c893d6297ae3191318940ddDouglas Gregor 13728233428da1ebec20c893d6297ae3191318940ddDouglas Gregor delete SavedMainFileBuffer; 138671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete PreambleBuffer; 139671947b18dba342f9aba022ee992babef325a833Douglas Gregor 140213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor ClearCachedCompletionResults(); 141e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor 142e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor if (getenv("LIBCLANG_OBJTRACKING")) { 1431fd9e0def66fbd50e99be5ff87c9fd1c91c428abDouglas Gregor llvm::sys::AtomicDecrement(&ActiveASTUnitObjects); 144e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor fprintf(stderr, "--- %d translation units\n", ActiveASTUnitObjects); 145e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor } 146abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 147abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 148abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregorvoid ASTUnit::CleanTemporaryFiles() { 149313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I) 150313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor TemporaryFiles[I].eraseFromDisk(); 151abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor TemporaryFiles.clear(); 152e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff} 1530853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 1548071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor/// \brief Determine the set of code-completion contexts in which this 1558071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor/// declaration should be shown. 1568071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregorstatic unsigned getDeclShowContexts(NamedDecl *ND, 157a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor const LangOptions &LangOpts, 158a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor bool &IsNestedNameSpecifier) { 159a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = false; 160a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor 1618071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (isa<UsingShadowDecl>(ND)) 1628071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor ND = dyn_cast<NamedDecl>(ND->getUnderlyingDecl()); 1638071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (!ND) 1648071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor return 0; 1658071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 1668071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor unsigned Contexts = 0; 1678071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND) || 1688071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND)) { 1698071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // Types can appear in these contexts. 1708071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus || !isa<TagDecl>(ND)) 1718071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_TopLevel - 1)) 1728071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1)) 1738071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1)) 1748071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor | (1 << (CodeCompletionContext::CCC_Statement - 1)) 1750268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_Type - 1)) 1760268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)); 1778071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 1788071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // In C++, types can appear in expressions contexts (for functional casts). 1798071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus) 1808071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_Expression - 1)); 1818071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 1828071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // In Objective-C, message sends can send interfaces. In Objective-C++, 1838071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // all types are available due to functional casts. 1848071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus || isa<ObjCInterfaceDecl>(ND)) 1858071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)); 1863da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor 1873da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor // In Objective-C, you can only be a subclass of another Objective-C class 1883da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor if (isa<ObjCInterfaceDecl>(ND)) 1893da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_ObjCSuperclass - 1)); 1908071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 1918071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // Deal with tag names. 1928071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (isa<EnumDecl>(ND)) { 1938071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_EnumTag - 1)); 1948071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 195a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // Part of the nested-name-specifier in C++0x. 1968071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus0x) 197a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = true; 1988071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } else if (RecordDecl *Record = dyn_cast<RecordDecl>(ND)) { 1998071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (Record->isUnion()) 2008071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_UnionTag - 1)); 2018071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor else 2028071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1)); 2038071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 2048071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus) 205a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = true; 20652779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor } else if (isa<ClassTemplateDecl>(ND)) 207a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = true; 2088071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } else if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) { 2098071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // Values can appear in these contexts. 2108071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts = (1 << (CodeCompletionContext::CCC_Statement - 1)) 2118071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor | (1 << (CodeCompletionContext::CCC_Expression - 1)) 2120268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)) 2138071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)); 2148071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } else if (isa<ObjCProtocolDecl>(ND)) { 2158071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts = (1 << (CodeCompletionContext::CCC_ObjCProtocolName - 1)); 2163da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor } else if (isa<ObjCCategoryDecl>(ND)) { 2173da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor Contexts = (1 << (CodeCompletionContext::CCC_ObjCCategoryName - 1)); 2188071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } else if (isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) { 219a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Contexts = (1 << (CodeCompletionContext::CCC_Namespace - 1)); 2208071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 2218071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // Part of the nested-name-specifier. 222a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = true; 2238071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } 2248071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 2258071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor return Contexts; 2268071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor} 2278071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 22887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregorvoid ASTUnit::CacheCodeCompletionResults() { 22987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor if (!TheSema) 23087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor return; 23187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 232213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer Timer(WantTiming); 233edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer Timer.setOutput("Cache global code completions for " + getMainFileName()); 23487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 23587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Clear out the previous results. 23687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor ClearCachedCompletionResults(); 23787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 23887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Gather the set of global code completions. 2390a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall typedef CodeCompletionResult Result; 2405f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Result, 8> Results; 24148601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor CachedCompletionAllocator = new GlobalCodeCompletionAllocator; 24248601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor TheSema->GatherGlobalCodeCompletions(*CachedCompletionAllocator, Results); 24387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 24487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Translate global code completions into cached completions. 245f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor llvm::DenseMap<CanQualType, unsigned> CompletionTypes; 246f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 24787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor for (unsigned I = 0, N = Results.size(); I != N; ++I) { 24887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor switch (Results[I].Kind) { 2498071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor case Result::RK_Declaration: { 250a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor bool IsNestedNameSpecifier = false; 2518071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedCodeCompletionResult CachedResult; 252218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema, 25348601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor *CachedCompletionAllocator); 2548071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedResult.ShowInContexts = getDeclShowContexts(Results[I].Declaration, 255a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Ctx->getLangOptions(), 256a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier); 2578071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedResult.Priority = Results[I].Priority; 2588071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedResult.Kind = Results[I].CursorKind; 25958ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor CachedResult.Availability = Results[I].Availability; 260c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor 261f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // Keep track of the type of this completion in an ASTContext-agnostic 262f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // way. 263c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor QualType UsageType = getDeclUsageType(*Ctx, Results[I].Declaration); 264f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor if (UsageType.isNull()) { 265c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor CachedResult.TypeClass = STC_Void; 266f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedResult.Type = 0; 267f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor } else { 268f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CanQualType CanUsageType 269f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor = Ctx->getCanonicalType(UsageType.getUnqualifiedType()); 270f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedResult.TypeClass = getSimplifiedTypeClass(CanUsageType); 271f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 272f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // Determine whether we have already seen this type. If so, we save 273f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // ourselves the work of formatting the type string by using the 274f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // temporary, CanQualType-based hash table to find the associated value. 275f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor unsigned &TypeValue = CompletionTypes[CanUsageType]; 276f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor if (TypeValue == 0) { 277f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor TypeValue = CompletionTypes.size(); 278f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedCompletionTypes[QualType(CanUsageType).getAsString()] 279f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor = TypeValue; 280f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor } 281f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 282f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedResult.Type = TypeValue; 283c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor } 284f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 2858071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedCompletionResults.push_back(CachedResult); 286a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor 287a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor /// Handle nested-name-specifiers in C++. 288a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor if (TheSema->Context.getLangOptions().CPlusPlus && 289a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier && !Results[I].StartsNestedNameSpecifier) { 290a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // The contexts in which a nested-name-specifier can appear in C++. 291a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor unsigned NNSContexts 292a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor = (1 << (CodeCompletionContext::CCC_TopLevel - 1)) 293a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1)) 294a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1)) 295a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_Statement - 1)) 296a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_Expression - 1)) 297a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)) 298a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_EnumTag - 1)) 299a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_UnionTag - 1)) 300a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1)) 3012ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor | (1 << (CodeCompletionContext::CCC_Type - 1)) 3020268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_PotentiallyQualifiedName - 1)) 3030268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)); 304a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor 305a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor if (isa<NamespaceDecl>(Results[I].Declaration) || 306a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor isa<NamespaceAliasDecl>(Results[I].Declaration)) 307a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor NNSContexts |= (1 << (CodeCompletionContext::CCC_Namespace - 1)); 308a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor 309a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor if (unsigned RemainingContexts 310a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor = NNSContexts & ~CachedResult.ShowInContexts) { 311a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // If there any contexts where this completion can be a 312a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // nested-name-specifier but isn't already an option, create a 313a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // nested-name-specifier completion. 314a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Results[I].StartsNestedNameSpecifier = true; 315218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor CachedResult.Completion 316218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor = Results[I].CreateCodeCompletionString(*TheSema, 31748601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor *CachedCompletionAllocator); 318a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedResult.ShowInContexts = RemainingContexts; 319a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedResult.Priority = CCP_NestedNameSpecifier; 320a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedResult.TypeClass = STC_Void; 321a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedResult.Type = 0; 322a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedCompletionResults.push_back(CachedResult); 323a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor } 324a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor } 32587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor break; 3268071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } 3278071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 32887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor case Result::RK_Keyword: 32987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor case Result::RK_Pattern: 33087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Ignore keywords and patterns; we don't care, since they are so 33187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // easily regenerated. 33287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor break; 33387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 33487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor case Result::RK_Macro: { 33587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedCodeCompletionResult CachedResult; 336218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor CachedResult.Completion 337218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor = Results[I].CreateCodeCompletionString(*TheSema, 33848601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor *CachedCompletionAllocator); 33987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedResult.ShowInContexts 34087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor = (1 << (CodeCompletionContext::CCC_TopLevel - 1)) 34187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCInterface - 1)) 34287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCImplementation - 1)) 34387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1)) 34487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1)) 34587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_Statement - 1)) 34687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_Expression - 1)) 3471fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)) 348f29c5233085a5af795c3c01b94d319e5b3235d56Douglas Gregor | (1 << (CodeCompletionContext::CCC_MacroNameUse - 1)) 3490268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_PreprocessorExpression - 1)) 3505c722c7020b33da57090422b854072258a50b3f0Douglas Gregor | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)) 3515c722c7020b33da57090422b854072258a50b3f0Douglas Gregor | (1 << (CodeCompletionContext::CCC_OtherWithMacros - 1)); 3522ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor 35387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedResult.Priority = Results[I].Priority; 35487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedResult.Kind = Results[I].CursorKind; 35558ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor CachedResult.Availability = Results[I].Availability; 3561827e10051638770ad9ccf3e285caf95f995afd1Douglas Gregor CachedResult.TypeClass = STC_Void; 357f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedResult.Type = 0; 35887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedCompletionResults.push_back(CachedResult); 35987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor break; 36087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 36187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 36287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 3639b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 3649b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor // Save the current top-level hash value. 3659b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CompletionCacheTopLevelHashValue = CurrentTopLevelHashValue; 36687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor} 36787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 36887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregorvoid ASTUnit::ClearCachedCompletionResults() { 36987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedCompletionResults.clear(); 370f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedCompletionTypes.clear(); 37148601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor CachedCompletionAllocator = 0; 37287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor} 37387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 3740853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisnamespace { 3750853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 376c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl/// \brief Gathers information from ASTReader that will be used to initialize 3770853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis/// a Preprocessor. 3783c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redlclass ASTInfoCollector : public ASTReaderListener { 3790853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis LangOptions &LangOpt; 3800853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis HeaderSearch &HSI; 3810853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string &TargetTriple; 3820853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string &Predefines; 3830853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned &Counter; 3841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3850853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned NumHeaderInfos; 3861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3870853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidispublic: 3883c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl ASTInfoCollector(LangOptions &LangOpt, HeaderSearch &HSI, 3890853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string &TargetTriple, std::string &Predefines, 3900853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned &Counter) 3910853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis : LangOpt(LangOpt), HSI(HSI), TargetTriple(TargetTriple), 3920853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Predefines(Predefines), Counter(Counter), NumHeaderInfos(0) {} 3931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3940853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis virtual bool ReadLanguageOptions(const LangOptions &LangOpts) { 3950853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis LangOpt = LangOpts; 3960853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return false; 3970853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 3981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3995f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner virtual bool ReadTargetTriple(StringRef Triple) { 4000853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis TargetTriple = Triple; 4010853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return false; 4020853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 4031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 404cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, 4055f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef OriginalFileName, 406277a6e752512cff286190d35cb353ce717e86b18Nick Lewycky std::string &SuggestedPredefines, 407277a6e752512cff286190d35cb353ce717e86b18Nick Lewycky FileManager &FileMgr) { 408cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl Predefines = Buffers[0].Data; 409cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl for (unsigned I = 1, N = Buffers.size(); I != N; ++I) { 410cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl Predefines += Buffers[I].Data; 411cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl } 4120853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return false; 4130853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 4141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 415ec1afbfd8e880d0169aab0ececa2e7e1611f4955Douglas Gregor virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID) { 4160853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis HSI.setHeaderFileInfoForUID(HFI, NumHeaderInfos++); 4170853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 4181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4190853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis virtual void ReadCounter(unsigned Value) { 4200853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Counter = Value; 4210853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 4220853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis}; 4230853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 424a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorclass StoredDiagnosticClient : public DiagnosticClient { 4255f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<StoredDiagnostic> &StoredDiags; 426a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 427a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorpublic: 428a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor explicit StoredDiagnosticClient( 4295f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<StoredDiagnostic> &StoredDiags) 430a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor : StoredDiags(StoredDiags) { } 431a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 432a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor virtual void HandleDiagnostic(Diagnostic::Level Level, 433a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor const DiagnosticInfo &Info); 434a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}; 435a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 436a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor/// \brief RAII object that optionally captures diagnostics, if 437a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor/// there is no diagnostic client to capture them already. 438a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorclass CaptureDroppedDiagnostics { 439a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor Diagnostic &Diags; 440a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor StoredDiagnosticClient Client; 441a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor DiagnosticClient *PreviousClient; 442a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 443a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorpublic: 444a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor CaptureDroppedDiagnostics(bool RequestCapture, Diagnostic &Diags, 4455f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<StoredDiagnostic> &StoredDiags) 446bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor : Diags(Diags), Client(StoredDiags), PreviousClient(0) 447a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor { 448bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor if (RequestCapture || Diags.getClient() == 0) { 449bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor PreviousClient = Diags.takeClient(); 450a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor Diags.setClient(&Client); 451bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor } 452a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor } 453a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 454a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor ~CaptureDroppedDiagnostics() { 455bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor if (Diags.getClient() == &Client) { 456bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor Diags.takeClient(); 457bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor Diags.setClient(PreviousClient); 458bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor } 459a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor } 460a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}; 461a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 4620853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis} // anonymous namespace 4630853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 464a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorvoid StoredDiagnosticClient::HandleDiagnostic(Diagnostic::Level Level, 465a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor const DiagnosticInfo &Info) { 466f2224d89a6ae65a3839529e26d0f6d025d83d6bbArgyrios Kyrtzidis // Default implementation (Warnings/errors count). 467f2224d89a6ae65a3839529e26d0f6d025d83d6bbArgyrios Kyrtzidis DiagnosticClient::HandleDiagnostic(Level, Info); 468f2224d89a6ae65a3839529e26d0f6d025d83d6bbArgyrios Kyrtzidis 469a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor StoredDiags.push_back(StoredDiagnostic(Level, Info)); 470a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor} 471a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 47277accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroffconst std::string &ASTUnit::getOriginalSourceFileName() { 47368d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar return OriginalSourceFile; 47477accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroff} 4750853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 4763c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redlconst std::string &ASTUnit::getASTFileName() { 4773c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl assert(isMainFileAST() && "Not an ASTUnit from an AST file!"); 478c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl return static_cast<ASTReader *>(Ctx->getExternalSource())->getFileName(); 479e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff} 480e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff 4815f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerllvm::MemoryBuffer *ASTUnit::getBufferForFile(StringRef Filename, 48275dfb65c38d51772df9a00ce2d2feeefd55667adChris Lattner std::string *ErrorStr) { 48339b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner assert(FileMgr); 48475dfb65c38d51772df9a00ce2d2feeefd55667adChris Lattner return FileMgr->getBufferForFile(Filename, ErrorStr); 485389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis} 486389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis 487e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor/// \brief Configure the diagnostics object for use with ASTUnit. 488e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregorvoid ASTUnit::ConfigureDiags(llvm::IntrusiveRefCntPtr<Diagnostic> &Diags, 4890b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor const char **ArgBegin, const char **ArgEnd, 490e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor ASTUnit &AST, bool CaptureDiagnostics) { 491e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor if (!Diags.getPtr()) { 492e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor // No diagnostics engine was provided, so create our own diagnostics object 493e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor // with the default options. 494e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor DiagnosticOptions DiagOpts; 495e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor DiagnosticClient *Client = 0; 496e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor if (CaptureDiagnostics) 497e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor Client = new StoredDiagnosticClient(AST.StoredDiagnostics); 4980b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor Diags = CompilerInstance::createDiagnostics(DiagOpts, ArgEnd- ArgBegin, 4990b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor ArgBegin, Client); 500e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor } else if (CaptureDiagnostics) { 501e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor Diags->setClient(new StoredDiagnosticClient(AST.StoredDiagnostics)); 502e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor } 503e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor} 504e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor 5053c7f4134603d04b44f997b43c0a9def270f25386Sebastian RedlASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, 50628019772db70d4547be05a042eb950bc910f134fDouglas Gregor llvm::IntrusiveRefCntPtr<Diagnostic> Diags, 507389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis const FileSystemOptions &FileSystemOpts, 5085cf48766d626ff6b223acc9d4b7e415ca8480836Ted Kremenek bool OnlyLocalDecls, 5094db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFile *RemappedFiles, 510a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor unsigned NumRemappedFiles, 511a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor bool CaptureDiagnostics) { 5123687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true)); 513b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek 514b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek // Recover resources if we crash before exiting this method. 51525a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> 51625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek ASTUnitCleanup(AST.get()); 51725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic, 51825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> > 51925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek DiagCleanup(Diags.getPtr()); 520b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek 5210b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics); 522abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 5237d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor AST->OnlyLocalDecls = OnlyLocalDecls; 524e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor AST->CaptureDiagnostics = CaptureDiagnostics; 52528019772db70d4547be05a042eb950bc910f134fDouglas Gregor AST->Diagnostics = Diags; 5264f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->FileMgr = new FileManager(FileSystemOpts); 5274f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->SourceMgr = new SourceManager(AST->getDiagnostics(), 5284f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->getFileManager()); 52939b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager())); 530914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor 5314db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor for (unsigned I = 0; I != NumRemappedFiles; ++I) { 532b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; 533b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (const llvm::MemoryBuffer * 534b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { 535b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // Create the file entry for the file that we're mapping from. 536b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *FromFile 537b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis = AST->getFileManager().getVirtualFile(RemappedFiles[I].first, 538b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf->getBufferSize(), 539b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 0); 540b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (!FromFile) { 541b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file) 542b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis << RemappedFiles[I].first; 543b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis delete memBuf; 544b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis continue; 545b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 546b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 547b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // Override the contents of the "from" file with the contents of 548b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // the "to" file. 549b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis AST->getSourceManager().overrideFileContents(FromFile, memBuf); 550b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 551b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } else { 552b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const char *fname = fileOrBuf.get<const char *>(); 553b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *ToFile = AST->FileMgr->getFile(fname); 554b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (!ToFile) { 555b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis AST->getDiagnostics().Report(diag::err_fe_remap_missing_to_file) 556b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis << RemappedFiles[I].first << fname; 557b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis continue; 558b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 559b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 560b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // Create the file entry for the file that we're mapping from. 561b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *FromFile 562b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis = AST->getFileManager().getVirtualFile(RemappedFiles[I].first, 563b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis ToFile->getSize(), 564b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 0); 565b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (!FromFile) { 566b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file) 567b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis << RemappedFiles[I].first; 568b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis delete memBuf; 569b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis continue; 570b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 571b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 572b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // Override the contents of the "from" file with the contents of 573b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis // the "to" file. 574b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis AST->getSourceManager().overrideFileContents(FromFile, ToFile); 5754db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 5764db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 5774db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 5780853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // Gather Info for preprocessor construction later on. 5791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5800853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis LangOptions LangInfo; 5810853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis HeaderSearch &HeaderInfo = *AST->HeaderInfo.get(); 5820853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string TargetTriple; 5830853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string Predefines; 5840853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned Counter; 5850853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 586c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl llvm::OwningPtr<ASTReader> Reader; 5870853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 588c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl Reader.reset(new ASTReader(AST->getSourceManager(), AST->getFileManager(), 58939b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner AST->getDiagnostics())); 5908c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek 5918c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek // Recover resources if we crash before exiting this method. 5928c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<ASTReader> 5938c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek ReaderCleanup(Reader.get()); 5948c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek 5953c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl Reader->setListener(new ASTInfoCollector(LangInfo, HeaderInfo, TargetTriple, 596cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar Predefines, Counter)); 597cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar 59872a9ae18553bf8b6bdad84d2c54f73741a47e275Douglas Gregor switch (Reader->ReadAST(Filename, serialization::MK_MainFile)) { 599c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl case ASTReader::Success: 6000853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis break; 6011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 602c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl case ASTReader::Failure: 603c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl case ASTReader::IgnorePCH: 6043687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch); 6050853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return NULL; 6060853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 6071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 60868d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar AST->OriginalSourceFile = Reader->getOriginalSourceFile(); 60968d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar 6103c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl // AST file loaded successfully. Now create the preprocessor. 6111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6120853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // Get information about the target being compiled for. 613d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar // 6143c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl // FIXME: This is broken, we should store the TargetOptions in the AST file. 615d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOptions TargetOpts; 616d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOpts.ABI = ""; 617875ab10245d3bf37252dd822aa1616bb0a391095John McCall TargetOpts.CXXABI = ""; 618d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOpts.CPU = ""; 619d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOpts.Features.clear(); 620d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOpts.Triple = TargetTriple; 6214f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->Target = TargetInfo::CreateTargetInfo(AST->getDiagnostics(), 6224f32786ac45210143654390177105eb749b614e9Ted Kremenek TargetOpts); 6234f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->PP = new Preprocessor(AST->getDiagnostics(), LangInfo, *AST->Target, 6244f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->getSourceManager(), HeaderInfo); 6254f32786ac45210143654390177105eb749b614e9Ted Kremenek Preprocessor &PP = *AST->PP; 6260853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 627d5b6126389e1e2fd89e498fe17da4bb44ece0302Daniel Dunbar PP.setPredefines(Reader->getSuggestedPredefines()); 6280853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis PP.setCounterValue(Counter); 629cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar Reader->setPreprocessor(PP); 6301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6310853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // Create and initialize the ASTContext. 6320853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 6334f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->Ctx = new ASTContext(LangInfo, 6344f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->getSourceManager(), 6354f32786ac45210143654390177105eb749b614e9Ted Kremenek *AST->Target, 6364f32786ac45210143654390177105eb749b614e9Ted Kremenek PP.getIdentifierTable(), 6374f32786ac45210143654390177105eb749b614e9Ted Kremenek PP.getSelectorTable(), 6384f32786ac45210143654390177105eb749b614e9Ted Kremenek PP.getBuiltinInfo(), 6394f32786ac45210143654390177105eb749b614e9Ted Kremenek /* size_reserve = */0); 6404f32786ac45210143654390177105eb749b614e9Ted Kremenek ASTContext &Context = *AST->Ctx; 6411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 642cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar Reader->InitializeContext(Context); 6431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 644c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl // Attach the AST reader to the AST context as an external AST 6450853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // source, so that declarations will be deserialized from the 6463c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl // AST file as needed. 647c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl ASTReader *ReaderPtr = Reader.get(); 648914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor llvm::OwningPtr<ExternalASTSource> Source(Reader.take()); 6498c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek 6508c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek // Unregister the cleanup for ASTReader. It will get cleaned up 6518c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek // by the ASTUnit cleanup. 6528c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek ReaderCleanup.unregister(); 6538c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek 6540853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Context.setExternalSource(Source); 6550853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 656914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor // Create an AST consumer, even though it isn't used. 657914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor AST->Consumer.reset(new ASTConsumer); 658914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor 659c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl // Create a semantic analysis object and tell the AST reader about it. 660914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor AST->TheSema.reset(new Sema(PP, Context, *AST->Consumer)); 661914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor AST->TheSema->Initialize(); 662914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor ReaderPtr->InitializeSema(*AST->TheSema); 663914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor 6641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return AST.take(); 6650853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis} 666521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 667521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarnamespace { 668521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 6699b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor/// \brief Preprocessor callback class that updates a hash value with the names 6709b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor/// of all macros that have been defined by the translation unit. 6719b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregorclass MacroDefinitionTrackerPPCallbacks : public PPCallbacks { 6729b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor unsigned &Hash; 6739b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 6749b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregorpublic: 6759b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor explicit MacroDefinitionTrackerPPCallbacks(unsigned &Hash) : Hash(Hash) { } 6769b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 6779b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) { 6789b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Hash = llvm::HashString(MacroNameTok.getIdentifierInfo()->getName(), Hash); 6799b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 6809b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor}; 6819b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 6829b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor/// \brief Add the given declaration to the hash of all top-level entities. 6839b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregorvoid AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) { 6849b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (!D) 6859b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return; 6869b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 6879b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor DeclContext *DC = D->getDeclContext(); 6889b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (!DC) 6899b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return; 6909b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 6919b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (!(DC->isTranslationUnit() || DC->getLookupParent()->isTranslationUnit())) 6929b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return; 6939b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 6949b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 6959b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (ND->getIdentifier()) 6969b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Hash = llvm::HashString(ND->getIdentifier()->getName(), Hash); 6979b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor else if (DeclarationName Name = ND->getDeclName()) { 6989b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor std::string NameStr = Name.getAsString(); 6999b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Hash = llvm::HashString(NameStr, Hash); 7009b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 7019b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return; 7029b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 7039b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 7049b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (ObjCForwardProtocolDecl *Forward 7059b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor = dyn_cast<ObjCForwardProtocolDecl>(D)) { 7069b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor for (ObjCForwardProtocolDecl::protocol_iterator 7079b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor P = Forward->protocol_begin(), 7089b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor PEnd = Forward->protocol_end(); 7099b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor P != PEnd; ++P) 7109b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor AddTopLevelDeclarationToHash(*P, Hash); 7119b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return; 7129b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 7139b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 7145f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner if (ObjCClassDecl *Class = dyn_cast<ObjCClassDecl>(D)) { 7159b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor for (ObjCClassDecl::iterator I = Class->begin(), IEnd = Class->end(); 7169b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor I != IEnd; ++I) 7179b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor AddTopLevelDeclarationToHash(I->getInterface(), Hash); 7189b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return; 7199b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 7209b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor} 7219b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 722f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerConsumer : public ASTConsumer { 723f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar ASTUnit &Unit; 7249b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor unsigned &Hash; 7259b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 726f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic: 7279b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor TopLevelDeclTrackerConsumer(ASTUnit &_Unit, unsigned &Hash) 7289b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor : Unit(_Unit), Hash(Hash) { 7299b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Hash = 0; 7309b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 7319b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 732f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar void HandleTopLevelDecl(DeclGroupRef D) { 733da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) { 734da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek Decl *D = *it; 735da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek // FIXME: Currently ObjC method declarations are incorrectly being 736da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek // reported as top-level declarations, even though their DeclContext 737da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek // is the containing ObjC @interface/@implementation. This is a 738da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek // fundamental problem in the parser right now. 739da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek if (isa<ObjCMethodDecl>(D)) 740da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek continue; 7419b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 7429b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor AddTopLevelDeclarationToHash(D, Hash); 743eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Unit.addTopLevelDecl(D); 744da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek } 745f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar } 74627372b4f1f402e95dd479ecf40c39ca71c15619fSebastian Redl 74727372b4f1f402e95dd479ecf40c39ca71c15619fSebastian Redl // We're not interested in "interesting" decls. 74827372b4f1f402e95dd479ecf40c39ca71c15619fSebastian Redl void HandleInterestingDecl(DeclGroupRef) {} 749f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar}; 750f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 751f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerAction : public ASTFrontendAction { 752f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic: 753f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar ASTUnit &Unit; 754f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 755521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 7565f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef InFile) { 7579b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CI.getPreprocessor().addPPCallbacks( 7589b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor new MacroDefinitionTrackerPPCallbacks(Unit.getCurrentTopLevelHashValue())); 7599b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor return new TopLevelDeclTrackerConsumer(Unit, 7609b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Unit.getCurrentTopLevelHashValue()); 761521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar } 762521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 763521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarpublic: 764f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {} 765f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 766521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar virtual bool hasCodeCompletionSupport() const { return false; } 767df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor virtual bool usesCompleteTranslationUnit() { 768df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor return Unit.isCompleteTranslationUnit(); 769df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 770521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar}; 771521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 77289d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregorclass PrecompilePreambleConsumer : public PCHGenerator, 77389d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor public ASTSerializationListener { 7741d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor ASTUnit &Unit; 7759b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor unsigned &Hash; 776eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor std::vector<Decl *> TopLevelDecls; 77789d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor 7781d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorpublic: 7791d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor PrecompilePreambleConsumer(ASTUnit &Unit, 7801d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor const Preprocessor &PP, bool Chaining, 7815f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef isysroot, raw_ostream *Out) 7829b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor : PCHGenerator(PP, "", Chaining, isysroot, Out), Unit(Unit), 7839b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Hash(Unit.getCurrentTopLevelHashValue()) { 7849b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor Hash = 0; 7859b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 7861d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 787eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor virtual void HandleTopLevelDecl(DeclGroupRef D) { 7881d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) { 7891d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor Decl *D = *it; 7901d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // FIXME: Currently ObjC method declarations are incorrectly being 7911d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // reported as top-level declarations, even though their DeclContext 7921d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // is the containing ObjC @interface/@implementation. This is a 7931d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // fundamental problem in the parser right now. 7941d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor if (isa<ObjCMethodDecl>(D)) 7951d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor continue; 7969b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor AddTopLevelDeclarationToHash(D, Hash); 797eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDecls.push_back(D); 798eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 799eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 800eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 801eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor virtual void HandleTranslationUnit(ASTContext &Ctx) { 802eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor PCHGenerator::HandleTranslationUnit(Ctx); 803eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (!Unit.getDiagnostics().hasErrorOccurred()) { 804eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // Translate the top-level declarations we captured during 805eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // parsing into declaration IDs in the precompiled 806eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // preamble. This will allow us to deserialize those top-level 807eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // declarations when requested. 808eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor for (unsigned I = 0, N = TopLevelDecls.size(); I != N; ++I) 809eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Unit.addTopLevelDeclFromPreamble( 810eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor getWriter().getDeclID(TopLevelDecls[I])); 8111d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor } 8121d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor } 81389d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor 81489d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor virtual void SerializedPreprocessedEntity(PreprocessedEntity *Entity, 81589d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor uint64_t Offset) { 81689d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor Unit.addPreprocessedEntityFromPreamble(Offset); 81789d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor } 81889d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor 81989d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor virtual ASTSerializationListener *GetASTSerializationListener() { 82089d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor return this; 82189d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor } 8221d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor}; 8231d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 8241d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorclass PrecompilePreambleAction : public ASTFrontendAction { 8251d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor ASTUnit &Unit; 8261d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 8271d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorpublic: 8281d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor explicit PrecompilePreambleAction(ASTUnit &Unit) : Unit(Unit) {} 8291d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 8301d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 8315f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef InFile) { 8321d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor std::string Sysroot; 8338e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis std::string OutputFile; 8345f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream *OS = 0; 8351d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor bool Chaining; 8368e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis if (GeneratePCHAction::ComputeASTConsumerArguments(CI, InFile, Sysroot, 8378e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis OutputFile, 8381d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor OS, Chaining)) 8391d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor return 0; 8401d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 841832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor if (!CI.getFrontendOpts().RelocatablePCH) 842832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor Sysroot.clear(); 843832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor 8449b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CI.getPreprocessor().addPPCallbacks( 8459b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor new MacroDefinitionTrackerPPCallbacks(Unit.getCurrentTopLevelHashValue())); 8461d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor return new PrecompilePreambleConsumer(Unit, CI.getPreprocessor(), Chaining, 847832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor Sysroot, OS); 8481d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor } 8491d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 8501d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor virtual bool hasCodeCompletionSupport() const { return false; } 8511d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor virtual bool hasASTFileSupport() const { return false; } 852df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor virtual bool usesCompleteTranslationUnit() { return false; } 8531d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor}; 8541d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 855521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar} 856521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 857abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// Parse the source file into a translation unit using the given compiler 858abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// invocation, replacing the current translation unit. 859abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// 860abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// \returns True if a failure occurred that causes the ASTUnit not to 861abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// contain any translation-unit information, false otherwise. 862754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregorbool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { 86328233428da1ebec20c893d6297ae3191318940ddDouglas Gregor delete SavedMainFileBuffer; 86428233428da1ebec20c893d6297ae3191318940ddDouglas Gregor SavedMainFileBuffer = 0; 86528233428da1ebec20c893d6297ae3191318940ddDouglas Gregor 8664f32786ac45210143654390177105eb749b614e9Ted Kremenek if (!Invocation) { 867671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete OverrideMainBuffer; 868abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 869671947b18dba342f9aba022ee992babef325a833Douglas Gregor } 870abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 871521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the compiler instance to use for building the AST. 87203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance()); 87303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 87403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek // Recover resources if we crash before exiting this method. 87525a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> 87625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek CICleanup(Clang.get()); 87703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 8784f32786ac45210143654390177105eb749b614e9Ted Kremenek Clang->setInvocation(&*Invocation); 87903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second; 880abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 8811abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set up diagnostics, capturing any diagnostics that would 8821abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // otherwise be dropped. 88303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setDiagnostics(&getDiagnostics()); 8843687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor 885521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the target instance. 88603201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTargetOpts().Features = TargetFeatures; 88703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), 8884f32786ac45210143654390177105eb749b614e9Ted Kremenek Clang->getTargetOpts())); 88903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek if (!Clang->hasTarget()) { 890671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete OverrideMainBuffer; 891abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 892671947b18dba342f9aba022ee992babef325a833Douglas Gregor } 893671947b18dba342f9aba022ee992babef325a833Douglas Gregor 894521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Inform the target of the language options. 895521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // 896521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // FIXME: We shouldn't need to do this, the target should be immutable once 897521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // created. This complexity should be lifted elsewhere. 89803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); 899abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 90003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs.size() == 1 && 901521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar "Invocation must have exactly one source file!"); 90203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs[0].first != IK_AST && 903521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar "FIXME: AST inputs not yet supported here!"); 90403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs[0].first != IK_LLVM_IR && 905faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar "IR inputs not support here!"); 906521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 907abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Configure the various subsystems. 908abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // FIXME: Should we retain the previous file manager? 90903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek FileSystemOpts = Clang->getFileSystemOpts(); 9104f32786ac45210143654390177105eb749b614e9Ted Kremenek FileMgr = new FileManager(FileSystemOpts); 9114f32786ac45210143654390177105eb749b614e9Ted Kremenek SourceMgr = new SourceManager(getDiagnostics(), *FileMgr); 912914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor TheSema.reset(); 9134f32786ac45210143654390177105eb749b614e9Ted Kremenek Ctx = 0; 9144f32786ac45210143654390177105eb749b614e9Ted Kremenek PP = 0; 915abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 916abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Clear out old caches and data. 917abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor TopLevelDecls.clear(); 91889d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor PreprocessedEntities.clear(); 919abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor CleanTemporaryFiles(); 920abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor PreprocessedEntitiesByFile.clear(); 921c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 922f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor if (!OverrideMainBuffer) { 9234cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.erase( 9244cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver, 9254cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.end()); 926f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor TopLevelDeclsInPreamble.clear(); 92789d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor PreprocessedEntitiesInPreamble.clear(); 928f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor } 929f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor 930521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create a file manager object to provide access to and cache the filesystem. 93103201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setFileManager(&getFileManager()); 932abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 933521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the source manager. 93403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setSourceManager(&getSourceManager()); 935abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 936f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // If the main file has been overridden due to the use of a preamble, 937f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // make that override happen and introduce the preamble. 93803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek PreprocessorOptions &PreprocessorOpts = Clang->getPreprocessorOpts(); 939ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth PreprocessorOpts.DetailedRecordIncludesNestedMacroExpansions 940ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth = NestedMacroExpansions; 9411abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor std::string PriorImplicitPCHInclude; 942f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (OverrideMainBuffer) { 943f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); 944f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size(); 945f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second 946f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor = PreambleEndsAtStartOfLine; 9471abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PriorImplicitPCHInclude = PreprocessorOpts.ImplicitPCHInclude; 948385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor PreprocessorOpts.ImplicitPCHInclude = PreambleFile; 949fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor PreprocessorOpts.DisablePCHValidation = true; 95028233428da1ebec20c893d6297ae3191318940ddDouglas Gregor 951c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // The stored diagnostic has the old source manager in it; update 952c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // the locations to refer into the new source manager. Since we've 953c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // been careful to make sure that the source manager's state 954c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // before and after are identical, so that we can reuse the source 955c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // location itself. 9564cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor for (unsigned I = NumStoredDiagnosticsFromDriver, 9574cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor N = StoredDiagnostics.size(); 9584cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor I < N; ++I) { 959c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor FullSourceLoc Loc(StoredDiagnostics[I].getLocation(), 960c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getSourceManager()); 961c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor StoredDiagnostics[I].setLocation(Loc); 962c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor } 9634cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 9644cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor // Keep track of the override buffer; 9654cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor SavedMainFileBuffer = OverrideMainBuffer; 966f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor } else { 967f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = 0; 968f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second = false; 969f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor } 970f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 97125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::OwningPtr<TopLevelDeclTrackerAction> Act( 97225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek new TopLevelDeclTrackerAction(*this)); 97325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek 97425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek // Recover resources if we crash before exiting this method. 97525a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction> 97625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek ActCleanup(Act.get()); 97725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek 97803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0].second, 97903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getFrontendOpts().Inputs[0].first)) 980521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar goto error; 981f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 982f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (OverrideMainBuffer) { 9839461fccd05bde8458710ba367be10b6e4efe2ec7Jonathan D. Turner std::string ModName = PreambleFile; 984f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateStoredDiagnostics(Clang->getModuleManager(), ModName, 985f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor getSourceManager(), PreambleDiagnostics, 986f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor StoredDiagnostics); 987f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 988f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 989f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar Act->Execute(); 990abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 9914f32786ac45210143654390177105eb749b614e9Ted Kremenek // Steal the created target, context, and preprocessor. 99203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek TheSema.reset(Clang->takeSema()); 99303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Consumer.reset(Clang->takeASTConsumer()); 9944f32786ac45210143654390177105eb749b614e9Ted Kremenek Ctx = &Clang->getASTContext(); 9954f32786ac45210143654390177105eb749b614e9Ted Kremenek PP = &Clang->getPreprocessor(); 9964f32786ac45210143654390177105eb749b614e9Ted Kremenek Clang->setSourceManager(0); 9974f32786ac45210143654390177105eb749b614e9Ted Kremenek Clang->setFileManager(0); 9984f32786ac45210143654390177105eb749b614e9Ted Kremenek Target = &Clang->getTarget(); 999abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1000f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar Act->EndSourceFile(); 1001f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 1002f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // Remove the overridden buffer we used for the preamble. 10031abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor if (OverrideMainBuffer) { 1004f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1005f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 10061abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PreprocessorOpts.ImplicitPCHInclude = PriorImplicitPCHInclude; 10071abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor } 10081abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 1009abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return false; 10104f32786ac45210143654390177105eb749b614e9Ted Kremenek 1011521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarerror: 1012f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // Remove the overridden buffer we used for the preamble. 1013fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor if (OverrideMainBuffer) { 1014f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1015f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 10161abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PreprocessorOpts.ImplicitPCHInclude = PriorImplicitPCHInclude; 1017671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete OverrideMainBuffer; 101837cf66350cb5a2bb68b0b7c7cca552f7a4867348Douglas Gregor SavedMainFileBuffer = 0; 1019fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor } 1020f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 1021d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor StoredDiagnostics.clear(); 1022abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 1023abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 1024abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 102544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor/// \brief Simple function to retrieve a path for a preamble precompiled header. 102644c181aec37789f25f6c15543c164416f72e562aDouglas Gregorstatic std::string GetPreamblePCHPath() { 102744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: This is lame; sys::Path should provide this function (in particular, 102844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // it should know how to find the temporary files dir). 102944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: This is really lame. I copied this code from the Driver! 1030424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor // FIXME: This is a hack so that we can override the preamble file during 1031424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor // crash-recovery testing, which is the only case where the preamble files 1032424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor // are not necessarily cleaned up. 1033424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor const char *TmpFile = ::getenv("CINDEXTEST_PREAMBLE_FILE"); 1034424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor if (TmpFile) 1035424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor return TmpFile; 1036424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor 103744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor std::string Error; 103844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor const char *TmpDir = ::getenv("TMPDIR"); 103944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!TmpDir) 104044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor TmpDir = ::getenv("TEMP"); 104144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!TmpDir) 104244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor TmpDir = ::getenv("TMP"); 1043c6cb2b02f0f4b3f162985803df3729b4def32108Douglas Gregor#ifdef LLVM_ON_WIN32 1044c6cb2b02f0f4b3f162985803df3729b4def32108Douglas Gregor if (!TmpDir) 1045c6cb2b02f0f4b3f162985803df3729b4def32108Douglas Gregor TmpDir = ::getenv("USERPROFILE"); 1046c6cb2b02f0f4b3f162985803df3729b4def32108Douglas Gregor#endif 104744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!TmpDir) 104844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor TmpDir = "/tmp"; 104944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor llvm::sys::Path P(TmpDir); 1050c6cb2b02f0f4b3f162985803df3729b4def32108Douglas Gregor P.createDirectoryOnDisk(true); 105144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor P.appendComponent("preamble"); 10526bf1830875673d6bd6c5bfcd65c9dcabfb45958bDouglas Gregor P.appendSuffix("pch"); 1053bc9d5a3ace7cb75e4bff3dd4a3999a3fc04f4d45Argyrios Kyrtzidis if (P.makeUnique(/*reuse_current=*/false, /*ErrMsg*/0)) 105444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor return std::string(); 105544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 105644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor return P.str(); 105744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor} 105844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 1059f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// \brief Compute the preamble for the main file, providing the source buffer 1060f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// that corresponds to the main file along with a pair (bytes, start-of-line) 1061f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// that describes the preamble. 1062f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregorstd::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > 1063df95a13ec73d2cdaea79555cb412d767f4963120Douglas GregorASTUnit::ComputePreamble(CompilerInvocation &Invocation, 1064df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor unsigned MaxLines, bool &CreatedBuffer) { 1065175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor FrontendOptions &FrontendOpts = Invocation.getFrontendOpts(); 106639b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner PreprocessorOptions &PreprocessorOpts = Invocation.getPreprocessorOpts(); 1067175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = false; 1068175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 106944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Try to determine if the main file has been remapped, either from the 107044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // command line (to another file) or directly through the compiler invocation 107144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // (to a memory buffer). 1072175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::MemoryBuffer *Buffer = 0; 107344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].second); 107444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (const llvm::sys::FileStatus *MainFileStatus = MainFilePath.getFileStatus()) { 107544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Check whether there is a file-file remapping of the main file 107644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor for (PreprocessorOptions::remapped_file_iterator 1077175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor M = PreprocessorOpts.remapped_file_begin(), 1078175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor E = PreprocessorOpts.remapped_file_end(); 107944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor M != E; 108044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor ++M) { 108144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor llvm::sys::PathWithStatus MPath(M->first); 108244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (const llvm::sys::FileStatus *MStatus = MPath.getFileStatus()) { 108344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (MainFileStatus->uniqueID == MStatus->uniqueID) { 108444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // We found a remapping. Try to load the resulting, remapped source. 1085175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (CreatedBuffer) { 108644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor delete Buffer; 1087175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = false; 1088175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 1089175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1090389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis Buffer = getBufferForFile(M->second); 109144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Buffer) 1092f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor return std::make_pair((llvm::MemoryBuffer*)0, 1093f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor std::make_pair(0, true)); 1094175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = true; 109544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 109644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 109744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 109844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 109944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Check whether there is a file-buffer remapping. It supercedes the 110044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // file-file remapping. 110144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 110244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor M = PreprocessorOpts.remapped_file_buffer_begin(), 110344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor E = PreprocessorOpts.remapped_file_buffer_end(); 110444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor M != E; 110544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor ++M) { 110644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor llvm::sys::PathWithStatus MPath(M->first); 110744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (const llvm::sys::FileStatus *MStatus = MPath.getFileStatus()) { 110844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (MainFileStatus->uniqueID == MStatus->uniqueID) { 110944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // We found a remapping. 1110175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (CreatedBuffer) { 111144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor delete Buffer; 1112175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = false; 1113175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 111444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 1115175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Buffer = const_cast<llvm::MemoryBuffer *>(M->second); 111644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 111744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 1118175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 111944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 112044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 112144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // If the main source file was not remapped, load it now. 112244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Buffer) { 1123389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis Buffer = getBufferForFile(FrontendOpts.Inputs[0].second); 112444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Buffer) 1125f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor return std::make_pair((llvm::MemoryBuffer*)0, std::make_pair(0, true)); 1126175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1127175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = true; 1128175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 1129175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1130df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor return std::make_pair(Buffer, Lexer::ComputePreamble(Buffer, MaxLines)); 1131175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor} 1132175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1133754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregorstatic llvm::MemoryBuffer *CreatePaddedMainFileBuffer(llvm::MemoryBuffer *Old, 1134754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor unsigned NewSize, 11355f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef NewName) { 1136754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor llvm::MemoryBuffer *Result 1137754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor = llvm::MemoryBuffer::getNewUninitMemBuffer(NewSize, NewName); 1138754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor memcpy(const_cast<char*>(Result->getBufferStart()), 1139754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor Old->getBufferStart(), Old->getBufferSize()); 1140754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor memset(const_cast<char*>(Result->getBufferStart()) + Old->getBufferSize(), 1141f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor ' ', NewSize - Old->getBufferSize() - 1); 1142f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor const_cast<char*>(Result->getBufferEnd())[-1] = '\n'; 1143754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor 1144754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return Result; 1145754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor} 1146754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor 1147175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// \brief Attempt to build or re-use a precompiled preamble when (re-)parsing 1148175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// the source file. 1149175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// 1150175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// This routine will compute the preamble of the main source file. If a 1151175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// non-trivial preamble is found, it will precompile that preamble into a 1152175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// precompiled header so that the precompiled preamble can be used to reduce 1153175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// reparsing time. If a precompiled preamble has already been constructed, 1154175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// this routine will determine if it is still valid and, if so, avoid 1155175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// rebuilding the precompiled preamble. 1156175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// 1157df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// \param AllowRebuild When true (the default), this routine is 1158df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// allowed to rebuild the precompiled preamble if it is found to be 1159df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// out-of-date. 1160df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// 1161df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// \param MaxLines When non-zero, the maximum number of lines that 1162df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// can occur within the preamble. 1163df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// 1164754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// \returns If the precompiled preamble can be used, returns a newly-allocated 1165754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// buffer that should be used in place of the main file when doing so. 1166754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// Otherwise, returns a NULL pointer. 1167df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregorllvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( 116801b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor const CompilerInvocation &PreambleInvocationIn, 1169df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool AllowRebuild, 1170df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor unsigned MaxLines) { 117101b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor 117201b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor llvm::IntrusiveRefCntPtr<CompilerInvocation> 117301b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor PreambleInvocation(new CompilerInvocation(PreambleInvocationIn)); 117401b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor FrontendOptions &FrontendOpts = PreambleInvocation->getFrontendOpts(); 1175175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreprocessorOptions &PreprocessorOpts 117601b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor = PreambleInvocation->getPreprocessorOpts(); 1177175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1178175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor bool CreatedPreambleBuffer = false; 1179f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > NewPreamble 118001b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor = ComputePreamble(*PreambleInvocation, MaxLines, CreatedPreambleBuffer); 1181175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1182f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // If ComputePreamble() Take ownership of the preamble buffer. 118373fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor llvm::OwningPtr<llvm::MemoryBuffer> OwnedPreambleBuffer; 118473fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor if (CreatedPreambleBuffer) 118573fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor OwnedPreambleBuffer.reset(NewPreamble.first); 118673fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor 1187f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (!NewPreamble.second.first) { 1188175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We couldn't find a preamble in the main source. Clear out the current 1189175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // preamble, if we have one. It's obviously no good any more. 1190175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1191175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (!PreambleFile.empty()) { 1192385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor llvm::sys::Path(PreambleFile).eraseFromDisk(); 1193175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleFile.clear(); 1194175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 1195eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 1196eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // The next time we actually see a preamble, precompile it. 1197eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = 1; 1198754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 119944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 120044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 1201175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (!Preamble.empty()) { 1202175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We've previously computed a preamble. Check whether we have the same 1203175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // preamble now that we did before, and that there's enough space in 1204175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // the main-file buffer within the precompiled preamble to fit the 1205175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // new main file. 1206f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (Preamble.size() == NewPreamble.second.first && 1207f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreambleEndsAtStartOfLine == NewPreamble.second.second && 1208592508ed997e52207cf380f9b6eb9943994ad7aeDouglas Gregor NewPreamble.first->getBufferSize() < PreambleReservedSize-2 && 1209175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor memcmp(&Preamble[0], NewPreamble.first->getBufferStart(), 1210f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor NewPreamble.second.first) == 0) { 1211175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // The preamble has not changed. We may be able to re-use the precompiled 1212175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // preamble. 1213c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 1214cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Check that none of the files used by the preamble have changed. 1215cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor bool AnyFileChanged = false; 1216cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1217cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // First, make a record of those files that have been overridden via 1218cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // remapping or unsaved_files. 1219cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor llvm::StringMap<std::pair<off_t, time_t> > OverriddenFiles; 1220cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (PreprocessorOptions::remapped_file_iterator 1221cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor R = PreprocessorOpts.remapped_file_begin(), 1222cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor REnd = PreprocessorOpts.remapped_file_end(); 1223cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor !AnyFileChanged && R != REnd; 1224cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++R) { 1225cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor struct stat StatBuf; 1226340415c0c7a7fdeb688fe5a0993bdd142cc9f59cAnders Carlsson if (FileMgr->getNoncachedStatValue(R->second, StatBuf)) { 1227cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // If we can't stat the file we're remapping to, assume that something 1228cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // horrible happened. 1229cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 1230cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor break; 1231cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1232754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor 1233cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor OverriddenFiles[R->first] = std::make_pair(StatBuf.st_size, 1234cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor StatBuf.st_mtime); 1235cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1236cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 1237cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor R = PreprocessorOpts.remapped_file_buffer_begin(), 1238cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor REnd = PreprocessorOpts.remapped_file_buffer_end(); 1239cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor !AnyFileChanged && R != REnd; 1240cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++R) { 1241cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // FIXME: Should we actually compare the contents of file->buffer 1242cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // remappings? 1243cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor OverriddenFiles[R->first] = std::make_pair(R->second->getBufferSize(), 1244cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 0); 1245cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1246cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1247cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Check whether anything has changed. 1248cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (llvm::StringMap<std::pair<off_t, time_t> >::iterator 1249cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor F = FilesInPreamble.begin(), FEnd = FilesInPreamble.end(); 1250cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor !AnyFileChanged && F != FEnd; 1251cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++F) { 1252cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor llvm::StringMap<std::pair<off_t, time_t> >::iterator Overridden 1253cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor = OverriddenFiles.find(F->first()); 1254cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (Overridden != OverriddenFiles.end()) { 1255cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // This file was remapped; check whether the newly-mapped file 1256cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // matches up with the previous mapping. 1257cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (Overridden->second != F->second) 1258cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 1259cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor continue; 1260cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1261cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1262cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // The file was not remapped; check whether it has changed on disk. 1263cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor struct stat StatBuf; 1264340415c0c7a7fdeb688fe5a0993bdd142cc9f59cAnders Carlsson if (FileMgr->getNoncachedStatValue(F->first(), StatBuf)) { 1265cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // If we can't stat the file, assume that something horrible happened. 1266cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 1267cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } else if (StatBuf.st_size != F->second.first || 1268cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor StatBuf.st_mtime != F->second.second) 1269cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 1270cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1271cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1272cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (!AnyFileChanged) { 1273c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Okay! We can re-use the precompiled preamble. 1274c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 1275c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Set the state of the diagnostic object to mimic its state 1276c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // after parsing the preamble. 127732be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor // FIXME: This won't catch any #pragma push warning changes that 127832be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor // have occurred in the preamble. 1279c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getDiagnostics().Reset(); 128032be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor ProcessWarningOptions(getDiagnostics(), 128101b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor PreambleInvocation->getDiagnosticOpts()); 1282c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getDiagnostics().setNumWarnings(NumWarningsInPreamble); 1283c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 1284c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Create a version of the main file buffer that is padded to 1285c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // buffer size we reserved when creating the preamble. 1286cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor return CreatePaddedMainFileBuffer(NewPreamble.first, 1287cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor PreambleReservedSize, 1288cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FrontendOpts.Inputs[0].second); 1289cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1290175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 1291df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 1292df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // If we aren't allowed to rebuild the precompiled preamble, just 1293df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // return now. 1294df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (!AllowRebuild) 1295df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor return 0; 1296aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor 1297175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We can't reuse the previously-computed preamble. Build a new one. 1298175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1299f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor PreambleDiagnostics.clear(); 1300385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor llvm::sys::Path(PreambleFile).eraseFromDisk(); 1301eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = 1; 1302df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } else if (!AllowRebuild) { 1303df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // We aren't allowed to rebuild the precompiled preamble; just 1304df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // return now. 1305df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor return 0; 1306df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 1307eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 1308eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // If the preamble rebuild counter > 1, it's because we previously 1309eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // failed to build a preamble and we're not yet ready to try 1310eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // again. Decrement the counter and return a failure. 1311eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor if (PreambleRebuildCounter > 1) { 1312eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor --PreambleRebuildCounter; 1313eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor return 0; 1314eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor } 1315eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 13162cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor // Create a temporary file for the precompiled preamble. In rare 13172cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor // circumstances, this can fail. 13182cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor std::string PreamblePCHPath = GetPreamblePCHPath(); 13192cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor if (PreamblePCHPath.empty()) { 13202cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor // Try again next time. 13212cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor PreambleRebuildCounter = 1; 13222cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor return 0; 13232cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor } 13242cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor 1325175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We did not previously compute a preamble, or it can't be reused anyway. 1326213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer PreambleTimer(WantTiming); 1327edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer PreambleTimer.setOutput("Precompiling preamble"); 132844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 132944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create a new buffer that stores the preamble. The buffer also contains 133044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // extra space for the original contents of the file (which will be present 133144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // when we actually parse the file) along with more room in case the file 1332175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // grows. 1333175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleReservedSize = NewPreamble.first->getBufferSize(); 1334175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (PreambleReservedSize < 4096) 1335f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreambleReservedSize = 8191; 133644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor else 1337175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleReservedSize *= 2; 1338175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1339c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Save the preamble text for later; we'll need to compare against it for 1340c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // subsequent reparses. 1341c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor Preamble.assign(NewPreamble.first->getBufferStart(), 1342c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor NewPreamble.first->getBufferStart() 1343c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor + NewPreamble.second.first); 1344c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor PreambleEndsAtStartOfLine = NewPreamble.second.second; 1345c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 1346671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete PreambleBuffer; 1347671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreambleBuffer 1348175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor = llvm::MemoryBuffer::getNewUninitMemBuffer(PreambleReservedSize, 134944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor FrontendOpts.Inputs[0].second); 135044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor memcpy(const_cast<char*>(PreambleBuffer->getBufferStart()), 1351175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor NewPreamble.first->getBufferStart(), Preamble.size()); 1352175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor memset(const_cast<char*>(PreambleBuffer->getBufferStart()) + Preamble.size(), 1353f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor ' ', PreambleReservedSize - Preamble.size() - 1); 1354f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor const_cast<char*>(PreambleBuffer->getBufferEnd())[-1] = '\n'; 135544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 135644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Remap the main source file to the preamble buffer. 1357175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].second); 135844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor PreprocessorOpts.addRemappedFile(MainFilePath.str(), PreambleBuffer); 135944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 136044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Tell the compiler invocation to generate a temporary precompiled header. 136144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor FrontendOpts.ProgramAction = frontend::GeneratePCH; 136285e5191934143edfa9fed582149d8f85c99c753fDouglas Gregor FrontendOpts.ChainedPCH = true; 136344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: Generate the precompiled header into memory? 13642cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor FrontendOpts.OutputFile = PreamblePCHPath; 1365aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = 0; 1366aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second = false; 136744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 136844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create the compiler instance to use for building the precompiled preamble. 136903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance()); 137003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 137103201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek // Recover resources if we crash before exiting this method. 137225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> 137325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek CICleanup(Clang.get()); 137403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 137501b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor Clang->setInvocation(&*PreambleInvocation); 137603201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second; 137744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 13781abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set up diagnostics, capturing all of the diagnostics produced. 137903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setDiagnostics(&getDiagnostics()); 138044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 138144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create the target instance. 138203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTargetOpts().Features = TargetFeatures; 138303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), 138403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTargetOpts())); 138503201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek if (!Clang->hasTarget()) { 1386175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 1387175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1388eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = DefaultPreambleRebuildInterval; 1389671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1390671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 1391754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 139244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 139344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 139444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Inform the target of the language options. 139544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // 139644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: We shouldn't need to do this, the target should be immutable once 139744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // created. This complexity should be lifted elsewhere. 139803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); 139944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 140003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs.size() == 1 && 140144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor "Invocation must have exactly one source file!"); 140203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs[0].first != IK_AST && 140344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor "FIXME: AST inputs not yet supported here!"); 140403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs[0].first != IK_LLVM_IR && 140544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor "IR inputs not support here!"); 140644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 140744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Clear out old caches and data. 1408aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor getDiagnostics().Reset(); 140903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek ProcessWarningOptions(getDiagnostics(), Clang->getDiagnosticOpts()); 14104cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.erase( 14114cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver, 14124cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.end()); 1413eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDecls.clear(); 1414eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDeclsInPreamble.clear(); 141589d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor PreprocessedEntities.clear(); 141689d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor PreprocessedEntitiesInPreamble.clear(); 141744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 141844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create a file manager object to provide access to and cache the filesystem. 141903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setFileManager(new FileManager(Clang->getFileSystemOpts())); 142044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 142144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create the source manager. 142203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setSourceManager(new SourceManager(getDiagnostics(), 14234f32786ac45210143654390177105eb749b614e9Ted Kremenek Clang->getFileManager())); 142444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 14251d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor llvm::OwningPtr<PrecompilePreambleAction> Act; 14261d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor Act.reset(new PrecompilePreambleAction(*this)); 142703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0].second, 142803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getFrontendOpts().Inputs[0].first)) { 1429175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 1430175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1431eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = DefaultPreambleRebuildInterval; 1432671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1433671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 1434754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 143544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 143644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 143744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Act->Execute(); 143844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Act->EndSourceFile(); 14394f32786ac45210143654390177105eb749b614e9Ted Kremenek 1440eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (Diagnostics->hasErrorOccurred()) { 1441175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // There were errors parsing the preamble, so no precompiled header was 1442175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // generated. Forget that we even tried. 144306e504462014b0506a70c7730ea45c551a103364Douglas Gregor // FIXME: Should we leave a note for ourselves to try again? 1444175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 1445175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1446eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDeclsInPreamble.clear(); 144789d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor PreprocessedEntities.clear(); 144889d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor PreprocessedEntitiesInPreamble.clear(); 1449eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = DefaultPreambleRebuildInterval; 1450671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1451671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 1452754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 1453175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 1454175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1455f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Transfer any diagnostics generated when parsing the preamble into the set 1456f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // of preamble diagnostics. 1457f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor PreambleDiagnostics.clear(); 1458f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor PreambleDiagnostics.insert(PreambleDiagnostics.end(), 1459f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver, 1460f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor StoredDiagnostics.end()); 1461f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor StoredDiagnostics.erase( 1462f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver, 1463f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor StoredDiagnostics.end()); 1464f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 1465175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // Keep track of the preamble we precompiled. 1466175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleFile = FrontendOpts.OutputFile; 1467c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor NumWarningsInPreamble = getDiagnostics().getNumWarnings(); 1468cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1469cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Keep track of all of the files that the source manager knows about, 1470cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // so we can verify whether they have changed or not. 1471cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FilesInPreamble.clear(); 147203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek SourceManager &SourceMgr = Clang->getSourceManager(); 1473cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor const llvm::MemoryBuffer *MainFileBuffer 1474cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor = SourceMgr.getBuffer(SourceMgr.getMainFileID()); 1475cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (SourceManager::fileinfo_iterator F = SourceMgr.fileinfo_begin(), 1476cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FEnd = SourceMgr.fileinfo_end(); 1477cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor F != FEnd; 1478cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++F) { 1479b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *File = F->second->OrigEntry; 1480cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (!File || F->second->getRawBuffer() == MainFileBuffer) 1481cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor continue; 1482cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1483cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FilesInPreamble[File->getName()] 1484cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor = std::make_pair(F->second->getSize(), File->getModificationTime()); 1485cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1486cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1487eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = 1; 1488671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1489671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 14909b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 14919b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor // If the hash of top-level entities differs from the hash of the top-level 14929b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor // entities the last time we rebuilt the preamble, clear out the completion 14939b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor // cache. 14949b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (CurrentTopLevelHashValue != PreambleTopLevelHashValue) { 14959b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CompletionCacheTopLevelHashValue = 0; 14969b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor PreambleTopLevelHashValue = CurrentTopLevelHashValue; 14979b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 14989b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 1499754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return CreatePaddedMainFileBuffer(NewPreamble.first, 1500754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor PreambleReservedSize, 1501754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor FrontendOpts.Inputs[0].second); 150244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor} 1503abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1504eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregorvoid ASTUnit::RealizeTopLevelDeclsFromPreamble() { 1505eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor std::vector<Decl *> Resolved; 1506eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Resolved.reserve(TopLevelDeclsInPreamble.size()); 1507eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor ExternalASTSource &Source = *getASTContext().getExternalSource(); 1508eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor for (unsigned I = 0, N = TopLevelDeclsInPreamble.size(); I != N; ++I) { 1509eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // Resolve the declaration ID to an actual declaration, possibly 1510eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // deserializing the declaration in the process. 1511eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Decl *D = Source.GetExternalDecl(TopLevelDeclsInPreamble[I]); 1512eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (D) 1513eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Resolved.push_back(D); 1514eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 1515eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDeclsInPreamble.clear(); 1516eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end()); 1517eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor} 1518eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 151989d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregorvoid ASTUnit::RealizePreprocessedEntitiesFromPreamble() { 152089d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor if (!PP) 152189d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor return; 152289d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor 152389d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor PreprocessingRecord *PPRec = PP->getPreprocessingRecord(); 152489d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor if (!PPRec) 152589d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor return; 152689d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor 152789d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor ExternalPreprocessingRecordSource *External = PPRec->getExternalSource(); 152889d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor if (!External) 152989d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor return; 153089d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor 153189d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor for (unsigned I = 0, N = PreprocessedEntitiesInPreamble.size(); I != N; ++I) { 153289d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor if (PreprocessedEntity *PE 15330a480293f726508ad9aed0be39e8c9779e84f2f2Douglas Gregor = External->ReadPreprocessedEntityAtOffset( 15340a480293f726508ad9aed0be39e8c9779e84f2f2Douglas Gregor PreprocessedEntitiesInPreamble[I])) 153589d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor PreprocessedEntities.push_back(PE); 153689d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor } 153789d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor 153889d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor if (PreprocessedEntities.empty()) 153989d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor return; 154089d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor 154189d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor PreprocessedEntities.insert(PreprocessedEntities.end(), 154289d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor PPRec->begin(true), PPRec->end(true)); 154389d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor} 154489d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor 154589d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas GregorASTUnit::pp_entity_iterator ASTUnit::pp_entity_begin() { 154689d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor if (!PreprocessedEntitiesInPreamble.empty() && 154789d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor PreprocessedEntities.empty()) 154889d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor RealizePreprocessedEntitiesFromPreamble(); 154989d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor 155089d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor return PreprocessedEntities.begin(); 155189d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor} 155289d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor 155389d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas GregorASTUnit::pp_entity_iterator ASTUnit::pp_entity_end() { 155489d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor if (!PreprocessedEntitiesInPreamble.empty() && 155589d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor PreprocessedEntities.empty()) 155689d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor RealizePreprocessedEntitiesFromPreamble(); 15574c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor 155889d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor return PreprocessedEntities.end(); 155989d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor} 156089d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor 1561eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregorunsigned ASTUnit::getMaxPCHLevel() const { 1562eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (!getOnlyLocalDecls()) 1563eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor return Decl::MaxPCHLevel; 1564eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 15651d9f1fe7173e3084325f43c78af812a36d8a2a7cSebastian Redl return 0; 1566eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor} 1567eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 15685f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerStringRef ASTUnit::getMainFileName() const { 1569213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor return Invocation->getFrontendOpts().Inputs[0].second; 1570213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor} 1571213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 1572b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios KyrtzidisASTUnit *ASTUnit::create(CompilerInvocation *CI, 1573b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis llvm::IntrusiveRefCntPtr<Diagnostic> Diags) { 1574b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis llvm::OwningPtr<ASTUnit> AST; 1575b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis AST.reset(new ASTUnit(false)); 1576b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis ConfigureDiags(Diags, 0, 0, *AST, /*CaptureDiagnostics=*/false); 1577b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis AST->Diagnostics = Diags; 15784f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->Invocation = CI; 15790d8d7e6067f9093e7d5abc45c9639ab977aab692Anders Carlsson AST->FileSystemOpts = CI->getFileSystemOpts(); 15804f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->FileMgr = new FileManager(AST->FileSystemOpts); 15814f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->SourceMgr = new SourceManager(*Diags, *AST->FileMgr); 1582b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 1583b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis return AST.take(); 1584b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis} 1585b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 1586d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios KyrtzidisASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI, 1587d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis llvm::IntrusiveRefCntPtr<Diagnostic> Diags, 1588d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis ASTFrontendAction *Action) { 1589d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis assert(CI && "A CompilerInvocation is required"); 1590d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1591d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Create the AST unit. 1592d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis llvm::OwningPtr<ASTUnit> AST; 1593d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST.reset(new ASTUnit(false)); 1594d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis ConfigureDiags(Diags, 0, 0, *AST, /*CaptureDiagnostics*/false); 1595d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->Diagnostics = Diags; 1596d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->OnlyLocalDecls = false; 1597d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->CaptureDiagnostics = false; 1598d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->CompleteTranslationUnit = Action ? Action->usesCompleteTranslationUnit() 1599d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis : true; 1600d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->ShouldCacheCodeCompletionResults = false; 1601d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->Invocation = CI; 1602d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1603d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Recover resources if we crash before exiting this method. 1604d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> 1605d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis ASTUnitCleanup(AST.get()); 1606d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic, 1607d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> > 1608d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis DiagCleanup(Diags.getPtr()); 1609d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1610d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // We'll manage file buffers ourselves. 1611d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis CI->getPreprocessorOpts().RetainRemappedFileBuffers = true; 1612d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis CI->getFrontendOpts().DisableFree = false; 1613d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts()); 1614d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1615d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Save the target features. 1616d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->TargetFeatures = CI->getTargetOpts().Features; 1617d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1618d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Create the compiler instance to use for building the AST. 1619d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance()); 1620d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1621d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Recover resources if we crash before exiting this method. 1622d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> 1623d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis CICleanup(Clang.get()); 1624d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1625d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setInvocation(CI); 1626d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second; 1627d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1628d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Set up diagnostics, capturing any diagnostics that would 1629d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // otherwise be dropped. 1630d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setDiagnostics(&AST->getDiagnostics()); 1631d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1632d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Create the target instance. 1633d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->getTargetOpts().Features = AST->TargetFeatures; 1634d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), 1635d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->getTargetOpts())); 1636d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis if (!Clang->hasTarget()) 1637d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis return 0; 1638d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1639d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Inform the target of the language options. 1640d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // 1641d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // FIXME: We shouldn't need to do this, the target should be immutable once 1642d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // created. This complexity should be lifted elsewhere. 1643d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); 1644d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1645d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis assert(Clang->getFrontendOpts().Inputs.size() == 1 && 1646d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis "Invocation must have exactly one source file!"); 1647d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis assert(Clang->getFrontendOpts().Inputs[0].first != IK_AST && 1648d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis "FIXME: AST inputs not yet supported here!"); 1649d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis assert(Clang->getFrontendOpts().Inputs[0].first != IK_LLVM_IR && 1650d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis "IR inputs not supported here!"); 1651d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1652d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Configure the various subsystems. 1653d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->FileSystemOpts = Clang->getFileSystemOpts(); 1654d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->FileMgr = new FileManager(AST->FileSystemOpts); 1655d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr); 1656d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->TheSema.reset(); 1657d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->Ctx = 0; 1658d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->PP = 0; 1659d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1660d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Create a file manager object to provide access to and cache the filesystem. 1661d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setFileManager(&AST->getFileManager()); 1662d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1663d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Create the source manager. 1664d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setSourceManager(&AST->getSourceManager()); 1665d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1666d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis ASTFrontendAction *Act = Action; 1667d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1668d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis llvm::OwningPtr<TopLevelDeclTrackerAction> TrackerAct; 1669d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis if (!Act) { 1670d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis TrackerAct.reset(new TopLevelDeclTrackerAction(*AST)); 1671d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Act = TrackerAct.get(); 1672d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis } 1673d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1674d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Recover resources if we crash before exiting this method. 1675d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction> 1676d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis ActCleanup(TrackerAct.get()); 1677d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1678d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis if (!Act->BeginSourceFile(*Clang.get(), 1679d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->getFrontendOpts().Inputs[0].second, 1680d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->getFrontendOpts().Inputs[0].first)) 1681d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis return 0; 1682d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1683d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Act->Execute(); 1684d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1685d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis // Steal the created target, context, and preprocessor. 1686d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->TheSema.reset(Clang->takeSema()); 1687d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->Consumer.reset(Clang->takeASTConsumer()); 1688d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->Ctx = &Clang->getASTContext(); 1689d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->PP = &Clang->getPreprocessor(); 1690d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setSourceManager(0); 1691d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Clang->setFileManager(0); 1692d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis AST->Target = &Clang->getTarget(); 1693d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1694d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis Act->EndSourceFile(); 1695d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 1696d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis return AST.take(); 1697d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis} 1698d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis 16994cd912aa94656697a44c3ebb159f05060300524eDouglas Gregorbool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) { 17004cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor if (!Invocation) 17014cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor return true; 17024cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 17034cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor // We'll manage file buffers ourselves. 17044cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor Invocation->getPreprocessorOpts().RetainRemappedFileBuffers = true; 17054cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor Invocation->getFrontendOpts().DisableFree = false; 17060b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts()); 17074cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 17081aa27307c462baaa9e5fda14ff6797dd39fe8b84Douglas Gregor // Save the target features. 17091aa27307c462baaa9e5fda14ff6797dd39fe8b84Douglas Gregor TargetFeatures = Invocation->getTargetOpts().Features; 17101aa27307c462baaa9e5fda14ff6797dd39fe8b84Douglas Gregor 17114cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor llvm::MemoryBuffer *OverrideMainBuffer = 0; 171299ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor if (PrecompilePreamble) { 171308bb4c622d0b79c33b4ac78ce1bec79398953daaDouglas Gregor PreambleRebuildCounter = 2; 17144cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor OverrideMainBuffer 17154cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor = getMainBufferWithPrecompiledPreamble(*Invocation); 17164cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor } 17174cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 1718213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer ParsingTimer(WantTiming); 1719edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer ParsingTimer.setOutput("Parsing " + getMainFileName()); 17204cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 172125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek // Recover resources if we crash before exiting this method. 172225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer> 172325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek MemBufferCleanup(OverrideMainBuffer); 172425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek 1725213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor return Parse(OverrideMainBuffer); 17264cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor} 17274cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 1728abc563f554951259bbe0315055cad92ee14d87e4Douglas GregorASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, 1729abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor llvm::IntrusiveRefCntPtr<Diagnostic> Diags, 1730abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor bool OnlyLocalDecls, 173144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor bool CaptureDiagnostics, 1732df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool PrecompilePreamble, 173387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor bool CompleteTranslationUnit, 1734dca8ee8b7bc86076916a3a80f553f7a4e98c14afDouglas Gregor bool CacheCodeCompletionResults, 1735ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth bool NestedMacroExpansions) { 1736abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Create the AST unit. 1737abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor llvm::OwningPtr<ASTUnit> AST; 1738abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST.reset(new ASTUnit(false)); 17390b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics); 1740abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST->Diagnostics = Diags; 1741abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST->OnlyLocalDecls = OnlyLocalDecls; 1742e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor AST->CaptureDiagnostics = CaptureDiagnostics; 1743df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor AST->CompleteTranslationUnit = CompleteTranslationUnit; 174487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults; 17454f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->Invocation = CI; 1746ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth AST->NestedMacroExpansions = NestedMacroExpansions; 1747385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor 1748b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek // Recover resources if we crash before exiting this method. 174925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> 175025a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek ASTUnitCleanup(AST.get()); 175125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic, 175225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> > 175325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek DiagCleanup(Diags.getPtr()); 1754b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek 17554cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor return AST->LoadFromCompilerInvocation(PrecompilePreamble)? 0 : AST.take(); 1756521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar} 17577b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 17587b55668db7618334cc40011d3c1e128524d89462Daniel DunbarASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, 17597b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar const char **ArgEnd, 176028019772db70d4547be05a042eb950bc910f134fDouglas Gregor llvm::IntrusiveRefCntPtr<Diagnostic> Diags, 17615f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef ResourceFilesPath, 17627b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar bool OnlyLocalDecls, 1763e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor bool CaptureDiagnostics, 17644db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFile *RemappedFiles, 1765a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor unsigned NumRemappedFiles, 1766299a4a967b02c9f0d0d94ad8560e3ced893f9116Argyrios Kyrtzidis bool RemappedFilesKeepOriginalName, 1767df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool PrecompilePreamble, 176887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor bool CompleteTranslationUnit, 176999ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor bool CacheCodeCompletionResults, 177099ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor bool CXXPrecompilePreamble, 1771dca8ee8b7bc86076916a3a80f553f7a4e98c14afDouglas Gregor bool CXXChainedPCH, 1772ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth bool NestedMacroExpansions) { 177328019772db70d4547be05a042eb950bc910f134fDouglas Gregor if (!Diags.getPtr()) { 17743687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor // No diagnostics engine was provided, so create our own diagnostics object 17753687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor // with the default options. 17763687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor DiagnosticOptions DiagOpts; 17770b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor Diags = CompilerInstance::createDiagnostics(DiagOpts, ArgEnd - ArgBegin, 17780b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor ArgBegin); 17793687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor } 17807b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 17815f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<StoredDiagnostic, 4> StoredDiagnostics; 17824cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 17834f32786ac45210143654390177105eb749b614e9Ted Kremenek llvm::IntrusiveRefCntPtr<CompilerInvocation> CI; 1784e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor 17854cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor { 1786f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 1787e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags, 17884cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics); 17894cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 1790832316e9a04242972f4b57281dccb8e4cf5894eaArgyrios Kyrtzidis CI = clang::createInvocationFromCommandLine( 1791e9c0265d6e6b5bf865f4a0c2c00d00ac251e6437Frits van Bommel llvm::makeArrayRef(ArgBegin, ArgEnd), 1792e9c0265d6e6b5bf865f4a0c2c00d00ac251e6437Frits van Bommel Diags); 1793054e4f50e2f1995e91b0cd3c3258aa252785fe3fArgyrios Kyrtzidis if (!CI) 17944e03c2b9d735063a60cd0623423f4814178857efArgyrios Kyrtzidis return 0; 17957b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar } 1796e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor 17974db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor // Override any files that need remapping 1798b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis for (unsigned I = 0; I != NumRemappedFiles; ++I) { 1799b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; 1800b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (const llvm::MemoryBuffer * 1801b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { 1802b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, memBuf); 1803b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } else { 1804b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const char *fname = fileOrBuf.get<const char *>(); 1805b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, fname); 1806b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 1807b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 1808299a4a967b02c9f0d0d94ad8560e3ced893f9116Argyrios Kyrtzidis CI->getPreprocessorOpts().RemappedFilesKeepOriginalName = 1809299a4a967b02c9f0d0d94ad8560e3ced893f9116Argyrios Kyrtzidis RemappedFilesKeepOriginalName; 18104db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 18118b9adfea5e834eaee0f45d8cc7fb052d68df4a46Daniel Dunbar // Override the resources path. 1812807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath; 18137b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 181499ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor // Check whether we should precompile the preamble and/or use chained PCH. 181599ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor // FIXME: This is a temporary hack while we debug C++ chained PCH. 181699ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor if (CI->getLangOpts().CPlusPlus) { 181799ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor PrecompilePreamble = PrecompilePreamble && CXXPrecompilePreamble; 181899ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor 181999ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor if (PrecompilePreamble && !CXXChainedPCH && 182099ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor !CI->getPreprocessorOpts().ImplicitPCHInclude.empty()) 182199ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor PrecompilePreamble = false; 182299ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor } 182399ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor 18244cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor // Create the AST unit. 18254cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor llvm::OwningPtr<ASTUnit> AST; 18264cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST.reset(new ASTUnit(false)); 18270b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor ConfigureDiags(Diags, ArgBegin, ArgEnd, *AST, CaptureDiagnostics); 18284cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->Diagnostics = Diags; 18290d8d7e6067f9093e7d5abc45c9639ab977aab692Anders Carlsson 18300d8d7e6067f9093e7d5abc45c9639ab977aab692Anders Carlsson AST->FileSystemOpts = CI->getFileSystemOpts(); 18314f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->FileMgr = new FileManager(AST->FileSystemOpts); 18324cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->OnlyLocalDecls = OnlyLocalDecls; 1833e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor AST->CaptureDiagnostics = CaptureDiagnostics; 18344cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->CompleteTranslationUnit = CompleteTranslationUnit; 18354cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults; 18364cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size(); 18374cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->StoredDiagnostics.swap(StoredDiagnostics); 18384f32786ac45210143654390177105eb749b614e9Ted Kremenek AST->Invocation = CI; 1839ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth AST->NestedMacroExpansions = NestedMacroExpansions; 1840b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek 1841b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek // Recover resources if we crash before exiting this method. 184225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> 184325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek ASTUnitCleanup(AST.get()); 184425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<CompilerInvocation, 184525a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextReleaseRefCleanup<CompilerInvocation> > 184625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek CICleanup(CI.getPtr()); 184725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic, 184825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> > 184925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek DiagCleanup(Diags.getPtr()); 1850b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek 185139b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner return AST->LoadFromCompilerInvocation(PrecompilePreamble) ? 0 : AST.take(); 18527b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar} 1853abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1854abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregorbool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) { 18554f32786ac45210143654390177105eb749b614e9Ted Kremenek if (!Invocation) 1856abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 1857abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1858213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer ParsingTimer(WantTiming); 1859edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer ParsingTimer.setOutput("Reparsing " + getMainFileName()); 1860213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 1861cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Remap files. 1862f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 18638ef6c8cb6c5627240e2339fd7062c9873f821d7eDouglas Gregor PPOpts.DisableStatCache = true; 1864f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 1865f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor R = PPOpts.remapped_file_buffer_begin(), 1866f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor REnd = PPOpts.remapped_file_buffer_end(); 1867f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor R != REnd; 1868f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor ++R) { 1869f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor delete R->second; 1870f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor } 1871cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor Invocation->getPreprocessorOpts().clearRemappedFiles(); 1872b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis for (unsigned I = 0; I != NumRemappedFiles; ++I) { 1873b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; 1874b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (const llvm::MemoryBuffer * 1875b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { 1876b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, 1877b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf); 1878b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } else { 1879b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const char *fname = fileOrBuf.get<const char *>(); 1880b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, 1881b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis fname); 1882b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 1883b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 1884cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1885eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // If we have a preamble file lying around, or if we might try to 1886eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // build a precompiled preamble, do so now. 1887754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor llvm::MemoryBuffer *OverrideMainBuffer = 0; 1888eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor if (!PreambleFile.empty() || PreambleRebuildCounter > 0) 18892283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation); 1890175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1891abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Clear out the diagnostics state. 189232be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor if (!OverrideMainBuffer) { 1893c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getDiagnostics().Reset(); 189432be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts()); 189532be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor } 1896abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1897175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // Parse the sources 18989b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor bool Result = Parse(OverrideMainBuffer); 18999b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 19009b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor // If we're caching global code-completion results, and the top-level 19019b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor // declarations have changed, clear out the code-completion cache. 19029b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor if (!Result && ShouldCacheCodeCompletionResults && 19039b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue) 19049b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor CacheCodeCompletionResults(); 19059b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 1906175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor return Result; 1907abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 19081abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 190987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor//----------------------------------------------------------------------------// 191087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor// Code completion 191187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor//----------------------------------------------------------------------------// 191287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 191387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregornamespace { 191487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor /// \brief Code completion consumer that combines the cached code-completion 191587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor /// results from an ASTUnit with the code-completion results provided to it, 191687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor /// then passes the result on to 191787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer { 19183da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor unsigned long long NormalContexts; 191987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor ASTUnit &AST; 192087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CodeCompleteConsumer &Next; 192187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 192287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor public: 192387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next, 19248071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor bool IncludeMacros, bool IncludeCodePatterns, 19258071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor bool IncludeGlobals) 19268071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals, 192787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor Next.isOutputBinary()), AST(AST), Next(Next) 192887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor { 192987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Compute the set of contexts in which we will look when we don't have 193087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // any information about the specific context. 193187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor NormalContexts 19323da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor = (1LL << (CodeCompletionContext::CCC_TopLevel - 1)) 19333da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ObjCInterface - 1)) 19343da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ObjCImplementation - 1)) 19353da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ObjCIvarList - 1)) 19363da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_Statement - 1)) 19373da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_Expression - 1)) 19383da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)) 19393da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_DotMemberAccess - 1)) 19403da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ArrowMemberAccess - 1)) 19413da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ObjCPropertyAccess - 1)) 19423da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ObjCProtocolName - 1)) 19433da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)) 19443da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_Recovery - 1)); 19450268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor 194687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor if (AST.getASTContext().getLangOptions().CPlusPlus) 19473da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor NormalContexts |= (1LL << (CodeCompletionContext::CCC_EnumTag - 1)) 19483da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_UnionTag - 1)) 19493da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor | (1LL << (CodeCompletionContext::CCC_ClassOrStructTag - 1)); 195087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 195187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 195287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor virtual void ProcessCodeCompleteResults(Sema &S, 195387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CodeCompletionContext Context, 19540a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall CodeCompletionResult *Results, 1955697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor unsigned NumResults); 195687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 195787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, 195887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor OverloadCandidate *Candidates, 195987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor unsigned NumCandidates) { 196087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates); 196187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 1962218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor 1963dae687575010c9c49a4b552f5eef82cd6279d9acDouglas Gregor virtual CodeCompletionAllocator &getAllocator() { 1964218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor return Next.getAllocator(); 1965218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor } 196687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor }; 196787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor} 1968697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 19695f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor/// \brief Helper function that computes which global names are hidden by the 19705f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor/// local code-completion results. 1971c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenekstatic void CalculateHiddenNames(const CodeCompletionContext &Context, 1972c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek CodeCompletionResult *Results, 1973c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek unsigned NumResults, 1974c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek ASTContext &Ctx, 1975c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek llvm::StringSet<llvm::BumpPtrAllocator> &HiddenNames){ 19765f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor bool OnlyTagNames = false; 19775f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor switch (Context.getKind()) { 197852779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor case CodeCompletionContext::CCC_Recovery: 19795f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_TopLevel: 19805f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCInterface: 19815f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCImplementation: 19825f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCIvarList: 19835f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ClassStructUnion: 19845f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_Statement: 19855f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_Expression: 19865f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCMessageReceiver: 19873da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_DotMemberAccess: 19883da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_ArrowMemberAccess: 19893da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_ObjCPropertyAccess: 19905f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_Namespace: 19915f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_Type: 19922ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor case CodeCompletionContext::CCC_Name: 19932ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor case CodeCompletionContext::CCC_PotentiallyQualifiedName: 19940268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor case CodeCompletionContext::CCC_ParenthesizedExpression: 19953da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_ObjCSuperclass: 19965f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor break; 19975f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 19985f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_EnumTag: 19995f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_UnionTag: 20005f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ClassOrStructTag: 20015f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor OnlyTagNames = true; 20025f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor break; 20035f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 20045f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCProtocolName: 20051fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor case CodeCompletionContext::CCC_MacroName: 20061fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor case CodeCompletionContext::CCC_MacroNameUse: 2007f29c5233085a5af795c3c01b94d319e5b3235d56Douglas Gregor case CodeCompletionContext::CCC_PreprocessorExpression: 2008721f359a350059a81945baa08f63b2e5feceb044Douglas Gregor case CodeCompletionContext::CCC_PreprocessorDirective: 200959a66946aa7723c7b14831aa50902d533baaa957Douglas Gregor case CodeCompletionContext::CCC_NaturalLanguage: 2010458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor case CodeCompletionContext::CCC_SelectorName: 20111a480c403a3b141ab89c9c59cf7b681102a1bfabDouglas Gregor case CodeCompletionContext::CCC_TypeQualifiers: 201252779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor case CodeCompletionContext::CCC_Other: 20135c722c7020b33da57090422b854072258a50b3f0Douglas Gregor case CodeCompletionContext::CCC_OtherWithMacros: 20143da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_ObjCInstanceMessage: 20153da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_ObjCClassMessage: 20163da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor case CodeCompletionContext::CCC_ObjCCategoryName: 2017721f359a350059a81945baa08f63b2e5feceb044Douglas Gregor // We're looking for nothing, or we're looking for names that cannot 2018721f359a350059a81945baa08f63b2e5feceb044Douglas Gregor // be hidden. 20195f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor return; 20205f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor } 20215f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 20220a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall typedef CodeCompletionResult Result; 20235f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor for (unsigned I = 0; I != NumResults; ++I) { 20245f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (Results[I].Kind != Result::RK_Declaration) 20255f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor continue; 20265f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 20275f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor unsigned IDNS 20285f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor = Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace(); 20295f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 20305f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor bool Hiding = false; 20315f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (OnlyTagNames) 20325f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor Hiding = (IDNS & Decl::IDNS_Tag); 20335f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor else { 20345f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member | 2035a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Decl::IDNS_Namespace | Decl::IDNS_Ordinary | 2036a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Decl::IDNS_NonMemberOperator); 20375f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (Ctx.getLangOptions().CPlusPlus) 20385f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenIDNS |= Decl::IDNS_Tag; 20395f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor Hiding = (IDNS & HiddenIDNS); 20405f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor } 20415f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 20425f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (!Hiding) 20435f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor continue; 20445f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 20455f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor DeclarationName Name = Results[I].Declaration->getDeclName(); 20465f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (IdentifierInfo *Identifier = Name.getAsIdentifierInfo()) 20475f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenNames.insert(Identifier->getName()); 20485f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor else 20495f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenNames.insert(Name.getAsString()); 20505f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor } 20515f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor} 20525f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 20535f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 2054697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregorvoid AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S, 2055697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor CodeCompletionContext Context, 20560a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall CodeCompletionResult *Results, 2057697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor unsigned NumResults) { 2058697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // Merge the results we were given with the results we cached. 2059697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor bool AddedResult = false; 20605f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor unsigned InContexts 206152779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor = (Context.getKind() == CodeCompletionContext::CCC_Recovery? NormalContexts 20625f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor : (1 << (Context.getKind() - 1))); 20635f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 20645f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor // Contains the set of names that are hidden by "local" completion results. 2065c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames; 20660a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall typedef CodeCompletionResult Result; 20675f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Result, 8> AllResults; 2068697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor for (ASTUnit::cached_completion_iterator 20695535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor C = AST.cached_completion_begin(), 20705535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor CEnd = AST.cached_completion_end(); 2071697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor C != CEnd; ++C) { 2072697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // If the context we are in matches any of the contexts we are 2073697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // interested in, we'll add this result. 2074697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if ((C->ShowInContexts & InContexts) == 0) 2075697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor continue; 2076697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 2077697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // If we haven't added any results previously, do so now. 2078697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (!AddedResult) { 20795f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor CalculateHiddenNames(Context, Results, NumResults, S.Context, 20805f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenNames); 2081697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor AllResults.insert(AllResults.end(), Results, Results + NumResults); 2082697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor AddedResult = true; 2083697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 2084697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 20855f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor // Determine whether this global completion result is hidden by a local 20865f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor // completion result. If so, skip it. 20875f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (C->Kind != CXCursor_MacroDefinition && 20885f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenNames.count(C->Completion->getTypedText())) 20895f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor continue; 20905f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 2091697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // Adjust priority based on similar type classes. 2092697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor unsigned Priority = C->Priority; 20934125c37c71c6c8475019497de837204f0ee4370fDouglas Gregor CXCursorKind CursorKind = C->Kind; 20941fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor CodeCompletionString *Completion = C->Completion; 2095697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (!Context.getPreferredType().isNull()) { 2096697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (C->Kind == CXCursor_MacroDefinition) { 2097697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Priority = getMacroUsagePriority(C->Completion->getTypedText(), 2098b05496dbd63f03bf474dae2c4d1e2142608780ccDouglas Gregor S.getLangOptions(), 20991fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor Context.getPreferredType()->isAnyPointerType()); 2100697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } else if (C->Type) { 2101697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor CanQualType Expected 21025535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor = S.Context.getCanonicalType( 2103697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Context.getPreferredType().getUnqualifiedType()); 2104697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor SimplifiedTypeClass ExpectedSTC = getSimplifiedTypeClass(Expected); 2105697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (ExpectedSTC == C->TypeClass) { 2106697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // We know this type is similar; check for an exact match. 2107697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor llvm::StringMap<unsigned> &CachedCompletionTypes 21085535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor = AST.getCachedCompletionTypes(); 2109697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor llvm::StringMap<unsigned>::iterator Pos 21105535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor = CachedCompletionTypes.find(QualType(Expected).getAsString()); 2111697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type) 2112697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Priority /= CCF_ExactTypeMatch; 2113697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor else 2114697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Priority /= CCF_SimilarTypeMatch; 2115697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 2116697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 2117697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 2118697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 21191fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor // Adjust the completion string, if required. 21201fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor if (C->Kind == CXCursor_MacroDefinition && 21211fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) { 21221fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor // Create a new code-completion string that just contains the 21231fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor // macro name, without its arguments. 2124218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor CodeCompletionBuilder Builder(getAllocator(), CCP_CodePattern, 2125218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor C->Availability); 2126218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor Builder.AddTypedTextChunk(C->Completion->getTypedText()); 21274125c37c71c6c8475019497de837204f0ee4370fDouglas Gregor CursorKind = CXCursor_NotImplemented; 21284125c37c71c6c8475019497de837204f0ee4370fDouglas Gregor Priority = CCP_CodePattern; 2129218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor Completion = Builder.TakeString(); 21301fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor } 21311fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor 21324125c37c71c6c8475019497de837204f0ee4370fDouglas Gregor AllResults.push_back(Result(Completion, Priority, CursorKind, 213358ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor C->Availability)); 2134697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 2135697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 2136697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // If we did not add any cached completion results, just forward the 2137697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // results we were given to the next consumer. 2138697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (!AddedResult) { 2139697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Next.ProcessCodeCompleteResults(S, Context, Results, NumResults); 2140697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor return; 2141697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 21421e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor 2143697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Next.ProcessCodeCompleteResults(S, Context, AllResults.data(), 2144697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor AllResults.size()); 2145697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor} 2146697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 2147697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 2148697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 21495f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, 21501abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor RemappedFile *RemappedFiles, 21511abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor unsigned NumRemappedFiles, 2152cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor bool IncludeMacros, 2153cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor bool IncludeCodePatterns, 21541abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor CodeCompleteConsumer &Consumer, 21551abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Diagnostic &Diag, LangOptions &LangOpts, 21561abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor SourceManager &SourceMgr, FileManager &FileMgr, 21575f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics, 21585f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers) { 21594f32786ac45210143654390177105eb749b614e9Ted Kremenek if (!Invocation) 21601abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor return; 21611abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 2162213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer CompletionTimer(WantTiming); 2163edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer CompletionTimer.setOutput("Code completion @ " + File + ":" + 21645f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner Twine(Line) + ":" + Twine(Column)); 2165df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 21664f32786ac45210143654390177105eb749b614e9Ted Kremenek llvm::IntrusiveRefCntPtr<CompilerInvocation> 21674f32786ac45210143654390177105eb749b614e9Ted Kremenek CCInvocation(new CompilerInvocation(*Invocation)); 21684f32786ac45210143654390177105eb749b614e9Ted Kremenek 21694f32786ac45210143654390177105eb749b614e9Ted Kremenek FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts(); 21704f32786ac45210143654390177105eb749b614e9Ted Kremenek PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts(); 2171cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor 217287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor FrontendOpts.ShowMacrosInCodeCompletion 217387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor = IncludeMacros && CachedCompletionResults.empty(); 2174cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor FrontendOpts.ShowCodePatternsInCodeCompletion = IncludeCodePatterns; 21758071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor FrontendOpts.ShowGlobalSymbolsInCodeCompletion 21768071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor = CachedCompletionResults.empty(); 21771abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor FrontendOpts.CodeCompletionAt.FileName = File; 21781abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor FrontendOpts.CodeCompletionAt.Line = Line; 21791abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor FrontendOpts.CodeCompletionAt.Column = Column; 21801abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 21811abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set the language options appropriately. 21824f32786ac45210143654390177105eb749b614e9Ted Kremenek LangOpts = CCInvocation->getLangOpts(); 21831abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 218403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance()); 218503201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 218603201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek // Recover resources if we crash before exiting this method. 218725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> 218825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek CICleanup(Clang.get()); 218903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek 21904f32786ac45210143654390177105eb749b614e9Ted Kremenek Clang->setInvocation(&*CCInvocation); 219103201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second; 21921abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 21931abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set up diagnostics, capturing any diagnostics produced. 219403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setDiagnostics(&Diag); 21954f32786ac45210143654390177105eb749b614e9Ted Kremenek ProcessWarningOptions(Diag, CCInvocation->getDiagnosticOpts()); 21961abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor CaptureDroppedDiagnostics Capture(true, 219703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getDiagnostics(), 21981abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor StoredDiagnostics); 21991abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 22001abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Create the target instance. 220103201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTargetOpts().Features = TargetFeatures; 220203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), 220303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTargetOpts())); 220403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek if (!Clang->hasTarget()) { 22054f32786ac45210143654390177105eb749b614e9Ted Kremenek Clang->setInvocation(0); 2206bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor return; 22071abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor } 22081abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 22091abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Inform the target of the language options. 22101abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // 22111abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // FIXME: We shouldn't need to do this, the target should be immutable once 22121abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // created. This complexity should be lifted elsewhere. 221303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); 22141abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 221503201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs.size() == 1 && 22161abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor "Invocation must have exactly one source file!"); 221703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs[0].first != IK_AST && 22181abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor "FIXME: AST inputs not yet supported here!"); 221903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek assert(Clang->getFrontendOpts().Inputs[0].first != IK_LLVM_IR && 22201abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor "IR inputs not support here!"); 22211abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 22221abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 22231abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Use the source and file managers that we were given. 222403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setFileManager(&FileMgr); 222503201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setSourceManager(&SourceMgr); 22261abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 22271abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Remap files. 22281abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PreprocessorOpts.clearRemappedFiles(); 2229b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor PreprocessorOpts.RetainRemappedFileBuffers = true; 22302283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor for (unsigned I = 0; I != NumRemappedFiles; ++I) { 2231b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; 2232b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (const llvm::MemoryBuffer * 2233b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { 2234b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, memBuf); 2235b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis OwnedBuffers.push_back(memBuf); 2236b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } else { 2237b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const char *fname = fileOrBuf.get<const char *>(); 2238b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, fname); 2239b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } 22402283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor } 22411abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 224287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Use the code completion consumer we were given, but adding any cached 224387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // code-completion results. 22447f946ad40877df749ad05392cc4b80dc4189d28fDouglas Gregor AugmentedCodeCompleteConsumer *AugmentedConsumer 22457f946ad40877df749ad05392cc4b80dc4189d28fDouglas Gregor = new AugmentedCodeCompleteConsumer(*this, Consumer, 22467f946ad40877df749ad05392cc4b80dc4189d28fDouglas Gregor FrontendOpts.ShowMacrosInCodeCompletion, 22477f946ad40877df749ad05392cc4b80dc4189d28fDouglas Gregor FrontendOpts.ShowCodePatternsInCodeCompletion, 22487f946ad40877df749ad05392cc4b80dc4189d28fDouglas Gregor FrontendOpts.ShowGlobalSymbolsInCodeCompletion); 224903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->setCodeCompletionConsumer(AugmentedConsumer); 22501abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 2251df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // If we have a precompiled preamble, try to use it. We only allow 2252df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // the use of the precompiled preamble if we're if the completion 2253df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // point is within the main file, after the end of the precompiled 2254df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // preamble. 2255df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor llvm::MemoryBuffer *OverrideMainBuffer = 0; 2256df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (!PreambleFile.empty()) { 2257df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor using llvm::sys::FileStatus; 2258df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor llvm::sys::PathWithStatus CompleteFilePath(File); 2259df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor llvm::sys::PathWithStatus MainPath(OriginalSourceFile); 2260df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (const FileStatus *CompleteFileStatus = CompleteFilePath.getFileStatus()) 2261df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (const FileStatus *MainStatus = MainPath.getFileStatus()) 2262df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (CompleteFileStatus->getUniqueID() == MainStatus->getUniqueID()) 22632283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor OverrideMainBuffer 22644f32786ac45210143654390177105eb749b614e9Ted Kremenek = getMainBufferWithPrecompiledPreamble(*CCInvocation, false, 2265c9c29a8d7a0f78ddf2b393dd92f77c7f2046179cDouglas Gregor Line - 1); 2266df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 2267df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 2268df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // If the main file has been overridden due to the use of a preamble, 2269df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // make that override happen and introduce the preamble. 22708ef6c8cb6c5627240e2339fd7062c9873f821d7eDouglas Gregor PreprocessorOpts.DisableStatCache = true; 22714cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.insert(StoredDiagnostics.end(), 22724cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor this->StoredDiagnostics.begin(), 22734cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor this->StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver); 2274df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (OverrideMainBuffer) { 2275df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); 2276df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size(); 2277df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second 2278df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor = PreambleEndsAtStartOfLine; 2279df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.ImplicitPCHInclude = PreambleFile; 2280df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.DisablePCHValidation = true; 2281df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 22822283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor OwnedBuffers.push_back(OverrideMainBuffer); 2283f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor } else { 2284f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = 0; 2285f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second = false; 2286df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 2287df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 2288dca8ee8b7bc86076916a3a80f553f7a4e98c14afDouglas Gregor // Disable the preprocessing record 2289dca8ee8b7bc86076916a3a80f553f7a4e98c14afDouglas Gregor PreprocessorOpts.DetailedRecord = false; 2290dca8ee8b7bc86076916a3a80f553f7a4e98c14afDouglas Gregor 22911abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor llvm::OwningPtr<SyntaxOnlyAction> Act; 22921abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Act.reset(new SyntaxOnlyAction); 229303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek if (Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0].second, 229403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek Clang->getFrontendOpts().Inputs[0].first)) { 2295f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (OverrideMainBuffer) { 22969461fccd05bde8458710ba367be10b6e4efe2ec7Jonathan D. Turner std::string ModName = PreambleFile; 2297f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateStoredDiagnostics(Clang->getModuleManager(), ModName, 2298f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor getSourceManager(), PreambleDiagnostics, 2299f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor StoredDiagnostics); 2300f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 23011abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Act->Execute(); 23021abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Act->EndSourceFile(); 23031abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor } 23041abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor} 23057ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor 23065f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerCXSaveError ASTUnit::Save(StringRef File) { 230785bea9777d444ccbcc086d98f075fe666c2e865dDouglas Gregor if (getDiagnostics().hasUnrecoverableErrorOccurred()) 230839c411fa229b2a6747b92f945d1702ee674d3470Douglas Gregor return CXSaveError_TranslationErrors; 23099cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis 23109cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis // Write to a temporary file and later rename it to the actual file, to avoid 23119cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis // possible race conditions. 23127e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis llvm::SmallString<128> TempPath; 23137e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis TempPath = File; 23147e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis TempPath += "-%%%%%%%%"; 23157e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis int fd; 23167e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis if (llvm::sys::fs::unique_file(TempPath.str(), fd, TempPath, 23177e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis /*makeAbsolute=*/false)) 23189cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis return CXSaveError_Unknown; 23199cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis 23207ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor // FIXME: Can we somehow regenerate the stat cache here, or do we need to 23217ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor // unconditionally create a stat cache when we parse the file? 23227e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis llvm::raw_fd_ostream Out(fd, /*shouldClose=*/true); 2323b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 2324b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis serialize(Out); 2325b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis Out.close(); 23269cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis if (Out.has_error()) 23279cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis return CXSaveError_Unknown; 23289cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis 23299cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis if (llvm::error_code ec = llvm::sys::fs::rename(TempPath.str(), File)) { 23309cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis bool exists; 23319cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis llvm::sys::fs::remove(TempPath.str(), exists); 23329cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis return CXSaveError_Unknown; 23339cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis } 23349cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis 23359cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis return CXSaveError_None; 2336b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis} 2337b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 23385f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerbool ASTUnit::serialize(raw_ostream &OS) { 2339b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis if (getDiagnostics().hasErrorOccurred()) 2340b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis return true; 2341b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 23427ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor std::vector<unsigned char> Buffer; 23437ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor llvm::BitstreamWriter Stream(Buffer); 2344a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl ASTWriter Writer(Stream); 2345832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor Writer.WriteAST(getSema(), 0, std::string(), ""); 23467ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor 23477ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor // Write the generated bitstream to "Out". 2348bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor if (!Buffer.empty()) 2349b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis OS.write((char *)&Buffer.front(), Buffer.size()); 2350b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 2351b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis return false; 23527ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor} 2353f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 2354f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregortypedef ContinuousRangeMap<unsigned, int, 2> SLocRemap; 2355f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 2356f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregorstatic void TranslateSLoc(SourceLocation &L, SLocRemap &Remap) { 2357f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned Raw = L.getRawEncoding(); 2358f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const unsigned MacroBit = 1U << 31; 2359f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor L = SourceLocation::getFromRawEncoding((Raw & MacroBit) | 2360f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor ((Raw & ~MacroBit) + Remap.find(Raw & ~MacroBit)->second)); 2361f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor} 2362f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 2363f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregorvoid ASTUnit::TranslateStoredDiagnostics( 2364f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor ASTReader *MMan, 23655f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef ModName, 2366f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceManager &SrcMgr, 23675f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner const SmallVectorImpl<StoredDiagnostic> &Diags, 23685f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<StoredDiagnostic> &Out) { 2369f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // The stored diagnostic has the old source manager in it; update 2370f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // the locations to refer into the new source manager. We also need to remap 2371f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // all the locations to the new view. This includes the diag location, any 2372f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // associated source ranges, and the source ranges of associated fix-its. 2373f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // FIXME: There should be a cleaner way to do this. 2374f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 23755f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<StoredDiagnostic, 4> Result; 2376f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Result.reserve(Diags.size()); 2377f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(MMan && "Don't have a module manager"); 237848d2c3f7c3ca48da05436afdc8426a245294ee65Jonathan D. Turner serialization::Module *Mod = MMan->ModuleMgr.lookup(ModName); 2379f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(Mod && "Don't have preamble module"); 2380f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SLocRemap &Remap = Mod->SLocRemap; 2381f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (unsigned I = 0, N = Diags.size(); I != N; ++I) { 2382f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Rebuild the StoredDiagnostic. 2383f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const StoredDiagnostic &SD = Diags[I]; 2384f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceLocation L = SD.getLocation(); 2385f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateSLoc(L, Remap); 2386f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FullSourceLoc Loc(L, SrcMgr); 2387f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 23885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CharSourceRange, 4> Ranges; 2389f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Ranges.reserve(SD.range_size()); 2390f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (StoredDiagnostic::range_iterator I = SD.range_begin(), 2391f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor E = SD.range_end(); 2392f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor I != E; ++I) { 2393f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceLocation BL = I->getBegin(); 2394f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateSLoc(BL, Remap); 2395f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceLocation EL = I->getEnd(); 2396f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateSLoc(EL, Remap); 2397f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Ranges.push_back(CharSourceRange(SourceRange(BL, EL), I->isTokenRange())); 2398f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 2399f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 24005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<FixItHint, 2> FixIts; 2401f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FixIts.reserve(SD.fixit_size()); 2402f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (StoredDiagnostic::fixit_iterator I = SD.fixit_begin(), 2403f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor E = SD.fixit_end(); 2404f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor I != E; ++I) { 2405f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FixIts.push_back(FixItHint()); 2406f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FixItHint &FH = FixIts.back(); 2407f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FH.CodeToInsert = I->CodeToInsert; 2408f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceLocation BL = I->RemoveRange.getBegin(); 2409f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateSLoc(BL, Remap); 2410f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SourceLocation EL = I->RemoveRange.getEnd(); 2411f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor TranslateSLoc(EL, Remap); 2412f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FH.RemoveRange = CharSourceRange(SourceRange(BL, EL), 2413f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor I->RemoveRange.isTokenRange()); 2414f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 2415f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 2416f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Result.push_back(StoredDiagnostic(SD.getLevel(), SD.getID(), 2417f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SD.getMessage(), Loc, Ranges, FixIts)); 2418f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 2419f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Result.swap(Out); 2420f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor} 2421