Tyker updated this revision to Diff 217600.
Tyker added a comment.
Sorry for the long wait.
Changes:
- Rebased on current master
- Duplicated test file so that it runs for both importing
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D63640/new/
https://reviews.llvm.org/D63640
Files:
clang/include/clang/AST/APValue.h
clang/include/clang/AST/ASTContext.h
clang/include/clang/AST/ASTImporter.h
clang/include/clang/AST/Expr.h
clang/include/clang/AST/TextNodeDumper.h
clang/include/clang/Serialization/ASTReader.h
clang/lib/AST/APValue.cpp
clang/lib/AST/ASTContext.cpp
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/Decl.cpp
clang/lib/AST/Expr.cpp
clang/lib/AST/TextNodeDumper.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/lib/Serialization/ASTWriterStmt.cpp
clang/test/ASTMerge/APValue/APValue.cpp
clang/test/PCH/APValue.cpp
Index: clang/test/PCH/APValue.cpp
===================================================================
--- /dev/null
+++ clang/test/PCH/APValue.cpp
@@ -0,0 +1,210 @@
+
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -emit-pch %s -o %t.pch
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -include-pch %t.pch -ast-dump-all | FileCheck %s
+
+#ifndef EMIT
+#define EMIT
+
+namespace Integer {
+
+constexpr int Unique_Int = int(6789);
+//CHECK: VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int' 6789
+
+constexpr __uint128_t Unique_Int128 = ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+//CHECK: VarDecl {{.*}} Unique_Int128
+//CHECK-NEXT: ConstantExpr {{.*}} 'unsigned __int128' 156773562844924187900898496343692168785
+
+}
+
+namespace FloatingPoint {
+
+constexpr double Unique_Double = double(567890.67890);
+//CHECK: VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}} 'double' 5.678907e+05
+
+}
+
+// FIXME: Add test for FixePoint, ComplexInt, ComplexFloat, AddrLabelDiff.
+
+namespace Struct {
+
+struct B {
+ int i;
+ double d;
+};
+
+constexpr B Basic_Struct = B{1, 0.7};
+//CHECK: VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::B' {1, 7.000000e-01}
+
+struct C {
+ int i = 9;
+};
+
+struct A : B {
+ int i;
+ double d;
+ C c;
+};
+
+constexpr A Advanced_Struct = A{Basic_Struct, 1, 79.789, {}};
+//CHECK: VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::A' {{[{][{]}}1, 7.000000e-01}, 1, 7.978900e+01, {9}}
+
+}
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Vector_Int = (v4si){8, 2, 3};
+//CHECK: VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'Vector::v4si':'__attribute__((__vector_size__(4 * sizeof(int)))) int' {8, 2, 3, 0}
+
+}
+
+namespace Array {
+
+constexpr int Array_Int[] = {1, 2, 3, 4, 5, 6};
+//CHECK: VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int [6]' {1, 2, 3, 4, 5, 6}
+
+struct A {
+ int i = 789;
+ double d = 67890.09876;
+};
+
+constexpr A Array2_Struct[][3] = {{{}, {-45678, 9.8}, {9}}, {{}}};
+//CHECK: VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'Array::A const [2][3]' {{[{][{]}}{789, 6.789010e+04}, {-45678, 9.800000e+00}, {9, 6.789010e+04}}, {{[{][{]}}789, 6.789010e+04}, {789, 6.789010e+04}, {789, 6.789010e+04}}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Array_Vector[] = {{1, 2, 3, 4}, {4, 5, 6, 7}};
+//CHECK: VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Array::v4si [2]' {{[{][{]}}1, 2, 3, 4}, {4, 5, 6, 7}}
+
+}
+
+namespace Union {
+
+struct A {
+ int i = 6789;
+ float f = 987.9876;
+};
+
+union U {
+ int i;
+ A a{567890, 9876.5678f};
+};
+
+constexpr U Unique_Union1 = U{0};
+//CHECK: VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.i = 0}
+
+constexpr U Unique_Union2 = U{};
+//CHECK: VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.a = {567890, 9.876567e+03}}
+
+}
+
+namespace MemberPointer{
+
+struct A {
+ struct B {
+ struct C {
+ struct D {
+ struct E {
+ struct F {
+ struct G {
+ int i;
+ };
+ };
+ };
+ };
+ };
+ };
+};
+
+constexpr auto MemberPointer1 = &A::B::C::D::E::F::G::i;
+//CHECK: VarDecl {{.*}} MemberPointer1
+//CHECK-NEXT: ConstantExpr {{.*}} 'int MemberPointer::A::B::C::D::E::F::G::*' &G::i
+
+struct A1 {
+ struct B1 {
+ int f() const {
+ return 0;
+ }
+ };
+
+};
+
+constexpr auto MemberPointer2 = &A1::B1::f;
+//CHECK: VarDecl {{.*}} MemberPointer2
+//CHECK-NEXT: ConstantExpr {{.*}} 'int (MemberPointer::A1::B1::*)() const' &B1::f
+
+}
+
+namespace std {
+ struct type_info;
+};
+
+namespace LValue {
+
+constexpr int LValueInt = 0;
+constexpr const int& ConstIntRef = LValueInt;
+//CHECK: VarDecl {{.*}} ConstIntRef
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int' lvalue &LValueInt
+constexpr const int* IntPtr = &LValueInt;
+//CHECK: VarDecl {{.*}} IntPtr
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int *' &LValueInt
+
+constexpr const int* NullPtr = nullptr;
+//CHECK: VarDecl {{.*}} NullPtr
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int *const' nullptr
+
+struct A {
+ int Arr[6] = {0, 1, 3, 4, 5, 9};
+ int i = 0;
+};
+
+constexpr A Arr[] = {{}, {}};
+
+constexpr const int& ArrayStructRef1 = Arr[0].i;
+//CHECK: VarDecl {{.*}} ArrayStructRef1
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int' lvalue &Arr[0].i
+
+constexpr const int& ArrayStructRef2 = Arr[1].Arr[5];
+//CHECK: VarDecl {{.*}} ArrayStructRef2
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int' lvalue &Arr[1].Arr[5]
+
+constexpr const int* ArrayStructRef3 = &ArrayStructRef2;
+//CHECK: VarDecl {{.*}} ArrayStructRef3
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int *' &Arr[1].Arr[5]
+
+struct B : A {
+};
+
+struct C {
+ B b;
+};
+
+constexpr C c;
+
+constexpr const int& StructPathRef = c.b.i;
+//CHECK: VarDecl {{.*}} StructPathRef
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int' lvalue &c.b.A::i
+
+constexpr const std::type_info &TypeID = typeid(c);
+//CHECK: VarDecl {{.*}} TypeID
+//CHECK-NEXT: ConstantExpr {{.*}} 'const std::type_info' lvalue &typeid(LValue::C)
+
+constexpr const std::type_info &TypeID2 = typeid(Arr[1].Arr[2]);
+//CHECK: VarDecl {{.*}} TypeID2
+//CHECK-NEXT: ConstantExpr {{.*}} 'const std::type_info' lvalue &typeid(int)
+
+}
+
+#endif
+
Index: clang/test/ASTMerge/APValue/APValue.cpp
===================================================================
--- /dev/null
+++ clang/test/ASTMerge/APValue/APValue.cpp
@@ -0,0 +1,210 @@
+
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -emit-pch %s -o %t.pch
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -ast-merge %t.pch -ast-dump-all | FileCheck %s
+
+#ifndef EMIT
+#define EMIT
+
+namespace Integer {
+
+constexpr int Unique_Int = int(6789);
+//CHECK: VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int' 6789
+
+constexpr __uint128_t Unique_Int128 = ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+//CHECK: VarDecl {{.*}} Unique_Int128
+//CHECK-NEXT: ConstantExpr {{.*}} 'unsigned __int128' 156773562844924187900898496343692168785
+
+}
+
+namespace FloatingPoint {
+
+constexpr double Unique_Double = double(567890.67890);
+//CHECK: VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}} 'double' 5.678907e+05
+
+}
+
+// FIXME: Add test for FixePoint, ComplexInt, ComplexFloat, AddrLabelDiff.
+
+namespace Struct {
+
+struct B {
+ int i;
+ double d;
+};
+
+constexpr B Basic_Struct = B{1, 0.7};
+//CHECK: VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::B' {1, 7.000000e-01}
+
+struct C {
+ int i = 9;
+};
+
+struct A : B {
+ int i;
+ double d;
+ C c;
+};
+
+constexpr A Advanced_Struct = A{Basic_Struct, 1, 79.789, {}};
+//CHECK: VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::A' {{[{][{]}}1, 7.000000e-01}, 1, 7.978900e+01, {9}}
+
+}
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Vector_Int = (v4si){8, 2, 3};
+//CHECK: VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'Vector::v4si':'__attribute__((__vector_size__(4 * sizeof(int)))) int' {8, 2, 3, 0}
+
+}
+
+namespace Array {
+
+constexpr int Array_Int[] = {1, 2, 3, 4, 5, 6};
+//CHECK: VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int [6]' {1, 2, 3, 4, 5, 6}
+
+struct A {
+ int i = 789;
+ double d = 67890.09876;
+};
+
+constexpr A Array2_Struct[][3] = {{{}, {-45678, 9.8}, {9}}, {{}}};
+//CHECK: VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'Array::A const [2][3]' {{[{][{]}}{789, 6.789010e+04}, {-45678, 9.800000e+00}, {9, 6.789010e+04}}, {{[{][{]}}789, 6.789010e+04}, {789, 6.789010e+04}, {789, 6.789010e+04}}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Array_Vector[] = {{1, 2, 3, 4}, {4, 5, 6, 7}};
+//CHECK: VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Array::v4si [2]' {{[{][{]}}1, 2, 3, 4}, {4, 5, 6, 7}}
+
+}
+
+namespace Union {
+
+struct A {
+ int i = 6789;
+ float f = 987.9876;
+};
+
+union U {
+ int i;
+ A a{567890, 9876.5678f};
+};
+
+constexpr U Unique_Union1 = U{0};
+//CHECK: VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.i = 0}
+
+constexpr U Unique_Union2 = U{};
+//CHECK: VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.a = {567890, 9.876567e+03}}
+
+}
+
+namespace MemberPointer{
+
+struct A {
+ struct B {
+ struct C {
+ struct D {
+ struct E {
+ struct F {
+ struct G {
+ int i;
+ };
+ };
+ };
+ };
+ };
+ };
+};
+
+constexpr auto MemberPointer1 = &A::B::C::D::E::F::G::i;
+//CHECK: VarDecl {{.*}} MemberPointer1
+//CHECK-NEXT: ConstantExpr {{.*}} 'int MemberPointer::A::B::C::D::E::F::G::*' &G::i
+
+struct A1 {
+ struct B1 {
+ int f() const {
+ return 0;
+ }
+ };
+
+};
+
+constexpr auto MemberPointer2 = &A1::B1::f;
+//CHECK: VarDecl {{.*}} MemberPointer2
+//CHECK-NEXT: ConstantExpr {{.*}} 'int (MemberPointer::A1::B1::*)() const' &B1::f
+
+}
+
+namespace std {
+ struct type_info;
+};
+
+namespace LValue {
+
+constexpr int LValueInt = 0;
+constexpr const int& ConstIntRef = LValueInt;
+//CHECK: VarDecl {{.*}} ConstIntRef
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int' lvalue &LValueInt
+constexpr const int* IntPtr = &LValueInt;
+//CHECK: VarDecl {{.*}} IntPtr
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int *' &LValueInt
+
+constexpr const int* NullPtr = nullptr;
+//CHECK: VarDecl {{.*}} NullPtr
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int *const' nullptr
+
+struct A {
+ int Arr[6] = {0, 1, 3, 4, 5, 9};
+ int i = 0;
+};
+
+constexpr A Arr[] = {{}, {}};
+
+constexpr const int& ArrayStructRef1 = Arr[0].i;
+//CHECK: VarDecl {{.*}} ArrayStructRef1
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int' lvalue &Arr[0].i
+
+constexpr const int& ArrayStructRef2 = Arr[1].Arr[5];
+//CHECK: VarDecl {{.*}} ArrayStructRef2
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int' lvalue &Arr[1].Arr[5]
+
+constexpr const int* ArrayStructRef3 = &ArrayStructRef2;
+//CHECK: VarDecl {{.*}} ArrayStructRef3
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int *' &Arr[1].Arr[5]
+
+struct B : A {
+};
+
+struct C {
+ B b;
+};
+
+constexpr C c;
+
+constexpr const int& StructPathRef = c.b.i;
+//CHECK: VarDecl {{.*}} StructPathRef
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int' lvalue &c.b.A::i
+
+constexpr const std::type_info &TypeID = typeid(c);
+//CHECK: VarDecl {{.*}} TypeID
+//CHECK-NEXT: ConstantExpr {{.*}} 'const std::type_info' lvalue &typeid(LValue::C)
+
+constexpr const std::type_info &TypeID2 = typeid(Arr[1].Arr[2]);
+//CHECK: VarDecl {{.*}} TypeID2
+//CHECK-NEXT: ConstantExpr {{.*}} 'const std::type_info' lvalue &typeid(int)
+
+}
+
+#endif
+
Index: clang/lib/Serialization/ASTWriterStmt.cpp
===================================================================
--- clang/lib/Serialization/ASTWriterStmt.cpp
+++ clang/lib/Serialization/ASTWriterStmt.cpp
@@ -11,13 +11,13 @@
///
//===----------------------------------------------------------------------===//
-#include "clang/Serialization/ASTWriter.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Lex/Token.h"
+#include "clang/Serialization/ASTWriter.h"
#include "llvm/Bitstream/BitstreamWriter.h"
using namespace clang;
@@ -27,35 +27,34 @@
namespace clang {
- class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
- ASTWriter &Writer;
- ASTRecordWriter Record;
+class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
+ ASTWriter &Writer;
+ ASTRecordWriter Record;
- serialization::StmtCode Code;
- unsigned AbbrevToUse;
+ serialization::StmtCode Code;
+ unsigned AbbrevToUse;
- public:
- ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
- : Writer(Writer), Record(Writer, Record),
- Code(serialization::STMT_NULL_PTR), AbbrevToUse(0) {}
+public:
+ ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
+ : Writer(Writer), Record(Writer, Record),
+ Code(serialization::STMT_NULL_PTR), AbbrevToUse(0) {}
- ASTStmtWriter(const ASTStmtWriter&) = delete;
+ ASTStmtWriter(const ASTStmtWriter &) = delete;
- uint64_t Emit() {
- assert(Code != serialization::STMT_NULL_PTR &&
- "unhandled sub-statement writing AST file");
- return Record.EmitStmt(Code, AbbrevToUse);
- }
+ uint64_t Emit() {
+ assert(Code != serialization::STMT_NULL_PTR &&
+ "unhandled sub-statement writing AST file");
+ return Record.EmitStmt(Code, AbbrevToUse);
+ }
- void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &ArgInfo,
- const TemplateArgumentLoc *Args);
+ void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &ArgInfo,
+ const TemplateArgumentLoc *Args);
- void VisitStmt(Stmt *S);
-#define STMT(Type, Base) \
- void Visit##Type(Type *);
+ void VisitStmt(Stmt *S);
+#define STMT(Type, Base) void Visit##Type(Type *);
#include "clang/AST/StmtNodes.inc"
- };
-}
+};
+} // namespace clang
void ASTStmtWriter::AddTemplateKWAndArgsInfo(
const ASTTemplateKWAndArgsInfo &ArgInfo, const TemplateArgumentLoc *Args) {
@@ -306,7 +305,8 @@
Record.AddStmt(S->getClobberStringLiteral(I));
// Labels
- for (auto *E : S->labels()) Record.AddStmt(E);
+ for (auto *E : S->labels())
+ Record.AddStmt(E);
Code = serialization::STMT_GCCASM;
}
@@ -437,7 +437,8 @@
case ConstantExpr::RSK_Int64:
Record.push_back(E->Int64Result());
Record.push_back(E->ConstantExprBits.IsUnsigned |
- E->ConstantExprBits.BitWidth << 1);
+ E->ConstantExprBits.BitWidth << 1 |
+ E->ConstantExprBits.APValueKind << 8);
break;
case ConstantExpr::RSK_APValue:
Record.AddAPValue(E->APValueResult());
@@ -724,8 +725,8 @@
Code = serialization::EXPR_OBJC_ISA;
}
-void ASTStmtWriter::
-VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
+void ASTStmtWriter::VisitObjCIndirectCopyRestoreExpr(
+ ObjCIndirectCopyRestoreExpr *E) {
VisitExpr(E);
Record.AddStmt(E->getSubExpr());
Record.push_back(E->shouldCopy());
@@ -746,8 +747,8 @@
Record.AddStmt(E->getSubExpr());
Record.push_back(E->getCastKind()); // FIXME: stable encoding
- for (CastExpr::path_iterator
- PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
+ for (CastExpr::path_iterator PI = E->path_begin(), PE = E->path_end();
+ PI != PE; ++PI)
Record.AddCXXBaseSpecifier(**PI);
}
@@ -778,8 +779,8 @@
Code = serialization::EXPR_CONDITIONAL_OPERATOR;
}
-void
-ASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
+void ASTStmtWriter::VisitBinaryConditionalOperator(
+ BinaryConditionalOperator *E) {
VisitExpr(E);
Record.AddStmt(E->getOpaqueValue());
Record.AddStmt(E->getCommon());
@@ -837,7 +838,7 @@
Record.AddStmt(E->getSyntacticForm());
Record.AddSourceLocation(E->getLBraceLoc());
Record.AddSourceLocation(E->getRBraceLoc());
- bool isArrayFiller = E->ArrayFillerOrUnionFieldInit.is<Expr*>();
+ bool isArrayFiller = E->ArrayFillerOrUnionFieldInit.is<Expr *>();
Record.push_back(isArrayFiller);
if (isArrayFiller)
Record.AddStmt(E->getArrayFiller());
@@ -1033,8 +1034,9 @@
Record.push_back(result);
Record.AddStmt(E->getSyntacticForm());
- for (PseudoObjectExpr::semantics_iterator
- i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
+ for (PseudoObjectExpr::semantics_iterator i = E->semantics_begin(),
+ e = E->semantics_end();
+ i != e; ++i) {
Record.AddStmt(*i);
}
Code = serialization::EXPR_PSEUDO_OBJECT;
@@ -1288,7 +1290,8 @@
Code = serialization::EXPR_OBJC_BOOL_LITERAL;
}
-void ASTStmtWriter::VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
+void ASTStmtWriter::VisitObjCAvailabilityCheckExpr(
+ ObjCAvailabilityCheckExpr *E) {
VisitExpr(E);
Record.AddSourceRange(E->getSourceRange());
Record.AddVersionTuple(E->getVersion());
@@ -1404,7 +1407,7 @@
// Add capture initializers.
for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(),
- CEnd = E->capture_init_end();
+ CEnd = E->capture_init_end();
C != CEnd; ++C) {
Record.AddStmt(*C);
}
@@ -1412,7 +1415,8 @@
Code = serialization::EXPR_LAMBDA;
}
-void ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
+void ASTStmtWriter::VisitCXXStdInitializerListExpr(
+ CXXStdInitializerListExpr *E) {
VisitExpr(E);
Record.AddStmt(E->getSubExpr());
Code = serialization::EXPR_CXX_STD_INITIALIZER_LIST;
@@ -1640,8 +1644,8 @@
Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
}
-void
-ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
+void ASTStmtWriter::VisitDependentScopeDeclRefExpr(
+ DependentScopeDeclRefExpr *E) {
VisitExpr(E);
// Don't emit anything here, HasTemplateKWAndArgsInfo must be
@@ -1661,12 +1665,13 @@
Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF;
}
-void
-ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
+void ASTStmtWriter::VisitCXXUnresolvedConstructExpr(
+ CXXUnresolvedConstructExpr *E) {
VisitExpr(E);
Record.push_back(E->arg_size());
- for (CXXUnresolvedConstructExpr::arg_iterator
- ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI)
+ for (CXXUnresolvedConstructExpr::arg_iterator ArgI = E->arg_begin(),
+ ArgE = E->arg_end();
+ ArgI != ArgE; ++ArgI)
Record.AddStmt(*ArgI);
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
Record.AddSourceLocation(E->getLParenLoc());
@@ -1779,7 +1784,7 @@
}
void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
- SubstNonTypeTemplateParmExpr *E) {
+ SubstNonTypeTemplateParmExpr *E) {
VisitExpr(E);
Record.AddDeclRef(E->getParameter());
Record.AddSourceLocation(E->getNameLoc());
@@ -1788,7 +1793,7 @@
}
void ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
- SubstNonTypeTemplateParmPackExpr *E) {
+ SubstNonTypeTemplateParmPackExpr *E) {
VisitExpr(E);
Record.AddDeclRef(E->getParameterPack());
Record.AddTemplateArgument(E->getArgumentPack());
@@ -1801,8 +1806,8 @@
Record.push_back(E->getNumExpansions());
Record.AddDeclRef(E->getParameterPack());
Record.AddSourceLocation(E->getParameterPackLocation());
- for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
- I != End; ++I)
+ for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end(); I != End;
+ ++I)
Record.AddDeclRef(*I);
Code = serialization::EXPR_FUNCTION_PARM_PACK;
}
@@ -2341,9 +2346,7 @@
return SwitchCaseIDs[S];
}
-void ASTWriter::ClearSwitchCaseIDs() {
- SwitchCaseIDs.clear();
-}
+void ASTWriter::ClearSwitchCaseIDs() { SwitchCaseIDs.clear(); }
/// Write the given substatement or subexpression to the
/// bitstream.
@@ -2372,12 +2375,10 @@
llvm::DenseSet<Stmt *> &ParentStmts;
ParentStmtInserterRAII(Stmt *S, llvm::DenseSet<Stmt *> &ParentStmts)
- : S(S), ParentStmts(ParentStmts) {
+ : S(S), ParentStmts(ParentStmts) {
ParentStmts.insert(S);
}
- ~ParentStmtInserterRAII() {
- ParentStmts.erase(S);
- }
+ ~ParentStmtInserterRAII() { ParentStmts.erase(S); }
};
ParentStmtInserterRAII ParentStmtInserter(S, ParentStmts);
@@ -2394,8 +2395,10 @@
void ASTRecordWriter::FlushStmts() {
// We expect to be the only consumer of the two temporary statement maps,
// assert that they are empty.
- assert(Writer->SubStmtEntries.empty() && "unexpected entries in sub-stmt map");
- assert(Writer->ParentStmts.empty() && "unexpected entries in parent stmt map");
+ assert(Writer->SubStmtEntries.empty() &&
+ "unexpected entries in sub-stmt map");
+ assert(Writer->ParentStmts.empty() &&
+ "unexpected entries in parent stmt map");
for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
Writer->WriteSubStmt(StmtsToEmit[I]);
Index: clang/lib/Serialization/ASTWriter.cpp
===================================================================
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -5445,20 +5445,98 @@
AddAPFloat(Value.getComplexFloatImag());
return;
}
- case APValue::LValue:
case APValue::Vector:
+ push_back(Value.getVectorLength());
+ for (unsigned Idx = 0; Idx < Value.getVectorLength(); Idx++)
+ AddAPValue(Value.getVectorElt(Idx));
+ return;
case APValue::Array:
+ push_back(Value.getArrayInitializedElts());
+ push_back(Value.getArraySize());
+ for (unsigned Idx = 0; Idx < Value.getArrayInitializedElts(); Idx++)
+ AddAPValue(Value.getArrayInitializedElt(Idx));
+ return;
case APValue::Struct:
+ push_back(Value.getStructNumBases());
+ push_back(Value.getStructNumFields());
+ for (unsigned Idx = 0; Idx < Value.getStructNumBases(); Idx++)
+ AddAPValue(Value.getStructBase(Idx));
+ for (unsigned Idx = 0; Idx < Value.getStructNumFields(); Idx++)
+ AddAPValue(Value.getStructField(Idx));
+ return;
case APValue::Union:
- case APValue::MemberPointer:
+ AddDeclRef(Value.getUnionField());
+ AddAPValue(Value.getUnionValue());
+ return;
case APValue::AddrLabelDiff:
- // TODO : Handle all these APValue::ValueKind.
+ AddStmt(const_cast<AddrLabelExpr *>(Value.getAddrLabelDiffLHS()));
+ AddStmt(const_cast<AddrLabelExpr *>(Value.getAddrLabelDiffRHS()));
+ return;
+ case APValue::MemberPointer: {
+ push_back(Value.isMemberPointerToDerivedMember());
+ AddDeclRef(Value.getMemberPointerDecl());
+ ArrayRef<const CXXRecordDecl *> RecordPath = Value.getMemberPointerPath();
+ push_back(RecordPath.size());
+ for (auto Elem : RecordPath)
+ AddDeclRef(Elem);
+ return;
+ }
+ case APValue::LValue: {
+ uint64_t tmp = Value.hasLValuePath() | Value.isLValueOnePastTheEnd() << 1 |
+ Value.getLValueBase().is<const Expr *>() << 2 |
+ Value.getLValueBase().is<TypeInfoLValue>() << 3 |
+ Value.isNullPointer() << 4 |
+ static_cast<bool>(Value.getLValueBase()) << 5;
+ push_back(tmp);
+ QualType ElemTy;
+ if (Value.getLValueBase()) {
+ if (!Value.getLValueBase().is<TypeInfoLValue>()) {
+ push_back(Value.getLValueBase().getCallIndex());
+ push_back(Value.getLValueBase().getVersion());
+ if (auto *E = Value.getLValueBase().dyn_cast<const Expr *>()) {
+ AddStmt(const_cast<Expr *>(E));
+ ElemTy = E->getType();
+ } else {
+ AddDeclRef(Value.getLValueBase().get<const ValueDecl *>());
+ ElemTy = Value.getLValueBase().get<const ValueDecl *>()->getType();
+ }
+ } else {
+ AddTypeRef(
+ QualType(Value.getLValueBase().get<TypeInfoLValue>().getType(), 0));
+ AddTypeRef(Value.getLValueBase().getTypeInfoType());
+ ElemTy = Value.getLValueBase().getTypeInfoType();
+ }
+ }
+ push_back(Value.getLValueOffset().getQuantity());
+ push_back(Value.getLValuePath().size());
+ if (Value.hasLValuePath()) {
+ ArrayRef<APValue::LValuePathEntry> Path = Value.getLValuePath();
+ for (auto Elem : Path) {
+ if (ElemTy->getAs<RecordType>()) {
+ push_back(Elem.getAsBaseOrMember().getInt());
+ const Decl *BaseOrMember = Elem.getAsBaseOrMember().getPointer();
+ if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
+ AddDeclRef(RD);
+ ElemTy = Writer->Context->getRecordType(RD);
+ } else {
+ const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
+ AddDeclRef(VD);
+ ElemTy = VD->getType();
+ }
+ } else {
+ push_back(Elem.getAsArrayIndex());
+ ElemTy = Writer->Context->getAsArrayType(ElemTy)->getElementType();
+ }
+ }
+ }
+ }
return;
}
llvm_unreachable("Invalid APValue::ValueKind");
}
-void ASTWriter::AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record) {
+void ASTWriter::AddIdentifierRef(const IdentifierInfo *II,
+ RecordDataImpl &Record) {
Record.push_back(getIdentifierRef(II));
}
Index: clang/lib/Serialization/ASTReaderStmt.cpp
===================================================================
--- clang/lib/Serialization/ASTReaderStmt.cpp
+++ clang/lib/Serialization/ASTReaderStmt.cpp
@@ -539,11 +539,12 @@
E->Int64Result() = Record.readInt();
uint64_t tmp = Record.readInt();
E->ConstantExprBits.IsUnsigned = tmp & 0x1;
- E->ConstantExprBits.BitWidth = tmp >> 1;
+ E->ConstantExprBits.BitWidth = (tmp >> 1) & /*7 bottom bits set*/0x7f;
+ E->ConstantExprBits.APValueKind = tmp >> 8;
break;
}
case ConstantExpr::RSK_APValue:
- E->APValueResult() = Record.readAPValue();
+ E->SetResult(Record.readAPValue(), Record.getContext());
}
E->setSubExpr(Record.readSubExpr());
}
Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -9535,45 +9535,152 @@
HasUnsignedPadding);
}
-APValue ASTReader::ReadAPValue(const RecordData &Record, unsigned &Idx) {
- unsigned Kind = Record[Idx++];
+APValue ASTReader::ReadAPValue(ModuleFile &F, const RecordData &Record,
+ unsigned &RecordIdx) {
+ auto Kind = static_cast<APValue::ValueKind>(Record[RecordIdx++]);
switch (Kind) {
case APValue::None:
return APValue();
case APValue::Indeterminate:
return APValue::IndeterminateValue();
case APValue::Int:
- return APValue(ReadAPSInt(Record, Idx));
+ return APValue(ReadAPSInt(Record, RecordIdx));
case APValue::Float: {
const llvm::fltSemantics &FloatSema = llvm::APFloatBase::EnumToSemantics(
- static_cast<llvm::APFloatBase::Semantics>(Record[Idx++]));
- return APValue(ReadAPFloat(Record, FloatSema, Idx));
+ static_cast<llvm::APFloatBase::Semantics>(Record[RecordIdx++]));
+ return APValue(ReadAPFloat(Record, FloatSema, RecordIdx));
}
case APValue::FixedPoint: {
- FixedPointSemantics FPSema = ReadFixedPointSemantics(Record, Idx);
- return APValue(APFixedPoint(ReadAPInt(Record, Idx), FPSema));
+ FixedPointSemantics FPSema = ReadFixedPointSemantics(Record, RecordIdx);
+ return APValue(APFixedPoint(ReadAPInt(Record, RecordIdx), FPSema));
}
case APValue::ComplexInt: {
- llvm::APSInt First = ReadAPSInt(Record, Idx);
- return APValue(std::move(First), ReadAPSInt(Record, Idx));
+ llvm::APSInt First = ReadAPSInt(Record, RecordIdx);
+ return APValue(std::move(First), ReadAPSInt(Record, RecordIdx));
}
case APValue::ComplexFloat: {
const llvm::fltSemantics &FloatSema1 = llvm::APFloatBase::EnumToSemantics(
- static_cast<llvm::APFloatBase::Semantics>(Record[Idx++]));
- llvm::APFloat First = ReadAPFloat(Record, FloatSema1, Idx);
+ static_cast<llvm::APFloatBase::Semantics>(Record[RecordIdx++]));
+ llvm::APFloat First = ReadAPFloat(Record, FloatSema1, RecordIdx);
const llvm::fltSemantics &FloatSema2 = llvm::APFloatBase::EnumToSemantics(
- static_cast<llvm::APFloatBase::Semantics>(Record[Idx++]));
- return APValue(std::move(First), ReadAPFloat(Record, FloatSema2, Idx));
- }
- case APValue::LValue:
- case APValue::Vector:
- case APValue::Array:
- case APValue::Struct:
- case APValue::Union:
- case APValue::MemberPointer:
- case APValue::AddrLabelDiff:
- // TODO : Handle all these APValue::ValueKind.
- return APValue();
+ static_cast<llvm::APFloatBase::Semantics>(Record[RecordIdx++]));
+ return APValue(std::move(First),
+ ReadAPFloat(Record, FloatSema2, RecordIdx));
+ }
+ case APValue::Vector: {
+ APValue Result;
+ Result.MakeVector();
+ unsigned Length = Record[RecordIdx++];
+ Result.ReserveVector(Length);
+ for (unsigned LoopIdx = 0; LoopIdx < Length; LoopIdx++)
+ Result.getVectorElt(LoopIdx) = ReadAPValue(F, Record, RecordIdx);
+ return Result;
+ }
+ case APValue::Array: {
+ APValue Result;
+ unsigned InitLength = Record[RecordIdx++];
+ unsigned TotalLength = Record[RecordIdx++];
+ Result.MakeArray(InitLength, TotalLength);
+ for (unsigned LoopIdx = 0; LoopIdx < InitLength; LoopIdx++)
+ Result.getArrayInitializedElt(LoopIdx) =
+ ReadAPValue(F, Record, RecordIdx);
+ return Result;
+ }
+ case APValue::Struct: {
+ APValue Result;
+ unsigned BasesLength = Record[RecordIdx++];
+ unsigned FieldsLength = Record[RecordIdx++];
+ Result.MakeStruct(BasesLength, FieldsLength);
+ for (unsigned LoopIdx = 0; LoopIdx < BasesLength; LoopIdx++)
+ Result.getStructBase(LoopIdx) = ReadAPValue(F, Record, RecordIdx);
+ for (unsigned LoopIdx = 0; LoopIdx < FieldsLength; LoopIdx++)
+ Result.getStructField(LoopIdx) = ReadAPValue(F, Record, RecordIdx);
+ return Result;
+ }
+ case APValue::Union: {
+ FieldDecl *FDecl =
+ cast<FieldDecl>(GetDecl(ReadDeclID(F, Record, RecordIdx)));
+ APValue Value = ReadAPValue(F, Record, RecordIdx);
+ return APValue(FDecl, Value);
+ }
+ case APValue::AddrLabelDiff: {
+ AddrLabelExpr *LHS = cast<AddrLabelExpr>(ReadExpr(F));
+ AddrLabelExpr *RHS = cast<AddrLabelExpr>(ReadExpr(F));
+ return APValue(LHS, RHS);
+ }
+ case APValue::MemberPointer: {
+ APValue Result;
+ bool IsDerived = Record[RecordIdx++];
+ ValueDecl *Member =
+ cast<ValueDecl>(GetDecl(ReadDeclID(F, Record, RecordIdx)));
+ unsigned PathSize = Record[RecordIdx++];
+ Result.MakeEmptyMemberPointer(Member, IsDerived, PathSize);
+ CXXRecordDecl **PathArray = Result.getMemberPointerPathPtr();
+ for (unsigned LoopIdx = 0; LoopIdx < PathSize; LoopIdx++)
+ PathArray[LoopIdx] =
+ cast<CXXRecordDecl>(GetDecl(ReadDeclID(F, Record, RecordIdx)));
+ return Result;
+ }
+ case APValue::LValue: {
+ uint64_t tmp = Record[RecordIdx++];
+ bool hasLValuePath = tmp & 0x1;
+ bool isLValueOnePastTheEnd = tmp & 0x2;
+ bool isExpr = tmp & 0x4;
+ bool isTypeInfo = tmp & 0x8;
+ bool isNullPtr = tmp & 0x10;
+ bool hasBase = tmp & 0x20;
+ APValue::LValueBase Base;
+ QualType ElemTy;
+ assert(!isExpr || !isTypeInfo && "LValueBase cannot be both");
+ if (hasBase) {
+ if (!isTypeInfo) {
+ unsigned CallIndex = Record[RecordIdx++];
+ unsigned Version = Record[RecordIdx++];
+ if (isExpr) {
+ Base = APValue::LValueBase(ReadExpr(F), CallIndex, Version);
+ ElemTy = Base.get<const Expr *>()->getType();
+ } else {
+ Base = APValue::LValueBase(
+ cast<ValueDecl>(GetDecl(ReadDeclID(F, Record, RecordIdx))),
+ CallIndex, Version);
+ ElemTy = Base.get<const ValueDecl *>()->getType();
+ }
+ } else {
+ QualType TypeInfo = readType(F, Record, RecordIdx);
+ QualType Type = readType(F, Record, RecordIdx);
+ Base = APValue::LValueBase::getTypeInfo(
+ TypeInfoLValue(TypeInfo.getTypePtr()), Type);
+ Base.getTypeInfoType();
+ }
+ }
+ CharUnits Offset = CharUnits::fromQuantity(Record[RecordIdx++]);
+ unsigned PathLength = Record[RecordIdx++];
+ APValue Result;
+ Result.MakeLValue();
+ if (hasLValuePath) {
+ Result.setLValueEmptyPath(Base, Offset, PathLength, isLValueOnePastTheEnd,
+ isNullPtr);
+ APValue::LValuePathEntry *Path = Result.getLValuePathPtr();
+ for (unsigned LoopIdx = 0; LoopIdx < PathLength; LoopIdx++) {
+ if (ElemTy->getAs<RecordType>()) {
+ unsigned Int = Record[RecordIdx++];
+ Decl *D = GetDecl(ReadDeclID(F, Record, RecordIdx));
+ if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
+ ElemTy = ContextObj->getRecordType(RD);
+ else
+ ElemTy = cast<ValueDecl>(D)->getType();
+ Path[LoopIdx] =
+ APValue::LValuePathEntry(APValue::BaseOrMemberType(D, Int));
+ } else {
+ ElemTy = ContextObj->getAsArrayType(ElemTy)->getElementType();
+ Path[LoopIdx] =
+ APValue::LValuePathEntry::ArrayIndex(Record[RecordIdx++]);
+ }
+ }
+ } else
+ Result.setLValue(Base, Offset, APValue::NoLValuePath{}, isNullPtr);
+ return Result;
+ }
}
llvm_unreachable("Invalid APValue::ValueKind");
}
@@ -11321,18 +11428,6 @@
break;
}
- if (FirstInit && SecondInit &&
- ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) {
- ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(),
- VarDifferentInitializer)
- << FirstName << FirstInit->getSourceRange();
- ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(),
- VarDifferentInitializer)
- << SecondName << SecondInit->getSourceRange();
- Diagnosed = true;
- break;
- }
-
const bool FirstIsConstexpr = FirstVD->isConstexpr();
const bool SecondIsConstexpr = SecondVD->isConstexpr();
if (FirstIsConstexpr != SecondIsConstexpr) {
@@ -11345,6 +11440,19 @@
Diagnosed = true;
break;
}
+
+ if (FirstInit && SecondInit &&
+ ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) {
+ ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(),
+ VarDifferentInitializer)
+ << FirstName << FirstInit->getSourceRange();
+ ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(),
+ VarDifferentInitializer)
+ << SecondName << SecondInit->getSourceRange();
+ Diagnosed = true;
+ break;
+ }
+
break;
}
case Friend: {
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11312,6 +11312,12 @@
FSI->markSafeWeakUse(Init);
}
+ if (VDecl->isConstexpr()) {
+ Init = ConstantExpr::Create(
+ Context, Init,
+ ConstantExpr::getStorageKind(VDecl->getType()->getAs<Type>(), Context));
+ }
+
// The initialization is usually a full-expression.
//
// FIXME: If this is a braced initialization of an aggregate, it is not
Index: clang/lib/AST/TextNodeDumper.cpp
===================================================================
--- clang/lib/AST/TextNodeDumper.cpp
+++ clang/lib/AST/TextNodeDumper.cpp
@@ -688,8 +688,11 @@
if (Node->getResultAPValueKind() != APValue::None) {
ColorScope Color(OS, ShowColors, ValueColor);
OS << " ";
- Node->getAPValueResult().printPretty(OS, *Context, Node->getType());
- }
+ if (Context)
+ Node->getAPValueResult().printPretty(OS, *Context, Node->getType());
+ else
+ Node->getAPValueResult().dump(OS);
+ } else {}
}
void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
Index: clang/lib/AST/Expr.cpp
===================================================================
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -260,8 +260,10 @@
void ConstantExpr::DefaultInit(ResultStorageKind StorageKind) {
ConstantExprBits.ResultKind = StorageKind;
ConstantExprBits.APValueKind = APValue::None;
+ ConstantExprBits.BitWidth = 0;
+ ConstantExprBits.IsUnsigned = false;
ConstantExprBits.HasCleanup = false;
- if (StorageKind == ConstantExpr::RSK_APValue)
+ if (StorageKind == RSK_APValue)
::new (getTrailingObjects<APValue>()) APValue();
}
@@ -278,8 +280,7 @@
StorageKind == ConstantExpr::RSK_APValue,
StorageKind == ConstantExpr::RSK_Int64);
void *Mem = Context.Allocate(Size, alignof(ConstantExpr));
- ConstantExpr *Self = new (Mem) ConstantExpr(E, StorageKind);
- return Self;
+ return new (Mem) ConstantExpr(E, StorageKind);
}
ConstantExpr *ConstantExpr::Create(const ASTContext &Context, Expr *E,
@@ -308,9 +309,11 @@
}
void ConstantExpr::MoveIntoResult(APValue &Value, const ASTContext &Context) {
- assert(getStorageKind(Value) == ConstantExprBits.ResultKind &&
+ assert(getStorageKind(Value) <= ConstantExprBits.ResultKind &&
"Invalid storage for this value kind");
ConstantExprBits.APValueKind = Value.getKind();
+ if (!Value.hasValue())
+ return;
switch (ConstantExprBits.ResultKind) {
case RSK_None:
return;
@@ -343,6 +346,8 @@
}
APValue ConstantExpr::getAPValueResult() const {
+ if (ConstantExprBits.APValueKind == APValue::None)
+ return APValue();
switch (ConstantExprBits.ResultKind) {
case ConstantExpr::RSK_APValue:
return APValueResult();
Index: clang/lib/AST/Decl.cpp
===================================================================
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -2347,6 +2347,11 @@
else if (Eval->Evaluated.needsCleanup())
getASTContext().addDestruction(&Eval->Evaluated);
+ if (auto *ConstantInit = dyn_cast<ConstantExpr>(Eval->Value))
+ if (ConstantExpr::getStorageKind(Eval->Evaluated) <=
+ ConstantInit->getResultStorageKind())
+ ConstantInit->SetResult(Eval->Evaluated, getASTContext());
+
Eval->IsEvaluating = false;
Eval->WasEvaluated = true;
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -6502,21 +6502,15 @@
}
ExpectedStmt ASTNodeImporter::VisitConstantExpr(ConstantExpr *E) {
- auto Imp = importSeq(E->getSubExpr());
+ auto Imp = importSeq(E->getSubExpr(), E->getAPValueResult());
if (!Imp)
return Imp.takeError();
Expr *ToSubExpr;
- std::tie(ToSubExpr) = *Imp;
+ APValue ToResult;
+ std::tie(ToSubExpr, ToResult) = *Imp;
- // TODO : Handle APValue::ValueKind that require importing.
- APValue::ValueKind Kind = E->getResultAPValueKind();
- if (Kind == APValue::Int || Kind == APValue::Float ||
- Kind == APValue::FixedPoint || Kind == APValue::ComplexFloat ||
- Kind == APValue::ComplexInt)
- return ConstantExpr::Create(Importer.getToContext(), ToSubExpr,
- E->getAPValueResult());
- return ConstantExpr::Create(Importer.getToContext(), ToSubExpr);
+ return ConstantExpr::Create(Importer.getToContext(), ToSubExpr, ToResult);
}
ExpectedStmt ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
@@ -8748,6 +8742,7 @@
return ToContext.Selectors.getSelector(FromSel.getNumArgs(), Idents.data());
}
+<<<<<<< HEAD
Expected<DeclarationName> ASTImporter::HandleNameConflict(DeclarationName Name,
DeclContext *DC,
unsigned IDNS,
@@ -8759,6 +8754,203 @@
else
// Allow to create the new Decl with the same name.
return Name;
+=======
+llvm::Expected<APValue> ASTImporter::Import(const APValue &FromValue) {
+ APValue Result;
+ llvm::Error Error = llvm::Error::success();
+ auto ImportLoop = [&](const APValue *From, APValue *To, unsigned Size) {
+ for (unsigned Idx = 0; Idx < Size; Idx++) {
+ llvm::Expected<APValue> Tmp = Import(From[Idx]);
+ if (!Tmp) {
+ Error = Tmp.takeError();
+ return;
+ }
+ To[Idx] = std::move(Tmp.get());
+ }
+ };
+ switch (FromValue.getKind()) {
+ case APValue::None:
+ case APValue::Indeterminate:
+ case APValue::Int:
+ case APValue::Float:
+ case APValue::FixedPoint:
+ case APValue::ComplexInt:
+ case APValue::ComplexFloat:
+ Result = FromValue;
+ break;
+ case APValue::Vector:
+ Result.MakeVector();
+ Result.ReserveVector(FromValue.getVectorLength());
+ ImportLoop(
+ ((const APValue::Vec *)(const char *)FromValue.Data.buffer)->Elts,
+ ((const APValue::Vec *)(const char *)Result.Data.buffer)->Elts,
+ FromValue.getVectorLength());
+ break;
+ case APValue::Array:
+ Result.MakeArray(FromValue.getArrayInitializedElts(),
+ FromValue.getArraySize());
+ ImportLoop(
+ ((const APValue::Arr *)(const char *)FromValue.Data.buffer)->Elts,
+ ((const APValue::Arr *)(const char *)Result.Data.buffer)->Elts,
+ FromValue.getArrayInitializedElts());
+ break;
+ case APValue::Struct:
+ Result.MakeStruct(FromValue.getStructNumBases(),
+ FromValue.getStructNumFields());
+ ImportLoop(
+ ((const APValue::StructData *)(const char *)FromValue.Data.buffer)
+ ->Elts,
+ ((const APValue::StructData *)(const char *)Result.Data.buffer)->Elts,
+ FromValue.getStructNumBases() + FromValue.getStructNumFields());
+ break;
+ case APValue::Union: {
+ Result.MakeUnion();
+ auto ImpFDecl = Import(FromValue.getUnionField());
+ if (!ImpFDecl) {
+ Error = ImpFDecl.takeError();
+ break;
+ }
+ auto ImpValue = Import(FromValue.getUnionValue());
+ if (!ImpValue) {
+ Error = ImpValue.takeError();
+ break;
+ }
+ Result.setUnion(cast<FieldDecl>(ImpFDecl.get()), ImpValue.get());
+ break;
+ }
+ case APValue::AddrLabelDiff: {
+ Result.MakeAddrLabelDiff();
+ auto ImpLHS =
+ Import(const_cast<AddrLabelExpr *>(FromValue.getAddrLabelDiffLHS()));
+ if (!ImpLHS) {
+ Error = ImpLHS.takeError();
+ break;
+ }
+ auto ImpRHS =
+ Import(const_cast<AddrLabelExpr *>(FromValue.getAddrLabelDiffRHS()));
+ if (!ImpRHS) {
+ Error = ImpRHS.takeError();
+ break;
+ }
+ Result.setAddrLabelDiff(cast<AddrLabelExpr>(ImpLHS.get()),
+ cast<AddrLabelExpr>(ImpRHS.get()));
+ break;
+ }
+ case APValue::MemberPointer: {
+ auto ImpMemPtrDecl = Import(FromValue.getMemberPointerDecl());
+ if (!ImpMemPtrDecl) {
+ Error = ImpMemPtrDecl.takeError();
+ break;
+ }
+ Result.MakeEmptyMemberPointer(cast<const ValueDecl>(ImpMemPtrDecl.get()),
+ FromValue.isMemberPointerToDerivedMember(),
+ FromValue.getMemberPointerPath().size());
+ llvm::ArrayRef<const CXXRecordDecl *> FromPath =
+ Result.getMemberPointerPath();
+ CXXRecordDecl **ToPath = Result.getMemberPointerPathPtr();
+ for (unsigned Idx = 0; Idx < FromValue.getMemberPointerPath().size();
+ Idx++) {
+ auto ImpDecl = Import(FromPath[Idx]);
+ if (!ImpDecl) {
+ Error = ImpDecl.takeError();
+ break;
+ }
+ ToPath[Idx] = cast<CXXRecordDecl>(const_cast<Decl *>(ImpDecl.get()));
+ }
+ break;
+ }
+ case APValue::LValue:
+ APValue::LValueBase Base;
+ QualType FromElemTy;
+ if (FromValue.getLValueBase()) {
+ if (!FromValue.getLValueBase().is<TypeInfoLValue>()) {
+ if (auto *E = FromValue.getLValueBase().dyn_cast<const Expr *>()) {
+ FromElemTy = E->getType();
+ auto ImpExpr = Import(const_cast<Expr *>(E));
+ if (!ImpExpr) {
+ Error = ImpExpr.takeError();
+ break;
+ }
+ Base = APValue::LValueBase(ImpExpr.get(),
+ FromValue.getLValueBase().getCallIndex(),
+ FromValue.getLValueBase().getVersion());
+ } else {
+ FromElemTy =
+ FromValue.getLValueBase().get<const ValueDecl *>()->getType();
+ auto ImpDecl =
+ Import(FromValue.getLValueBase().get<const ValueDecl *>());
+ if (!ImpDecl) {
+ Error = ImpDecl.takeError();
+ break;
+ }
+ Base = APValue::LValueBase(cast<ValueDecl>(ImpDecl.get()),
+ FromValue.getLValueBase().getCallIndex(),
+ FromValue.getLValueBase().getVersion());
+ }
+ } else {
+ FromElemTy = FromValue.getLValueBase().getTypeInfoType();
+ auto ImpTypeInfo = Import(QualType(
+ FromValue.getLValueBase().get<TypeInfoLValue>().getType(), 0));
+ if (!ImpTypeInfo) {
+ Error = ImpTypeInfo.takeError();
+ break;
+ }
+ auto ImpType = Import(FromValue.getLValueBase().getTypeInfoType());
+ if (!ImpType) {
+ Error = ImpType.takeError();
+ break;
+ }
+ Base = APValue::LValueBase::getTypeInfo(
+ TypeInfoLValue(ImpTypeInfo.get().getTypePtr()), ImpType.get());
+ }
+ }
+ CharUnits Offset = FromValue.getLValueOffset();
+ unsigned PathLength = FromValue.getLValuePath().size();
+ Result.MakeLValue();
+ if (FromValue.hasLValuePath()) {
+ Result.setLValueEmptyPath(Base, Offset, PathLength,
+ FromValue.isLValueOnePastTheEnd(),
+ FromValue.isNullPointer());
+ llvm::ArrayRef<APValue::LValuePathEntry> FromPath =
+ FromValue.getLValuePath();
+ APValue::LValuePathEntry *ToPath = Result.getLValuePathPtr();
+ for (unsigned LoopIdx = 0; LoopIdx < PathLength; LoopIdx++) {
+ if (FromElemTy->getAs<RecordType>()) {
+ const Decl *FromDecl =
+ FromPath[LoopIdx].getAsBaseOrMember().getPointer();
+ auto ImpDecl = Import(FromDecl);
+ if (!ImpDecl) {
+ Error = ImpDecl.takeError();
+ break;
+ }
+ if (auto *RD = dyn_cast<CXXRecordDecl>(FromDecl))
+ FromElemTy = FromContext.getRecordType(RD);
+ else
+ FromElemTy = cast<ValueDecl>(FromDecl)->getType();
+ ToPath[LoopIdx] = APValue::LValuePathEntry(APValue::BaseOrMemberType(
+ ImpDecl.get(), FromPath[LoopIdx].getAsBaseOrMember().getInt()));
+ } else {
+ FromElemTy = FromContext.getAsArrayType(FromElemTy)->getElementType();
+ ToPath[LoopIdx] = APValue::LValuePathEntry::ArrayIndex(
+ FromPath[LoopIdx].getAsArrayIndex());
+ }
+ }
+ } else
+ Result.setLValue(Base, Offset, APValue::NoLValuePath{},
+ FromValue.isNullPointer());
+ }
+ if (Error)
+ return std::move(Error);
+ return Result;
+}
+
+DeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
+ DeclContext *DC,
+ unsigned IDNS,
+ NamedDecl **Decls,
+ unsigned NumDecls) {
+ return Name;
+>>>>>>> tmp
}
DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -872,9 +872,6 @@
for (const auto &Value : ModuleInitializers)
Value.second->~PerModuleInitializers();
-
- for (APValue *Value : APValueCleanups)
- Value->~APValue();
}
class ASTContext::ParentMap {
Index: clang/lib/AST/APValue.cpp
===================================================================
--- clang/lib/AST/APValue.cpp
+++ clang/lib/AST/APValue.cpp
@@ -172,8 +172,8 @@
struct APValue::MemberPointerData : MemberPointerBase {
static const unsigned InlinePathSpace =
- (DataSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*);
- typedef const CXXRecordDecl *PathElem;
+ (DataSize - sizeof(MemberPointerBase)) / sizeof(CXXRecordDecl *);
+ typedef CXXRecordDecl *PathElem;
union {
PathElem Path[InlinePathSpace];
PathElem *PathPtr;
@@ -745,6 +745,10 @@
return ((const LV*)(const char*)Data.buffer)->IsNullPtr;
}
+APValue::LValuePathEntry *APValue::getLValuePathPtr() {
+ return ((LV *)(char *)Data.buffer)->getPath();
+}
+
void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
bool IsNullPtr) {
assert(isLValue() && "Invalid accessor");
@@ -756,17 +760,24 @@
LVal.IsNullPtr = IsNullPtr;
}
-void APValue::setLValue(LValueBase B, const CharUnits &O,
- ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
- bool IsNullPtr) {
+void APValue::setLValueEmptyPath(LValueBase B, const CharUnits &O,
+ unsigned Size, bool IsOnePastTheEnd,
+ bool IsNullPtr) {
assert(isLValue() && "Invalid accessor");
- LV &LVal = *((LV*)(char*)Data.buffer);
+ LV &LVal = *((LV *)(char *)Data.buffer);
LVal.Base = B;
LVal.IsOnePastTheEnd = IsOnePastTheEnd;
LVal.Offset = O;
- LVal.resizePath(Path.size());
- memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
LVal.IsNullPtr = IsNullPtr;
+ LVal.resizePath(Size);
+}
+
+void APValue::setLValue(LValueBase B, const CharUnits &O,
+ ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
+ bool IsNullPtr) {
+ setLValueEmptyPath(B, O, Path.size(), IsOnePastTheEnd, IsNullPtr);
+ memcpy(((LV *)(char *)Data.buffer)->getPath(), Path.data(),
+ Path.size() * sizeof(LValuePathEntry));
}
const ValueDecl *APValue::getMemberPointerDecl() const {
@@ -803,13 +814,23 @@
Kind = Array;
}
-void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
- ArrayRef<const CXXRecordDecl*> Path) {
+void APValue::MakeEmptyMemberPointer(const ValueDecl *Member,
+ bool IsDerivedMember, unsigned Size) {
assert(isAbsent() && "Bad state change");
MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
Kind = MemberPointer;
MPD->MemberAndIsDerivedMember.setPointer(Member);
MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
- MPD->resizePath(Path.size());
- memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*));
+ MPD->resizePath(Size);
+}
+
+void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
+ ArrayRef<const CXXRecordDecl *> Path) {
+ MakeEmptyMemberPointer(Member, IsDerivedMember, Path.size());
+ memcpy(((MemberPointerData *)(char *)Data.buffer)->getPath(), Path.data(),
+ Path.size() * sizeof(const CXXRecordDecl *));
+}
+
+CXXRecordDecl **APValue::getMemberPointerPathPtr() {
+ return ((MemberPointerData *)(char *)Data.buffer)->getPath();
}
Index: clang/include/clang/Serialization/ASTReader.h
===================================================================
--- clang/include/clang/Serialization/ASTReader.h
+++ clang/include/clang/Serialization/ASTReader.h
@@ -2222,7 +2222,7 @@
const llvm::fltSemantics &Sem, unsigned &Idx);
/// Read an APValue
- APValue ReadAPValue(const RecordData &Record, unsigned &Idx);
+ APValue ReadAPValue(ModuleFile &F, const RecordData &Record, unsigned &Idx);
// Read a string
static std::string ReadString(const RecordData &Record, unsigned &Idx);
@@ -2617,7 +2617,7 @@
return Reader->ReadSourceRange(*F, Record, Idx);
}
- APValue readAPValue() { return Reader->ReadAPValue(Record, Idx); }
+ APValue readAPValue() { return Reader->ReadAPValue(*F, Record, Idx); }
/// Read an integral value, advancing Idx.
llvm::APInt readAPInt() {
Index: clang/include/clang/AST/TextNodeDumper.h
===================================================================
--- clang/include/clang/AST/TextNodeDumper.h
+++ clang/include/clang/AST/TextNodeDumper.h
@@ -146,7 +146,7 @@
const comments::CommandTraits *Traits;
- const ASTContext *Context;
+ const ASTContext *Context = nullptr;
const char *getCommandName(unsigned CommandID);
Index: clang/include/clang/AST/Expr.h
===================================================================
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -954,6 +954,7 @@
public:
/// Describes the kind of result that can be trail-allocated.
+ /// Enumerator need to stay ordered by size of there storage.
enum ResultStorageKind { RSK_None, RSK_Int64, RSK_APValue };
private:
Index: clang/include/clang/AST/ASTImporter.h
===================================================================
--- clang/include/clang/AST/ASTImporter.h
+++ clang/include/clang/AST/ASTImporter.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_ASTIMPORTER_H
#include "clang/AST/DeclBase.h"
+#include "clang/AST/APValue.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateName.h"
@@ -494,6 +495,13 @@
/// "to" context, or the import error.
llvm::Expected<CXXBaseSpecifier *> Import(const CXXBaseSpecifier *FromSpec);
+ /// Import the given APValue from the "from" context into
+ /// the "to" context.
+ ///
+ /// \return the equivalent APValue in the "to" context or the import
+ /// error.
+ llvm::Expected<APValue> Import(const APValue &FromValue);
+
/// Import the definition of the given declaration, including all of
/// the declarations it contains.
LLVM_NODISCARD llvm::Error ImportDefinition(Decl *From);
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -271,9 +271,6 @@
llvm::DenseMap<const MaterializeTemporaryExpr *, APValue *>
MaterializedTemporaryValues;
- /// Used to cleanups APValues stored in the AST.
- mutable llvm::SmallVector<APValue *, 0> APValueCleanups;
-
/// A cache mapping a string value to a StringLiteral object with the same
/// value.
///
Index: clang/include/clang/AST/APValue.h
===================================================================
--- clang/include/clang/AST/APValue.h
+++ clang/include/clang/AST/APValue.h
@@ -185,6 +185,7 @@
friend class ASTReader;
friend class ASTWriter;
+ friend class ASTImporter;
private:
ValueKind Kind;
@@ -508,10 +509,13 @@
assert(isFixedPoint() && "Invalid accessor");
*(APFixedPoint *)(char *)Data.buffer = std::move(FX);
}
- void setVector(const APValue *E, unsigned N) {
+ void ReserveVector(unsigned N) {
assert(isVector() && "Invalid accessor");
((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
((Vec*)(char*)Data.buffer)->NumElts = N;
+ }
+ void setVector(const APValue *E, unsigned N) {
+ ReserveVector(N);
for (unsigned i = 0; i != N; ++i)
((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
}
@@ -529,6 +533,13 @@
((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
}
+
+private:
+ void setLValueEmptyPath(LValueBase B, const CharUnits &O, unsigned Size,
+ bool OnePastTheEnd, bool IsNullPtr);
+ LValuePathEntry *getLValuePathPtr();
+
+public:
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
bool IsNullPtr);
void setLValue(LValueBase B, const CharUnits &O,
@@ -595,13 +606,16 @@
new ((void*)(char*)Data.buffer) UnionData();
Kind = Union;
}
+ void MakeEmptyMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
+ unsigned Size);
void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
- ArrayRef<const CXXRecordDecl*> Path);
+ ArrayRef<const CXXRecordDecl *> Path);
void MakeAddrLabelDiff() {
assert(isAbsent() && "Bad state change");
- new ((void*)(char*)Data.buffer) AddrLabelDiffData();
+ new ((void *)(char *)Data.buffer) AddrLabelDiffData();
Kind = AddrLabelDiff;
}
+ CXXRecordDecl **getMemberPointerPathPtr();
};
} // end namespace clang.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits