summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2011-01-21 02:08:54 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2011-01-21 02:08:54 +0000
commit9f2a9909ae485059093ab718291060543552a640 (patch)
treed676b8c12b12fa0098bea44206af40bec3024f33 /clang
parentb331b267b105310e420b06f3aa46446b0afbd02f (diff)
downloadbcm5719-llvm-9f2a9909ae485059093ab718291060543552a640.tar.gz
bcm5719-llvm-9f2a9909ae485059093ab718291060543552a640.zip
Sema: process non-inheritable attributes on function declarations early
This allows us to simplify the handling for the overloadable attribute, removing a number of FIXMEs. llvm-svn: 123961
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Sema/Sema.h3
-rw-r--r--clang/lib/Sema/SemaDecl.cpp48
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp8
3 files changed, 29 insertions, 30 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index a7c62b82cad..05f266086b0 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -727,8 +727,7 @@ public:
void CheckFunctionDeclaration(Scope *S,
FunctionDecl *NewFD, LookupResult &Previous,
bool IsExplicitSpecialization,
- bool &Redeclaration,
- bool &OverloadableAttrRequired);
+ bool &Redeclaration);
void CheckMain(FunctionDecl *FD);
Decl *ActOnParamDeclarator(Scope *S, Declarator &D);
ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 8c78c0dd764..be6d60e6574 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -3844,13 +3844,15 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// Finally, we know we have the right number of parameters, install them.
NewFD->setParams(Params.data(), Params.size());
- bool OverloadableAttrRequired=false; // FIXME: HACK!
+ // Process the non-inheritable attributes on this declaration.
+ ProcessDeclAttributes(S, NewFD, D,
+ /*NonInheritable=*/true, /*Inheritable=*/false);
+
if (!getLangOptions().CPlusPlus) {
// Perform semantic checking on the function declaration.
bool isExplctSpecialization=false;
CheckFunctionDeclaration(S, NewFD, Previous, isExplctSpecialization,
- Redeclaration,
- /*FIXME:*/OverloadableAttrRequired);
+ Redeclaration);
assert((NewFD->isInvalidDecl() || !Redeclaration ||
Previous.getResultKind() != LookupResult::FoundOverloaded) &&
"previous declaration set still overloaded");
@@ -3926,9 +3928,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
}
// Perform semantic checking on the function declaration.
- bool flag_c_overloaded=false; // unused for c++
CheckFunctionDeclaration(S, NewFD, Previous, isExplicitSpecialization,
- Redeclaration, /*FIXME:*/flag_c_overloaded);
+ Redeclaration);
assert((NewFD->isInvalidDecl() || !Redeclaration ||
Previous.getResultKind() != LookupResult::FoundOverloaded) &&
@@ -4035,7 +4036,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// (for example to check for conflicts, etc).
// FIXME: This needs to happen before we merge declarations. Then,
// let attribute merging cope with attribute conflicts.
- ProcessDeclAttributes(S, NewFD, D);
+ ProcessDeclAttributes(S, NewFD, D,
+ /*NonInheritable=*/false, /*Inheritable=*/true);
// attributes declared post-definition are currently ignored
// FIXME: This should happen during attribute merging
@@ -4050,17 +4052,6 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
AddKnownFunctionAttributes(NewFD);
- if (OverloadableAttrRequired && !NewFD->hasAttr<OverloadableAttr>()) {
- // If a function name is overloadable in C, then every function
- // with that name must be marked "overloadable".
- Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
- << Redeclaration << NewFD;
- if (!Previous.empty())
- Diag(Previous.getRepresentativeDecl()->getLocation(),
- diag::note_attribute_overloadable_prev_overload);
- NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(), Context));
- }
-
if (NewFD->hasAttr<OverloadableAttr>() &&
!NewFD->getType()->getAs<FunctionProtoType>()) {
Diag(NewFD->getLocation(),
@@ -4121,8 +4112,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
LookupResult &Previous,
bool IsExplicitSpecialization,
- bool &Redeclaration,
- bool &OverloadableAttrRequired) {
+ bool &Redeclaration) {
// If NewFD is already known erroneous, don't do any of this checking.
if (NewFD->isInvalidDecl()) {
// If this is a class member, mark the class invalid immediately.
@@ -4167,9 +4157,6 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
Redeclaration = true;
OldDecl = Previous.getFoundDecl();
} else {
- if (!getLangOptions().CPlusPlus)
- OverloadableAttrRequired = true;
-
switch (CheckOverload(S, NewFD, Previous, OldDecl,
/*NewIsUsingDecl*/ false)) {
case Ovl_Match:
@@ -4184,6 +4171,23 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
Redeclaration = false;
break;
}
+
+ if (!getLangOptions().CPlusPlus && !NewFD->hasAttr<OverloadableAttr>()) {
+ // If a function name is overloadable in C, then every function
+ // with that name must be marked "overloadable".
+ Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
+ << Redeclaration << NewFD;
+ NamedDecl *OverloadedDecl = 0;
+ if (Redeclaration)
+ OverloadedDecl = OldDecl;
+ else if (!Previous.empty())
+ OverloadedDecl = Previous.getRepresentativeDecl();
+ if (OverloadedDecl)
+ Diag(OverloadedDecl->getLocation(),
+ diag::note_attribute_overloadable_prev_overload);
+ NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(),
+ Context));
+ }
}
if (Redeclaration) {
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 36a19002993..5238ad6dfc8 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1053,7 +1053,6 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
Function->setInvalidDecl();
bool Redeclaration = false;
- bool OverloadableAttrRequired = false;
bool isExplicitSpecialization = false;
LookupResult Previous(SemaRef, Function->getDeclName(), SourceLocation(),
@@ -1105,8 +1104,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
}
SemaRef.CheckFunctionDeclaration(/*Scope*/ 0, Function, Previous,
- isExplicitSpecialization, Redeclaration,
- /*FIXME:*/OverloadableAttrRequired);
+ isExplicitSpecialization, Redeclaration);
NamedDecl *PrincipalDecl = (TemplateParams
? cast<NamedDecl>(FunctionTemplate)
@@ -1386,9 +1384,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
}
bool Redeclaration = false;
- bool OverloadableAttrRequired = false;
- SemaRef.CheckFunctionDeclaration(0, Method, Previous, false, Redeclaration,
- /*FIXME:*/OverloadableAttrRequired);
+ SemaRef.CheckFunctionDeclaration(0, Method, Previous, false, Redeclaration);
if (D->isPure())
SemaRef.CheckPureMethod(Method, SourceRange());
OpenPOWER on IntegriCloud