[cfe-commits] r139348 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/DeclBase.h include/clang/Basic/TokenKinds.def include/clang/Sema/DeclSpec.h include/clang/Sema/Lookup.h include/clang/Sema/Sema.h lib/AST/DeclPrinter.cpp lib/Parse/

Eli Friedman eli.friedman at gmail.com
Thu Sep 8 20:06:00 PDT 2011


On Thu, Sep 8, 2011 at 7:06 PM, Douglas Gregor <dgregor at apple.com> 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




More information about the cfe-commits mailing list