[cfe-commits] r130030 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Parse/ParseCXXInlineMethods.cpp lib/Parse/Parser.cpp lib/Sema/SemaDecl.cpp test/Parser/DelayedTemplateParsing.cpp
Francois Pichet
pichet2000 at gmail.com
Fri Apr 22 16:20:45 PDT 2011
Author: fpichet
Date: Fri Apr 22 18:20:44 2011
New Revision: 130030
URL: http://llvm.org/viewvc/llvm-project?rev=130030&view=rev
Log:
Correctly emit a diagnostic for multiple templated function definitions in -flate-template-parsing mode.
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/Parser/DelayedTemplateParsing.cpp
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=130030&r1=130029&r2=130030&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Apr 22 18:20:44 2011
@@ -889,6 +889,7 @@
bool TypeMayContainAuto = true);
void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
SourceLocation LocAfterDecls);
+ void CheckForFunctionRedefinition(FunctionDecl *FD);
Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D);
void ActOnStartOfObjCMethodDef(Scope *S, Decl *D);
Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=130030&r1=130029&r2=130030&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Fri Apr 22 18:20:44 2011
@@ -65,6 +65,7 @@
FD = FunTmpl->getTemplatedDecl();
else
FD = cast<FunctionDecl>(FnD);
+ Actions.CheckForFunctionRedefinition(FD);
LateParsedTemplateMap[FD] = LPT;
Actions.MarkAsLateParsedTemplate(FD);
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=130030&r1=130029&r2=130030&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Fri Apr 22 18:20:44 2011
@@ -821,6 +821,7 @@
FnD = FunTmpl->getTemplatedDecl();
else
FnD = cast<FunctionDecl>(DP);
+ Actions.CheckForFunctionRedefinition(FnD);
LateParsedTemplateMap[FnD] = LPT;
Actions.MarkAsLateParsedTemplate(FnD);
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=130030&r1=130029&r2=130030&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Apr 22 18:20:44 2011
@@ -5729,6 +5729,22 @@
return MissingPrototype;
}
+void Sema::CheckForFunctionRedefinition(FunctionDecl *FD) {
+ // Don't complain if we're in GNU89 mode and the previous definition
+ // was an extern inline function.
+ const FunctionDecl *Definition;
+ if (FD->hasBody(Definition) &&
+ !canRedefineFunction(Definition, getLangOptions())) {
+ if (getLangOptions().GNUMode && Definition->isInlineSpecified() &&
+ Definition->getStorageClass() == SC_Extern)
+ Diag(FD->getLocation(), diag::err_redefinition_extern_inline)
+ << FD->getDeclName() << getLangOptions().CPlusPlus;
+ else
+ Diag(FD->getLocation(), diag::err_redefinition) << FD->getDeclName();
+ Diag(Definition->getLocation(), diag::note_previous_definition);
+ }
+}
+
Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
// Clear the last template instantiation error context.
LastTemplateInstantiationErrorContext = ActiveTemplateInstantiation();
@@ -5746,24 +5762,8 @@
PushFunctionScope();
// See if this is a redefinition.
- // But don't complain if we're in GNU89 mode and the previous definition
- // was an extern inline function.
-
- // FIXME: This code doesn't complain about multiple definition for late
- // parsed template function.
- bool IsLateParsingRedefinition = LateTemplateParser &&
- FD->isLateTemplateParsed();
- const FunctionDecl *Definition;
- if (FD->hasBody(Definition) && !IsLateParsingRedefinition &&
- !canRedefineFunction(Definition, getLangOptions())) {
- if (getLangOptions().GNUMode && Definition->isInlineSpecified() &&
- Definition->getStorageClass() == SC_Extern)
- Diag(FD->getLocation(), diag::err_redefinition_extern_inline)
- << FD->getDeclName() << getLangOptions().CPlusPlus;
- else
- Diag(FD->getLocation(), diag::err_redefinition) << FD->getDeclName();
- Diag(Definition->getLocation(), diag::note_previous_definition);
- }
+ if (!FD->isLateTemplateParsed())
+ CheckForFunctionRedefinition(FD);
// Builtin functions cannot be defined.
if (unsigned BuiltinID = FD->getBuiltinID()) {
Modified: cfe/trunk/test/Parser/DelayedTemplateParsing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/DelayedTemplateParsing.cpp?rev=130030&r1=130029&r2=130030&view=diff
==============================================================================
--- cfe/trunk/test/Parser/DelayedTemplateParsing.cpp (original)
+++ cfe/trunk/test/Parser/DelayedTemplateParsing.cpp Fri Apr 22 18:20:44 2011
@@ -2,14 +2,23 @@
template <class T>
class A {
-
void foo() {
undeclared();
}
-
- void foo2();
+ void foo2();
+};
+
+template <class T>
+class B {
+ void foo4() { } // expected-note {{previous definition is here}} expected-note {{previous definition is here}}
+ void foo4() { } // expected-error {{class member cannot be redeclared}} expected-error {{redefinition of 'foo4'}} expected-note {{previous definition is here}}
};
+
+template <class T>
+void B<T>::foo4() {// expected-error {{redefinition of 'foo4'}}
+}
+
template <class T>
void A<T>::foo2() {
undeclared();
@@ -29,3 +38,5 @@
}
+template <class T> void foo5() {} //expected-note {{previous definition is here}}
+template <class T> void foo5() {} // expected-error {{redefinition of 'foo5'}}
More information about the cfe-commits
mailing list