blob: 064c258edc8ddae825c2611833d42bc25429d3bc [file] [log] [blame]
Chris Lattner1f551822009-04-27 06:20:01 +00001//===--- PCHWriterStmt.cpp - Statement and Expression Serialization -------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements serialization for Statements and Expressions.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Frontend/PCHWriter.h"
Douglas Gregor5d3507d2009-09-09 23:08:42 +000015#include "clang/AST/DeclCXX.h"
Chris Lattner1f551822009-04-27 06:20:01 +000016#include "clang/AST/DeclObjC.h"
17#include "clang/AST/StmtVisitor.h"
18#include "llvm/Bitcode/BitstreamWriter.h"
19using namespace clang;
20
21//===----------------------------------------------------------------------===//
22// Statement/expression serialization
23//===----------------------------------------------------------------------===//
24
25namespace {
26 class PCHStmtWriter : public StmtVisitor<PCHStmtWriter, void> {
Chris Lattner1f551822009-04-27 06:20:01 +000027 PCHWriter &Writer;
28 PCHWriter::RecordData &Record;
29
30 public:
31 pch::StmtCode Code;
32
33 PCHStmtWriter(PCHWriter &Writer, PCHWriter::RecordData &Record)
34 : Writer(Writer), Record(Record) { }
35
36 void VisitStmt(Stmt *S);
37 void VisitNullStmt(NullStmt *S);
38 void VisitCompoundStmt(CompoundStmt *S);
39 void VisitSwitchCase(SwitchCase *S);
40 void VisitCaseStmt(CaseStmt *S);
41 void VisitDefaultStmt(DefaultStmt *S);
42 void VisitLabelStmt(LabelStmt *S);
43 void VisitIfStmt(IfStmt *S);
44 void VisitSwitchStmt(SwitchStmt *S);
45 void VisitWhileStmt(WhileStmt *S);
46 void VisitDoStmt(DoStmt *S);
47 void VisitForStmt(ForStmt *S);
48 void VisitGotoStmt(GotoStmt *S);
49 void VisitIndirectGotoStmt(IndirectGotoStmt *S);
50 void VisitContinueStmt(ContinueStmt *S);
51 void VisitBreakStmt(BreakStmt *S);
52 void VisitReturnStmt(ReturnStmt *S);
53 void VisitDeclStmt(DeclStmt *S);
54 void VisitAsmStmt(AsmStmt *S);
55 void VisitExpr(Expr *E);
56 void VisitPredefinedExpr(PredefinedExpr *E);
57 void VisitDeclRefExpr(DeclRefExpr *E);
58 void VisitIntegerLiteral(IntegerLiteral *E);
59 void VisitFloatingLiteral(FloatingLiteral *E);
60 void VisitImaginaryLiteral(ImaginaryLiteral *E);
61 void VisitStringLiteral(StringLiteral *E);
62 void VisitCharacterLiteral(CharacterLiteral *E);
63 void VisitParenExpr(ParenExpr *E);
64 void VisitUnaryOperator(UnaryOperator *E);
65 void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
66 void VisitArraySubscriptExpr(ArraySubscriptExpr *E);
67 void VisitCallExpr(CallExpr *E);
68 void VisitMemberExpr(MemberExpr *E);
69 void VisitCastExpr(CastExpr *E);
70 void VisitBinaryOperator(BinaryOperator *E);
71 void VisitCompoundAssignOperator(CompoundAssignOperator *E);
72 void VisitConditionalOperator(ConditionalOperator *E);
73 void VisitImplicitCastExpr(ImplicitCastExpr *E);
74 void VisitExplicitCastExpr(ExplicitCastExpr *E);
75 void VisitCStyleCastExpr(CStyleCastExpr *E);
76 void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
77 void VisitExtVectorElementExpr(ExtVectorElementExpr *E);
78 void VisitInitListExpr(InitListExpr *E);
79 void VisitDesignatedInitExpr(DesignatedInitExpr *E);
80 void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
81 void VisitVAArgExpr(VAArgExpr *E);
82 void VisitAddrLabelExpr(AddrLabelExpr *E);
83 void VisitStmtExpr(StmtExpr *E);
84 void VisitTypesCompatibleExpr(TypesCompatibleExpr *E);
85 void VisitChooseExpr(ChooseExpr *E);
86 void VisitGNUNullExpr(GNUNullExpr *E);
87 void VisitShuffleVectorExpr(ShuffleVectorExpr *E);
88 void VisitBlockExpr(BlockExpr *E);
89 void VisitBlockDeclRefExpr(BlockDeclRefExpr *E);
Mike Stump11289f42009-09-09 15:08:12 +000090
Chris Lattner1f551822009-04-27 06:20:01 +000091 // Objective-C Expressions
92 void VisitObjCStringLiteral(ObjCStringLiteral *E);
93 void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
94 void VisitObjCSelectorExpr(ObjCSelectorExpr *E);
95 void VisitObjCProtocolExpr(ObjCProtocolExpr *E);
96 void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E);
97 void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
Fariborz Jahanian9a846652009-08-20 17:02:02 +000098 void VisitObjCImplicitSetterGetterRefExpr(
99 ObjCImplicitSetterGetterRefExpr *E);
Chris Lattner1f551822009-04-27 06:20:01 +0000100 void VisitObjCMessageExpr(ObjCMessageExpr *E);
101 void VisitObjCSuperExpr(ObjCSuperExpr *E);
Steve Naroffe87026a2009-07-24 17:54:45 +0000102 void VisitObjCIsaExpr(ObjCIsaExpr *E);
Mike Stump11289f42009-09-09 15:08:12 +0000103
104 // Objective-C Statements
Chris Lattner1f551822009-04-27 06:20:01 +0000105 void VisitObjCForCollectionStmt(ObjCForCollectionStmt *);
106 void VisitObjCAtCatchStmt(ObjCAtCatchStmt *);
107 void VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *);
108 void VisitObjCAtTryStmt(ObjCAtTryStmt *);
109 void VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *);
110 void VisitObjCAtThrowStmt(ObjCAtThrowStmt *);
Argyrios Kyrtzidiseeaaead2009-07-14 03:19:21 +0000111
Mike Stump11289f42009-09-09 15:08:12 +0000112 // C++ Statements
Argyrios Kyrtzidiseeaaead2009-07-14 03:19:21 +0000113 void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
Douglas Gregor5d3507d2009-09-09 23:08:42 +0000114 void VisitCXXConstructExpr(CXXConstructExpr *E);
Chris Lattner1f551822009-04-27 06:20:01 +0000115 };
116}
117
Mike Stump11289f42009-09-09 15:08:12 +0000118void PCHStmtWriter::VisitStmt(Stmt *S) {
Chris Lattner1f551822009-04-27 06:20:01 +0000119}
120
121void PCHStmtWriter::VisitNullStmt(NullStmt *S) {
122 VisitStmt(S);
123 Writer.AddSourceLocation(S->getSemiLoc(), Record);
124 Code = pch::STMT_NULL;
125}
126
127void PCHStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
128 VisitStmt(S);
129 Record.push_back(S->size());
130 for (CompoundStmt::body_iterator CS = S->body_begin(), CSEnd = S->body_end();
131 CS != CSEnd; ++CS)
132 Writer.WriteSubStmt(*CS);
133 Writer.AddSourceLocation(S->getLBracLoc(), Record);
134 Writer.AddSourceLocation(S->getRBracLoc(), Record);
135 Code = pch::STMT_COMPOUND;
136}
137
138void PCHStmtWriter::VisitSwitchCase(SwitchCase *S) {
139 VisitStmt(S);
140 Record.push_back(Writer.RecordSwitchCaseID(S));
141}
142
143void PCHStmtWriter::VisitCaseStmt(CaseStmt *S) {
144 VisitSwitchCase(S);
145 Writer.WriteSubStmt(S->getLHS());
146 Writer.WriteSubStmt(S->getRHS());
147 Writer.WriteSubStmt(S->getSubStmt());
148 Writer.AddSourceLocation(S->getCaseLoc(), Record);
Douglas Gregor2a2d00f2009-05-15 23:57:33 +0000149 Writer.AddSourceLocation(S->getEllipsisLoc(), Record);
150 Writer.AddSourceLocation(S->getColonLoc(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000151 Code = pch::STMT_CASE;
152}
153
154void PCHStmtWriter::VisitDefaultStmt(DefaultStmt *S) {
155 VisitSwitchCase(S);
156 Writer.WriteSubStmt(S->getSubStmt());
157 Writer.AddSourceLocation(S->getDefaultLoc(), Record);
Douglas Gregor2a2d00f2009-05-15 23:57:33 +0000158 Writer.AddSourceLocation(S->getColonLoc(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000159 Code = pch::STMT_DEFAULT;
160}
161
162void PCHStmtWriter::VisitLabelStmt(LabelStmt *S) {
163 VisitStmt(S);
164 Writer.AddIdentifierRef(S->getID(), Record);
165 Writer.WriteSubStmt(S->getSubStmt());
166 Writer.AddSourceLocation(S->getIdentLoc(), Record);
167 Record.push_back(Writer.GetLabelID(S));
168 Code = pch::STMT_LABEL;
169}
170
171void PCHStmtWriter::VisitIfStmt(IfStmt *S) {
172 VisitStmt(S);
Douglas Gregor633caca2009-11-23 23:44:04 +0000173 Writer.AddDeclRef(S->getConditionVariable(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000174 Writer.WriteSubStmt(S->getCond());
175 Writer.WriteSubStmt(S->getThen());
176 Writer.WriteSubStmt(S->getElse());
177 Writer.AddSourceLocation(S->getIfLoc(), Record);
Douglas Gregor9d73cab2009-05-15 18:53:42 +0000178 Writer.AddSourceLocation(S->getElseLoc(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000179 Code = pch::STMT_IF;
180}
181
182void PCHStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
183 VisitStmt(S);
Douglas Gregordcf19622009-11-24 17:07:59 +0000184 Writer.AddDeclRef(S->getConditionVariable(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000185 Writer.WriteSubStmt(S->getCond());
186 Writer.WriteSubStmt(S->getBody());
187 Writer.AddSourceLocation(S->getSwitchLoc(), Record);
Mike Stump11289f42009-09-09 15:08:12 +0000188 for (SwitchCase *SC = S->getSwitchCaseList(); SC;
Chris Lattner1f551822009-04-27 06:20:01 +0000189 SC = SC->getNextSwitchCase())
190 Record.push_back(Writer.getSwitchCaseID(SC));
191 Code = pch::STMT_SWITCH;
192}
193
194void PCHStmtWriter::VisitWhileStmt(WhileStmt *S) {
195 VisitStmt(S);
196 Writer.WriteSubStmt(S->getCond());
197 Writer.WriteSubStmt(S->getBody());
198 Writer.AddSourceLocation(S->getWhileLoc(), Record);
199 Code = pch::STMT_WHILE;
200}
201
202void PCHStmtWriter::VisitDoStmt(DoStmt *S) {
203 VisitStmt(S);
204 Writer.WriteSubStmt(S->getCond());
205 Writer.WriteSubStmt(S->getBody());
206 Writer.AddSourceLocation(S->getDoLoc(), Record);
Douglas Gregor3daa82d2009-05-15 21:56:04 +0000207 Writer.AddSourceLocation(S->getWhileLoc(), Record);
Chris Lattner815b70e2009-06-12 23:04:47 +0000208 Writer.AddSourceLocation(S->getRParenLoc(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000209 Code = pch::STMT_DO;
210}
211
212void PCHStmtWriter::VisitForStmt(ForStmt *S) {
213 VisitStmt(S);
214 Writer.WriteSubStmt(S->getInit());
215 Writer.WriteSubStmt(S->getCond());
216 Writer.WriteSubStmt(S->getInc());
217 Writer.WriteSubStmt(S->getBody());
218 Writer.AddSourceLocation(S->getForLoc(), Record);
Douglas Gregor5d138682009-05-15 22:12:32 +0000219 Writer.AddSourceLocation(S->getLParenLoc(), Record);
220 Writer.AddSourceLocation(S->getRParenLoc(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000221 Code = pch::STMT_FOR;
222}
223
224void PCHStmtWriter::VisitGotoStmt(GotoStmt *S) {
225 VisitStmt(S);
226 Record.push_back(Writer.GetLabelID(S->getLabel()));
227 Writer.AddSourceLocation(S->getGotoLoc(), Record);
228 Writer.AddSourceLocation(S->getLabelLoc(), Record);
229 Code = pch::STMT_GOTO;
230}
231
232void PCHStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
233 VisitStmt(S);
234 Writer.AddSourceLocation(S->getGotoLoc(), Record);
Douglas Gregor30776d42009-05-16 00:20:29 +0000235 Writer.AddSourceLocation(S->getStarLoc(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000236 Writer.WriteSubStmt(S->getTarget());
237 Code = pch::STMT_INDIRECT_GOTO;
238}
239
240void PCHStmtWriter::VisitContinueStmt(ContinueStmt *S) {
241 VisitStmt(S);
242 Writer.AddSourceLocation(S->getContinueLoc(), Record);
243 Code = pch::STMT_CONTINUE;
244}
245
246void PCHStmtWriter::VisitBreakStmt(BreakStmt *S) {
247 VisitStmt(S);
248 Writer.AddSourceLocation(S->getBreakLoc(), Record);
249 Code = pch::STMT_BREAK;
250}
251
252void PCHStmtWriter::VisitReturnStmt(ReturnStmt *S) {
253 VisitStmt(S);
254 Writer.WriteSubStmt(S->getRetValue());
255 Writer.AddSourceLocation(S->getReturnLoc(), Record);
256 Code = pch::STMT_RETURN;
257}
258
259void PCHStmtWriter::VisitDeclStmt(DeclStmt *S) {
260 VisitStmt(S);
261 Writer.AddSourceLocation(S->getStartLoc(), Record);
262 Writer.AddSourceLocation(S->getEndLoc(), Record);
263 DeclGroupRef DG = S->getDeclGroup();
264 for (DeclGroupRef::iterator D = DG.begin(), DEnd = DG.end(); D != DEnd; ++D)
265 Writer.AddDeclRef(*D, Record);
266 Code = pch::STMT_DECL;
267}
268
269void PCHStmtWriter::VisitAsmStmt(AsmStmt *S) {
270 VisitStmt(S);
271 Record.push_back(S->getNumOutputs());
272 Record.push_back(S->getNumInputs());
273 Record.push_back(S->getNumClobbers());
274 Writer.AddSourceLocation(S->getAsmLoc(), Record);
275 Writer.AddSourceLocation(S->getRParenLoc(), Record);
276 Record.push_back(S->isVolatile());
277 Record.push_back(S->isSimple());
278 Writer.WriteSubStmt(S->getAsmString());
279
280 // Outputs
281 for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
282 Writer.AddString(S->getOutputName(I), Record);
283 Writer.WriteSubStmt(S->getOutputConstraintLiteral(I));
284 Writer.WriteSubStmt(S->getOutputExpr(I));
285 }
286
287 // Inputs
288 for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
289 Writer.AddString(S->getInputName(I), Record);
290 Writer.WriteSubStmt(S->getInputConstraintLiteral(I));
291 Writer.WriteSubStmt(S->getInputExpr(I));
292 }
293
294 // Clobbers
295 for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
296 Writer.WriteSubStmt(S->getClobber(I));
297
298 Code = pch::STMT_ASM;
299}
300
301void PCHStmtWriter::VisitExpr(Expr *E) {
302 VisitStmt(E);
303 Writer.AddTypeRef(E->getType(), Record);
304 Record.push_back(E->isTypeDependent());
305 Record.push_back(E->isValueDependent());
306}
307
308void PCHStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
309 VisitExpr(E);
310 Writer.AddSourceLocation(E->getLocation(), Record);
311 Record.push_back(E->getIdentType()); // FIXME: stable encoding
312 Code = pch::EXPR_PREDEFINED;
313}
314
315void PCHStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
316 VisitExpr(E);
317 Writer.AddDeclRef(E->getDecl(), Record);
318 Writer.AddSourceLocation(E->getLocation(), Record);
Douglas Gregor4bd90e52009-10-23 18:54:35 +0000319 // FIXME: write qualifier
320 // FIXME: write explicit template arguments
Chris Lattner1f551822009-04-27 06:20:01 +0000321 Code = pch::EXPR_DECL_REF;
322}
323
324void PCHStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
325 VisitExpr(E);
326 Writer.AddSourceLocation(E->getLocation(), Record);
327 Writer.AddAPInt(E->getValue(), Record);
328 Code = pch::EXPR_INTEGER_LITERAL;
329}
330
331void PCHStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
332 VisitExpr(E);
333 Writer.AddAPFloat(E->getValue(), Record);
334 Record.push_back(E->isExact());
335 Writer.AddSourceLocation(E->getLocation(), Record);
336 Code = pch::EXPR_FLOATING_LITERAL;
337}
338
339void PCHStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
340 VisitExpr(E);
341 Writer.WriteSubStmt(E->getSubExpr());
342 Code = pch::EXPR_IMAGINARY_LITERAL;
343}
344
345void PCHStmtWriter::VisitStringLiteral(StringLiteral *E) {
346 VisitExpr(E);
347 Record.push_back(E->getByteLength());
348 Record.push_back(E->getNumConcatenated());
349 Record.push_back(E->isWide());
350 // FIXME: String data should be stored as a blob at the end of the
351 // StringLiteral. However, we can't do so now because we have no
352 // provision for coping with abbreviations when we're jumping around
353 // the PCH file during deserialization.
Mike Stump11289f42009-09-09 15:08:12 +0000354 Record.insert(Record.end(),
Chris Lattner1f551822009-04-27 06:20:01 +0000355 E->getStrData(), E->getStrData() + E->getByteLength());
356 for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
357 Writer.AddSourceLocation(E->getStrTokenLoc(I), Record);
358 Code = pch::EXPR_STRING_LITERAL;
359}
360
361void PCHStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
362 VisitExpr(E);
363 Record.push_back(E->getValue());
Chris Lattnere6434cb2009-08-24 17:39:36 +0000364 Writer.AddSourceLocation(E->getLocation(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000365 Record.push_back(E->isWide());
366 Code = pch::EXPR_CHARACTER_LITERAL;
367}
368
369void PCHStmtWriter::VisitParenExpr(ParenExpr *E) {
370 VisitExpr(E);
371 Writer.AddSourceLocation(E->getLParen(), Record);
372 Writer.AddSourceLocation(E->getRParen(), Record);
373 Writer.WriteSubStmt(E->getSubExpr());
374 Code = pch::EXPR_PAREN;
375}
376
377void PCHStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
378 VisitExpr(E);
379 Writer.WriteSubStmt(E->getSubExpr());
380 Record.push_back(E->getOpcode()); // FIXME: stable encoding
381 Writer.AddSourceLocation(E->getOperatorLoc(), Record);
382 Code = pch::EXPR_UNARY_OPERATOR;
383}
384
Mike Stump11289f42009-09-09 15:08:12 +0000385void PCHStmtWriter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
Chris Lattner1f551822009-04-27 06:20:01 +0000386 VisitExpr(E);
387 Record.push_back(E->isSizeOf());
388 if (E->isArgumentType())
John McCall4c98fd82009-11-04 07:28:41 +0000389 Writer.AddDeclaratorInfo(E->getArgumentTypeInfo(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000390 else {
391 Record.push_back(0);
392 Writer.WriteSubStmt(E->getArgumentExpr());
393 }
394 Writer.AddSourceLocation(E->getOperatorLoc(), Record);
395 Writer.AddSourceLocation(E->getRParenLoc(), Record);
396 Code = pch::EXPR_SIZEOF_ALIGN_OF;
397}
398
399void PCHStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
400 VisitExpr(E);
401 Writer.WriteSubStmt(E->getLHS());
402 Writer.WriteSubStmt(E->getRHS());
403 Writer.AddSourceLocation(E->getRBracketLoc(), Record);
404 Code = pch::EXPR_ARRAY_SUBSCRIPT;
405}
406
407void PCHStmtWriter::VisitCallExpr(CallExpr *E) {
408 VisitExpr(E);
409 Record.push_back(E->getNumArgs());
410 Writer.AddSourceLocation(E->getRParenLoc(), Record);
411 Writer.WriteSubStmt(E->getCallee());
412 for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
413 Arg != ArgEnd; ++Arg)
414 Writer.WriteSubStmt(*Arg);
415 Code = pch::EXPR_CALL;
416}
417
418void PCHStmtWriter::VisitMemberExpr(MemberExpr *E) {
419 VisitExpr(E);
420 Writer.WriteSubStmt(E->getBase());
421 Writer.AddDeclRef(E->getMemberDecl(), Record);
422 Writer.AddSourceLocation(E->getMemberLoc(), Record);
423 Record.push_back(E->isArrow());
Douglas Gregorf4b34ba2009-08-31 23:44:04 +0000424 // FIXME: C++ nested-name-specifier
Douglas Gregor84f14dd2009-09-01 00:37:14 +0000425 // FIXME: C++ template argument list
Chris Lattner1f551822009-04-27 06:20:01 +0000426 Code = pch::EXPR_MEMBER;
427}
428
Steve Naroffe87026a2009-07-24 17:54:45 +0000429void PCHStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
430 VisitExpr(E);
431 Writer.WriteSubStmt(E->getBase());
432 Writer.AddSourceLocation(E->getIsaMemberLoc(), Record);
433 Record.push_back(E->isArrow());
434 Code = pch::EXPR_OBJC_ISA;
435}
436
Chris Lattner1f551822009-04-27 06:20:01 +0000437void PCHStmtWriter::VisitCastExpr(CastExpr *E) {
438 VisitExpr(E);
439 Writer.WriteSubStmt(E->getSubExpr());
Anders Carlssona2615922009-07-31 00:48:10 +0000440 Record.push_back(E->getCastKind()); // FIXME: stable encoding
Chris Lattner1f551822009-04-27 06:20:01 +0000441}
442
443void PCHStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
444 VisitExpr(E);
445 Writer.WriteSubStmt(E->getLHS());
446 Writer.WriteSubStmt(E->getRHS());
447 Record.push_back(E->getOpcode()); // FIXME: stable encoding
448 Writer.AddSourceLocation(E->getOperatorLoc(), Record);
449 Code = pch::EXPR_BINARY_OPERATOR;
450}
451
452void PCHStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
453 VisitBinaryOperator(E);
454 Writer.AddTypeRef(E->getComputationLHSType(), Record);
455 Writer.AddTypeRef(E->getComputationResultType(), Record);
456 Code = pch::EXPR_COMPOUND_ASSIGN_OPERATOR;
457}
458
459void PCHStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
460 VisitExpr(E);
461 Writer.WriteSubStmt(E->getCond());
462 Writer.WriteSubStmt(E->getLHS());
463 Writer.WriteSubStmt(E->getRHS());
Douglas Gregor7e112b02009-08-26 14:37:04 +0000464 Writer.AddSourceLocation(E->getQuestionLoc(), Record);
465 Writer.AddSourceLocation(E->getColonLoc(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000466 Code = pch::EXPR_CONDITIONAL_OPERATOR;
467}
468
469void PCHStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
470 VisitCastExpr(E);
471 Record.push_back(E->isLvalueCast());
472 Code = pch::EXPR_IMPLICIT_CAST;
473}
474
475void PCHStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
476 VisitCastExpr(E);
477 Writer.AddTypeRef(E->getTypeAsWritten(), Record);
478}
479
480void PCHStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
481 VisitExplicitCastExpr(E);
482 Writer.AddSourceLocation(E->getLParenLoc(), Record);
483 Writer.AddSourceLocation(E->getRParenLoc(), Record);
484 Code = pch::EXPR_CSTYLE_CAST;
485}
486
487void PCHStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
488 VisitExpr(E);
489 Writer.AddSourceLocation(E->getLParenLoc(), Record);
490 Writer.WriteSubStmt(E->getInitializer());
491 Record.push_back(E->isFileScope());
492 Code = pch::EXPR_COMPOUND_LITERAL;
493}
494
495void PCHStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
496 VisitExpr(E);
497 Writer.WriteSubStmt(E->getBase());
498 Writer.AddIdentifierRef(&E->getAccessor(), Record);
499 Writer.AddSourceLocation(E->getAccessorLoc(), Record);
500 Code = pch::EXPR_EXT_VECTOR_ELEMENT;
501}
502
503void PCHStmtWriter::VisitInitListExpr(InitListExpr *E) {
504 VisitExpr(E);
505 Record.push_back(E->getNumInits());
506 for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
507 Writer.WriteSubStmt(E->getInit(I));
508 Writer.WriteSubStmt(E->getSyntacticForm());
509 Writer.AddSourceLocation(E->getLBraceLoc(), Record);
510 Writer.AddSourceLocation(E->getRBraceLoc(), Record);
511 Writer.AddDeclRef(E->getInitializedFieldInUnion(), Record);
512 Record.push_back(E->hadArrayRangeDesignator());
513 Code = pch::EXPR_INIT_LIST;
514}
515
516void PCHStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
517 VisitExpr(E);
518 Record.push_back(E->getNumSubExprs());
519 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
520 Writer.WriteSubStmt(E->getSubExpr(I));
521 Writer.AddSourceLocation(E->getEqualOrColonLoc(), Record);
522 Record.push_back(E->usesGNUSyntax());
523 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
524 DEnd = E->designators_end();
525 D != DEnd; ++D) {
526 if (D->isFieldDesignator()) {
527 if (FieldDecl *Field = D->getField()) {
528 Record.push_back(pch::DESIG_FIELD_DECL);
529 Writer.AddDeclRef(Field, Record);
530 } else {
531 Record.push_back(pch::DESIG_FIELD_NAME);
532 Writer.AddIdentifierRef(D->getFieldName(), Record);
533 }
534 Writer.AddSourceLocation(D->getDotLoc(), Record);
535 Writer.AddSourceLocation(D->getFieldLoc(), Record);
536 } else if (D->isArrayDesignator()) {
537 Record.push_back(pch::DESIG_ARRAY);
538 Record.push_back(D->getFirstExprIndex());
539 Writer.AddSourceLocation(D->getLBracketLoc(), Record);
540 Writer.AddSourceLocation(D->getRBracketLoc(), Record);
541 } else {
542 assert(D->isArrayRangeDesignator() && "Unknown designator");
543 Record.push_back(pch::DESIG_ARRAY_RANGE);
544 Record.push_back(D->getFirstExprIndex());
545 Writer.AddSourceLocation(D->getLBracketLoc(), Record);
546 Writer.AddSourceLocation(D->getEllipsisLoc(), Record);
547 Writer.AddSourceLocation(D->getRBracketLoc(), Record);
548 }
549 }
550 Code = pch::EXPR_DESIGNATED_INIT;
551}
552
553void PCHStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
554 VisitExpr(E);
555 Code = pch::EXPR_IMPLICIT_VALUE_INIT;
556}
557
558void PCHStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
559 VisitExpr(E);
560 Writer.WriteSubStmt(E->getSubExpr());
561 Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
562 Writer.AddSourceLocation(E->getRParenLoc(), Record);
563 Code = pch::EXPR_VA_ARG;
564}
565
566void PCHStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
567 VisitExpr(E);
568 Writer.AddSourceLocation(E->getAmpAmpLoc(), Record);
569 Writer.AddSourceLocation(E->getLabelLoc(), Record);
570 Record.push_back(Writer.GetLabelID(E->getLabel()));
571 Code = pch::EXPR_ADDR_LABEL;
572}
573
574void PCHStmtWriter::VisitStmtExpr(StmtExpr *E) {
575 VisitExpr(E);
576 Writer.WriteSubStmt(E->getSubStmt());
577 Writer.AddSourceLocation(E->getLParenLoc(), Record);
578 Writer.AddSourceLocation(E->getRParenLoc(), Record);
579 Code = pch::EXPR_STMT;
580}
581
582void PCHStmtWriter::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) {
583 VisitExpr(E);
584 Writer.AddTypeRef(E->getArgType1(), Record);
585 Writer.AddTypeRef(E->getArgType2(), Record);
586 Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
587 Writer.AddSourceLocation(E->getRParenLoc(), Record);
588 Code = pch::EXPR_TYPES_COMPATIBLE;
589}
590
591void PCHStmtWriter::VisitChooseExpr(ChooseExpr *E) {
592 VisitExpr(E);
593 Writer.WriteSubStmt(E->getCond());
594 Writer.WriteSubStmt(E->getLHS());
595 Writer.WriteSubStmt(E->getRHS());
596 Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
597 Writer.AddSourceLocation(E->getRParenLoc(), Record);
598 Code = pch::EXPR_CHOOSE;
599}
600
601void PCHStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
602 VisitExpr(E);
603 Writer.AddSourceLocation(E->getTokenLocation(), Record);
604 Code = pch::EXPR_GNU_NULL;
605}
606
607void PCHStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
608 VisitExpr(E);
609 Record.push_back(E->getNumSubExprs());
610 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
611 Writer.WriteSubStmt(E->getExpr(I));
612 Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
613 Writer.AddSourceLocation(E->getRParenLoc(), Record);
614 Code = pch::EXPR_SHUFFLE_VECTOR;
615}
616
617void PCHStmtWriter::VisitBlockExpr(BlockExpr *E) {
618 VisitExpr(E);
619 Writer.AddDeclRef(E->getBlockDecl(), Record);
620 Record.push_back(E->hasBlockDeclRefExprs());
621 Code = pch::EXPR_BLOCK;
622}
623
624void PCHStmtWriter::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
625 VisitExpr(E);
626 Writer.AddDeclRef(E->getDecl(), Record);
627 Writer.AddSourceLocation(E->getLocation(), Record);
628 Record.push_back(E->isByRef());
Fariborz Jahaniane8918d52009-06-20 00:02:26 +0000629 Record.push_back(E->isConstQualAdded());
Chris Lattner1f551822009-04-27 06:20:01 +0000630 Code = pch::EXPR_BLOCK_DECL_REF;
631}
632
633//===----------------------------------------------------------------------===//
634// Objective-C Expressions and Statements.
635//===----------------------------------------------------------------------===//
636
637void PCHStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
638 VisitExpr(E);
639 Writer.WriteSubStmt(E->getString());
640 Writer.AddSourceLocation(E->getAtLoc(), Record);
641 Code = pch::EXPR_OBJC_STRING_LITERAL;
642}
643
Mike Stump11289f42009-09-09 15:08:12 +0000644void PCHStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
Chris Lattner1f551822009-04-27 06:20:01 +0000645 VisitExpr(E);
646 Writer.AddTypeRef(E->getEncodedType(), Record);
647 Writer.AddSourceLocation(E->getAtLoc(), Record);
648 Writer.AddSourceLocation(E->getRParenLoc(), Record);
649 Code = pch::EXPR_OBJC_ENCODE;
650}
651
652void PCHStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
653 VisitExpr(E);
654 Writer.AddSelectorRef(E->getSelector(), Record);
655 Writer.AddSourceLocation(E->getAtLoc(), Record);
656 Writer.AddSourceLocation(E->getRParenLoc(), Record);
657 Code = pch::EXPR_OBJC_SELECTOR_EXPR;
658}
659
660void PCHStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
661 VisitExpr(E);
662 Writer.AddDeclRef(E->getProtocol(), Record);
663 Writer.AddSourceLocation(E->getAtLoc(), Record);
664 Writer.AddSourceLocation(E->getRParenLoc(), Record);
665 Code = pch::EXPR_OBJC_PROTOCOL_EXPR;
666}
667
668void PCHStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
669 VisitExpr(E);
670 Writer.AddDeclRef(E->getDecl(), Record);
671 Writer.AddSourceLocation(E->getLocation(), Record);
672 Writer.WriteSubStmt(E->getBase());
673 Record.push_back(E->isArrow());
674 Record.push_back(E->isFreeIvar());
675 Code = pch::EXPR_OBJC_IVAR_REF_EXPR;
676}
677
678void PCHStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
679 VisitExpr(E);
680 Writer.AddDeclRef(E->getProperty(), Record);
681 Writer.AddSourceLocation(E->getLocation(), Record);
682 Writer.WriteSubStmt(E->getBase());
683 Code = pch::EXPR_OBJC_PROPERTY_REF_EXPR;
684}
685
Fariborz Jahanian9a846652009-08-20 17:02:02 +0000686void PCHStmtWriter::VisitObjCImplicitSetterGetterRefExpr(
687 ObjCImplicitSetterGetterRefExpr *E) {
Chris Lattner1f551822009-04-27 06:20:01 +0000688 VisitExpr(E);
689 Writer.AddDeclRef(E->getGetterMethod(), Record);
690 Writer.AddDeclRef(E->getSetterMethod(), Record);
Mike Stump11289f42009-09-09 15:08:12 +0000691
Fariborz Jahanian19380c42009-08-18 21:37:33 +0000692 // NOTE: InterfaceDecl and Base are mutually exclusive.
693 Writer.AddDeclRef(E->getInterfaceDecl(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000694 Writer.WriteSubStmt(E->getBase());
695 Writer.AddSourceLocation(E->getLocation(), Record);
696 Writer.AddSourceLocation(E->getClassLoc(), Record);
697 Code = pch::EXPR_OBJC_KVC_REF_EXPR;
698}
699
700void PCHStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
701 VisitExpr(E);
702 Record.push_back(E->getNumArgs());
703 Writer.AddSourceLocation(E->getLeftLoc(), Record);
704 Writer.AddSourceLocation(E->getRightLoc(), Record);
705 Writer.AddSelectorRef(E->getSelector(), Record);
706 Writer.AddDeclRef(E->getMethodDecl(), Record); // optional
707 Writer.WriteSubStmt(E->getReceiver());
708
709 if (!E->getReceiver()) {
710 ObjCMessageExpr::ClassInfo CI = E->getClassInfo();
711 Writer.AddDeclRef(CI.first, Record);
712 Writer.AddIdentifierRef(CI.second, Record);
713 }
714
715 for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
716 Arg != ArgEnd; ++Arg)
717 Writer.WriteSubStmt(*Arg);
718 Code = pch::EXPR_OBJC_MESSAGE_EXPR;
719}
720
721void PCHStmtWriter::VisitObjCSuperExpr(ObjCSuperExpr *E) {
722 VisitExpr(E);
723 Writer.AddSourceLocation(E->getLoc(), Record);
724 Code = pch::EXPR_OBJC_SUPER_EXPR;
725}
726
727void PCHStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
728 VisitStmt(S);
729 Writer.WriteSubStmt(S->getElement());
730 Writer.WriteSubStmt(S->getCollection());
731 Writer.WriteSubStmt(S->getBody());
732 Writer.AddSourceLocation(S->getForLoc(), Record);
733 Writer.AddSourceLocation(S->getRParenLoc(), Record);
734 Code = pch::STMT_OBJC_FOR_COLLECTION;
735}
736
737void PCHStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
738 Writer.WriteSubStmt(S->getCatchBody());
739 Writer.WriteSubStmt(S->getNextCatchStmt());
740 Writer.AddDeclRef(S->getCatchParamDecl(), Record);
741 Writer.AddSourceLocation(S->getAtCatchLoc(), Record);
742 Writer.AddSourceLocation(S->getRParenLoc(), Record);
743 Code = pch::STMT_OBJC_CATCH;
744}
745
746void PCHStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
747 Writer.WriteSubStmt(S->getFinallyBody());
748 Writer.AddSourceLocation(S->getAtFinallyLoc(), Record);
749 Code = pch::STMT_OBJC_FINALLY;
750}
751
752void PCHStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
753 Writer.WriteSubStmt(S->getTryBody());
754 Writer.WriteSubStmt(S->getCatchStmts());
755 Writer.WriteSubStmt(S->getFinallyStmt());
756 Writer.AddSourceLocation(S->getAtTryLoc(), Record);
757 Code = pch::STMT_OBJC_AT_TRY;
758}
759
760void PCHStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
761 Writer.WriteSubStmt(S->getSynchExpr());
762 Writer.WriteSubStmt(S->getSynchBody());
763 Writer.AddSourceLocation(S->getAtSynchronizedLoc(), Record);
764 Code = pch::STMT_OBJC_AT_SYNCHRONIZED;
765}
766
767void PCHStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
768 Writer.WriteSubStmt(S->getThrowExpr());
769 Writer.AddSourceLocation(S->getThrowLoc(), Record);
770 Code = pch::STMT_OBJC_AT_THROW;
771}
772
773//===----------------------------------------------------------------------===//
Argyrios Kyrtzidiseeaaead2009-07-14 03:19:21 +0000774// C++ Expressions and Statements.
775//===----------------------------------------------------------------------===//
776
777void PCHStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
778 VisitCallExpr(E);
779 Record.push_back(E->getOperator());
780 Code = pch::EXPR_CXX_OPERATOR_CALL;
781}
782
Douglas Gregor5d3507d2009-09-09 23:08:42 +0000783void PCHStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
784 VisitExpr(E);
785 Writer.AddDeclRef(E->getConstructor(), Record);
786 Record.push_back(E->isElidable());
787 Record.push_back(E->getNumArgs());
788 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
789 Writer.WriteSubStmt(E->getArg(I));
790 Code = pch::EXPR_CXX_CONSTRUCT;
791}
792
Argyrios Kyrtzidiseeaaead2009-07-14 03:19:21 +0000793//===----------------------------------------------------------------------===//
Chris Lattner1f551822009-04-27 06:20:01 +0000794// PCHWriter Implementation
795//===----------------------------------------------------------------------===//
796
797unsigned PCHWriter::RecordSwitchCaseID(SwitchCase *S) {
Mike Stump11289f42009-09-09 15:08:12 +0000798 assert(SwitchCaseIDs.find(S) == SwitchCaseIDs.end() &&
Chris Lattner1f551822009-04-27 06:20:01 +0000799 "SwitchCase recorded twice");
800 unsigned NextID = SwitchCaseIDs.size();
801 SwitchCaseIDs[S] = NextID;
802 return NextID;
803}
804
805unsigned PCHWriter::getSwitchCaseID(SwitchCase *S) {
Mike Stump11289f42009-09-09 15:08:12 +0000806 assert(SwitchCaseIDs.find(S) != SwitchCaseIDs.end() &&
Chris Lattner1f551822009-04-27 06:20:01 +0000807 "SwitchCase hasn't been seen yet");
808 return SwitchCaseIDs[S];
809}
810
811/// \brief Retrieve the ID for the given label statement, which may
812/// or may not have been emitted yet.
813unsigned PCHWriter::GetLabelID(LabelStmt *S) {
814 std::map<LabelStmt *, unsigned>::iterator Pos = LabelIDs.find(S);
815 if (Pos != LabelIDs.end())
816 return Pos->second;
Mike Stump11289f42009-09-09 15:08:12 +0000817
Chris Lattner1f551822009-04-27 06:20:01 +0000818 unsigned NextID = LabelIDs.size();
819 LabelIDs[S] = NextID;
820 return NextID;
821}
822
823/// \brief Write the given substatement or subexpression to the
824/// bitstream.
825void PCHWriter::WriteSubStmt(Stmt *S) {
826 RecordData Record;
827 PCHStmtWriter Writer(*this, Record);
828 ++NumStatements;
Mike Stump11289f42009-09-09 15:08:12 +0000829
Chris Lattner1f551822009-04-27 06:20:01 +0000830 if (!S) {
831 Stream.EmitRecord(pch::STMT_NULL_PTR, Record);
832 return;
833 }
Mike Stump11289f42009-09-09 15:08:12 +0000834
Chris Lattner1f551822009-04-27 06:20:01 +0000835 Writer.Code = pch::STMT_NULL_PTR;
836 Writer.Visit(S);
Mike Stump11289f42009-09-09 15:08:12 +0000837 assert(Writer.Code != pch::STMT_NULL_PTR &&
Chris Lattner1f551822009-04-27 06:20:01 +0000838 "Unhandled expression writing PCH file");
Mike Stump11289f42009-09-09 15:08:12 +0000839 Stream.EmitRecord(Writer.Code, Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000840}
841
842/// \brief Flush all of the statements that have been added to the
843/// queue via AddStmt().
844void PCHWriter::FlushStmts() {
845 RecordData Record;
846 PCHStmtWriter Writer(*this, Record);
Mike Stump11289f42009-09-09 15:08:12 +0000847
Chris Lattner1f551822009-04-27 06:20:01 +0000848 for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
849 ++NumStatements;
850 Stmt *S = StmtsToEmit[I];
Mike Stump11289f42009-09-09 15:08:12 +0000851
Chris Lattner1f551822009-04-27 06:20:01 +0000852 if (!S) {
853 Stream.EmitRecord(pch::STMT_NULL_PTR, Record);
854 continue;
855 }
Mike Stump11289f42009-09-09 15:08:12 +0000856
Chris Lattner1f551822009-04-27 06:20:01 +0000857 Writer.Code = pch::STMT_NULL_PTR;
858 Writer.Visit(S);
Mike Stump11289f42009-09-09 15:08:12 +0000859 assert(Writer.Code != pch::STMT_NULL_PTR &&
Chris Lattner1f551822009-04-27 06:20:01 +0000860 "Unhandled expression writing PCH file");
Mike Stump11289f42009-09-09 15:08:12 +0000861 Stream.EmitRecord(Writer.Code, Record);
862
863 assert(N == StmtsToEmit.size() &&
Chris Lattner1f551822009-04-27 06:20:01 +0000864 "Substatement writen via AddStmt rather than WriteSubStmt!");
Mike Stump11289f42009-09-09 15:08:12 +0000865
Chris Lattner1f551822009-04-27 06:20:01 +0000866 // Note that we are at the end of a full expression. Any
867 // expression records that follow this one are part of a different
868 // expression.
869 Record.clear();
870 Stream.EmitRecord(pch::STMT_STOP, Record);
871 }
Mike Stump11289f42009-09-09 15:08:12 +0000872
Chris Lattner1f551822009-04-27 06:20:01 +0000873 StmtsToEmit.clear();
Chris Lattner1f551822009-04-27 06:20:01 +0000874}