Add fastcall/stdcall attribute support
Generate CallingConv::Fast when fastcall attribute is present
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48017 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/CodeGen/CodeGenFunction.cpp b/CodeGen/CodeGenFunction.cpp
index f48d093..7d70e6c 100644
--- a/CodeGen/CodeGenFunction.cpp
+++ b/CodeGen/CodeGenFunction.cpp
@@ -15,6 +15,7 @@
#include "CodeGenModule.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/AST/AST.h"
+#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
@@ -76,6 +77,9 @@
else if (FD->getStorageClass() == FunctionDecl::Static)
CurFn->setLinkage(llvm::Function::InternalLinkage);
+ if (FD->getAttr<FastCallAttr>())
+ CurFn->setCallingConv(llvm::CallingConv::Fast);
+
if (const VisibilityAttr *attr = FD->getAttr<VisibilityAttr>())
CurFn->setVisibility(attr->getVisibility());
// FIXME: else handle -fvisibility
diff --git a/Parse/AttributeList.cpp b/Parse/AttributeList.cpp
index 05c6f77..0ff9447 100644
--- a/Parse/AttributeList.cpp
+++ b/Parse/AttributeList.cpp
@@ -65,11 +65,13 @@
if (!memcmp(Str, "aligned", 7)) return AT_aligned;
if (!memcmp(Str, "nothrow", 7)) return AT_nothrow;
if (!memcmp(Str, "nonnull", 7)) return AT_nonnull;
+ if (!memcmp(Str, "stdcall", 7)) return AT_stdcall;
break;
case 8:
if (!memcmp(Str, "annotate", 8)) return AT_annotate;
if (!memcmp(Str, "noreturn", 8)) return AT_noreturn;
if (!memcmp(Str, "noinline", 8)) return AT_noinline;
+ if (!memcmp(Str, "fastcall", 8)) return AT_fastcall;
break;
case 9:
if (!memcmp(Str, "dllimport", 9)) return AT_dllimport;
diff --git a/Sema/Sema.h b/Sema/Sema.h
index a3934c7..2fe54de 100644
--- a/Sema/Sema.h
+++ b/Sema/Sema.h
@@ -280,6 +280,8 @@
void HandleVisibilityAttribute(Decl *d, AttributeList *rawAttr);
void HandleNothrowAttribute(Decl *d, AttributeList *rawAttr);
void HandleFormatAttribute(Decl *d, AttributeList *rawAttr);
+ void HandleStdCallAttribute(Decl *d, AttributeList *rawAttr);
+ void HandleFastCallAttribute(Decl *d, AttributeList *rawAttr);
void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
bool &IncompleteImpl);
@@ -501,7 +503,7 @@
SourceLocation *CommaLocs,
SourceLocation BuiltinLoc,
SourceLocation RParenLoc);
-
+
// __builtin_va_arg(expr, type)
virtual ExprResult ActOnVAArg(SourceLocation BuiltinLoc,
ExprTy *expr, TypeTy *type,
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index 60fe7ab..7307fc4 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -1811,6 +1811,12 @@
case AttributeList::AT_nothrow:
HandleNothrowAttribute(New, Attr);
break;
+ case AttributeList::AT_stdcall:
+ HandleStdCallAttribute(New, Attr);
+ break;
+ case AttributeList::AT_fastcall:
+ HandleFastCallAttribute(New, Attr);
+ break;
case AttributeList::AT_aligned:
HandleAlignedAttribute(New, Attr);
break;
@@ -2073,6 +2079,28 @@
d->addAttr(new DLLExportAttr());
}
+void Sema::HandleStdCallAttribute(Decl *d, AttributeList *rawAttr) {
+ // check the attribute arguments.
+ if (rawAttr->getNumArgs() != 0) {
+ Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+ std::string("0"));
+ return;
+ }
+
+ d->addAttr(new StdCallAttr());
+}
+
+void Sema::HandleFastCallAttribute(Decl *d, AttributeList *rawAttr) {
+ // check the attribute arguments.
+ if (rawAttr->getNumArgs() != 0) {
+ Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+ std::string("0"));
+ return;
+ }
+
+ d->addAttr(new FastCallAttr());
+}
+
void Sema::HandleNothrowAttribute(Decl *d, AttributeList *rawAttr) {
// check the attribute arguments.
if (rawAttr->getNumArgs() != 0) {
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 160c4ac..72bc8a9 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -34,7 +34,9 @@
DLLExport,
NoThrow,
Format,
- Visibility
+ Visibility,
+ FastCall,
+ StdCall
};
private:
@@ -196,6 +198,26 @@
static bool classof(const DLLExportAttr *A) { return true; }
};
+class FastCallAttr : public Attr {
+public:
+ FastCallAttr() : Attr(FastCall) {}
+
+ // Implement isa/cast/dyncast/etc.
+
+ static bool classof(const Attr *A) { return A->getKind() == FastCall; }
+ static bool classof(const FastCallAttr *A) { return true; }
+};
+
+class StdCallAttr : public Attr {
+public:
+ StdCallAttr() : Attr(StdCall) {}
+
+ // Implement isa/cast/dyncast/etc.
+
+ static bool classof(const Attr *A) { return A->getKind() == StdCall; }
+ static bool classof(const StdCallAttr *A) { return true; }
+};
+
} // end namespace clang
#endif
diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h
index c8906d7..a8057d9 100644
--- a/include/clang/Parse/AttributeList.h
+++ b/include/clang/Parse/AttributeList.h
@@ -60,6 +60,8 @@
AT_dllimport,
AT_dllexport,
AT_visibility,
+ AT_fastcall,
+ AT_stdcall,
AT_nothrow,
AT_noinline,
AT_warn_unused_result