summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorSerge Pavlov <sepavloff@gmail.com>2014-06-25 17:09:41 +0000
committerSerge Pavlov <sepavloff@gmail.com>2014-06-25 17:09:41 +0000
commita826147eef05d1d4fa0f3efdd1eeb4c71ae13b9d (patch)
tree4d955aea3d73adfaaa7fe5b3097fc1b8f603293f /clang/lib/Sema/SemaDecl.cpp
parent9029bda8a31c6d2f908fd1d6e6e4d8615c8c76c7 (diff)
downloadbcm5719-llvm-a826147eef05d1d4fa0f3efdd1eeb4c71ae13b9d.tar.gz
bcm5719-llvm-a826147eef05d1d4fa0f3efdd1eeb4c71ae13b9d.zip
Fix treatment of types defined in function prototype
Types defined in function prototype are diagnosed earlier in C++ compilation. They are put into declaration context where the prototype is introduced. Later on, when FunctionDecl object is created, these types are moved into the function context. This patch fixes PR19018 and PR18963. Differential Revision: http://reviews.llvm.org/D4145 llvm-svn: 211718
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp33
1 files changed, 19 insertions, 14 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 90499d2749e..073da57b364 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -10874,11 +10874,6 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
while (isa<RecordDecl>(SearchDC) || isa<EnumDecl>(SearchDC))
SearchDC = SearchDC->getParent();
}
- } else if (S->isFunctionPrototypeScope()) {
- // If this is an enum declaration in function prototype scope, set its
- // initial context to the translation unit.
- // FIXME: [citation needed]
- SearchDC = Context.getTranslationUnitDecl();
}
if (Previous.isSingleResult() &&
@@ -11351,27 +11346,37 @@ CreateNewDecl:
else if (!SearchDC->isFunctionOrMethod())
New->setModulePrivate();
}
-
+
// If this is a specialization of a member class (of a class template),
// check the specialization.
if (isExplicitSpecialization && CheckMemberSpecialization(New, Previous))
Invalid = true;
-
- if (Invalid)
- New->setInvalidDecl();
-
- if (Attr)
- ProcessDeclAttributeList(S, New, Attr);
// If we're declaring or defining a tag in function prototype scope in C,
// note that this type can only be used within the function and add it to
// the list of decls to inject into the function definition scope.
- if (!getLangOpts().CPlusPlus && (Name || Kind == TTK_Enum) &&
+ if ((Name || Kind == TTK_Enum) &&
getNonFieldDeclScope(S)->isFunctionPrototypeScope()) {
- Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New);
+ if (getLangOpts().CPlusPlus) {
+ // C++ [dcl.fct]p6:
+ // Types shall not be defined in return or parameter types.
+ if (TUK == TUK_Definition && !IsTypeSpecifier) {
+ Diag(Loc, diag::err_type_defined_in_param_type)
+ << Name;
+ Invalid = true;
+ }
+ } else {
+ Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New);
+ }
DeclsInPrototypeScope.push_back(New);
}
+ if (Invalid)
+ New->setInvalidDecl();
+
+ if (Attr)
+ ProcessDeclAttributeList(S, New, Attr);
+
// Set the lexical context. If the tag has a C++ scope specifier, the
// lexical context will be different from the semantic context.
New->setLexicalDeclContext(CurContext);
OpenPOWER on IntegriCloud