diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Parse/Parser.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 3 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 40 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 18 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 13 |
7 files changed, 65 insertions, 20 deletions
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 5b38f60abe..495d5e51dd 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -740,7 +740,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) { } // The actions module must verify that all arguments were declared. - Actions.ActOnFinishKNRParamDeclarations(CurScope, D); + Actions.ActOnFinishKNRParamDeclarations(CurScope, D, Tok.getLocation()); } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index c442b84669..f9270cf64f 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -368,7 +368,8 @@ public: virtual void SetDeclDeleted(DeclPtrTy dcl, SourceLocation DelLoc); virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, DeclPtrTy *Group, unsigned NumDecls); - virtual void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D); + virtual void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, + SourceLocation LocAfterDecls); virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *S, Declarator &D); virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *S, DeclPtrTy D); virtual void ActOnStartOfObjCMethodDef(Scope *S, DeclPtrTy D); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index e02e2ee876..f67b417ddd 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2041,7 +2041,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, // typedef of void is not permitted. if (getLangOptions().CPlusPlus && Param->getType().getUnqualifiedType() != Context.VoidTy) { - Diag(Param->getLocation(), diag::ext_param_typedef_of_void); + Diag(Param->getLocation(), diag::err_param_typedef_of_void); } } else if (FTI.NumArgs > 0 && FTI.ArgInfo[0].Param != 0) { for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) @@ -2697,7 +2697,8 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { return DeclPtrTy::make(New); } -void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D) { +void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, + SourceLocation LocAfterDecls) { assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function && "Not a function declarator!"); DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun; @@ -2707,8 +2708,13 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D) { if (!FTI.hasPrototype) { for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) { if (FTI.ArgInfo[i].Param == 0) { + std::string Code = "int "; + Code += FTI.ArgInfo[i].Ident->getName(); + Code += ";\n "; Diag(FTI.ArgInfo[i].IdentLoc, diag::ext_param_not_declared) - << FTI.ArgInfo[i].Ident; + << FTI.ArgInfo[i].Ident + << CodeModificationHint::CreateInsertion(LocAfterDecls, Code); + // Implicitly declare the argument as type 'int' for lack of a better // type. DeclSpec DS; @@ -3215,13 +3221,29 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK, // Make sure that this wasn't declared as an enum and now used as a // struct or something similar. if (PrevTagDecl->getTagKind() != Kind) { - Diag(KWLoc, diag::err_use_with_wrong_tag) << Name; + bool SafeToContinue + = (PrevTagDecl->getTagKind() != TagDecl::TK_enum && + Kind != TagDecl::TK_enum); + if (SafeToContinue) + Diag(KWLoc, diag::err_use_with_wrong_tag) + << Name + << CodeModificationHint::CreateReplacement(SourceRange(KWLoc), + PrevTagDecl->getKindName()); + else + Diag(KWLoc, diag::err_use_with_wrong_tag) << Name; Diag(PrevDecl->getLocation(), diag::note_previous_use); - // Recover by making this an anonymous redefinition. - Name = 0; - PrevDecl = 0; - Invalid = true; - } else { + + if (SafeToContinue) + Kind = PrevTagDecl->getTagKind(); + else { + // Recover by making this an anonymous redefinition. + Name = 0; + PrevDecl = 0; + Invalid = true; + } + } + + if (!Invalid) { // If this is a use, just return the declaration we found. // FIXME: In the future, return a variant or some other clue diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index ea2af68d16..c2928dc6cc 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1307,8 +1307,9 @@ bool Sema::CheckConstructor(CXXConstructorDecl *Constructor) { QualType ParamType = Constructor->getParamDecl(0)->getType(); QualType ClassTy = Context.getTagDeclType(ClassDecl); if (Context.getCanonicalType(ParamType).getUnqualifiedType() == ClassTy) { - Diag(Constructor->getLocation(), diag::err_constructor_byvalue_arg) - << SourceRange(Constructor->getParamDecl(0)->getLocation()); + SourceLocation ParamLoc = Constructor->getParamDecl(0)->getLocation(); + Diag(ParamLoc, diag::err_constructor_byvalue_arg) + << CodeModificationHint::CreateInsertion(ParamLoc, "const &"); Invalid = true; } } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 7a25404faa..1540f0a009 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3402,11 +3402,25 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, // operand is null), the user probably wants strcmp. if ((isa<StringLiteral>(LHSStripped) || isa<ObjCEncodeExpr>(LHSStripped)) && !RHSStripped->isNullPointerConstant(Context)) - Diag(Loc, diag::warn_stringcompare) << lex->getSourceRange(); + Diag(Loc, diag::warn_stringcompare) + << lex->getSourceRange() + << CodeModificationHint::CreateReplacement(SourceRange(Loc), ", ") + << CodeModificationHint::CreateInsertion(lex->getLocStart(), + "strcmp(") + << CodeModificationHint::CreateInsertion( + PP.getLocForEndOfToken(rex->getLocEnd()), + ") == 0"); else if ((isa<StringLiteral>(RHSStripped) || isa<ObjCEncodeExpr>(RHSStripped)) && !LHSStripped->isNullPointerConstant(Context)) - Diag(Loc, diag::warn_stringcompare) << rex->getSourceRange(); + Diag(Loc, diag::warn_stringcompare) + << rex->getSourceRange() + << CodeModificationHint::CreateReplacement(SourceRange(Loc), ", ") + << CodeModificationHint::CreateInsertion(lex->getLocStart(), + "strcmp(") + << CodeModificationHint::CreateInsertion( + PP.getLocForEndOfToken(rex->getLocEnd()), + ") == 0"); } // The result of comparisons is 'bool' in C++, 'int' in C. diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index fbf3ae2a78..f8890c389b 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -540,7 +540,9 @@ void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T, if (T->isScalarType()) SemaRef.Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init) - << IList->getSourceRange(); + << IList->getSourceRange() + << CodeModificationHint::CreateRemoval(SourceRange(IList->getLocStart())) + << CodeModificationHint::CreateRemoval(SourceRange(IList->getLocEnd())); } void InitListChecker::CheckListElementTypes(InitListExpr *IList, diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index abc3ac08e9..d30726c766 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -462,12 +462,14 @@ Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK, // template declaration (7.1.5.3). RecordDecl *PrevRecordDecl = PrevClassTemplate->getTemplatedDecl(); if (PrevRecordDecl->getTagKind() != Kind) { - Diag(KWLoc, diag::err_use_with_wrong_tag) << Name; + Diag(KWLoc, diag::err_use_with_wrong_tag) + << Name + << CodeModificationHint::CreateReplacement(KWLoc, + PrevRecordDecl->getKindName()); Diag(PrevRecordDecl->getLocation(), diag::note_previous_use); - return true; + Kind = PrevRecordDecl->getTagKind(); } - // Check for redefinition of this class template. if (TK == TK_Definition) { if (TagDecl *Def = PrevRecordDecl->getDefinition(Context)) { @@ -1974,7 +1976,10 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, case DeclSpec::TST_class: Kind = TagDecl::TK_class; break; } if (ClassTemplate->getTemplatedDecl()->getTagKind() != Kind) { - Diag(KWLoc, diag::err_use_with_wrong_tag) << ClassTemplate; + Diag(KWLoc, diag::err_use_with_wrong_tag) + << ClassTemplate + << CodeModificationHint::CreateReplacement(KWLoc, + ClassTemplate->getTemplatedDecl()->getKindName()); Diag(ClassTemplate->getTemplatedDecl()->getLocation(), diag::note_previous_use); Kind = ClassTemplate->getTemplatedDecl()->getTagKind(); |