Skip to content

Commit 10b4ed3

Browse files
ChuanqiXu9memfrob
authored and
memfrob
committed
[C++20] [Modules] Disable preferred_name when writing a C++20 Module interface
Currently, the use of preferred_name would block implementing std modules in libcxx. See llvm/llvm-project#56490 for example. The problem is pretty hard and it looks like we couldn't solve it in a short time. So we sent this patch as a workaround to avoid blocking us to modularize STL. This is intended to be fixed properly in the future. Reviewed By: erichkeane, aaron.ballman, tahonermann Differential Revision: https://reviews.llvm.org/D130331
1 parent f90ad13 commit 10b4ed3

File tree

6 files changed

+72
-2
lines changed

6 files changed

+72
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,11 @@ Attribute Changes in Clang
435435
``__attribute__((function_return("keep")))`` was added. This is intended to
436436
be used by the Linux kernel to mitigate RETBLEED.
437437

438+
- Ignore the `__preferred_name__` attribute when writing for C++20 module interfaces.
439+
This is a short-term workaround intentionally since clang doesn't take care of the
440+
serialization and deserialization of `__preferred_name__`. See
441+
https://github.com/llvm/llvm-project/issues/56490 for example.
442+
438443
Windows Support
439444
---------------
440445

clang/include/clang/Basic/AttrDocs.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5040,6 +5040,12 @@ general this requires the template to be declared at least twice. For example:
50405040
clang::preferred_name(wstring)]] basic_string {
50415041
// ...
50425042
};
5043+
5044+
5045+
Note that the ``preferred_name`` attribute will be ignored when the compiler
5046+
writes a C++20 Module interface now. This is due to a compiler issue
5047+
(https://github.com/llvm/llvm-project/issues/56490) that blocks users to modularize
5048+
declarations with `preferred_name`. This is intended to be fixed in the future.
50435049
}];
50445050
}
50455051

clang/include/clang/Serialization/ASTWriter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,10 @@ class ASTWriter : public ASTDeserializationListener,
703703
bool hasChain() const { return Chain; }
704704
ASTReader *getChain() const { return Chain; }
705705

706+
bool isWritingNamedModules() const {
707+
return WritingModule && WritingModule->isModulePurview();
708+
}
709+
706710
private:
707711
// ASTDeserializationListener implementation
708712
void ReaderInitialized(ASTReader *Reader) override;

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2926,7 +2926,8 @@ Attr *ASTRecordReader::readAttr() {
29262926
/// Reads attributes from the current stream position.
29272927
void ASTRecordReader::readAttributes(AttrVec &Attrs) {
29282928
for (unsigned I = 0, E = readInt(); I != E; ++I)
2929-
Attrs.push_back(readAttr());
2929+
if (auto *A = readAttr())
2930+
Attrs.push_back(A);
29302931
}
29312932

29322933
//===----------------------------------------------------------------------===//

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4347,8 +4347,12 @@ void ASTWriter::WriteModuleFileExtension(Sema &SemaRef,
43474347

43484348
void ASTRecordWriter::AddAttr(const Attr *A) {
43494349
auto &Record = *this;
4350-
if (!A)
4350+
// FIXME: Clang can't handle the serialization/deserialization of
4351+
// preferred_name properly now. See
4352+
// https://github.com/llvm/llvm-project/issues/56490 for example.
4353+
if (!A || (isa<PreferredNameAttr>(A) && Writer->isWritingNamedModules()))
43514354
return Record.push_back(0);
4355+
43524356
Record.push_back(A->getKind() + 1); // FIXME: stable encoding, target attrs
43534357

43544358
Record.AddIdentifierRef(A->getAttrName());
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Tests that the ODR check wouldn't produce false-positive result for preferred_name attribute.
2+
//
3+
// RUN: rm -rf %t
4+
// RUN: mkdir -p %t
5+
// RUN: split-file %s %t
6+
//
7+
// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-module-interface -o %t/A.pcm
8+
// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use.cppm -verify -fsyntax-only
9+
// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use1.cpp -verify -fsyntax-only
10+
// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use2.cpp -verify -fsyntax-only
11+
//
12+
//--- foo.h
13+
template<class _CharT>
14+
class foo_templ;
15+
16+
typedef foo_templ<char> foo;
17+
18+
template<class _CharT>
19+
class
20+
__attribute__((__preferred_name__(foo)))
21+
foo_templ {
22+
public:
23+
foo_templ() {}
24+
};
25+
26+
inline foo_templ<char> bar()
27+
{
28+
return foo_templ<char>();
29+
}
30+
31+
//--- A.cppm
32+
module;
33+
#include "foo.h"
34+
export module A;
35+
36+
//--- Use.cppm
37+
// expected-no-diagnostics
38+
module;
39+
#include "foo.h"
40+
export module Use;
41+
import A;
42+
43+
//--- Use1.cpp
44+
import A; // [email protected]:8 {{attribute declaration must precede definition}}
45+
#include "foo.h" // [email protected]:9 {{previous definition is here}}
46+
47+
//--- Use2.cpp
48+
// expected-no-diagnostics
49+
#include "foo.h"
50+
import A;

0 commit comments

Comments
 (0)