diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2019-05-07 14:00:49 +0000 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2019-05-07 14:00:49 +0000 |
commit | bb6e7b36543634bba0a8bd5b3c4a2123902a63a5 (patch) | |
tree | ba44b4f596e06858efd43a07f7c2ab9a0efbc4f8 | |
parent | 435e76a558b324ecb77dac417663e1f7f49695c9 (diff) | |
download | bcm5719-llvm-bb6e7b36543634bba0a8bd5b3c4a2123902a63a5.tar.gz bcm5719-llvm-bb6e7b36543634bba0a8bd5b3c4a2123902a63a5.zip |
Allow field offset lookups in types with incomplete arrays within libclang.
Patch thanks to Jorn Vernee
llvm-svn: 360147
-rw-r--r-- | clang/test/Index/print-type-size.c | 31 | ||||
-rw-r--r-- | clang/tools/libclang/CXType.cpp | 12 |
2 files changed, 41 insertions, 2 deletions
diff --git a/clang/test/Index/print-type-size.c b/clang/test/Index/print-type-size.c new file mode 100644 index 00000000000..d2103419212 --- /dev/null +++ b/clang/test/Index/print-type-size.c @@ -0,0 +1,31 @@ +// RUN: c-index-test -test-print-type-size %s | FileCheck %s + +struct Foo { + int size; + // CHECK: FieldDecl=size:4:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0] + void *data[]; + // CHECK: FieldDecl=data:6:9 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64] +}; + +struct Bar { + int size; + // CHECK: FieldDecl=size:11:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0] + struct { + int dummy; + // CHECK: FieldDecl=dummy:14:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64/0] + void *data[]; + // CHECK: FieldDecl=data:16:11 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=128/64] + }; +}; + +struct Baz { + int size; + // CHECK: FieldDecl=size:22:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0] + union { + void *data1[]; + // CHECK: FieldDecl=data1:25:11 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64/0] + void *data2[]; + // CHECK: FieldDecl=data2:27:11 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64/0] + }; +}; + diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp index 6cb680a64d8..47a9bb9c1d2 100644 --- a/clang/tools/libclang/CXType.cpp +++ b/clang/tools/libclang/CXType.cpp @@ -885,6 +885,10 @@ long long clang_getArraySize(CXType CT) { return result; } +static bool isIncompleteTypeWithAlignment(QualType QT) { + return QT->isIncompleteArrayType() || !QT->isIncompleteType(); +} + long long clang_Type_getAlignOf(CXType T) { if (T.kind == CXType_Invalid) return CXTypeLayoutError_Invalid; @@ -895,7 +899,7 @@ long long clang_Type_getAlignOf(CXType T) { // [expr.alignof] p3: if reference type, return size of referenced type if (QT->isReferenceType()) QT = QT.getNonReferenceType(); - if (QT->isIncompleteType()) + if (!isIncompleteTypeWithAlignment(QT)) return CXTypeLayoutError_Incomplete; if (QT->isDependentType()) return CXTypeLayoutError_Dependent; @@ -950,10 +954,14 @@ long long clang_Type_getSizeOf(CXType T) { return Ctx.getTypeSizeInChars(QT).getQuantity(); } +static bool isTypeIncompleteForLayout(QualType QT) { + return QT->isIncompleteType() && !QT->isIncompleteArrayType(); +} + static long long visitRecordForValidation(const RecordDecl *RD) { for (const auto *I : RD->fields()){ QualType FQT = I->getType(); - if (FQT->isIncompleteType()) + if (isTypeIncompleteForLayout(FQT)) return CXTypeLayoutError_Incomplete; if (FQT->isDependentType()) return CXTypeLayoutError_Dependent; |