Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===-- ODRHash.h - Hashing to diagnose ODR failures ------------*- C++ -*-===// |
2 | // |
||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
||
4 | // See https://llvm.org/LICENSE.txt for license information. |
||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
||
6 | // |
||
7 | //===----------------------------------------------------------------------===// |
||
8 | /// |
||
9 | /// \file |
||
10 | /// This file contains the declaration of the ODRHash class, which calculates |
||
11 | /// a hash based on AST nodes, which is stable across different runs. |
||
12 | /// |
||
13 | //===----------------------------------------------------------------------===// |
||
14 | |||
15 | #ifndef LLVM_CLANG_AST_ODRHASH_H |
||
16 | #define LLVM_CLANG_AST_ODRHASH_H |
||
17 | |||
18 | #include "clang/AST/DeclarationName.h" |
||
19 | #include "clang/AST/Type.h" |
||
20 | #include "clang/AST/TemplateBase.h" |
||
21 | #include "llvm/ADT/DenseMap.h" |
||
22 | #include "llvm/ADT/FoldingSet.h" |
||
23 | #include "llvm/ADT/PointerUnion.h" |
||
24 | #include "llvm/ADT/SmallVector.h" |
||
25 | |||
26 | namespace clang { |
||
27 | |||
28 | class Decl; |
||
29 | class IdentifierInfo; |
||
30 | class NestedNameSpecifier; |
||
31 | class Stmt; |
||
32 | class TemplateParameterList; |
||
33 | |||
34 | // ODRHash is used to calculate a hash based on AST node contents that |
||
35 | // does not rely on pointer addresses. This allows the hash to not vary |
||
36 | // between runs and is usable to detect ODR problems in modules. To use, |
||
37 | // construct an ODRHash object, then call Add* methods over the nodes that |
||
38 | // need to be hashed. Then call CalculateHash to get the hash value. |
||
39 | // Typically, only one Add* call is needed. clear can be called to reuse the |
||
40 | // object. |
||
41 | class ODRHash { |
||
42 | // Use DenseMaps to convert from DeclarationName and Type pointers |
||
43 | // to an index value. |
||
44 | llvm::DenseMap<DeclarationName, unsigned> DeclNameMap; |
||
45 | |||
46 | // Save space by processing bools at the end. |
||
47 | llvm::SmallVector<bool, 128> Bools; |
||
48 | |||
49 | llvm::FoldingSetNodeID ID; |
||
50 | |||
51 | public: |
||
52 | ODRHash() {} |
||
53 | |||
54 | // Use this for ODR checking classes between modules. This method compares |
||
55 | // more information than the AddDecl class. |
||
56 | void AddCXXRecordDecl(const CXXRecordDecl *Record); |
||
57 | |||
58 | // Use this for ODR checking records in C/Objective-C between modules. This |
||
59 | // method compares more information than the AddDecl class. |
||
60 | void AddRecordDecl(const RecordDecl *Record); |
||
61 | |||
62 | // Use this for ODR checking ObjC interfaces. This |
||
63 | // method compares more information than the AddDecl class. |
||
64 | void AddObjCInterfaceDecl(const ObjCInterfaceDecl *Record); |
||
65 | |||
66 | // Use this for ODR checking functions between modules. This method compares |
||
67 | // more information than the AddDecl class. SkipBody will process the |
||
68 | // hash as if the function has no body. |
||
69 | void AddFunctionDecl(const FunctionDecl *Function, bool SkipBody = false); |
||
70 | |||
71 | // Use this for ODR checking enums between modules. This method compares |
||
72 | // more information than the AddDecl class. |
||
73 | void AddEnumDecl(const EnumDecl *Enum); |
||
74 | |||
75 | // Use this for ODR checking ObjC protocols. This |
||
76 | // method compares more information than the AddDecl class. |
||
77 | void AddObjCProtocolDecl(const ObjCProtocolDecl *P); |
||
78 | |||
79 | // Process SubDecls of the main Decl. This method calls the DeclVisitor |
||
80 | // while AddDecl does not. |
||
81 | void AddSubDecl(const Decl *D); |
||
82 | |||
83 | // Reset the object for reuse. |
||
84 | void clear(); |
||
85 | |||
86 | // Add booleans to ID and uses it to calculate the hash. |
||
87 | unsigned CalculateHash(); |
||
88 | |||
89 | // Add AST nodes that need to be processed. |
||
90 | void AddDecl(const Decl *D); |
||
91 | void AddType(const Type *T); |
||
92 | void AddQualType(QualType T); |
||
93 | void AddStmt(const Stmt *S); |
||
94 | void AddIdentifierInfo(const IdentifierInfo *II); |
||
95 | void AddNestedNameSpecifier(const NestedNameSpecifier *NNS); |
||
96 | void AddTemplateName(TemplateName Name); |
||
97 | void AddDeclarationName(DeclarationName Name, bool TreatAsDecl = false); |
||
98 | void AddTemplateArgument(TemplateArgument TA); |
||
99 | void AddTemplateParameterList(const TemplateParameterList *TPL); |
||
100 | |||
101 | // Save booleans until the end to lower the size of data to process. |
||
102 | void AddBoolean(bool value); |
||
103 | |||
104 | static bool isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent); |
||
105 | |||
106 | private: |
||
107 | void AddDeclarationNameImpl(DeclarationName Name); |
||
108 | }; |
||
109 | |||
110 | } // end namespace clang |
||
111 | |||
112 | #endif |