3535
3636COMMON_HEADER = PurePosixPath ("__llvm-libc-common.h" )
3737
38+ # These "attributes" are known macros defined in COMMON_HEADER.
39+ # Others are found in "llvm-libc-macros/{name}.h".
40+ COMMON_ATTRIBUTES = {
41+ "_Noreturn" ,
42+ "_Returns_twice" ,
43+ }
44+
3845# All the canonical identifiers are in lowercase for easy maintenance.
3946# This maps them to the pretty descriptions to generate in header comments.
4047LIBRARY_DESCRIPTIONS = {
5057HEADER_TEMPLATE = """\
5158 //===-- {library} header <{header}> --===//
5259//
53- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
54- // See https://llvm.org/LICENSE.txt for license information.
55- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60+ {license_lines}
5661//
5762//===---------------------------------------------------------------------===//
5863
6469#endif // {guard}
6570"""
6671
72+ LLVM_LICENSE_TEXT = [
73+ "Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions." ,
74+ "See https://llvm.org/LICENSE.txt for license information." ,
75+ "SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception" ,
76+ ]
77+
6778
6879class HeaderFile :
6980 def __init__ (self , name ):
@@ -74,8 +85,10 @@ def __init__(self, name):
7485 self .enumerations = []
7586 self .objects = []
7687 self .functions = []
88+ self .extra_standards = {}
7789 self .standards = []
7890 self .merge_yaml_files = []
91+ self .license_text = []
7992
8093 def add_macro (self , macro ):
8194 self .macros .append (macro )
@@ -98,6 +111,11 @@ def merge(self, other):
98111 self .enumerations = sorted (set (self .enumerations ) | set (other .enumerations ))
99112 self .objects = sorted (set (self .objects ) | set (other .objects ))
100113 self .functions = sorted (set (self .functions ) | set (other .functions ))
114+ self .extra_standards |= other .extra_standards
115+ if self .license_text :
116+ assert not other .license_text , "only one `license_text` allowed"
117+ else :
118+ self .license_text = other .license_text
101119
102120 def all_types (self ):
103121 return reduce (
@@ -106,6 +124,13 @@ def all_types(self):
106124 set (self .types ),
107125 )
108126
127+ def all_attributes (self ):
128+ return reduce (
129+ lambda a , b : a | b ,
130+ [set (f .attributes ) for f in self .functions ],
131+ set (),
132+ )
133+
109134 def all_standards (self ):
110135 # FIXME: Only functions have the "standard" field, but all the entity
111136 # types should have one too.
@@ -114,41 +139,54 @@ def all_standards(self):
114139 )
115140
116141 def includes (self ):
117- return {
118- PurePosixPath ("llvm-libc-macros" ) / macro .header
119- for macro in self .macros
120- if macro .header is not None
121- } | {
122- COMPILER_HEADER_TYPES .get (
123- typ .type_name , PurePosixPath ("llvm-libc-types" ) / f"{ typ .type_name } .h"
124- )
125- for typ in self .all_types ()
126- }
142+ return (
143+ {
144+ PurePosixPath ("llvm-libc-macros" ) / macro .header
145+ for macro in self .macros
146+ if macro .header is not None
147+ }
148+ | {
149+ COMPILER_HEADER_TYPES .get (
150+ typ .type_name ,
151+ PurePosixPath ("llvm-libc-types" ) / f"{ typ .type_name } .h" ,
152+ )
153+ for typ in self .all_types ()
154+ }
155+ | {
156+ PurePosixPath ("llvm-libc-macros" ) / f"{ attr } .h"
157+ for attr in self .all_attributes () - COMMON_ATTRIBUTES
158+ }
159+ )
127160
128161 def header_guard (self ):
129162 return "_LLVM_LIBC_" + "_" .join (
130163 word .upper () for word in NONIDENTIFIER .split (self .name ) if word
131164 )
132165
133166 def library_description (self ):
167+ descriptions = LIBRARY_DESCRIPTIONS | self .extra_standards
134168 # If the header itself is in standard C, just call it that.
135169 if "stdc" in self .standards :
136- return LIBRARY_DESCRIPTIONS ["stdc" ]
170+ return descriptions ["stdc" ]
137171 # If the header itself is in POSIX, just call it that.
138172 if "posix" in self .standards :
139- return LIBRARY_DESCRIPTIONS ["posix" ]
173+ return descriptions ["posix" ]
140174 # Otherwise, consider the standards for each symbol as well.
141175 standards = self .all_standards ()
142176 # Otherwise, it's described by all those that apply, but ignoring
143177 # "stdc" and "posix" since this is not a "stdc" or "posix" header.
144178 return " / " .join (
145179 sorted (
146- LIBRARY_DESCRIPTIONS [standard ]
180+ descriptions [standard ]
147181 for standard in standards
148182 if standard not in {"stdc" , "posix" }
149183 )
150184 )
151185
186+ def license_lines (self ):
187+ lines = self .license_text or LLVM_LICENSE_TEXT
188+ return "\n " .join ([f"// { line } " for line in lines ])
189+
152190 def template (self , dir , files_read ):
153191 if self .template_file is not None :
154192 # There's a custom template file, so just read it in and record
@@ -162,6 +200,7 @@ def template(self, dir, files_read):
162200 library = self .library_description (),
163201 header = self .name ,
164202 guard = self .header_guard (),
203+ license_lines = self .license_lines (),
165204 )
166205
167206 def public_api (self ):
0 commit comments