/// \brief Record code for pending implicit instantiations.
PENDING_IMPLICIT_INSTANTIATIONS = 26,
- /// \brief Record code for a decl replacement block.
- ///
- /// If a declaration is modified after having been deserialized, and then
- /// written to a dependent AST file, its ID and offset must be added to
- /// the replacement block.
- DECL_REPLACEMENTS = 27,
+ // ID 27 used to be for a list of replacement decls.
/// \brief Record code for an update to a decl context's lookup table.
///
/// declaration that has an exception specification.
llvm::SmallMapVector<Decl *, FunctionDecl *, 4> PendingExceptionSpecUpdates;
- struct ReplacedDeclInfo {
- ModuleFile *Mod;
- uint64_t Offset;
- unsigned RawLoc;
-
- ReplacedDeclInfo() : Mod(nullptr), Offset(0), RawLoc(0) {}
- ReplacedDeclInfo(ModuleFile *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;
-
/// \brief Declarations that have been imported and have typedef names for
/// linkage purposes.
llvm::DenseMap<std::pair<DeclContext*, IdentifierInfo*>, NamedDecl*>
/// should serialize.
llvm::SetVector<ObjCInterfaceDecl *> ObjCClassesWithCategories;
- 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<ReplacedDeclInfo, 16> ReplacedDecls;
-
/// \brief The set of declarations that may have redeclaration chains that
/// need to be serialized.
llvm::SmallVector<const Decl *, 16> Redeclarations;
bool IsModule);
void WriteAttributes(ArrayRef<const Attr*> Attrs, RecordDataImpl &Record);
void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord);
- void WriteDeclReplacementsBlock();
void WriteDeclContextVisibleUpdate(const DeclContext *DC);
void WriteFPPragmaOptions(const FPOptions &Opts);
void WriteOpenCLExtensions(Sema &SemaRef);
break;
}
- case DECL_REPLACEMENTS: {
- 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 += 3)
- ReplacedDecls[getGlobalDeclID(F, Record[I])]
- = ReplacedDeclInfo(&F, Record[I+1], Record[I+2]);
- break;
- }
-
case OBJC_CATEGORIES_MAP: {
if (F.LocalNumObjCCategoriesInMap != 0) {
Error("duplicate OBJC_CATEGORIES_MAP record in AST file");
/// \brief Get the correct cursor and offset for loading a declaration.
ASTReader::RecordLocation
ASTReader::DeclCursorForID(DeclID ID, unsigned &RawLocation) {
- // See if there's an override.
- DeclReplacementMap::iterator It = ReplacedDecls.find(ID);
- 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");
ModuleFile *M = I->second;
- const DeclOffset &
- DOffs = M->DeclOffsets[ID - M->BaseDeclID - NUM_PREDEF_DECL_IDS];
+ const DeclOffset &DOffs =
+ M->DeclOffsets[ID - M->BaseDeclID - NUM_PREDEF_DECL_IDS];
RawLocation = DOffs.Loc;
return RecordLocation(M, DOffs.BitOffset);
}
RECORD(SEMA_DECL_REFS);
RECORD(WEAK_UNDECLARED_IDENTIFIERS);
RECORD(PENDING_IMPLICIT_INSTANTIATIONS);
- RECORD(DECL_REPLACEMENTS);
RECORD(UPDATE_VISIBLE);
RECORD(DECL_UPDATE_OFFSETS);
RECORD(DECL_UPDATES);
}
}
- WriteDeclReplacementsBlock();
WriteObjCCategories();
if(!WritingModule) {
WriteOptimizePragmaOptions(SemaRef);
}
}
-void ASTWriter::WriteDeclReplacementsBlock() {
- if (ReplacedDecls.empty())
- return;
-
- RecordData Record;
- for (const auto &I : ReplacedDecls) {
- Record.push_back(I.ID);
- Record.push_back(I.Offset);
- Record.push_back(I.Loc);
- }
- Stream.EmitRecord(DECL_REPLACEMENTS, Record);
-}
-
void ASTWriter::AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record) {
Record.push_back(Loc.getRawEncoding());
}
ID = IDR;
- bool isReplacingADecl = ID < FirstDeclID;
+ assert(ID >= FirstDeclID && "invalid decl ID");
// If this declaration is also a DeclContext, write blocks for the
// declarations that lexically stored inside its context and those
uint64_t VisibleOffset = 0;
DeclContext *DC = dyn_cast<DeclContext>(D);
if (DC) {
- if (isReplacingADecl) {
- // It is replacing a decl from a chained PCH; make sure that the
- // DeclContext is fully loaded.
- if (DC->hasExternalLexicalStorage())
- DC->LoadLexicalDeclsFromExternalStorage();
- if (DC->hasExternalVisibleStorage())
- Chain->completeVisibleDeclsMap(DC);
- }
LexicalOffset = WriteDeclContextLexicalBlock(Context, DC);
VisibleOffset = WriteDeclContextVisibleBlock(Context, DC);
}
W.Visit(D);
if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
- if (isReplacingADecl) {
- // We're replacing a decl in a previous file.
- ReplacedDecls.push_back(ReplacedDeclInfo(ID, Stream.GetCurrentBitNo(),
- D->getLocation()));
- } else {
- unsigned Index = ID - FirstDeclID;
-
- // Record the offset for this declaration
- SourceLocation Loc = D->getLocation();
- if (DeclOffsets.size() == Index)
- DeclOffsets.push_back(DeclOffset(Loc, Stream.GetCurrentBitNo()));
- else if (DeclOffsets.size() < Index) {
- DeclOffsets.resize(Index+1);
- DeclOffsets[Index].setLocation(Loc);
- DeclOffsets[Index].BitOffset = Stream.GetCurrentBitNo();
- }
+ unsigned Index = ID - FirstDeclID;
- SourceManager &SM = Context.getSourceManager();
- if (Loc.isValid() && SM.isLocalSourceLocation(Loc))
- associateDeclWithFile(D, ID);
+ // Record the offset for this declaration
+ SourceLocation Loc = D->getLocation();
+ if (DeclOffsets.size() == Index)
+ DeclOffsets.push_back(DeclOffset(Loc, Stream.GetCurrentBitNo()));
+ else if (DeclOffsets.size() < Index) {
+ DeclOffsets.resize(Index+1);
+ DeclOffsets[Index].setLocation(Loc);
+ DeclOffsets[Index].BitOffset = Stream.GetCurrentBitNo();
}
+ SourceManager &SM = Context.getSourceManager();
+ if (Loc.isValid() && SM.isLocalSourceLocation(Loc))
+ associateDeclWithFile(D, ID);
+
if (!W.Code)
llvm::report_fatal_error(StringRef("unexpected declaration kind '") +
D->getDeclKindName() + "'");