
Following of https://github.com/llvm/llvm-project/pull/76930 This follows the idea of "only writes what we writes", which I think is the most natural and efficient way to implement this optimization. We start writing the BMI from the first declaration in module purview instead of the global module fragment, so that everything in the GMF untouched won't be written in the BMI naturally. The exception is, as I said in https://github.com/llvm/llvm-project/pull/76930, when we write a declaration we need to write its decl context, and when we write the decl context, we need to write everything from it. So when we see `std::vector`, we basically need to write everything under namespace std. This violates our intention. To fix this, this patch delays the writing of namespace in the GMF. From my local measurement, the size of the BMI decrease to 90M from 112M for a local modules build. I think this is significant. This feature will be covered under the experimental reduced BMI so that it won't affect any existing users. So I'd like to land this when the CI gets green. Documents will be added seperately.
127 lines
3.7 KiB
C++
127 lines
3.7 KiB
C++
// RUN: rm -rf %t
|
|
// RUN: mkdir %t
|
|
// RUN: split-file %s %t
|
|
//
|
|
// RUN: %clang_cc1 -std=c++20 %t/foo.cppm -I%t -emit-module-interface -o %t/foo.pcm
|
|
// RUN: %clang_cc1 -fprebuilt-module-path=%t -std=c++20 %t/use.cpp -I%t/. -fsyntax-only -verify
|
|
|
|
// RUN: %clang_cc1 -std=c++20 %t/foo.cppm -I%t -emit-reduced-module-interface -o %t/foo.pcm
|
|
// RUN: %clang_cc1 -fprebuilt-module-path=%t -std=c++20 %t/use.cpp -I%t/. -fsyntax-only -verify
|
|
|
|
//--- foo.h
|
|
template <typename T = int>
|
|
T v;
|
|
|
|
template <int T = 8>
|
|
int v2;
|
|
|
|
template <typename T>
|
|
class my_array {};
|
|
|
|
template <template <typename> typename C = my_array>
|
|
int v3;
|
|
|
|
template <typename T, int *i = nullptr>
|
|
T v4;
|
|
|
|
template <typename T, T *i = nullptr>
|
|
T v5;
|
|
|
|
inline int a = 43;
|
|
template <typename T, int *i = &a>
|
|
T v6;
|
|
|
|
inline int b = 43;
|
|
template <typename T, T *i = &b>
|
|
T v7;
|
|
|
|
template <int T = (3 > 2)>
|
|
int v8;
|
|
|
|
consteval int getInt() {
|
|
return 55;
|
|
}
|
|
template <int T = getInt()>
|
|
int v9;
|
|
|
|
//--- foo_bad.h
|
|
template <typename T = double>
|
|
T v;
|
|
|
|
template <int T = 9>
|
|
int v2;
|
|
|
|
template <typename T>
|
|
class others_array {};
|
|
|
|
template <template <typename> typename C = others_array>
|
|
int v3;
|
|
|
|
static int a;
|
|
consteval int *getIntPtr() {
|
|
return &a;
|
|
}
|
|
template <typename T, int *i = getIntPtr()>
|
|
T v4;
|
|
|
|
consteval void *getVoidPtr() {
|
|
return &a;
|
|
}
|
|
template <typename T, T *i = getVoidPtr()>
|
|
T v5;
|
|
|
|
inline int a_ = 43;
|
|
template <typename T, int *i = &a_>
|
|
T v6;
|
|
|
|
inline int b_ = 43;
|
|
template <typename T, T *i = &b_>
|
|
T v7;
|
|
|
|
template <int T = -1>
|
|
int v8;
|
|
|
|
consteval int getInt2() {
|
|
return 55;
|
|
}
|
|
template <int T = getInt2()>
|
|
int v9;
|
|
|
|
//--- foo.cppm
|
|
module;
|
|
#include "foo.h"
|
|
export module foo;
|
|
export using ::v;
|
|
export using ::v2;
|
|
export using ::my_array;
|
|
export using ::v3;
|
|
export using ::v4;
|
|
export using ::v5;
|
|
export using ::v6;
|
|
export using ::v7;
|
|
export using ::v8;
|
|
export using ::v9;
|
|
|
|
//--- use.cpp
|
|
import foo;
|
|
#include "foo_bad.h"
|
|
|
|
// expected-error@foo_bad.h:1 {{template parameter default argument is inconsistent with previous definition}}
|
|
// expected-note@foo.h:1 {{previous default template argument defined in module foo.<global>}}
|
|
// expected-error@foo_bad.h:4 {{template parameter default argument is inconsistent with previous definition}}
|
|
// expected-note@foo.h:4 {{previous default template argument defined in module foo.<global>}}
|
|
// expected-error@foo_bad.h:10 {{template parameter default argument is inconsistent with previous definition}}
|
|
// expected-note@foo.h:10 {{previous default template argument defined in module foo.<global>}}
|
|
// expected-error@foo_bad.h:17 {{template parameter default argument is inconsistent with previous definition}}
|
|
// expected-note@foo.h:13 {{previous default template argument defined in module foo.<global>}}
|
|
// expected-error@foo_bad.h:23 {{template parameter default argument is inconsistent with previous definition}}
|
|
// expected-note@foo.h:16 {{previous default template argument defined in module foo.<global>}}
|
|
// expected-error@foo_bad.h:27 {{template parameter default argument is inconsistent with previous definition}}
|
|
// expected-note@foo.h:20 {{previous default template argument defined in module foo.<global>}}
|
|
// expected-error@foo_bad.h:31 {{template parameter default argument is inconsistent with previous definition}}
|
|
// expected-note@foo.h:24 {{previous default template argument defined in module foo.<global>}}
|
|
// expected-error@foo_bad.h:34 {{template parameter default argument is inconsistent with previous definition}}
|
|
// expected-note@foo.h:27 {{previous default template argument defined in module foo.<global>}}
|
|
// expected-error@foo_bad.h:40 {{template parameter default argument is inconsistent with previous definition}}
|
|
// expected-note@foo.h:33 {{previous default template argument defined in module foo.<global>}}
|