2012-03-23 2 views
5

Come testare se un metodo C++ è qualificato in clang?Clang Const Qualified C++ Method

Per esempio ::

class Inner{ 
public: 
    int i; 
    Inner(); 
    float inner_method() const; 
}; 

Sto usando la libreria clang-c e ho provato ad utilizzare clang_isConstQualifiedType sul nodo inner_method. tuttavia questo restituisce falso.

Non mi importa se la risposta utilizza le intestazioni C++ clang.

risposta

2

Nell'interfaccia C++, il modo per controllare questo utilizza CXXMethodDecl::getTypeQualifiers() o FunctionProtoType::getTypeQuals() (a seconda se si dispone della dichiarazione o del tipo). Il bit Qualifiers::Const indica se il metodo (o il tipo di metodo) è const.

Nell'AP C libclang, questa informazione sembra essere utilizzata solo nell'implementazione di getCursorUSR, il cui risultato non è inteso per essere analizzato, pertanto l'utilizzo dell'API C++ o l'invio di una patch per aggiungere questa funzionalità all'API C sono le migliori opzioni.

1

Ho avuto lo stesso problema, ma avevo bisogno di farlo senza l'API C++. Ho messo la mia soluzione qui sotto per riferimento futuro. L'idea è quella di utilizzare la funzione tokenization libclang a ciclo su tutti i qualificatori del metodo:

std::string GetClangString(CXString str) 
{ 
    const char* tmp = clang_getCString(str); 
    if (tmp == NULL) 
    { 
    return ""; 
    } 
    else 
    { 
    std::string translated = std::string(tmp); 
    clang_disposeString(str); 
    return translated; 
    } 
} 

void GetMethodQualifiers(CXTranslationUnit translationUnit, 
         std::set<std::string>& qualifiers, 
         CXCursor cursor) 
{ 
    qualifiers.clear(); 

    CXSourceRange range = clang_getCursorExtent(cursor); 
    CXToken* tokens; 
    unsigned int numTokens; 
    clang_tokenize(translationUnit, range, &tokens, &numTokens); 

    bool insideBrackets = false; 
    for (unsigned int i = 0; i < numTokens; i++) 
    { 
    std::string token = GetClangString(clang_getTokenSpelling(translationUnit, tokens[i])); 
    if (token == "(") 
    { 
     insideBrackets = true; 
    } 
    else if (token == "{" || token == ";") 
    { 
     break; 
    } 
    else if (token == ")") 
    { 
     insideBrackets = false; 
    } 
    else if (clang_getTokenKind(tokens[i]) == CXToken_Keyword && 
      !insideBrackets) 
    { 
     qualifiers.insert(token); 
    } 
    } 

    clang_disposeTokens(translationUnit, tokens, numTokens); 
} 

Se un metodo indicizzati da cursor è dichiarata const caso può essere controllata attraverso i seguenti comandi:

std::set<std::string> qualifiers; 
GetMethodQualifiers(translationUnit, qualifiers, cursor); 
bool isConstant = (qualifiers.find("const") != qualifiers.end()); 
0

Ho fornito il codice in this SO answer che contiene il codice di analisi per clang_getCursorUSR (basato sul codice sorgente di LLVM 3.1).