1 /*
2  * This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>.
3  * It is copyright by its individual contributors, as recorded in the
4  * project's Git history.  See COPYING.txt at the top level for license
5  * terms and a link to the Git history.
6  */
7 
8 #pragma once
9 #include "dxxsconf.h"
10 
11 /* This header serves several purposes:
12  * - Declare namespace dcx and add it to the list of searched
13  *   namespaces.
14  * - If the compiler can disambiguate a namespace from a class inside a
15  *   searched namespace[1], declare dummy classes scoped so that
16  *   attempting to nest a namespace incorrectly causes a redefinition
17  *   error.  The build would usually fail even without this forced
18  *   check, but the redefinition error forces a clear and immediate
19  *   report.
20  *
21  * If building game-specific code:
22  * - #define dsx to a game-specific namespace: d1x or d2x, as
23  *   appropriate.
24  * - Declare namespace dsx and add it to the list of searched
25  *   namespaces.  When the dsx migration is finished, this `using
26  *   namespace` statement will be removed.
27  * Otherwise:
28  * - Declare dummy class dsx to force a redefinition error on attempts
29  *   to declare `namespace dsx` in common-only code.
30  *
31  * [1] gcc handles this in all tested versions.  There are no known
32  *	clang versions which handle this.  See the SConstruct test for
33  *	DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE for how this is detected.
34  */
35 #if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II)
36 #	if defined(DXX_BUILD_DESCENT_I)
37 #		define dsx d1x
38 #	else
39 #		define dsx d2x
40 #	endif
41 /* The "X declared inside Y" comments are on the same line as their
42  * declaration so that, if the compiler reports a redefinition error,
43  * the output shows the comment, which explains which type of mistake is
44  * being reported.
45  */
46 namespace d1x {	/* Force type mismatch on attempted nesting */
47 #	ifdef DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE
48 	class dcx;	/* dcx declared inside d1x */
49 	class d1x;	/* d1x declared inside d1x */
50 	class d2x;	/* d2x declared inside d1x */
51 #	endif
52 }
53 namespace d2x {	/* Force type mismatch on attempted nesting */
54 #	ifdef DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE
55 	class dcx;	/* dcx declared inside d2x */
56 	class d1x;	/* d1x declared inside d2x */
57 	class d2x;	/* d2x declared inside d2x */
58 #	endif
59 }
60 #ifndef DXX_NO_USING_DSX
61 /* For compatibility during migration, add namespace dsx to the search
62  * list.  This conflicts with the long term goal of the dsx project, but
63  * is currently required for a successful build.
64  *
65  * When working on the dsx project, define this preprocessor symbol on a
66  * file, then fix everything that breaks with that symbol defined.  Move
67  * on to the next file.  When all files build with this symbol set, the
68  * symbol and the using statement can be removed.
69  */
70 using namespace dsx;	// deprecated
71 #endif
72 #else
73 /* This dummy class does not need to be guarded by
74  * DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE because it is declared only
75  * when no other uses of `dsx` are present, so there is no ambiguity for
76  * the compiler to resolve.
77  */
78 class dsx;	/* dsx declared in common-only code */
79 class d1x;	/* d1x declared in common-only code */
80 class d2x;	/* d2x declared in common-only code */
81 #endif
82 
83 #ifdef DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE
84 namespace dcx {	/* Force type mismatch on attempted nesting */
85 	class dcx;	/* dcx declared inside dcx */
86 	class d1x;	/* d1x declared inside dcx */
87 	class d2x;	/* d2x declared inside dcx */
88 }
89 
90 namespace {
91 	class dcx;	/* dcx declared inside anonymous */
92 	class d1x;	/* d1x declared inside anonymous */
93 	class d2x;	/* d2x declared inside anonymous */
94 }
95 #else
96 /* This empty namespace is required because, if
97  * !DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE, then no other declaration
98  * of `namespace dcx` has been seen in this file.
99  */
100 namespace dcx {
101 }
102 #endif
103 
104 using namespace dcx;
105