Start processing template-ids as types when the template-name refers
to a class template. For example, the template-id 'vector<int>' now
has a nice, sugary type in the type system. What we can do now:

  - Parse template-ids like 'vector<int>' (where 'vector' names a
    class template) and form proper types for them in the type system.
  - Parse icky template-ids like 'A<5>' and 'A<(5 > 0)>' properly,
    using (sadly) a bool in the parser to tell it whether '>' should
    be treated as an operator or not.

This is a baby-step, with major problems and limitations:
  - There are currently two ways that we handle template arguments
  (whether they are types or expressions). These will be merged, and,
  most likely, TemplateArg will disappear.
  - We don't have any notion of the declaration of class template
  specializations or of template instantiations, so all template-ids
  are fancy names for 'int' :)



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64153 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 106d0eb..6ec5062 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -489,6 +489,14 @@
   return dyn_cast<TemplateTypeParmType>(CanonicalType);
 }
 
+const ClassTemplateSpecializationType *
+Type::getClassTemplateSpecializationType() const {
+  // There is no sugar for class template specialization types, so
+  // just return the canonical type pointer if it is the right class.
+  return dyn_cast<ClassTemplateSpecializationType>(CanonicalType);
+}
+
+
 bool Type::isIntegerType() const {
   if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
     return BT->getKind() >= BuiltinType::Bool &&
@@ -882,6 +890,54 @@
   return isa<EnumDecl>(TT->getDecl());
 }
 
+void 
+ClassTemplateSpecializationType::
+packBooleanValues(unsigned NumArgs, bool *Values, uintptr_t *Words) {
+  const unsigned BitsPerWord = sizeof(uintptr_t) * CHAR_BIT;
+
+  for (unsigned PW = 0, NumPackedWords = getNumPackedWords(NumArgs), Arg = 0;
+       PW != NumPackedWords; ++PW) {
+    uintptr_t Word = 0;
+    for (unsigned Bit = 0; Bit < BitsPerWord && Arg < NumArgs; ++Bit, ++Arg) {
+      Word <<= 1;
+      Word |= Values[Arg];
+    }
+    Words[PW] = Word;
+  }
+}
+
+ClassTemplateSpecializationType::
+ClassTemplateSpecializationType(TemplateDecl *T, unsigned NumArgs,
+                                uintptr_t *Args, bool *ArgIsType,
+                                QualType Canon)
+  : Type(ClassTemplateSpecialization, Canon, /*FIXME:Dependent=*/false),
+    Template(T), NumArgs(NumArgs) 
+{
+  uintptr_t *Data = reinterpret_cast<uintptr_t *>(this + 1);
+
+  // Pack the argument-is-type values into the words just after the
+  // class template specialization type.
+  packBooleanValues(NumArgs, ArgIsType, Data);
+
+  // Copy the template arguments after the packed words.
+  Data += getNumPackedWords(NumArgs);
+  for (unsigned Arg = 0; Arg < NumArgs; ++Arg)
+    Data[Arg] = Args[Arg];
+}
+
+uintptr_t
+ClassTemplateSpecializationType::getArgAsOpaqueValue(unsigned Arg) const {
+  const uintptr_t *Data = reinterpret_cast<const uintptr_t *>(this + 1);
+  Data += getNumPackedWords(NumArgs);
+  return Data[Arg];
+}
+
+bool ClassTemplateSpecializationType::isArgType(unsigned Arg) const {
+  const unsigned BitsPerWord = sizeof(uintptr_t) * CHAR_BIT;
+  const uintptr_t *Data = reinterpret_cast<const uintptr_t *>(this + 1);
+  Data += Arg / BitsPerWord;
+  return (*Data >> (Arg % BitsPerWord)) & 0x01;
+}
 
 //===----------------------------------------------------------------------===//
 // Type Printing
@@ -1146,6 +1202,47 @@
     InnerString = Name->getName() + InnerString;
 }
 
+void 
+ClassTemplateSpecializationType::
+getAsStringInternal(std::string &InnerString) const {
+  std::string SpecString = Template->getNameAsString();
+  SpecString += '<';
+  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
+    if (Arg)
+      SpecString += ", ";
+    
+    // Print the argument into a string.
+    std::string ArgString;
+    if (isArgType(Arg))
+      getArgAsType(Arg).getAsStringInternal(ArgString);
+    else {
+      llvm::raw_string_ostream s(ArgString);
+      getArgAsExpr(Arg)->printPretty(s);
+    }
+
+    // If this is the first argument and its string representation
+    // begins with the global scope specifier ('::foo'), add a space
+    // to avoid printing the diagraph '<:'.
+    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
+      SpecString += ' ';
+
+    SpecString += ArgString;
+  }
+
+  // If the last character of our string is '>', add another space to
+  // keep the two '>''s separate tokens. We don't *have* to do this in
+  // C++0x, but it's still good hygiene.
+  if (SpecString[SpecString.size() - 1] == '>')
+    SpecString += ' ';
+
+  SpecString += '>';
+
+  if (InnerString.empty())
+    InnerString.swap(SpecString);
+  else
+    InnerString = SpecString + ' ' + InnerString;
+}
+
 void ObjCInterfaceType::getAsStringInternal(std::string &InnerString) const {
   if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
     InnerString = ' ' + InnerString;