blob: 6ed8fbd5d8ce050a0c9bb52a37c974cf6629dd35 [file] [log] [blame]
Argiris Kirtzidisdbfe01e2009-06-20 08:08:23 +00001#include "clang/Frontend/ASTUnit.h"
2#include "clang/Frontend/PCHReader.h"
3#include "clang/Frontend/TextDiagnosticBuffer.h"
4#include "clang/AST/ASTContext.h"
5#include "clang/AST/DeclVisitor.h"
6#include "clang/AST/StmtVisitor.h"
7#include "clang/Lex/HeaderSearch.h"
8#include "clang/Lex/Preprocessor.h"
9#include "clang/Basic/TargetInfo.h"
10#include "clang/Basic/Diagnostic.h"
11#include "llvm/Support/Compiler.h"
12
13using namespace clang;
14
15ASTUnit::ASTUnit() { }
16ASTUnit::~ASTUnit() { }
17
18namespace {
19
20/// \brief Gathers information from PCHReader that will be used to initialize
21/// a Preprocessor.
22class VISIBILITY_HIDDEN PCHInfoCollector : public PCHReaderListener {
23 LangOptions &LangOpt;
24 HeaderSearch &HSI;
25 std::string &TargetTriple;
26 std::string &Predefines;
27 unsigned &Counter;
28
29 unsigned NumHeaderInfos;
30
31public:
32 PCHInfoCollector(LangOptions &LangOpt, HeaderSearch &HSI,
33 std::string &TargetTriple, std::string &Predefines,
34 unsigned &Counter)
35 : LangOpt(LangOpt), HSI(HSI), TargetTriple(TargetTriple),
36 Predefines(Predefines), Counter(Counter), NumHeaderInfos(0) {}
37
38 virtual bool ReadLanguageOptions(const LangOptions &LangOpts) {
39 LangOpt = LangOpts;
40 return false;
41 }
42
43 virtual bool ReadTargetTriple(const std::string &Triple) {
44 TargetTriple = Triple;
45 return false;
46 }
47
48 virtual bool ReadPredefinesBuffer(const char *PCHPredef,
49 unsigned PCHPredefLen,
50 FileID PCHBufferID,
51 std::string &SuggestedPredefines) {
52 Predefines = PCHPredef;
53 return false;
54 }
55
56 virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI) {
57 HSI.setHeaderFileInfoForUID(HFI, NumHeaderInfos++);
58 }
59
60 virtual void ReadCounter(unsigned Value) {
61 Counter = Value;
62 }
63};
64
65} // anonymous namespace
66
67
68ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
69 FileManager &FileMgr,
70 std::string *ErrMsg) {
71
72 llvm::OwningPtr<ASTUnit> AST(new ASTUnit());
73
74 AST->DiagClient.reset(new TextDiagnosticBuffer());
75 AST->Diags.reset(new Diagnostic(AST->DiagClient.get()));
76
77 AST->HeaderInfo.reset(new HeaderSearch(FileMgr));
78 AST->SourceMgr.reset(new SourceManager());
79
80 Diagnostic &Diags = *AST->Diags.get();
81 SourceManager &SourceMgr = *AST->SourceMgr.get();
82
83 // Gather Info for preprocessor construction later on.
84
85 LangOptions LangInfo;
86 HeaderSearch &HeaderInfo = *AST->HeaderInfo.get();
87 std::string TargetTriple;
88 std::string Predefines;
89 unsigned Counter;
90
91 llvm::OwningPtr<PCHReader> Reader;
92 llvm::OwningPtr<ExternalASTSource> Source;
93
94 Reader.reset(new PCHReader(SourceMgr, FileMgr, Diags));
95 Reader->setListener(new PCHInfoCollector(LangInfo, HeaderInfo, TargetTriple,
96 Predefines, Counter));
97
98 switch (Reader->ReadPCH(Filename)) {
99 case PCHReader::Success:
100 break;
101
102 case PCHReader::Failure:
103 // Unrecoverable failure: don't even try to process the input
104 // file.
105 if (ErrMsg)
106 *ErrMsg = "Could not load PCH file";
107 return NULL;
108
109 case PCHReader::IgnorePCH:
110 assert(0 && "Is there a validation that should not have happened ?");
111 }
112
113 // PCH loaded successfully. Now create the preprocessor.
114
115 // Get information about the target being compiled for.
116 AST->Target.reset(TargetInfo::CreateTargetInfo(TargetTriple));
117 AST->PP.reset(new Preprocessor(Diags, LangInfo, *AST->Target.get(),
118 SourceMgr, HeaderInfo));
119 Preprocessor &PP = *AST->PP.get();
120
121 PP.setPredefines(Predefines);
122 PP.setCounterValue(Counter);
123 Reader->setPreprocessor(PP);
124
125 // Create and initialize the ASTContext.
126
127 AST->Ctx.reset(new ASTContext(LangInfo,
128 SourceMgr,
129 *AST->Target.get(),
130 PP.getIdentifierTable(),
131 PP.getSelectorTable(),
132 PP.getBuiltinInfo(),
133 /* FreeMemory = */ true,
134 /* size_reserve = */0));
135 ASTContext &Context = *AST->Ctx.get();
136
137 Reader->InitializeContext(Context);
138
139 // Attach the PCH reader to the AST context as an external AST
140 // source, so that declarations will be deserialized from the
141 // PCH file as needed.
142 Source.reset(Reader.take());
143 Context.setExternalSource(Source);
144
145 return AST.take();
146}