On Thu, Sep 8, 2011 at 7:06 PM, Douglas Gregor <[email protected]> wrote: > Author: dgregor > Date: Thu Sep 8 21:06:17 2011 > New Revision: 139348 > > URL: http://llvm.org/viewvc/llvm-project?rev=139348&view=rev > Log: > Modules: introduce the __module_private__ declaration specifier, which > indicates that a declaration is only visible within the module it is > declared in. > > > Added: > cfe/trunk/test/Modules/module-private.cpp (with props) > Modified: > cfe/trunk/include/clang/AST/Decl.h > cfe/trunk/include/clang/AST/DeclBase.h > cfe/trunk/include/clang/Basic/TokenKinds.def > cfe/trunk/include/clang/Sema/DeclSpec.h > cfe/trunk/include/clang/Sema/Lookup.h > cfe/trunk/include/clang/Sema/Sema.h > cfe/trunk/lib/AST/DeclPrinter.cpp > cfe/trunk/lib/Parse/ParseDecl.cpp > cfe/trunk/lib/Parse/ParseDeclCXX.cpp > cfe/trunk/lib/Parse/ParseTentative.cpp > cfe/trunk/lib/Sema/DeclSpec.cpp > cfe/trunk/lib/Sema/SemaDecl.cpp > cfe/trunk/lib/Sema/SemaDeclCXX.cpp > cfe/trunk/lib/Sema/SemaTemplate.cpp > cfe/trunk/lib/Serialization/ASTReaderDecl.cpp > cfe/trunk/lib/Serialization/ASTWriterDecl.cpp > > Modified: cfe/trunk/include/clang/AST/Decl.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=139348&r1=139347&r2=139348&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/Decl.h (original) > +++ cfe/trunk/include/clang/AST/Decl.h Thu Sep 8 21:06:17 2011 > @@ -180,6 +180,16 @@ > /// \brief Determine whether this declaration has linkage. > bool hasLinkage() const; > > + /// \brief Whether this declaration was marked as being private to the > + /// module in which it was defined. > + bool isModulePrivate() const { return ModulePrivate; } > + > + /// \brief Specify whether this declaration was marked as being private > + /// to the module in which it was defined. > + void setModulePrivate(bool MP = true) { > + ModulePrivate = MP; > + } > + > /// \brief Determine whether this declaration is a C++ class member. > bool isCXXClassMember() const { > const DeclContext *DC = getDeclContext(); > > Modified: cfe/trunk/include/clang/AST/DeclBase.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=139348&r1=139347&r2=139348&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/DeclBase.h (original) > +++ cfe/trunk/include/clang/AST/DeclBase.h Thu Sep 8 21:06:17 2011 > @@ -243,7 +243,7 @@ > /// evaluated context or not, e.g. functions used in uninstantiated > templates > /// are regarded as "referenced" but not "used". > unsigned Referenced : 1; > - > + > protected: > /// Access - Used by C++ decls for the access specifier. > // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum > @@ -256,6 +256,10 @@ > /// ChangedAfterLoad - if this declaration has changed since being loaded > unsigned ChangedAfterLoad : 1; > > + /// \brief Whether this declaration is private to the module in which it > was > + /// defined. > + unsigned ModulePrivate : 1; > + > /// IdentifierNamespace - This specifies what IDNS_* namespace this lives > in. > unsigned IdentifierNamespace : 12; > > @@ -269,7 +273,9 @@ > /// This field is only valid for NamedDecls subclasses. > mutable unsigned CachedLinkage : 2; > > - > + friend class ASTDeclWriter; > + friend class ASTDeclReader; > + > private: > void CheckAccessDeclContext() const; > > @@ -280,6 +286,7 @@ > Loc(L), DeclKind(DK), InvalidDecl(0), > HasAttrs(false), Implicit(false), Used(false), Referenced(false), > Access(AS_none), PCHLevel(0), ChangedAfterLoad(false), > + ModulePrivate(0), > IdentifierNamespace(getIdentifierNamespaceForKind(DK)), > HasCachedLinkage(0) > { > @@ -290,6 +297,7 @@ > : NextDeclInContext(0), DeclKind(DK), InvalidDecl(0), > HasAttrs(false), Implicit(false), Used(false), Referenced(false), > Access(AS_none), PCHLevel(0), ChangedAfterLoad(false), > + ModulePrivate(0), > IdentifierNamespace(getIdentifierNamespaceForKind(DK)), > HasCachedLinkage(0) > { > > Modified: cfe/trunk/include/clang/Basic/TokenKinds.def > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=139348&r1=139347&r2=139348&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Basic/TokenKinds.def (original) > +++ cfe/trunk/include/clang/Basic/TokenKinds.def Thu Sep 8 21:06:17 2011 > @@ -401,6 +401,7 @@ > // Apple Extension. > KEYWORD(__private_extern__ , KEYALL) > KEYWORD(__import_module__ , KEYALL) > +KEYWORD(__module_private__ , KEYALL) > > // Microsoft Extension. > KEYWORD(__declspec , KEYALL) > > Modified: cfe/trunk/include/clang/Sema/DeclSpec.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=139348&r1=139347&r2=139348&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Sema/DeclSpec.h (original) > +++ cfe/trunk/include/clang/Sema/DeclSpec.h Thu Sep 8 21:06:17 2011 > @@ -345,7 +345,7 @@ > SourceRange TypeofParensRange; > SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc; > SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc; > - SourceLocation FriendLoc, ConstexprLoc; > + SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc; > > WrittenBuiltinSpecs writtenBS; > void SaveWrittenBuiltinSpecs(); > @@ -592,13 +592,17 @@ > > bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, > unsigned &DiagID); > - > + bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, > + unsigned &DiagID); > bool SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec, > unsigned &DiagID); > > bool isFriendSpecified() const { return Friend_specified; } > SourceLocation getFriendSpecLoc() const { return FriendLoc; } > > + bool isModulePrivateSpecified() const { return ModulePrivateLoc.isValid(); > } > + SourceLocation getModulePrivateSpecLoc() const { return ModulePrivateLoc; } > + > bool isConstexprSpecified() const { return Constexpr_specified; } > SourceLocation getConstexprSpecLoc() const { return ConstexprLoc; } > > > Modified: cfe/trunk/include/clang/Sema/Lookup.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Lookup.h?rev=139348&r1=139347&r2=139348&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Sema/Lookup.h (original) > +++ cfe/trunk/include/clang/Sema/Lookup.h Thu Sep 8 21:06:17 2011 > @@ -268,7 +268,19 @@ > > /// \brief Tests whether the given declaration is acceptable. > bool isAcceptableDecl(NamedDecl *D) const { > - return D->isInIdentifierNamespace(IDNS); > + if (!D->isInIdentifierNamespace(IDNS)) > + return false; > + > + // So long as this declaration is not module-private or was parsed as > + // part of this translation unit (i.e., in the module), we're allowed to > + // find it. > + if (!D->isModulePrivate() || D->getPCHLevel() == 0) > + return true; > + > + // FIXME: We should be allowed to refer to a module-private name from > + // within the same module, e.g., during template instantiation. > + // This requires us know which module a particular declaration came from. > + return false; > }
Suppose module A has a template function, call it docall(), that calls op(Obj) on the passed-in object. Then suppose module B, which depends on module A, has a module-private type BTy and op(BTy), and has a public template function fun() which uses docall() on BTy. Then suppose a module C depends on B. Is C allowed to call fun()? :) -Eli _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
