yichi170 updated this revision to Diff 548632.
yichi170 marked 4 inline comments as done.
yichi170 added a comment.

Applied the suggestions. Thanks for giving me feedback!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157201/new/

https://reviews.llvm.org/D157201

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/SemaCXX/offsetof.cpp

Index: clang/test/SemaCXX/offsetof.cpp
===================================================================
--- clang/test/SemaCXX/offsetof.cpp
+++ clang/test/SemaCXX/offsetof.cpp
@@ -98,3 +98,10 @@
     B x;
   }, a);
 }
+
+// https://github.com/llvm/llvm-project/issues/64154
+struct X2 { int a; static int static_a; };
+int x2[__builtin_offsetof(struct X2, X2::a) == 0 ? 1 : -1];
+int x3[__builtin_offsetof(struct X2, X2::static_a) == 0 ? 1 : -1]; // expected-error{{no member named 'static_a'}}
+int x4[__builtin_offsetof(struct X2, X2::X2) == 0 ? 1 : -1]; // expected-error{{no member named 'X2'}}
+
Index: clang/lib/Sema/TreeTransform.h
===================================================================
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -11028,7 +11028,7 @@
   for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
     const OffsetOfNode &ON = E->getComponent(I);
     Component Comp;
-    Comp.isBrackets = true;
+    Comp.Kind = Sema::OffsetOfComponent::Brackets;
     Comp.LocStart = ON.getSourceRange().getBegin();
     Comp.LocEnd = ON.getSourceRange().getEnd();
     switch (ON.getKind()) {
@@ -11039,14 +11039,14 @@
         return ExprError();
 
       ExprChanged = ExprChanged || Index.get() != FromIndex;
-      Comp.isBrackets = true;
+      Comp.Kind = Sema::OffsetOfComponent::Brackets;
       Comp.U.E = Index.get();
       break;
     }
 
     case OffsetOfNode::Field:
     case OffsetOfNode::Identifier:
-      Comp.isBrackets = false;
+      Comp.Kind = Sema::OffsetOfComponent::Identifier;
       Comp.U.IdentInfo = ON.getFieldName();
       if (!Comp.U.IdentInfo)
         continue;
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -16612,7 +16612,7 @@
   SmallVector<OffsetOfNode, 4> Comps;
   SmallVector<Expr*, 4> Exprs;
   for (const OffsetOfComponent &OC : Components) {
-    if (OC.isBrackets) {
+    if (OC.Kind == OffsetOfComponent::Brackets) {
       // Offset of an array sub-field.  TODO: Should we allow vector elements?
       if (!CurrentType->isDependentType()) {
         const ArrayType *AT = Context.getAsArrayType(CurrentType);
@@ -16682,6 +16682,10 @@
                               << SourceRange(Components[0].LocStart, OC.LocEnd)
                               << CurrentType))
         DidWarnAboutNonPOD = true;
+
+      if (OC.Kind == OffsetOfComponent::Qualifier &&
+          RD->getIdentifier() == OC.U.IdentInfo)
+        continue;
     }
 
     // Look for the field.
Index: clang/lib/Parse/ParseExpr.cpp
===================================================================
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -2635,16 +2635,23 @@
     SmallVector<Sema::OffsetOfComponent, 4> Comps;
 
     Comps.push_back(Sema::OffsetOfComponent());
-    Comps.back().isBrackets = false;
+    Comps.back().Kind = Sema::OffsetOfComponent::Identifier;
     Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
     Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken();
 
     // FIXME: This loop leaks the index expressions on error.
     while (true) {
-      if (Tok.is(tok::period)) {
+      if (Tok.is(tok::period) || Tok.is(tok::coloncolon)) {
         // offsetof-member-designator: offsetof-member-designator '.' identifier
+        if (Tok.is(tok::coloncolon) && getLangOpts().CPlusPlus) {
+          Comps.back().Kind = Sema::OffsetOfComponent::Qualifier;
+        } else if (Tok.is(tok::coloncolon) && !getLangOpts().CPlusPlus) {
+          Res = ExprError();
+          break;
+        }
+
         Comps.push_back(Sema::OffsetOfComponent());
-        Comps.back().isBrackets = false;
+        Comps.back().Kind = Sema::OffsetOfComponent::Identifier;
         Comps.back().LocStart = ConsumeToken();
 
         if (Tok.isNot(tok::identifier)) {
@@ -2660,7 +2667,7 @@
 
         // offsetof-member-designator: offsetof-member-design '[' expression ']'
         Comps.push_back(Sema::OffsetOfComponent());
-        Comps.back().isBrackets = true;
+        Comps.back().Kind = Sema::OffsetOfComponent::Brackets;
         BalancedDelimiterTracker ST(*this, tok::l_square);
         ST.consumeOpen();
         Comps.back().LocStart = ST.getOpenLocation();
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -6035,11 +6035,15 @@
   // __builtin_offsetof(type, identifier(.identifier|[expr])*)
   struct OffsetOfComponent {
     SourceLocation LocStart, LocEnd;
-    bool isBrackets;  // true if [expr], false if .ident
     union {
       IdentifierInfo *IdentInfo;
       Expr *E;
     } U;
+    enum {
+      Brackets,   // U.E is valid
+      Identifier, // U.IdentInfo is valid
+      Qualifier,  // Nothing in U is valid
+    } Kind;
   };
 
   /// __builtin_offsetof(type, a.b[123][456].c)
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -56,6 +56,7 @@
 
 C++ Language Changes
 --------------------
+- Improved ``__builtin_offsetof`` support, allowing qualified name in member designator. This fixes [Issue 64154](https://github.com/llvm/llvm-project/issues/64154).
 
 C++20 Feature Support
 ^^^^^^^^^^^^^^^^^^^^^
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to