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