Use Sema's LocInfoType to pass and preserve type source info through the Parser.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79395 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 35a2ae6..8921bae 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -464,6 +464,7 @@
   /// \brief Create a LocInfoType to hold the given QualType and DeclaratorInfo.
   QualType CreateLocInfoType(QualType T, DeclaratorInfo *DInfo);
   DeclarationName GetNameForDeclarator(Declarator &D);
+  static QualType GetTypeFromParser(TypeTy *Ty, DeclaratorInfo **DInfo = 0);
   bool CheckSpecifiedExceptionType(QualType T, const SourceRange &Range);
   bool CheckDistantExceptionSpec(QualType T);
   bool CheckEquivalentExceptionSpec(
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp
index b8dbd18..10da094 100644
--- a/lib/Sema/SemaCXXCast.cpp
+++ b/lib/Sema/SemaCXXCast.cpp
@@ -104,7 +104,8 @@
                         SourceLocation LParenLoc, ExprArg E,
                         SourceLocation RParenLoc) {
   Expr *Ex = E.takeAs<Expr>();
-  QualType DestType = QualType::getFromOpaquePtr(Ty);
+  // FIXME: Preserve type source info.
+  QualType DestType = GetTypeFromParser(Ty);
   SourceRange OpRange(OpLoc, RParenLoc);
   SourceRange DestRange(LAngleBracketLoc, RAngleBracketLoc);
 
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 977aa0f..1889571 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -333,7 +333,7 @@
                                                     SourceLocation CCLoc) {
   NestedNameSpecifier *Prefix 
     = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
-  QualType T = QualType::getFromOpaquePtr(Ty);
+  QualType T = GetTypeFromParser(Ty);
   return NestedNameSpecifier::Create(Context, Prefix, /*FIXME:*/false,
                                      T.getTypePtr());
 }
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 1f2689c..c2e8477 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1564,20 +1564,20 @@
     return DeclarationName(D.getIdentifier());
 
   case Declarator::DK_Constructor: {
-    QualType Ty = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
+    QualType Ty = GetTypeFromParser(D.getDeclaratorIdType());
     return Context.DeclarationNames.getCXXConstructorName(
                                                 Context.getCanonicalType(Ty));
   }
 
   case Declarator::DK_Destructor: {
-    QualType Ty = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
+    QualType Ty = GetTypeFromParser(D.getDeclaratorIdType());
     return Context.DeclarationNames.getCXXDestructorName(
                                                 Context.getCanonicalType(Ty));
   }
 
   case Declarator::DK_Conversion: {
     // FIXME: We'd like to keep the non-canonical type for diagnostics!
-    QualType Ty = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
+    QualType Ty = GetTypeFromParser(D.getDeclaratorIdType());
     return Context.DeclarationNames.getCXXConversionFunctionName(
                                                 Context.getCanonicalType(Ty));
   }
