Deleted Added
full compact
ASTUnit.cpp (206084) ASTUnit.cpp (206275)
1//===--- ASTUnit.cpp - ASTUnit utility ------------------------------------===//
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//===----------------------------------------------------------------------===//

--- 21 unchanged lines hidden (view full) ---

30#include "clang/Basic/TargetOptions.h"
31#include "clang/Basic/TargetInfo.h"
32#include "clang/Basic/Diagnostic.h"
33#include "llvm/Support/MemoryBuffer.h"
34#include "llvm/System/Host.h"
35#include "llvm/System/Path.h"
36using namespace clang;
37
1//===--- ASTUnit.cpp - ASTUnit utility ------------------------------------===//
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//===----------------------------------------------------------------------===//

--- 21 unchanged lines hidden (view full) ---

30#include "clang/Basic/TargetOptions.h"
31#include "clang/Basic/TargetInfo.h"
32#include "clang/Basic/Diagnostic.h"
33#include "llvm/Support/MemoryBuffer.h"
34#include "llvm/System/Host.h"
35#include "llvm/System/Path.h"
36using namespace clang;
37
38ASTUnit::ASTUnit(Diagnostic &Diag, bool _MainFileIsAST)
39 : SourceMgr(Diag), MainFileIsAST(_MainFileIsAST),
40 ConcurrencyCheckValue(CheckUnlocked) {
41}
38ASTUnit::ASTUnit(bool _MainFileIsAST)
39 : MainFileIsAST(_MainFileIsAST), ConcurrencyCheckValue(CheckUnlocked) { }
40
42ASTUnit::~ASTUnit() {
43 ConcurrencyCheckValue = CheckLocked;
44 for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
45 TemporaryFiles[I].eraseFromDisk();
46}
47
48namespace {
49

--- 87 unchanged lines hidden (view full) ---

137}
138
139const std::string &ASTUnit::getPCHFileName() {
140 assert(isMainFileAST() && "Not an ASTUnit from a PCH file!");
141 return static_cast<PCHReader *>(Ctx->getExternalSource())->getFileName();
142}
143
144ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
41ASTUnit::~ASTUnit() {
42 ConcurrencyCheckValue = CheckLocked;
43 for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
44 TemporaryFiles[I].eraseFromDisk();
45}
46
47namespace {
48

--- 87 unchanged lines hidden (view full) ---

136}
137
138const std::string &ASTUnit::getPCHFileName() {
139 assert(isMainFileAST() && "Not an ASTUnit from a PCH file!");
140 return static_cast<PCHReader *>(Ctx->getExternalSource())->getFileName();
141}
142
143ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
145 Diagnostic &Diags,
144 llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
146 bool OnlyLocalDecls,
147 RemappedFile *RemappedFiles,
148 unsigned NumRemappedFiles,
149 bool CaptureDiagnostics) {
145 bool OnlyLocalDecls,
146 RemappedFile *RemappedFiles,
147 unsigned NumRemappedFiles,
148 bool CaptureDiagnostics) {
150 llvm::OwningPtr<ASTUnit> AST(new ASTUnit(Diags, true));
149 llvm::OwningPtr AST(new ASTUnit(true));
150
151 if (!Diags.getPtr()) {
152 // No diagnostics engine was provided, so create our own diagnostics object
153 // with the default options.
154 DiagnosticOptions DiagOpts;
155 Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
156 }
157
151 AST->OnlyLocalDecls = OnlyLocalDecls;
158 AST->OnlyLocalDecls = OnlyLocalDecls;
159 AST->Diagnostics = Diags;
160 AST->FileMgr.reset(new FileManager);
161 AST->SourceMgr.reset(new SourceManager(AST->getDiagnostics()));
152 AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager()));
153
154 // If requested, capture diagnostics in the ASTUnit.
162 AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager()));
163
164 // If requested, capture diagnostics in the ASTUnit.
155 CaptureDroppedDiagnostics Capture(CaptureDiagnostics, Diags,
156 AST->Diagnostics);
165 CaptureDroppedDiagnostics Capture(CaptureDiagnostics, AST->getDiagnostics(),
166 AST->StoredDiagnostics);
157
158 for (unsigned I = 0; I != NumRemappedFiles; ++I) {
159 // Create the file entry for the file that we're mapping from.
160 const FileEntry *FromFile
161 = AST->getFileManager().getVirtualFile(RemappedFiles[I].first,
162 RemappedFiles[I].second->getBufferSize(),
163 0);
164 if (!FromFile) {
167
168 for (unsigned I = 0; I != NumRemappedFiles; ++I) {
169 // Create the file entry for the file that we're mapping from.
170 const FileEntry *FromFile
171 = AST->getFileManager().getVirtualFile(RemappedFiles[I].first,
172 RemappedFiles[I].second->getBufferSize(),
173 0);
174 if (!FromFile) {
165 Diags.Report(diag::err_fe_remap_missing_from_file)
175 AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file)
166 << RemappedFiles[I].first;
167 delete RemappedFiles[I].second;
168 continue;
169 }
170
171 // Override the contents of the "from" file with the contents of
172 // the "to" file.
173 AST->getSourceManager().overrideFileContents(FromFile,

--- 7 unchanged lines hidden (view full) ---

181 std::string TargetTriple;
182 std::string Predefines;
183 unsigned Counter;
184
185 llvm::OwningPtr<PCHReader> Reader;
186 llvm::OwningPtr<ExternalASTSource> Source;
187
188 Reader.reset(new PCHReader(AST->getSourceManager(), AST->getFileManager(),
176 << RemappedFiles[I].first;
177 delete RemappedFiles[I].second;
178 continue;
179 }
180
181 // Override the contents of the "from" file with the contents of
182 // the "to" file.
183 AST->getSourceManager().overrideFileContents(FromFile,

--- 7 unchanged lines hidden (view full) ---

191 std::string TargetTriple;
192 std::string Predefines;
193 unsigned Counter;
194
195 llvm::OwningPtr<PCHReader> Reader;
196 llvm::OwningPtr<ExternalASTSource> Source;
197
198 Reader.reset(new PCHReader(AST->getSourceManager(), AST->getFileManager(),
189 Diags));
199 AST->getDiagnostics()));
190 Reader->setListener(new PCHInfoCollector(LangInfo, HeaderInfo, TargetTriple,
191 Predefines, Counter));
192
193 switch (Reader->ReadPCH(Filename)) {
194 case PCHReader::Success:
195 break;
196
197 case PCHReader::Failure:
198 case PCHReader::IgnorePCH:
200 Reader->setListener(new PCHInfoCollector(LangInfo, HeaderInfo, TargetTriple,
201 Predefines, Counter));
202
203 switch (Reader->ReadPCH(Filename)) {
204 case PCHReader::Success:
205 break;
206
207 case PCHReader::Failure:
208 case PCHReader::IgnorePCH:
199 Diags.Report(diag::err_fe_unable_to_load_pch);
209 AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);
200 return NULL;
201 }
202
203 AST->OriginalSourceFile = Reader->getOriginalSourceFile();
204
205 // PCH loaded successfully. Now create the preprocessor.
206
207 // Get information about the target being compiled for.
208 //
209 // FIXME: This is broken, we should store the TargetOptions in the PCH.
210 TargetOptions TargetOpts;
211 TargetOpts.ABI = "";
212 TargetOpts.CPU = "";
213 TargetOpts.Features.clear();
214 TargetOpts.Triple = TargetTriple;
210 return NULL;
211 }
212
213 AST->OriginalSourceFile = Reader->getOriginalSourceFile();
214
215 // PCH loaded successfully. Now create the preprocessor.
216
217 // Get information about the target being compiled for.
218 //
219 // FIXME: This is broken, we should store the TargetOptions in the PCH.
220 TargetOptions TargetOpts;
221 TargetOpts.ABI = "";
222 TargetOpts.CPU = "";
223 TargetOpts.Features.clear();
224 TargetOpts.Triple = TargetTriple;
215 AST->Target.reset(TargetInfo::CreateTargetInfo(Diags, TargetOpts));
216 AST->PP.reset(new Preprocessor(Diags, LangInfo, *AST->Target.get(),
225 AST->Target.reset(TargetInfo::CreateTargetInfo(AST->getDiagnostics(),
226 TargetOpts));
227 AST->PP.reset(new Preprocessor(AST->getDiagnostics(), LangInfo,
228 *AST->Target.get(),
217 AST->getSourceManager(), HeaderInfo));
218 Preprocessor &PP = *AST->PP.get();
219
220 PP.setPredefines(Reader->getSuggestedPredefines());
221 PP.setCounterValue(Counter);
222 Reader->setPreprocessor(PP);
223
224 // Create and initialize the ASTContext.

--- 46 unchanged lines hidden (view full) ---

271 TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}
272
273 virtual bool hasCodeCompletionSupport() const { return false; }
274};
275
276}
277
278ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
229 AST->getSourceManager(), HeaderInfo));
230 Preprocessor &PP = *AST->PP.get();
231
232 PP.setPredefines(Reader->getSuggestedPredefines());
233 PP.setCounterValue(Counter);
234 Reader->setPreprocessor(PP);
235
236 // Create and initialize the ASTContext.

