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 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} |