 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
70.2% |
87 / 124 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
88.7% |
110 / 124 |
| |
|
Line Coverage: |
81.3% |
187 / 230 |
| |
 |
|
 |
1 : //===--- 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"
11 : #include "clang/AST/ASTConsumer.h"
12 : #include "clang/AST/ASTContext.h"
13 : #include "clang/Basic/Diagnostic.h"
14 : #include "clang/Basic/FileManager.h"
15 : #include "clang/Basic/SourceManager.h"
16 : #include "clang/Basic/TargetInfo.h"
17 : #include "clang/Basic/Version.h"
18 : #include "clang/Lex/HeaderSearch.h"
19 : #include "clang/Lex/Preprocessor.h"
20 : #include "clang/Lex/PTHManager.h"
21 : #include "clang/Frontend/ChainedDiagnosticClient.h"
22 : #include "clang/Frontend/FrontendAction.h"
23 : #include "clang/Frontend/PCHReader.h"
24 : #include "clang/Frontend/FrontendDiagnostic.h"
25 : #include "clang/Frontend/TextDiagnosticPrinter.h"
26 : #include "clang/Frontend/VerifyDiagnosticsClient.h"
27 : #include "clang/Frontend/Utils.h"
28 : #include "clang/Sema/CodeCompleteConsumer.h"
29 : #include "llvm/LLVMContext.h"
30 : #include "llvm/Support/MemoryBuffer.h"
31 : #include "llvm/Support/raw_ostream.h"
32 : #include "llvm/Support/Timer.h"
33 : #include "llvm/System/Host.h"
34 : #include "llvm/System/Path.h"
35 : #include "llvm/System/Program.h"
36 : using namespace clang;
37 :
38 : CompilerInstance::CompilerInstance(llvm::LLVMContext *_LLVMContext,
39 2523: bool _OwnsLLVMContext)
40 : : LLVMContext(_LLVMContext),
41 : OwnsLLVMContext(_OwnsLLVMContext),
42 2523: Invocation(new CompilerInvocation) {
43 2523: }
44 :
45 2523: CompilerInstance::~CompilerInstance() {
9: branch 0 taken
2514: branch 1 taken
2514: branch 2 taken
2514: branch 3 taken
46 2523: if (OwnsLLVMContext)
0: branch 0 not taken
9: branch 1 taken
0: branch 4 not taken
0: branch 5 not taken
47 9: delete LLVMContext;
48 2523: }
49 :
50 9: void CompilerInstance::setInvocation(CompilerInvocation *Value) {
51 9: Invocation.reset(Value);
52 9: }
53 :
54 9: void CompilerInstance::setDiagnostics(Diagnostic *Value) {
55 9: Diagnostics.reset(Value);
56 9: }
57 :
58 9: void CompilerInstance::setDiagnosticClient(DiagnosticClient *Value) {
59 9: DiagClient.reset(Value);
60 9: }
61 :
62 2522: void CompilerInstance::setTarget(TargetInfo *Value) {
63 2522: Target.reset(Value);
64 2522: }
65 :
66 11: void CompilerInstance::setFileManager(FileManager *Value) {
67 11: FileMgr.reset(Value);
68 11: }
69 :
70 11: void CompilerInstance::setSourceManager(SourceManager *Value) {
71 11: SourceMgr.reset(Value);
72 11: }
73 :
74 2: void CompilerInstance::setPreprocessor(Preprocessor *Value) {
75 2: PP.reset(Value);
76 2: }
77 :
78 2369: void CompilerInstance::setASTContext(ASTContext *Value) {
79 2369: Context.reset(Value);
80 2369: }
81 :
82 4606: void CompilerInstance::setASTConsumer(ASTConsumer *Value) {
83 4606: Consumer.reset(Value);
84 4606: }
85 :
86 0: void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) {
87 0: CompletionConsumer.reset(Value);
88 0: }
89 :
90 : // Diagnostics
91 : namespace {
52: branch 1 taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
92 52: class BinaryDiagnosticSerializer : public DiagnosticClient {
93 : llvm::raw_ostream &OS;
94 : SourceManager *SourceMgr;
95 : public:
96 52: explicit BinaryDiagnosticSerializer(llvm::raw_ostream &OS)
97 52: : OS(OS), SourceMgr(0) { }
98 :
99 : virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
100 : const DiagnosticInfo &Info);
101 : };
102 : }
103 :
104 : void BinaryDiagnosticSerializer::HandleDiagnostic(Diagnostic::Level DiagLevel,
105 54: const DiagnosticInfo &Info) {
106 54: Info.Serialize(DiagLevel, OS);
107 54: }
108 :
109 : static void SetUpBuildDumpLog(const DiagnosticOptions &DiagOpts,
110 : unsigned argc, char **argv,
111 0: llvm::OwningPtr<DiagnosticClient> &DiagClient) {
112 0: std::string ErrorInfo;
113 : llvm::raw_ostream *OS =
114 0: new llvm::raw_fd_ostream(DiagOpts.DumpBuildInformation.c_str(), ErrorInfo);
0: branch 1 not taken
0: branch 2 not taken
115 0: if (!ErrorInfo.empty()) {
116 : // FIXME: Do not fail like this.
117 : llvm::errs() << "error opening -dump-build-information file '"
118 0: << DiagOpts.DumpBuildInformation << "', option ignored!\n";
0: branch 0 not taken
0: branch 1 not taken
119 0: delete OS;
120 0: return;
121 : }
122 :
123 0: (*OS) << "clang -cc1 command line arguments: ";
0: branch 0 not taken
0: branch 1 not taken
124 0: for (unsigned i = 0; i != argc; ++i)
125 0: (*OS) << argv[i] << ' ';
126 0: (*OS) << '\n';
127 :
128 : // Chain in a diagnostic client which will log the diagnostics.
129 : DiagnosticClient *Logger =
130 0: new TextDiagnosticPrinter(*OS, DiagOpts, /*OwnsOutputStream=*/true);
0: branch 5 not taken
0: branch 6 not taken
131 0: DiagClient.reset(new ChainedDiagnosticClient(DiagClient.take(), Logger));
132 : }
133 :
134 2514: void CompilerInstance::createDiagnostics(int Argc, char **Argv) {
135 2514: Diagnostics.reset(createDiagnostics(getDiagnosticOpts(), Argc, Argv));
136 :
2514: branch 1 taken
0: branch 2 not taken
137 2514: if (Diagnostics)
138 2514: DiagClient.reset(Diagnostics->getClient());
139 2514: }
140 :
141 : Diagnostic *CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts,
142 2583: int Argc, char **Argv) {
143 2583: llvm::OwningPtr<Diagnostic> Diags(new Diagnostic());
144 :
145 : // Create the diagnostic client for reporting errors or for
146 : // implementing -verify.
147 2583: llvm::OwningPtr<DiagnosticClient> DiagClient;
52: branch 0 taken
2531: branch 1 taken
148 2583: if (Opts.BinaryOutput) {
0: branch 1 not taken
52: branch 2 taken
149 52: if (llvm::sys::Program::ChangeStderrToBinary()) {
150 : // We weren't able to set standard error to binary, which is a
151 : // bit of a problem. So, just create a text diagnostic printer
152 : // to complain about this problem, and pretend that the user
153 : // didn't try to use binary output.
154 0: DiagClient.reset(new TextDiagnosticPrinter(llvm::errs(), Opts));
155 0: Diags->setClient(DiagClient.take());
156 0: Diags->Report(diag::err_fe_stderr_binary);
157 0: return Diags.take();
158 : } else {
159 52: DiagClient.reset(new BinaryDiagnosticSerializer(llvm::errs()));
160 : }
161 : } else {
162 2531: DiagClient.reset(new TextDiagnosticPrinter(llvm::errs(), Opts));
163 : }
164 :
165 : // Chain in -verify checker, if requested.
1312: branch 0 taken
1271: branch 1 taken
166 2583: if (Opts.VerifyDiagnostics)
167 1312: DiagClient.reset(new VerifyDiagnosticsClient(*Diags, DiagClient.take()));
168 :
0: branch 1 not taken
2583: branch 2 taken
169 2583: if (!Opts.DumpBuildInformation.empty())
170 0: SetUpBuildDumpLog(Opts, Argc, Argv, DiagClient);
171 :
172 : // Configure our handling of diagnostics.
173 2583: Diags->setClient(DiagClient.take());
0: branch 2 not taken
2583: branch 3 taken
174 2583: if (ProcessWarningOptions(*Diags, Opts))
175 0: return 0;
176 :
177 2583: return Diags.take();
178 : }
179 :
180 : // File Manager
181 :
182 2511: void CompilerInstance::createFileManager() {
183 2511: FileMgr.reset(new FileManager());
184 2511: }
185 :
186 : // Source Manager
187 :
188 2511: void CompilerInstance::createSourceManager() {
189 2511: SourceMgr.reset(new SourceManager());
190 2511: }
191 :
192 : // Preprocessor
193 :
194 2520: void CompilerInstance::createPreprocessor() {
195 : PP.reset(createPreprocessor(getDiagnostics(), getLangOpts(),
196 : getPreprocessorOpts(), getHeaderSearchOpts(),
197 : getDependencyOutputOpts(), getTarget(),
198 : getFrontendOpts(), getSourceManager(),
199 2520: getFileManager()));
200 2520: }
201 :
202 : Preprocessor *
203 : CompilerInstance::createPreprocessor(Diagnostic &Diags,
204 : const LangOptions &LangInfo,
205 : const PreprocessorOptions &PPOpts,
206 : const HeaderSearchOptions &HSOpts,
207 : const DependencyOutputOptions &DepOpts,
208 : const TargetInfo &Target,
209 : const FrontendOptions &FEOpts,
210 : SourceManager &SourceMgr,
211 2520: FileManager &FileMgr) {
212 : // Create a PTH manager if we are using some form of a token cache.
213 2520: PTHManager *PTHMgr = 0;
1: branch 1 taken
2519: branch 2 taken
214 2520: if (!PPOpts.TokenCache.empty())
215 1: PTHMgr = PTHManager::Create(PPOpts.TokenCache, Diags);
216 :
217 : // Create the Preprocessor.
218 2520: HeaderSearch *HeaderInfo = new HeaderSearch(FileMgr);
219 : Preprocessor *PP = new Preprocessor(Diags, LangInfo, Target,
220 : SourceMgr, *HeaderInfo, PTHMgr,
221 2520: /*OwnsHeaderSearch=*/true);
222 :
223 : // Note that this is different then passing PTHMgr to Preprocessor's ctor.
224 : // That argument is used as the IdentifierInfoLookup argument to
225 : // IdentifierTable's ctor.
1: branch 0 taken
2519: branch 1 taken
226 2520: if (PTHMgr) {
227 1: PTHMgr->setPreprocessor(PP);
228 1: PP->setPTHManager(PTHMgr);
229 : }
230 :
231 2520: InitializePreprocessor(*PP, PPOpts, HSOpts, FEOpts);
232 :
233 : // Handle generating dependencies, if requested.
3: branch 1 taken
2517: branch 2 taken
234 2520: if (!DepOpts.OutputFile.empty())
235 3: AttachDependencyFileGen(*PP, DepOpts);
236 :
237 2520: return PP;
238 : }
239 :
240 : // ASTContext
241 :
242 2237: void CompilerInstance::createASTContext() {
243 2237: Preprocessor &PP = getPreprocessor();
244 : Context.reset(new ASTContext(getLangOpts(), PP.getSourceManager(),
245 : getTarget(), PP.getIdentifierTable(),
246 : PP.getSelectorTable(), PP.getBuiltinInfo(),
247 : /*FreeMemory=*/ !getFrontendOpts().DisableFree,
248 2237: /*size_reserve=*/ 0));
249 2237: }
250 :
251 : // ExternalASTSource
252 :
253 35: void CompilerInstance::createPCHExternalASTSource(llvm::StringRef Path) {
254 35: llvm::OwningPtr<ExternalASTSource> Source;
255 : Source.reset(createPCHExternalASTSource(Path, getHeaderSearchOpts().Sysroot,
256 35: getPreprocessor(), getASTContext()));
257 35: getASTContext().setExternalSource(Source);
258 35: }
259 :
260 : ExternalASTSource *
261 : CompilerInstance::createPCHExternalASTSource(llvm::StringRef Path,
262 : const std::string &Sysroot,
263 : Preprocessor &PP,
264 35: ASTContext &Context) {
265 35: llvm::OwningPtr<PCHReader> Reader;
266 : Reader.reset(new PCHReader(PP, &Context,
0: branch 1 not taken
35: branch 2 taken
267 35: Sysroot.empty() ? 0 : Sysroot.c_str()));
268 :
33: branch 4 taken
2: branch 5 taken
269 35: switch (Reader->ReadPCH(Path)) {
270 : case PCHReader::Success:
271 : // Set the predefines buffer as suggested by the PCH reader. Typically, the
272 : // predefines buffer will be empty.
273 33: PP.setPredefines(Reader->getSuggestedPredefines());
33: branch 1 taken
0: branch 2 not taken
274 33: return Reader.take();
275 :
276 : case PCHReader::Failure:
277 : // Unrecoverable failure: don't even try to process the input file.
278 : break;
279 :
280 : case PCHReader::IgnorePCH:
281 : // No suitable PCH file could be found. Return an error.
282 : break;
283 : }
284 :
285 2: return 0;
286 : }
287 :
288 : // Code Completion
289 :
290 87: void CompilerInstance::createCodeCompletionConsumer() {
291 87: const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt;
292 : CompletionConsumer.reset(
293 : createCodeCompletionConsumer(getPreprocessor(),
294 : Loc.FileName, Loc.Line, Loc.Column,
295 : getFrontendOpts().DebugCodeCompletionPrinter,
296 : getFrontendOpts().ShowMacrosInCodeCompletion,
297 87: llvm::outs()));
298 :
51: branch 2 taken
36: branch 3 taken
0: branch 5 not taken
51: branch 6 taken
0: branch 7 not taken
87: branch 8 taken
299 87: if (CompletionConsumer->isOutputBinary() &&
300 : llvm::sys::Program::ChangeStdoutToBinary()) {
301 0: getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary);
302 0: CompletionConsumer.reset();
303 : }
304 87: }
305 :
306 0: void CompilerInstance::createFrontendTimer() {
307 0: FrontendTimer.reset(new llvm::Timer("Clang front-end timer"));
308 0: }
309 :
310 : CodeCompleteConsumer *
311 : CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP,
312 : const std::string &Filename,
313 : unsigned Line,
314 : unsigned Column,
315 : bool UseDebugPrinter,
316 : bool ShowMacros,
317 87: llvm::raw_ostream &OS) {
318 : // Tell the source manager to chop off the given file at a specific
319 : // line and column.
320 87: const FileEntry *Entry = PP.getFileManager().getFile(Filename);
0: branch 0 not taken
87: branch 1 taken
321 87: if (!Entry) {
322 : PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file)
323 0: << Filename;
324 0: return 0;
325 : }
326 :
327 : // Truncate the named file at the given line/column.
328 87: PP.SetCodeCompletionPoint(Entry, Line, Column);
329 :
330 : // Set up the creation routine for code-completion.
36: branch 0 taken
51: branch 1 taken
331 87: if (UseDebugPrinter)
332 36: return new PrintingCodeCompleteConsumer(ShowMacros, OS);
333 : else
334 51: return new CIndexCodeCompleteConsumer(ShowMacros, OS);
335 : }
336 :
337 : // Output Files
338 :
339 : void CompilerInstance::addOutputFile(llvm::StringRef Path,
340 955: llvm::raw_ostream *OS) {
0: branch 0 not taken
955: branch 1 taken
341 955: assert(OS && "Attempt to add empty stream to output list!");
342 955: OutputFiles.push_back(std::make_pair(Path, OS));
343 955: }
344 :
345 2519: void CompilerInstance::ClearOutputFiles(bool EraseFiles) {
955: branch 2 taken
2519: branch 3 taken
346 3474: for (std::list< std::pair<std::string, llvm::raw_ostream*> >::iterator
347 2519: it = OutputFiles.begin(), ie = OutputFiles.end(); it != ie; ++it) {
955: branch 1 taken
0: branch 2 not taken
348 955: delete it->second;
17: branch 0 taken
938: branch 1 taken
1: branch 4 taken
16: branch 5 taken
1: branch 6 taken
954: branch 7 taken
349 955: if (EraseFiles && !it->first.empty())
350 1: llvm::sys::Path(it->first).eraseFromDisk();
351 : }
352 2519: OutputFiles.clear();
353 2519: }
354 :
355 : llvm::raw_fd_ostream *
356 : CompilerInstance::createDefaultOutputFile(bool Binary,
357 : llvm::StringRef InFile,
358 956: llvm::StringRef Extension) {
359 : return createOutputFile(getFrontendOpts().OutputFile, Binary,
360 956: InFile, Extension);
361 : }
362 :
363 : llvm::raw_fd_ostream *
364 : CompilerInstance::createOutputFile(llvm::StringRef OutputPath,
365 : bool Binary,
366 : llvm::StringRef InFile,
367 956: llvm::StringRef Extension) {
368 956: std::string Error, OutputPathName;
369 : llvm::raw_fd_ostream *OS = createOutputFile(OutputPath, Error, Binary,
370 : InFile, Extension,
371 956: &OutputPathName);
1: branch 0 taken
955: branch 1 taken
372 956: if (!OS) {
373 : getDiagnostics().Report(diag::err_fe_unable_to_open_output)
374 1: << OutputPath << Error;
375 1: return 0;
376 : }
377 :
378 : // Add the output file -- but don't try to remove "-", since this means we are
379 : // using stdin.
381: branch 1 taken
574: branch 2 taken
574: branch 9 taken
381: branch 10 taken
380 955: addOutputFile((OutputPathName != "-") ? OutputPathName : "", OS);
381 :
382 955: return OS;
383 : }
384 :
385 : llvm::raw_fd_ostream *
386 : CompilerInstance::createOutputFile(llvm::StringRef OutputPath,
387 : std::string &Error,
388 : bool Binary,
389 : llvm::StringRef InFile,
390 : llvm::StringRef Extension,
391 956: std::string *ResultPathName) {
392 956: std::string OutFile;
708: branch 1 taken
248: branch 2 taken
393 956: if (!OutputPath.empty()) {
394 708: OutFile = OutputPath;
64: branch 2 taken
184: branch 3 taken
395 248: } else if (InFile == "-") {
396 64: OutFile = "-";
0: branch 1 not taken
184: branch 2 taken
397 184: } else if (!Extension.empty()) {
398 0: llvm::sys::Path Path(InFile);
399 0: Path.eraseSuffix();
400 0: Path.appendSuffix(Extension);
401 0: OutFile = Path.str();
402 : } else {
403 184: OutFile = "-";
404 : }
405 :
406 : llvm::OwningPtr<llvm::raw_fd_ostream> OS(
407 : new llvm::raw_fd_ostream(OutFile.c_str(), Error,
309: branch 2 taken
647: branch 3 taken
408 956: (Binary ? llvm::raw_fd_ostream::F_Binary : 0)));
1: branch 1 taken
955: branch 2 taken
409 956: if (!Error.empty())
410 1: return 0;
411 :
955: branch 0 taken
0: branch 1 not taken
412 955: if (ResultPathName)
413 955: *ResultPathName = OutFile;
414 :
415 955: return OS.take();
416 : }
417 :
418 : // Initialization Utilities
419 :
420 2517: bool CompilerInstance::InitializeSourceManager(llvm::StringRef InputFile) {
421 : return InitializeSourceManager(InputFile, getDiagnostics(), getFileManager(),
422 2517: getSourceManager(), getFrontendOpts());
423 : }
424 :
425 : bool CompilerInstance::InitializeSourceManager(llvm::StringRef InputFile,
426 : Diagnostic &Diags,
427 : FileManager &FileMgr,
428 : SourceManager &SourceMgr,
429 2517: const FrontendOptions &Opts) {
430 : // Figure out where to get and map in the main file.
0: branch 0 not taken
2517: branch 1 taken
431 2517: if (Opts.EmptyInputOnly) {
432 0: const char *EmptyStr = "";
433 : llvm::MemoryBuffer *SB =
434 0: llvm::MemoryBuffer::getMemBuffer(EmptyStr, EmptyStr, "<empty input>");
435 0: SourceMgr.createMainFileIDForMemBuffer(SB);
2422: branch 2 taken
95: branch 3 taken
436 2517: } else if (InputFile != "-") {
437 2422: const FileEntry *File = FileMgr.getFile(InputFile);
2422: branch 0 taken
0: branch 1 not taken
438 2422: if (File) SourceMgr.createMainFileID(File, SourceLocation());
0: branch 2 not taken
2422: branch 3 taken
439 2422: if (SourceMgr.getMainFileID().isInvalid()) {
440 0: Diags.Report(diag::err_fe_error_reading) << InputFile;
441 0: return false;
442 : }
443 : } else {
444 95: llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getSTDIN();
445 95: SourceMgr.createMainFileIDForMemBuffer(SB);
0: branch 2 not taken
95: branch 3 taken
446 95: if (SourceMgr.getMainFileID().isInvalid()) {
447 0: Diags.Report(diag::err_fe_error_reading_stdin);
448 0: return false;
449 : }
450 : }
451 :
452 2517: return true;
453 : }
454 :
455 : // High-Level Operations
456 :
457 2513: bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
2513: branch 1 taken
0: branch 2 not taken
458 2513: assert(hasDiagnostics() && "Diagnostics engine is not initialized!");
2513: branch 1 taken
0: branch 2 not taken
459 2513: assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!");
2513: branch 1 taken
0: branch 2 not taken
460 2513: assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!");
461 :
462 : // FIXME: Take this as an argument, once all the APIs we used have moved to
463 : // taking it as an input instead of hard-coding llvm::errs.
464 2513: llvm::raw_ostream &OS = llvm::errs();
465 :
466 : // Create the target instance.
467 2513: setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), getTargetOpts()));
0: branch 1 not taken
2513: branch 2 taken
468 2513: if (!hasTarget())
469 0: return false;
470 :
471 : // Inform the target of the language options.
472 : //
473 : // FIXME: We shouldn't need to do this, the target should be immutable once
474 : // created. This complexity should be lifted elsewhere.
475 2513: getTarget().setForcedLangOptions(getLangOpts());
476 :
477 : // Validate/process some options.
1: branch 1 taken
2512: branch 2 taken
478 2513: if (getHeaderSearchOpts().Verbose)
479 : OS << "clang -cc1 version " CLANG_VERSION_STRING
480 : << " based upon " << PACKAGE_STRING
481 1: << " hosted on " << llvm::sys::getHostTriple() << "\n";
482 :
0: branch 1 not taken
2513: branch 2 taken
483 2513: if (getFrontendOpts().ShowTimers)
484 0: createFrontendTimer();
485 :
2513: branch 2 taken
2513: branch 3 taken
486 5026: for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) {
487 2513: const std::string &InFile = getFrontendOpts().Inputs[i].second;
488 :
489 : // If we aren't using an AST file, setup the file and source managers and
490 : // the preprocessor.
491 2513: bool IsAST = getFrontendOpts().Inputs[i].first == FrontendOptions::IK_AST;
2511: branch 0 taken
2: branch 1 taken
492 2513: if (!IsAST) {
2511: branch 0 taken
0: branch 1 not taken
493 2511: if (!i) {
494 : // Create a file manager object to provide access to and cache the
495 : // filesystem.
496 2511: createFileManager();
497 :
498 : // Create the source manager.
499 2511: createSourceManager();
500 : } else {
501 : // Reset the ID tables if we are reusing the SourceManager.
502 0: getSourceManager().clearIDTables();
503 : }
504 :
505 : // Create the preprocessor.
506 2511: createPreprocessor();
507 : }
508 :
2510: branch 2 taken
3: branch 3 taken
509 2513: if (Act.BeginSourceFile(*this, InFile, IsAST)) {
510 2510: Act.Execute();
511 2510: Act.EndSourceFile();
512 : }
513 : }
514 :
2511: branch 1 taken
2: branch 2 taken
515 2513: if (getDiagnosticOpts().ShowCarets)
1142: branch 2 taken
1369: branch 3 taken
516 2511: if (unsigned NumDiagnostics = getDiagnostics().getNumDiagnostics())
517 : OS << NumDiagnostics << " diagnostic"
518 : << (NumDiagnostics == 1 ? "" : "s")
248: branch 0 taken
894: branch 1 taken
519 1142: << " generated.\n";
520 :
2: branch 1 taken
2511: branch 2 taken
521 2513: if (getFrontendOpts().ShowStats) {
522 2: getFileManager().PrintStats();
523 2: OS << "\n";
524 : }
525 :
526 : // Return the appropriate status when verifying diagnostics.
527 : //
528 : // FIXME: If we could make getNumErrors() do the right thing, we wouldn't need
529 : // this.
1312: branch 1 taken
1201: branch 2 taken
530 2513: if (getDiagnosticOpts().VerifyDiagnostics)
531 : return !static_cast<VerifyDiagnosticsClient&>(
532 1312: getDiagnosticClient()).HadErrors();
533 :
534 1201: return !getDiagnostics().getNumErrors();
535 : }
536 :
537 :
Generated: 2010-02-10 01:31 by zcov