aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Parse/Parser.cpp2
-rw-r--r--lib/Sema/Sema.h3
-rw-r--r--lib/Sema/SemaDecl.cpp40
-rw-r--r--lib/Sema/SemaDeclCXX.cpp5
-rw-r--r--lib/Sema/SemaExpr.cpp18
-rw-r--r--lib/Sema/SemaInit.cpp4
-rw-r--r--lib/Sema/SemaTemplate.cpp13
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();