@@ -246,11 +246,10 @@ impl Cursor {
246246 pub ( crate ) fn is_toplevel ( & self ) -> bool {
247247 let mut semantic_parent = self . fallible_semantic_parent ( ) ;
248248
249- while semantic_parent. is_some ( ) &&
250- ( semantic_parent. unwrap ( ) . kind ( ) == CXCursor_Namespace ||
251- semantic_parent. unwrap ( ) . kind ( ) ==
252- CXCursor_NamespaceAlias ||
253- semantic_parent. unwrap ( ) . kind ( ) == CXCursor_NamespaceRef )
249+ while semantic_parent. is_some ( )
250+ && ( semantic_parent. unwrap ( ) . kind ( ) == CXCursor_Namespace
251+ || semantic_parent. unwrap ( ) . kind ( ) == CXCursor_NamespaceAlias
252+ || semantic_parent. unwrap ( ) . kind ( ) == CXCursor_NamespaceRef )
254253 {
255254 semantic_parent =
256255 semantic_parent. unwrap ( ) . fallible_semantic_parent ( ) ;
@@ -267,9 +266,9 @@ impl Cursor {
267266 pub ( crate ) fn is_template_like ( & self ) -> bool {
268267 matches ! (
269268 self . kind( ) ,
270- CXCursor_ClassTemplate |
271- CXCursor_ClassTemplatePartialSpecialization |
272- CXCursor_TypeAliasTemplateDecl
269+ CXCursor_ClassTemplate
270+ | CXCursor_ClassTemplatePartialSpecialization
271+ | CXCursor_TypeAliasTemplateDecl
273272 )
274273 }
275274
@@ -296,9 +295,9 @@ impl Cursor {
296295 /// Is the referent a fully specialized template specialization without any
297296 /// remaining free template arguments?
298297 pub ( crate ) fn is_fully_specialized_template ( & self ) -> bool {
299- self . is_template_specialization ( ) &&
300- self . kind ( ) != CXCursor_ClassTemplatePartialSpecialization &&
301- self . num_template_args ( ) . unwrap_or ( 0 ) > 0
298+ self . is_template_specialization ( )
299+ && self . kind ( ) != CXCursor_ClassTemplatePartialSpecialization
300+ && self . num_template_args ( ) . unwrap_or ( 0 ) > 0
302301 }
303302
304303 /// Is the referent a template specialization that still has remaining free
@@ -324,9 +323,9 @@ impl Cursor {
324323 pub ( crate ) fn is_template_parameter ( & self ) -> bool {
325324 matches ! (
326325 self . kind( ) ,
327- CXCursor_TemplateTemplateParameter |
328- CXCursor_TemplateTypeParameter |
329- CXCursor_NonTypeTemplateParameter
326+ CXCursor_TemplateTemplateParameter
327+ | CXCursor_TemplateTypeParameter
328+ | CXCursor_NonTypeTemplateParameter
330329 )
331330 }
332331
@@ -664,9 +663,9 @@ impl Cursor {
664663 // inline function without a definition, and it's not a defaulted
665664 // function, we can reasonably safely conclude that it's a deleted
666665 // function.
667- self . is_inlined_function ( ) &&
668- self . definition ( ) . is_none ( ) &&
669- !self . is_defaulted_function ( )
666+ self . is_inlined_function ( )
667+ && self . definition ( ) . is_none ( )
668+ && !self . is_defaulted_function ( )
670669 }
671670
672671 /// Is the referent a bit field declaration?
@@ -788,11 +787,11 @@ impl Cursor {
788787 let found_attr = & mut found_attrs[ idx] ;
789788 if !* found_attr {
790789 // `attr.name` and` attr.token_kind` are checked against unexposed attributes only.
791- if attr. kind == Some ( kind) ||
792- ( kind == CXCursor_UnexposedAttr &&
793- cur. tokens ( ) . iter ( ) . any ( |t| {
794- t. kind == attr. token_kind &&
795- t. spelling ( ) == attr. name
790+ if attr. kind == Some ( kind)
791+ || ( kind == CXCursor_UnexposedAttr
792+ && cur. tokens ( ) . iter ( ) . any ( |t| {
793+ t. kind == attr. token_kind
794+ && t. spelling ( ) == attr. name
796795 } ) )
797796 {
798797 * found_attr = true ;
@@ -1408,12 +1407,12 @@ impl Type {
14081407 /// to.
14091408 pub ( crate ) fn pointee_type ( & self ) -> Option < Type > {
14101409 match self . kind ( ) {
1411- CXType_Pointer |
1412- CXType_RValueReference |
1413- CXType_LValueReference |
1414- CXType_MemberPointer |
1415- CXType_BlockPointer |
1416- CXType_ObjCObjectPointer => {
1410+ CXType_Pointer
1411+ | CXType_RValueReference
1412+ | CXType_LValueReference
1413+ | CXType_MemberPointer
1414+ | CXType_BlockPointer
1415+ | CXType_ObjCObjectPointer => {
14171416 let ret = Type {
14181417 x : unsafe { clang_getPointeeType ( self . x ) } ,
14191418 } ;
@@ -1516,12 +1515,12 @@ impl Type {
15161515 // Yep, the spelling of this containing type-parameter is extremely
15171516 // nasty... But can happen in <type_traits>. Unfortunately I couldn't
15181517 // reduce it enough :(
1519- self . template_args ( ) . is_some_and ( |args| args. len ( ) > 0 ) &&
1520- !matches ! (
1518+ self . template_args ( ) . is_some_and ( |args| args. len ( ) > 0 )
1519+ && !matches ! (
15211520 self . declaration( ) . kind( ) ,
1522- CXCursor_ClassTemplatePartialSpecialization |
1523- CXCursor_TypeAliasTemplateDecl |
1524- CXCursor_TemplateTemplateParameter
1521+ CXCursor_ClassTemplatePartialSpecialization
1522+ | CXCursor_TypeAliasTemplateDecl
1523+ | CXCursor_TemplateTemplateParameter
15251524 )
15261525 }
15271526
@@ -1546,9 +1545,9 @@ impl Type {
15461545 . is_match ( spelling. as_ref ( ) )
15471546 }
15481547
1549- self . kind ( ) == CXType_Unexposed &&
1550- ( hacky_parse_associated_type ( self . spelling ( ) ) ||
1551- hacky_parse_associated_type (
1548+ self . kind ( ) == CXType_Unexposed
1549+ && ( hacky_parse_associated_type ( self . spelling ( ) )
1550+ || hacky_parse_associated_type (
15521551 self . canonical_type ( ) . spelling ( ) ,
15531552 ) )
15541553 }
@@ -2309,8 +2308,8 @@ impl EvalResult {
23092308 {
23102309 let mut found_cant_eval = false ;
23112310 cursor. visit ( |c| {
2312- if c. kind ( ) == CXCursor_TypeRef &&
2313- c. cur_type ( ) . canonical_type ( ) . kind ( ) == CXType_Unexposed
2311+ if c. kind ( ) == CXCursor_TypeRef
2312+ && c. cur_type ( ) . canonical_type ( ) . kind ( ) == CXType_Unexposed
23142313 {
23152314 found_cant_eval = true ;
23162315 return CXChildVisit_Break ;
@@ -2329,7 +2328,8 @@ impl EvalResult {
23292328 } )
23302329 }
23312330
2332- fn kind ( & self ) -> CXEvalResultKind {
2331+ /// Return the kind of the evaluation result.
2332+ pub ( crate ) fn kind ( & self ) -> CXEvalResultKind {
23332333 unsafe { clang_EvalResult_getKind ( self . x ) }
23342334 }
23352335
@@ -2370,6 +2370,30 @@ impl EvalResult {
23702370 Some ( value as i64 )
23712371 }
23722372
2373+ /// Try to resolve the result into a string literal.
2374+ /// This returns `None` if the result is not immediately a string literal.
2375+ pub ( crate ) fn as_str_literal ( & self ) -> Option < Vec < u8 > > {
2376+ if !matches ! (
2377+ self . kind( ) ,
2378+ CXEval_StrLiteral | CXEval_CFStr | CXEval_ObjCStrLiteral ,
2379+ ) {
2380+ return None ;
2381+ }
2382+ // Safety: we are only copying the content, not assuming a borrow.
2383+ // TODO(@dingxiangfei2009): LLVM Libclang does not return the true size
2384+ // of a string literal, which could be truncated due to a null character
2385+ // '\0' in the middle.
2386+ // Tracking issue: https://github.com/llvm/llvm-project/issues/69749
2387+ let value =
2388+ unsafe { CStr :: from_ptr ( clang_EvalResult_getAsStr ( self . x ) ) } ;
2389+ Some ( value. to_bytes ( ) . into ( ) )
2390+ }
2391+
2392+ /// Return the type of the value.
2393+ pub ( crate ) fn value_type ( & self ) -> Type {
2394+ self . ty
2395+ }
2396+
23732397 /// Evaluates the expression as a literal string, that may or may not be
23742398 /// valid utf-8.
23752399 pub ( crate ) fn as_literal_string ( & self ) -> Option < Vec < u8 > > {
0 commit comments