@@ -1651,7 +1651,8 @@
        DS.getTypeSpecType() == DeclSpec::TST_typeofExpr ||
        DS.getTypeSpecType() == DeclSpec::TST_decltype)) {
     if (DeclContext *DC = computeDeclContext(D.getCXXScopeSpec(), true)) {
-      QualType T = QualType::getFromOpaquePtr(DS.getTypeRep());
+      // FIXME: Preserve type source info.
+      QualType T = GetTypeFromParser(DS.getTypeRep());
       EnterDeclaratorContext(S, DC);
       T = RebuildTypeInCurrentInstantiation(T, D.getIdentifierLoc(), Name);
       ExitDeclaratorContext(S);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 9c4c2ab..e2aee5b 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -465,7 +465,7 @@
 
   AdjustDeclIfTemplate(classdecl);
   CXXRecordDecl *Class = cast<CXXRecordDecl>(classdecl.getAs<Decl>());
-  QualType BaseType = QualType::getFromOpaquePtr(basetype);
+  QualType BaseType = GetTypeFromParser(basetype);
   if (CXXBaseSpecifier *BaseSpec = CheckBaseSpecifier(Class, SpecifierRange,
                                                       Virtual, Access,
                                                       BaseType, BaseLoc))
@@ -617,7 +617,7 @@
     // typedef int f();
     // f a;
     //
-    QualType TDType = QualType::getFromOpaquePtr(DS.getTypeRep());
+    QualType TDType = GetTypeFromParser(DS.getTypeRep());
     isFunc = TDType->isFunctionType();
   }
 
@@ -738,7 +738,7 @@
     return Diag(IdLoc, diag::err_mem_init_not_member_or_class)
       << MemberOrBase << SourceRange(IdLoc, RParenLoc);
   
-  QualType BaseType = QualType::getFromOpaquePtr(BaseTy);
+  QualType BaseType = GetTypeFromParser(BaseTy);
 
   return BuildBaseInitializer(BaseType, (Expr **)Args, NumArgs, IdLoc,
                               RParenLoc, ClassDecl);
@@ -1688,7 +1688,7 @@
   //   (7.1.3); however, a typedef-name that names a class shall not
   //   be used as the identifier in the declarator for a destructor
   //   declaration.
-  QualType DeclaratorType = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
+  QualType DeclaratorType = GetTypeFromParser(D.getDeclaratorIdType());
   if (isa<TypedefType>(DeclaratorType)) {
     Diag(D.getIdentifierLoc(), diag::err_destructor_typedef_name)
       << DeclaratorType;
@@ -1814,7 +1814,7 @@
   // C++ [class.conv.fct]p4:
   //   The conversion-type-id shall not represent a function type nor
   //   an array type.
-  QualType ConvType = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
+  QualType ConvType = GetTypeFromParser(D.getDeclaratorIdType());
   if (ConvType->isArrayType()) {
     Diag(D.getIdentifierLoc(), diag::err_conv_function_to_array);
     ConvType = Context.getPointerType(ConvType);
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 8a19b64..573e6a2 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -1668,7 +1668,7 @@
   QualType resultDeclType;
   
   if (ReturnType) {
-    resultDeclType = QualType::getFromOpaquePtr(ReturnType);
+    resultDeclType = GetTypeFromParser(ReturnType);
     
     // Methods cannot return interface types. All ObjC objects are
     // passed by reference.
@@ -1697,7 +1697,7 @@
     if (ArgInfo[i].Type == 0) {
       UnpromotedArgType = ArgType = Context.getObjCIdType();
     } else {
-      UnpromotedArgType = ArgType = QualType::getFromOpaquePtr(ArgInfo[i].Type);
+      UnpromotedArgType = ArgType = GetTypeFromParser(ArgInfo[i].Type);
       // Perform the default array/function conversions (C99 6.7.5.3p[7,8]).
       ArgType = adjustParameterType(ArgType);
     }
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index a7cae8a..4b8cc0e 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1583,7 +1583,8 @@
   if (TyOrEx == 0) return ExprError();
 
   if (isType) {
-    QualType ArgTy = QualType::getFromOpaquePtr(TyOrEx);
+    // FIXME: Preserve type source info.
+    QualType ArgTy = GetTypeFromParser(TyOrEx);
     return CreateSizeOfAlignOfExpr(ArgTy, OpLoc, isSizeof, ArgRange);
   } 
 
@@ -2955,7 +2956,8 @@
 Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty,
                            SourceLocation RParenLoc, ExprArg InitExpr) {
   assert((Ty != 0) && "ActOnCompoundLiteral(): missing type");
-  QualType literalType = QualType::getFromOpaquePtr(Ty);
+  //FIXME: Preserve type source info.
+  QualType literalType = GetTypeFromParser(Ty);
   // FIXME: put back this assert when initializers are worked out.
   //assert((InitExpr != 0) && "ActOnCompoundLiteral(): missing expression");
   Expr *literalExpr = static_cast<Expr*>(InitExpr.get());
@@ -3124,7 +3126,8 @@
          "ActOnCastExpr(): missing type or expr");
 
   Expr *castExpr = (Expr *)Op.get();
-  QualType castType = QualType::getFromOpaquePtr(Ty);
+  //FIXME: Preserve type source info.
+  QualType castType = GetTypeFromParser(Ty);
   
   // If the Expr being casted is a ParenListExpr, handle it specially.
   if (isa<ParenListExpr>(castExpr))
@@ -5410,7 +5413,8 @@
                                                   SourceLocation RPLoc) {
   // FIXME: This function leaks all expressions in the offset components on
   // error.
-  QualType ArgTy = QualType::getFromOpaquePtr(argty);
+  // FIXME: Preserve type source info.
+  QualType ArgTy = GetTypeFromParser(argty);
   assert(!ArgTy.isNull() && "Missing type argument!");
 
   bool Dependent = ArgTy->isDependentType();
@@ -5523,8 +5527,9 @@
 Sema::OwningExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
                                                       TypeTy *arg1,TypeTy *arg2,
                                                       SourceLocation RPLoc) {
-  QualType argT1 = QualType::getFromOpaquePtr(arg1);
-  QualType argT2 = QualType::getFromOpaquePtr(arg2);
+  // FIXME: Preserve type source info.
+  QualType argT1 = GetTypeFromParser(arg1);
+  QualType argT2 = GetTypeFromParser(arg2);
 
   assert((!argT1.isNull() && !argT2.isNull()) && "Missing type argument(s)");
 
@@ -5747,7 +5752,7 @@
 Sema::OwningExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
                                         ExprArg expr, TypeTy *type,
                                         SourceLocation RPLoc) {
-  QualType T = QualType::getFromOpaquePtr(type);
+  QualType T = GetTypeFromParser(type);
   Expr *E = static_cast<Expr*>(expr.get());
   Expr *OrigExpr = E;
   
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 2705d99..7c3f7ec 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -31,7 +31,8 @@
                                      TypeTy *Ty, bool HasTrailingLParen,
                                      const CXXScopeSpec &SS,
                                      bool isAddressOfOperand) {
-  QualType ConvType = QualType::getFromOpaquePtr(Ty);
+  //FIXME: Preserve type source info.
+  QualType ConvType = GetTypeFromParser(Ty);
   CanQualType ConvTypeCanon = Context.getCanonicalType(ConvType);
   DeclarationName ConvName 
     = Context.DeclarationNames.getCXXConversionFunctionName(ConvTypeCanon);
@@ -62,7 +63,11 @@
   NamespaceDecl *StdNs = GetStdNamespace();
   if (!StdNs)
     return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
-  
+
+  if (isType)
+    // FIXME: Preserve type source info.
+    TyOrExpr = GetTypeFromParser(TyOrExpr).getAsOpaquePtr();
+
   IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
   Decl *TypeInfoDecl = LookupQualifiedName(StdNs, TypeInfoII, LookupTagName);
   RecordDecl *TypeInfoRecordDecl = dyn_cast_or_null<RecordDecl>(TypeInfoDecl);
@@ -179,7 +184,8 @@
                                 SourceLocation *CommaLocs,
                                 SourceLocation RParenLoc) {
   assert(TypeRep && "Missing type!");
-  QualType Ty = QualType::getFromOpaquePtr(TypeRep);
+  // FIXME: Preserve type source info.
+  QualType Ty = GetTypeFromParser(TypeRep);
   unsigned NumExprs = exprs.size();
   Expr **Exprs = (Expr**)exprs.get();
   SourceLocation TyBeginLoc = TypeRange.getBegin();
@@ -1051,7 +1057,7 @@
                                                  SourceLocation LParen,
                                                  TypeTy *Ty,
                                                  SourceLocation RParen) {
-  QualType T = QualType::getFromOpaquePtr(Ty);
+  QualType T = GetTypeFromParser(Ty);
   
   // According to http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
   // all traits except __is_class, __is_enum and __is_union require a the type
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 553a32f..3b28fae 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -120,7 +120,8 @@
                                                  SourceLocation LParenLoc,
                                                  TypeTy *ty,
                                                  SourceLocation RParenLoc) {
-  QualType EncodedType = QualType::getFromOpaquePtr(ty);
+  // FIXME: Preserve type source info ?
+  QualType EncodedType = GetTypeFromParser(ty);
 
   return BuildObjCEncodeExpression(AtLoc, EncodedType, RParenLoc);
 }
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index c9281c9..7b29c94 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -215,7 +215,8 @@
                                      TypeTy *DefaultT) {
   TemplateTypeParmDecl *Parm 
     = cast<TemplateTypeParmDecl>(TypeParam.getAs<Decl>());
-  QualType Default = QualType::getFromOpaquePtr(DefaultT);
+  // FIXME: Preserve type source info.
+  QualType Default = GetTypeFromParser(DefaultT);
 
   // C++0x [temp.param]p9:
   // A default template-argument may be specified for any kind of
@@ -921,7 +922,8 @@
   for (unsigned Arg = 0, Last = TemplateArgsIn.size(); Arg != Last; ++Arg) {
     TemplateArgs.push_back(
       ArgIsType[Arg]? TemplateArgument(TemplateArgLocs[Arg],
-                                       QualType::getFromOpaquePtr(Args[Arg]))
+                                       //FIXME: Preserve type source info.
+                                       Sema::GetTypeFromParser(Args[Arg]))
                     : TemplateArgument(reinterpret_cast<Expr *>(Args[Arg])));
   }
 }
@@ -1006,6 +1008,7 @@
   // Build the fully-sugared type for this class template
   // specialization, which refers back to the class template
   // specialization we created or found.
+  //FIXME: Preserve type source info.
   return Context.getTemplateSpecializationType(Name, TemplateArgs,
                                                NumTemplateArgs, CanonType);
 }
@@ -2969,7 +2972,7 @@
 Sema::TypeResult
 Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
                         SourceLocation TemplateLoc, TypeTy *Ty) {
-  QualType T = QualType::getFromOpaquePtr(Ty);
+  QualType T = GetTypeFromParser(Ty);
   NestedNameSpecifier *NNS 
     = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
   const TemplateSpecializationType *TemplateId 
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 0890340..d08722b 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -203,7 +203,7 @@
     assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 &&
            DS.getTypeSpecSign() == 0 &&
            "Can't handle qualifiers on typedef names yet!");
-    Result = QualType::getFromOpaquePtr(DS.getTypeRep());
+    Result = GetTypeFromParser(DS.getTypeRep());
 
     if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {
       if (const ObjCInterfaceType *Interface = Result->getAsObjCInterfaceType())
@@ -247,7 +247,8 @@
     break;
   }
   case DeclSpec::TST_typeofType:
-    Result = QualType::getFromOpaquePtr(DS.getTypeRep());
+    // FIXME: Preserve type source info.
+    Result = GetTypeFromParser(DS.getTypeRep());
     assert(!Result.isNull() && "Didn't get a type for typeof?");
     // TypeQuals handled by caller.
     Result = Context.getTypeOfType(Result);
@@ -777,6 +778,18 @@
   return Context.getBlockPointerType(T).getQualifiedType(Quals);
 }
 
+QualType Sema::GetTypeFromParser(TypeTy *Ty, DeclaratorInfo **DInfo) {
+  QualType QT = QualType::getFromOpaquePtr(Ty);
+  DeclaratorInfo *DI = 0;
+  if (LocInfoType *LIT = dyn_cast<LocInfoType>(QT)) {
+    QT = LIT->getType();
+    DI = LIT->getDeclaratorInfo();
+  }
+  
+  if (DInfo) *DInfo = DI;
+  return QT;
+}
+
 /// GetTypeForDeclarator - Convert the type for the specified
 /// declarator to Type instances. Skip the outermost Skip type
 /// objects.
@@ -1039,7 +1052,8 @@
           llvm::SmallVector<QualType, 4> Exceptions;
           Exceptions.reserve(FTI.NumExceptions);
           for(unsigned ei = 0, ee = FTI.NumExceptions; ei != ee; ++ei) {
-            QualType ET = QualType::getFromOpaquePtr(FTI.Exceptions[ei].Ty);
+            // FIXME: Preserve type source info.
+            QualType ET = GetTypeFromParser(FTI.Exceptions[ei].Ty);
             // Check that the type is valid for an exception spec, and drop it
             // if not.
             if (!CheckSpecifiedExceptionType(ET, FTI.Exceptions[ei].Range))
@@ -1126,7 +1140,8 @@
         llvm::SmallVector<QualType, 4> Exceptions;
         Exceptions.reserve(FTI.NumExceptions);
         for(unsigned ei = 0, ee = FTI.NumExceptions; ei != ee; ++ei) {
-          QualType ET = QualType::getFromOpaquePtr(FTI.Exceptions[ei].Ty);
+          // FIXME: Preserve type source info.
+          QualType ET = GetTypeFromParser(FTI.Exceptions[ei].Ty);
           // Check that the type is valid for an exception spec, and drop it if
           // not.
           if (!CheckSpecifiedExceptionType(ET, FTI.Exceptions[ei].Range))
@@ -1587,7 +1602,9 @@
         << Context.getTypeDeclType(OwnedTag);
   }
 
-  //FIXME: Also pass DeclaratorInfo.
+  if (DInfo)
+    T = CreateLocInfoType(T, DInfo);
+
   return T.getAsOpaquePtr();
 }