[cfe-commits] support for Borland extensions and __pascal
dawn at burble.org
dawn at burble.org
Tue Aug 31 18:05:11 PDT 2010
I posted a prior message to this list but before I subscribed, so it is
"awaiting approval". I'm attaching the patch again in case it doesn't
go through.
The patch adds support for Borland extentions via the option
"-fborland-extensions". It also adds support for the "__pascal" calling
convention.
Support for the new "__pascal" calling convention isn't vendor specific,
and adds support for "__attribute__((pascal))" as well. Should it be?
I can make it specific to "-fborland-extensions", but the patch wouldn't
fit with the existing code as cleanly. Note also that support hasn't
been added to llvm yet.
You'll see from the test case that I had some trouble with pointer to
member functions which I still need to investigate. I get the error
"no known conversion from 'float (M::*)() __attribute__((pascal))' to
'float (M::*const)()'" as if the attribute is getting lost.
Please review,
-Dawn
-------------- next part --------------
Index: test/SemaCXX/borland-extensions.cpp
===================================================================
--- test/SemaCXX/borland-extensions.cpp (revision 0)
+++ test/SemaCXX/borland-extensions.cpp (revision 0)
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -fborland-extensions
+
+// Borland extensions
+
+// test __pascal
+int __pascal f1();
+
+float __pascal gi1(int, int);
+template<typename T> T g1(T (__pascal * const )(int, int)) { return 0; }
+
+struct M {
+ int __pascal addP();
+ float __pascal subtractP();
+};
+#if 0
+template<typename T> int h1(T (__pascal M::* const )()) { return 0; }
+// FIXME clang doesn't think 'T (M::*const)()' is a function
+#endif
+void m1() {
+ int i; float f;
+ i = f1();
+ f = gi1(1, i);
+ f = g1(gi1);
+#if 0
+ i = h1<int>(&M::addP); // FIXME clang gets no match
+ f = h1(&M::subtractP); // FIXME clang gets no match
+#endif
+}
Index: include/clang/Basic/LangOptions.h
===================================================================
--- include/clang/Basic/LangOptions.h (revision 112654)
+++ include/clang/Basic/LangOptions.h (working copy)
@@ -34,6 +34,7 @@
unsigned HexFloats : 1; // C99 Hexadecimal float constants.
unsigned C99 : 1; // C99 Support
unsigned Microsoft : 1; // Microsoft extensions.
+ unsigned Borland : 1; // Borland extensions.
unsigned CPlusPlus : 1; // C++ Support
unsigned CPlusPlus0x : 1; // C++0x Support
unsigned CXXOperatorNames : 1; // Treat C++ operator names as keywords.
@@ -140,7 +141,7 @@
HexFloats = 0;
GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCNonFragileABI2 = 0;
NoConstantCFStrings = 0; InlineVisibilityHidden = 0;
- C99 = Microsoft = CPlusPlus = CPlusPlus0x = 0;
+ C99 = Microsoft = Borland = CPlusPlus = CPlusPlus0x = 0;
CXXOperatorNames = PascalStrings = WritableStrings = ConstStrings = 0;
Exceptions = SjLjExceptions = Freestanding = NoBuiltin = 0;
NeXTRuntime = 1;
Index: include/clang/Basic/TokenKinds.def
===================================================================
--- include/clang/Basic/TokenKinds.def (revision 112654)
+++ include/clang/Basic/TokenKinds.def (working copy)
@@ -335,6 +335,9 @@
KEYWORD(__thiscall , KEYALL)
KEYWORD(__forceinline , KEYALL)
+// Borland Extension.
+KEYWORD(__pascal , KEYALL)
+
// Altivec Extension.
KEYWORD(__vector , KEYALTIVEC)
KEYWORD(__pixel , KEYALTIVEC)
@@ -371,6 +374,9 @@
ALIAS("_stdcall" , __stdcall , KEYMS)
ALIAS("_thiscall" , __thiscall , KEYMS)
+// Borland Extensions.
+ALIAS("_pascal" , __pascal , KEYMS)
+
//===----------------------------------------------------------------------===//
// Objective-C @-preceeded keywords.
//===----------------------------------------------------------------------===//
Index: include/clang/Sema/AttributeList.h
===================================================================
--- include/clang/Sema/AttributeList.h (revision 112654)
+++ include/clang/Sema/AttributeList.h (working copy)
@@ -102,6 +102,7 @@
AT_ownership_returns, // Clang-specific.
AT_ownership_takes, // Clang-specific.
AT_packed,
+ AT_pascal,
AT_pure,
AT_regparm,
AT_section,
Index: include/clang/AST/Type.h
===================================================================
--- include/clang/AST/Type.h (revision 112654)
+++ include/clang/AST/Type.h (working copy)
@@ -410,7 +410,8 @@
CC_C, // __attribute__((cdecl))
CC_X86StdCall, // __attribute__((stdcall))
CC_X86FastCall, // __attribute__((fastcall))
- CC_X86ThisCall // __attribute__((thiscall))
+ CC_X86ThisCall, // __attribute__((thiscall))
+ CC_X86Pascal // __attribute__((pascal))
};
@@ -1928,7 +1929,7 @@
// The value passed to __attribute__((regparm(x)))
unsigned RegParm;
// The calling convention as specified via
- // __attribute__((cdecl|stdcall|fastcall|thiscall))
+ // __attribute__((cdecl|stdcall|fastcall|thiscall|pascal))
CallingConv CC;
};
Index: include/clang/Parse/Parser.h
===================================================================
--- include/clang/Parse/Parser.h (revision 112654)
+++ include/clang/Parse/Parser.h (working copy)
@@ -1365,6 +1365,7 @@
AttributeList *ParseGNUAttributes(SourceLocation *EndLoc = 0);
AttributeList *ParseMicrosoftDeclSpec(AttributeList* CurrAttr = 0);
AttributeList *ParseMicrosoftTypeAttributes(AttributeList* CurrAttr = 0);
+ AttributeList *ParseBorlandTypeAttributes(AttributeList* CurrAttr = 0);
void ParseTypeofSpecifier(DeclSpec &DS);
void ParseDecltypeSpecifier(DeclSpec &DS);
Index: docs/tools/clang.pod
===================================================================
--- docs/tools/clang.pod (revision 112654)
+++ docs/tools/clang.pod (working copy)
@@ -168,6 +168,10 @@
Enable support for Microsoft extensions.
+=item B<-fborland-extensions>
+
+Enable support for Borland extensions.
+
=item B<-fwritable-strings>
Make all string literals default to writable. This disables uniquing of
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp (revision 112654)
+++ lib/Frontend/CompilerInvocation.cpp (working copy)
@@ -526,6 +526,8 @@
Res.push_back("-fgnu-keywords");
if (Opts.Microsoft)
Res.push_back("-fms-extensions");
+ if (Opts.Borland)
+ Res.push_back("-fborland-extensions");
if (Opts.ObjCNonFragileABI)
Res.push_back("-fobjc-nonfragile-abi");
if (Opts.ObjCNonFragileABI2)
@@ -1317,6 +1319,7 @@
!Opts.AsmPreprocessor);
Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
+ Opts.Borland = Args.hasArg(OPT_fborland_extensions);
Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
Opts.ConstStrings = Args.hasArg(OPT_Wwrite_strings);
if (Args.hasArg(OPT_fno_lax_vector_conversions))
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp (revision 112654)
+++ lib/Sema/SemaDeclAttr.cpp (working copy)
@@ -1986,6 +1986,9 @@
case AttributeList::AT_cdecl:
d->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
return;
+ case AttributeList::AT_pascal:
+ d->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context));
+ return;
default:
llvm_unreachable("unexpected attribute kind");
return;
@@ -2294,6 +2297,7 @@
case AttributeList::AT_cdecl:
case AttributeList::AT_fastcall:
case AttributeList::AT_thiscall:
+ case AttributeList::AT_pascal:
HandleCallConvAttr(D, Attr, S);
break;
default:
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp (revision 112654)
+++ lib/Sema/SemaType.cpp (working copy)
@@ -1906,6 +1906,7 @@
case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
+ case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
default: llvm_unreachable("unexpected attribute kind"); return false;
}
@@ -2033,6 +2034,7 @@
case AttributeList::AT_fastcall:
case AttributeList::AT_stdcall:
case AttributeList::AT_thiscall:
+ case AttributeList::AT_pascal:
case AttributeList::AT_regparm:
// Don't process these on the DeclSpec.
if (IsDeclSpec ||
Index: lib/Sema/AttributeList.cpp
===================================================================
--- lib/Sema/AttributeList.cpp (revision 112654)
+++ lib/Sema/AttributeList.cpp (working copy)
@@ -126,9 +126,11 @@
.Case("init_priority", AT_init_priority)
.Case("no_instrument_function", AT_no_instrument_function)
.Case("thiscall", AT_thiscall)
+ .Case("pascal", AT_pascal)
.Case("__cdecl", AT_cdecl)
.Case("__stdcall", AT_stdcall)
.Case("__fastcall", AT_fastcall)
.Case("__thiscall", AT_thiscall)
+ .Case("__pascal", AT_pascal)
.Default(UnknownAttribute);
}
Index: lib/AST/Type.cpp
===================================================================
--- lib/AST/Type.cpp (revision 112654)
+++ lib/AST/Type.cpp (working copy)
@@ -1005,6 +1005,7 @@
case CC_X86StdCall: return "stdcall";
case CC_X86FastCall: return "fastcall";
case CC_X86ThisCall: return "thiscall";
+ case CC_X86Pascal: return "pascal";
}
}
Index: lib/AST/TypePrinter.cpp
===================================================================
--- lib/AST/TypePrinter.cpp (revision 112654)
+++ lib/AST/TypePrinter.cpp (working copy)
@@ -299,6 +299,9 @@
case CC_X86ThisCall:
S += " __attribute__((thiscall))";
break;
+ case CC_X86Pascal:
+ S += " __attribute__((pascal))";
+ break;
}
if (Info.getNoReturn())
S += " __attribute__((noreturn))";
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp (revision 112654)
+++ lib/Driver/Tools.cpp (working copy)
@@ -1215,6 +1215,11 @@
getToolChain().getTriple().getOS() == llvm::Triple::Win32))
CmdArgs.push_back("-fms-extensions");
+ // -fborland-extensions=0 is default.
+ if (Args.hasFlag(options::OPT_fborland_extensions,
+ options::OPT_fno_borland_extensions))
+ CmdArgs.push_back("-fborland-extensions");
+
// -fgnu-keywords default varies depending on language; only pass if
// specified.
if (Arg *A = Args.getLastArg(options::OPT_fgnu_keywords,
Index: lib/CodeGen/MicrosoftCXXABI.cpp
===================================================================
--- lib/CodeGen/MicrosoftCXXABI.cpp (revision 112654)
+++ lib/CodeGen/MicrosoftCXXABI.cpp (working copy)
@@ -919,6 +919,7 @@
switch (T->getCallConv()) {
case CC_Default:
case CC_C: Out << 'A'; break;
+ case CC_X86Pascal: Out << 'C'; break;
case CC_X86ThisCall: Out << 'E'; break;
case CC_X86StdCall: Out << 'G'; break;
case CC_X86FastCall: Out << 'I'; break;
Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp (revision 112654)
+++ lib/CodeGen/CGCall.cpp (working copy)
@@ -36,6 +36,7 @@
case CC_X86StdCall: return llvm::CallingConv::X86_StdCall;
case CC_X86FastCall: return llvm::CallingConv::X86_FastCall;
case CC_X86ThisCall: return llvm::CallingConv::X86_ThisCall;
+ // TODO: add support for CC_X86Pascal to llvm
}
}
@@ -100,6 +101,9 @@
if (D->hasAttr<ThisCallAttr>())
return CC_X86ThisCall;
+ if (D->hasAttr<PascalAttr>())
+ return CC_X86Pascal;
+
return CC_C;
}
Index: lib/Parse/ParseTentative.cpp
===================================================================
--- lib/Parse/ParseTentative.cpp (revision 112654)
+++ lib/Parse/ParseTentative.cpp (working copy)
@@ -757,6 +757,10 @@
case tok::kw___ptr64:
case tok::kw___forceinline:
return TPResult::True();
+
+ // Borland
+ case tok::kw___pascal:
+ return TPResult::True();
// AltiVec
case tok::kw___vector:
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp (revision 112654)
+++ lib/Parse/ParseDecl.cpp (working copy)
@@ -293,6 +293,17 @@
return CurrAttr;
}
+AttributeList* Parser::ParseBorlandTypeAttributes(AttributeList *CurrAttr) {
+ // Treat these like attributes
+ while (Tok.is(tok::kw___pascal)) {
+ IdentifierInfo *AttrName = Tok.getIdentifierInfo();
+ SourceLocation AttrNameLoc = ConsumeToken();
+ CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+ SourceLocation(), 0, 0, CurrAttr, true);
+ }
+ return CurrAttr;
+}
+
/// ParseDeclaration - Parse a full 'declaration', which consists of
/// declaration-specifiers, some number of declarators, and a semicolon.
/// 'Context' should be a Declarator::TheContext value. This returns the
@@ -1207,6 +1218,11 @@
DS.AddAttributes(ParseMicrosoftTypeAttributes());
continue;
+ // Borland single token adornments.
+ case tok::kw___pascal:
+ DS.AddAttributes(ParseBorlandTypeAttributes());
+ continue;
+
// storage-class-specifier
case tok::kw_typedef:
isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec,
@@ -1683,6 +1699,7 @@
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec, DiagID);
break;
+
case tok::kw___ptr64:
case tok::kw___w64:
case tok::kw___cdecl:
@@ -1692,6 +1709,10 @@
DS.AddAttributes(ParseMicrosoftTypeAttributes());
return true;
+ case tok::kw___pascal:
+ DS.AddAttributes(ParseBorlandTypeAttributes());
+ return true;
+
default:
// Not a type-specifier; do nothing.
return false;
@@ -2268,6 +2289,7 @@
case tok::kw___thiscall:
case tok::kw___w64:
case tok::kw___ptr64:
+ case tok::kw___pascal:
return true;
}
}
@@ -2376,6 +2398,7 @@
case tok::kw___w64:
case tok::kw___ptr64:
case tok::kw___forceinline:
+ case tok::kw___pascal:
return true;
}
}
@@ -2427,15 +2450,20 @@
}
/// ParseTypeQualifierListOpt
-/// type-qualifier-list: [C99 6.7.5]
-/// type-qualifier
-/// [GNU] attributes [ only if AttributesAllowed=true ]
-/// type-qualifier-list type-qualifier
-/// [GNU] type-qualifier-list attributes [ only if AttributesAllowed=true ]
-/// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq
-/// if CXX0XAttributesAllowed = true
+/// type-qualifier-list: [C99 6.7.5]
+/// type-qualifier
+/// [vendor] attributes
+/// [ only if VendorAttributesAllowed=true ]
+/// type-qualifier-list type-qualifier
+/// [vendor] type-qualifier-list attributes
+/// [ only if VendorAttributesAllowed=true ]
+/// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq
+/// [ only if CXX0XAttributesAllowed=true ]
+/// Note: vendor can be GNU, MS, etc.
+/// FIXME: would be nice to have bitfields for each vendor.
///
-void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed,
+void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
+ bool VendorAttributesAllowed,
bool CXX0XAttributesAllowed) {
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
SourceLocation Loc = Tok.getLocation();
@@ -2476,13 +2504,19 @@
case tok::kw___stdcall:
case tok::kw___fastcall:
case tok::kw___thiscall:
- if (GNUAttributesAllowed) {
+ if (VendorAttributesAllowed) {
DS.AddAttributes(ParseMicrosoftTypeAttributes());
continue;
}
goto DoneWithTypeQuals;
+ case tok::kw___pascal:
+ if (VendorAttributesAllowed) {
+ DS.AddAttributes(ParseBorlandTypeAttributes());
+ continue;
+ }
+ goto DoneWithTypeQuals;
case tok::kw___attribute:
- if (GNUAttributesAllowed) {
+ if (VendorAttributesAllowed) {
DS.AddAttributes(ParseGNUAttributes());
continue; // do *not* consume the next token!
}
@@ -2867,6 +2901,10 @@
Tok.is(tok::kw___w64) || Tok.is(tok::kw___ptr64)) {
AttrList.reset(ParseMicrosoftTypeAttributes(AttrList.take()));
}
+ // Eat any Borland extensions.
+ if (Tok.is(tok::kw___pascal)) {
+ AttrList.reset(ParseBorlandTypeAttributes(AttrList.take()));
+ }
// If we haven't past the identifier yet (or where the identifier would be
// stored, if this is an abstract declarator), then this is probably just
More information about the cfe-commits
mailing list