blob: 0829ce32cc3c8e8aabfda976fd9ed6f3bda9423b [file] [log] [blame]
Daniel Dunbar636404a2009-11-13 03:51:44 +00001//===--- CompilerInstance.cpp ---------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "clang/Frontend/CompilerInstance.h"
Daniel Dunbardf3e30c2009-11-13 08:20:47 +000011#include "clang/AST/ASTContext.h"
Daniel Dunbar636404a2009-11-13 03:51:44 +000012#include "clang/Basic/Diagnostic.h"
Daniel Dunbar546a6762009-11-13 04:12:06 +000013#include "clang/Basic/FileManager.h"
14#include "clang/Basic/SourceManager.h"
Daniel Dunbar636404a2009-11-13 03:51:44 +000015#include "clang/Basic/TargetInfo.h"
Daniel Dunbaraaa148f2009-11-13 05:52:11 +000016#include "clang/Lex/HeaderSearch.h"
17#include "clang/Lex/Preprocessor.h"
18#include "clang/Lex/PTHManager.h"
Daniel Dunbar7d75afc2009-11-13 05:52:34 +000019#include "clang/Frontend/ChainedDiagnosticClient.h"
20#include "clang/Frontend/TextDiagnosticBuffer.h"
21#include "clang/Frontend/TextDiagnosticPrinter.h"
Daniel Dunbaraaa148f2009-11-13 05:52:11 +000022#include "clang/Frontend/Utils.h"
Daniel Dunbar636404a2009-11-13 03:51:44 +000023#include "llvm/LLVMContext.h"
Daniel Dunbar7d75afc2009-11-13 05:52:34 +000024#include "llvm/Support/raw_ostream.h"
Daniel Dunbar636404a2009-11-13 03:51:44 +000025using namespace clang;
26
27CompilerInstance::CompilerInstance(llvm::LLVMContext *_LLVMContext,
28 bool _OwnsLLVMContext)
29 : LLVMContext(_LLVMContext),
30 OwnsLLVMContext(_OwnsLLVMContext) {
31}
32
33CompilerInstance::~CompilerInstance() {
34 if (OwnsLLVMContext)
35 delete LLVMContext;
36}
Daniel Dunbar546a6762009-11-13 04:12:06 +000037
Daniel Dunbar7d75afc2009-11-13 05:52:34 +000038// Diagnostics
39
40static void SetUpBuildDumpLog(const DiagnosticOptions &DiagOpts,
41 unsigned argc, char **argv,
42 llvm::OwningPtr<DiagnosticClient> &DiagClient) {
43 std::string ErrorInfo;
44 llvm::raw_ostream *OS =
45 new llvm::raw_fd_ostream(DiagOpts.DumpBuildInformation.c_str(), ErrorInfo);
46 if (!ErrorInfo.empty()) {
47 // FIXME: Do not fail like this.
48 llvm::errs() << "error opening -dump-build-information file '"
49 << DiagOpts.DumpBuildInformation << "', option ignored!\n";
50 delete OS;
51 return;
52 }
53
54 (*OS) << "clang-cc command line arguments: ";
55 for (unsigned i = 0; i != argc; ++i)
56 (*OS) << argv[i] << ' ';
57 (*OS) << '\n';
58
59 // Chain in a diagnostic client which will log the diagnostics.
60 DiagnosticClient *Logger =
61 new TextDiagnosticPrinter(*OS, DiagOpts, /*OwnsOutputStream=*/true);
62 DiagClient.reset(new ChainedDiagnosticClient(DiagClient.take(), Logger));
63}
64
65void CompilerInstance::createDiagnostics(int Argc, char **Argv) {
66 Diagnostics.reset(createDiagnostics(getDiagnosticOpts(), Argc, Argv));
67
68 if (Diagnostics)
69 DiagClient.reset(Diagnostics->getClient());
70}
71
72Diagnostic *CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts,
73 int Argc, char **Argv) {
74 // Create the diagnostic client for reporting errors or for
75 // implementing -verify.
76 llvm::OwningPtr<DiagnosticClient> DiagClient;
77 if (Opts.VerifyDiagnostics) {
78 // When checking diagnostics, just buffer them up.
79 DiagClient.reset(new TextDiagnosticBuffer());
80 } else {
81 DiagClient.reset(new TextDiagnosticPrinter(llvm::errs(), Opts));
82 }
83
84 if (!Opts.DumpBuildInformation.empty())
85 SetUpBuildDumpLog(Opts, Argc, Argv, DiagClient);
86
87 // Configure our handling of diagnostics.
88 Diagnostic *Diags = new Diagnostic(DiagClient.take());
89 if (ProcessWarningOptions(*Diags, Opts))
90 return 0;
91
92 return Diags;
93}
94
95// File Manager
96
Daniel Dunbar546a6762009-11-13 04:12:06 +000097void CompilerInstance::createFileManager() {
98 FileMgr.reset(new FileManager());
99}
100
Daniel Dunbar7d75afc2009-11-13 05:52:34 +0000101// Source Manager
102
Daniel Dunbar546a6762009-11-13 04:12:06 +0000103void CompilerInstance::createSourceManager() {
104 SourceMgr.reset(new SourceManager());
105}
Daniel Dunbaraaa148f2009-11-13 05:52:11 +0000106
Daniel Dunbar7d75afc2009-11-13 05:52:34 +0000107// Preprocessor
108
Daniel Dunbaraaa148f2009-11-13 05:52:11 +0000109void CompilerInstance::createPreprocessor() {
110 PP.reset(createPreprocessor(getDiagnostics(), getLangOpts(),
111 getPreprocessorOpts(), getHeaderSearchOpts(),
112 getDependencyOutputOpts(), getTarget(),
113 getSourceManager(), getFileManager()));
114}
115
116Preprocessor *
117CompilerInstance::createPreprocessor(Diagnostic &Diags,
118 const LangOptions &LangInfo,
119 const PreprocessorOptions &PPOpts,
120 const HeaderSearchOptions &HSOpts,
121 const DependencyOutputOptions &DepOpts,
122 const TargetInfo &Target,
123 SourceManager &SourceMgr,
124 FileManager &FileMgr) {
125 // Create a PTH manager if we are using some form of a token cache.
126 PTHManager *PTHMgr = 0;
127 if (!PPOpts.getTokenCache().empty())
128 PTHMgr = PTHManager::Create(PPOpts.getTokenCache(), Diags);
129
130 // FIXME: Don't fail like this.
131 if (Diags.hasErrorOccurred())
132 exit(1);
133
134 // Create the Preprocessor.
135 HeaderSearch *HeaderInfo = new HeaderSearch(FileMgr);
136 Preprocessor *PP = new Preprocessor(Diags, LangInfo, Target,
137 SourceMgr, *HeaderInfo, PTHMgr,
138 /*OwnsHeaderSearch=*/true);
139
140 // Note that this is different then passing PTHMgr to Preprocessor's ctor.
141 // That argument is used as the IdentifierInfoLookup argument to
142 // IdentifierTable's ctor.
143 if (PTHMgr) {
144 PTHMgr->setPreprocessor(PP);
145 PP->setPTHManager(PTHMgr);
146 }
147
148 InitializePreprocessor(*PP, PPOpts, HSOpts);
149
150 // Handle generating dependencies, if requested.
151 if (!DepOpts.OutputFile.empty())
152 AttachDependencyFileGen(*PP, DepOpts);
153
154 return PP;
155}
Daniel Dunbardf3e30c2009-11-13 08:20:47 +0000156
157// ASTContext
158
159void CompilerInstance::createASTContext() {
160 Preprocessor &PP = getPreprocessor();
161 Context.reset(new ASTContext(getLangOpts(), PP.getSourceManager(),
162 getTarget(), PP.getIdentifierTable(),
163 PP.getSelectorTable(), PP.getBuiltinInfo(),
164 /*FreeMemory=*/ !getFrontendOpts().DisableFree,
165 /*size_reserve=*/ 0));
166}