summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/include/clang/Sema/Lookup.h2
-rw-r--r--clang/include/clang/Sema/Sema.h6
-rw-r--r--clang/lib/Sema/SemaDecl.cpp42
-rw-r--r--clang/lib/Sema/SemaLookup.cpp2
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp9
-rw-r--r--clang/test/Modules/Inputs/module.map3
-rw-r--r--clang/test/Modules/Inputs/module_private_left.h8
-rw-r--r--clang/test/Modules/Inputs/module_private_right.h2
-rw-r--r--clang/test/Modules/Inputs/redecl-merge-left.h6
-rw-r--r--clang/test/Modules/Inputs/redecl-merge-right.h6
-rw-r--r--clang/test/Modules/Inputs/redecl-merge-top-explicit.h5
-rw-r--r--clang/test/Modules/module-private.cpp24
-rw-r--r--clang/test/Modules/redecl-merge.m12
14 files changed, 52 insertions, 77 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c0676dd3e1d..7c2e1f87976 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5154,8 +5154,6 @@ def note_related_result_type_inferred : Note<
}
let CategoryName = "Modules Issue" in {
-def err_module_private_follows_public : Error<
- "__module_private__ declaration of %0 follows public declaration">;
def err_module_private_specialization : Error<
"%select{template|partial|member}0 specialization cannot be "
"declared __module_private__">;
diff --git a/clang/include/clang/Sema/Lookup.h b/clang/include/clang/Sema/Lookup.h
index 9f8a239d9f2..1b991cb54b9 100644
--- a/clang/include/clang/Sema/Lookup.h
+++ b/clang/include/clang/Sema/Lookup.h
@@ -286,7 +286,7 @@ public:
if (!D->isInIdentifierNamespace(IDNS))
return 0;
- if (isVisible(D))
+ if (Redecl == Sema::ForRedeclaration || isVisible(D))
return D;
return getAcceptableDeclSlow(D);
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fd87d6b2de7..9b244cdc84f 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1119,12 +1119,6 @@ public:
/// \param Path The module access path.
DeclResult ActOnModuleImport(SourceLocation ImportLoc, ModuleIdPath Path);
- /// \brief Diagnose that \p New is a module-private redeclaration of
- /// \p Old.
- void diagnoseModulePrivateRedeclaration(NamedDecl *New, NamedDecl *Old,
- SourceLocation ModulePrivateKeyword
- = SourceLocation());
-
/// \brief Retrieve a suitable printing policy.
PrintingPolicy getPrintingPolicy() const;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index c31850313ad..ebcdcf58d04 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1456,12 +1456,6 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) {
if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Old))
New->setPreviousDeclaration(Typedef);
- // __module_private__ is propagated to later declarations.
- if (Old->isModulePrivate())
- New->setModulePrivate();
- else if (New->isModulePrivate())
- diagnoseModulePrivateRedeclaration(New, Old);
-
if (getLangOptions().MicrosoftExt)
return;
@@ -2047,12 +2041,6 @@ bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) {
if (Old->isPure())
New->setPure();
- // __module_private__ is propagated to later declarations.
- if (Old->isModulePrivate())
- New->setModulePrivate();
- else if (New->isModulePrivate())
- diagnoseModulePrivateRedeclaration(New, Old);
-
// Merge attributes from the parameters. These can mismatch with K&R
// declarations.
if (New->getNumParams() == Old->getNumParams())
@@ -2237,12 +2225,6 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
return New->setInvalidDecl();
}
- // __module_private__ is propagated to later declarations.
- if (Old->isModulePrivate())
- New->setModulePrivate();
- else if (New->isModulePrivate())
- diagnoseModulePrivateRedeclaration(New, Old);
-
// Variables with external linkage are analyzed in FinalizeDeclaratorGroup.
// FIXME: The test for external storage here seems wrong? We still
@@ -5627,9 +5609,6 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
assert(OldTemplateDecl->isMemberSpecialization());
}
- if (OldTemplateDecl->isModulePrivate())
- NewTemplateDecl->setModulePrivate();
-
} else {
if (isa<CXXMethodDecl>(NewFD)) // Set access for out-of-line definitions
NewFD->setAccess(OldDecl->getAccess());
@@ -8212,19 +8191,14 @@ CreateNewDecl:
AddMsStructLayoutForRecord(RD);
}
- if (PrevDecl && PrevDecl->isModulePrivate())
- New->setModulePrivate();
- else if (ModulePrivateLoc.isValid()) {
+ if (ModulePrivateLoc.isValid()) {
if (isExplicitSpecialization)
Diag(New->getLocation(), diag::err_module_private_specialization)
<< 2
<< FixItHint::CreateRemoval(ModulePrivateLoc);
- else if (PrevDecl && !PrevDecl->isModulePrivate())
- diagnoseModulePrivateRedeclaration(New, PrevDecl, ModulePrivateLoc);
// __module_private__ does not apply to local classes. However, we only
// diagnose this as an error when the declaration specifiers are
// freestanding. Here, we just ignore the __module_private__.
- // foobar
else if (!SearchDC->isFunctionOrMethod())
New->setModulePrivate();
}
@@ -9969,20 +9943,6 @@ DeclResult Sema::ActOnModuleImport(SourceLocation ImportLoc, ModuleIdPath Path)
return Import;
}
-void
-Sema::diagnoseModulePrivateRedeclaration(NamedDecl *New, NamedDecl *Old,
- SourceLocation ModulePrivateKeyword) {
- assert(!Old->isModulePrivate() && "Old is module-private!");
-
- Diag(New->getLocation(), diag::err_module_private_follows_public)
- << New->getDeclName() << SourceRange(ModulePrivateKeyword);
- Diag(Old->getLocation(), diag::note_previous_declaration)
- << Old->getDeclName();
-
- // Drop the __module_private__ from the new declaration, since it's invalid.
- New->setModulePrivate(false);
-}
-
void Sema::ActOnPragmaWeakID(IdentifierInfo* Name,
SourceLocation PragmaLoc,
SourceLocation NameLoc) {
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index bc1cb3fca63..a5fc682d18c 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -1169,7 +1169,7 @@ bool Sema::LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation) {
// If this declaration is module-private and it came from an AST
// file, we can't see it.
- NamedDecl *D = getVisibleDecl(*I);
+ NamedDecl *D = R.isForRedeclaration()? *I : getVisibleDecl(*I);
if (!D)
continue;
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 8ec4c195f91..d0c0f0bf2d1 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -1013,15 +1013,8 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
NewClass, PrevClassTemplate);
NewClass->setDescribedClassTemplate(NewTemplate);
- if (PrevClassTemplate && PrevClassTemplate->isModulePrivate()) {
+ if (ModulePrivateLoc.isValid())
NewTemplate->setModulePrivate();
- } else if (ModulePrivateLoc.isValid()) {
- if (PrevClassTemplate && !PrevClassTemplate->isModulePrivate())
- diagnoseModulePrivateRedeclaration(NewTemplate, PrevClassTemplate,
- ModulePrivateLoc);
- else
- NewTemplate->setModulePrivate();
- }
// Build the type for the class template declaration now.
QualType T = NewTemplate->getInjectedClassNameSpecialization();
diff --git a/clang/test/Modules/Inputs/module.map b/clang/test/Modules/Inputs/module.map
index b101c01567d..13a44eb6a76 100644
--- a/clang/test/Modules/Inputs/module.map
+++ b/clang/test/Modules/Inputs/module.map
@@ -44,7 +44,8 @@ module decldef {
}
module redecl_merge_top {
- header "redecl-merge-top.h"
+ header "redecl-merge-top.h"
+ explicit module Explicit { header "redecl-merge-top-explicit.h" }
}
module redecl_merge_left {
header "redecl-merge-left.h"
diff --git a/clang/test/Modules/Inputs/module_private_left.h b/clang/test/Modules/Inputs/module_private_left.h
index 617a7abf3d9..ff33999d0fb 100644
--- a/clang/test/Modules/Inputs/module_private_left.h
+++ b/clang/test/Modules/Inputs/module_private_left.h
@@ -1,6 +1,6 @@
__module_private__ struct HiddenStruct;
-struct HiddenStruct {
+__module_private__ struct HiddenStruct {
};
@@ -10,17 +10,17 @@ template<typename T>
__module_private__ void f1(T*);
template<typename T>
-void f1(T*);
+__module_private__ void f1(T*);
template<typename T>
__module_private__ class vector;
template<typename T>
-class vector {
+__module_private__ class vector {
};
vector<float> vec_float;
typedef __module_private__ int Integer;
-typedef int Integer;
+typedef __module_private__ int Integer;
diff --git a/clang/test/Modules/Inputs/module_private_right.h b/clang/test/Modules/Inputs/module_private_right.h
index e7c1bb82216..53efe25d088 100644
--- a/clang/test/Modules/Inputs/module_private_right.h
+++ b/clang/test/Modules/Inputs/module_private_right.h
@@ -1,5 +1,5 @@
__module_private__ double &f0(double);
-double &f0(double);
+__module_private__ double &f0(double);
__module_private__ int hidden_var;
diff --git a/clang/test/Modules/Inputs/redecl-merge-left.h b/clang/test/Modules/Inputs/redecl-merge-left.h
index 8e2fa53ae13..4e009591de6 100644
--- a/clang/test/Modules/Inputs/redecl-merge-left.h
+++ b/clang/test/Modules/Inputs/redecl-merge-left.h
@@ -10,6 +10,12 @@ __import_module__ redecl_merge_top;
@class A;
+@class Explicit;
+
+int *explicit_func(void);
+
+struct explicit_struct;
+
#ifdef __cplusplus
template<typename T> class Vector;
diff --git a/clang/test/Modules/Inputs/redecl-merge-right.h b/clang/test/Modules/Inputs/redecl-merge-right.h
index 6d697347114..f0bfd35746f 100644
--- a/clang/test/Modules/Inputs/redecl-merge-right.h
+++ b/clang/test/Modules/Inputs/redecl-merge-right.h
@@ -9,6 +9,12 @@ __import_module__ redecl_merge_top;
@class B;
+@class Explicit;
+
+int *explicit_func(void);
+
+struct explicit_struct;
+
#ifdef __cplusplus
template<typename T> class Vector {
public:
diff --git a/clang/test/Modules/Inputs/redecl-merge-top-explicit.h b/clang/test/Modules/Inputs/redecl-merge-top-explicit.h
new file mode 100644
index 00000000000..c8f51589f31
--- /dev/null
+++ b/clang/test/Modules/Inputs/redecl-merge-top-explicit.h
@@ -0,0 +1,5 @@
+@class Explicit;
+
+int *explicit_func(void);
+
+struct explicit_struct { int member; };
diff --git a/clang/test/Modules/module-private.cpp b/clang/test/Modules/module-private.cpp
index eb932a8eb85..bdfa2682ce1 100644
--- a/clang/test/Modules/module-private.cpp
+++ b/clang/test/Modules/module-private.cpp
@@ -31,28 +31,28 @@ int test_broken() {
// Check for private redeclarations of public entities.
template<typename T>
-class public_class_template; // expected-note{{previous declaration is here}}
+class public_class_template;
template<typename T>
-__module_private__ class public_class_template; // expected-error{{__module_private__ declaration of 'public_class_template' follows public declaration}}
+__module_private__ class public_class_template;
-typedef int public_typedef; // expected-note{{previous declaration is here}}
-typedef __module_private__ int public_typedef; // expected-error{{__module_private__ declaration of 'public_typedef' follows public declaration}}
+typedef int public_typedef;
+typedef __module_private__ int public_typedef;
-extern int public_var; // expected-note{{previous declaration is here}}
-extern __module_private__ int public_var; // expected-error{{__module_private__ declaration of 'public_var' follows public declaration}}
+extern int public_var;
+extern __module_private__ int public_var;
-void public_func(); // expected-note{{previous declaration is here}}
-__module_private__ void public_func(); // expected-error{{__module_private__ declaration of 'public_func' follows public declaration}}
+void public_func();
+__module_private__ void public_func();
template<typename T>
-void public_func_template(); // expected-note{{previous declaration is here}}
+void public_func_template();
template<typename T>
-__module_private__ void public_func_template(); // expected-error{{__module_private__ declaration of 'public_func_template' follows public declaration}}
+__module_private__ void public_func_template();
-struct public_struct; // expected-note{{previous declaration is here}}
-__module_private__ struct public_struct; // expected-error{{__module_private__ declaration of 'public_struct' follows public declaration}}
+struct public_struct;
+__module_private__ struct public_struct;
// Check for attempts to make specializations private
template<> __module_private__ void public_func_template<int>(); // expected-error{{template specialization cannot be declared __module_private__}}
diff --git a/clang/test/Modules/redecl-merge.m b/clang/test/Modules/redecl-merge.m
index 6497268c384..7021d14f698 100644
--- a/clang/test/Modules/redecl-merge.m
+++ b/clang/test/Modules/redecl-merge.m
@@ -20,6 +20,18 @@ B *f1() {
@class B;
+// Test redeclarations of entities in explicit submodules, to make
+// sure we're maintaining the declaration chains even when normal name
+// lookup can't see what we're looking for.
+void testExplicit() {
+ Explicit *e;
+ int *(*fp)(void) = &explicit_func;
+ int *ip = explicit_func();
+
+ // FIXME: Should complain about definition not having been imported.
+ struct explicit_struct es = { 0 };
+}
+
__import_module__ redecl_merge_bottom;
@implementation B
OpenPOWER on IntegriCloud