forked from OSchip/llvm-project
[libclang] Add functions to get information about fields.
Patch by Loïc Jaquemet! llvm-svn: 234762
This commit is contained in:
parent
e73300b925
commit
2bff5161c4
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_getSizeOf(CXType T);
|
|||
*/
|
||||
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,
|
||||
|
@ -5668,6 +5690,44 @@ CINDEX_LINKAGE void clang_indexLoc_getFileLocation(CXIdxLoc loc,
|
|||
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
|
||||
* \c clang_Type_visitFields. Its first argument is the cursor being
|
||||
* visited, its second argument is the client data provided to
|
||||
* \c clang_Type_visitFields.
|
||||
*
|
||||
* The visitor should return one of the \c CXVisitorResult values
|
||||
* to direct \c clang_Type_visitFields.
|
||||
*/
|
||||
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);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -44,6 +44,7 @@ void foo(int i, int incomplete_array[]) { int variable_array[i]; }
|
|||
|
||||
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=3]
|
||||
// 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]
|
||||
// CHECK: VarDecl=member_pointer:49:12 (Definition) [type=int Blob::*] [typekind=MemberPointer] [isPOD=1]
|
||||
|
|
|
@ -1250,6 +1250,12 @@ static void PrintTypeAndTypeKind(CXType T, const char *Format) {
|
|||
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(CXCursor cursor, CXCursor p,
|
|||
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 PrintTypeSize(CXCursor cursor, CXCursor p,
|
|||
{
|
||||
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);
|
||||
|
|
|
@ -775,13 +775,12 @@ static long long visitRecordForValidation(const RecordDecl *RD) {
|
|||
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 PT, const char *S) {
|
|||
return CXTypeLayoutError_Incomplete;
|
||||
if (RD->isInvalidDecl())
|
||||
return CXTypeLayoutError_Invalid;
|
||||
// validate parent type
|
||||
QualType RT = GetQualType(PT);
|
||||
if (RT->isIncompleteType())
|
||||
return CXTypeLayoutError_Incomplete;
|
||||
|
@ -796,6 +796,15 @@ long long clang_Type_getOffsetOf(CXType PT, const char *S) {
|
|||
return CXTypeLayoutError_Dependent;
|
||||
// We recurse into all record fields to detect incomplete and dependent types.
|
||||
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)
|
||||
|
@ -804,6 +813,10 @@ long long clang_Type_getOffsetOf(CXType PT, const char *S) {
|
|||
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_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 PT, const char *S) {
|
|||
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,41 @@ CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned i) {
|
|||
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:
|
||||
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"
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue