Пример #1
0
QualType
ClassTemplateDecl::getInjectedClassNameSpecialization() {
  Common *CommonPtr = getCommonPtr();
  if (!CommonPtr->InjectedClassNameType.isNull())
    return CommonPtr->InjectedClassNameType;

  // C++0x [temp.dep.type]p2:
  //  The template argument list of a primary template is a template argument 
  //  list in which the nth template argument has the value of the nth template
  //  parameter of the class template. If the nth template parameter is a 
  //  template parameter pack (14.5.3), the nth template argument is a pack 
  //  expansion (14.5.3) whose pattern is the name of the template parameter 
  //  pack.
  ASTContext &Context = getASTContext();
  TemplateParameterList *Params = getTemplateParameters();
  llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
  TemplateArgs.reserve(Params->size());
  for (TemplateParameterList::iterator Param = Params->begin(),
                                    ParamEnd = Params->end();
       Param != ParamEnd; ++Param) {
    TemplateArgument Arg;
    if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
      QualType ArgType = Context.getTypeDeclType(TTP);
      if (TTP->isParameterPack())
        ArgType = Context.getPackExpansionType(ArgType, 
                                               llvm::Optional<unsigned>());
      
      Arg = TemplateArgument(ArgType);
    } else if (NonTypeTemplateParmDecl *NTTP =
                 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
      Expr *E = new (Context) DeclRefExpr(NTTP,
                                  NTTP->getType().getNonLValueExprType(Context),
                                  Expr::getValueKindForType(NTTP->getType()),
                                          NTTP->getLocation());

      if (NTTP->isParameterPack())
        E = new (Context) PackExpansionExpr(Context.DependentTy, E,
                                            NTTP->getLocation(),
                                            llvm::Optional<unsigned>());
      Arg = TemplateArgument(E);
    } else {
      TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
      if (TTP->isParameterPack())
        Arg = TemplateArgument(TemplateName(TTP), llvm::Optional<unsigned>());
      else
        Arg = TemplateArgument(TemplateName(TTP));
    }
    
    if ((*Param)->isTemplateParameterPack())
      Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
    
    TemplateArgs.push_back(Arg);
  }

  CommonPtr->InjectedClassNameType
    = Context.getTemplateSpecializationType(TemplateName(this),
                                            &TemplateArgs[0],
                                            TemplateArgs.size());
  return CommonPtr->InjectedClassNameType;
}
Пример #2
0
QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
    if (!CommonPtr->InjectedClassNameType.isNull())
        return CommonPtr->InjectedClassNameType;

    // FIXME: n2800 14.6.1p1 should say how the template arguments
    // corresponding to template parameter packs should be pack
    // expansions. We already say that in 14.6.2.1p2, so it would be
    // better to fix that redundancy.

    TemplateParameterList *Params = getTemplateParameters();
    llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
    TemplateArgs.reserve(Params->size());
    for (TemplateParameterList::iterator Param = Params->begin(),
            ParamEnd = Params->end();
            Param != ParamEnd; ++Param) {
        if (isa<TemplateTypeParmDecl>(*Param)) {
            QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param));
            TemplateArgs.push_back(TemplateArgument(ParamType));
        } else if (NonTypeTemplateParmDecl *NTTP =
                       dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
            Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(),
                                                NTTP->getLocation());
            TemplateArgs.push_back(TemplateArgument(E));
        } else {
            TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
            TemplateArgs.push_back(TemplateArgument(TemplateName(TTP)));
        }
    }

    CommonPtr->InjectedClassNameType
        = Context.getTemplateSpecializationType(TemplateName(this),
                &TemplateArgs[0],
                TemplateArgs.size());
    return CommonPtr->InjectedClassNameType;
}
Пример #3
0
bool ClassTemplateToClass::isValidClassTemplateDecl(ClassTemplateDecl *TmplD)
{
  TemplateParameterList *TPList = TmplD->getTemplateParameters();
  if (TPList->size() != 1)
    return false;

  CXXRecordDecl *CXXRD = TmplD->getTemplatedDecl();
  CXXRecordDecl *Def = CXXRD->getDefinition();
  if (!Def)
    return true;

  NamedDecl *ND = TPList->getParam(0);
  if (dyn_cast<NonTypeTemplateParmDecl>(ND))
    return true;

  if (isUsedNamedDecl(ND, Def))
    return false;

  SmallVector<ClassTemplatePartialSpecializationDecl *, 10> PartialDecls;
  TmplD->getPartialSpecializations(PartialDecls);
  for (SmallVector<ClassTemplatePartialSpecializationDecl *, 10>::iterator 
         I = PartialDecls.begin(), E = PartialDecls.end(); I != E; ++I) {
    if (hasUsedNameDecl(*I))
      return false;
  }

  return true;
}
Пример #4
0
ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
  TemplateParameterList *Params = getTemplateParameters();
  Common *CommonPtr = getCommonPtr();
  if (!CommonPtr->InjectedArgs) {
    CommonPtr->InjectedArgs
      = new (getASTContext()) TemplateArgument[Params->size()];
    GenerateInjectedTemplateArgs(getASTContext(), Params,
                                 CommonPtr->InjectedArgs);
  }

  return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
}
void InstantiateTemplateParam::removeTemplateKeyword()
{
  if (dyn_cast<ClassTemplateDecl>(TheTemplateDecl))
    return;
  TemplateParameterList *TPList = TheTemplateDecl->getTemplateParameters();
  if (TPList->size() != 1)
    return;
  const NamedDecl *ND = TPList->getParam(0); (void)ND;
  TransAssert((ND == TheParameter) && "Invalid template parameter!");
  TheRewriter.RemoveText(SourceRange(TPList->getTemplateLoc(),
                                     TPList->getRAngleLoc()));
}
Пример #6
0
std::pair<const TemplateArgument *, unsigned> 
FunctionTemplateDecl::getInjectedTemplateArgs() {
  TemplateParameterList *Params = getTemplateParameters();
  Common *CommonPtr = getCommonPtr();
  if (!CommonPtr->InjectedArgs) {
    CommonPtr->InjectedArgs
      = new (getASTContext()) TemplateArgument [Params->size()];
    GenerateInjectedTemplateArgs(getASTContext(), Params, 
                                 CommonPtr->InjectedArgs);
  }
  
  return std::make_pair(CommonPtr->InjectedArgs, Params->size());
}
void InstantiateTemplateParam::handleOneTemplateSpecialization(
       const TemplateDecl *D, const TemplateArgumentList & ArgList)
{
  if (isInIncludedFile(D))
    return;

  NamedDecl *ND = D->getTemplatedDecl();
  TemplateParameterSet ParamsSet;
  TemplateParameterVisitor ParameterVisitor(ParamsSet);
  ParameterVisitor.TraverseDecl(ND);

  if (ParamsSet.size() == 0)
    return;

  unsigned NumArgs = ArgList.size(); (void)NumArgs;
  unsigned Idx = 0;
  TemplateParameterList *TPList = D->getTemplateParameters();
  for (TemplateParameterList::const_iterator I = TPList->begin(),
       E = TPList->end(); I != E; ++I) {
    const NamedDecl *ND = (*I);
    // make it simple, skip NonTypeTemplateParmDecl and 
    // TemplateTemplateParmDecl for now
    const TemplateTypeParmDecl *TyParmDecl = 
      dyn_cast<TemplateTypeParmDecl>(ND);
    if (!TyParmDecl || TyParmDecl->isParameterPack() || !ParamsSet.count(ND)) {
      Idx++;
      continue;
    }

    TransAssert((Idx < NumArgs) && "Invalid Idx!");
    const TemplateArgument &Arg = ArgList.get(Idx);
    std::string ArgStr;
    std::string ForwardStr;
    if (!getTemplateArgumentString(Arg, ArgStr, ForwardStr))
      continue;
    ValidInstanceNum++;
    if (ValidInstanceNum == TransformationCounter) {
      TheInstantiationString = ArgStr;
      TheParameter = ND;
      TheTemplateDecl = D;
      TheForwardDeclString = ForwardStr;
    }
  }
}
Пример #8
0
void TemplateArgToInt::collectInvalidParamIdx(
       const TemplateDecl *D,
       TemplateParameterIdxSet &InvalidParamIdx)
{
  TemplateParameterSet InvalidParams;
  NamedDecl *ND = D->getTemplatedDecl();
  TemplateInvalidParameterVisitor ParameterVisitor(InvalidParams, this);
  ParameterVisitor.TraverseDecl(ND);

  TemplateParameterList *TPList = D->getTemplateParameters();
  unsigned Idx = 0;
  for (TemplateParameterList::const_iterator I = TPList->begin(),
       E = TPList->end(); I != E; ++I) {
    const NamedDecl *ParamND = (*I);
    ParamToTemplateDecl[ParamND] = D;
    if (InvalidParams.count(ParamND)) {
      TransAssert(!InvalidParamIdx.count(Idx) && "Duplicate Index!");
      InvalidParamIdx.insert(Idx);
    }
    Idx++;
  }
}
Пример #9
0
QualType
ClassTemplateDecl::getInjectedClassNameSpecialization() {
  Common *CommonPtr = getCommonPtr();
  if (!CommonPtr->InjectedClassNameType.isNull())
    return CommonPtr->InjectedClassNameType;

  // C++0x [temp.dep.type]p2:
  //  The template argument list of a primary template is a template argument 
  //  list in which the nth template argument has the value of the nth template
  //  parameter of the class template. If the nth template parameter is a 
  //  template parameter pack (14.5.3), the nth template argument is a pack 
  //  expansion (14.5.3) whose pattern is the name of the template parameter 
  //  pack.
  ASTContext &Context = getASTContext();
  TemplateParameterList *Params = getTemplateParameters();
  SmallVector<TemplateArgument, 16> TemplateArgs;
  TemplateArgs.resize(Params->size());
  GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
  CommonPtr->InjectedClassNameType
    = Context.getTemplateSpecializationType(TemplateName(this),
                                            &TemplateArgs[0],
                                            TemplateArgs.size());
  return CommonPtr->InjectedClassNameType;
}
Пример #10
0
bool ClassTemplateToClass::hasUsedNameDecl(
       ClassTemplatePartialSpecializationDecl *PartialD)
{
  if (!PartialD->isCompleteDefinition())
    return false;

  SmallPtrSet<NamedDecl *, 8> Params;
  TemplateParameterList *PartialTPList = PartialD->getTemplateParameters();
  for (unsigned PI = 0; PI < PartialTPList->size(); ++PI) {
    NamedDecl *ND = PartialTPList->getParam(PI);
    if (dyn_cast<NonTypeTemplateParmDecl>(ND))
      continue;
    Params.insert(ND);  
  }

  TemplateParameterTypeVisitor ParamVisitor(Context);

  // Skip visiting parameters and arguments
  for (CXXRecordDecl::base_class_iterator I = PartialD->bases_begin(),
       E = PartialD->bases_end(); I != E; ++I) {
    ParamVisitor.TraverseType(I->getType());
  }

  DeclContext *Ctx = dyn_cast<DeclContext>(PartialD);
  for (DeclContext::decl_iterator DI = Ctx->decls_begin(), 
       DE = Ctx->decls_end(); DI != DE; ++DI) {
    ParamVisitor.TraverseDecl(*DI);
  }

  for (SmallPtrSet<NamedDecl *, 8>::iterator I = Params.begin(), 
       E = Params.end(); I != E; ++I) {
    if (ParamVisitor.isAUsedParameter(*I))
      return true;
  }
  return false;
}
Пример #11
0
void TemplateNonTypeArgToInt::handleOneTemplateDecl(const TemplateDecl *D)
{
  if (isInIncludedFile(D))
    return;
  TemplateParameterIdxSet *ValidParamIdx = new TemplateParameterIdxSet();
  TemplateParameterList *TPList = D->getTemplateParameters();
  unsigned Idx = 0;
  for (TemplateParameterList::const_iterator I = TPList->begin(),
       E = TPList->end(); I != E; ++I) {
    const NamedDecl *ParamND = (*I);
    if (isValidParameter(ParamND)) {
      ValidParamIdx->insert(Idx);
      if (const ValueDecl* ValD = dyn_cast<ValueDecl>(ParamND)) {
        ++ValidInstanceNum;
        if (ValidInstanceNum == TransformationCounter)
          TheValueDecl = ValD;
      }
    }
    Idx++;
  }

  TransAssert(!DeclToParamIdx[D] && "Duplicate TemplateDecl!");
  DeclToParamIdx[dyn_cast<TemplateDecl>(D->getCanonicalDecl())] = ValidParamIdx;
}
bool ReduceClassTemplateParameterASTVisitor::VisitClassTemplateDecl(
       ClassTemplateDecl *D)
{
  if (ConsumerInstance->isInIncludedFile(D))
    return true;

  ClassTemplateDecl *CanonicalD = D->getCanonicalDecl();
  if (ConsumerInstance->VisitedDecls.count(CanonicalD))
    return true;

  ConsumerInstance->VisitedDecls.insert(CanonicalD);
  if (!ConsumerInstance->isValidClassTemplateDecl(D))
    return true;

  TemplateParameterSet ParamsSet;
  TemplateParameterVisitor ParameterVisitor(ParamsSet);
  CXXRecordDecl *CXXRD = D->getTemplatedDecl();
  CXXRecordDecl *Def = CXXRD->getDefinition();
  if (Def)
    ParameterVisitor.TraverseDecl(Def);

  // ISSUE: we should also check the parameter usage for partial template
  //        specializations. For example:
  //   template<typename T1, typename T2> struct S{};
  //   template<typename T1, typename T2> struct<T1 *, T2 *> S{...};
  //   T1 or T2 could be used in "..."
  // Also, we could have another bad transformation, for example,
  //   template<bool, typename T> struct S{};
  //   template<typename T> struct<true, T> S{};
  // if we remove bool and true, we will have two definitions for S
  TemplateParameterList *TPList;
  if (Def) {
    // make sure we use the params as in ParameterVisitor
    const ClassTemplateDecl *CT = Def->getDescribedClassTemplate();
    TransAssert(CT && "NULL DescribedClassTemplate!");
    TPList = CT->getTemplateParameters();
  }
  else {
    TPList = CanonicalD->getTemplateParameters();
  }

  unsigned Index = 0;
  for (TemplateParameterList::const_iterator I = TPList->begin(),
       E = TPList->end(); I != E; ++I) {
    const NamedDecl *ND = (*I);
    if (ParamsSet.count(ND)) {
      Index++;
      continue;
    }

    ConsumerInstance->ValidInstanceNum++;
    if (ConsumerInstance->ValidInstanceNum == 
        ConsumerInstance->TransformationCounter) {
      ConsumerInstance->TheClassTemplateDecl = CanonicalD;
      ConsumerInstance->TheParameterIndex = Index;
      ConsumerInstance->TheTemplateName = new TemplateName(CanonicalD);
      ConsumerInstance->setDefaultArgFlag(ND);
    }
    Index++;
  }

  return true;
}