1f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks//===--- SemaFixItUtils.cpp - Sema FixIts ---------------------------------===//
2f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks//
3f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks//                     The LLVM Compiler Infrastructure
4f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks//
5f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks// This file is distributed under the University of Illinois Open Source
6f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks// License. See LICENSE.TXT for details.
7f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks//
8f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks//===----------------------------------------------------------------------===//
9f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks//
10f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks//  This file defines helper classes for generation of Sema FixItHints.
11f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks//
12f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks//===----------------------------------------------------------------------===//
13f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
14478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer#include "clang/AST/ASTContext.h"
15f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks#include "clang/AST/ExprCXX.h"
16f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks#include "clang/AST/ExprObjC.h"
17f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks#include "clang/Lex/Preprocessor.h"
18f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks#include "clang/Sema/Sema.h"
19f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks#include "clang/Sema/SemaFixItUtils.h"
20f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
21f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaksusing namespace clang;
22f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
23f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaksbool ConversionFixItGenerator::compareTypesSimple(CanQualType From,
24f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks                                                  CanQualType To,
25f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks                                                  Sema &S,
26f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks                                                  SourceLocation Loc,
27f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks                                                  ExprValueKind FromVK) {
28f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  if (!To.isAtLeastAsQualifiedAs(From))
29f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks    return false;
30f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
31f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  From = From.getNonReferenceType();
32f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  To = To.getNonReferenceType();
33f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
34f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  // If both are pointer types, work with the pointee types.
35f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  if (isa<PointerType>(From) && isa<PointerType>(To)) {
36f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks    From = S.Context.getCanonicalType(
37f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks        (cast<PointerType>(From))->getPointeeType());
38f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks    To = S.Context.getCanonicalType(
39f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks        (cast<PointerType>(To))->getPointeeType());
40f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  }
41f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
42f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  const CanQualType FromUnq = From.getUnqualifiedType();
43f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  const CanQualType ToUnq = To.getUnqualifiedType();
44f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
45f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  if ((FromUnq == ToUnq || (S.IsDerivedFrom(FromUnq, ToUnq)) ) &&
46f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      To.isAtLeastAsQualifiedAs(From))
47f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks    return true;
48f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  return false;
49f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks}
50f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
51f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaksbool ConversionFixItGenerator::tryToFixConversion(const Expr *FullExpr,
52f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks                                                  const QualType FromTy,
53f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks                                                  const QualType ToTy,
54f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks                                                  Sema &S) {
55f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  if (!FullExpr)
56f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks    return false;
57f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
58f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  const CanQualType FromQTy = S.Context.getCanonicalType(FromTy);
59f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  const CanQualType ToQTy = S.Context.getCanonicalType(ToTy);
60f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  const SourceLocation Begin = FullExpr->getSourceRange().getBegin();
61f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  const SourceLocation End = S.PP.getLocForEndOfToken(FullExpr->getSourceRange()
62f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks                                                      .getEnd());
63f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
64f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  // Strip the implicit casts - those are implied by the compiler, not the
65f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  // original source code.
66f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  const Expr* Expr = FullExpr->IgnoreImpCasts();
67f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
68f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  bool NeedParen = true;
69f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  if (isa<ArraySubscriptExpr>(Expr) ||
70f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<CallExpr>(Expr) ||
71f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<DeclRefExpr>(Expr) ||
72f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<CastExpr>(Expr) ||
73f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<CXXNewExpr>(Expr) ||
74f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<CXXConstructExpr>(Expr) ||
75f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<CXXDeleteExpr>(Expr) ||
76f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<CXXNoexceptExpr>(Expr) ||
77f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<CXXPseudoDestructorExpr>(Expr) ||
78f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<CXXScalarValueInitExpr>(Expr) ||
79f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<CXXThisExpr>(Expr) ||
80f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<CXXTypeidExpr>(Expr) ||
81f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<CXXUnresolvedConstructExpr>(Expr) ||
82f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<ObjCMessageExpr>(Expr) ||
83f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<ObjCPropertyRefExpr>(Expr) ||
84f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<ObjCProtocolExpr>(Expr) ||
85f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<MemberExpr>(Expr) ||
86f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<ParenExpr>(FullExpr) ||
87f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<ParenListExpr>(Expr) ||
88f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<SizeOfPackExpr>(Expr) ||
89f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      isa<UnaryOperator>(Expr))
90f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks    NeedParen = false;
91f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
92f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  // Check if the argument needs to be dereferenced:
93f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  //   (type * -> type) or (type * -> type &).
94f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  if (const PointerType *FromPtrTy = dyn_cast<PointerType>(FromQTy)) {
95f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks    OverloadFixItKind FixKind = OFIK_Dereference;
96f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
97f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks    bool CanConvert = CompareTypes(
98f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      S.Context.getCanonicalType(FromPtrTy->getPointeeType()), ToQTy,
99f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks                                 S, Begin, VK_LValue);
100f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks    if (CanConvert) {
101f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      // Do not suggest dereferencing a Null pointer.
102f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      if (Expr->IgnoreParenCasts()->
103f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks          isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull))
104f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks        return false;
105f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
106f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(Expr)) {
107f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks        if (UO->getOpcode() == UO_AddrOf) {
108f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks          FixKind = OFIK_RemoveTakeAddress;
109f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks          Hints.push_back(FixItHint::CreateRemoval(
110f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks                            CharSourceRange::getTokenRange(Begin, Begin)));
111f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks        }
112f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      } else if (NeedParen) {
113f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks        Hints.push_back(FixItHint::CreateInsertion(Begin, "*("));
114f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks        Hints.push_back(FixItHint::CreateInsertion(End, ")"));
115f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      } else {
116f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks        Hints.push_back(FixItHint::CreateInsertion(Begin, "*"));
117f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      }
118f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
119f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      NumConversionsFixed++;
120f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      if (NumConversionsFixed == 1)
121f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks        Kind = FixKind;
122f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      return true;
123f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks    }
124f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  }
125f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
126f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  // Check if the pointer to the argument needs to be passed:
127f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  //   (type -> type *) or (type & -> type *).
128f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  if (isa<PointerType>(ToQTy)) {
129f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks    bool CanConvert = false;
130f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks    OverloadFixItKind FixKind = OFIK_TakeAddress;
131f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
132f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks    // Only suggest taking address of L-values.
133f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks    if (!Expr->isLValue() || Expr->getObjectKind() != OK_Ordinary)
134f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      return false;
135f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
136f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks    CanConvert = CompareTypes(S.Context.getPointerType(FromQTy), ToQTy,
137f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks                              S, Begin, VK_RValue);
138f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks    if (CanConvert) {
139f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
140f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(Expr)) {
141f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks        if (UO->getOpcode() == UO_Deref) {
142f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks          FixKind = OFIK_RemoveDereference;
143f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks          Hints.push_back(FixItHint::CreateRemoval(
144f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks                            CharSourceRange::getTokenRange(Begin, Begin)));
145f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks        }
146f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      } else if (NeedParen) {
147f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks        Hints.push_back(FixItHint::CreateInsertion(Begin, "&("));
148f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks        Hints.push_back(FixItHint::CreateInsertion(End, ")"));
149f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      } else {
150f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks        Hints.push_back(FixItHint::CreateInsertion(Begin, "&"));
151f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      }
152f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
153f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      NumConversionsFixed++;
154f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      if (NumConversionsFixed == 1)
155f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks        Kind = FixKind;
156f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks      return true;
157f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks    }
158f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  }
159f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks
160f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks  return false;
161f3546eeef1eed4661b77b93b91a29be1bf5f7d0bAnna Zaks}
1627984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith
163e40141542d96f556b5c1b5e3b8acca8f11c27527Richard Smithstatic bool isMacroDefined(const Sema &S, StringRef Name) {
164e40141542d96f556b5c1b5e3b8acca8f11c27527Richard Smith  return S.PP.getMacroInfo(&S.getASTContext().Idents.get(Name));
165e40141542d96f556b5c1b5e3b8acca8f11c27527Richard Smith}
166e40141542d96f556b5c1b5e3b8acca8f11c27527Richard Smith
1672c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikiestatic std::string getScalarZeroExpressionForType(const Type& T, const Sema& S) {
1682c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie  assert(T.isScalarType() && "use scalar types only");
1692c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie  // Suggest "0" for non-enumeration scalar types, unless we can find a
1702c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie  // better initializer.
1712c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie  if (T.isEnumeralType())
1722c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie    return std::string();
1732c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie  if ((T.isObjCObjectPointerType() || T.isBlockPointerType()) &&
1742c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie      isMacroDefined(S, "nil"))
1752c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie    return "nil";
1762c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie  if (T.isRealFloatingType())
1772c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie    return "0.0";
1782c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie  if (T.isBooleanType() && S.LangOpts.CPlusPlus)
1792c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie    return "false";
1802c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie  if (T.isPointerType() || T.isMemberPointerType()) {
18180ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith    if (S.LangOpts.CPlusPlus11)
1822c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie      return "nullptr";
1832c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie    if (isMacroDefined(S, "NULL"))
1842c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie      return "NULL";
1852c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie  }
1862c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie  if (T.isCharType())
1872c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie    return "'\\0'";
1882c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie  if (T.isWideCharType())
1892c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie    return "L'\\0'";
1902c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie  if (T.isChar16Type())
1912c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie    return "u'\\0'";
1922c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie  if (T.isChar32Type())
1932c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie    return "U'\\0'";
1942c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie  return "0";
1952c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie}
1962c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie
1972c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikiestd::string Sema::getFixItZeroInitializerForType(QualType T) const {
198e40141542d96f556b5c1b5e3b8acca8f11c27527Richard Smith  if (T->isScalarType()) {
1992c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie    std::string s = getScalarZeroExpressionForType(*T, *this);
2002c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie    if (!s.empty())
2012c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie      s = " = " + s;
2022c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie    return s;
203e40141542d96f556b5c1b5e3b8acca8f11c27527Richard Smith  }
204e40141542d96f556b5c1b5e3b8acca8f11c27527Richard Smith
2057984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith  const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
206f037541d5c7dcf3553cf26e4b047be869980c23aRichard Smith  if (!RD || !RD->hasDefinition())
2072c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie    return std::string();
20880ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith  if (LangOpts.CPlusPlus11 && !RD->hasUserProvidedDefaultConstructor())
2097984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith    return "{}";
210f037541d5c7dcf3553cf26e4b047be869980c23aRichard Smith  if (RD->isAggregate())
2117984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith    return " = {}";
2122c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie  return std::string();
2132c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie}
2142c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie
2152c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikiestd::string Sema::getFixItZeroLiteralForType(QualType T) const {
2162c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie  return getScalarZeroExpressionForType(*T, *this);
2177984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith}
218