r227432 - libclang: Add three functions useful for dealing with anonymous fields:
Renato Golin
renato.golin at linaro.org
Thu Jan 29 07:23:58 PST 2015
This also failed our AArch64 buildbot with the error:
// CHECK: StructDecl=Bar:16:8 (Definition) [type=outer::inner::Bar]
[typekind=Record] [isPOD=0] [nbFields=1]
<stdin>:360:1: note: scanning from here
StructDecl=Bar:16:8 (Definition) [type=outer::inner::Bar]
[typekind=Record] [isPOD=0] [nbFields=3]
Unfortunately, the public bot is broken, so you can't see that. :(
cheers,
--renato
On 29 January 2015 at 14:28, Sean Silva <chisophugis at gmail.com> wrote:
> I'm seeing the following warning on Mac.
>
> /Users/ssilva/pg/llvm/tools/clang/tools/libclang/CXType.cpp:965:5: warning:
> default label in switch which covers all enumeration values
> [-Wcovered-switch-default]
>
> default:
>
> ^
>
> 1 warning generated.
>
>
> On Thu, Jan 29, 2015 at 12:45 PM, Francois Pichet <pichet2000 at gmail.com>
> wrote:
>>
>> Author: fpichet
>> Date: Thu Jan 29 06:45:29 2015
>> New Revision: 227432
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=227432&view=rev
>> Log:
>> libclang: Add three functions useful for dealing with anonymous fields:
>> clang_Cursor_getOffsetOfField
>> clang_Cursor_isAnonymous
>> clang_Type_visitFields
>> Python: Add corresponding methods for dealing with anonymous fields.
>>
>> Patch by Loïc Jaquemet
>>
>> Modified:
>> cfe/trunk/bindings/python/clang/cindex.py
>> cfe/trunk/bindings/python/tests/cindex/test_type.py
>> cfe/trunk/include/clang-c/Index.h
>> cfe/trunk/test/Index/print-type-size.cpp
>> cfe/trunk/test/Index/print-type.cpp
>> cfe/trunk/tools/c-index-test/c-index-test.c
>> cfe/trunk/tools/libclang/CXType.cpp
>> cfe/trunk/tools/libclang/libclang.exports
>>
>> Modified: cfe/trunk/bindings/python/clang/cindex.py
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/bindings/python/clang/cindex.py?rev=227432&r1=227431&r2=227432&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/bindings/python/clang/cindex.py (original)
>> +++ cfe/trunk/bindings/python/clang/cindex.py Thu Jan 29 06:45:29 2015
>> @@ -1476,6 +1476,18 @@ class Cursor(Structure):
>> """
>> return TokenGroup.get_tokens(self._tu, self.extent)
>>
>> + def get_field_offsetof(self):
>> + """Returns the offsetof the FIELD_DECL pointed by this Cursor."""
>> + return conf.lib.clang_Cursor_getOffsetOfField(self)
>> +
>> + def is_anonymous(self):
>> + """
>> + Check if the record is anonymous.
>> + """
>> + if self.kind == CursorKind.FIELD_DECL:
>> + return self.type.get_declaration().is_anonymous()
>> + return conf.lib.clang_Cursor_isAnonymous(self)
>> +
>> def is_bitfield(self):
>> """
>> Check if the field is a bitfield.
>> @@ -1884,6 +1896,21 @@ class Type(Structure):
>> return RefQualifierKind.from_id(
>> conf.lib.clang_Type_getCXXRefQualifier(self))
>>
>> + def get_fields(self):
>> + """Return an iterator for accessing the fields of this type."""
>> +
>> + def visitor(field, children):
>> + assert field != conf.lib.clang_getNullCursor()
>> +
>> + # Create reference to TU so it isn't GC'd before Cursor.
>> + field._tu = self._tu
>> + fields.append(field)
>> + return 1 # continue
>> + fields = []
>> + conf.lib.clang_Type_visitFields(self,
>> + callbacks['fields_visit'](visitor), fields)
>> + return iter(fields)
>> +
>> @property
>> def spelling(self):
>> """Retrieve the spelling of this Type."""
>> @@ -2780,6 +2807,7 @@ class Token(Structure):
>> callbacks['translation_unit_includes'] = CFUNCTYPE(None, c_object_p,
>> POINTER(SourceLocation), c_uint, py_object)
>> callbacks['cursor_visit'] = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
>> +callbacks['fields_visit'] = CFUNCTYPE(c_int, Cursor, py_object)
>>
>> # Functions strictly alphabetical order.
>> functionList = [
>> @@ -3367,6 +3395,10 @@ functionList = [
>> [Cursor, c_uint],
>> c_ulonglong),
>>
>> + ("clang_Cursor_isAnonymous",
>> + [Cursor],
>> + bool),
>> +
>> ("clang_Cursor_isBitField",
>> [Cursor],
>> bool),
>> @@ -3381,6 +3413,10 @@ functionList = [
>> _CXString,
>> _CXString.from_result),
>>
>> + ("clang_Cursor_getOffsetOfField",
>> + [Cursor],
>> + c_longlong),
>> +
>> ("clang_Type_getAlignOf",
>> [Type],
>> c_longlong),
>> @@ -3401,6 +3437,10 @@ functionList = [
>> ("clang_Type_getCXXRefQualifier",
>> [Type],
>> c_uint),
>> +
>> + ("clang_Type_visitFields",
>> + [Type, callbacks['fields_visit'], py_object],
>> + c_uint),
>> ]
>>
>> class LibclangError(Exception):
>>
>> Modified: cfe/trunk/bindings/python/tests/cindex/test_type.py
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/bindings/python/tests/cindex/test_type.py?rev=227432&r1=227431&r2=227432&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/bindings/python/tests/cindex/test_type.py (original)
>> +++ cfe/trunk/bindings/python/tests/cindex/test_type.py Thu Jan 29
>> 06:45:29 2015
>> @@ -363,6 +363,7 @@ def test_offset():
>> """Ensure Cursor.get_record_field_offset works in anonymous
>> records"""
>> source="""
>> struct Test {
>> + struct {int a;} typeanon;
>> struct {
>> int bariton;
>> union {
>> @@ -371,15 +372,23 @@ struct Test {
>> };
>> int bar;
>> };"""
>> - tries=[(['-target','i386-linux-gnu'],(4,16,0,32,64)),
>> - (['-target','nvptx64-unknown-unknown'],(8,24,0,32,64)),
>> - (['-target','i386-pc-win32'],(8,16,0,32,64)),
>> - (['-target','msp430-none-none'],(2,14,0,32,64))]
>> + tries=[(['-target','i386-linux-gnu'],(4,16,0,32,64,96)),
>> + (['-target','nvptx64-unknown-unknown'],(8,24,0,32,64,96)),
>> + (['-target','i386-pc-win32'],(8,16,0,32,64,96)),
>> + (['-target','msp430-none-none'],(2,14,0,32,64,96))]
>> for flags, values in tries:
>> - align,total,bariton,foo,bar = values
>> + align,total,f1,bariton,foo,bar = values
>> tu = get_tu(source)
>> teststruct = get_cursor(tu, 'Test')
>> - fields = list(teststruct.get_children())
>> + children = list(teststruct.get_children())
>> + fields = list(teststruct.type.get_fields())
>> + assert children[0].kind == CursorKind.STRUCT_DECL
>> + assert children[0].spelling != "typeanon"
>> + assert children[1].spelling == "typeanon"
>> + assert fields[0].kind == CursorKind.FIELD_DECL
>> + assert fields[1].kind == CursorKind.FIELD_DECL
>> + assert fields[1].is_anonymous()
>> + assert teststruct.type.get_offset("typeanon") == f1
>> assert teststruct.type.get_offset("bariton") == bariton
>> assert teststruct.type.get_offset("foo") == foo
>> assert teststruct.type.get_offset("bar") == bar
>>
>> Modified: cfe/trunk/include/clang-c/Index.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=227432&r1=227431&r2=227432&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang-c/Index.h (original)
>> +++ cfe/trunk/include/clang-c/Index.h Thu Jan 29 06:45:29 2015
>> @@ -32,7 +32,7 @@
>> * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
>> */
>> #define CINDEX_VERSION_MAJOR 0
>> -#define CINDEX_VERSION_MINOR 29
>> +#define CINDEX_VERSION_MINOR 30
>>
>> #define CINDEX_VERSION_ENCODE(major, minor) ( \
>> ((major) * 10000) \
>> @@ -3281,6 +3281,28 @@ CINDEX_LINKAGE long long clang_Type_getS
>> */
>> CINDEX_LINKAGE long long clang_Type_getOffsetOf(CXType T, const char *S);
>>
>> +/**
>> + * \brief Return the offset of the field represented by the Cursor.
>> + *
>> + * If the cursor is not a field declaration, -1 is returned.
>> + * If the cursor semantic parent is not a record field declaration,
>> + * CXTypeLayoutError_Invalid is returned.
>> + * If the field's type declaration is an incomplete type,
>> + * CXTypeLayoutError_Incomplete is returned.
>> + * If the field's type declaration is a dependent type,
>> + * CXTypeLayoutError_Dependent is returned.
>> + * If the field's name S is not found,
>> + * CXTypeLayoutError_InvalidFieldName is returned.
>> + */
>> +CINDEX_LINKAGE long long clang_Cursor_getOffsetOfField(CXCursor C);
>> +
>> +/**
>> + * \brief Determine whether the given cursor represents an anonymous
>> record
>> + * declaration.
>> + */
>> +CINDEX_LINKAGE unsigned clang_Cursor_isAnonymous(CXCursor C);
>> +
>> +
>> enum CXRefQualifierKind {
>> /** \brief No ref-qualifier was provided. */
>> CXRefQualifier_None = 0,
>> @@ -5669,6 +5691,44 @@ CINDEX_LINKAGE
>> CXSourceLocation clang_indexLoc_getCXSourceLocation(CXIdxLoc loc);
>>
>> /**
>> + * \brief Visitor invoked for each field found by a traversal.
>> + *
>> + * This visitor function will be invoked for each field found by
>> + * clang_visitCursorFields(). Its first argument is the cursor being
>> + * visited, its second argument is the client data provided to
>> + * clang_visitCursorFields().
>> + *
>> + * The visitor should return one of the \c CXVisitorResult values
>> + * to direct clang_visitCursorFields().
>> + */
>> +typedef enum CXVisitorResult (*CXFieldVisitor)(CXCursor C,
>> + CXClientData
>> client_data);
>> +
>> +/**
>> + * \brief Visit the fields of a particular type.
>> + *
>> + * This function visits all the direct fields of the given cursor,
>> + * invoking the given \p visitor function with the cursors of each
>> + * visited field. The traversal may be ended prematurely, if
>> + * the visitor returns \c CXFieldVisit_Break.
>> + *
>> + * \param T the record type whose field may be visited.
>> + *
>> + * \param visitor the visitor function that will be invoked for each
>> + * field of \p T.
>> + *
>> + * \param client_data pointer data supplied by the client, which will
>> + * be passed to the visitor each time it is invoked.
>> + *
>> + * \returns a non-zero value if the traversal was terminated
>> + * prematurely by the visitor returning \c CXFieldVisit_Break.
>> + */
>> +CINDEX_LINKAGE unsigned clang_Type_visitFields(CXType T,
>> + CXFieldVisitor visitor,
>> + CXClientData client_data);
>> +
>> +
>> +/**
>> * @}
>> */
>>
>>
>> Modified: cfe/trunk/test/Index/print-type-size.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/print-type-size.cpp?rev=227432&r1=227431&r2=227432&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/Index/print-type-size.cpp (original)
>> +++ cfe/trunk/test/Index/print-type-size.cpp Thu Jan 29 06:45:29 2015
>> @@ -65,12 +65,12 @@ struct Test2 {
>> int foo;
>> };
>> struct {
>> -//CHECK64: FieldDecl=bar:[[@LINE+1]]:11 (Definition) [type=int]
>> [typekind=Int] [sizeof=4] [alignof=4] [offsetof=32]
>> +//CHECK64: FieldDecl=bar:[[@LINE+1]]:11 (Definition) [type=int]
>> [typekind=Int] [sizeof=4] [alignof=4] [offsetof=32/0]
>> int bar;
>> };
>> struct {
>> struct {
>> -//CHECK64: FieldDecl=foobar:[[@LINE+1]]:15 (Definition) [type=int]
>> [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64]
>> +//CHECK64: FieldDecl=foobar:[[@LINE+1]]:15 (Definition) [type=int]
>> [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64/0]
>> int foobar;
>> };
>> };
>> @@ -160,6 +160,7 @@ struct s4a {
>> struct {
>> struct {
>> struct {
>> +//CHECK64: FieldDecl=s4_e1:[[@LINE+1]]:17 (Definition) [type=int]
>> [typekind=Int] [sizeof=4] [alignof=4] [offsetof=-1/0]
>> int s4_e1;
>> };
>> };
>>
>> Modified: cfe/trunk/test/Index/print-type.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/print-type.cpp?rev=227432&r1=227431&r2=227432&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/Index/print-type.cpp (original)
>> +++ cfe/trunk/test/Index/print-type.cpp Thu Jan 29 06:45:29 2015
>> @@ -44,6 +44,7 @@ void foo(int i, int incomplete_array[])
>>
>> struct Blob {
>> int i;
>> + int j;
>> };
>> int Blob::*member_pointer;
>>
>> @@ -58,7 +59,7 @@ int Blob::*member_pointer;
>> // CHECK: NonTypeTemplateParameter=U:8:32 (Definition) [type=unsigned
>> int] [typekind=UInt] [isPOD=1]
>> // CHECK: TemplateTemplateParameter=W:8:60 (Definition) [type=]
>> [typekind=Invalid] [isPOD=0]
>> // CHECK: Namespace=inner:14:11 (Definition) [type=] [typekind=Invalid]
>> [isPOD=0]
>> -// CHECK: StructDecl=Bar:16:8 (Definition) [type=outer::inner::Bar]
>> [typekind=Record] [isPOD=0]
>> +// CHECK: StructDecl=Bar:16:8 (Definition) [type=outer::inner::Bar]
>> [typekind=Record] [isPOD=0] [nbFields=1]
>> // CHECK: CXXConstructor=Bar:17:3 (Definition) [type=void
>> (outer::Foo<bool> *){{.*}}] [typekind=FunctionProto] [canonicaltype=void
>> (outer::Foo<bool> *){{.*}}] [canonicaltypekind=FunctionProto]
>> [resulttype=void] [resulttypekind=Void] [args= [outer::Foo<bool> *]
>> [Pointer]] [isPOD=0]
>> // CHECK: ParmDecl=foo:17:25 (Definition) [type=outer::Foo<bool> *]
>> [typekind=Pointer] [canonicaltype=outer::Foo<bool> *]
>> [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=outer::Foo<bool>]
>> [pointeekind=Unexposed]
>> // CHECK: NamespaceRef=outer:1:11 [type=] [typekind=Invalid] [isPOD=0]
>> @@ -115,6 +116,6 @@ int Blob::*member_pointer;
>> // CHECK: DeclStmt= [type=] [typekind=Invalid] [isPOD=0]
>> // CHECK: VarDecl=variable_array:43:47 (Definition) [type=int [i]]
>> [typekind=VariableArray] [isPOD=1]
>> // CHECK: DeclRefExpr=i:43:14 [type=int] [typekind=Int] [isPOD=1]
>> -// CHECK: StructDecl=Blob:45:8 (Definition) [type=Blob] [typekind=Record]
>> [isPOD=1]
>> +// CHECK: StructDecl=Blob:45:8 (Definition) [type=Blob] [typekind=Record]
>> [isPOD=1] [nbFields=2]
>> // CHECK: FieldDecl=i:46:7 (Definition) [type=int] [typekind=Int]
>> [isPOD=1]
>> // CHECK: VarDecl=member_pointer:48:12 (Definition) [type=int Blob::*]
>> [typekind=MemberPointer] [isPOD=1]
>>
>> Modified: cfe/trunk/tools/c-index-test/c-index-test.c
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=227432&r1=227431&r2=227432&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/tools/c-index-test/c-index-test.c (original)
>> +++ cfe/trunk/tools/c-index-test/c-index-test.c Thu Jan 29 06:45:29 2015
>> @@ -1250,6 +1250,12 @@ static void PrintTypeAndTypeKind(CXType
>> clang_disposeString(TypeKindSpelling);
>> }
>>
>> +static enum CXVisitorResult FieldVisitor(CXCursor C,
>> + CXClientData client_data) {
>> + (*(int *) client_data)+=1;
>> + return CXVisit_Continue;
>> +}
>> +
>> static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
>> CXClientData d) {
>> if (!clang_isInvalid(clang_getCursorKind(cursor))) {
>> @@ -1320,6 +1326,22 @@ static enum CXChildVisitResult PrintType
>> PrintTypeAndTypeKind(PT, " [pointeetype=%s] [pointeekind=%s]");
>> }
>> }
>> + /* Print the number of fields if they exist. */
>> + {
>> + int numFields = 0;
>> + if (clang_Type_visitFields(T, FieldVisitor, &numFields)){
>> + if (numFields != 0) {
>> + printf(" [nbFields=%d]", numFields);
>> + }
>> + /* Print if it is an anonymous record. */
>> + {
>> + unsigned isAnon = clang_Cursor_isAnonymous(cursor);
>> + if (isAnon != 0) {
>> + printf(" [isAnon=%d]", isAnon);
>> + }
>> + }
>> + }
>> + }
>>
>> printf("\n");
>> }
>> @@ -1353,28 +1375,29 @@ static enum CXChildVisitResult PrintType
>> {
>> CXString FieldSpelling = clang_getCursorSpelling(cursor);
>> const char *FieldName = clang_getCString(FieldSpelling);
>> - /* recurse to get the root anonymous record parent */
>> - CXCursor Parent, Root;
>> + /* recurse to get the first parent record that is not anonymous. */
>> + CXCursor Parent, Record;
>> + unsigned RecordIsAnonymous = 0;
>> if (clang_getCursorKind(cursor) == CXCursor_FieldDecl) {
>> - CXString RootParentSpelling;
>> - const char *RootParentName = 0;
>> - Parent = p;
>> + Record = Parent = p;
>> do {
>> - if (RootParentName != 0)
>> - clang_disposeString(RootParentSpelling);
>> -
>> - Root = Parent;
>> - RootParentSpelling = clang_getCursorSpelling(Root);
>> - RootParentName = clang_getCString(RootParentSpelling);
>> - Parent = clang_getCursorSemanticParent(Root);
>> - } while (clang_getCursorType(Parent).kind == CXType_Record &&
>> - !strcmp(RootParentName, ""));
>> - clang_disposeString(RootParentSpelling);
>> - /* if RootParentName is "", record is anonymous. */
>> + Record = Parent;
>> + Parent = clang_getCursorSemanticParent(Record);
>> + RecordIsAnonymous = clang_Cursor_isAnonymous(Record);
>> + /* Recurse as long as the parent is a CXType_Record and the
>> Record
>> + is anonymous */
>> + } while ( clang_getCursorType(Parent).kind == CXType_Record &&
>> + RecordIsAnonymous > 0);
>> {
>> - long long Offset =
>> clang_Type_getOffsetOf(clang_getCursorType(Root),
>> + long long Offset =
>> clang_Type_getOffsetOf(clang_getCursorType(Record),
>> FieldName);
>> - printf(" [offsetof=%lld]", Offset);
>> + long long Offset2 = clang_Cursor_getOffsetOfField(cursor);
>> + if (Offset == Offset2){
>> + printf(" [offsetof=%lld]", Offset);
>> + } else {
>> + /* Offsets will be different in anonymous records. */
>> + printf(" [offsetof=%lld/%lld]", Offset, Offset2);
>> + }
>> }
>> }
>> clang_disposeString(FieldSpelling);
>>
>> Modified: cfe/trunk/tools/libclang/CXType.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXType.cpp?rev=227432&r1=227431&r2=227432&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/tools/libclang/CXType.cpp (original)
>> +++ cfe/trunk/tools/libclang/CXType.cpp Thu Jan 29 06:45:29 2015
>> @@ -775,13 +775,12 @@ static long long visitRecordForValidatio
>> return 0;
>> }
>>
>> -long long clang_Type_getOffsetOf(CXType PT, const char *S) {
>> - // check that PT is not incomplete/dependent
>> - CXCursor PC = clang_getTypeDeclaration(PT);
>> +static long long validateFieldParentType(CXCursor PC, CXType PT){
>> if (clang_isInvalid(PC.kind))
>> return CXTypeLayoutError_Invalid;
>> const RecordDecl *RD =
>> dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
>> + // validate parent declaration
>> if (!RD || RD->isInvalidDecl())
>> return CXTypeLayoutError_Invalid;
>> RD = RD->getDefinition();
>> @@ -789,6 +788,7 @@ long long clang_Type_getOffsetOf(CXType
>> return CXTypeLayoutError_Incomplete;
>> if (RD->isInvalidDecl())
>> return CXTypeLayoutError_Invalid;
>> + // validate parent type
>> QualType RT = GetQualType(PT);
>> if (RT->isIncompleteType())
>> return CXTypeLayoutError_Incomplete;
>> @@ -798,12 +798,25 @@ long long clang_Type_getOffsetOf(CXType
>> long long Error = visitRecordForValidation(RD);
>> if (Error < 0)
>> return Error;
>> + return 0;
>> +}
>> +
>> +long long clang_Type_getOffsetOf(CXType PT, const char *S) {
>> + // check that PT is not incomplete/dependent
>> + CXCursor PC = clang_getTypeDeclaration(PT);
>> + long long Error = validateFieldParentType(PC,PT);
>> + if (Error < 0)
>> + return Error;
>> if (!S)
>> return CXTypeLayoutError_InvalidFieldName;
>> // lookup field
>> ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext();
>> IdentifierInfo *II = &Ctx.Idents.get(S);
>> DeclarationName FieldName(II);
>> + const RecordDecl *RD =
>> + dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
>> + // verified in validateFieldParentType
>> + RD = RD->getDefinition();
>> RecordDecl::lookup_const_result Res = RD->lookup(FieldName);
>> // If a field of the parent record is incomplete, lookup will fail.
>> // and we would return InvalidFieldName instead of Incomplete.
>> @@ -819,6 +832,25 @@ long long clang_Type_getOffsetOf(CXType
>> return CXTypeLayoutError_InvalidFieldName;
>> }
>>
>> +long long clang_Cursor_getOffsetOfField(CXCursor C) {
>> + if (clang_isDeclaration(C.kind)) {
>> + // we need to validate the parent type
>> + CXCursor PC = clang_getCursorSemanticParent(C);
>> + CXType PT = clang_getCursorType(PC);
>> + long long Error = validateFieldParentType(PC,PT);
>> + if (Error < 0)
>> + return Error;
>> + // proceed with the offset calculation
>> + const Decl *D = cxcursor::getCursorDecl(C);
>> + ASTContext &Ctx = cxcursor::getCursorContext(C);
>> + if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D))
>> + return Ctx.getFieldOffset(FD);
>> + if (const IndirectFieldDecl *IFD =
>> dyn_cast_or_null<IndirectFieldDecl>(D))
>> + return Ctx.getFieldOffset(IFD);
>> + }
>> + return -1;
>> +}
>> +
>> enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) {
>> QualType QT = GetQualType(T);
>> if (QT.isNull())
>> @@ -908,4 +940,42 @@ CXType clang_Type_getTemplateArgumentAsT
>> return MakeCXType(A.getAsType(), GetTU(CT));
>> }
>>
>> +unsigned clang_Type_visitFields(CXType PT,
>> + CXFieldVisitor visitor,
>> + CXClientData client_data){
>> + CXCursor PC = clang_getTypeDeclaration(PT);
>> + if (clang_isInvalid(PC.kind))
>> + return false;
>> + const RecordDecl *RD =
>> + dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
>> + if (!RD || RD->isInvalidDecl())
>> + return false;
>> + RD = RD->getDefinition();
>> + if (!RD || RD->isInvalidDecl())
>> + return false;
>> +
>> + for (RecordDecl::field_iterator I = RD->field_begin(), E =
>> RD->field_end();
>> + I != E; ++I){
>> + const FieldDecl *FD = dyn_cast_or_null<FieldDecl>((*I));
>> + // Callback to the client.
>> + switch (visitor(cxcursor::MakeCXCursor(FD, GetTU(PT)), client_data)){
>> + case CXVisit_Break:
>> + return true;
>> + case CXVisit_Continue:
>> + default:
>> + break;
>> + }
>> + }
>> + return true;
>> +}
>> +
>> +unsigned clang_Cursor_isAnonymous(CXCursor C){
>> + if (!clang_isDeclaration(C.kind))
>> + return 0;
>> + const Decl *D = cxcursor::getCursorDecl(C);
>> + if (const RecordDecl *FD = dyn_cast_or_null<RecordDecl>(D))
>> + return FD->isAnonymousStructOrUnion();
>> + return 0;
>> +}
>> +
>> } // end: extern "C"
>>
>> Modified: cfe/trunk/tools/libclang/libclang.exports
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.exports?rev=227432&r1=227431&r2=227432&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/tools/libclang/libclang.exports (original)
>> +++ cfe/trunk/tools/libclang/libclang.exports Thu Jan 29 06:45:29 2015
>> @@ -21,9 +21,11 @@ clang_Cursor_getNumArguments
>> clang_Cursor_getObjCDeclQualifiers
>> clang_Cursor_getObjCPropertyAttributes
>> clang_Cursor_getObjCSelectorIndex
>> +clang_Cursor_getOffsetOfField
>> clang_Cursor_getSpellingNameRange
>> clang_Cursor_getTranslationUnit
>> clang_Cursor_getReceiverType
>> +clang_Cursor_isAnonymous
>> clang_Cursor_isBitField
>> clang_Cursor_isDynamicCall
>> clang_Cursor_isNull
>> @@ -77,6 +79,7 @@ clang_Type_getOffsetOf
>> clang_Type_getNumTemplateArguments
>> clang_Type_getTemplateArgumentAsType
>> clang_Type_getCXXRefQualifier
>> +clang_Type_visitFields
>> clang_VerbatimBlockLineComment_getText
>> clang_VerbatimLineComment_getText
>> clang_HTMLTagComment_getAsString
>>
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
More information about the cfe-commits
mailing list