diff options
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 13 | ||||
-rw-r--r-- | include/clang/Serialization/ASTWriter.h | 14 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 6 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 6 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 7 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterDecl.cpp | 3 | ||||
-rw-r--r-- | test/PCH/replaced-decl.m | 22 |
7 files changed, 58 insertions, 13 deletions
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index ecc73c97fc..e0950192e3 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -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; diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index bad5c379bc..8c0ea4fc33 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -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. diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 7ae0c42069..4554f05256 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/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/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 7b37bbfa1b..d414c07290 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/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/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 1b44baa9ce..9716447dfa 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -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); } diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 3e3e28dfbb..c35d4b0d22 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/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/test/PCH/replaced-decl.m b/test/PCH/replaced-decl.m new file mode 100644 index 0000000000..b9fee950d7 --- /dev/null +++ b/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 |