//===--- DeclSerialization.cpp - Serialization of Decls ---------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines methods that implement bitcode serialization for Decls.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "llvm/Bitcode/Serialize.h"
#include "llvm/Bitcode/Deserialize.h"

using llvm::Serializer;
using llvm::Deserializer;
using llvm::SerializedPtrID;

using namespace clang;

//===----------------------------------------------------------------------===//
// Decl Serialization: Dispatch code to handle specialized decl types.
//===----------------------------------------------------------------------===//

void Decl::Emit(Serializer& S) const {
  S.EmitInt(getKind());
  EmitImpl(S);
  S.Emit(getLocation());
  S.EmitBool(InvalidDecl);
  // FIXME: HasAttrs?
  S.EmitBool(Implicit);
  S.EmitInt(IdentifierNamespace);
  S.EmitInt(Access);
  S.EmitPtr(cast_or_null<Decl>(getDeclContext()));  // From Decl.
  S.EmitPtr(cast_or_null<Decl>(getLexicalDeclContext()));  // From Decl.
  if (const DeclContext *DC = dyn_cast<const DeclContext>(this))
    DC->EmitOutRec(S);
  
  if (getDeclContext() && 
      !getDeclContext()->isFunctionOrMethod()) {
    S.EmitBool(true);
    S.EmitOwnedPtr(NextDeclInContext);
  } else {
    S.EmitBool(false);
    S.EmitPtr(NextDeclInContext);
  }
}

Decl* Decl::Create(Deserializer& D, ASTContext& C) {

  Decl *Dcl;
  Kind k = static_cast<Kind>(D.ReadInt());

  switch (k) {
    default:
      assert (false && "Not implemented.");

    case TranslationUnit:
      Dcl = TranslationUnitDecl::CreateImpl(D, C);
      break;

    case Namespace:
      Dcl = NamespaceDecl::CreateImpl(D, C);
      break;

    case Var:
      Dcl = VarDecl::CreateImpl(D, C);
      break;
      
    case Enum:
      Dcl = EnumDecl::CreateImpl(D, C);
      break;
      
    case EnumConstant:
      Dcl = EnumConstantDecl::CreateImpl(D, C);
      break;
      
    case Field:
      Dcl = FieldDecl::CreateImpl(D, C);
      break;
      
    case ParmVar:
      Dcl = ParmVarDecl::CreateImpl(D, C);
      break;
      
    case OriginalParmVar:
      Dcl = OriginalParmVarDecl::CreateImpl(D, C);
      break;
      
    case Function:
      Dcl = FunctionDecl::CreateImpl(D, C);
      break;

    case OverloadedFunction:
      Dcl = OverloadedFunctionDecl::CreateImpl(D, C);
      break;

    case Record:
      Dcl = RecordDecl::CreateImpl(D, C);
      break;
      
    case Typedef:
      Dcl = TypedefDecl::CreateImpl(D, C);
      break;
      
    case TemplateTypeParm:
      Dcl = TemplateTypeParmDecl::CreateImpl(D, C);
      break;

    case FileScopeAsm:
      Dcl = FileScopeAsmDecl::CreateImpl(D, C);
      break;
  }

  Dcl->Loc = SourceLocation::ReadVal(D);                 // From Decl.
  Dcl->InvalidDecl = D.ReadBool();
  // FIXME: HasAttrs?
  Dcl->Implicit = D.ReadBool();
  Dcl->IdentifierNamespace = D.ReadInt();
  Dcl->Access = D.ReadInt();

  assert(Dcl->DeclCtx.getOpaqueValue() == 0);

  const SerializedPtrID &SemaDCPtrID = D.ReadPtrID();
  const SerializedPtrID &LexicalDCPtrID = D.ReadPtrID();

  if (SemaDCPtrID == LexicalDCPtrID) {
    // Allow back-patching.  Observe that we register the variable of the
    // *object* for back-patching. Its actual value will get filled in later.
    uintptr_t X;
    D.ReadUIntPtr(X, SemaDCPtrID); 
    Dcl->DeclCtx = reinterpret_cast<DeclContext*>(X);
  } else {
    MultipleDC *MDC = new MultipleDC();
    Dcl->DeclCtx = MDC;
    // Allow back-patching.  Observe that we register the variable of the
    // *object* for back-patching. Its actual value will get filled in later.
    D.ReadPtr(MDC->SemanticDC, SemaDCPtrID);
    D.ReadPtr(MDC->LexicalDC, LexicalDCPtrID);
  }
  if (DeclContext *DC = dyn_cast<DeclContext>(Dcl))
    DC->ReadOutRec(D, C);
  bool OwnsNext = D.ReadBool();
  if (OwnsNext)
    Dcl->NextDeclInContext = D.ReadOwnedPtr<Decl>(C);
  else 
    D.ReadPtr(Dcl->NextDeclInContext);
  return Dcl;
}

