зеркало из https://github.com/microsoft/clang.git
__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
This commit is contained in:
Родитель
9134294114
Коммит
e761230ae3
|
@ -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.
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче