2013-10-29 9 views
7

desidero analizzare attributi generalizzati di funzioni membro classe nell'esempio seguente:Ispezione attributi generalizzate con libclang

class Foo 
{ 
public: 
    void foo [[interesting]](); 
    void bar(); 
}; 

Utilizzando l'API libclang C, desidero distinguere tra foo e bar (e sapere che foo ha l'attributo interesting) nell'origine. È possibile? Ho difficoltà a trovare esempi o documentazione che spieghi i concetti utilizzati nell'API (ho trovato un riferimento, ma è un po 'difficile da usare quando i concetti non sono spiegati).

risposta

1

Mentre non sono riuscito a trovare gli attributi generalizzati nell'AST (sembra che siano caduti quando o prima di costruire l'AST, non dopo di esso), ho trovato una soluzione alternativa.

C'è un attributo annotate clang nella forma seguente:

__attribute__((annotate("something"))) 

Con una macro ho potuto ottenere una sintassi ragionevole e un'annotazione che è visibile nella AST:

#define INTERESTING __attribute__((annotate("interesting"))) 

class Foo 
{ 
public: 
    INTERESTING void foo(); 
    void bar(); 
}; 

L'attributo sarà il figlio del nodo del metodo, con il suo display_name che è la stringa di annotazione. Una possibile discarica AST:

<CursorKind.TRANSLATION_UNIT> 
    "test.h" 
{ 
    __builtin_va_list <CursorKind.TYPEDEF_DECL> 
    "__builtin_va_list" 
    type_info <CursorKind.CLASS_DECL> 
    "type_info" 
    Foo <CursorKind.CLASS_DECL> 
    "Foo" 
    { 
    <CursorKind.CXX_ACCESS_SPEC_DECL> 
     "" 
    foo <CursorKind.CXX_METHOD> 
     "foo()" 
    { 
     <CursorKind.ANNOTATE_ATTR> 
     "interesting" 
    } 
    bar <CursorKind.CXX_METHOD> 
     "bar()" 
    } 
} 

produce lo stesso output con void foo INTERESTING(); troppo.

2

Qualcosa come la seguente funzione first_attr preleverà il cursore del primo attributo del cursore superato se esiste, o un cursore nullo in caso negativo (codice non testato ... lettore avvertimento)

CXChildVisitResult attr_visit(CXCursor cursor, CXCursor parent, CXClientData data) { 
    if (clang_isAttribute(cursor)) { 
     *data = cursor; 
     return CXChildVisit_Break; 
    } 
    return CXChildVisit_Continue; 
} 

CXCursor first_attr(const CXCursor& c) { 
    CXCursor attr; 
    unsigned visit_result = clang_visitChildren(c, attr_visit, &attr); 
    if (!visit_result) // attribute not found 
     attr = clang_getNullCursor(); 
    return attr; 
} 

quanto constatazione che specifica attribuiscono un cursore a rappresenta il risultato di clang_getCursorKind(a) può aiutare, ma gli unici attributi esposti sono:

CXCursor_IBActionAttr 
CXCursor_IBOutletAttr 
CXCursor_IBOutletCollectionAttr 
CXCursor_CXXFinalAttr 
CXCursor_CXXOverrideAttr 
CXCursor_AnnotateAttr 
CXCursor_AsmLabelAttr 

Tutto il resto sarà un CXCursor_UnexposedAttr un d l'unico modo in cui posso pensare di ottenere il suo testo è esaminare lo clang_getCursorExtent(a) (ad esempio, leggere il codice sorgente; cf. clang_tokenize). Nel caso di annotazioni, l'annotazione specifica utilizzata è disponibile tramite clang_getCursorDisplayName.

+0

Ho provato a farlo con i collegamenti Python per prototipare il codice, ma l'attributo non era affatto visibile nell'AST (nemmeno come attributo non esposto). L'attributo 'noreturn' è apparso nel mio dump AST quando l'ho aggiunto. –

Problemi correlati