I have a type that I have gotten with this expression:
callExpr->getArg(i)->IgnoreImplicit()->getType()
I am matching it against a set of types that I want to process. Currently
I am doing a string compare with the result of getAsString() and the
desired type. This works for trivial types (int, float, etc.) but it
doesn't scale to more complex types.
Using getAsString() isn't the best way to determine types are the same.
ASTContext has all the things you need to do this. Instead of doing:
QualType Ty = callExpr->getArg(i)->IgnoreImplicit()->getType();
if (Ty.getAsString() == "int") {...}
Use the type comparison function and the saved types by:
if (Context.hasSameType(Ty, Context.IntTy) {...}
How would I test to see if the type is an instantiation of std::vector,
and find the element type of the vector?
This requires a bit more work and you'll need to traverse the many classes
of Type. The specific Type is TemplateSpecializationType.
QualType Ty = callExpr->getArg(i)->IgnoreImplicit()->getType();
const TemplateSpecializationType *TST =
Ty->getAs<TemplateSpecializationType>();
if (!TST) return;
Make sure you are dealing with a template specialization.
TemplatedDecl *TD = TST->getTemplateName().getAsTemplateDecl();
if (!TD) return;
The TemplateDecl stores information about the template being specialized,
from it, you can check:
if (!TD->getIdentifier()->isStr("vector")) return;
if (!TD->isInStdNamespace()) return;
isStr() is a specialized function to check if the identifier matches a
string literal.
isInStdNamespace() checks the namespace, looking through inline namespaces.
if (TST->getNumArgs < 1) return;
Checks that specialization of vector has at least on template argument.
Use "< 1" instead of "!= 1" because std::vector is usually defined with
additional template arguments beyond the first one, but are mostly
defaulted away so users don't see them.
const TemplateArgument &TA = TST->getArg(0);
Get the first template argument.
if (TA.getKind() != TemplateArgument::Type) return;
Make sure the template argument is a type.
QualType ElementType = TA.getAsType();
Retrieve the type from the template argument, which for std::vector is the
element type.