aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2009-04-07 19:37:57 +0000
committerEli Friedman <eli.friedman@gmail.com>2009-04-07 19:37:57 +0000
commit85a5319ea4b5c916d7dd665e84af61e4a8a0b9c2 (patch)
treef8d79d5ab45d4ad1c2d465b4d35314954fb586b4 /lib/Sema/SemaDecl.cpp
parent5c1aaafbd6dd25a99ca1960e1c3c98aeefe9d728 (diff)
Diagnose uses of function specifiers on declarations which don't declare
functions. Fixes PR3941. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68541 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp37
1 files changed, 25 insertions, 12 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 7cf44bf6ac..54be9b4c3d 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1478,6 +1478,24 @@ Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND, NamedDecl *PrevDecl,
}
}
+/// \brief Diagnose function specifiers on a declaration of an identifier that
+/// does not identify a function.
+void Sema::DiagnoseFunctionSpecifiers(Declarator& D) {
+ // FIXME: We should probably indicate the identifier in question to avoid
+ // confusion for constructs like "inline int a(), b;"
+ if (D.getDeclSpec().isInlineSpecified())
+ Diag(D.getDeclSpec().getInlineSpecLoc(),
+ diag::err_inline_non_function);
+
+ if (D.getDeclSpec().isVirtualSpecified())
+ Diag(D.getDeclSpec().getVirtualSpecLoc(),
+ diag::err_virtual_non_function);
+
+ if (D.getDeclSpec().isExplicitSpecified())
+ Diag(D.getDeclSpec().getExplicitSpecLoc(),
+ diag::err_explicit_non_function);
+}
+
NamedDecl*
Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, Decl* PrevDecl, bool& InvalidDecl,
@@ -1494,12 +1512,10 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
if (getLangOptions().CPlusPlus) {
// Check that there are no default arguments (C++ only).
CheckExtraCXXDefaultArguments(D);
-
- if (D.getDeclSpec().isVirtualSpecified())
- Diag(D.getDeclSpec().getVirtualSpecLoc(),
- diag::err_virtual_non_function);
}
+ DiagnoseFunctionSpecifiers(D);
+
TypedefDecl *NewTD = ParseTypedefDecl(S, D, R);
if (!NewTD) return 0;
@@ -1639,9 +1655,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
return 0;
}
- if (D.getDeclSpec().isVirtualSpecified())
- Diag(D.getDeclSpec().getVirtualSpecLoc(),
- diag::err_virtual_non_function);
+ DiagnoseFunctionSpecifiers(D);
bool ThreadSpecified = D.getDeclSpec().isThreadSpecified();
if (!DC->isRecord() && S->getFnParent() == 0) {
@@ -2615,7 +2629,8 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
diag::err_invalid_storage_class_in_func_decl);
D.getMutableDeclSpec().ClearStorageClassSpecs();
}
-
+ DiagnoseFunctionSpecifiers(D);
+
// Check that there are no default arguments inside the type of this
// parameter (C++ only).
if (getLangOptions().CPlusPlus)
@@ -3566,12 +3581,10 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
if (getLangOptions().CPlusPlus) {
CheckExtraCXXDefaultArguments(D);
-
- if (D.getDeclSpec().isVirtualSpecified())
- Diag(D.getDeclSpec().getVirtualSpecLoc(),
- diag::err_virtual_non_function);
}
+ DiagnoseFunctionSpecifiers(D);
+
NamedDecl *PrevDecl = LookupName(S, II, LookupMemberName, true);
if (PrevDecl && !isDeclInScope(PrevDecl, Record, S))
PrevDecl = 0;