Introduce macro BORINGSSL_ALWAYS_USE_STATIC_INLINE.

This will control use of `static inline` even when compiling as C++.

This is related to symbol renaming, as `static inline` functions do not
need to be renamed; however it is not recommended to generally use this
in C++, as use of `static inline` functions from `inline` functions
typically violates the ODR. This should unblock use of symbol-renamed
BoringSSL with Swift, as in that configuration all symbols will either
be `static inline` or use the `redefine_extname` mechanism.

(May also want to consider switching to this for Rust)

Bug: 42220000
Change-Id: I63cde49b8e1d20adc1478c53805261086a6a6964
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/89867
Auto-Submit: Rudolf Polzer <rpolzer@google.com>
Reviewed-by: Xiangfei Ding <xfding@google.com>
Commit-Queue: Rudolf Polzer <rpolzer@google.com>
diff --git a/include/openssl/base.h b/include/openssl/base.h
index 36b9051..9954e17 100644
--- a/include/openssl/base.h
+++ b/include/openssl/base.h
@@ -200,13 +200,17 @@
 // not used much in practice, extern inline is tedious, and there are conflicts
 // with the old gnu89 model:
 // https://stackoverflow.com/questions/216510/extern-inline
-#if defined(__cplusplus)
-#define OPENSSL_INLINE inline
-#else
+#if !defined(__cplusplus) && !defined(BORINGSSL_ALWAYS_USE_STATIC_INLINE)
+#define BORINGSSL_ALWAYS_USE_STATIC_INLINE
+#endif
+
+#if defined(BORINGSSL_ALWAYS_USE_STATIC_INLINE)
 // Add OPENSSL_UNUSED so that, should an inline function be emitted via macro
 // (e.g. a |STACK_OF(T)| implementation) in a source file without tripping
 // clang's -Wunused-function.
 #define OPENSSL_INLINE static inline OPENSSL_UNUSED
+#else
+#define OPENSSL_INLINE inline
 #endif
 
 #if defined(__cplusplus)
diff --git a/include/openssl/prefix_symbols.h b/include/openssl/prefix_symbols.h
index 9a6b269..95bf738 100644
--- a/include/openssl/prefix_symbols.h
+++ b/include/openssl/prefix_symbols.h
@@ -6154,6 +6154,8 @@
 
 #endif  // __PRAGMA_REDEFINE_EXTNAME
 
+#if !defined(BORINGSSL_ALWAYS_USE_STATIC_INLINE)
+
 #define CBS_data BORINGSSL_ADD_PREFIX(CBS_data)
 #define CBS_init BORINGSSL_ADD_PREFIX(CBS_init)
 #define CBS_len BORINGSSL_ADD_PREFIX(CBS_len)
@@ -6912,4 +6914,6 @@
 #define sk_void_value BORINGSSL_ADD_PREFIX(sk_void_value)
 #define sk_void_zero BORINGSSL_ADD_PREFIX(sk_void_zero)
 
+#endif  // !BORINGSSL_ALWAYS_USE_STATIC_INLINE
+
 #endif  // OPENSSL_HEADER_PREFIX_SYMBOLS_H
diff --git a/util/pregenerate/build.go b/util/pregenerate/build.go
index 5aa8935..3203f38 100644
--- a/util/pregenerate/build.go
+++ b/util/pregenerate/build.go
@@ -372,25 +372,25 @@
 
 // MakePrefixingIncludes returns the tasks to generate the header files for symbol prefixing.
 func MakePrefixingIncludes(in map[string]InputTarget, targetsOut map[string]build.Target) []*Task {
-	var cHeader, bindgenInclude []byte
+	var syms cSymbolData
 	var err error
 	buildHeadersOnce := func() {
 		var headers []string
 		for _, t := range in {
 			headers = append(headers, t.Hdrs...)
 		}
-		cHeader, bindgenInclude, err = BuildCRenamingIncludes(headers)
+		syms, err = CollectCSymbols(headers)
 	}
 	addGeneratedHeader(targetsOut, "include/openssl/prefix_symbols.h")
 	var once sync.Once
 	return []*Task{
 		NewSimpleTask("prefix_symbols", "include/openssl/prefix_symbols.h", func() ([]byte, error) {
 			once.Do(buildHeadersOnce)
-			return cHeader, err
+			return BuildCRenamingInclude(syms), err
 		}),
 		NewSimpleTask("prefix_symbols", "rust/bssl-sys/boringssl_prefix_symbols_bindgen.rs.in", func() ([]byte, error) {
 			once.Do(buildHeadersOnce)
-			return bindgenInclude, err
+			return BuildBindgenRenamingInclude(syms), err
 		}),
 	}
 }
