]> CyberLeo.Net >> Repos - FreeBSD/releng/9.1.git/blob - contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp
Copy stable/9 to releng/9.1 as part of the 9.1-RELEASE release process.
[FreeBSD/releng/9.1.git] / contrib / llvm / tools / clang / lib / AST / StmtProfile.cpp
1 //===---- StmtProfile.cpp - Profile implementation for Stmt ASTs ----------===//
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 the Stmt::Profile method, which builds a unique bit
11 // representation that identifies a statement/expression.
12 //
13 //===----------------------------------------------------------------------===//
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/DeclCXX.h"
16 #include "clang/AST/DeclObjC.h"
17 #include "clang/AST/DeclTemplate.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/ExprCXX.h"
20 #include "clang/AST/ExprObjC.h"
21 #include "clang/AST/StmtVisitor.h"
22 #include "llvm/ADT/FoldingSet.h"
23 using namespace clang;
24
25 namespace {
26   class StmtProfiler : public ConstStmtVisitor<StmtProfiler> {
27     llvm::FoldingSetNodeID &ID;
28     const ASTContext &Context;
29     bool Canonical;
30
31   public:
32     StmtProfiler(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
33                  bool Canonical)
34       : ID(ID), Context(Context), Canonical(Canonical) { }
35
36     void VisitStmt(const Stmt *S);
37
38 #define STMT(Node, Base) void Visit##Node(const Node *S);
39 #include "clang/AST/StmtNodes.inc"
40
41     /// \brief Visit a declaration that is referenced within an expression
42     /// or statement.
43     void VisitDecl(const Decl *D);
44
45     /// \brief Visit a type that is referenced within an expression or
46     /// statement.
47     void VisitType(QualType T);
48
49     /// \brief Visit a name that occurs within an expression or statement.
50     void VisitName(DeclarationName Name);
51
52     /// \brief Visit a nested-name-specifier that occurs within an expression
53     /// or statement.
54     void VisitNestedNameSpecifier(NestedNameSpecifier *NNS);
55
56     /// \brief Visit a template name that occurs within an expression or
57     /// statement.
58     void VisitTemplateName(TemplateName Name);
59
60     /// \brief Visit template arguments that occur within an expression or
61     /// statement.
62     void VisitTemplateArguments(const TemplateArgumentLoc *Args,
63                                 unsigned NumArgs);
64
65     /// \brief Visit a single template argument.
66     void VisitTemplateArgument(const TemplateArgument &Arg);
67   };
68 }
69
70 void StmtProfiler::VisitStmt(const Stmt *S) {
71   ID.AddInteger(S->getStmtClass());
72   for (Stmt::const_child_range C = S->children(); C; ++C) {
73     if (*C)
74       Visit(*C);
75     else
76       ID.AddInteger(0);
77   }
78 }
79
80 void StmtProfiler::VisitDeclStmt(const DeclStmt *S) {
81   VisitStmt(S);
82   for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
83        D != DEnd; ++D)
84     VisitDecl(*D);
85 }
86
87 void StmtProfiler::VisitNullStmt(const NullStmt *S) {
88   VisitStmt(S);
89 }
90
91 void StmtProfiler::VisitCompoundStmt(const CompoundStmt *S) {
92   VisitStmt(S);
93 }
94
95 void StmtProfiler::VisitSwitchCase(const SwitchCase *S) {
96   VisitStmt(S);
97 }
98
99 void StmtProfiler::VisitCaseStmt(const CaseStmt *S) {
100   VisitStmt(S);
101 }
102
103 void StmtProfiler::VisitDefaultStmt(const DefaultStmt *S) {
104   VisitStmt(S);
105 }
106
107 void StmtProfiler::VisitLabelStmt(const LabelStmt *S) {
108   VisitStmt(S);
109   VisitDecl(S->getDecl());
110 }
111
112 void StmtProfiler::VisitAttributedStmt(const AttributedStmt *S) {
113   VisitStmt(S);
114   // TODO: maybe visit attributes?
115 }
116
117 void StmtProfiler::VisitIfStmt(const IfStmt *S) {
118   VisitStmt(S);
119   VisitDecl(S->getConditionVariable());
120 }
121
122 void StmtProfiler::VisitSwitchStmt(const SwitchStmt *S) {
123   VisitStmt(S);
124   VisitDecl(S->getConditionVariable());
125 }
126
127 void StmtProfiler::VisitWhileStmt(const WhileStmt *S) {
128   VisitStmt(S);
129   VisitDecl(S->getConditionVariable());
130 }
131
132 void StmtProfiler::VisitDoStmt(const DoStmt *S) {
133   VisitStmt(S);
134 }
135
136 void StmtProfiler::VisitForStmt(const ForStmt *S) {
137   VisitStmt(S);
138 }
139
140 void StmtProfiler::VisitGotoStmt(const GotoStmt *S) {
141   VisitStmt(S);
142   VisitDecl(S->getLabel());
143 }
144
145 void StmtProfiler::VisitIndirectGotoStmt(const IndirectGotoStmt *S) {
146   VisitStmt(S);
147 }
148
149 void StmtProfiler::VisitContinueStmt(const ContinueStmt *S) {
150   VisitStmt(S);
151 }
152
153 void StmtProfiler::VisitBreakStmt(const BreakStmt *S) {
154   VisitStmt(S);
155 }
156
157 void StmtProfiler::VisitReturnStmt(const ReturnStmt *S) {
158   VisitStmt(S);
159 }
160
161 void StmtProfiler::VisitAsmStmt(const AsmStmt *S) {
162   VisitStmt(S);
163   ID.AddBoolean(S->isVolatile());
164   ID.AddBoolean(S->isSimple());
165   VisitStringLiteral(S->getAsmString());
166   ID.AddInteger(S->getNumOutputs());
167   for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
168     ID.AddString(S->getOutputName(I));
169     VisitStringLiteral(S->getOutputConstraintLiteral(I));
170   }
171   ID.AddInteger(S->getNumInputs());
172   for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
173     ID.AddString(S->getInputName(I));
174     VisitStringLiteral(S->getInputConstraintLiteral(I));
175   }
176   ID.AddInteger(S->getNumClobbers());
177   for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
178     VisitStringLiteral(S->getClobber(I));
179 }
180
181 void StmtProfiler::VisitCXXCatchStmt(const CXXCatchStmt *S) {
182   VisitStmt(S);
183   VisitType(S->getCaughtType());
184 }
185
186 void StmtProfiler::VisitCXXTryStmt(const CXXTryStmt *S) {
187   VisitStmt(S);
188 }
189
190 void StmtProfiler::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
191   VisitStmt(S);
192 }
193
194 void StmtProfiler::VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
195   VisitStmt(S);
196   ID.AddBoolean(S->isIfExists());
197   VisitNestedNameSpecifier(S->getQualifierLoc().getNestedNameSpecifier());
198   VisitName(S->getNameInfo().getName());
199 }
200
201 void StmtProfiler::VisitSEHTryStmt(const SEHTryStmt *S) {
202   VisitStmt(S);
203 }
204
205 void StmtProfiler::VisitSEHFinallyStmt(const SEHFinallyStmt *S) {
206   VisitStmt(S);
207 }
208
209 void StmtProfiler::VisitSEHExceptStmt(const SEHExceptStmt *S) {
210   VisitStmt(S);
211 }
212
213 void StmtProfiler::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
214   VisitStmt(S);
215 }
216
217 void StmtProfiler::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *S) {
218   VisitStmt(S);
219   ID.AddBoolean(S->hasEllipsis());
220   if (S->getCatchParamDecl())
221     VisitType(S->getCatchParamDecl()->getType());
222 }
223
224 void StmtProfiler::VisitObjCAtFinallyStmt(const ObjCAtFinallyStmt *S) {
225   VisitStmt(S);
226 }
227
228 void StmtProfiler::VisitObjCAtTryStmt(const ObjCAtTryStmt *S) {
229   VisitStmt(S);
230 }
231
232 void
233 StmtProfiler::VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S) {
234   VisitStmt(S);
235 }
236
237 void StmtProfiler::VisitObjCAtThrowStmt(const ObjCAtThrowStmt *S) {
238   VisitStmt(S);
239 }
240
241 void
242 StmtProfiler::VisitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt *S) {
243   VisitStmt(S);
244 }
245
246 void StmtProfiler::VisitExpr(const Expr *S) {
247   VisitStmt(S);
248 }
249
250 void StmtProfiler::VisitDeclRefExpr(const DeclRefExpr *S) {
251   VisitExpr(S);
252   if (!Canonical)
253     VisitNestedNameSpecifier(S->getQualifier());
254   VisitDecl(S->getDecl());
255   if (!Canonical)
256     VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
257 }
258
259 void StmtProfiler::VisitPredefinedExpr(const PredefinedExpr *S) {
260   VisitExpr(S);
261   ID.AddInteger(S->getIdentType());
262 }
263
264 void StmtProfiler::VisitIntegerLiteral(const IntegerLiteral *S) {
265   VisitExpr(S);
266   S->getValue().Profile(ID);
267 }
268
269 void StmtProfiler::VisitCharacterLiteral(const CharacterLiteral *S) {
270   VisitExpr(S);
271   ID.AddInteger(S->getKind());
272   ID.AddInteger(S->getValue());
273 }
274
275 void StmtProfiler::VisitFloatingLiteral(const FloatingLiteral *S) {
276   VisitExpr(S);
277   S->getValue().Profile(ID);
278   ID.AddBoolean(S->isExact());
279 }
280
281 void StmtProfiler::VisitImaginaryLiteral(const ImaginaryLiteral *S) {
282   VisitExpr(S);
283 }
284
285 void StmtProfiler::VisitStringLiteral(const StringLiteral *S) {
286   VisitExpr(S);
287   ID.AddString(S->getBytes());
288   ID.AddInteger(S->getKind());
289 }
290
291 void StmtProfiler::VisitParenExpr(const ParenExpr *S) {
292   VisitExpr(S);
293 }
294
295 void StmtProfiler::VisitParenListExpr(const ParenListExpr *S) {
296   VisitExpr(S);
297 }
298
299 void StmtProfiler::VisitUnaryOperator(const UnaryOperator *S) {
300   VisitExpr(S);
301   ID.AddInteger(S->getOpcode());
302 }
303
304 void StmtProfiler::VisitOffsetOfExpr(const OffsetOfExpr *S) {
305   VisitType(S->getTypeSourceInfo()->getType());
306   unsigned n = S->getNumComponents();
307   for (unsigned i = 0; i < n; ++i) {
308     const OffsetOfExpr::OffsetOfNode& ON = S->getComponent(i);
309     ID.AddInteger(ON.getKind());
310     switch (ON.getKind()) {
311     case OffsetOfExpr::OffsetOfNode::Array:
312       // Expressions handled below.
313       break;
314
315     case OffsetOfExpr::OffsetOfNode::Field:
316       VisitDecl(ON.getField());
317       break;
318
319     case OffsetOfExpr::OffsetOfNode::Identifier:
320       ID.AddPointer(ON.getFieldName());
321       break;
322         
323     case OffsetOfExpr::OffsetOfNode::Base:
324       // These nodes are implicit, and therefore don't need profiling.
325       break;
326     }
327   }
328   
329   VisitExpr(S);
330 }
331
332 void
333 StmtProfiler::VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *S) {
334   VisitExpr(S);
335   ID.AddInteger(S->getKind());
336   if (S->isArgumentType())
337     VisitType(S->getArgumentType());
338 }
339
340 void StmtProfiler::VisitArraySubscriptExpr(const ArraySubscriptExpr *S) {
341   VisitExpr(S);
342 }
343
344 void StmtProfiler::VisitCallExpr(const CallExpr *S) {
345   VisitExpr(S);
346 }
347
348 void StmtProfiler::VisitMemberExpr(const MemberExpr *S) {
349   VisitExpr(S);
350   VisitDecl(S->getMemberDecl());
351   if (!Canonical)
352     VisitNestedNameSpecifier(S->getQualifier());
353   ID.AddBoolean(S->isArrow());
354 }
355
356 void StmtProfiler::VisitCompoundLiteralExpr(const CompoundLiteralExpr *S) {
357   VisitExpr(S);
358   ID.AddBoolean(S->isFileScope());
359 }
360
361 void StmtProfiler::VisitCastExpr(const CastExpr *S) {
362   VisitExpr(S);
363 }
364
365 void StmtProfiler::VisitImplicitCastExpr(const ImplicitCastExpr *S) {
366   VisitCastExpr(S);
367   ID.AddInteger(S->getValueKind());
368 }
369
370 void StmtProfiler::VisitExplicitCastExpr(const ExplicitCastExpr *S) {
371   VisitCastExpr(S);
372   VisitType(S->getTypeAsWritten());
373 }
374
375 void StmtProfiler::VisitCStyleCastExpr(const CStyleCastExpr *S) {
376   VisitExplicitCastExpr(S);
377 }
378
379 void StmtProfiler::VisitBinaryOperator(const BinaryOperator *S) {
380   VisitExpr(S);
381   ID.AddInteger(S->getOpcode());
382 }
383
384 void
385 StmtProfiler::VisitCompoundAssignOperator(const CompoundAssignOperator *S) {
386   VisitBinaryOperator(S);
387 }
388
389 void StmtProfiler::VisitConditionalOperator(const ConditionalOperator *S) {
390   VisitExpr(S);
391 }
392
393 void StmtProfiler::VisitBinaryConditionalOperator(
394     const BinaryConditionalOperator *S) {
395   VisitExpr(S);
396 }
397
398 void StmtProfiler::VisitAddrLabelExpr(const AddrLabelExpr *S) {
399   VisitExpr(S);
400   VisitDecl(S->getLabel());
401 }
402
403 void StmtProfiler::VisitStmtExpr(const StmtExpr *S) {
404   VisitExpr(S);
405 }
406
407 void StmtProfiler::VisitShuffleVectorExpr(const ShuffleVectorExpr *S) {
408   VisitExpr(S);
409 }
410
411 void StmtProfiler::VisitChooseExpr(const ChooseExpr *S) {
412   VisitExpr(S);
413 }
414
415 void StmtProfiler::VisitGNUNullExpr(const GNUNullExpr *S) {
416   VisitExpr(S);
417 }
418
419 void StmtProfiler::VisitVAArgExpr(const VAArgExpr *S) {
420   VisitExpr(S);
421 }
422
423 void StmtProfiler::VisitInitListExpr(const InitListExpr *S) {
424   if (S->getSyntacticForm()) {
425     VisitInitListExpr(S->getSyntacticForm());
426     return;
427   }
428
429   VisitExpr(S);
430 }
431
432 void StmtProfiler::VisitDesignatedInitExpr(const DesignatedInitExpr *S) {
433   VisitExpr(S);
434   ID.AddBoolean(S->usesGNUSyntax());
435   for (DesignatedInitExpr::const_designators_iterator D =
436          S->designators_begin(), DEnd = S->designators_end();
437        D != DEnd; ++D) {
438     if (D->isFieldDesignator()) {
439       ID.AddInteger(0);
440       VisitName(D->getFieldName());
441       continue;
442     }
443
444     if (D->isArrayDesignator()) {
445       ID.AddInteger(1);
446     } else {
447       assert(D->isArrayRangeDesignator());
448       ID.AddInteger(2);
449     }
450     ID.AddInteger(D->getFirstExprIndex());
451   }
452 }
453
454 void StmtProfiler::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *S) {
455   VisitExpr(S);
456 }
457
458 void StmtProfiler::VisitExtVectorElementExpr(const ExtVectorElementExpr *S) {
459   VisitExpr(S);
460   VisitName(&S->getAccessor());
461 }
462
463 void StmtProfiler::VisitBlockExpr(const BlockExpr *S) {
464   VisitExpr(S);
465   VisitDecl(S->getBlockDecl());
466 }
467
468 void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr *S) {
469   VisitExpr(S);
470   for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
471     QualType T = S->getAssocType(i);
472     if (T.isNull())
473       ID.AddPointer(0);
474     else
475       VisitType(T);
476     VisitExpr(S->getAssocExpr(i));
477   }
478 }
479
480 void StmtProfiler::VisitPseudoObjectExpr(const PseudoObjectExpr *S) {
481   VisitExpr(S);
482   for (PseudoObjectExpr::const_semantics_iterator
483          i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i)
484     // Normally, we would not profile the source expressions of OVEs.
485     if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(*i))
486       Visit(OVE->getSourceExpr());
487 }
488
489 void StmtProfiler::VisitAtomicExpr(const AtomicExpr *S) {
490   VisitExpr(S);
491   ID.AddInteger(S->getOp());
492 }
493
494 static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
495                                           UnaryOperatorKind &UnaryOp,
496                                           BinaryOperatorKind &BinaryOp) {
497   switch (S->getOperator()) {
498   case OO_None:
499   case OO_New:
500   case OO_Delete:
501   case OO_Array_New:
502   case OO_Array_Delete:
503   case OO_Arrow:
504   case OO_Call:
505   case OO_Conditional:
506   case NUM_OVERLOADED_OPERATORS:
507     llvm_unreachable("Invalid operator call kind");
508       
509   case OO_Plus:
510     if (S->getNumArgs() == 1) {
511       UnaryOp = UO_Plus;
512       return Stmt::UnaryOperatorClass;
513     }
514     
515     BinaryOp = BO_Add;
516     return Stmt::BinaryOperatorClass;
517       
518   case OO_Minus:
519     if (S->getNumArgs() == 1) {
520       UnaryOp = UO_Minus;
521       return Stmt::UnaryOperatorClass;
522     }
523     
524     BinaryOp = BO_Sub;
525     return Stmt::BinaryOperatorClass;
526
527   case OO_Star:
528     if (S->getNumArgs() == 1) {
529       UnaryOp = UO_Minus;
530       return Stmt::UnaryOperatorClass;
531     }
532     
533     BinaryOp = BO_Sub;
534     return Stmt::BinaryOperatorClass;
535
536   case OO_Slash:
537     BinaryOp = BO_Div;
538     return Stmt::BinaryOperatorClass;
539       
540   case OO_Percent:
541     BinaryOp = BO_Rem;
542     return Stmt::BinaryOperatorClass;
543
544   case OO_Caret:
545     BinaryOp = BO_Xor;
546     return Stmt::BinaryOperatorClass;
547
548   case OO_Amp:
549     if (S->getNumArgs() == 1) {
550       UnaryOp = UO_AddrOf;
551       return Stmt::UnaryOperatorClass;
552     }
553     
554     BinaryOp = BO_And;
555     return Stmt::BinaryOperatorClass;
556       
557   case OO_Pipe:
558     BinaryOp = BO_Or;
559     return Stmt::BinaryOperatorClass;
560
561   case OO_Tilde:
562     UnaryOp = UO_Not;
563     return Stmt::UnaryOperatorClass;
564
565   case OO_Exclaim:
566     UnaryOp = UO_LNot;
567     return Stmt::UnaryOperatorClass;
568
569   case OO_Equal:
570     BinaryOp = BO_Assign;
571     return Stmt::BinaryOperatorClass;
572
573   case OO_Less:
574     BinaryOp = BO_LT;
575     return Stmt::BinaryOperatorClass;
576
577   case OO_Greater:
578     BinaryOp = BO_GT;
579     return Stmt::BinaryOperatorClass;
580       
581   case OO_PlusEqual:
582     BinaryOp = BO_AddAssign;
583     return Stmt::CompoundAssignOperatorClass;
584
585   case OO_MinusEqual:
586     BinaryOp = BO_SubAssign;
587     return Stmt::CompoundAssignOperatorClass;
588
589   case OO_StarEqual:
590     BinaryOp = BO_MulAssign;
591     return Stmt::CompoundAssignOperatorClass;
592
593   case OO_SlashEqual:
594     BinaryOp = BO_DivAssign;
595     return Stmt::CompoundAssignOperatorClass;
596
597   case OO_PercentEqual:
598     BinaryOp = BO_RemAssign;
599     return Stmt::CompoundAssignOperatorClass;
600
601   case OO_CaretEqual:
602     BinaryOp = BO_XorAssign;
603     return Stmt::CompoundAssignOperatorClass;
604     
605   case OO_AmpEqual:
606     BinaryOp = BO_AndAssign;
607     return Stmt::CompoundAssignOperatorClass;
608     
609   case OO_PipeEqual:
610     BinaryOp = BO_OrAssign;
611     return Stmt::CompoundAssignOperatorClass;
612       
613   case OO_LessLess:
614     BinaryOp = BO_Shl;
615     return Stmt::BinaryOperatorClass;
616     
617   case OO_GreaterGreater:
618     BinaryOp = BO_Shr;
619     return Stmt::BinaryOperatorClass;
620
621   case OO_LessLessEqual:
622     BinaryOp = BO_ShlAssign;
623     return Stmt::CompoundAssignOperatorClass;
624     
625   case OO_GreaterGreaterEqual:
626     BinaryOp = BO_ShrAssign;
627     return Stmt::CompoundAssignOperatorClass;
628
629   case OO_EqualEqual:
630     BinaryOp = BO_EQ;
631     return Stmt::BinaryOperatorClass;
632     
633   case OO_ExclaimEqual:
634     BinaryOp = BO_NE;
635     return Stmt::BinaryOperatorClass;
636       
637   case OO_LessEqual:
638     BinaryOp = BO_LE;
639     return Stmt::BinaryOperatorClass;
640     
641   case OO_GreaterEqual:
642     BinaryOp = BO_GE;
643     return Stmt::BinaryOperatorClass;
644       
645   case OO_AmpAmp:
646     BinaryOp = BO_LAnd;
647     return Stmt::BinaryOperatorClass;
648     
649   case OO_PipePipe:
650     BinaryOp = BO_LOr;
651     return Stmt::BinaryOperatorClass;
652
653   case OO_PlusPlus:
654     UnaryOp = S->getNumArgs() == 1? UO_PreInc 
655                                   : UO_PostInc;
656     return Stmt::UnaryOperatorClass;
657
658   case OO_MinusMinus:
659     UnaryOp = S->getNumArgs() == 1? UO_PreDec
660                                   : UO_PostDec;
661     return Stmt::UnaryOperatorClass;
662
663   case OO_Comma:
664     BinaryOp = BO_Comma;
665     return Stmt::BinaryOperatorClass;
666
667
668   case OO_ArrowStar:
669     BinaryOp = BO_PtrMemI;
670     return Stmt::BinaryOperatorClass;
671       
672   case OO_Subscript:
673     return Stmt::ArraySubscriptExprClass;
674   }
675   
676   llvm_unreachable("Invalid overloaded operator expression");
677 }
678                                
679
680 void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
681   if (S->isTypeDependent()) {
682     // Type-dependent operator calls are profiled like their underlying
683     // syntactic operator.
684     UnaryOperatorKind UnaryOp = UO_Extension;
685     BinaryOperatorKind BinaryOp = BO_Comma;
686     Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp);
687     
688     ID.AddInteger(SC);
689     for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
690       Visit(S->getArg(I));
691     if (SC == Stmt::UnaryOperatorClass)
692       ID.AddInteger(UnaryOp);
693     else if (SC == Stmt::BinaryOperatorClass || 
694              SC == Stmt::CompoundAssignOperatorClass)
695       ID.AddInteger(BinaryOp);
696     else
697       assert(SC == Stmt::ArraySubscriptExprClass);
698                     
699     return;
700   }
701   
702   VisitCallExpr(S);
703   ID.AddInteger(S->getOperator());
704 }
705
706 void StmtProfiler::VisitCXXMemberCallExpr(const CXXMemberCallExpr *S) {
707   VisitCallExpr(S);
708 }
709
710 void StmtProfiler::VisitCUDAKernelCallExpr(const CUDAKernelCallExpr *S) {
711   VisitCallExpr(S);
712 }
713
714 void StmtProfiler::VisitAsTypeExpr(const AsTypeExpr *S) {
715   VisitExpr(S);
716 }
717
718 void StmtProfiler::VisitCXXNamedCastExpr(const CXXNamedCastExpr *S) {
719   VisitExplicitCastExpr(S);
720 }
721
722 void StmtProfiler::VisitCXXStaticCastExpr(const CXXStaticCastExpr *S) {
723   VisitCXXNamedCastExpr(S);
724 }
725
726 void StmtProfiler::VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *S) {
727   VisitCXXNamedCastExpr(S);
728 }
729
730 void
731 StmtProfiler::VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *S) {
732   VisitCXXNamedCastExpr(S);
733 }
734
735 void StmtProfiler::VisitCXXConstCastExpr(const CXXConstCastExpr *S) {
736   VisitCXXNamedCastExpr(S);
737 }
738
739 void StmtProfiler::VisitUserDefinedLiteral(const UserDefinedLiteral *S) {
740   VisitCallExpr(S);
741 }
742
743 void StmtProfiler::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *S) {
744   VisitExpr(S);
745   ID.AddBoolean(S->getValue());
746 }
747
748 void StmtProfiler::VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *S) {
749   VisitExpr(S);
750 }
751
752 void StmtProfiler::VisitCXXTypeidExpr(const CXXTypeidExpr *S) {
753   VisitExpr(S);
754   if (S->isTypeOperand())
755     VisitType(S->getTypeOperand());
756 }
757
758 void StmtProfiler::VisitCXXUuidofExpr(const CXXUuidofExpr *S) {
759   VisitExpr(S);
760   if (S->isTypeOperand())
761     VisitType(S->getTypeOperand());
762 }
763
764 void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr *S) {
765   VisitExpr(S);
766   ID.AddBoolean(S->isImplicit());
767 }
768
769 void StmtProfiler::VisitCXXThrowExpr(const CXXThrowExpr *S) {
770   VisitExpr(S);
771 }
772
773 void StmtProfiler::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *S) {
774   VisitExpr(S);
775   VisitDecl(S->getParam());
776 }
777
778 void StmtProfiler::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *S) {
779   VisitExpr(S);
780   VisitDecl(
781          const_cast<CXXDestructorDecl *>(S->getTemporary()->getDestructor()));
782 }
783
784 void StmtProfiler::VisitCXXConstructExpr(const CXXConstructExpr *S) {
785   VisitExpr(S);
786   VisitDecl(S->getConstructor());
787   ID.AddBoolean(S->isElidable());
788 }
789
790 void StmtProfiler::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *S) {
791   VisitExplicitCastExpr(S);
792 }
793
794 void
795 StmtProfiler::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *S) {
796   VisitCXXConstructExpr(S);
797 }
798
799 void
800 StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) {
801   VisitExpr(S);
802   for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
803                                  CEnd = S->explicit_capture_end();
804        C != CEnd; ++C) {
805     ID.AddInteger(C->getCaptureKind());
806     if (C->capturesVariable()) {
807       VisitDecl(C->getCapturedVar());
808       ID.AddBoolean(C->isPackExpansion());
809     }
810   }
811   // Note: If we actually needed to be able to match lambda
812   // expressions, we would have to consider parameters and return type
813   // here, among other things.
814   VisitStmt(S->getBody());
815 }
816
817 void
818 StmtProfiler::VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *S) {
819   VisitExpr(S);
820 }
821
822 void StmtProfiler::VisitCXXDeleteExpr(const CXXDeleteExpr *S) {
823   VisitExpr(S);
824   ID.AddBoolean(S->isGlobalDelete());
825   ID.AddBoolean(S->isArrayForm());
826   VisitDecl(S->getOperatorDelete());
827 }
828
829
830 void StmtProfiler::VisitCXXNewExpr(const CXXNewExpr *S) {
831   VisitExpr(S);
832   VisitType(S->getAllocatedType());
833   VisitDecl(S->getOperatorNew());
834   VisitDecl(S->getOperatorDelete());
835   ID.AddBoolean(S->isArray());
836   ID.AddInteger(S->getNumPlacementArgs());
837   ID.AddBoolean(S->isGlobalNew());
838   ID.AddBoolean(S->isParenTypeId());
839   ID.AddInteger(S->getInitializationStyle());
840 }
841
842 void
843 StmtProfiler::VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *S) {
844   VisitExpr(S);
845   ID.AddBoolean(S->isArrow());
846   VisitNestedNameSpecifier(S->getQualifier());
847   VisitType(S->getDestroyedType());
848 }
849
850 void StmtProfiler::VisitOverloadExpr(const OverloadExpr *S) {
851   VisitExpr(S);
852   VisitNestedNameSpecifier(S->getQualifier());
853   VisitName(S->getName());
854   ID.AddBoolean(S->hasExplicitTemplateArgs());
855   if (S->hasExplicitTemplateArgs())
856     VisitTemplateArguments(S->getExplicitTemplateArgs().getTemplateArgs(),
857                            S->getExplicitTemplateArgs().NumTemplateArgs);
858 }
859
860 void
861 StmtProfiler::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *S) {
862   VisitOverloadExpr(S);
863 }
864
865 void StmtProfiler::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *S) {
866   VisitExpr(S);
867   ID.AddInteger(S->getTrait());
868   VisitType(S->getQueriedType());
869 }
870
871 void StmtProfiler::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *S) {
872   VisitExpr(S);
873   ID.AddInteger(S->getTrait());
874   VisitType(S->getLhsType());
875   VisitType(S->getRhsType());
876 }
877
878 void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr *S) {
879   VisitExpr(S);
880   ID.AddInteger(S->getTrait());
881   ID.AddInteger(S->getNumArgs());
882   for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
883     VisitType(S->getArg(I)->getType());
884 }
885
886 void StmtProfiler::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *S) {
887   VisitExpr(S);
888   ID.AddInteger(S->getTrait());
889   VisitType(S->getQueriedType());
890 }
891
892 void StmtProfiler::VisitExpressionTraitExpr(const ExpressionTraitExpr *S) {
893   VisitExpr(S);
894   ID.AddInteger(S->getTrait());
895   VisitExpr(S->getQueriedExpression());
896 }
897
898 void StmtProfiler::VisitDependentScopeDeclRefExpr(
899     const DependentScopeDeclRefExpr *S) {
900   VisitExpr(S);
901   VisitName(S->getDeclName());
902   VisitNestedNameSpecifier(S->getQualifier());
903   ID.AddBoolean(S->hasExplicitTemplateArgs());
904   if (S->hasExplicitTemplateArgs())
905     VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
906 }
907
908 void StmtProfiler::VisitExprWithCleanups(const ExprWithCleanups *S) {
909   VisitExpr(S);
910 }
911
912 void StmtProfiler::VisitCXXUnresolvedConstructExpr(
913     const CXXUnresolvedConstructExpr *S) {
914   VisitExpr(S);
915   VisitType(S->getTypeAsWritten());
916 }
917
918 void StmtProfiler::VisitCXXDependentScopeMemberExpr(
919     const CXXDependentScopeMemberExpr *S) {
920   ID.AddBoolean(S->isImplicitAccess());
921   if (!S->isImplicitAccess()) {
922     VisitExpr(S);
923     ID.AddBoolean(S->isArrow());
924   }
925   VisitNestedNameSpecifier(S->getQualifier());
926   VisitName(S->getMember());
927   ID.AddBoolean(S->hasExplicitTemplateArgs());
928   if (S->hasExplicitTemplateArgs())
929     VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
930 }
931
932 void StmtProfiler::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *S) {
933   ID.AddBoolean(S->isImplicitAccess());
934   if (!S->isImplicitAccess()) {
935     VisitExpr(S);
936     ID.AddBoolean(S->isArrow());
937   }
938   VisitNestedNameSpecifier(S->getQualifier());
939   VisitName(S->getMemberName());
940   ID.AddBoolean(S->hasExplicitTemplateArgs());
941   if (S->hasExplicitTemplateArgs())
942     VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
943 }
944
945 void StmtProfiler::VisitCXXNoexceptExpr(const CXXNoexceptExpr *S) {
946   VisitExpr(S);
947 }
948
949 void StmtProfiler::VisitPackExpansionExpr(const PackExpansionExpr *S) {
950   VisitExpr(S);
951 }
952
953 void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr *S) {
954   VisitExpr(S);
955   VisitDecl(S->getPack());
956 }
957
958 void StmtProfiler::VisitSubstNonTypeTemplateParmPackExpr(
959     const SubstNonTypeTemplateParmPackExpr *S) {
960   VisitExpr(S);
961   VisitDecl(S->getParameterPack());
962   VisitTemplateArgument(S->getArgumentPack());
963 }
964
965 void StmtProfiler::VisitSubstNonTypeTemplateParmExpr(
966     const SubstNonTypeTemplateParmExpr *E) {
967   // Profile exactly as the replacement expression.
968   Visit(E->getReplacement());
969 }
970
971 void StmtProfiler::VisitMaterializeTemporaryExpr(
972                                            const MaterializeTemporaryExpr *S) {
973   VisitExpr(S);
974 }
975
976 void StmtProfiler::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
977   VisitExpr(E);  
978 }
979
980 void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral *S) {
981   VisitExpr(S);
982 }
983
984 void StmtProfiler::VisitObjCNumericLiteral(const ObjCNumericLiteral *E) {
985   VisitExpr(E);
986 }
987
988 void StmtProfiler::VisitObjCArrayLiteral(const ObjCArrayLiteral *E) {
989   VisitExpr(E);
990 }
991
992 void StmtProfiler::VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E) {
993   VisitExpr(E);
994 }
995
996 void StmtProfiler::VisitObjCEncodeExpr(const ObjCEncodeExpr *S) {
997   VisitExpr(S);
998   VisitType(S->getEncodedType());
999 }
1000
1001 void StmtProfiler::VisitObjCSelectorExpr(const ObjCSelectorExpr *S) {
1002   VisitExpr(S);
1003   VisitName(S->getSelector());
1004 }
1005
1006 void StmtProfiler::VisitObjCProtocolExpr(const ObjCProtocolExpr *S) {
1007   VisitExpr(S);
1008   VisitDecl(S->getProtocol());
1009 }
1010
1011 void StmtProfiler::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *S) {
1012   VisitExpr(S);
1013   VisitDecl(S->getDecl());
1014   ID.AddBoolean(S->isArrow());
1015   ID.AddBoolean(S->isFreeIvar());
1016 }
1017
1018 void StmtProfiler::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *S) {
1019   VisitExpr(S);
1020   if (S->isImplicitProperty()) {
1021     VisitDecl(S->getImplicitPropertyGetter());
1022     VisitDecl(S->getImplicitPropertySetter());
1023   } else {
1024     VisitDecl(S->getExplicitProperty());
1025   }
1026   if (S->isSuperReceiver()) {
1027     ID.AddBoolean(S->isSuperReceiver());
1028     VisitType(S->getSuperReceiverType());
1029   }
1030 }
1031
1032 void StmtProfiler::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *S) {
1033   VisitExpr(S);
1034   VisitDecl(S->getAtIndexMethodDecl());
1035   VisitDecl(S->setAtIndexMethodDecl());
1036 }
1037
1038 void StmtProfiler::VisitObjCMessageExpr(const ObjCMessageExpr *S) {
1039   VisitExpr(S);
1040   VisitName(S->getSelector());
1041   VisitDecl(S->getMethodDecl());
1042 }
1043
1044 void StmtProfiler::VisitObjCIsaExpr(const ObjCIsaExpr *S) {
1045   VisitExpr(S);
1046   ID.AddBoolean(S->isArrow());
1047 }
1048
1049 void StmtProfiler::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *S) {
1050   VisitExpr(S);
1051   ID.AddBoolean(S->getValue());
1052 }
1053
1054 void StmtProfiler::VisitObjCIndirectCopyRestoreExpr(
1055     const ObjCIndirectCopyRestoreExpr *S) {
1056   VisitExpr(S);
1057   ID.AddBoolean(S->shouldCopy());
1058 }
1059
1060 void StmtProfiler::VisitObjCBridgedCastExpr(const ObjCBridgedCastExpr *S) {
1061   VisitExplicitCastExpr(S);
1062   ID.AddBoolean(S->getBridgeKind());
1063 }
1064
1065 void StmtProfiler::VisitDecl(const Decl *D) {
1066   ID.AddInteger(D? D->getKind() : 0);
1067
1068   if (Canonical && D) {
1069     if (const NonTypeTemplateParmDecl *NTTP =
1070           dyn_cast<NonTypeTemplateParmDecl>(D)) {
1071       ID.AddInteger(NTTP->getDepth());
1072       ID.AddInteger(NTTP->getIndex());
1073       ID.AddBoolean(NTTP->isParameterPack());
1074       VisitType(NTTP->getType());
1075       return;
1076     }
1077
1078     if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
1079       // The Itanium C++ ABI uses the type, scope depth, and scope
1080       // index of a parameter when mangling expressions that involve
1081       // function parameters, so we will use the parameter's type for
1082       // establishing function parameter identity. That way, our
1083       // definition of "equivalent" (per C++ [temp.over.link]) is at
1084       // least as strong as the definition of "equivalent" used for
1085       // name mangling.
1086       VisitType(Parm->getType());
1087       ID.AddInteger(Parm->getFunctionScopeDepth());
1088       ID.AddInteger(Parm->getFunctionScopeIndex());
1089       return;
1090     }
1091
1092     if (const TemplateTypeParmDecl *TTP =
1093           dyn_cast<TemplateTypeParmDecl>(D)) {
1094       ID.AddInteger(TTP->getDepth());
1095       ID.AddInteger(TTP->getIndex());
1096       ID.AddBoolean(TTP->isParameterPack());
1097       return;
1098     }
1099
1100     if (const TemplateTemplateParmDecl *TTP =
1101           dyn_cast<TemplateTemplateParmDecl>(D)) {
1102       ID.AddInteger(TTP->getDepth());
1103       ID.AddInteger(TTP->getIndex());
1104       ID.AddBoolean(TTP->isParameterPack());
1105       return;
1106     }
1107   }
1108
1109   ID.AddPointer(D? D->getCanonicalDecl() : 0);
1110 }
1111
1112 void StmtProfiler::VisitType(QualType T) {
1113   if (Canonical)
1114     T = Context.getCanonicalType(T);
1115
1116   ID.AddPointer(T.getAsOpaquePtr());
1117 }
1118
1119 void StmtProfiler::VisitName(DeclarationName Name) {
1120   ID.AddPointer(Name.getAsOpaquePtr());
1121 }
1122
1123 void StmtProfiler::VisitNestedNameSpecifier(NestedNameSpecifier *NNS) {
1124   if (Canonical)
1125     NNS = Context.getCanonicalNestedNameSpecifier(NNS);
1126   ID.AddPointer(NNS);
1127 }
1128
1129 void StmtProfiler::VisitTemplateName(TemplateName Name) {
1130   if (Canonical)
1131     Name = Context.getCanonicalTemplateName(Name);
1132
1133   Name.Profile(ID);
1134 }
1135
1136 void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args,
1137                                           unsigned NumArgs) {
1138   ID.AddInteger(NumArgs);
1139   for (unsigned I = 0; I != NumArgs; ++I)
1140     VisitTemplateArgument(Args[I].getArgument());
1141 }
1142
1143 void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
1144   // Mostly repetitive with TemplateArgument::Profile!
1145   ID.AddInteger(Arg.getKind());
1146   switch (Arg.getKind()) {
1147   case TemplateArgument::Null:
1148     break;
1149
1150   case TemplateArgument::Type:
1151     VisitType(Arg.getAsType());
1152     break;
1153
1154   case TemplateArgument::Template:
1155   case TemplateArgument::TemplateExpansion:
1156     VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
1157     break;
1158       
1159   case TemplateArgument::Declaration:
1160     VisitDecl(Arg.getAsDecl());
1161     break;
1162
1163   case TemplateArgument::Integral:
1164     Arg.getAsIntegral()->Profile(ID);
1165     VisitType(Arg.getIntegralType());
1166     break;
1167
1168   case TemplateArgument::Expression:
1169     Visit(Arg.getAsExpr());
1170     break;
1171
1172   case TemplateArgument::Pack:
1173     const TemplateArgument *Pack = Arg.pack_begin();
1174     for (unsigned i = 0, e = Arg.pack_size(); i != e; ++i)
1175       VisitTemplateArgument(Pack[i]);
1176     break;
1177   }
1178 }
1179
1180 void Stmt::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
1181                    bool Canonical) const {
1182   StmtProfiler Profiler(ID, Context, Canonical);
1183   Profiler.Visit(this);
1184 }