//===----------------------------------------------------------------------===//
//      Common serialization logic for subclasses of DeclContext.
//===----------------------------------------------------------------------===//

void DeclContext::EmitOutRec(Serializer& S) const {
  bool Owned = !isFunctionOrMethod();
  S.EmitBool(Owned);
  if (Owned)
    S.EmitOwnedPtr(FirstDecl);
  else
    S.EmitPtr(FirstDecl);
  S.EmitPtr(LastDecl);
}

void DeclContext::ReadOutRec(Deserializer& D, ASTContext& C) {
  bool Owned = D.ReadBool();
  if (Owned)
    FirstDecl = cast_or_null<Decl>(D.ReadOwnedPtr<Decl>(C));
  else
    D.ReadPtr(FirstDecl);
  D.ReadPtr(LastDecl);
}

//===----------------------------------------------------------------------===//
//      Common serialization logic for subclasses of NamedDecl.
//===----------------------------------------------------------------------===//

void NamedDecl::EmitInRec(Serializer& S) const {
  S.EmitInt(Name.getNameKind());

  switch (Name.getNameKind()) {
  case DeclarationName::Identifier:
    S.EmitPtr(Name.getAsIdentifierInfo());
    break;

  case DeclarationName::ObjCZeroArgSelector:
  case DeclarationName::ObjCOneArgSelector:
  case DeclarationName::ObjCMultiArgSelector:
    Name.getObjCSelector().Emit(S);
    break;

  case DeclarationName::CXXConstructorName:
  case DeclarationName::CXXDestructorName:
  case DeclarationName::CXXConversionFunctionName:
    Name.getCXXNameType().Emit(S);
    break;

  case DeclarationName::CXXOperatorName:
    S.EmitInt(Name.getCXXOverloadedOperator());
    break;

  case DeclarationName::CXXUsingDirective:
    // No extra data to emit
    break;
  }
}

void NamedDecl::ReadInRec(Deserializer& D, ASTContext& C) {
  DeclarationName::NameKind Kind 
    = static_cast<DeclarationName::NameKind>(D.ReadInt());
  switch (Kind) {
  case DeclarationName::Identifier: {
    // Don't allow back-patching.  The IdentifierInfo table must already
    // be loaded.
    Name = D.ReadPtr<IdentifierInfo>();
    break;
  }

  case DeclarationName::ObjCZeroArgSelector:
  case DeclarationName::ObjCOneArgSelector:
  case DeclarationName::ObjCMultiArgSelector:
    Name = Selector::ReadVal(D);
    break;

  case DeclarationName::CXXConstructorName:
    Name = C.DeclarationNames.getCXXConstructorName(QualType::ReadVal(D));
    break;
                                                    
  case DeclarationName::CXXDestructorName:
    Name = C.DeclarationNames.getCXXDestructorName(QualType::ReadVal(D));
    break;

  case DeclarationName::CXXConversionFunctionName:
    Name 
      = C.DeclarationNames.getCXXConversionFunctionName(QualType::ReadVal(D));
    break;

  case DeclarationName::CXXOperatorName: {
    OverloadedOperatorKind Op 
      = static_cast<OverloadedOperatorKind>(D.ReadInt());
    Name = C.DeclarationNames.getCXXOperatorName(Op);
    break;
  }

  case DeclarationName::CXXUsingDirective: 
    Name = DeclarationName::getUsingDirectiveName();
    break;
  }
}

//===----------------------------------------------------------------------===//
//      Common serialization logic for subclasses of ValueDecl.
//===----------------------------------------------------------------------===//

