@@ -167,6 +167,14 @@ static bool is_bit_field(APValue &Result, Sema &S, EvalFn Evaluator,
167
167
QualType ResultTy, SourceRange Range,
168
168
ArrayRef<Expr *> Args);
169
169
170
+ static bool is_const (APValue &Result, Sema &S, EvalFn Evaluator,
171
+ QualType ResultTy, SourceRange Range,
172
+ ArrayRef<Expr *> Args);
173
+
174
+ static bool is_volatile (APValue &Result, Sema &S, EvalFn Evaluator,
175
+ QualType ResultTy, SourceRange Range,
176
+ ArrayRef<Expr *> Args);
177
+
170
178
static bool is_lvalue_reference_qualified (APValue &Result, Sema &S,
171
179
EvalFn Evaluator, QualType ResultTy,
172
180
SourceRange Range,
@@ -441,6 +449,8 @@ static constexpr Metafunction Metafunctions[] = {
441
449
{ Metafunction::MFRK_bool, 1 , 1 , is_explicit },
442
450
{ Metafunction::MFRK_bool, 1 , 1 , is_noexcept },
443
451
{ Metafunction::MFRK_bool, 1 , 1 , is_bit_field },
452
+ { Metafunction::MFRK_bool, 1 , 1 , is_const },
453
+ { Metafunction::MFRK_bool, 1 , 1 , is_volatile },
444
454
{ Metafunction::MFRK_bool, 1 , 1 , is_lvalue_reference_qualified },
445
455
{ Metafunction::MFRK_bool, 1 , 1 , is_rvalue_reference_qualified },
446
456
{ Metafunction::MFRK_bool, 1 , 1 , has_static_storage_duration },
@@ -597,9 +607,9 @@ static void encodeName(std::string &Result, StringRef In, bool BasicOnly) {
597
607
Result = In;
598
608
} else {
599
609
Result.reserve (In.size () * 8 ); // more than enough for '\u{XYZ}'
600
-
610
+
601
611
llvm::raw_string_ostream OS (Result);
602
-
612
+
603
613
const char *InCursor = In.begin ();
604
614
while (InCursor < In.end ()) {
605
615
if (isBasicCharacter (*InCursor)) {
@@ -1175,6 +1185,22 @@ static bool isFunctionOrMethodNoexcept(const QualType QT) {
1175
1185
return false ;
1176
1186
}
1177
1187
1188
+ static bool isConstQualifiedType (QualType QT) {
1189
+ bool result = QT.isConstQualified ();
1190
+ if (auto *FPT = dyn_cast<FunctionProtoType>(QT))
1191
+ result |= FPT->isConst ();
1192
+
1193
+ return result;
1194
+ }
1195
+
1196
+ static bool isVolatileQualifiedType (QualType QT) {
1197
+ bool result = QT.isVolatileQualified ();
1198
+ if (auto *FPT = dyn_cast<FunctionProtoType>(QT))
1199
+ result |= FPT->isVolatile ();
1200
+
1201
+ return result;
1202
+ }
1203
+
1178
1204
// -----------------------------------------------------------------------------
1179
1205
// Metafunction implementations
1180
1206
// -----------------------------------------------------------------------------
@@ -2747,7 +2773,7 @@ bool is_noexcept(APValue &Result, Sema &S, EvalFn Evaluator, QualType ResultTy,
2747
2773
case ReflectionValue::RK_declaration: {
2748
2774
const ValueDecl *D = R.getReflectedDecl ();
2749
2775
const auto result = isFunctionOrMethodNoexcept (D->getType ());
2750
-
2776
+
2751
2777
return SetAndSucceed (Result, makeBool (S.Context , result));
2752
2778
}
2753
2779
}
@@ -2771,6 +2797,77 @@ bool is_bit_field(APValue &Result, Sema &S, EvalFn Evaluator, QualType ResultTy,
2771
2797
return SetAndSucceed (Result, makeBool (S.Context , result));
2772
2798
}
2773
2799
2800
+ bool is_const (APValue &Result, Sema &S, EvalFn Evaluator, QualType ResultTy,
2801
+ SourceRange Range, ArrayRef<Expr *> Args) {
2802
+ assert (Args[0 ]->getType ()->isReflectionType ());
2803
+ assert (ResultTy == S.Context .BoolTy );
2804
+
2805
+ APValue R;
2806
+ if (!Evaluator (R, Args[0 ], true ))
2807
+ return true ;
2808
+
2809
+ switch (R.getReflection ().getKind ()) {
2810
+ case ReflectionValue::RK_null:
2811
+ case ReflectionValue::RK_template:
2812
+ case ReflectionValue::RK_namespace:
2813
+ case ReflectionValue::RK_base_specifier:
2814
+ case ReflectionValue::RK_data_member_spec:
2815
+ return SetAndSucceed (Result, makeBool (S.Context , false ));
2816
+ case ReflectionValue::RK_type: {
2817
+ bool result = isConstQualifiedType (R.getReflectedType ());
2818
+
2819
+ return SetAndSucceed (Result, makeBool (S.Context , result));
2820
+ }
2821
+ case ReflectionValue::RK_declaration: {
2822
+ bool result = isConstQualifiedType (R.getReflectedDecl ()->getType ());
2823
+
2824
+ return SetAndSucceed (Result, makeBool (S.Context , result));
2825
+ }
2826
+ case ReflectionValue::RK_expr_result: {
2827
+ bool result = isConstQualifiedType (R.getReflectedExprResult ()->getType ());
2828
+
2829
+ return SetAndSucceed (Result, makeBool (S.Context , result));
2830
+ }
2831
+ }
2832
+ llvm_unreachable (" invalid reflection type" );
2833
+ }
2834
+
2835
+ bool is_volatile (APValue &Result, Sema &S, EvalFn Evaluator, QualType ResultTy,
2836
+ SourceRange Range, ArrayRef<Expr *> Args) {
2837
+ assert (Args[0 ]->getType ()->isReflectionType ());
2838
+ assert (ResultTy == S.Context .BoolTy );
2839
+
2840
+ APValue R;
2841
+ if (!Evaluator (R, Args[0 ], true ))
2842
+ return true ;
2843
+
2844
+ switch (R.getReflection ().getKind ()) {
2845
+ case ReflectionValue::RK_null:
2846
+ case ReflectionValue::RK_template:
2847
+ case ReflectionValue::RK_namespace:
2848
+ case ReflectionValue::RK_base_specifier:
2849
+ case ReflectionValue::RK_data_member_spec:
2850
+ return SetAndSucceed (Result, makeBool (S.Context , false ));
2851
+ case ReflectionValue::RK_type: {
2852
+ bool result = isVolatileQualifiedType (R.getReflectedType ());
2853
+
2854
+ return SetAndSucceed (Result, makeBool (S.Context , result));
2855
+ }
2856
+ case ReflectionValue::RK_declaration: {
2857
+ bool result = isVolatileQualifiedType (R.getReflectedDecl ()->getType ());
2858
+
2859
+ return SetAndSucceed (Result, makeBool (S.Context , result));
2860
+ }
2861
+ case ReflectionValue::RK_expr_result: {
2862
+ bool result =
2863
+ isVolatileQualifiedType (R.getReflectedExprResult ()->getType ());
2864
+
2865
+ return SetAndSucceed (Result, makeBool (S.Context , result));
2866
+ }
2867
+ }
2868
+ llvm_unreachable (" invalid reflection type" );
2869
+ }
2870
+
2774
2871
bool is_lvalue_reference_qualified (APValue &Result, Sema &S, EvalFn Evaluator,
2775
2872
QualType ResultTy, SourceRange Range,
2776
2873
ArrayRef<Expr *> Args) {
0 commit comments