diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-09-15 16:23:51 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-09-15 16:23:51 +0000 |
commit | bf4ea56cdc376cef5a12abf6bf18dc34805c2226 (patch) | |
tree | e154efa0f765c75d233133bf493718f8a7da04db /lib/Sema/SemaTemplate.cpp | |
parent | 6826365294dc82bc6bbfd8a357a4e9ee661fe1ff (diff) |
Implement partial ordering of class template partial specializations
(C++ [temp.class.order]).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81866 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 80 |
1 files changed, 78 insertions, 2 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index ad9328f2ca..175f2dabfe 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -18,7 +18,7 @@ #include "clang/Parse/DeclSpec.h" #include "clang/Basic/LangOptions.h" #include "llvm/Support/Compiler.h" - +#include "llvm/ADT/StringExtras.h" using namespace clang; /// \brief Determine whether the declaration found is acceptable as the name @@ -537,7 +537,8 @@ Sema::ActOnTemplateParameterList(unsigned Depth, Diag(ExportLoc, diag::note_template_export_unsupported); return TemplateParameterList::Create(Context, TemplateLoc, LAngleLoc, - (Decl**)Params, NumParams, RAngleLoc); + (NamedDecl**)Params, NumParams, + RAngleLoc); } Sema::DeclResult @@ -3423,3 +3424,78 @@ QualType Sema::RebuildTypeInCurrentInstantiation(QualType T, SourceLocation Loc, CurrentInstantiationRebuilder Rebuilder(*this, Loc, Name); return Rebuilder.TransformType(T); } + +/// \brief Produces a formatted string that describes the binding of +/// template parameters to template arguments. +std::string +Sema::getTemplateArgumentBindingsText(const TemplateParameterList *Params, + const TemplateArgumentList &Args) { + std::string Result; + + if (!Params || Params->size() == 0) + return Result; + + for (unsigned I = 0, N = Params->size(); I != N; ++I) { + if (I == 0) + Result += "[with "; + else + Result += ", "; + + if (const IdentifierInfo *Id = Params->getParam(I)->getIdentifier()) { + Result += Id->getName(); + } else { + Result += '$'; + Result += llvm::utostr(I); + } + + Result += " = "; + + switch (Args[I].getKind()) { + case TemplateArgument::Null: + Result += "<no value>"; + break; + + case TemplateArgument::Type: { + std::string TypeStr; + Args[I].getAsType().getAsStringInternal(TypeStr, + Context.PrintingPolicy); + Result += TypeStr; + break; + } + + case TemplateArgument::Declaration: { + bool Unnamed = true; + if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Args[I].getAsDecl())) { + if (ND->getDeclName()) { + Unnamed = false; + Result += ND->getNameAsString(); + } + } + + if (Unnamed) { + Result += "<anonymous>"; + } + break; + } + + case TemplateArgument::Integral: { + Result += Args[I].getAsIntegral()->toString(10); + break; + } + + case TemplateArgument::Expression: { + assert(false && "No expressions in deduced template arguments!"); + Result += "<expression>"; + break; + } + + case TemplateArgument::Pack: + // FIXME: Format template argument packs + Result += "<template argument pack>"; + break; + } + } + + Result += ']'; + return Result; +} |