void ValueDecl::EmitInRec(Serializer& S) const {
  NamedDecl::EmitInRec(S);
  S.Emit(getType());                        // From ValueDecl.
}

void ValueDecl::ReadInRec(Deserializer& D, ASTContext& C) {
  NamedDecl::ReadInRec(D, C);
  DeclType = QualType::ReadVal(D);          // From ValueDecl.
}

//===----------------------------------------------------------------------===//
//      Common serialization logic for subclasses of VarDecl.
//===----------------------------------------------------------------------===//

void VarDecl::EmitInRec(Serializer& S) const {
  ValueDecl::EmitInRec(S);
  S.EmitInt(getStorageClass());             // From VarDecl.
  S.EmitBool(ThreadSpecified);
  S.EmitBool(HasCXXDirectInit);
  S.EmitBool(DeclaredInCondition);
  S.EmitPtr(PreviousDeclaration);
  S.Emit(TypeSpecStartLoc);
}

void VarDecl::ReadInRec(Deserializer& D, ASTContext& C) {
  ValueDecl::ReadInRec(D, C);
  SClass = static_cast<StorageClass>(D.ReadInt());  // From VarDecl. 
  ThreadSpecified = D.ReadBool();
  HasCXXDirectInit = D.ReadBool();
  DeclaredInCondition = D.ReadBool();
  D.ReadPtr(PreviousDeclaration);
  TypeSpecStartLoc = SourceLocation::ReadVal(D);
}

void VarDecl::EmitOutRec(Serializer& S) const {
  // Emit this last because it will create a record of its own.
  S.EmitOwnedPtr(getInit());
}

void VarDecl::ReadOutRec(Deserializer& D, ASTContext& C) {
  Init = D.ReadOwnedPtr<Stmt>(C);
}


void VarDecl::EmitImpl(Serializer& S) const {
  VarDecl::EmitInRec(S);
  VarDecl::EmitOutRec(S);
}

void VarDecl::ReadImpl(Deserializer& D, ASTContext& C) {
  ReadInRec(D, C);
  ReadOutRec(D, C);
}

//===----------------------------------------------------------------------===//
//      TranslationUnitDecl Serialization.
//===----------------------------------------------------------------------===//

void TranslationUnitDecl::EmitImpl(llvm::Serializer& S) const
{
}

TranslationUnitDecl* TranslationUnitDecl::CreateImpl(Deserializer& D,
                                                     ASTContext& C) {  
  return new (C) TranslationUnitDecl();
}

//===----------------------------------------------------------------------===//
//      NamespaceDecl Serialization.
//===----------------------------------------------------------------------===//

void NamespaceDecl::EmitImpl(llvm::Serializer& S) const
{
  NamedDecl::EmitInRec(S);
  S.Emit(getLBracLoc());
  S.Emit(getRBracLoc());
}

NamespaceDecl* NamespaceDecl::CreateImpl(Deserializer& D, ASTContext& C) {  
  NamespaceDecl* decl = new (C) NamespaceDecl(0, SourceLocation(), 0);
 
  decl->NamedDecl::ReadInRec(D, C);
  decl->LBracLoc = SourceLocation::ReadVal(D);
  decl->RBracLoc = SourceLocation::ReadVal(D);
  
  return decl;
}

//===----------------------------------------------------------------------===//
//      VarDecl Serialization.
//===----------------------------------------------------------------------===//

VarDecl* VarDecl::CreateImpl(Deserializer& D, ASTContext& C) {  
  VarDecl* decl =
    new (C) VarDecl(Var, 0, SourceLocation(), NULL, QualType(), None);
 
  decl->VarDecl::ReadImpl(D, C);
  return decl;
}

//===----------------------------------------------------------------------===//
//      ParmVarDecl Serialization.
//===----------------------------------------------------------------------===//

void ParmVarDecl::EmitImpl(llvm::Serializer& S) const {
  VarDecl::EmitImpl(S);
  S.EmitInt(getObjCDeclQualifier());        // From ParmVarDecl.
  S.EmitOwnedPtr(getDefaultArg());          // From ParmVarDecl.
}

