зеркало из https://github.com/microsoft/clang-1.git
[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:
Родитель
9d128d0457
Коммит
ef23b6001e
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
Загрузка…
Ссылка в новой задаче