summaryrefslogtreecommitdiff
path: root/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp250
1 files changed, 167 insertions, 83 deletions
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp
index fd6708dd5c3f..20ca6d6fd512 100644
--- a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -159,6 +159,22 @@ namespace clang {
Writer.AddStmt(FD->getBody());
}
+ /// Add to the record the first declaration from each module file that
+ /// provides a declaration of D. The intent is to provide a sufficient
+ /// set such that reloading this set will load all current redeclarations.
+ void AddFirstDeclFromEachModule(const Decl *D, bool IncludeLocal) {
+ llvm::MapVector<ModuleFile*, const Decl*> Firsts;
+ // FIXME: We can skip entries that we know are implied by others.
+ for (const Decl *R = D->getMostRecentDecl(); R; R = R->getPreviousDecl()) {
+ if (R->isFromASTFile())
+ Firsts[Writer.Chain->getOwningModuleFile(R)] = R;
+ else if (IncludeLocal)
+ Firsts[nullptr] = R;
+ }
+ for (const auto &F : Firsts)
+ Writer.AddDeclRef(F.second, Record);
+ }
+
/// Get the specialization decl from an entry in the specialization list.
template <typename EntryType>
typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
@@ -192,22 +208,48 @@ namespace clang {
auto &&PartialSpecializations = getPartialSpecializations(Common);
ArrayRef<DeclID> LazySpecializations;
if (auto *LS = Common->LazySpecializations)
- LazySpecializations = ArrayRef<DeclID>(LS + 1, LS + 1 + LS[0]);
+ LazySpecializations = llvm::makeArrayRef(LS + 1, LS[0]);
+
+ // Add a slot to the record for the number of specializations.
+ unsigned I = Record.size();
+ Record.push_back(0);
- Record.push_back(Specializations.size() +
- PartialSpecializations.size() +
- LazySpecializations.size());
for (auto &Entry : Specializations) {
auto *D = getSpecializationDecl(Entry);
assert(D->isCanonicalDecl() && "non-canonical decl in set");
- Writer.AddDeclRef(D, Record);
+ AddFirstDeclFromEachModule(D, /*IncludeLocal*/true);
}
for (auto &Entry : PartialSpecializations) {
auto *D = getSpecializationDecl(Entry);
assert(D->isCanonicalDecl() && "non-canonical decl in set");
- Writer.AddDeclRef(D, Record);
+ AddFirstDeclFromEachModule(D, /*IncludeLocal*/true);
}
Record.append(LazySpecializations.begin(), LazySpecializations.end());
+
+ // Update the size entry we added earlier.
+ Record[I] = Record.size() - I - 1;
+ }
+
+ /// Ensure that this template specialization is associated with the specified
+ /// template on reload.
+ void RegisterTemplateSpecialization(const Decl *Template,
+ const Decl *Specialization) {
+ Template = Template->getCanonicalDecl();
+
+ // If the canonical template is local, we'll write out this specialization
+ // when we emit it.
+ // FIXME: We can do the same thing if there is any local declaration of
+ // the template, to avoid emitting an update record.
+ if (!Template->isFromASTFile())
+ return;
+
+ // We only need to associate the first local declaration of the
+ // specialization. The other declarations will get pulled in by it.
+ if (Writer.getFirstLocalDecl(Specialization) != Specialization)
+ return;
+
+ Writer.DeclUpdates[Template].push_back(ASTWriter::DeclUpdate(
+ UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION, Specialization));
}
};
}
@@ -218,7 +260,7 @@ void ASTDeclWriter::Visit(Decl *D) {
// Source locations require array (variable-length) abbreviations. The
// abbreviation infrastructure requires that arrays are encoded last, so
// we handle it here in the case of those classes derived from DeclaratorDecl
- if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)){
+ if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Writer.AddTypeSourceInfo(DD->getTypeSourceInfo(), Record);
}
@@ -234,7 +276,10 @@ void ASTDeclWriter::Visit(Decl *D) {
void ASTDeclWriter::VisitDecl(Decl *D) {
Writer.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()), Record);
- Writer.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()), Record);
+ if (D->getDeclContext() != D->getLexicalDeclContext())
+ Writer.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()), Record);
+ else
+ Record.push_back(0);
Record.push_back(D->isInvalidDecl());
Record.push_back(D->hasAttrs());
if (D->hasAttrs())
@@ -298,7 +343,8 @@ void ASTDeclWriter::VisitTypedefNameDecl(TypedefNameDecl *D) {
void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
VisitTypedefNameDecl(D);
- if (!D->hasAttrs() &&
+ if (D->getDeclContext() == D->getLexicalDeclContext() &&
+ !D->hasAttrs() &&
!D->isImplicit() &&
D->getFirstDecl() == D->getMostRecentDecl() &&
!D->isInvalidDecl() &&
@@ -336,9 +382,6 @@ void ASTDeclWriter::VisitTagDecl(TagDecl *D) {
Record.push_back(2);
Writer.AddDeclRef(TD, Record);
Writer.AddIdentifierRef(TD->getDeclName().getAsIdentifierInfo(), Record);
- } else if (auto *DD = D->getDeclaratorForAnonDecl()) {
- Record.push_back(3);
- Writer.AddDeclRef(DD, Record);
} else {
Record.push_back(0);
}
@@ -363,12 +406,12 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
Writer.AddDeclRef(nullptr, Record);
}
- if (!D->hasAttrs() &&
+ if (D->getDeclContext() == D->getLexicalDeclContext() &&
+ !D->hasAttrs() &&
!D->isImplicit() &&
!D->isUsed(false) &&
!D->hasExtInfo() &&
!D->getTypedefNameForAnonDecl() &&
- !D->getDeclaratorForAnonDecl() &&
D->getFirstDecl() == D->getMostRecentDecl() &&
!D->isInvalidDecl() &&
!D->isReferenced() &&
@@ -392,12 +435,12 @@ void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {
Record.push_back(D->hasObjectMember());
Record.push_back(D->hasVolatileMember());
- if (!D->hasAttrs() &&
+ if (D->getDeclContext() == D->getLexicalDeclContext() &&
+ !D->hasAttrs() &&
!D->isImplicit() &&
!D->isUsed(false) &&
!D->hasExtInfo() &&
!D->getTypedefNameForAnonDecl() &&
- !D->getDeclaratorForAnonDecl() &&
D->getFirstDecl() == D->getMostRecentDecl() &&
!D->isInvalidDecl() &&
!D->isReferenced() &&
@@ -479,6 +522,9 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
case FunctionDecl::TK_FunctionTemplateSpecialization: {
FunctionTemplateSpecializationInfo *
FTSInfo = D->getTemplateSpecializationInfo();
+
+ RegisterTemplateSpecialization(FTSInfo->getTemplate(), D);
+
Writer.AddDeclRef(FTSInfo->getTemplate(), Record);
Record.push_back(FTSInfo->getTemplateSpecializationKind());
@@ -648,7 +694,8 @@ void ASTDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
Record.push_back(D->getAccessControl());
Record.push_back(D->getSynthesize());
- if (!D->hasAttrs() &&
+ if (D->getDeclContext() == D->getLexicalDeclContext() &&
+ !D->hasAttrs() &&
!D->isImplicit() &&
!D->isUsed(false) &&
!D->isInvalidDecl() &&
@@ -780,7 +827,8 @@ void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) {
if (!D->getDeclName())
Writer.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D), Record);
- if (!D->hasAttrs() &&
+ if (D->getDeclContext() == D->getLexicalDeclContext() &&
+ !D->hasAttrs() &&
!D->isImplicit() &&
!D->isUsed(false) &&
!D->isInvalidDecl() &&
@@ -854,7 +902,8 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
Record.push_back(VarNotTemplate);
}
- if (!D->hasAttrs() &&
+ if (D->getDeclContext() == D->getLexicalDeclContext() &&
+ !D->hasAttrs() &&
!D->isImplicit() &&
!D->isUsed(false) &&
!D->isInvalidDecl() &&
@@ -902,7 +951,8 @@ void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
// If the assumptions about the DECL_PARM_VAR abbrev are true, use it. Here
// we dynamically check for the properties that we optimize for, but don't
// know are true of all PARM_VAR_DECLs.
- if (!D->hasAttrs() &&
+ if (D->getDeclContext() == D->getLexicalDeclContext() &&
+ !D->hasAttrs() &&
!D->hasExtInfo() &&
!D->isImplicit() &&
!D->isUsed(false) &&
@@ -1122,7 +1172,8 @@ void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
Record.push_back(0);
}
- if (D->getFirstDecl() == D->getMostRecentDecl() &&
+ if (D->getDeclContext() == D->getLexicalDeclContext() &&
+ D->getFirstDecl() == D->getMostRecentDecl() &&
!D->isInvalidDecl() &&
!D->hasAttrs() &&
!D->isTopLevelDeclInObjCContainer() &&
@@ -1249,6 +1300,8 @@ void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
void ASTDeclWriter::VisitClassTemplateSpecializationDecl(
ClassTemplateSpecializationDecl *D) {
+ RegisterTemplateSpecialization(D->getSpecializedTemplate(), D);
+
VisitCXXRecordDecl(D);
llvm::PointerUnion<ClassTemplateDecl *,
@@ -1308,6 +1361,8 @@ void ASTDeclWriter::VisitVarTemplateDecl(VarTemplateDecl *D) {
void ASTDeclWriter::VisitVarTemplateSpecializationDecl(
VarTemplateSpecializationDecl *D) {
+ RegisterTemplateSpecialization(D->getSpecializedTemplate(), D);
+
VisitVarDecl(D);
llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
@@ -1478,48 +1533,77 @@ void ASTDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
Record.push_back(VisibleOffset);
}
-/// Determine whether D is the first declaration in its redeclaration chain that
-/// is not from an AST file.
-template <typename T>
-static bool isFirstLocalDecl(Redeclarable<T> *D) {
- assert(D && !static_cast<T*>(D)->isFromASTFile());
- do
- D = D->getPreviousDecl();
- while (D && static_cast<T*>(D)->isFromASTFile());
- return !D;
+const Decl *ASTWriter::getFirstLocalDecl(const Decl *D) {
+ /// \brief Is this a local declaration (that is, one that will be written to
+ /// our AST file)? This is the case for declarations that are neither imported
+ /// from another AST file nor predefined.
+ auto IsLocalDecl = [&](const Decl *D) -> bool {
+ if (D->isFromASTFile())
+ return false;
+ auto I = DeclIDs.find(D);
+ return (I == DeclIDs.end() || I->second >= NUM_PREDEF_DECL_IDS);
+ };
+
+ assert(IsLocalDecl(D) && "expected a local declaration");
+
+ const Decl *Canon = D->getCanonicalDecl();
+ if (IsLocalDecl(Canon))
+ return Canon;
+
+ const Decl *&CacheEntry = FirstLocalDeclCache[Canon];
+ if (CacheEntry)
+ return CacheEntry;
+
+ for (const Decl *Redecl = D; Redecl; Redecl = Redecl->getPreviousDecl())
+ if (IsLocalDecl(Redecl))
+ D = Redecl;
+ return CacheEntry = D;
}
template <typename T>
void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
T *First = D->getFirstDecl();
T *MostRecent = First->getMostRecentDecl();
+ T *DAsT = static_cast<T *>(D);
if (MostRecent != First) {
- assert(isRedeclarableDeclKind(static_cast<T *>(D)->getKind()) &&
+ assert(isRedeclarableDeclKind(DAsT->getKind()) &&
"Not considered redeclarable?");
Writer.AddDeclRef(First, Record);
- // In a modules build, emit a list of all imported key declarations
- // (excluding First, if it was imported), so that we can be sure that all
- // redeclarations visible to this module are before D in the redecl chain.
- unsigned I = Record.size();
- Record.push_back(0);
- if (Context.getLangOpts().Modules && Writer.Chain) {
- if (isFirstLocalDecl(D)) {
- Writer.Chain->forEachImportedKeyDecl(First, [&](const Decl *D) {
- if (D != First)
- Writer.AddDeclRef(D, Record);
- });
- Record[I] = Record.size() - I - 1;
-
- // Write a redeclaration chain, attached to the first key decl.
- Writer.Redeclarations.push_back(Writer.Chain->getKeyDeclaration(First));
+ // Write out a list of local redeclarations of this declaration if it's the
+ // first local declaration in the chain.
+ const Decl *FirstLocal = Writer.getFirstLocalDecl(DAsT);
+ if (DAsT == FirstLocal) {
+ // Emit a list of all imported first declarations so that we can be sure
+ // that all redeclarations visible to this module are before D in the
+ // redecl chain.
+ unsigned I = Record.size();
+ Record.push_back(0);
+ if (Writer.Chain)
+ AddFirstDeclFromEachModule(DAsT, /*IncludeLocal*/false);
+ // This is the number of imported first declarations + 1.
+ Record[I] = Record.size() - I;
+
+ // Collect the set of local redeclarations of this declaration, from
+ // newest to oldest.
+ RecordData LocalRedecls;
+ for (const Decl *Prev = FirstLocal->getMostRecentDecl();
+ Prev != FirstLocal; Prev = Prev->getPreviousDecl())
+ if (!Prev->isFromASTFile())
+ Writer.AddDeclRef(Prev, LocalRedecls);
+
+ // If we have any redecls, write them now as a separate record preceding
+ // the declaration itself.
+ if (LocalRedecls.empty())
+ Record.push_back(0);
+ else {
+ Record.push_back(Writer.Stream.GetCurrentBitNo());
+ Writer.Stream.EmitRecord(LOCAL_REDECLARATIONS, LocalRedecls);
}
- } else if (D == First || D->getPreviousDecl()->isFromASTFile()) {
- assert(isFirstLocalDecl(D) && "imported decl after local decl");
-
- // Write a redeclaration chain attached to the first decl.
- Writer.Redeclarations.push_back(First);
+ } else {
+ Record.push_back(0);
+ Writer.AddDeclRef(FirstLocal, Record);
}
// Make sure that we serialize both the previous and the most-recent
@@ -1558,7 +1642,7 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(serialization::DECL_FIELD));
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
+ Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
@@ -1591,7 +1675,7 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(serialization::DECL_OBJC_IVAR));
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
+ Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
@@ -1629,7 +1713,7 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
+ Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
@@ -1677,7 +1761,7 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
+ Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
@@ -1720,7 +1804,7 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
+ Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
@@ -1767,7 +1851,7 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
+ Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
@@ -1796,7 +1880,7 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
+ Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
@@ -1842,7 +1926,7 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // CanonicalDecl
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
+ Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
Abv->Add(BitCodeAbbrevOp(0)); // Invalid
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Implicit
@@ -1977,7 +2061,6 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_VISIBLE));
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
DeclContextVisibleLookupAbbrev = Stream.EmitAbbrev(Abv);
}
@@ -1994,14 +2077,19 @@ void ASTWriter::WriteDeclAbbrevs() {
/// clients to use a separate API call to "realize" the decl. This should be
/// relatively painless since they would presumably only do it for top-level
/// decls.
-static bool isRequiredDecl(const Decl *D, ASTContext &Context) {
+static bool isRequiredDecl(const Decl *D, ASTContext &Context,
+ bool WritingModule) {
// An ObjCMethodDecl is never considered as "required" because its
// implementation container always is.
- // File scoped assembly or obj-c implementation must be seen. ImportDecl is
- // used by codegen to determine the set of imported modules to search for
- // inputs for automatic linking.
- if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplDecl>(D) || isa<ImportDecl>(D))
+ // File scoped assembly or obj-c implementation must be seen.
+ if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplDecl>(D))
+ return true;
+
+ // ImportDecl is used by codegen to determine the set of imported modules to
+ // search for inputs for automatic linking; include it if it has a semantic
+ // effect.
+ if (isa<ImportDecl>(D) && !WritingModule)
return true;
return Context.DeclMustBeEmitted(D);
@@ -2016,16 +2104,12 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
// Determine the ID for this declaration.
serialization::DeclID ID;
- if (D->isFromASTFile()) {
- assert(isRewritten(D) && "should not be emitting imported decl");
- ID = getDeclID(D);
- } else {
- serialization::DeclID &IDR = DeclIDs[D];
- if (IDR == 0)
- IDR = NextDeclID++;
+ assert(!D->isFromASTFile() && "should not be emitting imported decl");
+ serialization::DeclID &IDR = DeclIDs[D];
+ if (IDR == 0)
+ IDR = NextDeclID++;
- ID= IDR;
- }
+ ID = IDR;
bool isReplacingADecl = ID < FirstDeclID;
@@ -2050,6 +2134,13 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
VisibleOffset = WriteDeclContextVisibleBlock(Context, DC);
}
+ // Build a record for this declaration
+ Record.clear();
+ W.Code = (serialization::DeclCode)0;
+ W.AbbrevToUse = 0;
+ 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(),
@@ -2066,19 +2157,12 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
DeclOffsets[Index].setLocation(Loc);
DeclOffsets[Index].BitOffset = Stream.GetCurrentBitNo();
}
-
+
SourceManager &SM = Context.getSourceManager();
if (Loc.isValid() && SM.isLocalSourceLocation(Loc))
associateDeclWithFile(D, ID);
}
- // Build and emit a record for this declaration
- Record.clear();
- W.Code = (serialization::DeclCode)0;
- W.AbbrevToUse = 0;
- W.Visit(D);
- if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
-
if (!W.Code)
llvm::report_fatal_error(StringRef("unexpected declaration kind '") +
D->getDeclKindName() + "'");
@@ -2090,7 +2174,7 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
// Note declarations that should be deserialized eagerly so that we can add
// them to a record in the AST file later.
- if (isRequiredDecl(D, Context))
+ if (isRequiredDecl(D, Context, WritingModule))
EagerlyDeserializedDecls.push_back(ID);
}