blob: 8de094a29673361b12bd51b716a1bb8bda8386b9 [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);
184 Writer.WriteSubStmt(S->getCond());
185 Writer.WriteSubStmt(S->getBody());
186 Writer.AddSourceLocation(S->getSwitchLoc(), Record);
Mike Stump11289f42009-09-09 15:08:12 +0000187 for (SwitchCase *SC = S->getSwitchCaseList(); SC;
Chris Lattner1f551822009-04-27 06:20:01 +0000188 SC = SC->getNextSwitchCase())
189 Record.push_back(Writer.getSwitchCaseID(SC));
190 Code = pch::STMT_SWITCH;
191}
192
193void PCHStmtWriter::VisitWhileStmt(WhileStmt *S) {
194 VisitStmt(S);
195 Writer.WriteSubStmt(S->getCond());
196 Writer.WriteSubStmt(S->getBody());
197 Writer.AddSourceLocation(S->getWhileLoc(), Record);
198 Code = pch::STMT_WHILE;
199}
200
201void PCHStmtWriter::VisitDoStmt(DoStmt *S) {
202 VisitStmt(S);
203 Writer.WriteSubStmt(S->getCond());
204 Writer.WriteSubStmt(S->getBody());
205 Writer.AddSourceLocation(S->getDoLoc(), Record);
Douglas Gregor3daa82d2009-05-15 21:56:04 +0000206 Writer.AddSourceLocation(S->getWhileLoc(), Record);
Chris Lattner815b70e2009-06-12 23:04:47 +0000207 Writer.AddSourceLocation(S->getRParenLoc(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000208 Code = pch::STMT_DO;
209}
210
211void PCHStmtWriter::VisitForStmt(ForStmt *S) {
212 VisitStmt(S);
213 Writer.WriteSubStmt(S->getInit());
214 Writer.WriteSubStmt(S->getCond());
215 Writer.WriteSubStmt(S->getInc());
216 Writer.WriteSubStmt(S->getBody());
217 Writer.AddSourceLocation(S->getForLoc(), Record);
Douglas Gregor5d138682009-05-15 22:12:32 +0000218 Writer.AddSourceLocation(S->getLParenLoc(), Record);
219 Writer.AddSourceLocation(S->getRParenLoc(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000220 Code = pch::STMT_FOR;
221}
222
223void PCHStmtWriter::VisitGotoStmt(GotoStmt *S) {
224 VisitStmt(S);
225 Record.push_back(Writer.GetLabelID(S->getLabel()));
226 Writer.AddSourceLocation(S->getGotoLoc(), Record);
227 Writer.AddSourceLocation(S->getLabelLoc(), Record);
228 Code = pch::STMT_GOTO;
229}
230
231void PCHStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
232 VisitStmt(S);
233 Writer.AddSourceLocation(S->getGotoLoc(), Record);
Douglas Gregor30776d42009-05-16 00:20:29 +0000234 Writer.AddSourceLocation(S->getStarLoc(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000235 Writer.WriteSubStmt(S->getTarget());
236 Code = pch::STMT_INDIRECT_GOTO;
237}
238
239void PCHStmtWriter::VisitContinueStmt(ContinueStmt *S) {
240 VisitStmt(S);
241 Writer.AddSourceLocation(S->getContinueLoc(), Record);
242 Code = pch::STMT_CONTINUE;
243}
244
245void PCHStmtWriter::VisitBreakStmt(BreakStmt *S) {
246 VisitStmt(S);
247 Writer.AddSourceLocation(S->getBreakLoc(), Record);
248 Code = pch::STMT_BREAK;
249}
250
251void PCHStmtWriter::VisitReturnStmt(ReturnStmt *S) {
252 VisitStmt(S);
253 Writer.WriteSubStmt(S->getRetValue());
254 Writer.AddSourceLocation(S->getReturnLoc(), Record);
255 Code = pch::STMT_RETURN;
256}
257
258void PCHStmtWriter::VisitDeclStmt(DeclStmt *S) {
259 VisitStmt(S);
260 Writer.AddSourceLocation(S->getStartLoc(), Record);
261 Writer.AddSourceLocation(S->getEndLoc(), Record);
262 DeclGroupRef DG = S->getDeclGroup();
263 for (DeclGroupRef::iterator D = DG.begin(), DEnd = DG.end(); D != DEnd; ++D)
264 Writer.AddDeclRef(*D, Record);
265 Code = pch::STMT_DECL;
266}
267
268void PCHStmtWriter::VisitAsmStmt(AsmStmt *S) {
269 VisitStmt(S);
270 Record.push_back(S->getNumOutputs());
271 Record.push_back(S->getNumInputs());
272 Record.push_back(S->getNumClobbers());
273 Writer.AddSourceLocation(S->getAsmLoc(), Record);
274 Writer.AddSourceLocation(S->getRParenLoc(), Record);
275 Record.push_back(S->isVolatile());
276 Record.push_back(S->isSimple());
277 Writer.WriteSubStmt(S->getAsmString());
278
279 // Outputs
280 for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
281 Writer.AddString(S->getOutputName(I), Record);
282 Writer.WriteSubStmt(S->getOutputConstraintLiteral(I));
283 Writer.WriteSubStmt(S->getOutputExpr(I));
284 }
285
286 // Inputs
287 for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
288 Writer.AddString(S->getInputName(I), Record);
289 Writer.WriteSubStmt(S->getInputConstraintLiteral(I));
290 Writer.WriteSubStmt(S->getInputExpr(I));
291 }
292
293 // Clobbers
294 for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
295 Writer.WriteSubStmt(S->getClobber(I));
296
297 Code = pch::STMT_ASM;
298}
299
300void PCHStmtWriter::VisitExpr(Expr *E) {
301 VisitStmt(E);
302 Writer.AddTypeRef(E->getType(), Record);
303 Record.push_back(E->isTypeDependent());
304 Record.push_back(E->isValueDependent());
305}
306
307void PCHStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
308 VisitExpr(E);
309 Writer.AddSourceLocation(E->getLocation(), Record);
310 Record.push_back(E->getIdentType()); // FIXME: stable encoding
311 Code = pch::EXPR_PREDEFINED;
312}
313
314void PCHStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
315 VisitExpr(E);
316 Writer.AddDeclRef(E->getDecl(), Record);
317 Writer.AddSourceLocation(E->getLocation(), Record);
Douglas Gregor4bd90e52009-10-23 18:54:35 +0000318 // FIXME: write qualifier
319 // FIXME: write explicit template arguments
Chris Lattner1f551822009-04-27 06:20:01 +0000320 Code = pch::EXPR_DECL_REF;
321}
322
323void PCHStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
324 VisitExpr(E);
325 Writer.AddSourceLocation(E->getLocation(), Record);
326 Writer.AddAPInt(E->getValue(), Record);
327 Code = pch::EXPR_INTEGER_LITERAL;
328}
329
330void PCHStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
331 VisitExpr(E);
332 Writer.AddAPFloat(E->getValue(), Record);
333 Record.push_back(E->isExact());
334 Writer.AddSourceLocation(E->getLocation(), Record);
335 Code = pch::EXPR_FLOATING_LITERAL;
336}
337
338void PCHStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
339 VisitExpr(E);
340 Writer.WriteSubStmt(E->getSubExpr());
341 Code = pch::EXPR_IMAGINARY_LITERAL;
342}
343
344void PCHStmtWriter::VisitStringLiteral(StringLiteral *E) {
345 VisitExpr(E);
346 Record.push_back(E->getByteLength());
347 Record.push_back(E->getNumConcatenated());
348 Record.push_back(E->isWide());
349 // FIXME: String data should be stored as a blob at the end of the
350 // StringLiteral. However, we can't do so now because we have no
351 // provision for coping with abbreviations when we're jumping around
352 // the PCH file during deserialization.
Mike Stump11289f42009-09-09 15:08:12 +0000353 Record.insert(Record.end(),
Chris Lattner1f551822009-04-27 06:20:01 +0000354 E->getStrData(), E->getStrData() + E->getByteLength());
355 for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
356 Writer.AddSourceLocation(E->getStrTokenLoc(I), Record);
357 Code = pch::EXPR_STRING_LITERAL;
358}
359
360void PCHStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
361 VisitExpr(E);
362 Record.push_back(E->getValue());
Chris Lattnere6434cb2009-08-24 17:39:36 +0000363 Writer.AddSourceLocation(E->getLocation(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000364 Record.push_back(E->isWide());
365 Code = pch::EXPR_CHARACTER_LITERAL;
366}
367
368void PCHStmtWriter::VisitParenExpr(ParenExpr *E) {
369 VisitExpr(E);
370 Writer.AddSourceLocation(E->getLParen(), Record);
371 Writer.AddSourceLocation(E->getRParen(), Record);
372 Writer.WriteSubStmt(E->getSubExpr());
373 Code = pch::EXPR_PAREN;
374}
375
376void PCHStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
377 VisitExpr(E);
378 Writer.WriteSubStmt(E->getSubExpr());
379 Record.push_back(E->getOpcode()); // FIXME: stable encoding
380 Writer.AddSourceLocation(E->getOperatorLoc(), Record);
381 Code = pch::EXPR_UNARY_OPERATOR;
382}
383
Mike Stump11289f42009-09-09 15:08:12 +0000384void PCHStmtWriter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
Chris Lattner1f551822009-04-27 06:20:01 +0000385 VisitExpr(E);
386 Record.push_back(E->isSizeOf());
387 if (E->isArgumentType())
John McCall4c98fd82009-11-04 07:28:41 +0000388 Writer.AddDeclaratorInfo(E->getArgumentTypeInfo(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000389 else {
390 Record.push_back(0);
391 Writer.WriteSubStmt(E->getArgumentExpr());
392 }
393 Writer.AddSourceLocation(E->getOperatorLoc(), Record);
394 Writer.AddSourceLocation(E->getRParenLoc(), Record);
395 Code = pch::EXPR_SIZEOF_ALIGN_OF;
396}
397
398void PCHStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
399 VisitExpr(E);
400 Writer.WriteSubStmt(E->getLHS());
401 Writer.WriteSubStmt(E->getRHS());
402 Writer.AddSourceLocation(E->getRBracketLoc(), Record);
403 Code = pch::EXPR_ARRAY_SUBSCRIPT;
404}
405
406void PCHStmtWriter::VisitCallExpr(CallExpr *E) {
407 VisitExpr(E);
408 Record.push_back(E->getNumArgs());
409 Writer.AddSourceLocation(E->getRParenLoc(), Record);
410 Writer.WriteSubStmt(E->getCallee());
411 for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
412 Arg != ArgEnd; ++Arg)
413 Writer.WriteSubStmt(*Arg);
414 Code = pch::EXPR_CALL;
415}
416
417void PCHStmtWriter::VisitMemberExpr(MemberExpr *E) {
418 VisitExpr(E);
419 Writer.WriteSubStmt(E->getBase());
420 Writer.AddDeclRef(E->getMemberDecl(), Record);
421 Writer.AddSourceLocation(E->getMemberLoc(), Record);
422 Record.push_back(E->isArrow());
Douglas Gregorf4b34ba2009-08-31 23:44:04 +0000423 // FIXME: C++ nested-name-specifier
Douglas Gregor84f14dd2009-09-01 00:37:14 +0000424 // FIXME: C++ template argument list
Chris Lattner1f551822009-04-27 06:20:01 +0000425 Code = pch::EXPR_MEMBER;
426}
427
Steve Naroffe87026a2009-07-24 17:54:45 +0000428void PCHStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
429 VisitExpr(E);
430 Writer.WriteSubStmt(E->getBase());
431 Writer.AddSourceLocation(E->getIsaMemberLoc(), Record);
432 Record.push_back(E->isArrow());
433 Code = pch::EXPR_OBJC_ISA;
434}
435
Chris Lattner1f551822009-04-27 06:20:01 +0000436void PCHStmtWriter::VisitCastExpr(CastExpr *E) {
437 VisitExpr(E);
438 Writer.WriteSubStmt(E->getSubExpr());
Anders Carlssona2615922009-07-31 00:48:10 +0000439 Record.push_back(E->getCastKind()); // FIXME: stable encoding
Chris Lattner1f551822009-04-27 06:20:01 +0000440}
441
442void PCHStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
443 VisitExpr(E);
444 Writer.WriteSubStmt(E->getLHS());
445 Writer.WriteSubStmt(E->getRHS());
446 Record.push_back(E->getOpcode()); // FIXME: stable encoding
447 Writer.AddSourceLocation(E->getOperatorLoc(), Record);
448 Code = pch::EXPR_BINARY_OPERATOR;
449}
450
451void PCHStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
452 VisitBinaryOperator(E);
453 Writer.AddTypeRef(E->getComputationLHSType(), Record);
454 Writer.AddTypeRef(E->getComputationResultType(), Record);
455 Code = pch::EXPR_COMPOUND_ASSIGN_OPERATOR;
456}
457
458void PCHStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
459 VisitExpr(E);
460 Writer.WriteSubStmt(E->getCond());
461 Writer.WriteSubStmt(E->getLHS());
462 Writer.WriteSubStmt(E->getRHS());
Douglas Gregor7e112b02009-08-26 14:37:04 +0000463 Writer.AddSourceLocation(E->getQuestionLoc(), Record);
464 Writer.AddSourceLocation(E->getColonLoc(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000465 Code = pch::EXPR_CONDITIONAL_OPERATOR;
466}
467
468void PCHStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
469 VisitCastExpr(E);
470 Record.push_back(E->isLvalueCast());
471 Code = pch::EXPR_IMPLICIT_CAST;
472}
473
474void PCHStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
475 VisitCastExpr(E);
476 Writer.AddTypeRef(E->getTypeAsWritten(), Record);
477}
478
479void PCHStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
480 VisitExplicitCastExpr(E);
481 Writer.AddSourceLocation(E->getLParenLoc(), Record);
482 Writer.AddSourceLocation(E->getRParenLoc(), Record);
483 Code = pch::EXPR_CSTYLE_CAST;
484}
485
486void PCHStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
487 VisitExpr(E);
488 Writer.AddSourceLocation(E->getLParenLoc(), Record);
489 Writer.WriteSubStmt(E->getInitializer());
490 Record.push_back(E->isFileScope());
491 Code = pch::EXPR_COMPOUND_LITERAL;
492}
493
494void PCHStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
495 VisitExpr(E);
496 Writer.WriteSubStmt(E->getBase());
497 Writer.AddIdentifierRef(&E->getAccessor(), Record);
498 Writer.AddSourceLocation(E->getAccessorLoc(), Record);
499 Code = pch::EXPR_EXT_VECTOR_ELEMENT;
500}
501
502void PCHStmtWriter::VisitInitListExpr(InitListExpr *E) {
503 VisitExpr(E);
504 Record.push_back(E->getNumInits());
505 for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
506 Writer.WriteSubStmt(E->getInit(I));
507 Writer.WriteSubStmt(E->getSyntacticForm());
508 Writer.AddSourceLocation(E->getLBraceLoc(), Record);
509 Writer.AddSourceLocation(E->getRBraceLoc(), Record);
510 Writer.AddDeclRef(E->getInitializedFieldInUnion(), Record);
511 Record.push_back(E->hadArrayRangeDesignator());
512 Code = pch::EXPR_INIT_LIST;
513}
514
515void PCHStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
516 VisitExpr(E);
517 Record.push_back(E->getNumSubExprs());
518 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
519 Writer.WriteSubStmt(E->getSubExpr(I));
520 Writer.AddSourceLocation(E->getEqualOrColonLoc(), Record);
521 Record.push_back(E->usesGNUSyntax());
522 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
523 DEnd = E->designators_end();
524 D != DEnd; ++D) {
525 if (D->isFieldDesignator()) {
526 if (FieldDecl *Field = D->getField()) {
527 Record.push_back(pch::DESIG_FIELD_DECL);
528 Writer.AddDeclRef(Field, Record);
529 } else {
530 Record.push_back(pch::DESIG_FIELD_NAME);
531 Writer.AddIdentifierRef(D->getFieldName(), Record);
532 }
533 Writer.AddSourceLocation(D->getDotLoc(), Record);
534 Writer.AddSourceLocation(D->getFieldLoc(), Record);
535 } else if (D->isArrayDesignator()) {
536 Record.push_back(pch::DESIG_ARRAY);
537 Record.push_back(D->getFirstExprIndex());
538 Writer.AddSourceLocation(D->getLBracketLoc(), Record);
539 Writer.AddSourceLocation(D->getRBracketLoc(), Record);
540 } else {
541 assert(D->isArrayRangeDesignator() && "Unknown designator");
542 Record.push_back(pch::DESIG_ARRAY_RANGE);
543 Record.push_back(D->getFirstExprIndex());
544 Writer.AddSourceLocation(D->getLBracketLoc(), Record);
545 Writer.AddSourceLocation(D->getEllipsisLoc(), Record);
546 Writer.AddSourceLocation(D->getRBracketLoc(), Record);
547 }
548 }
549 Code = pch::EXPR_DESIGNATED_INIT;
550}
551
552void PCHStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
553 VisitExpr(E);
554 Code = pch::EXPR_IMPLICIT_VALUE_INIT;
555}
556
557void PCHStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
558 VisitExpr(E);
559 Writer.WriteSubStmt(E->getSubExpr());
560 Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
561 Writer.AddSourceLocation(E->getRParenLoc(), Record);
562 Code = pch::EXPR_VA_ARG;
563}
564
565void PCHStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
566 VisitExpr(E);
567 Writer.AddSourceLocation(E->getAmpAmpLoc(), Record);
568 Writer.AddSourceLocation(E->getLabelLoc(), Record);
569 Record.push_back(Writer.GetLabelID(E->getLabel()));
570 Code = pch::EXPR_ADDR_LABEL;
571}
572
573void PCHStmtWriter::VisitStmtExpr(StmtExpr *E) {
574 VisitExpr(E);
575 Writer.WriteSubStmt(E->getSubStmt());
576 Writer.AddSourceLocation(E->getLParenLoc(), Record);
577 Writer.AddSourceLocation(E->getRParenLoc(), Record);
578 Code = pch::EXPR_STMT;
579}
580
581void PCHStmtWriter::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) {
582 VisitExpr(E);
583 Writer.AddTypeRef(E->getArgType1(), Record);
584 Writer.AddTypeRef(E->getArgType2(), Record);
585 Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
586 Writer.AddSourceLocation(E->getRParenLoc(), Record);
587 Code = pch::EXPR_TYPES_COMPATIBLE;
588}
589
590void PCHStmtWriter::VisitChooseExpr(ChooseExpr *E) {
591 VisitExpr(E);
592 Writer.WriteSubStmt(E->getCond());
593 Writer.WriteSubStmt(E->getLHS());
594 Writer.WriteSubStmt(E->getRHS());
595 Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
596 Writer.AddSourceLocation(E->getRParenLoc(), Record);
597 Code = pch::EXPR_CHOOSE;
598}
599
600void PCHStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
601 VisitExpr(E);
602 Writer.AddSourceLocation(E->getTokenLocation(), Record);
603 Code = pch::EXPR_GNU_NULL;
604}
605
606void PCHStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
607 VisitExpr(E);
608 Record.push_back(E->getNumSubExprs());
609 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
610 Writer.WriteSubStmt(E->getExpr(I));
611 Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
612 Writer.AddSourceLocation(E->getRParenLoc(), Record);
613 Code = pch::EXPR_SHUFFLE_VECTOR;
614}
615
616void PCHStmtWriter::VisitBlockExpr(BlockExpr *E) {
617 VisitExpr(E);
618 Writer.AddDeclRef(E->getBlockDecl(), Record);
619 Record.push_back(E->hasBlockDeclRefExprs());
620 Code = pch::EXPR_BLOCK;
621}
622
623void PCHStmtWriter::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
624 VisitExpr(E);
625 Writer.AddDeclRef(E->getDecl(), Record);
626 Writer.AddSourceLocation(E->getLocation(), Record);
627 Record.push_back(E->isByRef());
Fariborz Jahaniane8918d52009-06-20 00:02:26 +0000628 Record.push_back(E->isConstQualAdded());
Chris Lattner1f551822009-04-27 06:20:01 +0000629 Code = pch::EXPR_BLOCK_DECL_REF;
630}
631
632//===----------------------------------------------------------------------===//
633// Objective-C Expressions and Statements.
634//===----------------------------------------------------------------------===//
635
636void PCHStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
637 VisitExpr(E);
638 Writer.WriteSubStmt(E->getString());
639 Writer.AddSourceLocation(E->getAtLoc(), Record);
640 Code = pch::EXPR_OBJC_STRING_LITERAL;
641}
642
Mike Stump11289f42009-09-09 15:08:12 +0000643void PCHStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
Chris Lattner1f551822009-04-27 06:20:01 +0000644 VisitExpr(E);
645 Writer.AddTypeRef(E->getEncodedType(), Record);
646 Writer.AddSourceLocation(E->getAtLoc(), Record);
647 Writer.AddSourceLocation(E->getRParenLoc(), Record);
648 Code = pch::EXPR_OBJC_ENCODE;
649}
650
651void PCHStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
652 VisitExpr(E);
653 Writer.AddSelectorRef(E->getSelector(), Record);
654 Writer.AddSourceLocation(E->getAtLoc(), Record);
655 Writer.AddSourceLocation(E->getRParenLoc(), Record);
656 Code = pch::EXPR_OBJC_SELECTOR_EXPR;
657}
658
659void PCHStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
660 VisitExpr(E);
661 Writer.AddDeclRef(E->getProtocol(), Record);
662 Writer.AddSourceLocation(E->getAtLoc(), Record);
663 Writer.AddSourceLocation(E->getRParenLoc(), Record);
664 Code = pch::EXPR_OBJC_PROTOCOL_EXPR;
665}
666
667void PCHStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
668 VisitExpr(E);
669 Writer.AddDeclRef(E->getDecl(), Record);
670 Writer.AddSourceLocation(E->getLocation(), Record);
671 Writer.WriteSubStmt(E->getBase());
672 Record.push_back(E->isArrow());
673 Record.push_back(E->isFreeIvar());
674 Code = pch::EXPR_OBJC_IVAR_REF_EXPR;
675}
676
677void PCHStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
678 VisitExpr(E);
679 Writer.AddDeclRef(E->getProperty(), Record);
680 Writer.AddSourceLocation(E->getLocation(), Record);
681 Writer.WriteSubStmt(E->getBase());
682 Code = pch::EXPR_OBJC_PROPERTY_REF_EXPR;
683}
684
Fariborz Jahanian9a846652009-08-20 17:02:02 +0000685void PCHStmtWriter::VisitObjCImplicitSetterGetterRefExpr(
686 ObjCImplicitSetterGetterRefExpr *E) {
Chris Lattner1f551822009-04-27 06:20:01 +0000687 VisitExpr(E);
688 Writer.AddDeclRef(E->getGetterMethod(), Record);
689 Writer.AddDeclRef(E->getSetterMethod(), Record);
Mike Stump11289f42009-09-09 15:08:12 +0000690
Fariborz Jahanian19380c42009-08-18 21:37:33 +0000691 // NOTE: InterfaceDecl and Base are mutually exclusive.
692 Writer.AddDeclRef(E->getInterfaceDecl(), Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000693 Writer.WriteSubStmt(E->getBase());
694 Writer.AddSourceLocation(E->getLocation(), Record);
695 Writer.AddSourceLocation(E->getClassLoc(), Record);
696 Code = pch::EXPR_OBJC_KVC_REF_EXPR;
697}
698
699void PCHStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
700 VisitExpr(E);
701 Record.push_back(E->getNumArgs());
702 Writer.AddSourceLocation(E->getLeftLoc(), Record);
703 Writer.AddSourceLocation(E->getRightLoc(), Record);
704 Writer.AddSelectorRef(E->getSelector(), Record);
705 Writer.AddDeclRef(E->getMethodDecl(), Record); // optional
706 Writer.WriteSubStmt(E->getReceiver());
707
708 if (!E->getReceiver()) {
709 ObjCMessageExpr::ClassInfo CI = E->getClassInfo();
710 Writer.AddDeclRef(CI.first, Record);
711 Writer.AddIdentifierRef(CI.second, Record);
712 }
713
714 for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
715 Arg != ArgEnd; ++Arg)
716 Writer.WriteSubStmt(*Arg);
717 Code = pch::EXPR_OBJC_MESSAGE_EXPR;
718}
719
720void PCHStmtWriter::VisitObjCSuperExpr(ObjCSuperExpr *E) {
721 VisitExpr(E);
722 Writer.AddSourceLocation(E->getLoc(), Record);
723 Code = pch::EXPR_OBJC_SUPER_EXPR;
724}
725
726void PCHStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
727 VisitStmt(S);
728 Writer.WriteSubStmt(S->getElement());
729 Writer.WriteSubStmt(S->getCollection());
730 Writer.WriteSubStmt(S->getBody());
731 Writer.AddSourceLocation(S->getForLoc(), Record);
732 Writer.AddSourceLocation(S->getRParenLoc(), Record);
733 Code = pch::STMT_OBJC_FOR_COLLECTION;
734}
735
736void PCHStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
737 Writer.WriteSubStmt(S->getCatchBody());
738 Writer.WriteSubStmt(S->getNextCatchStmt());
739 Writer.AddDeclRef(S->getCatchParamDecl(), Record);
740 Writer.AddSourceLocation(S->getAtCatchLoc(), Record);
741 Writer.AddSourceLocation(S->getRParenLoc(), Record);
742 Code = pch::STMT_OBJC_CATCH;
743}
744
745void PCHStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
746 Writer.WriteSubStmt(S->getFinallyBody());
747 Writer.AddSourceLocation(S->getAtFinallyLoc(), Record);
748 Code = pch::STMT_OBJC_FINALLY;
749}
750
751void PCHStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
752 Writer.WriteSubStmt(S->getTryBody());
753 Writer.WriteSubStmt(S->getCatchStmts());
754 Writer.WriteSubStmt(S->getFinallyStmt());
755 Writer.AddSourceLocation(S->getAtTryLoc(), Record);
756 Code = pch::STMT_OBJC_AT_TRY;
757}
758
759void PCHStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
760 Writer.WriteSubStmt(S->getSynchExpr());
761 Writer.WriteSubStmt(S->getSynchBody());
762 Writer.AddSourceLocation(S->getAtSynchronizedLoc(), Record);
763 Code = pch::STMT_OBJC_AT_SYNCHRONIZED;
764}
765
766void PCHStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
767 Writer.WriteSubStmt(S->getThrowExpr());
768 Writer.AddSourceLocation(S->getThrowLoc(), Record);
769 Code = pch::STMT_OBJC_AT_THROW;
770}
771
772//===----------------------------------------------------------------------===//
Argyrios Kyrtzidiseeaaead2009-07-14 03:19:21 +0000773// C++ Expressions and Statements.
774//===----------------------------------------------------------------------===//
775
776void PCHStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
777 VisitCallExpr(E);
778 Record.push_back(E->getOperator());
779 Code = pch::EXPR_CXX_OPERATOR_CALL;
780}
781
Douglas Gregor5d3507d2009-09-09 23:08:42 +0000782void PCHStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
783 VisitExpr(E);
784 Writer.AddDeclRef(E->getConstructor(), Record);
785 Record.push_back(E->isElidable());
786 Record.push_back(E->getNumArgs());
787 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
788 Writer.WriteSubStmt(E->getArg(I));
789 Code = pch::EXPR_CXX_CONSTRUCT;
790}
791
Argyrios Kyrtzidiseeaaead2009-07-14 03:19:21 +0000792//===----------------------------------------------------------------------===//
Chris Lattner1f551822009-04-27 06:20:01 +0000793// PCHWriter Implementation
794//===----------------------------------------------------------------------===//
795
796unsigned PCHWriter::RecordSwitchCaseID(SwitchCase *S) {
Mike Stump11289f42009-09-09 15:08:12 +0000797 assert(SwitchCaseIDs.find(S) == SwitchCaseIDs.end() &&
Chris Lattner1f551822009-04-27 06:20:01 +0000798 "SwitchCase recorded twice");
799 unsigned NextID = SwitchCaseIDs.size();
800 SwitchCaseIDs[S] = NextID;
801 return NextID;
802}
803
804unsigned PCHWriter::getSwitchCaseID(SwitchCase *S) {
Mike Stump11289f42009-09-09 15:08:12 +0000805 assert(SwitchCaseIDs.find(S) != SwitchCaseIDs.end() &&
Chris Lattner1f551822009-04-27 06:20:01 +0000806 "SwitchCase hasn't been seen yet");
807 return SwitchCaseIDs[S];
808}
809
810/// \brief Retrieve the ID for the given label statement, which may
811/// or may not have been emitted yet.
812unsigned PCHWriter::GetLabelID(LabelStmt *S) {
813 std::map<LabelStmt *, unsigned>::iterator Pos = LabelIDs.find(S);
814 if (Pos != LabelIDs.end())
815 return Pos->second;
Mike Stump11289f42009-09-09 15:08:12 +0000816
Chris Lattner1f551822009-04-27 06:20:01 +0000817 unsigned NextID = LabelIDs.size();
818 LabelIDs[S] = NextID;
819 return NextID;
820}
821
822/// \brief Write the given substatement or subexpression to the
823/// bitstream.
824void PCHWriter::WriteSubStmt(Stmt *S) {
825 RecordData Record;
826 PCHStmtWriter Writer(*this, Record);
827 ++NumStatements;
Mike Stump11289f42009-09-09 15:08:12 +0000828
Chris Lattner1f551822009-04-27 06:20:01 +0000829 if (!S) {
830 Stream.EmitRecord(pch::STMT_NULL_PTR, Record);
831 return;
832 }
Mike Stump11289f42009-09-09 15:08:12 +0000833
Chris Lattner1f551822009-04-27 06:20:01 +0000834 Writer.Code = pch::STMT_NULL_PTR;
835 Writer.Visit(S);
Mike Stump11289f42009-09-09 15:08:12 +0000836 assert(Writer.Code != pch::STMT_NULL_PTR &&
Chris Lattner1f551822009-04-27 06:20:01 +0000837 "Unhandled expression writing PCH file");
Mike Stump11289f42009-09-09 15:08:12 +0000838 Stream.EmitRecord(Writer.Code, Record);
Chris Lattner1f551822009-04-27 06:20:01 +0000839}
840
841/// \brief Flush all of the statements that have been added to the
842/// queue via AddStmt().
843void PCHWriter::FlushStmts() {
844 RecordData Record;
845 PCHStmtWriter Writer(*this, Record);
Mike Stump11289f42009-09-09 15:08:12 +0000846
Chris Lattner1f551822009-04-27 06:20:01 +0000847 for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
848 ++NumStatements;
849 Stmt *S = StmtsToEmit[I];
Mike Stump11289f42009-09-09 15:08:12 +0000850
Chris Lattner1f551822009-04-27 06:20:01 +0000851 if (!S) {
852 Stream.EmitRecord(pch::STMT_NULL_PTR, Record);
853 continue;
854 }
Mike Stump11289f42009-09-09 15:08:12 +0000855
Chris Lattner1f551822009-04-27 06:20:01 +0000856 Writer.Code = pch::STMT_NULL_PTR;
857 Writer.Visit(S);
Mike Stump11289f42009-09-09 15:08:12 +0000858 assert(Writer.Code != pch::STMT_NULL_PTR &&
Chris Lattner1f551822009-04-27 06:20:01 +0000859 "Unhandled expression writing PCH file");
Mike Stump11289f42009-09-09 15:08:12 +0000860 Stream.EmitRecord(Writer.Code, Record);
861
862 assert(N == StmtsToEmit.size() &&
Chris Lattner1f551822009-04-27 06:20:01 +0000863 "Substatement writen via AddStmt rather than WriteSubStmt!");
Mike Stump11289f42009-09-09 15:08:12 +0000864
Chris Lattner1f551822009-04-27 06:20:01 +0000865 // Note that we are at the end of a full expression. Any
866 // expression records that follow this one are part of a different
867 // expression.
868 Record.clear();
869 Stream.EmitRecord(pch::STMT_STOP, Record);
870 }
Mike Stump11289f42009-09-09 15:08:12 +0000871
Chris Lattner1f551822009-04-27 06:20:01 +0000872 StmtsToEmit.clear();
Chris Lattner1f551822009-04-27 06:20:01 +0000873}