Basic support for representing elaborated type specifiers
directly in the AST.  The current thinking is to create these
only in C++ mode for efficiency.  But for now, they're not being
created at all; patch to follow.

This will let us do things like verify that tags match during
template instantation, as well as signal that an elaborated type
specifier was used for clients that actually care.

Optimally, the TypeLoc hierarchy should be adjusted to carry tag
location information as well.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81057 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 1143b30..780b1fd 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -733,6 +733,10 @@
     break;
   }
 
+  case Type::Elaborated: {
+    return getTypeInfo(cast<ElaboratedType>(T)->getUnderlyingType().getTypePtr());
+  }
+
   case Type::Typedef: {
     const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl();
     if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) {
@@ -1901,6 +1905,25 @@
   return QualType(T, 0);    
 }
 
+QualType
+ASTContext::getElaboratedType(QualType UnderlyingType,
+                              ElaboratedType::TagKind Tag) {
+  llvm::FoldingSetNodeID ID;
+  ElaboratedType::Profile(ID, UnderlyingType, Tag);
+  
+  void *InsertPos = 0;
+  ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
+  if (T)
+    return QualType(T, 0);
+
+  QualType Canon = getCanonicalType(UnderlyingType);
+
+  T = new (*this) ElaboratedType(UnderlyingType, Tag, Canon);
+  Types.push_back(T);
+  ElaboratedTypes.InsertNode(T, InsertPos);
+  return QualType(T, 0);
+}
+
 /// CmpProtocolNames - Comparison predicate for sorting protocols
 /// alphabetically.
 static bool CmpProtocolNames(const ObjCProtocolDecl *LHS,