aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2010-07-23 23:49:55 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2010-07-23 23:49:55 +0000
commitf2f0f03d08c6143137a79a8edffc7d41823bc3c7 (patch)
tree91df81088e1d756f673a35141a3c32a27161b913
parentc4b5bd89e1ef611c7a31b767763030acc45274c8 (diff)
Make declarations in the dependent PCH visible, for C at least.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109292 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Frontend/PCHDeserializationListener.h2
-rw-r--r--include/clang/Frontend/PCHReader.h7
-rw-r--r--include/clang/Frontend/PCHWriter.h16
-rw-r--r--lib/Frontend/PCHReader.cpp4
-rw-r--r--lib/Frontend/PCHWriter.cpp39
-rw-r--r--lib/Frontend/PCHWriterDecl.cpp4
-rw-r--r--test/PCH/Inputs/chain-function1.h1
-rw-r--r--test/PCH/Inputs/chain-function2.h1
-rw-r--r--test/PCH/chain-function.c8
9 files changed, 68 insertions, 14 deletions
diff --git a/include/clang/Frontend/PCHDeserializationListener.h b/include/clang/Frontend/PCHDeserializationListener.h
index 84d7f8c1f5..fe9c755605 100644
--- a/include/clang/Frontend/PCHDeserializationListener.h
+++ b/include/clang/Frontend/PCHDeserializationListener.h
@@ -27,6 +27,8 @@ protected:
virtual ~PCHDeserializationListener() {}
public:
+ /// \brief An identifier was deserialized from the PCH.
+ virtual void IdentifierRead(pch::IdentID ID, IdentifierInfo *II) = 0;
/// \brief A type was deserialized from the PCH. The ID here has the qualifier
/// bits already removed, and T is guaranteed to be locally unqualified
virtual void TypeRead(pch::TypeID ID, QualType T) = 0;
diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h
index 17a733ce30..8bf51e109e 100644
--- a/include/clang/Frontend/PCHReader.h
+++ b/include/clang/Frontend/PCHReader.h
@@ -655,11 +655,16 @@ public:
/// \brief Read preprocessed entities into the
virtual void ReadPreprocessedEntities();
- /// \brief Returns the number of source locations found in this file.
+ /// \brief Returns the number of source locations found in the chain.
unsigned getTotalNumSLocs() const {
return TotalNumSLocEntries;
}
+ /// \brief Returns the number of identifiers found in the chain.
+ unsigned getTotalNumIdentifiers() const {
+ return static_cast<unsigned>(IdentifiersLoaded.size());
+ }
+
/// \brief Returns the number of types found in this file.
unsigned getTotalNumTypes() const {
return static_cast<unsigned>(TypesLoaded.size());
diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h
index ab6c6ef8c6..10b96e8a3c 100644
--- a/include/clang/Frontend/PCHWriter.h
+++ b/include/clang/Frontend/PCHWriter.h
@@ -113,6 +113,9 @@ private:
/// \brief The first ID number we can use for our own declarations.
pch::DeclID FirstDeclID;
+ /// \brief The decl ID that will be assigned to the next new decl.
+ pch::DeclID NextDeclID;
+
/// \brief Map that provides the ID numbers of each declaration within
/// the output stream, as well as those deserialized from a chained PCH.
///
@@ -128,6 +131,9 @@ private:
/// \brief The first ID number we can use for our own types.
pch::TypeID FirstTypeID;
+ /// \brief The type ID that will be assigned to the next new type.
+ pch::TypeID NextTypeID;
+
/// \brief Map that provides the ID numbers of each type within the
/// output stream, plus those deserialized from a chained PCH.
///
@@ -143,8 +149,11 @@ private:
/// the type's ID.
std::vector<uint32_t> TypeOffsets;
- /// \brief The type ID that will be assigned to the next new type.
- pch::TypeID NextTypeID;
+ /// \brief The first ID number we can use for our own identifiers.
+ pch::IdentID FirstIdentID;
+
+ /// \brief The identifier ID that will be assigned to the next new identifier.
+ pch::IdentID NextIdentID;
/// \brief Map that provides the ID numbers of each identifier in
/// the output stream.
@@ -405,7 +414,10 @@ public:
unsigned getParmVarDeclAbbrev() const { return ParmVarDeclAbbrev; }
+ bool hasChain() const { return Chain; }
+
// PCHDeserializationListener implementation
+ void IdentifierRead(pch::IdentID ID, IdentifierInfo *II);
void TypeRead(pch::TypeID ID, QualType T);
void DeclRead(pch::DeclID ID, const Decl *D);
};
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index b4564885a8..48d05ba826 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -3193,6 +3193,8 @@ void PCHReader::SetIdentifierInfo(unsigned ID, IdentifierInfo *II) {
assert(ID && "Non-zero identifier ID required");
assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range");
IdentifiersLoaded[ID - 1] = II;
+ if (DeserializationListener)
+ DeserializationListener->IdentifierRead(ID, II);
}
/// \brief Set the globally-visible declarations associated with the given
@@ -3277,6 +3279,8 @@ IdentifierInfo *PCHReader::DecodeIdentifierInfo(unsigned ID) {
| (((unsigned) StrLenPtr[1]) << 8)) - 1;
IdentifiersLoaded[ID]
= &PP->getIdentifierTable().get(Str, StrLen);
+ if (DeserializationListener)
+ DeserializationListener->IdentifierRead(ID + 1, IdentifiersLoaded[ID]);
}
return IdentifiersLoaded[ID];
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 0b8c5b4258..4474eaef48 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -1851,12 +1851,14 @@ public:
// "stat"), but IdentifierResolver::AddDeclToIdentifierChain()
// adds declarations to the end of the list (so we need to see the
// struct "status" before the function "status").
+ // Only emit declarations that aren't from a chained PCH, though.
llvm::SmallVector<Decl *, 16> Decls(IdentifierResolver::begin(II),
IdentifierResolver::end());
for (llvm::SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(),
DEnd = Decls.rend();
D != DEnd; ++D)
- clang::io::Emit32(Out, Writer.getDeclID(*D));
+ if (!Writer.hasChain() || (*D)->getPCHLevel() == 0)
+ clang::io::Emit32(Out, Writer.getDeclID(*D));
}
};
} // end anonymous namespace
@@ -1884,13 +1886,17 @@ void PCHWriter::WriteIdentifierTable(Preprocessor &PP) {
ID != IDEnd; ++ID)
getIdentifierRef(ID->second);
- // Create the on-disk hash table representation.
- IdentifierOffsets.resize(IdentifierIDs.size());
+ // Create the on-disk hash table representation. We only store offsets
+ // for identifiers that appear here for the first time.
+ IdentifierOffsets.resize(NextIdentID - FirstIdentID);
for (llvm::DenseMap<const IdentifierInfo *, pch::IdentID>::iterator
ID = IdentifierIDs.begin(), IDEnd = IdentifierIDs.end();
ID != IDEnd; ++ID) {
assert(ID->first && "NULL identifier in identifier table");
- Generator.insert(ID->first, ID->second);
+ // FIXME: Right now, we only write identifiers that are new to this file.
+ // We need to write older identifiers that changed too, though.
+ if (ID->second >= FirstIdentID)
+ Generator.insert(ID->first, ID->second);
}
// Create the on-disk hash table in a buffer.
@@ -2116,7 +2122,11 @@ void PCHWriter::AddString(const std::string &Str, RecordData &Record) {
/// \brief Note that the identifier II occurs at the given offset
/// within the identifier table.
void PCHWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) {
- IdentifierOffsets[IdentifierIDs[II] - 1] = Offset;
+ pch::IdentID ID = IdentifierIDs[II];
+ // Only store offsets new to this PCH file. Other identifier names are looked
+ // up earlier in the chain and thus don't need an offset.
+ if (ID >= FirstIdentID)
+ IdentifierOffsets[ID - FirstIdentID] = Offset;
}
/// \brief Note that the selector Sel occurs at the given offset
@@ -2129,15 +2139,18 @@ void PCHWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream, PCHReader *Chain)
: Stream(Stream), Chain(Chain), FirstDeclID(1),
- FirstTypeID(pch::NUM_PREDEF_TYPE_IDS),
+ FirstTypeID(pch::NUM_PREDEF_TYPE_IDS), FirstIdentID(1),
CollectedStmts(&StmtsToEmit), NumStatements(0), NumMacros(0),
NumLexicalDeclContexts(0), NumVisibleDeclContexts(0) {
if (Chain) {
Chain->setDeserializationListener(this);
FirstDeclID += Chain->getTotalNumDecls();
FirstTypeID += Chain->getTotalNumTypes();
+ FirstIdentID += Chain->getTotalNumIdentifiers();
}
+ NextDeclID = FirstDeclID;
NextTypeID = FirstTypeID;
+ NextIdentID = FirstIdentID;
}
void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
@@ -2165,6 +2178,7 @@ void PCHWriter::WritePCHCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
// The translation unit is the first declaration we'll emit.
DeclIDs[Context.getTranslationUnitDecl()] = 1;
+ ++NextDeclID;
DeclTypesToEmit.push(Context.getTranslationUnitDecl());
// Make sure that we emit IdentifierInfos (and any attached
@@ -2334,6 +2348,9 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
// We don't start with the translation unit, but with its decls that
// don't come from the other PCH.
const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
+ // The TU was loaded before we managed to register ourselves as a listener.
+ // Thus we need to add it manually.
+ DeclIDs[TU] = 1;
// FIXME: We don't want to iterate over everything here, because it needlessly
// deserializes the entire original PCH. Instead we only want to iterate over
// the stuff that's already there.
@@ -2359,7 +2376,7 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
// FIXME: Preprocessor
// FIXME: Method pool
- // FIXME: Identifier table
+ WriteIdentifierTable(PP);
WriteTypeDeclOffsets();
// FIXME: External unnamed definitions
// FIXME: Tentative definitions
@@ -2407,7 +2424,7 @@ pch::IdentID PCHWriter::getIdentifierRef(const IdentifierInfo *II) {
pch::IdentID &ID = IdentifierIDs[II];
if (ID == 0)
- ID = IdentifierIDs.size();
+ ID = NextIdentID++;
return ID;
}
@@ -2576,7 +2593,7 @@ void PCHWriter::AddDeclRef(const Decl *D, RecordData &Record) {
if (ID == 0) {
// We haven't seen this declaration before. Give it a new ID and
// enqueue it in the list of declarations to emit.
- ID = DeclIDs.size();
+ ID = NextDeclID++;
DeclTypesToEmit.push(const_cast<Decl *>(D));
}
@@ -2777,6 +2794,10 @@ void PCHWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base,
AddSourceRange(Base.getSourceRange(), Record);
}
+void PCHWriter::IdentifierRead(pch::IdentID ID, IdentifierInfo *II) {
+ IdentifierIDs[II] = ID;
+}
+
void PCHWriter::TypeRead(pch::TypeID ID, QualType T) {
TypeIDs[T] = ID;
}
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
index 7c4a21adb6..09cafe2c33 100644
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -1144,9 +1144,9 @@ void PCHWriter::WriteDecl(ASTContext &Context, Decl *D) {
// Determine the ID for this declaration
pch::DeclID &ID = DeclIDs[D];
if (ID == 0)
- ID = DeclIDs.size();
+ ID = NextDeclID++;
- unsigned Index = ID - 1;
+ unsigned Index = ID - FirstDeclID;
// Record the offset for this declaration
if (DeclOffsets.size() == Index)
diff --git a/test/PCH/Inputs/chain-function1.h b/test/PCH/Inputs/chain-function1.h
new file mode 100644
index 0000000000..789447c027
--- /dev/null
+++ b/test/PCH/Inputs/chain-function1.h
@@ -0,0 +1 @@
+void f();
diff --git a/test/PCH/Inputs/chain-function2.h b/test/PCH/Inputs/chain-function2.h
new file mode 100644
index 0000000000..e8fc9651ed
--- /dev/null
+++ b/test/PCH/Inputs/chain-function2.h
@@ -0,0 +1 @@
+void g();
diff --git a/test/PCH/chain-function.c b/test/PCH/chain-function.c
new file mode 100644
index 0000000000..29bfdd4c3e
--- /dev/null
+++ b/test/PCH/chain-function.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-pch -o %t1 %S/Inputs/chain-function1.h
+// RUN: %clang_cc1 -emit-pch -o %t2 %S/Inputs/chain-function2.h -include-pch %t1 -chained-pch
+// RUN: %clang_cc1 -fsyntax-only -verify -include-pch %t2 %s
+
+void h() {
+ f();
+ g();
+}