diff options
author | Richard Trieu <rtrieu@google.com> | 2017-02-16 04:53:40 +0000 |
---|---|---|
committer | Richard Trieu <rtrieu@google.com> | 2017-02-16 04:53:40 +0000 |
commit | 425da462267937112ffbd4c5a7031ef42402c34f (patch) | |
tree | 2fec310ca80446f337840e04f572dbe823115c19 /include/clang/AST/DeclCXX.h | |
parent | 58aece0e2be5c36b3a576fcbb51d36bb1cdc88d3 (diff) |
Add better ODR checking for modules.
Recommit r293585 that was reverted in r293611 with new fixes. The previous
issue was determined to be an overly aggressive AST visitor from forward
declared objects. The visitor will now only deeply visit certain Decl's and
only do a shallow information extraction from all other Decl's.
When objects are imported for modules, there is a chance that a name collision
will cause an ODR violation. Previously, only a small number of such
violations were detected. This patch provides a stronger check based on
AST nodes.
The information needed to uniquely identify an object is taken from the AST and
put into a one-dimensional byte stream. This stream is then hashed to give
a value to represent the object, which is stored with the other object data
in the module.
When modules are loaded, and Decl's are merged, the hash values of the two
Decl's are compared. Only Decl's with matched hash values will be merged.
Mismatch hashes will generate a module error, and if possible, point to the
first difference between the two objects.
The transform from AST to byte stream is a modified depth first algorithm.
Due to references between some AST nodes, a pure depth first algorithm could
generate loops. For Stmt nodes, a straight depth first processing occurs.
For Type and Decl nodes, they are replaced with an index number and only on
first visit will these nodes be processed. As an optimization, boolean
values are saved and stored together in reverse order at the end of the
byte stream to lower the ammount of data that needs to be hashed.
Compile time impact was measured at 1.5-2.0% during module building, and
negligible during builds without module building.
Differential Revision: https://reviews.llvm.org/D21675
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@295284 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/AST/DeclCXX.h')
-rw-r--r-- | include/clang/AST/DeclCXX.h | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 020ebfb4af..c8db319f9d 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -458,6 +458,9 @@ class CXXRecordDecl : public RecordDecl { /// \brief Whether we are currently parsing base specifiers. unsigned IsParsingBaseSpecifiers : 1; + /// \brief A hash of parts of the class to help in ODR checking. + unsigned ODRHash; + /// \brief The number of base class specifiers in Bases. unsigned NumBases; @@ -703,6 +706,9 @@ public: return data().IsParsingBaseSpecifiers; } + void computeODRHash(); + unsigned getODRHash() const { return data().ODRHash; } + /// \brief Sets the base classes of this struct or class. void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases); |