Exemple #1
0
bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
  if (getKind() != Other.getKind()) return false;

  switch (getKind()) {
  case Null:
  case Type:
  case Declaration:
  case Template:
  case Expression:
    return TypeOrValue == Other.TypeOrValue;

  case Integral:
    return getIntegralType() == Other.getIntegralType() &&
           *getAsIntegral() == *Other.getAsIntegral();

  case Pack:
    if (Args.NumArgs != Other.Args.NumArgs) return false;
    for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
      if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
        return false;
    return true;
  }

  // Suppress warnings.
  return false;
}
void ReduceClassTemplateParameter::removeOneParameterByArgExpression(
       const ClassTemplatePartialSpecializationDecl *PartialD,
       const TemplateArgument &Arg)
{
  TransAssert((Arg.getKind() == TemplateArgument::Expression) && 
              "Arg is not TemplateArgument::Expression!");

  const Expr *E = Arg.getAsExpr();
  TransAssert(E && "Bad Expression!");
  const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts());
  TransAssert(DRE && "Bad DeclRefExpr!");
  const NonTypeTemplateParmDecl *ParmD = 
    dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl());
  TransAssert(ParmD && "Invalid NonTypeTemplateParmDecl!");
  
  const TemplateParameterList *TPList = PartialD->getTemplateParameters();
  unsigned Idx = 0;
  for (TemplateParameterList::const_iterator I = TPList->begin(),
       E = TPList->end(); I != E; ++I) {
    if ((*I) == ParmD)
      break;
    Idx++;
  }

  unsigned NumParams = TPList->size();
  TransAssert((Idx < NumParams) && "Cannot find valid TemplateParameter!");
  (void)NumParams;
  SourceRange Range = ParmD->getSourceRange();
  removeParameterByRange(Range, TPList, Idx);
}
Exemple #3
0
void ODRHash::AddTemplateArgument(TemplateArgument TA) {
  const auto Kind = TA.getKind();
  ID.AddInteger(Kind);
  switch (Kind) {
  case TemplateArgument::Null:
    llvm_unreachable("Require valid TemplateArgument");
  case TemplateArgument::Type:
    AddQualType(TA.getAsType());
    break;
  case TemplateArgument::Declaration:
    AddDecl(TA.getAsDecl());
    break;
  case TemplateArgument::NullPtr:
    AddQualType(TA.getNullPtrType());
    break;
  case TemplateArgument::Integral:
    TA.getAsIntegral().Profile(ID);
    AddQualType(TA.getIntegralType());
    break;
  case TemplateArgument::Template:
  case TemplateArgument::TemplateExpansion:
    AddTemplateName(TA.getAsTemplateOrTemplatePattern());
    break;
  case TemplateArgument::Expression:
    AddStmt(TA.getAsExpr());
    break;
  case TemplateArgument::Pack:
    ID.AddInteger(TA.pack_size());
    for (auto SubTA : TA.pack_elements())
      AddTemplateArgument(SubTA);
    break;
  }
}
Exemple #4
0
/// \brief Print a template integral argument value.
///
/// \param TemplArg the TemplateArgument instance to print.
///
/// \param Out the raw_ostream instance to use for printing.
///
/// \param Policy the printing policy for EnumConstantDecl printing.
static void printIntegral(const TemplateArgument &TemplArg,
                          raw_ostream &Out, const PrintingPolicy& Policy) {
  const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr();
  const llvm::APSInt &Val = TemplArg.getAsIntegral();

  if (const EnumType *ET = T->getAs<EnumType>()) {
    for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) {
      // In Sema::CheckTemplateArugment, enum template arguments value are
      // extended to the size of the integer underlying the enum type.  This
      // may create a size difference between the enum value and template
      // argument value, requiring isSameValue here instead of operator==.
      if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
        ECD->printQualifiedName(Out, Policy);
        return;
      }
    }
  }

  if (T->isBooleanType() && !Policy.MSVCFormatting) {
    Out << (Val.getBoolValue() ? "true" : "false");
  } else if (T->isCharType()) {
    const char Ch = Val.getZExtValue();
    Out << ((Ch == '\'') ? "'\\" : "'");
    Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
    Out << "'";
  } else {
    Out << Val;
  }
}
void ReduceClassTemplateParameter::removeOneParameterByArgTemplate(
       const ClassTemplatePartialSpecializationDecl *PartialD,
       const TemplateArgument &Arg)
{
  TransAssert((Arg.getKind() == TemplateArgument::Template) && 
              "Arg is not TemplateArgument::Template!");
  TemplateName TmplName = Arg.getAsTemplate();
  TransAssert((TmplName.getKind() == TemplateName::Template) &&
              "Invalid TemplateName Kind!");
  const TemplateDecl *TmplD = TmplName.getAsTemplateDecl();

  const TemplateParameterList *TPList = PartialD->getTemplateParameters();
  unsigned Idx = 0;
  for (TemplateParameterList::const_iterator I = TPList->begin(),
       E = TPList->end(); I != E; ++I) {
    if ((*I) == TmplD)
      break;
    Idx++;
  }

  unsigned NumParams = TPList->size();
  TransAssert((Idx < NumParams) && "Cannot find valid TemplateParameter!");
  (void)NumParams;
  SourceRange Range = TmplD->getSourceRange();
  removeParameterByRange(Range, TPList, Idx);
  
  return;
}
Exemple #6
0
bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
  if (getKind() != Other.getKind()) return false;

  switch (getKind()) {
  case Null:
  case Type:
  case Expression:      
  case Template:
  case TemplateExpansion:
  case NullPtr:
    return TypeOrValue.V == Other.TypeOrValue.V;

  case Declaration:
    return getAsDecl() == Other.getAsDecl() && 
           isDeclForReferenceParam() && Other.isDeclForReferenceParam();

  case Integral:
    return getIntegralType() == Other.getIntegralType() &&
           getAsIntegral() == Other.getAsIntegral();

  case Pack:
    if (Args.NumArgs != Other.Args.NumArgs) return false;
    for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
      if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
        return false;
    return true;
  }

  llvm_unreachable("Invalid TemplateArgument Kind!");
}
bool TemplateNonTypeArgToInt::isValidTemplateArgument(
       const TemplateArgument &Arg)
{
  TemplateArgument::ArgKind K = Arg.getKind();
  switch (K) {
  case TemplateArgument::Declaration: {
    return true;
  }

  case TemplateArgument::Expression: {
    const Expr *E = Arg.getAsExpr()->IgnoreParenCasts();
    if (dyn_cast<IntegerLiteral>(E) || dyn_cast<CXXBoolLiteralExpr>(E))
      return false;
    if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
      UnaryOperator::Opcode Op = UO->getOpcode();
      if((Op == UO_Minus) || (Op == UO_Plus))
        return false;
    }

    return true;
  }

  default:
    TransAssert(0 && "Unreachable code!");
    return false;
  }
  TransAssert(0 && "Unreachable code!");
  return false;
}
void ReduceClassTemplateParameter::removeOneParameterFromPartialDecl(
       const ClassTemplatePartialSpecializationDecl *PartialD,
       const TemplateArgument &Arg)
{
  if (!Arg.isInstantiationDependent())
    return;

  TemplateArgument::ArgKind K = Arg.getKind();
  switch (K) {
  case TemplateArgument::Expression:
    removeOneParameterByArgExpression(PartialD, Arg);
    return;

  case TemplateArgument::Template:
    removeOneParameterByArgTemplate(PartialD, Arg);
    return;

  case TemplateArgument::Type:
    removeOneParameterByArgType(PartialD, Arg);
    return;
  
  default:
    TransAssert(0 && "Uncatched ArgKind!");
  }
  TransAssert(0 && "Unreachable code!");
}
void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
    // Mostly repetitive with TemplateArgument::Profile!
    ID.AddInteger(Arg.getKind());
    switch (Arg.getKind()) {
        case TemplateArgument::Null:
            break;

        case TemplateArgument::Type:
            VisitType(Arg.getAsType());
            break;

        case TemplateArgument::Template:
            VisitTemplateName(Arg.getAsTemplate());
            break;

        case TemplateArgument::Declaration:
            VisitDecl(Arg.getAsDecl());
            break;

        case TemplateArgument::Integral:
            Arg.getAsIntegral()->Profile(ID);
            VisitType(Arg.getIntegralType());
            break;

        case TemplateArgument::Expression:
            Visit(Arg.getAsExpr());
            break;

        case TemplateArgument::Pack:
            const TemplateArgument *Pack = Arg.pack_begin();
            for (unsigned i = 0, e = Arg.pack_size(); i != e; ++i)
                VisitTemplateArgument(Pack[i]);
            break;
    }
}
SubstNonTypeTemplateParmPackExpr::
SubstNonTypeTemplateParmPackExpr(QualType T, 
                                 NonTypeTemplateParmDecl *Param,
                                 SourceLocation NameLoc,
                                 const TemplateArgument &ArgPack)
  : Expr(SubstNonTypeTemplateParmPackExprClass, T, VK_RValue, OK_Ordinary, 
         true, true, true, true),
    Param(Param), Arguments(ArgPack.pack_begin()), 
    NumArguments(ArgPack.pack_size()), NameLoc(NameLoc) { }
