diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-09-09 19:05:14 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-09-09 19:05:14 +0000 |
commit | e761230ae3751b525cadd8066c74ec278ee4ef57 (patch) | |
tree | 459e36d24abbe4c0680f2795203885991b4a6eb6 | |
parent | 9134294114c15b938f2ff954995d9f00f63dd9d8 (diff) |
__module_private__ is inherited by redeclarations of an entity, and
must also be present of the first declaration of that entity.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139384 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 6 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 11 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 2 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 38 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 15 | ||||
-rw-r--r-- | test/Modules/module-private.cpp | 26 |
8 files changed, 85 insertions, 17 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 568e0a3b6b..846b32ba89 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -4716,5 +4716,11 @@ 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">; + +} + } // end of sema component. diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 4bdf3802aa..3306a0f7f5 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1090,6 +1090,12 @@ public: IdentifierInfo &ModuleName, SourceLocation ModuleNameLoc); + /// \brief Diagnose that \p New is a module-private redeclaration of + /// \p Old. + void diagnoseModulePrivateRedeclaration(NamedDecl *New, NamedDecl *Old, + SourceLocation ModulePrivateKeyword + = SourceLocation()); + /// Scope actions. void ActOnPopScope(SourceLocation Loc, Scope *S); void ActOnTranslationUnitScope(Scope *S); @@ -1125,7 +1131,7 @@ public: SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, AttributeList *Attr, AccessSpecifier AS, - bool IsModulePrivate, + SourceLocation ModulePrivateLoc, MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl, bool &IsDependent, bool ScopedEnum, bool ScopedEnumUsesClassTag, TypeResult UnderlyingType); @@ -3775,7 +3781,8 @@ public: IdentifierInfo *Name, SourceLocation NameLoc, AttributeList *Attr, TemplateParameterList *TemplateParams, - AccessSpecifier AS, bool IsModulePrivate, + AccessSpecifier AS, + SourceLocation ModulePrivateLoc, unsigned NumOuterTemplateParamLists, TemplateParameterList **OuterTemplateParamLists); diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 3c692cc577..197e446fd3 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -2850,7 +2850,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, unsigned DiagID; Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK, StartLoc, SS, Name, NameLoc, attrs.getList(), - AS, DS.isModulePrivateSpecified(), + AS, DS.getModulePrivateSpecLoc(), MultiTemplateParamsArg(Actions), Owned, IsDependent, IsScopedEnum, IsScopedUsingClassTag, BaseType); diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 63f32d094b..dbdb184d4a 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -1193,7 +1193,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // Declaration or definition of a class type TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc, SS, Name, NameLoc, attrs.getList(), AS, - DS.isModulePrivateSpecified(), + DS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent, false, false, clang::TypeResult()); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 4a7be55366..003be8289f 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1397,7 +1397,9 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) { // __module_private__ is propagated to later declarations. if (Old->isModulePrivate()) New->setModulePrivate(); - + else if (New->isModulePrivate()) + diagnoseModulePrivateRedeclaration(New, Old); + if (getLangOptions().Microsoft) return; @@ -1966,7 +1968,9 @@ bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) { // __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()) @@ -2152,6 +2156,8 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { // __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. @@ -7139,7 +7145,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, AttributeList *Attr, AccessSpecifier AS, - bool IsModulePrivate, + SourceLocation ModulePrivateLoc, MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl, bool &IsDependent, bool ScopedEnum, bool ScopedEnumUsesClassTag, @@ -7179,7 +7185,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, DeclResult Result = CheckClassTemplate(S, TagSpec, TUK, KWLoc, SS, Name, NameLoc, Attr, TemplateParams, AS, - IsModulePrivate, + ModulePrivateLoc, TemplateParameterLists.size() - 1, (TemplateParameterList**) TemplateParameterLists.release()); return Result.get(); @@ -7744,9 +7750,13 @@ CreateNewDecl: if (PrevDecl && PrevDecl->isModulePrivate()) New->setModulePrivate(); - else if (IsModulePrivate) - New->setModulePrivate(); - + else if (ModulePrivateLoc.isValid()) { + if (PrevDecl && !PrevDecl->isModulePrivate()) + diagnoseModulePrivateRedeclaration(New, PrevDecl, ModulePrivateLoc); + else + New->setModulePrivate(); + } + // If this is a specialization of a member class (of a class template), // check the specialization. if (isExplicitSpecialization && CheckMemberSpecialization(New, Previous)) @@ -9417,6 +9427,20 @@ DeclResult Sema::ActOnModuleImport(SourceLocation ImportLoc, return DeclResult((Decl *)0); } +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/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 9ffb7765af..f8c2905316 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -9472,7 +9472,7 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, return CheckClassTemplate(S, TagSpec, TUK_Friend, TagLoc, SS, Name, NameLoc, Attr, TemplateParams, AS_public, - /*IsModulePrivate=*/false, + /*ModulePrivateLoc=*/SourceLocation(), TempParamLists.size() - 1, (TemplateParameterList**) TempParamLists.release()).take(); } else { diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index eb199aced4..4b3f6c45d5 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -811,7 +811,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, IdentifierInfo *Name, SourceLocation NameLoc, AttributeList *Attr, TemplateParameterList *TemplateParams, - AccessSpecifier AS, bool IsModulePrivate, + AccessSpecifier AS, SourceLocation ModulePrivateLoc, unsigned NumOuterTemplateParamLists, TemplateParameterList** OuterTemplateParamLists) { assert(TemplateParams && TemplateParams->size() > 0 && @@ -1002,8 +1002,13 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, if (PrevClassTemplate && PrevClassTemplate->isModulePrivate()) { NewTemplate->setModulePrivate(); - } else if (IsModulePrivate) - 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(); @@ -4943,7 +4948,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TemplateNameLoc, Attr, TemplateParams, - AS_none, /*IsModulePrivate=*/false, + AS_none, /*ModulePrivateLoc=*/SourceLocation(), TemplateParameterLists.size() - 1, (TemplateParameterList**) TemplateParameterLists.release()); } @@ -5978,7 +5983,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, bool IsDependent = false; Decl *TagD = ActOnTag(S, TagSpec, Sema::TUK_Reference, KWLoc, SS, Name, NameLoc, Attr, AS_none, - /*IsModulePrivate=*/false, + /*ModulePrivateLoc=*/SourceLocation(), MultiTemplateParamsArg(*this, 0, 0), Owned, IsDependent, false, false, TypeResult()); diff --git a/test/Modules/module-private.cpp b/test/Modules/module-private.cpp index 689abd746a..3ee59c8a9c 100644 --- a/test/Modules/module-private.cpp +++ b/test/Modules/module-private.cpp @@ -63,4 +63,30 @@ int test_broken() { return hidden_var; // expected-error{{use of undeclared identifier 'hidden_var'}} } +// Check for private redeclarations of public entities. +template<typename T> +class public_class_template; // expected-note{{previous declaration is here}} + +template<typename T> +__module_private__ class public_class_template; // expected-error{{__module_private__ declaration of 'public_class_template' follows public declaration}} + + +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}} + +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}} + +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}} + +template<typename T> +void public_func_template(); // expected-note{{previous declaration is here}} +template<typename T> +__module_private__ void public_func_template(); // expected-error{{__module_private__ declaration of 'public_func_template' follows public declaration}} + +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}} + + #endif |