diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2011-01-21 02:08:54 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2011-01-21 02:08:54 +0000 |
commit | c80e8115278ba1537c8b517a083ecbd0a018b579 (patch) | |
tree | 6c88d65811fe129979f5be77741710e2625cd7a0 | |
parent | 60700390a787471d3396f380e0679a6d08c27f1f (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123961 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Sema/Sema.h | 3 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 48 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 8 |
3 files changed, 29 insertions, 30 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index a7c62b82ca..05f266086b 100644 --- a/include/clang/Sema/Sema.h +++ b/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/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 8c78c0dd76..be6d60e657 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/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/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 36a1900299..5238ad6dfc 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/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()); |