From 8443a448fcfe0e03e237274e222a9fc479b1c1e3 Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Mon, 2 Dec 2013 17:07:07 +0000 Subject: [PATCH] Re-enabled support for the Subjects for the weak attribute. This changes the diagnostic involved to be more accurate -- for C++ code, it will now report that weak applies to variables, functions or classes. Added additional test case for this. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196120 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/Attr.td | 2 +- include/clang/Basic/DiagnosticSemaKinds.td | 4 ++-- include/clang/Sema/AttributeList.h | 3 ++- lib/Sema/SemaDeclAttr.cpp | 21 ++------------------- test/SemaCXX/attr-weak.cpp | 4 +++- utils/TableGen/ClangAttrEmitter.cpp | 6 ++++++ 6 files changed, 16 insertions(+), 24 deletions(-) diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index e947b8ebfd..c7223d6512 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -870,7 +870,7 @@ def WarnUnusedResult : InheritableAttr { def Weak : InheritableAttr { let Spellings = [GNU<"weak">, CXX11<"gnu", "weak">]; -// let Subjects = SubjectList<[Var, Function, CXXRecord]>; + let Subjects = SubjectList<[Var, Function, CXXRecord]>; } def WeakImport : InheritableAttr { diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 995603072c..20cdfdf545 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2037,7 +2037,7 @@ def warn_attribute_wrong_decl_type : Warning< "variables and fields|variables, data members and tag types|" "types and namespaces|Objective-C interfaces|methods and properties|" "struct or union|struct, union or class|types|" - "Objective-C instance methods}1">, + "Objective-C instance methods|variables, functions and classes}1">, InGroup; def err_attribute_wrong_decl_type : Error< "%0 attribute only applies to %select{functions|unions|" @@ -2049,7 +2049,7 @@ def err_attribute_wrong_decl_type : Error< "variables and fields|variables, data members and tag types|" "types and namespaces|Objective-C interfaces|methods and properties|" "struct or union|struct, union or class|types|" - "Objective-C instance methods}1">; + "Objective-C instance methods|variables, functions and classes}1">; def warn_type_attribute_wrong_type : Warning< "'%0' only applies to %select{function|pointer|" "Objective-C object or block pointer}1 types; type here is %2">, diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index 690ccccbef..e27209525e 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -859,7 +859,8 @@ enum AttributeDeclKind { ExpectedStructOrUnion, ExpectedStructOrUnionOrClass, ExpectedType, - ExpectedObjCInstanceMethod + ExpectedObjCInstanceMethod, + ExpectedFunctionVariableOrClass }; } // end namespace clang diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 1ae62ef3af..486375adde 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -2243,24 +2243,6 @@ static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) Attr.getAttributeSpellingListIndex())); } -static void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) { - if (!isa(D) && !isa(D)) { - if (isa(D)) { - D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context)); - return; - } - S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) - << Attr.getName() << ExpectedVariableOrFunction; - return; - } - - NamedDecl *nd = cast(D); - - nd->addAttr(::new (S.Context) - WeakAttr(Attr.getRange(), S.Context, - Attr.getAttributeSpellingListIndex())); -} - static void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) { // weak_import only applies to variable & function declarations. bool isDef = false; @@ -4168,7 +4150,8 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, handleSimpleAttribute(S, D, Attr); break; case AttributeList::AT_WarnUnusedResult: handleWarnUnusedResult(S, D, Attr); break; - case AttributeList::AT_Weak: handleWeakAttr (S, D, Attr); break; + case AttributeList::AT_Weak: + handleSimpleAttribute(S, D, Attr); break; case AttributeList::AT_WeakRef: handleWeakRefAttr (S, D, Attr); break; case AttributeList::AT_WeakImport: handleWeakImportAttr (S, D, Attr); break; case AttributeList::AT_TransparentUnion: diff --git a/test/SemaCXX/attr-weak.cpp b/test/SemaCXX/attr-weak.cpp index 8939a28d75..2000e7fc68 100644 --- a/test/SemaCXX/attr-weak.cpp +++ b/test/SemaCXX/attr-weak.cpp @@ -3,7 +3,7 @@ static int test0 __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} static void test1() __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} -namespace test2 __attribute__((weak)) { // expected-warning {{'weak' attribute only applies to variables and functions}} +namespace test2 __attribute__((weak)) { // expected-warning {{'weak' attribute only applies to variables, functions and classes}} } namespace { @@ -34,3 +34,5 @@ int Test7::var; namespace { class Internal; } template struct Test7; template struct Test7; + +class __attribute__((weak)) Test8 {}; // OK diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp index 08bcb501a8..d459059745 100644 --- a/utils/TableGen/ClangAttrEmitter.cpp +++ b/utils/TableGen/ClangAttrEmitter.cpp @@ -1797,6 +1797,12 @@ static std::string CalculateDiagnostic(const Record &S) { case Func | FuncTemplate: case Func | ObjCMethod: return "ExpectedFunctionOrMethod"; case Func | Var: return "ExpectedVariableOrFunction"; + + // If not compiling for C++, the class portion does not apply. + case Func | Var | Class: + return "(S.getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass : " + "ExpectedVariableOrFunction)"; + case ObjCMethod | ObjCProp: return "ExpectedMethodOrProperty"; case Field | Var: return "ExpectedFieldOrGlobalVar"; } -- 2.40.0