summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp11
-rw-r--r--clang/test/Modules/Inputs/PR20399/FirstHeader.h17
-rw-r--r--clang/test/Modules/Inputs/PR20399/SecondHeader.h13
-rw-r--r--clang/test/Modules/Inputs/PR20399/module.modulemap18
-rw-r--r--clang/test/Modules/Inputs/PR20399/stl_map.h25
-rw-r--r--clang/test/Modules/Inputs/PR20399/vector51
-rw-r--r--clang/test/Modules/pr20399.cpp2
7 files changed, 131 insertions, 6 deletions
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 04a39c07aaf..94eead8641f 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -5708,8 +5708,6 @@ void ASTWriter::CompletedTagDefinition(const TagDecl *D) {
}
void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {
- assert(!WritingAST && "Already writing the AST!");
-
// TU and namespaces are handled elsewhere.
if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC))
return;
@@ -5718,12 +5716,12 @@ void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {
return; // Not a source decl added to a DeclContext from PCH.
assert(!getDefinitiveDeclContext(DC) && "DeclContext not definitive!");
+ assert(!WritingAST && "Already writing the AST!");
AddUpdatedDeclContext(DC);
UpdatingVisibleDecls.push_back(D);
}
void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {
- assert(!WritingAST && "Already writing the AST!");
assert(D->isImplicit());
if (!(!D->isFromASTFile() && RD->isFromASTFile()))
return; // Not a source member added to a class from PCH.
@@ -5732,17 +5730,18 @@ void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {
// A decl coming from PCH was modified.
assert(RD->isCompleteDefinition());
+ assert(!WritingAST && "Already writing the AST!");
DeclUpdates[RD].push_back(DeclUpdate(UPD_CXX_ADDED_IMPLICIT_MEMBER, D));
}
void ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
const ClassTemplateSpecializationDecl *D) {
// The specializations set is kept in the canonical template.
- assert(!WritingAST && "Already writing the AST!");
TD = TD->getCanonicalDecl();
if (!(!D->isFromASTFile() && TD->isFromASTFile()))
return; // Not a source specialization added to a template from PCH.
+ assert(!WritingAST && "Already writing the AST!");
DeclUpdates[TD].push_back(DeclUpdate(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
D));
}
@@ -5750,11 +5749,11 @@ void ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
void ASTWriter::AddedCXXTemplateSpecialization(
const VarTemplateDecl *TD, const VarTemplateSpecializationDecl *D) {
// The specializations set is kept in the canonical template.
- assert(!WritingAST && "Already writing the AST!");
TD = TD->getCanonicalDecl();
if (!(!D->isFromASTFile() && TD->isFromASTFile()))
return; // Not a source specialization added to a template from PCH.
+ assert(!WritingAST && "Already writing the AST!");
DeclUpdates[TD].push_back(DeclUpdate(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
D));
}
@@ -5762,11 +5761,11 @@ void ASTWriter::AddedCXXTemplateSpecialization(
void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
const FunctionDecl *D) {
// The specializations set is kept in the canonical template.
- assert(!WritingAST && "Already writing the AST!");
TD = TD->getCanonicalDecl();
if (!(!D->isFromASTFile() && TD->isFromASTFile()))
return; // Not a source specialization added to a template from PCH.
+ assert(!WritingAST && "Already writing the AST!");
DeclUpdates[TD].push_back(DeclUpdate(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
D));
}
diff --git a/clang/test/Modules/Inputs/PR20399/FirstHeader.h b/clang/test/Modules/Inputs/PR20399/FirstHeader.h
new file mode 100644
index 00000000000..c8005227b35
--- /dev/null
+++ b/clang/test/Modules/Inputs/PR20399/FirstHeader.h
@@ -0,0 +1,17 @@
+#ifndef FIRSTHEADER
+#define FIRSTHEADER
+
+#include "SecondHeader.h" // Just a class which gets in the lazy deserialization chain
+
+#include "stl_map.h"
+#include "vector"
+struct A {
+ typedef std::map<int, int*>::iterator el;
+};
+
+struct B {
+ ~B() {}
+ std::vector<int> fvec; // Cannot replace with simple mockup
+};
+
+#endif
diff --git a/clang/test/Modules/Inputs/PR20399/SecondHeader.h b/clang/test/Modules/Inputs/PR20399/SecondHeader.h
new file mode 100644
index 00000000000..8548cc563ab
--- /dev/null
+++ b/clang/test/Modules/Inputs/PR20399/SecondHeader.h
@@ -0,0 +1,13 @@
+#ifndef SECONDHEADER
+#define SECONDHEADER
+
+#include "vector"
+
+class Collection {
+ template <class T> struct Address { };
+};
+
+template <> struct Collection::Address<std::vector<bool> >
+ : public Collection::Address<std::vector<bool>::iterator> { };
+
+#endif
diff --git a/clang/test/Modules/Inputs/PR20399/module.modulemap b/clang/test/Modules/Inputs/PR20399/module.modulemap
new file mode 100644
index 00000000000..223434adba1
--- /dev/null
+++ b/clang/test/Modules/Inputs/PR20399/module.modulemap
@@ -0,0 +1,18 @@
+module stdlib [system] {
+ header "stl_map.h"
+ header "vector"
+ }
+
+module libCore {
+ header "SecondHeader.h"
+ use stdlib
+ export *
+}
+
+module libGdml {
+ header "FirstHeader.h"
+ use libCore
+ use stdlib
+ export *
+}
+
diff --git a/clang/test/Modules/Inputs/PR20399/stl_map.h b/clang/test/Modules/Inputs/PR20399/stl_map.h
new file mode 100644
index 00000000000..11da0425348
--- /dev/null
+++ b/clang/test/Modules/Inputs/PR20399/stl_map.h
@@ -0,0 +1,25 @@
+namespace std
+{
+ template<typename _Iterator>
+ class reverse_iterator {};
+
+ template<typename _Iterator>
+ inline int*
+ operator-(const int& __x, const reverse_iterator<_Iterator>& __y) {};
+
+ template<typename _Tp>
+ struct _Rb_tree_iterator
+ {
+ typedef _Rb_tree_iterator<_Tp> _Self;
+ };
+
+ template <typename _Key, typename _Tp >
+ class map
+ {
+ public:
+ typedef _Rb_tree_iterator<int> iterator;
+
+ template<typename _K1, typename _T1>
+ friend bool operator<(const map<_K1, _T1>&, const map<_K1, _T1>&);
+ };
+} // namespace std
diff --git a/clang/test/Modules/Inputs/PR20399/vector b/clang/test/Modules/Inputs/PR20399/vector
new file mode 100644
index 00000000000..379e4661d35
--- /dev/null
+++ b/clang/test/Modules/Inputs/PR20399/vector
@@ -0,0 +1,51 @@
+namespace std
+{
+ template<typename _Tp, typename _Alloc = int>
+ class vector
+ {
+ public:
+ int* _M_start;
+ int* _M_end_of_storage;
+
+ ~vector()
+ { this->_M_end_of_storage - this->_M_start; }
+ };
+
+ struct _Bit_iterator {};
+
+ inline int* operator-(const _Bit_iterator& __x, const _Bit_iterator& __y)
+ {
+ return 0;
+ }
+
+ struct _Bvector_base
+ {
+ struct _Bvector_impl
+ {
+ _Bit_iterator _M_start;
+
+ _Bvector_impl() { }
+ };
+
+ public:
+ ~_Bvector_base()
+ { this->_M_deallocate(); }
+
+ protected:
+ _Bvector_impl _M_impl;
+
+ void _M_deallocate() {}
+ };
+
+ template<typename _Alloc>
+ class vector<bool, _Alloc> : protected _Bvector_base
+ {
+ typedef _Bvector_base _Base;
+ public:
+ typedef _Bit_iterator iterator;
+
+ vector()
+ : _Base() { }
+ };
+
+} // namespace std
diff --git a/clang/test/Modules/pr20399.cpp b/clang/test/Modules/pr20399.cpp
new file mode 100644
index 00000000000..4f4a02561fc
--- /dev/null
+++ b/clang/test/Modules/pr20399.cpp
@@ -0,0 +1,2 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodule-name=libGdml -emit-module -x c++ -std=c++11 %S/Inputs/PR20399/module.modulemap
OpenPOWER on IntegriCloud