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