Ejemplo n.º 1
0
static void indexPreprocessingRecord(ASTUnit &Unit, IndexingContext &IdxCtx) {
  Preprocessor &PP = Unit.getPreprocessor();
  if (!PP.getPreprocessingRecord())
    return;

  // FIXME: Only deserialize inclusion directives.

  PreprocessingRecord::iterator I, E;
  llvm::tie(I, E) = Unit.getLocalPreprocessingEntities();

  bool isModuleFile = Unit.isModuleFile();
  for (; I != E; ++I) {
    PreprocessedEntity *PPE = *I;

    if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
      SourceLocation Loc = ID->getSourceRange().getBegin();
      // Modules have synthetic main files as input, give an invalid location
      // if the location points to such a file.
      if (isModuleFile && Unit.isInMainFileID(Loc))
        Loc = SourceLocation();
      IdxCtx.ppIncludedFile(Loc, ID->getFileName(),
                            ID->getFile(),
                            ID->getKind() == InclusionDirective::Import,
                            !ID->wasInQuotes(), ID->importedModule());
    }
  }
}
Ejemplo n.º 2
0
std::vector<ASTMemoryUsage> TranslationUnitManager::GetMemoryUsageForProjectFile(ProjectFile* file)
{
    ASTUnit* tu = GetASTUnitForProjectFile(file);
    std::vector<ASTMemoryUsage> usages;
    if (tu)
    {
        //AST Context
        ASTContext& ctx = tu->getASTContext();
        usages.emplace_back(AST_Nodes, ctx.getASTAllocatedMemory());
        usages.emplace_back(AST_Identifiers, ctx.Idents.getAllocator().getTotalMemory());
        usages.emplace_back(AST_Selectors, ctx.Selectors.getTotalMemory());
        usages.emplace_back(AST_SideTables, ctx.getSideTableAllocatedMemory());

        //Source Manager
        usages.emplace_back(SM_ContentCache, ctx.getSourceManager().getContentCacheSize());
        const SourceManager::MemoryBufferSizes& srcBufs = tu->getSourceManager().getMemoryBufferSizes();
        usages.emplace_back(SM_Malloc, srcBufs.malloc_bytes);
        usages.emplace_back(SM_Mmap, srcBufs.mmap_bytes);
        usages.emplace_back(SM_DataStructures, tu->getSourceManager().getDataStructureSizes());
        // Preprocessor
        Preprocessor& PP = tu->getPreprocessor();
        usages.emplace_back(PP_Total, PP.getTotalMemory());
        usages.emplace_back(PP_HeaderSearch, PP.getHeaderSearchInfo().getTotalMemory());
        if (PP.getPreprocessorOpts().DetailedRecord)
            usages.emplace_back(ASTMemoryUsage(PP_PreprocessingRecord, PP.getPreprocessingRecord()->getTotalMemory()));
    }
    return usages;
}
Ejemplo n.º 3
0
static void indexPreprocessingRecord(ASTUnit &Unit, IndexingContext &IdxCtx) {
  Preprocessor &PP = Unit.getPreprocessor();
  if (!PP.getPreprocessingRecord())
    return;

  // FIXME: Only deserialize inclusion directives.

  PreprocessingRecord::iterator I, E;
  llvm::tie(I, E) = Unit.getLocalPreprocessingEntities();

  for (; I != E; ++I) {
    PreprocessedEntity *PPE = *I;

    if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
      if (!ID->importedModule())
        IdxCtx.ppIncludedFile(ID->getSourceRange().getBegin(),ID->getFileName(),
                     ID->getFile(), ID->getKind() == InclusionDirective::Import,
                     !ID->wasInQuotes());
    }
  }
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
                                     llvm::StringRef Filename,
                                     bool IsAST) {
  assert(!Instance && "Already processing a source file!");
  assert(!Filename.empty() && "Unexpected empty filename!");
  setCurrentFile(Filename);
  setCompilerInstance(&CI);

  // AST files follow a very different path, since they share objects via the
  // AST unit.
  if (IsAST) {
    assert(!usesPreprocessorOnly() &&
           "Attempt to pass AST file to preprocessor only action!");
    assert(hasASTSupport() && "This action does not have AST support!");

    llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics());
    std::string Error;
    ASTUnit *AST = ASTUnit::LoadFromPCHFile(Filename, Diags);
    if (!AST)
      goto failure;

    setCurrentFile(Filename, AST);

    // 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, Filename))
      goto failure;

    /// Create the AST consumer.
    CI.setASTConsumer(CreateASTConsumer(CI, Filename));
    if (!CI.hasASTConsumer())
      goto failure;

    return true;
  }

  // Inform the diagnostic client we are processing a source file.
  CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
                                           &CI.getPreprocessor());

  // Initialize the action.
  if (!BeginSourceFileAction(CI, Filename))
    goto failure;

  /// Create the AST context and consumer unless this is a preprocessor only
  /// action.
  if (!usesPreprocessorOnly()) {
    CI.createASTContext();
    CI.setASTConsumer(CreateASTConsumer(CI, Filename));
    if (!CI.hasASTConsumer())
      goto failure;

    /// Use PCH?
    if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
      assert(hasPCHSupport() && "This action does not have PCH support!");
      CI.createPCHExternalASTSource(
        CI.getPreprocessorOpts().ImplicitPCHInclude);
      if (!CI.getASTContext().getExternalSource())
        goto failure;
    }
  }

  // Initialize builtin 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.getLangOptions().NoBuiltin);
  }

  return true;

  // If we failed, reset state since the client will not end up calling the
  // matching EndSourceFile().
  failure:
  if (isCurrentFileAST()) {
    CI.takeASTContext();
    CI.takePreprocessor();
    CI.takeSourceManager();
    CI.takeFileManager();
  }

  CI.getDiagnosticClient().EndSourceFile();
  setCurrentFile("");
  setCompilerInstance(0);
  return false;
}
Ejemplo n.º 6
0
bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
                                     llvm::StringRef Filename,
                                     InputKind InputKind) {
  assert(!Instance && "Already processing a source file!");
  assert(!Filename.empty() && "Unexpected empty filename!");
  setCurrentFile(Filename, InputKind);
  setCompilerInstance(&CI);

  if (!BeginInvocation(CI))
    goto failure;

  // AST files follow a very different path, since they share objects via the
  // AST unit.
  if (InputKind == IK_AST) {
    assert(!usesPreprocessorOnly() &&
           "Attempt to pass AST file to preprocessor only action!");
    assert(hasASTFileSupport() &&
           "This action does not have AST file support!");

    llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics());
    std::string Error;
    ASTUnit *AST = ASTUnit::LoadFromASTFile(Filename, Diags,
                                            CI.getFileSystemOpts());
    if (!AST)
      goto failure;

    setCurrentFile(Filename, InputKind, AST);

    // 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, Filename))
      goto failure;

    /// Create the AST consumer.
    CI.setASTConsumer(CreateWrappedASTConsumer(CI, Filename));
    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 (InputKind == 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);

    // Initialize the action.
    if (!BeginSourceFileAction(CI, Filename))
      goto failure;

    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());

  // Initialize the action.
  if (!BeginSourceFileAction(CI, Filename))
    goto failure;

  /// Create the AST context and consumer unless this is a preprocessor only
  /// action.
  if (!usesPreprocessorOnly()) {
    CI.createASTContext();

    llvm::OwningPtr<ASTConsumer> Consumer(
        CreateWrappedASTConsumer(CI, Filename));
    if (!Consumer)
      goto failure;

    CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());

    if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
      // Convert headers to PCH and chain them.
      llvm::OwningPtr<ExternalASTSource> source;
      source.reset(ChainedIncludesSource::create(CI));
      if (!source)
        goto failure;
      CI.getASTContext().setExternalSource(source);

    } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
      // Use PCH.
      assert(hasPCHSupport() && "This action does not have PCH support!");
      ASTDeserializationListener *DeserialListener
          = CI.getInvocation().getFrontendOpts().ChainedPCH ?
                  Consumer->GetASTDeserializationListener() : 0;
      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().DisableStatCache,
                                DeserialListener);
      if (!CI.getASTContext().getExternalSource())
        goto failure;
    }

    CI.setASTConsumer(Consumer.take());
    if (!CI.hasASTConsumer())
      goto failure;
  }

  // Initialize builtin 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.getLangOptions());
  }

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

  CI.getDiagnosticClient().EndSourceFile();
  setCurrentFile("", IK_None);
  setCompilerInstance(0);
  return false;
}