diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-01-29 01:24:26 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-01-29 01:24:26 +0000 |
commit | 5cd532ca0bc1cb8110e24586d064f72332d8b767 (patch) | |
tree | fda31159ec2c469b75d54fca5e6c98a0a96733e4 | |
parent | a438b2d277fae00a4fa467ffcf382246e0a201e9 (diff) |
Replace AS_MSTypespec with AS_Keyword, for representing any attribute spelled
as a keyword. Rationalize existing attributes to use it as appropriate, and to
not lie about some __declspec attributes being GNU attributes. In passing,
remove a gross hack which was discarding attributes which we could handle. This
results in us actually respecting the __pascal keyword again.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173746 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/Attr.td | 60 | ||||
-rw-r--r-- | include/clang/Sema/AttributeList.h | 15 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 7 | ||||
-rw-r--r-- | test/Sema/attr-print.c | 7 | ||||
-rw-r--r-- | test/SemaCXX/attr-print.cpp | 7 | ||||
-rw-r--r-- | test/SemaCXX/borland-extensions.cpp | 9 | ||||
-rw-r--r-- | test/SemaCXX/cxx11-attr-print.cpp | 7 | ||||
-rw-r--r-- | utils/TableGen/ClangAttrEmitter.cpp | 6 |
10 files changed, 77 insertions, 63 deletions
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 2d4788ce2b..8a3e788bfe 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -29,8 +29,8 @@ class SubsetSubject<AttrSubject base, string description, code check> code CheckCode = check; } -// This is the type of a variable which C++11 defines [[aligned()]] as being -// a possible subject. +// This is the type of a variable which C++11 allows alignas(...) to appertain +// to. def NormalVar : SubsetSubject<Var, "non-register, non-parameter variable", [{S->getStorageClass() != VarDecl::Register && S->getKind() != Decl::ImplicitParam && @@ -91,6 +91,7 @@ class Declspec<string name> : Spelling<name, "Declspec">; class CXX11<string namespace, string name> : Spelling<name, "CXX11"> { string Namespace = namespace; } +class Keyword<string name> : Spelling<name, "Keyword">; class Attr { // The various ways in which an attribute can be spelled in source @@ -125,6 +126,13 @@ class InheritableAttr : Attr; /// redeclarations, even when it's written on a parameter. class InheritableParamAttr : InheritableAttr; +/// An ignored attribute, which we parse but discard with no checking. +class IgnoredAttr : Attr { + let Ignored = 1; + let ASTNode = 0; + let SemaHandler = 0; +} + // // Attributes begin here // @@ -141,7 +149,8 @@ def Alias : InheritableAttr { } def Aligned : InheritableAttr { - let Spellings = [GNU<"aligned">, GNU<"align">, CXX11<"gnu", "aligned">]; + let Spellings = [GNU<"aligned">, Declspec<"align">, CXX11<"gnu", "aligned">, + Keyword<"alignas">]; let Subjects = [NonBitField, NormalVar, Tag]; let Args = [AlignedArgument<"Alignment">, BoolArgument<"IsMSDeclSpec">]; } @@ -200,11 +209,8 @@ def Blocks : InheritableAttr { let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>]; } -def Bounded : Attr { +def Bounded : IgnoredAttr { let Spellings = [GNU<"bounded">]; - let ASTNode = 0; - let SemaHandler = 0; - let Ignored = 1; } def CarriesDependency : InheritableParamAttr { @@ -214,7 +220,7 @@ def CarriesDependency : InheritableParamAttr { } def CDecl : InheritableAttr { - let Spellings = [GNU<"cdecl">, GNU<"__cdecl">, CXX11<"gnu", "cdecl">]; + let Spellings = [GNU<"cdecl">, CXX11<"gnu", "cdecl">, Keyword<"__cdecl">]; } // cf_audited_transfer indicates that the given function has been @@ -302,7 +308,7 @@ def CXX11NoReturn : InheritableAttr { } def OpenCLKernel : Attr { - let Spellings = [GNU<"opencl_kernel_function">]; + let Spellings = [Keyword<"__kernel">, Keyword<"kernel">]; } def OpenCLImageAccess : Attr { @@ -333,8 +339,8 @@ def FallThrough : Attr { } def FastCall : InheritableAttr { - let Spellings = [GNU<"fastcall">, GNU<"__fastcall">, - CXX11<"gnu", "fastcall">]; + let Spellings = [GNU<"fastcall">, CXX11<"gnu", "fastcall">, + Keyword<"__fastcall">]; } def Final : InheritableAttr { @@ -631,16 +637,17 @@ def Sentinel : InheritableAttr { } def StdCall : InheritableAttr { - let Spellings = [GNU<"stdcall">, GNU<"__stdcall">, CXX11<"gnu", "stdcall">]; + let Spellings = [GNU<"stdcall">, CXX11<"gnu", "stdcall">, + Keyword<"__stdcall">]; } def ThisCall : InheritableAttr { - let Spellings = [GNU<"thiscall">, GNU<"__thiscall">, - CXX11<"gnu", "thiscall">]; + let Spellings = [GNU<"thiscall">, CXX11<"gnu", "thiscall">, + Keyword<"__thiscall">]; } def Pascal : InheritableAttr { - let Spellings = [GNU<"pascal">]; + let Spellings = [GNU<"pascal">, Keyword<"__pascal">]; } def TransparentUnion : InheritableAttr { @@ -694,11 +701,8 @@ def VectorSize : Attr { let ASTNode = 0; } -def VecTypeHint : Attr { +def VecTypeHint : IgnoredAttr { let Spellings = [GNU<"vec_type_hint">]; - let ASTNode = 0; - let SemaHandler = 0; - let Ignored = 1; } def Visibility : InheritableAttr { @@ -894,29 +898,33 @@ def DLLImport : InheritableAttr { } def ForceInline : InheritableAttr { - let Spellings = [Declspec<"__forceinline">]; + let Spellings = [Keyword<"__forceinline">]; } def Win64 : InheritableAttr { - let Spellings = [Declspec<"w64">]; + let Spellings = [Keyword<"__w64">]; } def Ptr32 : InheritableAttr { - let Spellings = [Declspec<"__ptr32">]; + let Spellings = [Keyword<"__ptr32">]; } def Ptr64 : InheritableAttr { - let Spellings = [Declspec<"__ptr64">]; + let Spellings = [Keyword<"__ptr64">]; } def SingleInheritance : InheritableAttr { - let Spellings = [Declspec<"__single_inheritance">]; + let Spellings = [Keyword<"__single_inheritance">]; } def MultipleInheritance : InheritableAttr { - let Spellings = [Declspec<"__multiple_inheritance">]; + let Spellings = [Keyword<"__multiple_inheritance">]; } def VirtualInheritance : InheritableAttr { - let Spellings = [Declspec<"__virtual_inheritance">]; + let Spellings = [Keyword<"__virtual_inheritance">]; +} + +def Unaligned : IgnoredAttr { + let Spellings = [Keyword<"__unaligned">]; } diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index 65a959526c..928fb5fc75 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -56,12 +56,14 @@ class AttributeList { // TODO: This should really be called ParsedAttribute public: /// The style used to specify an attribute. enum Syntax { + /// __attribute__((...)) AS_GNU, + /// [[...]] AS_CXX11, + /// __declspec(...) AS_Declspec, - // eg) __w64, __ptr32, etc. It is implied that an MSTypespec is also - // a declspec. - AS_MSTypespec + /// __ptr16, alignas(...), etc. + AS_Keyword }; private: IdentifierInfo *AttrName; @@ -227,12 +229,9 @@ public: IdentifierInfo *getParameterName() const { return ParmName; } SourceLocation getParameterLoc() const { return ParmLoc; } - /// Returns true if the attribute is a pure __declspec or a synthesized - /// declspec representing a type specification (like __w64 or __ptr32). - bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec || - SyntaxUsed == AS_MSTypespec; } + bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; } bool isCXX11Attribute() const { return SyntaxUsed == AS_CXX11; } - bool isMSTypespecAttribute() const { return SyntaxUsed == AS_MSTypespec; } + bool isKeywordAttribute() const { return SyntaxUsed == AS_Keyword; } bool isInvalid() const { return Invalid; } void setInvalid(bool b = true) const { Invalid = b; } diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index a851e2cb85..e6e010bd9c 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -462,7 +462,7 @@ void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) { IdentifierInfo *AttrName = Tok.getIdentifierInfo(); SourceLocation AttrNameLoc = ConsumeToken(); attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, - SourceLocation(), 0, 0, AttributeList::AS_MSTypespec); + SourceLocation(), 0, 0, AttributeList::AS_Keyword); } } @@ -472,21 +472,23 @@ void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) { IdentifierInfo *AttrName = Tok.getIdentifierInfo(); SourceLocation AttrNameLoc = ConsumeToken(); attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, - SourceLocation(), 0, 0, AttributeList::AS_MSTypespec); + SourceLocation(), 0, 0, AttributeList::AS_Keyword); } } void Parser::ParseOpenCLAttributes(ParsedAttributes &attrs) { // Treat these like attributes while (Tok.is(tok::kw___kernel)) { + IdentifierInfo *AttrName = Tok.getIdentifierInfo(); SourceLocation AttrNameLoc = ConsumeToken(); - attrs.addNew(PP.getIdentifierInfo("opencl_kernel_function"), - AttrNameLoc, 0, AttrNameLoc, 0, - SourceLocation(), 0, 0, AttributeList::AS_GNU); + attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, + SourceLocation(), 0, 0, AttributeList::AS_Keyword); } } void Parser::ParseOpenCLQualifiers(DeclSpec &DS) { + // FIXME: The mapping from attribute spelling to semantics should be + // performed in Sema, not here. SourceLocation Loc = Tok.getLocation(); switch(Tok.getKind()) { // OpenCL qualifiers: diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index adeb8e690f..12483a34e0 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -4759,11 +4759,11 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, if (Attr.isInvalid()) return; - // Type attributes are still treated as declaration attributes by - // ParseMicrosoftTypeAttributes and ParseBorlandTypeAttributes. We don't - // want to process them, however, because we will simply warn about ignoring - // them. So instead, we will bail out early. - if (Attr.isMSTypespecAttribute()) + // FIXME: Ignore unknown keyword attributes for now. We see this in the case + // of some Borland attributes, like __pascal. + // FIXME: Add these attributes to Attr.td and mark as ignored! + if (Attr.isKeywordAttribute() && + Attr.getKind() == AttributeList::UnknownAttribute) return; // Ignore C++11 attributes on declarator chunks: they appertain to the type diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 4819363f27..c101de844b 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -4336,13 +4336,6 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type, attr.setUsedAsTypeAttr(); break; - case AttributeList::AT_Win64: - case AttributeList::AT_Ptr32: - case AttributeList::AT_Ptr64: - // FIXME: don't ignore these - attr.setUsedAsTypeAttr(); - break; - case AttributeList::AT_NSReturnsRetained: if (!state.getSema().getLangOpts().ObjCAutoRefCount) break; diff --git a/test/Sema/attr-print.c b/test/Sema/attr-print.c index f952e4b410..5e4c0c2d1e 100644 --- a/test/Sema/attr-print.c +++ b/test/Sema/attr-print.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -ast-print | FileCheck %s +// RUN: %clang_cc1 %s -ast-print -fms-extensions | FileCheck %s // FIXME: we need to fix the "BoolArgument<"IsMSDeclSpec">" // hack in Attr.td for attribute "Aligned". @@ -6,8 +6,9 @@ // CHECK: int x __attribute__((aligned(4, 0))); int x __attribute__((aligned(4))); -// CHECK: int y __attribute__((align(4, 0))); -int y __attribute__((align(4))); +// FIXME: Print this at a valid location for a __declspec attr. +// CHECK: int y __declspec(align(4, 1)); +__declspec(align(4)) int y; // CHECK: void foo() __attribute__((const)); void foo() __attribute__((const)); diff --git a/test/SemaCXX/attr-print.cpp b/test/SemaCXX/attr-print.cpp index 317ba4d157..419f608c04 100644 --- a/test/SemaCXX/attr-print.cpp +++ b/test/SemaCXX/attr-print.cpp @@ -1,12 +1,13 @@ -// RUN: %clang_cc1 %s -ast-print | FileCheck %s +// RUN: %clang_cc1 %s -ast-print -fms-extensions | FileCheck %s // FIXME: align attribute print // CHECK: int x __attribute__((aligned(4, 0))); int x __attribute__((aligned(4))); -// CHECK: int y __attribute__((align(4, 0))); -int y __attribute__((align(4))); +// FIXME: Print this at a valid location for a __declspec attr. +// CHECK: int y __declspec(align(4, 1)); +__declspec(align(4)) int y; // CHECK: void foo() __attribute__((const)); void foo() __attribute__((const)); diff --git a/test/SemaCXX/borland-extensions.cpp b/test/SemaCXX/borland-extensions.cpp index 1e4bd45612..f9414f8869 100644 --- a/test/SemaCXX/borland-extensions.cpp +++ b/test/SemaCXX/borland-extensions.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify -fborland-extensions -// expected-no-diagnostics +// RUN: %clang_cc1 %s -fsyntax-only -fborland-extensions -triple x86_64-linux-gnu -verify +// RUN: %clang_cc1 %s -fsyntax-only -fborland-extensions -triple i686-linux-gnu -Werror // Borland extensions @@ -9,13 +9,18 @@ int dummy_function() { return 0; } // 2. test __pascal int _pascal f2(); +// expected-warning@+1 {{calling convention '__pascal' ignored for this target}} float __pascal gi2(int, int); +// expected-warning@+1 {{calling convention '__pascal' ignored for this target}} template<typename T> T g2(T (__pascal * const )(int, int)) { return 0; } struct M { + // expected-warning@+1 {{calling convention '__pascal' ignored for this target}} int __pascal addP(); + // expected-warning@+1 {{calling convention '__pascal' ignored for this target}} float __pascal subtractP(); }; +// expected-warning@+1 {{calling convention '__pascal' ignored for this target}} template<typename T> int h2(T (__pascal M::* const )()) { return 0; } void m2() { int i; float f; diff --git a/test/SemaCXX/cxx11-attr-print.cpp b/test/SemaCXX/cxx11-attr-print.cpp index 985d9a44fe..3cc6d00f08 100644 --- a/test/SemaCXX/cxx11-attr-print.cpp +++ b/test/SemaCXX/cxx11-attr-print.cpp @@ -1,11 +1,12 @@ -// RUN: %clang_cc1 -std=c++11 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -ast-print -fms-extensions %s | FileCheck %s // FIXME: align attribute print // CHECK: int x __attribute__((aligned(4, 0))); int x __attribute__((aligned(4))); -// CHECK: int y __attribute__((align(4, 0))); -int y __attribute__((align(4))); +// FIXME: Print this at a valid location for a __declspec attr. +// CHECK: int y __declspec(align(4, 1)); +__declspec(align(4)) int y; // CHECK: gnu::aligned(4, 0)]]; int z [[gnu::aligned(4)]]; diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp index 09f4e19081..d936e260b8 100644 --- a/utils/TableGen/ClangAttrEmitter.cpp +++ b/utils/TableGen/ClangAttrEmitter.cpp @@ -776,8 +776,11 @@ static void writePrettyPrintFunction(Record &R, std::vector<Argument*> &Args, } else if (Variety == "Declspec") { Prefix = " __declspec("; Suffix = ")"; + } else if (Variety == "Keyword") { + Prefix = " "; + Suffix = ""; } else { - llvm_unreachable("Unkown attribute syntax variety!"); + llvm_unreachable("Unknown attribute syntax variety!"); } Spelling += Name; @@ -1149,6 +1152,7 @@ void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) { .Case("GNU", 0) .Case("CXX11", 1) .Case("Declspec", 2) + .Case("Keyword", 3) .Default(0) << " && Scope == \"" << Namespace << "\")\n" << " return " << I << ";\n"; |