2 #===-- tdtags - TableGen tags wrapper ---------------------------*- sh -*-===#
3 # vim:set sts=2 sw=2 et:
4 #===----------------------------------------------------------------------===#
6 # The LLVM Compiler Infrastructure
8 # This file is distributed under the University of Illinois Open Source
9 # License. See LICENSE.TXT for details.
11 #===----------------------------------------------------------------------===#
13 # This is a wrapper script to simplify generating ctags(1)-compatible index
14 # files for target .td files. Run tdtags -H for more documentation.
16 # For portability, this script is intended to conform to IEEE Std 1003.1-2008.
18 #===----------------------------------------------------------------------===#
24 Usage: $SELF [ <options> ] tdfile
25 or: $SELF [ <options> ] -x recipe [arg ...]
27 -H Display further help.
28 -a Append the tags to an existing tags file.
29 -f <file> Write tags to the specified file (defaults to 'tags').
30 -I <dir> Add the directory to the search path for tblgen include files.
31 -x <recipe> Generate tags file(s) for a common use case:
32 -q Suppress $TBLGEN error messages.
33 -v Be verbose; report progress.
40 all - Generate an index in each directory that contains .td files
41 in the LLVM source tree.
42 here - Generate an index for all .td files in the current directory.
43 recurse - Generate an index in each directory that contains .td files
44 in and under the current directory.
46 - Generate a tags file for each specified LLVM code generator
47 target, or if none are specified, all targets.
54 $SELF - generate ctags(1)-compatible index files for tblgen .td source
57 $SELF [ options ] -x recipe [arg ...]
58 $SELF [ options ] [file ...]
61 With the '-x' option, $SELF produces one or more tags files for a
62 particular common use case. See the RECIPES section below for details.
64 Without the '-x' option, $SELF provides a ctags(1)-like interface to
68 -a Append newly generated tags to those already in an existing
69 tags file. Without ths option, any and all existing tags are
70 replaced. NOTE: When building a mixed tags file, using ${SELF}
71 for tblgen tags and ctags(1) for other languages, it is best
72 to run ${SELF} first without '-a', and ctags(1) second with '-a',
73 because ctags(1) handling is more capable.
74 -f <file> Use the name <file> for the tags file, rather than the default
75 "tags". If the <file> is "-", then the tag index is written to
77 -H Display this document.
78 -I <dir> Add the directory <dir> to the search path for 'include'
79 statements in tblgen source.
80 -x Run a canned recipe, rather than operate on specified files.
81 When '-x' is present, the first non-option argument is the
82 name of a recipe, and any further arguments are arguments to
83 that recipe. With no arguments, lists the available recipes.
84 -q Suppress $TBLGEN error messages. Not all .td files are well-
85 formed outside a specific context, so recipes will sometimes
86 produce error messages for certain .td files. These errors
87 do not affect the indices produced for valid files.
88 -v Be verbose; report progress.
92 Produce a tags file in every directory in the LLVM source tree
93 that contains any .td files.
95 Produce a tags file from .td files in the current directory.
97 Produce a tags file in every directory that contains any .td
98 files, in and under the current directory.
99 $SELF -x target [<target> ...]
100 Produce a tags file for each named code generator target, or
101 if none are named, for all code generator targets.
105 # Temporary file management.
107 # Since SUS sh(1) has no arrays, this script makes extensive use of
108 # temporary files. The follow are 'global' and used to carry information
110 # $TMP:D Include directories.
111 # $TMP:I Included files.
112 # $TMP:T Top-level files, that are not included by another.
113 # $TMP:W Directories in which to generate tags (Worklist).
114 # For portability to OS X, names must not differ only in case.
116 TMP=${TMPDIR:-/tmp}/$SELF:$$
123 if [ $OPT_VERBOSE -gt 1 ]
125 printf '===== %s =====\n' "$1"
130 # Escape the arguments, taken as a whole.
133 sed -e "s/'/'\\\\''/g" -e "1s/^/'/" -e "\$s/\$/'/"
136 # Determine whether the given directory contains at least one .td file.
140 [ -f "$i" ] && return 0
145 # Partition the supplied list of files, plus any files included from them,
147 # $TMP:T Top-level files, that are not included by another.
148 # $TMP:I Included files.
149 # Add standard directories to the include paths in $TMP:D if this would
150 # benefit the any of the included files.
156 [ "x$i" = 'x*.td' ] && return 1
159 printf '%s\n' "$i" >>$TMP:E
160 sed -n -e 's/include[[:space:]]"\(.*\)".*/\1/p' <"$i" >>$TMP:J
162 printf >&2 '%s: "%s" not found.\n' "$SELF" "$i"
166 sort -u <$TMP:E >$TMP:X
167 sort -u <$TMP:J >$TMP:I
168 # A file that exists but is not included is toplevel.
169 comm -23 $TMP:X $TMP:I >$TMP:T
172 # Check include files.
175 [ -f "$i" ] && continue
178 [ -f "$d/$i" ] && break
182 # See whether this include file can be found in a common location.
183 for d in $LLVM_SRC_ROOT/include \
184 $LLVM_SRC_ROOT/tools/clang/include
188 printf '%s\n' "$d" >>$TMP:D
197 # Generate tags for the list of files in $TMP:T.
199 # Collect include directories.
203 inc="${inc}${inc:+ }$(e "-I=$d")"
206 if [ $OPT_VERBOSE -ne 0 ]
208 printf >&2 'In "%s",\n' "$PWD"
211 # Generate tags for each file.
215 if [ $OPT_VERBOSE -ne 0 ]
217 printf >&2 ' generating tags from "%s"\n' "$i"
220 t=$(printf '%s:A:%05u' "$TMP" $n)
221 eval $TBLGEN --gen-ctags $inc "$i" >$t 2>$TMP:F
222 [ $OPT_NOTBLGENERR -eq 1 ] || cat $TMP:F
225 # Add existing tags if requested.
226 if [ $OPT_APPEND -eq 1 -a -f "$OPT_TAGSFILE" ]
228 if [ $OPT_VERBOSE -ne 0 ]
230 printf >&2 ' and existing tags from "%s"\n' "$OPT_TAGSFILE"
233 t=$(printf '%s:A:%05u' "$TMP" $n)
234 sed -e '/^!_TAG_/d' <"$OPT_TAGSFILE" | sort -u >$t
242 sort -m -u $TMP:A:* >$TMP:M
246 if [ x${OPT_TAGSFILE}x = x-x ]
250 if [ $OPT_VERBOSE -ne 0 ]
252 printf >&2 ' into "%s".\n' "$OPT_TAGSFILE"
254 mv -f $TMP:M "$OPT_TAGSFILE"
258 # Generate tags for the current directory.
261 [ -s $TMP:T ] || return 1
265 # Generate tags for the current directory, and report an error if there are
266 # no .td files present.
271 printf >&2 '%s: Nothing to do here.\n' "$SELF"
276 # Generate tags for all .td files under the current directory.
283 # Generate tags for all .td files in LLVM.
286 td_find "$LLVM_SRC_ROOT"
290 # Generate tags for each directory in the worklist $TMP:W.
299 # Find directories containing .td files within the specified directory,
300 # and record them in the worklist $TMP:W.
303 find -L "$1" -type f -name '*.td' |
304 sed -e 's:/[^/]*$::' |
309 # Generate tags for the specified code generator targets, or
310 # if there are no arguments, all targets.
312 cd $LLVM_SRC_ROOT/lib/Target
317 # Check that every specified argument is a target directory;
318 # if not, list all target directories.
321 if [ -d "$d" ] && dir_has_td "$d"
323 printf '%s/%s\n' "$PWD" "$d"
325 printf >&2 '%s: "%s" is not a target. Targets are:\n' "$SELF" "$d"
328 [ -d "$d" ] || continue
329 dir_has_td "$d" && printf >&2 ' %s\n' "$d"
338 # Change to the directory at the top of the enclosing LLVM source tree,
341 while [ "$PWD" != / ]
343 # Use this directory if multiple notable subdirectories are present.
344 [ -d include/llvm -a -d lib/Target ] && return 0
350 # Ensure sort(1) behaves consistently.
365 while getopts 'af:hxqvHI:' opt
372 OPT_TAGSFILE="$OPTARG"
381 OPT_VERBOSE=$((OPT_VERBOSE + 1))
384 printf '%s\n' "$OPTARG" >>$TMP:D
396 shift $((OPTIND - 1))
398 # Handle the case where tdtags is a simple ctags(1)-like wrapper for tblgen.
399 if [ $OPT_RECIPES -eq 0 ]
414 # Find the directory at the top of the enclosing LLVM source tree.
415 if ! LLVM_SRC_ROOT=$(llvm_src_root && pwd)
417 printf >&2 '%s: Run from within the LLVM source tree.\n' "$SELF"
421 # Select canned actions.
444 printf >&2 '%s: Unknown recipe "-x %s". ' "$SELF" "$RECIPE"
446 printf >&2 'Recipes:\n'
448 printf >&2 'Run "%s -H" for help.\n' "$SELF"