/// \brief Keeps track of the elements added to PendingDeclChains.
llvm::SmallSet<serialization::DeclID, 16> PendingDeclChainsKnown;
+ /// \brief The Decl IDs for the Sema/Lexical DeclContext of a Decl that has
+ /// been loaded but its DeclContext was not set yet.
+ struct PendingDeclContextInfo {
+ Decl *D;
+ serialization::GlobalDeclID SemaDC;
+ serialization::GlobalDeclID LexicalDC;
+ };
+
+ /// \brief The set of Decls that have been loaded but their DeclContexts are
+ /// not set yet.
+ ///
+ /// The DeclContexts for these Decls will be set once recursive loading has
+ /// been completed.
+ std::deque<PendingDeclContextInfo> PendingDeclContextInfos;
+
/// \brief The set of Objective-C categories that have been deserialized
/// since the last time the declaration chains were linked.
llvm::SmallPtrSet<ObjCCategoryDecl *, 16> CategoriesDeserialized;
void finishPendingActions();
+ void addPendingDeclContextInfo(Decl *D,
+ serialization::GlobalDeclID SemaDC,
+ serialization::GlobalDeclID LexicalDC) {
+ assert(D);
+ PendingDeclContextInfo Info = { D, SemaDC, LexicalDC };
+ PendingDeclContextInfos.push_back(Info);
+ }
+
/// \brief Produce an error diagnostic and return true.
///
/// This routine should only be used for fatal errors that have to
void ASTReader::finishPendingActions() {
while (!PendingIdentifierInfos.empty() || !PendingDeclChains.empty() ||
- !PendingMacroIDs.empty()) {
+ !PendingMacroIDs.empty() || !PendingDeclContextInfos.empty()) {
// If any identifiers with corresponding top-level declarations have
// been loaded, load those declarations now.
while (!PendingIdentifierInfos.empty()) {
}
}
PendingMacroIDs.clear();
+
+ // Wire up the DeclContexts for Decls that we delayed setting until
+ // recursive loading is completed.
+ while (!PendingDeclContextInfos.empty()) {
+ PendingDeclContextInfo Info = PendingDeclContextInfos.front();
+ PendingDeclContextInfos.pop_front();
+ DeclContext *SemaDC = cast<DeclContext>(GetDecl(Info.SemaDC));
+ DeclContext *LexicalDC = cast<DeclContext>(GetDecl(Info.LexicalDC));
+ Info.D->setDeclContextsImpl(SemaDC, LexicalDC, getContext());
+ }
}
// If we deserialized any C++ or Objective-C class definitions, any
unsigned &Idx;
TypeID TypeIDForTypeDecl;
- DeclID DeclContextIDForTemplateParmDecl;
- DeclID LexicalDeclContextIDForTemplateParmDecl;
-
bool HasPendingBody;
uint64_t GetCurrentCursorOffset();
Reader.PendingBodies[FD] = GetCurrentCursorOffset();
HasPendingBody = true;
}
- } else if (D->isTemplateParameter()) {
- // If we have a fully initialized template parameter, we can now
- // set its DeclContext.
- DeclContext *SemaDC = cast<DeclContext>(
- Reader.GetDecl(DeclContextIDForTemplateParmDecl));
- DeclContext *LexicalDC = cast<DeclContext>(
- Reader.GetDecl(LexicalDeclContextIDForTemplateParmDecl));
- D->setDeclContextsImpl(SemaDC, LexicalDC, Reader.getContext());
}
}
// parameter immediately, because the template parameter might be
// used in the formulation of its DeclContext. Use the translation
// unit DeclContext as a placeholder.
- DeclContextIDForTemplateParmDecl = ReadDeclID(Record, Idx);
- LexicalDeclContextIDForTemplateParmDecl = ReadDeclID(Record, Idx);
+ GlobalDeclID SemaDCIDForTemplateParmDecl = ReadDeclID(Record, Idx);
+ GlobalDeclID LexicalDCIDForTemplateParmDecl = ReadDeclID(Record, Idx);
+ Reader.addPendingDeclContextInfo(D,
+ SemaDCIDForTemplateParmDecl,
+ LexicalDCIDForTemplateParmDecl);
D->setDeclContext(Reader.getContext().getTranslationUnitDecl());
} else {
DeclContext *SemaDC = ReadDeclAs<DeclContext>(Record, Idx);
Int &g(Int, int, double);
Int &test = NestedExpansion<char, char, char>().f(0, 1, 2, Int(3), 4, 5.0);
}
+
+namespace rdar13135282 {
+ void test() {
+ __mt_alloc<> mt = __mt_alloc<>();
+ }
+}
template<typename...B> auto f(A...a, B...b) -> decltype(g(a + b...));
};
template struct NestedExpansion<char, char, char>;
+
+namespace rdar13135282 {
+template < typename _Alloc >
+void foo(_Alloc = _Alloc());
+
+template < bool > class __pool;
+
+template < template < bool > class _PoolTp >
+struct __common_pool {
+ typedef _PoolTp < 0 > pool_type;
+};
+
+template < template < bool > class _PoolTp >
+struct __common_pool_base : __common_pool < _PoolTp > {};
+
+template < template < bool > class _PoolTp >
+struct A : __common_pool_base < _PoolTp > {};
+
+template < typename _Poolp = A < __pool > >
+struct __mt_alloc {
+ typedef typename _Poolp::pool_type __pool_type;
+ __mt_alloc() {
+ foo<__mt_alloc<> >();
+ }
+};
+}