<commit_before>//===--- SourceManager.cpp - Track and cache source files -----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements the SourceManager interface.
//
//===----------------------------------------------------------------------===//

#include "clang/Basic/SourceManager.h"
#include "clang/Basic/SourceManagerInternals.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Path.h"
#include <algorithm>
#include <string>
#include <cstring>

using namespace clang;
using namespace SrcMgr;
using llvm::MemoryBuffer;

//===----------------------------------------------------------------------===//
// SourceManager Helper Classes
//===----------------------------------------------------------------------===//

ContentCache::~ContentCache() {
  delete Buffer.getPointer();
}

/// getSizeBytesMapped - Returns the number of bytes actually mapped for
///  this ContentCache.  This can be 0 if the MemBuffer was not actually
///  instantiated.
unsigned ContentCache::getSizeBytesMapped() const {
  return Buffer.getPointer() ? Buffer.getPointer()->getBufferSize() : 0;
}

/// getSize - Returns the size of the content encapsulated by this ContentCache.
///  This can be the size of the source file or the size of an arbitrary
///  scratch buffer.  If the ContentCache encapsulates a source file, that
///  file is not lazily brought in from disk to satisfy this query.
unsigned ContentCache::getSize() const {
  return Buffer.getPointer() ? (unsigned) Buffer.getPointer()->getBufferSize()
                             : (unsigned) Entry->getSize();
}

void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B) {
  assert(B != Buffer.getPointer());
  
  delete Buffer.getPointer();
  Buffer.setPointer(B);
  Buffer.setInt(false);
}

const llvm::MemoryBuffer *ContentCache::getBuffer(Diagnostic &Diag,
                                                  bool *Invalid) const {
  if (Invalid)
    *Invalid = false;
      
  // Lazily create the Buffer for ContentCaches that wrap files.
  if (!Buffer.getPointer() && Entry) {
    std::string ErrorStr;
    struct stat FileInfo;
    Buffer.setPointer(MemoryBuffer::getFile(Entry->getName(), &ErrorStr,
                                            Entry->getSize(), &FileInfo));
    Buffer.setInt(false);
    
    // If we were unable to open the file, then we are in an inconsistent
    // situation where the content cache referenced a file which no longer
    // exists. Most likely, we were using a stat cache with an invalid entry but
    // the file could also have been removed during processing. Since we can't
    // really deal with this situation, just create an empty buffer.
    //
    // FIXME: This is definitely not ideal, but our immediate clients can't
    // currently handle returning a null entry here. Ideally we should detect
    // that we are in an inconsistent situation and error out as quickly as
    // possible.
    if (!Buffer.getPointer()) {
      const llvm::StringRef FillStr("<<<MISSING SOURCE FILE>>>\n");
      Buffer.setPointer(MemoryBuffer::getNewMemBuffer(Entry->getSize(), 
                                                      "<invalid>"));
      char *Ptr = const_cast<char*>(Buffer.getPointer()->getBufferStart());
      for (unsigned i = 0, e = Entry->getSize(); i != e; ++i)
        Ptr[i] = FillStr[i % FillStr.size()];

      if (Diag.isDiagnosticInFlight())
        Diag.SetDelayedDiagnostic(diag::err_cannot_open_file, 
                                  Entry->getName(), ErrorStr);
      else 
        Diag.Report(diag::err_cannot_open_file)
          << Entry->getName() << ErrorStr;

      Buffer.setInt(true);
    } else if (FileInfo.st_size != Entry->getSize()
#if !defined(LLVM_ON_WIN32)
               // In our regression testing, the Windows file system
               // seems to have inconsistent modification times that
               // sometimes erroneously trigger this error-handling
               // path.
               || FileInfo.st_mtime != Entry->getModificationTime()
#endif
               ) {
      // Check that the file's size and modification time are the same
      // as in the file entry (which may have come from a stat cache).
      if (Diag.isDiagnosticInFlight())
        Diag.SetDelayedDiagnostic(diag::err_file_modified, 
                                  Entry->getName());
      else 
        Diag.Report(diag::err_file_modified) << Entry->getName();

      Buffer.setInt(true);
    }
  }
  
  if (Invalid)
    *Invalid = Buffer.getInt();
  
  return Buffer.getPointer();
}

unsigned LineTableInfo::getLineTableFilenameID(const char *Ptr, unsigned Len) {
  // Look up the filename in the string table, returning the pre-existing value
  // if it exists.
  llvm::StringMapEntry<unsigned> &Entry =
    FilenameIDs.GetOrCreateValue(Ptr, Ptr+Len, ~0U);
  if (Entry.getValue() != ~0U)
    return Entry.getValue();

  // Otherwise, assign this the next available ID.
  Entry.setValue(FilenamesByID.size());
  FilenamesByID.push_back(&Entry);
  return FilenamesByID.size()-1;
}

