blob: 0698d2f6094d364b8b0c081c288b4ccd6e0722f2 [file] [log] [blame]
Douglas Gregor41ef0c32009-07-28 00:33:38 +00001//===---- 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 identifiers a statement/expression.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/DeclTemplate.h"
16#include "clang/AST/Expr.h"
17#include "clang/AST/ExprCXX.h"
18#include "clang/AST/ExprObjC.h"
19#include "clang/AST/StmtVisitor.h"
20#include "llvm/ADT/FoldingSet.h"
21#include "llvm/Support/Compiler.h"
22using namespace clang;
23
24namespace {
25 class VISIBILITY_HIDDEN StmtProfiler : public StmtVisitor<StmtProfiler> {
26 llvm::FoldingSetNodeID &ID;
27 ASTContext &Context;
28 bool Canonical;
29
30 public:
31 StmtProfiler(llvm::FoldingSetNodeID &ID, ASTContext &Context,
32 bool Canonical)
33 : ID(ID), Context(Context), Canonical(Canonical) { }
34
35 // FIXME: Use StmtNodes.def to declare all VisitXXX functions
36
37 void VisitStmt(Stmt *S);
38 void VisitExpr(Expr *S);
39 void VisitDeclRefExpr(DeclRefExpr *S);
40 void VisitPredefinedExpr(PredefinedExpr *S);
41 void VisitIntegerLiteral(IntegerLiteral *S);
42 void VisitCharacterLiteral(CharacterLiteral *S);
43 void VisitFloatingLiteral(FloatingLiteral *S);
44 void VisitImaginaryLiteral(ImaginaryLiteral *S);
45 void VisitStringLiteral(StringLiteral *S);
46 void VisitParenExpr(ParenExpr *S);
47 void VisitUnaryOperator(UnaryOperator *S);
48 void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *S);
49 void VisitArraySubscriptExpr(ArraySubscriptExpr *S);
50 void VisitCallExpr(CallExpr *S);
51 void VisitMemberExpr(MemberExpr *S);
52 void VisitCompoundLiteralExpr(CompoundLiteralExpr *S);
53 void VisitCastExpr(CastExpr *S);
54 void VisitImplicitCastExpr(ImplicitCastExpr *S);
55 void VisitExplicitCastExpr(ExplicitCastExpr *S);
56 void VisitCStyleCastExpr(CStyleCastExpr *S);
57 void VisitBinaryOperator(BinaryOperator *S);
58 void VisitCompoundAssignOperator(CompoundAssignOperator *S);
59 void VisitConditionalOperator(ConditionalOperator *S);
60 void VisitAddrLabelExpr(AddrLabelExpr *S);
61 void VisitStmtExpr(StmtExpr *S);
62 void VisitTypesCompatibleExpr(TypesCompatibleExpr *S);
63 void VisitShuffleVectorExpr(ShuffleVectorExpr *S);
64 void VisitChooseExpr(ChooseExpr *S);
65 void VisitGNUNullExpr(GNUNullExpr *S);
66 void VisitInitListExpr(InitListExpr *S);
67 void VisitDesignatedInitExpr(DesignatedInitExpr *S);
68 void VisitImplicitValueInitExpr(ImplicitValueInitExpr *S);
69 void VisitExtVectorElementExpr(ExtVectorElementExpr *S);
70 void VisitBlockExpr(BlockExpr *S);
71 void VisitBlockDeclRefExpr(BlockDeclRefExpr *S);
72 void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *S);
73 void VisitCXXMemberCallExpr(CXXMemberCallExpr *S);
74 void VisitCXXNamedCastExpr(CXXNamedCastExpr *S);
75 void VisitCXXStaticCastExpr(CXXStaticCastExpr *S);
76 void VisitCXXDynamicCastExpr(CXXDynamicCastExpr *S);
77 void VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *S);
78 void VisitCXXConstCastExpr(CXXConstCastExpr *S);
79 void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *S);
80 void VisitCXXTypeidExpr(CXXTypeidExpr *S);
81 void VisitCXXThisExpr(CXXThisExpr *S);
82 void VisitCXXThrowExpr(CXXThrowExpr *S);
83 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *S);
84 void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *S);
85 void VisitCXXConstructExpr(CXXConstructExpr *S);
86 void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *S);
87 void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *S);
88 void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *S);
89 void VisitCXXConditionDeclExpr(CXXConditionDeclExpr *S);
90 void VisitCXXNewExpr(CXXNewExpr *S);
91 void VisitCXXDeleteExpr(CXXDeleteExpr *S);
92 void VisitUnresolvedFunctionNameExpr(UnresolvedFunctionNameExpr *S);
93 void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *S);
94 void VisitQualifiedDeclRefExpr(QualifiedDeclRefExpr *S);
95 void VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *S);
96 void VisitTemplateIdRefExpr(TemplateIdRefExpr *S);
97 // FIXME: pick up at CXXExprWithTemporaries, handle Objective-C expressions
98
99 /// \brief Visit a declaration that is referenced within an expression
100 /// or statement.
101 void VisitDecl(Decl *D);
102
103 /// \brief Visit a type that is referenced within an expression or
104 /// statement.
105 void VisitType(QualType T);
106
107 /// \brief Visit a name that occurs within an expression or statement.
108 void VisitName(DeclarationName Name);
109
110 /// \brief Visit a nested-name-specifier that occurs within an expression
111 /// or statement.
112 void VisitNestedNameSpecifier(NestedNameSpecifier *NNS);
113
114 /// \brief Visit a template name that occurs within an expression or
115 /// statement.
116 void VisitTemplateName(TemplateName Name);
117
118 /// \brief Visit template arguments that occur within an expression or
119 /// statement.
120 void VisitTemplateArguments(const TemplateArgument *Args, unsigned NumArgs);
121 };
122}
123
124void StmtProfiler::VisitStmt(Stmt *S) {
125 ID.AddInteger(S->getStmtClass());
126 for (Stmt::child_iterator C = S->child_begin(), CEnd = S->child_end();
127 C != CEnd; ++C)
128 Visit(*C);
129}
130
131void StmtProfiler::VisitExpr(Expr *S) {
132 VisitStmt(S);
133}
134
135void StmtProfiler::VisitDeclRefExpr(DeclRefExpr *S) {
136 VisitExpr(S);
137 VisitDecl(S->getDecl());
138}
139
140void StmtProfiler::VisitPredefinedExpr(PredefinedExpr *S) {
141 VisitExpr(S);
142 ID.AddInteger(S->getIdentType());
143}
144
145void StmtProfiler::VisitIntegerLiteral(IntegerLiteral *S) {
146 VisitExpr(S);
147 S->getValue().Profile(ID);
148}
149
150void StmtProfiler::VisitCharacterLiteral(CharacterLiteral *S) {
151 VisitExpr(S);
152 ID.AddBoolean(S->isWide());
153 ID.AddInteger(S->getValue());
154}
155
156void StmtProfiler::VisitFloatingLiteral(FloatingLiteral *S) {
157 VisitExpr(S);
158 S->getValue().Profile(ID);
159 ID.AddBoolean(S->isExact());
160}
161
162void StmtProfiler::VisitImaginaryLiteral(ImaginaryLiteral *S) {
163 VisitExpr(S);
164}
165
166void StmtProfiler::VisitStringLiteral(StringLiteral *S) {
167 VisitExpr(S);
168 ID.AddString(S->getStrData(), S->getStrData() + S->getByteLength());
169 ID.AddBoolean(S->isWide());
170}
171
172void StmtProfiler::VisitParenExpr(ParenExpr *S) {
173 VisitExpr(S);
174}
175
176void StmtProfiler::VisitUnaryOperator(UnaryOperator *S) {
177 VisitExpr(S);
178 ID.AddInteger(S->getOpcode());
179}
180
181void StmtProfiler::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *S) {
182 VisitExpr(S);
183 ID.AddBoolean(S->isSizeOf());
184 if (S->isArgumentType())
185 VisitType(S->getArgumentType());
186}
187
188void StmtProfiler::VisitArraySubscriptExpr(ArraySubscriptExpr *S) {
189 VisitExpr(S);
190}
191
192void StmtProfiler::VisitCallExpr(CallExpr *S) {
193 VisitExpr(S);
194}
195
196void StmtProfiler::VisitMemberExpr(MemberExpr *S) {
197 VisitExpr(S);
198 VisitDecl(S->getMemberDecl());
199 ID.AddBoolean(S->isArrow());
200}
201
202void StmtProfiler::VisitCompoundLiteralExpr(CompoundLiteralExpr *S) {
203 VisitExpr(S);
204 ID.AddBoolean(S->isFileScope());
205}
206
207void StmtProfiler::VisitDecl(Decl *D) {
208 if (Canonical) {
209 if (NonTypeTemplateParmDecl *NTTP
210 = dyn_cast_or_null<NonTypeTemplateParmDecl>(D)) {
211 ID.AddInteger(NTTP->getDepth());
212 ID.AddInteger(NTTP->getIndex());
213 return;
214 }
215
216 // FIXME: Other template template parameters?
217 }
218
219 ID.AddPointer(D? D->getCanonicalDecl() : 0);
220}
221
222void StmtProfiler::VisitCastExpr(CastExpr *S) {
223 VisitExpr(S);
224}
225
226void StmtProfiler::VisitImplicitCastExpr(ImplicitCastExpr *S) {
227 VisitCastExpr(S);
228 ID.AddBoolean(S->isLvalueCast());
229}
230
231void StmtProfiler::VisitExplicitCastExpr(ExplicitCastExpr *S) {
232 VisitCastExpr(S);
233 VisitType(S->getTypeAsWritten());
234}
235
236void StmtProfiler::VisitCStyleCastExpr(CStyleCastExpr *S) {
237 VisitExplicitCastExpr(S);
238}
239
240void StmtProfiler::VisitBinaryOperator(BinaryOperator *S) {
241 VisitExpr(S);
242 ID.AddInteger(S->getOpcode());
243}
244
245void StmtProfiler::VisitCompoundAssignOperator(CompoundAssignOperator *S) {
246 VisitBinaryOperator(S);
247}
248
249void StmtProfiler::VisitConditionalOperator(ConditionalOperator *S) {
250 VisitExpr(S);
251}
252
253void StmtProfiler::VisitAddrLabelExpr(AddrLabelExpr *S) {
254 VisitExpr(S);
255 ID.AddPointer(S->getLabel());
256}
257
258void StmtProfiler::VisitStmtExpr(StmtExpr *S) {
259 VisitExpr(S);
260}
261
262void StmtProfiler::VisitTypesCompatibleExpr(TypesCompatibleExpr *S) {
263 VisitExpr(S);
264 VisitType(S->getArgType1());
265 VisitType(S->getArgType2());
266}
267
268void StmtProfiler::VisitShuffleVectorExpr(ShuffleVectorExpr *S) {
269 VisitExpr(S);
270}
271
272void StmtProfiler::VisitChooseExpr(ChooseExpr *S) {
273 VisitExpr(S);
274}
275
276void StmtProfiler::VisitGNUNullExpr(GNUNullExpr *S) {
277 VisitExpr(S);
278}
279
280void StmtProfiler::VisitInitListExpr(InitListExpr *S) {
281 if (S->getSyntacticForm()) {
282 VisitInitListExpr(S->getSyntacticForm());
283 return;
284 }
285
286 VisitExpr(S);
287}
288
289void StmtProfiler::VisitDesignatedInitExpr(DesignatedInitExpr *S) {
290 VisitExpr(S);
291 ID.AddBoolean(S->usesGNUSyntax());
292 for (DesignatedInitExpr::designators_iterator D = S->designators_begin(),
293 DEnd = S->designators_end();
294 D != DEnd; ++D) {
295 if (D->isFieldDesignator()) {
296 ID.AddInteger(0);
297 VisitName(D->getFieldName());
298 continue;
299 }
300
301 if (D->isArrayDesignator()) {
302 ID.AddInteger(1);
303 } else {
304 assert(D->isArrayRangeDesignator());
305 ID.AddInteger(2);
306 }
307 ID.AddInteger(D->getFirstExprIndex());
308 }
309}
310
311void StmtProfiler::VisitImplicitValueInitExpr(ImplicitValueInitExpr *S) {
312 VisitExpr(S);
313}
314
315void StmtProfiler::VisitExtVectorElementExpr(ExtVectorElementExpr *S) {
316 VisitExpr(S);
317 VisitName(&S->getAccessor());
318}
319
320void StmtProfiler::VisitBlockExpr(BlockExpr *S) {
321 VisitExpr(S);
322 VisitDecl(S->getBlockDecl());
323}
324
325void StmtProfiler::VisitBlockDeclRefExpr(BlockDeclRefExpr *S) {
326 VisitExpr(S);
327 VisitDecl(S->getDecl());
328 ID.AddBoolean(S->isByRef());
329 ID.AddBoolean(S->isConstQualAdded());
330}
331
332void StmtProfiler::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
333 VisitCallExpr(S);
334 ID.AddInteger(S->getOperator());
335}
336
337void StmtProfiler::VisitCXXMemberCallExpr(CXXMemberCallExpr *S) {
338 VisitCallExpr(S);
339}
340
341void StmtProfiler::VisitCXXNamedCastExpr(CXXNamedCastExpr *S) {
342 VisitExplicitCastExpr(S);
343}
344
345void StmtProfiler::VisitCXXStaticCastExpr(CXXStaticCastExpr *S) {
346 VisitCXXNamedCastExpr(S);
347}
348
349void StmtProfiler::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *S) {
350 VisitCXXNamedCastExpr(S);
351}
352
353void StmtProfiler::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *S) {
354 VisitCXXNamedCastExpr(S);
355}
356
357void StmtProfiler::VisitCXXConstCastExpr(CXXConstCastExpr *S) {
358 VisitCXXNamedCastExpr(S);
359}
360
361void StmtProfiler::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *S) {
362 VisitExpr(S);
363 ID.AddBoolean(S->getValue());
364}
365
366void StmtProfiler::VisitCXXTypeidExpr(CXXTypeidExpr *S) {
367 VisitExpr(S);
368 if (S->isTypeOperand())
369 VisitType(S->getTypeOperand());
370}
371
372void StmtProfiler::VisitCXXThisExpr(CXXThisExpr *S) {
373 VisitExpr(S);
374}
375
376void StmtProfiler::VisitCXXThrowExpr(CXXThrowExpr *S) {
377 VisitExpr(S);
378}
379
380void StmtProfiler::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *S) {
381 VisitExpr(S);
382 VisitDecl(S->getParam());
383}
384
385void StmtProfiler::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *S) {
386 VisitExpr(S);
387 VisitDecl(
388 const_cast<CXXDestructorDecl *>(S->getTemporary()->getDestructor()));
389}
390
391void StmtProfiler::VisitCXXConstructExpr(CXXConstructExpr *S) {
392 VisitExpr(S);
393 VisitDecl(S->getConstructor());
394 ID.AddBoolean(S->isElidable());
395}
396
397void StmtProfiler::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *S) {
398 VisitExplicitCastExpr(S);
399}
400
401void StmtProfiler::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *S) {
402 VisitCXXConstructExpr(S);
403}
404
405void StmtProfiler::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *S) {
406 VisitExpr(S);
407}
408
409void StmtProfiler::VisitCXXConditionDeclExpr(CXXConditionDeclExpr *S) {
410 VisitDeclRefExpr(S);
411}
412
413void StmtProfiler::VisitCXXDeleteExpr(CXXDeleteExpr *S) {
414 VisitExpr(S);
415 ID.AddBoolean(S->isGlobalDelete());
416 ID.AddBoolean(S->isArrayForm());
417 VisitDecl(S->getOperatorDelete());
418}
419
420
421void StmtProfiler::VisitCXXNewExpr(CXXNewExpr *S) {
422 VisitExpr(S);
423 VisitType(S->getAllocatedType());
424 VisitDecl(S->getOperatorNew());
425 VisitDecl(S->getOperatorDelete());
426 VisitDecl(S->getConstructor());
427 ID.AddBoolean(S->isArray());
428 ID.AddInteger(S->getNumPlacementArgs());
429 ID.AddBoolean(S->isGlobalNew());
430 ID.AddBoolean(S->isParenTypeId());
431 ID.AddBoolean(S->hasInitializer());
432 ID.AddInteger(S->getNumConstructorArgs());
433}
434
435void
436StmtProfiler::VisitUnresolvedFunctionNameExpr(UnresolvedFunctionNameExpr *S) {
437 VisitExpr(S);
438 VisitName(S->getName());
439}
440
441void StmtProfiler::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *S) {
442 VisitExpr(S);
443 ID.AddInteger(S->getTrait());
444 VisitType(S->getQueriedType());
445}
446
447void StmtProfiler::VisitQualifiedDeclRefExpr(QualifiedDeclRefExpr *S) {
448 VisitDeclRefExpr(S);
449 VisitNestedNameSpecifier(S->getQualifier());
450}
451
452void StmtProfiler::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *S) {
453 VisitExpr(S);
454 VisitName(S->getDeclName());
455 VisitNestedNameSpecifier(S->getQualifier());
456 ID.AddBoolean(S->isAddressOfOperand());
457}
458
459void StmtProfiler::VisitTemplateIdRefExpr(TemplateIdRefExpr *S) {
460 VisitExpr(S);
461 VisitNestedNameSpecifier(S->getQualifier());
462 VisitTemplateName(S->getTemplateName());
463 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
464}
465
466void StmtProfiler::VisitType(QualType T) {
467 if (Canonical) {
468 if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) {
469 ID.AddInteger(TTP->getDepth());
470 ID.AddInteger(TTP->getIndex());
471 return;
472 }
473
474 T = Context.getCanonicalType(T);
475 }
476
477 ID.AddPointer(T.getAsOpaquePtr());
478}
479
480void StmtProfiler::VisitName(DeclarationName Name) {
481 ID.AddPointer(Name.getAsOpaquePtr());
482}
483
484void StmtProfiler::VisitNestedNameSpecifier(NestedNameSpecifier *NNS) {
485 if (Canonical)
486 NNS = Context.getCanonicalNestedNameSpecifier(NNS);
487 ID.AddPointer(NNS);
488}
489
490void StmtProfiler::VisitTemplateName(TemplateName Name) {
491 if (Canonical)
492 Name = Context.getCanonicalTemplateName(Name);
493
494 Name.Profile(ID);
495}
496
497void StmtProfiler::VisitTemplateArguments(const TemplateArgument *Args,
498 unsigned NumArgs) {
499 ID.AddInteger(NumArgs);
500 for (unsigned I = 0; I != NumArgs; ++I) {
501 const TemplateArgument &Arg = Args[I];
502
503 // Mostly repetitive with TemplateArgument::Profile!
504 ID.AddInteger(Arg.getKind());
505 switch (Arg.getKind()) {
506 case TemplateArgument::Null:
507 break;
508
509 case TemplateArgument::Type:
510 VisitType(Arg.getAsType());
511 break;
512
513 case TemplateArgument::Declaration:
514 VisitDecl(Arg.getAsDecl());
515 break;
516
517 case TemplateArgument::Integral:
518 Arg.getAsIntegral()->Profile(ID);
519 VisitType(Arg.getIntegralType());
520 break;
521
522 case TemplateArgument::Expression:
523 Visit(Arg.getAsExpr());
524 break;
525
526 case TemplateArgument::Pack:
527 VisitTemplateArguments(Arg.pack_begin(), Arg.pack_size());
528 break;
529 }
530 }
531}
532
533void Stmt::Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
534 bool Canonical) {
535 StmtProfiler Profiler(ID, Context, Canonical);
536 Profiler.Visit(this);
537}