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