Query only the latest version of an identifier in the PCH chain. Make sure this version holds the entire declaration chain. This is a much saner solution than trying to merge the info from all elements, and makes redeclarations work properly. Expand the declarations test case to cover more compliated cases.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110052 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h
index 87c7624..dda1567 100644
--- a/include/clang/Frontend/PCHReader.h
+++ b/include/clang/Frontend/PCHReader.h
@@ -906,12 +906,6 @@
/// \brief Retrieve the macro definition with the given ID.
MacroDefinition *getMacroDefinition(pch::IdentID ID);
- /// \brief Erase the macro that's bound to the given IdentifierInfo.
- void EraseMacro(IdentifierInfo *II);
-
- /// \brief Check if the given macro identifier is built-in.
- bool isBuiltinMacro(IdentifierInfo *II);
-
/// \brief Retrieve the AST context that this PCH reader
/// supplements.
ASTContext *getContext() { return Context; }
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index 0502e67..d5cf75c 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -689,9 +689,6 @@
uint32_t Offset = ReadUnalignedLE32(d);
Reader.ReadMacroRecord(Stream, Offset);
DataLen -= 4;
- } else if (II->hasMacroDefinition() && !Reader.isBuiltinMacro(II)) {
- // A previous part of the chain added a macro, but this part #undefed it.
- Reader.EraseMacro(II);
}
// Read all of the declarations visible at global scope with this
@@ -1389,15 +1386,6 @@
return MacroDefinitionsLoaded[ID];
}
-void PCHReader::EraseMacro(IdentifierInfo *II) {
- PP->setMacroInfo(II, 0);
-}
-
-bool PCHReader::isBuiltinMacro(IdentifierInfo *II) {
- assert(II->hasMacroDefinition() && "Identifier is not a macro");
- return PP->getMacroInfo(II)->isBuiltinMacro();
-}
-
/// \brief If we are loading a relocatable PCH file, and the filename is
/// not an absolute path, add the system root to the beginning of the file
/// name.
@@ -3184,12 +3172,11 @@
}
IdentifierInfo* PCHReader::get(const char *NameStart, const char *NameEnd) {
- // Try to find this name within our on-disk hash tables. We need to aggregate
- // the info from all of them.
- IdentifierInfo *II = 0;
+ // Try to find this name within our on-disk hash tables. We start with the
+ // most recent one, since that one contains the most up-to-date info.
for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
PCHIdentifierLookupTable *IdTable
- = (PCHIdentifierLookupTable *)Chain[N - I - 1]->IdentifierLookupTable;
+ = (PCHIdentifierLookupTable *)Chain[I]->IdentifierLookupTable;
if (!IdTable)
continue;
std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
@@ -3200,9 +3187,9 @@
// Dereferencing the iterator has the effect of building the
// IdentifierInfo node and populating it with the various
// declarations it needs.
- II = *Pos;
+ return *Pos;
}
- return II;
+ return 0;
}
std::pair<ObjCMethodList, ObjCMethodList>
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 8bf85ef..641492c 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -1819,8 +1819,7 @@
for (IdentifierResolver::iterator D = IdentifierResolver::begin(II),
DEnd = IdentifierResolver::end();
D != DEnd; ++D)
- if (!Writer.hasChain() || (*D)->getPCHLevel() == 0)
- DataLen += sizeof(pch::DeclID);
+ DataLen += sizeof(pch::DeclID);
}
clang::io::Emit16(Out, DataLen);
// We emit the key length after the data length so that every
@@ -1872,8 +1871,7 @@
for (llvm::SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(),
DEnd = Decls.rend();
D != DEnd; ++D)
- if (!Writer.hasChain() || (*D)->getPCHLevel() == 0)
- clang::io::Emit32(Out, Writer.getDeclID(*D));
+ clang::io::Emit32(Out, Writer.getDeclID(*D));
}
};
} // end anonymous namespace
diff --git a/test/PCH/Inputs/chain-decls1.h b/test/PCH/Inputs/chain-decls1.h
index 79586ce..9de4461 100644
--- a/test/PCH/Inputs/chain-decls1.h
+++ b/test/PCH/Inputs/chain-decls1.h
@@ -2,3 +2,10 @@
struct one {};
void two();
+
+void many(int i);
+struct many;
+void many(int j);
+struct many;
+
+void noret();
diff --git a/test/PCH/Inputs/chain-decls2.h b/test/PCH/Inputs/chain-decls2.h
index 1826da9..b8b7d04 100644
--- a/test/PCH/Inputs/chain-decls2.h
+++ b/test/PCH/Inputs/chain-decls2.h
@@ -3,3 +3,10 @@
struct two {};
void one();
struct three {}; // for verification
+
+void many(int k);
+struct many;
+void many(int l);
+struct many {};
+
+void noret() __attribute__((noreturn));
diff --git a/test/PCH/chain-decls.c b/test/PCH/chain-decls.c
index f790a29..b3daa4a 100644
--- a/test/PCH/chain-decls.c
+++ b/test/PCH/chain-decls.c
@@ -10,7 +10,7 @@
// CHECK: void f();
// CHECK: void g();
-void h() {
+int h() {
f();
g();
@@ -19,4 +19,9 @@
struct two y;
two();
struct three z;
+
+ many(0);
+ struct many m;
+
+ noret();
}