summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/AttrImpl.cpp1
-rw-r--r--clang/lib/AST/Type.cpp1
-rw-r--r--clang/lib/AST/TypePrinter.cpp3
-rw-r--r--clang/lib/CodeGen/CGCall.cpp4
-rw-r--r--clang/lib/Frontend/PCHReaderDecl.cpp1
-rw-r--r--clang/lib/Parse/AttributeList.cpp5
-rw-r--r--clang/lib/Parse/ParseDecl.cpp13
-rw-r--r--clang/lib/Parse/ParseTentative.cpp1
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp3
-rw-r--r--clang/lib/Sema/SemaType.cpp2
10 files changed, 30 insertions, 4 deletions
diff --git a/clang/lib/AST/AttrImpl.cpp b/clang/lib/AST/AttrImpl.cpp
index 423aa065e57..03452267870 100644
--- a/clang/lib/AST/AttrImpl.cpp
+++ b/clang/lib/AST/AttrImpl.cpp
@@ -100,6 +100,7 @@ DEF_SIMPLE_ATTR_CLONE(Override)
DEF_SIMPLE_ATTR_CLONE(Packed)
DEF_SIMPLE_ATTR_CLONE(Pure)
DEF_SIMPLE_ATTR_CLONE(StdCall)
+DEF_SIMPLE_ATTR_CLONE(ThisCall)
DEF_SIMPLE_ATTR_CLONE(TransparentUnion)
DEF_SIMPLE_ATTR_CLONE(Unavailable)
DEF_SIMPLE_ATTR_CLONE(Unused)
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index ebaad9a0a8c..5d27ba469c0 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -919,6 +919,7 @@ llvm::StringRef FunctionType::getNameForCallConv(CallingConv CC) {
case CC_C: return "cdecl";
case CC_X86StdCall: return "stdcall";
case CC_X86FastCall: return "fastcall";
+ case CC_X86ThisCall: return "thiscall";
}
}
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index ad5b91aac5f..35a7e096994 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -295,6 +295,9 @@ void TypePrinter::PrintFunctionProto(const FunctionProtoType *T,
case CC_X86FastCall:
S += " __attribute__((fastcall))";
break;
+ case CC_X86ThisCall:
+ S += " __attribute__((thiscall))";
+ break;
}
if (Info.getNoReturn())
S += " __attribute__((noreturn))";
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 92d15d9d8c9..0d6a70c64d4 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -38,6 +38,7 @@ static unsigned ClangCallConvToLLVMCallConv(CallingConv CC) {
default: return llvm::CallingConv::C;
case CC_X86StdCall: return llvm::CallingConv::X86_StdCall;
case CC_X86FastCall: return llvm::CallingConv::X86_FastCall;
+ case CC_X86ThisCall: return llvm::CallingConv::X86_ThisCall;
}
}
@@ -97,6 +98,9 @@ static CallingConv getCallingConventionForDecl(const Decl *D) {
if (D->hasAttr<FastCallAttr>())
return CC_X86FastCall;
+ if (D->hasAttr<ThisCallAttr>())
+ return CC_X86ThisCall;
+
return CC_C;
}
diff --git a/clang/lib/Frontend/PCHReaderDecl.cpp b/clang/lib/Frontend/PCHReaderDecl.cpp
index 49010bf0d6d..1e8bd2fe550 100644
--- a/clang/lib/Frontend/PCHReaderDecl.cpp
+++ b/clang/lib/Frontend/PCHReaderDecl.cpp
@@ -763,6 +763,7 @@ Attr *PCHReader::ReadAttributes() {
UNSIGNED_ATTR(Regparm);
STRING_ATTR(Section);
SIMPLE_ATTR(StdCall);
+ SIMPLE_ATTR(ThisCall);
SIMPLE_ATTR(TransparentUnion);
SIMPLE_ATTR(Unavailable);
SIMPLE_ATTR(Unused);
diff --git a/clang/lib/Parse/AttributeList.cpp b/clang/lib/Parse/AttributeList.cpp
index bae2a09a988..53406280bb7 100644
--- a/clang/lib/Parse/AttributeList.cpp
+++ b/clang/lib/Parse/AttributeList.cpp
@@ -119,5 +119,10 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
.Case("cf_returns_retained", AT_cf_returns_retained)
.Case("reqd_work_group_size", AT_reqd_wg_size)
.Case("no_instrument_function", AT_no_instrument_function)
+ .Case("thiscall", AT_thiscall)
+ .Case("__cdecl", AT_cdecl)
+ .Case("__stdcall", AT_stdcall)
+ .Case("__fastcall", AT_fastcall)
+ .Case("__thiscall", AT_thiscall)
.Default(UnknownAttribute);
}
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 28d9dd021c3..929b20cc3d4 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -277,8 +277,8 @@ AttributeList* Parser::ParseMicrosoftTypeAttributes(AttributeList *CurrAttr) {
// Treat these like attributes
// FIXME: Allow Sema to distinguish between these and real attributes!
while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) ||
- Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___ptr64) ||
- Tok.is(tok::kw___w64)) {
+ Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___cdecl) ||
+ Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64)) {
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = ConsumeToken();
if (Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64))
@@ -1143,6 +1143,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
case tok::kw___cdecl:
case tok::kw___stdcall:
case tok::kw___fastcall:
+ case tok::kw___thiscall:
DS.AddAttributes(ParseMicrosoftTypeAttributes());
continue;
@@ -1622,6 +1623,7 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid,
case tok::kw___cdecl:
case tok::kw___stdcall:
case tok::kw___fastcall:
+ case tok::kw___thiscall:
DS.AddAttributes(ParseMicrosoftTypeAttributes());
return true;
@@ -2198,6 +2200,7 @@ bool Parser::isTypeSpecifierQualifier() {
case tok::kw___cdecl:
case tok::kw___stdcall:
case tok::kw___fastcall:
+ case tok::kw___thiscall:
case tok::kw___w64:
case tok::kw___ptr64:
return true;
@@ -2304,6 +2307,7 @@ bool Parser::isDeclarationSpecifier() {
case tok::kw___cdecl:
case tok::kw___stdcall:
case tok::kw___fastcall:
+ case tok::kw___thiscall:
case tok::kw___w64:
case tok::kw___ptr64:
case tok::kw___forceinline:
@@ -2401,6 +2405,7 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed,
case tok::kw___cdecl:
case tok::kw___stdcall:
case tok::kw___fastcall:
+ case tok::kw___thiscall:
if (GNUAttributesAllowed) {
DS.AddAttributes(ParseMicrosoftTypeAttributes());
continue;
@@ -2785,8 +2790,8 @@ void Parser::ParseParenDeclarator(Declarator &D) {
}
// Eat any Microsoft extensions.
if (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) ||
- Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___w64) ||
- Tok.is(tok::kw___ptr64)) {
+ Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___fastcall) ||
+ Tok.is(tok::kw___w64) || Tok.is(tok::kw___ptr64)) {
AttrList.reset(ParseMicrosoftTypeAttributes(AttrList.take()));
}
diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
index a6c6d3f9453..5e64e6162b7 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -753,6 +753,7 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() {
case tok::kw___cdecl:
case tok::kw___stdcall:
case tok::kw___fastcall:
+ case tok::kw___thiscall:
case tok::kw___w64:
case tok::kw___ptr64:
case tok::kw___forceinline:
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 8d51639d22f..6b8afed6f66 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1654,6 +1654,8 @@ static void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) {
case AttributeList::AT_stdcall:
d->addAttr(::new (S.Context) StdCallAttr());
return;
+ case AttributeList::AT_thiscall:
+ d->addAttr(::new (S.Context) ThisCallAttr());
case AttributeList::AT_cdecl:
d->addAttr(::new (S.Context) CDeclAttr());
return;
@@ -1950,6 +1952,7 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,
case AttributeList::AT_stdcall:
case AttributeList::AT_cdecl:
case AttributeList::AT_fastcall:
+ case AttributeList::AT_thiscall:
HandleCallConvAttr(D, Attr, S);
break;
default:
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 59c699d498d..5ca632b8b3f 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -1825,6 +1825,7 @@ bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) {
case AttributeList::AT_cdecl: CC = CC_C; break;
case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
+ case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
default: llvm_unreachable("unexpected attribute kind"); return false;
}
@@ -1949,6 +1950,7 @@ void ProcessTypeAttributeList(Sema &S, QualType &Result,
case AttributeList::AT_cdecl:
case AttributeList::AT_fastcall:
case AttributeList::AT_stdcall:
+ case AttributeList::AT_thiscall:
case AttributeList::AT_regparm:
// Don't process these on the DeclSpec.
if (IsDeclSpec ||
OpenPOWER on IntegriCloud