clang-8: получение информации typedef из узла DeclRefExpr в AST

#clang #abstract-syntax-tree #clang-static-analyzer

#clang #абстрактное синтаксическое дерево #clang-статический анализатор

Вопрос:

Ниже приведен тестовый код:

 typedef void (*funcPtrType)()
funcPtrType FPT;

void myFunc(){
    
}

int main(){
    FPT = myFunc;
    FPT();
    return 0;
}
  

И ниже приведена часть дампа AST этого кода:

ASTDump

Мой вопрос в том, из какого API я могу получить информацию ‘void (*) ()’ из узла DeclRefExpr?

dclrfxpr

Уже пробовал динамическое приведение этого узла к VarDecl, но из него я не смог получить указанную мной информацию.

Заранее спасибо.

Ответ №1:

Если у вас есть a DeclRefExpr , это выражение, которое ссылается на объявленный объект. Вызовите getDecl метод, чтобы получить связанный ValueDecl , который является самим объявлением. Для этого объекта вызовите getType , чтобы получить QualType , который является типом, возможно, включая cv-квалификаторы.

Например:

 DeclRefExpr const *dre = ...;      // wherever you got it
ValueDecl const *decl = dre->getDecl();
QualType type = decl->getType();
  

В этом случае типом является a typedef . Чтобы проверить базовый тип, вызовите getTypePtr , чтобы получить неквалифицированный тип, а затем getUnqualifiedDesugaredType пропустить typedef:

 clang::Type const *underType = type.getTypePtr()->getUnqualifiedDesugaredType();
  

Затем вы можете вызвать, например, underType->isPointerType() чтобы узнать, является ли это типом указателя и т. Д. Смотрите Документацию clang::Type для других способов ее запроса.

Если вы хотите получить строковое представление underType , используйте статический QualType::print метод, что-то вроде этого:

 LangOptions lo;
PrintingPolicy pp(lo);
std::string s;
llvm::raw_string_ostream rso(s);
QualType::print(underType, Qualifiers(), rso, lo, llvm::Twine());
errs() << "type as string: "" << rso.str() << ""n";
  

Для вашего примера это выведет:

 type as string: "void (*)()"
  

Комментарии:

1. Спасибо за объяснение, но мой актуальный вопрос заключается в том, как найти объявление указателя после того, как я узнаю, что underType-> isPointerType() является true? Как и в вопросе, мне нужна информация «void (*) ()» в виде строки.

2. Хорошо, я добавил информацию о том, как получить строковое представление типа.

3. Большое вам спасибо, это та информация, которую я искал.