[PCH] Now that we store the location of a decl outside its record

make sure that we keep track of locations of replaced decls as well.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143341 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Argyrios Kyrtzidis 2011-10-31 07:20:15 +00:00
Родитель 9d128d0457
Коммит ef23b6001e
7 изменённых файлов: 58 добавлений и 13 удалений

Просмотреть файл

@ -290,8 +290,17 @@ private:
/// in the chain.
DeclUpdateOffsetsMap DeclUpdateOffsets;
typedef llvm::DenseMap<serialization::DeclID,
std::pair<Module *, uint64_t> >
struct ReplacedDeclInfo {
Module *Mod;
uint64_t Offset;
unsigned RawLoc;
ReplacedDeclInfo() : Mod(0), Offset(0), RawLoc(0) {}
ReplacedDeclInfo(Module *Mod, uint64_t Offset, unsigned RawLoc)
: Mod(Mod), Offset(Offset), RawLoc(RawLoc) {}
};
typedef llvm::DenseMap<serialization::DeclID, ReplacedDeclInfo>
DeclReplacementMap;
/// \brief Declarations that have been replaced in a later file in the chain.
DeclReplacementMap ReplacedDecls;

Просмотреть файл

@ -286,14 +286,24 @@ private:
/// another module.
SmallVector<ChainedObjCCategoriesData, 16> LocalChainedObjCCategories;
struct ReplacedDeclInfo {
serialization::DeclID ID;
uint64_t Offset;
unsigned Loc;
ReplacedDeclInfo() : ID(0), Offset(0), Loc(0) {}
ReplacedDeclInfo(serialization::DeclID ID, uint64_t Offset,
SourceLocation Loc)
: ID(ID), Offset(Offset), Loc(Loc.getRawEncoding()) {}
};
/// \brief Decls that have been replaced in the current dependent AST file.
///
/// When a decl changes fundamentally after being deserialized (this shouldn't
/// happen, but the ObjC AST nodes are designed this way), it will be
/// serialized again. In this case, it is registered here, so that the reader
/// knows to read the updated version.
SmallVector<std::pair<serialization::DeclID, uint64_t>, 16>
ReplacedDecls;
SmallVector<ReplacedDeclInfo, 16> ReplacedDecls;
/// \brief Statements that we've encountered while serializing a
/// declaration or type.

Просмотреть файл

@ -2217,13 +2217,13 @@ ASTReader::ReadASTBlock(Module &F) {
}
case DECL_REPLACEMENTS: {
if (Record.size() % 2 != 0) {
if (Record.size() % 3 != 0) {
Error("invalid DECL_REPLACEMENTS block in AST file");
return Failure;
}
for (unsigned I = 0, N = Record.size(); I != N; I += 2)
for (unsigned I = 0, N = Record.size(); I != N; I += 3)
ReplacedDecls[getGlobalDeclID(F, Record[I])]
= std::make_pair(&F, Record[I+1]);
= ReplacedDeclInfo(&F, Record[I+1], Record[I+2]);
break;
}

Просмотреть файл

@ -1449,8 +1449,10 @@ ASTReader::RecordLocation
ASTReader::DeclCursorForID(DeclID ID, unsigned &RawLocation) {
// See if there's an override.
DeclReplacementMap::iterator It = ReplacedDecls.find(ID);
if (It != ReplacedDecls.end())
return RecordLocation(It->second.first, It->second.second);
if (It != ReplacedDecls.end()) {
RawLocation = It->second.RawLoc;
return RecordLocation(It->second.Mod, It->second.Offset);
}
GlobalDeclMapType::iterator I = GlobalDeclMap.find(ID);
assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");

Просмотреть файл

@ -3234,10 +3234,11 @@ void ASTWriter::WriteDeclReplacementsBlock() {
return;
RecordData Record;
for (SmallVector<std::pair<DeclID, uint64_t>, 16>::iterator
for (SmallVector<ReplacedDeclInfo, 16>::iterator
I = ReplacedDecls.begin(), E = ReplacedDecls.end(); I != E; ++I) {
Record.push_back(I->first);
Record.push_back(I->second);
Record.push_back(I->ID);
Record.push_back(I->Offset);
Record.push_back(I->Loc);
}
Stream.EmitRecord(DECL_REPLACEMENTS, Record);
}

Просмотреть файл

@ -1647,7 +1647,8 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
if (ID < FirstDeclID) {
// We're replacing a decl in a previous file.
ReplacedDecls.push_back(std::make_pair(ID, Stream.GetCurrentBitNo()));
ReplacedDecls.push_back(ReplacedDeclInfo(ID, Stream.GetCurrentBitNo(),
D->getLocation()));
} else {
unsigned Index = ID - FirstDeclID;

22
test/PCH/replaced-decl.m Normal file
Просмотреть файл

@ -0,0 +1,22 @@
// Without PCH
// RUN: %clang_cc1 -fsyntax-only -verify %s -include %s -include %s
// With PCH
// RUN: %clang_cc1 -fsyntax-only -verify %s -chain-include %s -chain-include %s
#ifndef HEADER1
#define HEADER1
@class I;
#elif !defined(HEADER2)
#define HEADER2
@interface I // expected-note {{previous}}
@end
#else
typedef int I; // expected-error {{redefinition}}
#endif