llvm-project/clang/test/Preprocessor/embed_constexpr.cpp
The Phantom Derpstorm 5989450e00
[clang][Sema, Lex, Parse] Preprocessor embed in C and C++ (and Obj-C and Obj-C++ by-proxy) (#68620)
This commit implements the entirety of the now-accepted [N3017 -
Preprocessor
Embed](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3017.htm) and
its sister C++ paper [p1967](https://wg21.link/p1967). It implements
everything in the specification, and includes an implementation that
drastically improves the time it takes to embed data in specific
scenarios (the initialization of character type arrays). The mechanisms
used to do this are used under the "as-if" rule, and in general when the
system cannot detect it is initializing an array object in a variable
declaration, will generate EmbedExpr AST node which will be expanded
by AST consumers (CodeGen or constant expression evaluators) or
expand embed directive as a comma expression.

---------

Co-authored-by: Aaron Ballman <aaron@aaronballman.com>
Co-authored-by: cor3ntin <corentinjabot@gmail.com>
Co-authored-by: H. Vetinari <h.vetinari@gmx.com>
Co-authored-by: Podchishchaeva, Mariya <mariya.podchishchaeva@intel.com>
2024-06-12 09:16:02 +02:00

98 lines
1.7 KiB
C++

// RUN: %clang_cc1 %s -fsyntax-only --embed-dir=%S/Inputs -verify -Wno-c23-extensions
// RUN: %clang_cc1 %s -fsyntax-only --embed-dir=%S/Inputs -verify -fexperimental-new-constant-interpreter -Wno-c23-extensions
constexpr int value(int a, int b) {
return a + b;
}
constexpr int func_call() {
return value(
#embed <jk.txt>
);
}
constexpr int init_list_expr() {
int vals[] = {
#embed <jk.txt>
};
return value(vals[0], vals[1]);
}
template <int N, int M>
struct Hurr {
static constexpr int V1 = N;
static constexpr int V2 = M;
};
constexpr int template_args() {
Hurr<
#embed <jk.txt>
> H;
return value(H.V1, H.V2);
}
constexpr int ExpectedValue = 'j' + 'k';
static_assert(func_call() == ExpectedValue);
static_assert(init_list_expr() == ExpectedValue);
static_assert(template_args() == ExpectedValue);
static_assert(
#embed <jk.txt> limit(1) suffix(== 'j')
);
int array[
#embed <jk.txt> limit(1)
];
static_assert(sizeof(array) / sizeof(int) == 'j');
constexpr int comma_expr = (
#embed <jk.txt> // expected-warning {{left operand of comma operator has no effect}}
);
static_assert(comma_expr == 'k');
constexpr int comma_expr_init_list{ (
#embed <jk.txt> limit(1)
) };
static_assert(comma_expr_init_list == 'j');
constexpr int paren_init(
#embed <jk.txt> limit(1)
);
static_assert(paren_init == 'j');
struct S {
const char buffer[2] = {
#embed "jk.txt"
};
};
constexpr struct S s;
static_assert(s.buffer[1] == 'k');
struct S1 {
int x, y;
};
struct T {
int x, y;
struct S1 s;
};
constexpr struct T t[] = {
#embed <numbers.txt>
};
static_assert(t[0].s.x == '2');
constexpr int func(int i, int) { return i; }
static_assert(
func(
#embed <jk.txt>
) == 'j');
template <int N>
struct ST {};
ST<
#embed <jk.txt> limit(1)
> st;