//===--- PCHReaderStmt.cpp - Stmt/Expr Deserialization ----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // Statement/expression deserialization. This implements the // PCHReader::ReadStmt method. // //===----------------------------------------------------------------------===// #include "clang/Frontend/PCHReader.h" #include "clang/AST/StmtVisitor.h" using namespace clang; namespace { class PCHStmtReader : public StmtVisitor { PCHReader &Reader; const PCHReader::RecordData &Record; unsigned &Idx; llvm::SmallVectorImpl &StmtStack; public: PCHStmtReader(PCHReader &Reader, const PCHReader::RecordData &Record, unsigned &Idx, llvm::SmallVectorImpl &StmtStack) : Reader(Reader), Record(Record), Idx(Idx), StmtStack(StmtStack) { } /// \brief The number of record fields required for the Stmt class /// itself. static const unsigned NumStmtFields = 0; /// \brief The number of record fields required for the Expr class /// itself. static const unsigned NumExprFields = NumStmtFields + 3; // Each of the Visit* functions reads in part of the expression // from the given record and the current expression stack, then // return the total number of operands that it read from the // expression stack. unsigned VisitStmt(Stmt *S); unsigned VisitNullStmt(NullStmt *S); unsigned VisitCompoundStmt(CompoundStmt *S); unsigned VisitSwitchCase(SwitchCase *S); unsigned VisitCaseStmt(CaseStmt *S); unsigned VisitDefaultStmt(DefaultStmt *S); unsigned VisitLabelStmt(LabelStmt *S); unsigned VisitIfStmt(IfStmt *S); unsigned VisitSwitchStmt(SwitchStmt *S); unsigned VisitWhileStmt(WhileStmt *S); unsigned VisitDoStmt(DoStmt *S); unsigned VisitForStmt(ForStmt *S); unsigned VisitGotoStmt(GotoStmt *S); unsigned VisitIndirectGotoStmt(IndirectGotoStmt *S); unsigned VisitContinueStmt(ContinueStmt *S); unsigned VisitBreakStmt(BreakStmt *S); unsigned VisitReturnStmt(ReturnStmt *S); unsigned VisitDeclStmt(DeclStmt *S); unsigned VisitAsmStmt(AsmStmt *S); unsigned VisitExpr(Expr *E); unsigned VisitPredefinedExpr(PredefinedExpr *E); unsigned VisitDeclRefExpr(DeclRefExpr *E); unsigned VisitIntegerLiteral(IntegerLiteral *E); unsigned VisitFloatingLiteral(FloatingLiteral *E); unsigned VisitImaginaryLiteral(ImaginaryLiteral *E); unsigned VisitStringLiteral(StringLiteral *E); unsigned VisitCharacterLiteral(CharacterLiteral *E); unsigned VisitParenExpr(ParenExpr *E); unsigned VisitUnaryOperator(UnaryOperator *E); unsigned VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E); unsigned VisitArraySubscriptExpr(ArraySubscriptExpr *E); unsigned VisitCallExpr(CallExpr *E); unsigned VisitMemberExpr(MemberExpr *E); unsigned VisitCastExpr(CastExpr *E); unsigned VisitBinaryOperator(BinaryOperator *E); unsigned VisitCompoundAssignOperator(CompoundAssignOperator *E); unsigned VisitConditionalOperator(ConditionalOperator *E); unsigned VisitImplicitCastExpr(ImplicitCastExpr *E); unsigned VisitExplicitCastExpr(ExplicitCastExpr *E); unsigned VisitCStyleCastExpr(CStyleCastExpr *E); unsigned VisitCompoundLiteralExpr(CompoundLiteralExpr *E); unsigned VisitExtVectorElementExpr(ExtVectorElementExpr *E); unsigned VisitInitListExpr(InitListExpr *E); unsigned VisitDesignatedInitExpr(DesignatedInitExpr *E); unsigned VisitImplicitValueInitExpr(ImplicitValueInitExpr *E); unsigned VisitVAArgExpr(VAArgExpr *E); unsigned VisitAddrLabelExpr(AddrLabelExpr *E); unsigned VisitStmtExpr(StmtExpr *E); unsigned VisitTypesCompatibleExpr(TypesCompatibleExpr *E); unsigned VisitChooseExpr(ChooseExpr *E); unsigned VisitGNUNullExpr(GNUNullExpr *E); unsigned VisitShuffleVectorExpr(ShuffleVectorExpr *E); unsigned VisitBlockExpr(BlockExpr *E); unsigned VisitBlockDeclRefExpr(BlockDeclRefExpr *E); unsigned VisitObjCStringLiteral(ObjCStringLiteral *E); unsigned VisitObjCEncodeExpr(ObjCEncodeExpr *E); unsigned VisitObjCSelectorExpr(ObjCSelectorExpr *E); unsigned VisitObjCProtocolExpr(ObjCProtocolExpr *E); unsigned VisitObjCIvarRefExpr(ObjCIvarRefExpr *E); unsigned VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E); unsigned VisitObjCKVCRefExpr(ObjCKVCRefExpr *E); unsigned VisitObjCMessageExpr(ObjCMessageExpr *E); unsigned VisitObjCSuperExpr(ObjCSuperExpr *E); unsigned VisitObjCForCollectionStmt(ObjCForCollectionStmt *); unsigned VisitObjCAtCatchStmt(ObjCAtCatchStmt *); unsigned VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *); unsigned VisitObjCAtTryStmt(ObjCAtTryStmt *); unsigned VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *); unsigned VisitObjCAtThrowStmt(ObjCAtThrowStmt *); }; } unsigned PCHStmtReader::VisitStmt(Stmt *S) { assert(Idx == NumStmtFields && "Incorrect statement field count"); return 0; } unsigned PCHStmtReader::VisitNullStmt(NullStmt *S) { VisitStmt(S); S->setSemiLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 0; } unsigned PCHStmtReader::VisitCompoundStmt(CompoundStmt *S) { VisitStmt(S); unsigned NumStmts = Record[Idx++]; S->setStmts(*Reader.getContext(), StmtStack.data() + StmtStack.size() - NumStmts, NumStmts); S->setLBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setRBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return NumStmts; } unsigned PCHStmtReader::VisitSwitchCase(SwitchCase *S) { VisitStmt(S); Reader.RecordSwitchCaseID(S, Record[Idx++]); return 0; } unsigned PCHStmtReader::VisitCaseStmt(CaseStmt *S) { VisitSwitchCase(S); S->setLHS(cast(StmtStack[StmtStack.size() - 3])); S->setRHS(cast_or_null(StmtStack[StmtStack.size() - 2])); S->setSubStmt(StmtStack.back()); S->setCaseLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setEllipsisLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setColonLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 3; } unsigned PCHStmtReader::VisitDefaultStmt(DefaultStmt *S) { VisitSwitchCase(S); S->setSubStmt(StmtStack.back()); S->setDefaultLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setColonLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 1; } unsigned PCHStmtReader::VisitLabelStmt(LabelStmt *S) { VisitStmt(S); S->setID(Reader.GetIdentifierInfo(Record, Idx)); S->setSubStmt(StmtStack.back()); S->setIdentLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); Reader.RecordLabelStmt(S, Record[Idx++]); return 1; } unsigned PCHStmtReader::VisitIfStmt(IfStmt *S) { VisitStmt(S); S->setCond(cast(StmtStack[StmtStack.size() - 3])); S->setThen(StmtStack[StmtStack.size() - 2]); S->setElse(StmtStack[StmtStack.size() - 1]); S->setIfLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setElseLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 3; } unsigned PCHStmtReader::VisitSwitchStmt(SwitchStmt *S) { VisitStmt(S); S->setCond(cast(StmtStack[StmtStack.size() - 2])); S->setBody(StmtStack.back()); S->setSwitchLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); SwitchCase *PrevSC = 0; for (unsigned N = Record.size(); Idx != N; ++Idx) { SwitchCase *SC = Reader.getSwitchCaseWithID(Record[Idx]); if (PrevSC) PrevSC->setNextSwitchCase(SC); else S->setSwitchCaseList(SC); PrevSC = SC; } return 2; } unsigned PCHStmtReader::VisitWhileStmt(WhileStmt *S) { VisitStmt(S); S->setCond(cast_or_null(StmtStack[StmtStack.size() - 2])); S->setBody(StmtStack.back()); S->setWhileLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 2; } unsigned PCHStmtReader::VisitDoStmt(DoStmt *S) { VisitStmt(S); S->setCond(cast_or_null(StmtStack[StmtStack.size() - 2])); S->setBody(StmtStack.back()); S->setDoLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setWhileLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 2; } unsigned PCHStmtReader::VisitForStmt(ForStmt *S) { VisitStmt(S); S->setInit(StmtStack[StmtStack.size() - 4]); S->setCond(cast_or_null(StmtStack[StmtStack.size() - 3])); S->setInc(cast_or_null(StmtStack[StmtStack.size() - 2])); S->setBody(StmtStack.back()); S->setForLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 4; } unsigned PCHStmtReader::VisitGotoStmt(GotoStmt *S) { VisitStmt(S); Reader.SetLabelOf(S, Record[Idx++]); S->setGotoLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setLabelLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 0; } unsigned PCHStmtReader::VisitIndirectGotoStmt(IndirectGotoStmt *S) { VisitStmt(S); S->setGotoLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setTarget(cast_or_null(StmtStack.back())); return 1; } unsigned PCHStmtReader::VisitContinueStmt(ContinueStmt *S) { VisitStmt(S); S->setContinueLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 0; } unsigned PCHStmtReader::VisitBreakStmt(BreakStmt *S) { VisitStmt(S); S->setBreakLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 0; } unsigned PCHStmtReader::VisitReturnStmt(ReturnStmt *S) { VisitStmt(S); S->setRetValue(cast_or_null(StmtStack.back())); S->setReturnLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 1; } unsigned PCHStmtReader::VisitDeclStmt(DeclStmt *S) { VisitStmt(S); S->setStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setEndLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); if (Idx + 1 == Record.size()) { // Single declaration S->setDeclGroup(DeclGroupRef(Reader.GetDecl(Record[Idx++]))); } else { llvm::SmallVector Decls; Decls.reserve(Record.size() - Idx); for (unsigned N = Record.size(); Idx != N; ++Idx) Decls.push_back(Reader.GetDecl(Record[Idx])); S->setDeclGroup(DeclGroupRef(DeclGroup::Create(*Reader.getContext(), Decls.data(), Decls.size()))); } return 0; } unsigned PCHStmtReader::VisitAsmStmt(AsmStmt *S) { VisitStmt(S); unsigned NumOutputs = Record[Idx++]; unsigned NumInputs = Record[Idx++]; unsigned NumClobbers = Record[Idx++]; S->setAsmLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setVolatile(Record[Idx++]); S->setSimple(Record[Idx++]); unsigned StackIdx = StmtStack.size() - (NumOutputs*2 + NumInputs*2 + NumClobbers + 1); S->setAsmString(cast_or_null(StmtStack[StackIdx++])); // Outputs and inputs llvm::SmallVector Names; llvm::SmallVector Constraints; llvm::SmallVector Exprs; for (unsigned I = 0, N = NumOutputs + NumInputs; I != N; ++I) { Names.push_back(Reader.ReadString(Record, Idx)); Constraints.push_back(cast_or_null(StmtStack[StackIdx++])); Exprs.push_back(StmtStack[StackIdx++]); } S->setOutputsAndInputs(NumOutputs, NumInputs, Names.data(), Constraints.data(), Exprs.data()); // Constraints llvm::SmallVector Clobbers; for (unsigned I = 0; I != NumClobbers; ++I) Clobbers.push_back(cast_or_null(StmtStack[StackIdx++])); S->setClobbers(Clobbers.data(), NumClobbers); assert(StackIdx == StmtStack.size() && "Error deserializing AsmStmt"); return NumOutputs*2 + NumInputs*2 + NumClobbers + 1; } unsigned PCHStmtReader::VisitExpr(Expr *E) { VisitStmt(E); E->setType(Reader.GetType(Record[Idx++])); E->setTypeDependent(Record[Idx++]); E->setValueDependent(Record[Idx++]); assert(Idx == NumExprFields && "Incorrect expression field count"); return 0; } unsigned PCHStmtReader::VisitPredefinedExpr(PredefinedExpr *E) { VisitExpr(E); E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setIdentType((PredefinedExpr::IdentType)Record[Idx++]); return 0; } unsigned PCHStmtReader::VisitDeclRefExpr(DeclRefExpr *E) { VisitExpr(E); E->setDecl(cast(Reader.GetDecl(Record[Idx++]))); E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); return 0; } unsigned PCHStmtReader::VisitIntegerLiteral(IntegerLiteral *E) { VisitExpr(E); E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setValue(Reader.ReadAPInt(Record, Idx)); return 0; } unsigned PCHStmtReader::VisitFloatingLiteral(FloatingLiteral *E) { VisitExpr(E); E->setValue(Reader.ReadAPFloat(Record, Idx)); E->setExact(Record[Idx++]); E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); return 0; } unsigned PCHStmtReader::VisitImaginaryLiteral(ImaginaryLiteral *E) { VisitExpr(E); E->setSubExpr(cast(StmtStack.back())); return 1; } unsigned PCHStmtReader::VisitStringLiteral(StringLiteral *E) { VisitExpr(E); unsigned Len = Record[Idx++]; assert(Record[Idx] == E->getNumConcatenated() && "Wrong number of concatenated tokens!"); ++Idx; E->setWide(Record[Idx++]); // Read string data llvm::SmallVector Str(&Record[Idx], &Record[Idx] + Len); E->setStrData(*Reader.getContext(), Str.data(), Len); Idx += Len; // Read source locations for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I) E->setStrTokenLoc(I, SourceLocation::getFromRawEncoding(Record[Idx++])); return 0; } unsigned PCHStmtReader::VisitCharacterLiteral(CharacterLiteral *E) { VisitExpr(E); E->setValue(Record[Idx++]); E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setWide(Record[Idx++]); return 0; } unsigned PCHStmtReader::VisitParenExpr(ParenExpr *E) { VisitExpr(E); E->setLParen(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setRParen(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setSubExpr(cast(StmtStack.back())); return 1; } unsigned PCHStmtReader::VisitUnaryOperator(UnaryOperator *E) { VisitExpr(E); E->setSubExpr(cast(StmtStack.back())); E->setOpcode((UnaryOperator::Opcode)Record[Idx++]); E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 1; } unsigned PCHStmtReader::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { VisitExpr(E); E->setSizeof(Record[Idx++]); if (Record[Idx] == 0) { E->setArgument(cast(StmtStack.back())); ++Idx; } else { E->setArgument(Reader.GetType(Record[Idx++])); } E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return E->isArgumentType()? 0 : 1; } unsigned PCHStmtReader::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { VisitExpr(E); E->setLHS(cast(StmtStack[StmtStack.size() - 2])); E->setRHS(cast(StmtStack[StmtStack.size() - 1])); E->setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 2; } unsigned PCHStmtReader::VisitCallExpr(CallExpr *E) { VisitExpr(E); E->setNumArgs(*Reader.getContext(), Record[Idx++]); E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setCallee(cast(StmtStack[StmtStack.size() - E->getNumArgs() - 1])); for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) E->setArg(I, cast(StmtStack[StmtStack.size() - N + I])); return E->getNumArgs() + 1; } unsigned PCHStmtReader::VisitMemberExpr(MemberExpr *E) { VisitExpr(E); E->setBase(cast(StmtStack.back())); E->setMemberDecl(cast(Reader.GetDecl(Record[Idx++]))); E->setMemberLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setArrow(Record[Idx++]); return 1; } unsigned PCHStmtReader::VisitCastExpr(CastExpr *E) { VisitExpr(E); E->setSubExpr(cast(StmtStack.back())); return 1; } unsigned PCHStmtReader::VisitBinaryOperator(BinaryOperator *E) { VisitExpr(E); E->setLHS(cast(StmtStack.end()[-2])); E->setRHS(cast(StmtStack.end()[-1])); E->setOpcode((BinaryOperator::Opcode)Record[Idx++]); E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 2; } unsigned PCHStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator *E) { VisitBinaryOperator(E); E->setComputationLHSType(Reader.GetType(Record[Idx++])); E->setComputationResultType(Reader.GetType(Record[Idx++])); return 2; } unsigned PCHStmtReader::VisitConditionalOperator(ConditionalOperator *E) { VisitExpr(E); E->setCond(cast(StmtStack[StmtStack.size() - 3])); E->setLHS(cast_or_null(StmtStack[StmtStack.size() - 2])); E->setRHS(cast_or_null(StmtStack[StmtStack.size() - 1])); return 3; } unsigned PCHStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); E->setLvalueCast(Record[Idx++]); return 1; } unsigned PCHStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) { VisitCastExpr(E); E->setTypeAsWritten(Reader.GetType(Record[Idx++])); return 1; } unsigned PCHStmtReader::VisitCStyleCastExpr(CStyleCastExpr *E) { VisitExplicitCastExpr(E); E->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 1; } unsigned PCHStmtReader::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { VisitExpr(E); E->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setInitializer(cast(StmtStack.back())); E->setFileScope(Record[Idx++]); return 1; } unsigned PCHStmtReader::VisitExtVectorElementExpr(ExtVectorElementExpr *E) { VisitExpr(E); E->setBase(cast(StmtStack.back())); E->setAccessor(Reader.GetIdentifierInfo(Record, Idx)); E->setAccessorLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 1; } unsigned PCHStmtReader::VisitInitListExpr(InitListExpr *E) { VisitExpr(E); unsigned NumInits = Record[Idx++]; E->reserveInits(NumInits); for (unsigned I = 0; I != NumInits; ++I) E->updateInit(I, cast(StmtStack[StmtStack.size() - NumInits - 1 + I])); E->setSyntacticForm(cast_or_null(StmtStack.back())); E->setLBraceLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setRBraceLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setInitializedFieldInUnion( cast_or_null(Reader.GetDecl(Record[Idx++]))); E->sawArrayRangeDesignator(Record[Idx++]); return NumInits + 1; } unsigned PCHStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) { typedef DesignatedInitExpr::Designator Designator; VisitExpr(E); unsigned NumSubExprs = Record[Idx++]; assert(NumSubExprs == E->getNumSubExprs() && "Wrong number of subexprs"); for (unsigned I = 0; I != NumSubExprs; ++I) E->setSubExpr(I, cast(StmtStack[StmtStack.size() - NumSubExprs + I])); E->setEqualOrColonLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setGNUSyntax(Record[Idx++]); llvm::SmallVector Designators; while (Idx < Record.size()) { switch ((pch::DesignatorTypes)Record[Idx++]) { case pch::DESIG_FIELD_DECL: { FieldDecl *Field = cast(Reader.GetDecl(Record[Idx++])); SourceLocation DotLoc = SourceLocation::getFromRawEncoding(Record[Idx++]); SourceLocation FieldLoc = SourceLocation::getFromRawEncoding(Record[Idx++]); Designators.push_back(Designator(Field->getIdentifier(), DotLoc, FieldLoc)); Designators.back().setField(Field); break; } case pch::DESIG_FIELD_NAME: { const IdentifierInfo *Name = Reader.GetIdentifierInfo(Record, Idx); SourceLocation DotLoc = SourceLocation::getFromRawEncoding(Record[Idx++]); SourceLocation FieldLoc = SourceLocation::getFromRawEncoding(Record[Idx++]); Designators.push_back(Designator(Name, DotLoc, FieldLoc)); break; } case pch::DESIG_ARRAY: { unsigned Index = Record[Idx++]; SourceLocation LBracketLoc = SourceLocation::getFromRawEncoding(Record[Idx++]); SourceLocation RBracketLoc = SourceLocation::getFromRawEncoding(Record[Idx++]); Designators.push_back(Designator(Index, LBracketLoc, RBracketLoc)); break; } case pch::DESIG_ARRAY_RANGE: { unsigned Index = Record[Idx++]; SourceLocation LBracketLoc = SourceLocation::getFromRawEncoding(Record[Idx++]); SourceLocation EllipsisLoc = SourceLocation::getFromRawEncoding(Record[Idx++]); SourceLocation RBracketLoc = SourceLocation::getFromRawEncoding(Record[Idx++]); Designators.push_back(Designator(Index, LBracketLoc, EllipsisLoc, RBracketLoc)); break; } } } E->setDesignators(Designators.data(), Designators.size()); return NumSubExprs; } unsigned PCHStmtReader::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { VisitExpr(E); return 0; } unsigned PCHStmtReader::VisitVAArgExpr(VAArgExpr *E) { VisitExpr(E); E->setSubExpr(cast(StmtStack.back())); E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 1; } unsigned PCHStmtReader::VisitAddrLabelExpr(AddrLabelExpr *E) { VisitExpr(E); E->setAmpAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setLabelLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); Reader.SetLabelOf(E, Record[Idx++]); return 0; } unsigned PCHStmtReader::VisitStmtExpr(StmtExpr *E) { VisitExpr(E); E->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setSubStmt(cast_or_null(StmtStack.back())); return 1; } unsigned PCHStmtReader::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) { VisitExpr(E); E->setArgType1(Reader.GetType(Record[Idx++])); E->setArgType2(Reader.GetType(Record[Idx++])); E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 0; } unsigned PCHStmtReader::VisitChooseExpr(ChooseExpr *E) { VisitExpr(E); E->setCond(cast(StmtStack[StmtStack.size() - 3])); E->setLHS(cast_or_null(StmtStack[StmtStack.size() - 2])); E->setRHS(cast_or_null(StmtStack[StmtStack.size() - 1])); E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 3; } unsigned PCHStmtReader::VisitGNUNullExpr(GNUNullExpr *E) { VisitExpr(E); E->setTokenLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); return 0; } unsigned PCHStmtReader::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { VisitExpr(E); unsigned NumExprs = Record[Idx++]; E->setExprs((Expr **)&StmtStack[StmtStack.size() - NumExprs], NumExprs); E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return NumExprs; } unsigned PCHStmtReader::VisitBlockExpr(BlockExpr *E) { VisitExpr(E); E->setBlockDecl(cast_or_null(Reader.GetDecl(Record[Idx++]))); E->setHasBlockDeclRefExprs(Record[Idx++]); return 0; } unsigned PCHStmtReader::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { VisitExpr(E); E->setDecl(cast(Reader.GetDecl(Record[Idx++]))); E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setByRef(Record[Idx++]); return 0; } //===----------------------------------------------------------------------===// // Objective-C Expressions and Statements unsigned PCHStmtReader::VisitObjCStringLiteral(ObjCStringLiteral *E) { VisitExpr(E); E->setString(cast(StmtStack.back())); E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 1; } unsigned PCHStmtReader::VisitObjCEncodeExpr(ObjCEncodeExpr *E) { VisitExpr(E); E->setEncodedType(Reader.GetType(Record[Idx++])); E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 0; } unsigned PCHStmtReader::VisitObjCSelectorExpr(ObjCSelectorExpr *E) { VisitExpr(E); E->setSelector(Reader.GetSelector(Record, Idx)); E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 0; } unsigned PCHStmtReader::VisitObjCProtocolExpr(ObjCProtocolExpr *E) { VisitExpr(E); E->setProtocol(cast(Reader.GetDecl(Record[Idx++]))); E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 0; } unsigned PCHStmtReader::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { VisitExpr(E); E->setDecl(cast(Reader.GetDecl(Record[Idx++]))); E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setBase(cast(StmtStack.back())); E->setIsArrow(Record[Idx++]); E->setIsFreeIvar(Record[Idx++]); return 1; } unsigned PCHStmtReader::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { VisitExpr(E); E->setProperty(cast(Reader.GetDecl(Record[Idx++]))); E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setBase(cast(StmtStack.back())); return 1; } unsigned PCHStmtReader::VisitObjCKVCRefExpr(ObjCKVCRefExpr *E) { VisitExpr(E); E->setGetterMethod( cast_or_null(Reader.GetDecl(Record[Idx++]))); E->setSetterMethod( cast_or_null(Reader.GetDecl(Record[Idx++]))); E->setClassProp( cast_or_null(Reader.GetDecl(Record[Idx++]))); E->setBase(cast_or_null(StmtStack.back())); E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 1; } unsigned PCHStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) { VisitExpr(E); E->setNumArgs(Record[Idx++]); E->setLeftLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setRightLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setSelector(Reader.GetSelector(Record, Idx)); E->setMethodDecl(cast_or_null(Reader.GetDecl(Record[Idx++]))); E->setReceiver( cast_or_null(StmtStack[StmtStack.size() - E->getNumArgs() - 1])); if (!E->getReceiver()) { ObjCMessageExpr::ClassInfo CI; CI.first = cast_or_null(Reader.GetDecl(Record[Idx++])); CI.second = Reader.GetIdentifierInfo(Record, Idx); E->setClassInfo(CI); } for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) E->setArg(I, cast(StmtStack[StmtStack.size() - N + I])); return E->getNumArgs() + 1; } unsigned PCHStmtReader::VisitObjCSuperExpr(ObjCSuperExpr *E) { VisitExpr(E); E->setLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 0; } unsigned PCHStmtReader::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { VisitStmt(S); S->setElement(cast_or_null(StmtStack[StmtStack.size() - 3])); S->setCollection(cast_or_null(StmtStack[StmtStack.size() - 2])); S->setBody(cast_or_null(StmtStack[StmtStack.size() - 1])); S->setForLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 3; } unsigned PCHStmtReader::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) { VisitStmt(S); S->setCatchBody(cast_or_null(StmtStack[StmtStack.size() - 2])); S->setNextCatchStmt(cast_or_null(StmtStack[StmtStack.size() - 1])); S->setCatchParamDecl(cast_or_null(Reader.GetDecl(Record[Idx++]))); S->setAtCatchLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 2; } unsigned PCHStmtReader::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) { VisitStmt(S); S->setFinallyBody(StmtStack.back()); S->setAtFinallyLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 1; } unsigned PCHStmtReader::VisitObjCAtTryStmt(ObjCAtTryStmt *S) { VisitStmt(S); S->setTryBody(cast_or_null(StmtStack[StmtStack.size() - 3])); S->setCatchStmts(cast_or_null(StmtStack[StmtStack.size() - 2])); S->setFinallyStmt(cast_or_null(StmtStack[StmtStack.size() - 1])); S->setAtTryLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 3; } unsigned PCHStmtReader::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) { VisitStmt(S); S->setSynchExpr(cast_or_null(StmtStack[StmtStack.size() - 2])); S->setSynchBody(cast_or_null(StmtStack[StmtStack.size() - 1])); S->setAtSynchronizedLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 2; } unsigned PCHStmtReader::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) { VisitStmt(S); S->setThrowExpr(StmtStack.back()); S->setThrowLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); return 1; } // Within the bitstream, expressions are stored in Reverse Polish // Notation, with each of the subexpressions preceding the // expression they are stored in. To evaluate expressions, we // continue reading expressions and placing them on the stack, with // expressions having operands removing those operands from the // stack. Evaluation terminates when we see a STMT_STOP record, and // the single remaining expression on the stack is our result. Stmt *PCHReader::ReadStmt(llvm::BitstreamCursor &Cursor) { RecordData Record; unsigned Idx; llvm::SmallVector StmtStack; PCHStmtReader Reader(*this, Record, Idx, StmtStack); Stmt::EmptyShell Empty; while (true) { unsigned Code = Cursor.ReadCode(); if (Code == llvm::bitc::END_BLOCK) { if (Cursor.ReadBlockEnd()) { Error("error at end of block in PCH file"); return 0; } break; } if (Code == llvm::bitc::ENTER_SUBBLOCK) { // No known subblocks, always skip them. Cursor.ReadSubBlockID(); if (Cursor.SkipBlock()) { Error("malformed block record in PCH file"); return 0; } continue; } if (Code == llvm::bitc::DEFINE_ABBREV) { Cursor.ReadAbbrevRecord(); continue; } Stmt *S = 0; Idx = 0; Record.clear(); bool Finished = false; switch ((pch::StmtCode)Cursor.ReadRecord(Code, Record)) { case pch::STMT_STOP: Finished = true; break; case pch::STMT_NULL_PTR: S = 0; break; case pch::STMT_NULL: S = new (Context) NullStmt(Empty); break; case pch::STMT_COMPOUND: S = new (Context) CompoundStmt(Empty); break; case pch::STMT_CASE: S = new (Context) CaseStmt(Empty); break; case pch::STMT_DEFAULT: S = new (Context) DefaultStmt(Empty); break; case pch::STMT_LABEL: S = new (Context) LabelStmt(Empty); break; case pch::STMT_IF: S = new (Context) IfStmt(Empty); break; case pch::STMT_SWITCH: S = new (Context) SwitchStmt(Empty); break; case pch::STMT_WHILE: S = new (Context) WhileStmt(Empty); break; case pch::STMT_DO: S = new (Context) DoStmt(Empty); break; case pch::STMT_FOR: S = new (Context) ForStmt(Empty); break; case pch::STMT_GOTO: S = new (Context) GotoStmt(Empty); break; case pch::STMT_INDIRECT_GOTO: S = new (Context) IndirectGotoStmt(Empty); break; case pch::STMT_CONTINUE: S = new (Context) ContinueStmt(Empty); break; case pch::STMT_BREAK: S = new (Context) BreakStmt(Empty); break; case pch::STMT_RETURN: S = new (Context) ReturnStmt(Empty); break; case pch::STMT_DECL: S = new (Context) DeclStmt(Empty); break; case pch::STMT_ASM: S = new (Context) AsmStmt(Empty); break; case pch::EXPR_PREDEFINED: S = new (Context) PredefinedExpr(Empty); break; case pch::EXPR_DECL_REF: S = new (Context) DeclRefExpr(Empty); break; case pch::EXPR_INTEGER_LITERAL: S = new (Context) IntegerLiteral(Empty); break; case pch::EXPR_FLOATING_LITERAL: S = new (Context) FloatingLiteral(Empty); break; case pch::EXPR_IMAGINARY_LITERAL: S = new (Context) ImaginaryLiteral(Empty); break; case pch::EXPR_STRING_LITERAL: S = StringLiteral::CreateEmpty(*Context, Record[PCHStmtReader::NumExprFields + 1]); break; case pch::EXPR_CHARACTER_LITERAL: S = new (Context) CharacterLiteral(Empty); break; case pch::EXPR_PAREN: S = new (Context) ParenExpr(Empty); break; case pch::EXPR_UNARY_OPERATOR: S = new (Context) UnaryOperator(Empty); break; case pch::EXPR_SIZEOF_ALIGN_OF: S = new (Context) SizeOfAlignOfExpr(Empty); break; case pch::EXPR_ARRAY_SUBSCRIPT: S = new (Context) ArraySubscriptExpr(Empty); break; case pch::EXPR_CALL: S = new (Context) CallExpr(*Context, Empty); break; case pch::EXPR_MEMBER: S = new (Context) MemberExpr(Empty); break; case pch::EXPR_BINARY_OPERATOR: S = new (Context) BinaryOperator(Empty); break; case pch::EXPR_COMPOUND_ASSIGN_OPERATOR: S = new (Context) CompoundAssignOperator(Empty); break; case pch::EXPR_CONDITIONAL_OPERATOR: S = new (Context) ConditionalOperator(Empty); break; case pch::EXPR_IMPLICIT_CAST: S = new (Context) ImplicitCastExpr(Empty); break; case pch::EXPR_CSTYLE_CAST: S = new (Context) CStyleCastExpr(Empty); break; case pch::EXPR_COMPOUND_LITERAL: S = new (Context) CompoundLiteralExpr(Empty); break; case pch::EXPR_EXT_VECTOR_ELEMENT: S = new (Context) ExtVectorElementExpr(Empty); break; case pch::EXPR_INIT_LIST: S = new (Context) InitListExpr(Empty); break; case pch::EXPR_DESIGNATED_INIT: S = DesignatedInitExpr::CreateEmpty(*Context, Record[PCHStmtReader::NumExprFields] - 1); break; case pch::EXPR_IMPLICIT_VALUE_INIT: S = new (Context) ImplicitValueInitExpr(Empty); break; case pch::EXPR_VA_ARG: S = new (Context) VAArgExpr(Empty); break; case pch::EXPR_ADDR_LABEL: S = new (Context) AddrLabelExpr(Empty); break; case pch::EXPR_STMT: S = new (Context) StmtExpr(Empty); break; case pch::EXPR_TYPES_COMPATIBLE: S = new (Context) TypesCompatibleExpr(Empty); break; case pch::EXPR_CHOOSE: S = new (Context) ChooseExpr(Empty); break; case pch::EXPR_GNU_NULL: S = new (Context) GNUNullExpr(Empty); break; case pch::EXPR_SHUFFLE_VECTOR: S = new (Context) ShuffleVectorExpr(Empty); break; case pch::EXPR_BLOCK: S = new (Context) BlockExpr(Empty); break; case pch::EXPR_BLOCK_DECL_REF: S = new (Context) BlockDeclRefExpr(Empty); break; case pch::EXPR_OBJC_STRING_LITERAL: S = new (Context) ObjCStringLiteral(Empty); break; case pch::EXPR_OBJC_ENCODE: S = new (Context) ObjCEncodeExpr(Empty); break; case pch::EXPR_OBJC_SELECTOR_EXPR: S = new (Context) ObjCSelectorExpr(Empty); break; case pch::EXPR_OBJC_PROTOCOL_EXPR: S = new (Context) ObjCProtocolExpr(Empty); break; case pch::EXPR_OBJC_IVAR_REF_EXPR: S = new (Context) ObjCIvarRefExpr(Empty); break; case pch::EXPR_OBJC_PROPERTY_REF_EXPR: S = new (Context) ObjCPropertyRefExpr(Empty); break; case pch::EXPR_OBJC_KVC_REF_EXPR: S = new (Context) ObjCKVCRefExpr(Empty); break; case pch::EXPR_OBJC_MESSAGE_EXPR: S = new (Context) ObjCMessageExpr(Empty); break; case pch::EXPR_OBJC_SUPER_EXPR: S = new (Context) ObjCSuperExpr(Empty); break; case pch::STMT_OBJC_FOR_COLLECTION: S = new (Context) ObjCForCollectionStmt(Empty); break; case pch::STMT_OBJC_CATCH: S = new (Context) ObjCAtCatchStmt(Empty); break; case pch::STMT_OBJC_FINALLY: S = new (Context) ObjCAtFinallyStmt(Empty); break; case pch::STMT_OBJC_AT_TRY: S = new (Context) ObjCAtTryStmt(Empty); break; case pch::STMT_OBJC_AT_SYNCHRONIZED: S = new (Context) ObjCAtSynchronizedStmt(Empty); break; case pch::STMT_OBJC_AT_THROW: S = new (Context) ObjCAtThrowStmt(Empty); break; } // We hit a STMT_STOP, so we're done with this expression. if (Finished) break; ++NumStatementsRead; if (S) { unsigned NumSubStmts = Reader.Visit(S); while (NumSubStmts > 0) { StmtStack.pop_back(); --NumSubStmts; } } assert(Idx == Record.size() && "Invalid deserialization of statement"); StmtStack.push_back(S); } assert(StmtStack.size() == 1 && "Extra expressions on stack!"); SwitchCaseStmts.clear(); return StmtStack.back(); }