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"
15521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/AST/ASTConsumer.h"
1655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/ASTContext.h"
170853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/AST/DeclVisitor.h"
180853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/AST/StmtVisitor.h"
1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/TypeOrdering.h"
2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/Diagnostic.h"
2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/TargetInfo.h"
2255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/TargetOptions.h"
23521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/CompilerInstance.h"
24521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/FrontendActions.h"
257b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Frontend/FrontendDiagnostic.h"
26521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/FrontendOptions.h"
276f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis#include "clang/Frontend/MultiplexConsumer.h"
2832be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor#include "clang/Frontend/Utils.h"
290853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Lex/HeaderSearch.h"
300853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Lex/Preprocessor.h"
3136a16498ff911a218f26c7955376bbe99ddb16dfDouglas Gregor#include "clang/Lex/PreprocessorOptions.h"
3255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Serialization/ASTReader.h"
3355fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Serialization/ASTWriter.h"
347f9fc3f7ce076645cb6aefc99c64d9446caf13d6Chris Lattner#include "llvm/ADT/ArrayRef.h"
359b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor#include "llvm/ADT/StringExtras.h"
36349d38cef04ddf8938047c1b542a799aa82dfe84Douglas Gregor#include "llvm/ADT/StringSet.h"
371fd9e0def66fbd50e99be5ff87c9fd1c91c428abDouglas Gregor#include "llvm/Support/Atomic.h"
3855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/CrashRecoveryContext.h"
399cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis#include "llvm/Support/FileSystem.h"
4055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/Host.h"
4155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/MemoryBuffer.h"
42a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis#include "llvm/Support/Mutex.h"
43e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek#include "llvm/Support/MutexGuard.h"
4455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/Path.h"
4555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/Timer.h"
4655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/raw_ostream.h"
47ad23ebe22b7e52e3875981eeb46a1fd61a7554fbZhongxing Xu#include <cstdio>
4855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include <cstdlib>
49cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor#include <sys/stat.h>
500853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisusing namespace clang;
510853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
52213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregorusing llvm::TimeRecord;
53213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor
54213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregornamespace {
55213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor  class SimpleTimer {
56213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor    bool WantTiming;
57213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor    TimeRecord Start;
58213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor    std::string Output;
59213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor
60edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer  public:
619dba61a1e46099b77adf15de224aaa16037a7fffDouglas Gregor    explicit SimpleTimer(bool WantTiming) : WantTiming(WantTiming) {
62213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor      if (WantTiming)
63edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer        Start = TimeRecord::getCurrentTime();
64213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor    }
65213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor
665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    void setOutput(const Twine &Output) {
67213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor      if (WantTiming)
68edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer        this->Output = Output.str();
69213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor    }
70213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor
71213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor    ~SimpleTimer() {
72213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor      if (WantTiming) {
73213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor        TimeRecord Elapsed = TimeRecord::getCurrentTime();
74213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor        Elapsed -= Start;
75213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor        llvm::errs() << Output << ':';
76213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor        Elapsed.print(Elapsed, llvm::errs());
77213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor        llvm::errs() << '\n';
78213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor      }
79213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor    }
80213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor  };
811872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
821872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  struct OnDiskData {
831872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    /// \brief The file in which the precompiled preamble is stored.
841872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    std::string PreambleFile;
851872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
86b804cb315cfeebc4d1c4d2d023ffb08440f77254Rafael Espindola    /// \brief Temporary files that should be removed when the ASTUnit is
871872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    /// destroyed.
88b804cb315cfeebc4d1c4d2d023ffb08440f77254Rafael Espindola    SmallVector<std::string, 4> TemporaryFiles;
89b804cb315cfeebc4d1c4d2d023ffb08440f77254Rafael Espindola
901872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    /// \brief Erase temporary files.
911872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    void CleanTemporaryFiles();
921872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
931872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    /// \brief Erase the preamble file.
941872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    void CleanPreambleFile();
951872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
961872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    /// \brief Erase temporary files and the preamble file.
971872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    void Cleanup();
981872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  };
991872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek}
1001872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
101e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenekstatic llvm::sys::SmartMutex<false> &getOnDiskMutex() {
102e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek  static llvm::sys::SmartMutex<false> M(/* recursive = */ true);
103e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek  return M;
104e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek}
105e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek
106c4a77906c259cba58c147d8468c406a430ecdcbbDmitri Gribenkostatic void cleanupOnDiskMapAtExit();
1071872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
1081872b3153a388b3a548c9f699cbc348128059be9Ted Kremenektypedef llvm::DenseMap<const ASTUnit *, OnDiskData *> OnDiskDataMap;
1091872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekstatic OnDiskDataMap &getOnDiskDataMap() {
1101872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  static OnDiskDataMap M;
1111872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  static bool hasRegisteredAtExit = false;
1121872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  if (!hasRegisteredAtExit) {
1131872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    hasRegisteredAtExit = true;
1141872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    atexit(cleanupOnDiskMapAtExit);
1151872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  }
1161872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  return M;
1171872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek}
1181872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
119c4a77906c259cba58c147d8468c406a430ecdcbbDmitri Gribenkostatic void cleanupOnDiskMapAtExit() {
120817881376e3a40ca54376547dd1cb9ca5def7190Argyrios Kyrtzidis  // Use the mutex because there can be an alive thread destroying an ASTUnit.
121817881376e3a40ca54376547dd1cb9ca5def7190Argyrios Kyrtzidis  llvm::MutexGuard Guard(getOnDiskMutex());
1221872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  OnDiskDataMap &M = getOnDiskDataMap();
1231872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  for (OnDiskDataMap::iterator I = M.begin(), E = M.end(); I != E; ++I) {
1241872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    // We don't worry about freeing the memory associated with OnDiskDataMap.
1251872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    // All we care about is erasing stale files.
1261872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    I->second->Cleanup();
1271872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  }
1281872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek}
1291872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
1301872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekstatic OnDiskData &getOnDiskData(const ASTUnit *AU) {
131e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek  // We require the mutex since we are modifying the structure of the
132e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek  // DenseMap.
133e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek  llvm::MutexGuard Guard(getOnDiskMutex());
1341872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  OnDiskDataMap &M = getOnDiskDataMap();
1351872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  OnDiskData *&D = M[AU];
1361872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  if (!D)
1371872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    D = new OnDiskData();
1381872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  return *D;
1391872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek}
1401872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
1411872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekstatic void erasePreambleFile(const ASTUnit *AU) {
1421872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  getOnDiskData(AU).CleanPreambleFile();
1431872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek}
1441872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
1451872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekstatic void removeOnDiskEntry(const ASTUnit *AU) {
146e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek  // We require the mutex since we are modifying the structure of the
147e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek  // DenseMap.
148e055f8a1d8a33511394302d38af7ab0fbd2c35faTed Kremenek  llvm::MutexGuard Guard(getOnDiskMutex());
1491872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  OnDiskDataMap &M = getOnDiskDataMap();
1501872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  OnDiskDataMap::iterator I = M.find(AU);
1511872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  if (I != M.end()) {
1521872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    I->second->Cleanup();
1531872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    delete I->second;
1541872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    M.erase(AU);
1551872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  }
1561872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek}
1571872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
158cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenkostatic void setPreambleFile(const ASTUnit *AU, StringRef preambleFile) {
1591872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  getOnDiskData(AU).PreambleFile = preambleFile;
1601872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek}
1611872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
1621872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekstatic const std::string &getPreambleFile(const ASTUnit *AU) {
1631872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  return getOnDiskData(AU).PreambleFile;
1641872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek}
1651872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
1661872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekvoid OnDiskData::CleanTemporaryFiles() {
1671872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
168b804cb315cfeebc4d1c4d2d023ffb08440f77254Rafael Espindola    llvm::sys::fs::remove(TemporaryFiles[I]);
169b804cb315cfeebc4d1c4d2d023ffb08440f77254Rafael Espindola  TemporaryFiles.clear();
1701872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek}
1711872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
1721872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekvoid OnDiskData::CleanPreambleFile() {
1731872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  if (!PreambleFile.empty()) {
17485d28486b781f4e69dbff2d0b0239edc5a31ae16Rafael Espindola    llvm::sys::fs::remove(PreambleFile);
1751872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    PreambleFile.clear();
1761872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  }
1771872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek}
1781872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
1791872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekvoid OnDiskData::Cleanup() {
1801872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  CleanTemporaryFiles();
1811872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  CleanPreambleFile();
1821872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek}
1831872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
184900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidisstruct ASTUnit::ASTWriterData {
185900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis  SmallString<128> Buffer;
186900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis  llvm::BitstreamWriter Stream;
187900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis  ASTWriter Writer;
188900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis
189900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis  ASTWriterData() : Stream(Buffer), Writer(Stream) { }
190900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis};
191900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis
192332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidisvoid ASTUnit::clearFileLevelDecls() {
193332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  for (FileDeclsTy::iterator
194332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis         I = FileDecls.begin(), E = FileDecls.end(); I != E; ++I)
195332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    delete I->second;
196332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  FileDecls.clear();
197332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis}
198332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
1991872b3153a388b3a548c9f699cbc348128059be9Ted Kremenekvoid ASTUnit::CleanTemporaryFiles() {
2001872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  getOnDiskData(this).CleanTemporaryFiles();
2011872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek}
2021872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
203b804cb315cfeebc4d1c4d2d023ffb08440f77254Rafael Espindolavoid ASTUnit::addTemporaryFile(StringRef TempFile) {
2041872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  getOnDiskData(this).TemporaryFiles.push_back(TempFile);
205213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor}
206213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor
207eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// \brief After failing to build a precompiled preamble (due to
208eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// errors in the source that occurs in the preamble), the number of
209eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// reparses during which we'll skip even trying to precompile the
210eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// preamble.
211eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregorconst unsigned DefaultPreambleRebuildInterval = 5;
212eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor
213e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor/// \brief Tracks the number of ASTUnit objects that are currently active.
214e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor///
215e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor/// Used for debugging purposes only.
2161fd9e0def66fbd50e99be5ff87c9fd1c91c428abDouglas Gregorstatic llvm::sys::cas_flag ActiveASTUnitObjects;
217e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor
2183687e9d3a5dbfa9963af02a49a2b139d91310813Douglas GregorASTUnit::ASTUnit(bool _MainFileIsAST)
2193b7deda7137e62810a810ce25b062927a9fc7c71Argyrios Kyrtzidis  : Reader(0), HadModuleLoaderFatalFailure(false),
2203b7deda7137e62810a810ce25b062927a9fc7c71Argyrios Kyrtzidis    OnlyLocalDecls(false), CaptureDiagnostics(false),
221b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis    MainFileIsAST(_MainFileIsAST),
222467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor    TUKind(TU_Complete), WantTiming(getenv("LIBCLANG_TIMING")),
22315727ddb11405c45372150b5bfb07dbfa4c9960bArgyrios Kyrtzidis    OwnsRemappedFileBuffers(true),
224213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor    NumStoredDiagnosticsFromDriver(0),
225671947b18dba342f9aba022ee992babef325a833Douglas Gregor    PreambleRebuildCounter(0), SavedMainFileBuffer(0), PreambleBuffer(0),
2269870401105660efb1c393829e08eae44e0583b3dArgyrios Kyrtzidis    NumWarningsInPreamble(0),
227727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor    ShouldCacheCodeCompletionResults(false),
228ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis    IncludeBriefCommentsInCodeCompletion(false), UserFilesAreVolatile(false),
2299b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    CompletionCacheTopLevelHashValue(0),
2309b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    PreambleTopLevelHashValue(0),
2319b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    CurrentTopLevelHashValue(0),
2328b1540c159093e0e627ebf6542d0c0b7aba99eafDouglas Gregor    UnsafeToFree(false) {
233e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor  if (getenv("LIBCLANG_OBJTRACKING")) {
2341fd9e0def66fbd50e99be5ff87c9fd1c91c428abDouglas Gregor    llvm::sys::AtomicIncrement(&ActiveASTUnitObjects);
235e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor    fprintf(stderr, "+++ %d translation units\n", ActiveASTUnitObjects);
236e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor  }
237385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor}
2383687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor
239521bf9c529e653ab28896d027352d3e16e2672d5Daniel DunbarASTUnit::~ASTUnit() {
240a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor  // If we loaded from an AST file, balance out the BeginSourceFile call.
241a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor  if (MainFileIsAST && getDiagnostics().getClient()) {
242a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor    getDiagnostics().getClient()->EndSourceFile();
243a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor  }
244a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor
245332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  clearFileLevelDecls();
246332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
2471872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  // Clean up the temporary files and the preamble file.
2481872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  removeOnDiskEntry(this);
2491872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek
250f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  // Free the buffers associated with remapped files. We are required to
251f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  // perform this operation here because we explicitly request that the
252f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  // compiler instance *not* free these buffers for each invocation of the
253f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  // parser.
2544f32786ac45210143654390177105eb749b614e9Ted Kremenek  if (Invocation.getPtr() && OwnsRemappedFileBuffers) {
255f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor    PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
256f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor    for (PreprocessorOptions::remapped_file_buffer_iterator
257f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor           FB = PPOpts.remapped_file_buffer_begin(),
258f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor           FBEnd = PPOpts.remapped_file_buffer_end();
259f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor         FB != FBEnd;
260f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor         ++FB)
261f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor      delete FB->second;
262f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  }
26328233428da1ebec20c893d6297ae3191318940ddDouglas Gregor
26428233428da1ebec20c893d6297ae3191318940ddDouglas Gregor  delete SavedMainFileBuffer;
265671947b18dba342f9aba022ee992babef325a833Douglas Gregor  delete PreambleBuffer;
266671947b18dba342f9aba022ee992babef325a833Douglas Gregor
267213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor  ClearCachedCompletionResults();
268e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor
269e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor  if (getenv("LIBCLANG_OBJTRACKING")) {
2701fd9e0def66fbd50e99be5ff87c9fd1c91c428abDouglas Gregor    llvm::sys::AtomicDecrement(&ActiveASTUnitObjects);
271e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor    fprintf(stderr, "--- %d translation units\n", ActiveASTUnitObjects);
272e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor  }
273abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor}
274abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor
2757fe90f3bfa6bd7f779ecfd4ba201a296a3a1c8cbArgyrios Kyrtzidisvoid ASTUnit::setPreprocessor(Preprocessor *pp) { PP = pp; }
2767fe90f3bfa6bd7f779ecfd4ba201a296a3a1c8cbArgyrios Kyrtzidis
2778071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor/// \brief Determine the set of code-completion contexts in which this
2788071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor/// declaration should be shown.
27989cf425f1136f8d24a64ed94450e488b6794dfa4Dmitri Gribenkostatic unsigned getDeclShowContexts(const NamedDecl *ND,
280a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor                                    const LangOptions &LangOpts,
281a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor                                    bool &IsNestedNameSpecifier) {
282a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor  IsNestedNameSpecifier = false;
283a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor
2848071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor  if (isa<UsingShadowDecl>(ND))
2858071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor    ND = dyn_cast<NamedDecl>(ND->getUnderlyingDecl());
2868071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor  if (!ND)
2878071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor    return 0;
2888071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor
289026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith  uint64_t Contexts = 0;
2908071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor  if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND) ||
2918071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor      isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND)) {
2928071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor    // Types can appear in these contexts.
2938071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor    if (LangOpts.CPlusPlus || !isa<TagDecl>(ND))
294026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith      Contexts |= (1LL << CodeCompletionContext::CCC_TopLevel)
295026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith               |  (1LL << CodeCompletionContext::CCC_ObjCIvarList)
296026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith               |  (1LL << CodeCompletionContext::CCC_ClassStructUnion)
297026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith               |  (1LL << CodeCompletionContext::CCC_Statement)
298026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith               |  (1LL << CodeCompletionContext::CCC_Type)
299026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith               |  (1LL << CodeCompletionContext::CCC_ParenthesizedExpression);
3008071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor
3018071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor    // In C++, types can appear in expressions contexts (for functional casts).
3028071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor    if (LangOpts.CPlusPlus)
303026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith      Contexts |= (1LL << CodeCompletionContext::CCC_Expression);
3048071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor
3058071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor    // In Objective-C, message sends can send interfaces. In Objective-C++,
3068071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor    // all types are available due to functional casts.
3078071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor    if (LangOpts.CPlusPlus || isa<ObjCInterfaceDecl>(ND))
308026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith      Contexts |= (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver);
3093da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor
3103da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor    // In Objective-C, you can only be a subclass of another Objective-C class
3113da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor    if (isa<ObjCInterfaceDecl>(ND))
312026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith      Contexts |= (1LL << CodeCompletionContext::CCC_ObjCInterfaceName);
3138071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor
3148071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor    // Deal with tag names.
3158071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor    if (isa<EnumDecl>(ND)) {
316026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith      Contexts |= (1LL << CodeCompletionContext::CCC_EnumTag);
3178071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor
318a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor      // Part of the nested-name-specifier in C++0x.
31980ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith      if (LangOpts.CPlusPlus11)
320a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor        IsNestedNameSpecifier = true;
32189cf425f1136f8d24a64ed94450e488b6794dfa4Dmitri Gribenko    } else if (const RecordDecl *Record = dyn_cast<RecordDecl>(ND)) {
3228071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor      if (Record->isUnion())
323026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        Contexts |= (1LL << CodeCompletionContext::CCC_UnionTag);
3248071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor      else
325026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        Contexts |= (1LL << CodeCompletionContext::CCC_ClassOrStructTag);
3268071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor
3278071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor      if (LangOpts.CPlusPlus)
328a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor        IsNestedNameSpecifier = true;
32952779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor    } else if (isa<ClassTemplateDecl>(ND))
330a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor      IsNestedNameSpecifier = true;
3318071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor  } else if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) {
3328071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor    // Values can appear in these contexts.
333026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith    Contexts = (1LL << CodeCompletionContext::CCC_Statement)
334026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith             | (1LL << CodeCompletionContext::CCC_Expression)
335026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith             | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression)
336026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith             | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver);
3378071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor  } else if (isa<ObjCProtocolDecl>(ND)) {
338026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith    Contexts = (1LL << CodeCompletionContext::CCC_ObjCProtocolName);
3393da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor  } else if (isa<ObjCCategoryDecl>(ND)) {
340026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith    Contexts = (1LL << CodeCompletionContext::CCC_ObjCCategoryName);
3418071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor  } else if (isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) {
342026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith    Contexts = (1LL << CodeCompletionContext::CCC_Namespace);
3438071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor
3448071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor    // Part of the nested-name-specifier.
345a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor    IsNestedNameSpecifier = true;
3468071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor  }
3478071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor
3488071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor  return Contexts;
3498071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor}
3508071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor
35187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregorvoid ASTUnit::CacheCodeCompletionResults() {
35287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  if (!TheSema)
35387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor    return;
35487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
355213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor  SimpleTimer Timer(WantTiming);
356edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer  Timer.setOutput("Cache global code completions for " + getMainFileName());
35787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
35887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  // Clear out the previous results.
35987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  ClearCachedCompletionResults();
36087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
36187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  // Gather the set of global code completions.
3620a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall  typedef CodeCompletionResult Result;
3635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Result, 8> Results;
36448601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor  CachedCompletionAllocator = new GlobalCodeCompletionAllocator;
3657fdc8fdbfe0d2b4bc0f1a22b2560ca6d86a72c94Argyrios Kyrtzidis  CodeCompletionTUInfo CCTUInfo(CachedCompletionAllocator);
36628a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis  TheSema->GatherGlobalCodeCompletions(*CachedCompletionAllocator,
3677fdc8fdbfe0d2b4bc0f1a22b2560ca6d86a72c94Argyrios Kyrtzidis                                       CCTUInfo, Results);
36887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
36987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  // Translate global code completions into cached completions.
370f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  llvm::DenseMap<CanQualType, unsigned> CompletionTypes;
371f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor
37287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  for (unsigned I = 0, N = Results.size(); I != N; ++I) {
37387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor    switch (Results[I].Kind) {
3748071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor    case Result::RK_Declaration: {
375a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor      bool IsNestedNameSpecifier = false;
3768071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor      CachedCodeCompletionResult CachedResult;
377218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor      CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema,
37828a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis                                                    *CachedCompletionAllocator,
3797fdc8fdbfe0d2b4bc0f1a22b2560ca6d86a72c94Argyrios Kyrtzidis                                                    CCTUInfo,
380d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko                                          IncludeBriefCommentsInCodeCompletion);
3818071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor      CachedResult.ShowInContexts = getDeclShowContexts(Results[I].Declaration,
3824e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie                                                        Ctx->getLangOpts(),
383a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor                                                        IsNestedNameSpecifier);
3848071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor      CachedResult.Priority = Results[I].Priority;
3858071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor      CachedResult.Kind = Results[I].CursorKind;
38658ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor      CachedResult.Availability = Results[I].Availability;
387c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor
388f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor      // Keep track of the type of this completion in an ASTContext-agnostic
389f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor      // way.
390c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor      QualType UsageType = getDeclUsageType(*Ctx, Results[I].Declaration);
391f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor      if (UsageType.isNull()) {
392c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor        CachedResult.TypeClass = STC_Void;
393f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor        CachedResult.Type = 0;
394f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor      } else {
395f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor        CanQualType CanUsageType
396f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor          = Ctx->getCanonicalType(UsageType.getUnqualifiedType());
397f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor        CachedResult.TypeClass = getSimplifiedTypeClass(CanUsageType);
398f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor
399f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor        // Determine whether we have already seen this type. If so, we save
400f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor        // ourselves the work of formatting the type string by using the
401f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor        // temporary, CanQualType-based hash table to find the associated value.
402f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor        unsigned &TypeValue = CompletionTypes[CanUsageType];
403f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor        if (TypeValue == 0) {
404f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor          TypeValue = CompletionTypes.size();
405f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor          CachedCompletionTypes[QualType(CanUsageType).getAsString()]
406f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor            = TypeValue;
407f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor        }
408f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor
409f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor        CachedResult.Type = TypeValue;
410c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor      }
411f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor
4128071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor      CachedCompletionResults.push_back(CachedResult);
413a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor
414a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor      /// Handle nested-name-specifiers in C++.
4154e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      if (TheSema->Context.getLangOpts().CPlusPlus &&
416a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor          IsNestedNameSpecifier && !Results[I].StartsNestedNameSpecifier) {
417a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor        // The contexts in which a nested-name-specifier can appear in C++.
418026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        uint64_t NNSContexts
419026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith          = (1LL << CodeCompletionContext::CCC_TopLevel)
420026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith          | (1LL << CodeCompletionContext::CCC_ObjCIvarList)
421026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith          | (1LL << CodeCompletionContext::CCC_ClassStructUnion)
422026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith          | (1LL << CodeCompletionContext::CCC_Statement)
423026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith          | (1LL << CodeCompletionContext::CCC_Expression)
424026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith          | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver)
425026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith          | (1LL << CodeCompletionContext::CCC_EnumTag)
426026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith          | (1LL << CodeCompletionContext::CCC_UnionTag)
427026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith          | (1LL << CodeCompletionContext::CCC_ClassOrStructTag)
428026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith          | (1LL << CodeCompletionContext::CCC_Type)
429026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith          | (1LL << CodeCompletionContext::CCC_PotentiallyQualifiedName)
430026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith          | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression);
431a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor
432a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor        if (isa<NamespaceDecl>(Results[I].Declaration) ||
433a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor            isa<NamespaceAliasDecl>(Results[I].Declaration))
434026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith          NNSContexts |= (1LL << CodeCompletionContext::CCC_Namespace);
435a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor
436a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor        if (unsigned RemainingContexts
437a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor                                = NNSContexts & ~CachedResult.ShowInContexts) {
438a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor          // If there any contexts where this completion can be a
439a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor          // nested-name-specifier but isn't already an option, create a
440a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor          // nested-name-specifier completion.
441a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor          Results[I].StartsNestedNameSpecifier = true;
442218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor          CachedResult.Completion
443218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor            = Results[I].CreateCodeCompletionString(*TheSema,
44428a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis                                                    *CachedCompletionAllocator,
4457fdc8fdbfe0d2b4bc0f1a22b2560ca6d86a72c94Argyrios Kyrtzidis                                                    CCTUInfo,
446d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko                                        IncludeBriefCommentsInCodeCompletion);
447a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor          CachedResult.ShowInContexts = RemainingContexts;
448a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor          CachedResult.Priority = CCP_NestedNameSpecifier;
449a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor          CachedResult.TypeClass = STC_Void;
450a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor          CachedResult.Type = 0;
451a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor          CachedCompletionResults.push_back(CachedResult);
452a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor        }
453a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor      }
45487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor      break;
4558071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor    }
4568071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor
45787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor    case Result::RK_Keyword:
45887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor    case Result::RK_Pattern:
45987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor      // Ignore keywords and patterns; we don't care, since they are so
46087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor      // easily regenerated.
46187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor      break;
46287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
46387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor    case Result::RK_Macro: {
46487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor      CachedCodeCompletionResult CachedResult;
465218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor      CachedResult.Completion
466218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor        = Results[I].CreateCodeCompletionString(*TheSema,
46728a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis                                                *CachedCompletionAllocator,
4687fdc8fdbfe0d2b4bc0f1a22b2560ca6d86a72c94Argyrios Kyrtzidis                                                CCTUInfo,
469d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko                                          IncludeBriefCommentsInCodeCompletion);
47087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor      CachedResult.ShowInContexts
471026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        = (1LL << CodeCompletionContext::CCC_TopLevel)
472026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_ObjCInterface)
473026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_ObjCImplementation)
474026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_ObjCIvarList)
475026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_ClassStructUnion)
476026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_Statement)
477026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_Expression)
478026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver)
479026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_MacroNameUse)
480026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_PreprocessorExpression)
481026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression)
482026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_OtherWithMacros);
4832ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor
48487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor      CachedResult.Priority = Results[I].Priority;
48587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor      CachedResult.Kind = Results[I].CursorKind;
48658ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor      CachedResult.Availability = Results[I].Availability;
4871827e10051638770ad9ccf3e285caf95f995afd1Douglas Gregor      CachedResult.TypeClass = STC_Void;
488f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor      CachedResult.Type = 0;
48987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor      CachedCompletionResults.push_back(CachedResult);
49087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor      break;
49187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor    }
49287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor    }
49387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  }
4949b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor
4959b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  // Save the current top-level hash value.
4969b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  CompletionCacheTopLevelHashValue = CurrentTopLevelHashValue;
49787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor}
49887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
49987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregorvoid ASTUnit::ClearCachedCompletionResults() {
50087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  CachedCompletionResults.clear();
501f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  CachedCompletionTypes.clear();
50248601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor  CachedCompletionAllocator = 0;
50387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor}
50487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
5050853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisnamespace {
5060853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
507c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl/// \brief Gathers information from ASTReader that will be used to initialize
5080853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis/// a Preprocessor.
5093c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redlclass ASTInfoCollector : public ASTReaderListener {
510998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor  Preprocessor &PP;
511bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  ASTContext &Context;
5120853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  LangOptions &LangOpt;
51357016dda61498294120b1a881d9e6606337b29d9Douglas Gregor  IntrusiveRefCntPtr<TargetOptions> &TargetOpts;
514c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith  IntrusiveRefCntPtr<TargetInfo> &Target;
5150853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  unsigned &Counter;
5161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
517bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  bool InitializedLanguage;
5180853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidispublic:
519bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  ASTInfoCollector(Preprocessor &PP, ASTContext &Context, LangOptions &LangOpt,
52057016dda61498294120b1a881d9e6606337b29d9Douglas Gregor                   IntrusiveRefCntPtr<TargetOptions> &TargetOpts,
521c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith                   IntrusiveRefCntPtr<TargetInfo> &Target,
5220853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                   unsigned &Counter)
523f9ba851c9b5db8ea30846215e737702a1cc2c194Argyrios Kyrtzidis    : PP(PP), Context(Context), LangOpt(LangOpt),
5249a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor      TargetOpts(TargetOpts), Target(Target),
525f9ba851c9b5db8ea30846215e737702a1cc2c194Argyrios Kyrtzidis      Counter(Counter),
526bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      InitializedLanguage(false) {}
5271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
52827ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor  virtual bool ReadLanguageOptions(const LangOptions &LangOpts,
52938295beb73db5f90bfcf31625fb81dbc3b96290aDouglas Gregor                                   bool Complain) {
530900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    if (InitializedLanguage)
531998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor      return false;
532998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor
5330853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    LangOpt = LangOpts;
534bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor    InitializedLanguage = true;
535900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis
536900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    updated();
5370853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    return false;
5380853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  }
5391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
54027ffa6caf965ef20fdef5ae23b81cdc3d05e7afbDouglas Gregor  virtual bool ReadTargetOptions(const TargetOptions &TargetOpts,
54138295beb73db5f90bfcf31625fb81dbc3b96290aDouglas Gregor                                 bool Complain) {
542998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor    // If we've already initialized the target, don't do it again.
543900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    if (Target)
544998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor      return false;
545998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor
54657016dda61498294120b1a881d9e6606337b29d9Douglas Gregor    this->TargetOpts = new TargetOptions(TargetOpts);
54749a87549f4dc95ecb3d8a593b71df7c167a51f85Douglas Gregor    Target = TargetInfo::CreateTargetInfo(PP.getDiagnostics(),
54849a87549f4dc95ecb3d8a593b71df7c167a51f85Douglas Gregor                                          &*this->TargetOpts);
5497f1863326488813e7648845f3cec5225770b1a0bArgyrios Kyrtzidis
550900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    updated();
5510853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    return false;
5520853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  }
5531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
55462288edde26ff4af9fc079c979a0e1bdc577ce9dArgyrios Kyrtzidis  virtual void ReadCounter(const serialization::ModuleFile &M, unsigned Value) {
5550853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    Counter = Value;
5560853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  }
5577f1863326488813e7648845f3cec5225770b1a0bArgyrios Kyrtzidis
5587f1863326488813e7648845f3cec5225770b1a0bArgyrios Kyrtzidisprivate:
559900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis  void updated() {
560900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    if (!Target || !InitializedLanguage)
561900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis      return;
562900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis
563900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    // Inform the target of the language options.
564900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    //
565900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    // FIXME: We shouldn't need to do this, the target should be immutable once
566900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    // created. This complexity should be lifted elsewhere.
567900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    Target->setForcedLangOptions(LangOpt);
568900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis
569900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    // Initialize the preprocessor.
570900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    PP.Initialize(*Target);
571900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis
572900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    // Initialize the ASTContext
573900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    Context.InitBuiltinTypes(*Target);
5746ebf09130479bc7605aa09a3e6c4dc2ba3513495Dmitri Gribenko
5756ebf09130479bc7605aa09a3e6c4dc2ba3513495Dmitri Gribenko    // We didn't have access to the comment options when the ASTContext was
5766ebf09130479bc7605aa09a3e6c4dc2ba3513495Dmitri Gribenko    // constructed, so register them now.
5776ebf09130479bc7605aa09a3e6c4dc2ba3513495Dmitri Gribenko    Context.getCommentCommandTraits().registerCommentOptions(
5786ebf09130479bc7605aa09a3e6c4dc2ba3513495Dmitri Gribenko        LangOpt.CommentOpts);
5797f1863326488813e7648845f3cec5225770b1a0bArgyrios Kyrtzidis  }
5800853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis};
5810853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
582a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor  /// \brief Diagnostic consumer that saves each diagnostic it is given.
58326e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikieclass StoredDiagnosticConsumer : public DiagnosticConsumer {
5845f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVectorImpl<StoredDiagnostic> &StoredDiags;
585a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor  SourceManager *SourceMgr;
586a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor
587a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorpublic:
58826e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikie  explicit StoredDiagnosticConsumer(
5895f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                          SmallVectorImpl<StoredDiagnostic> &StoredDiags)
590a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor    : StoredDiags(StoredDiags), SourceMgr(0) { }
591a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor
592a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor  virtual void BeginSourceFile(const LangOptions &LangOpts,
593a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor                               const Preprocessor *PP = 0) {
594a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor    if (PP)
595a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor      SourceMgr = &PP->getSourceManager();
596a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor  }
597a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor
598d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  virtual void HandleDiagnostic(DiagnosticsEngine::Level Level,
59940847cfb58acc3cac7d68727df9455ac45f2e118David Blaikie                                const Diagnostic &Info);
600a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor};
601a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
602a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor/// \brief RAII object that optionally captures diagnostics, if
603a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor/// there is no diagnostic client to capture them already.
604a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorclass CaptureDroppedDiagnostics {
605d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  DiagnosticsEngine &Diags;
60626e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikie  StoredDiagnosticConsumer Client;
60778ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie  DiagnosticConsumer *PreviousClient;
608a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
609a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorpublic:
610d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  CaptureDroppedDiagnostics(bool RequestCapture, DiagnosticsEngine &Diags,
6115f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                          SmallVectorImpl<StoredDiagnostic> &StoredDiags)
612bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor    : Diags(Diags), Client(StoredDiags), PreviousClient(0)
613a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  {
614bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor    if (RequestCapture || Diags.getClient() == 0) {
615bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor      PreviousClient = Diags.takeClient();
616a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor      Diags.setClient(&Client);
617bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor    }
618a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  }
619a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
620a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  ~CaptureDroppedDiagnostics() {
621bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor    if (Diags.getClient() == &Client) {
622bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor      Diags.takeClient();
623bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor      Diags.setClient(PreviousClient);
624bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor    }
625a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  }
626a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor};
627a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
6280853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis} // anonymous namespace
6290853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
63026e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikievoid StoredDiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level Level,
63140847cfb58acc3cac7d68727df9455ac45f2e118David Blaikie                                              const Diagnostic &Info) {
632f2224d89a6ae65a3839529e26d0f6d025d83d6bbArgyrios Kyrtzidis  // Default implementation (Warnings/errors count).
63378ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie  DiagnosticConsumer::HandleDiagnostic(Level, Info);
634f2224d89a6ae65a3839529e26d0f6d025d83d6bbArgyrios Kyrtzidis
635a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor  // Only record the diagnostic if it's part of the source manager we know
636a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor  // about. This effectively drops diagnostics from modules we're building.
637a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor  // FIXME: In the long run, ee don't want to drop source managers from modules.
638a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor  if (!Info.hasSourceManager() || &Info.getSourceManager() == SourceMgr)
639a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor    StoredDiags.push_back(StoredDiagnostic(Level, Info));
640a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}
641a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
6427eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios KyrtzidisASTMutationListener *ASTUnit::getASTMutationListener() {
6437eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis  if (WriterData)
6447eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis    return &WriterData->Writer;
6457eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis  return 0;
6467eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis}
6477eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis
648900ab95e12bb7483971640a91075699eec391804Argyrios KyrtzidisASTDeserializationListener *ASTUnit::getDeserializationListener() {
649900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis  if (WriterData)
650900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    return &WriterData->Writer;
651900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis  return 0;
652900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis}
653900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis
6545f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerllvm::MemoryBuffer *ASTUnit::getBufferForFile(StringRef Filename,
65575dfb65c38d51772df9a00ce2d2feeefd55667adChris Lattner                                              std::string *ErrorStr) {
65639b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner  assert(FileMgr);
65775dfb65c38d51772df9a00ce2d2feeefd55667adChris Lattner  return FileMgr->getBufferForFile(Filename, ErrorStr);
658389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis}
659389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis
660e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor/// \brief Configure the diagnostics object for use with ASTUnit.
661c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmithvoid ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> &Diags,
6620b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor                             const char **ArgBegin, const char **ArgEnd,
663e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor                             ASTUnit &AST, bool CaptureDiagnostics) {
664e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor  if (!Diags.getPtr()) {
665e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor    // No diagnostics engine was provided, so create our own diagnostics object
666e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor    // with the default options.
66778ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie    DiagnosticConsumer *Client = 0;
668e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor    if (CaptureDiagnostics)
66926e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikie      Client = new StoredDiagnosticConsumer(AST.StoredDiagnostics);
67002c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor    Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions(),
671d47afb96a3f988e6d21a92fe4dfe875ab227c7c0Sean Silva                                                Client,
672cc2b653c319599f502425d2c3de29865d47bb9e4Douglas Gregor                                                /*ShouldOwnClient=*/true);
673e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor  } else if (CaptureDiagnostics) {
67426e7a90c7c74b0ecd8d3f19e216c72a8849017aeDavid Blaikie    Diags->setClient(new StoredDiagnosticConsumer(AST.StoredDiagnostics));
675e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor  }
676e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor}
677e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor
6783c7f4134603d04b44f997b43c0a9def270f25386Sebastian RedlASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename,
679c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith                              IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
680389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis                                  const FileSystemOptions &FileSystemOpts,
6815cf48766d626ff6b223acc9d4b7e415ca8480836Ted Kremenek                                  bool OnlyLocalDecls,
6824db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                  RemappedFile *RemappedFiles,
683a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                  unsigned NumRemappedFiles,
684bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis                                  bool CaptureDiagnostics,
685ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                  bool AllowPCHWithCompilerErrors,
686ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                  bool UserFilesAreVolatile) {
6876f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<ASTUnit> AST(new ASTUnit(true));
688b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek
689b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek  // Recover resources if we crash before exiting this method.
69025a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
69125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    ASTUnitCleanup(AST.get());
692d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
693d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie    llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
69425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    DiagCleanup(Diags.getPtr());
695b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek
6960b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor  ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics);
697abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor
6987d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor  AST->OnlyLocalDecls = OnlyLocalDecls;
699e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor  AST->CaptureDiagnostics = CaptureDiagnostics;
70028019772db70d4547be05a042eb950bc910f134fDouglas Gregor  AST->Diagnostics = Diags;
7014f32786ac45210143654390177105eb749b614e9Ted Kremenek  AST->FileMgr = new FileManager(FileSystemOpts);
702ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis  AST->UserFilesAreVolatile = UserFilesAreVolatile;
7034f32786ac45210143654390177105eb749b614e9Ted Kremenek  AST->SourceMgr = new SourceManager(AST->getDiagnostics(),
704ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                     AST->getFileManager(),
705ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                     UserFilesAreVolatile);
706c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregor  AST->HSOpts = new HeaderSearchOptions();
707c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregor
708c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregor  AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts,
709c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregor                                         AST->getFileManager(),
71051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor                                         AST->getDiagnostics(),
711dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor                                         AST->ASTFileLangOpts,
712dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor                                         /*Target=*/0));
713914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor
7144db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  for (unsigned I = 0; I != NumRemappedFiles; ++I) {
715b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second;
716b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    if (const llvm::MemoryBuffer *
717b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis          memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) {
718b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      // Create the file entry for the file that we're mapping from.
719b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      const FileEntry *FromFile
720b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis        = AST->getFileManager().getVirtualFile(RemappedFiles[I].first,
721b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis                                               memBuf->getBufferSize(),
722b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis                                               0);
723b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      if (!FromFile) {
724b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis        AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file)
725b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis          << RemappedFiles[I].first;
726b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis        delete memBuf;
727b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis        continue;
728b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      }
729b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis
730b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      // Override the contents of the "from" file with the contents of
731b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      // the "to" file.
732b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      AST->getSourceManager().overrideFileContents(FromFile, memBuf);
733b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis
734b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    } else {
735b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      const char *fname = fileOrBuf.get<const char *>();
736b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      const FileEntry *ToFile = AST->FileMgr->getFile(fname);
737b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      if (!ToFile) {
738b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis        AST->getDiagnostics().Report(diag::err_fe_remap_missing_to_file)
739b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis        << RemappedFiles[I].first << fname;
740b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis        continue;
741b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      }
742b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis
743b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      // Create the file entry for the file that we're mapping from.
744b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      const FileEntry *FromFile
745b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis        = AST->getFileManager().getVirtualFile(RemappedFiles[I].first,
746b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis                                               ToFile->getSize(),
747b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis                                               0);
748b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      if (!FromFile) {
749b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis        AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file)
750b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis          << RemappedFiles[I].first;
751b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis        delete memBuf;
752b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis        continue;
753b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      }
754b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis
755b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      // Override the contents of the "from" file with the contents of
756b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      // the "to" file.
757b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      AST->getSourceManager().overrideFileContents(FromFile, ToFile);
7584db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    }
7594db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  }
7604db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor
7610853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  // Gather Info for preprocessor construction later on.
7621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7630853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  HeaderSearch &HeaderInfo = *AST->HeaderInfo.get();
7640853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  unsigned Counter;
7650853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
7666f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<ASTReader> Reader;
7670853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
76836a16498ff911a218f26c7955376bbe99ddb16dfDouglas Gregor  AST->PP = new Preprocessor(new PreprocessorOptions(),
76936a16498ff911a218f26c7955376bbe99ddb16dfDouglas Gregor                             AST->getDiagnostics(), AST->ASTFileLangOpts,
770998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor                             /*Target=*/0, AST->getSourceManager(), HeaderInfo,
771998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor                             *AST,
772998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor                             /*IILookup=*/0,
773998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor                             /*OwnsHeaderSearch=*/false,
774998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor                             /*DelayInitialization=*/true);
775bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  Preprocessor &PP = *AST->PP;
776bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor
777bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  AST->Ctx = new ASTContext(AST->ASTFileLangOpts,
778bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor                            AST->getSourceManager(),
779bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor                            /*Target=*/0,
780bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor                            PP.getIdentifierTable(),
781bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor                            PP.getSelectorTable(),
782bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor                            PP.getBuiltinInfo(),
783bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor                            /* size_reserve = */0,
784bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor                            /*DelayInitialization=*/true);
785bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  ASTContext &Context = *AST->Ctx;
786998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor
78798e95bf1c84560684356088af7f4878bdacb5856Argyrios Kyrtzidis  bool disableValid = false;
78898e95bf1c84560684356088af7f4878bdacb5856Argyrios Kyrtzidis  if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
78998e95bf1c84560684356088af7f4878bdacb5856Argyrios Kyrtzidis    disableValid = true;
790bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis  Reader.reset(new ASTReader(PP, Context,
791bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis                             /*isysroot=*/"",
79298e95bf1c84560684356088af7f4878bdacb5856Argyrios Kyrtzidis                             /*DisableValidation=*/disableValid,
793bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis                             AllowPCHWithCompilerErrors));
7948c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek
7958c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek  // Recover resources if we crash before exiting this method.
7968c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek  llvm::CrashRecoveryContextCleanupRegistrar<ASTReader>
7978c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek    ReaderCleanup(Reader.get());
7988c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek
799bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  Reader->setListener(new ASTInfoCollector(*AST->PP, Context,
800f9ba851c9b5db8ea30846215e737702a1cc2c194Argyrios Kyrtzidis                                           AST->ASTFileLangOpts,
8019a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor                                           AST->TargetOpts, AST->Target,
8024399890d385171eff39927a26823426046d33456Douglas Gregor                                           Counter));
803cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar
80438295beb73db5f90bfcf31625fb81dbc3b96290aDouglas Gregor  switch (Reader->ReadAST(Filename, serialization::MK_MainFile,
805958bcaf3d4e0c1ae46de3e84e7c2a7638c3c5286Argyrios Kyrtzidis                          SourceLocation(), ASTReader::ARR_None)) {
806c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl  case ASTReader::Success:
8070853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    break;
8081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
809c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl  case ASTReader::Failure:
810677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor  case ASTReader::Missing:
8114825fd7fbb3fe87cdf8da9bccc1361fac45bdf2dDouglas Gregor  case ASTReader::OutOfDate:
8124825fd7fbb3fe87cdf8da9bccc1361fac45bdf2dDouglas Gregor  case ASTReader::VersionMismatch:
8134825fd7fbb3fe87cdf8da9bccc1361fac45bdf2dDouglas Gregor  case ASTReader::ConfigurationMismatch:
8144825fd7fbb3fe87cdf8da9bccc1361fac45bdf2dDouglas Gregor  case ASTReader::HadErrors:
8153687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor    AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);
8160853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    return NULL;
8170853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  }
8181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
81968d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar  AST->OriginalSourceFile = Reader->getOriginalSourceFile();
82068d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar
8210853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  PP.setCounterValue(Counter);
8221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
823c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl  // Attach the AST reader to the AST context as an external AST
8240853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  // source, so that declarations will be deserialized from the
8253c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl  // AST file as needed.
826c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl  ASTReader *ReaderPtr = Reader.get();
8276f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<ExternalASTSource> Source(Reader.take());
8288c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek
8298c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek  // Unregister the cleanup for ASTReader.  It will get cleaned up
8308c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek  // by the ASTUnit cleanup.
8318c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek  ReaderCleanup.unregister();
8328c647deada0c0e8407b4ced00ff09be1261fe147Ted Kremenek
8330853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  Context.setExternalSource(Source);
8340853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
835914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor  // Create an AST consumer, even though it isn't used.
836914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor  AST->Consumer.reset(new ASTConsumer);
837914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor
838c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl  // Create a semantic analysis object and tell the AST reader about it.
839914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor  AST->TheSema.reset(new Sema(PP, Context, *AST->Consumer));
840914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor  AST->TheSema->Initialize();
841914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor  ReaderPtr->InitializeSema(*AST->TheSema);
84262ba9f61af6177992d8cd2e3306257e1213b1bd3Argyrios Kyrtzidis  AST->Reader = ReaderPtr;
843914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor
844a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor  // Tell the diagnostic client that we have started a source file.
845a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor  AST->getDiagnostics().getClient()->BeginSourceFile(Context.getLangOpts(),&PP);
846a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor
8471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return AST.take();
8480853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis}
849521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
850521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarnamespace {
851521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
8529b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor/// \brief Preprocessor callback class that updates a hash value with the names
8539b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor/// of all macros that have been defined by the translation unit.
8549b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregorclass MacroDefinitionTrackerPPCallbacks : public PPCallbacks {
8559b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  unsigned &Hash;
8569b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor
8579b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregorpublic:
8589b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  explicit MacroDefinitionTrackerPPCallbacks(unsigned &Hash) : Hash(Hash) { }
8599b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor
860c515978bd3a703aa733f846a0094ffa84d149074Argyrios Kyrtzidis  virtual void MacroDefined(const Token &MacroNameTok,
861c515978bd3a703aa733f846a0094ffa84d149074Argyrios Kyrtzidis                            const MacroDirective *MD) {
8629b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    Hash = llvm::HashString(MacroNameTok.getIdentifierInfo()->getName(), Hash);
8639b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  }
8649b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor};
8659b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor
8669b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor/// \brief Add the given declaration to the hash of all top-level entities.
8679b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregorvoid AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) {
8689b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  if (!D)
8699b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    return;
8709b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor
8719b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  DeclContext *DC = D->getDeclContext();
8729b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  if (!DC)
8739b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    return;
8749b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor
8759b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  if (!(DC->isTranslationUnit() || DC->getLookupParent()->isTranslationUnit()))
8769b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    return;
8779b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor
8789b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
8799b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    if (ND->getIdentifier())
8809b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor      Hash = llvm::HashString(ND->getIdentifier()->getName(), Hash);
8819b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    else if (DeclarationName Name = ND->getDeclName()) {
8829b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor      std::string NameStr = Name.getAsString();
8839b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor      Hash = llvm::HashString(NameStr, Hash);
8849b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    }
8859b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    return;
8861f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis  }
8871f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis
8881f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis  if (ImportDecl *ImportD = dyn_cast<ImportDecl>(D)) {
8891f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis    if (Module *Mod = ImportD->getImportedModule()) {
8901f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis      std::string ModName = Mod->getFullModuleName();
8911f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis      Hash = llvm::HashString(ModName, Hash);
8921f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis    }
8931f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis    return;
8941f3ff6a709432e1131ff802d660def2fab2aea58Argyrios Kyrtzidis  }
8959b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor}
8969b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor
897f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerConsumer : public ASTConsumer {
898f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  ASTUnit &Unit;
8999b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  unsigned &Hash;
9009b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor
901f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic:
9029b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  TopLevelDeclTrackerConsumer(ASTUnit &_Unit, unsigned &Hash)
9039b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    : Unit(_Unit), Hash(Hash) {
9049b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    Hash = 0;
9059b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  }
9069b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor
907332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  void handleTopLevelDecl(Decl *D) {
90835593a9add85353532519f8eba5ec513a611aac5Argyrios Kyrtzidis    if (!D)
90935593a9add85353532519f8eba5ec513a611aac5Argyrios Kyrtzidis      return;
91035593a9add85353532519f8eba5ec513a611aac5Argyrios Kyrtzidis
911332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    // FIXME: Currently ObjC method declarations are incorrectly being
912332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    // reported as top-level declarations, even though their DeclContext
913332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    // is the containing ObjC @interface/@implementation.  This is a
914332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    // fundamental problem in the parser right now.
915332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    if (isa<ObjCMethodDecl>(D))
916332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis      return;
917332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
918332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    AddTopLevelDeclarationToHash(D, Hash);
919332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    Unit.addTopLevelDecl(D);
920332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
921332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    handleFileLevelDecl(D);
922332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  }
923332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
924332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  void handleFileLevelDecl(Decl *D) {
925332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    Unit.addFileLevelDecl(D);
926332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    if (NamespaceDecl *NSD = dyn_cast<NamespaceDecl>(D)) {
927332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis      for (NamespaceDecl::decl_iterator
928332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis             I = NSD->decls_begin(), E = NSD->decls_end(); I != E; ++I)
929332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis        handleFileLevelDecl(*I);
930da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek    }
931f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  }
93227372b4f1f402e95dd479ecf40c39ca71c15619fSebastian Redl
93388c2596edc8eb475e20f6033de1ea01669695a0cArgyrios Kyrtzidis  bool HandleTopLevelDecl(DeclGroupRef D) {
934332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it)
935332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis      handleTopLevelDecl(*it);
93688c2596edc8eb475e20f6033de1ea01669695a0cArgyrios Kyrtzidis    return true;
937332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  }
938332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
93927372b4f1f402e95dd479ecf40c39ca71c15619fSebastian Redl  // We're not interested in "interesting" decls.
94027372b4f1f402e95dd479ecf40c39ca71c15619fSebastian Redl  void HandleInterestingDecl(DeclGroupRef) {}
941332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
942332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) {
943332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it)
944332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis      handleTopLevelDecl(*it);
945332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  }
946900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis
9477eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis  virtual ASTMutationListener *GetASTMutationListener() {
9487eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis    return Unit.getASTMutationListener();
9497eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis  }
9507eca8d2262a26eedb2ff3cc0fd11be2494b17cc1Argyrios Kyrtzidis
951900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis  virtual ASTDeserializationListener *GetASTDeserializationListener() {
952900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    return Unit.getDeserializationListener();
953900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis  }
954f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar};
955f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
956f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerAction : public ASTFrontendAction {
957f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic:
958f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  ASTUnit &Unit;
959f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
960521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
9615f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                         StringRef InFile) {
9629b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    CI.getPreprocessor().addPPCallbacks(
9639b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor     new MacroDefinitionTrackerPPCallbacks(Unit.getCurrentTopLevelHashValue()));
9649b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    return new TopLevelDeclTrackerConsumer(Unit,
9659b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor                                           Unit.getCurrentTopLevelHashValue());
966521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  }
967521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
968521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarpublic:
969f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}
970f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
971521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  virtual bool hasCodeCompletionSupport() const { return false; }
972467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor  virtual TranslationUnitKind getTranslationUnitKind()  {
973467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor    return Unit.getTranslationUnitKind();
974df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  }
975521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar};
976521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
977b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramerclass PrecompilePreambleAction : public ASTFrontendAction {
978b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  ASTUnit &Unit;
979b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  bool HasEmittedPreamblePCH;
980b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer
981b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramerpublic:
982b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  explicit PrecompilePreambleAction(ASTUnit &Unit)
983b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer      : Unit(Unit), HasEmittedPreamblePCH(false) {}
984b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer
985b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
986b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer                                         StringRef InFile);
987b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  bool hasEmittedPreamblePCH() const { return HasEmittedPreamblePCH; }
988b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  void setHasEmittedPreamblePCH() { HasEmittedPreamblePCH = true; }
989b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  virtual bool shouldEraseOutputFiles() { return !hasEmittedPreamblePCH(); }
990b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer
991b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  virtual bool hasCodeCompletionSupport() const { return false; }
992b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  virtual bool hasASTFileSupport() const { return false; }
993b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  virtual TranslationUnitKind getTranslationUnitKind() { return TU_Prefix; }
994b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer};
995b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer
99692ddef1bf843e1e18c040d69f48a6bf0bc7c776aArgyrios Kyrtzidisclass PrecompilePreambleConsumer : public PCHGenerator {
9971d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor  ASTUnit &Unit;
998b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  unsigned &Hash;
999eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  std::vector<Decl *> TopLevelDecls;
1000b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  PrecompilePreambleAction *Action;
1001b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer
10021d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorpublic:
1003b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  PrecompilePreambleConsumer(ASTUnit &Unit, PrecompilePreambleAction *Action,
1004b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer                             const Preprocessor &PP, StringRef isysroot,
1005b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer                             raw_ostream *Out)
10061f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis    : PCHGenerator(PP, "", 0, isysroot, Out, /*AllowASTWithErrors=*/true),
1007b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer      Unit(Unit), Hash(Unit.getCurrentTopLevelHashValue()), Action(Action) {
10089b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    Hash = 0;
10099b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  }
10101d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor
101188c2596edc8eb475e20f6033de1ea01669695a0cArgyrios Kyrtzidis  virtual bool HandleTopLevelDecl(DeclGroupRef D) {
10121d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor    for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) {
10131d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor      Decl *D = *it;
10141d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor      // FIXME: Currently ObjC method declarations are incorrectly being
10151d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor      // reported as top-level declarations, even though their DeclContext
10161d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor      // is the containing ObjC @interface/@implementation.  This is a
10171d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor      // fundamental problem in the parser right now.
10181d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor      if (isa<ObjCMethodDecl>(D))
10191d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor        continue;
10209b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor      AddTopLevelDeclarationToHash(D, Hash);
1021eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor      TopLevelDecls.push_back(D);
1022eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor    }
102388c2596edc8eb475e20f6033de1ea01669695a0cArgyrios Kyrtzidis    return true;
1024eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  }
1025eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor
1026eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  virtual void HandleTranslationUnit(ASTContext &Ctx) {
1027eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor    PCHGenerator::HandleTranslationUnit(Ctx);
10281f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis    if (hasEmittedPCH()) {
1029eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor      // Translate the top-level declarations we captured during
1030eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor      // parsing into declaration IDs in the precompiled
1031eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor      // preamble. This will allow us to deserialize those top-level
1032eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor      // declarations when requested.
103351e75aecf4fb303b91c9e54fd88e3509e5acc7a6Argyrios Kyrtzidis      for (unsigned I = 0, N = TopLevelDecls.size(); I != N; ++I) {
103451e75aecf4fb303b91c9e54fd88e3509e5acc7a6Argyrios Kyrtzidis        Decl *D = TopLevelDecls[I];
103551e75aecf4fb303b91c9e54fd88e3509e5acc7a6Argyrios Kyrtzidis        // Invalid top-level decls may not have been serialized.
103651e75aecf4fb303b91c9e54fd88e3509e5acc7a6Argyrios Kyrtzidis        if (D->isInvalidDecl())
103751e75aecf4fb303b91c9e54fd88e3509e5acc7a6Argyrios Kyrtzidis          continue;
103851e75aecf4fb303b91c9e54fd88e3509e5acc7a6Argyrios Kyrtzidis        Unit.addTopLevelDeclFromPreamble(getWriter().getDeclID(D));
103951e75aecf4fb303b91c9e54fd88e3509e5acc7a6Argyrios Kyrtzidis      }
1040b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer
1041b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer      Action->setHasEmittedPreamblePCH();
10421d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor    }
10431d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor  }
10441d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor};
10451d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor
1046b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer}
10471d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor
1048b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin KramerASTConsumer *PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI,
1049b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer                                                         StringRef InFile) {
1050b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  std::string Sysroot;
1051b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  std::string OutputFile;
1052b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  raw_ostream *OS = 0;
1053b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  if (GeneratePCHAction::ComputeASTConsumerArguments(CI, InFile, Sysroot,
1054b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer                                                     OutputFile, OS))
1055b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer    return 0;
10561f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis
1057b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  if (!CI.getFrontendOpts().RelocatablePCH)
1058b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer    Sysroot.clear();
10591d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor
1060b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  CI.getPreprocessor().addPPCallbacks(new MacroDefinitionTrackerPPCallbacks(
1061b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer      Unit.getCurrentTopLevelHashValue()));
1062b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer  return new PrecompilePreambleConsumer(Unit, this, CI.getPreprocessor(),
1063b62b8b9aa5ee5035ca1e02e1191a22a21d0228f4Benjamin Kramer                                        Sysroot, OS);
1064521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar}
1065521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
1066fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin Kramerstatic bool isNonDriverDiag(const StoredDiagnostic &StoredDiag) {
1067fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin Kramer  return StoredDiag.getLocation().isValid();
1068fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin Kramer}
1069fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin Kramer
1070fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin Kramerstatic void
1071fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin KramercheckAndRemoveNonDriverDiags(SmallVectorImpl<StoredDiagnostic> &StoredDiags) {
10727f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis  // Get rid of stored diagnostics except the ones from the driver which do not
10737f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis  // have a source location.
1074fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin Kramer  StoredDiags.erase(
1075fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin Kramer      std::remove_if(StoredDiags.begin(), StoredDiags.end(), isNonDriverDiag),
1076fe57db23431463e137c4aaf01d999165c84b0e9fBenjamin Kramer      StoredDiags.end());
10777f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis}
10787f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis
10797f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidisstatic void checkAndSanitizeDiags(SmallVectorImpl<StoredDiagnostic> &
10807f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis                                                              StoredDiagnostics,
10817f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis                                  SourceManager &SM) {
10827f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis  // The stored diagnostic has the old source manager in it; update
10837f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis  // the locations to refer into the new source manager. Since we've
10847f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis  // been careful to make sure that the source manager's state
10857f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis  // before and after are identical, so that we can reuse the source
10867f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis  // location itself.
10877f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis  for (unsigned I = 0, N = StoredDiagnostics.size(); I < N; ++I) {
10887f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis    if (StoredDiagnostics[I].getLocation().isValid()) {
10897f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis      FullSourceLoc Loc(StoredDiagnostics[I].getLocation(), SM);
10907f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis      StoredDiagnostics[I].setLocation(Loc);
10917f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis    }
10927f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis  }
10937f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis}
10947f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis
1095abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// Parse the source file into a translation unit using the given compiler
1096abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// invocation, replacing the current translation unit.
1097abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor///
1098abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// \returns True if a failure occurred that causes the ASTUnit not to
1099abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// contain any translation-unit information, false otherwise.
1100754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregorbool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
110128233428da1ebec20c893d6297ae3191318940ddDouglas Gregor  delete SavedMainFileBuffer;
110228233428da1ebec20c893d6297ae3191318940ddDouglas Gregor  SavedMainFileBuffer = 0;
110328233428da1ebec20c893d6297ae3191318940ddDouglas Gregor
11044f32786ac45210143654390177105eb749b614e9Ted Kremenek  if (!Invocation) {
1105671947b18dba342f9aba022ee992babef325a833Douglas Gregor    delete OverrideMainBuffer;
1106abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor    return true;
1107671947b18dba342f9aba022ee992babef325a833Douglas Gregor  }
1108abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor
1109521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Create the compiler instance to use for building the AST.
11106f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<CompilerInstance> Clang(new CompilerInstance());
111103201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek
111203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  // Recover resources if we crash before exiting this method.
111325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
111425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    CICleanup(Clang.get());
111503201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek
1116c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith  IntrusiveRefCntPtr<CompilerInvocation>
111726d43cd3a088d4f1f1645328db3b73afbc7eaa61Argyrios Kyrtzidis    CCInvocation(new CompilerInvocation(*Invocation));
111826d43cd3a088d4f1f1645328db3b73afbc7eaa61Argyrios Kyrtzidis
111926d43cd3a088d4f1f1645328db3b73afbc7eaa61Argyrios Kyrtzidis  Clang->setInvocation(CCInvocation.getPtr());
11208616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis  OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile();
1121abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor
11221abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Set up diagnostics, capturing any diagnostics that would
11231abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // otherwise be dropped.
112403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  Clang->setDiagnostics(&getDiagnostics());
11253687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor
1126521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Create the target instance.
112703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
112849a87549f4dc95ecb3d8a593b71df7c167a51f85Douglas Gregor                   &Clang->getTargetOpts()));
112903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  if (!Clang->hasTarget()) {
1130671947b18dba342f9aba022ee992babef325a833Douglas Gregor    delete OverrideMainBuffer;
1131abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor    return true;
1132671947b18dba342f9aba022ee992babef325a833Douglas Gregor  }
1133671947b18dba342f9aba022ee992babef325a833Douglas Gregor
1134521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Inform the target of the language options.
1135521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  //
1136521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // FIXME: We shouldn't need to do this, the target should be immutable once
1137521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // created. This complexity should be lifted elsewhere.
113803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  Clang->getTarget().setForcedLangOptions(Clang->getLangOpts());
1139abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor
114003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
1141521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar         "Invocation must have exactly one source file!");
11428616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis  assert(Clang->getFrontendOpts().Inputs[0].getKind() != IK_AST &&
1143521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar         "FIXME: AST inputs not yet supported here!");
11448616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis  assert(Clang->getFrontendOpts().Inputs[0].getKind() != IK_LLVM_IR &&
1145faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar         "IR inputs not support here!");
1146521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
1147abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor  // Configure the various subsystems.
1148abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor  // FIXME: Should we retain the previous file manager?
1149d3b74d9ca4f239a7a90ad193378c494306c57352Ted Kremenek  LangOpts = &Clang->getLangOpts();
115003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  FileSystemOpts = Clang->getFileSystemOpts();
11514f32786ac45210143654390177105eb749b614e9Ted Kremenek  FileMgr = new FileManager(FileSystemOpts);
1152ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis  SourceMgr = new SourceManager(getDiagnostics(), *FileMgr,
1153ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                UserFilesAreVolatile);
1154914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor  TheSema.reset();
11554f32786ac45210143654390177105eb749b614e9Ted Kremenek  Ctx = 0;
11564f32786ac45210143654390177105eb749b614e9Ted Kremenek  PP = 0;
115762ba9f61af6177992d8cd2e3306257e1213b1bd3Argyrios Kyrtzidis  Reader = 0;
1158abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor
1159abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor  // Clear out old caches and data.
1160abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor  TopLevelDecls.clear();
1161332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  clearFileLevelDecls();
1162abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor  CleanTemporaryFiles();
1163c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor
1164f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor  if (!OverrideMainBuffer) {
11657f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis    checkAndRemoveNonDriverDiags(StoredDiagnostics);
1166f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor    TopLevelDeclsInPreamble.clear();
1167f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor  }
1168f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor
1169521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Create a file manager object to provide access to and cache the filesystem.
117003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  Clang->setFileManager(&getFileManager());
1171abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor
1172521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Create the source manager.
117303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  Clang->setSourceManager(&getSourceManager());
1174abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor
1175f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  // If the main file has been overridden due to the use of a preamble,
1176f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  // make that override happen and introduce the preamble.
117703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  PreprocessorOptions &PreprocessorOpts = Clang->getPreprocessorOpts();
1178f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  if (OverrideMainBuffer) {
1179f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor    PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer);
1180f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor    PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size();
1181f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor    PreprocessorOpts.PrecompiledPreambleBytes.second
1182f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor                                                    = PreambleEndsAtStartOfLine;
11831872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    PreprocessorOpts.ImplicitPCHInclude = getPreambleFile(this);
1184fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor    PreprocessorOpts.DisablePCHValidation = true;
118528233428da1ebec20c893d6297ae3191318940ddDouglas Gregor
1186c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor    // The stored diagnostic has the old source manager in it; update
1187c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor    // the locations to refer into the new source manager. Since we've
1188c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor    // been careful to make sure that the source manager's state
1189c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor    // before and after are identical, so that we can reuse the source
1190c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor    // location itself.
11917f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis    checkAndSanitizeDiags(StoredDiagnostics, getSourceManager());
11924cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor
11934cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor    // Keep track of the override buffer;
11944cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor    SavedMainFileBuffer = OverrideMainBuffer;
1195f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  }
1196f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor
11976f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<TopLevelDeclTrackerAction> Act(
119825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    new TopLevelDeclTrackerAction(*this));
119925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek
120025a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  // Recover resources if we crash before exiting this method.
120125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
120225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    ActCleanup(Act.get());
120325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek
12041f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor  if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
1205521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar    goto error;
1206f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor
1207f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  if (OverrideMainBuffer) {
12081872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    std::string ModName = getPreambleFile(this);
1209f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    TranslateStoredDiagnostics(Clang->getModuleManager(), ModName,
1210f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor                               getSourceManager(), PreambleDiagnostics,
1211f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor                               StoredDiagnostics);
1212f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  }
1213f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor
1214374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis  if (!Act->Execute())
1215374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis    goto error;
1216e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis
1217e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  transferASTDataFromCompilerInstance(*Clang);
1218abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor
1219f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  Act->EndSourceFile();
1220f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor
1221e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  FailedParseDiagnostics.clear();
1222e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis
1223abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor  return false;
12244f32786ac45210143654390177105eb749b614e9Ted Kremenek
1225521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarerror:
1226f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  // Remove the overridden buffer we used for the preamble.
1227fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor  if (OverrideMainBuffer) {
1228671947b18dba342f9aba022ee992babef325a833Douglas Gregor    delete OverrideMainBuffer;
122937cf66350cb5a2bb68b0b7c7cca552f7a4867348Douglas Gregor    SavedMainFileBuffer = 0;
1230fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor  }
1231e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis
1232e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  // Keep the ownership of the data in the ASTUnit because the client may
1233e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  // want to see the diagnostics.
1234e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  transferASTDataFromCompilerInstance(*Clang);
1235e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  FailedParseDiagnostics.swap(StoredDiagnostics);
1236d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  StoredDiagnostics.clear();
12373e9d32656a8a3a787f64f9beeef66d2d700eb85dArgyrios Kyrtzidis  NumStoredDiagnosticsFromDriver = 0;
1238abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor  return true;
1239abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor}
1240abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor
124144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor/// \brief Simple function to retrieve a path for a preamble precompiled header.
124244c181aec37789f25f6c15543c164416f72e562aDouglas Gregorstatic std::string GetPreamblePCHPath() {
1243424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor  // FIXME: This is a hack so that we can override the preamble file during
1244424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor  // crash-recovery testing, which is the only case where the preamble files
124585d28486b781f4e69dbff2d0b0239edc5a31ae16Rafael Espindola  // are not necessarily cleaned up.
1246424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor  const char *TmpFile = ::getenv("CINDEXTEST_PREAMBLE_FILE");
1247424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor  if (TmpFile)
1248424668cc90a07f3f98b36dad252940a43ded83d8Douglas Gregor    return TmpFile;
124985d28486b781f4e69dbff2d0b0239edc5a31ae16Rafael Espindola
125085d28486b781f4e69dbff2d0b0239edc5a31ae16Rafael Espindola  SmallString<128> Path;
12511ec4a86a867fc04f35d13bc9e33b04cf2171fe41Rafael Espindola  llvm::sys::fs::createTemporaryFile("preamble", "pch", Path);
125285d28486b781f4e69dbff2d0b0239edc5a31ae16Rafael Espindola
125385d28486b781f4e69dbff2d0b0239edc5a31ae16Rafael Espindola  return Path.str();
125444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor}
125544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
1256f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// \brief Compute the preamble for the main file, providing the source buffer
1257f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// that corresponds to the main file along with a pair (bytes, start-of-line)
1258f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// that describes the preamble.
1259f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregorstd::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> >
1260df95a13ec73d2cdaea79555cb412d767f4963120Douglas GregorASTUnit::ComputePreamble(CompilerInvocation &Invocation,
1261df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor                         unsigned MaxLines, bool &CreatedBuffer) {
1262175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  FrontendOptions &FrontendOpts = Invocation.getFrontendOpts();
126339b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner  PreprocessorOptions &PreprocessorOpts = Invocation.getPreprocessorOpts();
1264175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  CreatedBuffer = false;
1265175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor
126644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // Try to determine if the main file has been remapped, either from the
126744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // command line (to another file) or directly through the compiler invocation
126844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // (to a memory buffer).
1269175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  llvm::MemoryBuffer *Buffer = 0;
1270105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola  std::string MainFilePath(FrontendOpts.Inputs[0].getFile());
12714488835d1c78221553909447cf87d7e4ff7f99fbRafael Espindola  llvm::sys::fs::UniqueID MainFileID;
1272da4cb0cf401bb546574a7db46e50cda8b9d9c048Rafael Espindola  if (!llvm::sys::fs::getUniqueID(MainFilePath, MainFileID)) {
127344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor    // Check whether there is a file-file remapping of the main file
127444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor    for (PreprocessorOptions::remapped_file_iterator
1275175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor          M = PreprocessorOpts.remapped_file_begin(),
1276175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor          E = PreprocessorOpts.remapped_file_end();
127744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor         M != E;
127844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor         ++M) {
1279105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola      std::string MPath(M->first);
12804488835d1c78221553909447cf87d7e4ff7f99fbRafael Espindola      llvm::sys::fs::UniqueID MID;
1281da4cb0cf401bb546574a7db46e50cda8b9d9c048Rafael Espindola      if (!llvm::sys::fs::getUniqueID(MPath, MID)) {
1282105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola        if (MainFileID == MID) {
128344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor          // We found a remapping. Try to load the resulting, remapped source.
1284175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor          if (CreatedBuffer) {
128544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor            delete Buffer;
1286175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor            CreatedBuffer = false;
1287175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor          }
1288175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor
1289389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis          Buffer = getBufferForFile(M->second);
129044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor          if (!Buffer)
1291f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor            return std::make_pair((llvm::MemoryBuffer*)0,
1292f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor                                  std::make_pair(0, true));
1293175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor          CreatedBuffer = true;
129444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor        }
129544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor      }
129644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor    }
129744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
129844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor    // Check whether there is a file-buffer remapping. It supercedes the
129944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor    // file-file remapping.
130044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor    for (PreprocessorOptions::remapped_file_buffer_iterator
130144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor           M = PreprocessorOpts.remapped_file_buffer_begin(),
130244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor           E = PreprocessorOpts.remapped_file_buffer_end();
130344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor         M != E;
130444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor         ++M) {
1305105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola      std::string MPath(M->first);
13064488835d1c78221553909447cf87d7e4ff7f99fbRafael Espindola      llvm::sys::fs::UniqueID MID;
1307da4cb0cf401bb546574a7db46e50cda8b9d9c048Rafael Espindola      if (!llvm::sys::fs::getUniqueID(MPath, MID)) {
1308105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola        if (MainFileID == MID) {
1309105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola          // We found a remapping.
1310175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor          if (CreatedBuffer) {
131144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor            delete Buffer;
1312175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor            CreatedBuffer = false;
1313175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor          }
131444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
1315175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor          Buffer = const_cast<llvm::MemoryBuffer *>(M->second);
131644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor        }
131744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor      }
1318175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor    }
131944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  }
132044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
132144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // If the main source file was not remapped, load it now.
132244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  if (!Buffer) {
13238616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis    Buffer = getBufferForFile(FrontendOpts.Inputs[0].getFile());
132444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor    if (!Buffer)
1325f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor      return std::make_pair((llvm::MemoryBuffer*)0, std::make_pair(0, true));
1326175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor
1327175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor    CreatedBuffer = true;
1328175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  }
1329175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor
133003c107a42fae79e89d0016999a1a04c07d65591aArgyrios Kyrtzidis  return std::make_pair(Buffer, Lexer::ComputePreamble(Buffer,
1331d3b74d9ca4f239a7a90ad193378c494306c57352Ted Kremenek                                                       *Invocation.getLangOpts(),
133203c107a42fae79e89d0016999a1a04c07d65591aArgyrios Kyrtzidis                                                       MaxLines));
1333175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor}
1334175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor
1335754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregorstatic llvm::MemoryBuffer *CreatePaddedMainFileBuffer(llvm::MemoryBuffer *Old,
1336754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor                                                      unsigned NewSize,
13375f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                                      StringRef NewName) {
1338754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor  llvm::MemoryBuffer *Result
1339754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor    = llvm::MemoryBuffer::getNewUninitMemBuffer(NewSize, NewName);
1340754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor  memcpy(const_cast<char*>(Result->getBufferStart()),
1341754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor         Old->getBufferStart(), Old->getBufferSize());
1342754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor  memset(const_cast<char*>(Result->getBufferStart()) + Old->getBufferSize(),
1343f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor         ' ', NewSize - Old->getBufferSize() - 1);
1344f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  const_cast<char*>(Result->getBufferEnd())[-1] = '\n';
1345754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor
1346754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor  return Result;
1347754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor}
1348754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor
1349175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// \brief Attempt to build or re-use a precompiled preamble when (re-)parsing
1350175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// the source file.
1351175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor///
1352175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// This routine will compute the preamble of the main source file. If a
1353175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// non-trivial preamble is found, it will precompile that preamble into a
1354175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// precompiled header so that the precompiled preamble can be used to reduce
1355175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// reparsing time. If a precompiled preamble has already been constructed,
1356175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// this routine will determine if it is still valid and, if so, avoid
1357175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// rebuilding the precompiled preamble.
1358175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor///
1359df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// \param AllowRebuild When true (the default), this routine is
1360df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// allowed to rebuild the precompiled preamble if it is found to be
1361df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// out-of-date.
1362df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor///
1363df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// \param MaxLines When non-zero, the maximum number of lines that
1364df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// can occur within the preamble.
1365df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor///
1366754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// \returns If the precompiled preamble can be used, returns a newly-allocated
1367754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// buffer that should be used in place of the main file when doing so.
1368754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// Otherwise, returns a NULL pointer.
1369df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregorllvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(
137001b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor                              const CompilerInvocation &PreambleInvocationIn,
1371df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor                                                           bool AllowRebuild,
1372df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor                                                           unsigned MaxLines) {
137301b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor
1374c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith  IntrusiveRefCntPtr<CompilerInvocation>
137501b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor    PreambleInvocation(new CompilerInvocation(PreambleInvocationIn));
137601b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor  FrontendOptions &FrontendOpts = PreambleInvocation->getFrontendOpts();
1377175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  PreprocessorOptions &PreprocessorOpts
137801b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor    = PreambleInvocation->getPreprocessorOpts();
1379175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor
1380175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  bool CreatedPreambleBuffer = false;
1381f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > NewPreamble
138201b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor    = ComputePreamble(*PreambleInvocation, MaxLines, CreatedPreambleBuffer);
1383175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor
1384f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  // If ComputePreamble() Take ownership of the preamble buffer.
13856f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<llvm::MemoryBuffer> OwnedPreambleBuffer;
138673fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor  if (CreatedPreambleBuffer)
138773fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor    OwnedPreambleBuffer.reset(NewPreamble.first);
138873fc91275a4dc7cb0b0b12a8022319ea78c1f9feDouglas Gregor
1389f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  if (!NewPreamble.second.first) {
1390175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor    // We couldn't find a preamble in the main source. Clear out the current
1391175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor    // preamble, if we have one. It's obviously no good any more.
1392175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor    Preamble.clear();
13931872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    erasePreambleFile(this);
1394eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor
1395eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor    // The next time we actually see a preamble, precompile it.
1396eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor    PreambleRebuildCounter = 1;
1397754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor    return 0;
139844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  }
139944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
1400175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  if (!Preamble.empty()) {
1401175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor    // We've previously computed a preamble. Check whether we have the same
1402175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor    // preamble now that we did before, and that there's enough space in
1403175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor    // the main-file buffer within the precompiled preamble to fit the
1404175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor    // new main file.
1405f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor    if (Preamble.size() == NewPreamble.second.first &&
1406f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor        PreambleEndsAtStartOfLine == NewPreamble.second.second &&
1407592508ed997e52207cf380f9b6eb9943994ad7aeDouglas Gregor        NewPreamble.first->getBufferSize() < PreambleReservedSize-2 &&
1408507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis        memcmp(Preamble.getBufferStart(), NewPreamble.first->getBufferStart(),
1409f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor               NewPreamble.second.first) == 0) {
1410175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor      // The preamble has not changed. We may be able to re-use the precompiled
1411175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor      // preamble.
1412c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor
1413cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor      // Check that none of the files used by the preamble have changed.
1414cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor      bool AnyFileChanged = false;
1415cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor
1416cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor      // First, make a record of those files that have been overridden via
1417cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor      // remapping or unsaved_files.
1418cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor      llvm::StringMap<std::pair<off_t, time_t> > OverriddenFiles;
1419cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor      for (PreprocessorOptions::remapped_file_iterator
1420cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor                R = PreprocessorOpts.remapped_file_begin(),
1421cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor             REnd = PreprocessorOpts.remapped_file_end();
1422cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor           !AnyFileChanged && R != REnd;
1423cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor           ++R) {
1424aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola        llvm::sys::fs::file_status Status;
1425aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola        if (FileMgr->getNoncachedStatValue(R->second, Status)) {
1426cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor          // If we can't stat the file we're remapping to, assume that something
1427cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor          // horrible happened.
1428cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor          AnyFileChanged = true;
1429cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor          break;
1430cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor        }
1431aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola
1432aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola        OverriddenFiles[R->first] = std::make_pair(
1433aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola            Status.getSize(), Status.getLastModificationTime().toEpochTime());
1434cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor      }
1435cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor      for (PreprocessorOptions::remapped_file_buffer_iterator
1436cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor                R = PreprocessorOpts.remapped_file_buffer_begin(),
1437cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor             REnd = PreprocessorOpts.remapped_file_buffer_end();
1438cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor           !AnyFileChanged && R != REnd;
1439cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor           ++R) {
1440cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor        // FIXME: Should we actually compare the contents of file->buffer
1441cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor        // remappings?
1442cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor        OverriddenFiles[R->first] = std::make_pair(R->second->getBufferSize(),
1443cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor                                                   0);
1444cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor      }
1445cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor
1446cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor      // Check whether anything has changed.
1447cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor      for (llvm::StringMap<std::pair<off_t, time_t> >::iterator
1448cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor             F = FilesInPreamble.begin(), FEnd = FilesInPreamble.end();
1449cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor           !AnyFileChanged && F != FEnd;
1450cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor           ++F) {
1451cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor        llvm::StringMap<std::pair<off_t, time_t> >::iterator Overridden
1452cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor          = OverriddenFiles.find(F->first());
1453cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor        if (Overridden != OverriddenFiles.end()) {
1454cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor          // This file was remapped; check whether the newly-mapped file
1455cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor          // matches up with the previous mapping.
1456cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor          if (Overridden->second != F->second)
1457cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor            AnyFileChanged = true;
1458cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor          continue;
1459cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor        }
1460cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor
1461cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor        // The file was not remapped; check whether it has changed on disk.
1462aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola        llvm::sys::fs::file_status Status;
1463aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola        if (FileMgr->getNoncachedStatValue(F->first(), Status)) {
1464cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor          // If we can't stat the file, assume that something horrible happened.
1465cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor          AnyFileChanged = true;
1466aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola        } else if (Status.getSize() != uint64_t(F->second.first) ||
1467aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola                   Status.getLastModificationTime().toEpochTime() !=
1468aefb1d3312a63ac8d289a2e84747fe61a7f61823Rafael Espindola                       uint64_t(F->second.second))
1469cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor          AnyFileChanged = true;
1470cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor      }
1471cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor
1472cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor      if (!AnyFileChanged) {
1473c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor        // Okay! We can re-use the precompiled preamble.
1474c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor
1475c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor        // Set the state of the diagnostic object to mimic its state
1476c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor        // after parsing the preamble.
1477c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor        getDiagnostics().Reset();
147832be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor        ProcessWarningOptions(getDiagnostics(),
147901b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor                              PreambleInvocation->getDiagnosticOpts());
1480c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor        getDiagnostics().setNumWarnings(NumWarningsInPreamble);
1481c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor
1482c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor        // Create a version of the main file buffer that is padded to
1483c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor        // buffer size we reserved when creating the preamble.
1484cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor        return CreatePaddedMainFileBuffer(NewPreamble.first,
1485cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor                                          PreambleReservedSize,
14868616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis                                          FrontendOpts.Inputs[0].getFile());
1487cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor      }
1488175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor    }
1489df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor
1490df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    // If we aren't allowed to rebuild the precompiled preamble, just
1491df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    // return now.
1492df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    if (!AllowRebuild)
1493df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor      return 0;
1494aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor
1495175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor    // We can't reuse the previously-computed preamble. Build a new one.
1496175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor    Preamble.clear();
1497f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    PreambleDiagnostics.clear();
14981872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    erasePreambleFile(this);
1499eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor    PreambleRebuildCounter = 1;
1500df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  } else if (!AllowRebuild) {
1501df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    // We aren't allowed to rebuild the precompiled preamble; just
1502df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    // return now.
1503df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    return 0;
1504df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  }
1505eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor
1506eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor  // If the preamble rebuild counter > 1, it's because we previously
1507eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor  // failed to build a preamble and we're not yet ready to try
1508eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor  // again. Decrement the counter and return a failure.
1509eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor  if (PreambleRebuildCounter > 1) {
1510eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor    --PreambleRebuildCounter;
1511eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor    return 0;
1512eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor  }
1513eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor
15142cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor  // Create a temporary file for the precompiled preamble. In rare
15152cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor  // circumstances, this can fail.
15162cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor  std::string PreamblePCHPath = GetPreamblePCHPath();
15172cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor  if (PreamblePCHPath.empty()) {
15182cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor    // Try again next time.
15192cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor    PreambleRebuildCounter = 1;
15202cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor    return 0;
15212cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor  }
15222cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor
1523175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  // We did not previously compute a preamble, or it can't be reused anyway.
1524213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor  SimpleTimer PreambleTimer(WantTiming);
1525edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer  PreambleTimer.setOutput("Precompiling preamble");
152644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
152744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // Create a new buffer that stores the preamble. The buffer also contains
152844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // extra space for the original contents of the file (which will be present
152944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // when we actually parse the file) along with more room in case the file
1530175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  // grows.
1531175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  PreambleReservedSize = NewPreamble.first->getBufferSize();
1532175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  if (PreambleReservedSize < 4096)
1533f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor    PreambleReservedSize = 8191;
153444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  else
1535175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor    PreambleReservedSize *= 2;
1536175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor
1537c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor  // Save the preamble text for later; we'll need to compare against it for
1538c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor  // subsequent reparses.
15398616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis  StringRef MainFilename = PreambleInvocation->getFrontendOpts().Inputs[0].getFile();
1540507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis  Preamble.assign(FileMgr->getFile(MainFilename),
1541507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis                  NewPreamble.first->getBufferStart(),
1542c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor                  NewPreamble.first->getBufferStart()
1543c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor                                                  + NewPreamble.second.first);
1544c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor  PreambleEndsAtStartOfLine = NewPreamble.second.second;
1545c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor
1546671947b18dba342f9aba022ee992babef325a833Douglas Gregor  delete PreambleBuffer;
1547671947b18dba342f9aba022ee992babef325a833Douglas Gregor  PreambleBuffer
1548175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor    = llvm::MemoryBuffer::getNewUninitMemBuffer(PreambleReservedSize,
15498616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis                                                FrontendOpts.Inputs[0].getFile());
155044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  memcpy(const_cast<char*>(PreambleBuffer->getBufferStart()),
1551175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor         NewPreamble.first->getBufferStart(), Preamble.size());
1552175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  memset(const_cast<char*>(PreambleBuffer->getBufferStart()) + Preamble.size(),
1553f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor         ' ', PreambleReservedSize - Preamble.size() - 1);
1554f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  const_cast<char*>(PreambleBuffer->getBufferEnd())[-1] = '\n';
15551cd7df45ac8909a92a80af4be7ec1bbdcb3a84e7Rafael Espindola
155644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // Remap the main source file to the preamble buffer.
15571cd7df45ac8909a92a80af4be7ec1bbdcb3a84e7Rafael Espindola  StringRef MainFilePath = FrontendOpts.Inputs[0].getFile();
15581cd7df45ac8909a92a80af4be7ec1bbdcb3a84e7Rafael Espindola  PreprocessorOpts.addRemappedFile(MainFilePath, PreambleBuffer);
15591cd7df45ac8909a92a80af4be7ec1bbdcb3a84e7Rafael Espindola
156044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // Tell the compiler invocation to generate a temporary precompiled header.
156144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  FrontendOpts.ProgramAction = frontend::GeneratePCH;
156244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // FIXME: Generate the precompiled header into memory?
15632cd4fd4b7554480cbea67b48de5e5d467d06e292Douglas Gregor  FrontendOpts.OutputFile = PreamblePCHPath;
1564aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor  PreprocessorOpts.PrecompiledPreambleBytes.first = 0;
1565aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor  PreprocessorOpts.PrecompiledPreambleBytes.second = false;
156644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
156744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // Create the compiler instance to use for building the precompiled preamble.
15686f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<CompilerInstance> Clang(new CompilerInstance());
156903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek
157003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  // Recover resources if we crash before exiting this method.
157125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
157225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    CICleanup(Clang.get());
157303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek
157401b6e31a62e2265849f4388b9be6be0a5d13348dDouglas Gregor  Clang->setInvocation(&*PreambleInvocation);
15758616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis  OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile();
157644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
15771abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Set up diagnostics, capturing all of the diagnostics produced.
157803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  Clang->setDiagnostics(&getDiagnostics());
157944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
158044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // Create the target instance.
158103201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
158249a87549f4dc95ecb3d8a593b71df7c167a51f85Douglas Gregor                                                &Clang->getTargetOpts()));
158303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  if (!Clang->hasTarget()) {
158421b1824304076325a72239a4446e5f7e97370cfdRafael Espindola    llvm::sys::fs::remove(FrontendOpts.OutputFile);
1585175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor    Preamble.clear();
1586eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor    PreambleRebuildCounter = DefaultPreambleRebuildInterval;
1587671947b18dba342f9aba022ee992babef325a833Douglas Gregor    PreprocessorOpts.eraseRemappedFile(
1588671947b18dba342f9aba022ee992babef325a833Douglas Gregor                               PreprocessorOpts.remapped_file_buffer_end() - 1);
1589754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor    return 0;
159044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  }
159144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
159244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // Inform the target of the language options.
159344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  //
159444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // FIXME: We shouldn't need to do this, the target should be immutable once
159544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // created. This complexity should be lifted elsewhere.
159603201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  Clang->getTarget().setForcedLangOptions(Clang->getLangOpts());
159744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
159803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
159944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor         "Invocation must have exactly one source file!");
16008616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis  assert(Clang->getFrontendOpts().Inputs[0].getKind() != IK_AST &&
160144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor         "FIXME: AST inputs not yet supported here!");
16028616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis  assert(Clang->getFrontendOpts().Inputs[0].getKind() != IK_LLVM_IR &&
160344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor         "IR inputs not support here!");
160444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
160544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // Clear out old caches and data.
1606aa3e6babe646329310388e5b7e0c9045e0018715Douglas Gregor  getDiagnostics().Reset();
160703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  ProcessWarningOptions(getDiagnostics(), Clang->getDiagnosticOpts());
16087f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis  checkAndRemoveNonDriverDiags(StoredDiagnostics);
1609eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  TopLevelDecls.clear();
1610eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  TopLevelDeclsInPreamble.clear();
161144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
161244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // Create a file manager object to provide access to and cache the filesystem.
161303201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  Clang->setFileManager(new FileManager(Clang->getFileSystemOpts()));
161444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
161544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // Create the source manager.
161603201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  Clang->setSourceManager(new SourceManager(getDiagnostics(),
16174f32786ac45210143654390177105eb749b614e9Ted Kremenek                                            Clang->getFileManager()));
161844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
16196f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<PrecompilePreambleAction> Act;
16201d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor  Act.reset(new PrecompilePreambleAction(*this));
16211f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor  if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {
162221b1824304076325a72239a4446e5f7e97370cfdRafael Espindola    llvm::sys::fs::remove(FrontendOpts.OutputFile);
1623175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor    Preamble.clear();
1624eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor    PreambleRebuildCounter = DefaultPreambleRebuildInterval;
1625671947b18dba342f9aba022ee992babef325a833Douglas Gregor    PreprocessorOpts.eraseRemappedFile(
1626671947b18dba342f9aba022ee992babef325a833Douglas Gregor                               PreprocessorOpts.remapped_file_buffer_end() - 1);
1627754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor    return 0;
162844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  }
162944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
163044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  Act->Execute();
163144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  Act->EndSourceFile();
16324f32786ac45210143654390177105eb749b614e9Ted Kremenek
16331f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis  if (!Act->hasEmittedPreamblePCH()) {
1634739f9e575cfa3ade546b3845eeea86eabd67357fArgyrios Kyrtzidis    // The preamble PCH failed (e.g. there was a module loading fatal error),
1635739f9e575cfa3ade546b3845eeea86eabd67357fArgyrios Kyrtzidis    // so no precompiled header was generated. Forget that we even tried.
163606e504462014b0506a70c7730ea45c551a103364Douglas Gregor    // FIXME: Should we leave a note for ourselves to try again?
163721b1824304076325a72239a4446e5f7e97370cfdRafael Espindola    llvm::sys::fs::remove(FrontendOpts.OutputFile);
1638175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor    Preamble.clear();
1639eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor    TopLevelDeclsInPreamble.clear();
1640eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor    PreambleRebuildCounter = DefaultPreambleRebuildInterval;
1641671947b18dba342f9aba022ee992babef325a833Douglas Gregor    PreprocessorOpts.eraseRemappedFile(
1642671947b18dba342f9aba022ee992babef325a833Douglas Gregor                               PreprocessorOpts.remapped_file_buffer_end() - 1);
1643754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor    return 0;
1644175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  }
1645175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor
1646f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  // Transfer any diagnostics generated when parsing the preamble into the set
1647f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  // of preamble diagnostics.
1648f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  PreambleDiagnostics.clear();
1649f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  PreambleDiagnostics.insert(PreambleDiagnostics.end(),
16503e9d32656a8a3a787f64f9beeef66d2d700eb85dArgyrios Kyrtzidis                            stored_diag_afterDriver_begin(), stored_diag_end());
16517f3a458cd46f19a854fb710fa9d27c411ddd5101Argyrios Kyrtzidis  checkAndRemoveNonDriverDiags(StoredDiagnostics);
1652f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor
1653175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  // Keep track of the preamble we precompiled.
16541872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  setPreambleFile(this, FrontendOpts.OutputFile);
1655c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor  NumWarningsInPreamble = getDiagnostics().getNumWarnings();
1656cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor
1657cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor  // Keep track of all of the files that the source manager knows about,
1658cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor  // so we can verify whether they have changed or not.
1659cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor  FilesInPreamble.clear();
166003201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  SourceManager &SourceMgr = Clang->getSourceManager();
1661cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor  const llvm::MemoryBuffer *MainFileBuffer
1662cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor    = SourceMgr.getBuffer(SourceMgr.getMainFileID());
1663cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor  for (SourceManager::fileinfo_iterator F = SourceMgr.fileinfo_begin(),
1664cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor                                     FEnd = SourceMgr.fileinfo_end();
1665cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor       F != FEnd;
1666cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor       ++F) {
1667b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    const FileEntry *File = F->second->OrigEntry;
1668cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor    if (!File || F->second->getRawBuffer() == MainFileBuffer)
1669cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor      continue;
1670cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor
1671cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor    FilesInPreamble[File->getName()]
1672cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor      = std::make_pair(F->second->getSize(), File->getModificationTime());
1673cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor  }
1674cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor
1675eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor  PreambleRebuildCounter = 1;
1676671947b18dba342f9aba022ee992babef325a833Douglas Gregor  PreprocessorOpts.eraseRemappedFile(
1677671947b18dba342f9aba022ee992babef325a833Douglas Gregor                               PreprocessorOpts.remapped_file_buffer_end() - 1);
16789b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor
16799b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  // If the hash of top-level entities differs from the hash of the top-level
16809b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  // entities the last time we rebuilt the preamble, clear out the completion
16819b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  // cache.
16829b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  if (CurrentTopLevelHashValue != PreambleTopLevelHashValue) {
16839b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    CompletionCacheTopLevelHashValue = 0;
16849b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor    PreambleTopLevelHashValue = CurrentTopLevelHashValue;
16859b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  }
16869b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor
1687754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor  return CreatePaddedMainFileBuffer(NewPreamble.first,
1688754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor                                    PreambleReservedSize,
16898616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis                                    FrontendOpts.Inputs[0].getFile());
169044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor}
1691abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor
1692eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregorvoid ASTUnit::RealizeTopLevelDeclsFromPreamble() {
1693eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  std::vector<Decl *> Resolved;
1694eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  Resolved.reserve(TopLevelDeclsInPreamble.size());
1695eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  ExternalASTSource &Source = *getASTContext().getExternalSource();
1696eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  for (unsigned I = 0, N = TopLevelDeclsInPreamble.size(); I != N; ++I) {
1697eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor    // Resolve the declaration ID to an actual declaration, possibly
1698eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor    // deserializing the declaration in the process.
1699eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor    Decl *D = Source.GetExternalDecl(TopLevelDeclsInPreamble[I]);
1700eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor    if (D)
1701eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor      Resolved.push_back(D);
1702eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  }
1703eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  TopLevelDeclsInPreamble.clear();
1704eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end());
1705eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor}
1706eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor
1707e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidisvoid ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) {
1708e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  // Steal the created target, context, and preprocessor.
1709e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  TheSema.reset(CI.takeSema());
1710e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  Consumer.reset(CI.takeASTConsumer());
1711e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  Ctx = &CI.getASTContext();
1712e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  PP = &CI.getPreprocessor();
1713e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  CI.setSourceManager(0);
1714e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  CI.setFileManager(0);
1715e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  Target = &CI.getTarget();
1716e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  Reader = CI.getModuleManager();
17173b7deda7137e62810a810ce25b062927a9fc7c71Argyrios Kyrtzidis  HadModuleLoaderFatalFailure = CI.hadModuleLoaderFatalFailure();
1718e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis}
1719e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis
17205f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerStringRef ASTUnit::getMainFileName() const {
1721814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis  if (Invocation && !Invocation->getFrontendOpts().Inputs.empty()) {
1722814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis    const FrontendInputFile &Input = Invocation->getFrontendOpts().Inputs[0];
1723814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis    if (Input.isFile())
1724814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis      return Input.getFile();
1725814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis    else
1726814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis      return Input.getBuffer()->getBufferIdentifier();
1727814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis  }
1728814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis
1729814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis  if (SourceMgr) {
1730814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis    if (const FileEntry *
1731814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis          FE = SourceMgr->getFileEntryForID(SourceMgr->getMainFileID()))
1732814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis      return FE->getName();
1733814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis  }
1734814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis
1735814b51a3d572d4e4107e67d549c8a82484ce8160Argyrios Kyrtzidis  return StringRef();
1736213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor}
1737213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor
173844f65a587ee39c20e715c9df411c864d328c71b5Argyrios KyrtzidisStringRef ASTUnit::getASTFileName() const {
173944f65a587ee39c20e715c9df411c864d328c71b5Argyrios Kyrtzidis  if (!isMainFileAST())
174044f65a587ee39c20e715c9df411c864d328c71b5Argyrios Kyrtzidis    return StringRef();
174144f65a587ee39c20e715c9df411c864d328c71b5Argyrios Kyrtzidis
174244f65a587ee39c20e715c9df411c864d328c71b5Argyrios Kyrtzidis  serialization::ModuleFile &
174344f65a587ee39c20e715c9df411c864d328c71b5Argyrios Kyrtzidis    Mod = Reader->getModuleManager().getPrimaryModule();
174444f65a587ee39c20e715c9df411c864d328c71b5Argyrios Kyrtzidis  return Mod.FileName;
174544f65a587ee39c20e715c9df411c864d328c71b5Argyrios Kyrtzidis}
174644f65a587ee39c20e715c9df411c864d328c71b5Argyrios Kyrtzidis
1747b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios KyrtzidisASTUnit *ASTUnit::create(CompilerInvocation *CI,
1748c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith                         IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
1749ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                         bool CaptureDiagnostics,
1750ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                         bool UserFilesAreVolatile) {
17516f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<ASTUnit> AST;
1752b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis  AST.reset(new ASTUnit(false));
1753991bf49f68e8caeb900dd9738712b861073363d9Argyrios Kyrtzidis  ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics);
1754b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis  AST->Diagnostics = Diags;
17554f32786ac45210143654390177105eb749b614e9Ted Kremenek  AST->Invocation = CI;
17560d8d7e6067f9093e7d5abc45c9639ab977aab692Anders Carlsson  AST->FileSystemOpts = CI->getFileSystemOpts();
17574f32786ac45210143654390177105eb749b614e9Ted Kremenek  AST->FileMgr = new FileManager(AST->FileSystemOpts);
1758ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis  AST->UserFilesAreVolatile = UserFilesAreVolatile;
1759ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis  AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr,
1760ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                     UserFilesAreVolatile);
1761b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis
1762b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis  return AST.take();
1763b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis}
1764b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis
1765d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios KyrtzidisASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI,
1766c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith                              IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
1767abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis                                             ASTFrontendAction *Action,
17686f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis                                             ASTUnit *Unit,
17696f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis                                             bool Persistent,
17706f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis                                             StringRef ResourceFilesPath,
17716f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis                                             bool OnlyLocalDecls,
17726f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis                                             bool CaptureDiagnostics,
17736f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis                                             bool PrecompilePreamble,
1774e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis                                             bool CacheCodeCompletionResults,
1775d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko                                    bool IncludeBriefCommentsInCodeCompletion,
1776ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                             bool UserFilesAreVolatile,
1777e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis                                             OwningPtr<ASTUnit> *ErrAST) {
1778d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  assert(CI && "A CompilerInvocation is required");
1779d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
17806f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<ASTUnit> OwnAST;
1781abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis  ASTUnit *AST = Unit;
1782abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis  if (!AST) {
1783abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis    // Create the AST unit.
1784ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis    OwnAST.reset(create(CI, Diags, CaptureDiagnostics, UserFilesAreVolatile));
1785abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis    AST = OwnAST.get();
1786abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis  }
1787abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis
17886f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  if (!ResourceFilesPath.empty()) {
17896f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis    // Override the resources path.
17906f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis    CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
17916f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  }
17926f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  AST->OnlyLocalDecls = OnlyLocalDecls;
17936f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  AST->CaptureDiagnostics = CaptureDiagnostics;
17946f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  if (PrecompilePreamble)
17956f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis    AST->PreambleRebuildCounter = 2;
1796467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor  AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete;
17976f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1798d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko  AST->IncludeBriefCommentsInCodeCompletion
1799d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko    = IncludeBriefCommentsInCodeCompletion;
1800d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
1801d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  // Recover resources if we crash before exiting this method.
1802d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1803abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis    ASTUnitCleanup(OwnAST.get());
1804d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
1805d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie    llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
1806d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis    DiagCleanup(Diags.getPtr());
1807d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
1808d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  // We'll manage file buffers ourselves.
1809d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  CI->getPreprocessorOpts().RetainRemappedFileBuffers = true;
1810d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  CI->getFrontendOpts().DisableFree = false;
1811d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts());
1812d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
1813d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  // Create the compiler instance to use for building the AST.
18146f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<CompilerInstance> Clang(new CompilerInstance());
1815d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
1816d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  // Recover resources if we crash before exiting this method.
1817d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
1818d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis    CICleanup(Clang.get());
1819d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
1820d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  Clang->setInvocation(CI);
18218616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis  AST->OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile();
1822d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
1823d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  // Set up diagnostics, capturing any diagnostics that would
1824d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  // otherwise be dropped.
1825d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  Clang->setDiagnostics(&AST->getDiagnostics());
1826d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
1827d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  // Create the target instance.
1828d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
182949a87549f4dc95ecb3d8a593b71df7c167a51f85Douglas Gregor                                                &Clang->getTargetOpts()));
1830d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  if (!Clang->hasTarget())
1831d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis    return 0;
1832d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
1833d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  // Inform the target of the language options.
1834d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  //
1835d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  // FIXME: We shouldn't need to do this, the target should be immutable once
1836d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  // created. This complexity should be lifted elsewhere.
1837d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  Clang->getTarget().setForcedLangOptions(Clang->getLangOpts());
1838d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
1839d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
1840d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis         "Invocation must have exactly one source file!");
18418616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis  assert(Clang->getFrontendOpts().Inputs[0].getKind() != IK_AST &&
1842d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis         "FIXME: AST inputs not yet supported here!");
18438616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis  assert(Clang->getFrontendOpts().Inputs[0].getKind() != IK_LLVM_IR &&
1844d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis         "IR inputs not supported here!");
1845d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
1846d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  // Configure the various subsystems.
1847d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  AST->TheSema.reset();
1848d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  AST->Ctx = 0;
1849d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  AST->PP = 0;
185062ba9f61af6177992d8cd2e3306257e1213b1bd3Argyrios Kyrtzidis  AST->Reader = 0;
1851d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
1852d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  // Create a file manager object to provide access to and cache the filesystem.
1853d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  Clang->setFileManager(&AST->getFileManager());
1854d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
1855d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  // Create the source manager.
1856d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  Clang->setSourceManager(&AST->getSourceManager());
1857d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
1858d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  ASTFrontendAction *Act = Action;
1859d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
18606f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<TopLevelDeclTrackerAction> TrackerAct;
1861d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  if (!Act) {
1862d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis    TrackerAct.reset(new TopLevelDeclTrackerAction(*AST));
1863d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis    Act = TrackerAct.get();
1864d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  }
1865d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
1866d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  // Recover resources if we crash before exiting this method.
1867d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
1868d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis    ActCleanup(TrackerAct.get());
1869d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
1870e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {
1871e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis    AST->transferASTDataFromCompilerInstance(*Clang);
1872e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis    if (OwnAST && ErrAST)
1873e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis      ErrAST->swap(OwnAST);
1874e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis
1875d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis    return 0;
1876e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  }
18776f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis
18786f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  if (Persistent && !TrackerAct) {
18796f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis    Clang->getPreprocessor().addPPCallbacks(
18806f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis     new MacroDefinitionTrackerPPCallbacks(AST->getCurrentTopLevelHashValue()));
18816f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis    std::vector<ASTConsumer*> Consumers;
18826f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis    if (Clang->hasASTConsumer())
18836f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis      Consumers.push_back(Clang->takeASTConsumer());
18846f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis    Consumers.push_back(new TopLevelDeclTrackerConsumer(*AST,
18856f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis                                           AST->getCurrentTopLevelHashValue()));
18866f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis    Clang->setASTConsumer(new MultiplexConsumer(Consumers));
18876f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  }
1888374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis  if (!Act->Execute()) {
1889374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis    AST->transferASTDataFromCompilerInstance(*Clang);
1890374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis    if (OwnAST && ErrAST)
1891374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis      ErrAST->swap(OwnAST);
1892374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis
1893374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis    return 0;
1894374a00bcc6e26b4fc3cd1d378a5d056c4c7d618eArgyrios Kyrtzidis  }
1895e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis
1896d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  // Steal the created target, context, and preprocessor.
1897e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  AST->transferASTDataFromCompilerInstance(*Clang);
1898d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
1899d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis  Act->EndSourceFile();
1900d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
1901abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis  if (OwnAST)
1902abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis    return OwnAST.take();
1903abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis  else
1904abb5afadd11b19568359880faa5d966a4e33551cArgyrios Kyrtzidis    return AST;
1905d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis}
1906d808bd2978bd4ac95a92b309b038452b533fd7a0Argyrios Kyrtzidis
19074cd912aa94656697a44c3ebb159f05060300524eDouglas Gregorbool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) {
19084cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  if (!Invocation)
19094cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor    return true;
19104cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor
19114cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  // We'll manage file buffers ourselves.
19124cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  Invocation->getPreprocessorOpts().RetainRemappedFileBuffers = true;
19134cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  Invocation->getFrontendOpts().DisableFree = false;
19140b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor  ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
19154cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor
19164cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  llvm::MemoryBuffer *OverrideMainBuffer = 0;
191799ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor  if (PrecompilePreamble) {
191808bb4c622d0b79c33b4ac78ce1bec79398953daaDouglas Gregor    PreambleRebuildCounter = 2;
19194cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor    OverrideMainBuffer
19204cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor      = getMainBufferWithPrecompiledPreamble(*Invocation);
19214cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  }
19224cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor
1923213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor  SimpleTimer ParsingTimer(WantTiming);
1924edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer  ParsingTimer.setOutput("Parsing " + getMainFileName());
19254cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor
192625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  // Recover resources if we crash before exiting this method.
192725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer>
192825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    MemBufferCleanup(OverrideMainBuffer);
192925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek
1930213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor  return Parse(OverrideMainBuffer);
19314cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor}
19324cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor
1933abc563f554951259bbe0315055cad92ee14d87e4Douglas GregorASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
1934c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith                              IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
1935abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor                                             bool OnlyLocalDecls,
193644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor                                             bool CaptureDiagnostics,
1937df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor                                             bool PrecompilePreamble,
1938467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor                                             TranslationUnitKind TUKind,
1939d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko                                             bool CacheCodeCompletionResults,
1940ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                    bool IncludeBriefCommentsInCodeCompletion,
1941ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                             bool UserFilesAreVolatile) {
1942abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor  // Create the AST unit.
19436f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<ASTUnit> AST;
1944abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor  AST.reset(new ASTUnit(false));
19450b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor  ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics);
1946abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor  AST->Diagnostics = Diags;
1947abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor  AST->OnlyLocalDecls = OnlyLocalDecls;
1948e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor  AST->CaptureDiagnostics = CaptureDiagnostics;
1949467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor  AST->TUKind = TUKind;
195087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1951d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko  AST->IncludeBriefCommentsInCodeCompletion
1952d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko    = IncludeBriefCommentsInCodeCompletion;
19534f32786ac45210143654390177105eb749b614e9Ted Kremenek  AST->Invocation = CI;
1954eb8fc58241e1781a77c958764e16a4c402e4d707Argyrios Kyrtzidis  AST->FileSystemOpts = CI->getFileSystemOpts();
1955eb8fc58241e1781a77c958764e16a4c402e4d707Argyrios Kyrtzidis  AST->FileMgr = new FileManager(AST->FileSystemOpts);
1956ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis  AST->UserFilesAreVolatile = UserFilesAreVolatile;
1957385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor
1958b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek  // Recover resources if we crash before exiting this method.
195925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
196025a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    ASTUnitCleanup(AST.get());
1961d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
1962d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie    llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
196325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    DiagCleanup(Diags.getPtr());
1964b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek
19654cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  return AST->LoadFromCompilerInvocation(PrecompilePreamble)? 0 : AST.take();
1966521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar}
19677b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar
19687b55668db7618334cc40011d3c1e128524d89462Daniel DunbarASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
19697b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar                                      const char **ArgEnd,
1970c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith                                    IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
19715f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                      StringRef ResourceFilesPath,
19727b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar                                      bool OnlyLocalDecls,
1973e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor                                      bool CaptureDiagnostics,
19744db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                      RemappedFile *RemappedFiles,
1975a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                      unsigned NumRemappedFiles,
1976299a4a967b02c9f0d0d94ad8560e3ced893f9116Argyrios Kyrtzidis                                      bool RemappedFilesKeepOriginalName,
1977df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor                                      bool PrecompilePreamble,
1978467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor                                      TranslationUnitKind TUKind,
1979bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis                                      bool CacheCodeCompletionResults,
1980d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko                                      bool IncludeBriefCommentsInCodeCompletion,
1981e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis                                      bool AllowPCHWithCompilerErrors,
19826a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen                                      bool SkipFunctionBodies,
1983ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                      bool UserFilesAreVolatile,
1984900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis                                      bool ForSerialization,
1985e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis                                      OwningPtr<ASTUnit> *ErrAST) {
198628019772db70d4547be05a042eb950bc910f134fDouglas Gregor  if (!Diags.getPtr()) {
19873687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor    // No diagnostics engine was provided, so create our own diagnostics object
19883687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor    // with the default options.
1989d47afb96a3f988e6d21a92fe4dfe875ab227c7c0Sean Silva    Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions());
19903687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  }
19917b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar
19925f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
19934cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor
1994c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith  IntrusiveRefCntPtr<CompilerInvocation> CI;
1995e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor
19964cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  {
1997f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor
1998e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor    CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags,
19994cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor                                      StoredDiagnostics);
20004cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor
2001832316e9a04242972f4b57281dccb8e4cf5894eaArgyrios Kyrtzidis    CI = clang::createInvocationFromCommandLine(
2002e9c0265d6e6b5bf865f4a0c2c00d00ac251e6437Frits van Bommel                                           llvm::makeArrayRef(ArgBegin, ArgEnd),
2003e9c0265d6e6b5bf865f4a0c2c00d00ac251e6437Frits van Bommel                                           Diags);
2004054e4f50e2f1995e91b0cd3c3258aa252785fe3fArgyrios Kyrtzidis    if (!CI)
20054e03c2b9d735063a60cd0623423f4814178857efArgyrios Kyrtzidis      return 0;
20067b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  }
2007e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor
20084db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  // Override any files that need remapping
2009b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis  for (unsigned I = 0; I != NumRemappedFiles; ++I) {
2010b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second;
2011b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    if (const llvm::MemoryBuffer *
2012b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis            memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) {
2013b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, memBuf);
2014b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    } else {
2015b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      const char *fname = fileOrBuf.get<const char *>();
2016b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, fname);
2017b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    }
2018b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis  }
2019bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis  PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();
2020bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis  PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName;
2021bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis  PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;
20224db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor
20238b9adfea5e834eaee0f45d8cc7fb052d68df4a46Daniel Dunbar  // Override the resources path.
2024807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar  CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
20257b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar
20266a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen  CI->getFrontendOpts().SkipFunctionBodies = SkipFunctionBodies;
20276a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen
20284cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  // Create the AST unit.
20296f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<ASTUnit> AST;
20304cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  AST.reset(new ASTUnit(false));
20310b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor  ConfigureDiags(Diags, ArgBegin, ArgEnd, *AST, CaptureDiagnostics);
20324cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  AST->Diagnostics = Diags;
2033d04a982d3472d98e58f58dfc327ca11e236980f5Ted Kremenek  Diags = 0; // Zero out now to ease cleanup during crash recovery.
20340d8d7e6067f9093e7d5abc45c9639ab977aab692Anders Carlsson  AST->FileSystemOpts = CI->getFileSystemOpts();
20354f32786ac45210143654390177105eb749b614e9Ted Kremenek  AST->FileMgr = new FileManager(AST->FileSystemOpts);
20364cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  AST->OnlyLocalDecls = OnlyLocalDecls;
2037e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor  AST->CaptureDiagnostics = CaptureDiagnostics;
2038467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor  AST->TUKind = TUKind;
20394cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
2040d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko  AST->IncludeBriefCommentsInCodeCompletion
2041d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko    = IncludeBriefCommentsInCodeCompletion;
2042ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis  AST->UserFilesAreVolatile = UserFilesAreVolatile;
20434cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
20444cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  AST->StoredDiagnostics.swap(StoredDiagnostics);
20454f32786ac45210143654390177105eb749b614e9Ted Kremenek  AST->Invocation = CI;
2046900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis  if (ForSerialization)
2047900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    AST->WriterData.reset(new ASTWriterData());
2048d04a982d3472d98e58f58dfc327ca11e236980f5Ted Kremenek  CI = 0; // Zero out now to ease cleanup during crash recovery.
2049b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek
2050b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek  // Recover resources if we crash before exiting this method.
205125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
205225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    ASTUnitCleanup(AST.get());
2053b547eebdffb07dbc2a8239ca93b696b051096933Ted Kremenek
2054e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  if (AST->LoadFromCompilerInvocation(PrecompilePreamble)) {
2055e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis    // Some error occurred, if caller wants to examine diagnostics, pass it the
2056e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis    // ASTUnit.
2057e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis    if (ErrAST) {
2058e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis      AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics);
2059e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis      ErrAST->swap(AST);
2060e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis    }
2061e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis    return 0;
2062e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  }
2063e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis
2064e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  return AST.take();
20657b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar}
2066abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor
2067abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregorbool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) {
20684f32786ac45210143654390177105eb749b614e9Ted Kremenek  if (!Invocation)
2069abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor    return true;
2070332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
2071332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  clearFileLevelDecls();
2072abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor
2073213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor  SimpleTimer ParsingTimer(WantTiming);
2074edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer  ParsingTimer.setOutput("Reparsing " + getMainFileName());
2075213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor
2076cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor  // Remap files.
2077f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor  PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
2078f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor  for (PreprocessorOptions::remapped_file_buffer_iterator
2079f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor         R = PPOpts.remapped_file_buffer_begin(),
2080f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor         REnd = PPOpts.remapped_file_buffer_end();
2081f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor       R != REnd;
2082f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor       ++R) {
2083f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor    delete R->second;
2084f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor  }
2085cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor  Invocation->getPreprocessorOpts().clearRemappedFiles();
2086b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis  for (unsigned I = 0; I != NumRemappedFiles; ++I) {
2087b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second;
2088b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    if (const llvm::MemoryBuffer *
2089b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis            memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) {
2090b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
2091b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis                                                        memBuf);
2092b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    } else {
2093b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      const char *fname = fileOrBuf.get<const char *>();
2094b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
2095b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis                                                        fname);
2096b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    }
2097b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis  }
2098cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor
2099eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor  // If we have a preamble file lying around, or if we might try to
2100eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor  // build a precompiled preamble, do so now.
2101754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor  llvm::MemoryBuffer *OverrideMainBuffer = 0;
21021872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  if (!getPreambleFile(this).empty() || PreambleRebuildCounter > 0)
21032283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor    OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation);
2104175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor
2105abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor  // Clear out the diagnostics state.
2106e6825d39e89362105171c013f4018c4d1134ad6fArgyrios Kyrtzidis  getDiagnostics().Reset();
2107e6825d39e89362105171c013f4018c4d1134ad6fArgyrios Kyrtzidis  ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
210827368f9f1942a42b668cd1d9426859566c4f8540Argyrios Kyrtzidis  if (OverrideMainBuffer)
210927368f9f1942a42b668cd1d9426859566c4f8540Argyrios Kyrtzidis    getDiagnostics().setNumWarnings(NumWarningsInPreamble);
2110e6825d39e89362105171c013f4018c4d1134ad6fArgyrios Kyrtzidis
2111175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  // Parse the sources
21129b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor  bool Result = Parse(OverrideMainBuffer);
21132fe17fc5ead5e42ef195618228bca53c79e0e50dArgyrios Kyrtzidis
21142fe17fc5ead5e42ef195618228bca53c79e0e50dArgyrios Kyrtzidis  // If we're caching global code-completion results, and the top-level
21152fe17fc5ead5e42ef195618228bca53c79e0e50dArgyrios Kyrtzidis  // declarations have changed, clear out the code-completion cache.
21162fe17fc5ead5e42ef195618228bca53c79e0e50dArgyrios Kyrtzidis  if (!Result && ShouldCacheCodeCompletionResults &&
21172fe17fc5ead5e42ef195618228bca53c79e0e50dArgyrios Kyrtzidis      CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)
21182fe17fc5ead5e42ef195618228bca53c79e0e50dArgyrios Kyrtzidis    CacheCodeCompletionResults();
21199b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor
212028a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis  // We now need to clear out the completion info related to this translation
212128a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis  // unit; it'll be recreated if necessary.
212228a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis  CCTUInfo.reset();
21238fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor
2124175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  return Result;
2125abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor}
21261abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
212787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor//----------------------------------------------------------------------------//
212887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor// Code completion
212987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor//----------------------------------------------------------------------------//
213087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
213187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregornamespace {
213287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  /// \brief Code completion consumer that combines the cached code-completion
213387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  /// results from an ASTUnit with the code-completion results provided to it,
213487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  /// then passes the result on to
213587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer {
2136026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith    uint64_t NormalContexts;
213787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor    ASTUnit &AST;
213887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor    CodeCompleteConsumer &Next;
213987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
214087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  public:
214187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor    AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next,
2142d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko                                  const CodeCompleteOptions &CodeCompleteOpts)
2143d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko      : CodeCompleteConsumer(CodeCompleteOpts, Next.isOutputBinary()),
2144d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko        AST(AST), Next(Next)
214587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor    {
214687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor      // Compute the set of contexts in which we will look when we don't have
214787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor      // any information about the specific context.
214887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor      NormalContexts
2149026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        = (1LL << CodeCompletionContext::CCC_TopLevel)
2150026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_ObjCInterface)
2151026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_ObjCImplementation)
2152026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_ObjCIvarList)
2153026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_Statement)
2154026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_Expression)
2155026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver)
2156026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_DotMemberAccess)
2157026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_ArrowMemberAccess)
2158026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_ObjCPropertyAccess)
2159026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_ObjCProtocolName)
2160026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression)
2161026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        | (1LL << CodeCompletionContext::CCC_Recovery);
21620268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor
21634e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      if (AST.getASTContext().getLangOpts().CPlusPlus)
2164026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        NormalContexts |= (1LL << CodeCompletionContext::CCC_EnumTag)
2165026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith                       |  (1LL << CodeCompletionContext::CCC_UnionTag)
2166026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith                       |  (1LL << CodeCompletionContext::CCC_ClassOrStructTag);
216787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor    }
216887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
216987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor    virtual void ProcessCodeCompleteResults(Sema &S,
217087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor                                            CodeCompletionContext Context,
21710a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall                                            CodeCompletionResult *Results,
2172697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor                                            unsigned NumResults);
217387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
217487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor    virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
217587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor                                           OverloadCandidate *Candidates,
217687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor                                           unsigned NumCandidates) {
217787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor      Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates);
217887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor    }
2179218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor
2180dae687575010c9c49a4b552f5eef82cd6279d9acDouglas Gregor    virtual CodeCompletionAllocator &getAllocator() {
2181218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor      return Next.getAllocator();
2182218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor    }
218328a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis
218428a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis    virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() {
218528a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis      return Next.getCodeCompletionTUInfo();
218628a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis    }
218787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  };
218887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor}
2189697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor
21905f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor/// \brief Helper function that computes which global names are hidden by the
21915f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor/// local code-completion results.
2192c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenekstatic void CalculateHiddenNames(const CodeCompletionContext &Context,
2193c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek                                 CodeCompletionResult *Results,
2194c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek                                 unsigned NumResults,
2195c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek                                 ASTContext &Ctx,
2196c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek                          llvm::StringSet<llvm::BumpPtrAllocator> &HiddenNames){
21975f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  bool OnlyTagNames = false;
21985f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  switch (Context.getKind()) {
219952779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor  case CodeCompletionContext::CCC_Recovery:
22005f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  case CodeCompletionContext::CCC_TopLevel:
22015f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  case CodeCompletionContext::CCC_ObjCInterface:
22025f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  case CodeCompletionContext::CCC_ObjCImplementation:
22035f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  case CodeCompletionContext::CCC_ObjCIvarList:
22045f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  case CodeCompletionContext::CCC_ClassStructUnion:
22055f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  case CodeCompletionContext::CCC_Statement:
22065f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  case CodeCompletionContext::CCC_Expression:
22075f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  case CodeCompletionContext::CCC_ObjCMessageReceiver:
22083da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor  case CodeCompletionContext::CCC_DotMemberAccess:
22093da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor  case CodeCompletionContext::CCC_ArrowMemberAccess:
22103da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor  case CodeCompletionContext::CCC_ObjCPropertyAccess:
22115f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  case CodeCompletionContext::CCC_Namespace:
22125f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  case CodeCompletionContext::CCC_Type:
22132ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor  case CodeCompletionContext::CCC_Name:
22142ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor  case CodeCompletionContext::CCC_PotentiallyQualifiedName:
22150268810a46780144a2d5fb5a017c938d1199189cDouglas Gregor  case CodeCompletionContext::CCC_ParenthesizedExpression:
22160f91c8ccb398be2bd40dc402309bd79737542396Douglas Gregor  case CodeCompletionContext::CCC_ObjCInterfaceName:
22175f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor    break;
22185f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor
22195f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  case CodeCompletionContext::CCC_EnumTag:
22205f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  case CodeCompletionContext::CCC_UnionTag:
22215f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  case CodeCompletionContext::CCC_ClassOrStructTag:
22225f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor    OnlyTagNames = true;
22235f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor    break;
22245f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor
22255f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  case CodeCompletionContext::CCC_ObjCProtocolName:
22261fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor  case CodeCompletionContext::CCC_MacroName:
22271fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor  case CodeCompletionContext::CCC_MacroNameUse:
2228f29c5233085a5af795c3c01b94d319e5b3235d56Douglas Gregor  case CodeCompletionContext::CCC_PreprocessorExpression:
2229721f359a350059a81945baa08f63b2e5feceb044Douglas Gregor  case CodeCompletionContext::CCC_PreprocessorDirective:
223059a66946aa7723c7b14831aa50902d533baaa957Douglas Gregor  case CodeCompletionContext::CCC_NaturalLanguage:
2231458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor  case CodeCompletionContext::CCC_SelectorName:
22321a480c403a3b141ab89c9c59cf7b681102a1bfabDouglas Gregor  case CodeCompletionContext::CCC_TypeQualifiers:
223352779fb71795534d0447f6f4d4a6f6a7b09c4639Douglas Gregor  case CodeCompletionContext::CCC_Other:
22345c722c7020b33da57090422b854072258a50b3f0Douglas Gregor  case CodeCompletionContext::CCC_OtherWithMacros:
22353da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor  case CodeCompletionContext::CCC_ObjCInstanceMessage:
22363da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor  case CodeCompletionContext::CCC_ObjCClassMessage:
22373da626b4f38eb0350de960d71271ca77af7a9cc8Douglas Gregor  case CodeCompletionContext::CCC_ObjCCategoryName:
2238721f359a350059a81945baa08f63b2e5feceb044Douglas Gregor    // We're looking for nothing, or we're looking for names that cannot
2239721f359a350059a81945baa08f63b2e5feceb044Douglas Gregor    // be hidden.
22405f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor    return;
22415f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  }
22425f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor
22430a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall  typedef CodeCompletionResult Result;
22445f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  for (unsigned I = 0; I != NumResults; ++I) {
22455f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor    if (Results[I].Kind != Result::RK_Declaration)
22465f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor      continue;
22475f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor
22485f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor    unsigned IDNS
22495f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor      = Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace();
22505f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor
22515f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor    bool Hiding = false;
22525f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor    if (OnlyTagNames)
22535f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor      Hiding = (IDNS & Decl::IDNS_Tag);
22545f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor    else {
22555f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor      unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member |
2256a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor                             Decl::IDNS_Namespace | Decl::IDNS_Ordinary |
2257a5fb7c3b56c3698e19a7c1e97d41150de33cf6c9Douglas Gregor                             Decl::IDNS_NonMemberOperator);
22584e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      if (Ctx.getLangOpts().CPlusPlus)
22595f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor        HiddenIDNS |= Decl::IDNS_Tag;
22605f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor      Hiding = (IDNS & HiddenIDNS);
22615f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor    }
22625f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor
22635f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor    if (!Hiding)
22645f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor      continue;
22655f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor
22665f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor    DeclarationName Name = Results[I].Declaration->getDeclName();
22675f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor    if (IdentifierInfo *Identifier = Name.getAsIdentifierInfo())
22685f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor      HiddenNames.insert(Identifier->getName());
22695f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor    else
22705f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor      HiddenNames.insert(Name.getAsString());
22715f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  }
22725f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor}
22735f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor
22745f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor
2275697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregorvoid AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
2276697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor                                            CodeCompletionContext Context,
22770a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall                                            CodeCompletionResult *Results,
2278697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor                                            unsigned NumResults) {
2279697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor  // Merge the results we were given with the results we cached.
2280697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor  bool AddedResult = false;
2281026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith  uint64_t InContexts =
2282026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith      Context.getKind() == CodeCompletionContext::CCC_Recovery
2283026b3588b9916f3fcb20ad2f02ca5472cbbdc5d7Richard Smith        ? NormalContexts : (1LL << Context.getKind());
22845f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor  // Contains the set of names that are hidden by "local" completion results.
2285c198f6170f9a66a78f12ab014694e2f5701f7f19Ted Kremenek  llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames;
22860a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall  typedef CodeCompletionResult Result;
22875f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Result, 8> AllResults;
2288697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor  for (ASTUnit::cached_completion_iterator
22895535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor            C = AST.cached_completion_begin(),
22905535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor         CEnd = AST.cached_completion_end();
2291697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor       C != CEnd; ++C) {
2292697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor    // If the context we are in matches any of the contexts we are
2293697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor    // interested in, we'll add this result.
2294697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor    if ((C->ShowInContexts & InContexts) == 0)
2295697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor      continue;
2296697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor
2297697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor    // If we haven't added any results previously, do so now.
2298697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor    if (!AddedResult) {
22995f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor      CalculateHiddenNames(Context, Results, NumResults, S.Context,
23005f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor                           HiddenNames);
2301697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor      AllResults.insert(AllResults.end(), Results, Results + NumResults);
2302697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor      AddedResult = true;
2303697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor    }
2304697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor
23055f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor    // Determine whether this global completion result is hidden by a local
23065f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor    // completion result. If so, skip it.
23075f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor    if (C->Kind != CXCursor_MacroDefinition &&
23085f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor        HiddenNames.count(C->Completion->getTypedText()))
23095f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor      continue;
23105f808c2bfe2f95c984029d76deb4aaebcad30cbcDouglas Gregor
2311697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor    // Adjust priority based on similar type classes.
2312697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor    unsigned Priority = C->Priority;
23131fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor    CodeCompletionString *Completion = C->Completion;
2314697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor    if (!Context.getPreferredType().isNull()) {
2315697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor      if (C->Kind == CXCursor_MacroDefinition) {
2316697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor        Priority = getMacroUsagePriority(C->Completion->getTypedText(),
23174e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie                                         S.getLangOpts(),
23181fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor                               Context.getPreferredType()->isAnyPointerType());
2319697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor      } else if (C->Type) {
2320697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor        CanQualType Expected
23215535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor          = S.Context.getCanonicalType(
2322697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor                               Context.getPreferredType().getUnqualifiedType());
2323697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor        SimplifiedTypeClass ExpectedSTC = getSimplifiedTypeClass(Expected);
2324697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor        if (ExpectedSTC == C->TypeClass) {
2325697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor          // We know this type is similar; check for an exact match.
2326697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor          llvm::StringMap<unsigned> &CachedCompletionTypes
23275535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor            = AST.getCachedCompletionTypes();
2328697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor          llvm::StringMap<unsigned>::iterator Pos
23295535d5721b6bfb5df9583bc0632da910a176109dDouglas Gregor            = CachedCompletionTypes.find(QualType(Expected).getAsString());
2330697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor          if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type)
2331697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor            Priority /= CCF_ExactTypeMatch;
2332697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor          else
2333697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor            Priority /= CCF_SimilarTypeMatch;
2334697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor        }
2335697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor      }
2336697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor    }
2337697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor
23381fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor    // Adjust the completion string, if required.
23391fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor    if (C->Kind == CXCursor_MacroDefinition &&
23401fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor        Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) {
23411fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor      // Create a new code-completion string that just contains the
23421fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor      // macro name, without its arguments.
234328a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis      CodeCompletionBuilder Builder(getAllocator(), getCodeCompletionTUInfo(),
234428a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis                                    CCP_CodePattern, C->Availability);
2345218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor      Builder.AddTypedTextChunk(C->Completion->getTypedText());
23464125c37c71c6c8475019497de837204f0ee4370fDouglas Gregor      Priority = CCP_CodePattern;
2347218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor      Completion = Builder.TakeString();
23481fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor    }
23491fbb447e9d43c2c676e94081fbfee7eb6cbe933bDouglas Gregor
2350c04bb926ef693c94560da254e87926e93bb9c92fArgyrios Kyrtzidis    AllResults.push_back(Result(Completion, Priority, C->Kind,
235158ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor                                C->Availability));
2352697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor  }
2353697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor
2354697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor  // If we did not add any cached completion results, just forward the
2355697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor  // results we were given to the next consumer.
2356697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor  if (!AddedResult) {
2357697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor    Next.ProcessCodeCompleteResults(S, Context, Results, NumResults);
2358697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor    return;
2359697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor  }
23601e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor
2361697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor  Next.ProcessCodeCompleteResults(S, Context, AllResults.data(),
2362697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor                                  AllResults.size());
2363697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor}
2364697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor
2365697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor
2366697ca6dc944fd1233a6f07f0777807fbab6a31c1Douglas Gregor
23675f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column,
23681abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                           RemappedFile *RemappedFiles,
23691abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                           unsigned NumRemappedFiles,
2370cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor                           bool IncludeMacros,
2371cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor                           bool IncludeCodePatterns,
2372d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko                           bool IncludeBriefComments,
23731abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                           CodeCompleteConsumer &Consumer,
2374d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie                           DiagnosticsEngine &Diag, LangOptions &LangOpts,
23751abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                           SourceManager &SourceMgr, FileManager &FileMgr,
23765f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                   SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
23775f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner             SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers) {
23784f32786ac45210143654390177105eb749b614e9Ted Kremenek  if (!Invocation)
23791abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    return;
23801abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
2381213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor  SimpleTimer CompletionTimer(WantTiming);
2382edfb7ecea0222be2796469f8c41b836129f833f8Benjamin Kramer  CompletionTimer.setOutput("Code completion @ " + File + ":" +
23835f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                            Twine(Line) + ":" + Twine(Column));
2384df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor
2385c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith  IntrusiveRefCntPtr<CompilerInvocation>
23864f32786ac45210143654390177105eb749b614e9Ted Kremenek    CCInvocation(new CompilerInvocation(*Invocation));
23874f32786ac45210143654390177105eb749b614e9Ted Kremenek
23884f32786ac45210143654390177105eb749b614e9Ted Kremenek  FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts();
2389d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko  CodeCompleteOptions &CodeCompleteOpts = FrontendOpts.CodeCompleteOpts;
23904f32786ac45210143654390177105eb749b614e9Ted Kremenek  PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts();
2391cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor
2392d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko  CodeCompleteOpts.IncludeMacros = IncludeMacros &&
2393d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko                                   CachedCompletionResults.empty();
2394d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko  CodeCompleteOpts.IncludeCodePatterns = IncludeCodePatterns;
2395d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko  CodeCompleteOpts.IncludeGlobals = CachedCompletionResults.empty();
2396d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko  CodeCompleteOpts.IncludeBriefComments = IncludeBriefComments;
2397d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko
2398d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko  assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion);
2399d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko
24001abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  FrontendOpts.CodeCompletionAt.FileName = File;
24011abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  FrontendOpts.CodeCompletionAt.Line = Line;
24021abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  FrontendOpts.CodeCompletionAt.Column = Column;
24031abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
24041abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Set the language options appropriately.
2405d3b74d9ca4f239a7a90ad193378c494306c57352Ted Kremenek  LangOpts = *CCInvocation->getLangOpts();
24061abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
24076f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<CompilerInstance> Clang(new CompilerInstance());
240803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek
240903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  // Recover resources if we crash before exiting this method.
241025a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
241125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    CICleanup(Clang.get());
241203201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek
24134f32786ac45210143654390177105eb749b614e9Ted Kremenek  Clang->setInvocation(&*CCInvocation);
24148616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis  OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile();
24151abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
24161abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Set up diagnostics, capturing any diagnostics produced.
241703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  Clang->setDiagnostics(&Diag);
24181abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  CaptureDroppedDiagnostics Capture(true,
241903201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek                                    Clang->getDiagnostics(),
24201abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                                    StoredDiagnostics);
2421f0c06a3fa424a7bf858d95f6e83c392dbb31ea43Manuel Klimek  ProcessWarningOptions(Diag, CCInvocation->getDiagnosticOpts());
24221abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
24231abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Create the target instance.
242403201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
242549a87549f4dc95ecb3d8a593b71df7c167a51f85Douglas Gregor                                                &Clang->getTargetOpts()));
242603201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  if (!Clang->hasTarget()) {
24274f32786ac45210143654390177105eb749b614e9Ted Kremenek    Clang->setInvocation(0);
2428bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor    return;
24291abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  }
24301abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
24311abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Inform the target of the language options.
24321abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  //
24331abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // FIXME: We shouldn't need to do this, the target should be immutable once
24341abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // created. This complexity should be lifted elsewhere.
243503201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  Clang->getTarget().setForcedLangOptions(Clang->getLangOpts());
24361abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
243703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
24381abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor         "Invocation must have exactly one source file!");
24398616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis  assert(Clang->getFrontendOpts().Inputs[0].getKind() != IK_AST &&
24401abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor         "FIXME: AST inputs not yet supported here!");
24418616f9af65b9a3662f2c9dfed38eeabc509f8446Argyrios Kyrtzidis  assert(Clang->getFrontendOpts().Inputs[0].getKind() != IK_LLVM_IR &&
24421abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor         "IR inputs not support here!");
24431abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
24441abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
24451abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Use the source and file managers that we were given.
244603201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  Clang->setFileManager(&FileMgr);
244703201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  Clang->setSourceManager(&SourceMgr);
24481abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
24491abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Remap files.
24501abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  PreprocessorOpts.clearRemappedFiles();
2451b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  PreprocessorOpts.RetainRemappedFileBuffers = true;
24522283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor  for (unsigned I = 0; I != NumRemappedFiles; ++I) {
2453b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second;
2454b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    if (const llvm::MemoryBuffer *
2455b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis            memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) {
2456b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, memBuf);
2457b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      OwnedBuffers.push_back(memBuf);
2458b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    } else {
2459b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      const char *fname = fileOrBuf.get<const char *>();
2460b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis      PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, fname);
2461b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    }
24622283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor  }
24631abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
246487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  // Use the code completion consumer we were given, but adding any cached
246587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  // code-completion results.
24667f946ad40877df749ad05392cc4b80dc4189d28fDouglas Gregor  AugmentedCodeCompleteConsumer *AugmentedConsumer
2467d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko    = new AugmentedCodeCompleteConsumer(*this, Consumer, CodeCompleteOpts);
246803201fbbdeb3eb7f465610b09c281ee6aa84e3caTed Kremenek  Clang->setCodeCompletionConsumer(AugmentedConsumer);
24691abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
2470df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  // If we have a precompiled preamble, try to use it. We only allow
2471df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  // the use of the precompiled preamble if we're if the completion
2472df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  // point is within the main file, after the end of the precompiled
2473df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  // preamble.
2474df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  llvm::MemoryBuffer *OverrideMainBuffer = 0;
24751872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek  if (!getPreambleFile(this).empty()) {
2476105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola    std::string CompleteFilePath(File);
24774488835d1c78221553909447cf87d7e4ff7f99fbRafael Espindola    llvm::sys::fs::UniqueID CompleteFileID;
2478105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola
2479da4cb0cf401bb546574a7db46e50cda8b9d9c048Rafael Espindola    if (!llvm::sys::fs::getUniqueID(CompleteFilePath, CompleteFileID)) {
2480105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola      std::string MainPath(OriginalSourceFile);
24814488835d1c78221553909447cf87d7e4ff7f99fbRafael Espindola      llvm::sys::fs::UniqueID MainID;
2482da4cb0cf401bb546574a7db46e50cda8b9d9c048Rafael Espindola      if (!llvm::sys::fs::getUniqueID(MainPath, MainID)) {
2483105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola        if (CompleteFileID == MainID && Line > 1)
24842283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor          OverrideMainBuffer
24854f32786ac45210143654390177105eb749b614e9Ted Kremenek            = getMainBufferWithPrecompiledPreamble(*CCInvocation, false,
2486c9c29a8d7a0f78ddf2b393dd92f77c7f2046179cDouglas Gregor                                                   Line - 1);
2487105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola      }
2488105b207db81a4cce4f5e76d8da634d800ff5cb36Rafael Espindola    }
2489df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  }
2490df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor
2491df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  // If the main file has been overridden due to the use of a preamble,
2492df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  // make that override happen and introduce the preamble.
2493df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  if (OverrideMainBuffer) {
2494df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer);
2495df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size();
2496df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    PreprocessorOpts.PrecompiledPreambleBytes.second
2497df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor                                                    = PreambleEndsAtStartOfLine;
24981872b3153a388b3a548c9f699cbc348128059be9Ted Kremenek    PreprocessorOpts.ImplicitPCHInclude = getPreambleFile(this);
2499df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    PreprocessorOpts.DisablePCHValidation = true;
2500df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor
25012283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor    OwnedBuffers.push_back(OverrideMainBuffer);
2502f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor  } else {
2503f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor    PreprocessorOpts.PrecompiledPreambleBytes.first = 0;
2504f128fed9c2ae16d3d6d8b8580b7a257e5c0a7754Douglas Gregor    PreprocessorOpts.PrecompiledPreambleBytes.second = false;
2505df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  }
2506df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor
2507e50904f83b1b09bff487185dd823dfc8415cb300Argyrios Kyrtzidis  // Disable the preprocessing record if modules are not enabled.
2508e50904f83b1b09bff487185dd823dfc8415cb300Argyrios Kyrtzidis  if (!Clang->getLangOpts().Modules)
2509e50904f83b1b09bff487185dd823dfc8415cb300Argyrios Kyrtzidis    PreprocessorOpts.DetailedRecord = false;
2510dca8ee8b7bc86076916a3a80f553f7a4e98c14afDouglas Gregor
25116f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<SyntaxOnlyAction> Act;
25121abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  Act.reset(new SyntaxOnlyAction);
25131f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor  if (Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {
25141abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    Act->Execute();
25151abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    Act->EndSourceFile();
25161abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  }
25171abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor}
25187ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor
2519e6d22027bc22d3767a2acdc80299c76b91159867Argyrios Kyrtzidisbool ASTUnit::Save(StringRef File) {
25203b7deda7137e62810a810ce25b062927a9fc7c71Argyrios Kyrtzidis  if (HadModuleLoaderFatalFailure)
25213b7deda7137e62810a810ce25b062927a9fc7c71Argyrios Kyrtzidis    return true;
25223b7deda7137e62810a810ce25b062927a9fc7c71Argyrios Kyrtzidis
25239cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis  // Write to a temporary file and later rename it to the actual file, to avoid
25249cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis  // possible race conditions.
2525f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<128> TempPath;
25267e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis  TempPath = File;
25277e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis  TempPath += "-%%%%%%%%";
25287e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis  int fd;
252970e7aeccbf5856a84f81366c6c1a0c0c01e70063Rafael Espindola  if (llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath))
2530e6d22027bc22d3767a2acdc80299c76b91159867Argyrios Kyrtzidis    return true;
25319cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis
25327ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor  // FIXME: Can we somehow regenerate the stat cache here, or do we need to
25337ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor  // unconditionally create a stat cache when we parse the file?
25347e90985df09855dc309ed888a5b16a0ae684f8e3Argyrios Kyrtzidis  llvm::raw_fd_ostream Out(fd, /*shouldClose=*/true);
2535b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis
2536b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis  serialize(Out);
2537b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis  Out.close();
25384bd265468cb115efd5c87c59d5a5b6af5d24d48cArgyrios Kyrtzidis  if (Out.has_error()) {
25394bd265468cb115efd5c87c59d5a5b6af5d24d48cArgyrios Kyrtzidis    Out.clear_error();
2540e6d22027bc22d3767a2acdc80299c76b91159867Argyrios Kyrtzidis    return true;
25414bd265468cb115efd5c87c59d5a5b6af5d24d48cArgyrios Kyrtzidis  }
25429cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis
25438d2a701734f6e0aa778f6be4e6b6d561d8ba6fdbRafael Espindola  if (llvm::sys::fs::rename(TempPath.str(), File)) {
25449cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis    bool exists;
25459cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis    llvm::sys::fs::remove(TempPath.str(), exists);
2546e6d22027bc22d3767a2acdc80299c76b91159867Argyrios Kyrtzidis    return true;
25479cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis  }
25489cca68dbfc42f7778f8db0bcfe8b3e575599ac0fArgyrios Kyrtzidis
2549e6d22027bc22d3767a2acdc80299c76b91159867Argyrios Kyrtzidis  return false;
2550b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis}
2551b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis
2552900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidisstatic bool serializeUnit(ASTWriter &Writer,
2553900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis                          SmallVectorImpl<char> &Buffer,
2554900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis                          Sema &S,
2555900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis                          bool hasErrors,
2556900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis                          raw_ostream &OS) {
25574182ed686283b72736b287cbe28583cb641f8934Argyrios Kyrtzidis  Writer.WriteAST(S, std::string(), 0, "", hasErrors);
2558900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis
2559900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis  // Write the generated bitstream to "Out".
2560900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis  if (!Buffer.empty())
2561900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    OS.write(Buffer.data(), Buffer.size());
2562900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis
2563900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis  return false;
2564900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis}
2565900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis
25665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerbool ASTUnit::serialize(raw_ostream &OS) {
2567bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis  bool hasErrors = getDiagnostics().hasErrorOccurred();
2568b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis
2569900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis  if (WriterData)
2570900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis    return serializeUnit(WriterData->Writer, WriterData->Buffer,
2571900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis                         getSema(), hasErrors, OS);
2572900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis
25738d6ff02cb78c67c615125782967b44d1b37e5815Daniel Dunbar  SmallString<128> Buffer;
25747ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor  llvm::BitstreamWriter Stream(Buffer);
2575a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl  ASTWriter Writer(Stream);
2576900ab95e12bb7483971640a91075699eec391804Argyrios Kyrtzidis  return serializeUnit(Writer, Buffer, getSema(), hasErrors, OS);
25777ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor}
2578f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor
2579f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregortypedef ContinuousRangeMap<unsigned, int, 2> SLocRemap;
2580f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor
2581f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregorstatic void TranslateSLoc(SourceLocation &L, SLocRemap &Remap) {
2582f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  unsigned Raw = L.getRawEncoding();
2583f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  const unsigned MacroBit = 1U << 31;
2584f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  L = SourceLocation::getFromRawEncoding((Raw & MacroBit) |
2585f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor      ((Raw & ~MacroBit) + Remap.find(Raw & ~MacroBit)->second));
2586f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor}
2587f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor
2588f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregorvoid ASTUnit::TranslateStoredDiagnostics(
2589f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor                          ASTReader *MMan,
25905f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                          StringRef ModName,
2591f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor                          SourceManager &SrcMgr,
25925f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                          const SmallVectorImpl<StoredDiagnostic> &Diags,
25935f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                          SmallVectorImpl<StoredDiagnostic> &Out) {
2594f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  // The stored diagnostic has the old source manager in it; update
2595f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  // the locations to refer into the new source manager. We also need to remap
2596f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  // all the locations to the new view. This includes the diag location, any
2597f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  // associated source ranges, and the source ranges of associated fix-its.
2598f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  // FIXME: There should be a cleaner way to do this.
2599f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor
26005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<StoredDiagnostic, 4> Result;
2601f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  Result.reserve(Diags.size());
2602f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  assert(MMan && "Don't have a module manager");
26031a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor  serialization::ModuleFile *Mod = MMan->ModuleMgr.lookup(ModName);
2604f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  assert(Mod && "Don't have preamble module");
2605f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  SLocRemap &Remap = Mod->SLocRemap;
2606f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  for (unsigned I = 0, N = Diags.size(); I != N; ++I) {
2607f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    // Rebuild the StoredDiagnostic.
2608f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    const StoredDiagnostic &SD = Diags[I];
2609f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    SourceLocation L = SD.getLocation();
2610f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    TranslateSLoc(L, Remap);
2611f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    FullSourceLoc Loc(L, SrcMgr);
2612f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor
26135f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<CharSourceRange, 4> Ranges;
2614f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    Ranges.reserve(SD.range_size());
2615f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    for (StoredDiagnostic::range_iterator I = SD.range_begin(),
2616f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor                                          E = SD.range_end();
2617f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor         I != E; ++I) {
2618f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor      SourceLocation BL = I->getBegin();
2619f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor      TranslateSLoc(BL, Remap);
2620f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor      SourceLocation EL = I->getEnd();
2621f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor      TranslateSLoc(EL, Remap);
2622f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor      Ranges.push_back(CharSourceRange(SourceRange(BL, EL), I->isTokenRange()));
2623f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    }
2624f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor
26255f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<FixItHint, 2> FixIts;
2626f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    FixIts.reserve(SD.fixit_size());
2627f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    for (StoredDiagnostic::fixit_iterator I = SD.fixit_begin(),
2628f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor                                          E = SD.fixit_end();
2629f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor         I != E; ++I) {
2630f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor      FixIts.push_back(FixItHint());
2631f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor      FixItHint &FH = FixIts.back();
2632f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor      FH.CodeToInsert = I->CodeToInsert;
2633f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor      SourceLocation BL = I->RemoveRange.getBegin();
2634f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor      TranslateSLoc(BL, Remap);
2635f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor      SourceLocation EL = I->RemoveRange.getEnd();
2636f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor      TranslateSLoc(EL, Remap);
2637f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor      FH.RemoveRange = CharSourceRange(SourceRange(BL, EL),
2638f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor                                       I->RemoveRange.isTokenRange());
2639f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    }
2640f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor
2641f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    Result.push_back(StoredDiagnostic(SD.getLevel(), SD.getID(),
2642f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor                                      SD.getMessage(), Loc, Ranges, FixIts));
2643f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  }
2644f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  Result.swap(Out);
2645f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor}
2646507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis
2647332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidisstatic inline bool compLocDecl(std::pair<unsigned, Decl *> L,
2648332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis                               std::pair<unsigned, Decl *> R) {
2649332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  return L.first < R.first;
2650332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis}
2651332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
2652332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidisvoid ASTUnit::addFileLevelDecl(Decl *D) {
2653332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  assert(D);
265466e870029fdc1a36e79e62fd64430b527a318868Douglas Gregor
265566e870029fdc1a36e79e62fd64430b527a318868Douglas Gregor  // We only care about local declarations.
265666e870029fdc1a36e79e62fd64430b527a318868Douglas Gregor  if (D->isFromASTFile())
265766e870029fdc1a36e79e62fd64430b527a318868Douglas Gregor    return;
2658332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
2659332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  SourceManager &SM = *SourceMgr;
2660332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  SourceLocation Loc = D->getLocation();
2661332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  if (Loc.isInvalid() || !SM.isLocalSourceLocation(Loc))
2662332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    return;
2663332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
2664332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  // We only keep track of the file-level declarations of each file.
2665332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  if (!D->getLexicalDeclContext()->isFileContext())
2666332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    return;
2667332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
2668332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  SourceLocation FileLoc = SM.getFileLoc(Loc);
2669332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  assert(SM.isLocalSourceLocation(FileLoc));
2670332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  FileID FID;
2671332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  unsigned Offset;
2672332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  llvm::tie(FID, Offset) = SM.getDecomposedLoc(FileLoc);
2673332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  if (FID.isInvalid())
2674332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    return;
2675332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
2676332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  LocDeclsTy *&Decls = FileDecls[FID];
2677332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  if (!Decls)
2678332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    Decls = new LocDeclsTy();
2679332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
2680332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  std::pair<unsigned, Decl *> LocDecl(Offset, D);
2681332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
2682332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  if (Decls->empty() || Decls->back().first <= Offset) {
2683332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    Decls->push_back(LocDecl);
2684332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    return;
2685332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  }
2686332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
2687332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  LocDeclsTy::iterator
2688332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis    I = std::upper_bound(Decls->begin(), Decls->end(), LocDecl, compLocDecl);
2689332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
2690332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis  Decls->insert(I, LocDecl);
2691332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis}
2692332cb9be88fd2d1b294a2fbc299c354e93be673cArgyrios Kyrtzidis
2693dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidisvoid ASTUnit::findFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
2694dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis                                  SmallVectorImpl<Decl *> &Decls) {
2695dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis  if (File.isInvalid())
2696dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis    return;
2697dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis
2698dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis  if (SourceMgr->isLoadedFileID(File)) {
2699dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis    assert(Ctx->getExternalSource() && "No external source!");
2700dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis    return Ctx->getExternalSource()->FindFileRegionDecls(File, Offset, Length,
2701dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis                                                         Decls);
2702dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis  }
2703dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis
2704dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis  FileDeclsTy::iterator I = FileDecls.find(File);
2705dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis  if (I == FileDecls.end())
2706dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis    return;
2707dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis
2708dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis  LocDeclsTy &LocDecls = *I->second;
2709dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis  if (LocDecls.empty())
2710dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis    return;
2711dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis
2712dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis  LocDeclsTy::iterator
2713dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis    BeginIt = std::lower_bound(LocDecls.begin(), LocDecls.end(),
2714dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis                               std::make_pair(Offset, (Decl*)0), compLocDecl);
2715dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis  if (BeginIt != LocDecls.begin())
2716dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis    --BeginIt;
2717dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis
2718c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis  // If we are pointing at a top-level decl inside an objc container, we need
2719c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis  // to backtrack until we find it otherwise we will fail to report that the
2720c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis  // region overlaps with an objc container.
2721c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis  while (BeginIt != LocDecls.begin() &&
2722c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis         BeginIt->second->isTopLevelDeclInObjCContainer())
2723c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis    --BeginIt;
2724c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis
2725dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis  LocDeclsTy::iterator
2726dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis    EndIt = std::upper_bound(LocDecls.begin(), LocDecls.end(),
2727dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis                             std::make_pair(Offset+Length, (Decl*)0),
2728dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis                             compLocDecl);
2729dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis  if (EndIt != LocDecls.end())
2730dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis    ++EndIt;
2731dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis
2732dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis  for (LocDeclsTy::iterator DIt = BeginIt; DIt != EndIt; ++DIt)
2733dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis    Decls.push_back(DIt->second);
2734dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis}
2735dfb332d0081c6641d1dbae6a2aeff757c99cc740Argyrios Kyrtzidis
2736507097ec40105ed927cb5a744fad98f5875aacacArgyrios KyrtzidisSourceLocation ASTUnit::getLocation(const FileEntry *File,
2737507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis                                    unsigned Line, unsigned Col) const {
2738507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis  const SourceManager &SM = getSourceManager();
2739ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis  SourceLocation Loc = SM.translateFileLineCol(File, Line, Col);
2740507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis  return SM.getMacroArgExpandedLocation(Loc);
2741507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis}
2742507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis
2743507097ec40105ed927cb5a744fad98f5875aacacArgyrios KyrtzidisSourceLocation ASTUnit::getLocation(const FileEntry *File,
2744507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis                                    unsigned Offset) const {
2745507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis  const SourceManager &SM = getSourceManager();
2746ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis  SourceLocation FileLoc = SM.translateFileLineCol(File, 1, 1);
2747507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis  return SM.getMacroArgExpandedLocation(FileLoc.getLocWithOffset(Offset));
2748507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis}
2749507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis
2750ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// \brief If \arg Loc is a loaded location from the preamble, returns
2751ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// the corresponding local location of the main file, otherwise it returns
2752ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// \arg Loc.
2753ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios KyrtzidisSourceLocation ASTUnit::mapLocationFromPreamble(SourceLocation Loc) {
2754ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis  FileID PreambleID;
2755ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis  if (SourceMgr)
2756ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis    PreambleID = SourceMgr->getPreambleFileID();
2757ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis
2758ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis  if (Loc.isInvalid() || Preamble.empty() || PreambleID.isInvalid())
2759ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis    return Loc;
2760ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis
2761ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis  unsigned Offs;
2762ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis  if (SourceMgr->isInFileID(Loc, PreambleID, &Offs) && Offs < Preamble.size()) {
2763ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis    SourceLocation FileLoc
2764ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis        = SourceMgr->getLocForStartOfFile(SourceMgr->getMainFileID());
2765ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis    return FileLoc.getLocWithOffset(Offs);
2766ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis  }
2767ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis
2768ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis  return Loc;
2769ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis}
2770ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis
2771ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// \brief If \arg Loc is a local location of the main file but inside the
2772ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// preamble chunk, returns the corresponding loaded location from the
2773ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis/// preamble, otherwise it returns \arg Loc.
2774ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios KyrtzidisSourceLocation ASTUnit::mapLocationToPreamble(SourceLocation Loc) {
2775ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis  FileID PreambleID;
2776ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis  if (SourceMgr)
2777ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis    PreambleID = SourceMgr->getPreambleFileID();
2778ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis
2779ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis  if (Loc.isInvalid() || Preamble.empty() || PreambleID.isInvalid())
2780ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis    return Loc;
2781ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis
2782ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis  unsigned Offs;
2783ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis  if (SourceMgr->isInFileID(Loc, SourceMgr->getMainFileID(), &Offs) &&
2784ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis      Offs < Preamble.size()) {
2785ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis    SourceLocation FileLoc = SourceMgr->getLocForStartOfFile(PreambleID);
2786ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis    return FileLoc.getLocWithOffset(Offs);
2787ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis  }
2788ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis
2789ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis  return Loc;
2790ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis}
2791ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis
2792f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidisbool ASTUnit::isInPreambleFileID(SourceLocation Loc) {
2793f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis  FileID FID;
2794f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis  if (SourceMgr)
2795f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis    FID = SourceMgr->getPreambleFileID();
2796f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis
2797f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis  if (Loc.isInvalid() || FID.isInvalid())
2798f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis    return false;
2799f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis
2800f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis  return SourceMgr->isInFileID(Loc, FID);
2801f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis}
2802f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis
2803f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidisbool ASTUnit::isInMainFileID(SourceLocation Loc) {
2804f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis  FileID FID;
2805f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis  if (SourceMgr)
2806f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis    FID = SourceMgr->getMainFileID();
2807f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis
2808f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis  if (Loc.isInvalid() || FID.isInvalid())
2809f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis    return false;
2810f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis
2811f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis  return SourceMgr->isInFileID(Loc, FID);
2812f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis}
2813f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis
2814f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios KyrtzidisSourceLocation ASTUnit::getEndOfPreambleFileID() {
2815f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis  FileID FID;
2816f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis  if (SourceMgr)
2817f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis    FID = SourceMgr->getPreambleFileID();
2818f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis
2819f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis  if (FID.isInvalid())
2820f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis    return SourceLocation();
2821f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis
2822f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis  return SourceMgr->getLocForEndOfFile(FID);
2823f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis}
2824f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis
2825f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios KyrtzidisSourceLocation ASTUnit::getStartOfMainFileID() {
2826f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis  FileID FID;
2827f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis  if (SourceMgr)
2828f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis    FID = SourceMgr->getMainFileID();
2829f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis
2830f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis  if (FID.isInvalid())
2831f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis    return SourceLocation();
2832f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis
2833f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis  return SourceMgr->getLocForStartOfFile(FID);
2834f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis}
2835f226ff9fe8c8db6c5b74a61ce649eda1491c3502Argyrios Kyrtzidis
2836632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidisstd::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
2837632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios KyrtzidisASTUnit::getLocalPreprocessingEntities() const {
2838632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis  if (isMainFileAST()) {
2839632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis    serialization::ModuleFile &
2840632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis      Mod = Reader->getModuleManager().getPrimaryModule();
2841632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis    return Reader->getModulePreprocessedEntities(Mod);
2842632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis  }
2843632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis
2844632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis  if (PreprocessingRecord *PPRec = PP->getPreprocessingRecord())
2845632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis    return std::make_pair(PPRec->local_begin(), PPRec->local_end());
2846632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis
2847632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis  return std::make_pair(PreprocessingRecord::iterator(),
2848632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis                        PreprocessingRecord::iterator());
2849632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis}
2850632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis
285195c579cae01118eadd311d445ff7f491d0011fb0Argyrios Kyrtzidisbool ASTUnit::visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn) {
28522093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis  if (isMainFileAST()) {
28532093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis    serialization::ModuleFile &
28542093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis      Mod = Reader->getModuleManager().getPrimaryModule();
28552093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis    ASTReader::ModuleDeclIterator MDI, MDE;
28562093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis    llvm::tie(MDI, MDE) = Reader->getModuleFileLevelDecls(Mod);
28572093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis    for (; MDI != MDE; ++MDI) {
28582093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis      if (!Fn(context, *MDI))
28592093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis        return false;
28602093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis    }
28612093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis
28622093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis    return true;
28632093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis  }
28642093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis
28652093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis  for (ASTUnit::top_level_iterator TL = top_level_begin(),
28662093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis                                TLEnd = top_level_end();
28672093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis         TL != TLEnd; ++TL) {
28682093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis    if (!Fn(context, *TL))
28692093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis      return false;
28702093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis  }
28712093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis
28722093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis  return true;
28732093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis}
28742093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis
28753da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidisnamespace {
28763da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidisstruct PCHLocatorInfo {
28773da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis  serialization::ModuleFile *Mod;
28783da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis  PCHLocatorInfo() : Mod(0) {}
28793da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis};
28803da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis}
28813da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis
28823da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidisstatic bool PCHLocator(serialization::ModuleFile &M, void *UserData) {
28833da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis  PCHLocatorInfo &Info = *static_cast<PCHLocatorInfo*>(UserData);
28843da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis  switch (M.Kind) {
28853da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis  case serialization::MK_Module:
28863da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis    return true; // skip dependencies.
28873da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis  case serialization::MK_PCH:
28883da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis    Info.Mod = &M;
28893da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis    return true; // found it.
28903da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis  case serialization::MK_Preamble:
28913da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis    return false; // look in dependencies.
28923da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis  case serialization::MK_MainFile:
28933da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis    return false; // look in dependencies.
28943da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis  }
28953da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis
28963da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis  return true;
28973da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis}
28983da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis
28993da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidisconst FileEntry *ASTUnit::getPCHFile() {
29003da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis  if (!Reader)
29013da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis    return 0;
29023da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis
29033da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis  PCHLocatorInfo Info;
29043da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis  Reader->getModuleManager().visit(PCHLocator, &Info);
29053da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis  if (Info.Mod)
29063da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis    return Info.Mod->File;
29073da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis
29083da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis  return 0;
29093da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis}
29103da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis
291162288edde26ff4af9fc079c979a0e1bdc577ce9dArgyrios Kyrtzidisbool ASTUnit::isModuleFile() {
291262288edde26ff4af9fc079c979a0e1bdc577ce9dArgyrios Kyrtzidis  return isMainFileAST() && !ASTFileLangOpts.CurrentModule.empty();
291362288edde26ff4af9fc079c979a0e1bdc577ce9dArgyrios Kyrtzidis}
291462288edde26ff4af9fc079c979a0e1bdc577ce9dArgyrios Kyrtzidis
2915507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidisvoid ASTUnit::PreambleData::countLines() const {
2916507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis  NumLines = 0;
2917507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis  if (empty())
2918507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis    return;
2919507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis
2920507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis  for (std::vector<char>::const_iterator
2921507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis         I = Buffer.begin(), E = Buffer.end(); I != E; ++I) {
2922507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis    if (*I == '\n')
2923507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis      ++NumLines;
2924507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis  }
2925507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis  if (Buffer.back() != '\n')
2926507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis    ++NumLines;
2927507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis}
2928a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis
2929a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis#ifndef NDEBUG
2930a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios KyrtzidisASTUnit::ConcurrencyState::ConcurrencyState() {
2931a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis  Mutex = new llvm::sys::MutexImpl(/*recursive=*/true);
2932a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis}
2933a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis
2934a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios KyrtzidisASTUnit::ConcurrencyState::~ConcurrencyState() {
2935a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis  delete static_cast<llvm::sys::MutexImpl *>(Mutex);
2936a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis}
2937a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis
2938a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidisvoid ASTUnit::ConcurrencyState::start() {
2939a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis  bool acquired = static_cast<llvm::sys::MutexImpl *>(Mutex)->tryacquire();
2940a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis  assert(acquired && "Concurrent access to ASTUnit!");
2941a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis}
2942a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis
2943a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidisvoid ASTUnit::ConcurrencyState::finish() {
2944a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis  static_cast<llvm::sys::MutexImpl *>(Mutex)->release();
2945a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis}
2946a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis
2947a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis#else // NDEBUG
2948a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis
2949a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios KyrtzidisASTUnit::ConcurrencyState::ConcurrencyState() {}
2950a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios KyrtzidisASTUnit::ConcurrencyState::~ConcurrencyState() {}
2951a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidisvoid ASTUnit::ConcurrencyState::start() {}
2952a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidisvoid ASTUnit::ConcurrencyState::finish() {}
2953a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis
2954a696ece1ac449a2b77e7c0a693b55cb10e9e2068Argyrios Kyrtzidis#endif
2955