//===--- LayoutOverrideSource.cpp --Override Record Layouts ---------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "clang/Frontend/LayoutOverrideSource.h"
#include "clang/AST/Decl.h"
#include "llvm/Support/raw_ostream.h"
#include <cctype>
#include <fstream>
#include <string>

using namespace clang;

/// \brief Parse a simple identifier.
static std::string parseName(StringRef S) {
  unsigned Offset = 0;
  while (Offset < S.size() &&
         (isalpha(S[Offset]) || S[Offset] == '_' ||
          (Offset > 0 && isdigit(S[Offset]))))
    ++Offset;
  
  return S.substr(0, Offset).str();
}

LayoutOverrideSource::LayoutOverrideSource(llvm::StringRef Filename) {
  std::ifstream Input(Filename.str().c_str());
  if (!Input.is_open())
    return;
  
  // Parse the output of -fdump-record-layouts.
  std::string CurrentType;
  Layout CurrentLayout;
  bool ExpectingType = false;
  
  while (Input.good()) {
    std::string Line;
    getline(Input, Line);
    
    StringRef LineStr(Line);

    // Determine whether the following line will start a 
    if (LineStr.find("*** Dumping AST Record Layout") != StringRef::npos)  {
      // Flush the last type/layout, if there is one.
      if (!CurrentType.empty())
        Layouts[CurrentType] = CurrentLayout;
      CurrentLayout = Layout();
      
      ExpectingType = true;
      continue;
    }
    
    // If we're expecting a type, grab it.
    if (ExpectingType) {
      ExpectingType = false;
      
      StringRef::size_type Pos;
      if ((Pos = LineStr.find("struct ")) != StringRef::npos)
        LineStr = LineStr.substr(Pos + strlen("struct "));
      else if ((Pos = LineStr.find("class ")) != StringRef::npos)
        LineStr = LineStr.substr(Pos + strlen("class "));
      else if ((Pos = LineStr.find("union ")) != StringRef::npos)
        LineStr = LineStr.substr(Pos + strlen("union "));
      else
        continue;
      
      // Find the name of the type.
      CurrentType = parseName(LineStr);
      CurrentLayout = Layout();
      continue;
    }
    
    // Check for the size of the type.
    StringRef::size_type Pos = LineStr.find(" Size:");
    if (Pos != StringRef::npos) {
      // Skip past the " Size:" prefix.
      LineStr = LineStr.substr(Pos + strlen(" Size:"));
      
      unsigned long long Size = 0;
      (void)LineStr.getAsInteger(10, Size);
      CurrentLayout.Size = Size;
      continue;
    }

    // Check for the alignment of the type.
    Pos = LineStr.find("Alignment:");
    if (Pos != StringRef::npos) {
      // Skip past the "Alignment:" prefix.
      LineStr = LineStr.substr(Pos + strlen("Alignment:"));
      
      unsigned long long Alignment = 0;
      (void)LineStr.getAsInteger(10, Alignment);
      CurrentLayout.Align = Alignment;
      continue;
    }
    
    // Check for the size/alignment of the type.
    Pos = LineStr.find("sizeof=");
    if (Pos != StringRef::npos) {
      /* Skip past the sizeof= prefix. */
      LineStr = LineStr.substr(Pos + strlen("sizeof="));

      // Parse size.
      unsigned long long Size = 0;
      (void)LineStr.getAsInteger(10, Size);
      CurrentLayout.Size = Size;

      Pos = LineStr.find("align=");
      if (Pos != StringRef::npos) {
        /* Skip past the align= prefix. */
        LineStr = LineStr.substr(Pos + strlen("align="));
        
        // Parse alignment.
        unsigned long long Alignment = 0;
        (void)LineStr.getAsInteger(10, Alignment);
        CurrentLayout.Align = Alignment;
      }
      
      continue;
    }
    
    // Check for the field offsets of the type.
    Pos = LineStr.find("FieldOffsets: [");
    if (Pos == StringRef::npos)
      continue;

    LineStr = LineStr.substr(Pos + strlen("FieldOffsets: ["));
    while (!LineStr.empty() && isdigit(LineStr[0])) {
      // Parse this offset.
      unsigned Idx = 1;
      while (Idx < LineStr.size() && isdigit(LineStr[Idx]))
        ++Idx;
      
      unsigned long long Offset = 0;
      (void)LineStr.substr(0, Idx).getAsInteger(10, Offset);
      
      CurrentLayout.FieldOffsets.push_back(Offset);
      
      // Skip over this offset, the following comma, and any spaces.
      LineStr = LineStr.substr(Idx + 1);
      while (!LineStr.empty() && isspace(LineStr[0]))
        LineStr = LineStr.substr(1);
    }
  }
  
  // Flush the last type/layout, if there is one.
  if (!CurrentType.empty())
    Layouts[CurrentType] = CurrentLayout;
}

bool 
LayoutOverrideSource::layoutRecordType(const RecordDecl *Record,
  uint64_t &Size, uint64_t &Alignment,
  llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
  llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
  llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets) 
{
  // We can't override unnamed declarations.
  if (!Record->getIdentifier())
    return false;
  
  // Check whether we have a layout for this record.
  llvm::StringMap<Layout>::iterator Known = Layouts.find(Record->getName());
  if (Known == Layouts.end())
    return false;
  
  // Provide field layouts.
  unsigned NumFields = 0;
  for (RecordDecl::field_iterator F = Record->field_begin(), 
                               FEnd = Record->field_end();
       F != FEnd; ++F, ++NumFields) {
    if (NumFields >= Known->second.FieldOffsets.size())
      continue;
    
    FieldOffsets[*F] = Known->second.FieldOffsets[NumFields];
  }
  
  // Wrong number of fields.
  if (NumFields != Known->second.FieldOffsets.size())
    return false;
  
  Size = Known->second.Size;
  Alignment = Known->second.Align;
  return true;
}

void LayoutOverrideSource::dump() {
  llvm::raw_ostream &OS = llvm::errs();
  for (llvm::StringMap<Layout>::iterator L = Layouts.begin(), 
                                      LEnd = Layouts.end();
       L != LEnd; ++L) {
    OS << "Type: blah " << L->first() << '\n';
    OS << "  Size:" << L->second.Size << '\n';
    OS << "  Alignment:" << L->second.Align << '\n';
    OS << "  FieldOffsets: [";
    for (unsigned I = 0, N = L->second.FieldOffsets.size(); I != N; ++I) {
      if (I)
        OS << ", ";
      OS << L->second.FieldOffsets[I];
    }
    OS << "]\n";
  }
}

