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