ParmVarDecl* ParmVarDecl::CreateImpl(Deserializer& D, ASTContext& C) {
  ParmVarDecl* decl = new (C)
    ParmVarDecl(ParmVar,
                0, SourceLocation(), NULL, QualType(), None, NULL);
  
  decl->VarDecl::ReadImpl(D, C);
  decl->objcDeclQualifier = static_cast<ObjCDeclQualifier>(D.ReadInt());
  decl->DefaultArg = D.ReadOwnedPtr<Expr>(C);
  return decl;
}

//===----------------------------------------------------------------------===//
//      OriginalParmVarDecl Serialization.
//===----------------------------------------------------------------------===//

void OriginalParmVarDecl::EmitImpl(llvm::Serializer& S) const {
  ParmVarDecl::EmitImpl(S);
  S.Emit(OriginalType);
}

OriginalParmVarDecl* OriginalParmVarDecl::CreateImpl(
                                              Deserializer& D, ASTContext& C) {
  OriginalParmVarDecl* decl = new (C)
    OriginalParmVarDecl(0, SourceLocation(), NULL, QualType(), 
                                QualType(), None, NULL);
  
  decl->ParmVarDecl::ReadImpl(D, C);
  decl->OriginalType = QualType::ReadVal(D);
  return decl;
}
//===----------------------------------------------------------------------===//
//      EnumDecl Serialization.
//===----------------------------------------------------------------------===//

void EnumDecl::EmitImpl(Serializer& S) const {
  NamedDecl::EmitInRec(S);
  S.EmitBool(isDefinition());
  S.Emit(IntegerType);
}

EnumDecl* EnumDecl::CreateImpl(Deserializer& D, ASTContext& C) {
  EnumDecl* decl = new (C) EnumDecl(0, SourceLocation(), NULL);
  
  decl->NamedDecl::ReadInRec(D, C);
  decl->setDefinition(D.ReadBool());
  decl->IntegerType = QualType::ReadVal(D);
  
  return decl;
}

//===----------------------------------------------------------------------===//
//      EnumConstantDecl Serialization.
//===----------------------------------------------------------------------===//

void EnumConstantDecl::EmitImpl(Serializer& S) const {
  S.Emit(Val);
  ValueDecl::EmitInRec(S);
  S.EmitOwnedPtr(Init);
}
 
EnumConstantDecl* EnumConstantDecl::CreateImpl(Deserializer& D, ASTContext& C) {
  llvm::APSInt val(1);
  D.Read(val);
  
  EnumConstantDecl* decl = new (C)
    EnumConstantDecl(0, SourceLocation(), NULL, QualType(), NULL, val);
  
  decl->ValueDecl::ReadInRec(D, C);
  decl->Init = D.ReadOwnedPtr<Stmt>(C);
  return decl;    
}

//===----------------------------------------------------------------------===//
//      FieldDecl Serialization.
//===----------------------------------------------------------------------===//

void FieldDecl::EmitImpl(Serializer& S) const {
  S.EmitBool(Mutable);
  S.Emit(getType());
  ValueDecl::EmitInRec(S);
  S.EmitOwnedPtr(BitWidth);  
}

FieldDecl* FieldDecl::CreateImpl(Deserializer& D, ASTContext& C) {
  FieldDecl* decl = new (C) FieldDecl(Field, 0, SourceLocation(), NULL, 
                                        QualType(), 0, false);
  decl->Mutable = D.ReadBool();
  decl->ValueDecl::ReadInRec(D, C);
  decl->BitWidth = D.ReadOwnedPtr<Expr>(C);
  return decl;
}

//===----------------------------------------------------------------------===//
//      FunctionDecl Serialization.
//===----------------------------------------------------------------------===//

void FunctionDecl::EmitImpl(Serializer& S) const {
  S.EmitInt(SClass);           // From FunctionDecl.
  S.EmitBool(IsInline);        // From FunctionDecl.
  ValueDecl::EmitInRec(S);
  S.EmitPtr(PreviousDeclaration);
  
  // NOTE: We do not need to serialize out the number of parameters, because
  //  that is encoded in the type (accessed via getNumParams()).
  
  if (ParamInfo != NULL) {
    S.EmitBool(true);
    S.EmitInt(getNumParams());
    // FIXME:    S.BatchEmitOwnedPtrs(getNumParams(),&ParamInfo[0], Body);
  }
  else {
    S.EmitBool(false);
    // FIXME:    S.EmitOwnedPtr(Body);
  }
}

