r186714 - Create calling convention AttributedType sugar nodes
Reid Kleckner
reid at kleckner.net
Fri Jul 19 12:51:04 PDT 2013
Author: rnk
Date: Fri Jul 19 14:51:03 2013
New Revision: 186714
URL: http://llvm.org/viewvc/llvm-project?rev=186714&view=rev
Log:
Create calling convention AttributedType sugar nodes
Canonical types are unchanged. The type printer had to be changed to
avoid printing any non-default implicit calling convention as well as
the calling convention attribute.
Reviewers: rjmccall
Differential Revision: http://llvm-reviews.chandlerc.com/D1132
Modified:
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/AST/TypePrinter.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/test/SemaTemplate/instantiate-function-params.cpp
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=186714&r1=186713&r2=186714&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Fri Jul 19 14:51:03 2013
@@ -3360,9 +3360,10 @@ public:
attr_objc_gc,
attr_objc_ownership,
attr_pcs,
+ attr_pcs_vfp,
FirstEnumOperandKind = attr_objc_gc,
- LastEnumOperandKind = attr_pcs,
+ LastEnumOperandKind = attr_pcs_vfp,
// No operand.
attr_noreturn,
@@ -3406,16 +3407,9 @@ public:
bool isSugared() const { return true; }
QualType desugar() const { return getEquivalentType(); }
- bool isMSTypeSpec() const {
- switch (getAttrKind()) {
- default: return false;
- case attr_ptr32:
- case attr_ptr64:
- case attr_sptr:
- case attr_uptr:
- return true;
- }
- }
+ bool isMSTypeSpec() const;
+
+ bool isCallingConv() const;
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getAttrKind(), ModifiedType, EquivalentType);
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=186714&r1=186713&r2=186714&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Fri Jul 19 14:51:03 2013
@@ -1842,6 +1842,47 @@ bool TagType::isBeingDefined() const {
return getDecl()->isBeingDefined();
}
+bool AttributedType::isMSTypeSpec() const {
+ switch (getAttrKind()) {
+ default: return false;
+ case attr_ptr32:
+ case attr_ptr64:
+ case attr_sptr:
+ case attr_uptr:
+ return true;
+ }
+ llvm_unreachable("invalid attr kind");
+}
+
+bool AttributedType::isCallingConv() const {
+ switch (getAttrKind()) {
+ case attr_ptr32:
+ case attr_ptr64:
+ case attr_sptr:
+ case attr_uptr:
+ case attr_address_space:
+ case attr_regparm:
+ case attr_vector_size:
+ case attr_neon_vector_type:
+ case attr_neon_polyvector_type:
+ case attr_objc_gc:
+ case attr_objc_ownership:
+ case attr_noreturn:
+ return false;
+ case attr_pcs:
+ case attr_pcs_vfp:
+ case attr_cdecl:
+ case attr_fastcall:
+ case attr_stdcall:
+ case attr_thiscall:
+ case attr_pascal:
+ case attr_pnaclcall:
+ case attr_inteloclbicc:
+ return true;
+ }
+ llvm_unreachable("invalid attr kind");
+}
+
CXXRecordDecl *InjectedClassNameType::getDecl() const {
return cast<CXXRecordDecl>(getInterestingTagDecl(Decl));
}
Modified: cfe/trunk/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=186714&r1=186713&r2=186714&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Fri Jul 19 14:51:03 2013
@@ -81,10 +81,11 @@ namespace {
class TypePrinter {
PrintingPolicy Policy;
bool HasEmptyPlaceHolder;
+ bool InsideCCAttribute;
public:
explicit TypePrinter(const PrintingPolicy &Policy)
- : Policy(Policy), HasEmptyPlaceHolder(false) { }
+ : Policy(Policy), HasEmptyPlaceHolder(false), InsideCCAttribute(false) { }
void print(const Type *ty, Qualifiers qs, raw_ostream &OS,
StringRef PlaceHolder);
@@ -630,36 +631,40 @@ void TypePrinter::printFunctionProtoAfte
OS << ')';
FunctionType::ExtInfo Info = T->getExtInfo();
- switch(Info.getCC()) {
- case CC_Default: break;
- case CC_C:
- OS << " __attribute__((cdecl))";
- break;
- case CC_X86StdCall:
- OS << " __attribute__((stdcall))";
- break;
- case CC_X86FastCall:
- OS << " __attribute__((fastcall))";
- break;
- case CC_X86ThisCall:
- OS << " __attribute__((thiscall))";
- break;
- case CC_X86Pascal:
- OS << " __attribute__((pascal))";
- break;
- case CC_AAPCS:
- OS << " __attribute__((pcs(\"aapcs\")))";
- break;
- case CC_AAPCS_VFP:
- OS << " __attribute__((pcs(\"aapcs-vfp\")))";
- break;
- case CC_PnaclCall:
- OS << " __attribute__((pnaclcall))";
- break;
- case CC_IntelOclBicc:
- OS << " __attribute__((intel_ocl_bicc))";
- break;
+
+ if (!InsideCCAttribute) {
+ switch (Info.getCC()) {
+ case CC_Default: break;
+ case CC_C:
+ OS << " __attribute__((cdecl))";
+ break;
+ case CC_X86StdCall:
+ OS << " __attribute__((stdcall))";
+ break;
+ case CC_X86FastCall:
+ OS << " __attribute__((fastcall))";
+ break;
+ case CC_X86ThisCall:
+ OS << " __attribute__((thiscall))";
+ break;
+ case CC_X86Pascal:
+ OS << " __attribute__((pascal))";
+ break;
+ case CC_AAPCS:
+ OS << " __attribute__((pcs(\"aapcs\")))";
+ break;
+ case CC_AAPCS_VFP:
+ OS << " __attribute__((pcs(\"aapcs-vfp\")))";
+ break;
+ case CC_PnaclCall:
+ OS << " __attribute__((pnaclcall))";
+ break;
+ case CC_IntelOclBicc:
+ OS << " __attribute__((intel_ocl_bicc))";
+ break;
+ }
}
+
if (Info.getNoReturn())
OS << " __attribute__((noreturn))";
if (Info.getRegParm())
@@ -1089,7 +1094,7 @@ void TypePrinter::printAttributedBefore(
case AttributedType::attr_ptr64: OS << " __ptr64"; break;
case AttributedType::attr_sptr: OS << " __sptr"; break;
case AttributedType::attr_uptr: OS << " __uptr"; break;
-}
+ }
spaceBeforePlaceHolder(OS);
}
}
@@ -1105,6 +1110,12 @@ void TypePrinter::printAttributedAfter(c
if (T->isMSTypeSpec())
return;
+ // If this is a calling convention attribute, don't print the implicit CC from
+ // the modified type.
+ SaveAndRestore<bool> MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
+
+ printAfter(T->getModifiedType(), OS);
+
OS << " __attribute__((";
switch (T->getAttrKind()) {
default: llvm_unreachable("This attribute should have been handled already");
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=186714&r1=186713&r2=186714&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri Jul 19 14:51:03 2013
@@ -546,12 +546,7 @@ distributeFunctionTypeAttrToInnermost(Ty
return true;
}
- if (handleFunctionTypeAttr(state, attr, declSpecType)) {
- spliceAttrOutOfList(attr, attrList);
- return true;
- }
-
- return false;
+ return handleFunctionTypeAttr(state, attr, declSpecType);
}
/// A function type attribute was written in the decl spec. Try to
@@ -3345,6 +3340,7 @@ static AttributeList::Kind getAttrListKi
case AttributedType::attr_pascal:
return AttributeList::AT_Pascal;
case AttributedType::attr_pcs:
+ case AttributedType::attr_pcs_vfp:
return AttributeList::AT_Pcs;
case AttributedType::attr_pnaclcall:
return AttributeList::AT_PnaclCall;
@@ -4302,6 +4298,36 @@ static bool handleMSPointerTypeQualifier
return false;
}
+static AttributedType::Kind getCCTypeAttrKind(AttributeList &Attr) {
+ assert(!Attr.isInvalid());
+ switch (Attr.getKind()) {
+ default:
+ llvm_unreachable("not a calling convention attribute");
+ case AttributeList::AT_CDecl:
+ return AttributedType::attr_cdecl;
+ case AttributeList::AT_FastCall:
+ return AttributedType::attr_fastcall;
+ case AttributeList::AT_StdCall:
+ return AttributedType::attr_stdcall;
+ case AttributeList::AT_ThisCall:
+ return AttributedType::attr_thiscall;
+ case AttributeList::AT_Pascal:
+ return AttributedType::attr_pascal;
+ case AttributeList::AT_Pcs: {
+ // We know attr is valid so it can only have one of two strings args.
+ StringLiteral *Str = cast<StringLiteral>(Attr.getArg(0));
+ return llvm::StringSwitch<AttributedType::Kind>(Str->getString())
+ .Case("aapcs", AttributedType::attr_pcs)
+ .Case("aapcs-vfp", AttributedType::attr_pcs_vfp);
+ }
+ case AttributeList::AT_PnaclCall:
+ return AttributedType::attr_pnaclcall;
+ case AttributeList::AT_IntelOclBicc:
+ return AttributedType::attr_inteloclbicc;
+ }
+ llvm_unreachable("unexpected attribute kind!");
+}
+
/// Process an individual function attribute. Returns true to
/// indicate that the attribute was handled, false if it wasn't.
static bool handleFunctionTypeAttr(TypeProcessingState &state,
@@ -4421,8 +4447,13 @@ static bool handleFunctionTypeAttr(TypeP
}
}
+ // Modify the CC from the wrapped function type, wrap it all back, and then
+ // wrap the whole thing in an AttributedType as written. The modified type
+ // might have a different CC if we ignored the attribute.
FunctionType::ExtInfo EI = unwrapped.get()->getExtInfo().withCallingConv(CC);
- type = unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI));
+ QualType Equivalent =
+ unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI));
+ type = S.Context.getAttributedType(getCCTypeAttrKind(attr), type, Equivalent);
return true;
}
Modified: cfe/trunk/test/SemaTemplate/instantiate-function-params.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-function-params.cpp?rev=186714&r1=186713&r2=186714&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-function-params.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-function-params.cpp Fri Jul 19 14:51:03 2013
@@ -82,9 +82,15 @@ namespace InstantiateFunctionTypedef {
struct X {
typedef int functype(int, int);
functype func;
+
+ typedef int stdfunctype(int, int) __attribute__((stdcall));
+ __attribute__((stdcall)) functype stdfunc1;
+ stdfunctype stdfunc2;
};
void f(X<int> x) {
(void)x.func(1, 2);
+ (void)x.stdfunc1(1, 2);
+ (void)x.stdfunc2(1, 2);
}
}
More information about the cfe-commits
mailing list