static CompilerInvocation * createInvocationForMigration(CompilerInvocation &origCI) { OwningPtr<CompilerInvocation> CInvok; CInvok.reset(new CompilerInvocation(origCI)); PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts(); if (!PPOpts.ImplicitPCHInclude.empty()) { // We can't use a PCH because it was likely built in non-ARC mode and we // want to parse in ARC. Include the original header. FileManager FileMgr(origCI.getFileSystemOpts()); IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); IntrusiveRefCntPtr<DiagnosticsEngine> Diags( new DiagnosticsEngine(DiagID, &origCI.getDiagnosticOpts(), new IgnoringDiagConsumer())); std::string OriginalFile = ASTReader::getOriginalSourceFile(PPOpts.ImplicitPCHInclude, FileMgr, *Diags); if (!OriginalFile.empty()) PPOpts.Includes.insert(PPOpts.Includes.begin(), OriginalFile); PPOpts.ImplicitPCHInclude.clear(); } // FIXME: Get the original header of a PTH as well. CInvok->getPreprocessorOpts().ImplicitPTHInclude.clear(); std::string define = getARCMTMacroName(); define += '='; CInvok->getPreprocessorOpts().addMacroDef(define); CInvok->getLangOpts()->ObjCAutoRefCount = true; CInvok->getLangOpts()->setGC(LangOptions::NonGC); CInvok->getDiagnosticOpts().ErrorLimit = 0; CInvok->getDiagnosticOpts().PedanticErrors = 0; // Ignore -Werror flags when migrating. std::vector<std::string> WarnOpts; for (std::vector<std::string>::iterator I = CInvok->getDiagnosticOpts().Warnings.begin(), E = CInvok->getDiagnosticOpts().Warnings.end(); I != E; ++I) { if (!StringRef(*I).startswith("error")) WarnOpts.push_back(*I); } WarnOpts.push_back("error=arc-unsafe-retained-assign"); CInvok->getDiagnosticOpts().Warnings = llvm_move(WarnOpts); CInvok->getLangOpts()->ObjCARCWeak = HasARCRuntime(origCI); return CInvok.take(); }
error_code MachOUniversalBinary::ObjectForArch::getAsObjectFile( OwningPtr<ObjectFile> &Result) const { if (Parent) { StringRef ParentData = Parent->getData(); StringRef ObjectData = ParentData.substr(Header.offset, Header.size); std::string ObjectName = Parent->getFileName().str() + ":" + Triple::getArchTypeName(MachOObjectFile::getArch(Header.cputype)); MemoryBuffer *ObjBuffer = MemoryBuffer::getMemBuffer( ObjectData, ObjectName, false); ErrorOr<ObjectFile *> Obj = ObjectFile::createMachOObjectFile(ObjBuffer); if (error_code EC = Obj.getError()) return EC; Result.reset(Obj.get()); return object_error::success; } return object_error::parse_failed; }
/// addPassesToEmitMC - Add passes to the specified pass manager to get /// machine code emitted with the MCJIT. This method returns true if machine /// code is not supported. It fills the MCContext Ctx pointer which can be /// used to build custom MCStreamer. /// bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx, raw_ostream &Out, bool DisableVerify) { // Add common CodeGen passes. Ctx = addPassesToGenerateCode(this, PM, DisableVerify, 0, 0); if (!Ctx) return true; if (hasMCSaveTempLabels()) Ctx->setAllowTemporaryLabels(false); // Create the code emitter for the target if it exists. If not, .o file // emission fails. const MCRegisterInfo &MRI = *getRegisterInfo(); const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>(); MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), MRI, STI, *Ctx); MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(), TargetCPU); if (MCE == 0 || MAB == 0) return true; OwningPtr<MCStreamer> AsmStreamer; AsmStreamer.reset(getTarget().createMCObjectStreamer(getTargetTriple(), *Ctx, *MAB, Out, MCE, hasMCRelaxAll(), hasMCNoExecStack())); AsmStreamer.get()->InitSections(); // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer); if (Printer == 0) return true; // If successful, createAsmPrinter took ownership of AsmStreamer. AsmStreamer.take(); PM.add(Printer); return false; // success! }
ExternalASTSource * CompilerInstance::createPCHExternalASTSource(StringRef Path, const std::string &Sysroot, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, void *DeserializationListener, bool Preamble) { OwningPtr<ASTReader> Reader; Reader.reset(new ASTReader(PP, Context, Sysroot.empty() ? "" : Sysroot.c_str(), DisablePCHValidation, AllowPCHWithCompilerErrors)); Reader->setDeserializationListener( static_cast<ASTDeserializationListener *>(DeserializationListener)); switch (Reader->ReadAST(Path, Preamble ? serialization::MK_Preamble : serialization::MK_PCH, SourceLocation(), ASTReader::ARR_None)) { case ASTReader::Success: // Set the predefines buffer as suggested by the PCH reader. Typically, the // predefines buffer will be empty. PP.setPredefines(Reader->getSuggestedPredefines()); return Reader.take(); case ASTReader::Failure: // Unrecoverable failure: don't even try to process the input file. break; case ASTReader::OutOfDate: case ASTReader::VersionMismatch: case ASTReader::ConfigurationMismatch: case ASTReader::HadErrors: // No suitable PCH file could be found. Return an error. break; } return 0; }
static error_code getMemoryBufferForStream(int FD, StringRef BufferName, OwningPtr<MemoryBuffer> &result) { const ssize_t ChunkSize = 4096*4; SmallString<ChunkSize> Buffer; ssize_t ReadBytes; // Read into Buffer until we hit EOF. do { Buffer.reserve(Buffer.size() + ChunkSize); ReadBytes = read(FD, Buffer.end(), ChunkSize); if (ReadBytes == -1) { if (errno == EINTR) continue; return error_code(errno, posix_category()); } Buffer.set_size(Buffer.size() + ReadBytes); } while (ReadBytes != 0); result.reset(MemoryBuffer::getMemBufferCopy(Buffer, BufferName)); return error_code::success(); }
static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts, DiagnosticsEngine &Diags, StringRef OutputFile) { std::string ErrorInfo; OwningPtr<llvm::raw_fd_ostream> OS; OS.reset(new llvm::raw_fd_ostream(OutputFile.str().c_str(), ErrorInfo, llvm::raw_fd_ostream::F_Binary)); if (!ErrorInfo.empty()) { Diags.Report(diag::warn_fe_serialized_diag_failure) << OutputFile << ErrorInfo; return; } DiagnosticConsumer *SerializedConsumer = clang::serialized_diags::create(OS.take(), DiagOpts); Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), SerializedConsumer)); }
int main (int argc, char ** argv) { if (argc < 3) { fprintf(stderr,"Not enough positional arguments to %s.\n",argv[0]); return 1; } llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. LLVMContext &Context = getGlobalContext(); std::string InputFilename(argv[1]); std::string OutputFilename(argv[2]); OwningPtr<tool_output_file> Out; std::string ErrorInfo; Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, sys::fs::F_Binary)); SMDiagnostic Err; std::auto_ptr<Module> M; M.reset(ParseIRFile(InputFilename, Err, Context)); if (M.get() == 0) { Err.print(argv[0], errs()); return 1; } Summarize(M.get()); WriteBitcodeToFile(M.get(),Out->os()); Out->keep(); return 0; }
bool SimplePrinterConsumer::HandleTopLevelDecl(DeclGroupRef D) { if(D.begin() == D.end()) { return true; } Decl *firstD = *(D.begin()); if(compInst->getSourceManager().isInSystemHeader(firstD->getLocation())) { return true; } PrintingPolicy policy = compInst->getASTContext().getPrintingPolicy(); NullStmt *nullSt = new (compInst->getASTContext()) NullStmt(SourceLocation()); for(DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { Decl *dd = *I; DPRINT("PrintingPolicy: %d %d %d %d %d", policy.SuppressSpecifiers, policy.SuppressScope, policy.SuppressTag, policy.SuppressUnwrittenScope, policy.SuppressSpecifiers); dd->print(out, policy); nullSt->printPretty(out, NULL, policy); if(dd->hasBody()) { Stmt *ss = dd->getBody(); // Print Stmts //dd->dump(); //StmtPrinter(compInst, dd->getBody()).TraverseDecl(dd); // CFG OwningPtr<CFG> cfg; cfg.reset(CFG::buildCFG((const Decl*)dd, (Stmt*)(dd->getBody()), &compInst->getASTContext(), CFG::BuildOptions())); assert(cfg.get() != NULL && "build CFG failed."); cfg->dump(compInst->getLangOpts(), true); cfg->viewCFG(compInst->getLangOpts()); } } return true; };
/// addPassesToEmitMC - Add passes to the specified pass manager to get /// machine code emitted with the MCJIT. This method returns true if machine /// code is not supported. It fills the MCContext Ctx pointer which can be /// used to build custom MCStreamer. /// bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx, raw_ostream &Out, CodeGenOpt::Level OptLevel, bool DisableVerify) { // Add common CodeGen passes. if (addCommonCodeGenPasses(PM, OptLevel, DisableVerify, Ctx)) return true; // Create the code emitter for the target if it exists. If not, .o file // emission fails. MCCodeEmitter *MCE = getTarget().createCodeEmitter(*this, *Ctx); TargetAsmBackend *TAB = getTarget().createAsmBackend(TargetTriple); if (MCE == 0 || TAB == 0) return true; OwningPtr<MCStreamer> AsmStreamer; AsmStreamer.reset(getTarget().createObjectStreamer(TargetTriple, *Ctx, *TAB, Out, MCE, hasMCRelaxAll(), hasMCNoExecStack())); AsmStreamer.get()->InitSections(); // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer); if (Printer == 0) return true; // If successful, createAsmPrinter took ownership of AsmStreamer. AsmStreamer.take(); PM.add(Printer); // Make sure the code model is set. setCodeModelForJIT(); return false; // success! }
int main(int argc, char **argv) { // Init LLVM, call llvm_shutdown() on exit, parse args, etc. llvm::PrettyStackTraceProgram X(argc, argv); cl::ParseCommandLineOptions(argc, argv, "llvm codegen stress-tester\n"); llvm_shutdown_obj Y; OwningPtr<Module> M(new Module("/tmp/autogen.bc", getGlobalContext())); Function *F = GenEmptyFunction(M.get()); // Pick an initial seed value Random R(SeedCL); // Generate lots of random instructions inside a single basic block. FillFunction(F, R); // Break the basic block into many loops. IntroduceControlFlow(F, R); // Figure out what stream we are supposed to write to... OwningPtr<tool_output_file> Out; // Default to standard output. if (OutputFilename.empty()) OutputFilename = "-"; std::string ErrorInfo; Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, sys::fs::F_Binary)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; } PassManager Passes; Passes.add(createVerifierPass()); Passes.add(createPrintModulePass(Out->os())); Passes.run(*M.get()); Out->keep(); return 0; }
error_code MemoryBuffer::getSTDIN(OwningPtr<MemoryBuffer> &result) { // Read in all of the data from stdin, we cannot mmap stdin. // // FIXME: That isn't necessarily true, we should try to mmap stdin and // fallback if it fails. sys::Program::ChangeStdinToBinary(); const ssize_t ChunkSize = 4096*4; SmallString<ChunkSize> Buffer; ssize_t ReadBytes; // Read into Buffer until we hit EOF. do { Buffer.reserve(Buffer.size() + ChunkSize); ReadBytes = read(0, Buffer.end(), ChunkSize); if (ReadBytes == -1) { if (errno == EINTR) continue; return error_code(errno, posix_category()); } Buffer.set_size(Buffer.size() + ReadBytes); } while (ReadBytes != 0); result.reset(getMemBufferCopy(Buffer, "<stdin>")); return error_code::success(); }
bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { // Open the module file. OwningPtr<llvm::MemoryBuffer> Buffer; Buffer.reset(FileMgr.getBufferForFile(File)); if (!Buffer) { return true; } // Initialize the input stream llvm::BitstreamReader InStreamFile; llvm::BitstreamCursor InStream; InStreamFile.init((const unsigned char *)Buffer->getBufferStart(), (const unsigned char *)Buffer->getBufferEnd()); InStream.init(InStreamFile); // Sniff for the signature. if (InStream.Read(8) != 'C' || InStream.Read(8) != 'P' || InStream.Read(8) != 'C' || InStream.Read(8) != 'H') { return true; } // Record this module file and assign it a unique ID (if it doesn't have // one already). unsigned ID = getModuleFileInfo(File).ID; // Search for the blocks and records we care about. enum { Other, ControlBlock, ASTBlock } State = Other; bool Done = false; while (!Done) { llvm::BitstreamEntry Entry = InStream.advance(); switch (Entry.Kind) { case llvm::BitstreamEntry::Error: Done = true; continue; case llvm::BitstreamEntry::Record: // In the 'other' state, just skip the record. We don't care. if (State == Other) { InStream.skipRecord(Entry.ID); continue; } // Handle potentially-interesting records below. break; case llvm::BitstreamEntry::SubBlock: if (Entry.ID == CONTROL_BLOCK_ID) { if (InStream.EnterSubBlock(CONTROL_BLOCK_ID)) return true; // Found the control block. State = ControlBlock; continue; } if (Entry.ID == AST_BLOCK_ID) { if (InStream.EnterSubBlock(AST_BLOCK_ID)) return true; // Found the AST block. State = ASTBlock; continue; } if (InStream.SkipBlock()) return true; continue; case llvm::BitstreamEntry::EndBlock: State = Other; continue; } // Read the given record. SmallVector<uint64_t, 64> Record; StringRef Blob; unsigned Code = InStream.readRecord(Entry.ID, Record, &Blob); // Handle module dependencies. if (State == ControlBlock && Code == IMPORTS) { // Load each of the imported PCH files. unsigned Idx = 0, N = Record.size(); while (Idx < N) { // Read information about the AST file. // Skip the imported kind ++Idx; // Skip the import location ++Idx; // Retrieve the imported file name. unsigned Length = Record[Idx++]; SmallString<128> ImportedFile(Record.begin() + Idx, Record.begin() + Idx + Length); Idx += Length; // Find the imported module file. const FileEntry *DependsOnFile = FileMgr.getFile(ImportedFile); if (!DependsOnFile) return true; // Record the dependency. unsigned DependsOnID = getModuleFileInfo(DependsOnFile).ID; getModuleFileInfo(File).Dependencies.push_back(DependsOnID); } continue; } // Handle the identifier table if (State == ASTBlock && Code == IDENTIFIER_TABLE && Record[0] > 0) { typedef OnDiskChainedHashTable<InterestingASTIdentifierLookupTrait> InterestingIdentifierTable; llvm::OwningPtr<InterestingIdentifierTable> Table(InterestingIdentifierTable::Create( (const unsigned char *)Blob.data() + Record[0], (const unsigned char *)Blob.data())); for (InterestingIdentifierTable::data_iterator D = Table->data_begin(), DEnd = Table->data_end(); D != DEnd; ++D) { std::pair<StringRef, bool> Ident = *D; if (Ident.second) InterestingIdentifiers[Ident.first].push_back(ID); else (void)InterestingIdentifiers[Ident.first]; } } // FIXME: Handle the selector table. // We don't care about this record. } return false; }
ModuleLoadResult CompilerInstance::loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective) { // If we've already handled this import, just return the cached result. // This one-element cache is important to eliminate redundant diagnostics // when both the preprocessor and parser see the same import declaration. if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) { // Make the named module visible. if (LastModuleImportResult) ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility); return LastModuleImportResult; } // Determine what file we're searching from. StringRef ModuleName = Path[0].first->getName(); SourceLocation ModuleNameLoc = Path[0].second; clang::Module *Module = 0; // If we don't already have information on this module, load the module now. llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known = KnownModules.find(Path[0].first); if (Known != KnownModules.end()) { // Retrieve the cached top-level module. Module = Known->second; } else if (ModuleName == getLangOpts().CurrentModule) { // This is the module we're building. Module = PP->getHeaderSearchInfo().getModuleMap().findModule(ModuleName); Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; } else { // Search for a module with the given name. Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); std::string ModuleFileName; if (Module) ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module); else ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(ModuleName); if (ModuleFileName.empty()) { getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); LastModuleImportLoc = ImportLoc; LastModuleImportResult = ModuleLoadResult(); return LastModuleImportResult; } const FileEntry *ModuleFile = getFileManager().getFile(ModuleFileName, /*OpenFile=*/false, /*CacheFailure=*/false); bool BuildingModule = false; if (!ModuleFile && Module) { // The module is not cached, but we have a module map from which we can // build the module. // Check whether there is a cycle in the module graph. ModuleBuildStack Path = getSourceManager().getModuleBuildStack(); ModuleBuildStack::iterator Pos = Path.begin(), PosEnd = Path.end(); for (; Pos != PosEnd; ++Pos) { if (Pos->first == ModuleName) break; } if (Pos != PosEnd) { SmallString<256> CyclePath; for (; Pos != PosEnd; ++Pos) { CyclePath += Pos->first; CyclePath += " -> "; } CyclePath += ModuleName; getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle) << ModuleName << CyclePath; return ModuleLoadResult(); } // Check whether we have already attempted to build this module (but // failed). if (getPreprocessorOpts().FailedModules && getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); return ModuleLoadResult(); } BuildingModule = true; compileModule(*this, ModuleNameLoc, Module, ModuleFileName); ModuleFile = FileMgr->getFile(ModuleFileName); if (!ModuleFile && getPreprocessorOpts().FailedModules) getPreprocessorOpts().FailedModules->addFailed(ModuleName); } if (!ModuleFile) { getDiagnostics().Report(ModuleNameLoc, BuildingModule? diag::err_module_not_built : diag::err_module_not_found) << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); return ModuleLoadResult(); } // If we don't already have an ASTReader, create one now. if (!ModuleManager) { if (!hasASTContext()) createASTContext(); std::string Sysroot = getHeaderSearchOpts().Sysroot; const PreprocessorOptions &PPOpts = getPreprocessorOpts(); ModuleManager = new ASTReader(getPreprocessor(), *Context, Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation); if (hasASTConsumer()) { ModuleManager->setDeserializationListener( getASTConsumer().GetASTDeserializationListener()); getASTContext().setASTMutationListener( getASTConsumer().GetASTMutationListener()); getPreprocessor().setPPMutationListener( getASTConsumer().GetPPMutationListener()); } OwningPtr<ExternalASTSource> Source; Source.reset(ModuleManager); getASTContext().setExternalSource(Source); if (hasSema()) ModuleManager->InitializeSema(getSema()); if (hasASTConsumer()) ModuleManager->StartTranslationUnit(&getASTConsumer()); } // Try to load the module we found. unsigned ARRFlags = ASTReader::ARR_None; if (Module) ARRFlags |= ASTReader::ARR_OutOfDate; switch (ModuleManager->ReadAST(ModuleFile->getName(), serialization::MK_Module, ImportLoc, ARRFlags)) { case ASTReader::Success: break; case ASTReader::OutOfDate: { // The module file is out-of-date. Rebuild it. getFileManager().invalidateCache(ModuleFile); bool Existed; llvm::sys::fs::remove(ModuleFileName, Existed); // Check whether we have already attempted to build this module (but // failed). if (getPreprocessorOpts().FailedModules && getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); return ModuleLoadResult(); } compileModule(*this, ModuleNameLoc, Module, ModuleFileName); // Try loading the module again. ModuleFile = FileMgr->getFile(ModuleFileName); if (!ModuleFile || ModuleManager->ReadAST(ModuleFileName, serialization::MK_Module, ImportLoc, ASTReader::ARR_None) != ASTReader::Success) { if (getPreprocessorOpts().FailedModules) getPreprocessorOpts().FailedModules->addFailed(ModuleName); KnownModules[Path[0].first] = 0; return ModuleLoadResult(); } // Okay, we've rebuilt and now loaded the module. break; } case ASTReader::VersionMismatch: case ASTReader::ConfigurationMismatch: case ASTReader::HadErrors: // FIXME: The ASTReader will already have complained, but can we showhorn // that diagnostic information into a more useful form? KnownModules[Path[0].first] = 0; return ModuleLoadResult(); case ASTReader::Failure: // Already complained, but note now that we failed. KnownModules[Path[0].first] = 0; return ModuleLoadResult(); } if (!Module) { // If we loaded the module directly, without finding a module map first, // we'll have loaded the module's information from the module itself. Module = PP->getHeaderSearchInfo().getModuleMap() .findModule((Path[0].first->getName())); } if (Module) Module->setASTFile(ModuleFile); // Cache the result of this top-level module lookup for later. Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; } // If we never found the module, fail. if (!Module) return ModuleLoadResult(); // Verify that the rest of the module path actually corresponds to // a submodule. if (Path.size() > 1) { for (unsigned I = 1, N = Path.size(); I != N; ++I) { StringRef Name = Path[I].first->getName(); clang::Module *Sub = Module->findSubmodule(Name); if (!Sub) { // Attempt to perform typo correction to find a module name that works. llvm::SmallVector<StringRef, 2> Best; unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)(); for (clang::Module::submodule_iterator J = Module->submodule_begin(), JEnd = Module->submodule_end(); J != JEnd; ++J) { unsigned ED = Name.edit_distance((*J)->Name, /*AllowReplacements=*/true, BestEditDistance); if (ED <= BestEditDistance) { if (ED < BestEditDistance) { Best.clear(); BestEditDistance = ED; } Best.push_back((*J)->Name); } } // If there was a clear winner, user it. if (Best.size() == 1) { getDiagnostics().Report(Path[I].second, diag::err_no_submodule_suggest) << Path[I].first << Module->getFullModuleName() << Best[0] << SourceRange(Path[0].second, Path[I-1].second) << FixItHint::CreateReplacement(SourceRange(Path[I].second), Best[0]); Sub = Module->findSubmodule(Best[0]); } } if (!Sub) { // No submodule by this name. Complain, and don't look for further // submodules. getDiagnostics().Report(Path[I].second, diag::err_no_submodule) << Path[I].first << Module->getFullModuleName() << SourceRange(Path[0].second, Path[I-1].second); break; } Module = Sub; } } // Make the named module visible, if it's not already part of the module // we are parsing. if (ModuleName != getLangOpts().CurrentModule) { if (!Module->IsFromModuleFile) { // We have an umbrella header or directory that doesn't actually include // all of the headers within the directory it covers. Complain about // this missing submodule and recover by forgetting that we ever saw // this submodule. // FIXME: Should we detect this at module load time? It seems fairly // expensive (and rare). getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule) << Module->getFullModuleName() << SourceRange(Path.front().second, Path.back().second); return ModuleLoadResult(0, true); } // Check whether this module is available. StringRef Feature; if (!Module->isAvailable(getLangOpts(), getTarget(), Feature)) { getDiagnostics().Report(ImportLoc, diag::err_module_unavailable) << Module->getFullModuleName() << Feature << SourceRange(Path.front().second, Path.back().second); LastModuleImportLoc = ImportLoc; LastModuleImportResult = ModuleLoadResult(); return ModuleLoadResult(); } ModuleManager->makeModuleVisible(Module, Visibility); } // If this module import was due to an inclusion directive, create an // implicit import declaration to capture it in the AST. if (IsInclusionDirective && hasASTContext()) { TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU, ImportLoc, Module, Path.back().second); TU->addDecl(ImportD); if (Consumer) Consumer->HandleImplicitImportDecl(ImportD); } LastModuleImportLoc = ImportLoc; LastModuleImportResult = ModuleLoadResult(Module, false); return LastModuleImportResult; }
llvm::raw_fd_ostream * CompilerInstance::createOutputFile(StringRef OutputPath, std::string &Error, bool Binary, bool RemoveFileOnSignal, StringRef InFile, StringRef Extension, bool UseTemporary, bool CreateMissingDirectories, std::string *ResultPathName, std::string *TempPathName) { assert((!CreateMissingDirectories || UseTemporary) && "CreateMissingDirectories is only allowed when using temporary files"); std::string OutFile, TempFile; if (!OutputPath.empty()) { OutFile = OutputPath; } else if (InFile == "-") { OutFile = "-"; } else if (!Extension.empty()) { llvm::sys::Path Path(InFile); Path.eraseSuffix(); Path.appendSuffix(Extension); OutFile = Path.str(); } else { OutFile = "-"; } OwningPtr<llvm::raw_fd_ostream> OS; std::string OSFile; if (UseTemporary && OutFile != "-") { // Only create the temporary if the parent directory exists (or create // missing directories is true) and we can actually write to OutPath, // otherwise we want to fail early. SmallString<256> AbsPath(OutputPath); llvm::sys::fs::make_absolute(AbsPath); llvm::sys::Path OutPath(AbsPath); bool ParentExists = false; if (llvm::sys::fs::exists(llvm::sys::path::parent_path(AbsPath.str()), ParentExists)) ParentExists = false; bool Exists; if ((CreateMissingDirectories || ParentExists) && ((llvm::sys::fs::exists(AbsPath.str(), Exists) || !Exists) || (OutPath.isRegularFile() && OutPath.canWrite()))) { // Create a temporary file. SmallString<128> TempPath; TempPath = OutFile; TempPath += "-%%%%%%%%"; int fd; if (llvm::sys::fs::unique_file(TempPath.str(), fd, TempPath, /*makeAbsolute=*/false, 0664) == llvm::errc::success) { OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true)); OSFile = TempFile = TempPath.str(); } } } if (!OS) { OSFile = OutFile; OS.reset( new llvm::raw_fd_ostream(OSFile.c_str(), Error, (Binary ? llvm::raw_fd_ostream::F_Binary : 0))); if (!Error.empty()) return 0; } // Make sure the out stream file gets removed if we crash. if (RemoveFileOnSignal) llvm::sys::RemoveFileOnSignal(llvm::sys::Path(OSFile)); if (ResultPathName) *ResultPathName = OutFile; if (TempPathName) *TempPathName = TempFile; return OS.take(); }
static int AssembleInput(const char *ProgName) { const Target *TheTarget = GetTarget(ProgName); if (!TheTarget) return 1; std::string Error; MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, &Error); if (Buffer == 0) { errs() << ProgName << ": "; if (Error.size()) errs() << Error << "\n"; else errs() << "input file didn't read correctly.\n"; return 1; } SourceMgr SrcMgr; // Tell SrcMgr about this buffer, which is what the parser will pick up. SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); // Record the location of the include directories so that the lexer can find // it later. SrcMgr.setIncludeDirs(IncludeDirs); MCContext Ctx; formatted_raw_ostream *Out = GetOutputStream(); if (!Out) return 1; // FIXME: We shouldn't need to do this (and link in codegen). OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(TripleName, "")); if (!TM) { errs() << ProgName << ": error: could not create target for triple '" << TripleName << "'.\n"; return 1; } OwningPtr<AsmPrinter> AP; OwningPtr<MCStreamer> Str; if (FileType == OFT_AssemblyFile) { const TargetAsmInfo *TAI = TheTarget->createAsmInfo(TripleName); assert(TAI && "Unable to create target asm info!"); AP.reset(TheTarget->createAsmPrinter(*Out, *TM, TAI, true)); Str.reset(createAsmStreamer(Ctx, *Out, *TAI, AP.get())); } else { assert(FileType == OFT_ObjectFile && "Invalid file type!"); Str.reset(createMachOStreamer(Ctx, *Out)); } // FIXME: Target hook & command line option for initial section. Str.get()->SwitchSection(MCSectionMachO::Create("__TEXT","__text", MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 0, SectionKind::getText(), Ctx)); AsmParser Parser(SrcMgr, Ctx, *Str.get()); OwningPtr<TargetAsmParser> TAP(TheTarget->createAsmParser(Parser)); if (!TAP) { errs() << ProgName << ": error: this target does not support assembly parsing.\n"; return 1; } Parser.setTargetParser(*TAP.get()); int Res = Parser.Run(); if (Out != &fouts()) delete Out; return Res; }
bool FrontendAction::BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input) { assert(!Instance && "Already processing a source file!"); assert(!Input.isEmpty() && "Unexpected empty filename!"); setCurrentInput(Input); setCompilerInstance(&CI); StringRef InputFile = Input.getFile(); bool HasBegunSourceFile = false; if (!BeginInvocation(CI)) goto failure; // AST files follow a very different path, since they share objects via the // AST unit. if (Input.getKind() == IK_AST) { assert(!usesPreprocessorOnly() && "Attempt to pass AST file to preprocessor only action!"); assert(hasASTFileSupport() && "This action does not have AST file support!"); IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics()); ASTUnit *AST = ASTUnit::LoadFromASTFile(InputFile, Diags, CI.getFileSystemOpts()); if (!AST) goto failure; setCurrentInput(Input, AST); // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0); HasBegunSourceFile = true; // Set the shared objects, these are reset when we finish processing the // file, otherwise the CompilerInstance will happily destroy them. CI.setFileManager(&AST->getFileManager()); CI.setSourceManager(&AST->getSourceManager()); CI.setPreprocessor(&AST->getPreprocessor()); CI.setASTContext(&AST->getASTContext()); // Initialize the action. if (!BeginSourceFileAction(CI, InputFile)) goto failure; // Create the AST consumer. CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile)); if (!CI.hasASTConsumer()) goto failure; return true; } // Set up the file and source managers, if needed. if (!CI.hasFileManager()) CI.createFileManager(); if (!CI.hasSourceManager()) CI.createSourceManager(CI.getFileManager()); // IR files bypass the rest of initialization. if (Input.getKind() == IK_LLVM_IR) { assert(hasIRSupport() && "This action does not have IR file support!"); // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0); HasBegunSourceFile = true; // Initialize the action. if (!BeginSourceFileAction(CI, InputFile)) goto failure; return true; } // If the implicit PCH include is actually a directory, rather than // a single file, search for a suitable PCH file in that directory. if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { FileManager &FileMgr = CI.getFileManager(); PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); StringRef PCHInclude = PPOpts.ImplicitPCHInclude; if (const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude)) { llvm::error_code EC; SmallString<128> DirNative; llvm::sys::path::native(PCHDir->getName(), DirNative); bool Found = false; for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) { // Check whether this is an acceptable AST file. if (ASTReader::isAcceptableASTFile(Dir->path(), FileMgr, CI.getLangOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts())) { PPOpts.ImplicitPCHInclude = Dir->path(); Found = true; break; } } if (!Found) { CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude; return true; } } } // Set up the preprocessor. CI.createPreprocessor(); // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), &CI.getPreprocessor()); HasBegunSourceFile = true; // Initialize the action. if (!BeginSourceFileAction(CI, InputFile)) goto failure; // Create the AST context and consumer unless this is a preprocessor only // action. if (!usesPreprocessorOnly()) { CI.createASTContext(); OwningPtr<ASTConsumer> Consumer( CreateWrappedASTConsumer(CI, InputFile)); if (!Consumer) goto failure; CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener()); if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) { // Convert headers to PCH and chain them. OwningPtr<ExternalASTSource> source; source.reset(ChainedIncludesSource::create(CI)); if (!source) goto failure; CI.setModuleManager(static_cast<ASTReader*>( &static_cast<ChainedIncludesSource*>(source.get())->getFinalReader())); CI.getASTContext().setExternalSource(source); } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { // Use PCH. assert(hasPCHSupport() && "This action does not have PCH support!"); ASTDeserializationListener *DeserialListener = Consumer->GetASTDeserializationListener(); if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) DeserialListener = new DeserializedDeclsDumper(DeserialListener); if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) DeserialListener = new DeserializedDeclsChecker(CI.getASTContext(), CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn, DeserialListener); CI.createPCHExternalASTSource( CI.getPreprocessorOpts().ImplicitPCHInclude, CI.getPreprocessorOpts().DisablePCHValidation, CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, DeserialListener); if (!CI.getASTContext().getExternalSource()) goto failure; } CI.setASTConsumer(Consumer.take()); if (!CI.hasASTConsumer()) goto failure; } // Initialize built-in info as long as we aren't using an external AST // source. if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) { Preprocessor &PP = CI.getPreprocessor(); PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), PP.getLangOpts()); } // If there is a layout overrides file, attach an external AST source that // provides the layouts from that file. if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && CI.hasASTContext() && !CI.getASTContext().getExternalSource()) { OwningPtr<ExternalASTSource> Override(new LayoutOverrideSource( CI.getFrontendOpts().OverrideRecordLayoutsFile)); CI.getASTContext().setExternalSource(Override); } return true; // If we failed, reset state since the client will not end up calling the // matching EndSourceFile(). failure: if (isCurrentFileAST()) { CI.setASTContext(0); CI.setPreprocessor(0); CI.setSourceManager(0); CI.setFileManager(0); } if (HasBegunSourceFile) CI.getDiagnosticClient().EndSourceFile(); CI.clearOutputFiles(/*EraseFiles=*/true); setCurrentInput(FrontendInputFile()); setCompilerInstance(0); return false; }
int main(int argc, char *argv[]) { cl::ParseCommandLineOptions(argc, argv); auto& err = llvm::errs(); ManifestFile Result; std::map<Identifier,const AutomatonDescription*> Automata; std::map<Identifier,const Usage*> Usages; for (auto& Filename : InputFiles) { OwningPtr<Manifest> Manifest(Manifest::load(llvm::errs(), Automaton::Unlinked, Filename)); if (!Manifest) { err << "Unable to read manifest '" << Filename << "'\n"; return 1; } for (auto i : Manifest->AllAutomata()) { auto Existing = Automata.find(i.first); if (Existing == Automata.end()) Automata[i.first] = &(*Result.add_automaton() = *i.second); // If we already have this automaton, verify that both are // exactly the same. else if (*Existing->second != *i.second) panic("Attempting to cat two files containing automaton '" + ShortName(Existing->first) + "', but these automata are not exactly the same."); } for (auto i : Manifest->RootAutomata()) { auto Existing = Usages.find(i->identifier()); if (Existing == Usages.end()) Usages[i->identifier()] = &(*Result.add_root() = *i); else if (*Existing->second != *i) panic("Attempting to cat two files containing root '" + ShortName(i->identifier()) + "', but these roots are not exactly the same."); } } string ProtobufText; google::protobuf::TextFormat::PrintToString(Result, &ProtobufText); bool UseFile = (OutputFile != "-"); OwningPtr<raw_fd_ostream> outfile; if (UseFile) { string OutErrorInfo; outfile.reset(new raw_fd_ostream(OutputFile.c_str(), OutErrorInfo)); } raw_ostream& out = UseFile ? *outfile : llvm::outs(); out << ProtobufText; google::protobuf::ShutdownProtobufLibrary(); return 0; }
//===----------------------------------------------------------------------===// // main for opt // int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc, argv); if (AnalyzeOnly && NoOutput) { errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n"; return 1; } // Enable debug stream buffering. EnableDebugBuffering = true; llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. LLVMContext &Context = getGlobalContext(); cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .bc modular optimizer and analysis printer\n"); // Allocate a full target machine description only if necessary. // FIXME: The choice of target should be controllable on the command line. std::auto_ptr<TargetMachine> target; SMDiagnostic Err; // Load the input module... std::auto_ptr<Module> M; M.reset(ParseIRFile(InputFilename, Err, Context)); if (M.get() == 0) { Err.Print(argv[0], errs()); return 1; } // Figure out what stream we are supposed to write to... OwningPtr<tool_output_file> Out; if (NoOutput) { if (!OutputFilename.empty()) errs() << "WARNING: The -o (output filename) option is ignored when\n" "the --disable-output option is used.\n"; } else { // Default to standard output. if (OutputFilename.empty()) OutputFilename = "-"; std::string ErrorInfo; Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, raw_fd_ostream::F_Binary)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; } } // If the output is set to be emitted to standard out, and standard out is a // console, print out a warning message and refuse to do it. We don't // impress anyone by spewing tons of binary goo to a terminal. if (!Force && !NoOutput && !AnalyzeOnly && !OutputAssembly) if (CheckBitcodeOutputToConsole(Out->os(), !Quiet)) NoOutput = true; // Create a PassManager to hold and optimize the collection of passes we are // about to build... // PassManager Passes; // Add an appropriate TargetData instance for this module... TargetData *TD = 0; const std::string &ModuleDataLayout = M.get()->getDataLayout(); if (!ModuleDataLayout.empty()) TD = new TargetData(ModuleDataLayout); else if (!DefaultDataLayout.empty()) TD = new TargetData(DefaultDataLayout); if (TD) Passes.add(TD); OwningPtr<PassManager> FPasses; if (OptLevelO1 || OptLevelO2 || OptLevelO3) { FPasses.reset(new PassManager()); if (TD) FPasses->add(new TargetData(*TD)); } // If the -strip-debug command line option was specified, add it. If // -std-compile-opts was also specified, it will handle StripDebug. if (StripDebug && !StandardCompileOpts) addPass(Passes, createStripSymbolsPass(true)); // Create a new optimization pass for each one specified on the command line for (unsigned i = 0; i < PassList.size(); ++i) { // Check to see if -std-compile-opts was specified before this option. If // so, handle it. if (StandardCompileOpts && StandardCompileOpts.getPosition() < PassList.getPosition(i)) { AddStandardCompilePasses(Passes); StandardCompileOpts = false; } if (StandardLinkOpts && StandardLinkOpts.getPosition() < PassList.getPosition(i)) { AddStandardLinkPasses(Passes); StandardLinkOpts = false; } if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 1); OptLevelO1 = false; } if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 2); OptLevelO2 = false; } if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 3); OptLevelO3 = false; } const PassInfo *PassInf = PassList[i]; Pass *P = 0; if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); else errs() << argv[0] << ": cannot create pass: "******"\n"; if (P) { PassKind Kind = P->getPassKind(); addPass(Passes, P); if (AnalyzeOnly) { switch (Kind) { case PT_BasicBlock: Passes.add(new BasicBlockPassPrinter(PassInf, Out->os())); break; case PT_Loop: Passes.add(new LoopPassPrinter(PassInf, Out->os())); break; case PT_Function: Passes.add(new FunctionPassPrinter(PassInf, Out->os())); break; case PT_CallGraphSCC: Passes.add(new CallGraphSCCPassPrinter(PassInf, Out->os())); break; default: Passes.add(new ModulePassPrinter(PassInf, Out->os())); break; } } } if (PrintEachXForm) Passes.add(createPrintModulePass(&errs())); } // If -std-compile-opts was specified at the end of the pass list, add them. if (StandardCompileOpts) { AddStandardCompilePasses(Passes); StandardCompileOpts = false; } if (StandardLinkOpts) { AddStandardLinkPasses(Passes); StandardLinkOpts = false; } if (OptLevelO1) AddOptimizationPasses(Passes, *FPasses, 1); if (OptLevelO2) AddOptimizationPasses(Passes, *FPasses, 2); if (OptLevelO3) AddOptimizationPasses(Passes, *FPasses, 3); if (OptLevelO1 || OptLevelO2 || OptLevelO3) FPasses->run(*M.get()); // Check that the module is well formed on completion of optimization if (!NoVerify && !VerifyEach) Passes.add(createVerifierPass()); // Write bitcode or assembly to the output as the last step... if (!NoOutput && !AnalyzeOnly) { if (OutputAssembly) Passes.add(createPrintModulePass(&Out->os())); else Passes.add(createBitcodeWriterPass(Out->os())); } // Now that we have all of the passes ready, run them. Passes.run(*M.get()); // Declare success. if (!NoOutput) Out->keep(); return 0; }
bool arcmt::checkForManualIssues(CompilerInvocation &origCI, const FrontendInputFile &Input, DiagnosticConsumer *DiagClient, bool emitPremigrationARCErrors, StringRef plistOut) { if (!origCI.getLangOpts()->ObjC1) return false; LangOptions::GCMode OrigGCMode = origCI.getLangOpts()->getGC(); bool NoNSAllocReallocError = origCI.getMigratorOpts().NoNSAllocReallocError; bool NoFinalizeRemoval = origCI.getMigratorOpts().NoFinalizeRemoval; std::vector<TransformFn> transforms = arcmt::getAllTransformations(OrigGCMode, NoFinalizeRemoval); assert(!transforms.empty()); OwningPtr<CompilerInvocation> CInvok; CInvok.reset(createInvocationForMigration(origCI)); CInvok->getFrontendOpts().Inputs.clear(); CInvok->getFrontendOpts().Inputs.push_back(Input); CapturedDiagList capturedDiags; assert(DiagClient); IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); IntrusiveRefCntPtr<DiagnosticsEngine> Diags( new DiagnosticsEngine(DiagID, DiagClient, /*ShouldOwnClient=*/false)); // Filter of all diagnostics. CaptureDiagnosticConsumer errRec(*Diags, capturedDiags); Diags->setClient(&errRec, /*ShouldOwnClient=*/false); OwningPtr<ASTUnit> Unit( ASTUnit::LoadFromCompilerInvocationAction(CInvok.take(), Diags)); if (!Unit) return true; // Don't filter diagnostics anymore. Diags->setClient(DiagClient, /*ShouldOwnClient=*/false); ASTContext &Ctx = Unit->getASTContext(); if (Diags->hasFatalErrorOccurred()) { Diags->Reset(); DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor()); capturedDiags.reportDiagnostics(*Diags); DiagClient->EndSourceFile(); return true; } if (emitPremigrationARCErrors) emitPremigrationErrors(capturedDiags, origCI.getDiagnosticOpts(), Unit->getPreprocessor()); if (!plistOut.empty()) { SmallVector<StoredDiagnostic, 8> arcDiags; for (CapturedDiagList::iterator I = capturedDiags.begin(), E = capturedDiags.end(); I != E; ++I) arcDiags.push_back(*I); writeARCDiagsToPlist(plistOut, arcDiags, Ctx.getSourceManager(), Ctx.getLangOpts()); } // After parsing of source files ended, we want to reuse the // diagnostics objects to emit further diagnostics. // We call BeginSourceFile because DiagnosticConsumer requires that // diagnostics with source range information are emitted only in between // BeginSourceFile() and EndSourceFile(). DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor()); // No macros will be added since we are just checking and we won't modify // source code. std::vector<SourceLocation> ARCMTMacroLocs; TransformActions testAct(*Diags, capturedDiags, Ctx, Unit->getPreprocessor()); MigrationPass pass(Ctx, OrigGCMode, Unit->getSema(), testAct, ARCMTMacroLocs); pass.setNSAllocReallocError(NoNSAllocReallocError); pass.setNoFinalizeRemoval(NoFinalizeRemoval); for (unsigned i=0, e = transforms.size(); i != e; ++i) transforms[i](pass); capturedDiags.reportDiagnostics(*Diags); DiagClient->EndSourceFile(); // If we are migrating code that gets the '-fobjc-arc' flag, make sure // to remove it so that we don't get errors from normal compilation. origCI.getLangOpts()->ObjCAutoRefCount = false; return capturedDiags.hasErrors() || testAct.hasReportedErrors(); }
static bool ExecuteAssembler(AssemblerInvocation &Opts, DiagnosticsEngine &Diags) { // Get the target specific parser. std::string Error; const Target *TheTarget(TargetRegistry::lookupTarget(Opts.Triple, Error)); if (!TheTarget) { Diags.Report(diag::err_target_unknown_triple) << Opts.Triple; return false; } OwningPtr<MemoryBuffer> BufferPtr; if (error_code ec = MemoryBuffer::getFileOrSTDIN(Opts.InputFile, BufferPtr)) { Error = ec.message(); Diags.Report(diag::err_fe_error_reading) << Opts.InputFile; return false; } MemoryBuffer *Buffer = BufferPtr.take(); SourceMgr SrcMgr; // Tell SrcMgr about this buffer, which is what the parser will pick up. SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); // Record the location of the include directories so that the lexer can find // it later. SrcMgr.setIncludeDirs(Opts.IncludePaths); OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(Opts.Triple)); assert(MAI && "Unable to create target asm info!"); OwningPtr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple)); assert(MRI && "Unable to create target register info!"); bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj; formatted_raw_ostream *Out = GetOutputStream(Opts, Diags, IsBinary); if (!Out) return false; // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and // MCObjectFileInfo needs a MCContext reference in order to initialize itself. OwningPtr<MCObjectFileInfo> MOFI(new MCObjectFileInfo()); MCContext Ctx(*MAI, *MRI, MOFI.get()); // FIXME: Assembler behavior can change with -static. MOFI->InitMCObjectFileInfo(Opts.Triple, Reloc::Default, CodeModel::Default, Ctx); if (Opts.SaveTemporaryLabels) Ctx.setAllowTemporaryLabels(false); OwningPtr<MCStreamer> Str; OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo()); OwningPtr<MCSubtargetInfo> STI(TheTarget->createMCSubtargetInfo(Opts.Triple, "", "")); // FIXME: There is a bit of code duplication with addPassesToEmitFile. if (Opts.OutputType == AssemblerInvocation::FT_Asm) { MCInstPrinter *IP = TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI, *MCII, *MRI, *STI); MCCodeEmitter *CE = 0; MCAsmBackend *MAB = 0; if (Opts.ShowEncoding) { CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx); MAB = TheTarget->createMCAsmBackend(Opts.Triple); } Str.reset(TheTarget->createAsmStreamer(Ctx, *Out, /*asmverbose*/true, /*useLoc*/ true, /*useCFI*/ true, /*useDwarfDirectory*/ true, IP, CE, MAB, Opts.ShowInst)); } else if (Opts.OutputType == AssemblerInvocation::FT_Null) { Str.reset(createNullStreamer(Ctx)); } else { assert(Opts.OutputType == AssemblerInvocation::FT_Obj && "Invalid file type!"); MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx); MCAsmBackend *MAB = TheTarget->createMCAsmBackend(Opts.Triple); Str.reset(TheTarget->createMCObjectStreamer(Opts.Triple, Ctx, *MAB, *Out, CE, Opts.RelaxAll, Opts.NoExecStack)); Str.get()->InitSections(); } OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI)); OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(*STI, *Parser)); if (!TAP) { Diags.Report(diag::err_target_unknown_triple) << Opts.Triple; return false; } Parser->setTargetParser(*TAP.get()); bool Success = !Parser->Run(Opts.NoInitialTextSection); // Close the output. delete Out; // Delete output on errors. if (!Success && Opts.OutputPath != "-") sys::Path(Opts.OutputPath).eraseFromDisk(); return Success; }
CXDiagnosticSet DiagLoader::load(const char *file) { // Open the diagnostics file. std::string ErrStr; FileSystemOptions FO; FileManager FileMgr(FO); OwningPtr<llvm::MemoryBuffer> Buffer; Buffer.reset(FileMgr.getBufferForFile(file)); if (!Buffer) { reportBad(CXLoadDiag_CannotLoad, ErrStr); return 0; } llvm::BitstreamReader StreamFile; StreamFile.init((const unsigned char *)Buffer->getBufferStart(), (const unsigned char *)Buffer->getBufferEnd()); llvm::BitstreamCursor Stream; Stream.init(StreamFile); // Sniff for the signature. if (Stream.Read(8) != 'D' || Stream.Read(8) != 'I' || Stream.Read(8) != 'A' || Stream.Read(8) != 'G') { reportBad(CXLoadDiag_InvalidFile, "Bad header in diagnostics file"); return 0; } OwningPtr<CXLoadedDiagnosticSetImpl> Diags(new CXLoadedDiagnosticSetImpl()); while (true) { unsigned BlockID = 0; StreamResult Res = readToNextRecordOrBlock(Stream, "Top-level", BlockID, true); switch (Res) { case Read_EndOfStream: return (CXDiagnosticSet) Diags.take(); case Read_Failure: return 0; case Read_Record: llvm_unreachable("Top-level does not have records"); case Read_BlockEnd: continue; case Read_BlockBegin: break; } switch (BlockID) { case serialized_diags::BLOCK_META: if (readMetaBlock(Stream)) return 0; break; case serialized_diags::BLOCK_DIAG: if (readDiagnosticBlock(Stream, *Diags.get(), *Diags.get())) return 0; break; default: if (!Stream.SkipBlock()) { reportInvalidFile("Malformed block at top-level of diagnostics file"); return 0; } break; } } }
static void DisassembleInputMachO2(StringRef Filename, MachOObjectFile *MachOOF) { const Target *TheTarget = GetTarget(MachOOF); if (!TheTarget) { // GetTarget prints out stuff. return; } OwningPtr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo()); OwningPtr<MCInstrAnalysis> InstrAnalysis(TheTarget->createMCInstrAnalysis(InstrInfo.get())); // Set up disassembler. OwningPtr<const MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); OwningPtr<const MCAsmInfo> AsmInfo( TheTarget->createMCAsmInfo(*MRI, TripleName)); OwningPtr<const MCSubtargetInfo> STI(TheTarget->createMCSubtargetInfo(TripleName, "", "")); OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI)); int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *InstrInfo, *MRI, *STI)); if (!InstrAnalysis || !AsmInfo || !STI || !DisAsm || !IP) { errs() << "error: couldn't initialize disassembler for target " << TripleName << '\n'; return; } outs() << '\n' << Filename << ":\n\n"; macho::Header Header = MachOOF->getHeader(); // FIXME: FoundFns isn't used anymore. Using symbols/LC_FUNCTION_STARTS to // determine function locations will eventually go in MCObjectDisassembler. // FIXME: Using the -cfg command line option, this code used to be able to // annotate relocations with the referenced symbol's name, and if this was // inside a __[cf]string section, the data it points to. This is now replaced // by the upcoming MCSymbolizer, which needs the appropriate setup done above. std::vector<SectionRef> Sections; std::vector<SymbolRef> Symbols; SmallVector<uint64_t, 8> FoundFns; getSectionsAndSymbols(Header, MachOOF, Sections, Symbols, FoundFns); // Make a copy of the unsorted symbol list. FIXME: duplication std::vector<SymbolRef> UnsortedSymbols(Symbols); // Sort the symbols by address, just in case they didn't come in that way. std::sort(Symbols.begin(), Symbols.end(), SymbolSorter()); #ifndef NDEBUG raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls(); #else raw_ostream &DebugOut = nulls(); #endif OwningPtr<DIContext> diContext; ObjectFile *DbgObj = MachOOF; // Try to find debug info and set up the DIContext for it. if (UseDbg) { // A separate DSym file path was specified, parse it as a macho file, // get the sections and supply it to the section name parsing machinery. if (!DSYMFile.empty()) { OwningPtr<MemoryBuffer> Buf; if (error_code ec = MemoryBuffer::getFileOrSTDIN(DSYMFile.c_str(), Buf)) { errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n'; return; } DbgObj = ObjectFile::createMachOObjectFile(Buf.take()); } // Setup the DIContext diContext.reset(DIContext::getDWARFContext(DbgObj)); } for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) { bool SectIsText = false; Sections[SectIdx].isText(SectIsText); if (SectIsText == false) continue; StringRef SectName; if (Sections[SectIdx].getName(SectName) || SectName != "__text") continue; // Skip non-text sections DataRefImpl DR = Sections[SectIdx].getRawDataRefImpl(); StringRef SegmentName = MachOOF->getSectionFinalSegmentName(DR); if (SegmentName != "__TEXT") continue; StringRef Bytes; Sections[SectIdx].getContents(Bytes); StringRefMemoryObject memoryObject(Bytes); bool symbolTableWorked = false; // Parse relocations. std::vector<std::pair<uint64_t, SymbolRef> > Relocs; error_code ec; for (relocation_iterator RI = Sections[SectIdx].begin_relocations(), RE = Sections[SectIdx].end_relocations(); RI != RE; RI.increment(ec)) { uint64_t RelocOffset, SectionAddress; RI->getOffset(RelocOffset); Sections[SectIdx].getAddress(SectionAddress); RelocOffset -= SectionAddress; SymbolRef RelocSym; RI->getSymbol(RelocSym); Relocs.push_back(std::make_pair(RelocOffset, RelocSym)); } array_pod_sort(Relocs.begin(), Relocs.end()); // Disassemble symbol by symbol. for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) { StringRef SymName; Symbols[SymIdx].getName(SymName); SymbolRef::Type ST; Symbols[SymIdx].getType(ST); if (ST != SymbolRef::ST_Function) continue; // Make sure the symbol is defined in this section. bool containsSym = false; Sections[SectIdx].containsSymbol(Symbols[SymIdx], containsSym); if (!containsSym) continue; // Start at the address of the symbol relative to the section's address. uint64_t SectionAddress = 0; uint64_t Start = 0; Sections[SectIdx].getAddress(SectionAddress); Symbols[SymIdx].getAddress(Start); Start -= SectionAddress; // Stop disassembling either at the beginning of the next symbol or at // the end of the section. bool containsNextSym = false; uint64_t NextSym = 0; uint64_t NextSymIdx = SymIdx+1; while (Symbols.size() > NextSymIdx) { SymbolRef::Type NextSymType; Symbols[NextSymIdx].getType(NextSymType); if (NextSymType == SymbolRef::ST_Function) { Sections[SectIdx].containsSymbol(Symbols[NextSymIdx], containsNextSym); Symbols[NextSymIdx].getAddress(NextSym); NextSym -= SectionAddress; break; } ++NextSymIdx; } uint64_t SectSize; Sections[SectIdx].getSize(SectSize); uint64_t End = containsNextSym ? NextSym : SectSize; uint64_t Size; symbolTableWorked = true; outs() << SymName << ":\n"; DILineInfo lastLine; for (uint64_t Index = Start; Index < End; Index += Size) { MCInst Inst; if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, DebugOut, nulls())) { uint64_t SectAddress = 0; Sections[SectIdx].getAddress(SectAddress); outs() << format("%8" PRIx64 ":\t", SectAddress + Index); DumpBytes(StringRef(Bytes.data() + Index, Size)); IP->printInst(&Inst, outs(), ""); // Print debug info. if (diContext) { DILineInfo dli = diContext->getLineInfoForAddress(SectAddress + Index); // Print valid line info if it changed. if (dli != lastLine && dli.getLine() != 0) outs() << "\t## " << dli.getFileName() << ':' << dli.getLine() << ':' << dli.getColumn(); lastLine = dli; } outs() << "\n"; } else { errs() << "llvm-objdump: warning: invalid instruction encoding\n"; if (Size == 0) Size = 1; // skip illegible bytes } } } if (!symbolTableWorked) { // Reading the symbol table didn't work, disassemble the whole section. uint64_t SectAddress; Sections[SectIdx].getAddress(SectAddress); uint64_t SectSize; Sections[SectIdx].getSize(SectSize); uint64_t InstSize; for (uint64_t Index = 0; Index < SectSize; Index += InstSize) { MCInst Inst; if (DisAsm->getInstruction(Inst, InstSize, memoryObject, Index, DebugOut, nulls())) { outs() << format("%8" PRIx64 ":\t", SectAddress + Index); DumpBytes(StringRef(Bytes.data() + Index, InstSize)); IP->printInst(&Inst, outs(), ""); outs() << "\n"; } else { errs() << "llvm-objdump: warning: invalid instruction encoding\n"; if (InstSize == 0) InstSize = 1; // skip illegible bytes } } } } }
bool MigrationProcess::applyTransform(TransformFn trans, RewriteListener *listener) { OwningPtr<CompilerInvocation> CInvok; CInvok.reset(createInvocationForMigration(OrigCI)); CInvok->getDiagnosticOpts().IgnoreWarnings = true; Remapper.applyMappings(CInvok->getPreprocessorOpts()); CapturedDiagList capturedDiags; std::vector<SourceLocation> ARCMTMacroLocs; assert(DiagClient); IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); IntrusiveRefCntPtr<DiagnosticsEngine> Diags( new DiagnosticsEngine(DiagID, DiagClient, /*ShouldOwnClient=*/false)); // Filter of all diagnostics. CaptureDiagnosticConsumer errRec(*Diags, capturedDiags); Diags->setClient(&errRec, /*ShouldOwnClient=*/false); OwningPtr<ARCMTMacroTrackerAction> ASTAction; ASTAction.reset(new ARCMTMacroTrackerAction(ARCMTMacroLocs)); OwningPtr<ASTUnit> Unit( ASTUnit::LoadFromCompilerInvocationAction(CInvok.take(), Diags, ASTAction.get())); if (!Unit) return true; Unit->setOwnsRemappedFileBuffers(false); // FileRemapper manages that. // Don't filter diagnostics anymore. Diags->setClient(DiagClient, /*ShouldOwnClient=*/false); ASTContext &Ctx = Unit->getASTContext(); if (Diags->hasFatalErrorOccurred()) { Diags->Reset(); DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor()); capturedDiags.reportDiagnostics(*Diags); DiagClient->EndSourceFile(); return true; } // After parsing of source files ended, we want to reuse the // diagnostics objects to emit further diagnostics. // We call BeginSourceFile because DiagnosticConsumer requires that // diagnostics with source range information are emitted only in between // BeginSourceFile() and EndSourceFile(). DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor()); Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts()); TransformActions TA(*Diags, capturedDiags, Ctx, Unit->getPreprocessor()); MigrationPass pass(Ctx, OrigCI.getLangOpts()->getGC(), Unit->getSema(), TA, ARCMTMacroLocs); trans(pass); { RewritesApplicator applicator(rewriter, Ctx, listener); TA.applyRewrites(applicator); } DiagClient->EndSourceFile(); if (DiagClient->getNumErrors()) return true; for (Rewriter::buffer_iterator I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) { FileID FID = I->first; RewriteBuffer &buf = I->second; const FileEntry *file = Ctx.getSourceManager().getFileEntryForID(FID); assert(file); std::string newFname = file->getName(); newFname += "-trans"; SmallString<512> newText; llvm::raw_svector_ostream vecOS(newText); buf.write(vecOS); vecOS.flush(); llvm::MemoryBuffer *memBuf = llvm::MemoryBuffer::getMemBufferCopy( StringRef(newText.data(), newText.size()), newFname); SmallString<64> filePath(file->getName()); Unit->getFileManager().FixupRelativePath(filePath); Remapper.remap(filePath.str(), memBuf); } return false; }
void llvm::DisassembleInputMachO(StringRef Filename) { OwningPtr<MemoryBuffer> Buff; if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { errs() << "llvm-objdump: " << Filename << ": " << ec.message() << "\n"; return; } OwningPtr<MachOObjectFile> MachOOF(static_cast<MachOObjectFile*>( ObjectFile::createMachOObjectFile(Buff.take()))); MachOObject *MachOObj = MachOOF->getObject(); const Target *TheTarget = GetTarget(MachOObj); if (!TheTarget) { // GetTarget prints out stuff. return; } OwningPtr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo()); OwningPtr<MCInstrAnalysis> InstrAnalysis(TheTarget->createMCInstrAnalysis(InstrInfo.get())); // Set up disassembler. OwningPtr<const MCAsmInfo> AsmInfo(TheTarget->createMCAsmInfo(TripleName)); OwningPtr<const MCSubtargetInfo> STI(TheTarget->createMCSubtargetInfo(TripleName, "", "")); OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI)); OwningPtr<const MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *InstrInfo, *MRI, *STI)); if (!InstrAnalysis || !AsmInfo || !STI || !DisAsm || !IP) { errs() << "error: couldn't initialize disassembler for target " << TripleName << '\n'; return; } outs() << '\n' << Filename << ":\n\n"; const macho::Header &Header = MachOObj->getHeader(); const MachOObject::LoadCommandInfo *SymtabLCI = 0; // First, find the symbol table segment. for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { const MachOObject::LoadCommandInfo &LCI = MachOObj->getLoadCommandInfo(i); if (LCI.Command.Type == macho::LCT_Symtab) { SymtabLCI = &LCI; break; } } // Read and register the symbol table data. InMemoryStruct<macho::SymtabLoadCommand> SymtabLC; if (SymtabLCI) { MachOObj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC); MachOObj->RegisterStringTable(*SymtabLC); } std::vector<SectionRef> Sections; std::vector<SymbolRef> Symbols; SmallVector<uint64_t, 8> FoundFns; getSectionsAndSymbols(Header, MachOOF.get(), &SymtabLC, Sections, Symbols, FoundFns); // Make a copy of the unsorted symbol list. FIXME: duplication std::vector<SymbolRef> UnsortedSymbols(Symbols); // Sort the symbols by address, just in case they didn't come in that way. std::sort(Symbols.begin(), Symbols.end(), SymbolSorter()); #ifndef NDEBUG raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls(); #else raw_ostream &DebugOut = nulls(); #endif StringRef DebugAbbrevSection, DebugInfoSection, DebugArangesSection, DebugLineSection, DebugStrSection; OwningPtr<DIContext> diContext; OwningPtr<MachOObjectFile> DSYMObj; MachOObject *DbgInfoObj = MachOObj; // Try to find debug info and set up the DIContext for it. if (UseDbg) { ArrayRef<SectionRef> DebugSections = Sections; std::vector<SectionRef> DSYMSections; // A separate DSym file path was specified, parse it as a macho file, // get the sections and supply it to the section name parsing machinery. if (!DSYMFile.empty()) { OwningPtr<MemoryBuffer> Buf; if (error_code ec = MemoryBuffer::getFileOrSTDIN(DSYMFile.c_str(), Buf)) { errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n'; return; } DSYMObj.reset(static_cast<MachOObjectFile*>( ObjectFile::createMachOObjectFile(Buf.take()))); const macho::Header &Header = DSYMObj->getObject()->getHeader(); std::vector<SymbolRef> Symbols; SmallVector<uint64_t, 8> FoundFns; getSectionsAndSymbols(Header, DSYMObj.get(), 0, DSYMSections, Symbols, FoundFns); DebugSections = DSYMSections; DbgInfoObj = DSYMObj.get()->getObject(); } // Find the named debug info sections. for (unsigned SectIdx = 0; SectIdx != DebugSections.size(); SectIdx++) { StringRef SectName; if (!DebugSections[SectIdx].getName(SectName)) { if (SectName.equals("__DWARF,__debug_abbrev")) DebugSections[SectIdx].getContents(DebugAbbrevSection); else if (SectName.equals("__DWARF,__debug_info")) DebugSections[SectIdx].getContents(DebugInfoSection); else if (SectName.equals("__DWARF,__debug_aranges")) DebugSections[SectIdx].getContents(DebugArangesSection); else if (SectName.equals("__DWARF,__debug_line")) DebugSections[SectIdx].getContents(DebugLineSection); else if (SectName.equals("__DWARF,__debug_str")) DebugSections[SectIdx].getContents(DebugStrSection); } } // Setup the DIContext. diContext.reset(DIContext::getDWARFContext(DbgInfoObj->isLittleEndian(), DebugInfoSection, DebugAbbrevSection, DebugArangesSection, DebugLineSection, DebugStrSection)); } FunctionMapTy FunctionMap; FunctionListTy Functions; for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) { StringRef SectName; if (Sections[SectIdx].getName(SectName) || SectName.compare("__TEXT,__text")) continue; // Skip non-text sections // Insert the functions from the function starts segment into our map. uint64_t VMAddr; Sections[SectIdx].getAddress(VMAddr); for (unsigned i = 0, e = FoundFns.size(); i != e; ++i) { StringRef SectBegin; Sections[SectIdx].getContents(SectBegin); uint64_t Offset = (uint64_t)SectBegin.data(); FunctionMap.insert(std::make_pair(VMAddr + FoundFns[i]-Offset, (MCFunction*)0)); } StringRef Bytes; Sections[SectIdx].getContents(Bytes); StringRefMemoryObject memoryObject(Bytes); bool symbolTableWorked = false; // Parse relocations. std::vector<std::pair<uint64_t, SymbolRef> > Relocs; error_code ec; for (relocation_iterator RI = Sections[SectIdx].begin_relocations(), RE = Sections[SectIdx].end_relocations(); RI != RE; RI.increment(ec)) { uint64_t RelocOffset, SectionAddress; RI->getAddress(RelocOffset); Sections[SectIdx].getAddress(SectionAddress); RelocOffset -= SectionAddress; SymbolRef RelocSym; RI->getSymbol(RelocSym); Relocs.push_back(std::make_pair(RelocOffset, RelocSym)); } array_pod_sort(Relocs.begin(), Relocs.end()); // Disassemble symbol by symbol. for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) { StringRef SymName; Symbols[SymIdx].getName(SymName); SymbolRef::Type ST; Symbols[SymIdx].getType(ST); if (ST != SymbolRef::ST_Function) continue; // Make sure the symbol is defined in this section. bool containsSym = false; Sections[SectIdx].containsSymbol(Symbols[SymIdx], containsSym); if (!containsSym) continue; // Start at the address of the symbol relative to the section's address. uint64_t SectionAddress = 0; uint64_t Start = 0; Sections[SectIdx].getAddress(SectionAddress); Symbols[SymIdx].getAddress(Start); Start -= SectionAddress; // Stop disassembling either at the beginning of the next symbol or at // the end of the section. bool containsNextSym = false; uint64_t NextSym = 0; uint64_t NextSymIdx = SymIdx+1; while (Symbols.size() > NextSymIdx) { SymbolRef::Type NextSymType; Symbols[NextSymIdx].getType(NextSymType); if (NextSymType == SymbolRef::ST_Function) { Sections[SectIdx].containsSymbol(Symbols[NextSymIdx], containsNextSym); Symbols[NextSymIdx].getAddress(NextSym); NextSym -= SectionAddress; break; } ++NextSymIdx; } uint64_t SectSize; Sections[SectIdx].getSize(SectSize); uint64_t End = containsNextSym ? NextSym : SectSize; uint64_t Size; symbolTableWorked = true; if (!CFG) { // Normal disassembly, print addresses, bytes and mnemonic form. StringRef SymName; Symbols[SymIdx].getName(SymName); outs() << SymName << ":\n"; DILineInfo lastLine; for (uint64_t Index = Start; Index < End; Index += Size) { MCInst Inst; if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, DebugOut, nulls())) { uint64_t SectAddress = 0; Sections[SectIdx].getAddress(SectAddress); outs() << format("%8" PRIx64 ":\t", SectAddress + Index); DumpBytes(StringRef(Bytes.data() + Index, Size)); IP->printInst(&Inst, outs(), ""); // Print debug info. if (diContext) { DILineInfo dli = diContext->getLineInfoForAddress(SectAddress + Index); // Print valid line info if it changed. if (dli != lastLine && dli.getLine() != 0) outs() << "\t## " << dli.getFileName() << ':' << dli.getLine() << ':' << dli.getColumn(); lastLine = dli; } outs() << "\n"; } else { errs() << "llvm-objdump: warning: invalid instruction encoding\n"; if (Size == 0) Size = 1; // skip illegible bytes } } } else { // Create CFG and use it for disassembly. StringRef SymName; Symbols[SymIdx].getName(SymName); createMCFunctionAndSaveCalls( SymName, DisAsm.get(), memoryObject, Start, End, InstrAnalysis.get(), Start, DebugOut, FunctionMap, Functions); } } if (!CFG && !symbolTableWorked) { // Reading the symbol table didn't work, disassemble the whole section. uint64_t SectAddress; Sections[SectIdx].getAddress(SectAddress); uint64_t SectSize; Sections[SectIdx].getSize(SectSize); uint64_t InstSize; for (uint64_t Index = 0; Index < SectSize; Index += InstSize) { MCInst Inst; if (DisAsm->getInstruction(Inst, InstSize, memoryObject, Index, DebugOut, nulls())) { outs() << format("%8" PRIx64 ":\t", SectAddress + Index); DumpBytes(StringRef(Bytes.data() + Index, InstSize)); IP->printInst(&Inst, outs(), ""); outs() << "\n"; } else { errs() << "llvm-objdump: warning: invalid instruction encoding\n"; if (InstSize == 0) InstSize = 1; // skip illegible bytes } } } if (CFG) { if (!symbolTableWorked) { // Reading the symbol table didn't work, create a big __TEXT symbol. uint64_t SectSize = 0, SectAddress = 0; Sections[SectIdx].getSize(SectSize); Sections[SectIdx].getAddress(SectAddress); createMCFunctionAndSaveCalls("__TEXT", DisAsm.get(), memoryObject, 0, SectSize, InstrAnalysis.get(), SectAddress, DebugOut, FunctionMap, Functions); } for (std::map<uint64_t, MCFunction*>::iterator mi = FunctionMap.begin(), me = FunctionMap.end(); mi != me; ++mi) if (mi->second == 0) { // Create functions for the remaining callees we have gathered, // but we didn't find a name for them. uint64_t SectSize = 0; Sections[SectIdx].getSize(SectSize); SmallVector<uint64_t, 16> Calls; MCFunction f = MCFunction::createFunctionFromMC("unknown", DisAsm.get(), memoryObject, mi->first, SectSize, InstrAnalysis.get(), DebugOut, Calls); Functions.push_back(f); mi->second = &Functions.back(); for (unsigned i = 0, e = Calls.size(); i != e; ++i) { std::pair<uint64_t, MCFunction*> p(Calls[i], (MCFunction*)0); if (FunctionMap.insert(p).second) mi = FunctionMap.begin(); } } DenseSet<uint64_t> PrintedBlocks; for (unsigned ffi = 0, ffe = Functions.size(); ffi != ffe; ++ffi) { MCFunction &f = Functions[ffi]; for (MCFunction::iterator fi = f.begin(), fe = f.end(); fi != fe; ++fi){ if (!PrintedBlocks.insert(fi->first).second) continue; // We already printed this block. // We assume a block has predecessors when it's the first block after // a symbol. bool hasPreds = FunctionMap.find(fi->first) != FunctionMap.end(); // See if this block has predecessors. // FIXME: Slow. for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe; ++pi) if (pi->second.contains(fi->first)) { hasPreds = true; break; } uint64_t SectSize = 0, SectAddress; Sections[SectIdx].getSize(SectSize); Sections[SectIdx].getAddress(SectAddress); // No predecessors, this is a data block. Print as .byte directives. if (!hasPreds) { uint64_t End = llvm::next(fi) == fe ? SectSize : llvm::next(fi)->first; outs() << "# " << End-fi->first << " bytes of data:\n"; for (unsigned pos = fi->first; pos != End; ++pos) { outs() << format("%8x:\t", SectAddress + pos); DumpBytes(StringRef(Bytes.data() + pos, 1)); outs() << format("\t.byte 0x%02x\n", (uint8_t)Bytes[pos]); } continue; } if (fi->second.contains(fi->first)) // Print a header for simple loops outs() << "# Loop begin:\n"; DILineInfo lastLine; // Walk over the instructions and print them. for (unsigned ii = 0, ie = fi->second.getInsts().size(); ii != ie; ++ii) { const MCDecodedInst &Inst = fi->second.getInsts()[ii]; // If there's a symbol at this address, print its name. if (FunctionMap.find(SectAddress + Inst.Address) != FunctionMap.end()) outs() << FunctionMap[SectAddress + Inst.Address]-> getName() << ":\n"; outs() << format("%8" PRIx64 ":\t", SectAddress + Inst.Address); DumpBytes(StringRef(Bytes.data() + Inst.Address, Inst.Size)); if (fi->second.contains(fi->first)) // Indent simple loops. outs() << '\t'; IP->printInst(&Inst.Inst, outs(), ""); // Look for relocations inside this instructions, if there is one // print its target and additional information if available. for (unsigned j = 0; j != Relocs.size(); ++j) if (Relocs[j].first >= SectAddress + Inst.Address && Relocs[j].first < SectAddress + Inst.Address + Inst.Size) { StringRef SymName; uint64_t Addr; Relocs[j].second.getAddress(Addr); Relocs[j].second.getName(SymName); outs() << "\t# " << SymName << ' '; DumpAddress(Addr, Sections, MachOObj, outs()); } // If this instructions contains an address, see if we can evaluate // it and print additional information. uint64_t targ = InstrAnalysis->evaluateBranch(Inst.Inst, Inst.Address, Inst.Size); if (targ != -1ULL) DumpAddress(targ, Sections, MachOObj, outs()); // Print debug info. if (diContext) { DILineInfo dli = diContext->getLineInfoForAddress(SectAddress + Inst.Address); // Print valid line info if it changed. if (dli != lastLine && dli.getLine() != 0) outs() << "\t## " << dli.getFileName() << ':' << dli.getLine() << ':' << dli.getColumn(); lastLine = dli; } outs() << '\n'; } } emitDOTFile((f.getName().str() + ".dot").c_str(), f, IP.get()); } } } }
int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n"); std::string ErrorMessage; std::auto_ptr<Module> M; // Use the bitcode streaming interface DataStreamer *streamer = getDataFileStreamer(InputFilename, &ErrorMessage); if (streamer) { std::string DisplayFilename; if (InputFilename == "-") DisplayFilename = "<stdin>"; else DisplayFilename = InputFilename; // @LOCALMOD-BEGIN switch (InputFileFormat) { case LLVMFormat: M.reset(getStreamedBitcodeModule(DisplayFilename, streamer, Context, &ErrorMessage)); break; case PNaClFormat: M.reset(getNaClStreamedBitcodeModule(DisplayFilename, streamer, Context, &ErrorMessage)); break; default: ErrorMessage = "Don't understand specified bitcode format"; break; } // @LOCALMOD-END if(M.get() != 0 && M->MaterializeAllPermanently(&ErrorMessage)) { M.reset(); } } if (M.get() == 0) { errs() << argv[0] << ": "; if (ErrorMessage.size()) errs() << ErrorMessage << "\n"; else errs() << "bitcode didn't read correctly.\n"; return 1; } // Just use stdout. We won't actually print anything on it. if (DontPrint) OutputFilename = "-"; if (OutputFilename.empty()) { // Unspecified output, infer it. if (InputFilename == "-" || DumpMetadata) { // @LOCALMOD OutputFilename = "-"; } else { const std::string &IFN = InputFilename; int Len = IFN.length(); // If the source ends in .bc, strip it off. if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll"; else OutputFilename = IFN+".ll"; } } std::string ErrorInfo; OwningPtr<tool_output_file> Out(new tool_output_file(OutputFilename.c_str(), ErrorInfo, raw_fd_ostream::F_Binary)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; } // @LOCALMOD-BEGIN if (DumpMetadata) { M->dumpMeta(Out->os()); Out->keep(); return 0; } // @LOCALMOD-END OwningPtr<AssemblyAnnotationWriter> Annotator; if (ShowAnnotations) Annotator.reset(new CommentWriter()); // All that llvm-dis does is write the assembly to a file. if (!DontPrint) M->print(Out->os(), Annotator.get()); // Declare success. Out->keep(); return 0; }
static void clang_indexSourceFile_Impl(void *UserData) { IndexSourceFileInfo *ITUI = static_cast<IndexSourceFileInfo*>(UserData); CXIndex CIdx = (CXIndex)ITUI->idxAction; CXClientData client_data = ITUI->client_data; IndexerCallbacks *client_index_callbacks = ITUI->index_callbacks; unsigned index_callbacks_size = ITUI->index_callbacks_size; unsigned index_options = ITUI->index_options; const char *source_filename = ITUI->source_filename; const char * const *command_line_args = ITUI->command_line_args; int num_command_line_args = ITUI->num_command_line_args; struct CXUnsavedFile *unsaved_files = ITUI->unsaved_files; unsigned num_unsaved_files = ITUI->num_unsaved_files; CXTranslationUnit *out_TU = ITUI->out_TU; unsigned TU_options = ITUI->TU_options; ITUI->result = 1; // init as error. if (out_TU) *out_TU = 0; bool requestedToGetTU = (out_TU != 0); if (!CIdx) return; if (!client_index_callbacks || index_callbacks_size == 0) return; IndexerCallbacks CB; memset(&CB, 0, sizeof(CB)); unsigned ClientCBSize = index_callbacks_size < sizeof(CB) ? index_callbacks_size : sizeof(CB); memcpy(&CB, client_index_callbacks, ClientCBSize); CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing)) setThreadBackgroundPriority(); CaptureDiagnosticConsumer *CaptureDiag = new CaptureDiagnosticConsumer(); // Configure the diagnostics. DiagnosticOptions DiagOpts; IntrusiveRefCntPtr<DiagnosticsEngine> Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args, command_line_args, CaptureDiag, /*ShouldOwnClient=*/true, /*ShouldCloneClient=*/false)); // Recover resources if we crash before exiting this function. llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > DiagCleanup(Diags.getPtr()); OwningPtr<std::vector<const char *> > Args(new std::vector<const char*>()); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> > ArgsCleanup(Args.get()); Args->insert(Args->end(), command_line_args, command_line_args + num_command_line_args); // The 'source_filename' argument is optional. If the caller does not // specify it then it is assumed that the source file is specified // in the actual argument list. // Put the source file after command_line_args otherwise if '-x' flag is // present it will be unused. if (source_filename) Args->push_back(source_filename); IntrusiveRefCntPtr<CompilerInvocation> CInvok(createInvocationFromCommandLine(*Args, Diags)); if (!CInvok) return; // Recover resources if we crash before exiting this function. llvm::CrashRecoveryContextCleanupRegistrar<CompilerInvocation, llvm::CrashRecoveryContextReleaseRefCleanup<CompilerInvocation> > CInvokCleanup(CInvok.getPtr()); if (CInvok->getFrontendOpts().Inputs.empty()) return; OwningPtr<MemBufferOwner> BufOwner(new MemBufferOwner()); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<MemBufferOwner> BufOwnerCleanup(BufOwner.get()); for (unsigned I = 0; I != num_unsaved_files; ++I) { StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); const llvm::MemoryBuffer *Buffer = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); CInvok->getPreprocessorOpts().addRemappedFile(unsaved_files[I].Filename, Buffer); BufOwner->Buffers.push_back(Buffer); } // Since libclang is primarily used by batch tools dealing with // (often very broken) source code, where spell-checking can have a // significant negative impact on performance (particularly when // precompiled headers are involved), we disable it. CInvok->getLangOpts()->SpellChecking = false; if (index_options & CXIndexOpt_SuppressWarnings) CInvok->getDiagnosticOpts().IgnoreWarnings = true; ASTUnit *Unit = ASTUnit::create(CInvok.getPtr(), Diags, /*CaptureDiagnostics=*/true, /*UserFilesAreVolatile=*/true); OwningPtr<CXTUOwner> CXTU(new CXTUOwner(MakeCXTranslationUnit(CXXIdx, Unit))); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<CXTUOwner> CXTUCleanup(CXTU.get()); OwningPtr<IndexingFrontendAction> IndexAction; IndexAction.reset(new IndexingFrontendAction(client_data, CB, index_options, CXTU->getTU())); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<IndexingFrontendAction> IndexActionCleanup(IndexAction.get()); bool Persistent = requestedToGetTU; bool OnlyLocalDecls = false; bool PrecompilePreamble = false; bool CacheCodeCompletionResults = false; PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts(); PPOpts.AllowPCHWithCompilerErrors = true; if (requestedToGetTU) { OnlyLocalDecls = CXXIdx->getOnlyLocalDecls(); PrecompilePreamble = TU_options & CXTranslationUnit_PrecompiledPreamble; // FIXME: Add a flag for modules. CacheCodeCompletionResults = TU_options & CXTranslationUnit_CacheCompletionResults; if (TU_options & CXTranslationUnit_DetailedPreprocessingRecord) { PPOpts.DetailedRecord = true; } } IndexAction->EnablePPDetailedRecordForModules = PPOpts.DetailedRecord || (TU_options & CXTranslationUnit_DetailedPreprocessingRecord); if (!requestedToGetTU) PPOpts.DetailedRecord = false; DiagnosticErrorTrap DiagTrap(*Diags); bool Success = ASTUnit::LoadFromCompilerInvocationAction(CInvok.getPtr(), Diags, IndexAction.get(), Unit, Persistent, CXXIdx->getClangResourcesPath(), OnlyLocalDecls, /*CaptureDiagnostics=*/true, PrecompilePreamble, CacheCodeCompletionResults, /*IncludeBriefCommentsInCodeCompletion=*/false, /*UserFilesAreVolatile=*/true); if (DiagTrap.hasErrorOccurred() && CXXIdx->getDisplayDiagnostics()) printDiagsToStderr(Unit); if (!Success) return; if (out_TU) *out_TU = CXTU->takeTU(); ITUI->result = 0; // success. }
bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out, CodeGenFileType FileType, CodeGenOpt::Level OptLevel, bool DisableVerify) { // Add common CodeGen passes. MCContext *Context = 0; if (addCommonCodeGenPasses(PM, OptLevel, DisableVerify, Context)) return true; assert(Context != 0 && "Failed to get MCContext"); if (hasMCSaveTempLabels()) Context->setAllowTemporaryLabels(false); const MCAsmInfo &MAI = *getMCAsmInfo(); const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>(); OwningPtr<MCStreamer> AsmStreamer; switch (FileType) { default: return true; case CGFT_AssemblyFile: { MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI, STI); // Create a code emitter if asked to show the encoding. MCCodeEmitter *MCE = 0; MCAsmBackend *MAB = 0; if (ShowMCEncoding) { const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>(); MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), STI, *Context); MAB = getTarget().createMCAsmBackend(getTargetTriple()); } MCStreamer *S = getTarget().createAsmStreamer(*Context, Out, getVerboseAsm(), hasMCUseLoc(), hasMCUseCFI(), hasMCUseDwarfDirectory(), InstPrinter, MCE, MAB, ShowMCInst); AsmStreamer.reset(S); break; } case CGFT_ObjectFile: { // Create the code emitter for the target if it exists. If not, .o file // emission fails. MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), STI, *Context); MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple()); if (MCE == 0 || MAB == 0) return true; AsmStreamer.reset(getTarget().createMCObjectStreamer(getTargetTriple(), *Context, *MAB, Out, MCE, hasMCRelaxAll(), hasMCNoExecStack())); AsmStreamer.get()->InitSections(); break; } case CGFT_Null: // The Null output is intended for use for performance analysis and testing, // not real users. AsmStreamer.reset(createNullStreamer(*Context)); break; } if (EnableMCLogging) AsmStreamer.reset(createLoggingStreamer(AsmStreamer.take(), errs())); // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer); if (Printer == 0) return true; // If successful, createAsmPrinter took ownership of AsmStreamer. AsmStreamer.take(); PM.add(Printer); PM.add(createGCInfoDeleter()); return false; }
bool PTXTargetMachine::addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out, CodeGenFileType FileType, bool DisableVerify) { // This is mostly based on LLVMTargetMachine::addPassesToEmitFile // Add common CodeGen passes. MCContext *Context = 0; if (addCommonCodeGenPasses(PM, DisableVerify, Context)) return true; assert(Context != 0 && "Failed to get MCContext"); if (hasMCSaveTempLabels()) Context->setAllowTemporaryLabels(false); const MCAsmInfo &MAI = *getMCAsmInfo(); const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>(); OwningPtr<MCStreamer> AsmStreamer; switch (FileType) { default: return true; case CGFT_AssemblyFile: { MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI, STI); // Create a code emitter if asked to show the encoding. MCCodeEmitter *MCE = 0; MCAsmBackend *MAB = 0; MCStreamer *S = getTarget().createAsmStreamer(*Context, Out, true, /* verbose asm */ hasMCUseLoc(), hasMCUseCFI(), hasMCUseDwarfDirectory(), InstPrinter, MCE, MAB, false /* show MC encoding */); AsmStreamer.reset(S); break; } case CGFT_ObjectFile: { llvm_unreachable("Object file emission is not supported with PTX"); } case CGFT_Null: // The Null output is intended for use for performance analysis and testing, // not real users. AsmStreamer.reset(createNullStreamer(*Context)); break; } // MC Logging //AsmStreamer.reset(createLoggingStreamer(AsmStreamer.take(), errs())); // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer); if (Printer == 0) return true; // If successful, createAsmPrinter took ownership of AsmStreamer. AsmStreamer.take(); PM.add(Printer); PM.add(createGCInfoDeleter()); return false; }
//===----------------------------------------------------------------------===// // main for opt // int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc, argv); // Enable debug stream buffering. EnableDebugBuffering = true; llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. LLVMContext &Context = getGlobalContext(); InitializeAllTargets(); InitializeAllTargetMCs(); // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeScalarOpts(Registry); initializeObjCARCOpts(Registry); initializeVectorization(Registry); initializeIPO(Registry); initializeAnalysis(Registry); initializeIPA(Registry); initializeTransformUtils(Registry); initializeInstCombine(Registry); initializeInstrumentation(Registry); initializeTarget(Registry); // @LOCALMOD-BEGIN initializeAddPNaClExternalDeclsPass(Registry); initializeCanonicalizeMemIntrinsicsPass(Registry); initializeExpandArithWithOverflowPass(Registry); initializeExpandByValPass(Registry); initializeExpandConstantExprPass(Registry); initializeExpandCtorsPass(Registry); initializeExpandGetElementPtrPass(Registry); initializeExpandSmallArgumentsPass(Registry); initializeExpandStructRegsPass(Registry); initializeExpandTlsConstantExprPass(Registry); initializeExpandTlsPass(Registry); initializeExpandVarArgsPass(Registry); initializeFlattenGlobalsPass(Registry); initializeGlobalCleanupPass(Registry); initializeInsertDivideCheckPass(Registry); initializePNaClABIVerifyFunctionsPass(Registry); initializePNaClABIVerifyModulePass(Registry); initializePNaClSjLjEHPass(Registry); initializePromoteI1OpsPass(Registry); initializePromoteIntegersPass(Registry); initializeRemoveAsmMemoryPass(Registry); initializeReplacePtrsWithIntsPass(Registry); initializeResolveAliasesPass(Registry); initializeResolvePNaClIntrinsicsPass(Registry); initializeRewriteAtomicsPass(Registry); initializeRewriteLLVMIntrinsicsPass(Registry); initializeRewritePNaClLibraryCallsPass(Registry); initializeStripAttributesPass(Registry); initializeStripMetadataPass(Registry); initializeExpandI64Pass(Registry); // @LOCALMOD-END cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .bc modular optimizer and analysis printer\n"); if (AnalyzeOnly && NoOutput) { errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n"; return 1; } SMDiagnostic Err; // Load the input module... OwningPtr<Module> M; M.reset(ParseIRFile(InputFilename, Err, Context)); if (M.get() == 0) { Err.print(argv[0], errs()); return 1; } // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) M->setTargetTriple(Triple::normalize(TargetTriple)); // Figure out what stream we are supposed to write to... OwningPtr<tool_output_file> Out; if (NoOutput) { if (!OutputFilename.empty()) errs() << "WARNING: The -o (output filename) option is ignored when\n" "the --disable-output option is used.\n"; } else { // Default to standard output. if (OutputFilename.empty()) OutputFilename = "-"; std::string ErrorInfo; Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, raw_fd_ostream::F_Binary)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; } } // If the output is set to be emitted to standard out, and standard out is a // console, print out a warning message and refuse to do it. We don't // impress anyone by spewing tons of binary goo to a terminal. if (!Force && !NoOutput && !AnalyzeOnly && !OutputAssembly) if (CheckBitcodeOutputToConsole(Out->os(), !Quiet)) NoOutput = true; // Create a PassManager to hold and optimize the collection of passes we are // about to build. // PassManager Passes; // Add an appropriate TargetLibraryInfo pass for the module's triple. TargetLibraryInfo *TLI = new TargetLibraryInfo(Triple(M->getTargetTriple())); // The -disable-simplify-libcalls flag actually disables all builtin optzns. if (DisableSimplifyLibCalls) TLI->disableAllFunctions(); Passes.add(TLI); // Add an appropriate DataLayout instance for this module. DataLayout *TD = 0; const std::string &ModuleDataLayout = M.get()->getDataLayout(); if (!ModuleDataLayout.empty()) TD = new DataLayout(ModuleDataLayout); else if (!DefaultDataLayout.empty()) TD = new DataLayout(DefaultDataLayout); if (TD) Passes.add(TD); Triple ModuleTriple(M->getTargetTriple()); TargetMachine *Machine = 0; if (ModuleTriple.getArch()) Machine = GetTargetMachine(Triple(ModuleTriple)); OwningPtr<TargetMachine> TM(Machine); // Add internal analysis passes from the target machine. if (TM.get()) TM->addAnalysisPasses(Passes); OwningPtr<FunctionPassManager> FPasses; if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { FPasses.reset(new FunctionPassManager(M.get())); if (TD) FPasses->add(new DataLayout(*TD)); } if (PrintBreakpoints) { // Default to standard output. if (!Out) { if (OutputFilename.empty()) OutputFilename = "-"; std::string ErrorInfo; Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, raw_fd_ostream::F_Binary)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; } } Passes.add(new BreakpointPrinter(Out->os())); NoOutput = true; } // If the -strip-debug command line option was specified, add it. If // -std-compile-opts was also specified, it will handle StripDebug. if (StripDebug && !StandardCompileOpts) addPass(Passes, createStripSymbolsPass(true)); // Create a new optimization pass for each one specified on the command line for (unsigned i = 0; i < PassList.size(); ++i) { // Check to see if -std-compile-opts was specified before this option. If // so, handle it. if (StandardCompileOpts && StandardCompileOpts.getPosition() < PassList.getPosition(i)) { AddStandardCompilePasses(Passes); StandardCompileOpts = false; } if (StandardLinkOpts && StandardLinkOpts.getPosition() < PassList.getPosition(i)) { AddStandardLinkPasses(Passes); StandardLinkOpts = false; } if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 1, 0); OptLevelO1 = false; } if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 2, 0); OptLevelO2 = false; } if (OptLevelOs && OptLevelOs.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 2, 1); OptLevelOs = false; } if (OptLevelOz && OptLevelOz.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 2, 2); OptLevelOz = false; } if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 3, 0); OptLevelO3 = false; } // @LOCALMOD-BEGIN if (PNaClABISimplifyPreOpt && PNaClABISimplifyPreOpt.getPosition() < PassList.getPosition(i)) { PNaClABISimplifyAddPreOptPasses(Passes); PNaClABISimplifyPreOpt = false; } if (PNaClABISimplifyPostOpt && PNaClABISimplifyPostOpt.getPosition() < PassList.getPosition(i)) { PNaClABISimplifyAddPostOptPasses(Passes); PNaClABISimplifyPostOpt = false; } // @LOCALMOD-END const PassInfo *PassInf = PassList[i]; Pass *P = 0; if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); else errs() << argv[0] << ": cannot create pass: "******"\n"; if (P) { PassKind Kind = P->getPassKind(); addPass(Passes, P); if (AnalyzeOnly) { switch (Kind) { case PT_BasicBlock: Passes.add(new BasicBlockPassPrinter(PassInf, Out->os())); break; case PT_Region: Passes.add(new RegionPassPrinter(PassInf, Out->os())); break; case PT_Loop: Passes.add(new LoopPassPrinter(PassInf, Out->os())); break; case PT_Function: Passes.add(new FunctionPassPrinter(PassInf, Out->os())); break; case PT_CallGraphSCC: Passes.add(new CallGraphSCCPassPrinter(PassInf, Out->os())); break; default: Passes.add(new ModulePassPrinter(PassInf, Out->os())); break; } } } if (PrintEachXForm) Passes.add(createPrintModulePass(&errs())); } // If -std-compile-opts was specified at the end of the pass list, add them. if (StandardCompileOpts) { AddStandardCompilePasses(Passes); StandardCompileOpts = false; } if (StandardLinkOpts) { AddStandardLinkPasses(Passes); StandardLinkOpts = false; } if (OptLevelO1) AddOptimizationPasses(Passes, *FPasses, 1, 0); if (OptLevelO2) AddOptimizationPasses(Passes, *FPasses, 2, 0); if (OptLevelOs) AddOptimizationPasses(Passes, *FPasses, 2, 1); if (OptLevelOz) AddOptimizationPasses(Passes, *FPasses, 2, 2); if (OptLevelO3) AddOptimizationPasses(Passes, *FPasses, 3, 0); if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { FPasses->doInitialization(); for (Module::iterator F = M->begin(), E = M->end(); F != E; ++F) FPasses->run(*F); FPasses->doFinalization(); } // @LOCALMOD-BEGIN if (PNaClABISimplifyPreOpt) PNaClABISimplifyAddPreOptPasses(Passes); if (PNaClABISimplifyPostOpt) PNaClABISimplifyAddPostOptPasses(Passes); // @LOCALMOD-END // Check that the module is well formed on completion of optimization if (!NoVerify && !VerifyEach) Passes.add(createVerifierPass()); // Write bitcode or assembly to the output as the last step... if (!NoOutput && !AnalyzeOnly) { if (OutputAssembly) Passes.add(createPrintModulePass(&Out->os())); // @LOCALMOD } // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); // Now that we have all of the passes ready, run them. Passes.run(*M.get()); // @LOCALMOD-BEGIN // Write bitcode to the output. if (!NoOutput && !AnalyzeOnly && !OutputAssembly) { switch (OutputFileFormat) { case LLVMFormat: WriteBitcodeToFile(M.get(), Out->os()); break; case PNaClFormat: NaClWriteBitcodeToFile(M.get(), Out->os()); break; default: errs() << "Don't understand bitcode format for generated bitcode.\n"; return 1; } } // @LOCALMOD-END // Declare success. if (!NoOutput || PrintBreakpoints) Out->keep(); return 0; }
bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out, CodeGenFileType FileType, bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter) { // Add common CodeGen passes. MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify, StartAfter, StopAfter); if (!Context) return true; if (StopAfter) { // FIXME: The intent is that this should eventually write out a YAML file, // containing the LLVM IR, the machine-level IR (when stopping after a // machine-level pass), and whatever other information is needed to // deserialize the code and resume compilation. For now, just write the // LLVM IR. PM.add(createPrintModulePass(&Out)); return false; } if (hasMCSaveTempLabels()) Context->setAllowTemporaryLabels(false); const MCAsmInfo &MAI = *getMCAsmInfo(); const MCRegisterInfo &MRI = *getRegisterInfo(); const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>(); OwningPtr<MCStreamer> AsmStreamer; switch (FileType) { case CGFT_AssemblyFile: { MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI, *getInstrInfo(), Context->getRegisterInfo(), STI); // Create a code emitter if asked to show the encoding. MCCodeEmitter *MCE = 0; MCAsmBackend *MAB = 0; if (ShowMCEncoding) { const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>(); MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), MRI, STI, *Context); MAB = getTarget().createMCAsmBackend(getTargetTriple(), TargetCPU); } MCStreamer *S = getTarget().createAsmStreamer(*Context, Out, getVerboseAsm(), hasMCUseLoc(), hasMCUseCFI(), hasMCUseDwarfDirectory(), InstPrinter, MCE, MAB, ShowMCInst); AsmStreamer.reset(S); break; } case CGFT_ObjectFile: { // Create the code emitter for the target if it exists. If not, .o file // emission fails. MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), MRI, STI, *Context); MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple(), TargetCPU); if (MCE == 0 || MAB == 0) return true; AsmStreamer.reset(getTarget().createMCObjectStreamer(getTargetTriple(), *Context, *MAB, Out, MCE, hasMCRelaxAll(), hasMCNoExecStack())); AsmStreamer.get()->InitSections(); break; } case CGFT_Null: // The Null output is intended for use for performance analysis and testing, // not real users. AsmStreamer.reset(createNullStreamer(*Context)); break; } // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer); if (Printer == 0) return true; // If successful, createAsmPrinter took ownership of AsmStreamer. AsmStreamer.take(); PM.add(Printer); PM.add(createGCInfoDeleter()); return false; }