-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[clang][TableGen] Fix Duplicate Entries in TableGen #140828
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
Changes from 4 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| // RUN: %clang_cc1 -triple riscv64 -ast-dump -ast-dump-filter c23 -std=c23 -x c %s | FileCheck --strict-whitespace %s | ||
|
|
||
| // CHECK: FunctionDecl{{.*}}pre_c23 | ||
| // CHECK-NEXT: |-CompoundStmt | ||
| // CHECK-NEXT: `-RISCVInterruptAttr{{.*}}supervisor | ||
| __attribute__((interrupt("supervisor"))) void pre_c23(){} | ||
|
|
||
| // CHECK: FunctionDecl{{.*}}in_c23 | ||
| // CHECK-NEXT: |-CompoundStmt | ||
| // CHECK-NEXT: `-RISCVInterruptAttr{{.*}}supervisor | ||
| // CHECK-NOT: `-RISCVInterruptAttr{{.*}}machine | ||
| [[gnu::interrupt("supervisor")]] void in_c23(){} | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -20,6 +20,7 @@ | |||||||||||||||||||
| #include "llvm/ADT/STLExtras.h" | ||||||||||||||||||||
| #include "llvm/ADT/SmallString.h" | ||||||||||||||||||||
| #include "llvm/ADT/StringExtras.h" | ||||||||||||||||||||
| #include "llvm/ADT/StringMap.h" | ||||||||||||||||||||
| #include "llvm/ADT/StringRef.h" | ||||||||||||||||||||
| #include "llvm/ADT/StringSwitch.h" | ||||||||||||||||||||
| #include "llvm/Support/ErrorHandling.h" | ||||||||||||||||||||
|
|
@@ -3667,6 +3668,12 @@ static bool GenerateTargetSpecificAttrChecks(const Record *R, | |||||||||||||||||||
| static void GenerateHasAttrSpellingStringSwitch( | ||||||||||||||||||||
| ArrayRef<std::pair<const Record *, FlattenedSpelling>> Attrs, | ||||||||||||||||||||
| raw_ostream &OS, StringRef Variety, StringRef Scope = "") { | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // It turns out that there are duplicate records for a given spelling. This | ||||||||||||||||||||
| // map combines matching test strings using '||'. For example, if there are | ||||||||||||||||||||
| // three conditions A, B, and C, the final result will be: A || B || C. | ||||||||||||||||||||
| llvm::StringMap<std::string> TestStringMap; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| for (const auto &[Attr, Spelling] : Attrs) { | ||||||||||||||||||||
| // C++11-style attributes have specific version information associated with | ||||||||||||||||||||
| // them. If the attribute has no scope, the version information must not | ||||||||||||||||||||
|
|
@@ -3727,12 +3734,26 @@ static void GenerateHasAttrSpellingStringSwitch( | |||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| std::string TestStr = !Test.empty() | ||||||||||||||||||||
| ? Test + " ? " + itostr(Version) + " : 0" | ||||||||||||||||||||
| : itostr(Version); | ||||||||||||||||||||
| if (Scope.empty() || Scope == Spelling.nameSpace()) | ||||||||||||||||||||
| OS << " .Case(\"" << Spelling.name() << "\", " << TestStr << ")\n"; | ||||||||||||||||||||
| std::string TestStr = | ||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you share a before/after generated file so that I can take a look? I'm having a hard time visualizing what this does.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Before: https://pastebin.com/iwkWd3Bf
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Take the This is the original string: The problem is that there are multiple of them for a single attribute, such as Meaning that, we used to get: This is the new one So now we have a single case statement instead,
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it, thank you for that! |
||||||||||||||||||||
| !Test.empty() ? '(' + Test + " ? " + itostr(Version) + " : 0" + ')' | ||||||||||||||||||||
| : '(' + itostr(Version) + ')'; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if (Scope.empty() || Scope == Spelling.nameSpace()) { | ||||||||||||||||||||
| if (TestStringMap.contains(Spelling.name())) { | ||||||||||||||||||||
| TestStringMap[Spelling.name()] += " || " + TestStr; | ||||||||||||||||||||
| } else { | ||||||||||||||||||||
| TestStringMap[Spelling.name()] = TestStr; | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
||||||||||||||||||||
| if (TestStringMap.contains(Spelling.name())) { | |
| TestStringMap[Spelling.name()] += " || " + TestStr; | |
| } else { | |
| TestStringMap[Spelling.name()] = TestStr; | |
| } | |
| if (TestStringMap.contains(Spelling.name())) | |
| TestStringMap[Spelling.name()] += " || " + TestStr; | |
| else | |
| TestStringMap[Spelling.name()] = TestStr; |
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.
done, thanks.
Outdated
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.
| // been parsed | |
| // been parsed. |
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.
done.
Outdated
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.
| for (auto &entry : TestStringMap) { | |
| OS << " .Case(\"" << entry.getKey() << "\", " << entry.getValue() | |
| << ")\n"; | |
| for (auto &Entry : TestStringMap) { | |
| OS << " .Case(\"" << Entry.getKey() << "\", " << Entry.getValue() | |
| << ")\n"; |
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.
done.
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 don't get this test. Why does this choose the RISCV interrupt instead of the GNU one? And where would 'machine' come from?
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.
"-triple riscv64" is why you get the
RISCVInterruptAttr, which is expected."machine" is on a
CHECK-NOTline, which is what the bug was about.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 guess the question is 'how'? Is the "supervisor" not coming from the string?
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.
Before this patch, our "has attribute" check was looking through a
StringSwitchthat had multiple cases with the same string argument but different resulting values (that would check for target triples and arches). So we'd hit the first case, say "this matches", and the test for the attribute would only pass if the target triple matched. Because the first triple was never the RISCV attribute, we'd always say "we don't have this attribute". In turn, this would mean parsing would say "well, we don't know about this attribute, so eat all the arguments". But because Sema could figure out whichhandleInterruptAttrfunction to call, we'd actually go ahead and make the correct attribute, just with the incorrect argument. The default if no argument is specified for RISCV ismachine. So we'd ignoresupervisorand just substitute inmachinequietly for the user.