2012-03-23 10 views
5

¿Cómo puedo probar si un método C++ está const calificado en clang?Clang Const Qualified C++ Método

Por ejemplo ::

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

estoy usando la biblioteca de sonido metálico-C e I han intentado usar clang_isConstQualifiedType en el nodo inner_method. sin embargo, esto devuelve falso.

No me importa si la respuesta usa los encabezados de cg + cg.

Respuesta

2

En la interfaz C++, la forma de comprobar esto es usando CXXMethodDecl::getTypeQualifiers(), o usando FunctionProtoType::getTypeQuals() (dependiendo de si tiene la declaración o el tipo). El bit Qualifiers::Const indica si el método (o tipo de método) es const.

En la API C de libclang, esta información parece usarse solo en la implementación de getCursorUSR, cuyo resultado no se debe analizar, por lo tanto, usar la API C++ o enviar un parche para agregar esta funcionalidad a la API C las mejores opciones

1

Tuve el mismo problema, pero necesitaba hacerlo sin la API de C++. Puse mi solución a continuación para referencia futura. La idea es utilizar la función de tokenización libclang para recorrer todos los calificadores del método:

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); 
} 

Ya sea un método indexado por cursor se declara const continuación, se puede comprobar a través de los siguientes comandos:

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

He proporcionado el código in this SO answer que contiene el código de análisis para clang_getCursorUSR (basado en el código fuente de LLVM 3.1).