@@ -274,15 +274,30 @@ void DeclRewriter::denestTagDecls() {
274
274
std::string DefinitionStr = R.getRewrittenText (CSR);
275
275
// Delete the definition from the old location.
276
276
rewriteSourceRange (R, CSR, " " );
277
- // We want to insert RD as a new child of its original semantic DeclContext,
278
- // just before the existing child of that DeclContext of which RD was
279
- // originally a descendant.
280
- DeclContext *TopChild = TD;
281
- while (TopChild->getLexicalParent () != TD->getDeclContext ()) {
282
- TopChild = TopChild->getLexicalParent ();
277
+ // We want to find the nearest ancestor DeclContext of TD that is _not_ a
278
+ // TagDecl and make TD a child of that DeclContext (named `Parent` below),
279
+ // just before the child `TopTagDecl` of `Parent` of which TD was originally
280
+ // a descendant.
281
+ //
282
+ // As of this writing, it seems that if TD is named, we get
283
+ // `Parent == TD->getDeclContext()` due to the code at
284
+ // https://github.com/correctcomputation/checkedc-clang/blob/fd4d8af4383d40af10ee8bc92b7bf88061a11035/clang/lib/Sema/SemaDecl.cpp#L16980-L16981,
285
+ // But that code doesn't run if TD is unnamed (which makes some sense
286
+ // because name visibility isn't an issue for TagDecls that have no name),
287
+ // and we want to de-nest TagDecls with names we assigned just like ones
288
+ // that were originally named, so we can't just use `TD->getDeclContext()`.
289
+ // In any event, maybe we wouldn't want to rely on this kind of internal
290
+ // Clang behavior.
291
+ DeclContext *TopTagDecl = TD;
292
+ for (;;) {
293
+ DeclContext *Parent = TopTagDecl->getLexicalParent ();
294
+ if (!isa<TagDecl>(Parent))
295
+ break ;
296
+ TopTagDecl = Parent;
283
297
}
284
- // TODO: Use a wrapper like rewriteSourceRange.
285
- R.InsertText (cast<Decl>(TopChild)->getBeginLoc (), DefinitionStr);
298
+ // TODO: Use a wrapper like rewriteSourceRange that tries harder with
299
+ // macros, reports failure, etc.
300
+ R.InsertText (cast<Decl>(TopTagDecl)->getBeginLoc (), DefinitionStr);
286
301
}
287
302
}
288
303
@@ -332,8 +347,8 @@ void DeclRewriter::rewriteMultiDecl(MultiDeclInfo &MDI, RSet &ToRewrite) {
332
347
llvm_unreachable (" Failed to find place to insert assigned TagDecl name." );
333
348
}
334
349
}
335
- // Make a note if the RecordDecl needs to be de-nested later.
336
- if (TD-> getLexicalDeclContext () != TD->getDeclContext ( ))
350
+ // Make a note if the TagDecl needs to be de-nested later.
351
+ if (isa<TagDecl>( TD->getLexicalDeclContext () ))
337
352
TagDeclsToDenest.push_back (TD);
338
353
// `struct T { ... } foo;` -> `struct T { ... };\nfoo;`
339
354
rewriteSourceRange (R, TD->getEndLoc (), " };\n " );
0 commit comments