aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-09-15 16:23:51 +0000
committerDouglas Gregor <dgregor@apple.com>2009-09-15 16:23:51 +0000
commitbf4ea56cdc376cef5a12abf6bf18dc34805c2226 (patch)
treee154efa0f765c75d233133bf493718f8a7da04db /lib/Sema/SemaTemplate.cpp
parent6826365294dc82bc6bbfd8a357a4e9ee661fe1ff (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.cpp80
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;
+}