StmtProfile.cpp revision 41ef0c3472a3d09c29bc1792f3d26842f2b8a695
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 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}
538