1 | class 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 | |
11 | class Expr { |
12 | code Code = [{ |
13 | addData(S->getType()); |
14 | }]; |
15 | } |
16 | |
17 | //--- Builtin functionality ----------------------------------------------// |
18 | class ArrayTypeTraitExpr { |
19 | code Code = [{ |
20 | addData(S->getTrait()); |
21 | }]; |
22 | } |
23 | class ExpressionTraitExpr { |
24 | code Code = [{ |
25 | addData(S->getTrait()); |
26 | }]; |
27 | } |
28 | class PredefinedExpr { |
29 | code Code = [{ |
30 | addData(S->getIdentKind()); |
31 | }]; |
32 | } |
33 | class 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 --------------------------------------------------------------// |
42 | class 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); |
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 ---------------------------------------------------// |
68 | class DeclRefExpr { |
69 | code Code = [{ |
70 | addData(S->getDecl()->getQualifiedNameAsString()); |
71 | }]; |
72 | } |
73 | class MemberExpr { |
74 | code Code = [{ |
75 | addData(S->getMemberDecl()->getName()); |
76 | }]; |
77 | } |
78 | |
79 | //--- Literals -----------------------------------------------------------// |
80 | class IntegerLiteral { |
81 | code Code = [{ |
82 | addData(llvm::hash_value(S->getValue())); |
83 | }]; |
84 | } |
85 | class FloatingLiteral { |
86 | code Code = [{ |
87 | addData(llvm::hash_value(S->getValue())); |
88 | }]; |
89 | } |
90 | class StringLiteral { |
91 | code Code = [{ |
92 | addData(S->getString()); |
93 | }]; |
94 | } |
95 | class CXXBoolLiteralExpr { |
96 | code Code = [{ |
97 | addData(S->getValue()); |
98 | }]; |
99 | } |
100 | class CharacterLiteral { |
101 | code Code = [{ |
102 | addData(S->getValue()); |
103 | }]; |
104 | } |
105 | |
106 | //--- Exceptions ---------------------------------------------------------// |
107 | class CXXCatchStmt { |
108 | code Code = [{ |
109 | addData(S->getCaughtType()); |
110 | }]; |
111 | } |
112 | |
113 | //--- C++ OOP Stmts ------------------------------------------------------// |
114 | class CXXDeleteExpr { |
115 | code Code = [{ |
116 | addData(S->isArrayFormAsWritten()); addData(S->isGlobalDelete()); |
117 | }]; |
118 | } |
119 | |
120 | //--- Casts --------------------------------------------------------------// |
121 | class ObjCBridgedCastExpr { |
122 | code Code = [{ |
123 | addData(S->getBridgeKind()); |
124 | }]; |
125 | } |
126 | |
127 | //--- Miscellaneous Exprs ------------------------------------------------// |
128 | class BinaryOperator { |
129 | code Code = [{ |
130 | addData(S->getOpcode()); |
131 | }]; |
132 | } |
133 | class UnaryOperator { |
134 | code Code = [{ |
135 | addData(S->getOpcode()); |
136 | }]; |
137 | } |
138 | |
139 | //--- Control flow -------------------------------------------------------// |
140 | class GotoStmt { |
141 | code Code = [{ |
142 | addData(S->getLabel()->getName()); |
143 | }]; |
144 | } |
145 | class IndirectGotoStmt { |
146 | code Code = [{ |
147 | if (S->getConstantTarget()) |
148 | addData(S->getConstantTarget()->getName()); |
149 | }]; |
150 | } |
151 | class LabelStmt { |
152 | code Code = [{ |
153 | addData(S->getDecl()->getName()); |
154 | }]; |
155 | } |
156 | class MSDependentExistsStmt { |
157 | code Code = [{ |
158 | addData(S->isIfExists()); |
159 | }]; |
160 | } |
161 | class AddrLabelExpr { |
162 | code Code = [{ |
163 | addData(S->getLabel()->getName()); |
164 | }]; |
165 | } |
166 | |
167 | //--- Objective-C --------------------------------------------------------// |
168 | class ObjCIndirectCopyRestoreExpr { |
169 | code Code = [{ |
170 | addData(S->shouldCopy()); |
171 | }]; |
172 | } |
173 | class ObjCPropertyRefExpr { |
174 | code Code = [{ |
175 | addData(S->isSuperReceiver()); addData(S->isImplicitProperty()); |
176 | }]; |
177 | } |
178 | class ObjCAtCatchStmt { |
179 | code Code = [{ |
180 | addData(S->hasEllipsis()); |
181 | }]; |
182 | } |
183 | |
184 | //--- Miscellaneous Stmts ------------------------------------------------// |
185 | class CXXFoldExpr { |
186 | code Code = [{ |
187 | addData(S->isRightFold()); addData(S->getOperator()); |
188 | }]; |
189 | } |
190 | class GenericSelectionExpr { |
191 | code Code = [{ |
192 | for (const GenericSelectionExpr::ConstAssociation &Assoc : S->associations()) { |
193 | addData(Assoc.getType()); |
194 | } |
195 | }]; |
196 | } |
197 | class 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 | } |
209 | class 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 | } |
220 | class 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 | } |
236 | class AttributedStmt { |
237 | code Code = [{ |
238 | for (const Attr *A : S->getAttrs()) { |
239 | addData(std::string(A->getSpelling())); |
240 | } |
241 | }]; |
242 | } |
243 | |