]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/AST/StmtProfile.cpp
Update clang to r96341.
[FreeBSD/FreeBSD.git] / 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 StmtVisitor<StmtProfiler> {
27     llvm::FoldingSetNodeID &ID;
28     ASTContext &Context;
29     bool Canonical;
30
31   public:
32     StmtProfiler(llvm::FoldingSetNodeID &ID, ASTContext &Context,
33                  bool Canonical)
34       : ID(ID), Context(Context), Canonical(Canonical) { }
35
36     void VisitStmt(Stmt *S);
37
38 #define STMT(Node, Base) void Visit##Node(Node *S);
39 #include "clang/AST/StmtNodes.def"
40
41     /// \brief Visit a declaration that is referenced within an expression
42     /// or statement.
43     void VisitDecl(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, unsigned NumArgs);
63
64     /// \brief Visit a single template argument.
65     void VisitTemplateArgument(const TemplateArgument &Arg);
66   };
67 }
68
69 void StmtProfiler::VisitStmt(Stmt *S) {
70   ID.AddInteger(S->getStmtClass());
71   for (Stmt::child_iterator C = S->child_begin(), CEnd = S->child_end();
72        C != CEnd; ++C)
73     Visit(*C);
74 }
75
76 void StmtProfiler::VisitDeclStmt(DeclStmt *S) {
77   VisitStmt(S);
78   for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
79        D != DEnd; ++D)
80     VisitDecl(*D);
81 }
82
83 void StmtProfiler::VisitNullStmt(NullStmt *S) {
84   VisitStmt(S);
85 }
86
87 void StmtProfiler::VisitCompoundStmt(CompoundStmt *S) {
88   VisitStmt(S);
89 }
90
91 void StmtProfiler::VisitSwitchCase(SwitchCase *S) {
92   VisitStmt(S);
93 }
94
95 void StmtProfiler::VisitCaseStmt(CaseStmt *S) {
96   VisitStmt(S);
97 }
98
99 void StmtProfiler::VisitDefaultStmt(DefaultStmt *S) {
100   VisitStmt(S);
101 }
102
103 void StmtProfiler::VisitLabelStmt(LabelStmt *S) {
104   VisitStmt(S);
105   VisitName(S->getID());
106 }
107
108 void StmtProfiler::VisitIfStmt(IfStmt *S) {
109   VisitStmt(S);
110   VisitDecl(S->getConditionVariable());
111 }
112
113 void StmtProfiler::VisitSwitchStmt(SwitchStmt *S) {
114   VisitStmt(S);
115   VisitDecl(S->getConditionVariable());
116 }
117
118 void StmtProfiler::VisitWhileStmt(WhileStmt *S) {
119   VisitStmt(S);
120   VisitDecl(S->getConditionVariable());
121 }
122
123 void StmtProfiler::VisitDoStmt(DoStmt *S) {
124   VisitStmt(S);
125 }
126
127 void StmtProfiler::VisitForStmt(ForStmt *S) {
128   VisitStmt(S);
129 }
130
131 void StmtProfiler::VisitGotoStmt(GotoStmt *S) {
132   VisitStmt(S);
133   VisitName(S->getLabel()->getID());
134 }
135
136 void StmtProfiler::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
137   VisitStmt(S);
138 }
139
140 void StmtProfiler::VisitContinueStmt(ContinueStmt *S) {
141   VisitStmt(S);
142 }
143
144 void StmtProfiler::VisitBreakStmt(BreakStmt *S) {
145   VisitStmt(S);
146 }
147
148 void StmtProfiler::VisitReturnStmt(ReturnStmt *S) {
149   VisitStmt(S);
150 }
151
152 void StmtProfiler::VisitAsmStmt(AsmStmt *S) {
153   VisitStmt(S);
154   ID.AddBoolean(S->isVolatile());
155   ID.AddBoolean(S->isSimple());
156   VisitStringLiteral(S->getAsmString());
157   ID.AddInteger(S->getNumOutputs());
158   for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
159     ID.AddString(S->getOutputName(I));
160     VisitStringLiteral(S->getOutputConstraintLiteral(I));
161   }
162   ID.AddInteger(S->getNumInputs());
163   for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
164     ID.AddString(S->getInputName(I));
165     VisitStringLiteral(S->getInputConstraintLiteral(I));
166   }
167   ID.AddInteger(S->getNumClobbers());
168   for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
169     VisitStringLiteral(S->getClobber(I));
170 }
171
172 void StmtProfiler::VisitCXXCatchStmt(CXXCatchStmt *S) {
173   VisitStmt(S);
174   VisitType(S->getCaughtType());
175 }
176
177 void StmtProfiler::VisitCXXTryStmt(CXXTryStmt *S) {
178   VisitStmt(S);
179 }
180
181 void StmtProfiler::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
182   VisitStmt(S);
183 }
184
185 void StmtProfiler::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
186   VisitStmt(S);
187   ID.AddBoolean(S->hasEllipsis());
188   if (S->getCatchParamDecl())
189     VisitType(S->getCatchParamDecl()->getType());
190 }
191
192 void StmtProfiler::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
193   VisitStmt(S);
194 }
195
196 void StmtProfiler::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
197   VisitStmt(S);
198 }
199
200 void StmtProfiler::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
201   VisitStmt(S);
202 }
203
204 void StmtProfiler::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
205   VisitStmt(S);
206 }
207
208 void StmtProfiler::VisitExpr(Expr *S) {
209   VisitStmt(S);
210 }
211
212 void StmtProfiler::VisitDeclRefExpr(DeclRefExpr *S) {
213   VisitExpr(S);
214   VisitNestedNameSpecifier(S->getQualifier());
215   VisitDecl(S->getDecl());
216   VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
217 }
218
219 void StmtProfiler::VisitPredefinedExpr(PredefinedExpr *S) {
220   VisitExpr(S);
221   ID.AddInteger(S->getIdentType());
222 }
223
224 void StmtProfiler::VisitIntegerLiteral(IntegerLiteral *S) {
225   VisitExpr(S);
226   S->getValue().Profile(ID);
227 }
228
229 void StmtProfiler::VisitCharacterLiteral(CharacterLiteral *S) {
230   VisitExpr(S);
231   ID.AddBoolean(S->isWide());
232   ID.AddInteger(S->getValue());
233 }
234
235 void StmtProfiler::VisitFloatingLiteral(FloatingLiteral *S) {
236   VisitExpr(S);
237   S->getValue().Profile(ID);
238   ID.AddBoolean(S->isExact());
239 }
240
241 void StmtProfiler::VisitImaginaryLiteral(ImaginaryLiteral *S) {
242   VisitExpr(S);
243 }
244
245 void StmtProfiler::VisitStringLiteral(StringLiteral *S) {
246   VisitExpr(S);
247   ID.AddString(S->getString());
248   ID.AddBoolean(S->isWide());
249 }
250
251 void StmtProfiler::VisitParenExpr(ParenExpr *S) {
252   VisitExpr(S);
253 }
254
255 void StmtProfiler::VisitParenListExpr(ParenListExpr *S) {
256   VisitExpr(S);
257 }
258
259 void StmtProfiler::VisitUnaryOperator(UnaryOperator *S) {
260   VisitExpr(S);
261   ID.AddInteger(S->getOpcode());
262 }
263
264 void StmtProfiler::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *S) {
265   VisitExpr(S);
266   ID.AddBoolean(S->isSizeOf());
267   if (S->isArgumentType())
268     VisitType(S->getArgumentType());
269 }
270
271 void StmtProfiler::VisitArraySubscriptExpr(ArraySubscriptExpr *S) {
272   VisitExpr(S);
273 }
274
275 void StmtProfiler::VisitCallExpr(CallExpr *S) {
276   VisitExpr(S);
277 }
278
279 void StmtProfiler::VisitMemberExpr(MemberExpr *S) {
280   VisitExpr(S);
281   VisitDecl(S->getMemberDecl());
282   VisitNestedNameSpecifier(S->getQualifier());
283   ID.AddBoolean(S->isArrow());
284 }
285
286 void StmtProfiler::VisitCompoundLiteralExpr(CompoundLiteralExpr *S) {
287   VisitExpr(S);
288   ID.AddBoolean(S->isFileScope());
289 }
290
291 void StmtProfiler::VisitCastExpr(CastExpr *S) {
292   VisitExpr(S);
293 }
294
295 void StmtProfiler::VisitImplicitCastExpr(ImplicitCastExpr *S) {
296   VisitCastExpr(S);
297   ID.AddBoolean(S->isLvalueCast());
298 }
299
300 void StmtProfiler::VisitExplicitCastExpr(ExplicitCastExpr *S) {
301   VisitCastExpr(S);
302   VisitType(S->getTypeAsWritten());
303 }
304
305 void StmtProfiler::VisitCStyleCastExpr(CStyleCastExpr *S) {
306   VisitExplicitCastExpr(S);
307 }
308
309 void StmtProfiler::VisitBinaryOperator(BinaryOperator *S) {
310   VisitExpr(S);
311   ID.AddInteger(S->getOpcode());
312 }
313
314 void StmtProfiler::VisitCompoundAssignOperator(CompoundAssignOperator *S) {
315   VisitBinaryOperator(S);
316 }
317
318 void StmtProfiler::VisitConditionalOperator(ConditionalOperator *S) {
319   VisitExpr(S);
320 }
321
322 void StmtProfiler::VisitAddrLabelExpr(AddrLabelExpr *S) {
323   VisitExpr(S);
324   VisitName(S->getLabel()->getID());
325 }
326
327 void StmtProfiler::VisitStmtExpr(StmtExpr *S) {
328   VisitExpr(S);
329 }
330
331 void StmtProfiler::VisitTypesCompatibleExpr(TypesCompatibleExpr *S) {
332   VisitExpr(S);
333   VisitType(S->getArgType1());
334   VisitType(S->getArgType2());
335 }
336
337 void StmtProfiler::VisitShuffleVectorExpr(ShuffleVectorExpr *S) {
338   VisitExpr(S);
339 }
340
341 void StmtProfiler::VisitChooseExpr(ChooseExpr *S) {
342   VisitExpr(S);
343 }
344
345 void StmtProfiler::VisitGNUNullExpr(GNUNullExpr *S) {
346   VisitExpr(S);
347 }
348
349 void StmtProfiler::VisitVAArgExpr(VAArgExpr *S) {
350   VisitExpr(S);
351 }
352
353 void StmtProfiler::VisitInitListExpr(InitListExpr *S) {
354   if (S->getSyntacticForm()) {
355     VisitInitListExpr(S->getSyntacticForm());
356     return;
357   }
358
359   VisitExpr(S);
360 }
361
362 void StmtProfiler::VisitDesignatedInitExpr(DesignatedInitExpr *S) {
363   VisitExpr(S);
364   ID.AddBoolean(S->usesGNUSyntax());
365   for (DesignatedInitExpr::designators_iterator D = S->designators_begin(),
366                                              DEnd = S->designators_end();
367        D != DEnd; ++D) {
368     if (D->isFieldDesignator()) {
369       ID.AddInteger(0);
370       VisitName(D->getFieldName());
371       continue;
372     }
373
374     if (D->isArrayDesignator()) {
375       ID.AddInteger(1);
376     } else {
377       assert(D->isArrayRangeDesignator());
378       ID.AddInteger(2);
379     }
380     ID.AddInteger(D->getFirstExprIndex());
381   }
382 }
383
384 void StmtProfiler::VisitImplicitValueInitExpr(ImplicitValueInitExpr *S) {
385   VisitExpr(S);
386 }
387
388 void StmtProfiler::VisitExtVectorElementExpr(ExtVectorElementExpr *S) {
389   VisitExpr(S);
390   VisitName(&S->getAccessor());
391 }
392
393 void StmtProfiler::VisitBlockExpr(BlockExpr *S) {
394   VisitExpr(S);
395   VisitDecl(S->getBlockDecl());
396 }
397
398 void StmtProfiler::VisitBlockDeclRefExpr(BlockDeclRefExpr *S) {
399   VisitExpr(S);
400   VisitDecl(S->getDecl());
401   ID.AddBoolean(S->isByRef());
402   ID.AddBoolean(S->isConstQualAdded());
403 }
404
405 void StmtProfiler::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
406   VisitCallExpr(S);
407   ID.AddInteger(S->getOperator());
408 }
409
410 void StmtProfiler::VisitCXXMemberCallExpr(CXXMemberCallExpr *S) {
411   VisitCallExpr(S);
412 }
413
414 void StmtProfiler::VisitCXXNamedCastExpr(CXXNamedCastExpr *S) {
415   VisitExplicitCastExpr(S);
416 }
417
418 void StmtProfiler::VisitCXXStaticCastExpr(CXXStaticCastExpr *S) {
419   VisitCXXNamedCastExpr(S);
420 }
421
422 void StmtProfiler::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *S) {
423   VisitCXXNamedCastExpr(S);
424 }
425
426 void StmtProfiler::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *S) {
427   VisitCXXNamedCastExpr(S);
428 }
429
430 void StmtProfiler::VisitCXXConstCastExpr(CXXConstCastExpr *S) {
431   VisitCXXNamedCastExpr(S);
432 }
433
434 void StmtProfiler::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *S) {
435   VisitExpr(S);
436   ID.AddBoolean(S->getValue());
437 }
438
439 void StmtProfiler::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *S) {
440   VisitExpr(S);
441 }
442
443 void StmtProfiler::VisitCXXTypeidExpr(CXXTypeidExpr *S) {
444   VisitExpr(S);
445   if (S->isTypeOperand())
446     VisitType(S->getTypeOperand());
447 }
448
449 void StmtProfiler::VisitCXXThisExpr(CXXThisExpr *S) {
450   VisitExpr(S);
451 }
452
453 void StmtProfiler::VisitCXXThrowExpr(CXXThrowExpr *S) {
454   VisitExpr(S);
455 }
456
457 void StmtProfiler::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *S) {
458   VisitExpr(S);
459   VisitDecl(S->getParam());
460 }
461
462 void StmtProfiler::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *S) {
463   VisitExpr(S);
464   VisitDecl(
465          const_cast<CXXDestructorDecl *>(S->getTemporary()->getDestructor()));
466 }
467
468 void StmtProfiler::VisitCXXBindReferenceExpr(CXXBindReferenceExpr *S) {
469   VisitExpr(S);
470 }
471
472 void StmtProfiler::VisitCXXConstructExpr(CXXConstructExpr *S) {
473   VisitExpr(S);
474   VisitDecl(S->getConstructor());
475   ID.AddBoolean(S->isElidable());
476 }
477
478 void StmtProfiler::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *S) {
479   VisitExplicitCastExpr(S);
480 }
481
482 void StmtProfiler::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *S) {
483   VisitCXXConstructExpr(S);
484 }
485
486 void StmtProfiler::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *S) {
487   VisitExpr(S);
488 }
489
490 void StmtProfiler::VisitCXXDeleteExpr(CXXDeleteExpr *S) {
491   VisitExpr(S);
492   ID.AddBoolean(S->isGlobalDelete());
493   ID.AddBoolean(S->isArrayForm());
494   VisitDecl(S->getOperatorDelete());
495 }
496
497
498 void StmtProfiler::VisitCXXNewExpr(CXXNewExpr *S) {
499   VisitExpr(S);
500   VisitType(S->getAllocatedType());
501   VisitDecl(S->getOperatorNew());
502   VisitDecl(S->getOperatorDelete());
503   VisitDecl(S->getConstructor());
504   ID.AddBoolean(S->isArray());
505   ID.AddInteger(S->getNumPlacementArgs());
506   ID.AddBoolean(S->isGlobalNew());
507   ID.AddBoolean(S->isParenTypeId());
508   ID.AddBoolean(S->hasInitializer());
509   ID.AddInteger(S->getNumConstructorArgs());
510 }
511
512 void StmtProfiler::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *S) {
513   VisitExpr(S);
514   ID.AddBoolean(S->isArrow());
515   VisitNestedNameSpecifier(S->getQualifier());
516   VisitType(S->getDestroyedType());
517 }
518
519 void
520 StmtProfiler::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *S) {
521   VisitExpr(S);
522   VisitNestedNameSpecifier(S->getQualifier());
523   VisitName(S->getName());
524   ID.AddBoolean(S->hasExplicitTemplateArgs());
525   if (S->hasExplicitTemplateArgs())
526     VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
527 }
528
529 void StmtProfiler::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *S) {
530   VisitExpr(S);
531   ID.AddInteger(S->getTrait());
532   VisitType(S->getQueriedType());
533 }
534
535 void
536 StmtProfiler::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *S) {
537   VisitExpr(S);
538   VisitName(S->getDeclName());
539   VisitNestedNameSpecifier(S->getQualifier());
540   ID.AddBoolean(S->hasExplicitTemplateArgs());
541   if (S->hasExplicitTemplateArgs())
542     VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
543 }
544
545 void StmtProfiler::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *S) {
546   VisitExpr(S);
547   for (unsigned I = 0, N = S->getNumTemporaries(); I != N; ++I)
548     VisitDecl(
549       const_cast<CXXDestructorDecl *>(S->getTemporary(I)->getDestructor()));
550 }
551
552 void
553 StmtProfiler::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *S) {
554   VisitExpr(S);
555   VisitType(S->getTypeAsWritten());
556 }
557
558 void
559 StmtProfiler::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *S) {
560   ID.AddBoolean(S->isImplicitAccess());
561   if (!S->isImplicitAccess()) {
562     VisitExpr(S);
563     ID.AddBoolean(S->isArrow());
564   }
565   VisitNestedNameSpecifier(S->getQualifier());
566   VisitName(S->getMember());
567   ID.AddBoolean(S->hasExplicitTemplateArgs());
568   if (S->hasExplicitTemplateArgs())
569     VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
570 }
571
572 void StmtProfiler::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *S) {
573   ID.AddBoolean(S->isImplicitAccess());
574   if (!S->isImplicitAccess()) {
575     VisitExpr(S);
576     ID.AddBoolean(S->isArrow());
577   }
578   VisitNestedNameSpecifier(S->getQualifier());
579   VisitName(S->getMemberName());
580   ID.AddBoolean(S->hasExplicitTemplateArgs());
581   if (S->hasExplicitTemplateArgs())
582     VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
583 }
584
585 void StmtProfiler::VisitObjCStringLiteral(ObjCStringLiteral *S) {
586   VisitExpr(S);
587 }
588
589 void StmtProfiler::VisitObjCEncodeExpr(ObjCEncodeExpr *S) {
590   VisitExpr(S);
591   VisitType(S->getEncodedType());
592 }
593
594 void StmtProfiler::VisitObjCSelectorExpr(ObjCSelectorExpr *S) {
595   VisitExpr(S);
596   VisitName(S->getSelector());
597 }
598
599 void StmtProfiler::VisitObjCProtocolExpr(ObjCProtocolExpr *S) {
600   VisitExpr(S);
601   VisitDecl(S->getProtocol());
602 }
603
604 void StmtProfiler::VisitObjCIvarRefExpr(ObjCIvarRefExpr *S) {
605   VisitExpr(S);
606   VisitDecl(S->getDecl());
607   ID.AddBoolean(S->isArrow());
608   ID.AddBoolean(S->isFreeIvar());
609 }
610
611 void StmtProfiler::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *S) {
612   VisitExpr(S);
613   VisitDecl(S->getProperty());
614 }
615
616 void StmtProfiler::VisitObjCImplicitSetterGetterRefExpr(
617                                   ObjCImplicitSetterGetterRefExpr *S) {
618   VisitExpr(S);
619   VisitDecl(S->getGetterMethod());
620   VisitDecl(S->getSetterMethod());
621   VisitDecl(S->getInterfaceDecl());
622 }
623
624 void StmtProfiler::VisitObjCMessageExpr(ObjCMessageExpr *S) {
625   VisitExpr(S);
626   VisitName(S->getSelector());
627   VisitDecl(S->getMethodDecl());
628 }
629
630 void StmtProfiler::VisitObjCSuperExpr(ObjCSuperExpr *S) {
631   VisitExpr(S);
632 }
633
634 void StmtProfiler::VisitObjCIsaExpr(ObjCIsaExpr *S) {
635   VisitExpr(S);
636   ID.AddBoolean(S->isArrow());
637 }
638
639 void StmtProfiler::VisitDecl(Decl *D) {
640   ID.AddInteger(D? D->getKind() : 0);
641
642   if (Canonical && D) {
643     if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
644       ID.AddInteger(NTTP->getDepth());
645       ID.AddInteger(NTTP->getIndex());
646       VisitType(NTTP->getType());
647       return;
648     }
649
650     if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
651       // The Itanium C++ ABI uses the type of a parameter when mangling
652       // expressions that involve function parameters, so we will use the
653       // parameter's type for establishing function parameter identity. That
654       // way, our definition of "equivalent" (per C++ [temp.over.link])
655       // matches the definition of "equivalent" used for name mangling.
656       VisitType(Parm->getType());
657       return;
658     }
659
660     if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(D)) {
661       ID.AddInteger(TTP->getDepth());
662       ID.AddInteger(TTP->getIndex());
663       return;
664     }
665   }
666
667   ID.AddPointer(D? D->getCanonicalDecl() : 0);
668 }
669
670 void StmtProfiler::VisitType(QualType T) {
671   if (Canonical)
672     T = Context.getCanonicalType(T);
673
674   ID.AddPointer(T.getAsOpaquePtr());
675 }
676
677 void StmtProfiler::VisitName(DeclarationName Name) {
678   ID.AddPointer(Name.getAsOpaquePtr());
679 }
680
681 void StmtProfiler::VisitNestedNameSpecifier(NestedNameSpecifier *NNS) {
682   if (Canonical)
683     NNS = Context.getCanonicalNestedNameSpecifier(NNS);
684   ID.AddPointer(NNS);
685 }
686
687 void StmtProfiler::VisitTemplateName(TemplateName Name) {
688   if (Canonical)
689     Name = Context.getCanonicalTemplateName(Name);
690
691   Name.Profile(ID);
692 }
693
694 void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args,
695                                           unsigned NumArgs) {
696   ID.AddInteger(NumArgs);
697   for (unsigned I = 0; I != NumArgs; ++I)
698     VisitTemplateArgument(Args[I].getArgument());
699 }
700
701 void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
702   // Mostly repetitive with TemplateArgument::Profile!
703   ID.AddInteger(Arg.getKind());
704   switch (Arg.getKind()) {
705   case TemplateArgument::Null:
706     break;
707
708   case TemplateArgument::Type:
709     VisitType(Arg.getAsType());
710     break;
711
712   case TemplateArgument::Template:
713     VisitTemplateName(Arg.getAsTemplate());
714     break;
715       
716   case TemplateArgument::Declaration:
717     VisitDecl(Arg.getAsDecl());
718     break;
719
720   case TemplateArgument::Integral:
721     Arg.getAsIntegral()->Profile(ID);
722     VisitType(Arg.getIntegralType());
723     break;
724
725   case TemplateArgument::Expression:
726     Visit(Arg.getAsExpr());
727     break;
728
729   case TemplateArgument::Pack:
730     const TemplateArgument *Pack = Arg.pack_begin();
731     for (unsigned i = 0, e = Arg.pack_size(); i != e; ++i)
732       VisitTemplateArgument(Pack[i]);
733     break;
734   }
735 }
736
737 void Stmt::Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
738                    bool Canonical) {
739   StmtProfiler Profiler(ID, Context, Canonical);
740   Profiler.Visit(this);
741 }