[clang] [Clang] Implement the core language parts of P2786 - Trivial relocation (PR #127636)

Mariya Podchishchaeva via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 24 05:41:58 PST 2025


================
@@ -3808,13 +3868,39 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
   SourceLocation AbstractLoc;
   bool IsFinalSpelledSealed = false;
   bool IsAbstract = false;
+  TriviallyRelocatableSpecifier TriviallyRelocatable;
+  ReplaceableSpecifier Replacable;
 
   // Parse the optional 'final' keyword.
   if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) {
     while (true) {
       VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier(Tok);
-      if (Specifier == VirtSpecifiers::VS_None)
-        break;
+      if (Specifier == VirtSpecifiers::VS_None) {
+        if (isCXX2CTriviallyRelocatableKeyword(Tok)) {
+          if (TriviallyRelocatable.isSet()) {
+            auto Skipped = Tok;
+            ConsumeToken();
+            Diag(Skipped, diag::err_duplicate_class_relocation_specifier)
+                << /*trivial_relocatable*/ 0
+                << TriviallyRelocatable.getLocation();
+          } else {
+            ParseCXX2CTriviallyRelocatableSpecifier(TriviallyRelocatable);
+          }
+          continue;
+        } else if (isCXX2CReplaceableKeyword(Tok)) {
+          if (Replacable.isSet()) {
+            auto Skipped = Tok;
+            ConsumeToken();
+            Diag(Skipped, diag::err_duplicate_class_relocation_specifier)
+                << /*replaceable*/ 1 << Replacable.getLocation();
+          } else {
+            ParseCXX2CReplaceableSpecifier(Replacable);
+          }
+          continue;
----------------
Fznamznon wrote:

I have a feeling that if TriviallyRelocatableSpecifier/ReplaceableSpecifier were not templated and instead had some enum "Kind" field, the following two almost identical branches could be rewritten into:
```
BasicRelocatableOrReplaceableClassSpecifier ToComplain;


if (isCXX2CTriviallyRelocatableKeyword(Tok))
  ToComplain = TriviallyRelocatable;
else if (isCXX2CReplaceableKeyword(Tok))
  ToComplain = Replacable;

if (ToComplain.isSet()) {
    auto Skipped = Tok;
    ConsumeToken();
    Diag(Skipped, diag::err_duplicate_class_relocation_specifier)
    << /*trivial_relocatable*/ ToComplain.getKind()
    << TriviallyRelocatable.getLocation();
} else if (ToComplain.isNotEmpty()) {
  (ToComplain.getKind)? ParseCXX2CTriviallyRelocatableSpecifier(ToComplain) : ParseCXX2CReplaceableSpecifier(ToComplain);
}

```
that is an entirely optional suggestion but that amount of else/if/{} for a technically same code just makes it look sad.

https://github.com/llvm/llvm-project/pull/127636


More information about the cfe-commits mailing list