[cfe-commits] [PATCH] [VCPP] Mangle template parameters pack

Eli Friedman eli.friedman at gmail.com
Mon Nov 5 12:34:32 PST 2012


http://llvm.org/docs/CodingStandards.html .  And please don't include
commented-out code in patches.

-Eli

On Mon, Nov 5, 2012 at 11:48 AM, pravic <ehysta at gmail.com> wrote:
> This patch enables mangling of the template parameters pack with microsoft compatibility mode.
>
> Also it adds "__ptr64" qualifier under X64 as VC++ does.
>
> Variadic templates for VC++ was introduced at CTP update (http://bit.ly/Ud918z), so we can use them too now.
>
> Tests included here contains only compilable by VC++ parts.
>
> http://llvm-reviews.chandlerc.com/D99
>
> Files:
>   lib/AST/MicrosoftMangle.cpp
>   test/CodeGenCXX/mangle-ms-variadic-templates.cpp
>
> Index: lib/AST/MicrosoftMangle.cpp
> ===================================================================
> --- lib/AST/MicrosoftMangle.cpp
> +++ lib/AST/MicrosoftMangle.cpp
> @@ -825,9 +825,22 @@
>        break;
>      case TemplateArgument::Template:
>      case TemplateArgument::TemplateExpansion:
> -    case TemplateArgument::Declaration:
> -    case TemplateArgument::NullPtr:
>      case TemplateArgument::Pack: {
> +      SourceRange loc = TAL.getSourceRange();
> +      if(TA.pack_size() > 0){
> +        // mangle pack as template types sequence
> +        for (TemplateArgument::pack_iterator PA = TA.pack_begin(), PAEnd = TA.pack_end(); PA != PAEnd; ++PA){
> +          mangleType(PA->getAsType(), loc);
> +        }
> +      }else{
> +        // mangle empty pack
> +        // <empty VT> ::= '@' "$$$V" '@'
> +        Out << "$$$V";
> +      }
> +      break;
> +      }
> +    case TemplateArgument::Declaration:
> +    case TemplateArgument::NullPtr: {
>        // Issue a diagnostic.
>        DiagnosticsEngine &Diags = Context.getDiags();
>        unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
> @@ -1218,6 +1231,11 @@
>            Out << 'U';
>          else
>            Out << 'Q';
> +
> +        // mangle __ptr64
> +        if(getASTContext().getTargetInfo().getPointerWidth(0) == 64)
> +          Out << 'E';
> +
>      }
>    } else
>      Out << 'Y';
> Index: test/CodeGenCXX/mangle-ms-variadic-templates.cpp
> ===================================================================
> --- test/CodeGenCXX/mangle-ms-variadic-templates.cpp
> +++ test/CodeGenCXX/mangle-ms-variadic-templates.cpp
> @@ -0,0 +1,112 @@
> +// RUN: %clang_cc1 -std=c++11 -emit-llvm -fms-extensions -Xclang -cxx-abi -Xclang microsoft -target i386-pc-win32 -o - %s | FileCheck %s
> +// RUN: %clang_cc1 -std=c++11 -emit-llvm -fms-extensions -Xclang -cxx-abi -Xclang microsoft -target x86_64-pc-win32 -o - %s | FileCheck -check-prefix=CHK64 %s
> +// expected-no-diagnostics
> +
> +// Simple mangling test
> +template<typename... T> void va(T...);
> +
> +void test_va(){
> +       // CHECK: call void @"\01??$va@$$$V@@YAXXZ"()
> +       // CHK64: call void @"\01??$va@$$$V@@YAXXZ"()
> +       va();
> +       // CHECK: call void @"\01??$va at H@@YAXH at Z"(i32 1)
> +       // CHK64: call void @"\01??$va at H@@YAXH at Z"(i32 1)
> +       va(1);
> +       // CHECK: call void @"\01??$va at HN@@YAXHN at Z"(i32 1, double 2.300000e+00)
> +       // CHK64: call void @"\01??$va at HN@@YAXHN at Z"(i32 1, double 2.300000e+00)
> +       va(1,2.3);
> +       // CHECK: call void @"\01??$va at M@@YAXM at Z"(float 2.500000e+00)
> +       // CHK64: call void @"\01??$va at M@@YAXM at Z"(float 2.500000e+00)
> +       va(2.5f);
> +}
> +
> +// Struct mangling
> +template<class... T> struct VS
> +{
> +       VS(T...){}
> +};
> +
> +void test_vs(){
> +       // 'QAE':  __thiscall (x86)
> +       // 'QAA':  __cdecl (x86)
> +       // 'QEAA': __cdecl __ptr64 (x64)
> +       // CHECK: %struct.VS* @"\01??0?$VS@$$$V@@QAE at XZ"(%struct.VS* %vs0)
> +       // CHK64: %struct.VS* @"\01??0?$VS@$$$V@@QEAA at XZ"(%struct.VS* %vs0)
> +       VS<> vs0;
> +       // CHECK: %struct.VS.0* @"\01??0?$VS at H@@QAE at H@Z"(%struct.VS.0* %vs1, i32 1)
> +       // CHK64: %struct.VS.0* @"\01??0?$VS at H@@QEAA at H@Z"(%struct.VS.0* %vs1, i32 1)
> +       VS<int> vs1(1);
> +       // CHECK: %struct.VS.2* @"\01??0?$VS at HN@@QAE at HN@Z"(%struct.VS.2* %vs2, i32 1, double 2.300000e+00)
> +       // CHK64: %struct.VS.2* @"\01??0?$VS at HN@@QEAA at HN@Z"(%struct.VS.2* %vs2, i32 1, double 2.300000e+00)
> +       VS<int, double> vs2(1, 2.3);
> +}
> +
> +
> +template<unsigned I, typename ...Types>
> +struct X { };
> +
> +template<typename T> struct identity { };
> +template<typename T> struct add_reference;
> +template<typename ...Types> struct tuple { };
> +template<int ...Values> struct int_tuple { };
> +template<template<typename> class ...Templates> struct template_tuple { };
> +
> +template<typename ...Types>
> +void f0(X<sizeof...(Types), Types&...>) { }
> +
> +//template void f0(X<0>);
> +
> +//template void f0<int, float, double>(X<3, int&, float&, double&>);
> +
> +// Mangling for template argument packs
> +template<typename ...Types> void f1() {}
> +// CHECK: define weak_odr void @"\01??$f1@$$$V@@YAXXZ"
> +// CHK64: define weak_odr void @"\01??$f1@$$$V@@YAXXZ"
> +template void f1<>();
> +// CHECK: define weak_odr void @"\01??$f1 at H@@YAXXZ"
> +// CHK64: define weak_odr void @"\01??$f1 at H@@YAXXZ"
> +template void f1<int>();
> +// CHECK: define weak_odr void @"\01??$f1 at HM@@YAXXZ"
> +// CHK64: define weak_odr void @"\01??$f1 at HM@@YAXXZ"
> +template void f1<int, float>();
> +
> +// Mangling function parameter packs
> +template<typename ...Types> void f2(Types...) {}
> +// CHECK: define weak_odr void @"\01??$f2@$$$V@@YAXXZ"
> +// CHK64: define weak_odr void @"\01??$f2@$$$V@@YAXXZ"
> +template void f2<>();
> +
> +//template void f2<int>(int);
> +
> +//template void f2<int, float>(int, float);
> +
> +// Mangling non-trivial function parameter packs
> +template<typename ...Types> void f3(const Types *...) {}
> +// CHECK: define weak_odr void @"\01??$f3@$$$V@@YAXXZ"
> +// CHK64: define weak_odr void @"\01??$f3@$$$V@@YAXXZ"
> +template void f3<>();
> +
> +//template void f3<int>(const int*);
> +
> +//template void f3<int, float>(const int*, const float*);
> +
> +// Mangling of type pack expansions in a template argument
> +template<typename ...Types> tuple<Types...> f4() {}
> +
> +//template tuple<int, float, double> f4();
> +
> +// Mangling of type pack expansions in a function type
> +template<typename R, typename ...ArgTypes> identity<R(ArgTypes...)> f5() {}
> +
> +//template identity<int(int, float, double)> f5();
> +
> +// Mangling of non-type template argument expansions
> +template<int ...Values> int_tuple<Values...> f6() {}
> +
> +//template int_tuple<1, 2, 3> f6();
> +
> +// Mangling of template template argument expansions
> +template<template<typename> class ...Templates>
> +template_tuple<Templates...> f7() {}
> +
> +//template template_tuple<identity, add_reference> f7();
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>



More information about the cfe-commits mailing list