forked from OSchip/llvm-project
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. llvm-svn: 173746
This commit is contained in:
parent
3c94737fb7
commit
0cdcc98200
|
@ -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">];
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)]];
|
||||
|
|
|
@ -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";
|
||||
|
|
Loading…
Reference in New Issue