예제 #1
0
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();
}
예제 #2
0
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;
}
예제 #3
0
/// 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;
}
예제 #5
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));
}
예제 #7
0
파일: main.cpp 프로젝트: FeifeiWang7/ECE566
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;
};
예제 #9
0
/// 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!
}
예제 #10
0
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;
}
예제 #11
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();
}
예제 #12
0
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();
}
예제 #15
0
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;
}  
예제 #16
0
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;
}
예제 #17
0
파일: cat.cpp 프로젝트: CTSRD-TESLA/TESLA
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;
}
예제 #18
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;
}
예제 #19
0
파일: ARCMT.cpp 프로젝트: CTSRD-TESLA/clang
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();
}
예제 #20
0
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;
}
예제 #21
0
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;
    }
  }
}
예제 #22
0
파일: MachODump.cpp 프로젝트: cfscosta/llvm
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
        }
      }
    }
  }
}
예제 #23
0
파일: ARCMT.cpp 프로젝트: CTSRD-TESLA/clang
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;
}
예제 #24
0
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());
      }
    }
  }
}
예제 #25
0
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;
}
예제 #26
0
파일: Indexing.cpp 프로젝트: My-Source/root
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;
}
예제 #28
0
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;
}
예제 #29
0
//===----------------------------------------------------------------------===//
// 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;
}
예제 #30
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;
}