--- 46 unchanged lines hidden (view full) ---

283 TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}
284
285 virtual bool hasCodeCompletionSupport() const { return false; }
286};
287
288}
289
290ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
279 Diagnostic &Diags,
291 llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
280 bool OnlyLocalDecls,
281 bool CaptureDiagnostics) {
282 // Create the compiler instance to use for building the AST.
283 CompilerInstance Clang;
284 llvm::OwningPtr<ASTUnit> AST;
285 llvm::OwningPtr<TopLevelDeclTrackerAction> Act;
286
292 bool OnlyLocalDecls,
293 bool CaptureDiagnostics) {
294 // Create the compiler instance to use for building the AST.
295 CompilerInstance Clang;
296 llvm::OwningPtr<ASTUnit> AST;
297 llvm::OwningPtr<TopLevelDeclTrackerAction> Act;
298
299 if (!Diags.getPtr()) {
300 // No diagnostics engine was provided, so create our own diagnostics object
301 // with the default options.
302 DiagnosticOptions DiagOpts;
303 Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
304 }
305
287 Clang.setInvocation(CI);
288
306 Clang.setInvocation(CI);
307
289 Clang.setDiagnostics(&Diags);
290 Clang.setDiagnosticClient(Diags.getClient());
308 Clang.setDiagnostics(Diags.getPtr());
309 Clang.setDiagnosticClient(Diags->getClient());
291
292 // Create the target instance.
293 Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(),
294 Clang.getTargetOpts()));
295 if (!Clang.hasTarget()) {
296 Clang.takeDiagnosticClient();
310
311 // Create the target instance.
312 Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(),
313 Clang.getTargetOpts()));
314 if (!Clang.hasTarget()) {
315 Clang.takeDiagnosticClient();
297 Clang.takeDiagnostics();
298 return 0;
299 }
300
301 // Inform the target of the language options.
302 //
303 // FIXME: We shouldn't need to do this, the target should be immutable once
304 // created. This complexity should be lifted elsewhere.
305 Clang.getTarget().setForcedLangOptions(Clang.getLangOpts());
306
307 assert(Clang.getFrontendOpts().Inputs.size() == 1 &&
308 "Invocation must have exactly one source file!");
309 assert(Clang.getFrontendOpts().Inputs[0].first != FrontendOptions::IK_AST &&
310 "FIXME: AST inputs not yet supported here!");
311
312 // Create the AST unit.
316 return 0;
317 }
318
319 // Inform the target of the language options.
320 //
321 // FIXME: We shouldn't need to do this, the target should be immutable once
322 // created. This complexity should be lifted elsewhere.
323 Clang.getTarget().setForcedLangOptions(Clang.getLangOpts());
324
325 assert(Clang.getFrontendOpts().Inputs.size() == 1 &&
326 "Invocation must have exactly one source file!");
327 assert(Clang.getFrontendOpts().Inputs[0].first != FrontendOptions::IK_AST &&
328 "FIXME: AST inputs not yet supported here!");
329
330 // Create the AST unit.
313 AST.reset(new ASTUnit(Diags, false));
331 AST.reset(new ASTUnit(false));
332 AST->Diagnostics = Diags;
333 AST->FileMgr.reset(new FileManager);
334 AST->SourceMgr.reset(new SourceManager(AST->getDiagnostics()));
314 AST->OnlyLocalDecls = OnlyLocalDecls;
315 AST->OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second;
316
317 // Capture any diagnostics that would otherwise be dropped.
318 CaptureDroppedDiagnostics Capture(CaptureDiagnostics,
319 Clang.getDiagnostics(),
335 AST->OnlyLocalDecls = OnlyLocalDecls;
336 AST->OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second;
337
338 // Capture any diagnostics that would otherwise be dropped.
339 CaptureDroppedDiagnostics Capture(CaptureDiagnostics,
340 Clang.getDiagnostics(),
320 AST->Diagnostics);
341 AST->StoredDiagnostics);
321
322 // Create a file manager object to provide access to and cache the filesystem.
323 Clang.setFileManager(&AST->getFileManager());
324
325 // Create the source manager.
326 Clang.setSourceManager(&AST->getSourceManager());
327
328 // Create the preprocessor.

