|
11 | 11 | //===----------------------------------------------------------------------===//
|
12 | 12 |
|
13 | 13 | #include "clang/AST/APValue.h"
|
| 14 | +#include "Linkage.h" |
14 | 15 | #include "clang/AST/ASTContext.h"
|
15 | 16 | #include "clang/AST/CharUnits.h"
|
16 | 17 | #include "clang/AST/DeclCXX.h"
|
17 | 18 | #include "clang/AST/Expr.h"
|
| 19 | +#include "clang/AST/ExprCXX.h" |
18 | 20 | #include "clang/AST/Type.h"
|
19 | 21 | #include "llvm/Support/ErrorHandling.h"
|
20 | 22 | #include "llvm/Support/raw_ostream.h"
|
@@ -977,3 +979,99 @@ void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
|
977 | 979 | for (unsigned I = 0; I != Path.size(); ++I)
|
978 | 980 | InternalPath[I] = Path[I]->getCanonicalDecl();
|
979 | 981 | }
|
| 982 | + |
| 983 | +LinkageInfo LinkageComputer::getLVForValue(const APValue &V, |
| 984 | + LVComputationKind computation) { |
| 985 | + LinkageInfo LV = LinkageInfo::external(); |
| 986 | + |
| 987 | + auto MergeLV = [&](LinkageInfo MergeLV) { |
| 988 | + LV.merge(MergeLV); |
| 989 | + return LV.getLinkage() == InternalLinkage; |
| 990 | + }; |
| 991 | + auto Merge = [&](const APValue &V) { |
| 992 | + return MergeLV(getLVForValue(V, computation)); |
| 993 | + }; |
| 994 | + |
| 995 | + switch (V.getKind()) { |
| 996 | + case APValue::None: |
| 997 | + case APValue::Indeterminate: |
| 998 | + case APValue::Int: |
| 999 | + case APValue::Float: |
| 1000 | + case APValue::FixedPoint: |
| 1001 | + case APValue::ComplexInt: |
| 1002 | + case APValue::ComplexFloat: |
| 1003 | + case APValue::Vector: |
| 1004 | + break; |
| 1005 | + |
| 1006 | + case APValue::AddrLabelDiff: |
| 1007 | + // Even for an inline function, it's not reasonable to treat a difference |
| 1008 | + // between the addresses of labels as an external value. |
| 1009 | + return LinkageInfo::internal(); |
| 1010 | + |
| 1011 | + case APValue::Struct: { |
| 1012 | + for (unsigned I = 0, N = V.getStructNumBases(); I != N; ++I) |
| 1013 | + if (Merge(V.getStructBase(I))) |
| 1014 | + break; |
| 1015 | + for (unsigned I = 0, N = V.getStructNumFields(); I != N; ++I) |
| 1016 | + if (Merge(V.getStructField(I))) |
| 1017 | + break; |
| 1018 | + break; |
| 1019 | + } |
| 1020 | + |
| 1021 | + case APValue::Union: |
| 1022 | + if (const auto *FD = V.getUnionField()) |
| 1023 | + Merge(V.getUnionValue()); |
| 1024 | + break; |
| 1025 | + |
| 1026 | + case APValue::Array: { |
| 1027 | + for (unsigned I = 0, N = V.getArrayInitializedElts(); I != N; ++I) |
| 1028 | + if (Merge(V.getArrayInitializedElt(I))) |
| 1029 | + break; |
| 1030 | + if (V.hasArrayFiller()) |
| 1031 | + Merge(V.getArrayFiller()); |
| 1032 | + break; |
| 1033 | + } |
| 1034 | + |
| 1035 | + case APValue::LValue: { |
| 1036 | + if (!V.getLValueBase()) { |
| 1037 | + // Null or absolute address: this is external. |
| 1038 | + } else if (const auto *VD = |
| 1039 | + V.getLValueBase().dyn_cast<const ValueDecl *>()) { |
| 1040 | + if (VD && MergeLV(getLVForDecl(VD, computation))) |
| 1041 | + break; |
| 1042 | + } else if (const auto TI = V.getLValueBase().dyn_cast<TypeInfoLValue>()) { |
| 1043 | + if (MergeLV(getLVForType(*TI.getType(), computation))) |
| 1044 | + break; |
| 1045 | + } else if (const Expr *E = V.getLValueBase().dyn_cast<const Expr *>()) { |
| 1046 | + // Almost all expression bases are internal. The exception is |
| 1047 | + // lifetime-extended temporaries. |
| 1048 | + // FIXME: These should be modeled as having the |
| 1049 | + // LifetimeExtendedTemporaryDecl itself as the base. |
| 1050 | + // FIXME: If we permit Objective-C object literals in template arguments, |
| 1051 | + // they should not imply internal linkage. |
| 1052 | + auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E); |
| 1053 | + if (!MTE || MTE->getStorageDuration() == SD_FullExpression) |
| 1054 | + return LinkageInfo::internal(); |
| 1055 | + if (MergeLV(getLVForDecl(MTE->getExtendingDecl(), computation))) |
| 1056 | + break; |
| 1057 | + } else { |
| 1058 | + assert(V.getLValueBase().is<DynamicAllocLValue>() && |
| 1059 | + "unexpected LValueBase kind"); |
| 1060 | + return LinkageInfo::internal(); |
| 1061 | + } |
| 1062 | + // The lvalue path doesn't matter: pointers to all subobjects always have |
| 1063 | + // the same visibility as pointers to the complete object. |
| 1064 | + break; |
| 1065 | + } |
| 1066 | + |
| 1067 | + case APValue::MemberPointer: |
| 1068 | + if (const NamedDecl *D = V.getMemberPointerDecl()) |
| 1069 | + MergeLV(getLVForDecl(D, computation)); |
| 1070 | + // Note that we could have a base-to-derived conversion here to a member of |
| 1071 | + // a derived class with less linkage/visibility. That's covered by the |
| 1072 | + // linkage and visibility of the value's type. |
| 1073 | + break; |
| 1074 | + } |
| 1075 | + |
| 1076 | + return LV; |
| 1077 | +} |
0 commit comments