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;
    }
}
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;
}
Пример #3
0
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();
}
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;
  }
}
Пример #5
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;
  }
}
Пример #6
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;
}
Пример #7
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;
}
// Adapted from tools\clang\lib\AST\TemplateBase.cpp TemplateArgument::print
void printTemplateArgument(raw_ostream &out, const PrintingPolicy &policy, TemplateArgument const &arg, bool qualifyNames)
{
    switch (arg.getKind()) {
    case TemplateArgument::Null:
        out << "(no value)";
        break;

    case TemplateArgument::Type: {
        PrintingPolicy SubPolicy(policy);
        SubPolicy.SuppressStrongLifetime = true;
        arg.getAsType().print(out, SubPolicy);
        break;
    }

    case TemplateArgument::Declaration: {
        NamedDecl *ND = cast<NamedDecl>(arg.getAsDecl());
        out << '&';
        if (ND->getDeclName()) {
            // FIXME: distinguish between pointer and reference args?
            ND->printQualifiedName(out);
        }
        else {
            out << "(anonymous)";
        }
        break;
    }

    case TemplateArgument::NullPtr:
        out << "nullptr";
        break;

    case TemplateArgument::Template:
        // Orig: arg.getAsTemplate().print(out, policy);
    {
        auto templateName = arg.getAsTemplate();
        printTemplateName(out, policy, templateName, qualifyNames);
        break;
    }

    case TemplateArgument::TemplateExpansion:
        arg.getAsTemplateOrTemplatePattern().print(out, policy);
        out << "...";
        break;

    case TemplateArgument::Integral: {
        printIntegral(arg, out, policy);
        break;
    }

    case TemplateArgument::Expression:
        arg.getAsExpr()->printPretty(out, nullptr, policy);
        break;

    case TemplateArgument::Pack:
        out << "<";
        bool First = true;
        for (const auto &P : arg.pack_elements()) {
            if (First)
                First = false;
            else
                out << ", ";

            P.print(policy, out);
        }
        out << ">";
        break;
    }
}