--- 12 unchanged lines hidden (view full) ---

341 AST->PP.reset(Clang.takePreprocessor());
342 Clang.takeSourceManager();
343 Clang.takeFileManager();
344 AST->Target.reset(Clang.takeTarget());
345
346 Act->EndSourceFile();
347
348 Clang.takeDiagnosticClient();
342
343 // Create a file manager object to provide access to and cache the filesystem.
344 Clang.setFileManager(&AST->getFileManager());
345
346 // Create the source manager.
347 Clang.setSourceManager(&AST->getSourceManager());
348
349 // Create the preprocessor.

--- 12 unchanged lines hidden (view full) ---

362 AST->PP.reset(Clang.takePreprocessor());
363 Clang.takeSourceManager();
364 Clang.takeFileManager();
365 AST->Target.reset(Clang.takeTarget());
366
367 Act->EndSourceFile();
368
369 Clang.takeDiagnosticClient();
349 Clang.takeDiagnostics();
350 Clang.takeInvocation();
351
352 AST->Invocation.reset(Clang.takeInvocation());
353 return AST.take();
354
355error:
356 Clang.takeSourceManager();
357 Clang.takeFileManager();
358 Clang.takeDiagnosticClient();
370 Clang.takeInvocation();
371
372 AST->Invocation.reset(Clang.takeInvocation());
373 return AST.take();
374
375error:
376 Clang.takeSourceManager();
377 Clang.takeFileManager();
378 Clang.takeDiagnosticClient();
359 Clang.takeDiagnostics();
360 return 0;
361}
362
363ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
364 const char **ArgEnd,
379 return 0;
380}
381
382ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
383 const char **ArgEnd,
365 Diagnostic &Diags,
384 llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
366 llvm::StringRef ResourceFilesPath,
367 bool OnlyLocalDecls,
368 RemappedFile *RemappedFiles,
369 unsigned NumRemappedFiles,
370 bool CaptureDiagnostics) {
385 llvm::StringRef ResourceFilesPath,
386 bool OnlyLocalDecls,
387 RemappedFile *RemappedFiles,
388 unsigned NumRemappedFiles,
389 bool CaptureDiagnostics) {
390 if (!Diags.getPtr()) {
391 // No diagnostics engine was provided, so create our own diagnostics object
392 // with the default options.
393 DiagnosticOptions DiagOpts;
394 Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
395 }
396
371 llvm::SmallVector<const char *, 16> Args;
372 Args.push_back("<clang>"); // FIXME: Remove dummy argument.
373 Args.insert(Args.end(), ArgBegin, ArgEnd);
374
375 // FIXME: Find a cleaner way to force the driver into restricted modes. We
376 // also want to force it to use clang.
377 Args.push_back("-fsyntax-only");
378
379 // FIXME: We shouldn't have to pass in the path info.
380 driver::Driver TheDriver("clang", "/", llvm::sys::getHostTriple(),
397 llvm::SmallVector<const char *, 16> Args;
398 Args.push_back("<clang>"); // FIXME: Remove dummy argument.
399 Args.insert(Args.end(), ArgBegin, ArgEnd);
400
401 // FIXME: Find a cleaner way to force the driver into restricted modes. We
402 // also want to force it to use clang.
403 Args.push_back("-fsyntax-only");
404
405 // FIXME: We shouldn't have to pass in the path info.
406 driver::Driver TheDriver("clang", "/", llvm::sys::getHostTriple(),
381 "a.out", false, false, Diags);
407 "a.out", false, false, *Diags);
382
383 // Don't check that inputs exist, they have been remapped.
384 TheDriver.setCheckInputsExist(false);
385
386 llvm::OwningPtr<driver::Compilation> C(
387 TheDriver.BuildCompilation(Args.size(), Args.data()));
388
389 // We expect to get back exactly one command job, if we didn't something
390 // failed.
391 const driver::JobList &Jobs = C->getJobs();
392 if (Jobs.size() != 1 || !isa<driver::Command>(Jobs.begin())) {
393 llvm::SmallString<256> Msg;
394 llvm::raw_svector_ostream OS(Msg);
395 C->PrintJob(OS, C->getJobs(), "; ", true);
408
409 // Don't check that inputs exist, they have been remapped.
410 TheDriver.setCheckInputsExist(false);
411
412 llvm::OwningPtr<driver::Compilation> C(
413 TheDriver.BuildCompilation(Args.size(), Args.data()));
414
415 // We expect to get back exactly one command job, if we didn't something
416 // failed.
417 const driver::JobList &Jobs = C->getJobs();
418 if (Jobs.size() != 1 || !isa<driver::Command>(Jobs.begin())) {
419 llvm::SmallString<256> Msg;
420 llvm::raw_svector_ostream OS(Msg);
421 C->PrintJob(OS, C->getJobs(), "; ", true);
396 Diags.Report(diag::err_fe_expected_compiler_job) << OS.str();
422 Diags->Report(diag::err_fe_expected_compiler_job) << OS.str();
397 return 0;
398 }
399
400 const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin());
401 if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") {
423 return 0;
424 }
425
426 const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin());
427 if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") {
402 Diags.Report(diag::err_fe_expected_clang_command);
428 Diags->Report(diag::err_fe_expected_clang_command);
403 return 0;
404 }
405
406 const driver::ArgStringList &CCArgs = Cmd->getArguments();
407 llvm::OwningPtr<CompilerInvocation> CI(new CompilerInvocation);
408 CompilerInvocation::CreateFromArgs(*CI, (const char**) CCArgs.data(),
409 (const char**) CCArgs.data()+CCArgs.size(),
429 return 0;
430 }
431
432 const driver::ArgStringList &CCArgs = Cmd->getArguments();
433 llvm::OwningPtr<CompilerInvocation> CI(new CompilerInvocation);
434 CompilerInvocation::CreateFromArgs(*CI, (const char**) CCArgs.data(),
435 (const char**) CCArgs.data()+CCArgs.size(),
410 Diags);
436 *Diags);
411
412 // Override any files that need remapping
413 for (unsigned I = 0; I != NumRemappedFiles; ++I)
414 CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
415 RemappedFiles[I].second);
416
417 // Override the resources path.
418 CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
419
420 CI->getFrontendOpts().DisableFree = true;
421 return LoadFromCompilerInvocation(CI.take(), Diags, OnlyLocalDecls,
422 CaptureDiagnostics);
423}
437
438 // Override any files that need remapping
439 for (unsigned I = 0; I != NumRemappedFiles; ++I)
440 CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
441 RemappedFiles[I].second);
442
443 // Override the resources path.
444 CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
445
446 CI->getFrontendOpts().DisableFree = true;
447 return LoadFromCompilerInvocation(CI.take(), Diags, OnlyLocalDecls,
448 CaptureDiagnostics);
449}