#clang #abstract-syntax-tree #clang-static-analyzer
#clang #абстрактное синтаксическое дерево #clang-статический анализатор
Вопрос:
Ниже приведен тестовый код:
typedef void (*funcPtrType)()
funcPtrType FPT;
void myFunc(){
}
int main(){
FPT = myFunc;
FPT();
return 0;
}
И ниже приведена часть дампа AST этого кода:
Мой вопрос в том, из какого API я могу получить информацию ‘void (*) ()’ из узла DeclRefExpr?
Уже пробовал динамическое приведение этого узла к 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. Большое вам спасибо, это та информация, которую я искал.