Reworked representation of PredefinedExpr after review.
http://reviews.llvm.org/D5365
Files:
include/clang/AST/Expr.h
include/clang/Sema/Sema.h
lib/AST/ASTDumper.cpp
lib/AST/Expr.cpp
lib/AST/ExprConstant.cpp
lib/AST/StmtPrinter.cpp
lib/CodeGen/CGExpr.cpp
lib/Parse/ParseExpr.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaTemplateInstantiate.cpp
lib/Sema/TreeTransform.h
lib/Serialization/ASTReaderStmt.cpp
lib/Serialization/ASTWriterStmt.cpp
lib/StaticAnalyzer/Core/ExprEngine.cpp
test/CodeGen/const-init.c
test/CodeGen/func-in-block.c
test/CodeGen/predefined-expr.c
test/CodeGenCXX/funcsig.cpp
test/CodeGenCXX/ms_wide_predefined_expr.cpp
test/CodeGenCXX/predefined-expr-cxx14.cpp
test/CodeGenCXX/predefined-expr.cpp
test/CodeGenObjC/predefined-expr.m
test/SemaCXX/predefined-expr.cpp
Index: test/CodeGenCXX/predefined-expr-cxx14.cpp
===================================================================
--- test/CodeGenCXX/predefined-expr-cxx14.cpp
+++ test/CodeGenCXX/predefined-expr-cxx14.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -std=c++14 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
+
+// CHECK-DAG: @_ZZN13ClassTemplateIiE21classTemplateFunctionERiE8__func__ = linkonce_odr constant [22 x i8] c"classTemplateFunction\00"
+// CHECK-DAG: @_ZZN13ClassTemplateIiE21classTemplateFunctionERiE19__PRETTY_FUNCTION__ = linkonce_odr constant [69 x i8] c"const auto &ClassTemplate<int>::classTemplateFunction(T &) [T = int]\00"
+
+// CHECK-DAG: @_ZZN24ClassInTopLevelNamespace16functionTemplateIiEERDaRT_E8__func__ = linkonce_odr constant [17 x i8] c"functionTemplate\00"
+// CHECK-DAG: @_ZZN24ClassInTopLevelNamespace16functionTemplateIiEERDaRT_E19__PRETTY_FUNCTION__ = linkonce_odr constant [64 x i8] c"auto &ClassInTopLevelNamespace::functionTemplate(T &) [T = int]\00"
+
+// CHECK-DAG: @_ZZN24ClassInTopLevelNamespace16variadicFunctionEPizE8__func__ = linkonce_odr constant [17 x i8] c"variadicFunction\00"
+// CHECK-DAG: @_ZZN24ClassInTopLevelNamespace16variadicFunctionEPizE19__PRETTY_FUNCTION__ = linkonce_odr constant [70 x i8] c"decltype(auto) ClassInTopLevelNamespace::variadicFunction(int *, ...)\00"
+
+// CHECK-DAG: @_ZZN24ClassInTopLevelNamespace25topLevelNamespaceFunctionEvE8__func__ = linkonce_odr constant [26 x i8] c"topLevelNamespaceFunction\00"
+// CHECK-DAG: @_ZZN24ClassInTopLevelNamespace25topLevelNamespaceFunctionEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [60 x i8] c"auto *ClassInTopLevelNamespace::topLevelNamespaceFunction()\00"
+
+int printf(const char * _Format, ...);
+
+class ClassInTopLevelNamespace {
+public:
+ auto *topLevelNamespaceFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ return static_cast<int *>(nullptr);
+ }
+
+ decltype(auto) variadicFunction(int *a, ...) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ return a;
+ }
+
+ template<typename T>
+ auto &functionTemplate(T &t) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ return t;
+ }
+};
+
+template<typename T>
+class ClassTemplate {
+public:
+ const auto &classTemplateFunction(T &t) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ return t;
+ }
+};
+
+int main() {
+ int a;
+ ClassInTopLevelNamespace topLevelNamespace;
+ topLevelNamespace.topLevelNamespaceFunction();
+ topLevelNamespace.variadicFunction(&a);
+ topLevelNamespace.functionTemplate(a);
+
+ ClassTemplate<int> t;
+ t.classTemplateFunction(a);
+ return 0;
+}
Index: test/CodeGenCXX/ms_wide_predefined_expr.cpp
===================================================================
--- test/CodeGenCXX/ms_wide_predefined_expr.cpp
+++ test/CodeGenCXX/ms_wide_predefined_expr.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 %s -fms-extensions -triple i686-pc-win32 -emit-llvm -o - | FileCheck %s
-// CHECK: @"\01??_C@_19DPFBEKIN@?$AAf?$AAu?$AAn?$AAc?$AA?$AA@" = linkonce_odr unnamed_addr constant [5 x i16] [i16 102, i16 117, i16 110, i16 99, i16 0], align 2
+// CHECK: @"\01?L__FUNCTION__@?0??func@@YAXXZ@4QB_WB" = internal constant [5 x i16] [i16 102, i16 117, i16 110, i16 99, i16 0], align 2
void wprint(const wchar_t*);
Index: test/CodeGenCXX/funcsig.cpp
===================================================================
--- test/CodeGenCXX/funcsig.cpp
+++ test/CodeGenCXX/funcsig.cpp
@@ -8,22 +8,22 @@
void freeFunc(int *, char) {
printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
}
-// CHECK: private unnamed_addr constant [{{.*}} x i8] c"void __cdecl freeFunc(int *, char)\00"
+// CHECK: internal constant [{{.*}} x i8] c"void __cdecl freeFunc(int *, char)\00"
struct TopLevelClass {
void topLevelMethod(int *, char);
};
void TopLevelClass::topLevelMethod(int *, char) {
printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
}
-// CHECK: private unnamed_addr constant [{{.*}} x i8] c"void __thiscall TopLevelClass::topLevelMethod(int *, char)\00"
+// CHECK: internal constant [{{.*}} x i8] c"void __thiscall TopLevelClass::topLevelMethod(int *, char)\00"
namespace NS {
struct NamespacedClass {
void namespacedMethod(int *, char);
};
void NamespacedClass::namespacedMethod(int *, char) {
printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
}
-// CHECK: private unnamed_addr constant [{{.*}} x i8] c"void __thiscall NS::NamespacedClass::namespacedMethod(int *, char)\00"
+// CHECK: internal constant [{{.*}} x i8] c"void __thiscall NS::NamespacedClass::namespacedMethod(int *, char)\00"
}
Index: test/CodeGenCXX/predefined-expr.cpp
===================================================================
--- test/CodeGenCXX/predefined-expr.cpp
+++ test/CodeGenCXX/predefined-expr.cpp
@@ -1,102 +1,102 @@
// RUN: %clang_cc1 -std=c++11 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
-// CHECK: private unnamed_addr constant [15 x i8] c"externFunction\00"
-// CHECK: private unnamed_addr constant [26 x i8] c"void NS::externFunction()\00"
-// CHECK: private unnamed_addr constant [49 x i8] c"void functionTemplateExplicitSpecialization(int)\00"
+// CHECK: internal constant [15 x i8] c"externFunction\00"
+// CHECK: internal constant [26 x i8] c"void NS::externFunction()\00"
+// CHECK: _ZZ38functionTemplateExplicitSpecializationIiEvT_E19__PRETTY_FUNCTION__ = constant [49 x i8] c"void functionTemplateExplicitSpecialization(int)\00"
-// CHECK: private unnamed_addr constant [95 x i8] c"void SpecializedClassTemplate<char>::memberFunctionTemplate(T, U) const [T = char, U = double]\00"
-// CHECK: private unnamed_addr constant [85 x i8] c"void SpecializedClassTemplate<int>::memberFunctionTemplate(int, U) const [U = float]\00"
-// CHECK: private unnamed_addr constant [57 x i8] c"void NonTypeTemplateParam<42>::size() const [Count = 42]\00"
-// CHECK: private unnamed_addr constant [122 x i8] c"static void ClassWithTemplateTemplateParam<char, NS::ClassTemplate>::staticMember() [T = char, Param = NS::ClassTemplate]\00"
-// CHECK: private unnamed_addr constant [106 x i8] c"void OuterClass<int *>::MiddleClass::InnerClass<float>::memberFunction(T, U) const [T = int *, U = float]\00"
-// CHECK: private unnamed_addr constant [51 x i8] c"void functionTemplateWithCapturedStmt(T) [T = int]\00"
-// CHECK: private unnamed_addr constant [76 x i8] c"auto functionTemplateWithLambda(int)::(anonymous class)::operator()() const\00"
-// CHECK: private unnamed_addr constant [65 x i8] c"void functionTemplateWithUnnamedTemplateParameter(T) [T = float]\00"
+// CHECK: @_ZZNK24SpecializedClassTemplateIcE22memberFunctionTemplateIdEEvcT_E19__PRETTY_FUNCTION__ = linkonce_odr constant [95 x i8] c"void SpecializedClassTemplate<char>::memberFunctionTemplate(T, U) const [T = char, U = double]\00"
+// CHECK: @_ZZNK24SpecializedClassTemplateIiE22memberFunctionTemplateIfEEviT_E19__PRETTY_FUNCTION__ = linkonce_odr constant [85 x i8] c"void SpecializedClassTemplate<int>::memberFunctionTemplate(int, U) const [U = float]\00"
+// CHECK: @_ZZNK20NonTypeTemplateParamILi42EE4sizeEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [57 x i8] c"void NonTypeTemplateParam<42>::size() const [Count = 42]\00"
+// CHECK: @_ZZN30ClassWithTemplateTemplateParamIcN2NS13ClassTemplateEE12staticMemberEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [122 x i8] c"static void ClassWithTemplateTemplateParam<char, NS::ClassTemplate>::staticMember() [T = char, Param = NS::ClassTemplate]\00"
+// CHECK: @_ZZNK10OuterClassIPiE11MiddleClass10InnerClassIfE14memberFunctionES0_fE19__PRETTY_FUNCTION__ = linkonce_odr constant [106 x i8] c"void OuterClass<int *>::MiddleClass::InnerClass<float>::memberFunction(T, U) const [T = int *, U = float]\00"
+// CHECK: @_ZZ32functionTemplateWithCapturedStmtIiEvT_E19__PRETTY_FUNCTION__ = linkonce_odr constant [51 x i8] c"void functionTemplateWithCapturedStmt(T) [T = int]\00"
+// CHECK: @_ZZZ26functionTemplateWithLambdaIiEvT_ENKUlvE_clEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [76 x i8] c"auto functionTemplateWithLambda(int)::(anonymous class)::operator()() const\00"
+// CHECK: @_ZZ44functionTemplateWithUnnamedTemplateParameterIifEvT0_E19__PRETTY_FUNCTION__ = linkonce_odr constant [65 x i8] c"void functionTemplateWithUnnamedTemplateParameter(T) [T = float]\00"
-// CHECK: private unnamed_addr constant [60 x i8] c"void functionTemplateExplicitSpecialization(T) [T = double]\00"
-// CHECK: private unnamed_addr constant [52 x i8] c"T *functionTemplateWithCompoundTypes(T *) [T = int]\00"
-// CHECK: private unnamed_addr constant [54 x i8] c"T functionTemplateWithTemplateReturnType() [T = char]\00"
-// CHECK: private unnamed_addr constant [57 x i8] c"void functionTemplateWithoutParameterList() [T = double]\00"
-// CHECK: private unnamed_addr constant [62 x i8] c"void functionTemplateWithTwoParams(T, U) [T = int, U = float]\00"
+// CHECK: @_ZZ38functionTemplateExplicitSpecializationIdEvT_E19__PRETTY_FUNCTION__ = linkonce_odr constant [60 x i8] c"void functionTemplateExplicitSpecialization(T) [T = double]\00"
+// CHECK: @_ZZ33functionTemplateWithCompoundTypesIiEPT_S1_E19__PRETTY_FUNCTION__ = linkonce_odr constant [52 x i8] c"T *functionTemplateWithCompoundTypes(T *) [T = int]\00"
+// CHECK: @_ZZ38functionTemplateWithTemplateReturnTypeIcET_vE19__PRETTY_FUNCTION__ = linkonce_odr constant [54 x i8] c"T functionTemplateWithTemplateReturnType() [T = char]\00"
+// CHECK: @_ZZ36functionTemplateWithoutParameterListIdEvvE19__PRETTY_FUNCTION__ = linkonce_odr constant [57 x i8] c"void functionTemplateWithoutParameterList() [T = double]\00"
+// CHECK: @_ZZ29functionTemplateWithTwoParamsIifEvT_T0_E19__PRETTY_FUNCTION__ = linkonce_odr constant [62 x i8] c"void functionTemplateWithTwoParams(T, U) [T = int, U = float]\00"
-// CHECK: private unnamed_addr constant [22 x i8] c"classTemplateFunction\00"
-// CHECK: private unnamed_addr constant [77 x i8] c"void NS::ClassTemplate<NS::Base *>::classTemplateFunction() [T = NS::Base *]\00"
-// CHECK: private unnamed_addr constant [63 x i8] c"void NS::ClassTemplate<int>::classTemplateFunction() [T = int]\00"
+// CHECK: @_ZZN2NS13ClassTemplateIPNS_4BaseEE21classTemplateFunctionEvE8__func__ = linkonce_odr constant [22 x i8] c"classTemplateFunction\00"
+// CHECK: @_ZZN2NS13ClassTemplateIPNS_4BaseEE21classTemplateFunctionEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [77 x i8] c"void NS::ClassTemplate<NS::Base *>::classTemplateFunction() [T = NS::Base *]\00"
+// CHECK: @_ZZN2NS13ClassTemplateIiE21classTemplateFunctionEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [63 x i8] c"void NS::ClassTemplate<int>::classTemplateFunction() [T = int]\00"
-// CHECK: private unnamed_addr constant [18 x i8] c"functionTemplate1\00"
-// CHECK: private unnamed_addr constant [53 x i8] c"void NS::Base::functionTemplate1(T) [T = NS::Base *]\00"
-// CHECK: private unnamed_addr constant [46 x i8] c"void NS::Base::functionTemplate1(T) [T = int]\00"
+// CHECK: @_ZZN2NS4Base17functionTemplate1IPS0_EEvT_E8__func__ = linkonce_odr constant [18 x i8] c"functionTemplate1\00"
+// CHECK: @_ZZN2NS4Base17functionTemplate1IPS0_EEvT_E19__PRETTY_FUNCTION__ = linkonce_odr constant [53 x i8] c"void NS::Base::functionTemplate1(T) [T = NS::Base *]\00"
+// CHECK: @_ZZN2NS4Base17functionTemplate1IiEEvT_E19__PRETTY_FUNCTION__ = linkonce_odr constant [46 x i8] c"void NS::Base::functionTemplate1(T) [T = int]\00"
-// CHECK: private unnamed_addr constant [23 x i8] c"anonymousUnionFunction\00"
-// CHECK: private unnamed_addr constant [83 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous union)::anonymousUnionFunction()\00"
+// CHECK: @_ZZN2NS28ContainerForAnonymousRecordsUt1_22anonymousUnionFunctionEvE8__func__ = linkonce_odr constant [23 x i8] c"anonymousUnionFunction\00"
+// CHECK: @_ZZN2NS28ContainerForAnonymousRecordsUt1_22anonymousUnionFunctionEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [83 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous union)::anonymousUnionFunction()\00"
-// CHECK: private unnamed_addr constant [24 x i8] c"anonymousStructFunction\00"
-// CHECK: private unnamed_addr constant [85 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous struct)::anonymousStructFunction()\00"
+// CHECK: @_ZZN2NS28ContainerForAnonymousRecordsUt0_23anonymousStructFunctionEvE8__func__ = linkonce_odr constant [24 x i8] c"anonymousStructFunction\00"
+// CHECK: @_ZZN2NS28ContainerForAnonymousRecordsUt0_23anonymousStructFunctionEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [85 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous struct)::anonymousStructFunction()\00"
-// CHECK: private unnamed_addr constant [23 x i8] c"anonymousClassFunction\00"
-// CHECK: private unnamed_addr constant [83 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous class)::anonymousClassFunction()\00"
+// CHECK: @_ZZN2NS28ContainerForAnonymousRecordsUt_22anonymousClassFunctionEvE8__func__ = linkonce_odr constant [23 x i8] c"anonymousClassFunction\00"
+// CHECK: @_ZZN2NS28ContainerForAnonymousRecordsUt_22anonymousClassFunctionEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [83 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous class)::anonymousClassFunction()\00"
-// CHECK: private unnamed_addr constant [12 x i8] c"~Destructor\00"
-// CHECK: private unnamed_addr constant [30 x i8] c"NS::Destructor::~Destructor()\00"
+// CHECK: @_ZZN2NS10DestructorD1EvE8__func__ = linkonce_odr constant [12 x i8] c"~Destructor\00"
+// CHECK: @_ZZN2NS10DestructorD1EvE19__PRETTY_FUNCTION__ = linkonce_odr constant [30 x i8] c"NS::Destructor::~Destructor()\00"
-// CHECK: private unnamed_addr constant [12 x i8] c"Constructor\00"
-// CHECK: private unnamed_addr constant [41 x i8] c"NS::Constructor::Constructor(NS::Base *)\00"
-// CHECK: private unnamed_addr constant [34 x i8] c"NS::Constructor::Constructor(int)\00"
-// CHECK: private unnamed_addr constant [31 x i8] c"NS::Constructor::Constructor()\00"
+// CHECK: @_ZZN2NS11ConstructorC1EPNS_4BaseEE8__func__ = linkonce_odr constant [12 x i8] c"Constructor\00"
+// CHECK: @_ZZN2NS11ConstructorC1EPNS_4BaseEE19__PRETTY_FUNCTION__ = linkonce_odr constant [41 x i8] c"NS::Constructor::Constructor(NS::Base *)\00"
+// CHECK: @_ZZN2NS11ConstructorC1EiE19__PRETTY_FUNCTION__ = linkonce_odr constant [34 x i8] c"NS::Constructor::Constructor(int)\00"
+// CHECK: @_ZZN2NS11ConstructorC1EvE19__PRETTY_FUNCTION__ = linkonce_odr constant [31 x i8] c"NS::Constructor::Constructor()\00"
-// CHECK: private unnamed_addr constant [16 x i8] c"virtualFunction\00"
-// CHECK: private unnamed_addr constant [44 x i8] c"virtual void NS::Derived::virtualFunction()\00"
+// CHECK: @_ZZN2NS7Derived15virtualFunctionEvE8__func__ = linkonce_odr constant [16 x i8] c"virtualFunction\00"
+// CHECK: @_ZZN2NS7Derived15virtualFunctionEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [44 x i8] c"virtual void NS::Derived::virtualFunction()\00"
-// CHECK: private unnamed_addr constant [21 x i8] c"refQualifiedFunction\00"
-// CHECK: private unnamed_addr constant [41 x i8] c"void NS::Base::refQualifiedFunction() &&\00"
-// CHECK: private unnamed_addr constant [40 x i8] c"void NS::Base::refQualifiedFunction() &\00"
+// CHECK: @_ZZNO2NS4Base20refQualifiedFunctionEvE8__func__ = linkonce_odr constant [21 x i8] c"refQualifiedFunction\00"
+// CHECK: @_ZZNO2NS4Base20refQualifiedFunctionEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [41 x i8] c"void NS::Base::refQualifiedFunction() &&\00"
+// CHECK: @_ZZNR2NS4Base20refQualifiedFunctionEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [40 x i8] c"void NS::Base::refQualifiedFunction() &\00"
-// CHECK: private unnamed_addr constant [22 x i8] c"constVolatileFunction\00"
-// CHECK: private unnamed_addr constant [54 x i8] c"void NS::Base::constVolatileFunction() const volatile\00"
+// CHECK: @_ZZNVK2NS4Base21constVolatileFunctionEvE8__func__ = linkonce_odr constant [22 x i8] c"constVolatileFunction\00"
+// CHECK: @_ZZNVK2NS4Base21constVolatileFunctionEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [54 x i8] c"void NS::Base::constVolatileFunction() const volatile\00"
-// CHECK: private unnamed_addr constant [17 x i8] c"volatileFunction\00"
-// CHECK: private unnamed_addr constant [43 x i8] c"void NS::Base::volatileFunction() volatile\00"
+// CHECK: @_ZZNV2NS4Base16volatileFunctionEvE8__func__ = linkonce_odr constant [17 x i8] c"volatileFunction\00"
+// CHECK: @_ZZNV2NS4Base16volatileFunctionEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [43 x i8] c"void NS::Base::volatileFunction() volatile\00"
-// CHECK: private unnamed_addr constant [14 x i8] c"constFunction\00"
-// CHECK: private unnamed_addr constant [37 x i8] c"void NS::Base::constFunction() const\00"
+// CHECK: @_ZZNK2NS4Base13constFunctionEvE8__func__ = linkonce_odr constant [14 x i8] c"constFunction\00"
+// CHECK: @_ZZNK2NS4Base13constFunctionEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [37 x i8] c"void NS::Base::constFunction() const\00"
-// CHECK: private unnamed_addr constant [26 x i8] c"functionReturingTemplate2\00"
-// CHECK: private unnamed_addr constant [64 x i8] c"ClassTemplate<NS::Base *> NS::Base::functionReturingTemplate2()\00"
+// CHECK: @_ZZN2NS4Base25functionReturingTemplate2EvE8__func__ = linkonce_odr constant [26 x i8] c"functionReturingTemplate2\00"
+// CHECK: @_ZZN2NS4Base25functionReturingTemplate2EvE19__PRETTY_FUNCTION__ = linkonce_odr constant [64 x i8] c"ClassTemplate<NS::Base *> NS::Base::functionReturingTemplate2()\00"
-// CHECK: private unnamed_addr constant [26 x i8] c"functionReturingTemplate1\00"
-// CHECK: private unnamed_addr constant [57 x i8] c"ClassTemplate<int> NS::Base::functionReturingTemplate1()\00"
+// CHECK: @_ZZN2NS4Base25functionReturingTemplate1EvE8__func__ = linkonce_odr constant [26 x i8] c"functionReturingTemplate1\00"
+// CHECK: @_ZZN2NS4Base25functionReturingTemplate1EvE19__PRETTY_FUNCTION__ = linkonce_odr constant [57 x i8] c"ClassTemplate<int> NS::Base::functionReturingTemplate1()\00"
-// CHECK: private unnamed_addr constant [23 x i8] c"withTemplateParameter2\00"
-// CHECK: private unnamed_addr constant [65 x i8] c"void NS::Base::withTemplateParameter2(ClassTemplate<NS::Base *>)\00"
+// CHECK: @_ZZN2NS4Base22withTemplateParameter2ENS_13ClassTemplateIPS0_EEE8__func__ = linkonce_odr constant [23 x i8] c"withTemplateParameter2\00"
+// CHECK: @_ZZN2NS4Base22withTemplateParameter2ENS_13ClassTemplateIPS0_EEE19__PRETTY_FUNCTION__ = linkonce_odr constant [65 x i8] c"void NS::Base::withTemplateParameter2(ClassTemplate<NS::Base *>)\00"
-// CHECK: private unnamed_addr constant [23 x i8] c"withTemplateParameter1\00"
-// CHECK: private unnamed_addr constant [58 x i8] c"void NS::Base::withTemplateParameter1(ClassTemplate<int>)\00"
+// CHECK: @_ZZN2NS4Base22withTemplateParameter1ENS_13ClassTemplateIiEEE8__func__ = linkonce_odr constant [23 x i8] c"withTemplateParameter1\00"
+// CHECK: @_ZZN2NS4Base22withTemplateParameter1ENS_13ClassTemplateIiEEE19__PRETTY_FUNCTION__ = linkonce_odr constant [58 x i8] c"void NS::Base::withTemplateParameter1(ClassTemplate<int>)\00"
-// CHECK: private unnamed_addr constant [23 x i8] c"functionReturningClass\00"
-// CHECK: private unnamed_addr constant [45 x i8] c"NS::Base *NS::Base::functionReturningClass()\00"
+// CHECK: @_ZZN2NS4Base22functionReturningClassEvE8__func__ = linkonce_odr constant [23 x i8] c"functionReturningClass\00"
+// CHECK: @_ZZN2NS4Base22functionReturningClassEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [45 x i8] c"NS::Base *NS::Base::functionReturningClass()\00"
-// CHECK: private unnamed_addr constant [23 x i8] c"functionWithParameters\00"
-// CHECK: private unnamed_addr constant [64 x i8] c"void NS::Base::functionWithParameters(int, float *, NS::Base *)\00"
+// CHECK: @_ZZN2NS4Base22functionWithParametersEiPfPS0_E8__func__ = linkonce_odr constant [23 x i8] c"functionWithParameters\00"
+// CHECK: @_ZZN2NS4Base22functionWithParametersEiPfPS0_E19__PRETTY_FUNCTION__ = linkonce_odr constant [64 x i8] c"void NS::Base::functionWithParameters(int, float *, NS::Base *)\00"
-// CHECK: private unnamed_addr constant [17 x i8] c"variadicFunction\00"
-// CHECK: private unnamed_addr constant [42 x i8] c"void NS::Base::variadicFunction(int, ...)\00"
+// CHECK: @_ZZN2NS4Base16variadicFunctionEizE8__func__ = linkonce_odr constant [17 x i8] c"variadicFunction\00"
+// CHECK: @_ZZN2NS4Base16variadicFunctionEizE19__PRETTY_FUNCTION__ = linkonce_odr constant [42 x i8] c"void NS::Base::variadicFunction(int, ...)\00"
-// CHECK: private unnamed_addr constant [41 x i8] c"virtual void NS::Base::virtualFunction()\00"
+// CHECK: @_ZZN2NS4Base15virtualFunctionEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [41 x i8] c"virtual void NS::Base::virtualFunction()\00"
-// CHECK: private unnamed_addr constant [15 x i8] c"inlineFunction\00"
-// CHECK: private unnamed_addr constant [32 x i8] c"void NS::Base::inlineFunction()\00"
+// CHECK: @_ZZN2NS4Base14inlineFunctionEvE8__func__ = linkonce_odr constant [15 x i8] c"inlineFunction\00"
+// CHECK: @_ZZN2NS4Base14inlineFunctionEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [32 x i8] c"void NS::Base::inlineFunction()\00"
-// CHECK: private unnamed_addr constant [15 x i8] c"staticFunction\00"
-// CHECK: private unnamed_addr constant [39 x i8] c"static void NS::Base::staticFunction()\00"
+// CHECK: @_ZZN2NS4Base14staticFunctionEvE8__func__ = linkonce_odr constant [15 x i8] c"staticFunction\00"
+// CHECK: @_ZZN2NS4Base14staticFunctionEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [39 x i8] c"static void NS::Base::staticFunction()\00"
-// CHECK: private unnamed_addr constant [26 x i8] c"topLevelNamespaceFunction\00"
-// CHECK: private unnamed_addr constant [59 x i8] c"void ClassInTopLevelNamespace::topLevelNamespaceFunction()\00"
+// CHECK: @_ZZN24ClassInTopLevelNamespace25topLevelNamespaceFunctionEvE8__func__ = linkonce_odr constant [26 x i8] c"topLevelNamespaceFunction\00"
+// CHECK: @_ZZN24ClassInTopLevelNamespace25topLevelNamespaceFunctionEvE19__PRETTY_FUNCTION__ = linkonce_odr constant [59 x i8] c"void ClassInTopLevelNamespace::topLevelNamespaceFunction()\00"
-// CHECK: private unnamed_addr constant [27 x i8] c"anonymousNamespaceFunction\00"
-// CHECK: private unnamed_addr constant [84 x i8] c"void (anonymous namespace)::ClassInAnonymousNamespace::anonymousNamespaceFunction()\00"
+// CHECK: internal constant [27 x i8] c"anonymousNamespaceFunction\00"
+// CHECK: internal constant [84 x i8] c"void (anonymous namespace)::ClassInAnonymousNamespace::anonymousNamespaceFunction()\00"
-// CHECK: private unnamed_addr constant [19 x i8] c"localClassFunction\00"
-// CHECK: private unnamed_addr constant [59 x i8] c"void NS::localClass(int)::LocalClass::localClassFunction()\00"
+// CHECK: internal constant [19 x i8] c"localClassFunction\00"
+// CHECK: internal constant [59 x i8] c"void NS::localClass(int)::LocalClass::localClassFunction()\00"
Index: test/CodeGenObjC/predefined-expr.m
===================================================================
--- test/CodeGenObjC/predefined-expr.m
+++ test/CodeGenObjC/predefined-expr.m
@@ -1,15 +1,15 @@
// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 %s -emit-llvm -o - | FileCheck %s
-// CHECK: @"__func__.-[Foo instanceTest1]" = private unnamed_addr constant [21 x i8] c"-[Foo instanceTest1]\00"
-// CHECK: @"__func__.-[Foo instanceTest2:]" = private unnamed_addr constant [22 x i8] c"-[Foo instanceTest2:]\00"
-// CHECK: @"__func__.-[Foo instanceTest3:withB:]" = private unnamed_addr constant [28 x i8] c"-[Foo instanceTest3:withB:]\00"
-// CHECK: @"__func__.-[Foo instanceTest4]" = private unnamed_addr constant [21 x i8] c"-[Foo instanceTest4]\00"
-// CHECK: @"__func__.+[Foo classTest1]" = private unnamed_addr constant [18 x i8] c"+[Foo classTest1]\00"
-// CHECK: @"__func__.+[Foo classTest2:]" = private unnamed_addr constant [19 x i8] c"+[Foo classTest2:]\00"
-// CHECK: @"__func__.+[Foo classTest3:withB:]" = private unnamed_addr constant [25 x i8] c"+[Foo classTest3:withB:]\00"
-// CHECK: @"__func__.+[Foo classTest4]" = private unnamed_addr constant [18 x i8] c"+[Foo classTest4]\00"
-// CHECK: @"__func__.-[Foo(Category) instanceTestWithCategory]" = private unnamed_addr constant [42 x i8] c"-[Foo(Category) instanceTestWithCategory]\00"
-// CHECK: @"__func__.+[Foo(Category) classTestWithCategory]" = private unnamed_addr constant [39 x i8] c"+[Foo(Category) classTestWithCategory]\00"
+// CHECK: @"\01-[Foo instanceTest1].__func__" = internal constant [21 x i8] c"-[Foo instanceTest1]\00"
+// CHECK: @"\01-[Foo instanceTest2:].__func__" = internal constant [22 x i8] c"-[Foo instanceTest2:]\00"
+// CHECK: @"\01-[Foo instanceTest3:withB:].__func__" = internal constant [28 x i8] c"-[Foo instanceTest3:withB:]\00"
+// CHECK: @"\01-[Foo instanceTest4].__func__" = internal constant [21 x i8] c"-[Foo instanceTest4]\00"
+// CHECK: @"\01+[Foo classTest1].__func__" = internal constant [18 x i8] c"+[Foo classTest1]\00"
+// CHECK: @"\01+[Foo classTest2:].__func__" = internal constant [19 x i8] c"+[Foo classTest2:]\00"
+// CHECK: @"\01+[Foo classTest3:withB:].__func__" = internal constant [25 x i8] c"+[Foo classTest3:withB:]\00"
+// CHECK: @"\01+[Foo classTest4].__func__" = internal constant [18 x i8] c"+[Foo classTest4]\00"
+// CHECK: @"\01-[Foo(Category) instanceTestWithCategory].__func__" = internal constant [42 x i8] c"-[Foo(Category) instanceTestWithCategory]\00"
+// CHECK: @"\01+[Foo(Category) classTestWithCategory].__func__" = internal constant [39 x i8] c"+[Foo(Category) classTestWithCategory]\00"
int printf(const char * _Format, ...);
Index: test/CodeGen/const-init.c
===================================================================
--- test/CodeGen/const-init.c
+++ test/CodeGen/const-init.c
@@ -121,8 +121,8 @@
struct g23 {char a; short b; char c; struct g22 d;};
struct g23 g24 = {1,2,3,4};
-// CHECK: @g25.g26 = internal global i8* getelementptr inbounds ([4 x i8]* @__func__.g25, i32 0, i32 0)
-// CHECK: @__func__.g25 = private unnamed_addr constant [4 x i8] c"g25\00"
+// CHECK: @g25.g26 = internal global i8* getelementptr inbounds ([4 x i8]* @g25.__func__, i32 0, i32 0)
+// CHECK: @g25.__func__ = internal constant [4 x i8] c"g25\00"
int g25() {
static const char *g26 = __func__;
return *g26;
Index: test/CodeGen/func-in-block.c
===================================================================
--- test/CodeGen/func-in-block.c
+++ test/CodeGen/func-in-block.c
@@ -15,5 +15,5 @@
return 0; // not reached
}
-// CHECK: @__func__.__main_block_invoke = private unnamed_addr constant [20 x i8] c"__main_block_invoke\00"
-// CHECK: call void @PRINTF({{.*}}@__func__.__main_block_invoke
+// CHECK: [[BLOCK_FUNC:@.+]] = internal constant [20 x i8] c"__main_block_invoke\00"
+// CHECK: call void @PRINTF({{.*}}[[BLOCK_FUNC]]
Index: test/CodeGen/predefined-expr.c
===================================================================
--- test/CodeGen/predefined-expr.c
+++ test/CodeGen/predefined-expr.c
@@ -1,16 +1,16 @@
// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -fms-extensions %s -emit-llvm -o - | FileCheck %s
-// CHECK: @__func__.plainFunction = private unnamed_addr constant [14 x i8] c"plainFunction\00"
-// CHECK: @__PRETTY_FUNCTION__.plainFunction = private unnamed_addr constant [21 x i8] c"void plainFunction()\00"
-// CHECK: @__func__.externFunction = private unnamed_addr constant [15 x i8] c"externFunction\00"
-// CHECK: @__PRETTY_FUNCTION__.externFunction = private unnamed_addr constant [22 x i8] c"void externFunction()\00"
-// CHECK: @__func__.privateExternFunction = private unnamed_addr constant [22 x i8] c"privateExternFunction\00"
-// CHECK: @__PRETTY_FUNCTION__.privateExternFunction = private unnamed_addr constant [29 x i8] c"void privateExternFunction()\00"
-// CHECK: @__func__.__captured_stmt = private unnamed_addr constant [25 x i8] c"functionWithCapturedStmt\00"
-// CHECK: @__PRETTY_FUNCTION__.__captured_stmt = private unnamed_addr constant [32 x i8] c"void functionWithCapturedStmt()\00"
-// CHECK: @__func__.staticFunction = private unnamed_addr constant [15 x i8] c"staticFunction\00"
-// CHECK: @__PRETTY_FUNCTION__.staticFunction = private unnamed_addr constant [22 x i8] c"void staticFunction()\00"
+// CHECK: @plainFunction.__func__ = internal constant [14 x i8] c"plainFunction\00"
+// CHECK: @plainFunction.__PRETTY_FUNCTION__ = internal constant [21 x i8] c"void plainFunction()\00"
+// CHECK: @externFunction.__func__ = internal constant [15 x i8] c"externFunction\00"
+// CHECK: @externFunction.__PRETTY_FUNCTION__ = internal constant [22 x i8] c"void externFunction()\00"
+// CHECK: @privateExternFunction.__func__ = internal constant [22 x i8] c"privateExternFunction\00"
+// CHECK: @privateExternFunction.__PRETTY_FUNCTION__ = internal constant [29 x i8] c"void privateExternFunction()\00"
+// CHECK: @functionWithCapturedStmt.__func__ = internal constant [25 x i8] c"functionWithCapturedStmt\00"
+// CHECK: @functionWithCapturedStmt.__PRETTY_FUNCTION__ = internal constant [32 x i8] c"void functionWithCapturedStmt()\00"
+// CHECK: @staticFunction.__func__ = internal constant [15 x i8] c"staticFunction\00"
+// CHECK: @staticFunction.__PRETTY_FUNCTION__ = internal constant [22 x i8] c"void staticFunction()\00"
int printf(const char *, ...);
Index: test/SemaCXX/predefined-expr.cpp
===================================================================
--- test/SemaCXX/predefined-expr.cpp
+++ test/SemaCXX/predefined-expr.cpp
@@ -33,10 +33,9 @@
();
^{
- // FIXME: This is obviously wrong.
- static_assert(sizeof(__func__) == 1, "__baz_block_invoke");
- static_assert(sizeof(__FUNCTION__) == 1, "__baz_block_invoke");
- static_assert(sizeof(__PRETTY_FUNCTION__) == 1, "__baz_block_invoke");
+ static_assert(sizeof(__func__) == 27, "___Z3bazIiEiv_block_invoke");
+ static_assert(sizeof(__FUNCTION__) == 27, "___Z3bazIiEiv_block_invoke");
+ static_assert(sizeof(__PRETTY_FUNCTION__) == 27, "___Z3bazIiEiv_block_invoke");
}
();
@@ -65,10 +64,9 @@
();
^{
- // FIXME: This is obviously wrong.
- static_assert(sizeof(__func__) == 1, "__main_block_invoke");
- static_assert(sizeof(__FUNCTION__) == 1, "__main_block_invoke");
- static_assert(sizeof(__PRETTY_FUNCTION__) == 1, "__main_block_invoke");
+ static_assert(sizeof(__func__) == 20, "__main_block_invoke");
+ static_assert(sizeof(__FUNCTION__) == 20, "__main_block_invoke");
+ static_assert(sizeof(__PRETTY_FUNCTION__) == 20, "__main_block_invoke");
}
();
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -3472,9 +3472,10 @@
SourceLocation LitEndLoc,
TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr);
- ExprResult BuildPredefinedExpr(SourceLocation Loc,
+ ExprResult BuildPredefinedExpr(Scope *S, SourceLocation Loc,
PredefinedExpr::IdentType IT);
- ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
+ ExprResult ActOnPredefinedExpr(Scope *S, SourceLocation Loc,
+ tok::TokenKind Kind);
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);
ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr);
ExprResult ActOnCharacterConstant(const Token &Tok,
Index: include/clang/AST/Expr.h
===================================================================
--- include/clang/AST/Expr.h
+++ include/clang/AST/Expr.h
@@ -1161,7 +1161,7 @@
friend class ASTStmtWriter;
};
-/// PredefinedExpr - [C99 6.4.2.2] - A predefined identifier such as __func__.
+/// \brief [C99 6.4.2.2] - A predefined identifier such as __func__.
class PredefinedExpr : public Expr {
public:
enum IdentType {
@@ -1171,32 +1171,41 @@
FuncDName,
FuncSig,
PrettyFunction,
- /// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
+ /// \brief The same as PrettyFunction, except that the
/// 'virtual' keyword is omitted for virtual member functions.
PrettyFunctionNoVirtual
};
private:
SourceLocation Loc;
IdentType Type;
+ VarDecl *FNRef;
+
+ void setIdentType(IdentType IT) { Type = IT; }
+ void setFunctionNameRef(VarDecl *D) { FNRef = D; };
+
public:
- PredefinedExpr(SourceLocation l, QualType type, IdentType IT)
- : Expr(PredefinedExprClass, type, VK_LValue, OK_Ordinary,
- type->isDependentType(), type->isDependentType(),
- type->isInstantiationDependentType(),
- /*ContainsUnexpandedParameterPack=*/false),
- Loc(l), Type(IT) {}
+ PredefinedExpr(SourceLocation L, QualType FNTy, IdentType IT,
+ VarDecl *FNRef = nullptr)
+ : Expr(PredefinedExprClass, FNTy, VK_LValue, OK_Ordinary,
+ FNTy->isDependentType(), FNTy->isDependentType(),
+ FNTy->isInstantiationDependentType(),
+ /*ContainsUnexpandedParameterPack=*/false),
+ Loc(L), Type(IT), FNRef(FNRef) {}
/// \brief Construct an empty predefined expression.
explicit PredefinedExpr(EmptyShell Empty)
- : Expr(PredefinedExprClass, Empty) { }
+ : Expr(PredefinedExprClass, Empty), Loc(), Type(Func), FNRef(nullptr) {}
IdentType getIdentType() const { return Type; }
- void setIdentType(IdentType IT) { Type = IT; }
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
+ const VarDecl *getFunctionNameRef() const { return FNRef; }
+ VarDecl *getFunctionNameRef() { return FNRef; }
+
+ static StringRef getIdentTypeName(IdentType IT);
static std::string ComputeName(IdentType IT, const Decl *CurrentDecl);
SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
@@ -1208,6 +1217,8 @@
// Iterators
child_range children() { return child_range(); }
+
+ friend class ASTStmtReader;
};
/// \brief Used by IntegerLiteral/FloatingLiteral to store the numeric without
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -1677,6 +1677,15 @@
return getSema().ActOnSEHFinallyBlock(Loc, Block);
}
+ /// \brief Build a new predefined expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ ExprResult RebuildPredefinedExpr(SourceLocation Loc,
+ PredefinedExpr::IdentType IT) {
+ return getSema().BuildPredefinedExpr(/*S*/ nullptr, Loc, IT);
+ }
+
/// \brief Build a new expression that references a declaration.
///
/// By default, performs semantic analysis to build the new expression.
@@ -6964,7 +6973,11 @@
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
- return E;
+ if (!E->isTypeDependent())
+ return E;
+
+ return getDerived().RebuildPredefinedExpr(E->getLocation(),
+ E->getIdentType());
}
template<typename Derived>
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -42,6 +42,7 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaFixItUtils.h"
#include "clang/Sema/Template.h"
+#include "llvm/Support/ConvertUTF.h"
using namespace clang;
using namespace sema;
@@ -2901,7 +2902,18 @@
}
}
-ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc,
+static void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source,
+ SmallString<32> &Target) {
+ Target.resize(CharByteWidth * (Source.size() + 1));
+ char *ResultPtr = &Target[0];
+ const UTF8 *ErrorPtr;
+ bool success = ConvertUTF8toWide(CharByteWidth, Source, ResultPtr, ErrorPtr);
+ (void)success;
+ assert(success);
+ Target.resize(ResultPtr - &Target[0]);
+}
+
+ExprResult Sema::BuildPredefinedExpr(Scope *S, SourceLocation Loc,
PredefinedExpr::IdentType IT) {
// Pick the current block, lambda, captured statement or function.
Decl *currentDecl = nullptr;
@@ -2920,25 +2932,58 @@
}
QualType ResTy;
+ NamedDecl *ND = nullptr;
if (cast<DeclContext>(currentDecl)->isDependentContext())
ResTy = Context.DependentTy;
else {
// Pre-defined identifiers are of type char[x], where x is the length of
// the string.
- unsigned Length = PredefinedExpr::ComputeName(IT, currentDecl).length();
+ auto Str = PredefinedExpr::ComputeName(IT, currentDecl);
+ unsigned Length = Str.length();
+ StringLiteral *SL = nullptr;
llvm::APInt LengthI(32, Length + 1);
- if (IT == PredefinedExpr::LFunction)
+ if (IT == PredefinedExpr::LFunction) {
ResTy = Context.WideCharTy.withConst();
- else
+ SmallString<32> RawChars;
+ ConvertUTF8ToWideString(Context.getTypeSizeInChars(ResTy).getQuantity(),
+ Str, RawChars);
+ ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal,
+ /*IndexTypeQuals*/ 0);
+ SL = StringLiteral::Create(Context, RawChars, StringLiteral::Wide,
+ /*Pascal*/ false, ResTy, Loc);
+ } else {
ResTy = Context.CharTy.withConst();
- ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, 0);
+ ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal,
+ /*IndexTypeQuals*/ 0);
+ SL = StringLiteral::Create(Context, Str, StringLiteral::Ascii,
+ /*Pascal*/ false, ResTy, Loc);
+ }
+ auto Id = &Context.Idents.get(PredefinedExpr::getIdentTypeName(IT));
+ DeclarationName DN(Id);
+ auto DC = cast<DeclContext>(currentDecl);
+ ND = LookupSingleName(S, DN, Loc, LookupOrdinaryName);
+ // The variable must be static local for the current decl (required for
+ // blocks).
+ if (ND == nullptr || !DC->containsDecl(ND)) {
+ ND = VarDecl::Create(Context, DC, currentDecl->getLocation(),
+ currentDecl->getLocation(), Id, ResTy,
+ Context.getTrivialTypeSourceInfo(ResTy), SC_Static);
+ AddInitializerToDecl(ND, SL, /*DirectInit*/ true,
+ /*TypeMayContainAuto*/ false);
+ if (S)
+ PushOnScopeChains(ND, S);
+ else
+ DC->addDecl(ND);
+ }
}
- return new (Context) PredefinedExpr(Loc, ResTy, IT);
+ return new (Context)
+ PredefinedExpr(Loc, ResTy, IT, cast_or_null<VarDecl>(ND));
}
-ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) {
+ExprResult Sema::ActOnPredefinedExpr(Scope *S, SourceLocation Loc,
+ tok::TokenKind Kind) {
PredefinedExpr::IdentType IT;
switch (Kind) {
@@ -2951,7 +2996,7 @@
case tok::kw___PRETTY_FUNCTION__: IT = PredefinedExpr::PrettyFunction; break;
}
- return BuildPredefinedExpr(Loc, IT);
+ return BuildPredefinedExpr(S, Loc, IT);
}
ExprResult Sema::ActOnCharacterConstant(const Token &Tok, Scope *UDLScope) {
Index: lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiate.cpp
+++ lib/Sema/SemaTemplateInstantiate.cpp
@@ -1086,7 +1086,8 @@
if (!E->isTypeDependent())
return E;
- return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentType());
+ return getSema().BuildPredefinedExpr(/*S*/ nullptr, E->getLocation(),
+ E->getIdentType());
}
ExprResult
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -2021,7 +2021,9 @@
/// Extract the value of a character from a string literal.
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit,
uint64_t Index) {
- // FIXME: Support PredefinedExpr, ObjCEncodeExpr, MakeStringConstant
+ // FIXME: Support ObjCEncodeExpr, MakeStringConstant
+ if (auto PE = dyn_cast<PredefinedExpr>(Lit))
+ Lit = PE->getFunctionNameRef()->getInit()->IgnoreImpCasts();
const StringLiteral *S = cast<StringLiteral>(Lit);
const ConstantArrayType *CAT =
Info.Ctx.getAsConstantArrayType(S->getType());
@@ -2649,10 +2651,10 @@
return false;
CompleteObject LitObj(&Lit, Base->getType());
return extractSubobject(Info, Conv, LitObj, LVal.Designator, RVal);
- } else if (isa<StringLiteral>(Base)) {
+ } else if (isa<StringLiteral>(Base) || isa<PredefinedExpr>(Base)) {
// We represent a string literal array as an lvalue pointing at the
// corresponding expression, rather than building an array of chars.
- // FIXME: Support PredefinedExpr, ObjCEncodeExpr, MakeStringConstant
+ // FIXME: Support ObjCEncodeExpr, MakeStringConstant
APValue Str(Base, CharUnits::Zero(), APValue::NoLValuePath(), 0);
CompleteObject StrObj(&Str, Base->getType());
return extractSubobject(Info, Conv, StrObj, LVal.Designator, RVal);
Index: lib/AST/StmtPrinter.cpp
===================================================================
--- lib/AST/StmtPrinter.cpp
+++ lib/AST/StmtPrinter.cpp
@@ -983,28 +983,7 @@
}
void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
- switch (Node->getIdentType()) {
- default:
- llvm_unreachable("unknown case");
- case PredefinedExpr::Func:
- OS << "__func__";
- break;
- case PredefinedExpr::Function:
- OS << "__FUNCTION__";
- break;
- case PredefinedExpr::FuncDName:
- OS << "__FUNCDNAME__";
- break;
- case PredefinedExpr::FuncSig:
- OS << "__FUNCSIG__";
- break;
- case PredefinedExpr::LFunction:
- OS << "L__FUNCTION__";
- break;
- case PredefinedExpr::PrettyFunction:
- OS << "__PRETTY_FUNCTION__";
- break;
- }
+ OS << PredefinedExpr::getIdentTypeName(Node->getIdentType());
}
void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
Index: lib/AST/ASTDumper.cpp
===================================================================
--- lib/AST/ASTDumper.cpp
+++ lib/AST/ASTDumper.cpp
@@ -1714,15 +1714,7 @@
void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
VisitExpr(Node);
- switch (Node->getIdentType()) {
- default: llvm_unreachable("unknown case");
- case PredefinedExpr::Func: OS << " __func__"; break;
- case PredefinedExpr::Function: OS << " __FUNCTION__"; break;
- case PredefinedExpr::FuncDName: OS << " __FUNCDNAME__"; break;
- case PredefinedExpr::LFunction: OS << " L__FUNCTION__"; break;
- case PredefinedExpr::PrettyFunction: OS << " __PRETTY_FUNCTION__";break;
- case PredefinedExpr::FuncSig: OS << " __FUNCSIG__"; break;
- }
+ OS << " " << PredefinedExpr::getIdentTypeName(Node->getIdentType());
}
void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
Index: lib/AST/Expr.cpp
===================================================================
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -448,6 +448,25 @@
return getNameInfo().getLocEnd();
}
+StringRef PredefinedExpr::getIdentTypeName(PredefinedExpr::IdentType IT) {
+ switch (IT) {
+ case Func:
+ return "__func__";
+ case Function:
+ return "__FUNCTION__";
+ case FuncDName:
+ return "__FUNCDNAME__";
+ case LFunction:
+ return "L__FUNCTION__";
+ case PrettyFunction:
+ return "__PRETTY_FUNCTION__";
+ case FuncSig:
+ return "__FUNCSIG__";
+ case PrettyFunctionNoVirtual:
+ llvm_unreachable("unknown case");
+ }
+}
+
// FIXME: Maybe this should use DeclPrinter with a special "print predefined
// expr" policy instead.
std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
@@ -477,6 +496,18 @@
}
return "";
}
+ if (auto *BD = dyn_cast<BlockDecl>(CurrentDecl)) {
+ std::unique_ptr<MangleContext> MC;
+ MC.reset(Context.createMangleContext());
+ SmallString<256> Buffer;
+ llvm::raw_svector_ostream Out(Buffer);
+ auto DC = CurrentDecl->getDeclContext();
+ if (DC->isFileContext())
+ MC->mangleGlobalBlock(BD, /*ID*/ nullptr, Out);
+ else
+ MC->mangleBlock(DC, BD, Out);
+ return Out.str();
+ }
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) {
if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual && IT != FuncSig)
return FD->getNameAsString();
@@ -600,9 +631,8 @@
// type deduction and lambdas. For trailing return types resolve the
// decltype expression. Otherwise print the real type when this is
// not a constructor or destructor.
- if ((isa<CXXMethodDecl>(FD) &&
- cast<CXXMethodDecl>(FD)->getParent()->isLambda()) ||
- (FT && FT->getReturnType()->getAs<AutoType>()))
+ if (isa<CXXMethodDecl>(FD) &&
+ cast<CXXMethodDecl>(FD)->getParent()->isLambda())
Proto = "auto " + Proto;
else if (FT && FT->getReturnType()->getAs<DecltypeType>())
FT->getReturnType()
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -864,7 +864,6 @@
case Stmt::ObjCProtocolExprClass:
case Stmt::ObjCSelectorExprClass:
case Stmt::ParenListExprClass:
- case Stmt::PredefinedExprClass:
case Stmt::ShuffleVectorExprClass:
case Stmt::ConvertVectorExprClass:
case Stmt::VAArgExprClass:
@@ -876,6 +875,7 @@
// Cases we intentionally don't evaluate, since they don't need
// to be explicitly evaluated.
+ case Stmt::PredefinedExprClass:
case Stmt::AddrLabelExprClass:
case Stmt::AttributedStmtClass:
case Stmt::IntegerLiteralClass:
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -24,6 +24,7 @@
#include "clang/AST/Attr.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
@@ -2051,86 +2052,22 @@
E->getType());
}
-static void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source,
- SmallString<32>& Target) {
- Target.resize(CharByteWidth * (Source.size() + 1));
- char *ResultPtr = &Target[0];
- const UTF8 *ErrorPtr;
- bool success = ConvertUTF8toWide(CharByteWidth, Source, ResultPtr, ErrorPtr);
- (void)success;
- assert(success);
- Target.resize(ResultPtr - &Target[0]);
-}
-
LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
- switch (E->getIdentType()) {
- default:
- return EmitUnsupportedLValue(E, "predefined expression");
-
- case PredefinedExpr::Func:
- case PredefinedExpr::Function:
- case PredefinedExpr::LFunction:
- case PredefinedExpr::FuncDName:
- case PredefinedExpr::FuncSig:
- case PredefinedExpr::PrettyFunction: {
- PredefinedExpr::IdentType IdentType = E->getIdentType();
- std::string GVName;
-
- // FIXME: We should use the string literal mangling for the Microsoft C++
- // ABI so that strings get merged.
- switch (IdentType) {
- default: llvm_unreachable("Invalid type");
- case PredefinedExpr::Func: GVName = "__func__."; break;
- case PredefinedExpr::Function: GVName = "__FUNCTION__."; break;
- case PredefinedExpr::FuncDName: GVName = "__FUNCDNAME__."; break;
- case PredefinedExpr::FuncSig: GVName = "__FUNCSIG__."; break;
- case PredefinedExpr::LFunction: GVName = "L__FUNCTION__."; break;
- case PredefinedExpr::PrettyFunction: GVName = "__PRETTY_FUNCTION__."; break;
- }
-
- StringRef FnName = CurFn->getName();
- if (FnName.startswith("\01"))
- FnName = FnName.substr(1);
- GVName += FnName;
-
- // If this is outside of a function use the top level decl.
- const Decl *CurDecl = CurCodeDecl;
- if (!CurDecl || isa<VarDecl>(CurDecl))
- CurDecl = getContext().getTranslationUnitDecl();
-
- const Type *ElemType = E->getType()->getArrayElementTypeNoTypeQual();
- std::string FunctionName;
- if (isa<BlockDecl>(CurDecl)) {
- // Blocks use the mangled function name.
- // FIXME: ComputeName should handle blocks.
- FunctionName = FnName.str();
- } else if (isa<CapturedDecl>(CurDecl)) {
- // For a captured statement, the function name is its enclosing
- // function name not the one compiler generated.
- FunctionName = PredefinedExpr::ComputeName(IdentType, CurDecl);
- } else {
- FunctionName = PredefinedExpr::ComputeName(IdentType, CurDecl);
- assert(cast<ConstantArrayType>(E->getType())->getSize() - 1 ==
- FunctionName.size() &&
- "Computed __func__ length differs from type!");
- }
-
- llvm::Constant *C;
- if (ElemType->isWideCharType()) {
- SmallString<32> RawChars;
- ConvertUTF8ToWideString(
- getContext().getTypeSizeInChars(ElemType).getQuantity(), FunctionName,
- RawChars);
- StringLiteral *SL = StringLiteral::Create(
- getContext(), RawChars, StringLiteral::Wide,
- /*Pascal = */ false, E->getType(), E->getLocation());
- C = CGM.GetAddrOfConstantStringFromLiteral(SL);
- } else {
- C = CGM.GetAddrOfConstantCString(FunctionName, GVName.c_str(), 1);
- }
- return MakeAddrLValue(C, E->getType());
- }
- }
+ auto VD = E->getFunctionNameRef();
+ assert(VD != nullptr && "No variable is associated with PredefinedExpr");
+// auto SL = cast<StringLiteral>(VD->getInit()->IgnoreImpCasts());
+// StringRef FnName = CurFn->getName();
+// if (FnName.startswith("\01"))
+// FnName = FnName.substr(1);
+// std::string NameItems[] = {VD->getNameAsString(), FnName};
+// std::string GVName = llvm::join(NameItems, NameItems + 2, ".");
+//
+// auto C = CGM.GetAddrOfConstantStringFromLiteral(SL, GVName);
+// return MakeAddrLValue(C, E->getType());
+ if (LocalDeclMap.count(VD) == 0)
+ EmitStaticVarDecl(
+ *VD, CGM.getLLVMLinkageVarDefinition(VD, /*isConstant*/ false));
+ return MakeAddrLValue(CGM.getStaticLocalDeclAddress(VD), E->getType());
}
/// Emit a type description suitable for use by a runtime sanitizer library. The
Index: lib/Parse/ParseExpr.cpp
===================================================================
--- lib/Parse/ParseExpr.cpp
+++ lib/Parse/ParseExpr.cpp
@@ -834,7 +834,8 @@
case tok::kw___FUNCSIG__: // primary-expression: __FUNCSIG__ [MS]
case tok::kw_L__FUNCTION__: // primary-expression: L__FUNCTION__ [MS]
case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU]
- Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind);
+ Res = Actions.ActOnPredefinedExpr(getCurScope(), Tok.getLocation(),
+ SavedKind);
ConsumeToken();
break;
case tok::string_literal: // primary-expression: string-literal
Index: lib/Serialization/ASTReaderStmt.cpp
===================================================================
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -423,6 +423,7 @@
VisitExpr(E);
E->setLocation(ReadSourceLocation(Record, Idx));
E->setIdentType((PredefinedExpr::IdentType)Record[Idx++]);
+ E->setFunctionNameRef(ReadDeclAs<VarDecl>(Record, Idx));
}
void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
Index: lib/Serialization/ASTWriterStmt.cpp
===================================================================
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -333,6 +333,7 @@
VisitExpr(E);
Writer.AddSourceLocation(E->getLocation(), Record);
Record.push_back(E->getIdentType()); // FIXME: stable encoding
+ Writer.AddDeclRef(E->getFunctionNameRef(), Record);
Code = serialization::EXPR_PREDEFINED;
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits