[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/

Douglas Gregor dgregor at apple.com
Fri Sep 9 10:10:20 PDT 2011


On Sep 8, 2011, at 8:06 PM, Eli Friedman wrote:

> 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()? :)


I think the answer is "yes", but the visibility model for template instantiation needs a lot more thought. My rough estimate behavior is that module-private entities will be ignored (hidden) by normal, qualified, and member name lookup from outside the model, but argument-dependent lookup will be able to find those module-private entities. 

Maybe :)

	- Doug



More information about the cfe-commits mailing list