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