@@ -110,9 +110,9 @@ unsafe fn location_in_scope(r: CXSourceRange) -> bool {
110
110
&& file. 0 !=ptr:: null_mut ( )
111
111
}
112
112
113
- fn test_file ( file : & str ) -> bool {
114
- let mut idents= HashMap :: new ( ) ;
115
- let mut all_succeeded= true ;
113
+ /// tokenize_range_adjust can be used to work around LLVM bug 9069
114
+ /// https://bugs.llvm.org//show_bug.cgi?id=9069
115
+ fn file_visit_macros < F : FnMut ( Vec < u8 > , Vec < Token > ) > ( file : & str , tokenize_range_adjust : bool , mut visitor : F ) {
116
116
unsafe {
117
117
let tu={
118
118
let index=clang_createIndex ( true as _ , false as _ ) ;
@@ -132,7 +132,7 @@ fn test_file(file: &str) -> bool {
132
132
if cur. kind ==CXCursor_MacroDefinition {
133
133
let mut range=clang_getCursorExtent ( cur) ;
134
134
if !location_in_scope ( range) { return CXChildVisit_Continue }
135
- range. end_int_data -=1 ; // clang bug for macros only
135
+ range. end_int_data -=if tokenize_range_adjust { 1 } else { 0 } ;
136
136
let mut token_ptr=ptr:: null_mut ( ) ;
137
137
let mut num=0 ;
138
138
clang_tokenize ( tu, range, & mut token_ptr, & mut num) ;
@@ -146,16 +146,44 @@ fn test_file(file: &str) -> bool {
146
146
}
147
147
) . collect ( ) ;
148
148
clang_disposeTokens ( tu, token_ptr, num) ;
149
- all_succeeded&= test_definition ( clang_str_to_vec ( clang_getCursorSpelling ( cur) ) , & tokens, & mut idents ) ;
149
+ visitor ( clang_str_to_vec ( clang_getCursorSpelling ( cur) ) , tokens)
150
150
}
151
151
}
152
152
CXChildVisit_Continue
153
153
} ) ;
154
154
clang_disposeTranslationUnit ( tu) ;
155
155
} ;
156
+ }
157
+
158
+ fn test_file ( file : & str ) -> bool {
159
+ let mut idents=HashMap :: new ( ) ;
160
+ let mut all_succeeded=true ;
161
+ file_visit_macros ( file, fix_bug_9069 ( ) , |ident, tokens| all_succeeded&=test_definition ( ident, & tokens, & mut idents) ) ;
156
162
all_succeeded
157
163
}
158
164
165
+ fn fix_bug_9069 ( ) -> bool {
166
+ fn check_bug_9069 ( ) -> bool {
167
+ let mut token_sets = vec ! [ ] ;
168
+ file_visit_macros ( "tests/input/test_llvm_bug_9069.h" , false , |ident, tokens| {
169
+ assert_eq ! ( & ident, b"A" ) ;
170
+ token_sets. push ( tokens) ;
171
+ } ) ;
172
+ assert_eq ! ( token_sets. len( ) , 2 ) ;
173
+ token_sets[ 0 ] != token_sets[ 1 ]
174
+ }
175
+
176
+ use std:: sync:: { Once , ONCE_INIT } ;
177
+ use std:: sync:: atomic:: { AtomicBool , ATOMIC_BOOL_INIT , Ordering } ;
178
+
179
+ static CHECK_FIX : Once = ONCE_INIT ;
180
+ static FIX : AtomicBool = ATOMIC_BOOL_INIT ;
181
+
182
+ CHECK_FIX . call_once ( || FIX . store ( check_bug_9069 ( ) , Ordering :: SeqCst ) ) ;
183
+
184
+ FIX . load ( Ordering :: SeqCst )
185
+ }
186
+
159
187
macro_rules! test_file {
160
188
( $f: ident) => {
161
189
#[ test] fn $f( ) {
0 commit comments