@@ -77,8 +77,11 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Context,
7777 *PrefixPtr = ID.getRawValue ();
7878
7979 // We leave the upper 16 bits to store the module IDs. 48 bits should be
80- // sufficient to store a declaration ID.
81- assert (*PrefixPtr < llvm::maskTrailingOnes<uint64_t >(48 ));
80+ // sufficient to store a declaration ID. See the comments in setOwningModuleID
81+ // for details.
82+ assert ((*PrefixPtr < llvm::maskTrailingOnes<uint64_t >(48 )) &&
83+ " Current Implementation limits the number of module files to not "
84+ " exceed 2^16. Contact Clang Developers to remove the limitation." );
8285
8386 return Result;
8487}
@@ -122,6 +125,25 @@ unsigned Decl::getOwningModuleID() const {
122125
123126void Decl::setOwningModuleID (unsigned ID) {
124127 assert (isFromASTFile () && " Only works on a deserialized declaration" );
128+ // Currently, we use 64 bits to store the GlobalDeclID and the module ID
129+ // to save the space. See `Decl::operator new` for details. To make it,
130+ // we split the higher 32 bits to 2 16bits for the module file index of
131+ // GlobalDeclID and the module ID. This introduces a limitation that the
132+ // number of modules can't exceed 2^16. (The number of module files should be
133+ // less than the number of modules).
134+ //
135+ // It is counter-intuitive to store both the module file index and the
136+ // module ID as it seems redundant. However, this is not true.
137+ // The module ID may be different from the module file where it is serialized
138+ // from for implicit template instantiations. See
139+ // https://github.com/llvm/llvm-project/issues/101939
140+ //
141+ // If we reach the limitation, we have to remove the limitation by asking
142+ // every deserialized declaration to pay for yet another 32 bits, or we have
143+ // to review the above issue to decide what we should do for it.
144+ assert ((ID < llvm::maskTrailingOnes<unsigned >(16 )) &&
145+ " Current Implementation limits the number of modules to not exceed "
146+ " 2^16. Contact Clang Developers to remove the limitation." );
125147 uint64_t *IDAddress = (uint64_t *)this - 1 ;
126148 *IDAddress &= llvm::maskTrailingOnes<uint64_t >(48 );
127149 *IDAddress |= (uint64_t )ID << 48 ;
0 commit comments