PR17290: Use 'false' macro in fix-it hint for initializing a variable of type

_Bool in C, if the macro is defined. Also teach FixItUtils to look at whether
the macro was defined at the source location for which it is creating a fixit,
rather than looking at whether it's defined *now*. This is especially relevant
for analysis-based warnings which are delayed until end of TU.

llvm-svn: 191057
This commit is contained in:
Richard Smith
2013-09-20 00:27:40 +00:00
parent b523b9c8d4
commit f7ec86a55b
5 changed files with 32 additions and 21 deletions

View File

@@ -160,27 +160,33 @@ bool ConversionFixItGenerator::tryToFixConversion(const Expr *FullExpr,
return false;
}
static bool isMacroDefined(const Sema &S, StringRef Name) {
return S.PP.getMacroInfo(&S.getASTContext().Idents.get(Name));
static bool isMacroDefined(const Sema &S, SourceLocation Loc, StringRef Name) {
const IdentifierInfo *II = &S.getASTContext().Idents.get(Name);
if (!II->hadMacroDefinition()) return false;
MacroDirective *Macro = S.PP.getMacroDirectiveHistory(II);
return Macro && Macro->findDirectiveAtLoc(Loc, S.getSourceManager());
}
static std::string getScalarZeroExpressionForType(const Type& T, const Sema& S) {
static std::string getScalarZeroExpressionForType(
const Type &T, SourceLocation Loc, const Sema &S) {
assert(T.isScalarType() && "use scalar types only");
// Suggest "0" for non-enumeration scalar types, unless we can find a
// better initializer.
if (T.isEnumeralType())
return std::string();
if ((T.isObjCObjectPointerType() || T.isBlockPointerType()) &&
isMacroDefined(S, "nil"))
isMacroDefined(S, Loc, "nil"))
return "nil";
if (T.isRealFloatingType())
return "0.0";
if (T.isBooleanType() && S.LangOpts.CPlusPlus)
if (T.isBooleanType() &&
(S.LangOpts.CPlusPlus || isMacroDefined(S, Loc, "false")))
return "false";
if (T.isPointerType() || T.isMemberPointerType()) {
if (S.LangOpts.CPlusPlus11)
return "nullptr";
if (isMacroDefined(S, "NULL"))
if (isMacroDefined(S, Loc, "NULL"))
return "NULL";
}
if (T.isCharType())
@@ -194,9 +200,10 @@ static std::string getScalarZeroExpressionForType(const Type& T, const Sema& S)
return "0";
}
std::string Sema::getFixItZeroInitializerForType(QualType T) const {
std::string
Sema::getFixItZeroInitializerForType(QualType T, SourceLocation Loc) const {
if (T->isScalarType()) {
std::string s = getScalarZeroExpressionForType(*T, *this);
std::string s = getScalarZeroExpressionForType(*T, Loc, *this);
if (!s.empty())
s = " = " + s;
return s;
@@ -212,6 +219,7 @@ std::string Sema::getFixItZeroInitializerForType(QualType T) const {
return std::string();
}
std::string Sema::getFixItZeroLiteralForType(QualType T) const {
return getScalarZeroExpressionForType(*T, *this);
std::string
Sema::getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const {
return getScalarZeroExpressionForType(*T, Loc, *this);
}