blob: e528f32d911b0f85eab842a09182e7a5e3a612ec [file] [edit]
struct S {
int field;
int other;
void method();
};
struct Inner {
int leaf;
int otherLeaf;
void method();
};
struct Outer {
Inner inner;
Inner array[2];
};
struct Base {
int inherited;
};
struct Derived : Base {
int direct;
};
struct RefOuter {
Inner &ref;
};
struct WithAnon {
int outer;
union {
int anonInt;
Inner anonInner;
};
};
struct ShadowBase {
Inner shadowed;
};
struct ShadowDerived : ShadowBase {
using ShadowBase::shadowed;
};
struct WithBitField {
int regular;
int bit : 4;
int : 4;
int otherRegular;
};
struct WithAnonBitField {
int outer;
struct {
int anonRegular;
int anonBit : 4;
};
};
#define offsetof(type, member) __builtin_offsetof(type, member)
// Cursor immediately after the comma: empty designator path.
int empty = __builtin_offsetof(S, field);
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:%(line-1):35 %s -o - -std=c++17 | FileCheck -check-prefix=CHECK-S --implicit-check-not=method %s
// Cursor after a dot: completion in the nested record's type.
int after_dot = __builtin_offsetof(Outer, inner.leaf);
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:%(line-1):49 %s -o - -std=c++17 | FileCheck -check-prefix=CHECK-INNER --implicit-check-not=method %s
// Cursor after a dot following an array subscript.
int array = __builtin_offsetof(Outer, array[0].leaf);
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:%(line-1):48 %s -o - -std=c++17 | FileCheck -check-prefix=CHECK-INNER --implicit-check-not=method %s
// Inherited fields participate in offsetof completion.
int inherited = __builtin_offsetof(Derived, inherited);
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:%(line-1):45 %s -o - -std=c++17 | FileCheck -check-prefix=CHECK-DERIVED %s
// Reference field: dereferenced before continuing the path.
int ref = __builtin_offsetof(RefOuter, ref.leaf);
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:%(line-1):44 %s -o - -std=c++17 | FileCheck -check-prefix=CHECK-INNER --implicit-check-not=method %s
// Empty path on a record with anonymous-member indirect fields.
int anon_empty = __builtin_offsetof(WithAnon, anonInt);
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:%(line-1):47 %s -o - -std=c++17 | FileCheck -check-prefix=CHECK-ANON %s
// Designator that starts with an indirect field from an anonymous member.
int anon_nested = __builtin_offsetof(WithAnon, anonInner.leaf);
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:%(line-1):58 %s -o - -std=c++17 | FileCheck -check-prefix=CHECK-INNER --implicit-check-not=method %s
// Field exposed via `using Base::...` resolves through its UsingShadowDecl.
int shadowed = __builtin_offsetof(ShadowDerived, shadowed.leaf);
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:%(line-1):59 %s -o - -std=c++17 | FileCheck -check-prefix=CHECK-INNER --implicit-check-not=method %s
// Macro form expands to __builtin_offsetof with the same completion behavior.
int macro = offsetof(S, field);
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:%(line-1):25 %s -o - -std=c++17 | FileCheck -check-prefix=CHECK-S --implicit-check-not=method %s
// Bit-fields are not valid as the offsetof member designator
// (err_offsetof_bitfield), so they should not be offered as completions.
// Unnamed bit-fields have no identifier and are filtered out of lookup
// independently.
int bf = __builtin_offsetof(WithBitField, regular);
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:%(line-1):43 %s -o - -std=c++17 | FileCheck -check-prefix=CHECK-BF --implicit-check-not=bit %s
// Bit-fields exposed via an anonymous struct's IndirectFieldDecl are also
// filtered: the leaf field is what offsetof would name.
int abf = __builtin_offsetof(WithAnonBitField, outer);
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:%(line-1):48 %s -o - -std=c++17 | FileCheck -check-prefix=CHECK-ABF --implicit-check-not=anonBit %s
// CHECK-S-DAG: COMPLETION: field : [#int#]field
// CHECK-S-DAG: COMPLETION: other : [#int#]other
// CHECK-INNER-DAG: COMPLETION: leaf : [#int#]leaf
// CHECK-INNER-DAG: COMPLETION: otherLeaf : [#int#]otherLeaf
// CHECK-DERIVED-DAG: COMPLETION: direct : [#int#]direct
// CHECK-DERIVED-DAG: COMPLETION: inherited (InBase) : [#int#]inherited
// CHECK-ANON-DAG: COMPLETION: anonInner : [#Inner#]anonInner
// CHECK-ANON-DAG: COMPLETION: anonInt : [#int#]anonInt
// CHECK-ANON-DAG: COMPLETION: outer : [#int#]outer
// CHECK-BF-DAG: COMPLETION: regular : [#int#]regular
// CHECK-BF-DAG: COMPLETION: otherRegular : [#int#]otherRegular
// CHECK-ABF-DAG: COMPLETION: outer : [#int#]outer
// CHECK-ABF-DAG: COMPLETION: anonRegular : [#int#]anonRegular