[cfe-users] dissecting the type of a VarDecl

folkert via cfe-users cfe-users at lists.llvm.org
Fri Sep 16 05:37:51 PDT 2016


Hi,

I have a VarDecl instance for which I want to dissect the type.
E.g. a const int a would be a const, an int and the name a /
std::vector<std::string> would be namespace std, vector and so on.

The first one is easy but the second one: I have no idea where to begin.

Sofar I have the following:

#include <unistd.h>
#include <vector>
#include <clang/Tooling/Tooling.h>

using namespace clang;

void printQT(ASTContext *const Context, const QualType x)
{
        if (x.isNull())
                return;

        QualType type = x.getNonReferenceType();

        for(;!type.isNull();) {
                if (type.hasQualifiers()) {
                        Qualifiers q = type.getQualifiers();

                        if (q.hasConst())
                                printf("const ");

                        if (q.hasVolatile())
                                printf("volatile ");

                        if (q.hasRestrict())
                                printf("restrict ");
                }

                const Type *t = type.getTypePtr();

                if (!t) {
                        printf("null?\n");
                        break;
                }
                else if (t -> isPointerType())
                        printf("* ");
                else if (t -> isFundamentalType()) {
                        std::string curType = type.getUnqualifiedType().getAsString();

                        printf("[F]%s ", curType.c_str());
                        break; // should be last entry in this chain
                }
                else {
                        std::string curType = type.getUnqualifiedType().getAsString();
// dissect

                        printf("%s ", curType.c_str());
                        break; // should be last entry in this chain
                }

                type = type->getPointeeType();
        }

        printf("\n");
}

int main(int argc, char **argv)
{
        FILE *fh = fopen("example.cpp", "r");

        fseek(fh, 0, SEEK_END);
        size_t len = ftell(fh);
        fseek(fh, 0, SEEK_SET);
        char *buf = (char *)malloc(len + 1);
        fread(buf, 1, len, fh);
        buf[len] = 0x00;
        fclose(fh);

        llvm::Twine code(buf);

        std::vector<std::string> arguments;
        arguments.push_back("-resource-dir=/usr/local/llvm/lib/clang/4.0.0");

        std::unique_ptr<ASTUnit> au = clang::tooling::buildASTFromCodeWithArgs(code, arguments, llvm::Twine("example.cpp"));

        for(clang::ASTUnit::top_level_iterator dit = au -> top_level_begin(); dit != au -> top_level_end(); dit++)
        {
                if (isa<VarDecl>(*dit)) {
                        const VarDecl *vd = static_cast<const VarDecl *>(*dit);
                        printQT(&au -> getASTContext(), vd -> getType());
                }
        }

        return 0;
}



Folkert van Heusden



More information about the cfe-users mailing list