[libc] Switch to using the generic `<gpuintrin.h>` implementations (#121810)
[llvm-project.git] / openmp / runtime / tools / generate-def.py
blob6781fe74fdc17b6ef5c5a1ae464d15ffd845aae2
1 #!/usr/bin/env python3
4 # //===----------------------------------------------------------------------===//
5 # //
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
9 # //
10 # //===----------------------------------------------------------------------===//
13 import argparse
14 import os
15 import re
16 import sys
17 from libomputils import error, ScriptError, print_error_line
20 class DllExports(object):
21 def __init__(self):
22 self.filename = None
23 self.exports = {}
24 self.ordinals = set([])
26 def add_uppercase_entries(self):
27 # Ignored entries are C/C++ only functions
28 ignores = [
29 "omp_alloc",
30 "omp_free",
31 "omp_calloc",
32 "omp_realloc",
33 "omp_aligned_alloc",
34 "omp_aligned_calloc",
36 keys = list(self.exports.keys())
37 for entry in keys:
38 info = self.exports[entry]
39 if info["obsolete"] or info["is_data"] or entry in ignores:
40 continue
41 if entry.startswith("omp_") or entry.startswith("kmp_"):
42 newentry = entry.upper()
43 if info["ordinal"]:
44 newordinal = info["ordinal"] + 1000
45 else:
46 newordinal = None
47 self.exports[newentry] = {
48 "obsolete": False,
49 "is_data": False,
50 "ordinal": newordinal,
53 @staticmethod
54 def create(inputFile, defs=None):
55 """Creates DllExports object from inputFile"""
56 dllexports = DllExports()
57 dllexports.filename = inputFile
58 # Create a (possibly empty) list of definitions
59 if defs:
60 definitions = set(list(defs))
61 else:
62 definitions = set([])
63 # Different kinds of lines to parse
64 kw = r"[a-zA-Z_][a-zA-Z0-9_]*"
65 ifndef = re.compile(r"%ifndef\s+({})".format(kw))
66 ifdef = re.compile(r"%ifdef\s+({})".format(kw))
67 endif = re.compile(r"%endif")
68 export = re.compile(r"(-)?\s*({0})(=({0}))?(\s+([0-9]+|DATA))?".format(kw))
70 def err(fil, num, msg):
71 error("{}: {}: {}".format(fil, num, msg))
73 defs_stack = []
74 with open(inputFile) as f:
75 for lineNumber, line in enumerate(f):
76 line = line.strip()
77 # Skip empty lines
78 if not line:
79 continue
80 # Skip comment lines
81 if line.startswith("#"):
82 continue
83 # Encountered %ifndef DEF
84 m = ifndef.search(line)
85 if m:
86 defs_stack.append(m.group(1) not in definitions)
87 continue
88 # Encountered %ifdef DEF
89 m = ifdef.search(line)
90 if m:
91 defs_stack.append(m.group(1) in definitions)
92 continue
93 # Encountered %endif
94 m = endif.search(line)
95 if m:
96 if not defs_stack:
97 err(inputFile, lineNumber, "orphan %endif directive")
98 defs_stack.pop()
99 continue
100 # Skip lines when not all %ifdef or %ifndef are true
101 if defs_stack and not all(defs_stack):
102 continue
103 # Encountered an export line
104 m = export.search(line)
105 if m:
106 obsolete = m.group(1) is not None
107 entry = m.group(2)
108 rename = m.group(4)
109 ordinal = m.group(6)
110 if entry in dllexports.exports:
111 err(
112 inputFile,
113 lineNumber,
114 "already specified entry: {}".format(entry),
116 if rename:
117 entry += "={}".format(rename)
118 # No ordinal number nor DATA specified
119 if not ordinal:
120 ordinal = None
121 is_data = False
122 # DATA ordinal
123 elif ordinal == "DATA":
124 ordinal = None
125 is_data = True
126 # Regular ordinal number
127 else:
128 is_data = False
129 try:
130 ordinal = int(ordinal)
131 except:
132 err(
133 inputFile,
134 lineNumber,
135 "Bad ordinal value: {}".format(ordinal),
137 if ordinal >= 1000 and (
138 entry.startswith("omp_") or entry.startswith("kmp_")
140 err(
141 inputFile,
142 lineNumber,
143 "Ordinal of user-callable entry must be < 1000",
145 if ordinal >= 1000 and ordinal < 2000:
146 err(
147 inputFile,
148 lineNumber,
149 "Ordinals between 1000 and 1999 are reserved.",
151 if ordinal in dllexports.ordinals:
152 err(
153 inputFile,
154 lineNumber,
155 "Ordinal {} has already been used.".format(ordinal),
157 dllexports.exports[entry] = {
158 "ordinal": ordinal,
159 "obsolete": obsolete,
160 "is_data": is_data,
162 continue
163 err(
164 inputFile,
165 lineNumber,
166 'Cannot parse line:{}"{}"'.format(os.linesep, line),
168 if defs_stack:
169 error("syntax error: Unterminated %if directive")
170 return dllexports
173 def generate_def(dllexports, f, no_ordinals=False, name=None):
174 """Using dllexports data, write the exports to file, f"""
175 if name:
176 f.write("LIBRARY {}\n".format(name))
177 f.write("EXPORTS\n")
178 for entry in sorted(list(dllexports.exports.keys())):
179 info = dllexports.exports[entry]
180 if info["obsolete"]:
181 continue
182 f.write(" {:<40} ".format(entry))
183 if info["is_data"]:
184 f.write("DATA\n")
185 elif no_ordinals or not info["ordinal"]:
186 f.write("\n")
187 else:
188 f.write("@{}\n".format(info["ordinal"]))
191 def main():
192 parser = argparse.ArgumentParser(
193 description="Reads input file of dllexports, processes conditional"
194 " directives, checks content for consistency, and generates"
195 " output file suitable for linker"
197 parser.add_argument(
198 "-D",
199 metavar="DEF",
200 action="append",
201 dest="defs",
202 help="Define a variable. Can specify" " this more than once.",
204 parser.add_argument(
205 "--no-ordinals",
206 action="store_true",
207 help="Specify that no ordinal numbers should be generated",
209 parser.add_argument(
210 "-n",
211 "--name",
212 dest="name",
213 help="Specify library name for def file LIBRARY statement",
215 parser.add_argument(
216 "-o",
217 "--output",
218 metavar="FILE",
219 dest="output",
220 help="Specify output file name. If not specified," " output is sent to stdout",
222 parser.add_argument("dllexports", help="The input file describing dllexports")
223 commandArgs = parser.parse_args()
224 defs = set([])
225 if commandArgs.defs:
226 defs = set(commandArgs.defs)
227 dllexports = DllExports.create(commandArgs.dllexports, defs)
228 dllexports.add_uppercase_entries()
229 try:
230 output = open(commandArgs.output, "w") if commandArgs.output else sys.stdout
231 generate_def(dllexports, output, commandArgs.no_ordinals, commandArgs.name)
232 finally:
233 if commandArgs.output:
234 output.close()
237 if __name__ == "__main__":
238 try:
239 main()
240 except ScriptError as e:
241 print_error_line(str(e))
242 sys.exit(1)
244 # end of file