aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization/ASTReaderDecl.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-12-30 11:49:41 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-12-30 11:49:41 +0000
commit45b533945f0851ec234ca846e1af5ee1e4df0b6e (patch)
tree0a5b74c0b9ca73aded34df95c91fcaf3815230d8 /lib/Serialization/ASTReaderDecl.cpp
parent7e86edd64bfae4e324224452e4ea879b3371a4bd (diff)
downloadsrc-45b533945f0851ec234ca846e1af5ee1e4df0b6e.tar.gz
src-45b533945f0851ec234ca846e1af5ee1e4df0b6e.zip
Vendor import of clang trunk r256633:vendor/clang/clang-trunk-r256633
Notes
Notes: svn path=/vendor/clang/dist/; revision=292920 svn path=/vendor/clang/clang-trunk-r256633/; revision=292923; tag=vendor/clang/clang-trunk-r256633
Diffstat (limited to 'lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp437
1 files changed, 152 insertions, 285 deletions
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 1a0c5b58e7f6..8fb110e4551d 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -26,6 +26,7 @@
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "llvm/Support/SaveAndRestore.h"
+
using namespace clang;
using namespace clang::serialization;
@@ -120,45 +121,20 @@ namespace clang {
static void setAnonymousDeclForMerging(ASTReader &Reader, DeclContext *DC,
unsigned Index, NamedDecl *D);
- /// \brief RAII class used to capture the first ID within a redeclaration
- /// chain and to introduce it into the list of pending redeclaration chains
- /// on destruction.
+ /// Results from loading a RedeclarableDecl.
class RedeclarableResult {
- ASTReader &Reader;
GlobalDeclID FirstID;
Decl *MergeWith;
- mutable bool Owning;
bool IsKeyDecl;
- Decl::Kind DeclKind;
-
- void operator=(RedeclarableResult &) = delete;
public:
- RedeclarableResult(ASTReader &Reader, GlobalDeclID FirstID,
- Decl *MergeWith, Decl::Kind DeclKind,
- bool IsKeyDecl)
- : Reader(Reader), FirstID(FirstID), MergeWith(MergeWith),
- Owning(true), IsKeyDecl(IsKeyDecl), DeclKind(DeclKind) {}
-
- RedeclarableResult(RedeclarableResult &&Other)
- : Reader(Other.Reader), FirstID(Other.FirstID),
- MergeWith(Other.MergeWith), Owning(Other.Owning),
- IsKeyDecl(Other.IsKeyDecl), DeclKind(Other.DeclKind) {
- Other.Owning = false;
- }
-
- ~RedeclarableResult() {
- if (FirstID && Owning && isRedeclarableDeclKind(DeclKind)) {
- auto Canon = Reader.GetDecl(FirstID)->getCanonicalDecl();
- if (Reader.PendingDeclChainsKnown.insert(Canon).second)
- Reader.PendingDeclChains.push_back(Canon);
- }
- }
+ RedeclarableResult(GlobalDeclID FirstID, Decl *MergeWith, bool IsKeyDecl)
+ : FirstID(FirstID), MergeWith(MergeWith), IsKeyDecl(IsKeyDecl) {}
/// \brief Retrieve the first ID.
GlobalDeclID getFirstID() const { return FirstID; }
- /// \brief Is this declaration the key declaration?
+ /// \brief Is this declaration a key declaration?
bool isKeyDecl() const { return IsKeyDecl; }
/// \brief Get a known declaration that this should be merged with, if
@@ -185,7 +161,7 @@ namespace clang {
public:
FindExistingResult(ASTReader &Reader)
: Reader(Reader), New(nullptr), Existing(nullptr), AddResult(false),
- AnonymousDeclNumber(0), TypedefNameForLinkage(0) {}
+ AnonymousDeclNumber(0), TypedefNameForLinkage(nullptr) {}
FindExistingResult(ASTReader &Reader, NamedDecl *New, NamedDecl *Existing,
unsigned AnonymousDeclNumber,
@@ -317,6 +293,7 @@ namespace clang {
DeclID VisitTemplateDecl(TemplateDecl *D);
RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
void VisitClassTemplateDecl(ClassTemplateDecl *D);
+ void VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D);
void VisitVarTemplateDecl(VarTemplateDecl *D);
void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
@@ -395,7 +372,7 @@ namespace clang {
}
}
};
-}
+} // end namespace clang
namespace {
/// Iterator over the redeclarations of a declaration that have already
@@ -431,12 +408,12 @@ public:
return A.Current != B.Current;
}
};
-}
+} // end anonymous namespace
+
template<typename DeclT>
llvm::iterator_range<MergedRedeclIterator<DeclT>> merged_redecls(DeclT *D) {
- return llvm::iterator_range<MergedRedeclIterator<DeclT>>(
- MergedRedeclIterator<DeclT>(D),
- MergedRedeclIterator<DeclT>());
+ return llvm::make_range(MergedRedeclIterator<DeclT>(D),
+ MergedRedeclIterator<DeclT>());
}
uint64_t ASTDeclReader::GetCurrentCursorOffset() {
@@ -465,8 +442,8 @@ void ASTDeclReader::Visit(Decl *D) {
// If this is a tag declaration with a typedef name for linkage, it's safe
// to load that typedef now.
if (NamedDeclForTagDecl)
- cast<TagDecl>(D)->NamedDeclOrQualifier =
- cast<NamedDecl>(Reader.GetDecl(NamedDeclForTagDecl));
+ cast<TagDecl>(D)->TypedefNameDeclOrQualifier =
+ cast<TypedefNameDecl>(Reader.GetDecl(NamedDeclForTagDecl));
} else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
// if we have a fully initialized TypeDecl, we can safely read its type now.
ID->TypeForDecl = Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull();
@@ -499,6 +476,8 @@ void ASTDeclReader::VisitDecl(Decl *D) {
// placeholder.
GlobalDeclID SemaDCIDForTemplateParmDecl = ReadDeclID(Record, Idx);
GlobalDeclID LexicalDCIDForTemplateParmDecl = ReadDeclID(Record, Idx);
+ if (!LexicalDCIDForTemplateParmDecl)
+ LexicalDCIDForTemplateParmDecl = SemaDCIDForTemplateParmDecl;
Reader.addPendingDeclContextInfo(D,
SemaDCIDForTemplateParmDecl,
LexicalDCIDForTemplateParmDecl);
@@ -506,6 +485,8 @@ void ASTDeclReader::VisitDecl(Decl *D) {
} else {
DeclContext *SemaDC = ReadDeclAs<DeclContext>(Record, Idx);
DeclContext *LexicalDC = ReadDeclAs<DeclContext>(Record, Idx);
+ if (!LexicalDC)
+ LexicalDC = SemaDC;
DeclContext *MergedSemaDC = Reader.MergedDeclContexts.lookup(SemaDC);
// Avoid calling setLexicalDeclContext() directly because it uses
// Decl::getASTContext() internally which is unsafe during derialization.
@@ -619,16 +600,13 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitTagDecl(TagDecl *TD) {
case 1: { // ExtInfo
TagDecl::ExtInfo *Info = new (Reader.getContext()) TagDecl::ExtInfo();
ReadQualifierInfo(*Info, Record, Idx);
- TD->NamedDeclOrQualifier = Info;
+ TD->TypedefNameDeclOrQualifier = Info;
break;
}
case 2: // TypedefNameForAnonDecl
NamedDeclForTagDecl = ReadDeclID(Record, Idx);
TypedefNameForLinkage = Reader.GetIdentifierInfo(F, Record, Idx);
break;
- case 3: // DeclaratorForAnonDecl
- NamedDeclForTagDecl = ReadDeclID(Record, Idx);
- break;
default:
llvm_unreachable("unexpected tag info kind");
}
@@ -771,8 +749,9 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
// Template arguments.
SmallVector<TemplateArgument, 8> TemplArgs;
- Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
-
+ Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx,
+ /*Canonicalize*/ true);
+
// Template args as written.
SmallVector<TemplateArgumentLoc, 8> TemplArgLocs;
SourceLocation LAngleLoc, RAngleLoc;
@@ -909,6 +888,7 @@ void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
void ASTDeclReader::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
VisitTypedefNameDecl(D);
+
D->Variance = Record[Idx++];
D->Index = Record[Idx++];
D->VarianceLoc = ReadSourceLocation(Record, Idx);
@@ -1121,7 +1101,6 @@ void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
D->IvarInitializers = Reader.ReadCXXCtorInitializersRef(F, Record, Idx);
}
-
void ASTDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
VisitDecl(D);
D->setAtLoc(ReadSourceLocation(Record, Idx));
@@ -1168,6 +1147,8 @@ void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) {
for (unsigned I = 0; I != FD->ChainingSize; ++I)
FD->Chaining[I] = ReadDeclAs<NamedDecl>(Record, Idx);
+
+ mergeMergeable(FD);
}
ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
@@ -1208,8 +1189,9 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
};
switch ((VarKind)Record[Idx++]) {
case VarNotTemplate:
- // Only true variables (not parameters or implicit parameters) can be merged
- if (VD->getKind() != Decl::ParmVar && VD->getKind() != Decl::ImplicitParam &&
+ // Only true variables (not parameters or implicit parameters) can be
+ // merged; the other kinds are not really redeclarable at all.
+ if (!isa<ParmVarDecl>(VD) && !isa<ImplicitParamDecl>(VD) &&
!isa<VarTemplateSpecializationDecl>(VD))
mergeRedeclarable(VD, Redecl);
break;
@@ -1290,8 +1272,7 @@ void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) {
captures.push_back(BlockDecl::Capture(decl, byRef, nested, copyExpr));
}
- BD->setCaptures(Reader.getContext(), captures.begin(),
- captures.end(), capturesCXXThis);
+ BD->setCaptures(Reader.getContext(), captures, capturesCXXThis);
}
void ASTDeclReader::VisitCapturedDecl(CapturedDecl *CD) {
@@ -1319,7 +1300,6 @@ void ASTDeclReader::VisitLabelDecl(LabelDecl *D) {
D->setLocStart(ReadSourceLocation(Record, Idx));
}
-
void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
RedeclarableResult Redecl = VisitRedeclarable(D);
VisitNamedDecl(D);
@@ -1506,21 +1486,14 @@ void ASTDeclReader::MergeDefinitionData(
auto &DD = *D->DefinitionData.getNotUpdated();
if (DD.Definition != MergeDD.Definition) {
- // If the new definition has new special members, let the name lookup
- // code know that it needs to look in the new definition too.
- //
- // FIXME: We only need to do this if the merged definition declares members
- // that this definition did not declare, or if it defines members that this
- // definition did not define.
- Reader.MergedLookups[DD.Definition].push_back(MergeDD.Definition);
- DD.Definition->setHasExternalVisibleStorage();
-
// Track that we merged the definitions.
Reader.MergedDeclContexts.insert(std::make_pair(MergeDD.Definition,
DD.Definition));
Reader.PendingDefinitions.erase(MergeDD.Definition);
MergeDD.Definition->IsCompleteDefinition = false;
mergeDefinitionVisibility(DD.Definition, MergeDD.Definition);
+ assert(Reader.Lookups.find(MergeDD.Definition) == Reader.Lookups.end() &&
+ "already loaded pending lookups for merged definition");
}
auto PFDI = Reader.PendingFakeDefinitionData.find(&DD);
@@ -1758,7 +1731,7 @@ void ASTDeclReader::VisitImportDecl(ImportDecl *D) {
VisitDecl(D);
D->ImportedAndComplete.setPointer(readModule(Record, Idx));
D->ImportedAndComplete.setInt(Record[Idx++]);
- SourceLocation *StoredLocs = reinterpret_cast<SourceLocation *>(D + 1);
+ SourceLocation *StoredLocs = D->getTrailingObjects<SourceLocation>();
for (unsigned I = 0, N = Record.back(); I != N; ++I)
StoredLocs[I] = ReadSourceLocation(Record, Idx);
++Idx; // The number of stored source locations.
@@ -1776,7 +1749,8 @@ void ASTDeclReader::VisitFriendDecl(FriendDecl *D) {
else
D->Friend = GetTypeSourceInfo(Record, Idx);
for (unsigned i = 0; i != D->NumTPLists; ++i)
- D->getTPLists()[i] = Reader.ReadTemplateParameterList(F, Record, Idx);
+ D->getTrailingObjects<TemplateParameterList *>()[i] =
+ Reader.ReadTemplateParameterList(F, Record, Idx);
D->NextFriend = ReadDeclID(Record, Idx);
D->UnsupportedFriend = (Record[Idx++] != 0);
D->FriendLoc = ReadSourceLocation(Record, Idx);
@@ -1887,6 +1861,10 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
}
}
+void ASTDeclReader::VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D) {
+ llvm_unreachable("BuiltinTemplates are not serialized");
+}
+
/// TODO: Unify with ClassTemplateDecl version?
/// May require unifying ClassTemplateDecl and
/// VarTemplateDecl beyond TemplateDecl...
@@ -1933,7 +1911,8 @@ ASTDeclReader::VisitClassTemplateSpecializationDeclImpl(
}
SmallVector<TemplateArgument, 8> TemplArgs;
- Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
+ Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx,
+ /*Canonicalize*/ true);
D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs.data(),
TemplArgs.size());
D->PointOfInstantiation = ReadSourceLocation(Record, Idx);
@@ -2060,7 +2039,8 @@ ASTDeclReader::VisitVarTemplateSpecializationDeclImpl(
}
SmallVector<TemplateArgument, 8> TemplArgs;
- Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
+ Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx,
+ /*Canonicalize*/ true);
D->TemplateArgs =
TemplateArgumentList::CreateCopy(C, TemplArgs.data(), TemplArgs.size());
D->PointOfInstantiation = ReadSourceLocation(Record, Idx);
@@ -2070,6 +2050,7 @@ ASTDeclReader::VisitVarTemplateSpecializationDeclImpl(
if (writtenAsCanonicalDecl) {
VarTemplateDecl *CanonPattern = ReadDeclAs<VarTemplateDecl>(Record, Idx);
if (D->isCanonicalDecl()) { // It's kept in the folding set.
+ // FIXME: If it's already present, merge it.
if (VarTemplatePartialSpecializationDecl *Partial =
dyn_cast<VarTemplatePartialSpecializationDecl>(D)) {
CanonPattern->getCommonPtr()->PartialSpecializations
@@ -2118,10 +2099,11 @@ void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
D->setDepth(Record[Idx++]);
D->setPosition(Record[Idx++]);
if (D->isExpandedParameterPack()) {
- void **Data = reinterpret_cast<void **>(D + 1);
+ auto TypesAndInfos =
+ D->getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {
- Data[2*I] = Reader.readType(F, Record, Idx).getAsOpaquePtr();
- Data[2*I + 1] = GetTypeSourceInfo(Record, Idx);
+ new (&TypesAndInfos[I].first) QualType(Reader.readType(F, Record, Idx));
+ TypesAndInfos[I].second = GetTypeSourceInfo(Record, Idx);
}
} else {
// Rest of NonTypeTemplateParmDecl.
@@ -2137,7 +2119,8 @@ void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
D->setDepth(Record[Idx++]);
D->setPosition(Record[Idx++]);
if (D->isExpandedParameterPack()) {
- void **Data = reinterpret_cast<void **>(D + 1);
+ TemplateParameterList **Data =
+ D->getTrailingObjects<TemplateParameterList *>();
for (unsigned I = 0, N = D->getNumExpansionTemplateParameters();
I != N; ++I)
Data[I] = Reader.ReadTemplateParameterList(F, Record, Idx);
@@ -2178,23 +2161,37 @@ ASTDeclReader::RedeclarableResult
ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
DeclID FirstDeclID = ReadDeclID(Record, Idx);
Decl *MergeWith = nullptr;
+
bool IsKeyDecl = ThisDeclID == FirstDeclID;
+ bool IsFirstLocalDecl = false;
+
+ uint64_t RedeclOffset = 0;
// 0 indicates that this declaration was the only declaration of its entity,
// and is used for space optimization.
if (FirstDeclID == 0) {
FirstDeclID = ThisDeclID;
IsKeyDecl = true;
+ IsFirstLocalDecl = true;
} else if (unsigned N = Record[Idx++]) {
- IsKeyDecl = false;
+ // This declaration was the first local declaration, but may have imported
+ // other declarations.
+ IsKeyDecl = N == 1;
+ IsFirstLocalDecl = true;
// We have some declarations that must be before us in our redeclaration
// chain. Read them now, and remember that we ought to merge with one of
// them.
// FIXME: Provide a known merge target to the second and subsequent such
// declaration.
- for (unsigned I = 0; I != N; ++I)
+ for (unsigned I = 0; I != N - 1; ++I)
MergeWith = ReadDecl(Record, Idx/*, MergeWith*/);
+
+ RedeclOffset = Record[Idx++];
+ } else {
+ // This declaration was not the first local declaration. Read the first
+ // local declaration now, to trigger the import of other redeclarations.
+ (void)ReadDecl(Record, Idx);
}
T *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID));
@@ -2206,14 +2203,17 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
D->RedeclLink = Redeclarable<T>::PreviousDeclLink(FirstDecl);
D->First = FirstDecl->getCanonicalDecl();
}
-
- // Note that this declaration has been deserialized.
- Reader.RedeclsDeserialized.insert(static_cast<T *>(D));
-
- // The result structure takes care to note that we need to load the
- // other declaration chains for this ID.
- return RedeclarableResult(Reader, FirstDeclID, MergeWith,
- static_cast<T *>(D)->getKind(), IsKeyDecl);
+
+ T *DAsT = static_cast<T*>(D);
+
+ // Note that we need to load local redeclarations of this decl and build a
+ // decl chain for them. This must happen *after* we perform the preloading
+ // above; this ensures that the redeclaration chain is built in the correct
+ // order.
+ if (IsFirstLocalDecl)
+ Reader.PendingDeclChains.push_back(std::make_pair(DAsT, RedeclOffset));
+
+ return RedeclarableResult(FirstDeclID, MergeWith, IsKeyDecl);
}
/// \brief Attempts to merge the given declaration (D) with another declaration
@@ -2255,9 +2255,8 @@ void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D,
DeclID DsID, bool IsKeyDecl) {
auto *DPattern = D->getTemplatedDecl();
auto *ExistingPattern = Existing->getTemplatedDecl();
- RedeclarableResult Result(Reader, DPattern->getCanonicalDecl()->getGlobalID(),
- /*MergeWith*/ExistingPattern, DPattern->getKind(),
- IsKeyDecl);
+ RedeclarableResult Result(DPattern->getCanonicalDecl()->getGlobalID(),
+ /*MergeWith*/ ExistingPattern, IsKeyDecl);
if (auto *DClass = dyn_cast<CXXRecordDecl>(DPattern)) {
// Merge with any existing definition.
@@ -2323,11 +2322,8 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing,
TemplatePatternID, Redecl.isKeyDecl());
// If this declaration is a key declaration, make a note of that.
- if (Redecl.isKeyDecl()) {
+ if (Redecl.isKeyDecl())
Reader.KeyDecls[ExistingCanon].push_back(Redecl.getFirstID());
- if (Reader.PendingDeclChainsKnown.insert(ExistingCanon).second)
- Reader.PendingDeclChains.push_back(ExistingCanon);
- }
}
}
@@ -2626,6 +2622,13 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
return X->getASTContext().hasSameType(FDX->getType(), FDY->getType());
}
+ // Indirect fields with the same target field match.
+ if (auto *IFDX = dyn_cast<IndirectFieldDecl>(X)) {
+ auto *IFDY = cast<IndirectFieldDecl>(Y);
+ return IFDX->getAnonField()->getCanonicalDecl() ==
+ IFDY->getAnonField()->getCanonicalDecl();
+ }
+
// Enumerators with the same name match.
if (isa<EnumConstantDecl>(X))
// FIXME: Also check the value is odr-equivalent.
@@ -2749,12 +2752,12 @@ static NamedDecl *getDeclForMerging(NamedDecl *Found,
// declaration, then we want that inner declaration. Declarations from
// AST files are handled via ImportedTypedefNamesForLinkage.
if (Found->isFromASTFile())
- return 0;
+ return nullptr;
if (auto *TND = dyn_cast<TypedefNameDecl>(Found))
return TND->getAnonDeclWithTypedefName();
- return 0;
+ return nullptr;
}
NamedDecl *ASTDeclReader::getAnonymousDeclForMerging(ASTReader &Reader,
@@ -2924,6 +2927,7 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
D->RedeclLink.setPrevious(cast<DeclT>(Previous));
D->First = cast<DeclT>(Previous)->First;
}
+
namespace clang {
template<>
void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
@@ -2969,7 +2973,8 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
std::make_pair(Canon, IsUnresolved ? PrevFD : FD));
}
}
-}
+} // end namespace clang
+
void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, ...) {
llvm_unreachable("attachPreviousDecl on non-redeclarable declaration");
}
@@ -3319,37 +3324,13 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
// If this declaration is also a declaration context, get the
// offsets for its tables of lexical and visible declarations.
if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
- // FIXME: This should really be
- // DeclContext *LookupDC = DC->getPrimaryContext();
- // but that can walk the redeclaration chain, which might not work yet.
- DeclContext *LookupDC = DC;
- if (isa<NamespaceDecl>(DC))
- LookupDC = DC->getPrimaryContext();
std::pair<uint64_t, uint64_t> Offsets = Reader.VisitDeclContext(DC);
- if (Offsets.first || Offsets.second) {
- if (Offsets.first != 0)
- DC->setHasExternalLexicalStorage(true);
- if (Offsets.second != 0)
- LookupDC->setHasExternalVisibleStorage(true);
- if (ReadDeclContextStorage(*Loc.F, DeclsCursor, Offsets,
- Loc.F->DeclContextInfos[DC]))
- return nullptr;
- }
-
- // Now add the pending visible updates for this decl context, if it has any.
- DeclContextVisibleUpdatesPending::iterator I =
- PendingVisibleUpdates.find(ID);
- if (I != PendingVisibleUpdates.end()) {
- // There are updates. This means the context has external visible
- // storage, even if the original stored version didn't.
- LookupDC->setHasExternalVisibleStorage(true);
- for (const auto &Update : I->second) {
- DeclContextInfo &Info = Update.second->DeclContextInfos[DC];
- delete Info.NameLookupTableData;
- Info.NameLookupTableData = Update.first;
- }
- PendingVisibleUpdates.erase(I);
- }
+ if (Offsets.first &&
+ ReadLexicalDeclContextStorage(*Loc.F, DeclsCursor, Offsets.first, DC))
+ return nullptr;
+ if (Offsets.second &&
+ ReadVisibleDeclContextStorage(*Loc.F, DeclsCursor, Offsets.second, ID))
+ return nullptr;
}
assert(Idx == Record.size());
@@ -3372,17 +3353,32 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
}
void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
+ // Load the pending visible updates for this decl context, if it has any.
+ auto I = PendingVisibleUpdates.find(ID);
+ if (I != PendingVisibleUpdates.end()) {
+ auto VisibleUpdates = std::move(I->second);
+ PendingVisibleUpdates.erase(I);
+
+ auto *DC = cast<DeclContext>(D)->getPrimaryContext();
+ for (const PendingVisibleUpdate &Update : VisibleUpdates)
+ Lookups[DC].Table.add(
+ Update.Mod, Update.Data,
+ reader::ASTDeclContextNameLookupTrait(*this, *Update.Mod));
+ DC->setHasExternalVisibleStorage(true);
+ }
+
// The declaration may have been modified by files later in the chain.
// If this is the case, read the record containing the updates from each file
// and pass it to ASTDeclReader to make the modifications.
DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID);
if (UpdI != DeclUpdateOffsets.end()) {
- FileOffsetsTy &UpdateOffsets = UpdI->second;
+ auto UpdateOffsets = std::move(UpdI->second);
+ DeclUpdateOffsets.erase(UpdI);
+
bool WasInteresting = isConsumerInterestedIn(D, false);
- for (FileOffsetsTy::iterator
- I = UpdateOffsets.begin(), E = UpdateOffsets.end(); I != E; ++I) {
- ModuleFile *F = I->first;
- uint64_t Offset = I->second;
+ for (auto &FileAndOffset : UpdateOffsets) {
+ ModuleFile *F = FileAndOffset.first;
+ uint64_t Offset = FileAndOffset.second;
llvm::BitstreamCursor &Cursor = F->DeclsCursor;
SavedStreamPosition SavedPosition(Cursor);
Cursor.JumpToBit(Offset);
@@ -3407,154 +3403,42 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
}
}
-namespace {
- /// \brief Module visitor class that finds all of the redeclarations of a
- /// redeclarable declaration.
- class RedeclChainVisitor {
- ASTReader &Reader;
- SmallVectorImpl<DeclID> &SearchDecls;
- llvm::SmallPtrSetImpl<Decl *> &Deserialized;
- GlobalDeclID CanonID;
- SmallVector<Decl *, 4> Chain;
-
- public:
- RedeclChainVisitor(ASTReader &Reader, SmallVectorImpl<DeclID> &SearchDecls,
- llvm::SmallPtrSetImpl<Decl *> &Deserialized,
- GlobalDeclID CanonID)
- : Reader(Reader), SearchDecls(SearchDecls), Deserialized(Deserialized),
- CanonID(CanonID) {
- // Ensure that the canonical ID goes at the start of the chain.
- addToChain(Reader.GetDecl(CanonID));
- }
-
- static ModuleManager::DFSPreorderControl
- visitPreorder(ModuleFile &M, void *UserData) {
- return static_cast<RedeclChainVisitor *>(UserData)->visitPreorder(M);
- }
-
- static bool visitPostorder(ModuleFile &M, void *UserData) {
- return static_cast<RedeclChainVisitor *>(UserData)->visitPostorder(M);
- }
-
- void addToChain(Decl *D) {
- if (!D)
- return;
-
- if (Deserialized.erase(D))
- Chain.push_back(D);
- }
-
- void searchForID(ModuleFile &M, GlobalDeclID GlobalID) {
- // Map global ID of the first declaration down to the local ID
- // used in this module file.
- DeclID ID = Reader.mapGlobalIDToModuleFileGlobalID(M, GlobalID);
- if (!ID)
- return;
-
- // If the search decl was from this module, add it to the chain before any
- // of its redeclarations in this module or users of it, and after any from
- // imported modules.
- if (CanonID != GlobalID && Reader.isDeclIDFromModule(GlobalID, M))
- addToChain(Reader.GetDecl(GlobalID));
-
- // Perform a binary search to find the local redeclarations for this
- // declaration (if any).
- const LocalRedeclarationsInfo Compare = { ID, 0 };
- const LocalRedeclarationsInfo *Result
- = std::lower_bound(M.RedeclarationsMap,
- M.RedeclarationsMap + M.LocalNumRedeclarationsInMap,
- Compare);
- if (Result == M.RedeclarationsMap + M.LocalNumRedeclarationsInMap ||
- Result->FirstID != ID)
- return;
-
- // Dig out all of the redeclarations.
- unsigned Offset = Result->Offset;
- unsigned N = M.RedeclarationChains[Offset];
- M.RedeclarationChains[Offset++] = 0; // Don't try to deserialize again
- for (unsigned I = 0; I != N; ++I)
- addToChain(Reader.GetLocalDecl(M, M.RedeclarationChains[Offset++]));
- }
-
- bool needsToVisitImports(ModuleFile &M, GlobalDeclID GlobalID) {
- DeclID ID = Reader.mapGlobalIDToModuleFileGlobalID(M, GlobalID);
- if (!ID)
- return false;
-
- const LocalRedeclarationsInfo Compare = {ID, 0};
- const LocalRedeclarationsInfo *Result = std::lower_bound(
- M.RedeclarationsMap,
- M.RedeclarationsMap + M.LocalNumRedeclarationsInMap, Compare);
- if (Result == M.RedeclarationsMap + M.LocalNumRedeclarationsInMap ||
- Result->FirstID != ID) {
- return true;
- }
- unsigned Offset = Result->Offset;
- unsigned N = M.RedeclarationChains[Offset];
- // We don't need to visit a module or any of its imports if we've already
- // deserialized the redecls from this module.
- return N != 0;
- }
+void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) {
+ // Attach FirstLocal to the end of the decl chain.
+ Decl *CanonDecl = FirstLocal->getCanonicalDecl();
+ if (FirstLocal != CanonDecl) {
+ Decl *PrevMostRecent = ASTDeclReader::getMostRecentDecl(CanonDecl);
+ ASTDeclReader::attachPreviousDecl(
+ *this, FirstLocal, PrevMostRecent ? PrevMostRecent : CanonDecl,
+ CanonDecl);
+ }
- ModuleManager::DFSPreorderControl visitPreorder(ModuleFile &M) {
- for (unsigned I = 0, N = SearchDecls.size(); I != N; ++I) {
- if (needsToVisitImports(M, SearchDecls[I]))
- return ModuleManager::Continue;
- }
- return ModuleManager::SkipImports;
- }
+ if (!LocalOffset) {
+ ASTDeclReader::attachLatestDecl(CanonDecl, FirstLocal);
+ return;
+ }
- bool visitPostorder(ModuleFile &M) {
- // Visit each of the declarations.
- for (unsigned I = 0, N = SearchDecls.size(); I != N; ++I)
- searchForID(M, SearchDecls[I]);
- return false;
- }
-
- ArrayRef<Decl *> getChain() const {
- return Chain;
- }
- };
-}
+ // Load the list of other redeclarations from this module file.
+ ModuleFile *M = getOwningModuleFile(FirstLocal);
+ assert(M && "imported decl from no module file");
-void ASTReader::loadPendingDeclChain(Decl *CanonDecl) {
- // The decl might have been merged into something else after being added to
- // our list. If it was, just skip it.
- if (!CanonDecl->isCanonicalDecl())
- return;
+ llvm::BitstreamCursor &Cursor = M->DeclsCursor;
+ SavedStreamPosition SavedPosition(Cursor);
+ Cursor.JumpToBit(LocalOffset);
- // Determine the set of declaration IDs we'll be searching for.
- SmallVector<DeclID, 16> SearchDecls;
- GlobalDeclID CanonID = CanonDecl->getGlobalID();
- if (CanonID)
- SearchDecls.push_back(CanonDecl->getGlobalID()); // Always first.
- KeyDeclsMap::iterator KeyPos = KeyDecls.find(CanonDecl);
- if (KeyPos != KeyDecls.end())
- SearchDecls.append(KeyPos->second.begin(), KeyPos->second.end());
-
- // Build up the list of redeclarations.
- RedeclChainVisitor Visitor(*this, SearchDecls, RedeclsDeserialized, CanonID);
- ModuleMgr.visitDepthFirst(&RedeclChainVisitor::visitPreorder,
- &RedeclChainVisitor::visitPostorder, &Visitor);
-
- // Retrieve the chains.
- ArrayRef<Decl *> Chain = Visitor.getChain();
- if (Chain.empty() || (Chain.size() == 1 && Chain[0] == CanonDecl))
- return;
+ RecordData Record;
+ unsigned Code = Cursor.ReadCode();
+ unsigned RecCode = Cursor.readRecord(Code, Record);
+ (void)RecCode;
+ assert(RecCode == LOCAL_REDECLARATIONS && "expected LOCAL_REDECLARATIONS record!");
- // Hook up the chains.
- //
- // FIXME: We have three different dispatches on decl kind here; maybe
+ // FIXME: We have several different dispatches on decl kind here; maybe
// we should instead generate one loop per kind and dispatch up-front?
- Decl *MostRecent = ASTDeclReader::getMostRecentDecl(CanonDecl);
- if (!MostRecent)
- MostRecent = CanonDecl;
- for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
- if (Chain[I] == CanonDecl)
- continue;
-
- ASTDeclReader::attachPreviousDecl(*this, Chain[I], MostRecent, CanonDecl);
- MostRecent = Chain[I];
+ Decl *MostRecent = FirstLocal;
+ for (unsigned I = 0, N = Record.size(); I != N; ++I) {
+ auto *D = GetLocalDecl(*M, Record[N - I - 1]);
+ ASTDeclReader::attachPreviousDecl(*this, D, MostRecent, CanonDecl);
+ MostRecent = D;
}
ASTDeclReader::attachLatestDecl(CanonDecl, MostRecent);
}
@@ -3630,11 +3514,7 @@ namespace {
}
}
- static bool visit(ModuleFile &M, void *UserData) {
- return static_cast<ObjCCategoriesVisitor *>(UserData)->visit(M);
- }
-
- bool visit(ModuleFile &M) {
+ bool operator()(ModuleFile &M) {
// If we've loaded all of the category information we care about from
// this module file, we're done.
if (M.Generation <= PreviousGeneration)
@@ -3672,14 +3552,14 @@ namespace {
return true;
}
};
-}
+} // end anonymous namespace
void ASTReader::loadObjCCategories(serialization::GlobalDeclID ID,
ObjCInterfaceDecl *D,
unsigned PreviousGeneration) {
ObjCCategoriesVisitor Visitor(*this, ID, D, CategoriesDeserialized,
PreviousGeneration);
- ModuleMgr.visit(ObjCCategoriesVisitor::visit, &Visitor);
+ ModuleMgr.visit(Visitor);
}
template<typename DeclT, typename Fn>
@@ -3716,17 +3596,6 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
// FIXME: We should call addHiddenDecl instead, to add the member
// to its DeclContext.
RD->addedMember(MD);
-
- // If we've added a new special member to a class definition that is not
- // the canonical definition, then we need special member lookups in the
- // canonical definition to also look into our class.
- auto *DD = RD->DefinitionData.getNotUpdated();
- if (DD && DD->Definition != RD) {
- auto &Merged = Reader.MergedLookups[DD->Definition];
- // FIXME: Avoid the linear-time scan here.
- if (std::find(Merged.begin(), Merged.end(), RD) == Merged.end())
- Merged.push_back(RD);
- }
break;
}
@@ -3798,10 +3667,8 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
// Visible update is handled separately.
uint64_t LexicalOffset = Record[Idx++];
if (!HadRealDefinition && LexicalOffset) {
- RD->setHasExternalLexicalStorage(true);
- Reader.ReadDeclContextStorage(ModuleFile, ModuleFile.DeclsCursor,
- std::make_pair(LexicalOffset, 0),
- ModuleFile.DeclContextInfos[RD]);
+ Reader.ReadLexicalDeclContextStorage(ModuleFile, ModuleFile.DeclsCursor,
+ LexicalOffset, RD);
Reader.PendingFakeDefinitionData.erase(OldDD);
}