2 #===-- tdtags - TableGen tags wrapper ---------------------------*- sh -*-===#
3 # vim:set sts=2 sw=2 et:
4 #===----------------------------------------------------------------------===#
6 # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
7 # See https://llvm.org/LICENSE.txt for license information.
8 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
10 #===----------------------------------------------------------------------===#
12 # This is a wrapper script to simplify generating ctags(1)-compatible index
13 # files for target .td files. Run tdtags -H for more documentation.
15 # For portability, this script is intended to conform to IEEE Std 1003.1-2008.
17 #===----------------------------------------------------------------------===#
23 Usage: $SELF [ <options> ] tdfile
24 or: $SELF [ <options> ] -x recipe [arg ...]
26 -H Display further help.
27 -a Append the tags to an existing tags file.
28 -f <file> Write tags to the specified file (defaults to 'tags').
29 -I <dir> Add the directory to the search path for tblgen include files.
30 -x <recipe> Generate tags file(s) for a common use case:
31 -q Suppress $TBLGEN error messages.
32 -v Be verbose; report progress.
39 all - Generate an index in each directory that contains .td files
40 in the LLVM source tree.
41 here - Generate an index for all .td files in the current directory.
42 recurse - Generate an index in each directory that contains .td files
43 in and under the current directory.
45 - Generate a tags file for each specified LLVM code generator
46 target, or if none are specified, all targets.
53 $SELF - generate ctags(1)-compatible index files for tblgen .td source
56 $SELF [ options ] -x recipe [arg ...]
57 $SELF [ options ] [file ...]
60 With the '-x' option, $SELF produces one or more tags files for a
61 particular common use case. See the RECIPES section below for details.
63 Without the '-x' option, $SELF provides a ctags(1)-like interface to
67 -a Append newly generated tags to those already in an existing
68 tags file. Without ths option, any and all existing tags are
69 replaced. NOTE: When building a mixed tags file, using ${SELF}
70 for tblgen tags and ctags(1) for other languages, it is best
71 to run ${SELF} first without '-a', and ctags(1) second with '-a',
72 because ctags(1) handling is more capable.
73 -f <file> Use the name <file> for the tags file, rather than the default
74 "tags". If the <file> is "-", then the tag index is written to
76 -H Display this document.
77 -I <dir> Add the directory <dir> to the search path for 'include'
78 statements in tblgen source.
79 -x Run a canned recipe, rather than operate on specified files.
80 When '-x' is present, the first non-option argument is the
81 name of a recipe, and any further arguments are arguments to
82 that recipe. With no arguments, lists the available recipes.
83 -q Suppress $TBLGEN error messages. Not all .td files are well-
84 formed outside a specific context, so recipes will sometimes
85 produce error messages for certain .td files. These errors
86 do not affect the indices produced for valid files.
87 -v Be verbose; report progress.
91 Produce a tags file in every directory in the LLVM source tree
92 that contains any .td files.
94 Produce a tags file from .td files in the current directory.
96 Produce a tags file in every directory that contains any .td
97 files, in and under the current directory.
98 $SELF -x target [<target> ...]
99 Produce a tags file for each named code generator target, or
100 if none are named, for all code generator targets.
104 # Temporary file management.
106 # Since SUS sh(1) has no arrays, this script makes extensive use of
107 # temporary files. The follow are 'global' and used to carry information
109 # $TMP:D Include directories.
110 # $TMP:I Included files.
111 # $TMP:T Top-level files, that are not included by another.
112 # $TMP:W Directories in which to generate tags (Worklist).
113 # For portability to OS X, names must not differ only in case.
115 TMP
=${TMPDIR:-/tmp}/$SELF:$$
122 if [ $OPT_VERBOSE -gt 1 ]
124 printf '===== %s =====\n' "$1"
129 # Escape the arguments, taken as a whole.
132 sed -e "s/'/'\\\\''/g" -e "1s/^/'/" -e "\$s/\$/'/"
135 # Determine whether the given directory contains at least one .td file.
139 [ -f "$i" ] && return 0
144 # Partition the supplied list of files, plus any files included from them,
146 # $TMP:T Top-level files, that are not included by another.
147 # $TMP:I Included files.
148 # Add standard directories to the include paths in $TMP:D if this would
149 # benefit the any of the included files.
155 [ "x$i" = 'x*.td' ] && return 1
158 printf '%s\n' "$i" >>$TMP:E
159 sed -n -e 's/include[[:space:]]"\(.*\)".*/\1/p' <"$i" >>$TMP:J
161 printf >&2 '%s: "%s" not found.\n' "$SELF" "$i"
165 sort -u <$TMP:E
>$TMP:X
166 sort -u <$TMP:J
>$TMP:I
167 # A file that exists but is not included is toplevel.
168 comm -23 $TMP:X
$TMP:I
>$TMP:T
171 # Check include files.
174 [ -f "$i" ] && continue
177 [ -f "$d/$i" ] && break
181 # See whether this include file can be found in a common location.
182 for d
in $LLVM_SRC_ROOT/include \
183 $LLVM_SRC_ROOT/tools
/clang
/include
187 printf '%s\n' "$d" >>$TMP:D
196 # Generate tags for the list of files in $TMP:T.
198 # Collect include directories.
202 inc
="${inc}${inc:+ }$(e "-I=$d")"
205 if [ $OPT_VERBOSE -ne 0 ]
207 printf >&2 'In "%s",\n' "$PWD"
210 # Generate tags for each file.
214 if [ $OPT_VERBOSE -ne 0 ]
216 printf >&2 ' generating tags from "%s"\n' "$i"
219 t
=$
(printf '%s:A:%05u' "$TMP" $n)
220 eval $TBLGEN --gen-ctags $inc "$i" >$t 2>$TMP:F
221 [ $OPT_NOTBLGENERR -eq 1 ] ||
cat $TMP:F
224 # Add existing tags if requested.
225 if [ $OPT_APPEND -eq 1 -a -f "$OPT_TAGSFILE" ]
227 if [ $OPT_VERBOSE -ne 0 ]
229 printf >&2 ' and existing tags from "%s"\n' "$OPT_TAGSFILE"
232 t
=$
(printf '%s:A:%05u' "$TMP" $n)
233 sed -e '/^!_TAG_/d' <"$OPT_TAGSFILE" |
sort -u >$t
241 sort -m -u $TMP:A
:* >$TMP:M
245 if [ x
${OPT_TAGSFILE}x
= x-x
]
249 if [ $OPT_VERBOSE -ne 0 ]
251 printf >&2 ' into "%s".\n' "$OPT_TAGSFILE"
253 mv -f $TMP:M
"$OPT_TAGSFILE"
257 # Generate tags for the current directory.
260 [ -s $TMP:T
] ||
return 1
264 # Generate tags for the current directory, and report an error if there are
265 # no .td files present.
270 printf >&2 '%s: Nothing to do here.\n' "$SELF"
275 # Generate tags for all .td files under the current directory.
282 # Generate tags for all .td files in LLVM.
285 td_find
"$LLVM_SRC_ROOT"
289 # Generate tags for each directory in the worklist $TMP:W.
298 # Find directories containing .td files within the specified directory,
299 # and record them in the worklist $TMP:W.
302 find -L "$1" -type f
-name '*.td' |
303 sed -e 's:/[^/]*$::' |
308 # Generate tags for the specified code generator targets, or
309 # if there are no arguments, all targets.
311 cd $LLVM_SRC_ROOT/lib
/Target
316 # Check that every specified argument is a target directory;
317 # if not, list all target directories.
320 if [ -d "$d" ] && dir_has_td
"$d"
322 printf '%s/%s\n' "$PWD" "$d"
324 printf >&2 '%s: "%s" is not a target. Targets are:\n' "$SELF" "$d"
327 [ -d "$d" ] ||
continue
328 dir_has_td
"$d" && printf >&2 ' %s\n' "$d"
337 # Change to the directory at the top of the enclosing LLVM source tree,
340 while [ "$PWD" != / ]
342 # Use this directory if multiple notable subdirectories are present.
343 [ -d include
/llvm
-a -d lib
/Target
] && return 0
349 # Ensure sort(1) behaves consistently.
364 while getopts 'af:hxqvHI:' opt
371 OPT_TAGSFILE
="$OPTARG"
380 OPT_VERBOSE
=$
((OPT_VERBOSE
+ 1))
383 printf '%s\n' "$OPTARG" >>$TMP:D
395 shift $
((OPTIND
- 1))
397 # Handle the case where tdtags is a simple ctags(1)-like wrapper for tblgen.
398 if [ $OPT_RECIPES -eq 0 ]
413 # Find the directory at the top of the enclosing LLVM source tree.
414 if ! LLVM_SRC_ROOT
=$
(llvm_src_root
&& pwd)
416 printf >&2 '%s: Run from within the LLVM source tree.\n' "$SELF"
420 # Select canned actions.
443 printf >&2 '%s: Unknown recipe "-x %s". ' "$SELF" "$RECIPE"
445 printf >&2 'Recipes:\n'
447 printf >&2 'Run "%s -H" for help.\n' "$SELF"