diff options
Diffstat (limited to 'lib/Frontend/ASTUnit.cpp')
| -rw-r--r-- | lib/Frontend/ASTUnit.cpp | 355 | 
1 files changed, 160 insertions, 195 deletions
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index fc44d9f1b4c0..a3998fa351de 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -105,7 +105,8 @@ static llvm::sys::SmartMutex<false> &getOnDiskMutex() {  static void cleanupOnDiskMapAtExit(); -typedef llvm::DenseMap<const ASTUnit *, OnDiskData *> OnDiskDataMap; +typedef llvm::DenseMap<const ASTUnit *, +                       std::unique_ptr<OnDiskData>> OnDiskDataMap;  static OnDiskDataMap &getOnDiskDataMap() {    static OnDiskDataMap M;    static bool hasRegisteredAtExit = false; @@ -132,9 +133,9 @@ static OnDiskData &getOnDiskData(const ASTUnit *AU) {    // DenseMap.    llvm::MutexGuard Guard(getOnDiskMutex());    OnDiskDataMap &M = getOnDiskDataMap(); -  OnDiskData *&D = M[AU]; +  auto &D = M[AU];    if (!D) -    D = new OnDiskData(); +    D = llvm::make_unique<OnDiskData>();    return *D;  } @@ -150,7 +151,6 @@ static void removeOnDiskEntry(const ASTUnit *AU) {    OnDiskDataMap::iterator I = M.find(AU);    if (I != M.end()) {      I->second->Cleanup(); -    delete I->second;      M.erase(AU);    }  } @@ -219,8 +219,8 @@ ASTUnit::ASTUnit(bool _MainFileIsAST)      TUKind(TU_Complete), WantTiming(getenv("LIBCLANG_TIMING")),      OwnsRemappedFileBuffers(true),      NumStoredDiagnosticsFromDriver(0), -    PreambleRebuildCounter(0), SavedMainFileBuffer(nullptr), -    PreambleBuffer(nullptr), NumWarningsInPreamble(0), +    PreambleRebuildCounter(0), +    NumWarningsInPreamble(0),      ShouldCacheCodeCompletionResults(false),      IncludeBriefCommentsInCodeCompletion(false), UserFilesAreVolatile(false),      CompletionCacheTopLevelHashValue(0), @@ -251,9 +251,6 @@ ASTUnit::~ASTUnit() {      for (const auto &RB : PPOpts.RemappedFileBuffers)        delete RB.second;    } -   -  delete SavedMainFileBuffer; -  delete PreambleBuffer;    ClearCachedCompletionResults();   @@ -511,8 +508,8 @@ public:        : PP(PP), Context(Context), LangOpt(LangOpt), TargetOpts(TargetOpts),          Target(Target), Counter(Counter), InitializedLanguage(false) {} -  bool ReadLanguageOptions(const LangOptions &LangOpts, -                           bool Complain) override { +  bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain, +                           bool AllowCompatibleDifferences) override {      if (InitializedLanguage)        return false; @@ -592,6 +589,7 @@ class CaptureDroppedDiagnostics {    DiagnosticsEngine &Diags;    StoredDiagnosticConsumer Client;    DiagnosticConsumer *PreviousClient; +  std::unique_ptr<DiagnosticConsumer> OwningPreviousClient;  public:    CaptureDroppedDiagnostics(bool RequestCapture, DiagnosticsEngine &Diags, @@ -599,16 +597,15 @@ public:      : Diags(Diags), Client(StoredDiags), PreviousClient(nullptr)    {      if (RequestCapture || Diags.getClient() == nullptr) { -      PreviousClient = Diags.takeClient(); -      Diags.setClient(&Client); +      OwningPreviousClient = Diags.takeClient(); +      PreviousClient = Diags.getClient(); +      Diags.setClient(&Client, false);      }    }    ~CaptureDroppedDiagnostics() { -    if (Diags.getClient() == &Client) { -      Diags.takeClient(); -      Diags.setClient(PreviousClient); -    } +    if (Diags.getClient() == &Client) +      Diags.setClient(PreviousClient, !!OwningPreviousClient.release());    }  }; @@ -638,38 +635,30 @@ ASTDeserializationListener *ASTUnit::getDeserializationListener() {    return nullptr;  } -llvm::MemoryBuffer *ASTUnit::getBufferForFile(StringRef Filename, -                                              std::string *ErrorStr) { +std::unique_ptr<llvm::MemoryBuffer> +ASTUnit::getBufferForFile(StringRef Filename, std::string *ErrorStr) {    assert(FileMgr); -  return FileMgr->getBufferForFile(Filename, ErrorStr); +  auto Buffer = FileMgr->getBufferForFile(Filename); +  if (Buffer) +    return std::move(*Buffer); +  if (ErrorStr) +    *ErrorStr = Buffer.getError().message(); +  return nullptr;  }  /// \brief Configure the diagnostics object for use with ASTUnit. -void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> &Diags, -                             const char **ArgBegin, const char **ArgEnd, +void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,                               ASTUnit &AST, bool CaptureDiagnostics) { -  if (!Diags.get()) { -    // No diagnostics engine was provided, so create our own diagnostics object -    // with the default options. -    DiagnosticConsumer *Client = nullptr; -    if (CaptureDiagnostics) -      Client = new StoredDiagnosticConsumer(AST.StoredDiagnostics); -    Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions(), -                                                Client, -                                                /*ShouldOwnClient=*/true); -  } else if (CaptureDiagnostics) { +  assert(Diags.get() && "no DiagnosticsEngine was provided"); +  if (CaptureDiagnostics)      Diags->setClient(new StoredDiagnosticConsumer(AST.StoredDiagnostics)); -  }  } -ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, -                              IntrusiveRefCntPtr<DiagnosticsEngine> Diags, -                                  const FileSystemOptions &FileSystemOpts, -                                  bool OnlyLocalDecls, -                                  ArrayRef<RemappedFile> RemappedFiles, -                                  bool CaptureDiagnostics, -                                  bool AllowPCHWithCompilerErrors, -                                  bool UserFilesAreVolatile) { +std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( +    const std::string &Filename, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, +    const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls, +    ArrayRef<RemappedFile> RemappedFiles, bool CaptureDiagnostics, +    bool AllowPCHWithCompilerErrors, bool UserFilesAreVolatile) {    std::unique_ptr<ASTUnit> AST(new ASTUnit(true));    // Recover resources if we crash before exiting this method. @@ -679,7 +668,7 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename,      llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >      DiagCleanup(Diags.get()); -  ConfigureDiags(Diags, nullptr, nullptr, *AST, CaptureDiagnostics); +  ConfigureDiags(Diags, *AST, CaptureDiagnostics);    AST->OnlyLocalDecls = OnlyLocalDecls;    AST->CaptureDiagnostics = CaptureDiagnostics; @@ -705,7 +694,7 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename,    // Gather Info for preprocessor construction later on. -  HeaderSearch &HeaderInfo = *AST->HeaderInfo.get(); +  HeaderSearch &HeaderInfo = *AST->HeaderInfo;    unsigned Counter;    AST->PP = @@ -728,10 +717,9 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename,                               /*DisableValidation=*/disableValid,                               AllowPCHWithCompilerErrors); -  AST->Reader->setListener(new ASTInfoCollector(*AST->PP, Context, -                                           AST->ASTFileLangOpts, -                                           AST->TargetOpts, AST->Target,  -                                           Counter)); +  AST->Reader->setListener(llvm::make_unique<ASTInfoCollector>( +      *AST->PP, Context, AST->ASTFileLangOpts, AST->TargetOpts, AST->Target, +      Counter));    switch (AST->Reader->ReadAST(Filename, serialization::MK_MainFile,                            SourceLocation(), ASTReader::ARR_None)) { @@ -768,7 +756,7 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename,    // Tell the diagnostic client that we have started a source file.    AST->getDiagnostics().getClient()->BeginSourceFile(Context.getLangOpts(),&PP); -  return AST.release(); +  return AST;  }  namespace { @@ -891,12 +879,13 @@ class TopLevelDeclTrackerAction : public ASTFrontendAction {  public:    ASTUnit &Unit; -  ASTConsumer *CreateASTConsumer(CompilerInstance &CI, -                                 StringRef InFile) override { +  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, +                                                 StringRef InFile) override {      CI.getPreprocessor().addPPCallbacks( -     new MacroDefinitionTrackerPPCallbacks(Unit.getCurrentTopLevelHashValue())); -    return new TopLevelDeclTrackerConsumer(Unit,  -                                           Unit.getCurrentTopLevelHashValue()); +        llvm::make_unique<MacroDefinitionTrackerPPCallbacks>( +                                           Unit.getCurrentTopLevelHashValue())); +    return llvm::make_unique<TopLevelDeclTrackerConsumer>( +        Unit, Unit.getCurrentTopLevelHashValue());    }  public: @@ -916,8 +905,8 @@ public:    explicit PrecompilePreambleAction(ASTUnit &Unit)        : Unit(Unit), HasEmittedPreamblePCH(false) {} -  ASTConsumer *CreateASTConsumer(CompilerInstance &CI, -                                 StringRef InFile) override; +  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, +                                                 StringRef InFile) override;    bool hasEmittedPreamblePCH() const { return HasEmittedPreamblePCH; }    void setHasEmittedPreamblePCH() { HasEmittedPreamblePCH = true; }    bool shouldEraseOutputFiles() override { return !hasEmittedPreamblePCH(); } @@ -979,8 +968,9 @@ public:  } -ASTConsumer *PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI, -                                                         StringRef InFile) { +std::unique_ptr<ASTConsumer> +PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI, +                                            StringRef InFile) {    std::string Sysroot;    std::string OutputFile;    raw_ostream *OS = nullptr; @@ -991,10 +981,11 @@ ASTConsumer *PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI,    if (!CI.getFrontendOpts().RelocatablePCH)      Sysroot.clear(); -  CI.getPreprocessor().addPPCallbacks(new MacroDefinitionTrackerPPCallbacks( -      Unit.getCurrentTopLevelHashValue())); -  return new PrecompilePreambleConsumer(Unit, this, CI.getPreprocessor(), -                                        Sysroot, OS); +  CI.getPreprocessor().addPPCallbacks( +      llvm::make_unique<MacroDefinitionTrackerPPCallbacks>( +                                           Unit.getCurrentTopLevelHashValue())); +  return llvm::make_unique<PrecompilePreambleConsumer>( +      Unit, this, CI.getPreprocessor(), Sysroot, OS);  }  static bool isNonDriverDiag(const StoredDiagnostic &StoredDiag) { @@ -1031,15 +1022,12 @@ static void checkAndSanitizeDiags(SmallVectorImpl<StoredDiagnostic> &  ///  /// \returns True if a failure occurred that causes the ASTUnit not to  /// contain any translation-unit information, false otherwise. -bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { -  delete SavedMainFileBuffer; -  SavedMainFileBuffer = nullptr; +bool ASTUnit::Parse(std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer) { +  SavedMainFileBuffer.reset(); -  if (!Invocation) { -    delete OverrideMainBuffer; +  if (!Invocation)      return true; -  } -   +    // Create the compiler instance to use for building the AST.    std::unique_ptr<CompilerInstance> Clang(new CompilerInstance()); @@ -1060,10 +1048,8 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {    // Create the target instance.    Clang->setTarget(TargetInfo::CreateTargetInfo(        Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); -  if (!Clang->hasTarget()) { -    delete OverrideMainBuffer; +  if (!Clang->hasTarget())      return true; -  }    // Inform the target of the language options.    // @@ -1083,10 +1069,8 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {    FileSystemOpts = Clang->getFileSystemOpts();    IntrusiveRefCntPtr<vfs::FileSystem> VFS =        createVFSFromCompilerInvocation(Clang->getInvocation(), getDiagnostics()); -  if (!VFS) { -    delete OverrideMainBuffer; +  if (!VFS)      return true; -  }    FileMgr = new FileManager(FileSystemOpts, VFS);    SourceMgr = new SourceManager(getDiagnostics(), *FileMgr,                                  UserFilesAreVolatile); @@ -1115,7 +1099,8 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {    // make that override happen and introduce the preamble.    PreprocessorOptions &PreprocessorOpts = Clang->getPreprocessorOpts();    if (OverrideMainBuffer) { -    PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); +    PreprocessorOpts.addRemappedFile(OriginalSourceFile, +                                     OverrideMainBuffer.get());      PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size();      PreprocessorOpts.PrecompiledPreambleBytes.second                                                      = PreambleEndsAtStartOfLine; @@ -1130,7 +1115,7 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {      checkAndSanitizeDiags(StoredDiagnostics, getSourceManager());      // Keep track of the override buffer; -    SavedMainFileBuffer = OverrideMainBuffer; +    SavedMainFileBuffer = std::move(OverrideMainBuffer);    }    std::unique_ptr<TopLevelDeclTrackerAction> Act( @@ -1143,7 +1128,7 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {    if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))      goto error; -  if (OverrideMainBuffer) { +  if (SavedMainFileBuffer) {      std::string ModName = getPreambleFile(this);      TranslateStoredDiagnostics(getFileManager(), getSourceManager(),                                 PreambleDiagnostics, StoredDiagnostics); @@ -1162,10 +1147,7 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {  error:    // Remove the overridden buffer we used for the preamble. -  if (OverrideMainBuffer) { -    delete OverrideMainBuffer; -    SavedMainFileBuffer = nullptr; -  } +  SavedMainFileBuffer = nullptr;    // Keep the ownership of the data in the ASTUnit because the client may    // want to see the diagnostics. @@ -1194,17 +1176,16 @@ static std::string GetPreamblePCHPath() {  /// \brief Compute the preamble for the main file, providing the source buffer  /// that corresponds to the main file along with a pair (bytes, start-of-line)  /// that describes the preamble. -std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> >  -ASTUnit::ComputePreamble(CompilerInvocation &Invocation,  -                         unsigned MaxLines, bool &CreatedBuffer) { +ASTUnit::ComputedPreamble +ASTUnit::ComputePreamble(CompilerInvocation &Invocation, unsigned MaxLines) {    FrontendOptions &FrontendOpts = Invocation.getFrontendOpts();    PreprocessorOptions &PreprocessorOpts = Invocation.getPreprocessorOpts(); -  CreatedBuffer = false;    // Try to determine if the main file has been remapped, either from the     // command line (to another file) or directly through the compiler invocation    // (to a memory buffer).    llvm::MemoryBuffer *Buffer = nullptr; +  std::unique_ptr<llvm::MemoryBuffer> BufferOwner;    std::string MainFilePath(FrontendOpts.Inputs[0].getFile());    llvm::sys::fs::UniqueID MainFileID;    if (!llvm::sys::fs::getUniqueID(MainFilePath, MainFileID)) { @@ -1215,15 +1196,9 @@ ASTUnit::ComputePreamble(CompilerInvocation &Invocation,        if (!llvm::sys::fs::getUniqueID(MPath, MID)) {          if (MainFileID == MID) {            // We found a remapping. Try to load the resulting, remapped source. -          if (CreatedBuffer) { -            delete Buffer; -            CreatedBuffer = false; -          } - -          Buffer = getBufferForFile(RF.second); -          if (!Buffer) -            return std::make_pair(nullptr, std::make_pair(0, true)); -          CreatedBuffer = true; +          BufferOwner = getBufferForFile(RF.second); +          if (!BufferOwner) +            return ComputedPreamble(nullptr, nullptr, 0, true);          }        }      } @@ -1236,11 +1211,7 @@ ASTUnit::ComputePreamble(CompilerInvocation &Invocation,        if (!llvm::sys::fs::getUniqueID(MPath, MID)) {          if (MainFileID == MID) {            // We found a remapping. -          if (CreatedBuffer) { -            delete Buffer; -            CreatedBuffer = false; -          } - +          BufferOwner.reset();            Buffer = const_cast<llvm::MemoryBuffer *>(RB.second);          }        } @@ -1248,17 +1219,18 @@ ASTUnit::ComputePreamble(CompilerInvocation &Invocation,    }    // If the main source file was not remapped, load it now. -  if (!Buffer) { -    Buffer = getBufferForFile(FrontendOpts.Inputs[0].getFile()); -    if (!Buffer) -      return std::make_pair(nullptr, std::make_pair(0, true)); - -    CreatedBuffer = true; +  if (!Buffer && !BufferOwner) { +    BufferOwner = getBufferForFile(FrontendOpts.Inputs[0].getFile()); +    if (!BufferOwner) +      return ComputedPreamble(nullptr, nullptr, 0, true);    } -   -  return std::make_pair(Buffer, Lexer::ComputePreamble(Buffer, -                                                       *Invocation.getLangOpts(), -                                                       MaxLines)); + +  if (!Buffer) +    Buffer = BufferOwner.get(); +  auto Pre = Lexer::ComputePreamble(Buffer->getBuffer(), +                                    *Invocation.getLangOpts(), MaxLines); +  return ComputedPreamble(Buffer, std::move(BufferOwner), Pre.first, +                          Pre.second);  }  ASTUnit::PreambleFileHash @@ -1300,42 +1272,44 @@ makeStandaloneRange(CharSourceRange Range, const SourceManager &SM,    return std::make_pair(Offset, EndOffset);  } -static void makeStandaloneFixIt(const SourceManager &SM, -                                const LangOptions &LangOpts, -                                const FixItHint &InFix, -                                ASTUnit::StandaloneFixIt &OutFix) { +static ASTUnit::StandaloneFixIt makeStandaloneFixIt(const SourceManager &SM, +                                                    const LangOptions &LangOpts, +                                                    const FixItHint &InFix) { +  ASTUnit::StandaloneFixIt OutFix;    OutFix.RemoveRange = makeStandaloneRange(InFix.RemoveRange, SM, LangOpts);    OutFix.InsertFromRange = makeStandaloneRange(InFix.InsertFromRange, SM,                                                 LangOpts);    OutFix.CodeToInsert = InFix.CodeToInsert;    OutFix.BeforePreviousInsertions = InFix.BeforePreviousInsertions; +  return OutFix;  } -static void makeStandaloneDiagnostic(const LangOptions &LangOpts, -                                     const StoredDiagnostic &InDiag, -                                     ASTUnit::StandaloneDiagnostic &OutDiag) { +static ASTUnit::StandaloneDiagnostic +makeStandaloneDiagnostic(const LangOptions &LangOpts, +                         const StoredDiagnostic &InDiag) { +  ASTUnit::StandaloneDiagnostic OutDiag;    OutDiag.ID = InDiag.getID();    OutDiag.Level = InDiag.getLevel();    OutDiag.Message = InDiag.getMessage();    OutDiag.LocOffset = 0;    if (InDiag.getLocation().isInvalid()) -    return; +    return OutDiag;    const SourceManager &SM = InDiag.getLocation().getManager();    SourceLocation FileLoc = SM.getFileLoc(InDiag.getLocation());    OutDiag.Filename = SM.getFilename(FileLoc);    if (OutDiag.Filename.empty()) -    return; +    return OutDiag;    OutDiag.LocOffset = SM.getFileOffset(FileLoc);    for (StoredDiagnostic::range_iterator           I = InDiag.range_begin(), E = InDiag.range_end(); I != E; ++I) {      OutDiag.Ranges.push_back(makeStandaloneRange(*I, SM, LangOpts));    } -  for (StoredDiagnostic::fixit_iterator -         I = InDiag.fixit_begin(), E = InDiag.fixit_end(); I != E; ++I) { -    ASTUnit::StandaloneFixIt Fix; -    makeStandaloneFixIt(SM, LangOpts, *I, Fix); -    OutDiag.FixIts.push_back(Fix); -  } +  for (StoredDiagnostic::fixit_iterator I = InDiag.fixit_begin(), +                                        E = InDiag.fixit_end(); +       I != E; ++I) +    OutDiag.FixIts.push_back(makeStandaloneFixIt(SM, LangOpts, *I)); + +  return OutDiag;  }  /// \brief Attempt to build or re-use a precompiled preamble when (re-)parsing @@ -1358,27 +1332,20 @@ static void makeStandaloneDiagnostic(const LangOptions &LangOpts,  /// \returns If the precompiled preamble can be used, returns a newly-allocated  /// buffer that should be used in place of the main file when doing so.  /// Otherwise, returns a NULL pointer. -llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( -                              const CompilerInvocation &PreambleInvocationIn, -                                                           bool AllowRebuild, -                                                           unsigned MaxLines) { -   +std::unique_ptr<llvm::MemoryBuffer> +ASTUnit::getMainBufferWithPrecompiledPreamble( +    const CompilerInvocation &PreambleInvocationIn, bool AllowRebuild, +    unsigned MaxLines) { +    IntrusiveRefCntPtr<CompilerInvocation>      PreambleInvocation(new CompilerInvocation(PreambleInvocationIn));    FrontendOptions &FrontendOpts = PreambleInvocation->getFrontendOpts();    PreprocessorOptions &PreprocessorOpts      = PreambleInvocation->getPreprocessorOpts(); -  bool CreatedPreambleBuffer = false; -  std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > NewPreamble  -    = ComputePreamble(*PreambleInvocation, MaxLines, CreatedPreambleBuffer); - -  // If ComputePreamble() Take ownership of the preamble buffer. -  std::unique_ptr<llvm::MemoryBuffer> OwnedPreambleBuffer; -  if (CreatedPreambleBuffer) -    OwnedPreambleBuffer.reset(NewPreamble.first); +  ComputedPreamble NewPreamble = ComputePreamble(*PreambleInvocation, MaxLines); -  if (!NewPreamble.second.first) { +  if (!NewPreamble.Size) {      // We couldn't find a preamble in the main source. Clear out the current      // preamble, if we have one. It's obviously no good any more.      Preamble.clear(); @@ -1394,10 +1361,10 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(      // preamble now that we did before, and that there's enough space in      // the main-file buffer within the precompiled preamble to fit the      // new main file. -    if (Preamble.size() == NewPreamble.second.first && -        PreambleEndsAtStartOfLine == NewPreamble.second.second && -        memcmp(Preamble.getBufferStart(), NewPreamble.first->getBufferStart(), -               NewPreamble.second.first) == 0) { +    if (Preamble.size() == NewPreamble.Size && +        PreambleEndsAtStartOfLine == NewPreamble.PreambleEndsAtStartOfLine && +        memcmp(Preamble.getBufferStart(), NewPreamble.Buffer->getBufferStart(), +               NewPreamble.Size) == 0) {        // The preamble has not changed. We may be able to re-use the precompiled        // preamble. @@ -1467,7 +1434,7 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(          getDiagnostics().setNumWarnings(NumWarningsInPreamble);          return llvm::MemoryBuffer::getMemBufferCopy( -            NewPreamble.first->getBuffer(), FrontendOpts.Inputs[0].getFile()); +            NewPreamble.Buffer->getBuffer(), FrontendOpts.Inputs[0].getFile());        }      } @@ -1512,19 +1479,16 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(    // subsequent reparses.    StringRef MainFilename = FrontendOpts.Inputs[0].getFile();    Preamble.assign(FileMgr->getFile(MainFilename), -                  NewPreamble.first->getBufferStart(),  -                  NewPreamble.first->getBufferStart()  -                                                  + NewPreamble.second.first); -  PreambleEndsAtStartOfLine = NewPreamble.second.second; +                  NewPreamble.Buffer->getBufferStart(), +                  NewPreamble.Buffer->getBufferStart() + NewPreamble.Size); +  PreambleEndsAtStartOfLine = NewPreamble.PreambleEndsAtStartOfLine; -  delete PreambleBuffer; -  PreambleBuffer -    = llvm::MemoryBuffer::getMemBufferCopy( -        NewPreamble.first->getBuffer().slice(0, Preamble.size()), MainFilename); +  PreambleBuffer = llvm::MemoryBuffer::getMemBufferCopy( +      NewPreamble.Buffer->getBuffer().slice(0, Preamble.size()), MainFilename);    // Remap the main source file to the preamble buffer.    StringRef MainFilePath = FrontendOpts.Inputs[0].getFile(); -  PreprocessorOpts.addRemappedFile(MainFilePath, PreambleBuffer); +  PreprocessorOpts.addRemappedFile(MainFilePath, PreambleBuffer.get());    // Tell the compiler invocation to generate a temporary precompiled header.    FrontendOpts.ProgramAction = frontend::GeneratePCH; @@ -1607,13 +1571,11 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(    // Transfer any diagnostics generated when parsing the preamble into the set    // of preamble diagnostics. -  for (stored_diag_iterator -         I = stored_diag_afterDriver_begin(), -         E = stored_diag_end(); I != E; ++I) { -    StandaloneDiagnostic Diag; -    makeStandaloneDiagnostic(Clang->getLangOpts(), *I, Diag); -    PreambleDiagnostics.push_back(Diag); -  } +  for (stored_diag_iterator I = stored_diag_afterDriver_begin(), +                            E = stored_diag_end(); +       I != E; ++I) +    PreambleDiagnostics.push_back( +        makeStandaloneDiagnostic(Clang->getLangOpts(), *I));    Act->EndSourceFile(); @@ -1663,8 +1625,8 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(      CompletionCacheTopLevelHashValue = 0;      PreambleTopLevelHashValue = CurrentTopLevelHashValue;    } -   -  return llvm::MemoryBuffer::getMemBufferCopy(NewPreamble.first->getBuffer(), + +  return llvm::MemoryBuffer::getMemBufferCopy(NewPreamble.Buffer->getBuffer(),                                                MainFilename);  } @@ -1688,8 +1650,8 @@ void ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) {    // created.    assert(CI.hasInvocation() && "missing invocation");    LangOpts = CI.getInvocation().LangOpts; -  TheSema.reset(CI.takeSema()); -  Consumer.reset(CI.takeASTConsumer()); +  TheSema = CI.takeSema(); +  Consumer = CI.takeASTConsumer();    if (CI.hasASTContext())      Ctx = &CI.getASTContext();    if (CI.hasPreprocessor()) @@ -1735,7 +1697,7 @@ ASTUnit *ASTUnit::create(CompilerInvocation *CI,                           bool UserFilesAreVolatile) {    std::unique_ptr<ASTUnit> AST;    AST.reset(new ASTUnit(false)); -  ConfigureDiags(Diags, nullptr, nullptr, *AST, CaptureDiagnostics); +  ConfigureDiags(Diags, *AST, CaptureDiagnostics);    AST->Diagnostics = Diags;    AST->Invocation = CI;    AST->FileSystemOpts = CI->getFileSystemOpts(); @@ -1862,13 +1824,15 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(    if (Persistent && !TrackerAct) {      Clang->getPreprocessor().addPPCallbacks( -     new MacroDefinitionTrackerPPCallbacks(AST->getCurrentTopLevelHashValue())); -    std::vector<ASTConsumer*> Consumers; +        llvm::make_unique<MacroDefinitionTrackerPPCallbacks>( +                                           AST->getCurrentTopLevelHashValue())); +    std::vector<std::unique_ptr<ASTConsumer>> Consumers;      if (Clang->hasASTConsumer())        Consumers.push_back(Clang->takeASTConsumer()); -    Consumers.push_back(new TopLevelDeclTrackerConsumer(*AST, -                                           AST->getCurrentTopLevelHashValue())); -    Clang->setASTConsumer(new MultiplexConsumer(Consumers)); +    Consumers.push_back(llvm::make_unique<TopLevelDeclTrackerConsumer>( +        *AST, AST->getCurrentTopLevelHashValue())); +    Clang->setASTConsumer( +        llvm::make_unique<MultiplexConsumer>(std::move(Consumers)));    }    if (!Act->Execute()) {      AST->transferASTDataFromCompilerInstance(*Clang); @@ -1898,11 +1862,10 @@ bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) {    Invocation->getFrontendOpts().DisableFree = false;    ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts()); -  llvm::MemoryBuffer *OverrideMainBuffer = nullptr; +  std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;    if (PrecompilePreamble) {      PreambleRebuildCounter = 2; -    OverrideMainBuffer -      = getMainBufferWithPrecompiledPreamble(*Invocation); +    OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation);    }    SimpleTimer ParsingTimer(WantTiming); @@ -1910,9 +1873,9 @@ bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) {    // Recover resources if we crash before exiting this method.    llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer> -    MemBufferCleanup(OverrideMainBuffer); -   -  return Parse(OverrideMainBuffer); +    MemBufferCleanup(OverrideMainBuffer.get()); + +  return Parse(std::move(OverrideMainBuffer));  }  std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation( @@ -1922,7 +1885,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(      bool IncludeBriefCommentsInCodeCompletion, bool UserFilesAreVolatile) {    // Create the AST unit.    std::unique_ptr<ASTUnit> AST(new ASTUnit(false)); -  ConfigureDiags(Diags, nullptr, nullptr, *AST, CaptureDiagnostics); +  ConfigureDiags(Diags, *AST, CaptureDiagnostics);    AST->Diagnostics = Diags;    AST->OnlyLocalDecls = OnlyLocalDecls;    AST->CaptureDiagnostics = CaptureDiagnostics; @@ -1961,11 +1924,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(      bool AllowPCHWithCompilerErrors, bool SkipFunctionBodies,      bool UserFilesAreVolatile, bool ForSerialization,      std::unique_ptr<ASTUnit> *ErrAST) { -  if (!Diags.get()) { -    // No diagnostics engine was provided, so create our own diagnostics object -    // with the default options. -    Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions()); -  } +  assert(Diags.get() && "no DiagnosticsEngine was provided");    SmallVector<StoredDiagnostic, 4> StoredDiagnostics; @@ -2000,9 +1959,8 @@ ASTUnit *ASTUnit::LoadFromCommandLine(    // Create the AST unit.    std::unique_ptr<ASTUnit> AST;    AST.reset(new ASTUnit(false)); -  ConfigureDiags(Diags, ArgBegin, ArgEnd, *AST, CaptureDiagnostics); +  ConfigureDiags(Diags, *AST, CaptureDiagnostics);    AST->Diagnostics = Diags; -  Diags = nullptr; // Zero out now to ease cleanup during crash recovery.    AST->FileSystemOpts = CI->getFileSystemOpts();    IntrusiveRefCntPtr<vfs::FileSystem> VFS =        createVFSFromCompilerInvocation(*CI, *Diags); @@ -2021,7 +1979,9 @@ ASTUnit *ASTUnit::LoadFromCommandLine(    AST->Invocation = CI;    if (ForSerialization)      AST->WriterData.reset(new ASTWriterData()); -  CI = nullptr; // Zero out now to ease cleanup during crash recovery. +  // Zero out now to ease cleanup during crash recovery. +  CI = nullptr; +  Diags = nullptr;    // Recover resources if we crash before exiting this method.    llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> @@ -2062,7 +2022,7 @@ bool ASTUnit::Reparse(ArrayRef<RemappedFile> RemappedFiles) {    // If we have a preamble file lying around, or if we might try to    // build a precompiled preamble, do so now. -  llvm::MemoryBuffer *OverrideMainBuffer = nullptr; +  std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;    if (!getPreambleFile(this).empty() || PreambleRebuildCounter > 0)      OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation); @@ -2073,8 +2033,8 @@ bool ASTUnit::Reparse(ArrayRef<RemappedFile> RemappedFiles) {      getDiagnostics().setNumWarnings(NumWarningsInPreamble);    // Parse the sources -  bool Result = Parse(OverrideMainBuffer); -   +  bool Result = Parse(std::move(OverrideMainBuffer)); +    // If we're caching global code-completion results, and the top-level     // declarations have changed, clear out the code-completion cache.    if (!Result && ShouldCacheCodeCompletionResults && @@ -2366,6 +2326,10 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column,    // Set the language options appropriately.    LangOpts = *CCInvocation->getLangOpts(); +  // Spell-checking and warnings are wasteful during code-completion. +  LangOpts.SpellChecking = false; +  CCInvocation->getDiagnosticOpts().IgnoreWarnings = true; +    std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());    // Recover resources if we crash before exiting this method. @@ -2427,7 +2391,7 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column,    // the use of the precompiled preamble if we're if the completion    // point is within the main file, after the end of the precompiled    // preamble. -  llvm::MemoryBuffer *OverrideMainBuffer = nullptr; +  std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;    if (!getPreambleFile(this).empty()) {      std::string CompleteFilePath(File);      llvm::sys::fs::UniqueID CompleteFileID; @@ -2437,9 +2401,8 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column,        llvm::sys::fs::UniqueID MainID;        if (!llvm::sys::fs::getUniqueID(MainPath, MainID)) {          if (CompleteFileID == MainID && Line > 1) -          OverrideMainBuffer -            = getMainBufferWithPrecompiledPreamble(*CCInvocation, false,  -                                                   Line - 1); +          OverrideMainBuffer = getMainBufferWithPrecompiledPreamble( +              *CCInvocation, false, Line - 1);        }      }    } @@ -2447,14 +2410,15 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column,    // If the main file has been overridden due to the use of a preamble,    // make that override happen and introduce the preamble.    if (OverrideMainBuffer) { -    PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); +    PreprocessorOpts.addRemappedFile(OriginalSourceFile, +                                     OverrideMainBuffer.get());      PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size();      PreprocessorOpts.PrecompiledPreambleBytes.second                                                      = PreambleEndsAtStartOfLine;      PreprocessorOpts.ImplicitPCHInclude = getPreambleFile(this);      PreprocessorOpts.DisablePCHValidation = true; -     -    OwnedBuffers.push_back(OverrideMainBuffer); + +    OwnedBuffers.push_back(OverrideMainBuffer.release());    } else {      PreprocessorOpts.PrecompiledPreambleBytes.first = 0;      PreprocessorOpts.PrecompiledPreambleBytes.second = false; @@ -2821,7 +2785,8 @@ struct PCHLocatorInfo {  static bool PCHLocator(serialization::ModuleFile &M, void *UserData) {    PCHLocatorInfo &Info = *static_cast<PCHLocatorInfo*>(UserData);    switch (M.Kind) { -  case serialization::MK_Module: +  case serialization::MK_ImplicitModule: +  case serialization::MK_ExplicitModule:      return true; // skip dependencies.    case serialization::MK_PCH:      Info.Mod = &M;  | 