static void describeTemplateParameter(raw_ostream &Out,
                                      const TemplateArgument &TArg,
                                      const LangOptions &LO) {

  if (TArg.getKind() == TemplateArgument::ArgKind::Pack) {
    describeTemplateParameters(Out, TArg.getPackAsArray(), LO);
  } else {
    TArg.print(PrintingPolicy(LO), Out);
  }
}
Exemple #12
0
Type *
TypeCheck::visit(TemplateArgumentList *ast)
{
	FUNCLOG;
	List<TemplateArgument*>::iterator it = ast->args.begin();
	while (it != ast->args.end()) {
		TemplateArgument *arg = *it;
		arg->accept(this);
		++it;
	}
	return NULL;
}
bool 
InstantiateTemplateParam::getTemplateArgumentString(const TemplateArgument &Arg,
                                                    std::string &ArgStr, 
                                                    std::string &ForwardStr)
{
  ArgStr = "";
  ForwardStr = "";
  if (Arg.getKind() != TemplateArgument::Type)
    return false;
  QualType QT = Arg.getAsType();
  return getTypeString(QT, ArgStr, ForwardStr);
}
Exemple #14
0
CXType clang_Cursor_getTemplateArgumentType(CXCursor C, unsigned I) {
  TemplateArgument TA;
  if (clang_Cursor_getTemplateArgument(C, I, &TA) !=
      CXGetTemplateArgumentStatus_Success) {
    return cxtype::MakeCXType(QualType(), getCursorTU(C));
  }

  if (TA.getKind() != TemplateArgument::Type) {
    return cxtype::MakeCXType(QualType(), getCursorTU(C));
  }

  return cxtype::MakeCXType(TA.getAsType(), getCursorTU(C));
}
Optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) {
  assert(Arg.containsUnexpandedParameterPack());

  // If this is a substituted pack, grab that pack. If not, we don't know
  // the size yet.
  // FIXME: We could find a size in more cases by looking for a substituted
  // pack anywhere within this argument, but that's not necessary in the common
  // case for 'sizeof...(A)' handling.
  TemplateArgument Pack;
  switch (Arg.getKind()) {
  case TemplateArgument::Type:
    if (auto *Subst = Arg.getAsType()->getAs<SubstTemplateTypeParmPackType>())
      Pack = Subst->getArgumentPack();
    else
      return None;
    break;

  case TemplateArgument::Expression:
    if (auto *Subst =
            dyn_cast<SubstNonTypeTemplateParmPackExpr>(Arg.getAsExpr()))
      Pack = Subst->getArgumentPack();
    else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Arg.getAsExpr()))  {
      for (ParmVarDecl *PD : *Subst)
        if (PD->isParameterPack())
          return None;
      return Subst->getNumExpansions();
    } else
      return None;
    break;

  case TemplateArgument::Template:
    if (SubstTemplateTemplateParmPackStorage *Subst =
            Arg.getAsTemplate().getAsSubstTemplateTemplateParmPack())
      Pack = Subst->getArgumentPack();
    else
      return None;
    break;

  case TemplateArgument::Declaration:
  case TemplateArgument::NullPtr:
  case TemplateArgument::TemplateExpansion:
  case TemplateArgument::Integral:
  case TemplateArgument::Pack:
  case TemplateArgument::Null:
    return None;
  }

  // Check that no argument in the pack is itself a pack expansion.
  for (TemplateArgument Elem : Pack.pack_elements()) {
    // There's no point recursing in this case; we would have already
    // expanded this pack expansion into the enclosing pack if we could.
    if (Elem.isPackExpansion())
      return None;
  }
  return Pack.pack_size();
}
Exemple #16
0
long long clang_Cursor_getTemplateArgumentValue(CXCursor C, unsigned I) {
  TemplateArgument TA;
  if (clang_Cursor_getTemplateArgument(C, I, &TA) !=
      CXGetTemplateArgumentStatus_Success) {
    assert(0 && "Unable to retrieve TemplateArgument");
    return 0;
  }

  if (TA.getKind() != TemplateArgument::Integral) {
    assert(0 && "Passed template argument is not Integral");
    return 0;
  }

  return TA.getAsIntegral().getSExtValue();
}
Exemple #17
0
void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
                                                   ASTContext &Context,
                                           TemplateTemplateParmDecl *Parameter,
                                             const TemplateArgument &ArgPack) {
  ID.AddPointer(Parameter);
  ArgPack.Profile(ID, Context);
}
Exemple #18
0
/// \brief Print a template integral argument value.
///
/// \param TemplArg the TemplateArgument instance to print.
///
/// \param Out the raw_ostream instance to use for printing.
static void printIntegral(const TemplateArgument &TemplArg,
                          raw_ostream &Out) {
  const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr();
  const llvm::APSInt &Val = TemplArg.getAsIntegral();

  if (T->isBooleanType()) {
    Out << (Val.getBoolValue() ? "true" : "false");
  } else if (T->isCharType()) {
    const char Ch = Val.getZExtValue();
    Out << ((Ch == '\'') ? "'\\" : "'");
    Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
    Out << "'";
  } else {
    Out << Val;
  }
}
Exemple #19
0
void TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) {
    switch (Arg.getKind()) {
    default:
        break;
    case TemplateArgument::Type:
        assert(Arg.getAsType().isCanonical() && "Type must be canonical!");
        break;
    }

    assert(NumFlatArgs < MaxFlatArgs && "Argument list builder is full!");
    assert(!StructuredArgs &&
           "Can't append arguments when an argument pack has been added!");

    if (!FlatArgs)
        FlatArgs = new TemplateArgument[MaxFlatArgs];

    FlatArgs[NumFlatArgs++] = Arg;
}
// Get |count| number of template arguments. Returns false if there
// are fewer than |count| arguments or any of the arguments are not
// of a valid Type structure. If |count| is non-positive, all
// arguments are collected.
bool RecordInfo::GetTemplateArgs(size_t count, TemplateArgs* output_args) {
  ClassTemplateSpecializationDecl* tmpl =
      dyn_cast<ClassTemplateSpecializationDecl>(record_);
  if (!tmpl)
    return false;
  const TemplateArgumentList& args = tmpl->getTemplateArgs();
  if (args.size() < count)
    return false;
  if (count <= 0)
    count = args.size();
  for (unsigned i = 0; i < count; ++i) {
    TemplateArgument arg = args[i];
    if (arg.getKind() == TemplateArgument::Type && !arg.getAsType().isNull()) {
      output_args->push_back(arg.getAsType().getTypePtr());
    } else {
      return false;
    }
  }
  return true;
}
void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) {
  IndentScope Indent(*this);
  OS << "TemplateArgument";
  if (R.isValid())
    dumpSourceRange(R);

  switch (A.getKind()) {
  case TemplateArgument::Null:
    OS << " null";
    break;
  case TemplateArgument::Type:
    OS << " type";
    dumpType(A.getAsType());
    break;
  case TemplateArgument::Declaration:
    OS << " decl";
    dumpDeclRef(A.getAsDecl());
    break;
  case TemplateArgument::NullPtr:
    OS << " nullptr";
    break;
  case TemplateArgument::Integral:
    OS << " integral " << A.getAsIntegral();
    break;
  case TemplateArgument::Template:
    OS << " template ";
    A.getAsTemplate().dump(OS);
    break;
  case TemplateArgument::TemplateExpansion:
    OS << " template expansion";
    A.getAsTemplateOrTemplatePattern().dump(OS);
    break;
  case TemplateArgument::Expression:
    OS << " expr";
    dumpStmt(A.getAsExpr());
    break;
  case TemplateArgument::Pack:
    OS << " pack";
    for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end();
         I != E; ++I)
      dumpTemplateArgument(*I);
    break;
  }
}
Exemple #22
0
void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
  // Mostly repetitive with TemplateArgument::Profile!
  ID.AddInteger(Arg.getKind());
  switch (Arg.getKind()) {
  case TemplateArgument::Null:
    break;

  case TemplateArgument::Type:
    VisitType(Arg.getAsType());
    break;

  case TemplateArgument::Template:
  case TemplateArgument::TemplateExpansion:
    VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
    break;
      
  case TemplateArgument::Declaration:
    VisitDecl(Arg.getAsDecl());
    break;

  case TemplateArgument::NullPtr:
    VisitType(Arg.getNullPtrType());
    break;

  case TemplateArgument::Integral:
    Arg.getAsIntegral().Profile(ID);
    VisitType(Arg.getIntegralType());
    break;

  case TemplateArgument::Expression:
    Visit(Arg.getAsExpr());
    break;

  case TemplateArgument::Pack:
    for (const auto &P : Arg.pack_elements())
      VisitTemplateArgument(P);
    break;
  }
}
Exemple #23
0
enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(CXCursor C,
                                                                 unsigned I) {
  TemplateArgument TA;
  if (clang_Cursor_getTemplateArgument(C, I, &TA)) {
    return CXTemplateArgumentKind_Invalid;
  }

  switch (TA.getKind()) {
    case TemplateArgument::Null: return CXTemplateArgumentKind_Null;
    case TemplateArgument::Type: return CXTemplateArgumentKind_Type;
    case TemplateArgument::Declaration:
      return CXTemplateArgumentKind_Declaration;
    case TemplateArgument::NullPtr: return CXTemplateArgumentKind_NullPtr;
    case TemplateArgument::Integral: return CXTemplateArgumentKind_Integral;
    case TemplateArgument::Template: return CXTemplateArgumentKind_Template;
    case TemplateArgument::TemplateExpansion:
      return CXTemplateArgumentKind_TemplateExpansion;
    case TemplateArgument::Expression: return CXTemplateArgumentKind_Expression;
    case TemplateArgument::Pack: return CXTemplateArgumentKind_Pack;
  }

  return CXTemplateArgumentKind_Invalid;
}
void InstantiateTemplateParam::getForwardDeclStr(
       const Type *Ty,
       std::string &ForwardStr,
       RecordDeclSet &TempAvailableRecordDecls)
{
  if (const RecordType *RT = Ty->getAsUnionType()) {
    const RecordDecl *RD = RT->getDecl();
    addOneForwardDeclStr(RD, ForwardStr, TempAvailableRecordDecls);
    return;
  }

  const CXXRecordDecl *CXXRD = Ty->getAsCXXRecordDecl();
  if (!CXXRD)
    return;

  const ClassTemplateSpecializationDecl *SpecD = 
    dyn_cast<ClassTemplateSpecializationDecl>(CXXRD);
  if (!SpecD) {
    addOneForwardDeclStr(CXXRD, ForwardStr, TempAvailableRecordDecls);
    return;
  }
  
  addForwardTemplateDeclStr(SpecD->getSpecializedTemplate(),
                            ForwardStr,
                            TempAvailableRecordDecls);

  const TemplateArgumentList &ArgList = SpecD->getTemplateArgs();
  unsigned NumArgs = ArgList.size();
  for (unsigned I = 0; I < NumArgs; ++I) {
    const TemplateArgument Arg = ArgList[I];
    if (Arg.getKind() != TemplateArgument::Type)
      continue;
    getForwardDeclStr(Arg.getAsType().getTypePtr(), 
                      ForwardStr,
                      TempAvailableRecordDecls);
  }
}
Exemple #25
0
void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
  switch (Arg.getKind()) {
  case TemplateArgument::Null:
    break;

  case TemplateArgument::Declaration:
    Visit(Arg.getAsDecl());
    break;

  case TemplateArgument::NullPtr:
    break;

  case TemplateArgument::TemplateExpansion:
    Out << 'P'; // pack expansion of...
    // Fall through
  case TemplateArgument::Template:
    VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
    break;
      
  case TemplateArgument::Expression:
    // FIXME: Visit expressions.
    break;
      
  case TemplateArgument::Pack:
    Out << 'p' << Arg.pack_size();
    for (TemplateArgument::pack_iterator P = Arg.pack_begin(), PEnd = Arg.pack_end();
         P != PEnd; ++P)
      VisitTemplateArgument(*P);
    break;
      
  case TemplateArgument::Type:
    VisitType(Arg.getAsType());
    break;
      
  case TemplateArgument::Integral:
    Out << 'V';
    VisitType(Arg.getIntegralType());
    Out << Arg.getAsIntegral();
    break;
  }
}
Exemple #26
0
static bool getFullyQualifiedTemplateArgument(const ASTContext &Ctx,
                                              TemplateArgument &Arg) {
  bool Changed = false;

  // Note: we do not handle TemplateArgument::Expression, to replace it
  // we need the information for the template instance decl.

  if (Arg.getKind() == TemplateArgument::Template) {
    TemplateName TName = Arg.getAsTemplate();
    Changed = getFullyQualifiedTemplateName(Ctx, TName);
    if (Changed) {
      Arg = TemplateArgument(TName);
    }
  } else if (Arg.getKind() == TemplateArgument::Type) {
    QualType SubTy = Arg.getAsType();
    // Check if the type needs more desugaring and recurse.
    QualType QTFQ = getFullyQualifiedType(SubTy, Ctx);
    if (QTFQ != SubTy) {
      Arg = TemplateArgument(QTFQ);
      Changed = true;
    }
  }
  return Changed;
}
Exemple #27
0
string getTemplateArgumentName(const TemplateArgument & argument)
{
	string qualifiedName;

	switch(argument.getKind()) {
		case TemplateArgument::Null:
			qualifiedName = "NULL";
			break;

		case TemplateArgument::Type:
			qualifiedName = CppType(argument.getAsType()).getQualifiedName();
			break;

		case TemplateArgument::Declaration:
			qualifiedName = dyn_cast<NamedDecl>(argument.getAsDecl())->getQualifiedNameAsString();
			break;

		case TemplateArgument::Integral:
		case TemplateArgument::Expression:
			qualifiedName = exprToText(argument.getAsExpr());
			break;

		case TemplateArgument::Template:
			qualifiedName = argument.getAsTemplate().getAsTemplateDecl()->getQualifiedNameAsString();
			break;

		case TemplateArgument::TemplateExpansion:
			break;

		case TemplateArgument::Pack:
			break;

	}

	return qualifiedName;
}
Exemple #28
0
void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
  switch (Arg.getKind()) {
  case TemplateArgument::Null:
    break;

  case TemplateArgument::Declaration:
    Visit(Arg.getAsDecl());
    break;

  case TemplateArgument::NullPtr:
    break;

  case TemplateArgument::TemplateExpansion:
    Out << 'P'; // pack expansion of...
    LLVM_FALLTHROUGH;
  case TemplateArgument::Template:
    VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
    break;

  case TemplateArgument::Expression:
    // FIXME: Visit expressions.
    break;

  case TemplateArgument::Pack:
    Out << 'p' << Arg.pack_size();
    for (const auto &P : Arg.pack_elements())
      VisitTemplateArgument(P);
    break;

  case TemplateArgument::Type:
    VisitType(Arg.getAsType());
    break;

  case TemplateArgument::Integral:
    Out << 'V';
    VisitType(Arg.getIntegralType());
    Out << Arg.getAsIntegral();
    break;
  }
}
Exemple #29
0
static void PrintTemplateArgument(std::string &Buffer,
                                  const TemplateArgument &Arg,
                                  const PrintingPolicy &Policy) {
  switch (Arg.getKind()) {
    case TemplateArgument::Null:
      assert(false && "Null template argument");
      break;
      
    case TemplateArgument::Type:
      Arg.getAsType().getAsStringInternal(Buffer, Policy);
      break;
      
    case TemplateArgument::Declaration:
      Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString();
      break;
      
    case TemplateArgument::Template: {
      llvm::raw_string_ostream s(Buffer);
      Arg.getAsTemplate().print(s, Policy);
      break;
    }
      
    case TemplateArgument::Integral:
      Buffer = Arg.getAsIntegral()->toString(10, true);
      break;
      
    case TemplateArgument::Expression: {
      llvm::raw_string_ostream s(Buffer);
      Arg.getAsExpr()->printPretty(s, 0, Policy);
      break;
    }
      
    case TemplateArgument::Pack:
      assert(0 && "FIXME: Implement!");
      break;
  }
}
void ReduceClassTemplateParameter::removeOneParameterByArgType(
       const ClassTemplatePartialSpecializationDecl *PartialD,
       const TemplateArgument &Arg)
{
  TransAssert((Arg.getKind() == TemplateArgument::Type) && 
              "Arg is not TemplateArgument::Type!");
  llvm::DenseMap<const Type *, unsigned> TypeToVisitsCount;
  llvm::DenseMap<const Type *, const NamedDecl *> TypeToNamedDecl;
  llvm::DenseMap<const Type *, unsigned> TypeToIndex;

  // retrieve all TemplateTypeParmType
  const TemplateParameterList *TPList = PartialD->getTemplateParameters();
  unsigned Idx = 0;
  for (TemplateParameterList::const_iterator I = TPList->begin(),
       E = TPList->end(); I != E; ++I) {
    const NamedDecl *ND = (*I);
    const TemplateTypeParmDecl *TypeD = dyn_cast<TemplateTypeParmDecl>(ND);
    if (!TypeD) {
      Idx++;
      continue;
    }
    const Type *ParmTy = TypeD->getTypeForDecl();
    TypeToVisitsCount[ParmTy] = 0;
    TypeToNamedDecl[ParmTy] = ND;
    TypeToIndex[ParmTy] = Idx;
  }

  QualType QTy = Arg.getAsType();
  ArgumentDependencyVisitor V(TypeToVisitsCount);
  // collect TemplateTypeParmType being used by Arg
  V.TraverseType(QTy);

  llvm::DenseMap<const Type *, unsigned> DependentTypeToVisitsCount;
  for (llvm::DenseMap<const Type *, unsigned>::iterator 
         I = TypeToVisitsCount.begin(), E = TypeToVisitsCount.end();
       I != E; ++I) {
    if ((*I).second > 0)
      DependentTypeToVisitsCount[(*I).first] = 1;
  }

  // check if the used TemplateTypeParmType[s] have dependencies
  // on other Args. If yes, we cannot remove it from the parameter list.
  // For example:
  //   template <typename T>
  //   struct S <T*, T&> {};
  // removing either of the arguments needs to keep the template 
  // parameter
  ArgumentDependencyVisitor AccumV(DependentTypeToVisitsCount);
  
  const ASTTemplateArgumentListInfo *ArgList = 
    PartialD->getTemplateArgsAsWritten();
  
  const TemplateArgumentLoc *ArgLocs = ArgList->getTemplateArgs();
  unsigned NumArgs = ArgList->NumTemplateArgs;
  TransAssert((TheParameterIndex < NumArgs) && 
               "Bad NumArgs from partial template decl!");
  for (unsigned I = 0; I < NumArgs; ++I) {
    if (I == TheParameterIndex)
      continue;
    
    const TemplateArgumentLoc ArgLoc = ArgLocs[I];
    TemplateArgument OtherArg = ArgLoc.getArgument();
    if (OtherArg.isInstantiationDependent() && 
        (OtherArg.getKind() == TemplateArgument::Type)) {
      QualType QTy = OtherArg.getAsType();
      AccumV.TraverseType(QTy);
    }
  }

  for (llvm::DenseMap<const Type *, unsigned>::iterator 
         I = DependentTypeToVisitsCount.begin(), 
         E = DependentTypeToVisitsCount.end();
       I != E; ++I) {
    if ((*I).second != 1)
      continue;

    const NamedDecl *Param = TypeToNamedDecl[(*I).first];
    TransAssert(Param && "NULL Parameter!");
    SourceRange Range = Param->getSourceRange();
    removeParameterByRange(Range, TPList, TypeToIndex[(*I).first]);
  }
}