FunctionDecl* FunctionDecl::CreateImpl(Deserializer& D, ASTContext& C) {
  StorageClass SClass = static_cast<StorageClass>(D.ReadInt());
  bool IsInline = D.ReadBool();
  
  FunctionDecl* decl = new (C)
    FunctionDecl(Function, 0, SourceLocation(), DeclarationName(),
                 QualType(), SClass, IsInline);
  
  decl->ValueDecl::ReadInRec(D, C);
  D.ReadPtr(decl->PreviousDeclaration);

  int numParams = 0;
  bool hasParamDecls = D.ReadBool();
  if (hasParamDecls)
    numParams = D.ReadInt();
    
  decl->ParamInfo = hasParamDecls
                  ? new ParmVarDecl*[numParams] 
                  : NULL;  
  
  if (hasParamDecls)
    D.BatchReadOwnedPtrs(numParams,
                         reinterpret_cast<Decl**>(&decl->ParamInfo[0]),
                         /*FIXME: decl->Body,*/ C);
  else
    decl->Body = D.ReadOwnedPtr<Stmt>(C);
  
  return decl;
}

void BlockDecl::EmitImpl(Serializer& S) const {
  // FIXME: what about arguments?
  S.Emit(getCaretLocation());
  S.EmitOwnedPtr(Body);
}

BlockDecl* BlockDecl::CreateImpl(Deserializer& D, ASTContext& C) {
  QualType Q = QualType::ReadVal(D);
  SourceLocation L = SourceLocation::ReadVal(D);
  /*CompoundStmt* BodyStmt = cast<CompoundStmt>(*/D.ReadOwnedPtr<Stmt>(C)/*)*/;
  assert(0 && "Cannot deserialize BlockBlockExpr yet");
  // FIXME: need to handle parameters.
  //return new BlockBlockExpr(L, Q, BodyStmt);
  return 0;
}

//===----------------------------------------------------------------------===//
//      OverloadedFunctionDecl Serialization.
//===----------------------------------------------------------------------===//

void OverloadedFunctionDecl::EmitImpl(Serializer& S) const {
  NamedDecl::EmitInRec(S);

  S.EmitInt(getNumFunctions());
  for (unsigned func = 0; func < getNumFunctions(); ++func)
    S.EmitPtr(Functions[func]);
}

OverloadedFunctionDecl * 
OverloadedFunctionDecl::CreateImpl(Deserializer& D, ASTContext& C) {
  OverloadedFunctionDecl* decl = new (C)
    OverloadedFunctionDecl(0, DeclarationName());
  
  decl->NamedDecl::ReadInRec(D, C);

  unsigned numFunctions = D.ReadInt();
  decl->Functions.reserve(numFunctions);
  for (unsigned func = 0; func < numFunctions; ++func)
    D.ReadPtr(decl->Functions[func]);
  
  return decl;
}

//===----------------------------------------------------------------------===//
//      RecordDecl Serialization.
//===----------------------------------------------------------------------===//

void RecordDecl::EmitImpl(Serializer& S) const {
  S.EmitInt(getTagKind());

  NamedDecl::EmitInRec(S);
  S.EmitBool(isDefinition());
  S.EmitBool(hasFlexibleArrayMember());
  S.EmitBool(isAnonymousStructOrUnion());
}

RecordDecl* RecordDecl::CreateImpl(Deserializer& D, ASTContext& C) {
  TagKind TK = TagKind(D.ReadInt());

  RecordDecl* decl = new (C) RecordDecl(Record, TK, 0, SourceLocation(), NULL);
    
  decl->NamedDecl::ReadInRec(D, C);
  decl->setDefinition(D.ReadBool());
  decl->setHasFlexibleArrayMember(D.ReadBool());
  decl->setAnonymousStructOrUnion(D.ReadBool());
    
  return decl;
}

//===----------------------------------------------------------------------===//
//      TypedefDecl Serialization.
//===----------------------------------------------------------------------===//

