@@ -97,6 +97,48 @@ PushNextNodeId(uint32_t &NodeId, ReflectionData &Refl, const SourceManager &SM,
9797 if (LocalId >= (1u << 24 ))
9898 return HLSL_REFL_ERR (" LocalId overflow" );
9999
100+ bool isFwdDeclare = false ;
101+ bool canHaveFwdDeclare = false ;
102+ const Decl *fwdDeclare = nullptr ;
103+
104+ if (DeclSelf) {
105+
106+ if (const FunctionDecl *func = dyn_cast<FunctionDecl>(DeclSelf)) {
107+ isFwdDeclare = !func->doesThisDeclarationHaveABody ();
108+ fwdDeclare = func->getCanonicalDecl ();
109+ canHaveFwdDeclare = true ;
110+ }
111+
112+ else if (const EnumDecl *enm = dyn_cast<EnumDecl>(DeclSelf)) {
113+ isFwdDeclare = !enm->isCompleteDefinition ();
114+ fwdDeclare = enm->getCanonicalDecl ();
115+ canHaveFwdDeclare = true ;
116+ }
117+
118+ else if (const RecordDecl *rec = dyn_cast<RecordDecl>(DeclSelf)) {
119+
120+ isFwdDeclare = !rec->isThisDeclarationADefinition ();
121+ fwdDeclare = rec->getCanonicalDecl ();
122+ canHaveFwdDeclare = true ;
123+
124+ if (isFwdDeclare && rec->isImplicit ()) { // Inner ghost node
125+ NodeId = uint32_t (-1 );
126+ return ReflectionErrorSuccess;
127+ }
128+ }
129+ }
130+
131+ // There is a forward declare, but we haven't seen it before.
132+ // This happens for example if we have a fwd func declare in a struct, but define it in global namespace.
133+ // (only) -reflect-function will hide this struct from us, but will still find a function in the global scope.
134+ // This fixes that problem.
135+
136+ if (!isFwdDeclare && fwdDeclare && fwdDeclare != DeclSelf &&
137+ FwdDecls->find (fwdDeclare) == FwdDecls->end ()) {
138+ NodeId = uint32_t (-1 );
139+ return ReflectionErrorSuccess;
140+ }
141+
100142 uint32_t nodeId = Refl.Nodes .size ();
101143
102144 uint16_t annotationStart = uint16_t (Refl.Annotations .size ());
@@ -179,37 +221,6 @@ PushNextNodeId(uint32_t &NodeId, ReflectionData &Refl, const SourceManager &SM,
179221
180222 D3D_INTERPOLATION_MODE interpolationMode = GetInterpolationMode (DeclSelf);
181223
182- bool isFwdDeclare = false ;
183- bool canHaveFwdDeclare = false ;
184- const Decl *fwdDeclare = nullptr ;
185-
186- if (DeclSelf) {
187-
188- if (const FunctionDecl *func = dyn_cast<FunctionDecl>(DeclSelf)) {
189- isFwdDeclare = !func->doesThisDeclarationHaveABody ();
190- fwdDeclare = func->getCanonicalDecl ();
191- canHaveFwdDeclare = true ;
192- }
193-
194- else if (const EnumDecl *enm = dyn_cast<EnumDecl>(DeclSelf)) {
195- isFwdDeclare = !enm->isCompleteDefinition ();
196- fwdDeclare = enm->getCanonicalDecl ();
197- canHaveFwdDeclare = true ;
198- }
199-
200- else if (const RecordDecl *rec = dyn_cast<RecordDecl>(DeclSelf)) {
201-
202- isFwdDeclare = !rec->isThisDeclarationADefinition ();
203- fwdDeclare = rec->getCanonicalDecl ();
204- canHaveFwdDeclare = true ;
205-
206- if (isFwdDeclare && rec->isImplicit ()) { // Inner ghost node
207- NodeId = uint32_t (-1 );
208- return ReflectionErrorSuccess;
209- }
210- }
211- }
212-
213224 uint32_t currId = uint32_t (Refl.Nodes .size ());
214225
215226 if (canHaveFwdDeclare) {
0 commit comments