1class Stmt {
2  code Code = [{
3    addData(S->getStmtClass());
4    // This ensures that non-macro-generated code isn't identical to
5    // macro-generated code.
6    addData(data_collection::getMacroStack(S->getBeginLoc(), Context));
7    addData(data_collection::getMacroStack(S->getEndLoc(), Context));
8  }];
9}
10
11class Expr {
12  code Code = [{
13    addData(S->getType());
14  }];
15}
16
17//--- Builtin functionality ----------------------------------------------//
18class ArrayTypeTraitExpr {
19  code Code = [{
20    addData(S->getTrait());
21  }];
22}
23class ExpressionTraitExpr {
24  code Code = [{
25    addData(S->getTrait());
26  }];
27}
28class PredefinedExpr {
29  code Code = [{
30    addData(S->getIdentKind());
31  }];
32}
33class TypeTraitExpr {
34  code Code = [{
35    addData(S->getTrait());
36    for (unsigned i = 0; i < S->getNumArgs(); ++i)
37      addData(S->getArg(i)->getType());
38  }];
39}
40
41//--- Calls --------------------------------------------------------------//
42class CallExpr {
43  code Code = [{
44    // Function pointers don't have a callee and we just skip hashing it.
45    if (const FunctionDecl *D = S->getDirectCallee()) {
46      // If the function is a template specialization, we also need to handle
47      // the template arguments as they are not included in the qualified name.
48      if (auto Args = D->getTemplateSpecializationArgs()) {
49        std::string ArgString;
50
51        // Print all template arguments into ArgString
52        llvm::raw_string_ostream OS(ArgString);
53        for (unsigned i = 0; i < Args->size(); ++i) {
54          Args->get(i).print(Context.getLangOpts(), OS, /*IncludeType*/ true);
55          // Add a padding character so that 'foo<X, XX>()' != 'foo<XX, X>()'.
56          OS << '\n';
57        }
58        OS.flush();
59
60        addData(ArgString);
61      }
62      addData(D->getQualifiedNameAsString());
63    }
64  }];
65}
66
67//--- Value references ---------------------------------------------------//
68class DeclRefExpr {
69  code Code = [{
70    addData(S->getDecl()->getQualifiedNameAsString());
71  }];
72}
73class MemberExpr {
74  code Code = [{
75    addData(S->getMemberDecl()->getName());
76  }];
77}
78
79//--- Literals -----------------------------------------------------------//
80class IntegerLiteral {
81  code Code = [{
82    addData(llvm::hash_value(S->getValue()));
83  }];
84}
85class FloatingLiteral {
86  code Code = [{
87    addData(llvm::hash_value(S->getValue()));
88  }];
89}
90class StringLiteral {
91  code Code = [{
92    addData(S->getString());
93}];
94}
95class CXXBoolLiteralExpr {
96  code Code = [{
97    addData(S->getValue());
98  }];
99}
100class CharacterLiteral {
101  code Code = [{
102    addData(S->getValue());
103  }];
104}
105
106//--- Exceptions ---------------------------------------------------------//
107class CXXCatchStmt {
108  code Code = [{
109    addData(S->getCaughtType());
110  }];
111}
112
113//--- C++ OOP Stmts ------------------------------------------------------//
114class CXXDeleteExpr {
115  code Code = [{
116    addData(S->isArrayFormAsWritten()); addData(S->isGlobalDelete());
117  }];
118}
119
120//--- Casts --------------------------------------------------------------//
121class ObjCBridgedCastExpr {
122  code Code = [{
123    addData(S->getBridgeKind());
124  }];
125}
126
127//--- Miscellaneous Exprs ------------------------------------------------//
128class BinaryOperator {
129  code Code = [{
130    addData(S->getOpcode());
131  }];
132}
133class UnaryOperator {
134  code Code = [{
135    addData(S->getOpcode());
136  }];
137}
138
139//--- Control flow -------------------------------------------------------//
140class GotoStmt {
141  code Code = [{
142    addData(S->getLabel()->getName());
143  }];
144}
145class IndirectGotoStmt {
146  code Code = [{
147    if (S->getConstantTarget())
148      addData(S->getConstantTarget()->getName());
149  }];
150}
151class LabelStmt {
152  code Code = [{
153    addData(S->getDecl()->getName());
154  }];
155}
156class MSDependentExistsStmt {
157  code Code = [{
158    addData(S->isIfExists());
159  }];
160}
161class AddrLabelExpr {
162  code Code = [{
163    addData(S->getLabel()->getName());
164  }];
165}
166
167//--- Objective-C --------------------------------------------------------//
168class ObjCIndirectCopyRestoreExpr {
169  code Code = [{
170    addData(S->shouldCopy());
171  }];
172}
173class ObjCPropertyRefExpr {
174  code Code = [{
175    addData(S->isSuperReceiver()); addData(S->isImplicitProperty());
176  }];
177}
178class ObjCAtCatchStmt {
179  code Code = [{
180    addData(S->hasEllipsis());
181  }];
182}
183
184//--- Miscellaneous Stmts ------------------------------------------------//
185class CXXFoldExpr {
186  code Code = [{
187    addData(S->isRightFold()); addData(S->getOperator());
188  }];
189}
190class GenericSelectionExpr {
191  code Code = [{
192    for (const GenericSelectionExpr::ConstAssociation Assoc : S->associations()) {
193      addData(Assoc.getType());
194    }
195  }];
196}
197class LambdaExpr {
198  code Code = [{
199    for (const LambdaCapture &C : S->captures()) {
200      addData(C.isPackExpansion());
201      addData(C.getCaptureKind());
202      if (C.capturesVariable())
203        addData(C.getCapturedVar()->getType());
204    }
205    addData(S->isGenericLambda());
206    addData(S->isMutable());
207  }];
208}
209class DeclStmt {
210  code Code = [{
211    auto numDecls = std::distance(S->decl_begin(), S->decl_end());
212    addData(static_cast<unsigned>(numDecls));
213    for (const Decl *D : S->decls()) {
214      if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
215        addData(VD->getType());
216      }
217    }
218  }];
219}
220class AsmStmt {
221  code Code = [{
222    addData(S->isSimple());
223    addData(S->isVolatile());
224    addData(S->generateAsmString(Context));
225    for (unsigned i = 0; i < S->getNumInputs(); ++i) {
226      addData(S->getInputConstraint(i));
227    }
228    for (unsigned i = 0; i < S->getNumOutputs(); ++i) {
229      addData(S->getOutputConstraint(i));
230    }
231    for (unsigned i = 0; i < S->getNumClobbers(); ++i) {
232      addData(S->getClobber(i));
233    }
234  }];
235}
236class AttributedStmt {
237  code Code = [{
238    for (const Attr *A : S->getAttrs()) {
239      addData(std::string(A->getSpelling()));
240    }
241  }];
242}
243