ASTUnit.cpp revision f2224d89a6ae65a3839529e26d0f6d025d83d6bb
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" 237b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Driver/Tool.h" 24521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/CompilerInstance.h" 25521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/FrontendActions.h" 267b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Frontend/FrontendDiagnostic.h" 27521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/FrontendOptions.h" 2832be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor#include "clang/Frontend/Utils.h" 296ab7cd853e9c15cf986a8a7c3db1f8d20e275409Sebastian Redl#include "clang/Serialization/ASTReader.h" 307faa2ec03a7ef120ac165bb45b6c70a8b20c9f1cSebastian Redl#include "clang/Serialization/ASTWriter.h" 310853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Lex/HeaderSearch.h" 320853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Lex/Preprocessor.h" 33d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar#include "clang/Basic/TargetOptions.h" 340853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Basic/TargetInfo.h" 350853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Basic/Diagnostic.h" 36349d38cef04ddf8938047c1b542a799aa82dfe84Douglas Gregor#include "llvm/ADT/StringSet.h" 374db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor#include "llvm/Support/MemoryBuffer.h" 387b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "llvm/System/Host.h" 394a630d30cd8ee9c8f46b8d3c9ad7e7e00d393f32Benjamin Kramer#include "llvm/System/Path.h" 40df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor#include "llvm/Support/raw_ostream.h" 41385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor#include "llvm/Support/Timer.h" 4244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor#include <cstdlib> 43ad23ebe22b7e52e3875981eeb46a1fd61a7554fbZhongxing Xu#include <cstdio> 44cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor#include <sys/stat.h> 450853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisusing namespace clang; 460853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 47213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregorusing llvm::TimeRecord; 48213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 49213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregornamespace { 50213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor class SimpleTimer { 51213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor bool WantTiming; 52213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor TimeRecord Start; 53213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor std::string Output; 54213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 55edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer public: 569dba61a1e46099b77adf15de224aaa16037a7fffDouglas Gregor explicit SimpleTimer(bool WantTiming) : WantTiming(WantTiming) { 57213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor if (WantTiming) 58edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer Start = TimeRecord::getCurrentTime(); 59213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor } 60213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 61edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer void setOutput(const llvm::Twine &Output) { 62213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor if (WantTiming) 63edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer this->Output = Output.str(); 64213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor } 65213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 66213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor ~SimpleTimer() { 67213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor if (WantTiming) { 68213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor TimeRecord Elapsed = TimeRecord::getCurrentTime(); 69213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor Elapsed -= Start; 70213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor llvm::errs() << Output << ':'; 71213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor Elapsed.print(Elapsed, llvm::errs()); 72213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor llvm::errs() << '\n'; 73213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor } 74213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor } 75213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor }; 76213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor} 77213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 78eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// \brief After failing to build a precompiled preamble (due to 79eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// errors in the source that occurs in the preamble), the number of 80eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// reparses during which we'll skip even trying to precompile the 81eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// preamble. 82eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregorconst unsigned DefaultPreambleRebuildInterval = 5; 83eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 84e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor/// \brief Tracks the number of ASTUnit objects that are currently active. 85e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor/// 86e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor/// Used for debugging purposes only. 87e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregorstatic unsigned ActiveASTUnitObjects; 88e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor 893687e9d3a5dbfa9963af02a49a2b139d91310813Douglas GregorASTUnit::ASTUnit(bool _MainFileIsAST) 90abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor : CaptureDiagnostics(false), MainFileIsAST(_MainFileIsAST), 91213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor CompleteTranslationUnit(true), WantTiming(getenv("LIBCLANG_TIMING")), 92213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor NumStoredDiagnosticsFromDriver(0), 934cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor ConcurrencyCheckValue(CheckUnlocked), 94671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreambleRebuildCounter(0), SavedMainFileBuffer(0), PreambleBuffer(0), 95727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor ShouldCacheCodeCompletionResults(false), 96727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor NumTopLevelDeclsAtLastCompletionCache(0), 978b1540c159093e0e627ebf6542d0c0b7aba99eafDouglas Gregor CacheCodeCompletionCoolDown(0), 988b1540c159093e0e627ebf6542d0c0b7aba99eafDouglas Gregor UnsafeToFree(false) { 99e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor if (getenv("LIBCLANG_OBJTRACKING")) { 100e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor ++ActiveASTUnitObjects; 101e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor fprintf(stderr, "+++ %d translation units\n", ActiveASTUnitObjects); 102e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor } 103385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor} 1043687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor 105521bf9c529e653ab28896d027352d3e16e2672d5Daniel DunbarASTUnit::~ASTUnit() { 106bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor ConcurrencyCheckValue = CheckLocked; 107abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor CleanTemporaryFiles(); 108175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (!PreambleFile.empty()) 109385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor llvm::sys::Path(PreambleFile).eraseFromDisk(); 110f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 111f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // Free the buffers associated with remapped files. We are required to 112f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // perform this operation here because we explicitly request that the 113f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // compiler instance *not* free these buffers for each invocation of the 114f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // parser. 115f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (Invocation.get()) { 116f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 117f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 118f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor FB = PPOpts.remapped_file_buffer_begin(), 119f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor FBEnd = PPOpts.remapped_file_buffer_end(); 120f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor FB != FBEnd; 121f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor ++FB) 122f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor delete FB->second; 123f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor } 12428233428da1ebec20c893d6297ae3191318940ddDouglas Gregor 12528233428da1ebec20c893d6297ae3191318940ddDouglas Gregor delete SavedMainFileBuffer; 126671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete PreambleBuffer; 127671947b18dba342f9aba022ee992babef325a833Douglas Gregor 128213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor ClearCachedCompletionResults(); 129e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor 130e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor if (getenv("LIBCLANG_OBJTRACKING")) { 131e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor --ActiveASTUnitObjects; 132e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor fprintf(stderr, "--- %d translation units\n", ActiveASTUnitObjects); 133e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor } 134abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 135abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 136abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregorvoid ASTUnit::CleanTemporaryFiles() { 137313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I) 138313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor TemporaryFiles[I].eraseFromDisk(); 139abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor TemporaryFiles.clear(); 140e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff} 1410853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 1428071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor/// \brief Determine the set of code-completion contexts in which this 1438071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor/// declaration should be shown. 1448071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregorstatic unsigned getDeclShowContexts(NamedDecl *ND, 145a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor const LangOptions &LangOpts, 146a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor bool &IsNestedNameSpecifier) { 147a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = false; 148a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor 1498071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (isa<UsingShadowDecl>(ND)) 1508071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor ND = dyn_cast<NamedDecl>(ND->getUnderlyingDecl()); 1518071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (!ND) 1528071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor return 0; 1538071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 1548071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor unsigned Contexts = 0; 1558071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND) || 1568071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND)) { 1578071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // Types can appear in these contexts. 1588071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus || !isa<TagDecl>(ND)) 1598071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_TopLevel - 1)) 1608071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1)) 1618071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1)) 1628071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor | (1 << (CodeCompletionContext::CCC_Statement - 1)) 1630268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_Type - 1)) 1640268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)); 1658071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 1668071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // In C++, types can appear in expressions contexts (for functional casts). 1678071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus) 1688071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_Expression - 1)); 1698071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 1708071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // In Objective-C, message sends can send interfaces. In Objective-C++, 1718071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // all types are available due to functional casts. 1728071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus || isa<ObjCInterfaceDecl>(ND)) 1738071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)); 1748071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 1758071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // Deal with tag names. 1768071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (isa<EnumDecl>(ND)) { 1778071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_EnumTag - 1)); 1788071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 179a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // Part of the nested-name-specifier in C++0x. 1808071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus0x) 181a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = true; 1828071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } else if (RecordDecl *Record = dyn_cast<RecordDecl>(ND)) { 1838071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (Record->isUnion()) 1848071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_UnionTag - 1)); 1858071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor else 1868071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts |= (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1)); 1878071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 1888071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor if (LangOpts.CPlusPlus) 189a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = true; 19052779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor } else if (isa<ClassTemplateDecl>(ND)) 191a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = true; 1928071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } else if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) { 1938071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // Values can appear in these contexts. 1948071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts = (1 << (CodeCompletionContext::CCC_Statement - 1)) 1958071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor | (1 << (CodeCompletionContext::CCC_Expression - 1)) 1960268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)) 1978071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)); 1988071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } else if (isa<ObjCProtocolDecl>(ND)) { 1998071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor Contexts = (1 << (CodeCompletionContext::CCC_ObjCProtocolName - 1)); 2008071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } else if (isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) { 201a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Contexts = (1 << (CodeCompletionContext::CCC_Namespace - 1)); 2028071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 2038071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor // Part of the nested-name-specifier. 204a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier = true; 2058071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } 2068071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 2078071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor return Contexts; 2088071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor} 2098071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 21087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregorvoid ASTUnit::CacheCodeCompletionResults() { 21187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor if (!TheSema) 21287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor return; 21387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 214213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer Timer(WantTiming); 215edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer Timer.setOutput("Cache global code completions for " + getMainFileName()); 21687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 21787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Clear out the previous results. 21887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor ClearCachedCompletionResults(); 21987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 22087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Gather the set of global code completions. 2210a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall typedef CodeCompletionResult Result; 22287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor llvm::SmallVector<Result, 8> Results; 22387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor TheSema->GatherGlobalCodeCompletions(Results); 22487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 22587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Translate global code completions into cached completions. 226f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor llvm::DenseMap<CanQualType, unsigned> CompletionTypes; 227f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 22887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor for (unsigned I = 0, N = Results.size(); I != N; ++I) { 22987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor switch (Results[I].Kind) { 2308071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor case Result::RK_Declaration: { 231a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor bool IsNestedNameSpecifier = false; 2328071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedCodeCompletionResult CachedResult; 2338071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema); 2348071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedResult.ShowInContexts = getDeclShowContexts(Results[I].Declaration, 235a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Ctx->getLangOptions(), 236a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier); 2378071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedResult.Priority = Results[I].Priority; 2388071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedResult.Kind = Results[I].CursorKind; 23958ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor CachedResult.Availability = Results[I].Availability; 240c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor 241f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // Keep track of the type of this completion in an ASTContext-agnostic 242f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // way. 243c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor QualType UsageType = getDeclUsageType(*Ctx, Results[I].Declaration); 244f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor if (UsageType.isNull()) { 245c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor CachedResult.TypeClass = STC_Void; 246f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedResult.Type = 0; 247f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor } else { 248f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CanQualType CanUsageType 249f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor = Ctx->getCanonicalType(UsageType.getUnqualifiedType()); 250f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedResult.TypeClass = getSimplifiedTypeClass(CanUsageType); 251f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 252f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // Determine whether we have already seen this type. If so, we save 253f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // ourselves the work of formatting the type string by using the 254f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor // temporary, CanQualType-based hash table to find the associated value. 255f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor unsigned &TypeValue = CompletionTypes[CanUsageType]; 256f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor if (TypeValue == 0) { 257f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor TypeValue = CompletionTypes.size(); 258f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedCompletionTypes[QualType(CanUsageType).getAsString()] 259f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor = TypeValue; 260f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor } 261f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 262f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedResult.Type = TypeValue; 263c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor } 264f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 2658071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor CachedCompletionResults.push_back(CachedResult); 266a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor 267a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor /// Handle nested-name-specifiers in C++. 268a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor if (TheSema->Context.getLangOptions().CPlusPlus && 269a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor IsNestedNameSpecifier && !Results[I].StartsNestedNameSpecifier) { 270a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // The contexts in which a nested-name-specifier can appear in C++. 271a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor unsigned NNSContexts 272a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor = (1 << (CodeCompletionContext::CCC_TopLevel - 1)) 273a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1)) 274a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1)) 275a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_Statement - 1)) 276a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_Expression - 1)) 277a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)) 278a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_EnumTag - 1)) 279a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_UnionTag - 1)) 280a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor | (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1)) 2812ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor | (1 << (CodeCompletionContext::CCC_Type - 1)) 2820268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_PotentiallyQualifiedName - 1)) 2830268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)); 284a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor 285a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor if (isa<NamespaceDecl>(Results[I].Declaration) || 286a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor isa<NamespaceAliasDecl>(Results[I].Declaration)) 287a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor NNSContexts |= (1 << (CodeCompletionContext::CCC_Namespace - 1)); 288a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor 289a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor if (unsigned RemainingContexts 290a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor = NNSContexts & ~CachedResult.ShowInContexts) { 291a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // If there any contexts where this completion can be a 292a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // nested-name-specifier but isn't already an option, create a 293a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor // nested-name-specifier completion. 294a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Results[I].StartsNestedNameSpecifier = true; 295a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema); 296a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedResult.ShowInContexts = RemainingContexts; 297a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedResult.Priority = CCP_NestedNameSpecifier; 298a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedResult.TypeClass = STC_Void; 299a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedResult.Type = 0; 300a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor CachedCompletionResults.push_back(CachedResult); 301a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor } 302a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor } 30387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor break; 3048071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor } 3058071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor 30687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor case Result::RK_Keyword: 30787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor case Result::RK_Pattern: 30887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Ignore keywords and patterns; we don't care, since they are so 30987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // easily regenerated. 31087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor break; 31187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 31287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor case Result::RK_Macro: { 31387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedCodeCompletionResult CachedResult; 31487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema); 31587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedResult.ShowInContexts 31687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor = (1 << (CodeCompletionContext::CCC_TopLevel - 1)) 31787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCInterface - 1)) 31887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCImplementation - 1)) 31987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1)) 32087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1)) 32187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_Statement - 1)) 32287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_Expression - 1)) 3231fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)) 324f29c5233085a5af795c3c01b94d319e5b3235d56Douglas Gregor | (1 << (CodeCompletionContext::CCC_MacroNameUse - 1)) 3250268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_PreprocessorExpression - 1)) 3260268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)); 3270268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor 3282ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor 32987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedResult.Priority = Results[I].Priority; 33087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedResult.Kind = Results[I].CursorKind; 33158ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor CachedResult.Availability = Results[I].Availability; 3321827e10051638770ad9ccf3e285caf95f995afd1Douglas Gregor CachedResult.TypeClass = STC_Void; 333f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedResult.Type = 0; 33487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedCompletionResults.push_back(CachedResult); 33587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor break; 33687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 33787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 33887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor Results[I].Destroy(); 33987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 34087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 341727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor // Make a note of the state when we performed this caching. 342727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor NumTopLevelDeclsAtLastCompletionCache = top_level_size(); 34387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor} 34487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 34587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregorvoid ASTUnit::ClearCachedCompletionResults() { 34687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor for (unsigned I = 0, N = CachedCompletionResults.size(); I != N; ++I) 34787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor delete CachedCompletionResults[I].Completion; 34887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CachedCompletionResults.clear(); 349f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor CachedCompletionTypes.clear(); 35087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor} 35187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 3520853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisnamespace { 3530853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 354c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl/// \brief Gathers information from ASTReader that will be used to initialize 3550853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis/// a Preprocessor. 3563c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redlclass ASTInfoCollector : public ASTReaderListener { 3570853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis LangOptions &LangOpt; 3580853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis HeaderSearch &HSI; 3590853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string &TargetTriple; 3600853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string &Predefines; 3610853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned &Counter; 3621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3630853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned NumHeaderInfos; 3641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3650853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidispublic: 3663c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl ASTInfoCollector(LangOptions &LangOpt, HeaderSearch &HSI, 3670853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string &TargetTriple, std::string &Predefines, 3680853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned &Counter) 3690853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis : LangOpt(LangOpt), HSI(HSI), TargetTriple(TargetTriple), 3700853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Predefines(Predefines), Counter(Counter), NumHeaderInfos(0) {} 3711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3720853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis virtual bool ReadLanguageOptions(const LangOptions &LangOpts) { 3730853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis LangOpt = LangOpts; 3740853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return false; 3750853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 3761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 377dc3c0d20375bda7775b2fade05b20e315798b9feDaniel Dunbar virtual bool ReadTargetTriple(llvm::StringRef Triple) { 3780853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis TargetTriple = Triple; 3790853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return false; 3800853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 3811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 382cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, 3837b5a1210d93ca62ecd61800f245c87259b1f8f79Daniel Dunbar llvm::StringRef OriginalFileName, 3840853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string &SuggestedPredefines) { 385cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl Predefines = Buffers[0].Data; 386cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl for (unsigned I = 1, N = Buffers.size(); I != N; ++I) { 387cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl Predefines += Buffers[I].Data; 388cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl } 3890853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return false; 3900853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 3911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 392ec1afbfd8e880d0169aab0ececa2e7e1611f4955Douglas Gregor virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID) { 3930853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis HSI.setHeaderFileInfoForUID(HFI, NumHeaderInfos++); 3940853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3960853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis virtual void ReadCounter(unsigned Value) { 3970853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Counter = Value; 3980853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 3990853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis}; 4000853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 401a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorclass StoredDiagnosticClient : public DiagnosticClient { 402a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags; 403a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 404a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorpublic: 405a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor explicit StoredDiagnosticClient( 406a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags) 407a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor : StoredDiags(StoredDiags) { } 408a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 409a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor virtual void HandleDiagnostic(Diagnostic::Level Level, 410a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor const DiagnosticInfo &Info); 411a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}; 412a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 413a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor/// \brief RAII object that optionally captures diagnostics, if 414a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor/// there is no diagnostic client to capture them already. 415a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorclass CaptureDroppedDiagnostics { 416a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor Diagnostic &Diags; 417a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor StoredDiagnosticClient Client; 418a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor DiagnosticClient *PreviousClient; 419a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 420a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorpublic: 421a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor CaptureDroppedDiagnostics(bool RequestCapture, Diagnostic &Diags, 422e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags) 423bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor : Diags(Diags), Client(StoredDiags), PreviousClient(0) 424a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor { 425bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor if (RequestCapture || Diags.getClient() == 0) { 426bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor PreviousClient = Diags.takeClient(); 427a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor Diags.setClient(&Client); 428bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor } 429a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor } 430a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 431a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor ~CaptureDroppedDiagnostics() { 432bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor if (Diags.getClient() == &Client) { 433bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor Diags.takeClient(); 434bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor Diags.setClient(PreviousClient); 435bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor } 436a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor } 437a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}; 438a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 4390853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis} // anonymous namespace 4400853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 441a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorvoid StoredDiagnosticClient::HandleDiagnostic(Diagnostic::Level Level, 442a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor const DiagnosticInfo &Info) { 443f2224d89a6ae65a3839529e26d0f6d025d83d6bbArgyrios Kyrtzidis // Default implementation (Warnings/errors count). 444f2224d89a6ae65a3839529e26d0f6d025d83d6bbArgyrios Kyrtzidis DiagnosticClient::HandleDiagnostic(Level, Info); 445f2224d89a6ae65a3839529e26d0f6d025d83d6bbArgyrios Kyrtzidis 446a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor StoredDiags.push_back(StoredDiagnostic(Level, Info)); 447a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor} 448a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 44977accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroffconst std::string &ASTUnit::getOriginalSourceFileName() { 45068d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar return OriginalSourceFile; 45177accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroff} 4520853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 4533c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redlconst std::string &ASTUnit::getASTFileName() { 4543c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl assert(isMainFileAST() && "Not an ASTUnit from an AST file!"); 455c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl return static_cast<ASTReader *>(Ctx->getExternalSource())->getFileName(); 456e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff} 457e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff 458389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidisllvm::MemoryBuffer *ASTUnit::getBufferForFile(llvm::StringRef Filename, 459389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis std::string *ErrorStr, 460389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis int64_t FileSize, 461389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis struct stat *FileInfo) { 462389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis return FileMgr->getBufferForFile(Filename, FileSystemOpts, 463389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis ErrorStr, FileSize, FileInfo); 464389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis} 465389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis 466e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor/// \brief Configure the diagnostics object for use with ASTUnit. 467e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregorvoid ASTUnit::ConfigureDiags(llvm::IntrusiveRefCntPtr<Diagnostic> &Diags, 468e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor ASTUnit &AST, bool CaptureDiagnostics) { 469e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor if (!Diags.getPtr()) { 470e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor // No diagnostics engine was provided, so create our own diagnostics object 471e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor // with the default options. 472e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor DiagnosticOptions DiagOpts; 473e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor DiagnosticClient *Client = 0; 474e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor if (CaptureDiagnostics) 475e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor Client = new StoredDiagnosticClient(AST.StoredDiagnostics); 476e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0, Client); 477e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor } else if (CaptureDiagnostics) { 478e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor Diags->setClient(new StoredDiagnosticClient(AST.StoredDiagnostics)); 479e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor } 480e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor} 481e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor 4823c7f4134603d04b44f997b43c0a9def270f25386Sebastian RedlASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, 48328019772db70d4547be05a042eb950bc910f134fDouglas Gregor llvm::IntrusiveRefCntPtr<Diagnostic> Diags, 484389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis const FileSystemOptions &FileSystemOpts, 4855cf48766d626ff6b223acc9d4b7e415ca8480836Ted Kremenek bool OnlyLocalDecls, 4864db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFile *RemappedFiles, 487a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor unsigned NumRemappedFiles, 488a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor bool CaptureDiagnostics) { 4893687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true)); 490e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor ConfigureDiags(Diags, *AST, CaptureDiagnostics); 491abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 4927d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor AST->OnlyLocalDecls = OnlyLocalDecls; 493e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor AST->CaptureDiagnostics = CaptureDiagnostics; 49428019772db70d4547be05a042eb950bc910f134fDouglas Gregor AST->Diagnostics = Diags; 495389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis AST->FileSystemOpts = FileSystemOpts; 4963687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor AST->FileMgr.reset(new FileManager); 497389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis AST->SourceMgr.reset(new SourceManager(AST->getDiagnostics(), 498389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis AST->getFileManager(), 499389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis AST->getFileSystemOpts())); 500389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager(), 501389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis AST->getFileSystemOpts())); 502914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor 5034db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor for (unsigned I = 0; I != NumRemappedFiles; ++I) { 5044db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor // Create the file entry for the file that we're mapping from. 5054db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor const FileEntry *FromFile 5064db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor = AST->getFileManager().getVirtualFile(RemappedFiles[I].first, 5074db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFiles[I].second->getBufferSize(), 508389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis 0, 509389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis AST->getFileSystemOpts()); 5104db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor if (!FromFile) { 5113687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file) 5124db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor << RemappedFiles[I].first; 513c8dfe5ece04e683106eb96c58a2999f70b53ac21Douglas Gregor delete RemappedFiles[I].second; 5144db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor continue; 5154db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 5164db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 5174db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor // Override the contents of the "from" file with the contents of 5184db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor // the "to" file. 5194db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor AST->getSourceManager().overrideFileContents(FromFile, 5204db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFiles[I].second); 5214db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 5224db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 5230853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // Gather Info for preprocessor construction later on. 5241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5250853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis LangOptions LangInfo; 5260853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis HeaderSearch &HeaderInfo = *AST->HeaderInfo.get(); 5270853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string TargetTriple; 5280853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string Predefines; 5290853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned Counter; 5300853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 531c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl llvm::OwningPtr<ASTReader> Reader; 5320853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 533c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl Reader.reset(new ASTReader(AST->getSourceManager(), AST->getFileManager(), 534389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis AST->getFileSystemOpts(), AST->getDiagnostics())); 5353c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl Reader->setListener(new ASTInfoCollector(LangInfo, HeaderInfo, TargetTriple, 536cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar Predefines, Counter)); 537cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar 5381d9f1fe7173e3084325f43c78af812a36d8a2a7cSebastian Redl switch (Reader->ReadAST(Filename, ASTReader::MainFile)) { 539c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl case ASTReader::Success: 5400853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis break; 5411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 542c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl case ASTReader::Failure: 543c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl case ASTReader::IgnorePCH: 5443687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch); 5450853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return NULL; 5460853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 5471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 54868d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar AST->OriginalSourceFile = Reader->getOriginalSourceFile(); 54968d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar 5503c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl // AST file loaded successfully. Now create the preprocessor. 5511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5520853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // Get information about the target being compiled for. 553d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar // 5543c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl // FIXME: This is broken, we should store the TargetOptions in the AST file. 555d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOptions TargetOpts; 556d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOpts.ABI = ""; 557875ab10245d3bf37252dd822aa1616bb0a391095John McCall TargetOpts.CXXABI = ""; 558d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOpts.CPU = ""; 559d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOpts.Features.clear(); 560d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOpts.Triple = TargetTriple; 5613687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor AST->Target.reset(TargetInfo::CreateTargetInfo(AST->getDiagnostics(), 5623687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor TargetOpts)); 5633687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor AST->PP.reset(new Preprocessor(AST->getDiagnostics(), LangInfo, 5643687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor *AST->Target.get(), 56531b87d8006d4863dd9b17e515ac720941efc38e3Daniel Dunbar AST->getSourceManager(), HeaderInfo)); 5660853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Preprocessor &PP = *AST->PP.get(); 5670853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 568d5b6126389e1e2fd89e498fe17da4bb44ece0302Daniel Dunbar PP.setPredefines(Reader->getSuggestedPredefines()); 5690853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis PP.setCounterValue(Counter); 570cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar Reader->setPreprocessor(PP); 5711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5720853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // Create and initialize the ASTContext. 5730853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 5740853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis AST->Ctx.reset(new ASTContext(LangInfo, 57531b87d8006d4863dd9b17e515ac720941efc38e3Daniel Dunbar AST->getSourceManager(), 5760853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis *AST->Target.get(), 5770853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis PP.getIdentifierTable(), 5780853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis PP.getSelectorTable(), 5790853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis PP.getBuiltinInfo(), 5800853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis /* size_reserve = */0)); 5810853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis ASTContext &Context = *AST->Ctx.get(); 5821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 583cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar Reader->InitializeContext(Context); 5841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 585c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl // Attach the AST reader to the AST context as an external AST 5860853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // source, so that declarations will be deserialized from the 5873c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl // AST file as needed. 588c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl ASTReader *ReaderPtr = Reader.get(); 589914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor llvm::OwningPtr<ExternalASTSource> Source(Reader.take()); 5900853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Context.setExternalSource(Source); 5910853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 592914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor // Create an AST consumer, even though it isn't used. 593914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor AST->Consumer.reset(new ASTConsumer); 594914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor 595c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl // Create a semantic analysis object and tell the AST reader about it. 596914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor AST->TheSema.reset(new Sema(PP, Context, *AST->Consumer)); 597914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor AST->TheSema->Initialize(); 598914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor ReaderPtr->InitializeSema(*AST->TheSema); 599914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor 6001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return AST.take(); 6010853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis} 602521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 603521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarnamespace { 604521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 605f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerConsumer : public ASTConsumer { 606f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar ASTUnit &Unit; 607f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 608f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic: 609f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar TopLevelDeclTrackerConsumer(ASTUnit &_Unit) : Unit(_Unit) {} 610f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 611f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar void HandleTopLevelDecl(DeclGroupRef D) { 612da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) { 613da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek Decl *D = *it; 614da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek // FIXME: Currently ObjC method declarations are incorrectly being 615da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek // reported as top-level declarations, even though their DeclContext 616da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek // is the containing ObjC @interface/@implementation. This is a 617da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek // fundamental problem in the parser right now. 618da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek if (isa<ObjCMethodDecl>(D)) 619da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek continue; 620eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Unit.addTopLevelDecl(D); 621da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek } 622f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar } 62327372b4f1f402e95dd479ecf40c39ca71c15619fSebastian Redl 62427372b4f1f402e95dd479ecf40c39ca71c15619fSebastian Redl // We're not interested in "interesting" decls. 62527372b4f1f402e95dd479ecf40c39ca71c15619fSebastian Redl void HandleInterestingDecl(DeclGroupRef) {} 626f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar}; 627f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 628f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerAction : public ASTFrontendAction { 629f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic: 630f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar ASTUnit &Unit; 631f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 632521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 633521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar llvm::StringRef InFile) { 634f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar return new TopLevelDeclTrackerConsumer(Unit); 635521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar } 636521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 637521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarpublic: 638f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {} 639f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 640521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar virtual bool hasCodeCompletionSupport() const { return false; } 641df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor virtual bool usesCompleteTranslationUnit() { 642df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor return Unit.isCompleteTranslationUnit(); 643df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 644521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar}; 645521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 6461d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorclass PrecompilePreambleConsumer : public PCHGenerator { 6471d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor ASTUnit &Unit; 648eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor std::vector<Decl *> TopLevelDecls; 6491d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 6501d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorpublic: 6511d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor PrecompilePreambleConsumer(ASTUnit &Unit, 6521d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor const Preprocessor &PP, bool Chaining, 6531d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor const char *isysroot, llvm::raw_ostream *Out) 6541d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor : PCHGenerator(PP, Chaining, isysroot, Out), Unit(Unit) { } 6551d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 656eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor virtual void HandleTopLevelDecl(DeclGroupRef D) { 6571d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) { 6581d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor Decl *D = *it; 6591d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // FIXME: Currently ObjC method declarations are incorrectly being 6601d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // reported as top-level declarations, even though their DeclContext 6611d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // is the containing ObjC @interface/@implementation. This is a 6621d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // fundamental problem in the parser right now. 6631d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor if (isa<ObjCMethodDecl>(D)) 6641d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor continue; 665eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDecls.push_back(D); 666eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 667eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 668eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 669eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor virtual void HandleTranslationUnit(ASTContext &Ctx) { 670eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor PCHGenerator::HandleTranslationUnit(Ctx); 671eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (!Unit.getDiagnostics().hasErrorOccurred()) { 672eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // Translate the top-level declarations we captured during 673eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // parsing into declaration IDs in the precompiled 674eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // preamble. This will allow us to deserialize those top-level 675eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // declarations when requested. 676eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor for (unsigned I = 0, N = TopLevelDecls.size(); I != N; ++I) 677eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Unit.addTopLevelDeclFromPreamble( 678eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor getWriter().getDeclID(TopLevelDecls[I])); 6791d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor } 6801d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor } 6811d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor}; 6821d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 6831d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorclass PrecompilePreambleAction : public ASTFrontendAction { 6841d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor ASTUnit &Unit; 6851d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 6861d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorpublic: 6871d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor explicit PrecompilePreambleAction(ASTUnit &Unit) : Unit(Unit) {} 6881d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 6891d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 6901d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor llvm::StringRef InFile) { 6911d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor std::string Sysroot; 6921d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor llvm::raw_ostream *OS = 0; 6931d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor bool Chaining; 6941d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor if (GeneratePCHAction::ComputeASTConsumerArguments(CI, InFile, Sysroot, 6951d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor OS, Chaining)) 6961d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor return 0; 6971d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 6981d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor const char *isysroot = CI.getFrontendOpts().RelocatablePCH ? 6991d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor Sysroot.c_str() : 0; 7001d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor return new PrecompilePreambleConsumer(Unit, CI.getPreprocessor(), Chaining, 7011d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor isysroot, OS); 7021d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor } 7031d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 7041d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor virtual bool hasCodeCompletionSupport() const { return false; } 7051d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor virtual bool hasASTFileSupport() const { return false; } 706df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor virtual bool usesCompleteTranslationUnit() { return false; } 7071d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor}; 7081d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 709521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar} 710521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 711abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// Parse the source file into a translation unit using the given compiler 712abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// invocation, replacing the current translation unit. 713abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// 714abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// \returns True if a failure occurred that causes the ASTUnit not to 715abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// contain any translation-unit information, false otherwise. 716754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregorbool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { 71728233428da1ebec20c893d6297ae3191318940ddDouglas Gregor delete SavedMainFileBuffer; 71828233428da1ebec20c893d6297ae3191318940ddDouglas Gregor SavedMainFileBuffer = 0; 71928233428da1ebec20c893d6297ae3191318940ddDouglas Gregor 720671947b18dba342f9aba022ee992babef325a833Douglas Gregor if (!Invocation.get()) { 721671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete OverrideMainBuffer; 722abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 723671947b18dba342f9aba022ee992babef325a833Douglas Gregor } 724abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 725521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the compiler instance to use for building the AST. 726cb6dda1a7abe2fe30b0345bfbbf872cc73446678Daniel Dunbar CompilerInstance Clang; 727abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Clang.setInvocation(Invocation.take()); 728abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second; 729abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 7301abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set up diagnostics, capturing any diagnostics that would 7311abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // otherwise be dropped. 732abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Clang.setDiagnostics(&getDiagnostics()); 7333687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor 734521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the target instance. 735521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), 736521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.getTargetOpts())); 737671947b18dba342f9aba022ee992babef325a833Douglas Gregor if (!Clang.hasTarget()) { 738671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete OverrideMainBuffer; 739abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 740671947b18dba342f9aba022ee992babef325a833Douglas Gregor } 741671947b18dba342f9aba022ee992babef325a833Douglas Gregor 742521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Inform the target of the language options. 743521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // 744521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // FIXME: We shouldn't need to do this, the target should be immutable once 745521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // created. This complexity should be lifted elsewhere. 746521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.getTarget().setForcedLangOptions(Clang.getLangOpts()); 747abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 748521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar assert(Clang.getFrontendOpts().Inputs.size() == 1 && 749521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar "Invocation must have exactly one source file!"); 750c34ce3fa613d5e4a283e53615fceafd17390445bDaniel Dunbar assert(Clang.getFrontendOpts().Inputs[0].first != IK_AST && 751521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar "FIXME: AST inputs not yet supported here!"); 752faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar assert(Clang.getFrontendOpts().Inputs[0].first != IK_LLVM_IR && 753faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar "IR inputs not support here!"); 754521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 755abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Configure the various subsystems. 756abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // FIXME: Should we retain the previous file manager? 757abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor FileMgr.reset(new FileManager); 758389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis FileSystemOpts = Clang.getFileSystemOpts(); 759389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis SourceMgr.reset(new SourceManager(getDiagnostics(), *FileMgr, FileSystemOpts)); 760914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor TheSema.reset(); 761abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Ctx.reset(); 762abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor PP.reset(); 763abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 764abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Clear out old caches and data. 765abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor TopLevelDecls.clear(); 766abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor CleanTemporaryFiles(); 767abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor PreprocessedEntitiesByFile.clear(); 768c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 769f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor if (!OverrideMainBuffer) { 7704cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.erase( 7714cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver, 7724cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.end()); 773f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor TopLevelDeclsInPreamble.clear(); 774f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor } 775f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor 776521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create a file manager object to provide access to and cache the filesystem. 777abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Clang.setFileManager(&getFileManager()); 778abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 779521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the source manager. 780abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Clang.setSourceManager(&getSourceManager()); 781abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 782f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // If the main file has been overridden due to the use of a preamble, 783f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // make that override happen and introduce the preamble. 784f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOptions &PreprocessorOpts = Clang.getPreprocessorOpts(); 7851abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor std::string PriorImplicitPCHInclude; 786f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (OverrideMainBuffer) { 787f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); 788f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size(); 789f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second 790f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor = PreambleEndsAtStartOfLine; 7911abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PriorImplicitPCHInclude = PreprocessorOpts.ImplicitPCHInclude; 792385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor PreprocessorOpts.ImplicitPCHInclude = PreambleFile; 793fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor PreprocessorOpts.DisablePCHValidation = true; 79428233428da1ebec20c893d6297ae3191318940ddDouglas Gregor 795c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // The stored diagnostic has the old source manager in it; update 796c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // the locations to refer into the new source manager. Since we've 797c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // been careful to make sure that the source manager's state 798c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // before and after are identical, so that we can reuse the source 799c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // location itself. 8004cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor for (unsigned I = NumStoredDiagnosticsFromDriver, 8014cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor N = StoredDiagnostics.size(); 8024cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor I < N; ++I) { 803c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor FullSourceLoc Loc(StoredDiagnostics[I].getLocation(), 804c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getSourceManager()); 805c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor StoredDiagnostics[I].setLocation(Loc); 806c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor } 8074cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 8084cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor // Keep track of the override buffer; 8094cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor SavedMainFileBuffer = OverrideMainBuffer; 810f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor } else { 811f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = 0; 812f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second = false; 813f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor } 814f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 815abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor llvm::OwningPtr<TopLevelDeclTrackerAction> Act; 816abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Act.reset(new TopLevelDeclTrackerAction(*this)); 817f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar if (!Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second, 818d3598a65716e120aef45aa2841d730e03f7101feDaniel Dunbar Clang.getFrontendOpts().Inputs[0].first)) 819521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar goto error; 820abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 821f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar Act->Execute(); 822abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 82364a32baec6fdc7e5fbcba417a2754f78ab876245Daniel Dunbar // Steal the created target, context, and preprocessor, and take back the 82464a32baec6fdc7e5fbcba417a2754f78ab876245Daniel Dunbar // source and file managers. 825914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor TheSema.reset(Clang.takeSema()); 826914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor Consumer.reset(Clang.takeASTConsumer()); 827abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Ctx.reset(Clang.takeASTContext()); 828abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor PP.reset(Clang.takePreprocessor()); 829521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeSourceManager(); 830521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeFileManager(); 831abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Target.reset(Clang.takeTarget()); 832abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 833f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar Act->EndSourceFile(); 834f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 835f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // Remove the overridden buffer we used for the preamble. 8361abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor if (OverrideMainBuffer) { 837f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.eraseRemappedFile( 838f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 8391abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PreprocessorOpts.ImplicitPCHInclude = PriorImplicitPCHInclude; 8401abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor } 8411abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 842abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Invocation.reset(Clang.takeInvocation()); 843abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return false; 844abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 845521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarerror: 846f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // Remove the overridden buffer we used for the preamble. 847fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor if (OverrideMainBuffer) { 848f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.eraseRemappedFile( 849f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 8501abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PreprocessorOpts.ImplicitPCHInclude = PriorImplicitPCHInclude; 851671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete OverrideMainBuffer; 85237cf66350cb5a2bb68b0b7c7cca552f7a4867348Douglas Gregor SavedMainFileBuffer = 0; 853fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor } 854f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 855d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor StoredDiagnostics.clear(); 856521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeSourceManager(); 857521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeFileManager(); 858abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Invocation.reset(Clang.takeInvocation()); 859abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 860abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 861abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 86244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor/// \brief Simple function to retrieve a path for a preamble precompiled header. 86344c181aec37789f25f6c15543c164416f72e562aDouglas Gregorstatic std::string GetPreamblePCHPath() { 86444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: This is lame; sys::Path should provide this function (in particular, 86544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // it should know how to find the temporary files dir). 86644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: This is really lame. I copied this code from the Driver! 867424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor // FIXME: This is a hack so that we can override the preamble file during 868424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor // crash-recovery testing, which is the only case where the preamble files 869424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor // are not necessarily cleaned up. 870424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor const char *TmpFile = ::getenv("CINDEXTEST_PREAMBLE_FILE"); 871424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor if (TmpFile) 872424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor return TmpFile; 873424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor 87444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor std::string Error; 87544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor const char *TmpDir = ::getenv("TMPDIR"); 87644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!TmpDir) 87744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor TmpDir = ::getenv("TEMP"); 87844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!TmpDir) 87944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor TmpDir = ::getenv("TMP"); 880c6cb2b02f0f4b3f162985803df3729b4def32108Douglas Gregor#ifdef LLVM_ON_WIN32 881c6cb2b02f0f4b3f162985803df3729b4def32108Douglas Gregor if (!TmpDir) 882c6cb2b02f0f4b3f162985803df3729b4def32108Douglas Gregor TmpDir = ::getenv("USERPROFILE"); 883c6cb2b02f0f4b3f162985803df3729b4def32108Douglas Gregor#endif 88444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!TmpDir) 88544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor TmpDir = "/tmp"; 88644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor llvm::sys::Path P(TmpDir); 887c6cb2b02f0f4b3f162985803df3729b4def32108Douglas Gregor P.createDirectoryOnDisk(true); 88844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor P.appendComponent("preamble"); 8896bf1830875673d6bd6c5bfcd65c9dcabfb45958bDouglas Gregor P.appendSuffix("pch"); 89044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (P.createTemporaryFileOnDisk()) 89144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor return std::string(); 89244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 89344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor return P.str(); 89444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor} 89544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 896f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// \brief Compute the preamble for the main file, providing the source buffer 897f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// that corresponds to the main file along with a pair (bytes, start-of-line) 898f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// that describes the preamble. 899f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregorstd::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > 900df95a13ec73d2cdaea79555cb412d767f4963120Douglas GregorASTUnit::ComputePreamble(CompilerInvocation &Invocation, 901df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor unsigned MaxLines, bool &CreatedBuffer) { 902175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor FrontendOptions &FrontendOpts = Invocation.getFrontendOpts(); 90344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor PreprocessorOptions &PreprocessorOpts 904175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor = Invocation.getPreprocessorOpts(); 905175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = false; 906175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 90744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Try to determine if the main file has been remapped, either from the 90844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // command line (to another file) or directly through the compiler invocation 90944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // (to a memory buffer). 910175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::MemoryBuffer *Buffer = 0; 91144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].second); 91244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (const llvm::sys::FileStatus *MainFileStatus = MainFilePath.getFileStatus()) { 91344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Check whether there is a file-file remapping of the main file 91444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor for (PreprocessorOptions::remapped_file_iterator 915175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor M = PreprocessorOpts.remapped_file_begin(), 916175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor E = PreprocessorOpts.remapped_file_end(); 91744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor M != E; 91844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor ++M) { 91944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor llvm::sys::PathWithStatus MPath(M->first); 92044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (const llvm::sys::FileStatus *MStatus = MPath.getFileStatus()) { 92144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (MainFileStatus->uniqueID == MStatus->uniqueID) { 92244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // We found a remapping. Try to load the resulting, remapped source. 923175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (CreatedBuffer) { 92444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor delete Buffer; 925175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = false; 926175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 927175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 928389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis Buffer = getBufferForFile(M->second); 92944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Buffer) 930f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor return std::make_pair((llvm::MemoryBuffer*)0, 931f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor std::make_pair(0, true)); 932175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = true; 93344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 93444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 93544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 93644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 93744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Check whether there is a file-buffer remapping. It supercedes the 93844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // file-file remapping. 93944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 94044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor M = PreprocessorOpts.remapped_file_buffer_begin(), 94144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor E = PreprocessorOpts.remapped_file_buffer_end(); 94244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor M != E; 94344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor ++M) { 94444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor llvm::sys::PathWithStatus MPath(M->first); 94544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (const llvm::sys::FileStatus *MStatus = MPath.getFileStatus()) { 94644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (MainFileStatus->uniqueID == MStatus->uniqueID) { 94744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // We found a remapping. 948175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (CreatedBuffer) { 94944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor delete Buffer; 950175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = false; 951175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 95244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 953175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Buffer = const_cast<llvm::MemoryBuffer *>(M->second); 95444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 95544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 956175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 95744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 95844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 95944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // If the main source file was not remapped, load it now. 96044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Buffer) { 961389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis Buffer = getBufferForFile(FrontendOpts.Inputs[0].second); 96244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Buffer) 963f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor return std::make_pair((llvm::MemoryBuffer*)0, std::make_pair(0, true)); 964175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 965175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = true; 966175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 967175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 968df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor return std::make_pair(Buffer, Lexer::ComputePreamble(Buffer, MaxLines)); 969175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor} 970175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 971754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregorstatic llvm::MemoryBuffer *CreatePaddedMainFileBuffer(llvm::MemoryBuffer *Old, 972754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor unsigned NewSize, 973754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor llvm::StringRef NewName) { 974754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor llvm::MemoryBuffer *Result 975754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor = llvm::MemoryBuffer::getNewUninitMemBuffer(NewSize, NewName); 976754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor memcpy(const_cast<char*>(Result->getBufferStart()), 977754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor Old->getBufferStart(), Old->getBufferSize()); 978754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor memset(const_cast<char*>(Result->getBufferStart()) + Old->getBufferSize(), 979f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor ' ', NewSize - Old->getBufferSize() - 1); 980f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor const_cast<char*>(Result->getBufferEnd())[-1] = '\n'; 981754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor 982754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return Result; 983754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor} 984754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor 985175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// \brief Attempt to build or re-use a precompiled preamble when (re-)parsing 986175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// the source file. 987175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// 988175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// This routine will compute the preamble of the main source file. If a 989175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// non-trivial preamble is found, it will precompile that preamble into a 990175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// precompiled header so that the precompiled preamble can be used to reduce 991175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// reparsing time. If a precompiled preamble has already been constructed, 992175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// this routine will determine if it is still valid and, if so, avoid 993175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// rebuilding the precompiled preamble. 994175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// 995df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// \param AllowRebuild When true (the default), this routine is 996df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// allowed to rebuild the precompiled preamble if it is found to be 997df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// out-of-date. 998df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// 999df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// \param MaxLines When non-zero, the maximum number of lines that 1000df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// can occur within the preamble. 1001df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// 1002754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// \returns If the precompiled preamble can be used, returns a newly-allocated 1003754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// buffer that should be used in place of the main file when doing so. 1004754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// Otherwise, returns a NULL pointer. 1005df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregorllvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( 10062283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor CompilerInvocation PreambleInvocation, 1007df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool AllowRebuild, 1008df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor unsigned MaxLines) { 1009175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor FrontendOptions &FrontendOpts = PreambleInvocation.getFrontendOpts(); 1010175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreprocessorOptions &PreprocessorOpts 1011175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor = PreambleInvocation.getPreprocessorOpts(); 1012175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1013175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor bool CreatedPreambleBuffer = false; 1014f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > NewPreamble 1015df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor = ComputePreamble(PreambleInvocation, MaxLines, CreatedPreambleBuffer); 1016175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 101773fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor // If ComputePreamble() Take ownership of the 101873fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor llvm::OwningPtr<llvm::MemoryBuffer> OwnedPreambleBuffer; 101973fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor if (CreatedPreambleBuffer) 102073fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor OwnedPreambleBuffer.reset(NewPreamble.first); 102173fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor 1022f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (!NewPreamble.second.first) { 1023175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We couldn't find a preamble in the main source. Clear out the current 1024175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // preamble, if we have one. It's obviously no good any more. 1025175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1026175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (!PreambleFile.empty()) { 1027385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor llvm::sys::Path(PreambleFile).eraseFromDisk(); 1028175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleFile.clear(); 1029175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 1030eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 1031eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // The next time we actually see a preamble, precompile it. 1032eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = 1; 1033754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 103444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 103544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 1036175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (!Preamble.empty()) { 1037175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We've previously computed a preamble. Check whether we have the same 1038175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // preamble now that we did before, and that there's enough space in 1039175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // the main-file buffer within the precompiled preamble to fit the 1040175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // new main file. 1041f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (Preamble.size() == NewPreamble.second.first && 1042f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreambleEndsAtStartOfLine == NewPreamble.second.second && 1043592508ed997e52207cf380f9b6eb9943994ad7aeDouglas Gregor NewPreamble.first->getBufferSize() < PreambleReservedSize-2 && 1044175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor memcmp(&Preamble[0], NewPreamble.first->getBufferStart(), 1045f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor NewPreamble.second.first) == 0) { 1046175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // The preamble has not changed. We may be able to re-use the precompiled 1047175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // preamble. 1048c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 1049cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Check that none of the files used by the preamble have changed. 1050cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor bool AnyFileChanged = false; 1051cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1052cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // First, make a record of those files that have been overridden via 1053cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // remapping or unsaved_files. 1054cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor llvm::StringMap<std::pair<off_t, time_t> > OverriddenFiles; 1055cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (PreprocessorOptions::remapped_file_iterator 1056cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor R = PreprocessorOpts.remapped_file_begin(), 1057cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor REnd = PreprocessorOpts.remapped_file_end(); 1058cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor !AnyFileChanged && R != REnd; 1059cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++R) { 1060cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor struct stat StatBuf; 1061cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (stat(R->second.c_str(), &StatBuf)) { 1062cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // If we can't stat the file we're remapping to, assume that something 1063cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // horrible happened. 1064cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 1065cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor break; 1066cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1067754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor 1068cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor OverriddenFiles[R->first] = std::make_pair(StatBuf.st_size, 1069cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor StatBuf.st_mtime); 1070cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1071cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 1072cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor R = PreprocessorOpts.remapped_file_buffer_begin(), 1073cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor REnd = PreprocessorOpts.remapped_file_buffer_end(); 1074cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor !AnyFileChanged && R != REnd; 1075cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++R) { 1076cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // FIXME: Should we actually compare the contents of file->buffer 1077cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // remappings? 1078cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor OverriddenFiles[R->first] = std::make_pair(R->second->getBufferSize(), 1079cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 0); 1080cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1081cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1082cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Check whether anything has changed. 1083cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (llvm::StringMap<std::pair<off_t, time_t> >::iterator 1084cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor F = FilesInPreamble.begin(), FEnd = FilesInPreamble.end(); 1085cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor !AnyFileChanged && F != FEnd; 1086cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++F) { 1087cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor llvm::StringMap<std::pair<off_t, time_t> >::iterator Overridden 1088cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor = OverriddenFiles.find(F->first()); 1089cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (Overridden != OverriddenFiles.end()) { 1090cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // This file was remapped; check whether the newly-mapped file 1091cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // matches up with the previous mapping. 1092cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (Overridden->second != F->second) 1093cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 1094cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor continue; 1095cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1096cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1097cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // The file was not remapped; check whether it has changed on disk. 1098cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor struct stat StatBuf; 1099cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (stat(F->first(), &StatBuf)) { 1100cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // If we can't stat the file, assume that something horrible happened. 1101cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 1102cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } else if (StatBuf.st_size != F->second.first || 1103cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor StatBuf.st_mtime != F->second.second) 1104cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 1105cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1106cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1107cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (!AnyFileChanged) { 1108c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Okay! We can re-use the precompiled preamble. 1109c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 1110c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Set the state of the diagnostic object to mimic its state 1111c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // after parsing the preamble. 111232be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor // FIXME: This won't catch any #pragma push warning changes that 111332be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor // have occurred in the preamble. 1114c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getDiagnostics().Reset(); 111532be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor ProcessWarningOptions(getDiagnostics(), 111632be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor PreambleInvocation.getDiagnosticOpts()); 1117c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getDiagnostics().setNumWarnings(NumWarningsInPreamble); 1118c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor if (StoredDiagnostics.size() > NumStoredDiagnosticsInPreamble) 1119c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor StoredDiagnostics.erase( 1120c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor StoredDiagnostics.begin() + NumStoredDiagnosticsInPreamble, 1121c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor StoredDiagnostics.end()); 1122c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 1123c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Create a version of the main file buffer that is padded to 1124c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // buffer size we reserved when creating the preamble. 1125cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor return CreatePaddedMainFileBuffer(NewPreamble.first, 1126cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor PreambleReservedSize, 1127cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FrontendOpts.Inputs[0].second); 1128cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1129175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 1130df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 1131df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // If we aren't allowed to rebuild the precompiled preamble, just 1132df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // return now. 1133df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (!AllowRebuild) 1134df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor return 0; 1135aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor 1136175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We can't reuse the previously-computed preamble. Build a new one. 1137175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1138385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor llvm::sys::Path(PreambleFile).eraseFromDisk(); 1139eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = 1; 1140df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } else if (!AllowRebuild) { 1141df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // We aren't allowed to rebuild the precompiled preamble; just 1142df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // return now. 1143df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor return 0; 1144df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 1145eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 1146eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // If the preamble rebuild counter > 1, it's because we previously 1147eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // failed to build a preamble and we're not yet ready to try 1148eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // again. Decrement the counter and return a failure. 1149eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor if (PreambleRebuildCounter > 1) { 1150eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor --PreambleRebuildCounter; 1151eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor return 0; 1152eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor } 1153eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 11542cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor // Create a temporary file for the precompiled preamble. In rare 11552cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor // circumstances, this can fail. 11562cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor std::string PreamblePCHPath = GetPreamblePCHPath(); 11572cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor if (PreamblePCHPath.empty()) { 11582cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor // Try again next time. 11592cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor PreambleRebuildCounter = 1; 11602cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor return 0; 11612cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor } 11622cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor 1163175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We did not previously compute a preamble, or it can't be reused anyway. 1164213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer PreambleTimer(WantTiming); 1165edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer PreambleTimer.setOutput("Precompiling preamble"); 116644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 116744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create a new buffer that stores the preamble. The buffer also contains 116844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // extra space for the original contents of the file (which will be present 116944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // when we actually parse the file) along with more room in case the file 1170175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // grows. 1171175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleReservedSize = NewPreamble.first->getBufferSize(); 1172175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (PreambleReservedSize < 4096) 1173f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreambleReservedSize = 8191; 117444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor else 1175175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleReservedSize *= 2; 1176175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1177c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Save the preamble text for later; we'll need to compare against it for 1178c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // subsequent reparses. 1179c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor Preamble.assign(NewPreamble.first->getBufferStart(), 1180c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor NewPreamble.first->getBufferStart() 1181c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor + NewPreamble.second.first); 1182c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor PreambleEndsAtStartOfLine = NewPreamble.second.second; 1183c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 1184671947b18dba342f9aba022ee992babef325a833Douglas Gregor delete PreambleBuffer; 1185671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreambleBuffer 1186175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor = llvm::MemoryBuffer::getNewUninitMemBuffer(PreambleReservedSize, 118744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor FrontendOpts.Inputs[0].second); 118844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor memcpy(const_cast<char*>(PreambleBuffer->getBufferStart()), 1189175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor NewPreamble.first->getBufferStart(), Preamble.size()); 1190175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor memset(const_cast<char*>(PreambleBuffer->getBufferStart()) + Preamble.size(), 1191f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor ' ', PreambleReservedSize - Preamble.size() - 1); 1192f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor const_cast<char*>(PreambleBuffer->getBufferEnd())[-1] = '\n'; 119344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 119444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Remap the main source file to the preamble buffer. 1195175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].second); 119644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor PreprocessorOpts.addRemappedFile(MainFilePath.str(), PreambleBuffer); 119744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 119844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Tell the compiler invocation to generate a temporary precompiled header. 119944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor FrontendOpts.ProgramAction = frontend::GeneratePCH; 120085e5191934143edfa9fed582149d8f85c99c753fDouglas Gregor FrontendOpts.ChainedPCH = true; 120144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: Generate the precompiled header into memory? 12022cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor FrontendOpts.OutputFile = PreamblePCHPath; 1203aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = 0; 1204aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second = false; 120544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 120644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create the compiler instance to use for building the precompiled preamble. 120744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor CompilerInstance Clang; 120844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.setInvocation(&PreambleInvocation); 120944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second; 121044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 12111abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set up diagnostics, capturing all of the diagnostics produced. 121244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.setDiagnostics(&getDiagnostics()); 121344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 121444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create the target instance. 121544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), 121644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.getTargetOpts())); 121744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Clang.hasTarget()) { 1218175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 1219175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1220eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = DefaultPreambleRebuildInterval; 1221671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1222671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 1223754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 122444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 122544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 122644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Inform the target of the language options. 122744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // 122844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: We shouldn't need to do this, the target should be immutable once 122944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // created. This complexity should be lifted elsewhere. 123044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.getTarget().setForcedLangOptions(Clang.getLangOpts()); 123144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 123244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor assert(Clang.getFrontendOpts().Inputs.size() == 1 && 123344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor "Invocation must have exactly one source file!"); 123444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor assert(Clang.getFrontendOpts().Inputs[0].first != IK_AST && 123544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor "FIXME: AST inputs not yet supported here!"); 123644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor assert(Clang.getFrontendOpts().Inputs[0].first != IK_LLVM_IR && 123744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor "IR inputs not support here!"); 123844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 123944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Clear out old caches and data. 1240aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor getDiagnostics().Reset(); 124132be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor ProcessWarningOptions(getDiagnostics(), Clang.getDiagnosticOpts()); 12424cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.erase( 12434cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver, 12444cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.end()); 1245eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDecls.clear(); 1246eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDeclsInPreamble.clear(); 124744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 124844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create a file manager object to provide access to and cache the filesystem. 124944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.setFileManager(new FileManager); 125044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 125144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create the source manager. 1252389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis Clang.setSourceManager(new SourceManager(getDiagnostics(), 1253389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis Clang.getFileManager(), 1254389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis Clang.getFileSystemOpts())); 125544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 12561d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor llvm::OwningPtr<PrecompilePreambleAction> Act; 12571d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor Act.reset(new PrecompilePreambleAction(*this)); 125844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second, 125944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.getFrontendOpts().Inputs[0].first)) { 126044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.takeInvocation(); 1261175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 1262175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1263eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = DefaultPreambleRebuildInterval; 1264671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1265671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 1266754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 126744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 126844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 126944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Act->Execute(); 127044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Act->EndSourceFile(); 127144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.takeInvocation(); 127244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 1273eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (Diagnostics->hasErrorOccurred()) { 1274175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // There were errors parsing the preamble, so no precompiled header was 1275175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // generated. Forget that we even tried. 127606e504462014b0506a70c7730ea45c551a103364Douglas Gregor // FIXME: Should we leave a note for ourselves to try again? 1277175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 1278175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 1279eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDeclsInPreamble.clear(); 1280eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = DefaultPreambleRebuildInterval; 1281671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1282671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 1283754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 1284175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 1285175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1286175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // Keep track of the preamble we precompiled. 1287175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleFile = FrontendOpts.OutputFile; 1288c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor NumStoredDiagnosticsInPreamble = StoredDiagnostics.size(); 1289c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor NumWarningsInPreamble = getDiagnostics().getNumWarnings(); 1290cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1291cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Keep track of all of the files that the source manager knows about, 1292cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // so we can verify whether they have changed or not. 1293cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FilesInPreamble.clear(); 1294cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor SourceManager &SourceMgr = Clang.getSourceManager(); 1295cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor const llvm::MemoryBuffer *MainFileBuffer 1296cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor = SourceMgr.getBuffer(SourceMgr.getMainFileID()); 1297cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (SourceManager::fileinfo_iterator F = SourceMgr.fileinfo_begin(), 1298cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FEnd = SourceMgr.fileinfo_end(); 1299cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor F != FEnd; 1300cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++F) { 1301cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor const FileEntry *File = F->second->Entry; 1302cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (!File || F->second->getRawBuffer() == MainFileBuffer) 1303cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor continue; 1304cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1305cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FilesInPreamble[File->getName()] 1306cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor = std::make_pair(F->second->getSize(), File->getModificationTime()); 1307cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 1308cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1309eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = 1; 1310671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.eraseRemappedFile( 1311671947b18dba342f9aba022ee992babef325a833Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 1312754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return CreatePaddedMainFileBuffer(NewPreamble.first, 1313754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor PreambleReservedSize, 1314754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor FrontendOpts.Inputs[0].second); 131544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor} 1316abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1317eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregorvoid ASTUnit::RealizeTopLevelDeclsFromPreamble() { 1318eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor std::vector<Decl *> Resolved; 1319eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Resolved.reserve(TopLevelDeclsInPreamble.size()); 1320eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor ExternalASTSource &Source = *getASTContext().getExternalSource(); 1321eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor for (unsigned I = 0, N = TopLevelDeclsInPreamble.size(); I != N; ++I) { 1322eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // Resolve the declaration ID to an actual declaration, possibly 1323eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // deserializing the declaration in the process. 1324eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Decl *D = Source.GetExternalDecl(TopLevelDeclsInPreamble[I]); 1325eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (D) 1326eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Resolved.push_back(D); 1327eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 1328eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDeclsInPreamble.clear(); 1329eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end()); 1330eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor} 1331eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 1332eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregorunsigned ASTUnit::getMaxPCHLevel() const { 1333eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (!getOnlyLocalDecls()) 1334eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor return Decl::MaxPCHLevel; 1335eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 13361d9f1fe7173e3084325f43c78af812a36d8a2a7cSebastian Redl return 0; 1337eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor} 1338eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 1339213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregorllvm::StringRef ASTUnit::getMainFileName() const { 1340213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor return Invocation->getFrontendOpts().Inputs[0].second; 1341213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor} 1342213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 13434cd912aa94656697a44c3ebb159f05060300524eDouglas Gregorbool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) { 13444cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor if (!Invocation) 13454cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor return true; 13464cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 13474cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor // We'll manage file buffers ourselves. 13484cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor Invocation->getPreprocessorOpts().RetainRemappedFileBuffers = true; 13494cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor Invocation->getFrontendOpts().DisableFree = false; 13504cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 13514cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor llvm::MemoryBuffer *OverrideMainBuffer = 0; 135299ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor if (PrecompilePreamble) { 135308bb4c622d0b79c33b4ac78ce1bec79398953daaDouglas Gregor PreambleRebuildCounter = 2; 13544cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor OverrideMainBuffer 13554cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor = getMainBufferWithPrecompiledPreamble(*Invocation); 13564cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor } 13574cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 1358213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer ParsingTimer(WantTiming); 1359edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer ParsingTimer.setOutput("Parsing " + getMainFileName()); 13604cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 1361213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor return Parse(OverrideMainBuffer); 13624cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor} 13634cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 1364abc563f554951259bbe0315055cad92ee14d87e4Douglas GregorASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, 1365abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor llvm::IntrusiveRefCntPtr<Diagnostic> Diags, 1366abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor bool OnlyLocalDecls, 136744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor bool CaptureDiagnostics, 1368df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool PrecompilePreamble, 136987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor bool CompleteTranslationUnit, 1370e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor bool CacheCodeCompletionResults) { 1371abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Create the AST unit. 1372abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor llvm::OwningPtr<ASTUnit> AST; 1373abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST.reset(new ASTUnit(false)); 1374e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor ConfigureDiags(Diags, *AST, CaptureDiagnostics); 1375abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST->Diagnostics = Diags; 1376abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST->OnlyLocalDecls = OnlyLocalDecls; 1377e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor AST->CaptureDiagnostics = CaptureDiagnostics; 1378df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor AST->CompleteTranslationUnit = CompleteTranslationUnit; 137987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults; 138008bb4c622d0b79c33b4ac78ce1bec79398953daaDouglas Gregor AST->CacheCodeCompletionCoolDown = 1; 1381abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST->Invocation.reset(CI); 1382385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor 13834cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor return AST->LoadFromCompilerInvocation(PrecompilePreamble)? 0 : AST.take(); 1384521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar} 13857b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 13867b55668db7618334cc40011d3c1e128524d89462Daniel DunbarASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, 13877b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar const char **ArgEnd, 138828019772db70d4547be05a042eb950bc910f134fDouglas Gregor llvm::IntrusiveRefCntPtr<Diagnostic> Diags, 1389869824e87940f97b87064db2df2861e82e08a8c6Daniel Dunbar llvm::StringRef ResourceFilesPath, 13907b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar bool OnlyLocalDecls, 1391e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor bool CaptureDiagnostics, 13924db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFile *RemappedFiles, 1393a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor unsigned NumRemappedFiles, 1394df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool PrecompilePreamble, 139587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor bool CompleteTranslationUnit, 139699ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor bool CacheCodeCompletionResults, 139799ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor bool CXXPrecompilePreamble, 139899ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor bool CXXChainedPCH) { 139928019772db70d4547be05a042eb950bc910f134fDouglas Gregor if (!Diags.getPtr()) { 14003687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor // No diagnostics engine was provided, so create our own diagnostics object 14013687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor // with the default options. 14023687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor DiagnosticOptions DiagOpts; 140328019772db70d4547be05a042eb950bc910f134fDouglas Gregor Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0); 14043687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor } 14053687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor 14067b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar llvm::SmallVector<const char *, 16> Args; 14077b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar Args.push_back("<clang>"); // FIXME: Remove dummy argument. 14087b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar Args.insert(Args.end(), ArgBegin, ArgEnd); 14097b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 14107b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar // FIXME: Find a cleaner way to force the driver into restricted modes. We 14117b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar // also want to force it to use clang. 14127b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar Args.push_back("-fsyntax-only"); 14137b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 14144cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor llvm::SmallVector<StoredDiagnostic, 4> StoredDiagnostics; 14154cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 14164cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor llvm::OwningPtr<CompilerInvocation> CI; 1417e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor 14184cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor { 1419e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags, 14204cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics); 14214cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 14224cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor // FIXME: We shouldn't have to pass in the path info. 14234cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor driver::Driver TheDriver("clang", llvm::sys::getHostTriple(), 14244cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor "a.out", false, false, *Diags); 14254cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 14264cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor // Don't check that inputs exist, they have been remapped. 14274cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor TheDriver.setCheckInputsExist(false); 14284cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 14294cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor llvm::OwningPtr<driver::Compilation> C( 14304cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor TheDriver.BuildCompilation(Args.size(), Args.data())); 14314cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 14324cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor // We expect to get back exactly one command job, if we didn't something 14334cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor // failed. 14344cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor const driver::JobList &Jobs = C->getJobs(); 14354cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor if (Jobs.size() != 1 || !isa<driver::Command>(Jobs.begin())) { 14364cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor llvm::SmallString<256> Msg; 14374cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor llvm::raw_svector_ostream OS(Msg); 14384cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor C->PrintJob(OS, C->getJobs(), "; ", true); 14394cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor Diags->Report(diag::err_fe_expected_compiler_job) << OS.str(); 14404cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor return 0; 14414cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor } 14427b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 14434cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin()); 14444cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") { 14454cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor Diags->Report(diag::err_fe_expected_clang_command); 14464cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor return 0; 14474cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor } 14487b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 14494cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor const driver::ArgStringList &CCArgs = Cmd->getArguments(); 14504cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor CI.reset(new CompilerInvocation); 14514cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor CompilerInvocation::CreateFromArgs(*CI, 1452e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor const_cast<const char **>(CCArgs.data()), 1453e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor const_cast<const char **>(CCArgs.data()) + 14544cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor CCArgs.size(), 14554cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor *Diags); 14567b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar } 1457e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor 14584db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor // Override any files that need remapping 14594db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor for (unsigned I = 0; I != NumRemappedFiles; ++I) 1460807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, 1461b26d483a9f7fdc815e87bbbac4af916307b4c07dDaniel Dunbar RemappedFiles[I].second); 14624db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 14638b9adfea5e834eaee0f45d8cc7fb052d68df4a46Daniel Dunbar // Override the resources path. 1464807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath; 14657b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 146699ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor // Check whether we should precompile the preamble and/or use chained PCH. 146799ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor // FIXME: This is a temporary hack while we debug C++ chained PCH. 146899ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor if (CI->getLangOpts().CPlusPlus) { 146999ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor PrecompilePreamble = PrecompilePreamble && CXXPrecompilePreamble; 147099ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor 147199ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor if (PrecompilePreamble && !CXXChainedPCH && 147299ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor !CI->getPreprocessorOpts().ImplicitPCHInclude.empty()) 147399ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor PrecompilePreamble = false; 147499ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor } 147599ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor 14764cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor // Create the AST unit. 14774cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor llvm::OwningPtr<ASTUnit> AST; 14784cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST.reset(new ASTUnit(false)); 1479e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor ConfigureDiags(Diags, *AST, CaptureDiagnostics); 14804cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->Diagnostics = Diags; 14814cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->OnlyLocalDecls = OnlyLocalDecls; 1482e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor AST->CaptureDiagnostics = CaptureDiagnostics; 14834cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->CompleteTranslationUnit = CompleteTranslationUnit; 14844cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults; 148508bb4c622d0b79c33b4ac78ce1bec79398953daaDouglas Gregor AST->CacheCodeCompletionCoolDown = 1; 14864cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size(); 14874cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->NumStoredDiagnosticsInPreamble = StoredDiagnostics.size(); 14884cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->StoredDiagnostics.swap(StoredDiagnostics); 14894cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor AST->Invocation.reset(CI.take()); 14904cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor return AST->LoadFromCompilerInvocation(PrecompilePreamble)? 0 : AST.take(); 14917b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar} 1492abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1493abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregorbool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) { 1494abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor if (!Invocation.get()) 1495abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 1496abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1497213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer ParsingTimer(WantTiming); 1498edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer ParsingTimer.setOutput("Reparsing " + getMainFileName()); 1499213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor 1500cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Remap files. 1501f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 1502f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 1503f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor R = PPOpts.remapped_file_buffer_begin(), 1504f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor REnd = PPOpts.remapped_file_buffer_end(); 1505f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor R != REnd; 1506f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor ++R) { 1507f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor delete R->second; 1508f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor } 1509cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor Invocation->getPreprocessorOpts().clearRemappedFiles(); 1510cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (unsigned I = 0; I != NumRemappedFiles; ++I) 1511cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, 1512cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor RemappedFiles[I].second); 1513cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1514eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // If we have a preamble file lying around, or if we might try to 1515eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // build a precompiled preamble, do so now. 1516754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor llvm::MemoryBuffer *OverrideMainBuffer = 0; 1517eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor if (!PreambleFile.empty() || PreambleRebuildCounter > 0) 15182283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation); 1519175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1520abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Clear out the diagnostics state. 152132be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor if (!OverrideMainBuffer) { 1522c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getDiagnostics().Reset(); 152332be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts()); 152432be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor } 1525abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1526175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // Parse the sources 1527754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor bool Result = Parse(OverrideMainBuffer); 1528727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor 1529727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor if (ShouldCacheCodeCompletionResults) { 1530727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor if (CacheCodeCompletionCoolDown > 0) 1531727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor --CacheCodeCompletionCoolDown; 1532727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor else if (top_level_size() != NumTopLevelDeclsAtLastCompletionCache) 1533727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor CacheCodeCompletionResults(); 1534727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor } 1535727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor 1536175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor return Result; 1537abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 15381abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 153987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor//----------------------------------------------------------------------------// 154087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor// Code completion 154187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor//----------------------------------------------------------------------------// 154287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 154387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregornamespace { 154487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor /// \brief Code completion consumer that combines the cached code-completion 154587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor /// results from an ASTUnit with the code-completion results provided to it, 154687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor /// then passes the result on to 154787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer { 154887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor unsigned NormalContexts; 154987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor ASTUnit &AST; 155087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CodeCompleteConsumer &Next; 155187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 155287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor public: 155387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next, 15548071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor bool IncludeMacros, bool IncludeCodePatterns, 15558071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor bool IncludeGlobals) 15568071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals, 155787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor Next.isOutputBinary()), AST(AST), Next(Next) 155887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor { 155987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Compute the set of contexts in which we will look when we don't have 156087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // any information about the specific context. 156187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor NormalContexts 156287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor = (1 << (CodeCompletionContext::CCC_TopLevel - 1)) 156387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCInterface - 1)) 156487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCImplementation - 1)) 156587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1)) 156687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_Statement - 1)) 156787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_Expression - 1)) 156887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)) 156987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_MemberAccess - 1)) 15700268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor | (1 << (CodeCompletionContext::CCC_ObjCProtocolName - 1)) 157152779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)) 157252779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor | (1 << (CodeCompletionContext::CCC_Recovery - 1)); 15730268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor 157487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor if (AST.getASTContext().getLangOptions().CPlusPlus) 157587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor NormalContexts |= (1 << (CodeCompletionContext::CCC_EnumTag - 1)) 157687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_UnionTag - 1)) 157787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor | (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1)); 157887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 157987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 158087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor virtual void ProcessCodeCompleteResults(Sema &S, 158187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor CodeCompletionContext Context, 15820a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall CodeCompletionResult *Results, 1583697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor unsigned NumResults); 158487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 158587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, 158687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor OverloadCandidate *Candidates, 158787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor unsigned NumCandidates) { 158887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates); 158987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 159087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor }; 159187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor} 1592697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 15935f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor/// \brief Helper function that computes which global names are hidden by the 15945f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor/// local code-completion results. 1595c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenekstatic void CalculateHiddenNames(const CodeCompletionContext &Context, 1596c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek CodeCompletionResult *Results, 1597c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek unsigned NumResults, 1598c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek ASTContext &Ctx, 1599c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek llvm::StringSet<llvm::BumpPtrAllocator> &HiddenNames){ 16005f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor bool OnlyTagNames = false; 16015f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor switch (Context.getKind()) { 160252779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor case CodeCompletionContext::CCC_Recovery: 16035f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_TopLevel: 16045f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCInterface: 16055f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCImplementation: 16065f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCIvarList: 16075f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ClassStructUnion: 16085f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_Statement: 16095f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_Expression: 16105f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCMessageReceiver: 16115f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_MemberAccess: 16125f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_Namespace: 16135f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_Type: 16142ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor case CodeCompletionContext::CCC_Name: 16152ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor case CodeCompletionContext::CCC_PotentiallyQualifiedName: 16160268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor case CodeCompletionContext::CCC_ParenthesizedExpression: 16175f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor break; 16185f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 16195f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_EnumTag: 16205f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_UnionTag: 16215f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ClassOrStructTag: 16225f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor OnlyTagNames = true; 16235f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor break; 16245f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 16255f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor case CodeCompletionContext::CCC_ObjCProtocolName: 16261fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor case CodeCompletionContext::CCC_MacroName: 16271fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor case CodeCompletionContext::CCC_MacroNameUse: 1628f29c5233085a5af795c3c01b94d319e5b3235d56Douglas Gregor case CodeCompletionContext::CCC_PreprocessorExpression: 1629721f359a350059a81945baa08f63b2e5feceb044Douglas Gregor case CodeCompletionContext::CCC_PreprocessorDirective: 163059a66946aa7723c7b14831aa50902d533baaa957Douglas Gregor case CodeCompletionContext::CCC_NaturalLanguage: 1631458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor case CodeCompletionContext::CCC_SelectorName: 16321a480c403a3b141ab89c9c59cf7b681102a1bfabDouglas Gregor case CodeCompletionContext::CCC_TypeQualifiers: 163352779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor case CodeCompletionContext::CCC_Other: 1634721f359a350059a81945baa08f63b2e5feceb044Douglas Gregor // We're looking for nothing, or we're looking for names that cannot 1635721f359a350059a81945baa08f63b2e5feceb044Douglas Gregor // be hidden. 16365f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor return; 16375f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor } 16385f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 16390a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall typedef CodeCompletionResult Result; 16405f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor for (unsigned I = 0; I != NumResults; ++I) { 16415f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (Results[I].Kind != Result::RK_Declaration) 16425f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor continue; 16435f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 16445f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor unsigned IDNS 16455f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor = Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace(); 16465f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 16475f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor bool Hiding = false; 16485f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (OnlyTagNames) 16495f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor Hiding = (IDNS & Decl::IDNS_Tag); 16505f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor else { 16515f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member | 1652a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Decl::IDNS_Namespace | Decl::IDNS_Ordinary | 1653a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor Decl::IDNS_NonMemberOperator); 16545f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (Ctx.getLangOptions().CPlusPlus) 16555f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenIDNS |= Decl::IDNS_Tag; 16565f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor Hiding = (IDNS & HiddenIDNS); 16575f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor } 16585f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 16595f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (!Hiding) 16605f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor continue; 16615f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 16625f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor DeclarationName Name = Results[I].Declaration->getDeclName(); 16635f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (IdentifierInfo *Identifier = Name.getAsIdentifierInfo()) 16645f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenNames.insert(Identifier->getName()); 16655f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor else 16665f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenNames.insert(Name.getAsString()); 16675f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor } 16685f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor} 16695f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 16705f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 1671697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregorvoid AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S, 1672697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor CodeCompletionContext Context, 16730a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall CodeCompletionResult *Results, 1674697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor unsigned NumResults) { 1675697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // Merge the results we were given with the results we cached. 1676697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor bool AddedResult = false; 16775f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor unsigned InContexts 167852779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor = (Context.getKind() == CodeCompletionContext::CCC_Recovery? NormalContexts 16795f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor : (1 << (Context.getKind() - 1))); 16805f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 16815f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor // Contains the set of names that are hidden by "local" completion results. 1682c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames; 16831fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor llvm::SmallVector<CodeCompletionString *, 4> StringsToDestroy; 16840a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall typedef CodeCompletionResult Result; 1685697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor llvm::SmallVector<Result, 8> AllResults; 1686697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor for (ASTUnit::cached_completion_iterator 16875535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor C = AST.cached_completion_begin(), 16885535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor CEnd = AST.cached_completion_end(); 1689697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor C != CEnd; ++C) { 1690697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // If the context we are in matches any of the contexts we are 1691697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // interested in, we'll add this result. 1692697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if ((C->ShowInContexts & InContexts) == 0) 1693697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor continue; 1694697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 1695697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // If we haven't added any results previously, do so now. 1696697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (!AddedResult) { 16975f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor CalculateHiddenNames(Context, Results, NumResults, S.Context, 16985f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenNames); 1699697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor AllResults.insert(AllResults.end(), Results, Results + NumResults); 1700697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor AddedResult = true; 1701697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 1702697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 17035f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor // Determine whether this global completion result is hidden by a local 17045f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor // completion result. If so, skip it. 17055f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor if (C->Kind != CXCursor_MacroDefinition && 17065f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor HiddenNames.count(C->Completion->getTypedText())) 17075f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor continue; 17085f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor 1709697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // Adjust priority based on similar type classes. 1710697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor unsigned Priority = C->Priority; 17114125c37c71c6c8475019497de837204f0ee4370fDouglas Gregor CXCursorKind CursorKind = C->Kind; 17121fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor CodeCompletionString *Completion = C->Completion; 1713697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (!Context.getPreferredType().isNull()) { 1714697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (C->Kind == CXCursor_MacroDefinition) { 1715697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Priority = getMacroUsagePriority(C->Completion->getTypedText(), 1716b05496dbd63f03bf474dae2c4d1e2142608780ccDouglas Gregor S.getLangOptions(), 17171fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor Context.getPreferredType()->isAnyPointerType()); 1718697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } else if (C->Type) { 1719697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor CanQualType Expected 17205535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor = S.Context.getCanonicalType( 1721697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Context.getPreferredType().getUnqualifiedType()); 1722697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor SimplifiedTypeClass ExpectedSTC = getSimplifiedTypeClass(Expected); 1723697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (ExpectedSTC == C->TypeClass) { 1724697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // We know this type is similar; check for an exact match. 1725697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor llvm::StringMap<unsigned> &CachedCompletionTypes 17265535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor = AST.getCachedCompletionTypes(); 1727697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor llvm::StringMap<unsigned>::iterator Pos 17285535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor = CachedCompletionTypes.find(QualType(Expected).getAsString()); 1729697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type) 1730697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Priority /= CCF_ExactTypeMatch; 1731697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor else 1732697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Priority /= CCF_SimilarTypeMatch; 1733697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 1734697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 1735697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 1736697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 17371fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor // Adjust the completion string, if required. 17381fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor if (C->Kind == CXCursor_MacroDefinition && 17391fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) { 17401fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor // Create a new code-completion string that just contains the 17411fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor // macro name, without its arguments. 17421fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor Completion = new CodeCompletionString; 17431fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor Completion->AddTypedTextChunk(C->Completion->getTypedText()); 17441fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor StringsToDestroy.push_back(Completion); 17454125c37c71c6c8475019497de837204f0ee4370fDouglas Gregor CursorKind = CXCursor_NotImplemented; 17464125c37c71c6c8475019497de837204f0ee4370fDouglas Gregor Priority = CCP_CodePattern; 17471fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor } 17481fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor 17494125c37c71c6c8475019497de837204f0ee4370fDouglas Gregor AllResults.push_back(Result(Completion, Priority, CursorKind, 175058ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor C->Availability)); 1751697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 1752697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 1753697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // If we did not add any cached completion results, just forward the 1754697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor // results we were given to the next consumer. 1755697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor if (!AddedResult) { 1756697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Next.ProcessCodeCompleteResults(S, Context, Results, NumResults); 1757697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor return; 1758697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor } 17591e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor 1760697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor Next.ProcessCodeCompleteResults(S, Context, AllResults.data(), 1761697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor AllResults.size()); 17621fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor 17631fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor for (unsigned I = 0, N = StringsToDestroy.size(); I != N; ++I) 17641fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor delete StringsToDestroy[I]; 1765697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor} 1766697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 1767697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 1768697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor 17691abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregorvoid ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column, 17701abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor RemappedFile *RemappedFiles, 17711abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor unsigned NumRemappedFiles, 1772cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor bool IncludeMacros, 1773cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor bool IncludeCodePatterns, 17741abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor CodeCompleteConsumer &Consumer, 17751abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Diagnostic &Diag, LangOptions &LangOpts, 17761abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor SourceManager &SourceMgr, FileManager &FileMgr, 17772283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics, 17782283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor llvm::SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers) { 17791abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor if (!Invocation.get()) 17801abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor return; 17811abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 1782213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor SimpleTimer CompletionTimer(WantTiming); 1783edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer CompletionTimer.setOutput("Code completion @ " + File + ":" + 1784edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer llvm::Twine(Line) + ":" + llvm::Twine(Column)); 1785df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 17861abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor CompilerInvocation CCInvocation(*Invocation); 17871abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor FrontendOptions &FrontendOpts = CCInvocation.getFrontendOpts(); 17881abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PreprocessorOptions &PreprocessorOpts = CCInvocation.getPreprocessorOpts(); 1789cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor 179087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor FrontendOpts.ShowMacrosInCodeCompletion 179187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor = IncludeMacros && CachedCompletionResults.empty(); 1792cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor FrontendOpts.ShowCodePatternsInCodeCompletion = IncludeCodePatterns; 17938071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor FrontendOpts.ShowGlobalSymbolsInCodeCompletion 17948071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor = CachedCompletionResults.empty(); 17951abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor FrontendOpts.CodeCompletionAt.FileName = File; 17961abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor FrontendOpts.CodeCompletionAt.Line = Line; 17971abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor FrontendOpts.CodeCompletionAt.Column = Column; 17981abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 17991abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set the language options appropriately. 18001abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor LangOpts = CCInvocation.getLangOpts(); 18011abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 18021abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor CompilerInstance Clang; 18031abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.setInvocation(&CCInvocation); 18041abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second; 18051abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 18061abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set up diagnostics, capturing any diagnostics produced. 18071abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.setDiagnostics(&Diag); 180832be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor ProcessWarningOptions(Diag, CCInvocation.getDiagnosticOpts()); 18091abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor CaptureDroppedDiagnostics Capture(true, 1810e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor Clang.getDiagnostics(), 18111abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor StoredDiagnostics); 18121abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 18131abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Create the target instance. 18141abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), 18151abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.getTargetOpts())); 18161abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor if (!Clang.hasTarget()) { 18171abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.takeInvocation(); 1818bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor return; 18191abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor } 18201abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 18211abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Inform the target of the language options. 18221abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // 18231abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // FIXME: We shouldn't need to do this, the target should be immutable once 18241abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // created. This complexity should be lifted elsewhere. 18251abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.getTarget().setForcedLangOptions(Clang.getLangOpts()); 18261abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 18271abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor assert(Clang.getFrontendOpts().Inputs.size() == 1 && 18281abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor "Invocation must have exactly one source file!"); 18291abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor assert(Clang.getFrontendOpts().Inputs[0].first != IK_AST && 18301abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor "FIXME: AST inputs not yet supported here!"); 18311abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor assert(Clang.getFrontendOpts().Inputs[0].first != IK_LLVM_IR && 18321abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor "IR inputs not support here!"); 18331abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 18341abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 18351abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Use the source and file managers that we were given. 18361abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.setFileManager(&FileMgr); 18371abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.setSourceManager(&SourceMgr); 18381abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 18391abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Remap files. 18401abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PreprocessorOpts.clearRemappedFiles(); 1841b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor PreprocessorOpts.RetainRemappedFileBuffers = true; 18422283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor for (unsigned I = 0; I != NumRemappedFiles; ++I) { 18431abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, 18441abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor RemappedFiles[I].second); 18452283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor OwnedBuffers.push_back(RemappedFiles[I].second); 18462283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor } 18471abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 184887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // Use the code completion consumer we were given, but adding any cached 184987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor // code-completion results. 185087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor AugmentedCodeCompleteConsumer 185187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor AugmentedConsumer(*this, Consumer, FrontendOpts.ShowMacrosInCodeCompletion, 18528071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor FrontendOpts.ShowCodePatternsInCodeCompletion, 18538071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor FrontendOpts.ShowGlobalSymbolsInCodeCompletion); 185487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor Clang.setCodeCompletionConsumer(&AugmentedConsumer); 18551abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 1856df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // If we have a precompiled preamble, try to use it. We only allow 1857df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // the use of the precompiled preamble if we're if the completion 1858df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // point is within the main file, after the end of the precompiled 1859df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // preamble. 1860df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor llvm::MemoryBuffer *OverrideMainBuffer = 0; 1861df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (!PreambleFile.empty()) { 1862df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor using llvm::sys::FileStatus; 1863df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor llvm::sys::PathWithStatus CompleteFilePath(File); 1864df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor llvm::sys::PathWithStatus MainPath(OriginalSourceFile); 1865df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (const FileStatus *CompleteFileStatus = CompleteFilePath.getFileStatus()) 1866df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (const FileStatus *MainStatus = MainPath.getFileStatus()) 1867df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (CompleteFileStatus->getUniqueID() == MainStatus->getUniqueID()) 18682283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor OverrideMainBuffer 1869c9c29a8d7a0f78ddf2b393dd92f77c7f2046179cDouglas Gregor = getMainBufferWithPrecompiledPreamble(CCInvocation, false, 1870c9c29a8d7a0f78ddf2b393dd92f77c7f2046179cDouglas Gregor Line - 1); 1871df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 1872df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 1873df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // If the main file has been overridden due to the use of a preamble, 1874df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // make that override happen and introduce the preamble. 18754cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor StoredDiagnostics.insert(StoredDiagnostics.end(), 18764cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor this->StoredDiagnostics.begin(), 18774cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor this->StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver); 1878df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (OverrideMainBuffer) { 1879df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); 1880df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size(); 1881df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second 1882df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor = PreambleEndsAtStartOfLine; 1883df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.ImplicitPCHInclude = PreambleFile; 1884df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.DisablePCHValidation = true; 1885df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 1886df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // The stored diagnostics have the old source manager. Copy them 1887df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // to our output set of stored diagnostics, updating the source 1888df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // manager to the one we were given. 18894cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor for (unsigned I = NumStoredDiagnosticsFromDriver, 18904cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor N = this->StoredDiagnostics.size(); 18914cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor I < N; ++I) { 1892df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor StoredDiagnostics.push_back(this->StoredDiagnostics[I]); 1893df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor FullSourceLoc Loc(StoredDiagnostics[I].getLocation(), SourceMgr); 1894df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor StoredDiagnostics[I].setLocation(Loc); 1895df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 18964cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 18972283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor OwnedBuffers.push_back(OverrideMainBuffer); 1898f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor } else { 1899f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = 0; 1900f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second = false; 1901df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 1902df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 19031abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor llvm::OwningPtr<SyntaxOnlyAction> Act; 19041abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Act.reset(new SyntaxOnlyAction); 19051abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor if (Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second, 19061abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.getFrontendOpts().Inputs[0].first)) { 19071abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Act->Execute(); 19081abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Act->EndSourceFile(); 19091abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor } 1910df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 19111abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Steal back our resources. 19121abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.takeFileManager(); 19131abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.takeSourceManager(); 19141abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.takeInvocation(); 19151abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.takeCodeCompletionConsumer(); 19161abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor} 19177ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor 19187ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregorbool ASTUnit::Save(llvm::StringRef File) { 19197ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor if (getDiagnostics().hasErrorOccurred()) 19207ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor return true; 19217ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor 19227ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor // FIXME: Can we somehow regenerate the stat cache here, or do we need to 19237ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor // unconditionally create a stat cache when we parse the file? 19247ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor std::string ErrorInfo; 19251395c5d00588a9c3154683ffe6c223bb7af2fbf2Benjamin Kramer llvm::raw_fd_ostream Out(File.str().c_str(), ErrorInfo, 19261395c5d00588a9c3154683ffe6c223bb7af2fbf2Benjamin Kramer llvm::raw_fd_ostream::F_Binary); 19277ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor if (!ErrorInfo.empty() || Out.has_error()) 19287ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor return true; 19297ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor 19307ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor std::vector<unsigned char> Buffer; 19317ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor llvm::BitstreamWriter Stream(Buffer); 1932a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl ASTWriter Writer(Stream); 1933a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl Writer.WriteAST(getSema(), 0, 0); 19347ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor 19357ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor // Write the generated bitstream to "Out". 1936bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor if (!Buffer.empty()) 1937bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor Out.write((char *)&Buffer.front(), Buffer.size()); 19387ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor Out.close(); 19397ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor return Out.has_error(); 19407ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor} 1941