diff --git a/util/pregenerate/idextractor.go b/util/pregenerate/idextractor.go
index a4dc42c..18e1df4 100644
--- a/util/pregenerate/idextractor.go
+++ b/util/pregenerate/idextractor.go
@@ -52,13 +52,19 @@
 	return strings.TrimSuffix(strings.ToLower(filepath.Base(clang)), ".exe") == "clang-cl", nil
 }
 
-// BuildCRenamingHeader calls Clang to extract the AST of the headers, then processes them to extract the symbols.
+// cSymbolData is data for generating the C renaming includes.
+type cSymbolData struct {
+	inlineDefinitions  map[string]struct{}
+	externDeclarations map[string]struct{}
+}
+
+// CollectCSymbols calls Clang to extract the AST of the headers, then processes them to extract the symbols.
 //
-// It returns a header for C and a matching one for Rust's bindgen.
-func BuildCRenamingIncludes(headers []string) (cHeader []byte, bindgenInclude []byte, err error) {
+// It returns data for generating C and Rust includes.
+func CollectCSymbols(headers []string) (syms cSymbolData, err error) {
 	cmd := *clangPath
 	if cmd == "" {
-		return nil, nil, fmt.Errorf("%w: clang has been disabled by flag", TaskSkipped)
+		return cSymbolData{}, fmt.Errorf("%w: clang has been disabled by flag", TaskSkipped)
 	}
 
 	defer func() {
@@ -69,7 +75,7 @@
 
 	isCL, err := isClangCL(cmd)
 	if err != nil {
-		return nil, nil, err
+		return cSymbolData{}, err
 	}
 
 	var args []string
@@ -106,23 +112,23 @@
 
 	stdout, err := c.StdoutPipe()
 	if err != nil {
-		return nil, nil, err
+		return cSymbolData{}, err
 	}
 	defer stdout.Close()
 
 	err = c.Start()
 	if err != nil {
-		return nil, nil, err
+		return cSymbolData{}, err
 	}
 
-	var viaRedefineExtname = map[string]struct{}{}
+	syms.externDeclarations = map[string]struct{}{}
 	for _, sym := range platformDependentRedefineExtnameSymbols {
-		viaRedefineExtname[sym] = struct{}{}
+		syms.externDeclarations[sym] = struct{}{}
 	}
 
-	var viaMacro = map[string]struct{}{}
+	syms.inlineDefinitions = map[string]struct{}{}
 	for _, sym := range platformDependentMacroSymbols {
-		viaMacro[sym] = struct{}{}
+		syms.inlineDefinitions[sym] = struct{}{}
 	}
 
 	report := func(id idextractor.IdentifierInfo) error {
@@ -136,7 +142,7 @@
 			// Already in a namespace.
 			return nil
 		}
-		canRedefineExtname := true
+		var isInline bool
 		switch id.Linkage {
 		case "", "static", "static inline":
 			// Definitely not linked.
@@ -144,9 +150,10 @@
 		case `extern "C" inline`, `extern "C++" inline`:
 			// Sorry, can't redefine_extname inline functions:
 			// error: #pragma redefine_extname is applicable to external C declarations only; not applied to function
-			canRedefineExtname = false
+			isInline = true
 		case `extern "C"`:
 			// Link those.
+			isInline = false
 		default:
 			return fmt.Errorf("unexpected linkage: %q", id.Linkage)
 		}
@@ -159,10 +166,10 @@
 			// however cannot be namespaced as known callers forward declare them.
 			return nil
 		case "function", "var":
-			if canRedefineExtname {
-				viaRedefineExtname[id.Symbol] = struct{}{}
+			if isInline {
+				syms.inlineDefinitions[id.Symbol] = struct{}{}
 			} else {
-				viaMacro[id.Symbol] = struct{}{}
+				syms.externDeclarations[id.Symbol] = struct{}{}
 			}
 			return nil
 		default:
@@ -170,26 +177,30 @@
 		}
 	}
 
-	for sym := range viaMacro {
-		if _, found := viaRedefineExtname[sym]; found {
-			return nil, nil, fmt.Errorf("symbol %q both marked for macro and redefine_extname renaming; please fix", sym)
+	for sym := range syms.inlineDefinitions {
+		if _, found := syms.externDeclarations[sym]; found {
+			return cSymbolData{}, fmt.Errorf("symbol %q both marked as extern and inline type symbol renaming; please fix", sym)
 		}
 	}
 
 	err = idextractor.New(report, idextractor.Options{Language: "C++"}).Parse(stdout)
 	if err != nil {
 		c.Process.Kill()
-		return nil, nil, err
+		return cSymbolData{}, err
 	}
 
 	err = c.Wait()
 	if err != nil {
-		return nil, nil, err
+		return cSymbolData{}, err
 	}
 
-	var cOutput bytes.Buffer
-	writeHeader(&cOutput, "//")
-	cOutput.WriteString(`
+	return syms, nil
+}
+
+func BuildCRenamingInclude(syms cSymbolData) []byte {
+	var output bytes.Buffer
+	writeHeader(&output, "//")
+	output.WriteString(`
 #ifndef OPENSSL_HEADER_PREFIX_SYMBOLS_H
 #define OPENSSL_HEADER_PREFIX_SYMBOLS_H
 
@@ -207,33 +218,40 @@
 #endif  // __APPLE__
 
 `)
-	cOutput.WriteString("#if defined(__PRAGMA_REDEFINE_EXTNAME)\n")
-	cOutput.WriteString("\n")
-	for _, sym := range slices.Sorted(maps.Keys(viaRedefineExtname)) {
-		fmt.Fprintf(&cOutput, "#pragma redefine_extname %s BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(%s))\n", sym, sym)
+	output.WriteString("#if defined(__PRAGMA_REDEFINE_EXTNAME)\n")
+	output.WriteString("\n")
+	for _, sym := range slices.Sorted(maps.Keys(syms.externDeclarations)) {
+		fmt.Fprintf(&output, "#pragma redefine_extname %s BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(%s))\n", sym, sym)
 	}
-	cOutput.WriteString("\n")
-	cOutput.WriteString("#else  // __PRAGMA_REDEFINE_EXTNAME\n")
-	cOutput.WriteString("\n")
-	for _, sym := range slices.Sorted(maps.Keys(viaRedefineExtname)) {
-		fmt.Fprintf(&cOutput, "#define %s BORINGSSL_ADD_PREFIX(%s)\n", sym, sym)
+	output.WriteString("\n")
+	output.WriteString("#else  // __PRAGMA_REDEFINE_EXTNAME\n")
+	output.WriteString("\n")
+	for _, sym := range slices.Sorted(maps.Keys(syms.externDeclarations)) {
+		fmt.Fprintf(&output, "#define %s BORINGSSL_ADD_PREFIX(%s)\n", sym, sym)
 	}
-	cOutput.WriteString("\n")
-	cOutput.WriteString("#endif  // __PRAGMA_REDEFINE_EXTNAME\n")
-	cOutput.WriteString("\n")
-	for _, sym := range slices.Sorted(maps.Keys(viaMacro)) {
-		fmt.Fprintf(&cOutput, "#define %s BORINGSSL_ADD_PREFIX(%s)\n", sym, sym)
+	output.WriteString("\n")
+	output.WriteString("#endif  // __PRAGMA_REDEFINE_EXTNAME\n")
+	output.WriteString("\n")
+	output.WriteString("#if !defined(BORINGSSL_ALWAYS_USE_STATIC_INLINE)\n")
+	output.WriteString("\n")
+	for _, sym := range slices.Sorted(maps.Keys(syms.inlineDefinitions)) {
+		fmt.Fprintf(&output, "#define %s BORINGSSL_ADD_PREFIX(%s)\n", sym, sym)
 	}
-	cOutput.WriteString(`
+	output.WriteString("\n")
+	output.WriteString("#endif  // !BORINGSSL_ALWAYS_USE_STATIC_INLINE\n")
+	output.WriteString(`
 #endif  // OPENSSL_HEADER_PREFIX_SYMBOLS_H
 `)
+	return output.Bytes()
+}
 
-	var bindgenOutput bytes.Buffer
-	writeHeader(&bindgenOutput, "//")
-	bindgenOutput.WriteString("\n")
-	for _, sym := range slices.Sorted(maps.Keys(viaMacro)) {
-		fmt.Fprintf(&bindgenOutput, "pub use ${BORINGSSL_PREFIX}_%s as %s;\n", sym, sym)
+func BuildBindgenRenamingInclude(syms cSymbolData) []byte {
+	var output bytes.Buffer
+	writeHeader(&output, "//")
+	output.WriteString("\n")
+	for _, sym := range slices.Sorted(maps.Keys(syms.inlineDefinitions)) {
+		fmt.Fprintf(&output, "pub use ${BORINGSSL_PREFIX}_%s as %s;\n", sym, sym)
 	}
 
-	return cOutput.Bytes(), bindgenOutput.Bytes(), nil
+	return output.Bytes()
 }