-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][AST] fix ast-print of extern <lang>
with >=2 declarators
#93131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write If you have received no comments on your PR for a week, you can request a review If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-clang Author: Artem Yurchenko (temyurchenko) ChangesProblem: the printer used to ignore all but the first declarator for unbraced language linkage declarators. Furthemore, that one would be printed without the final semicolon. Solution: when there is more than one declarator, we print them in a braced N.B. We are printing braces which were, in some cases, absent from the original CST. If that's an issue, I'll work on it. See the tests for the examples. Full diff: https://github.com/llvm/llvm-project/pull/93131.diff 2 Files Affected:
diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp
index 0cf4e64f83b8d..369dfffe58667 100644
--- a/clang/lib/AST/DeclPrinter.cpp
+++ b/clang/lib/AST/DeclPrinter.cpp
@@ -1145,13 +1145,15 @@ void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
l = "C++";
}
+ bool HasMoreThanOneDecl =
+ *D->decls_begin() && D->decls_begin()->getNextDeclInContext();
Out << "extern \"" << l << "\" ";
- if (D->hasBraces()) {
+ if (D->hasBraces() || HasMoreThanOneDecl) {
Out << "{\n";
VisitDeclContext(D);
Indent() << "}";
} else
- Visit(*D->decls_begin());
+ VisitDeclContext(D);
}
void DeclPrinter::printTemplateParameters(const TemplateParameterList *Params,
diff --git a/clang/test/AST/ast-print-language-linkage.cpp b/clang/test/AST/ast-print-language-linkage.cpp
new file mode 100644
index 0000000000000..4998a62f280b5
--- /dev/null
+++ b/clang/test/AST/ast-print-language-linkage.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -ast-print %s -o - | FileCheck %s
+
+// CHECK: extern "C" int printf(const char *, ...);
+extern "C" int printf(const char *...);
+
+// CHECK: extern "C++" {
+// CHECK-NEXT: int f(int);
+// CHECK-NEXT: int g(int);
+// CHECK-NEXT: }
+extern "C++" int f(int), g(int);
+
+// CHECK: extern "C" {
+// CHECK-NEXT: void foo();
+// CHECK-NEXT: int x;
+// CHECK-NEXT: int y;
+// CHECK-NEXT: }
+extern "C" {
+ void foo(void);
+ int x, y;
+}
+
+// CHECK: extern "C" {
+// CHECK-NEXT: }
+extern "C" {}
+
+// CHECK: extern "C++" ;
+extern "C++";
|
Fixes #93085 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we're going to be printing incorrect code either way, but with this patch, we're more likely to be closer to the original intent of the code than without the patch. So even though this isn't perfect, it's forward progress and I think we're fine to land it as-is. However, if we can fix it correctly, that would be preferred.
3e19f75
to
ae5225a
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
0fd91ab
to
a8f1503
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm in favor, let aaron take a look, else LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM aside from some coding style nits. Because AST printing is not part of the public interface for Clang, I don't think these changes need a release note.
Problem: the printer used to ignore all but the first declarator for unbraced language linkage declarators. Furthemore, that one would be printed without the final semicolon. Solution: for unbraced case we traverse all declarators via `VisitDeclContext`. Furthermore, in appropriate visitors we query for whether they are a part of the unbraced extern language linkage spec, and if so, print appropriately.
What should be the next step following the approvals? |
If you do not have 'squash and merge' rights here, one of us can do it for you once testing completes. |
I don't have them, would be glad if you could do that! |
@temyurchenko Congratulations on having your first Pull Request (PR) merged into the LLVM Project! Your changes will be combined with recent changes from other authors, then tested Please check whether problems have been caused by your change specifically, as How to do this, and the rest of the post-merge process, is covered in detail here. If your change does cause a problem, it may be reverted, or you can revert it yourself. If you don't get any reports, no action is required from you. Your changes are working as expected, well done! |
We started seeing an lldb test failure, and I bisected to this commit:
|
I see the source of the issue, I'm thinking how to address it best. If it's urgent, I can produce an urgent fix. |
Can you please revert it in the meantime because it is breaking our builders? Instead of a quick fix, I recommend a revert and a reland with a fix. I can help you to verify whether it actually fixes the issue in our builders. |
Unfortunately, I don't have the right to revert. |
…ators" (#93912) Reverts #93131 because it broke some lldb tests on the Fuchsia Clang toolchain builders. https://ci.chromium.org/ui/p/fuchsia/builders/toolchain.ci/clang-linux-x64/b8746482644341901905/infra
No worries, and I reverted it for you. When you have the fix ready, I'm happy to verify it on our builders before you reland. |
Can you also reopen this PR, please? For documentation/history reasons, it's probably better to provide a fix within the scope of this PR. |
I don't think our github is configured to allow that. You'll have to start a new PR. |
…lvm#93131) Problem: the printer used to ignore all but the first declarator for unbraced language linkage declarators. Furthemore, that one would be printed without the final semicolon. Solution: when there is more than one declarator, we print them in a braced `extern <lang>` block. If the original declaration was unbraced and there is one or less declarator, we omit the braces, but add the semicolon. **N.B.** We are printing braces which were, in some cases, absent from the original CST. If that's an issue, I'll work on it. See the tests for the examples.
…lvm#93131) Problem: the printer used to ignore all but the first declarator for unbraced language linkage declarators. Furthemore, that one would be printed without the final semicolon. Solution: for unbraced case we traverse all declarators via `VisitDeclContext`. Furthermore, in appropriate visitors we query for whether they are a part of the unbraced extern language linkage spec, and if so, print appropriately.
Problem: the printer used to ignore all but the first declarator for unbraced language linkage declarators. Furthemore, that one would be printed without the final semicolon.
Solution: when there is more than one declarator, we print them in a braced
extern <lang>
block. If the original declaration was unbraced and there is one or less declarator, we omit the braces, but add the semicolon.N.B. We are printing braces which were, in some cases, absent from the original CST. If that's an issue, I'll work on it. See the tests for the examples.