Preliminary support for template alias.

GetPartiallyDesaguredType now desugar template alias
but does not yet properly propagate the opaque typedef
and thus:

  template <typename T> using myvector = std::vector<T>;
  myvector<Double32_t> vd32d;

  template<class T> using ptr = T*;
  ptr<Double32_t> p3;

Both currently result in the Double32_t being ignored.
This commit is contained in:
Philippe Canal 2014-03-21 09:48:31 -05:00 committed by sftnight
parent 45895aec23
commit 93ce42bdc3
2 changed files with 72 additions and 1 deletions

View File

@ -724,9 +724,15 @@ namespace utils {
//return false;
}
case Type::TemplateSpecialization: {
return false;
//const TemplateSpecializationType* Ty =
// llvm::cast<TemplateSpecializationType>(QTy);
// Too broad, this returns a the target template but with
// canonical argument types.
//if (Ty->isTypeAlias()) {
// QT = Ty->getAliasedType();
// return true;
//}
// Too broad, this returns the canonical type
//if (Ty->isSugared()) {
// QT = Ty->desugar();
// return true;
@ -970,6 +976,38 @@ namespace utils {
if (const TemplateSpecializationType* TST
= dyn_cast<const TemplateSpecializationType>(QT.getTypePtr())) {
if (TST->isTypeAlias()) {
QualType targetType = TST->getAliasedType();
/*
// We really need to find a way to propagate/keep the opaque typedef
// that are available in TST to the aliased type. We would need
// to do something like:
QualType targetType = TST->getAliasedType();
QualType resubst = ReSubstTemplateArg(targetType,TST);
return GetPartiallyDesugaredTypeImpl(Ctx, resubst, TypeConfig,
fullyQualifyType,
fullyQualifyTmpltArg);
// But this is not quite right (ReSubstTemplateArg is from TMetaUtils)
// as it does not resubst for
template <typename T> using myvector = std::vector<T>;
myvector<Double32_t> vd32d;
// and does not work at all for
template<class T> using ptr = T*;
ptr<Double32_t> p2;
// as the target is not a template.
*/
// So for now just return move on with the least lose we can do
return GetPartiallyDesugaredTypeImpl(Ctx, targetType, TypeConfig,
fullyQualifyType,
fullyQualifyTmpltArg);
}
bool mightHaveChanged = false;
llvm::SmallVector<TemplateArgument, 4> desArgs;
unsigned int argi = 0;

View File

@ -70,6 +70,7 @@ namespace NS {
typedef ArrayType<float, typeN + 1> FArray;
typedef int IntNS_t;
}
// Anonymous namespace
@ -107,22 +108,46 @@ public:
EmbeddedTypedef::Embedded4 m_emb4;
Embedded_objects::EmbeddedClasses::Embedded5 m_emb5;
Embedded_objects::EmbeddedTypedef::Embedded6 m_emb6;
typedef std::vector<int> vecint;
vecint* m_iter;
const Eenum m_enum;
typedef vector<int> vecint2;
vecint2* m_iter2;
vector<Double32_t> vd32a;
typedef vector<Double32_t> vecd32t1;
vecd32t1 vd32b;
using vecd32t2 = vector<Double32_t>;
vecd32t2 vd32c;
template <typename T> using myvector = std::vector<T>;
myvector<float> vfa;
// Not yet, the desugar of template alias do not keep the opaque typedef.
// myvector<Double32_t> vd32d;
Double32_t *p1;
template<class T> using ptr = T*;
ptr<float> p2;
// Not yet, the desugar of template alias do not keep the opaque typedef.
// ptr<Double32_t> p3;
};
namespace NS1 {
namespace NS2 {
namespace NS3 {
inline namespace InlinedNamespace {
class InsideInline {};
}
class Point {};
class Inner3 {
public:
Point p1;
NS3::Point p2;
::NS1::NS2::NS3::Point p3;
InsideInline p4;
};
}
}
@ -345,6 +370,14 @@ if (decl) {
// CHECK: std::vector<int> *
// CHECK: const Embedded_objects::Eenum
// CHECK: std::vector<int> *
// CHECK: std::vector<Double32_t>
// CHECK: std::vector<Double32_t>
// CHECK: std::vector<Double32_t>
// CHECK: std::vector<float>
// NOT-YET-CHECK: std::vector<Double32_t>
// CHECK: Double32_t *
// CHECK: float *
// NOT-YET-CHECK: Double32_t *
// In the partial desugaring add support for the case where we have a type
// that point to an already completely desugared template instantiation in