diff options
author | Anders Carlsson <andersca@mac.com> | 2011-03-09 05:09:32 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2011-03-09 05:09:32 +0000 |
commit | 1f13bb5f00ece51fb247f7d85cc21ee55ddb5717 (patch) | |
tree | 04a0eaf4d47742b3a95829deea2577da140c151a /clang | |
parent | a738c25f5e095b2c72c4bfece65c00df7e23d750 (diff) | |
download | bcm5719-llvm-1f13bb5f00ece51fb247f7d85cc21ee55ddb5717.tar.gz bcm5719-llvm-1f13bb5f00ece51fb247f7d85cc21ee55ddb5717.zip |
When deserializing CXXBaseSpecifiers (and offsets), make sure to walk the chain in the correct order.
llvm-svn: 127315
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 18 | ||||
-rw-r--r-- | clang/test/PCH/chain-cxx.cpp | 6 |
2 files changed, 16 insertions, 8 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 72637c1eb0b..4717cd62684 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -3730,11 +3730,13 @@ ASTReader::GetCXXBaseSpecifiersOffset(serialization::CXXBaseSpecifiersID ID) { --ID; uint64_t Offset = 0; for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - if (ID < Chain[I]->LocalNumCXXBaseSpecifiers) - return Offset + Chain[I]->CXXBaseSpecifiersOffsets[ID]; + PerFileData &F = *Chain[N - I - 1]; + + if (ID < F.LocalNumCXXBaseSpecifiers) + return Offset + F.CXXBaseSpecifiersOffsets[ID]; - ID -= Chain[I]->LocalNumCXXBaseSpecifiers; - Offset += Chain[I]->SizeInBits; + ID -= F.LocalNumCXXBaseSpecifiers; + Offset += F.SizeInBits; } assert(false && "CXXBaseSpecifiers not found"); @@ -3745,14 +3747,14 @@ CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) { // Figure out which AST file contains this offset. PerFileData *F = 0; for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - if (Offset < Chain[I]->SizeInBits) { - F = Chain[I]; + if (Offset < Chain[N - I - 1]->SizeInBits) { + F = Chain[N - I - 1]; break; } - Offset -= Chain[I]->SizeInBits; + Offset -= Chain[N - I - 1]->SizeInBits; } - + if (!F) { Error("Malformed AST file: C++ base specifiers at impossible offset"); return 0; diff --git a/clang/test/PCH/chain-cxx.cpp b/clang/test/PCH/chain-cxx.cpp index 852af05d572..bf37acb298e 100644 --- a/clang/test/PCH/chain-cxx.cpp +++ b/clang/test/PCH/chain-cxx.cpp @@ -34,6 +34,9 @@ struct S<T *> { typedef int H; }; template <typename T> struct TS2; typedef TS2<int> TS2int; +template <typename T> struct TestBaseSpecifiers { }; +template<typename T> struct TestBaseSpecifiers2 : TestBaseSpecifiers<T> { }; + //===----------------------------------------------------------------------===// #elif not defined(HEADER2) #define HEADER2 @@ -73,6 +76,9 @@ struct S<int &> { typedef int L; }; template <typename T> struct TS2 { }; +struct TestBaseSpecifiers3 { }; +struct TestBaseSpecifiers4 : TestBaseSpecifiers3 { }; + struct A { }; struct B : A { }; |