[cfe-commits] r115647 - in /cfe/trunk: lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp test/PCH/Inputs/chain-remap-types1.h test/PCH/Inputs/chain-remap-types2.h test/PCH/chain-remap-types.m tools/libclang/CIndexUSRs.cpp
Douglas Gregor
dgregor at apple.com
Tue Oct 5 11:37:06 PDT 2010
Author: dgregor
Date: Tue Oct 5 13:37:06 2010
New Revision: 115647
URL: http://llvm.org/viewvc/llvm-project?rev=115647&view=rev
Log:
Fix a marvelous chained AST writing bug, where we end up with the
following amusing sequence:
- AST writing schedules writing a type X* that it had never seen
before
- AST writing starts writing another declaration, ends up
deserializing X* from a prior AST file. Now we have two type IDs for
the same type!
- AST writer tries to write X*. It only has the lower-numbered ID
from the the prior AST file, so references to the higher-numbered ID
that was scheduled for writing go off into lalaland.
To fix this, keep the higher-numbered ID so we end up writing the type
twice. Since this issue occurs so rarely, and type records are
generally rather small, I deemed this better than the alternative: to
keep a separate mapping from the higher-numbered IDs to the
lower-numbered IDs, which we would end up having to check whenever we
want to deserialize any type.
Fixes <rdar://problem/8511624>, I think.
Added:
cfe/trunk/test/PCH/Inputs/chain-remap-types1.h
cfe/trunk/test/PCH/Inputs/chain-remap-types2.h
cfe/trunk/test/PCH/chain-remap-types.m
Modified:
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
cfe/trunk/tools/libclang/CIndexUSRs.cpp
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=115647&r1=115646&r2=115647&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Oct 5 13:37:06 2010
@@ -3115,6 +3115,9 @@
assert(Index < TypesLoaded.size() && "Type index out-of-range");
if (TypesLoaded[Index].isNull()) {
TypesLoaded[Index] = ReadTypeRecord(Index);
+ if (TypesLoaded[Index].isNull())
+ return QualType();
+
TypesLoaded[Index]->setFromAST();
TypeIdxs[TypesLoaded[Index]] = TypeIdx::fromTypeID(ID);
if (DeserializationListener)
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=115647&r1=115646&r2=115647&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Oct 5 13:37:06 2010
@@ -1419,10 +1419,7 @@
if (Idx.getIndex() == 0) // we haven't seen this type before.
Idx = TypeIdx(NextTypeID++);
- // If this type comes from a previously-loaded PCH/AST file, don't try to
- // write the type again.
- if (Idx.getIndex() < FirstTypeID)
- return;
+ assert(Idx.getIndex() >= FirstTypeID && "Re-writing a type from a prior AST");
// Record the offset for this type.
unsigned Index = Idx.getIndex() - FirstTypeID;
@@ -2872,7 +2869,7 @@
if (D == 0) {
return 0;
}
-
+ assert(!(reinterpret_cast<uintptr_t>(D) & 0x01) && "Invalid decl pointer");
DeclID &ID = DeclIDs[D];
if (ID == 0) {
// We haven't seen this declaration before. Give it a new ID and
@@ -3130,7 +3127,14 @@
}
void ASTWriter::TypeRead(TypeIdx Idx, QualType T) {
- TypeIdxs[T] = Idx;
+ // Always take the highest-numbered type index. This copes with an interesting
+ // case for chained AST writing where we schedule writing the type and then,
+ // later, deserialize the type from another AST. In this case, we want to
+ // keep the higher-numbered entry so that we can properly write it out to
+ // the AST file.
+ TypeIdx &StoredIdx = TypeIdxs[T];
+ if (Idx.getIndex() >= StoredIdx.getIndex())
+ StoredIdx = Idx;
}
void ASTWriter::DeclRead(DeclID ID, const Decl *D) {
Added: cfe/trunk/test/PCH/Inputs/chain-remap-types1.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/Inputs/chain-remap-types1.h?rev=115647&view=auto
==============================================================================
--- cfe/trunk/test/PCH/Inputs/chain-remap-types1.h (added)
+++ cfe/trunk/test/PCH/Inputs/chain-remap-types1.h Tue Oct 5 13:37:06 2010
@@ -0,0 +1,10 @@
+ at class X;
+
+struct Y {
+ X *my_X;
+};
+
+ at interface X {
+}
+ at property X *prop;
+ at end
Added: cfe/trunk/test/PCH/Inputs/chain-remap-types2.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/Inputs/chain-remap-types2.h?rev=115647&view=auto
==============================================================================
--- cfe/trunk/test/PCH/Inputs/chain-remap-types2.h (added)
+++ cfe/trunk/test/PCH/Inputs/chain-remap-types2.h Tue Oct 5 13:37:06 2010
@@ -0,0 +1,8 @@
+void h(X*);
+
+ at interface X (Blah) {
+}
+ at end
+
+void g(X*);
+
Added: cfe/trunk/test/PCH/chain-remap-types.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/chain-remap-types.m?rev=115647&view=auto
==============================================================================
--- cfe/trunk/test/PCH/chain-remap-types.m (added)
+++ cfe/trunk/test/PCH/chain-remap-types.m Tue Oct 5 13:37:06 2010
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-pch -x objective-c-header -o %t1 %S/Inputs/chain-remap-types1.h
+// RUN: %clang_cc1 -emit-pch -x objective-c-header -o %t2 %S/Inputs/chain-remap-types2.h -include-pch %t1 -chained-pch
+// RUN: %clang_cc1 -include-pch %t2 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -ast-print -include-pch %t2 %s | FileCheck %s
+
+// CHECK: @class X;
+// CHECK: struct Y
+// CHECK: @property ( assign,readwrite ) X * prop
+// CHECK: void h(X *);
+// CHECK: @interface X(Blah)
+// CHECK: void g(X *);
+
Modified: cfe/trunk/tools/libclang/CIndexUSRs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexUSRs.cpp?rev=115647&r1=115646&r2=115647&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexUSRs.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexUSRs.cpp Tue Oct 5 13:37:06 2010
@@ -699,7 +699,8 @@
break;
case TemplateArgument::Declaration:
- Visit(Arg.getAsDecl());
+ if (Decl *D = Arg.getAsDecl())
+ Visit(D);
break;
case TemplateArgument::Template:
More information about the cfe-commits
mailing list