From 6fb6003aad61169a5bd7eb4b85fa7e93a986333d Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Mon, 31 Oct 2011 07:20:15 +0000 Subject: [PATCH] [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. llvm-svn: 143341 --- clang/include/clang/Serialization/ASTReader.h | 13 +++++++++-- clang/include/clang/Serialization/ASTWriter.h | 14 ++++++++++-- clang/lib/Serialization/ASTReader.cpp | 6 ++--- clang/lib/Serialization/ASTReaderDecl.cpp | 6 +++-- clang/lib/Serialization/ASTWriter.cpp | 7 +++--- clang/lib/Serialization/ASTWriterDecl.cpp | 3 ++- clang/test/PCH/replaced-decl.m | 22 +++++++++++++++++++ 7 files changed, 58 insertions(+), 13 deletions(-) create mode 100644 clang/test/PCH/replaced-decl.m diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index ecc73c97fca6..e0950192e35e 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -290,8 +290,17 @@ private: /// in the chain. DeclUpdateOffsetsMap DeclUpdateOffsets; - typedef llvm::DenseMap > + 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 DeclReplacementMap; /// \brief Declarations that have been replaced in a later file in the chain. DeclReplacementMap ReplacedDecls; diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index bad5c379bcbf..8c0ea4fc33c2 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -286,14 +286,24 @@ private: /// another module. SmallVector 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, 16> - ReplacedDecls; + SmallVector ReplacedDecls; /// \brief Statements that we've encountered while serializing a /// declaration or type. diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 7ae0c4206991..4554f0525600 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -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; } diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 7b37bbfa1b69..d414c0729079 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -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"); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 1b44baa9ce53..9716447dfa93 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3234,10 +3234,11 @@ void ASTWriter::WriteDeclReplacementsBlock() { return; RecordData Record; - for (SmallVector, 16>::iterator + for (SmallVector::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); } diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 3e3e28dfbb7d..c35d4b0d2206 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -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; diff --git a/clang/test/PCH/replaced-decl.m b/clang/test/PCH/replaced-decl.m new file mode 100644 index 000000000000..b9fee950d7a1 --- /dev/null +++ b/clang/test/PCH/replaced-decl.m @@ -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 -- GitLab