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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits