kadircet created this revision.
kadircet added a reviewer: ilya-biryukov.
Herald added a subscriber: cfe-commits.

Repository:
  rC Clang

https://reviews.llvm.org/D52301

Files:
  include/clang/AST/PrettyPrinter.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/TypePrinter.cpp
  lib/Frontend/ASTConsumers.cpp
  lib/Sema/SemaChecking.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaLambda.cpp
  lib/Sema/SemaStmt.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
  test/Analysis/scopes-cfg-output.cpp
  test/Driver/Xarch.c
  test/SemaOpenCL/to_addr_builtin.cl

Index: test/SemaOpenCL/to_addr_builtin.cl
===================================================================
--- test/SemaOpenCL/to_addr_builtin.cl
+++ test/SemaOpenCL/to_addr_builtin.cl
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -verify -fsyntax-only %s
-// RUN: %clang_cc1 -Wconversion -verify -fsyntax-only -cl-std=CL2.0 %s
+// RUN: %clang_cc1 -verify -fsyntax-only -cl-std=CL2.0 %s
 
 void test(void) {
   global int *glob;
@@ -43,15 +43,13 @@
   // expected-warning@-2{{incompatible integer to pointer conversion assigning to '__local int *' from 'int'}}
 #else
   // expected-error@-4{{assigning '__global int *' to '__local int *' changes address space of pointer}}
-  // expected-warning@-5{{passing non-generic address space pointer to to_global may cause dynamic conversion affecting performance}}
 #endif
 
   global char *glob_c = to_global(loc);
 #if __OPENCL_C_VERSION__ < CL_VERSION_2_0
   // expected-warning@-2{{incompatible integer to pointer conversion initializing '__global char *' with an expression of type 'int'}}
 #else
   // expected-warning@-4{{incompatible pointer types initializing '__global char *' with an expression of type '__global int *'}}
-  // expected-warning@-5{{passing non-generic address space pointer to to_global may cause dynamic conversion affecting performance}}
 #endif
 
 }
Index: test/Driver/Xarch.c
===================================================================
--- test/Driver/Xarch.c
+++ test/Driver/Xarch.c
@@ -1,12 +1,9 @@
-// RUN: %clang -target i386-apple-darwin9 -m32 -Xarch_i386 -O2 %s -S -### 2>&1 | FileCheck -check-prefix=O2ONCE %s
-// O2ONCE: "-O2"
-// O2ONCE-NOT: "-O2"
+// RUN: %clang -target i386-apple-darwin9 -m32 -Xarch_i386 -O2 %s -S -### 2> %t.log
+// RUN: grep ' "-O2" ' %t.log | count 1
+// RUN: %clang -target i386-apple-darwin9 -m64 -Xarch_i386 -O2 %s -S -### 2> %t.log
+// RUN: not grep ' "-O2" ' %t.log
+// RUN: grep "argument unused during compilation: '-Xarch_i386 -O2'" %t.log
+// RUN: not %clang -target i386-apple-darwin9 -m32 -Xarch_i386 -o -Xarch_i386 -S %s -S -Xarch_i386 -o 2> %t.log
+// RUN: grep "error: invalid Xarch argument: '-Xarch_i386 -o'" %t.log | count 2
+// RUN: grep "error: invalid Xarch argument: '-Xarch_i386 -S'" %t.log
 
-// RUN: %clang -target i386-apple-darwin9 -m64 -Xarch_i386 -O2 %s -S -### 2>&1 | FileCheck -check-prefix=O2NONE %s
-// O2NONE-NOT: "-O2"
-// O2NONE: argument unused during compilation: '-Xarch_i386 -O2'
-
-// RUN: not %clang -target i386-apple-darwin9 -m32 -Xarch_i386 -o -Xarch_i386 -S %s -S -Xarch_i386 -o 2>&1 | FileCheck -check-prefix=INVALID %s
-// INVALID: error: invalid Xarch argument: '-Xarch_i386 -o'
-// INVALID: error: invalid Xarch argument: '-Xarch_i386 -S'
-// INVALID: error: invalid Xarch argument: '-Xarch_i386 -o'
Index: test/Analysis/scopes-cfg-output.cpp
===================================================================
--- test/Analysis/scopes-cfg-output.cpp
+++ test/Analysis/scopes-cfg-output.cpp
@@ -820,7 +820,7 @@
 // CHECK-NEXT:   3: __end1
 // CHECK-NEXT:   4: [B2.3] (ImplicitCastExpr, LValueToRValue, class A *)
 // CHECK-NEXT:   5: [B2.2] != [B2.4]
-// CHECK-NEXT:   T: for (auto &i : [B5.4]) {
+// CHECK-NEXT:   T: for (A &i : [B5.4]) {
 // CHECK:         [B4.11];
 // CHECK-NEXT:}
 // CHECK-NEXT:   Preds (2): B3 B5
@@ -835,7 +835,7 @@
 // CHECK-NEXT:   2: __begin1
 // CHECK-NEXT:   3: [B4.2] (ImplicitCastExpr, LValueToRValue, class A *)
 // CHECK-NEXT:   4: *[B4.3]
-// CHECK-NEXT:   5: auto &i = *__begin1;
+// CHECK-NEXT:   5: A &i = *__begin1;
 // CHECK-NEXT:   6: operator=
 // CHECK-NEXT:   7: [B4.6] (ImplicitCastExpr, FunctionToPointerDecay, class A &(*)(const class A &)
 // CHECK-NEXT:   8: i
@@ -850,16 +850,16 @@
 // CHECK-NEXT:   2:  (CXXConstructExpr, [B5.3], class A [10])
 // CHECK-NEXT:   3: A a[10];
 // CHECK-NEXT:   4: a
-// CHECK-NEXT:   5: auto &&__range1 = a;
+// CHECK-NEXT:   5: A (&__range1)[10] = a;
 // CHECK-NEXT:   6: CFGScopeBegin(__end1)
 // CHECK-NEXT:   7: __range1
 // CHECK-NEXT:   8: [B5.7] (ImplicitCastExpr, ArrayToPointerDecay, class A *)
 // CHECK-NEXT:   9: 10
 // CHECK-NEXT:  10: [B5.8] + [B5.9]
-// CHECK-NEXT:  11: auto __end1 = __range1 + 10
+// CHECK-NEXT:  11: A *__end1 = __range1 + 10
 // CHECK-NEXT:  12: __range1
 // CHECK-NEXT:  13: [B5.12] (ImplicitCastExpr, ArrayToPointerDecay, class A *)
-// CHECK-NEXT:  14: auto __begin1 = __range1;
+// CHECK-NEXT:  14: A *__begin1 = __range1;
 // CHECK-NEXT:   Preds (1): B6
 // CHECK-NEXT:   Succs (1): B2
 // CHECK:      [B0 (EXIT)]
Index: lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
===================================================================
--- lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
+++ lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
@@ -351,6 +351,8 @@
   }
 
   bool VisitTypeLoc(TypeLoc Loc) {
+    if(Loc.getTypeLocClass() == TypeLoc::Auto)
+      return true;
     auto Parents = Context.getParents(Loc);
     TypeLoc ParentTypeLoc;
     if (!Parents.empty()) {
Index: lib/Sema/SemaTemplateDeduction.cpp
===================================================================
--- lib/Sema/SemaTemplateDeduction.cpp
+++ lib/Sema/SemaTemplateDeduction.cpp
@@ -4340,19 +4340,20 @@
       return E;
     }
 
-    QualType Apply(TypeLoc TL) {
+    TypeSourceInfo* Apply(TypeLoc TL) {
       // Create some scratch storage for the transformed type locations.
       // FIXME: We're just going to throw this information away. Don't build it.
       TypeLocBuilder TLB;
       TLB.reserve(TL.getFullDataSize());
-      return TransformType(TLB, TL);
+      QualType Result = TransformType(TLB, TL);
+      return TLB.getTypeSourceInfo(getSema().Context, Result);
     }
   };
 
 } // namespace
 
 Sema::DeduceAutoResult
-Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, QualType &Result,
+Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, TypeSourceInfo *&Result,
                      Optional<unsigned> DependentDeductionDepth) {
   return DeduceAutoType(Type->getTypeLoc(), Init, Result,
                         DependentDeductionDepth);
@@ -4398,7 +4399,7 @@
 ///        'auto' template parameters. The value specified is the template
 ///        parameter depth at which we should perform 'auto' deduction.
 Sema::DeduceAutoResult
-Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result,
+Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, TypeSourceInfo *&Result,
                      Optional<unsigned> DependentDeductionDepth) {
   if (Init->getType()->isNonOverloadPlaceholderType()) {
     ExprResult NonPlaceholder = CheckPlaceholderExpr(Init);
@@ -4410,7 +4411,8 @@
   if (!DependentDeductionDepth &&
       (Type.getType()->isDependentType() || Init->isTypeDependent())) {
     Result = SubstituteDeducedTypeTransform(*this, QualType()).Apply(Type);
-    assert(!Result.isNull() && "substituting DependentTy can't fail");
+    assert(Result && !Result->getType().isNull() &&
+           "substituting DependentTy can't fail");
     return DAR_Succeeded;
   }
 
@@ -4433,7 +4435,7 @@
       // FIXME: Support a non-canonical deduced type for 'auto'.
       Deduced = Context.getCanonicalType(Deduced);
       Result = SubstituteDeducedTypeTransform(*this, Deduced).Apply(Type);
-      if (Result.isNull())
+      if (!Result || Result->getType().isNull())
         return DAR_FailedAlreadyDiagnosed;
       return DAR_Succeeded;
     } else if (!getLangOpts().CPlusPlus) {
@@ -4456,10 +4458,10 @@
   FixedSizeTemplateParameterListStorage<1, false> TemplateParamsSt(
       Loc, Loc, TemplParamPtr, Loc, nullptr);
 
-  QualType FuncParam =
-      SubstituteDeducedTypeTransform(*this, TemplArg, /*UseTypeSugar*/false)
+  TypeSourceInfo *FuncParamTSI =
+      SubstituteDeducedTypeTransform(*this, TemplArg, /*UseTypeSugar*/ false)
           .Apply(Type);
-  assert(!FuncParam.isNull() &&
+  assert(!FuncParamTSI->getType().isNull() &&
          "substituting template parameter for 'auto' failed");
 
   // Deduce type of TemplParam in Func(Init)
@@ -4474,7 +4476,8 @@
                              ArrayRef<SourceRange> Ranges) -> DeduceAutoResult {
     if (Init->isTypeDependent()) {
       Result = SubstituteDeducedTypeTransform(*this, QualType()).Apply(Type);
-      assert(!Result.isNull() && "substituting DependentTy can't fail");
+      assert(Result && !Result->getType().isNull() &&
+             "substituting DependentTy can't fail");
       return DAR_Succeeded;
     }
     if (diagnoseAutoDeductionFailure(*this, TDK, Info, Ranges))
@@ -4514,8 +4517,9 @@
     }
 
     if (auto TDK = DeduceTemplateArgumentsFromCallArgument(
-            *this, TemplateParamsSt.get(), 0, FuncParam, Init, Info, Deduced,
-            OriginalCallArgs, /*Decomposed*/ false, /*ArgIdx*/ 0, /*TDF*/ 0))
+            *this, TemplateParamsSt.get(), 0, FuncParamTSI->getType(), Init,
+            Info, Deduced, OriginalCallArgs, /*Decomposed*/ false, /*ArgIdx*/ 0,
+            /*TDF*/ 0))
       return DeductionFailed(TDK, {});
   }
 
@@ -4532,18 +4536,18 @@
   }
 
   Result = SubstituteDeducedTypeTransform(*this, DeducedType).Apply(Type);
-  if (Result.isNull())
+  if (!Result || Result->getType().isNull())
     return DAR_FailedAlreadyDiagnosed;
 
   // Check that the deduced argument type is compatible with the original
   // argument type per C++ [temp.deduct.call]p4.
-  QualType DeducedA = InitList ? Deduced[0].getAsType() : Result;
+  QualType DeducedA = InitList ? Deduced[0].getAsType() : Result->getType();
   for (const OriginalCallArg &OriginalArg : OriginalCallArgs) {
     assert((bool)InitList == OriginalArg.DecomposedParam &&
            "decomposed non-init-list in auto deduction?");
     if (auto TDK =
             CheckOriginalCallArgDeduction(*this, Info, OriginalArg, DeducedA)) {
-      Result = QualType();
+      Result = nullptr;
       return DeductionFailed(TDK, {});
     }
   }
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -6157,9 +6157,10 @@
     Optional<unsigned> Depth;
     if (CTAK != CTAK_Specified)
       Depth = Param->getDepth() + 1;
+    TypeSourceInfo *ParamTypeTSI = nullptr;
     if (DeduceAutoType(
             Context.getTrivialTypeSourceInfo(ParamType, Param->getLocation()),
-            Arg, ParamType, Depth) == DAR_Failed) {
+            Arg, ParamTypeTSI, Depth) == DAR_Failed) {
       Diag(Arg->getExprLoc(),
            diag::err_non_type_template_parm_type_deduction_failure)
         << Param->getDeclName() << Param->getType() << Arg->getType()
@@ -6171,7 +6172,8 @@
     // an error. The error message normally references the parameter
     // declaration, but here we'll pass the argument location because that's
     // where the parameter type is deduced.
-    ParamType = CheckNonTypeTemplateParameterType(ParamType, Arg->getExprLoc());
+    ParamType = CheckNonTypeTemplateParameterType(ParamTypeTSI->getType(),
+                                                  Arg->getExprLoc());
     if (ParamType.isNull()) {
       Diag(Param->getLocation(), diag::note_template_param_here);
       return ExprError();
Index: lib/Sema/SemaStmt.cpp
===================================================================
--- lib/Sema/SemaStmt.cpp
+++ lib/Sema/SemaStmt.cpp
@@ -1883,7 +1883,7 @@
     CheckObjCForCollectionOperand(ForLoc, collection);
 
   if (First) {
-    QualType FirstType;
+    TypeSourceInfo* FirstTypeTSI;
     if (DeclStmt *DS = dyn_cast<DeclStmt>(First)) {
       if (!DS->isSingleDecl())
         return StmtError(Diag((*DS->decl_begin())->getLocation(),
@@ -1893,28 +1893,28 @@
       if (!D || D->isInvalidDecl())
         return StmtError();
 
-      FirstType = D->getType();
+      FirstTypeTSI = D->getTypeSourceInfo();
       // C99 6.8.5p3: The declaration part of a 'for' statement shall only
       // declare identifiers for objects having storage class 'auto' or
       // 'register'.
       if (!D->hasLocalStorage())
         return StmtError(Diag(D->getLocation(),
                               diag::err_non_local_variable_decl_in_for));
 
       // If the type contained 'auto', deduce the 'auto' to 'id'.
-      if (FirstType->getContainedAutoType()) {
+      if (FirstTypeTSI->getType()->getContainedAutoType()) {
         OpaqueValueExpr OpaqueId(D->getLocation(), Context.getObjCIdType(),
                                  VK_RValue);
         Expr *DeducedInit = &OpaqueId;
-        if (DeduceAutoType(D->getTypeSourceInfo(), DeducedInit, FirstType) ==
+        if (DeduceAutoType(D->getTypeSourceInfo(), DeducedInit, FirstTypeTSI) ==
                 DAR_Failed)
           DiagnoseAutoDeductionFailure(D, DeducedInit);
-        if (FirstType.isNull()) {
+        if (FirstTypeTSI->getType().isNull()) {
           D->setInvalidDecl();
           return StmtError();
         }
 
-        D->setType(FirstType);
+        D->setType(FirstTypeTSI->getType());
 
         if (!inTemplateInstantiation()) {
           SourceLocation Loc =
@@ -1931,16 +1931,17 @@
             Diag(First->getBeginLoc(), diag::err_selector_element_not_lvalue)
             << First->getSourceRange());
 
-      FirstType = static_cast<Expr*>(First)->getType();
+      QualType FirstType = static_cast<Expr*>(First)->getType();
       if (FirstType.isConstQualified())
         Diag(ForLoc, diag::err_selector_element_const_type)
           << FirstType << First->getSourceRange();
+      FirstTypeTSI = this->Context.getTrivialTypeSourceInfo(FirstType);
     }
-    if (!FirstType->isDependentType() &&
-        !FirstType->isObjCObjectPointerType() &&
-        !FirstType->isBlockPointerType())
+    if (!FirstTypeTSI->getType()->isDependentType() &&
+        !FirstTypeTSI->getType()->isObjCObjectPointerType() &&
+        !FirstTypeTSI->getType()->isBlockPointerType())
         return StmtError(Diag(ForLoc, diag::err_selector_element_type)
-                           << FirstType << First->getSourceRange());
+                           << FirstTypeTSI->getType() << First->getSourceRange());
   }
 
   if (CollectionExprResult.isInvalid())
@@ -1969,16 +1970,17 @@
 
   // Deduce the type for the iterator variable now rather than leaving it to
   // AddInitializerToDecl, so we can produce a more suitable diagnostic.
-  QualType InitType;
+  TypeSourceInfo* InitTypeTSI = nullptr;
   if ((!isa<InitListExpr>(Init) && Init->getType()->isVoidType()) ||
-      SemaRef.DeduceAutoType(Decl->getTypeSourceInfo(), Init, InitType) ==
+      SemaRef.DeduceAutoType(Decl->getTypeSourceInfo(), Init, InitTypeTSI) ==
           Sema::DAR_Failed)
     SemaRef.Diag(Loc, DiagID) << Init->getType();
-  if (InitType.isNull()) {
+  if (!InitTypeTSI || InitTypeTSI->getType().isNull()) {
     Decl->setInvalidDecl();
     return true;
   }
-  Decl->setType(InitType);
+  Decl->setType(InitTypeTSI->getType());
+  Decl->setTypeSourceInfo(InitTypeTSI);
 
   // In ARC, infer lifetime.
   // FIXME: ARC may want to turn this into 'const __unsafe_unretained' if
@@ -3384,7 +3386,8 @@
   if (RetExpr) {
     //  Otherwise, [...] deduce a value for U using the rules of template
     //  argument deduction.
-    DeduceAutoResult DAR = DeduceAutoType(OrigResultType, RetExpr, Deduced);
+    TypeSourceInfo* DeducedTSI = nullptr;
+    DeduceAutoResult DAR = DeduceAutoType(OrigResultType, RetExpr, DeducedTSI);
 
     if (DAR == DAR_Failed && !FD->isInvalidDecl())
       Diag(RetExpr->getExprLoc(), diag::err_auto_fn_deduction_failure)
@@ -3397,6 +3400,7 @@
     // referenced.
     LocalTypedefNameReferencer Referencer(*this);
     Referencer.TraverseType(RetExpr->getType());
+    Deduced = DeducedTSI->getType();
   } else {
     //  In the case of a return with no operand, the initializer is considered
     //  to be void().
Index: lib/Sema/SemaLambda.cpp
===================================================================
--- lib/Sema/SemaLambda.cpp
+++ lib/Sema/SemaLambda.cpp
@@ -747,7 +747,7 @@
   // Deduce the type of the init capture.
   QualType DeducedType = deduceVarTypeFromInitializer(
       /*VarDecl*/nullptr, DeclarationName(Id), DeductType, TSI,
-      SourceRange(Loc, Loc), IsDirectInit, Init);
+      SourceRange(Loc, Loc), IsDirectInit, Init).first;
   if (DeducedType.isNull())
     return QualType();
 
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -1840,14 +1840,14 @@
       Diag(Initializer->getBeginLoc(), diag::ext_auto_new_list_init)
           << AllocType << TypeRange;
     Expr *Deduce = Inits[0];
-    QualType DeducedType;
-    if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) == DAR_Failed)
+    TypeSourceInfo* DeducedTypeTSI = nullptr;
+    if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedTypeTSI) == DAR_Failed)
       return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure)
                        << AllocType << Deduce->getType()
                        << TypeRange << Deduce->getSourceRange());
-    if (DeducedType.isNull())
+    if (DeducedTypeTSI->getType().isNull())
       return ExprError();
-    AllocType = DeducedType;
+    AllocType = DeducedTypeTSI->getType();
   }
 
   // Per C++0x [expr.new]p5, the type being constructed may be a
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -10763,7 +10763,7 @@
   };
 } // end anonymous namespace
 
-QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
+std::pair<QualType, TypeSourceInfo*> Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
                                             DeclarationName Name, QualType Type,
                                             TypeSourceInfo *TSI,
                                             SourceRange Range, bool DirectInit,
@@ -10788,7 +10788,7 @@
         VDecl->isStaticDataMember()) {
       Diag(VDecl->getLocation(), diag::err_auto_var_requires_init)
         << VDecl->getDeclName() << Type;
-      return QualType();
+      return {QualType(), nullptr};
     }
   }
 
@@ -10808,8 +10808,8 @@
         VDecl->getLocation(), DirectInit, Init);
     // FIXME: Initialization should not be taking a mutable list of inits.
     SmallVector<Expr*, 8> InitsCopy(DeduceInits.begin(), DeduceInits.end());
-    return DeduceTemplateSpecializationFromInitializer(TSI, Entity, Kind,
-                                                       InitsCopy);
+    return {DeduceTemplateSpecializationFromInitializer(TSI, Entity, Kind,
+                                                       InitsCopy), nullptr};
   }
 
   if (DirectInit) {
@@ -10825,33 +10825,33 @@
                                   ? diag::err_init_capture_no_expression
                                   : diag::err_auto_var_init_no_expression)
         << VN << Type << Range;
-    return QualType();
+    return {QualType(), nullptr};
   }
 
   if (DeduceInits.size() > 1) {
     Diag(DeduceInits[1]->getBeginLoc(),
          IsInitCapture ? diag::err_init_capture_multiple_expressions
                        : diag::err_auto_var_init_multiple_expressions)
         << VN << Type << Range;
-    return QualType();
+    return {QualType(), nullptr};
   }
 
   Expr *DeduceInit = DeduceInits[0];
   if (DirectInit && isa<InitListExpr>(DeduceInit)) {
     Diag(Init->getBeginLoc(), IsInitCapture
                                   ? diag::err_init_capture_paren_braces
                                   : diag::err_auto_var_init_paren_braces)
         << isa<InitListExpr>(Init) << VN << Type << Range;
-    return QualType();
+    return {QualType(), nullptr};
   }
 
   // Expressions default to 'id' when we're in a debugger.
   bool DefaultedAnyToId = false;
   if (getLangOpts().DebuggerCastResultToId &&
       Init->getType() == Context.UnknownAnyTy && !IsInitCapture) {
     ExprResult Result = forceUnknownAnyToType(Init, Context.getObjCIdType());
     if (Result.isInvalid()) {
-      return QualType();
+      return {QualType(), nullptr};
     }
     Init = Result.get();
     DefaultedAnyToId = true;
@@ -10863,11 +10863,11 @@
   if (VDecl && isa<DecompositionDecl>(VDecl) &&
       Context.hasSameUnqualifiedType(Type, Context.getAutoDeductType()) &&
       DeduceInit->getType()->isConstantArrayType())
-    return Context.getQualifiedType(DeduceInit->getType(),
-                                    Type.getQualifiers());
+    return {Context.getQualifiedType(DeduceInit->getType(),
+                                    Type.getQualifiers()), nullptr};
 
-  QualType DeducedType;
-  if (DeduceAutoType(TSI, DeduceInit, DeducedType) == DAR_Failed) {
+  TypeSourceInfo* DeducedTypeTSI = nullptr;
+  if (DeduceAutoType(TSI, DeduceInit, DeducedTypeTSI) == DAR_Failed) {
     if (!IsInitCapture)
       DiagnoseAutoDeductionFailure(VDecl, DeduceInit);
     else if (isa<InitListExpr>(Init))
@@ -10891,25 +10891,29 @@
   // We only want to warn outside of template instantiations, though:
   // inside a template, the 'id' could have come from a parameter.
   if (!inTemplateInstantiation() && !DefaultedAnyToId && !IsInitCapture &&
-      !DeducedType.isNull() && DeducedType->isObjCIdType()) {
+      DeducedTypeTSI && !DeducedTypeTSI->getType().isNull() &&
+      DeducedTypeTSI->getType()->isObjCIdType()) {
     SourceLocation Loc = TSI->getTypeLoc().getBeginLoc();
     Diag(Loc, diag::warn_auto_var_is_id) << VN << Range;
   }
 
-  return DeducedType;
+  return {DeducedTypeTSI ? DeducedTypeTSI->getType() : QualType(),
+          DeducedTypeTSI};
 }
 
 bool Sema::DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit,
                                          Expr *Init) {
-  QualType DeducedType = deduceVarTypeFromInitializer(
+  auto DeducedTypeAndTSI = deduceVarTypeFromInitializer(
       VDecl, VDecl->getDeclName(), VDecl->getType(), VDecl->getTypeSourceInfo(),
       VDecl->getSourceRange(), DirectInit, Init);
-  if (DeducedType.isNull()) {
+  if (DeducedTypeAndTSI.first.isNull()) {
     VDecl->setInvalidDecl();
     return true;
   }
 
-  VDecl->setType(DeducedType);
+  VDecl->setType(DeducedTypeAndTSI.first);
+  if (DeducedTypeAndTSI.second)
+    VDecl->setTypeSourceInfo(DeducedTypeAndTSI.second);
   assert(VDecl->isLinkageValid());
 
   // In ARC, infer lifetime.
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -849,13 +849,6 @@
     return true;
   }
 
-  if (RT->getPointeeType().getAddressSpace() != LangAS::opencl_generic) {
-    S.Diag(Call->getArg(0)->getBeginLoc(),
-           diag::warn_opencl_generic_address_space_arg)
-        << Call->getDirectCallee()->getNameInfo().getAsString()
-        << Call->getArg(0)->getSourceRange();
-  }
-
   RT = RT->getPointeeType();
   auto Qual = RT.getQualifiers();
   switch (BuiltinID) {
Index: lib/Frontend/ASTConsumers.cpp
===================================================================
--- lib/Frontend/ASTConsumers.cpp
+++ lib/Frontend/ASTConsumers.cpp
@@ -89,6 +89,9 @@
           Out << "Not a DeclContext\n";
       } else if (OutputKind == Print) {
         PrintingPolicy Policy(D->getASTContext().getLangOpts());
+        // Since ASTPrinter is used for pretty printing and auto is generally
+        // prettier than real type itself, we'll choose to print auto always.
+        Policy.UseDeducedType = false;
         D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
       } else if (OutputKind != None)
         D->dump(Out, OutputKind == DumpFull);
Index: lib/AST/TypePrinter.cpp
===================================================================
--- lib/AST/TypePrinter.cpp
+++ lib/AST/TypePrinter.cpp
@@ -1010,7 +1010,7 @@
 
 void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
   // If the type has been deduced, do not print 'auto'.
-  if (!T->getDeducedType().isNull()) {
+  if (Policy.UseDeducedType && !T->getDeducedType().isNull()) {
     printBefore(T->getDeducedType(), OS);
   } else {
     switch (T->getKeyword()) {
@@ -1024,7 +1024,7 @@
 
 void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
   // If the type has been deduced, do not print 'auto'.
-  if (!T->getDeducedType().isNull())
+  if (Policy.UseDeducedType && !T->getDeducedType().isNull())
     printAfter(T->getDeducedType(), OS);
 }
 
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -7031,10 +7031,12 @@
   };
 
   DeduceAutoResult
-  DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer, QualType &Result,
+  DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer,
+                 TypeSourceInfo *&Result,
                  Optional<unsigned> DependentDeductionDepth = None);
   DeduceAutoResult
-  DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer, QualType &Result,
+  DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer,
+                 TypeSourceInfo *&Result,
                  Optional<unsigned> DependentDeductionDepth = None);
   void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init);
   bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc,
@@ -7049,10 +7051,10 @@
       TypeSourceInfo *TInfo, const InitializedEntity &Entity,
       const InitializationKind &Kind, MultiExprArg Init);
 
-  QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name,
-                                        QualType Type, TypeSourceInfo *TSI,
-                                        SourceRange Range, bool DirectInit,
-                                        Expr *Init);
+  std::pair<QualType, TypeSourceInfo *>
+  deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name,
+                               QualType Type, TypeSourceInfo *TSI,
+                               SourceRange Range, bool DirectInit, Expr *Init);
 
   TypeLoc getReturnTypeLoc(FunctionDecl *FD) const;
 
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -8613,10 +8613,6 @@
   "invalid prototype, variadic arguments are not allowed in OpenCL">;
 def err_opencl_requires_extension : Error<
   "use of %select{type|declaration}0 %1 requires %2 extension to be enabled">;
-def warn_opencl_generic_address_space_arg : Warning<
-  "passing non-generic address space pointer to %0"
-  " may cause dynamic conversion affecting performance">,
-  InGroup<Conversion>, DefaultIgnore;
 
 // OpenCL v2.0 s6.13.6 -- Builtin Pipe Functions
 def err_opencl_builtin_pipe_first_arg : Error<
Index: include/clang/AST/PrettyPrinter.h
===================================================================
--- include/clang/AST/PrettyPrinter.h
+++ include/clang/AST/PrettyPrinter.h
@@ -52,7 +52,7 @@
       Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
       IncludeNewlines(true), MSVCFormatting(false),
       ConstantsAsWritten(false), SuppressImplicitBase(false),
-      FullyQualifiedName(false) { }
+      FullyQualifiedName(false), UseDeducedType(true) { }
 
   /// Adjust this printing policy for cases where it's known that we're
   /// printing C++ code (for instance, if AST dumping reaches a C++-only
@@ -225,6 +225,11 @@
   /// When true, print the fully qualified name of function declarations.
   /// This is the opposite of SuppressScope and thus overrules it.
   unsigned FullyQualifiedName : 1;
+
+  /// When true, prints deduced type for auto typed variables if their type has
+  /// been deduced. When false, always prints auto(or other variants e.g.
+  /// decltype(auto)) even if type was deduced.
+  unsigned UseDeducedType : 1;
 };
 
 } // end namespace clang
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to