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 <[email protected]> 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 <[email protected]> > 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 >> [email protected] >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
