forked from OSchip/llvm-project
464 lines
14 KiB
C++
464 lines
14 KiB
C++
//===--- 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/Decl.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);
|
|
}
|
|
|
|
Decl* Decl::Create(Deserializer& D) {
|
|
|
|
Kind k = static_cast<Kind>(D.ReadInt());
|
|
|
|
switch (k) {
|
|
default:
|
|
assert (false && "Not implemented.");
|
|
break;
|
|
|
|
case BlockVar:
|
|
return BlockVarDecl::CreateImpl(D);
|
|
|
|
case Enum:
|
|
return EnumDecl::CreateImpl(D);
|
|
|
|
case EnumConstant:
|
|
return EnumConstantDecl::CreateImpl(D);
|
|
|
|
case Field:
|
|
return FieldDecl::CreateImpl(D);
|
|
|
|
case FileVar:
|
|
return FileVarDecl::CreateImpl(D);
|
|
|
|
case ParmVar:
|
|
return ParmVarDecl::CreateImpl(D);
|
|
|
|
case Function:
|
|
return FunctionDecl::CreateImpl(D);
|
|
|
|
case Union:
|
|
case Struct:
|
|
return RecordDecl::CreateImpl(k,D);
|
|
|
|
case Typedef:
|
|
return TypedefDecl::CreateImpl(D);
|
|
|
|
case FileScopeAsm:
|
|
return FileScopeAsmDecl::CreateImpl(D);
|
|
}
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Common serialization logic for subclasses of Decl.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void Decl::EmitInRec(Serializer& S) const {
|
|
S.Emit(getLocation()); // From Decl.
|
|
}
|
|
|
|
void Decl::ReadInRec(Deserializer& D) {
|
|
Loc = SourceLocation::ReadVal(D); // From Decl.
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Common serialization logic for subclasses of NamedDecl.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void NamedDecl::EmitInRec(Serializer& S) const {
|
|
Decl::EmitInRec(S);
|
|
S.EmitPtr(getIdentifier()); // From NamedDecl.
|
|
}
|
|
|
|
void NamedDecl::ReadInRec(Deserializer& D) {
|
|
Decl::ReadInRec(D);
|
|
D.ReadPtr(Identifier); // From NamedDecl.
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Common serialization logic for subclasses of ScopedDecl.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ScopedDecl::EmitInRec(Serializer& S) const {
|
|
NamedDecl::EmitInRec(S);
|
|
S.EmitPtr(getNext()); // From ScopedDecl.
|
|
}
|
|
|
|
void ScopedDecl::ReadInRec(Deserializer& D) {
|
|
NamedDecl::ReadInRec(D);
|
|
D.ReadPtr(Next); // From ScopedDecl.
|
|
}
|
|
|
|
//===------------------------------------------------------------===//
|
|
// NOTE: Not all subclasses of ScopedDecl will use the "OutRec" //
|
|
// methods. This is because owned pointers are usually "batched" //
|
|
// together for efficiency. //
|
|
//===------------------------------------------------------------===//
|
|
|
|
void ScopedDecl::EmitOutRec(Serializer& S) const {
|
|
S.EmitOwnedPtr(getNextDeclarator()); // From ScopedDecl.
|
|
}
|
|
|
|
void ScopedDecl::ReadOutRec(Deserializer& D) {
|
|
NextDeclarator =
|
|
cast_or_null<ScopedDecl>(D.ReadOwnedPtr<Decl>()); // From ScopedDecl.
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Common serialization logic for subclasses of ValueDecl.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ValueDecl::EmitInRec(Serializer& S) const {
|
|
ScopedDecl::EmitInRec(S);
|
|
S.Emit(getType()); // From ValueDecl.
|
|
}
|
|
|
|
void ValueDecl::ReadInRec(Deserializer& D) {
|
|
ScopedDecl::ReadInRec(D);
|
|
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.
|
|
}
|
|
|
|
void VarDecl::ReadInRec(Deserializer& D) {
|
|
ValueDecl::ReadInRec(D);
|
|
SClass = static_cast<StorageClass>(D.ReadInt()); // From VarDecl.
|
|
}
|
|
|
|
//===------------------------------------------------------------===//
|
|
// NOTE: VarDecl has its own "OutRec" methods that doesn't use //
|
|
// the one define in ScopedDecl. This is to batch emit the //
|
|
// owned pointers, which results in a smaller output.
|
|
//===------------------------------------------------------------===//
|
|
|
|
void VarDecl::EmitOutRec(Serializer& S) const {
|
|
// Emit these last because they will create records of their own.
|
|
S.BatchEmitOwnedPtrs(getInit(), // From VarDecl.
|
|
getNextDeclarator()); // From ScopedDecl.
|
|
}
|
|
|
|
void VarDecl::ReadOutRec(Deserializer& D) {
|
|
Decl* next_declarator;
|
|
|
|
D.BatchReadOwnedPtrs(Init, // From VarDecl.
|
|
next_declarator); // From ScopedDecl.
|
|
|
|
setNextDeclarator(cast_or_null<ScopedDecl>(next_declarator));
|
|
}
|
|
|
|
|
|
void VarDecl::EmitImpl(Serializer& S) const {
|
|
VarDecl::EmitInRec(S);
|
|
VarDecl::EmitOutRec(S);
|
|
}
|
|
|
|
void VarDecl::ReadImpl(Deserializer& D) {
|
|
ReadInRec(D);
|
|
ReadOutRec(D);
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// BlockVarDecl Serialization.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
BlockVarDecl* BlockVarDecl::CreateImpl(Deserializer& D) {
|
|
BlockVarDecl* decl =
|
|
new BlockVarDecl(SourceLocation(),NULL,QualType(),None,NULL);
|
|
|
|
decl->VarDecl::ReadImpl(D);
|
|
|
|
return decl;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// FileVarDecl Serialization.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
FileVarDecl* FileVarDecl::CreateImpl(Deserializer& D) {
|
|
FileVarDecl* decl =
|
|
new FileVarDecl(SourceLocation(),NULL,QualType(),None,NULL);
|
|
|
|
decl->VarDecl::ReadImpl(D);
|
|
|
|
return decl;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// ParmDecl Serialization.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ParmVarDecl::EmitImpl(llvm::Serializer& S) const {
|
|
VarDecl::EmitImpl(S);
|
|
S.EmitInt(getObjCDeclQualifier()); // From ParmVarDecl.
|
|
}
|
|
|
|
ParmVarDecl* ParmVarDecl::CreateImpl(Deserializer& D) {
|
|
ParmVarDecl* decl =
|
|
new ParmVarDecl(SourceLocation(),NULL,QualType(),None,NULL);
|
|
|
|
decl->VarDecl::ReadImpl(D);
|
|
decl->objcDeclQualifier = static_cast<ObjCDeclQualifier>(D.ReadInt());
|
|
|
|
return decl;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// EnumDecl Serialization.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void EnumDecl::EmitImpl(Serializer& S) const {
|
|
ScopedDecl::EmitInRec(S);
|
|
S.EmitBool(isDefinition());
|
|
S.Emit(IntegerType);
|
|
S.BatchEmitOwnedPtrs(ElementList,getNextDeclarator());
|
|
}
|
|
|
|
EnumDecl* EnumDecl::CreateImpl(Deserializer& D) {
|
|
EnumDecl* decl = new EnumDecl(SourceLocation(),NULL,NULL);
|
|
|
|
decl->ScopedDecl::ReadInRec(D);
|
|
decl->setDefinition(D.ReadBool());
|
|
decl->IntegerType = QualType::ReadVal(D);
|
|
|
|
Decl* next_declarator;
|
|
Decl* Elist;
|
|
|
|
D.BatchReadOwnedPtrs(Elist,next_declarator);
|
|
|
|
decl->ElementList = cast_or_null<EnumConstantDecl>(Elist);
|
|
decl->setNextDeclarator(cast_or_null<ScopedDecl>(next_declarator));
|
|
|
|
return decl;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// EnumConstantDecl Serialization.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void EnumConstantDecl::EmitImpl(Serializer& S) const {
|
|
S.Emit(Val);
|
|
ValueDecl::EmitInRec(S);
|
|
S.BatchEmitOwnedPtrs(getNextDeclarator(),Init);
|
|
}
|
|
|
|
EnumConstantDecl* EnumConstantDecl::CreateImpl(Deserializer& D) {
|
|
llvm::APSInt val(1);
|
|
D.Read(val);
|
|
|
|
EnumConstantDecl* decl =
|
|
new EnumConstantDecl(SourceLocation(),NULL,QualType(),NULL,
|
|
val,NULL);
|
|
|
|
decl->ValueDecl::ReadInRec(D);
|
|
|
|
Decl* next_declarator;
|
|
|
|
D.BatchReadOwnedPtrs(next_declarator,decl->Init);
|
|
|
|
decl->setNextDeclarator(cast_or_null<ScopedDecl>(next_declarator));
|
|
|
|
return decl;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// FieldDecl Serialization.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void FieldDecl::EmitImpl(Serializer& S) const {
|
|
S.Emit(getType());
|
|
NamedDecl::EmitInRec(S);
|
|
S.EmitOwnedPtr(BitWidth);
|
|
}
|
|
|
|
FieldDecl* FieldDecl::CreateImpl(Deserializer& D) {
|
|
FieldDecl* decl = new FieldDecl(SourceLocation(),NULL,QualType());
|
|
decl->DeclType.ReadBackpatch(D);
|
|
decl->ReadInRec(D);
|
|
decl->BitWidth = D.ReadOwnedPtr<Expr>();
|
|
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(DeclChain);
|
|
|
|
// 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.BatchEmitOwnedPtrs(getNumParams(),&ParamInfo[0], Body,
|
|
getNextDeclarator());
|
|
}
|
|
else {
|
|
S.EmitBool(false);
|
|
S.BatchEmitOwnedPtrs(Body,getNextDeclarator());
|
|
}
|
|
}
|
|
|
|
FunctionDecl* FunctionDecl::CreateImpl(Deserializer& D) {
|
|
StorageClass SClass = static_cast<StorageClass>(D.ReadInt());
|
|
bool IsInline = D.ReadBool();
|
|
|
|
FunctionDecl* decl =
|
|
new FunctionDecl(SourceLocation(),NULL,QualType(),SClass,IsInline);
|
|
|
|
decl->ValueDecl::ReadInRec(D);
|
|
D.ReadPtr(decl->DeclChain);
|
|
|
|
Decl* next_declarator;
|
|
|
|
bool hasParamDecls = D.ReadBool();
|
|
|
|
decl->ParamInfo = hasParamDecls
|
|
? new ParmVarDecl*[decl->getNumParams()]
|
|
: NULL;
|
|
|
|
if (hasParamDecls)
|
|
D.BatchReadOwnedPtrs(decl->getNumParams(),
|
|
reinterpret_cast<Decl**>(&decl->ParamInfo[0]),
|
|
decl->Body, next_declarator);
|
|
else
|
|
D.BatchReadOwnedPtrs(decl->Body, next_declarator);
|
|
|
|
decl->setNextDeclarator(cast_or_null<ScopedDecl>(next_declarator));
|
|
|
|
return decl;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// RecordDecl Serialization.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void RecordDecl::EmitImpl(Serializer& S) const {
|
|
ScopedDecl::EmitInRec(S);
|
|
S.EmitBool(isDefinition());
|
|
S.EmitBool(hasFlexibleArrayMember());
|
|
S.EmitSInt(getNumMembers());
|
|
if (getNumMembers() > 0) {
|
|
assert (Members);
|
|
S.BatchEmitOwnedPtrs((unsigned) getNumMembers(),
|
|
(Decl**) &Members[0],getNextDeclarator());
|
|
}
|
|
else
|
|
ScopedDecl::EmitOutRec(S);
|
|
}
|
|
|
|
RecordDecl* RecordDecl::CreateImpl(Decl::Kind DK, Deserializer& D) {
|
|
RecordDecl* decl = new RecordDecl(DK,SourceLocation(),NULL,NULL);
|
|
|
|
decl->ScopedDecl::ReadInRec(D);
|
|
decl->setDefinition(D.ReadBool());
|
|
decl->setHasFlexibleArrayMember(D.ReadBool());
|
|
decl->NumMembers = D.ReadSInt();
|
|
|
|
if (decl->getNumMembers() > 0) {
|
|
Decl* next_declarator;
|
|
decl->Members = new FieldDecl*[(unsigned) decl->getNumMembers()];
|
|
|
|
D.BatchReadOwnedPtrs((unsigned) decl->getNumMembers(),
|
|
(Decl**) &decl->Members[0],
|
|
next_declarator);
|
|
|
|
decl->setNextDeclarator(cast_or_null<ScopedDecl>(next_declarator));
|
|
}
|
|
else
|
|
decl->ScopedDecl::ReadOutRec(D);
|
|
|
|
return decl;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// TypedefDecl Serialization.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void TypedefDecl::EmitImpl(Serializer& S) const {
|
|
S.Emit(UnderlyingType);
|
|
ScopedDecl::EmitInRec(S);
|
|
ScopedDecl::EmitOutRec(S);
|
|
}
|
|
|
|
TypedefDecl* TypedefDecl::CreateImpl(Deserializer& D) {
|
|
QualType T = QualType::ReadVal(D);
|
|
|
|
TypedefDecl* decl = new TypedefDecl(SourceLocation(),NULL,T,NULL);
|
|
|
|
decl->ScopedDecl::ReadInRec(D);
|
|
decl->ScopedDecl::ReadOutRec(D);
|
|
|
|
return decl;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// LinkageSpec Serialization.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void LinkageSpecDecl::EmitInRec(Serializer& S) const {
|
|
Decl::EmitInRec(S);
|
|
S.EmitInt(getLanguage());
|
|
S.EmitPtr(D);
|
|
}
|
|
|
|
void LinkageSpecDecl::ReadInRec(Deserializer& D) {
|
|
Decl::ReadInRec(D);
|
|
Language = static_cast<LanguageIDs>(D.ReadInt());
|
|
D.ReadPtr(this->D);
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// FileScopeAsm Serialization.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void FileScopeAsmDecl::EmitImpl(llvm::Serializer& S) const
|
|
{
|
|
Decl::EmitInRec(S);
|
|
S.EmitOwnedPtr(AsmString);
|
|
}
|
|
|
|
FileScopeAsmDecl* FileScopeAsmDecl::CreateImpl(Deserializer& D) {
|
|
FileScopeAsmDecl* decl = new FileScopeAsmDecl(SourceLocation(), 0);
|
|
|
|
decl->Decl::ReadInRec(D);
|
|
decl->AsmString = cast<StringLiteral>(D.ReadOwnedPtr<Expr>());
|
|
// D.ReadOwnedPtr(D.ReadOwnedPtr<StringLiteral>())<#T * * Ptr#>, <#bool AutoRegister#>)(decl->AsmString);
|
|
|
|
return decl;
|
|
}
|