blob: 86d52a4f681180db45df21b2cfa81466057e7d63 [file] [log] [blame]
//===--- StmtSerialization.cpp - Serialization of Statements --------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Ted Kremenek and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the type-specific methods for serializing statements
// and expressions.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/Expr.h"
#include "llvm/Bitcode/Serialize.h"
#include "llvm/Bitcode/Deserialize.h"
using namespace clang;
using llvm::Serializer;
using llvm::Deserializer;
void Stmt::Emit(Serializer& S) const {
S.FlushRecord();
S.EmitInt(getStmtClass());
directEmit(S);
S.FlushRecord();
}
Stmt* Stmt::Materialize(Deserializer& D) {
StmtClass SC = static_cast<StmtClass>(D.ReadInt());
switch (SC) {
default:
assert (false && "Not implemented.");
return NULL;
case ArraySubscriptExprClass:
return ArraySubscriptExpr::directMaterialize(D);
case BinaryOperatorClass:
return BinaryOperator::directMaterialize(D);
case BreakStmtClass:
return BreakStmt::directMaterialize(D);
case CallExprClass:
return CallExpr::directMaterialize(D);
case CaseStmtClass:
return CaseStmt::directMaterialize(D);
case CastExprClass:
return CastExpr::directMaterialize(D);
case CharacterLiteralClass:
return CharacterLiteral::directMaterialize(D);
case CompoundAssignOperatorClass:
return CompoundAssignOperator::directMaterialize(D);
case CompoundStmtClass:
return CompoundStmt::directMaterialize(D);
case ContinueStmtClass:
return ContinueStmt::directMaterialize(D);
case DeclRefExprClass:
return DeclRefExpr::directMaterialize(D);
case DeclStmtClass:
return DeclStmt::directMaterialize(D);
case DefaultStmtClass:
return DefaultStmt::directMaterialize(D);
case DoStmtClass:
return DoStmt::directMaterialize(D);
case FloatingLiteralClass:
return FloatingLiteral::directMaterialize(D);
case ForStmtClass:
return ForStmt::directMaterialize(D);
case GotoStmtClass:
return GotoStmt::directMaterialize(D);
case IfStmtClass:
return IfStmt::directMaterialize(D);
case ImaginaryLiteralClass:
return ImaginaryLiteral::directMaterialize(D);
case ImplicitCastExprClass:
return ImplicitCastExpr::directMaterialize(D);
case IndirectGotoStmtClass:
return IndirectGotoStmt::directMaterialize(D);
case IntegerLiteralClass:
return IntegerLiteral::directMaterialize(D);
case LabelStmtClass:
return LabelStmt::directMaterialize(D);
case NullStmtClass:
return NullStmt::directMaterialize(D);
case ParenExprClass:
return ParenExpr::directMaterialize(D);
case PreDefinedExprClass:
return PreDefinedExpr::directMaterialize(D);
case ReturnStmtClass:
return ReturnStmt::directMaterialize(D);
case StringLiteralClass:
return StringLiteral::directMaterialize(D);
case SwitchStmtClass:
return SwitchStmt::directMaterialize(D);
case UnaryOperatorClass:
return UnaryOperator::directMaterialize(D);
case WhileStmtClass:
return WhileStmt::directMaterialize(D);
}
}
void ArraySubscriptExpr::directEmit(Serializer& S) const {
S.Emit(getType());
S.Emit(RBracketLoc);
S.BatchEmitOwnedPtrs(getLHS(),getRHS());
}
ArraySubscriptExpr* ArraySubscriptExpr::directMaterialize(Deserializer& D) {
QualType t = QualType::ReadVal(D);
SourceLocation L = SourceLocation::ReadVal(D);
Expr *LHS, *RHS;
D.BatchReadOwnedPtrs(LHS,RHS);
return new ArraySubscriptExpr(LHS,RHS,t,L);
}
void BinaryOperator::directEmit(Serializer& S) const {
S.EmitInt(Opc);
S.Emit(OpLoc);;
S.Emit(getType());
S.BatchEmitOwnedPtrs(getLHS(),getRHS());
}
BinaryOperator* BinaryOperator::directMaterialize(Deserializer& D) {
Opcode Opc = static_cast<Opcode>(D.ReadInt());
SourceLocation OpLoc = SourceLocation::ReadVal(D);
QualType Result = QualType::ReadVal(D);
Expr *LHS, *RHS;
D.BatchReadOwnedPtrs(LHS,RHS);
return new BinaryOperator(LHS,RHS,Opc,Result,OpLoc);
}
void BreakStmt::directEmit(Serializer& S) const {
S.Emit(BreakLoc);
}
BreakStmt* BreakStmt::directMaterialize(Deserializer& D) {
SourceLocation Loc = SourceLocation::ReadVal(D);
return new BreakStmt(Loc);
}
void CallExpr::directEmit(Serializer& S) const {
S.Emit(getType());
S.Emit(RParenLoc);
S.EmitInt(NumArgs);
S.BatchEmitOwnedPtrs(NumArgs+1,SubExprs);
}
CallExpr* CallExpr::directMaterialize(Deserializer& D) {
QualType t = QualType::ReadVal(D);
SourceLocation L = SourceLocation::ReadVal(D);
unsigned NumArgs = D.ReadInt();
Expr** SubExprs = new Expr*[NumArgs+1];
D.BatchReadOwnedPtrs(NumArgs+1,SubExprs);
return new CallExpr(SubExprs,NumArgs,t,L);
}
void CaseStmt::directEmit(Serializer& S) const {
S.Emit(CaseLoc);
S.EmitPtr(getNextSwitchCase());
S.BatchEmitOwnedPtrs(getLHS(),getRHS(),getSubStmt());
}
CaseStmt* CaseStmt::directMaterialize(Deserializer& D) {
SourceLocation CaseLoc = SourceLocation::ReadVal(D);
Expr *LHS, *RHS;
Stmt* SubStmt;
D.BatchReadOwnedPtrs(LHS,RHS,SubStmt);
CaseStmt* stmt = new CaseStmt(LHS,RHS,SubStmt,CaseLoc);
stmt->setNextSwitchCase(D.ReadPtr<SwitchCase>());
return stmt;
}
void CastExpr::directEmit(Serializer& S) const {
S.Emit(getType());
S.Emit(Loc);
S.EmitOwnedPtr(Op);
}
CastExpr* CastExpr::directMaterialize(Deserializer& D) {
QualType t = QualType::ReadVal(D);
SourceLocation Loc = SourceLocation::ReadVal(D);
Expr* Op = D.ReadOwnedPtr<Expr>();
return new CastExpr(t,Op,Loc);
}
void CharacterLiteral::directEmit(Serializer& S) const {
S.Emit(Value);
S.Emit(Loc);
S.Emit(getType());
}
CharacterLiteral* CharacterLiteral::directMaterialize(Deserializer& D) {
unsigned value = D.ReadInt();
SourceLocation Loc = SourceLocation::ReadVal(D);
QualType T = QualType::ReadVal(D);
return new CharacterLiteral(value,T,Loc);
}
void CompoundAssignOperator::directEmit(Serializer& S) const {
S.Emit(getType());
S.Emit(ComputationType);
S.Emit(getOperatorLoc());
S.EmitInt(getOpcode());
S.BatchEmitOwnedPtrs(getLHS(),getRHS());
}
CompoundAssignOperator*
CompoundAssignOperator::directMaterialize(Deserializer& D) {
QualType t = QualType::ReadVal(D);
QualType c = QualType::ReadVal(D);
SourceLocation L = SourceLocation::ReadVal(D);
Opcode Opc = static_cast<Opcode>(D.ReadInt());
Expr* LHS, *RHS;
D.BatchReadOwnedPtrs(LHS,RHS);
return new CompoundAssignOperator(LHS,RHS,Opc,t,c,L);
}
void CompoundStmt::directEmit(Serializer& S) const {
S.Emit(LBracLoc);
S.Emit(RBracLoc);
S.Emit(Body.size());
for (const_body_iterator I=body_begin(), E=body_end(); I!=E; ++I)
S.EmitOwnedPtr(*I);
}
CompoundStmt* CompoundStmt::directMaterialize(Deserializer& D) {
SourceLocation LB = SourceLocation::ReadVal(D);
SourceLocation RB = SourceLocation::ReadVal(D);
unsigned size = D.ReadInt();
CompoundStmt* stmt = new CompoundStmt(NULL,0,LB,RB);
stmt->Body.reserve(size);
for (unsigned i = 0; i < size; ++i)
stmt->Body.push_back(D.ReadOwnedPtr<Stmt>());
return stmt;
}
void ContinueStmt::directEmit(Serializer& S) const {
S.Emit(ContinueLoc);
}
ContinueStmt* ContinueStmt::directMaterialize(Deserializer& D) {
SourceLocation Loc = SourceLocation::ReadVal(D);
return new ContinueStmt(Loc);
}
void DeclStmt::directEmit(Serializer& S) const {
// FIXME: special handling for struct decls.
S.EmitOwnedPtr(getDecl());
}
void DeclRefExpr::directEmit(Serializer& S) const {
S.Emit(Loc);
S.Emit(getType());
S.EmitPtr(getDecl());
}
DeclRefExpr* DeclRefExpr::directMaterialize(Deserializer& D) {
SourceLocation Loc = SourceLocation::ReadVal(D);
QualType T = QualType::ReadVal(D);
DeclRefExpr* dr = new DeclRefExpr(NULL,T,Loc);
D.ReadPtr(dr->D,false);
return dr;
}
DeclStmt* DeclStmt::directMaterialize(Deserializer& D) {
ScopedDecl* decl = cast<ScopedDecl>(D.ReadOwnedPtr<Decl>());
return new DeclStmt(decl);
}
void DefaultStmt::directEmit(Serializer& S) const {
S.Emit(DefaultLoc);
S.EmitOwnedPtr(getSubStmt());
S.EmitPtr(getNextSwitchCase());
}
DefaultStmt* DefaultStmt::directMaterialize(Deserializer& D) {
SourceLocation Loc = SourceLocation::ReadVal(D);
Stmt* SubStmt = D.ReadOwnedPtr<Stmt>();
DefaultStmt* stmt = new DefaultStmt(Loc,SubStmt);
stmt->setNextSwitchCase(D.ReadPtr<SwitchCase>());
return stmt;
}
void DoStmt::directEmit(Serializer& S) const {
S.Emit(DoLoc);
S.EmitOwnedPtr(getCond());
S.EmitOwnedPtr(getBody());
}
DoStmt* DoStmt::directMaterialize(Deserializer& D) {
SourceLocation DoLoc = SourceLocation::ReadVal(D);
Expr* Cond = D.ReadOwnedPtr<Expr>();
Stmt* Body = D.ReadOwnedPtr<Stmt>();
return new DoStmt(Body,Cond,DoLoc);
}
void FloatingLiteral::directEmit(Serializer& S) const {
S.Emit(Loc);
S.Emit(getType());
S.Emit(Value);
}
FloatingLiteral* FloatingLiteral::directMaterialize(Deserializer& D) {
SourceLocation Loc = SourceLocation::ReadVal(D);
QualType t = QualType::ReadVal(D);
llvm::APFloat Val = llvm::APFloat::ReadVal(D);
FloatingLiteral* expr = new FloatingLiteral(Val,t,Loc);
return expr;
}
void ForStmt::directEmit(Serializer& S) const {
S.Emit(ForLoc);
S.EmitOwnedPtr(getInit());
S.EmitOwnedPtr(getCond());
S.EmitOwnedPtr(getInc());
S.EmitOwnedPtr(getBody());
}
ForStmt* ForStmt::directMaterialize(Deserializer& D) {
SourceLocation ForLoc = SourceLocation::ReadVal(D);
Stmt* Init = D.ReadOwnedPtr<Stmt>();
Expr* Cond = D.ReadOwnedPtr<Expr>();
Expr* Inc = D.ReadOwnedPtr<Expr>();
Stmt* Body = D.ReadOwnedPtr<Stmt>();
return new ForStmt(Init,Cond,Inc,Body,ForLoc);
}
void GotoStmt::directEmit(Serializer& S) const {
S.Emit(GotoLoc);
S.Emit(LabelLoc);
S.EmitPtr(Label);
}
GotoStmt* GotoStmt::directMaterialize(Deserializer& D) {
SourceLocation GotoLoc = SourceLocation::ReadVal(D);
SourceLocation LabelLoc = SourceLocation::ReadVal(D);
GotoStmt* stmt = new GotoStmt(NULL,GotoLoc,LabelLoc);
D.ReadPtr(stmt->Label); // This pointer may be backpatched later.
return stmt;
}
void IfStmt::directEmit(Serializer& S) const {
S.Emit(IfLoc);
S.EmitOwnedPtr(getCond());
S.EmitOwnedPtr(getThen());
S.EmitOwnedPtr(getElse());
}
IfStmt* IfStmt::directMaterialize(Deserializer& D) {
SourceLocation L = SourceLocation::ReadVal(D);
Expr* Cond = D.ReadOwnedPtr<Expr>();
Stmt* Then = D.ReadOwnedPtr<Stmt>();
Stmt* Else = D.ReadOwnedPtr<Stmt>();
return new IfStmt(L,Cond,Then,Else);
}
void ImaginaryLiteral::directEmit(Serializer& S) const {
S.Emit(getType());
S.EmitOwnedPtr(Val);
}
ImaginaryLiteral* ImaginaryLiteral::directMaterialize(Deserializer& D) {
QualType t = QualType::ReadVal(D);
Expr* expr = D.ReadOwnedPtr<Expr>();
assert (isa<FloatingLiteral>(expr) || isa<IntegerLiteral>(expr));
return new ImaginaryLiteral(expr,t);
}
void ImplicitCastExpr::directEmit(Serializer& S) const {
S.Emit(getType());
S.EmitOwnedPtr(Op);
}
ImplicitCastExpr* ImplicitCastExpr::directMaterialize(Deserializer& D) {
QualType t = QualType::ReadVal(D);
Expr* Op = D.ReadOwnedPtr<Expr>();
return new ImplicitCastExpr(t,Op);
}
void IndirectGotoStmt::directEmit(Serializer& S) const {
S.EmitPtr(Target);
}
IndirectGotoStmt* IndirectGotoStmt::directMaterialize(Deserializer& D) {
IndirectGotoStmt* stmt = new IndirectGotoStmt(NULL);
D.ReadPtr(stmt->Target); // The target may be backpatched.
return stmt;
}
void IntegerLiteral::directEmit(Serializer& S) const {
S.Emit(Loc);
S.Emit(getType());
S.Emit(getValue());
}
IntegerLiteral* IntegerLiteral::directMaterialize(Deserializer& D) {
SourceLocation Loc = SourceLocation::ReadVal(D);
QualType T = QualType::ReadVal(D);
// Create a dummy APInt because it is more efficient to deserialize
// it in place with the deserialized IntegerLiteral. (fewer copies)
llvm::APInt temp;
IntegerLiteral* expr = new IntegerLiteral(temp,T,Loc);
D.Read(expr->Value);
return expr;
}
void LabelStmt::directEmit(Serializer& S) const {
S.EmitPtr(Label);
S.Emit(IdentLoc);
S.EmitOwnedPtr(SubStmt);
}
LabelStmt* LabelStmt::directMaterialize(Deserializer& D) {
IdentifierInfo* Label = D.ReadPtr<IdentifierInfo>();
SourceLocation IdentLoc = SourceLocation::ReadVal(D);
Stmt* SubStmt = D.ReadOwnedPtr<Stmt>();
return new LabelStmt(IdentLoc,Label,SubStmt);
}
void NullStmt::directEmit(Serializer& S) const {
S.Emit(SemiLoc);
}
NullStmt* NullStmt::directMaterialize(Deserializer& D) {
SourceLocation SemiLoc = SourceLocation::ReadVal(D);
return new NullStmt(SemiLoc);
}
void ParenExpr::directEmit(Serializer& S) const {
S.Emit(L);
S.Emit(R);
S.EmitOwnedPtr(Val);
}
ParenExpr* ParenExpr::directMaterialize(Deserializer& D) {
SourceLocation L = SourceLocation::ReadVal(D);
SourceLocation R = SourceLocation::ReadVal(D);
Expr* val = D.ReadOwnedPtr<Expr>();
return new ParenExpr(L,R,val);
}
void PreDefinedExpr::directEmit(Serializer& S) const {
S.Emit(Loc);
S.EmitInt(getIdentType());
S.Emit(getType());
}
PreDefinedExpr* PreDefinedExpr::directMaterialize(Deserializer& D) {
SourceLocation Loc = SourceLocation::ReadVal(D);
IdentType it = static_cast<IdentType>(D.ReadInt());
QualType Q = QualType::ReadVal(D);
return new PreDefinedExpr(Loc,Q,it);
}
void ReturnStmt::directEmit(Serializer& S) const {
S.Emit(RetLoc);
S.EmitOwnedPtr(RetExpr);
}
ReturnStmt* ReturnStmt::directMaterialize(Deserializer& D) {
SourceLocation RetLoc = SourceLocation::ReadVal(D);
Expr* RetExpr = D.ReadOwnedPtr<Expr>();
return new ReturnStmt(RetLoc,RetExpr);
}
void StringLiteral::directEmit(Serializer& S) const {
S.Emit(getType());
S.Emit(firstTokLoc);
S.Emit(lastTokLoc);
S.EmitBool(isWide());
S.Emit(getByteLength());
for (unsigned i = 0 ; i < ByteLength; ++i)
S.EmitInt(StrData[i]);
}
StringLiteral* StringLiteral::directMaterialize(Deserializer& D) {
QualType t = QualType::ReadVal(D);
SourceLocation firstTokLoc = SourceLocation::ReadVal(D);
SourceLocation lastTokLoc = SourceLocation::ReadVal(D);
bool isWide = D.ReadBool();
unsigned ByteLength = D.ReadInt();
StringLiteral* sl = new StringLiteral(NULL,0,isWide,t,firstTokLoc,lastTokLoc);
char* StrData = new char[ByteLength];
for (unsigned i = 0; i < ByteLength; ++i)
StrData[i] = (char) D.ReadInt();
sl->ByteLength = ByteLength;
sl->StrData = StrData;
return sl;
}
void SwitchStmt::directEmit(Serializer& S) const {
S.Emit(SwitchLoc);
S.EmitOwnedPtr(getCond());
S.EmitOwnedPtr(getBody());
S.EmitPtr(FirstCase);
}
SwitchStmt* SwitchStmt::directMaterialize(Deserializer& D) {
SourceLocation Loc = SourceLocation::ReadVal(D);
Stmt* Cond = D.ReadOwnedPtr<Stmt>();
Stmt* Body = D.ReadOwnedPtr<Stmt>();
SwitchCase* FirstCase = cast<SwitchCase>(D.ReadPtr<Stmt>());
SwitchStmt* stmt = new SwitchStmt(cast<Expr>(Cond));
stmt->setBody(Body,Loc);
stmt->FirstCase = FirstCase;
return stmt;
}
void UnaryOperator::directEmit(Serializer& S) const {
S.Emit(getType());
S.Emit(Loc);
S.EmitInt(Opc);
S.EmitOwnedPtr(Val);
}
UnaryOperator* UnaryOperator::directMaterialize(Deserializer& D) {
QualType t = QualType::ReadVal(D);
SourceLocation L = SourceLocation::ReadVal(D);
Opcode Opc = static_cast<Opcode>(D.ReadInt());
Expr* Val = D.ReadOwnedPtr<Expr>();
return new UnaryOperator(Val,Opc,t,L);
}
void WhileStmt::directEmit(Serializer& S) const {
S.Emit(WhileLoc);
S.EmitOwnedPtr(getCond());
S.EmitOwnedPtr(getBody());
}
WhileStmt* WhileStmt::directMaterialize(Deserializer& D) {
SourceLocation WhileLoc = SourceLocation::ReadVal(D);
Expr* Cond = D.ReadOwnedPtr<Expr>();
Stmt* Body = D.ReadOwnedPtr<Stmt>();
return new WhileStmt(Cond,Body,WhileLoc);
}