/// AddLineNote - Add a line note to the line table that indicates that there
/// is a #line at the specified FID/Offset location which changes the presumed
/// location to LineNo/FilenameID.
void LineTableInfo::AddLineNote(unsigned FID, unsigned Offset,<commit_msg>Disable diag::err_file_modified on Win32 completely, until someone cares to fix it. PR6812.  - This is another attempt at silencing annoying buildbot failures.<commit_after>//===--- SourceManager.cpp - Track and cache source files -----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements the SourceManager interface.
//
//===----------------------------------------------------------------------===//

#include "clang/Basic/SourceManager.h"
#include "clang/Basic/SourceManagerInternals.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Path.h"
#include <algorithm>
#include <string>
#include <cstring>

using namespace clang;
using namespace SrcMgr;
using llvm::MemoryBuffer;

//===----------------------------------------------------------------------===//
// SourceManager Helper Classes
//===----------------------------------------------------------------------===//

ContentCache::~ContentCache() {
  delete Buffer.getPointer();
}

/// getSizeBytesMapped - Returns the number of bytes actually mapped for
///  this ContentCache.  This can be 0 if the MemBuffer was not actually
///  instantiated.
unsigned ContentCache::getSizeBytesMapped() const {
  return Buffer.getPointer() ? Buffer.getPointer()->getBufferSize() : 0;
}

/// getSize - Returns the size of the content encapsulated by this ContentCache.
///  This can be the size of the source file or the size of an arbitrary
///  scratch buffer.  If the ContentCache encapsulates a source file, that
///  file is not lazily brought in from disk to satisfy this query.
unsigned ContentCache::getSize() const {
  return Buffer.getPointer() ? (unsigned) Buffer.getPointer()->getBufferSize()
                             : (unsigned) Entry->getSize();
}

void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B) {
  assert(B != Buffer.getPointer());
  
  delete Buffer.getPointer();
  Buffer.setPointer(B);
  Buffer.setInt(false);
}

const llvm::MemoryBuffer *ContentCache::getBuffer(Diagnostic &Diag,
                                                  bool *Invalid) const {
  if (Invalid)
    *Invalid = false;
      
  // Lazily create the Buffer for ContentCaches that wrap files.
  if (!Buffer.getPointer() && Entry) {
    std::string ErrorStr;
    struct stat FileInfo;
    Buffer.setPointer(MemoryBuffer::getFile(Entry->getName(), &ErrorStr,
                                            Entry->getSize(), &FileInfo));
    Buffer.setInt(false);
    
    // If we were unable to open the file, then we are in an inconsistent
    // situation where the content cache referenced a file which no longer
    // exists. Most likely, we were using a stat cache with an invalid entry but
    // the file could also have been removed during processing. Since we can't
    // really deal with this situation, just create an empty buffer.
    //
    // FIXME: This is definitely not ideal, but our immediate clients can't
    // currently handle returning a null entry here. Ideally we should detect
    // that we are in an inconsistent situation and error out as quickly as
    // possible.
    if (!Buffer.getPointer()) {
      const llvm::StringRef FillStr("<<<MISSING SOURCE FILE>>>\n");
      Buffer.setPointer(MemoryBuffer::getNewMemBuffer(Entry->getSize(), 
                                                      "<invalid>"));
      char *Ptr = const_cast<char*>(Buffer.getPointer()->getBufferStart());
      for (unsigned i = 0, e = Entry->getSize(); i != e; ++i)
        Ptr[i] = FillStr[i % FillStr.size()];

      if (Diag.isDiagnosticInFlight())
        Diag.SetDelayedDiagnostic(diag::err_cannot_open_file, 
                                  Entry->getName(), ErrorStr);
      else 
        Diag.Report(diag::err_cannot_open_file)
          << Entry->getName() << ErrorStr;

      Buffer.setInt(true);

    // FIXME: This conditionalization is horrible, but we see spurious failures
    // in the test suite due to this warning and no one has had time to hunt it
    // down. So for now, we just don't emit this diagnostic on Win32, and hope
    // nothing bad happens.
    //
    // PR6812.
#if !defined(LLVM_ON_WIN32)
    } else if (FileInfo.st_size != Entry->getSize() ||
               FileInfo.st_mtime != Entry->getModificationTime()) {
      // Check that the file's size and modification time are the same
      // as in the file entry (which may have come from a stat cache).
      if (Diag.isDiagnosticInFlight())
        Diag.SetDelayedDiagnostic(diag::err_file_modified,
                                  Entry->getName());
      else
        Diag.Report(diag::err_file_modified) << Entry->getName();

      Buffer.setInt(true);
#endif
    }
  }
  
  if (Invalid)
    *Invalid = Buffer.getInt();
  
  return Buffer.getPointer();
}

unsigned LineTableInfo::getLineTableFilenameID(const char *Ptr, unsigned Len) {
  // Look up the filename in the string table, returning the pre-existing value
  // if it exists.
  llvm::StringMapEntry<unsigned> &Entry =
    FilenameIDs.GetOrCreateValue(Ptr, Ptr+Len, ~0U);
  if (Entry.getValue() != ~0U)
    return Entry.getValue();

  // Otherwise, assign this the next available ID.
  Entry.setValue(FilenamesByID.size());
  FilenamesByID.push_back(&Entry);
  return FilenamesByID.size()-1;
}

/// AddLineNote - Add a line note to the line table that indicates that there
/// is a #line at the specified FID/Offset location which changes the presumed
/// location to LineNo/FilenameID.
void LineTableInfo::AddLineNote(unsigned FID, unsigned Offset,
{'fraction_non_alphanumeric': 0.162227602905569, 'fraction_numerical': 0.002421307506053269, 'mean_word_length': 2.3453861729823546, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3715137', 'n_tokens_mistral': 3078, 'n_tokens_neox': 3011, 'n_words': 987}