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