void TypedefDecl::EmitImpl(Serializer& S) const {
  S.Emit(UnderlyingType);
  NamedDecl::EmitInRec(S);
}

TypedefDecl* TypedefDecl::CreateImpl(Deserializer& D, ASTContext& C) {
  QualType T = QualType::ReadVal(D);
  
  TypedefDecl* decl = new (C) TypedefDecl(0, SourceLocation(), NULL, T);
  
  decl->NamedDecl::ReadInRec(D, C);

  return decl;
}

//===----------------------------------------------------------------------===//
//      TemplateTypeParmDecl Serialization.
//===----------------------------------------------------------------------===//

void TemplateTypeParmDecl::EmitImpl(Serializer& S) const {
  S.EmitBool(Typename);
  TypeDecl::EmitInRec(S);
}

TemplateTypeParmDecl *
TemplateTypeParmDecl::CreateImpl(Deserializer& D, ASTContext& C) {
  bool Typename = D.ReadBool();
  TemplateTypeParmDecl *decl
    = new (C) TemplateTypeParmDecl(0, SourceLocation(), 0, Typename, 
                                   QualType());
  decl->TypeDecl::ReadInRec(D, C);
  return decl;
}

//===----------------------------------------------------------------------===//
//      NonTypeTemplateParmDecl Serialization.
//===----------------------------------------------------------------------===//
void NonTypeTemplateParmDecl::EmitImpl(Serializer& S) const {
  S.EmitInt(Depth);
  S.EmitInt(Position);
  NamedDecl::Emit(S);
}

NonTypeTemplateParmDecl*
NonTypeTemplateParmDecl::CreateImpl(Deserializer& D, ASTContext& C) {
  unsigned Depth = D.ReadInt();
  unsigned Position = D.ReadInt();
  NonTypeTemplateParmDecl *decl
    = new (C) NonTypeTemplateParmDecl(0, SourceLocation(), Depth, Position,
                                      0, QualType(), SourceLocation());
  decl->NamedDecl::ReadInRec(D, C);
  return decl;
}

//===----------------------------------------------------------------------===//
//      TemplateTemplateParmDecl Serialization.
//===----------------------------------------------------------------------===//
void TemplateTemplateParmDecl::EmitImpl(Serializer& S) const {
  S.EmitInt(Depth);
  S.EmitInt(Position);
  NamedDecl::EmitInRec(S);
}

TemplateTemplateParmDecl*
TemplateTemplateParmDecl::CreateImpl(Deserializer& D, ASTContext& C) {
  unsigned Depth = D.ReadInt();
  unsigned Position = D.ReadInt();
  TemplateTemplateParmDecl *decl
    = new (C) TemplateTemplateParmDecl(0, SourceLocation(), Depth, Position,
                                       0, 0);
  decl->NamedDecl::ReadInRec(D, C);
  return decl;
}

//===----------------------------------------------------------------------===//
//      LinkageSpec Serialization.
//===----------------------------------------------------------------------===//

void LinkageSpecDecl::EmitInRec(Serializer& S) const {
  S.EmitInt(getLanguage());
  S.EmitBool(HadBraces);
}

void LinkageSpecDecl::ReadInRec(Deserializer& D, ASTContext& C) {
  Language = static_cast<LanguageIDs>(D.ReadInt());
  HadBraces = D.ReadBool();
}

//===----------------------------------------------------------------------===//
//      FileScopeAsm Serialization.
//===----------------------------------------------------------------------===//

void FileScopeAsmDecl::EmitImpl(llvm::Serializer& S) const
{
  S.EmitOwnedPtr(AsmString);
}

FileScopeAsmDecl* FileScopeAsmDecl::CreateImpl(Deserializer& D, ASTContext& C) { 
  FileScopeAsmDecl* decl = new (C) FileScopeAsmDecl(0, SourceLocation(), 0);

  decl->AsmString = cast<StringLiteral>(D.ReadOwnedPtr<Expr>(C));
//  D.ReadOwnedPtr(D.ReadOwnedPtr<StringLiteral>())<#T * * Ptr#>, <#bool AutoRegister#>)(decl->AsmString);
  
  return decl;
}
