diff options
author | dim <dim@FreeBSD.org> | 2016-12-26 20:36:37 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2016-12-26 20:36:37 +0000 |
commit | 06210ae42d418d50d8d9365d5c9419308ae9e7ee (patch) | |
tree | ab60b4cdd6e430dda1f292a46a77ddb744723f31 /contrib/llvm/tools/clang/lib/AST | |
parent | 2dd166267f53df1c3748b4325d294b9b839de74b (diff) | |
download | FreeBSD-src-06210ae42d418d50d8d9365d5c9419308ae9e7ee.zip FreeBSD-src-06210ae42d418d50d8d9365d5c9419308ae9e7ee.tar.gz |
MFC r309124:
Upgrade our copies of clang, llvm, lldb, compiler-rt and libc++ to 3.9.0
release, and add lld 3.9.0. Also completely revamp the build system for
clang, llvm, lldb and their related tools.
Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11
support to build; see UPDATING for more information.
Release notes for llvm, clang and lld are available here:
<http://llvm.org/releases/3.9.0/docs/ReleaseNotes.html>
<http://llvm.org/releases/3.9.0/tools/clang/docs/ReleaseNotes.html>
<http://llvm.org/releases/3.9.0/tools/lld/docs/ReleaseNotes.html>
Thanks to Ed Maste, Bryan Drewery, Andrew Turner, Antoine Brodin and Jan
Beich for their help.
Relnotes: yes
MFC r309147:
Pull in r282174 from upstream llvm trunk (by Krzysztof Parzyszek):
[PPC] Set SP after loading data from stack frame, if no red zone is
present
Follow-up to r280705: Make sure that the SP is only restored after
all data is loaded from the stack frame, if there is no red zone.
This completes the fix for
https://llvm.org/bugs/show_bug.cgi?id=26519.
Differential Revision: https://reviews.llvm.org/D24466
Reported by: Mark Millard
PR: 214433
MFC r309149:
Pull in r283060 from upstream llvm trunk (by Hal Finkel):
[PowerPC] Refactor soft-float support, and enable PPC64 soft float
This change enables soft-float for PowerPC64, and also makes
soft-float disable all vector instruction sets for both 32-bit and
64-bit modes. This latter part is necessary because the PPC backend
canonicalizes many Altivec vector types to floating-point types, and
so soft-float breaks scalarization support for many operations. Both
for embedded targets and for operating-system kernels desiring
soft-float support, it seems reasonable that disabling hardware
floating-point also disables vector instructions (embedded targets
without hardware floating point support are unlikely to have Altivec,
etc. and operating system kernels desiring not to use floating-point
registers to lower syscall cost are unlikely to want to use vector
registers either). If someone needs this to work, we'll need to
change the fact that we promote many Altivec operations to act on
v4f32. To make it possible to disable Altivec when soft-float is
enabled, hardware floating-point support needs to be expressed as a
positive feature, like the others, and not a negative feature,
because target features cannot have dependencies on the disabling of
some other feature. So +soft-float has now become -hard-float.
Fixes PR26970.
Pull in r283061 from upstream clang trunk (by Hal Finkel):
[PowerPC] Enable soft-float for PPC64, and +soft-float -> -hard-float
Enable soft-float support on PPC64, as the backend now supports it.
Also, the backend now uses -hard-float instead of +soft-float, so set
the target features accordingly.
Fixes PR26970.
Reported by: Mark Millard
PR: 214433
MFC r309212:
Add a few missed clang 3.9.0 files to OptionalObsoleteFiles.
MFC r309262:
Fix packaging for clang, lldb and lld 3.9.0
During the upgrade of clang/llvm etc to 3.9.0 in r309124, the PACKAGE
directive in the usr.bin/clang/*.mk files got dropped accidentally.
Restore it, with a few minor changes and additions:
* Correct license in clang.ucl to NCSA
* Add PACKAGE=clang for clang and most of the "ll" tools
* Put lldb in its own package
* Put lld in its own package
Reviewed by: gjb, jmallett
Differential Revision: https://reviews.freebsd.org/D8666
MFC r309656:
During the bootstrap phase, when building the minimal llvm library on
PowerPC, add lib/Support/Atomic.cpp. This is needed because upstream
llvm revision r271821 disabled the use of std::call_once, which causes
some fallback functions from Atomic.cpp to be used instead.
Reported by: Mark Millard
PR: 214902
MFC r309835:
Tentatively apply https://reviews.llvm.org/D18730 to work around gcc PR
70528 (bogus error: constructor required before non-static data member).
This should fix buildworld with the external gcc package.
Reported by: https://jenkins.freebsd.org/job/FreeBSD_HEAD_amd64_gcc/
MFC r310194:
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
3.9.1 release.
Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11
support to build; see UPDATING for more information.
Release notes for llvm, clang and lld will be available here:
<http://releases.llvm.org/3.9.1/docs/ReleaseNotes.html>
<http://releases.llvm.org/3.9.1/tools/clang/docs/ReleaseNotes.html>
<http://releases.llvm.org/3.9.1/tools/lld/docs/ReleaseNotes.html>
Relnotes: yes
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST')
44 files changed, 5132 insertions, 2049 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/APValue.cpp b/contrib/llvm/tools/clang/lib/AST/APValue.cpp index 91f1e20..3c58733 100644 --- a/contrib/llvm/tools/clang/lib/AST/APValue.cpp +++ b/contrib/llvm/tools/clang/lib/AST/APValue.cpp @@ -255,7 +255,7 @@ void APValue::swap(APValue &RHS) { memcpy(RHS.Data.buffer, TmpData, DataSize); } -void APValue::dump() const { +LLVM_DUMP_METHOD void APValue::dump() const { dump(llvm::errs()); llvm::errs() << '\n'; } diff --git a/contrib/llvm/tools/clang/lib/AST/ASTConsumer.cpp b/contrib/llvm/tools/clang/lib/AST/ASTConsumer.cpp index cff82e9..55033b2 100644 --- a/contrib/llvm/tools/clang/lib/AST/ASTConsumer.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ASTConsumer.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "clang/AST/ASTConsumer.h" -#include "llvm/Bitcode/BitstreamReader.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclGroup.h" using namespace clang; diff --git a/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp b/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp index 6438696..6aad4d1 100644 --- a/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp @@ -58,7 +58,7 @@ unsigned ASTContext::NumImplicitDestructors; unsigned ASTContext::NumImplicitDestructorsDeclared; enum FloatingRank { - HalfRank, FloatRank, DoubleRank, LongDoubleRank + HalfRank, FloatRank, DoubleRank, LongDoubleRank, Float128Rank }; RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { @@ -633,9 +633,8 @@ ASTContext::getCanonicalTemplateTemplateParmDecl( NTTP->getPosition(), nullptr, T, TInfo, - ExpandedTypes.data(), - ExpandedTypes.size(), - ExpandedTInfos.data()); + ExpandedTypes, + ExpandedTInfos); } else { Param = NonTypeTemplateParmDecl::Create(*this, getTranslationUnitDecl(), SourceLocation(), @@ -734,16 +733,16 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM, DependentTemplateSpecializationTypes(this_()), SubstTemplateTemplateParmPacks(this_()), GlobalNestedNameSpecifier(nullptr), Int128Decl(nullptr), - UInt128Decl(nullptr), Float128StubDecl(nullptr), - BuiltinVaListDecl(nullptr), BuiltinMSVaListDecl(nullptr), - ObjCIdDecl(nullptr), ObjCSelDecl(nullptr), ObjCClassDecl(nullptr), - ObjCProtocolClassDecl(nullptr), BOOLDecl(nullptr), - CFConstantStringTypeDecl(nullptr), ObjCInstanceTypeDecl(nullptr), - FILEDecl(nullptr), jmp_bufDecl(nullptr), sigjmp_bufDecl(nullptr), - ucontext_tDecl(nullptr), BlockDescriptorType(nullptr), - BlockDescriptorExtendedType(nullptr), cudaConfigureCallDecl(nullptr), - FirstLocalImport(), LastLocalImport(), ExternCContext(nullptr), - MakeIntegerSeqDecl(nullptr), SourceMgr(SM), LangOpts(LOpts), + UInt128Decl(nullptr), BuiltinVaListDecl(nullptr), + BuiltinMSVaListDecl(nullptr), ObjCIdDecl(nullptr), ObjCSelDecl(nullptr), + ObjCClassDecl(nullptr), ObjCProtocolClassDecl(nullptr), BOOLDecl(nullptr), + CFConstantStringTagDecl(nullptr), CFConstantStringTypeDecl(nullptr), + ObjCInstanceTypeDecl(nullptr), FILEDecl(nullptr), jmp_bufDecl(nullptr), + sigjmp_bufDecl(nullptr), ucontext_tDecl(nullptr), + BlockDescriptorType(nullptr), BlockDescriptorExtendedType(nullptr), + cudaConfigureCallDecl(nullptr), FirstLocalImport(), LastLocalImport(), + ExternCContext(nullptr), MakeIntegerSeqDecl(nullptr), + TypePackElementDecl(nullptr), SourceMgr(SM), LangOpts(LOpts), SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)), AddrSpaceMap(nullptr), Target(nullptr), AuxTarget(nullptr), PrintingPolicy(LOpts), Idents(idents), Selectors(sels), @@ -816,7 +815,7 @@ void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) { void ASTContext::setExternalSource(IntrusiveRefCntPtr<ExternalASTSource> Source) { - ExternalSource = Source; + ExternalSource = std::move(Source); } void ASTContext::PrintStats() const { @@ -928,6 +927,14 @@ ASTContext::getMakeIntegerSeqDecl() const { return MakeIntegerSeqDecl; } +BuiltinTemplateDecl * +ASTContext::getTypePackElementDecl() const { + if (!TypePackElementDecl) + TypePackElementDecl = buildBuiltinTemplateDecl(BTK__type_pack_element, + getTypePackElementName()); + return TypePackElementDecl; +} + RecordDecl *ASTContext::buildImplicitRecord(StringRef Name, RecordDecl::TagKind TK) const { SourceLocation Loc; @@ -966,14 +973,6 @@ TypedefDecl *ASTContext::getUInt128Decl() const { return UInt128Decl; } -TypeDecl *ASTContext::getFloat128StubType() const { - assert(LangOpts.CPlusPlus && "should only be called for c++"); - if (!Float128StubDecl) - Float128StubDecl = buildImplicitRecord("__float128"); - - return Float128StubDecl; -} - void ASTContext::InitBuiltinType(CanQualType &R, BuiltinType::Kind K) { BuiltinType *Ty = new (*this, TypeAlignment) BuiltinType(K); R = CanQualType::CreateUnsafe(QualType(Ty, 0)); @@ -1022,6 +1021,9 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target, InitBuiltinType(DoubleTy, BuiltinType::Double); InitBuiltinType(LongDoubleTy, BuiltinType::LongDouble); + // GNU extension, __float128 for IEEE quadruple precision + InitBuiltinType(Float128Ty, BuiltinType::Float128); + // GNU extension, 128-bit integers. InitBuiltinType(Int128Ty, BuiltinType::Int128); InitBuiltinType(UnsignedInt128Ty, BuiltinType::UInt128); @@ -1083,26 +1085,17 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target, FloatComplexTy = getComplexType(FloatTy); DoubleComplexTy = getComplexType(DoubleTy); LongDoubleComplexTy = getComplexType(LongDoubleTy); + Float128ComplexTy = getComplexType(Float128Ty); // Builtin types for 'id', 'Class', and 'SEL'. InitBuiltinType(ObjCBuiltinIdTy, BuiltinType::ObjCId); InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass); InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel); - if (LangOpts.OpenCL) { - InitBuiltinType(OCLImage1dTy, BuiltinType::OCLImage1d); - InitBuiltinType(OCLImage1dArrayTy, BuiltinType::OCLImage1dArray); - InitBuiltinType(OCLImage1dBufferTy, BuiltinType::OCLImage1dBuffer); - InitBuiltinType(OCLImage2dTy, BuiltinType::OCLImage2d); - InitBuiltinType(OCLImage2dArrayTy, BuiltinType::OCLImage2dArray); - InitBuiltinType(OCLImage2dDepthTy, BuiltinType::OCLImage2dDepth); - InitBuiltinType(OCLImage2dArrayDepthTy, BuiltinType::OCLImage2dArrayDepth); - InitBuiltinType(OCLImage2dMSAATy, BuiltinType::OCLImage2dMSAA); - InitBuiltinType(OCLImage2dArrayMSAATy, BuiltinType::OCLImage2dArrayMSAA); - InitBuiltinType(OCLImage2dMSAADepthTy, BuiltinType::OCLImage2dMSAADepth); - InitBuiltinType(OCLImage2dArrayMSAADepthTy, - BuiltinType::OCLImage2dArrayMSAADepth); - InitBuiltinType(OCLImage3dTy, BuiltinType::OCLImage3d); + if (LangOpts.OpenCL) { +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + InitBuiltinType(SingletonId, BuiltinType::Id); +#include "clang/Basic/OpenCLImageTypes.def" InitBuiltinType(OCLSamplerTy, BuiltinType::OCLSampler); InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent); @@ -1268,34 +1261,37 @@ void ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, ASTContext::overridden_cxx_method_iterator ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const { - llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos - = OverriddenMethods.find(Method->getCanonicalDecl()); + llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos = + OverriddenMethods.find(Method->getCanonicalDecl()); if (Pos == OverriddenMethods.end()) return nullptr; - return Pos->second.begin(); } ASTContext::overridden_cxx_method_iterator ASTContext::overridden_methods_end(const CXXMethodDecl *Method) const { - llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos - = OverriddenMethods.find(Method->getCanonicalDecl()); + llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos = + OverriddenMethods.find(Method->getCanonicalDecl()); if (Pos == OverriddenMethods.end()) return nullptr; - return Pos->second.end(); } unsigned ASTContext::overridden_methods_size(const CXXMethodDecl *Method) const { - llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos - = OverriddenMethods.find(Method->getCanonicalDecl()); + llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos = + OverriddenMethods.find(Method->getCanonicalDecl()); if (Pos == OverriddenMethods.end()) return 0; - return Pos->second.size(); } +ASTContext::overridden_method_range +ASTContext::overridden_methods(const CXXMethodDecl *Method) const { + return overridden_method_range(overridden_methods_begin(Method), + overridden_methods_end(Method)); +} + void ASTContext::addOverriddenMethod(const CXXMethodDecl *Method, const CXXMethodDecl *Overridden) { assert(Method->isCanonicalDecl() && Overridden->isCanonicalDecl()); @@ -1350,6 +1346,7 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { case BuiltinType::Float: return Target->getFloatFormat(); case BuiltinType::Double: return Target->getDoubleFormat(); case BuiltinType::LongDouble: return Target->getLongDoubleFormat(); + case BuiltinType::Float128: return Target->getFloat128Format(); } } @@ -1480,7 +1477,7 @@ static getConstantArrayInfoInChars(const ASTContext &Context, unsigned Align = EltInfo.second.getQuantity(); if (!Context.getTargetInfo().getCXXABI().isMicrosoft() || Context.getTargetInfo().getPointerWidth(0) == 64) - Width = llvm::RoundUpToAlignment(Width, Align); + Width = llvm::alignTo(Width, Align); return std::make_pair(CharUnits::fromQuantity(Width), CharUnits::fromQuantity(Align)); } @@ -1564,7 +1561,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { Align = EltInfo.Align; if (!getTargetInfo().getCXXABI().isMicrosoft() || getTargetInfo().getPointerWidth(0) == 64) - Width = llvm::RoundUpToAlignment(Width, Align); + Width = llvm::alignTo(Width, Align); break; } case Type::ExtVector: @@ -1577,7 +1574,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { // This happens for non-power-of-2 length vectors. if (Align & (Align-1)) { Align = llvm::NextPowerOf2(Align); - Width = llvm::RoundUpToAlignment(Width, Align); + Width = llvm::alignTo(Width, Align); } // Adjust the alignment based on the target max. uint64_t TargetVectorAlign = Target->getMaxVectorAlign(); @@ -1660,6 +1657,10 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { Width = Target->getLongDoubleWidth(); Align = Target->getLongDoubleAlign(); break; + case BuiltinType::Float128: + Width = Target->getFloat128Width(); + Align = Target->getFloat128Align(); + break; case BuiltinType::NullPtr: Width = Target->getPointerWidth(0); // C++ 3.9.1p11: sizeof(nullptr_t) Align = Target->getPointerAlign(0); // == sizeof(void*) @@ -1680,18 +1681,10 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { case BuiltinType::OCLQueue: case BuiltinType::OCLNDRange: case BuiltinType::OCLReserveID: - case BuiltinType::OCLImage1d: - case BuiltinType::OCLImage1dArray: - case BuiltinType::OCLImage1dBuffer: - case BuiltinType::OCLImage2d: - case BuiltinType::OCLImage2dArray: - case BuiltinType::OCLImage2dDepth: - case BuiltinType::OCLImage2dArrayDepth: - case BuiltinType::OCLImage2dMSAA: - case BuiltinType::OCLImage2dArrayMSAA: - case BuiltinType::OCLImage2dMSAADepth: - case BuiltinType::OCLImage2dArrayMSAADepth: - case BuiltinType::OCLImage3d: +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/Basic/OpenCLImageTypes.def" + // Currently these types are pointers to opaque types. Width = Target->getPointerWidth(0); Align = Target->getPointerAlign(0); @@ -1903,8 +1896,8 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const { if (T->isMemberPointerType()) return getPreferredTypeAlign(getPointerDiffType().getTypePtr()); - if (Target->getTriple().getArch() == llvm::Triple::xcore) - return ABIAlign; // Never overalign on XCore. + if (!Target->allowsLargerPreferedTypeAlignment()) + return ABIAlign; // Double and long long should be naturally aligned if possible. if (const ComplexType *CT = T->getAs<ComplexType>()) @@ -2991,13 +2984,18 @@ ASTContext::getDependentSizedExtVectorType(QualType vecType, return QualType(New, 0); } +/// \brief Determine whether \p T is canonical as the result type of a function. +static bool isCanonicalResultType(QualType T) { + return T.isCanonical() && + (T.getObjCLifetime() == Qualifiers::OCL_None || + T.getObjCLifetime() == Qualifiers::OCL_ExplicitNone); +} + /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. /// QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const { - const CallingConv CallConv = Info.getCC(); - // Unique functions, to guarantee there is only one function of a particular // structure. llvm::FoldingSetNodeID ID; @@ -3009,8 +3007,9 @@ ASTContext::getFunctionNoProtoType(QualType ResultTy, return QualType(FT, 0); QualType Canonical; - if (!ResultTy.isCanonical()) { - Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), Info); + if (!isCanonicalResultType(ResultTy)) { + Canonical = + getFunctionNoProtoType(getCanonicalFunctionResultType(ResultTy), Info); // Get the new insert position for the node we care about. FunctionNoProtoType *NewIP = @@ -3018,21 +3017,13 @@ ASTContext::getFunctionNoProtoType(QualType ResultTy, assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP; } - FunctionProtoType::ExtInfo newInfo = Info.withCallingConv(CallConv); FunctionNoProtoType *New = new (*this, TypeAlignment) - FunctionNoProtoType(ResultTy, Canonical, newInfo); + FunctionNoProtoType(ResultTy, Canonical, Info); Types.push_back(New); FunctionNoProtoTypes.InsertNode(New, InsertPos); return QualType(New, 0); } -/// \brief Determine whether \p T is canonical as the result type of a function. -static bool isCanonicalResultType(QualType T) { - return T.isCanonical() && - (T.getObjCLifetime() == Qualifiers::OCL_None || - T.getObjCLifetime() == Qualifiers::OCL_ExplicitNone); -} - CanQualType ASTContext::getCanonicalFunctionResultType(QualType ResultType) const { CanQualType CanResultType = getCanonicalType(ResultType); @@ -3099,12 +3090,13 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray, // them for three variable size arrays at the end: // - parameter types // - exception types - // - consumed-arguments flags + // - extended parameter information // Instead of the exception types, there could be a noexcept // expression, or information used to resolve the exception // specification. size_t Size = sizeof(FunctionProtoType) + NumArgs * sizeof(QualType); + if (EPI.ExceptionSpec.Type == EST_Dynamic) { Size += EPI.ExceptionSpec.Exceptions.size() * sizeof(QualType); } else if (EPI.ExceptionSpec.Type == EST_ComputedNoexcept) { @@ -3114,8 +3106,16 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray, } else if (EPI.ExceptionSpec.Type == EST_Unevaluated) { Size += sizeof(FunctionDecl*); } - if (EPI.ConsumedParameters) - Size += NumArgs * sizeof(bool); + + // Put the ExtParameterInfos last. If all were equal, it would make + // more sense to put these before the exception specification, because + // it's much easier to skip past them compared to the elaborate switch + // required to skip the exception specification. However, all is not + // equal; ExtParameterInfos are used to model very uncommon features, + // and it's better not to burden the more common paths. + if (EPI.ExtParameterInfos) { + Size += NumArgs * sizeof(FunctionProtoType::ExtParameterInfo); + } FunctionProtoType *FTP = (FunctionProtoType*) Allocate(Size, TypeAlignment); FunctionProtoType::ExtProtoInfo newEPI = EPI; @@ -3393,23 +3393,19 @@ ASTContext::getTemplateSpecializationType(TemplateName Template, QualType Underlying) const { assert(!Template.getAsDependentTemplateName() && "No dependent template names here!"); - - unsigned NumArgs = Args.size(); SmallVector<TemplateArgument, 4> ArgVec; - ArgVec.reserve(NumArgs); - for (unsigned i = 0; i != NumArgs; ++i) - ArgVec.push_back(Args[i].getArgument()); + ArgVec.reserve(Args.size()); + for (const TemplateArgumentLoc &Arg : Args.arguments()) + ArgVec.push_back(Arg.getArgument()); - return getTemplateSpecializationType(Template, ArgVec.data(), NumArgs, - Underlying); + return getTemplateSpecializationType(Template, ArgVec, Underlying); } #ifndef NDEBUG -static bool hasAnyPackExpansions(const TemplateArgument *Args, - unsigned NumArgs) { - for (unsigned I = 0; I != NumArgs; ++I) - if (Args[I].isPackExpansion()) +static bool hasAnyPackExpansions(ArrayRef<TemplateArgument> Args) { + for (const TemplateArgument &Arg : Args) + if (Arg.isPackExpansion()) return true; return true; @@ -3418,8 +3414,7 @@ static bool hasAnyPackExpansions(const TemplateArgument *Args, QualType ASTContext::getTemplateSpecializationType(TemplateName Template, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef<TemplateArgument> Args, QualType Underlying) const { assert(!Template.getAsDependentTemplateName() && "No dependent template names here!"); @@ -3436,32 +3431,29 @@ ASTContext::getTemplateSpecializationType(TemplateName Template, else { // We can get here with an alias template when the specialization contains // a pack expansion that does not match up with a parameter pack. - assert((!IsTypeAlias || hasAnyPackExpansions(Args, NumArgs)) && + assert((!IsTypeAlias || hasAnyPackExpansions(Args)) && "Caller must compute aliased type"); IsTypeAlias = false; - CanonType = getCanonicalTemplateSpecializationType(Template, Args, - NumArgs); + CanonType = getCanonicalTemplateSpecializationType(Template, Args); } // Allocate the (non-canonical) template specialization type, but don't // try to unique it: these types typically have location information that // we don't unique and don't want to lose. void *Mem = Allocate(sizeof(TemplateSpecializationType) + - sizeof(TemplateArgument) * NumArgs + + sizeof(TemplateArgument) * Args.size() + (IsTypeAlias? sizeof(QualType) : 0), TypeAlignment); TemplateSpecializationType *Spec - = new (Mem) TemplateSpecializationType(Template, Args, NumArgs, CanonType, + = new (Mem) TemplateSpecializationType(Template, Args, CanonType, IsTypeAlias ? Underlying : QualType()); Types.push_back(Spec); return QualType(Spec, 0); } -QualType -ASTContext::getCanonicalTemplateSpecializationType(TemplateName Template, - const TemplateArgument *Args, - unsigned NumArgs) const { +QualType ASTContext::getCanonicalTemplateSpecializationType( + TemplateName Template, ArrayRef<TemplateArgument> Args) const { assert(!Template.getAsDependentTemplateName() && "No dependent template names here!"); @@ -3472,15 +3464,16 @@ ASTContext::getCanonicalTemplateSpecializationType(TemplateName Template, // Build the canonical template specialization type. TemplateName CanonTemplate = getCanonicalTemplateName(Template); SmallVector<TemplateArgument, 4> CanonArgs; + unsigned NumArgs = Args.size(); CanonArgs.reserve(NumArgs); - for (unsigned I = 0; I != NumArgs; ++I) - CanonArgs.push_back(getCanonicalTemplateArgument(Args[I])); + for (const TemplateArgument &Arg : Args) + CanonArgs.push_back(getCanonicalTemplateArgument(Arg)); // Determine whether this canonical template specialization type already // exists. llvm::FoldingSetNodeID ID; TemplateSpecializationType::Profile(ID, CanonTemplate, - CanonArgs.data(), NumArgs, *this); + CanonArgs, *this); void *InsertPos = nullptr; TemplateSpecializationType *Spec @@ -3492,7 +3485,7 @@ ASTContext::getCanonicalTemplateSpecializationType(TemplateName Template, sizeof(TemplateArgument) * NumArgs), TypeAlignment); Spec = new (Mem) TemplateSpecializationType(CanonTemplate, - CanonArgs.data(), NumArgs, + CanonArgs, QualType(), QualType()); Types.push_back(Spec); TemplateSpecializationTypes.InsertNode(Spec, InsertPos); @@ -3592,9 +3585,7 @@ ASTContext::getDependentTemplateSpecializationType( SmallVector<TemplateArgument, 16> ArgCopy; for (unsigned I = 0, E = Args.size(); I != E; ++I) ArgCopy.push_back(Args[I].getArgument()); - return getDependentTemplateSpecializationType(Keyword, NNS, Name, - ArgCopy.size(), - ArgCopy.data()); + return getDependentTemplateSpecializationType(Keyword, NNS, Name, ArgCopy); } QualType @@ -3602,14 +3593,13 @@ ASTContext::getDependentTemplateSpecializationType( ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, - unsigned NumArgs, - const TemplateArgument *Args) const { + ArrayRef<TemplateArgument> Args) const { assert((!NNS || NNS->isDependent()) && "nested-name-specifier must be dependent"); llvm::FoldingSetNodeID ID; DependentTemplateSpecializationType::Profile(ID, *this, Keyword, NNS, - Name, NumArgs, Args); + Name, Args); void *InsertPos = nullptr; DependentTemplateSpecializationType *T @@ -3623,6 +3613,7 @@ ASTContext::getDependentTemplateSpecializationType( if (Keyword == ETK_None) CanonKeyword = ETK_Typename; bool AnyNonCanonArgs = false; + unsigned NumArgs = Args.size(); SmallVector<TemplateArgument, 16> CanonArgs(NumArgs); for (unsigned I = 0; I != NumArgs; ++I) { CanonArgs[I] = getCanonicalTemplateArgument(Args[I]); @@ -3633,8 +3624,8 @@ ASTContext::getDependentTemplateSpecializationType( QualType Canon; if (AnyNonCanonArgs || CanonNNS != NNS || CanonKeyword != Keyword) { Canon = getDependentTemplateSpecializationType(CanonKeyword, CanonNNS, - Name, NumArgs, - CanonArgs.data()); + Name, + CanonArgs); // Find the insert position again. DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos); @@ -3644,7 +3635,7 @@ ASTContext::getDependentTemplateSpecializationType( sizeof(TemplateArgument) * NumArgs), TypeAlignment); T = new (Mem) DependentTemplateSpecializationType(Keyword, NNS, - Name, NumArgs, Args, Canon); + Name, Args, Canon); Types.push_back(T); DependentTemplateSpecializationTypes.InsertNode(T, InsertPos); return QualType(T, 0); @@ -4012,13 +4003,35 @@ QualType ASTContext::getUnaryTransformType(QualType BaseType, QualType UnderlyingType, UnaryTransformType::UTTKind Kind) const { - UnaryTransformType *Ty = - new (*this, TypeAlignment) UnaryTransformType (BaseType, UnderlyingType, - Kind, - UnderlyingType->isDependentType() ? - QualType() : getCanonicalType(UnderlyingType)); - Types.push_back(Ty); - return QualType(Ty, 0); + UnaryTransformType *ut = nullptr; + + if (BaseType->isDependentType()) { + // Look in the folding set for an existing type. + llvm::FoldingSetNodeID ID; + DependentUnaryTransformType::Profile(ID, getCanonicalType(BaseType), Kind); + + void *InsertPos = nullptr; + DependentUnaryTransformType *Canon + = DependentUnaryTransformTypes.FindNodeOrInsertPos(ID, InsertPos); + + if (!Canon) { + // Build a new, canonical __underlying_type(type) type. + Canon = new (*this, TypeAlignment) + DependentUnaryTransformType(*this, getCanonicalType(BaseType), + Kind); + DependentUnaryTransformTypes.InsertNode(Canon, InsertPos); + } + ut = new (*this, TypeAlignment) UnaryTransformType (BaseType, + QualType(), Kind, + QualType(Canon, 0)); + } else { + QualType CanonType = getCanonicalType(UnderlyingType); + ut = new (*this, TypeAlignment) UnaryTransformType (BaseType, + UnderlyingType, Kind, + CanonType); + } + Types.push_back(ut); + return QualType(ut, 0); } /// getAutoType - Return the uniqued reference to the 'auto' type which has been @@ -4623,6 +4636,7 @@ static FloatingRank getFloatingRank(QualType T) { case BuiltinType::Float: return FloatRank; case BuiltinType::Double: return DoubleRank; case BuiltinType::LongDouble: return LongDoubleRank; + case BuiltinType::Float128: return Float128Rank; } } @@ -4639,6 +4653,7 @@ QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size, case FloatRank: return FloatComplexTy; case DoubleRank: return DoubleComplexTy; case LongDoubleRank: return LongDoubleComplexTy; + case Float128Rank: return Float128ComplexTy; } } @@ -4648,6 +4663,7 @@ QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size, case FloatRank: return FloatTy; case DoubleRank: return DoubleTy; case LongDoubleRank: return LongDoubleTy; + case Float128Rank: return Float128Ty; } llvm_unreachable("getFloatingRank(): illegal value for rank"); } @@ -4868,40 +4884,63 @@ int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) const { return 1; } -// getCFConstantStringType - Return the type used for constant CFStrings. -QualType ASTContext::getCFConstantStringType() const { +TypedefDecl *ASTContext::getCFConstantStringDecl() const { if (!CFConstantStringTypeDecl) { - CFConstantStringTypeDecl = buildImplicitRecord("NSConstantString"); - CFConstantStringTypeDecl->startDefinition(); + assert(!CFConstantStringTagDecl && + "tag and typedef should be initialized together"); + CFConstantStringTagDecl = buildImplicitRecord("__NSConstantString_tag"); + CFConstantStringTagDecl->startDefinition(); QualType FieldTypes[4]; + const char *FieldNames[4]; // const int *isa; FieldTypes[0] = getPointerType(IntTy.withConst()); + FieldNames[0] = "isa"; // int flags; FieldTypes[1] = IntTy; + FieldNames[1] = "flags"; // const char *str; FieldTypes[2] = getPointerType(CharTy.withConst()); + FieldNames[2] = "str"; // long length; FieldTypes[3] = LongTy; + FieldNames[3] = "length"; // Create fields for (unsigned i = 0; i < 4; ++i) { - FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTypeDecl, + FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTagDecl, + SourceLocation(), SourceLocation(), - SourceLocation(), nullptr, + &Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr, /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit); Field->setAccess(AS_public); - CFConstantStringTypeDecl->addDecl(Field); + CFConstantStringTagDecl->addDecl(Field); } - CFConstantStringTypeDecl->completeDefinition(); + CFConstantStringTagDecl->completeDefinition(); + // This type is designed to be compatible with NSConstantString, but cannot + // use the same name, since NSConstantString is an interface. + auto tagType = getTagDeclType(CFConstantStringTagDecl); + CFConstantStringTypeDecl = + buildImplicitTypedef(tagType, "__NSConstantString"); } - return getTagDeclType(CFConstantStringTypeDecl); + return CFConstantStringTypeDecl; +} + +RecordDecl *ASTContext::getCFConstantStringTagDecl() const { + if (!CFConstantStringTagDecl) + getCFConstantStringDecl(); // Build the tag and the typedef. + return CFConstantStringTagDecl; +} + +// getCFConstantStringType - Return the type used for constant CFStrings. +QualType ASTContext::getCFConstantStringType() const { + return getTypedefType(getCFConstantStringDecl()); } QualType ASTContext::getObjCSuperType() const { @@ -4914,9 +4953,13 @@ QualType ASTContext::getObjCSuperType() const { } void ASTContext::setCFConstantStringType(QualType T) { - const RecordType *Rec = T->getAs<RecordType>(); - assert(Rec && "Invalid CFConstantStringType"); - CFConstantStringTypeDecl = Rec->getDecl(); + const TypedefType *TD = T->getAs<TypedefType>(); + assert(TD && "Invalid CFConstantStringType"); + CFConstantStringTypeDecl = cast<TypedefDecl>(TD->getDecl()); + auto TagType = + CFConstantStringTypeDecl->getUnderlyingType()->getAs<RecordType>(); + assert(TagType && "Invalid CFConstantStringType"); + CFConstantStringTagDecl = TagType->getDecl(); } QualType ASTContext::getBlockDescriptorType() const { @@ -5096,6 +5139,27 @@ bool ASTContext::isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const { !VD->getFirstDecl()->isOutOfLine() && VD->getFirstDecl()->hasInit(); } +ASTContext::InlineVariableDefinitionKind +ASTContext::getInlineVariableDefinitionKind(const VarDecl *VD) const { + if (!VD->isInline()) + return InlineVariableDefinitionKind::None; + + // In almost all cases, it's a weak definition. + auto *First = VD->getFirstDecl(); + if (!First->isConstexpr() || First->isInlineSpecified() || + !VD->isStaticDataMember()) + return InlineVariableDefinitionKind::Weak; + + // If there's a file-context declaration in this translation unit, it's a + // non-discardable definition. + for (auto *D : VD->redecls()) + if (D->getLexicalDeclContext()->isFileContext()) + return InlineVariableDefinitionKind::Strong; + + // If we've not seen one yet, we don't know. + return InlineVariableDefinitionKind::WeakUnknown; +} + static inline std::string charUnitsToString(const CharUnits &CU) { return llvm::itostr(CU.getQuantity()); @@ -5122,7 +5186,7 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const { SourceLocation Loc; CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy); CharUnits ParmOffset = PtrSize; - for (auto PI : Decl->params()) { + for (auto PI : Decl->parameters()) { QualType PType = PI->getType(); CharUnits sz = getObjCEncodingTypeSize(PType); if (sz.isZero()) @@ -5137,7 +5201,7 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const { // Argument types. ParmOffset = PtrSize; - for (auto PVDecl : Decl->params()) { + for (auto PVDecl : Decl->parameters()) { QualType PType = PVDecl->getOriginalType(); if (const ArrayType *AT = dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) { @@ -5165,7 +5229,7 @@ bool ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, getObjCEncodingForType(Decl->getReturnType(), S); CharUnits ParmOffset; // Compute size of all parameters. - for (auto PI : Decl->params()) { + for (auto PI : Decl->parameters()) { QualType PType = PI->getType(); CharUnits sz = getObjCEncodingTypeSize(PType); if (sz.isZero()) @@ -5179,7 +5243,7 @@ bool ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, ParmOffset = CharUnits::Zero(); // Argument types. - for (auto PVDecl : Decl->params()) { + for (auto PVDecl : Decl->parameters()) { QualType PType = PVDecl->getOriginalType(); if (const ArrayType *AT = dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) { @@ -5450,6 +5514,7 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C, case BuiltinType::LongDouble: return 'D'; case BuiltinType::NullPtr: return '*'; // like char* + case BuiltinType::Float128: case BuiltinType::Half: // FIXME: potentially need @encodes for these! return ' '; @@ -5460,18 +5525,9 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C, llvm_unreachable("@encoding ObjC primitive type"); // OpenCL and placeholder types don't need @encodings. - case BuiltinType::OCLImage1d: - case BuiltinType::OCLImage1dArray: - case BuiltinType::OCLImage1dBuffer: - case BuiltinType::OCLImage2d: - case BuiltinType::OCLImage2dArray: - case BuiltinType::OCLImage2dDepth: - case BuiltinType::OCLImage2dArrayDepth: - case BuiltinType::OCLImage2dMSAA: - case BuiltinType::OCLImage2dArrayMSAA: - case BuiltinType::OCLImage2dMSAADepth: - case BuiltinType::OCLImage2dArrayMSAADepth: - case BuiltinType::OCLImage3d: +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/Basic/OpenCLImageTypes.def" case BuiltinType::OCLEvent: case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: @@ -5691,8 +5747,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); llvm::raw_string_ostream OS(S); TemplateSpecializationType::PrintTemplateArgumentList(OS, - TemplateArgs.data(), - TemplateArgs.size(), + TemplateArgs.asArray(), (*this).getPrintingPolicy()); } } else { @@ -5913,7 +5968,7 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, QualType *NotEncodedT) const { assert(RDecl && "Expected non-null RecordDecl"); assert(!RDecl->isUnion() && "Should not be called for unions"); - if (!RDecl->getDefinition()) + if (!RDecl->getDefinition() || RDecl->getDefinition()->isInvalidDecl()) return; CXXRecordDecl *CXXRec = dyn_cast<CXXRecordDecl>(RDecl); @@ -6354,6 +6409,7 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) { // }; VaListDecl->completeDefinition(); + Context->VaListTagDecl = VaListDecl; // typedef struct __va_list __builtin_va_list; QualType T = Context->getRecordType(VaListDecl); @@ -7132,6 +7188,11 @@ QualType ASTContext::areCommonBaseCompatible( if (!LDecl || !RDecl) return QualType(); + // When either LHS or RHS is a kindof type, we should return a kindof type. + // For example, for common base of kindof(ASub1) and kindof(ASub2), we return + // kindof(A). + bool anyKindOf = LHS->isKindOfType() || RHS->isKindOfType(); + // Follow the left-hand side up the class hierarchy until we either hit a // root or find the RHS. Record the ancestors in case we don't find it. llvm::SmallDenseMap<const ObjCInterfaceDecl *, const ObjCObjectType *, 4> @@ -7166,10 +7227,12 @@ QualType ASTContext::areCommonBaseCompatible( anyChanges = true; // If anything in the LHS will have changed, build a new result type. - if (anyChanges) { + // If we need to return a kindof type but LHS is not a kindof type, we + // build a new result type. + if (anyChanges || LHS->isKindOfType() != anyKindOf) { QualType Result = getObjCInterfaceType(LHS->getInterface()); Result = getObjCObjectType(Result, LHSTypeArgs, Protocols, - LHS->isKindOfType()); + anyKindOf || LHS->isKindOfType()); return getObjCObjectPointerType(Result); } @@ -7214,10 +7277,12 @@ QualType ASTContext::areCommonBaseCompatible( if (!Protocols.empty()) anyChanges = true; - if (anyChanges) { + // If we need to return a kindof type but RHS is not a kindof type, we + // build a new result type. + if (anyChanges || RHS->isKindOfType() != anyKindOf) { QualType Result = getObjCInterfaceType(RHS->getInterface()); Result = getObjCObjectType(Result, RHSTypeArgs, Protocols, - RHS->isKindOfType()); + anyKindOf || RHS->isKindOfType()); return getObjCObjectPointerType(Result); } @@ -7461,8 +7526,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, if (lproto->getTypeQuals() != rproto->getTypeQuals()) return QualType(); - if (LangOpts.ObjCAutoRefCount && - !FunctionTypesMatchOnNSConsumedAttrs(rproto, lproto)) + if (!doFunctionTypesMatchOnExtParameterInfos(rproto, lproto)) return QualType(); // Check parameter type compatibility @@ -7587,6 +7651,15 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, Qualifiers LQuals = LHSCan.getLocalQualifiers(); Qualifiers RQuals = RHSCan.getLocalQualifiers(); if (LQuals != RQuals) { + if (getLangOpts().OpenCL) { + if (LHSCan.getUnqualifiedType() != RHSCan.getUnqualifiedType() || + LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers()) + return QualType(); + if (LQuals.isAddressSpaceSupersetOf(RQuals)) + return LHS; + if (RQuals.isAddressSpaceSupersetOf(LQuals)) + return RHS; + } // If any of these qualifiers are different, we have a type // mismatch. if (LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers() || @@ -7850,21 +7923,26 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, llvm_unreachable("Invalid Type::Class!"); } -bool ASTContext::FunctionTypesMatchOnNSConsumedAttrs( - const FunctionProtoType *FromFunctionType, - const FunctionProtoType *ToFunctionType) { - if (FromFunctionType->hasAnyConsumedParams() != - ToFunctionType->hasAnyConsumedParams()) +bool ASTContext::doFunctionTypesMatchOnExtParameterInfos( + const FunctionProtoType *firstFnType, + const FunctionProtoType *secondFnType) { + // Fast path: if the first type doesn't have ext parameter infos, + // we match if and only if they second type also doesn't have them. + if (!firstFnType->hasExtParameterInfos()) + return !secondFnType->hasExtParameterInfos(); + + // Otherwise, we can only match if the second type has them. + if (!secondFnType->hasExtParameterInfos()) return false; - FunctionProtoType::ExtProtoInfo FromEPI = - FromFunctionType->getExtProtoInfo(); - FunctionProtoType::ExtProtoInfo ToEPI = - ToFunctionType->getExtProtoInfo(); - if (FromEPI.ConsumedParameters && ToEPI.ConsumedParameters) - for (unsigned i = 0, n = FromFunctionType->getNumParams(); i != n; ++i) { - if (FromEPI.ConsumedParameters[i] != ToEPI.ConsumedParameters[i]) - return false; - } + + auto firstEPI = firstFnType->getExtParameterInfos(); + auto secondEPI = secondFnType->getExtParameterInfos(); + assert(firstEPI.size() == secondEPI.size()); + + for (size_t i = 0, n = firstEPI.size(); i != n; ++i) { + if (firstEPI[i] != secondEPI[i]) + return false; + } return true; } @@ -8374,22 +8452,29 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context, return GVA_DiscardableODR; } -static GVALinkage adjustGVALinkageForAttributes(GVALinkage L, const Decl *D) { +static GVALinkage adjustGVALinkageForAttributes(const ASTContext &Context, + GVALinkage L, const Decl *D) { // See http://msdn.microsoft.com/en-us/library/xa0d9ste.aspx // dllexport/dllimport on inline functions. if (D->hasAttr<DLLImportAttr>()) { if (L == GVA_DiscardableODR || L == GVA_StrongODR) return GVA_AvailableExternally; - } else if (D->hasAttr<DLLExportAttr>() || D->hasAttr<CUDAGlobalAttr>()) { + } else if (D->hasAttr<DLLExportAttr>()) { if (L == GVA_DiscardableODR) return GVA_StrongODR; + } else if (Context.getLangOpts().CUDA && Context.getLangOpts().CUDAIsDevice && + D->hasAttr<CUDAGlobalAttr>()) { + // Device-side functions with __global__ attribute must always be + // visible externally so they can be launched from host. + if (L == GVA_DiscardableODR || L == GVA_Internal) + return GVA_StrongODR; } return L; } GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const { - return adjustGVALinkageForAttributes(basicGVALinkageForFunction(*this, FD), - FD); + return adjustGVALinkageForAttributes( + *this, basicGVALinkageForFunction(*this, FD), FD); } static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, @@ -8422,15 +8507,31 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, if (Context.isMSStaticDataMemberInlineDefinition(VD)) return GVA_DiscardableODR; + // Most non-template variables have strong linkage; inline variables are + // linkonce_odr or (occasionally, for compatibility) weak_odr. + GVALinkage StrongLinkage; + switch (Context.getInlineVariableDefinitionKind(VD)) { + case ASTContext::InlineVariableDefinitionKind::None: + StrongLinkage = GVA_StrongExternal; + break; + case ASTContext::InlineVariableDefinitionKind::Weak: + case ASTContext::InlineVariableDefinitionKind::WeakUnknown: + StrongLinkage = GVA_DiscardableODR; + break; + case ASTContext::InlineVariableDefinitionKind::Strong: + StrongLinkage = GVA_StrongODR; + break; + } + switch (VD->getTemplateSpecializationKind()) { case TSK_Undeclared: - return GVA_StrongExternal; + return StrongLinkage; case TSK_ExplicitSpecialization: return Context.getTargetInfo().getCXXABI().isMicrosoft() && VD->isStaticDataMember() ? GVA_StrongODR - : GVA_StrongExternal; + : StrongLinkage; case TSK_ExplicitInstantiationDefinition: return GVA_StrongODR; @@ -8446,8 +8547,8 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, } GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { - return adjustGVALinkageForAttributes(basicGVALinkageForVariable(*this, VD), - VD); + return adjustGVALinkageForAttributes( + *this, basicGVALinkageForVariable(*this, VD), VD); } bool ASTContext::DeclMustBeEmitted(const Decl *D) { @@ -8464,8 +8565,17 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { // We never need to emit an uninstantiated function template. if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate) return false; - } else if (isa<OMPThreadPrivateDecl>(D)) + } else if (isa<PragmaCommentDecl>(D)) + return true; + else if (isa<OMPThreadPrivateDecl>(D) || + D->hasAttr<OMPDeclareTargetDeclAttr>()) return true; + else if (isa<PragmaDetectMismatchDecl>(D)) + return true; + else if (isa<OMPThreadPrivateDecl>(D)) + return !D->getDeclContext()->isDependentContext(); + else if (isa<OMPDeclareReductionDecl>(D)) + return !D->getDeclContext()->isDependentContext(); else return false; @@ -8545,8 +8655,25 @@ CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic, if (IsCXXMethod) return ABI->getDefaultMethodCallConv(IsVariadic); - if (LangOpts.MRTD && !IsVariadic) return CC_X86StdCall; - + switch (LangOpts.getDefaultCallingConv()) { + case LangOptions::DCC_None: + break; + case LangOptions::DCC_CDecl: + return CC_C; + case LangOptions::DCC_FastCall: + if (getTargetInfo().hasFeature("sse2")) + return CC_X86FastCall; + break; + case LangOptions::DCC_StdCall: + if (!IsVariadic) + return CC_X86StdCall; + break; + case LangOptions::DCC_VectorCall: + // __vectorcall cannot be applied to variadic functions. + if (!IsVariadic) + return CC_X86VectorCall; + break; + } return Target->getDefaultCallingConv(TargetInfo::CCMT_Unknown); } @@ -8626,6 +8753,8 @@ QualType ASTContext::getRealTypeForBitwidth(unsigned DestWidth) const { return DoubleTy; case TargetInfo::LongDouble: return LongDoubleTy; + case TargetInfo::Float128: + return Float128Ty; case TargetInfo::NoFloat: return QualType(); } @@ -8639,8 +8768,7 @@ void ASTContext::setManglingNumber(const NamedDecl *ND, unsigned Number) { } unsigned ASTContext::getManglingNumber(const NamedDecl *ND) const { - llvm::DenseMap<const NamedDecl *, unsigned>::const_iterator I = - MangleNumbers.find(ND); + auto I = MangleNumbers.find(ND); return I != MangleNumbers.end() ? I->second : 1; } @@ -8650,8 +8778,7 @@ void ASTContext::setStaticLocalNumber(const VarDecl *VD, unsigned Number) { } unsigned ASTContext::getStaticLocalNumber(const VarDecl *VD) const { - llvm::DenseMap<const VarDecl *, unsigned>::const_iterator I = - StaticLocalNumbers.find(VD); + auto I = StaticLocalNumbers.find(VD); return I != StaticLocalNumbers.end() ? I->second : 1; } diff --git a/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp b/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp index 2ab5a32..0f5a8b5 100644 --- a/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp @@ -10,6 +10,7 @@ // This file implements a diagnostic formatting hook for AST elements. // //===----------------------------------------------------------------------===// + #include "clang/AST/ASTDiagnostic.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTLambda.h" @@ -118,7 +119,7 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) { if (DesugarArgument) { ShouldAKA = true; QT = Context.getTemplateSpecializationType( - TST->getTemplateName(), Args.data(), Args.size(), QT); + TST->getTemplateName(), Args, QT); } break; } @@ -443,7 +444,6 @@ void clang::FormatASTNodeDiagnosticArgument( NeedQuotes = false; break; } - } if (NeedQuotes) { @@ -497,7 +497,7 @@ class TemplateDiff { enum DiffKind { /// Incomplete or invalid node. Invalid, - /// Another level of templates, requires that + /// Another level of templates Template, /// Type difference, all type differences except those falling under /// the Template difference. @@ -616,7 +616,7 @@ class TemplateDiff { SetDefault(FromDefault, ToDefault); } - void SetIntegerDiff(llvm::APSInt FromInt, llvm::APSInt ToInt, + void SetIntegerDiff(const llvm::APSInt &FromInt, const llvm::APSInt &ToInt, bool IsValidFromInt, bool IsValidToInt, QualType FromIntType, QualType ToIntType, Expr *FromExpr, Expr *ToExpr, bool FromDefault, @@ -653,7 +653,7 @@ class TemplateDiff { void SetFromDeclarationAndToIntegerDiff( ValueDecl *FromValueDecl, bool FromAddressOf, bool FromNullPtr, - Expr *FromExpr, llvm::APSInt ToInt, bool IsValidToInt, + Expr *FromExpr, const llvm::APSInt &ToInt, bool IsValidToInt, QualType ToIntType, Expr *ToExpr, bool FromDefault, bool ToDefault) { assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); FlatTree[CurrentNode].Kind = FromDeclarationAndToInteger; @@ -669,7 +669,7 @@ class TemplateDiff { } void SetFromIntegerAndToDeclarationDiff( - llvm::APSInt FromInt, bool IsValidFromInt, QualType FromIntType, + const llvm::APSInt &FromInt, bool IsValidFromInt, QualType FromIntType, Expr *FromExpr, ValueDecl *ToValueDecl, bool ToAddressOf, bool ToNullPtr, Expr *ToExpr, bool FromDefault, bool ToDefault) { assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); @@ -917,6 +917,8 @@ class TemplateDiff { /// template argument. InternalIterator(const TemplateSpecializationType *TST) : TST(TST), Index(0), CurrentTA(nullptr), EndTA(nullptr) { + if (!TST) return; + if (isEnd()) return; // Set to first template argument. If not a parameter pack, done. @@ -937,11 +939,13 @@ class TemplateDiff { /// isEnd - Returns true if the iterator is one past the end. bool isEnd() const { + assert(TST && "InternalIterator is invalid with a null TST."); return Index >= TST->getNumArgs(); } /// &operator++ - Increment the iterator to the next template argument. InternalIterator &operator++() { + assert(TST && "InternalIterator is invalid with a null TST."); if (isEnd()) { return *this; } @@ -977,6 +981,7 @@ class TemplateDiff { /// operator* - Returns the appropriate TemplateArgument. reference operator*() const { + assert(TST && "InternalIterator is invalid with a null TST."); assert(!isEnd() && "Index exceeds number of arguments."); if (CurrentTA == EndTA) return TST->getArg(Index); @@ -986,23 +991,27 @@ class TemplateDiff { /// operator-> - Allow access to the underlying TemplateArgument. pointer operator->() const { + assert(TST && "InternalIterator is invalid with a null TST."); return &operator*(); } }; + bool UseDesugaredIterator; InternalIterator SugaredIterator; InternalIterator DesugaredIterator; public: TSTiterator(ASTContext &Context, const TemplateSpecializationType *TST) - : SugaredIterator(TST), + : UseDesugaredIterator(TST->isSugared() && !TST->isTypeAlias()), + SugaredIterator(TST), DesugaredIterator( GetTemplateSpecializationType(Context, TST->desugar())) {} /// &operator++ - Increment the iterator to the next template argument. TSTiterator &operator++() { ++SugaredIterator; - ++DesugaredIterator; + if (UseDesugaredIterator) + ++DesugaredIterator; return *this; } @@ -1024,11 +1033,13 @@ class TemplateDiff { /// hasDesugaredTA - Returns true if there is another TemplateArgument /// available. bool hasDesugaredTA() const { - return !DesugaredIterator.isEnd(); + return UseDesugaredIterator && !DesugaredIterator.isEnd(); } /// getDesugaredTA - Returns the desugared TemplateArgument. reference getDesugaredTA() const { + assert(UseDesugaredIterator && + "Desugared TemplateArgument should not be used."); return *DesugaredIterator; } }; @@ -1055,8 +1066,7 @@ class TemplateDiff { Ty = Context.getTemplateSpecializationType( TemplateName(CTSD->getSpecializedTemplate()), - CTSD->getTemplateArgs().data(), - CTSD->getTemplateArgs().size(), + CTSD->getTemplateArgs().asArray(), Ty.getLocalUnqualifiedType().getCanonicalType()); return Ty->getAs<TemplateSpecializationType>(); @@ -1523,12 +1533,14 @@ class TemplateDiff { OS << FromTD->getNameAsString() << '<'; Tree.MoveToChild(); unsigned NumElideArgs = 0; + bool AllArgsElided = true; do { if (ElideType) { if (Tree.NodeIsSame()) { ++NumElideArgs; continue; } + AllArgsElided = false; if (NumElideArgs > 0) { PrintElideArgs(NumElideArgs, Indent); NumElideArgs = 0; @@ -1539,8 +1551,12 @@ class TemplateDiff { if (Tree.HasNextSibling()) OS << ", "; } while (Tree.AdvanceSibling()); - if (NumElideArgs > 0) - PrintElideArgs(NumElideArgs, Indent); + if (NumElideArgs > 0) { + if (AllArgsElided) + OS << "..."; + else + PrintElideArgs(NumElideArgs, Indent); + } Tree.Parent(); OS << ">"; @@ -1622,7 +1638,6 @@ class TemplateDiff { Unbold(); OS << "]"; } - return; } /// PrintExpr - Prints out the expr template arguments, highlighting argument @@ -1695,7 +1710,7 @@ class TemplateDiff { /// PrintAPSInt - Handles printing of integral arguments, highlighting /// argument differences. - void PrintAPSInt(llvm::APSInt FromInt, llvm::APSInt ToInt, + void PrintAPSInt(const llvm::APSInt &FromInt, const llvm::APSInt &ToInt, bool IsValidFromInt, bool IsValidToInt, QualType FromIntType, QualType ToIntType, Expr *FromExpr, Expr *ToExpr, bool FromDefault, bool ToDefault, bool Same) { @@ -1728,8 +1743,8 @@ class TemplateDiff { /// PrintAPSInt - If valid, print the APSInt. If the expression is /// gives more information, print it too. - void PrintAPSInt(llvm::APSInt Val, Expr *E, bool Valid, QualType IntType, - bool PrintType) { + void PrintAPSInt(const llvm::APSInt &Val, Expr *E, bool Valid, + QualType IntType, bool PrintType) { Bold(); if (Valid) { if (HasExtraInfo(E)) { @@ -1834,14 +1849,13 @@ class TemplateDiff { Unbold(); OS << ']'; } - } /// PrintValueDeclAndInteger - Uses the print functions for ValueDecl and /// APSInt to print a mixed difference. void PrintValueDeclAndInteger(ValueDecl *VD, bool NeedAddressOf, bool IsNullPtr, Expr *VDExpr, bool DefaultDecl, - llvm::APSInt Val, QualType IntType, + const llvm::APSInt &Val, QualType IntType, Expr *IntExpr, bool DefaultInt) { if (!PrintTree) { OS << (DefaultDecl ? "(default) " : ""); @@ -1861,7 +1875,7 @@ class TemplateDiff { /// PrintIntegerAndValueDecl - Uses the print functions for APSInt and /// ValueDecl to print a mixed difference. - void PrintIntegerAndValueDecl(llvm::APSInt Val, QualType IntType, + void PrintIntegerAndValueDecl(const llvm::APSInt &Val, QualType IntType, Expr *IntExpr, bool DefaultInt, ValueDecl *VD, bool NeedAddressOf, bool IsNullPtr, Expr *VDExpr, bool DefaultDecl) { @@ -2016,7 +2030,7 @@ public: return true; } }; // end class TemplateDiff -} // end namespace +} // end anonymous namespace /// FormatTemplateTypeDiff - A helper static function to start the template /// diff and return the properly formatted string. Returns true if the diff diff --git a/contrib/llvm/tools/clang/lib/AST/ASTDumper.cpp b/contrib/llvm/tools/clang/lib/AST/ASTDumper.cpp index 4622a75..872ba35 100644 --- a/contrib/llvm/tools/clang/lib/AST/ASTDumper.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ASTDumper.cpp @@ -18,13 +18,14 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclLookups.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclVisitor.h" +#include "clang/AST/LocInfoType.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/TypeVisitor.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" -#include "clang/Sema/LocInfoType.h" #include "llvm/Support/raw_ostream.h" using namespace clang; using namespace clang::comments; @@ -403,6 +404,9 @@ namespace { void VisitAtomicType(const AtomicType *T) { dumpTypeAsChild(T->getValueType()); } + void VisitPipeType(const PipeType *T) { + dumpTypeAsChild(T->getElementType()); + } void VisitAdjustedType(const AdjustedType *T) { dumpTypeAsChild(T->getOriginalType()); } @@ -426,6 +430,14 @@ namespace { void VisitVarDecl(const VarDecl *D); void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D); void VisitImportDecl(const ImportDecl *D); + void VisitPragmaCommentDecl(const PragmaCommentDecl *D); + void VisitPragmaDetectMismatchDecl(const PragmaDetectMismatchDecl *D); + void VisitCapturedDecl(const CapturedDecl *D); + + // OpenMP decls + void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D); + void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D); + void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D); // C++ Decls void VisitNamespaceDecl(const NamespaceDecl *D); @@ -462,6 +474,7 @@ namespace { void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D); void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D); void VisitUsingShadowDecl(const UsingShadowDecl *D); + void VisitConstructorUsingShadowDecl(const ConstructorUsingShadowDecl *D); void VisitLinkageSpecDecl(const LinkageSpecDecl *D); void VisitAccessSpecDecl(const AccessSpecDecl *D); void VisitFriendDecl(const FriendDecl *D); @@ -487,6 +500,10 @@ namespace { void VisitLabelStmt(const LabelStmt *Node); void VisitGotoStmt(const GotoStmt *Node); void VisitCXXCatchStmt(const CXXCatchStmt *Node); + void VisitCapturedStmt(const CapturedStmt *Node); + + // OpenMP + void VisitOMPExecutableDirective(const OMPExecutableDirective *Node); // Exprs void VisitExpr(const Expr *Node); @@ -697,6 +714,12 @@ void ASTDumper::dumpTypeAsChild(const Type *T) { } void ASTDumper::dumpBareDeclRef(const Decl *D) { + if (!D) { + ColorScope Color(*this, NullColor); + OS << "<<<NULL>>>"; + return; + } + { ColorScope Color(*this, DeclKindNameColor); OS << D->getDeclKindName(); @@ -819,8 +842,6 @@ void ASTDumper::dumpAttr(const Attr *A) { switch (A->getKind()) { #define ATTR(X) case attr::X: OS << #X; break; #include "clang/Basic/AttrList.inc" - default: - llvm_unreachable("unexpected attribute kind"); } OS << "Attr"; } @@ -1140,10 +1161,8 @@ void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { if (!D->param_begin() && D->getNumParams()) dumpChild([=] { OS << "<<NULL params x " << D->getNumParams() << ">>"; }); else - for (FunctionDecl::param_const_iterator I = D->param_begin(), - E = D->param_end(); - I != E; ++I) - dumpDecl(*I); + for (const ParmVarDecl *Parameter : D->parameters()) + dumpDecl(Parameter); if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D)) for (CXXConstructorDecl::init_const_iterator I = C->init_begin(), @@ -1184,6 +1203,10 @@ void ASTDumper::VisitVarDecl(const VarDecl *D) { OS << " __module_private__"; if (D->isNRVOVariable()) OS << " nrvo"; + if (D->isInline()) + OS << " inline"; + if (D->isConstexpr()) + OS << " constexpr"; if (D->hasInit()) { switch (D->getInitStyle()) { case VarDecl::CInit: OS << " cinit"; break; @@ -1202,6 +1225,56 @@ void ASTDumper::VisitImportDecl(const ImportDecl *D) { OS << ' ' << D->getImportedModule()->getFullModuleName(); } +void ASTDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) { + OS << ' '; + switch (D->getCommentKind()) { + case PCK_Unknown: llvm_unreachable("unexpected pragma comment kind"); + case PCK_Compiler: OS << "compiler"; break; + case PCK_ExeStr: OS << "exestr"; break; + case PCK_Lib: OS << "lib"; break; + case PCK_Linker: OS << "linker"; break; + case PCK_User: OS << "user"; break; + } + StringRef Arg = D->getArg(); + if (!Arg.empty()) + OS << " \"" << Arg << "\""; +} + +void ASTDumper::VisitPragmaDetectMismatchDecl( + const PragmaDetectMismatchDecl *D) { + OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\""; +} + +void ASTDumper::VisitCapturedDecl(const CapturedDecl *D) { + dumpStmt(D->getBody()); +} + +//===----------------------------------------------------------------------===// +// OpenMP Declarations +//===----------------------------------------------------------------------===// + +void ASTDumper::VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) { + for (auto *E : D->varlists()) + dumpStmt(E); +} + +void ASTDumper::VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) { + dumpName(D); + dumpType(D->getType()); + OS << " combiner"; + dumpStmt(D->getCombiner()); + if (auto *Initializer = D->getInitializer()) { + OS << " initializer"; + dumpStmt(Initializer); + } +} + +void ASTDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) { + dumpName(D); + dumpType(D->getType()); + dumpStmt(D->getInit()); +} + //===----------------------------------------------------------------------===// // C++ Declarations //===----------------------------------------------------------------------===// @@ -1425,6 +1498,31 @@ void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) { dumpTypeAsChild(TD->getTypeForDecl()); } +void ASTDumper::VisitConstructorUsingShadowDecl( + const ConstructorUsingShadowDecl *D) { + if (D->constructsVirtualBase()) + OS << " virtual"; + + dumpChild([=] { + OS << "target "; + dumpBareDeclRef(D->getTargetDecl()); + }); + + dumpChild([=] { + OS << "nominated "; + dumpBareDeclRef(D->getNominatedBaseClass()); + OS << ' '; + dumpBareDeclRef(D->getNominatedBaseClassShadowDecl()); + }); + + dumpChild([=] { + OS << "constructed "; + dumpBareDeclRef(D->getConstructedBaseClass()); + OS << ' '; + dumpBareDeclRef(D->getConstructedBaseClassShadowDecl()); + }); +} + void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) { switch (D->getLanguage()) { case LinkageSpecDecl::lang_c: OS << " C"; break; @@ -1484,10 +1582,8 @@ void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) { if (D->isThisDeclarationADefinition()) { dumpDeclContext(D); } else { - for (ObjCMethodDecl::param_const_iterator I = D->param_begin(), - E = D->param_end(); - I != E; ++I) - dumpDecl(*I); + for (const ParmVarDecl *Parameter : D->parameters()) + dumpDecl(Parameter); } if (D->isVariadic()) @@ -1597,6 +1693,8 @@ void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { OS << " strong"; if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) OS << " unsafe_unretained"; + if (Attrs & ObjCPropertyDecl::OBJC_PR_class) + OS << " class"; if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) dumpDeclRef(D->getGetterMethodDecl(), "getter"); if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) @@ -1615,7 +1713,7 @@ void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { } void ASTDumper::VisitBlockDecl(const BlockDecl *D) { - for (auto I : D->params()) + for (auto I : D->parameters()) dumpDecl(I); if (D->isVariadic()) @@ -1707,6 +1805,41 @@ void ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) { dumpDecl(Node->getExceptionDecl()); } +void ASTDumper::VisitCapturedStmt(const CapturedStmt *Node) { + VisitStmt(Node); + dumpDecl(Node->getCapturedDecl()); +} + +//===----------------------------------------------------------------------===// +// OpenMP dumping methods. +//===----------------------------------------------------------------------===// + +void ASTDumper::VisitOMPExecutableDirective( + const OMPExecutableDirective *Node) { + VisitStmt(Node); + for (auto *C : Node->clauses()) { + dumpChild([=] { + if (!C) { + ColorScope Color(*this, NullColor); + OS << "<<<NULL>>> OMPClause"; + return; + } + { + ColorScope Color(*this, AttrColor); + StringRef ClauseName(getOpenMPClauseName(C->getClauseKind())); + OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() + << ClauseName.drop_front() << "Clause"; + } + dumpPointer(C); + dumpSourceRange(SourceRange(C->getLocStart(), C->getLocEnd())); + if (C->isImplicit()) + OS << " <implicit>"; + for (auto *S : C->children()) + dumpStmt(S); + }); + } +} + //===----------------------------------------------------------------------===// // Expr dumping methods. //===----------------------------------------------------------------------===// @@ -2076,8 +2209,10 @@ void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) { void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) { VisitExpr(Node); - OS << " selector="; - Node->getBoxingMethod()->getSelector().print(OS); + if (auto *BoxingMethod = Node->getBoxingMethod()) { + OS << " selector="; + BoxingMethod->getSelector().print(OS); + } } void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { diff --git a/contrib/llvm/tools/clang/lib/AST/ASTImporter.cpp b/contrib/llvm/tools/clang/lib/AST/ASTImporter.cpp index 916f108..bc1f9f9 100644 --- a/contrib/llvm/tools/clang/lib/AST/ASTImporter.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ASTImporter.cpp @@ -29,7 +29,7 @@ namespace clang { public DeclVisitor<ASTNodeImporter, Decl *>, public StmtVisitor<ASTNodeImporter, Stmt *> { ASTImporter &Importer; - + public: explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) { } @@ -64,11 +64,12 @@ namespace clang { QualType VisitDecltypeType(const DecltypeType *T); QualType VisitUnaryTransformType(const UnaryTransformType *T); QualType VisitAutoType(const AutoType *T); + QualType VisitInjectedClassNameType(const InjectedClassNameType *T); // FIXME: DependentDecltypeType QualType VisitRecordType(const RecordType *T); QualType VisitEnumType(const EnumType *T); QualType VisitAttributedType(const AttributedType *T); - // FIXME: TemplateTypeParmType + QualType VisitTemplateTypeParmType(const TemplateTypeParmType *T); // FIXME: SubstTemplateTypeParmType QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T); QualType VisitElaboratedType(const ElaboratedType *T); @@ -86,6 +87,10 @@ namespace clang { void ImportDeclarationNameLoc(const DeclarationNameInfo &From, DeclarationNameInfo& To); void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false); + + typedef DesignatedInitExpr::Designator Designator; + Designator ImportDesignator(const Designator &D); + /// \brief What we should import from the definition. enum ImportDefinitionKind { @@ -130,11 +135,13 @@ namespace clang { bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To); bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To); Decl *VisitDecl(Decl *D); + Decl *VisitAccessSpecDecl(AccessSpecDecl *D); Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D); Decl *VisitNamespaceDecl(NamespaceDecl *D); Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias); Decl *VisitTypedefDecl(TypedefDecl *D); Decl *VisitTypeAliasDecl(TypeAliasDecl *D); + Decl *VisitLabelDecl(LabelDecl *D); Decl *VisitEnumDecl(EnumDecl *D); Decl *VisitRecordDecl(RecordDecl *D); Decl *VisitEnumConstantDecl(EnumConstantDecl *D); @@ -174,6 +181,7 @@ namespace clang { DeclGroupRef ImportDeclGroup(DeclGroupRef DG); Stmt *VisitStmt(Stmt *S); + Stmt *VisitGCCAsmStmt(GCCAsmStmt *S); Stmt *VisitDeclStmt(DeclStmt *S); Stmt *VisitNullStmt(NullStmt *S); Stmt *VisitCompoundStmt(CompoundStmt *S); @@ -191,7 +199,6 @@ namespace clang { Stmt *VisitContinueStmt(ContinueStmt *S); Stmt *VisitBreakStmt(BreakStmt *S); Stmt *VisitReturnStmt(ReturnStmt *S); - // FIXME: GCCAsmStmt // FIXME: MSAsmStmt // FIXME: SEHExceptStmt // FIXME: SEHFinallyStmt @@ -212,21 +219,69 @@ namespace clang { // Importing expressions Expr *VisitExpr(Expr *E); + Expr *VisitVAArgExpr(VAArgExpr *E); + Expr *VisitGNUNullExpr(GNUNullExpr *E); + Expr *VisitPredefinedExpr(PredefinedExpr *E); Expr *VisitDeclRefExpr(DeclRefExpr *E); + Expr *VisitImplicitValueInitExpr(ImplicitValueInitExpr *ILE); + Expr *VisitDesignatedInitExpr(DesignatedInitExpr *E); + Expr *VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E); Expr *VisitIntegerLiteral(IntegerLiteral *E); + Expr *VisitFloatingLiteral(FloatingLiteral *E); Expr *VisitCharacterLiteral(CharacterLiteral *E); + Expr *VisitStringLiteral(StringLiteral *E); + Expr *VisitCompoundLiteralExpr(CompoundLiteralExpr *E); + Expr *VisitAtomicExpr(AtomicExpr *E); + Expr *VisitAddrLabelExpr(AddrLabelExpr *E); Expr *VisitParenExpr(ParenExpr *E); + Expr *VisitParenListExpr(ParenListExpr *E); + Expr *VisitStmtExpr(StmtExpr *E); Expr *VisitUnaryOperator(UnaryOperator *E); Expr *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E); Expr *VisitBinaryOperator(BinaryOperator *E); + Expr *VisitConditionalOperator(ConditionalOperator *E); + Expr *VisitBinaryConditionalOperator(BinaryConditionalOperator *E); + Expr *VisitOpaqueValueExpr(OpaqueValueExpr *E); Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E); Expr *VisitImplicitCastExpr(ImplicitCastExpr *E); Expr *VisitCStyleCastExpr(CStyleCastExpr *E); Expr *VisitCXXConstructExpr(CXXConstructExpr *E); + Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E); + Expr *VisitCXXThisExpr(CXXThisExpr *E); + Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); Expr *VisitMemberExpr(MemberExpr *E); Expr *VisitCallExpr(CallExpr *E); + Expr *VisitInitListExpr(InitListExpr *E); + Expr *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E); + Expr *VisitCXXNamedCastExpr(CXXNamedCastExpr *E); + + template<typename IIter, typename OIter> + void ImportArray(IIter Ibegin, IIter Iend, OIter Obegin) { + typedef typename std::remove_reference<decltype(*Obegin)>::type ItemT; + ASTImporter &ImporterRef = Importer; + std::transform(Ibegin, Iend, Obegin, + [&ImporterRef](ItemT From) -> ItemT { + return ImporterRef.Import(From); + }); + } + + template<typename IIter, typename OIter> + bool ImportArrayChecked(IIter Ibegin, IIter Iend, OIter Obegin) { + typedef typename std::remove_reference<decltype(**Obegin)>::type ItemT; + ASTImporter &ImporterRef = Importer; + bool Failed = false; + std::transform(Ibegin, Iend, Obegin, + [&ImporterRef, &Failed](ItemT *From) -> ItemT * { + ItemT *To = ImporterRef.Import(From); + if (!To && From) + Failed = true; + return To; + }); + return Failed; + } }; } + using namespace clang; //---------------------------------------------------------------------------- @@ -618,8 +673,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, if (!IsStructurallyEquivalent(Context, Function1->getReturnType(), Function2->getReturnType())) return false; - if (Function1->getExtInfo() != Function2->getExtInfo()) - return false; + if (Function1->getExtInfo() != Function2->getExtInfo()) + return false; break; } @@ -974,7 +1029,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, /// including the next assigned index (if none of them match). Returns an /// empty option if the context is not a record, i.e.. if the anonymous /// struct/union is at namespace or block scope. -static Optional<unsigned> findAnonymousStructOrUnionIndex(RecordDecl *Anon) { +static Optional<unsigned> findUntaggedStructOrUnionIndex(RecordDecl *Anon) { ASTContext &Context = Anon->getASTContext(); QualType AnonTy = Context.getRecordType(Anon); @@ -985,13 +1040,29 @@ static Optional<unsigned> findAnonymousStructOrUnionIndex(RecordDecl *Anon) { unsigned Index = 0; for (const auto *D : Owner->noload_decls()) { const auto *F = dyn_cast<FieldDecl>(D); - if (!F || !F->isAnonymousStructOrUnion()) + if (!F) continue; - if (Context.hasSameType(F->getType(), AnonTy)) - break; + if (F->isAnonymousStructOrUnion()) { + if (Context.hasSameType(F->getType(), AnonTy)) + break; + ++Index; + continue; + } - ++Index; + // If the field looks like this: + // struct { ... } A; + QualType FieldType = F->getType(); + if (const auto *RecType = dyn_cast<RecordType>(FieldType)) { + const RecordDecl *RecDecl = RecType->getDecl(); + if (RecDecl->getDeclContext() == Owner && + !RecDecl->getIdentifier()) { + if (Context.hasSameType(FieldType, AnonTy)) + break; + ++Index; + continue; + } + } } return Index; @@ -1013,8 +1084,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, if (D1->isAnonymousStructOrUnion() && D2->isAnonymousStructOrUnion()) { // If both anonymous structs/unions are in a record context, make sure // they occur in the same location in the context records. - if (Optional<unsigned> Index1 = findAnonymousStructOrUnionIndex(D1)) { - if (Optional<unsigned> Index2 = findAnonymousStructOrUnionIndex(D2)) { + if (Optional<unsigned> Index1 = findUntaggedStructOrUnionIndex(D1)) { + if (Optional<unsigned> Index2 = findUntaggedStructOrUnionIndex(D2)) { if (*Index1 != *Index2) return false; } @@ -1480,6 +1551,10 @@ QualType ASTNodeImporter::VisitType(const Type *T) { QualType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) { switch (T->getKind()) { +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: \ + return Importer.getToContext().SingletonId; +#include "clang/Basic/OpenCLImageTypes.def" #define SHARED_SINGLETON_TYPE(Expansion) #define BUILTIN_TYPE(Id, SingletonId) \ case BuiltinType::Id: return Importer.getToContext().SingletonId; @@ -1758,6 +1833,28 @@ QualType ASTNodeImporter::VisitAutoType(const AutoType *T) { /*IsDependent*/false); } +QualType ASTNodeImporter::VisitInjectedClassNameType( + const InjectedClassNameType *T) { + CXXRecordDecl *D = cast_or_null<CXXRecordDecl>(Importer.Import(T->getDecl())); + if (!D) + return QualType(); + + QualType InjType = Importer.Import(T->getInjectedSpecializationType()); + if (InjType.isNull()) + return QualType(); + + // FIXME: ASTContext::getInjectedClassNameType is not suitable for AST reading + // See comments in InjectedClassNameType definition for details + // return Importer.getToContext().getInjectedClassNameType(D, InjType); + enum { + TypeAlignmentInBits = 4, + TypeAlignment = 1 << TypeAlignmentInBits + }; + + return QualType(new (Importer.getToContext(), TypeAlignment) + InjectedClassNameType(D, InjType), 0); +} + QualType ASTNodeImporter::VisitRecordType(const RecordType *T) { RecordDecl *ToDecl = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl())); @@ -1797,6 +1894,18 @@ QualType ASTNodeImporter::VisitAttributedType(const AttributedType *T) { ToModifiedType, ToEquivalentType); } + +QualType ASTNodeImporter::VisitTemplateTypeParmType( + const TemplateTypeParmType *T) { + TemplateTypeParmDecl *ParmDecl = + cast_or_null<TemplateTypeParmDecl>(Importer.Import(T->getDecl())); + if (!ParmDecl && T->getDecl()) + return QualType(); + + return Importer.getToContext().getTemplateTypeParmType( + T->getDepth(), T->getIndex(), T->isParameterPack(), ParmDecl); +} + QualType ASTNodeImporter::VisitTemplateSpecializationType( const TemplateSpecializationType *T) { TemplateName ToTemplate = Importer.Import(T->getTemplateName()); @@ -1816,8 +1925,7 @@ QualType ASTNodeImporter::VisitTemplateSpecializationType( return QualType(); } return Importer.getToContext().getTemplateSpecializationType(ToTemplate, - ToTemplateArgs.data(), - ToTemplateArgs.size(), + ToTemplateArgs, ToCanonType); } @@ -2023,6 +2131,9 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To, ToData.HasInClassInitializer = FromData.HasInClassInitializer; ToData.HasUninitializedReferenceMember = FromData.HasUninitializedReferenceMember; + ToData.HasUninitializedFields = FromData.HasUninitializedFields; + ToData.HasInheritedConstructor = FromData.HasInheritedConstructor; + ToData.HasInheritedAssignment = FromData.HasInheritedAssignment; ToData.NeedOverloadResolutionForMoveConstructor = FromData.NeedOverloadResolutionForMoveConstructor; ToData.NeedOverloadResolutionForMoveAssignment @@ -2038,6 +2149,8 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To, ToData.HasIrrelevantDestructor = FromData.HasIrrelevantDestructor; ToData.HasConstexprNonCopyMoveConstructor = FromData.HasConstexprNonCopyMoveConstructor; + ToData.HasDefaultedDefaultConstructor + = FromData.HasDefaultedDefaultConstructor; ToData.DefaultedDefaultConstructorIsConstexpr = FromData.DefaultedDefaultConstructorIsConstexpr; ToData.HasConstexprDefaultConstructor @@ -2316,6 +2429,31 @@ Decl *ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) { return ToD; } +Decl *ASTNodeImporter::VisitAccessSpecDecl(AccessSpecDecl *D) { + + SourceLocation Loc = Importer.Import(D->getLocation()); + SourceLocation ColonLoc = Importer.Import(D->getColonLoc()); + + // Import the context of this declaration. + DeclContext *DC = Importer.ImportContext(D->getDeclContext()); + if (!DC) + return nullptr; + + AccessSpecDecl *accessSpecDecl + = AccessSpecDecl::Create(Importer.getToContext(), D->getAccess(), + DC, Loc, ColonLoc); + + if (!accessSpecDecl) + return nullptr; + + // Lexical DeclContext and Semantic DeclContext + // is always the same for the accessSpec. + accessSpecDecl->setLexicalDeclContext(DC); + DC->addDeclInternal(accessSpecDecl); + + return accessSpecDecl; +} + Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) { // Import the major distinguishing characteristics of this namespace. DeclContext *DC, *LexicalDC; @@ -2464,6 +2602,39 @@ Decl *ASTNodeImporter::VisitTypeAliasDecl(TypeAliasDecl *D) { return VisitTypedefNameDecl(D, /*IsAlias=*/true); } +Decl *ASTNodeImporter::VisitLabelDecl(LabelDecl *D) { + // Import the major distinguishing characteristics of this label. + DeclContext *DC, *LexicalDC; + DeclarationName Name; + SourceLocation Loc; + NamedDecl *ToD; + if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) + return nullptr; + if (ToD) + return ToD; + + assert(LexicalDC->isFunctionOrMethod()); + + LabelDecl *ToLabel = D->isGnuLocal() + ? LabelDecl::Create(Importer.getToContext(), + DC, Importer.Import(D->getLocation()), + Name.getAsIdentifierInfo(), + Importer.Import(D->getLocStart())) + : LabelDecl::Create(Importer.getToContext(), + DC, Importer.Import(D->getLocation()), + Name.getAsIdentifierInfo()); + Importer.Imported(D, ToLabel); + + LabelStmt *Label = cast_or_null<LabelStmt>(Importer.Import(D->getStmt())); + if (!Label) + return nullptr; + + ToLabel->setStmt(Label); + ToLabel->setLexicalDeclContext(LexicalDC); + LexicalDC->addDeclInternal(ToLabel); + return ToLabel; +} + Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) { // Import the major distinguishing characteristics of this enum. DeclContext *DC, *LexicalDC; @@ -2594,9 +2765,9 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) { // If both anonymous structs/unions are in a record context, make sure // they occur in the same location in the context records. if (Optional<unsigned> Index1 - = findAnonymousStructOrUnionIndex(D)) { + = findUntaggedStructOrUnionIndex(D)) { if (Optional<unsigned> Index2 = - findAnonymousStructOrUnionIndex(FoundRecord)) { + findUntaggedStructOrUnionIndex(FoundRecord)) { if (*Index1 != *Index2) continue; } @@ -2654,11 +2825,35 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) { RecordDecl *D2 = AdoptDecl; SourceLocation StartLoc = Importer.Import(D->getLocStart()); if (!D2) { - if (isa<CXXRecordDecl>(D)) { - CXXRecordDecl *D2CXX = CXXRecordDecl::Create(Importer.getToContext(), - D->getTagKind(), - DC, StartLoc, Loc, - Name.getAsIdentifierInfo()); + CXXRecordDecl *D2CXX = nullptr; + if (CXXRecordDecl *DCXX = llvm::dyn_cast<CXXRecordDecl>(D)) { + if (DCXX->isLambda()) { + TypeSourceInfo *TInfo = Importer.Import(DCXX->getLambdaTypeInfo()); + D2CXX = CXXRecordDecl::CreateLambda(Importer.getToContext(), + DC, TInfo, Loc, + DCXX->isDependentLambda(), + DCXX->isGenericLambda(), + DCXX->getLambdaCaptureDefault()); + Decl *CDecl = Importer.Import(DCXX->getLambdaContextDecl()); + if (DCXX->getLambdaContextDecl() && !CDecl) + return nullptr; + D2CXX->setLambdaMangling(DCXX->getLambdaManglingNumber(), CDecl); + } else if (DCXX->isInjectedClassName()) { + // We have to be careful to do a similar dance to the one in + // Sema::ActOnStartCXXMemberDeclarations + CXXRecordDecl *const PrevDecl = nullptr; + const bool DelayTypeCreation = true; + D2CXX = CXXRecordDecl::Create( + Importer.getToContext(), D->getTagKind(), DC, StartLoc, Loc, + Name.getAsIdentifierInfo(), PrevDecl, DelayTypeCreation); + Importer.getToContext().getTypeDeclType( + D2CXX, llvm::dyn_cast<CXXRecordDecl>(DC)); + } else { + D2CXX = CXXRecordDecl::Create(Importer.getToContext(), + D->getTagKind(), + DC, StartLoc, Loc, + Name.getAsIdentifierInfo()); + } D2 = D2CXX; D2->setAccess(D->getAccess()); } else { @@ -2830,7 +3025,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { // Import the function parameters. SmallVector<ParmVarDecl *, 8> Parameters; - for (auto P : D->params()) { + for (auto P : D->parameters()) { ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(P)); if (!ToP) return nullptr; @@ -2851,6 +3046,22 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { D->isInlineSpecified(), D->isImplicit(), D->isConstexpr()); + if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) { + SmallVector<CXXCtorInitializer *, 4> CtorInitializers; + for (CXXCtorInitializer *I : FromConstructor->inits()) { + CXXCtorInitializer *ToI = + cast_or_null<CXXCtorInitializer>(Importer.Import(I)); + if (!ToI && I) + return nullptr; + CtorInitializers.push_back(ToI); + } + CXXCtorInitializer **Memory = + new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers]; + std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory); + CXXConstructorDecl *ToCtor = llvm::cast<CXXConstructorDecl>(ToFunction); + ToCtor->setCtorInitializers(Memory); + ToCtor->setNumCtorInitializers(NumInitializers); + } } else if (isa<CXXDestructorDecl>(D)) { ToFunction = CXXDestructorDecl::Create(Importer.getToContext(), cast<CXXRecordDecl>(DC), @@ -3009,8 +3220,13 @@ Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) { D->getInClassInitStyle()); ToField->setAccess(D->getAccess()); ToField->setLexicalDeclContext(LexicalDC); - if (ToField->hasInClassInitializer()) - ToField->setInClassInitializer(D->getInClassInitializer()); + if (Expr *FromInitializer = D->getInClassInitializer()) { + Expr *ToInitializer = Importer.Import(FromInitializer); + if (ToInitializer) + ToField->setInClassInitializer(ToInitializer); + else + return nullptr; + } ToField->setImplicit(D->isImplicit()); Importer.Imported(D, ToField); LexicalDC->addDeclInternal(ToField); @@ -3075,7 +3291,7 @@ Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) { IndirectFieldDecl *ToIndirectField = IndirectFieldDecl::Create( Importer.getToContext(), DC, Loc, Name.getAsIdentifierInfo(), T, - NamedChain, D->getChainingSize()); + {NamedChain, D->getChainingSize()}); for (const auto *Attr : D->attrs()) ToIndirectField->addAttr(Attr->clone(Importer.getToContext())); @@ -3418,7 +3634,7 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) { // Import the parameters SmallVector<ParmVarDecl *, 5> ToParams; - for (auto *FromP : D->params()) { + for (auto *FromP : D->parameters()) { ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(FromP)); if (!ToP) return nullptr; @@ -4061,7 +4277,8 @@ Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) { } ObjCPropertyImplDecl *ToImpl - = InImpl->FindPropertyImplDecl(Property->getIdentifier()); + = InImpl->FindPropertyImplDecl(Property->getIdentifier(), + Property->getQueryKind()); if (!ToImpl) { ToImpl = ObjCPropertyImplDecl::Create(Importer.getToContext(), DC, Importer.Import(D->getLocStart()), @@ -4246,16 +4463,16 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) { CXXRecordDecl *DTemplated = D->getTemplatedDecl(); // Create the declaration that is being templated. - SourceLocation StartLoc = Importer.Import(DTemplated->getLocStart()); - SourceLocation IdLoc = Importer.Import(DTemplated->getLocation()); - CXXRecordDecl *D2Templated = CXXRecordDecl::Create(Importer.getToContext(), - DTemplated->getTagKind(), - DC, StartLoc, IdLoc, - Name.getAsIdentifierInfo()); - D2Templated->setAccess(DTemplated->getAccess()); - D2Templated->setQualifierInfo(Importer.Import(DTemplated->getQualifierLoc())); - D2Templated->setLexicalDeclContext(LexicalDC); - + // Create the declaration that is being templated. + CXXRecordDecl *D2Templated = cast_or_null<CXXRecordDecl>( + Importer.Import(DTemplated)); + if (!D2Templated) + return nullptr; + + // Resolve possible cyclic import. + if (Decl *AlreadyImported = Importer.GetAlreadyImportedOrNull(D)) + return AlreadyImported; + // Create the class template declaration itself. TemplateParameterList *TemplateParams = ImportTemplateParameterList(D->getTemplateParameters()); @@ -4351,8 +4568,7 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl( D->getTagKind(), DC, StartLoc, IdLoc, ClassTemplate, - TemplateArgs.data(), - TemplateArgs.size(), + TemplateArgs, /*PrevDecl=*/nullptr); D2->setSpecializationKind(D->getSpecializationKind()); @@ -4553,7 +4769,7 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl( // Create a new specialization. D2 = VarTemplateSpecializationDecl::Create( Importer.getToContext(), DC, StartLoc, IdLoc, VarTemplate, T, TInfo, - D->getStorageClass(), TemplateArgs.data(), TemplateArgs.size()); + D->getStorageClass(), TemplateArgs); D2->setSpecializationKind(D->getSpecializationKind()); D2->setTemplateArgsInfo(D->getTemplateArgsInfo()); @@ -4599,7 +4815,78 @@ DeclGroupRef ASTNodeImporter::ImportDeclGroup(DeclGroupRef DG) { << S->getStmtClassName(); return nullptr; } - + + +Stmt *ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) { + SmallVector<IdentifierInfo *, 4> Names; + for (unsigned I = 0, E = S->getNumOutputs(); I != E; I++) { + IdentifierInfo *ToII = Importer.Import(S->getOutputIdentifier(I)); + if (!ToII) + return nullptr; + Names.push_back(ToII); + } + for (unsigned I = 0, E = S->getNumInputs(); I != E; I++) { + IdentifierInfo *ToII = Importer.Import(S->getInputIdentifier(I)); + if (!ToII) + return nullptr; + Names.push_back(ToII); + } + + SmallVector<StringLiteral *, 4> Clobbers; + for (unsigned I = 0, E = S->getNumClobbers(); I != E; I++) { + StringLiteral *Clobber = cast_or_null<StringLiteral>( + Importer.Import(S->getClobberStringLiteral(I))); + if (!Clobber) + return nullptr; + Clobbers.push_back(Clobber); + } + + SmallVector<StringLiteral *, 4> Constraints; + for (unsigned I = 0, E = S->getNumOutputs(); I != E; I++) { + StringLiteral *Output = cast_or_null<StringLiteral>( + Importer.Import(S->getOutputConstraintLiteral(I))); + if (!Output) + return nullptr; + Constraints.push_back(Output); + } + + for (unsigned I = 0, E = S->getNumInputs(); I != E; I++) { + StringLiteral *Input = cast_or_null<StringLiteral>( + Importer.Import(S->getInputConstraintLiteral(I))); + if (!Input) + return nullptr; + Constraints.push_back(Input); + } + + SmallVector<Expr *, 4> Exprs(S->getNumOutputs() + S->getNumInputs()); + if (ImportArrayChecked(S->begin_outputs(), S->end_outputs(), Exprs.begin())) + return nullptr; + + if (ImportArrayChecked(S->begin_inputs(), S->end_inputs(), + Exprs.begin() + S->getNumOutputs())) + return nullptr; + + StringLiteral *AsmStr = cast_or_null<StringLiteral>( + Importer.Import(S->getAsmString())); + if (!AsmStr) + return nullptr; + + return new (Importer.getToContext()) GCCAsmStmt( + Importer.getToContext(), + Importer.Import(S->getAsmLoc()), + S->isSimple(), + S->isVolatile(), + S->getNumOutputs(), + S->getNumInputs(), + Names.data(), + Constraints.data(), + Exprs.data(), + AsmStr, + S->getNumClobbers(), + Clobbers.data(), + Importer.Import(S->getRParenLoc())); +} + Stmt *ASTNodeImporter::VisitDeclStmt(DeclStmt *S) { DeclGroupRef ToDG = ImportDeclGroup(S->getDeclGroup()); for (Decl *ToD : ToDG) { @@ -4618,16 +4905,11 @@ Stmt *ASTNodeImporter::VisitNullStmt(NullStmt *S) { } Stmt *ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) { - SmallVector<Stmt *, 4> ToStmts(S->size()); - auto &_Importer = this->Importer; - std::transform(S->body_begin(), S->body_end(), ToStmts.begin(), - [&_Importer](Stmt *CS) -> Stmt * { - return _Importer.Import(CS); - }); - for (Stmt *ToS : ToStmts) { - if (!ToS) - return nullptr; - } + llvm::SmallVector<Stmt *, 8> ToStmts(S->size()); + + if (ImportArrayChecked(S->body_begin(), S->body_end(), ToStmts.begin())) + return nullptr; + SourceLocation ToLBraceLoc = Importer.Import(S->getLBracLoc()); SourceLocation ToRBraceLoc = Importer.Import(S->getRBracLoc()); return new (Importer.getToContext()) CompoundStmt(Importer.getToContext(), @@ -4695,6 +4977,9 @@ Stmt *ASTNodeImporter::VisitAttributedStmt(AttributedStmt *S) { Stmt *ASTNodeImporter::VisitIfStmt(IfStmt *S) { SourceLocation ToIfLoc = Importer.Import(S->getIfLoc()); + Stmt *ToInit = Importer.Import(S->getInit()); + if (!ToInit && S->getInit()) + return nullptr; VarDecl *ToConditionVariable = nullptr; if (VarDecl *FromConditionVariable = S->getConditionVariable()) { ToConditionVariable = @@ -4713,12 +4998,17 @@ Stmt *ASTNodeImporter::VisitIfStmt(IfStmt *S) { if (!ToElseStmt && S->getElse()) return nullptr; return new (Importer.getToContext()) IfStmt(Importer.getToContext(), - ToIfLoc, ToConditionVariable, + ToIfLoc, S->isConstexpr(), + ToInit, + ToConditionVariable, ToCondition, ToThenStmt, ToElseLoc, ToElseStmt); } Stmt *ASTNodeImporter::VisitSwitchStmt(SwitchStmt *S) { + Stmt *ToInit = Importer.Import(S->getInit()); + if (!ToInit && S->getInit()) + return nullptr; VarDecl *ToConditionVariable = nullptr; if (VarDecl *FromConditionVariable = S->getConditionVariable()) { ToConditionVariable = @@ -4730,8 +5020,8 @@ Stmt *ASTNodeImporter::VisitSwitchStmt(SwitchStmt *S) { if (!ToCondition && S->getCond()) return nullptr; SwitchStmt *ToStmt = new (Importer.getToContext()) SwitchStmt( - Importer.getToContext(), ToConditionVariable, - ToCondition); + Importer.getToContext(), ToInit, + ToConditionVariable, ToCondition); Stmt *ToBody = Importer.Import(S->getBody()); if (!ToBody && S->getBody()) return nullptr; @@ -4905,9 +5195,13 @@ Stmt *ASTNodeImporter::VisitCXXForRangeStmt(CXXForRangeStmt *S) { dyn_cast_or_null<DeclStmt>(Importer.Import(S->getRangeStmt())); if (!ToRange && S->getRangeStmt()) return nullptr; - DeclStmt *ToBeginEnd = - dyn_cast_or_null<DeclStmt>(Importer.Import(S->getBeginEndStmt())); - if (!ToBeginEnd && S->getBeginEndStmt()) + DeclStmt *ToBegin = + dyn_cast_or_null<DeclStmt>(Importer.Import(S->getBeginStmt())); + if (!ToBegin && S->getBeginStmt()) + return nullptr; + DeclStmt *ToEnd = + dyn_cast_or_null<DeclStmt>(Importer.Import(S->getEndStmt())); + if (!ToEnd && S->getEndStmt()) return nullptr; Expr *ToCond = Importer.Import(S->getCond()); if (!ToCond && S->getCond()) @@ -4926,7 +5220,7 @@ Stmt *ASTNodeImporter::VisitCXXForRangeStmt(CXXForRangeStmt *S) { SourceLocation ToCoawaitLoc = Importer.Import(S->getCoawaitLoc()); SourceLocation ToColonLoc = Importer.Import(S->getColonLoc()); SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc()); - return new (Importer.getToContext()) CXXForRangeStmt(ToRange, ToBeginEnd, + return new (Importer.getToContext()) CXXForRangeStmt(ToRange, ToBegin, ToEnd, ToCond, ToInc, ToLoopVar, ToBody, ToForLoc, ToCoawaitLoc, @@ -5042,6 +5336,48 @@ Expr *ASTNodeImporter::VisitExpr(Expr *E) { return nullptr; } +Expr *ASTNodeImporter::VisitVAArgExpr(VAArgExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + Expr *SubExpr = Importer.Import(E->getSubExpr()); + if (!SubExpr && E->getSubExpr()) + return nullptr; + + TypeSourceInfo *TInfo = Importer.Import(E->getWrittenTypeInfo()); + if (!TInfo) + return nullptr; + + return new (Importer.getToContext()) VAArgExpr( + Importer.Import(E->getBuiltinLoc()), SubExpr, TInfo, + Importer.Import(E->getRParenLoc()), T, E->isMicrosoftABI()); +} + + +Expr *ASTNodeImporter::VisitGNUNullExpr(GNUNullExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + return new (Importer.getToContext()) GNUNullExpr( + T, Importer.Import(E->getExprLoc())); +} + +Expr *ASTNodeImporter::VisitPredefinedExpr(PredefinedExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + StringLiteral *SL = cast_or_null<StringLiteral>( + Importer.Import(E->getFunctionName())); + if (!SL && E->getFunctionName()) + return nullptr; + + return new (Importer.getToContext()) PredefinedExpr( + Importer.Import(E->getExprLoc()), T, E->getIdentType(), SL); +} + Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) { ValueDecl *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl())); if (!ToD) @@ -5072,6 +5408,74 @@ Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) { return DRE; } +Expr *ASTNodeImporter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return NULL; + + return new (Importer.getToContext()) ImplicitValueInitExpr(T); +} + +ASTNodeImporter::Designator +ASTNodeImporter::ImportDesignator(const Designator &D) { + if (D.isFieldDesignator()) { + IdentifierInfo *ToFieldName = Importer.Import(D.getFieldName()); + // Caller checks for import error + return Designator(ToFieldName, Importer.Import(D.getDotLoc()), + Importer.Import(D.getFieldLoc())); + } + if (D.isArrayDesignator()) + return Designator(D.getFirstExprIndex(), + Importer.Import(D.getLBracketLoc()), + Importer.Import(D.getRBracketLoc())); + + assert(D.isArrayRangeDesignator()); + return Designator(D.getFirstExprIndex(), + Importer.Import(D.getLBracketLoc()), + Importer.Import(D.getEllipsisLoc()), + Importer.Import(D.getRBracketLoc())); +} + + +Expr *ASTNodeImporter::VisitDesignatedInitExpr(DesignatedInitExpr *DIE) { + Expr *Init = cast_or_null<Expr>(Importer.Import(DIE->getInit())); + if (!Init) + return nullptr; + + SmallVector<Expr *, 4> IndexExprs(DIE->getNumSubExprs() - 1); + // List elements from the second, the first is Init itself + for (unsigned I = 1, E = DIE->getNumSubExprs(); I < E; I++) { + if (Expr *Arg = cast_or_null<Expr>(Importer.Import(DIE->getSubExpr(I)))) + IndexExprs[I - 1] = Arg; + else + return nullptr; + } + + SmallVector<Designator, 4> Designators(DIE->size()); + llvm::transform(DIE->designators(), Designators.begin(), + [this](const Designator &D) -> Designator { + return ImportDesignator(D); + }); + + for (const Designator &D : DIE->designators()) + if (D.isFieldDesignator() && !D.getFieldName()) + return nullptr; + + return DesignatedInitExpr::Create( + Importer.getToContext(), Designators, + IndexExprs, Importer.Import(DIE->getEqualOrColonLoc()), + DIE->usesGNUSyntax(), Init); +} + +Expr *ASTNodeImporter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + return new (Importer.getToContext()) + CXXNullPtrLiteralExpr(T, Importer.Import(E->getLocation())); +} + Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) @@ -5082,6 +5486,16 @@ Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) { Importer.Import(E->getLocation())); } +Expr *ASTNodeImporter::VisitFloatingLiteral(FloatingLiteral *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + return FloatingLiteral::Create(Importer.getToContext(), + E->getValue(), E->isExact(), T, + Importer.Import(E->getLocation())); +} + Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) @@ -5092,6 +5506,67 @@ Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) { Importer.Import(E->getLocation())); } +Expr *ASTNodeImporter::VisitStringLiteral(StringLiteral *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + SmallVector<SourceLocation, 4> Locations(E->getNumConcatenated()); + ImportArray(E->tokloc_begin(), E->tokloc_end(), Locations.begin()); + + return StringLiteral::Create(Importer.getToContext(), E->getBytes(), + E->getKind(), E->isPascal(), T, + Locations.data(), Locations.size()); +} + +Expr *ASTNodeImporter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + TypeSourceInfo *TInfo = Importer.Import(E->getTypeSourceInfo()); + if (!TInfo) + return nullptr; + + Expr *Init = Importer.Import(E->getInitializer()); + if (!Init) + return nullptr; + + return new (Importer.getToContext()) CompoundLiteralExpr( + Importer.Import(E->getLParenLoc()), TInfo, T, E->getValueKind(), + Init, E->isFileScope()); +} + +Expr *ASTNodeImporter::VisitAtomicExpr(AtomicExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + SmallVector<Expr *, 6> Exprs(E->getNumSubExprs()); + if (ImportArrayChecked( + E->getSubExprs(), E->getSubExprs() + E->getNumSubExprs(), + Exprs.begin())) + return nullptr; + + return new (Importer.getToContext()) AtomicExpr( + Importer.Import(E->getBuiltinLoc()), Exprs, T, E->getOp(), + Importer.Import(E->getRParenLoc())); +} + +Expr *ASTNodeImporter::VisitAddrLabelExpr(AddrLabelExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + LabelDecl *ToLabel = cast_or_null<LabelDecl>(Importer.Import(E->getLabel())); + if (!ToLabel) + return nullptr; + + return new (Importer.getToContext()) AddrLabelExpr( + Importer.Import(E->getAmpAmpLoc()), Importer.Import(E->getLabelLoc()), + ToLabel, T); +} + Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) { Expr *SubExpr = Importer.Import(E->getSubExpr()); if (!SubExpr) @@ -5103,6 +5578,31 @@ Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) { SubExpr); } +Expr *ASTNodeImporter::VisitParenListExpr(ParenListExpr *E) { + SmallVector<Expr *, 4> Exprs(E->getNumExprs()); + if (ImportArrayChecked( + E->getExprs(), E->getExprs() + E->getNumExprs(), Exprs.begin())) + return nullptr; + + return new (Importer.getToContext()) ParenListExpr( + Importer.getToContext(), Importer.Import(E->getLParenLoc()), + Exprs, Importer.Import(E->getLParenLoc())); +} + +Expr *ASTNodeImporter::VisitStmtExpr(StmtExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + CompoundStmt *ToSubStmt = cast_or_null<CompoundStmt>( + Importer.Import(E->getSubStmt())); + if (!ToSubStmt && E->getSubStmt()) + return nullptr; + + return new (Importer.getToContext()) StmtExpr(ToSubStmt, T, + Importer.Import(E->getLParenLoc()), Importer.Import(E->getRParenLoc())); +} + Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) @@ -5163,6 +5663,76 @@ Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) { E->isFPContractable()); } +Expr *ASTNodeImporter::VisitConditionalOperator(ConditionalOperator *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + Expr *ToLHS = Importer.Import(E->getLHS()); + if (!ToLHS) + return nullptr; + + Expr *ToRHS = Importer.Import(E->getRHS()); + if (!ToRHS) + return nullptr; + + Expr *ToCond = Importer.Import(E->getCond()); + if (!ToCond) + return nullptr; + + return new (Importer.getToContext()) ConditionalOperator( + ToCond, Importer.Import(E->getQuestionLoc()), + ToLHS, Importer.Import(E->getColonLoc()), + ToRHS, T, E->getValueKind(), E->getObjectKind()); +} + +Expr *ASTNodeImporter::VisitBinaryConditionalOperator( + BinaryConditionalOperator *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + Expr *Common = Importer.Import(E->getCommon()); + if (!Common) + return nullptr; + + Expr *Cond = Importer.Import(E->getCond()); + if (!Cond) + return nullptr; + + OpaqueValueExpr *OpaqueValue = cast_or_null<OpaqueValueExpr>( + Importer.Import(E->getOpaqueValue())); + if (!OpaqueValue) + return nullptr; + + Expr *TrueExpr = Importer.Import(E->getTrueExpr()); + if (!TrueExpr) + return nullptr; + + Expr *FalseExpr = Importer.Import(E->getFalseExpr()); + if (!FalseExpr) + return nullptr; + + return new (Importer.getToContext()) BinaryConditionalOperator( + Common, OpaqueValue, Cond, TrueExpr, FalseExpr, + Importer.Import(E->getQuestionLoc()), Importer.Import(E->getColonLoc()), + T, E->getValueKind(), E->getObjectKind()); +} + +Expr *ASTNodeImporter::VisitOpaqueValueExpr(OpaqueValueExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + Expr *SourceExpr = Importer.Import(E->getSourceExpr()); + if (!SourceExpr && E->getSourceExpr()) + return nullptr; + + return new (Importer.getToContext()) OpaqueValueExpr( + Importer.Import(E->getExprLoc()), T, E->getValueKind(), + E->getObjectKind(), SourceExpr); +} + Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) @@ -5247,21 +5817,14 @@ Expr *ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) { return nullptr; CXXConstructorDecl *ToCCD = - dyn_cast<CXXConstructorDecl>(Importer.Import(E->getConstructor())); - if (!ToCCD && E->getConstructor()) + dyn_cast_or_null<CXXConstructorDecl>(Importer.Import(E->getConstructor())); + if (!ToCCD) return nullptr; - size_t NumArgs = E->getNumArgs(); - SmallVector<Expr *, 1> ToArgs(NumArgs); - ASTImporter &_Importer = Importer; - std::transform(E->arg_begin(), E->arg_end(), ToArgs.begin(), - [&_Importer](Expr *AE) -> Expr * { - return _Importer.Import(AE); - }); - for (Expr *ToA : ToArgs) { - if (!ToA) - return nullptr; - } + SmallVector<Expr *, 6> ToArgs(E->getNumArgs()); + if (ImportArrayChecked(E->getArgs(), E->getArgs() + E->getNumArgs(), + ToArgs.begin())) + return nullptr; return CXXConstructExpr::Create(Importer.getToContext(), T, Importer.Import(E->getLocation()), @@ -5274,6 +5837,44 @@ Expr *ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) { Importer.Import(E->getParenOrBraceRange())); } +Expr *ASTNodeImporter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + Expr *ToFn = Importer.Import(E->getCallee()); + if (!ToFn) + return nullptr; + + SmallVector<Expr *, 4> ToArgs(E->getNumArgs()); + + if (ImportArrayChecked(E->arg_begin(), E->arg_end(), ToArgs.begin())) + return nullptr; + + return new (Importer.getToContext()) CXXMemberCallExpr( + Importer.getToContext(), ToFn, ToArgs, T, E->getValueKind(), + Importer.Import(E->getRParenLoc())); +} + +Expr *ASTNodeImporter::VisitCXXThisExpr(CXXThisExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + return new (Importer.getToContext()) + CXXThisExpr(Importer.Import(E->getLocation()), T, E->isImplicit()); +} + +Expr *ASTNodeImporter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + return new (Importer.getToContext()) + CXXBoolLiteralExpr(E->getValue(), T, Importer.Import(E->getLocation())); +} + + Expr *ASTNodeImporter::VisitMemberExpr(MemberExpr *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) @@ -5342,6 +5943,95 @@ Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) { Importer.Import(E->getRParenLoc())); } +Expr *ASTNodeImporter::VisitInitListExpr(InitListExpr *ILE) { + QualType T = Importer.Import(ILE->getType()); + if (T.isNull()) + return nullptr; + + llvm::SmallVector<Expr *, 4> Exprs(ILE->getNumInits()); + if (ImportArrayChecked( + ILE->getInits(), ILE->getInits() + ILE->getNumInits(), Exprs.begin())) + return nullptr; + + ASTContext &ToCtx = Importer.getToContext(); + InitListExpr *To = new (ToCtx) InitListExpr( + ToCtx, Importer.Import(ILE->getLBraceLoc()), + Exprs, Importer.Import(ILE->getLBraceLoc())); + To->setType(T); + + if (ILE->hasArrayFiller()) { + Expr *Filler = Importer.Import(ILE->getArrayFiller()); + if (!Filler) + return nullptr; + To->setArrayFiller(Filler); + } + + if (FieldDecl *FromFD = ILE->getInitializedFieldInUnion()) { + FieldDecl *ToFD = cast_or_null<FieldDecl>(Importer.Import(FromFD)); + if (!ToFD) + return nullptr; + To->setInitializedFieldInUnion(ToFD); + } + + if (InitListExpr *SyntForm = ILE->getSyntacticForm()) { + InitListExpr *ToSyntForm = cast_or_null<InitListExpr>( + Importer.Import(SyntForm)); + if (!ToSyntForm) + return nullptr; + To->setSyntacticForm(ToSyntForm); + } + + To->sawArrayRangeDesignator(ILE->hadArrayRangeDesignator()); + To->setValueDependent(ILE->isValueDependent()); + To->setInstantiationDependent(ILE->isInstantiationDependent()); + + return To; +} + +Expr *ASTNodeImporter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) { + FieldDecl *ToField = llvm::dyn_cast_or_null<FieldDecl>( + Importer.Import(DIE->getField())); + if (!ToField && DIE->getField()) + return nullptr; + + return CXXDefaultInitExpr::Create( + Importer.getToContext(), Importer.Import(DIE->getLocStart()), ToField); +} + +Expr *ASTNodeImporter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) { + QualType ToType = Importer.Import(E->getType()); + if (ToType.isNull() && !E->getType().isNull()) + return nullptr; + ExprValueKind VK = E->getValueKind(); + CastKind CK = E->getCastKind(); + Expr *ToOp = Importer.Import(E->getSubExpr()); + if (!ToOp && E->getSubExpr()) + return nullptr; + CXXCastPath BasePath; + if (ImportCastPath(E, BasePath)) + return nullptr; + TypeSourceInfo *ToWritten = Importer.Import(E->getTypeInfoAsWritten()); + SourceLocation ToOperatorLoc = Importer.Import(E->getOperatorLoc()); + SourceLocation ToRParenLoc = Importer.Import(E->getRParenLoc()); + SourceRange ToAngleBrackets = Importer.Import(E->getAngleBrackets()); + + if (isa<CXXStaticCastExpr>(E)) { + return CXXStaticCastExpr::Create( + Importer.getToContext(), ToType, VK, CK, ToOp, &BasePath, + ToWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets); + } else if (isa<CXXDynamicCastExpr>(E)) { + return CXXDynamicCastExpr::Create( + Importer.getToContext(), ToType, VK, CK, ToOp, &BasePath, + ToWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets); + } else if (isa<CXXReinterpretCastExpr>(E)) { + return CXXReinterpretCastExpr::Create( + Importer.getToContext(), ToType, VK, CK, ToOp, &BasePath, + ToWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets); + } else { + return nullptr; + } +} + ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager, ASTContext &FromContext, FileManager &FromFileManager, bool MinimalImport) @@ -5747,6 +6437,72 @@ FileID ASTImporter::Import(FileID FromID) { return ToID; } +CXXCtorInitializer *ASTImporter::Import(CXXCtorInitializer *From) { + Expr *ToExpr = Import(From->getInit()); + if (!ToExpr && From->getInit()) + return nullptr; + + if (From->isBaseInitializer()) { + TypeSourceInfo *ToTInfo = Import(From->getTypeSourceInfo()); + if (!ToTInfo && From->getTypeSourceInfo()) + return nullptr; + + return new (ToContext) CXXCtorInitializer( + ToContext, ToTInfo, From->isBaseVirtual(), Import(From->getLParenLoc()), + ToExpr, Import(From->getRParenLoc()), + From->isPackExpansion() ? Import(From->getEllipsisLoc()) + : SourceLocation()); + } else if (From->isMemberInitializer()) { + FieldDecl *ToField = + llvm::cast_or_null<FieldDecl>(Import(From->getMember())); + if (!ToField && From->getMember()) + return nullptr; + + return new (ToContext) CXXCtorInitializer( + ToContext, ToField, Import(From->getMemberLocation()), + Import(From->getLParenLoc()), ToExpr, Import(From->getRParenLoc())); + } else if (From->isIndirectMemberInitializer()) { + IndirectFieldDecl *ToIField = llvm::cast_or_null<IndirectFieldDecl>( + Import(From->getIndirectMember())); + if (!ToIField && From->getIndirectMember()) + return nullptr; + + return new (ToContext) CXXCtorInitializer( + ToContext, ToIField, Import(From->getMemberLocation()), + Import(From->getLParenLoc()), ToExpr, Import(From->getRParenLoc())); + } else if (From->isDelegatingInitializer()) { + TypeSourceInfo *ToTInfo = Import(From->getTypeSourceInfo()); + if (!ToTInfo && From->getTypeSourceInfo()) + return nullptr; + + return new (ToContext) + CXXCtorInitializer(ToContext, ToTInfo, Import(From->getLParenLoc()), + ToExpr, Import(From->getRParenLoc())); + } else if (unsigned NumArrayIndices = From->getNumArrayIndices()) { + FieldDecl *ToField = + llvm::cast_or_null<FieldDecl>(Import(From->getMember())); + if (!ToField && From->getMember()) + return nullptr; + + SmallVector<VarDecl *, 4> ToAIs(NumArrayIndices); + + for (unsigned AII = 0; AII < NumArrayIndices; ++AII) { + VarDecl *ToArrayIndex = + dyn_cast_or_null<VarDecl>(Import(From->getArrayIndex(AII))); + if (!ToArrayIndex && From->getArrayIndex(AII)) + return nullptr; + } + + return CXXCtorInitializer::Create( + ToContext, ToField, Import(From->getMemberLocation()), + Import(From->getLParenLoc()), ToExpr, Import(From->getRParenLoc()), + ToAIs.data(), NumArrayIndices); + } else { + return nullptr; + } +} + + void ASTImporter::ImportDefinition(Decl *From) { Decl *To = Import(From); if (!To) @@ -5851,7 +6607,12 @@ IdentifierInfo *ASTImporter::Import(const IdentifierInfo *FromId) { if (!FromId) return nullptr; - return &ToContext.Idents.get(FromId->getName()); + IdentifierInfo *ToId = &ToContext.Idents.get(FromId->getName()); + + if (!ToId->getBuiltinID() && FromId->getBuiltinID()) + ToId->setBuiltinID(FromId->getBuiltinID()); + + return ToId; } Selector ASTImporter::Import(Selector FromSel) { @@ -5910,6 +6671,16 @@ void ASTImporter::CompleteDecl (Decl *D) { } Decl *ASTImporter::Imported(Decl *From, Decl *To) { + if (From->hasAttrs()) { + for (Attr *FromAttr : From->getAttrs()) + To->addAttr(FromAttr->clone(To->getASTContext())); + } + if (From->isUsed()) { + To->setIsUsed(); + } + if (From->isImplicit()) { + To->setImplicit(); + } ImportedDecls[From] = To; return To; } diff --git a/contrib/llvm/tools/clang/lib/AST/ASTTypeTraits.cpp b/contrib/llvm/tools/clang/lib/AST/ASTTypeTraits.cpp index ec0671c..2336c98 100644 --- a/contrib/llvm/tools/clang/lib/AST/ASTTypeTraits.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ASTTypeTraits.cpp @@ -22,12 +22,12 @@ namespace ast_type_traits { const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = { { NKI_None, "<None>" }, - { NKI_None, "CXXCtorInitializer" }, { NKI_None, "TemplateArgument" }, - { NKI_None, "NestedNameSpecifier" }, { NKI_None, "NestedNameSpecifierLoc" }, { NKI_None, "QualType" }, { NKI_None, "TypeLoc" }, + { NKI_None, "CXXCtorInitializer" }, + { NKI_None, "NestedNameSpecifier" }, { NKI_None, "Decl" }, #define DECL(DERIVED, BASE) { NKI_##BASE, #DERIVED "Decl" }, #include "clang/AST/DeclNodes.inc" @@ -43,10 +43,6 @@ bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const { return isBaseOf(KindId, Other.KindId, Distance); } -bool ASTNodeKind::isSame(ASTNodeKind Other) const { - return KindId != NKI_None && KindId == Other.KindId; -} - bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance) { if (Base == NKI_None || Derived == NKI_None) return false; diff --git a/contrib/llvm/tools/clang/lib/AST/CXXInheritance.cpp b/contrib/llvm/tools/clang/lib/AST/CXXInheritance.cpp index 6785a0c..6a6ca76 100644 --- a/contrib/llvm/tools/clang/lib/AST/CXXInheritance.cpp +++ b/contrib/llvm/tools/clang/lib/AST/CXXInheritance.cpp @@ -405,6 +405,21 @@ bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier, return false; } +bool CXXRecordDecl::FindOMPReductionMember(const CXXBaseSpecifier *Specifier, + CXXBasePath &Path, + DeclarationName Name) { + RecordDecl *BaseRecord = + Specifier->getType()->castAs<RecordType>()->getDecl(); + + for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty(); + Path.Decls = Path.Decls.slice(1)) { + if (Path.Decls.front()->isInIdentifierNamespace(IDNS_OMPReduction)) + return true; + } + + return false; +} + bool CXXRecordDecl:: FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier, CXXBasePath &Path, diff --git a/contrib/llvm/tools/clang/lib/AST/Comment.cpp b/contrib/llvm/tools/clang/lib/AST/Comment.cpp index d05c5de..893bdc5 100644 --- a/contrib/llvm/tools/clang/lib/AST/Comment.cpp +++ b/contrib/llvm/tools/clang/lib/AST/Comment.cpp @@ -157,7 +157,7 @@ void DeclInfo::fill() { case Decl::CXXConversion: { const FunctionDecl *FD = cast<FunctionDecl>(CommentDecl); Kind = FunctionKind; - ParamVars = llvm::makeArrayRef(FD->param_begin(), FD->getNumParams()); + ParamVars = FD->parameters(); ReturnType = FD->getReturnType(); unsigned NumLists = FD->getNumTemplateParameterLists(); if (NumLists != 0) { @@ -177,7 +177,7 @@ void DeclInfo::fill() { case Decl::ObjCMethod: { const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(CommentDecl); Kind = FunctionKind; - ParamVars = llvm::makeArrayRef(MD->param_begin(), MD->param_size()); + ParamVars = MD->parameters(); ReturnType = MD->getReturnType(); IsObjCMethod = true; IsInstanceMethod = MD->isInstanceMethod(); @@ -189,7 +189,7 @@ void DeclInfo::fill() { Kind = FunctionKind; TemplateKind = Template; const FunctionDecl *FD = FTD->getTemplatedDecl(); - ParamVars = llvm::makeArrayRef(FD->param_begin(), FD->getNumParams()); + ParamVars = FD->parameters(); ReturnType = FD->getReturnType(); TemplateParameters = FTD->getTemplateParameters(); break; diff --git a/contrib/llvm/tools/clang/lib/AST/CommentLexer.cpp b/contrib/llvm/tools/clang/lib/AST/CommentLexer.cpp index 98b7e36..57bfef0 100644 --- a/contrib/llvm/tools/clang/lib/AST/CommentLexer.cpp +++ b/contrib/llvm/tools/clang/lib/AST/CommentLexer.cpp @@ -1,3 +1,12 @@ +//===--- CommentLexer.cpp -------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + #include "clang/AST/CommentLexer.h" #include "clang/AST/CommentCommandTraits.h" #include "clang/AST/CommentDiagnostic.h" @@ -44,7 +53,7 @@ namespace { #include "clang/AST/CommentHTMLTags.inc" #include "clang/AST/CommentHTMLNamedCharacterReferences.inc" -} // unnamed namespace +} // end anonymous namespace StringRef Lexer::resolveHTMLNamedCharacterReference(StringRef Name) const { // Fast path, first check a few most widely used named character references. @@ -266,7 +275,7 @@ const char *findCCommentEnd(const char *BufferPtr, const char *BufferEnd) { llvm_unreachable("buffer end hit before '*/' was seen"); } -} // unnamed namespace +} // end anonymous namespace void Lexer::formTokenWithChars(Token &Result, const char *TokEnd, tok::TokenKind Kind) { @@ -411,7 +420,6 @@ void Lexer::lexCommentText(Token &T) { setupAndLexHTMLEndTag(T); else formTextToken(T, TokenPtr); - return; } @@ -604,7 +612,6 @@ void Lexer::lexHTMLCharacterReference(Token &T) { } formTokenWithChars(T, TokenPtr, tok::text); T.setText(Resolved); - return; } void Lexer::setupAndLexHTMLStartTag(Token &T) { @@ -848,4 +855,3 @@ StringRef Lexer::getSpelling(const Token &Tok, } // end namespace comments } // end namespace clang - diff --git a/contrib/llvm/tools/clang/lib/AST/CommentSema.cpp b/contrib/llvm/tools/clang/lib/AST/CommentSema.cpp index 12823c3..f5f4f70 100644 --- a/contrib/llvm/tools/clang/lib/AST/CommentSema.cpp +++ b/contrib/llvm/tools/clang/lib/AST/CommentSema.cpp @@ -23,7 +23,7 @@ namespace comments { namespace { #include "clang/AST/CommentHTMLTagsProperties.inc" -} // unnamed namespace +} // end anonymous namespace Sema::Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr, DiagnosticsEngine &Diags, CommandTraits &Traits, @@ -353,8 +353,6 @@ void Sema::actOnTParamCommandParamNameArg(TParamCommandComment *Command, << CorrectedName << FixItHint::CreateReplacement(ArgRange, CorrectedName); } - - return; } void Sema::actOnTParamCommandFinish(TParamCommandComment *Command, @@ -1002,7 +1000,7 @@ void SimpleTypoCorrector::addDecl(const NamedDecl *ND) { BestIndex = CurrIndex; } } -} // unnamed namespace +} // end anonymous namespace unsigned Sema::correctTypoInParmVarReference( StringRef Typo, @@ -1040,7 +1038,7 @@ bool ResolveTParamReferenceHelper( } return false; } -} // unnamed namespace +} // end anonymous namespace bool Sema::resolveTParamReference( StringRef Name, @@ -1067,7 +1065,7 @@ void CorrectTypoInTParamReferenceHelper( Corrector); } } -} // unnamed namespace +} // end anonymous namespace StringRef Sema::correctTypoInTParamReference( StringRef Typo, @@ -1095,4 +1093,3 @@ Sema::getInlineCommandRenderKind(StringRef Name) const { } // end namespace comments } // end namespace clang - diff --git a/contrib/llvm/tools/clang/lib/AST/Decl.cpp b/contrib/llvm/tools/clang/lib/AST/Decl.cpp index 427ca5e..d1e8d25 100644 --- a/contrib/llvm/tools/clang/lib/AST/Decl.cpp +++ b/contrib/llvm/tools/clang/lib/AST/Decl.cpp @@ -18,6 +18,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" @@ -221,7 +222,7 @@ static Optional<Visibility> getVisibilityOf(const NamedDecl *D, // implies visibility(default). if (D->getASTContext().getTargetInfo().getTriple().isOSDarwin()) { for (const auto *A : D->specific_attrs<AvailabilityAttr>()) - if (A->getPlatform()->getName().equals("macosx")) + if (A->getPlatform()->getName().equals("macos")) return DefaultVisibility; } @@ -591,12 +592,14 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, if (Var->getStorageClass() == SC_Static) return LinkageInfo::internal(); - // - a non-volatile object or reference that is explicitly declared const - // or constexpr and neither explicitly declared extern nor previously - // declared to have external linkage; or (there is no equivalent in C99) + // - a non-inline, non-volatile object or reference that is explicitly + // declared const or constexpr and neither explicitly declared extern + // nor previously declared to have external linkage; or (there is no + // equivalent in C99) if (Context.getLangOpts().CPlusPlus && Var->getType().isConstQualified() && - !Var->getType().isVolatileQualified()) { + !Var->getType().isVolatileQualified() && + !Var->isInline()) { const VarDecl *PrevVar = Var->getPreviousDecl(); if (PrevVar) return getLVForDecl(PrevVar, computation); @@ -1421,16 +1424,13 @@ void NamedDecl::printQualifiedName(raw_ostream &OS, Ctx = Ctx->getParent(); } - for (ContextsTy::reverse_iterator I = Contexts.rbegin(), E = Contexts.rend(); - I != E; ++I) { - if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(*I)) { + for (const DeclContext *DC : reverse(Contexts)) { + if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) { OS << Spec->getName(); const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); - TemplateSpecializationType::PrintTemplateArgumentList(OS, - TemplateArgs.data(), - TemplateArgs.size(), - P); - } else if (const auto *ND = dyn_cast<NamespaceDecl>(*I)) { + TemplateSpecializationType::PrintTemplateArgumentList( + OS, TemplateArgs.asArray(), P); + } else if (const auto *ND = dyn_cast<NamespaceDecl>(DC)) { if (P.SuppressUnwrittenScope && (ND->isAnonymousNamespace() || ND->isInline())) continue; @@ -1440,12 +1440,12 @@ void NamedDecl::printQualifiedName(raw_ostream &OS, } else OS << *ND; - } else if (const auto *RD = dyn_cast<RecordDecl>(*I)) { + } else if (const auto *RD = dyn_cast<RecordDecl>(DC)) { if (!RD->getIdentifier()) OS << "(anonymous " << RD->getKindName() << ')'; else OS << *RD; - } else if (const auto *FD = dyn_cast<FunctionDecl>(*I)) { + } else if (const auto *FD = dyn_cast<FunctionDecl>(DC)) { const FunctionProtoType *FT = nullptr; if (FD->hasWrittenPrototype()) FT = dyn_cast<FunctionProtoType>(FD->getType()->castAs<FunctionType>()); @@ -1466,7 +1466,7 @@ void NamedDecl::printQualifiedName(raw_ostream &OS, } } OS << ')'; - } else if (const auto *ED = dyn_cast<EnumDecl>(*I)) { + } else if (const auto *ED = dyn_cast<EnumDecl>(DC)) { // C++ [dcl.enum]p10: Each enum-name and each unscoped // enumerator is declared in the scope that immediately contains // the enum-specifier. Each scoped enumerator is declared in the @@ -1476,7 +1476,7 @@ void NamedDecl::printQualifiedName(raw_ostream &OS, else continue; } else { - OS << *cast<NamedDecl>(*I); + OS << *cast<NamedDecl>(DC); } OS << "::"; } @@ -1912,7 +1912,9 @@ VarDecl::isThisDeclarationADefinition(ASTContext &C) const { // C++ [basic.def]p2: // A declaration is a definition unless [...] it contains the 'extern' // specifier or a linkage-specification and neither an initializer [...], - // it declares a static data member in a class declaration [...]. + // it declares a non-inline static data member in a class declaration [...], + // it declares a static data member outside a class definition and the variable + // was defined within the class with the constexpr specifier [...], // C++1y [temp.expl.spec]p15: // An explicit specialization of a static data member or an explicit // specialization of a static data member template is a definition if the @@ -1922,6 +1924,8 @@ VarDecl::isThisDeclarationADefinition(ASTContext &C) const { // a static data member template outside the containing class? if (isStaticDataMember()) { if (isOutOfLine() && + !(getCanonicalDecl()->isInline() && + getCanonicalDecl()->isConstexpr()) && (hasInit() || // If the first declaration is out-of-line, this may be an // instantiation of an out-of-line partial specialization of a variable @@ -1932,6 +1936,8 @@ VarDecl::isThisDeclarationADefinition(ASTContext &C) const { TSK_ExplicitSpecialization) || isa<VarTemplatePartialSpecializationDecl>(this))) return Definition; + else if (!isOutOfLine() && isInline()) + return Definition; else return DeclarationOnly; } @@ -1945,7 +1951,7 @@ VarDecl::isThisDeclarationADefinition(ASTContext &C) const { if (hasInit()) return Definition; - if (hasAttr<AliasAttr>()) + if (hasDefiningAttr()) return Definition; if (const auto *SAA = getAttr<SelectAnyAttr>()) @@ -2072,18 +2078,6 @@ bool VarDecl::isOutOfLine() const { return false; } -VarDecl *VarDecl::getOutOfLineDefinition() { - if (!isStaticDataMember()) - return nullptr; - - for (auto RD : redecls()) { - if (RD->getLexicalDeclContext()->isFileContext()) - return RD; - } - - return nullptr; -} - void VarDecl::setInit(Expr *I) { if (auto *Eval = Init.dyn_cast<EvaluatedStmt *>()) { Eval->~EvaluatedStmt(); @@ -2448,7 +2442,7 @@ void FunctionDecl::getNameForDiagnostic( const TemplateArgumentList *TemplateArgs = getTemplateSpecializationArgs(); if (TemplateArgs) TemplateSpecializationType::PrintTemplateArgumentList( - OS, TemplateArgs->data(), TemplateArgs->size(), Policy); + OS, TemplateArgs->asArray(), Policy); } bool FunctionDecl::isVariadic() const { @@ -2485,7 +2479,7 @@ bool FunctionDecl::hasTrivialBody() const bool FunctionDecl::isDefined(const FunctionDecl *&Definition) const { for (auto I : redecls()) { if (I->IsDeleted || I->IsDefaulted || I->Body || I->IsLateTemplateParsed || - I->hasAttr<AliasAttr>()) { + I->hasDefiningAttr()) { Definition = I->IsDeleted ? I->getCanonicalDecl() : I; return true; } @@ -2708,8 +2702,7 @@ unsigned FunctionDecl::getBuiltinID() const { // declaration, for instance "extern "C" { namespace std { decl } }". if (!LinkageDecl) { if (BuiltinID == Builtin::BI__GetExceptionInfo && - Context.getTargetInfo().getCXXABI().isMicrosoft() && - isInStdNamespace()) + Context.getTargetInfo().getCXXABI().isMicrosoft()) return Builtin::BI__GetExceptionInfo; return 0; } @@ -2733,6 +2726,12 @@ unsigned FunctionDecl::getBuiltinID() const { if (getStorageClass() == SC_Static) return 0; + // OpenCL v1.2 s6.9.f - The library functions defined in + // the C99 standard headers are not available. + if (Context.getLangOpts().OpenCL && + Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) + return 0; + return BuiltinID; } @@ -2788,7 +2787,7 @@ unsigned FunctionDecl::getMinRequiredArguments() const { return getNumParams(); unsigned NumRequiredArgs = 0; - for (auto *Param : params()) + for (auto *Param : parameters()) if (!Param->isParameterPack() && !Param->hasDefaultArg()) ++NumRequiredArgs; return NumRequiredArgs; @@ -2929,16 +2928,22 @@ SourceRange FunctionDecl::getReturnTypeSourceRange() const { return RTRange; } -bool FunctionDecl::hasUnusedResultAttr() const { +const Attr *FunctionDecl::getUnusedResultAttr() const { QualType RetType = getReturnType(); if (RetType->isRecordType()) { const CXXRecordDecl *Ret = RetType->getAsCXXRecordDecl(); const auto *MD = dyn_cast<CXXMethodDecl>(this); - if (Ret && Ret->hasAttr<WarnUnusedResultAttr>() && - !(MD && MD->getCorrespondingMethodInClass(Ret, true))) - return true; + if (Ret && !(MD && MD->getCorrespondingMethodInClass(Ret, true))) { + if (const auto *R = Ret->getAttr<WarnUnusedResultAttr>()) + return R; + } + } else if (const auto *ET = RetType->getAs<EnumType>()) { + if (const EnumDecl *ED = ET->getDecl()) { + if (const auto *R = ED->getAttr<WarnUnusedResultAttr>()) + return R; + } } - return hasAttr<WarnUnusedResultAttr>(); + return getAttr<WarnUnusedResultAttr>(); } /// \brief For an inline function definition in C, or for a gnu_inline function @@ -3520,6 +3525,7 @@ SourceLocation TagDecl::getOuterLocStart() const { } SourceRange TagDecl::getSourceRange() const { + SourceLocation RBraceLoc = BraceRange.getEnd(); SourceLocation E = RBraceLoc.isValid() ? RBraceLoc : getLocation(); return SourceRange(getOuterLocStart(), E); } @@ -3675,6 +3681,21 @@ void EnumDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK, MSI->setPointOfInstantiation(PointOfInstantiation); } +EnumDecl *EnumDecl::getTemplateInstantiationPattern() const { + if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) { + if (isTemplateInstantiation(MSInfo->getTemplateSpecializationKind())) { + EnumDecl *ED = getInstantiatedFromMemberEnum(); + while (auto *NewED = ED->getInstantiatedFromMemberEnum()) + ED = NewED; + return ED; + } + } + + assert(!isTemplateInstantiation(getTemplateSpecializationKind()) && + "couldn't find pattern for enum instantiation"); + return nullptr; +} + EnumDecl *EnumDecl::getInstantiatedFromMemberEnum() const { if (SpecializationInfo) return cast<EnumDecl>(SpecializationInfo->getInstantiatedFrom()); @@ -3900,6 +3921,53 @@ TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) { return new (C, (DeclContext *)nullptr) TranslationUnitDecl(C); } +void PragmaCommentDecl::anchor() { } + +PragmaCommentDecl *PragmaCommentDecl::Create(const ASTContext &C, + TranslationUnitDecl *DC, + SourceLocation CommentLoc, + PragmaMSCommentKind CommentKind, + StringRef Arg) { + PragmaCommentDecl *PCD = + new (C, DC, additionalSizeToAlloc<char>(Arg.size() + 1)) + PragmaCommentDecl(DC, CommentLoc, CommentKind); + memcpy(PCD->getTrailingObjects<char>(), Arg.data(), Arg.size()); + PCD->getTrailingObjects<char>()[Arg.size()] = '\0'; + return PCD; +} + +PragmaCommentDecl *PragmaCommentDecl::CreateDeserialized(ASTContext &C, + unsigned ID, + unsigned ArgSize) { + return new (C, ID, additionalSizeToAlloc<char>(ArgSize + 1)) + PragmaCommentDecl(nullptr, SourceLocation(), PCK_Unknown); +} + +void PragmaDetectMismatchDecl::anchor() { } + +PragmaDetectMismatchDecl * +PragmaDetectMismatchDecl::Create(const ASTContext &C, TranslationUnitDecl *DC, + SourceLocation Loc, StringRef Name, + StringRef Value) { + size_t ValueStart = Name.size() + 1; + PragmaDetectMismatchDecl *PDMD = + new (C, DC, additionalSizeToAlloc<char>(ValueStart + Value.size() + 1)) + PragmaDetectMismatchDecl(DC, Loc, ValueStart); + memcpy(PDMD->getTrailingObjects<char>(), Name.data(), Name.size()); + PDMD->getTrailingObjects<char>()[Name.size()] = '\0'; + memcpy(PDMD->getTrailingObjects<char>() + ValueStart, Value.data(), + Value.size()); + PDMD->getTrailingObjects<char>()[ValueStart + Value.size()] = '\0'; + return PDMD; +} + +PragmaDetectMismatchDecl * +PragmaDetectMismatchDecl::CreateDeserialized(ASTContext &C, unsigned ID, + unsigned NameValueSize) { + return new (C, ID, additionalSizeToAlloc<char>(NameValueSize + 1)) + PragmaDetectMismatchDecl(nullptr, SourceLocation(), 0); +} + void ExternCContextDecl::anchor() { } ExternCContextDecl *ExternCContextDecl::Create(const ASTContext &C, @@ -4026,8 +4094,10 @@ void IndirectFieldDecl::anchor() { } IndirectFieldDecl::IndirectFieldDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName N, - QualType T, NamedDecl **CH, unsigned CHS) - : ValueDecl(IndirectField, DC, L, N, T), Chaining(CH), ChainingSize(CHS) { + QualType T, + MutableArrayRef<NamedDecl *> CH) + : ValueDecl(IndirectField, DC, L, N, T), Chaining(CH.data()), + ChainingSize(CH.size()) { // In C++, indirect field declarations conflict with tag declarations in the // same scope, so add them to IDNS_Tag so that tag redeclaration finds them. if (C.getLangOpts().CPlusPlus) @@ -4036,16 +4106,15 @@ IndirectFieldDecl::IndirectFieldDecl(ASTContext &C, DeclContext *DC, IndirectFieldDecl * IndirectFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, QualType T, NamedDecl **CH, - unsigned CHS) { - return new (C, DC) IndirectFieldDecl(C, DC, L, Id, T, CH, CHS); + IdentifierInfo *Id, QualType T, + llvm::MutableArrayRef<NamedDecl *> CH) { + return new (C, DC) IndirectFieldDecl(C, DC, L, Id, T, CH); } IndirectFieldDecl *IndirectFieldDecl::CreateDeserialized(ASTContext &C, unsigned ID) { return new (C, ID) IndirectFieldDecl(C, nullptr, SourceLocation(), - DeclarationName(), QualType(), nullptr, - 0); + DeclarationName(), QualType(), None); } SourceRange EnumConstantDecl::getSourceRange() const { diff --git a/contrib/llvm/tools/clang/lib/AST/DeclBase.cpp b/contrib/llvm/tools/clang/lib/AST/DeclBase.cpp index 72587e3..bfb7d02 100644 --- a/contrib/llvm/tools/clang/lib/AST/DeclBase.cpp +++ b/contrib/llvm/tools/clang/lib/AST/DeclBase.cpp @@ -46,7 +46,7 @@ void Decl::updateOutOfDate(IdentifierInfo &II) const { } #define DECL(DERIVED, BASE) \ - static_assert(Decl::DeclObjAlignment >= \ + static_assert(llvm::AlignOf<Decl>::Alignment >= \ llvm::AlignOf<DERIVED##Decl>::Alignment, \ "Alignment sufficient after objects prepended to " #DERIVED); #define ABSTRACT_DECL(DECL) @@ -56,7 +56,7 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Context, unsigned ID, std::size_t Extra) { // Allocate an extra 8 bytes worth of storage, which ensures that the // resulting pointer will still be 8-byte aligned. - static_assert(sizeof(unsigned) * 2 >= DeclObjAlignment, + static_assert(sizeof(unsigned) * 2 >= llvm::AlignOf<Decl>::Alignment, "Decl won't be misaligned"); void *Start = Context.Allocate(Size + Extra + 8); void *Result = (char*)Start + 8; @@ -81,7 +81,8 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Ctx, // Ensure required alignment of the resulting object by adding extra // padding at the start if required. size_t ExtraAlign = - llvm::OffsetToAlignment(sizeof(Module *), DeclObjAlignment); + llvm::OffsetToAlignment(sizeof(Module *), + llvm::AlignOf<Decl>::Alignment); char *Buffer = reinterpret_cast<char *>( ::operator new(ExtraAlign + sizeof(Module *) + Size + Extra, Ctx)); Buffer += ExtraAlign; @@ -196,6 +197,17 @@ bool Decl::isTemplateDecl() const { return isa<TemplateDecl>(this); } +TemplateDecl *Decl::getDescribedTemplate() const { + if (auto *FD = dyn_cast<FunctionDecl>(this)) + return FD->getDescribedFunctionTemplate(); + else if (auto *RD = dyn_cast<CXXRecordDecl>(this)) + return RD->getDescribedClassTemplate(); + else if (auto *VD = dyn_cast<VarDecl>(this)) + return VD->getDescribedVarTemplate(); + + return nullptr; +} + const DeclContext *Decl::getParentFunctionOrMethod() const { for (const DeclContext *DC = getDeclContext(); DC && !DC->isTranslationUnit() && !DC->isNamespace(); @@ -329,25 +341,29 @@ unsigned Decl::getMaxAlignment() const { return Align; } -bool Decl::isUsed(bool CheckUsedAttr) const { - if (Used) +bool Decl::isUsed(bool CheckUsedAttr) const { + const Decl *CanonD = getCanonicalDecl(); + if (CanonD->Used) return true; - + // Check for used attribute. - if (CheckUsedAttr && hasAttr<UsedAttr>()) + // Ask the most recent decl, since attributes accumulate in the redecl chain. + if (CheckUsedAttr && getMostRecentDecl()->hasAttr<UsedAttr>()) return true; - return false; + // The information may have not been deserialized yet. Force deserialization + // to complete the needed information. + return getMostRecentDecl()->getCanonicalDecl()->Used; } void Decl::markUsed(ASTContext &C) { - if (Used) + if (isUsed(false)) return; if (C.getASTMutationListener()) C.getASTMutationListener()->DeclarationMarkedUsed(this); - Used = true; + setIsUsed(); } bool Decl::isReferenced() const { @@ -362,6 +378,18 @@ bool Decl::isReferenced() const { return false; } +bool Decl::hasDefiningAttr() const { + return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>(); +} + +const Attr *Decl::getDefiningAttr() const { + if (AliasAttr *AA = getAttr<AliasAttr>()) + return AA; + if (IFuncAttr *IFA = getAttr<IFuncAttr>()) + return IFA; + return nullptr; +} + /// \brief Determine the availability of the given declaration based on /// the target platform. /// @@ -432,7 +460,7 @@ static AvailabilityResult CheckAvailability(ASTContext &Context, << VTI << HintMessage; } - return AR_NotYetIntroduced; + return A->getStrict() ? AR_Unavailable : AR_NotYetIntroduced; } // Make sure that this declaration hasn't been obsoleted. @@ -467,6 +495,9 @@ static AvailabilityResult CheckAvailability(ASTContext &Context, } AvailabilityResult Decl::getAvailability(std::string *Message) const { + if (auto *FTD = dyn_cast<FunctionTemplateDecl>(this)) + return FTD->getTemplatedDecl()->getAvailability(Message); + AvailabilityResult Result = AR_Available; std::string ResultMessage; @@ -563,6 +594,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case Function: case CXXMethod: case CXXConstructor: + case ConstructorUsingShadow: case CXXDestructor: case CXXConversion: case EnumConstant: @@ -630,6 +662,9 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case TemplateTemplateParm: return IDNS_Ordinary | IDNS_Tag | IDNS_Type; + case OMPDeclareReduction: + return IDNS_OMPReduction; + // Never have names. case Friend: case FriendTemplate: @@ -638,6 +673,8 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case FileScopeAsm: case StaticAssert: case ObjCPropertyImpl: + case PragmaComment: + case PragmaDetectMismatch: case Block: case Captured: case TranslationUnit: @@ -655,6 +692,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case ObjCCategoryImpl: case Import: case OMPThreadPrivate: + case OMPCapturedExpr: case Empty: // Never looked up by name. return 0; @@ -957,6 +995,7 @@ DeclContext *DeclContext::getPrimaryContext() { case Decl::LinkageSpec: case Decl::Block: case Decl::Captured: + case Decl::OMPDeclareReduction: // There is only one DeclContext for these entities. return this; @@ -1549,9 +1588,12 @@ void DeclContext::makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal, bool Recoverable) { assert(this == getPrimaryContext() && "expected a primary DC"); - // Skip declarations within functions. - if (isFunctionOrMethod()) + if (!isLookupContext()) { + if (isTransparentContext()) + getParent()->getPrimaryContext() + ->makeDeclVisibleInContextWithFlags(D, Internal, Recoverable); return; + } // Skip declarations which should be invisible to name lookup. if (shouldBeHidden(D)) diff --git a/contrib/llvm/tools/clang/lib/AST/DeclCXX.cpp b/contrib/llvm/tools/clang/lib/AST/DeclCXX.cpp index 4f24fdc..81f9414 100644 --- a/contrib/llvm/tools/clang/lib/AST/DeclCXX.cpp +++ b/contrib/llvm/tools/clang/lib/AST/DeclCXX.cpp @@ -46,34 +46,33 @@ void LazyASTUnresolvedSet::getFromExternalSource(ASTContext &C) const { } CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) - : UserDeclaredConstructor(false), UserDeclaredSpecialMembers(0), - Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false), - Abstract(false), IsStandardLayout(true), HasNoNonEmptyBases(true), - HasPrivateFields(false), HasProtectedFields(false), HasPublicFields(false), - HasMutableFields(false), HasVariantMembers(false), HasOnlyCMembers(true), - HasInClassInitializer(false), HasUninitializedReferenceMember(false), - NeedOverloadResolutionForMoveConstructor(false), - NeedOverloadResolutionForMoveAssignment(false), - NeedOverloadResolutionForDestructor(false), - DefaultedMoveConstructorIsDeleted(false), - DefaultedMoveAssignmentIsDeleted(false), - DefaultedDestructorIsDeleted(false), - HasTrivialSpecialMembers(SMF_All), - DeclaredNonTrivialSpecialMembers(0), - HasIrrelevantDestructor(true), - HasConstexprNonCopyMoveConstructor(false), - DefaultedDefaultConstructorIsConstexpr(true), - HasConstexprDefaultConstructor(false), - HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false), - UserProvidedDefaultConstructor(false), DeclaredSpecialMembers(0), - ImplicitCopyConstructorHasConstParam(true), - ImplicitCopyAssignmentHasConstParam(true), - HasDeclaredCopyConstructorWithConstParam(false), - HasDeclaredCopyAssignmentWithConstParam(false), - IsLambda(false), IsParsingBaseSpecifiers(false), NumBases(0), NumVBases(0), - Bases(), VBases(), - Definition(D), FirstFriend() { -} + : UserDeclaredConstructor(false), UserDeclaredSpecialMembers(0), + Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false), + Abstract(false), IsStandardLayout(true), HasNoNonEmptyBases(true), + HasPrivateFields(false), HasProtectedFields(false), + HasPublicFields(false), HasMutableFields(false), HasVariantMembers(false), + HasOnlyCMembers(true), HasInClassInitializer(false), + HasUninitializedReferenceMember(false), HasUninitializedFields(false), + HasInheritedConstructor(false), HasInheritedAssignment(false), + NeedOverloadResolutionForMoveConstructor(false), + NeedOverloadResolutionForMoveAssignment(false), + NeedOverloadResolutionForDestructor(false), + DefaultedMoveConstructorIsDeleted(false), + DefaultedMoveAssignmentIsDeleted(false), + DefaultedDestructorIsDeleted(false), HasTrivialSpecialMembers(SMF_All), + DeclaredNonTrivialSpecialMembers(0), HasIrrelevantDestructor(true), + HasConstexprNonCopyMoveConstructor(false), + HasDefaultedDefaultConstructor(false), + DefaultedDefaultConstructorIsConstexpr(true), + HasConstexprDefaultConstructor(false), + HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false), + UserProvidedDefaultConstructor(false), DeclaredSpecialMembers(0), + ImplicitCopyConstructorHasConstParam(true), + ImplicitCopyAssignmentHasConstParam(true), + HasDeclaredCopyConstructorWithConstParam(false), + HasDeclaredCopyAssignmentWithConstParam(false), IsLambda(false), + IsParsingBaseSpecifiers(false), NumBases(0), NumVBases(0), Bases(), + VBases(), Definition(D), FirstFriend() {} CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const { return Bases.get(Definition->getASTContext().getExternalSource()); @@ -89,7 +88,7 @@ CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, CXXRecordDecl *PrevDecl) : RecordDecl(K, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl), DefinitionData(PrevDecl ? PrevDecl->DefinitionData - : DefinitionDataPtr(this)), + : nullptr), TemplateOrInstantiation() {} CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK, @@ -143,9 +142,11 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, C.Deallocate(data().getBases()); if (NumBases) { - // C++ [dcl.init.aggr]p1: - // An aggregate is [...] a class with [...] no base classes [...]. - data().Aggregate = false; + if (!C.getLangOpts().CPlusPlus1z) { + // C++ [dcl.init.aggr]p1: + // An aggregate is [...] a class with [...] no base classes [...]. + data().Aggregate = false; + } // C++ [class]p4: // A POD-struct is an aggregate class... @@ -171,8 +172,6 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl()); - // A class with a non-empty base class is not empty. - // FIXME: Standard ref? if (!BaseClassDecl->isEmpty()) { if (!data().Empty) { // C++0x [class]p7: @@ -186,10 +185,18 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, data().IsStandardLayout = false; } + // C++14 [meta.unary.prop]p4: + // T is a class type [...] with [...] no base class B for which + // is_empty<B>::value is false. data().Empty = false; data().HasNoNonEmptyBases = false; } + // C++1z [dcl.init.agg]p1: + // An aggregate is a class with [...] no private or protected base classes + if (Base->getAccessSpecifier() != AS_public) + data().Aggregate = false; + // C++ [class.virtual]p1: // A class that declares or inherits a virtual function is called a // polymorphic class. @@ -220,6 +227,10 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, if (CXXRecordDecl *VBaseDecl = VBase.getType()->getAsCXXRecordDecl()) if (!VBaseDecl->hasCopyConstructorWithConstParam()) data().ImplicitCopyConstructorHasConstParam = false; + + // C++1z [dcl.init.agg]p1: + // An aggregate is a class with [...] no virtual base classes + data().Aggregate = false; } } @@ -228,11 +239,15 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, if (SeenVBaseTypes.insert(C.getCanonicalType(BaseType)).second) VBases.push_back(Base); - // C++0x [meta.unary.prop] is_empty: - // T is a class type, but not a union type, with ... no virtual base - // classes + // C++14 [meta.unary.prop] is_empty: + // T is a class type, but not a union type, with ... no virtual base + // classes data().Empty = false; + // C++1z [dcl.init.agg]p1: + // An aggregate is a class with [...] no virtual base classes + data().Aggregate = false; + // C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25: // A [default constructor, copy/move constructor, or copy/move assignment // operator for a class X] is trivial [...] if: @@ -332,6 +347,9 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, if (BaseClassDecl->hasUninitializedReferenceMember()) data().HasUninitializedReferenceMember = true; + if (!BaseClassDecl->allowConstDefaultInit()) + data().HasUninitializedFields = true; + addedClassSubobject(BaseClassDecl); } @@ -430,6 +448,15 @@ void CXXRecordDecl::addedMember(Decl *D) { FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D); if (FunTmpl) D = FunTmpl->getTemplatedDecl(); + + // FIXME: Pass NamedDecl* to addedMember? + Decl *DUnderlying = D; + if (auto *ND = dyn_cast<NamedDecl>(DUnderlying)) { + DUnderlying = ND->getUnderlyingDecl(); + if (FunctionTemplateDecl *UnderlyingFunTmpl = + dyn_cast<FunctionTemplateDecl>(DUnderlying)) + DUnderlying = UnderlyingFunTmpl->getTemplatedDecl(); + } if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { if (Method->isVirtual()) { @@ -441,8 +468,8 @@ void CXXRecordDecl::addedMember(Decl *D) { // A POD-struct is an aggregate class... data().PlainOldData = false; - // Virtual functions make the class non-empty. - // FIXME: Standard ref? + // C++14 [meta.unary.prop]p4: + // T is a class type [...] with [...] no virtual member functions... data().Empty = false; // C++ [class.virtual]p1: @@ -485,18 +512,15 @@ void CXXRecordDecl::addedMember(Decl *D) { data().PlainOldData = false; } - // Technically, "user-provided" is only defined for special member - // functions, but the intent of the standard is clearly that it should apply - // to all functions. - bool UserProvided = Constructor->isUserProvided(); - if (Constructor->isDefaultConstructor()) { SMKind |= SMF_DefaultConstructor; - if (UserProvided) + if (Constructor->isUserProvided()) data().UserProvidedDefaultConstructor = true; if (Constructor->isConstexpr()) data().HasConstexprDefaultConstructor = true; + if (Constructor->isDefaulted()) + data().HasDefaultedDefaultConstructor = true; } if (!FunTmpl) { @@ -509,9 +533,17 @@ void CXXRecordDecl::addedMember(Decl *D) { } else if (Constructor->isMoveConstructor()) SMKind |= SMF_MoveConstructor; } + } + // Handle constructors, including those inherited from base classes. + if (CXXConstructorDecl *Constructor = + dyn_cast<CXXConstructorDecl>(DUnderlying)) { // Record if we see any constexpr constructors which are neither copy // nor move constructors. + // C++1z [basic.types]p10: + // [...] has at least one constexpr constructor or constructor template + // (possibly inherited from a base class) that is not a copy or move + // constructor [...] if (Constructor->isConstexpr() && !Constructor->isCopyOrMoveConstructor()) data().HasConstexprNonCopyMoveConstructor = true; @@ -521,8 +553,12 @@ void CXXRecordDecl::addedMember(Decl *D) { // C++11 [dcl.init.aggr]p1: // An aggregate is an array or a class with no user-provided // constructors [...]. + // C++11 [dcl.init.aggr]p1: + // An aggregate is an array or a class with no user-provided + // constructors (including those inherited from a base class) [...]. if (getASTContext().getLangOpts().CPlusPlus11 - ? UserProvided : !Constructor->isImplicit()) + ? Constructor->isUserProvided() + : !Constructor->isImplicit()) data().Aggregate = false; } @@ -702,6 +738,15 @@ void CXXRecordDecl::addedMember(Decl *D) { data().IsStandardLayout = false; } + if (!Field->hasInClassInitializer() && !Field->isMutable()) { + if (CXXRecordDecl *FieldType = Field->getType()->getAsCXXRecordDecl()) { + if (FieldType->hasDefinition() && !FieldType->allowConstDefaultInit()) + data().HasUninitializedFields = true; + } else { + data().HasUninitializedFields = true; + } + } + // Record if this field is the first non-literal or volatile field or base. if (!T->isLiteralType(Context) || T.isVolatileQualified()) data().HasNonLiteralTypeFieldsOrBases = true; @@ -720,7 +765,7 @@ void CXXRecordDecl::addedMember(Decl *D) { // An aggregate is a [...] class with [...] no // brace-or-equal-initializers for non-static data members. // - // This rule was removed in C++1y. + // This rule was removed in C++14. if (!getASTContext().getLangOpts().CPlusPlus14) data().Aggregate = false; @@ -762,6 +807,17 @@ void CXXRecordDecl::addedMember(Decl *D) { data().DefaultedDestructorIsDeleted = true; } + // For an anonymous union member, our overload resolution will perform + // overload resolution for its members. + if (Field->isAnonymousStructOrUnion()) { + data().NeedOverloadResolutionForMoveConstructor |= + FieldRec->data().NeedOverloadResolutionForMoveConstructor; + data().NeedOverloadResolutionForMoveAssignment |= + FieldRec->data().NeedOverloadResolutionForMoveAssignment; + data().NeedOverloadResolutionForDestructor |= + FieldRec->data().NeedOverloadResolutionForDestructor; + } + // C++0x [class.ctor]p5: // A default constructor is trivial [...] if: // -- for all the non-static data members of its class that are of @@ -910,7 +966,9 @@ void CXXRecordDecl::addedMember(Decl *D) { if (!data().HasNoNonEmptyBases) data().IsStandardLayout = false; - // If this is not a zero-length bit-field, then the class is not empty. + // C++14 [meta.unary.prop]p4: + // T is a class type [...] with [...] no non-static data members other + // than bit-fields of length 0... if (data().Empty) { if (!Field->isBitField() || (!Field->getBitWidth()->isTypeDependent() && @@ -928,6 +986,15 @@ void CXXRecordDecl::addedMember(Decl *D) { data().Conversions.get(Ctx).addDecl(Ctx, Shadow, Shadow->getAccess()); } } + + if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) { + if (Using->getDeclName().getNameKind() == + DeclarationName::CXXConstructorName) + data().HasInheritedConstructor = true; + + if (Using->getDeclName().getCXXOverloadedOperator() == OO_Equal) + data().HasInheritedAssignment = true; + } } void CXXRecordDecl::finishedDefaultedOrDeletedMember(CXXMethodDecl *D) { @@ -1595,6 +1662,13 @@ unsigned CXXMethodDecl::size_overridden_methods() const { return getASTContext().overridden_methods_size(this); } +CXXMethodDecl::overridden_method_range +CXXMethodDecl::overridden_methods() const { + if (isa<CXXConstructorDecl>(this)) + return overridden_method_range(nullptr, nullptr); + return getASTContext().overridden_methods(this); +} + QualType CXXMethodDecl::getThisType(ASTContext &C) const { // C++ 9.3.2p1: The type of this in a member function of a class X is X*. // If the member function is declared const, the type of this is const X*, @@ -1606,7 +1680,7 @@ QualType CXXMethodDecl::getThisType(ASTContext &C) const { QualType ClassTy = C.getTypeDeclType(getParent()); ClassTy = C.getQualifiedType(ClassTy, - Qualifiers::fromCVRMask(getTypeQualifiers())); + Qualifiers::fromCVRUMask(getTypeQualifiers())); return C.getPointerType(ClassTy); } @@ -1744,11 +1818,15 @@ SourceRange CXXCtorInitializer::getSourceRange() const { void CXXConstructorDecl::anchor() { } -CXXConstructorDecl * -CXXConstructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) CXXConstructorDecl(C, nullptr, SourceLocation(), - DeclarationNameInfo(), QualType(), - nullptr, false, false, false, false); +CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C, + unsigned ID, + bool Inherited) { + unsigned Extra = additionalSizeToAlloc<InheritedConstructor>(Inherited); + auto *Result = new (C, ID, Extra) CXXConstructorDecl( + C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, + false, false, false, false, InheritedConstructor()); + Result->IsInheritingConstructor = Inherited; + return Result; } CXXConstructorDecl * @@ -1757,13 +1835,16 @@ CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isExplicit, bool isInline, - bool isImplicitlyDeclared, bool isConstexpr) { + bool isImplicitlyDeclared, bool isConstexpr, + InheritedConstructor Inherited) { assert(NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName && "Name must refer to a constructor"); - return new (C, RD) CXXConstructorDecl(C, RD, StartLoc, NameInfo, T, TInfo, - isExplicit, isInline, - isImplicitlyDeclared, isConstexpr); + unsigned Extra = + additionalSizeToAlloc<InheritedConstructor>(Inherited ? 1 : 0); + return new (C, RD, Extra) CXXConstructorDecl( + C, RD, StartLoc, NameInfo, T, TInfo, isExplicit, isInline, + isImplicitlyDeclared, isConstexpr, Inherited); } CXXConstructorDecl::init_const_iterator CXXConstructorDecl::init_begin() const { @@ -1878,23 +1959,6 @@ bool CXXConstructorDecl::isSpecializationCopyingObject() const { return true; } -const CXXConstructorDecl *CXXConstructorDecl::getInheritedConstructor() const { - // Hack: we store the inherited constructor in the overridden method table - method_iterator It = getASTContext().overridden_methods_begin(this); - if (It == getASTContext().overridden_methods_end(this)) - return nullptr; - - return cast<CXXConstructorDecl>(*It); -} - -void -CXXConstructorDecl::setInheritedConstructor(const CXXConstructorDecl *BaseCtor){ - // Hack: we store the inherited constructor in the overridden method table - assert(getASTContext().overridden_methods_size(this) == 0 && - "Base ctor already set."); - getASTContext().addOverriddenMethod(this, BaseCtor); -} - void CXXDestructorDecl::anchor() { } CXXDestructorDecl * @@ -2090,10 +2154,24 @@ NamespaceAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) { void UsingShadowDecl::anchor() { } +UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, DeclContext *DC, + SourceLocation Loc, UsingDecl *Using, + NamedDecl *Target) + : NamedDecl(K, DC, Loc, Using ? Using->getDeclName() : DeclarationName()), + redeclarable_base(C), Underlying(Target), + UsingOrNextShadow(cast<NamedDecl>(Using)) { + if (Target) + IdentifierNamespace = Target->getIdentifierNamespace(); + setImplicit(); +} + +UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, EmptyShell Empty) + : NamedDecl(K, nullptr, SourceLocation(), DeclarationName()), + redeclarable_base(C), Underlying(), UsingOrNextShadow() {} + UsingShadowDecl * UsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) UsingShadowDecl(C, nullptr, SourceLocation(), - nullptr, nullptr); + return new (C, ID) UsingShadowDecl(UsingShadow, C, EmptyShell()); } UsingDecl *UsingShadowDecl::getUsingDecl() const { @@ -2104,6 +2182,25 @@ UsingDecl *UsingShadowDecl::getUsingDecl() const { return cast<UsingDecl>(Shadow->UsingOrNextShadow); } +void ConstructorUsingShadowDecl::anchor() { } + +ConstructorUsingShadowDecl * +ConstructorUsingShadowDecl::Create(ASTContext &C, DeclContext *DC, + SourceLocation Loc, UsingDecl *Using, + NamedDecl *Target, bool IsVirtual) { + return new (C, DC) ConstructorUsingShadowDecl(C, DC, Loc, Using, Target, + IsVirtual); +} + +ConstructorUsingShadowDecl * +ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned ID) { + return new (C, ID) ConstructorUsingShadowDecl(C, EmptyShell()); +} + +CXXRecordDecl *ConstructorUsingShadowDecl::getNominatedBaseClass() const { + return getUsingDecl()->getQualifier()->getAsRecordDecl(); +} + void UsingDecl::anchor() { } void UsingDecl::addShadowDecl(UsingShadowDecl *S) { diff --git a/contrib/llvm/tools/clang/lib/AST/DeclObjC.cpp b/contrib/llvm/tools/clang/lib/AST/DeclObjC.cpp index 050a0f5..d270121 100644 --- a/contrib/llvm/tools/clang/lib/AST/DeclObjC.cpp +++ b/contrib/llvm/tools/clang/lib/AST/DeclObjC.cpp @@ -152,7 +152,8 @@ bool ObjCContainerDecl::HasUserDeclaredSetterMethod( ObjCPropertyDecl * ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC, - const IdentifierInfo *propertyID) { + const IdentifierInfo *propertyID, + ObjCPropertyQueryKind queryKind) { // If this context is a hidden protocol definition, don't find any // property. if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(DC)) { @@ -166,15 +167,33 @@ ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC, if (auto *IDecl = dyn_cast<ObjCInterfaceDecl>(DC)) { for (const auto *Ext : IDecl->known_extensions()) if (ObjCPropertyDecl *PD = ObjCPropertyDecl::findPropertyDecl(Ext, - propertyID)) + propertyID, + queryKind)) return PD; } DeclContext::lookup_result R = DC->lookup(propertyID); + ObjCPropertyDecl *classProp = nullptr; for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; ++I) - if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(*I)) - return PD; + if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(*I)) { + // If queryKind is unknown, we return the instance property if one + // exists; otherwise we return the class property. + if ((queryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown && + !PD->isClassProperty()) || + (queryKind == ObjCPropertyQueryKind::OBJC_PR_query_class && + PD->isClassProperty()) || + (queryKind == ObjCPropertyQueryKind::OBJC_PR_query_instance && + !PD->isClassProperty())) + return PD; + + if (PD->isClassProperty()) + classProp = PD; + } + + if (queryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown) + // We can't find the instance property, return the class property. + return classProp; return nullptr; } @@ -192,7 +211,8 @@ ObjCPropertyDecl::getDefaultSynthIvarName(ASTContext &Ctx) const { /// FindPropertyDeclaration - Finds declaration of the property given its name /// in 'PropertyId' and returns it. It returns 0, if not found. ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration( - const IdentifierInfo *PropertyId) const { + const IdentifierInfo *PropertyId, + ObjCPropertyQueryKind QueryKind) const { // Don't find properties within hidden protocol definitions. if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) { if (const ObjCProtocolDecl *Def = Proto->getDefinition()) @@ -204,13 +224,14 @@ ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration( // the class itself. if (const auto *ClassDecl = dyn_cast<ObjCInterfaceDecl>(this)) { for (const auto *Ext : ClassDecl->visible_extensions()) { - if (auto *P = Ext->FindPropertyDeclaration(PropertyId)) + if (auto *P = Ext->FindPropertyDeclaration(PropertyId, QueryKind)) return P; } } if (ObjCPropertyDecl *PD = - ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId)) + ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId, + QueryKind)) return PD; switch (getKind()) { @@ -219,7 +240,8 @@ ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration( case Decl::ObjCProtocol: { const ObjCProtocolDecl *PID = cast<ObjCProtocolDecl>(this); for (const auto *I : PID->protocols()) - if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId)) + if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId, + QueryKind)) return P; break; } @@ -228,18 +250,20 @@ ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration( // Look through categories (but not extensions; they were handled above). for (const auto *Cat : OID->visible_categories()) { if (!Cat->IsClassExtension()) - if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(PropertyId)) + if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration( + PropertyId, QueryKind)) return P; } // Look through protocols. for (const auto *I : OID->all_referenced_protocols()) - if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId)) + if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId, + QueryKind)) return P; // Finally, check the super class. if (const ObjCInterfaceDecl *superClass = OID->getSuperClass()) - return superClass->FindPropertyDeclaration(PropertyId); + return superClass->FindPropertyDeclaration(PropertyId, QueryKind); break; } case Decl::ObjCCategory: { @@ -247,7 +271,8 @@ ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration( // Look through protocols. if (!OCD->IsClassExtension()) for (const auto *I : OCD->protocols()) - if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId)) + if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId, + QueryKind)) return P; break; } @@ -319,7 +344,8 @@ SourceLocation ObjCInterfaceDecl::getSuperClassLoc() const { /// ObjCPropertyDecl * ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass( - IdentifierInfo *PropertyId) const { + IdentifierInfo *PropertyId, + ObjCPropertyQueryKind QueryKind) const { // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) return nullptr; @@ -328,12 +354,14 @@ ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass( LoadExternalDefinition(); if (ObjCPropertyDecl *PD = - ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId)) + ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId, + QueryKind)) return PD; // Look through protocols. for (const auto *I : all_referenced_protocols()) - if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId)) + if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId, + QueryKind)) return P; return nullptr; @@ -342,13 +370,13 @@ ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass( void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM, PropertyDeclOrder &PO) const { for (auto *Prop : properties()) { - PM[Prop->getIdentifier()] = Prop; + PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop; PO.push_back(Prop); } for (const auto *Ext : known_extensions()) { const ObjCCategoryDecl *ClassExt = Ext; for (auto *Prop : ClassExt->properties()) { - PM[Prop->getIdentifier()] = Prop; + PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop; PO.push_back(Prop); } } @@ -1206,23 +1234,29 @@ ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const { if (NumArgs > 1) return nullptr; - if (!isInstanceMethod()) - return nullptr; - if (isPropertyAccessor()) { const ObjCContainerDecl *Container = cast<ObjCContainerDecl>(getParent()); bool IsGetter = (NumArgs == 0); + bool IsInstance = isInstanceMethod(); /// Local function that attempts to find a matching property within the /// given Objective-C container. auto findMatchingProperty = [&](const ObjCContainerDecl *Container) -> const ObjCPropertyDecl * { - - for (const auto *I : Container->properties()) { - Selector NextSel = IsGetter ? I->getGetterName() - : I->getSetterName(); - if (NextSel == Sel) - return I; + if (IsInstance) { + for (const auto *I : Container->instance_properties()) { + Selector NextSel = IsGetter ? I->getGetterName() + : I->getSetterName(); + if (NextSel == Sel) + return I; + } + } else { + for (const auto *I : Container->class_properties()) { + Selector NextSel = IsGetter ? I->getGetterName() + : I->getSetterName(); + if (NextSel == Sel) + return I; + } } return nullptr; @@ -1822,7 +1856,9 @@ void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM, if (const ObjCProtocolDecl *PDecl = getDefinition()) { for (auto *Prop : PDecl->properties()) { // Insert into PM if not there already. - PM.insert(std::make_pair(Prop->getIdentifier(), Prop)); + PM.insert(std::make_pair( + std::make_pair(Prop->getIdentifier(), Prop->isClassProperty()), + Prop)); PO.push_back(Prop); } // Scan through protocol's protocols. @@ -2011,10 +2047,29 @@ FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const { /// category \@implementation block. /// ObjCPropertyImplDecl *ObjCImplDecl:: -FindPropertyImplDecl(IdentifierInfo *Id) const { +FindPropertyImplDecl(IdentifierInfo *Id, + ObjCPropertyQueryKind QueryKind) const { + ObjCPropertyImplDecl *ClassPropImpl = nullptr; for (auto *PID : property_impls()) - if (PID->getPropertyDecl()->getIdentifier() == Id) - return PID; + // If queryKind is unknown, we return the instance property if one + // exists; otherwise we return the class property. + if (PID->getPropertyDecl()->getIdentifier() == Id) { + if ((QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown && + !PID->getPropertyDecl()->isClassProperty()) || + (QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_class && + PID->getPropertyDecl()->isClassProperty()) || + (QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_instance && + !PID->getPropertyDecl()->isClassProperty())) + return PID; + + if (PID->getPropertyDecl()->isClassProperty()) + ClassPropImpl = PID; + } + + if (QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown) + // We can't find the instance property, return the class property. + return ClassPropImpl; + return nullptr; } diff --git a/contrib/llvm/tools/clang/lib/AST/DeclOpenMP.cpp b/contrib/llvm/tools/clang/lib/AST/DeclOpenMP.cpp index 493e2cd..5b06ce0 100644 --- a/contrib/llvm/tools/clang/lib/AST/DeclOpenMP.cpp +++ b/contrib/llvm/tools/clang/lib/AST/DeclOpenMP.cpp @@ -7,7 +7,8 @@ // //===----------------------------------------------------------------------===// /// \file -/// \brief This file implements OMPThreadPrivateDecl class. +/// \brief This file implements OMPThreadPrivateDecl, OMPCapturedExprDecl +/// classes. /// //===----------------------------------------------------------------------===// @@ -52,3 +53,50 @@ void OMPThreadPrivateDecl::setVars(ArrayRef<Expr *> VL) { std::uninitialized_copy(VL.begin(), VL.end(), getTrailingObjects<Expr *>()); } +//===----------------------------------------------------------------------===// +// OMPDeclareReductionDecl Implementation. +//===----------------------------------------------------------------------===// + +void OMPDeclareReductionDecl::anchor() {} + +OMPDeclareReductionDecl *OMPDeclareReductionDecl::Create( + ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, + QualType T, OMPDeclareReductionDecl *PrevDeclInScope) { + return new (C, DC) OMPDeclareReductionDecl(OMPDeclareReduction, DC, L, Name, + T, PrevDeclInScope); +} + +OMPDeclareReductionDecl * +OMPDeclareReductionDecl::CreateDeserialized(ASTContext &C, unsigned ID) { + return new (C, ID) OMPDeclareReductionDecl( + OMPDeclareReduction, /*DC=*/nullptr, SourceLocation(), DeclarationName(), + QualType(), /*PrevDeclInScope=*/nullptr); +} + +OMPDeclareReductionDecl *OMPDeclareReductionDecl::getPrevDeclInScope() { + return cast_or_null<OMPDeclareReductionDecl>( + PrevDeclInScope.get(getASTContext().getExternalSource())); +} +const OMPDeclareReductionDecl * +OMPDeclareReductionDecl::getPrevDeclInScope() const { + return cast_or_null<OMPDeclareReductionDecl>( + PrevDeclInScope.get(getASTContext().getExternalSource())); +} + +//===----------------------------------------------------------------------===// +// OMPCapturedExprDecl Implementation. +//===----------------------------------------------------------------------===// + +void OMPCapturedExprDecl::anchor() {} + +OMPCapturedExprDecl *OMPCapturedExprDecl::Create(ASTContext &C, DeclContext *DC, + IdentifierInfo *Id, + QualType T) { + return new (C, DC) OMPCapturedExprDecl(C, DC, Id, T); +} + +OMPCapturedExprDecl *OMPCapturedExprDecl::CreateDeserialized(ASTContext &C, + unsigned ID) { + return new (C, ID) OMPCapturedExprDecl(C, nullptr, nullptr, QualType()); +} + diff --git a/contrib/llvm/tools/clang/lib/AST/DeclPrinter.cpp b/contrib/llvm/tools/clang/lib/AST/DeclPrinter.cpp index 5c6002d..7e78699 100644 --- a/contrib/llvm/tools/clang/lib/AST/DeclPrinter.cpp +++ b/contrib/llvm/tools/clang/lib/AST/DeclPrinter.cpp @@ -92,6 +92,8 @@ namespace { void VisitUsingDecl(UsingDecl *D); void VisitUsingShadowDecl(UsingShadowDecl *D); void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D); + void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D); + void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D); void PrintTemplateParameters(const TemplateParameterList *Params, const TemplateArgumentList *Args = nullptr); @@ -130,6 +132,8 @@ static QualType GetBaseType(QualType T) { BaseType = VTy->getElementType(); else if (const ReferenceType *RTy = BaseType->getAs<ReferenceType>()) BaseType = RTy->getPointeeType(); + else if (const AutoType *ATy = BaseType->getAs<AutoType>()) + BaseType = ATy->getDeducedType(); else llvm_unreachable("Unknown declarator!"); } @@ -158,19 +162,17 @@ void Decl::printGroup(Decl** Begin, unsigned NumDecls, ++Begin; PrintingPolicy SubPolicy(Policy); - if (TD && TD->isCompleteDefinition()) { - TD->print(Out, Policy, Indentation); - Out << " "; - SubPolicy.SuppressTag = true; - } bool isFirst = true; for ( ; Begin != End; ++Begin) { if (isFirst) { + if(TD) + SubPolicy.IncludeTagDefinition = true; SubPolicy.SuppressSpecifiers = false; isFirst = false; } else { if (!isFirst) Out << ", "; + SubPolicy.IncludeTagDefinition = false; SubPolicy.SuppressSpecifiers = true; } @@ -244,7 +246,7 @@ void DeclPrinter::printDeclType(QualType T, StringRef DeclName, bool Pack) { Pack = true; T = PET->getPattern(); } - T.print(Out, Policy, (Pack ? "..." : "") + DeclName); + T.print(Out, Policy, (Pack ? "..." : "") + DeclName, Indentation); } void DeclPrinter::ProcessDeclGroup(SmallVectorImpl<Decl*>& Decls) { @@ -333,7 +335,7 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { // FIXME: Need to be able to tell the DeclPrinter when const char *Terminator = nullptr; - if (isa<OMPThreadPrivateDecl>(*D)) + if (isa<OMPThreadPrivateDecl>(*D) || isa<OMPDeclareReductionDecl>(*D)) Terminator = nullptr; else if (isa<FunctionDecl>(*D) && cast<FunctionDecl>(*D)->isThisDeclarationADefinition()) @@ -358,6 +360,11 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { if (Terminator) Out << Terminator; Out << "\n"; + + // Declare target attribute is special one, natural spelling for the pragma + // assumes "ending" construct so print it here. + if (D->hasAttr<OMPDeclareTargetDeclAttr>()) + Out << "#pragma omp end declare target\n"; } if (!Decls.empty()) @@ -378,7 +385,8 @@ void DeclPrinter::VisitTypedefDecl(TypedefDecl *D) { if (D->isModulePrivate()) Out << "__module_private__ "; } - D->getTypeSourceInfo()->getType().print(Out, Policy, D->getName()); + QualType Ty = D->getTypeSourceInfo()->getType(); + Ty.print(Out, Policy, D->getName(), Indentation); prettyPrintAttributes(D); } @@ -683,7 +691,7 @@ void DeclPrinter::VisitFieldDecl(FieldDecl *D) { Out << "__module_private__ "; Out << D->getASTContext().getUnqualifiedObjCPointerType(D->getType()). - stream(Policy, D->getName()); + stream(Policy, D->getName(), Indentation); if (D->isBitField()) { Out << " : "; @@ -707,6 +715,11 @@ void DeclPrinter::VisitLabelDecl(LabelDecl *D) { void DeclPrinter::VisitVarDecl(VarDecl *D) { prettyPrintPragmas(D); + + QualType T = D->getTypeSourceInfo() + ? D->getTypeSourceInfo()->getType() + : D->getASTContext().getUnqualifiedObjCPointerType(D->getType()); + if (!Policy.SuppressSpecifiers) { StorageClass SC = D->getStorageClass(); if (SC != SC_None) @@ -728,11 +741,13 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) { if (D->isModulePrivate()) Out << "__module_private__ "; + + if (D->isConstexpr()) { + Out << "constexpr "; + T.removeLocalConst(); + } } - QualType T = D->getTypeSourceInfo() - ? D->getTypeSourceInfo()->getType() - : D->getASTContext().getUnqualifiedObjCPointerType(D->getType()); printDeclType(T, D->getName()); Expr *Init = D->getInit(); if (!Policy.SuppressInitializers && Init) { @@ -751,7 +766,10 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) { else if (D->getInitStyle() == VarDecl::CInit) { Out << " = "; } - Init->printPretty(Out, nullptr, Policy, Indentation); + PrintingPolicy SubPolicy(Policy); + SubPolicy.SuppressSpecifiers = false; + SubPolicy.IncludeTagDefinition = false; + Init->printPretty(Out, nullptr, SubPolicy, Indentation); if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init)) Out << ")"; } @@ -1046,7 +1064,7 @@ void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) { std::string name = OMD->getSelector().getAsString(); std::string::size_type pos, lastPos = 0; - for (const auto *PI : OMD->params()) { + for (const auto *PI : OMD->parameters()) { // FIXME: selector is missing here! pos = name.find_first_of(':', lastPos); Out << " " << name.substr(lastPos, pos - lastPos) << ':'; @@ -1298,6 +1316,11 @@ void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) { } } + if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_class) { + Out << (first ? ' ' : ',') << "class"; + first = false; + } + (void) first; // Silence dead store warning due to idiomatic code. Out << " )"; } @@ -1358,3 +1381,38 @@ void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { } } +void DeclPrinter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) { + if (!D->isInvalidDecl()) { + Out << "#pragma omp declare reduction ("; + if (D->getDeclName().getNameKind() == DeclarationName::CXXOperatorName) { + static const char *const OperatorNames[NUM_OVERLOADED_OPERATORS] = { + nullptr, +#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \ + Spelling, +#include "clang/Basic/OperatorKinds.def" + }; + const char *OpName = + OperatorNames[D->getDeclName().getCXXOverloadedOperator()]; + assert(OpName && "not an overloaded operator"); + Out << OpName; + } else { + assert(D->getDeclName().isIdentifier()); + D->printName(Out); + } + Out << " : "; + D->getType().print(Out, Policy); + Out << " : "; + D->getCombiner()->printPretty(Out, nullptr, Policy, 0); + Out << ")"; + if (auto *Init = D->getInitializer()) { + Out << " initializer("; + Init->printPretty(Out, nullptr, Policy, 0); + Out << ")"; + } + } +} + +void DeclPrinter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) { + D->getInit()->printPretty(Out, nullptr, Policy, Indentation); +} + diff --git a/contrib/llvm/tools/clang/lib/AST/DeclTemplate.cpp b/contrib/llvm/tools/clang/lib/AST/DeclTemplate.cpp index de3ebd2..37943cd 100644 --- a/contrib/llvm/tools/clang/lib/AST/DeclTemplate.cpp +++ b/contrib/llvm/tools/clang/lib/AST/DeclTemplate.cpp @@ -65,32 +65,29 @@ TemplateParameterList *TemplateParameterList::Create( unsigned TemplateParameterList::getMinRequiredArguments() const { unsigned NumRequiredArgs = 0; - for (iterator P = const_cast<TemplateParameterList *>(this)->begin(), - PEnd = const_cast<TemplateParameterList *>(this)->end(); - P != PEnd; ++P) { - if ((*P)->isTemplateParameterPack()) { - if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) + for (const NamedDecl *P : asArray()) { + if (P->isTemplateParameterPack()) { + if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) if (NTTP->isExpandedParameterPack()) { NumRequiredArgs += NTTP->getNumExpansionTypes(); continue; } - + break; } - - if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) { + + if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) { if (TTP->hasDefaultArgument()) break; - } else if (NonTypeTemplateParmDecl *NTTP - = dyn_cast<NonTypeTemplateParmDecl>(*P)) { + } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) { if (NTTP->hasDefaultArgument()) break; - } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument()) + } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument()) break; - + ++NumRequiredArgs; } - + return NumRequiredArgs; } @@ -111,12 +108,10 @@ unsigned TemplateParameterList::getDepth() const { static void AdoptTemplateParameterList(TemplateParameterList *Params, DeclContext *Owner) { - for (TemplateParameterList::iterator P = Params->begin(), - PEnd = Params->end(); - P != PEnd; ++P) { - (*P)->setDeclContext(Owner); - - if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P)) + for (NamedDecl *P : *Params) { + P->setDeclContext(Owner); + + if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner); } } @@ -157,8 +152,8 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() c } // Update any previous declarations we saw with the common pointer. - for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I) - PrevDecls[I]->Common = Common; + for (const RedeclarableTemplateDecl *Prev : PrevDecls) + Prev->Common = Common; return Common; } @@ -205,44 +200,41 @@ void RedeclarableTemplateDecl::addSpecializationImpl( /// \brief Generate the injected template arguments for the given template /// parameter list, e.g., for the injected-class-name of a class template. static void GenerateInjectedTemplateArgs(ASTContext &Context, - TemplateParameterList *Params, + TemplateParameterList *Params, TemplateArgument *Args) { - for (TemplateParameterList::iterator Param = Params->begin(), - ParamEnd = Params->end(); - Param != ParamEnd; ++Param) { + for (NamedDecl *Param : *Params) { TemplateArgument Arg; - if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) { + if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) { QualType ArgType = Context.getTypeDeclType(TTP); if (TTP->isParameterPack()) ArgType = Context.getPackExpansionType(ArgType, None); Arg = TemplateArgument(ArgType); - } else if (NonTypeTemplateParmDecl *NTTP = - dyn_cast<NonTypeTemplateParmDecl>(*Param)) { + } else if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) { Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false, NTTP->getType().getNonLValueExprType(Context), Expr::getValueKindForType(NTTP->getType()), NTTP->getLocation()); - + if (NTTP->isParameterPack()) E = new (Context) PackExpansionExpr(Context.DependentTy, E, NTTP->getLocation(), None); Arg = TemplateArgument(E); } else { - TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param); + auto *TTP = cast<TemplateTemplateParmDecl>(Param); if (TTP->isParameterPack()) Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>()); else Arg = TemplateArgument(TemplateName(TTP)); } - - if ((*Param)->isTemplateParameterPack()) + + if (Param->isTemplateParameterPack()) Arg = TemplateArgument::CreatePackCopy(Context, Arg); *Args++ = Arg; } } - + //===----------------------------------------------------------------------===// // FunctionTemplateDecl Implementation //===----------------------------------------------------------------------===// @@ -421,23 +413,17 @@ void ClassTemplateDecl::getPartialSpecializations( = getPartialSpecializations(); PS.clear(); PS.reserve(PartialSpecs.size()); - for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator - P = PartialSpecs.begin(), PEnd = PartialSpecs.end(); - P != PEnd; ++P) - PS.push_back(P->getMostRecentDecl()); + for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs) + PS.push_back(P.getMostRecentDecl()); } ClassTemplatePartialSpecializationDecl * ClassTemplateDecl::findPartialSpecialization(QualType T) { ASTContext &Context = getASTContext(); - using llvm::FoldingSetVector; - typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator - partial_spec_iterator; - for (partial_spec_iterator P = getPartialSpecializations().begin(), - PEnd = getPartialSpecializations().end(); - P != PEnd; ++P) { - if (Context.hasSameType(P->getInjectedSpecializationType(), T)) - return P->getMostRecentDecl(); + for (ClassTemplatePartialSpecializationDecl &P : + getPartialSpecializations()) { + if (Context.hasSameType(P.getInjectedSpecializationType(), T)) + return P.getMostRecentDecl(); } return nullptr; @@ -447,12 +433,9 @@ ClassTemplatePartialSpecializationDecl * ClassTemplateDecl::findPartialSpecInstantiatedFromMember( ClassTemplatePartialSpecializationDecl *D) { Decl *DCanon = D->getCanonicalDecl(); - for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator - P = getPartialSpecializations().begin(), - PEnd = getPartialSpecializations().end(); - P != PEnd; ++P) { - if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon) - return P->getMostRecentDecl(); + for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) { + if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon) + return P.getMostRecentDecl(); } return nullptr; @@ -478,8 +461,7 @@ ClassTemplateDecl::getInjectedClassNameSpecialization() { GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data()); CommonPtr->InjectedClassNameType = Context.getTemplateSpecializationType(TemplateName(this), - &TemplateArgs[0], - TemplateArgs.size()); + TemplateArgs); return CommonPtr->InjectedClassNameType; } @@ -535,20 +517,14 @@ bool TemplateTypeParmDecl::isParameterPack() const { // NonTypeTemplateParmDecl Method Implementations //===----------------------------------------------------------------------===// -NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC, - SourceLocation StartLoc, - SourceLocation IdLoc, - unsigned D, unsigned P, - IdentifierInfo *Id, - QualType T, - TypeSourceInfo *TInfo, - const QualType *ExpandedTypes, - unsigned NumExpandedTypes, - TypeSourceInfo **ExpandedTInfos) - : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), - TemplateParmPosition(D, P), ParameterPack(true), - ExpandedParameterPack(true), NumExpandedTypes(NumExpandedTypes) { - if (ExpandedTypes && ExpandedTInfos) { +NonTypeTemplateParmDecl::NonTypeTemplateParmDecl( + DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, + unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, + ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos) + : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), + TemplateParmPosition(D, P), ParameterPack(true), + ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) { + if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) { auto TypesAndInfos = getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>(); for (unsigned I = 0; I != NumExpandedTypes; ++I) { @@ -568,20 +544,16 @@ NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, T, ParameterPack, TInfo); } -NonTypeTemplateParmDecl * -NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, - SourceLocation StartLoc, SourceLocation IdLoc, - unsigned D, unsigned P, - IdentifierInfo *Id, QualType T, - TypeSourceInfo *TInfo, - const QualType *ExpandedTypes, - unsigned NumExpandedTypes, - TypeSourceInfo **ExpandedTInfos) { +NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( + const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, + QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes, + ArrayRef<TypeSourceInfo *> ExpandedTInfos) { return new (C, DC, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>( - NumExpandedTypes)) + ExpandedTypes.size())) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo, - ExpandedTypes, NumExpandedTypes, ExpandedTInfos); + ExpandedTypes, ExpandedTInfos); } NonTypeTemplateParmDecl * @@ -594,12 +566,14 @@ NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { NonTypeTemplateParmDecl * NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, unsigned NumExpandedTypes) { - return new (C, ID, - additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>( - NumExpandedTypes)) - NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), 0, 0, - nullptr, QualType(), nullptr, nullptr, - NumExpandedTypes, nullptr); + auto *NTTP = + new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>( + NumExpandedTypes)) + NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), + 0, 0, nullptr, QualType(), nullptr, None, + None); + NTTP->NumExpandedTypes = NumExpandedTypes; + return NTTP; } SourceRange NonTypeTemplateParmDecl::getSourceRange() const { @@ -624,12 +598,12 @@ void TemplateTemplateParmDecl::anchor() { } TemplateTemplateParmDecl::TemplateTemplateParmDecl( DeclContext *DC, SourceLocation L, unsigned D, unsigned P, IdentifierInfo *Id, TemplateParameterList *Params, - unsigned NumExpansions, TemplateParameterList * const *Expansions) - : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), - TemplateParmPosition(D, P), ParameterPack(true), - ExpandedParameterPack(true), NumExpandedParams(NumExpansions) { - if (Expansions) - std::uninitialized_copy(Expansions, Expansions + NumExpandedParams, + ArrayRef<TemplateParameterList *> Expansions) + : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), + TemplateParmPosition(D, P), ParameterPack(true), + ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) { + if (!Expansions.empty()) + std::uninitialized_copy(Expansions.begin(), Expansions.end(), getTrailingObjects<TemplateParameterList *>()); } @@ -650,8 +624,7 @@ TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, ArrayRef<TemplateParameterList *> Expansions) { return new (C, DC, additionalSizeToAlloc<TemplateParameterList *>(Expansions.size())) - TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions.size(), - Expansions.data()); + TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions); } TemplateTemplateParmDecl * @@ -663,10 +636,12 @@ TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { TemplateTemplateParmDecl * TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, unsigned NumExpansions) { - return new (C, ID, - additionalSizeToAlloc<TemplateParameterList *>(NumExpansions)) - TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr, - nullptr, NumExpansions, nullptr); + auto *TTP = + new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions)) + TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr, + nullptr, None); + TTP->NumExpandedParams = NumExpansions; + return TTP; } SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const { @@ -685,19 +660,18 @@ void TemplateTemplateParmDecl::setDefaultArgument( //===----------------------------------------------------------------------===// // TemplateArgumentList Implementation //===----------------------------------------------------------------------===// -TemplateArgumentList::TemplateArgumentList(const TemplateArgument *Args, - unsigned NumArgs) - : Arguments(getTrailingObjects<TemplateArgument>()), NumArguments(NumArgs) { - std::uninitialized_copy(Args, Args + NumArgs, +TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args) + : Arguments(getTrailingObjects<TemplateArgument>()), + NumArguments(Args.size()) { + std::uninitialized_copy(Args.begin(), Args.end(), getTrailingObjects<TemplateArgument>()); } TemplateArgumentList * TemplateArgumentList::CreateCopy(ASTContext &Context, - const TemplateArgument *Args, - unsigned NumArgs) { - void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(NumArgs)); - return new (Mem) TemplateArgumentList(Args, NumArgs); + ArrayRef<TemplateArgument> Args) { + void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size())); + return new (Mem) TemplateArgumentList(Args); } FunctionTemplateSpecializationInfo * @@ -732,15 +706,14 @@ ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef<TemplateArgument> Args, ClassTemplateSpecializationDecl *PrevDecl) : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc, SpecializedTemplate->getIdentifier(), PrevDecl), SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr), - TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)), + TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)), SpecializationKind(TSK_Undeclared) { } @@ -756,13 +729,12 @@ ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef<TemplateArgument> Args, ClassTemplateSpecializationDecl *PrevDecl) { ClassTemplateSpecializationDecl *Result = new (Context, DC) ClassTemplateSpecializationDecl( Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc, - SpecializedTemplate, Args, NumArgs, PrevDecl); + SpecializedTemplate, Args, PrevDecl); Result->MayHaveOutOfDateDef = false; Context.getTypeDeclType(Result, PrevDecl); @@ -784,7 +756,7 @@ void ClassTemplateSpecializationDecl::getNameForDiagnostic( const TemplateArgumentList &TemplateArgs = getTemplateArgs(); TemplateSpecializationType::PrintTemplateArgumentList( - OS, TemplateArgs.data(), TemplateArgs.size(), Policy); + OS, TemplateArgs.asArray(), Policy); } ClassTemplateDecl * @@ -806,7 +778,7 @@ ClassTemplateSpecializationDecl::getSourceRange() const { getSpecializationKind() == TSK_ExplicitInstantiationDefinition); if (getExternLoc().isValid()) Begin = getExternLoc(); - SourceLocation End = getRBraceLoc(); + SourceLocation End = getBraceRange().getEnd(); if (End.isInvalid()) End = getTypeAsWritten()->getTypeLoc().getEndLoc(); return SourceRange(Begin, End); @@ -846,15 +818,14 @@ ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK, SourceLocation IdLoc, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef<TemplateArgument> Args, const ASTTemplateArgumentListInfo *ArgInfos, ClassTemplatePartialSpecializationDecl *PrevDecl) : ClassTemplateSpecializationDecl(Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc, SpecializedTemplate, - Args, NumArgs, PrevDecl), + Args, PrevDecl), TemplateParams(Params), ArgsAsWritten(ArgInfos), InstantiatedFromMember(nullptr, false) { @@ -867,8 +838,7 @@ Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef<TemplateArgument> Args, const TemplateArgumentListInfo &ArgInfos, QualType CanonInjectedType, ClassTemplatePartialSpecializationDecl *PrevDecl) { @@ -878,7 +848,7 @@ Create(ASTContext &Context, TagKind TK,DeclContext *DC, ClassTemplatePartialSpecializationDecl *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args, - NumArgs, ASTArgInfos, PrevDecl); + ASTArgInfos, PrevDecl); Result->setSpecializationKind(TSK_ExplicitSpecialization); Result->MayHaveOutOfDateDef = false; @@ -901,15 +871,12 @@ ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, void FriendTemplateDecl::anchor() { } -FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context, - DeclContext *DC, - SourceLocation L, - unsigned NParams, - TemplateParameterList **Params, - FriendUnion Friend, - SourceLocation FLoc) { - return new (Context, DC) FriendTemplateDecl(DC, L, NParams, Params, - Friend, FLoc); +FriendTemplateDecl * +FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC, + SourceLocation L, + MutableArrayRef<TemplateParameterList *> Params, + FriendUnion Friend, SourceLocation FLoc) { + return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc); } FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, @@ -1065,23 +1032,17 @@ void VarTemplateDecl::getPartialSpecializations( getPartialSpecializations(); PS.clear(); PS.reserve(PartialSpecs.size()); - for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator - P = PartialSpecs.begin(), - PEnd = PartialSpecs.end(); - P != PEnd; ++P) - PS.push_back(P->getMostRecentDecl()); + for (VarTemplatePartialSpecializationDecl &P : PartialSpecs) + PS.push_back(P.getMostRecentDecl()); } VarTemplatePartialSpecializationDecl * VarTemplateDecl::findPartialSpecInstantiatedFromMember( VarTemplatePartialSpecializationDecl *D) { Decl *DCanon = D->getCanonicalDecl(); - for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator - P = getPartialSpecializations().begin(), - PEnd = getPartialSpecializations().end(); - P != PEnd; ++P) { - if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon) - return P->getMostRecentDecl(); + for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) { + if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon) + return P.getMostRecentDecl(); } return nullptr; @@ -1093,12 +1054,11 @@ VarTemplateDecl::findPartialSpecInstantiatedFromMember( VarTemplateSpecializationDecl::VarTemplateSpecializationDecl( Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, - TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, - unsigned NumArgs) + TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) : VarDecl(DK, Context, DC, StartLoc, IdLoc, SpecializedTemplate->getIdentifier(), T, TInfo, S), SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr), - TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)), + TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)), SpecializationKind(TSK_Undeclared) {} VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK, @@ -1110,11 +1070,10 @@ VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK, VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, - TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, - unsigned NumArgs) { + TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) { return new (Context, DC) VarTemplateSpecializationDecl( VarTemplateSpecialization, Context, DC, StartLoc, IdLoc, - SpecializedTemplate, T, TInfo, S, Args, NumArgs); + SpecializedTemplate, T, TInfo, S, Args); } VarTemplateSpecializationDecl * @@ -1129,7 +1088,7 @@ void VarTemplateSpecializationDecl::getNameForDiagnostic( const TemplateArgumentList &TemplateArgs = getTemplateArgs(); TemplateSpecializationType::PrintTemplateArgumentList( - OS, TemplateArgs.data(), TemplateArgs.size(), Policy); + OS, TemplateArgs.asArray(), Policy); } VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const { @@ -1141,11 +1100,10 @@ VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const { void VarTemplateSpecializationDecl::setTemplateArgsInfo( const TemplateArgumentListInfo &ArgsInfo) { - unsigned N = ArgsInfo.size(); TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc()); TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc()); - for (unsigned I = 0; I != N; ++I) - TemplateArgsInfo.addArgument(ArgsInfo[I]); + for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments()) + TemplateArgsInfo.addArgument(Loc); } //===----------------------------------------------------------------------===// @@ -1157,11 +1115,11 @@ VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl( ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, - StorageClass S, const TemplateArgument *Args, unsigned NumArgs, + StorageClass S, ArrayRef<TemplateArgument> Args, const ASTTemplateArgumentListInfo *ArgInfos) : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context, DC, StartLoc, IdLoc, SpecializedTemplate, T, - TInfo, S, Args, NumArgs), + TInfo, S, Args), TemplateParams(Params), ArgsAsWritten(ArgInfos), InstantiatedFromMember(nullptr, false) { // TODO: The template parameters should be in DC by now. Verify. @@ -1173,7 +1131,7 @@ VarTemplatePartialSpecializationDecl::Create( ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, - StorageClass S, const TemplateArgument *Args, unsigned NumArgs, + StorageClass S, ArrayRef<TemplateArgument> Args, const TemplateArgumentListInfo &ArgInfos) { const ASTTemplateArgumentListInfo *ASTArgInfos = ASTTemplateArgumentListInfo::Create(Context, ArgInfos); @@ -1181,7 +1139,7 @@ VarTemplatePartialSpecializationDecl::Create( VarTemplatePartialSpecializationDecl *Result = new (Context, DC) VarTemplatePartialSpecializationDecl( Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, - S, Args, NumArgs, ASTArgInfos); + S, Args, ASTArgInfos); Result->setSpecializationKind(TSK_ExplicitSpecialization); return Result; } @@ -1239,11 +1197,34 @@ createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) { Params, SourceLocation()); } +static TemplateParameterList * +createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) { + // std::size_t Index + TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType()); + auto *Index = NonTypeTemplateParmDecl::Create( + C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0, + /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo); + + // typename ...T + auto *Ts = TemplateTypeParmDecl::Create( + C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, + /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true); + Ts->setImplicit(true); + + // template <std::size_t Index, typename ...T> + NamedDecl *Params[] = {Index, Ts}; + return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), + llvm::makeArrayRef(Params), + SourceLocation()); +} + static TemplateParameterList *createBuiltinTemplateParameterList( const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) { switch (BTK) { case BTK__make_integer_seq: return createMakeIntegerSeqParameterList(C, DC); + case BTK__type_pack_element: + return createTypePackElementParameterList(C, DC); } llvm_unreachable("unhandled BuiltinTemplateKind!"); diff --git a/contrib/llvm/tools/clang/lib/AST/DeclarationName.cpp b/contrib/llvm/tools/clang/lib/AST/DeclarationName.cpp index b2f2727..2a988e1 100644 --- a/contrib/llvm/tools/clang/lib/AST/DeclarationName.cpp +++ b/contrib/llvm/tools/clang/lib/AST/DeclarationName.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// #include "clang/AST/ASTContext.h" -#include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" @@ -133,36 +133,45 @@ int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) { llvm_unreachable("Invalid DeclarationName Kind!"); } -raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) { +static void printCXXConstructorDestructorName(QualType ClassType, + raw_ostream &OS, + PrintingPolicy Policy) { + // We know we're printing C++ here. Ensure we print types properly. + Policy.adjustForCPlusPlus(); + + if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) { + OS << *ClassRec->getDecl(); + return; + } + if (Policy.SuppressTemplateArgsInCXXConstructors) { + if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) { + OS << *InjTy->getDecl(); + return; + } + } + ClassType.print(OS, Policy); +} + +void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) { + DeclarationName &N = *this; switch (N.getNameKind()) { case DeclarationName::Identifier: if (const IdentifierInfo *II = N.getAsIdentifierInfo()) OS << II->getName(); - return OS; + return; case DeclarationName::ObjCZeroArgSelector: case DeclarationName::ObjCOneArgSelector: case DeclarationName::ObjCMultiArgSelector: N.getObjCSelector().print(OS); - return OS; - - case DeclarationName::CXXConstructorName: { - QualType ClassType = N.getCXXNameType(); - if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) - return OS << *ClassRec->getDecl(); - LangOptions LO; - LO.CPlusPlus = true; - return OS << ClassType.getAsString(PrintingPolicy(LO)); - } + return; + + case DeclarationName::CXXConstructorName: + return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy); case DeclarationName::CXXDestructorName: { OS << '~'; - QualType Type = N.getCXXNameType(); - if (const RecordType *Rec = Type->getAs<RecordType>()) - return OS << *Rec->getDecl(); - LangOptions LO; - LO.CPlusPlus = true; - return OS << Type.getAsString(PrintingPolicy(LO)); + return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy); } case DeclarationName::CXXOperatorName: { @@ -178,29 +187,41 @@ raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) { OS << "operator"; if (OpName[0] >= 'a' && OpName[0] <= 'z') OS << ' '; - return OS << OpName; + OS << OpName; + return; } case DeclarationName::CXXLiteralOperatorName: - return OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName(); + OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName(); + return; case DeclarationName::CXXConversionFunctionName: { OS << "operator "; QualType Type = N.getCXXNameType(); - if (const RecordType *Rec = Type->getAs<RecordType>()) - return OS << *Rec->getDecl(); - LangOptions LO; - LO.CPlusPlus = true; - LO.Bool = true; - return OS << Type.getAsString(PrintingPolicy(LO)); + if (const RecordType *Rec = Type->getAs<RecordType>()) { + OS << *Rec->getDecl(); + return; + } + // We know we're printing C++ here, ensure we print 'bool' properly. + PrintingPolicy CXXPolicy = Policy; + CXXPolicy.adjustForCPlusPlus(); + Type.print(OS, CXXPolicy); + return; } case DeclarationName::CXXUsingDirective: - return OS << "<using-directive>"; + OS << "<using-directive>"; + return; } llvm_unreachable("Unexpected declaration name kind"); } +raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) { + LangOptions LO; + N.print(OS, PrintingPolicy(LO)); + return OS; +} + } // end namespace clang DeclarationName::NameKind DeclarationName::getNameKind() const { @@ -333,7 +354,7 @@ DeclarationName DeclarationName::getUsingDirectiveName() { return DeclarationName(Ptr); } -void DeclarationName::dump() const { +LLVM_DUMP_METHOD void DeclarationName::dump() const { llvm::errs() << *this << '\n'; } diff --git a/contrib/llvm/tools/clang/lib/AST/Expr.cpp b/contrib/llvm/tools/clang/lib/AST/Expr.cpp index 52f34df..091e878 100644 --- a/contrib/llvm/tools/clang/lib/AST/Expr.cpp +++ b/contrib/llvm/tools/clang/lib/AST/Expr.cpp @@ -985,7 +985,7 @@ void StringLiteral::setString(const ASTContext &C, StringRef Str, break; } default: - assert(false && "unsupported CharByteWidth"); + llvm_unreachable("unsupported CharByteWidth"); } } @@ -1084,20 +1084,8 @@ StringLiteral::getLocationOfByte(unsigned ByteNo, const SourceManager &SM, /// corresponds to, e.g. "sizeof" or "[pre]++". StringRef UnaryOperator::getOpcodeStr(Opcode Op) { switch (Op) { - case UO_PostInc: return "++"; - case UO_PostDec: return "--"; - case UO_PreInc: return "++"; - case UO_PreDec: return "--"; - case UO_AddrOf: return "&"; - case UO_Deref: return "*"; - case UO_Plus: return "+"; - case UO_Minus: return "-"; - case UO_Not: return "~"; - case UO_LNot: return "!"; - case UO_Real: return "__real"; - case UO_Imag: return "__imag"; - case UO_Extension: return "__extension__"; - case UO_Coawait: return "co_await"; +#define UNARY_OPERATION(Name, Spelling) case UO_##Name: return Spelling; +#include "clang/AST/OperationKinds.def" } llvm_unreachable("Unknown unary operator"); } @@ -1138,28 +1126,23 @@ OverloadedOperatorKind UnaryOperator::getOverloadedOperator(Opcode Opc) { // Postfix Operators. //===----------------------------------------------------------------------===// -CallExpr::CallExpr(const ASTContext& C, StmtClass SC, Expr *fn, - unsigned NumPreArgs, ArrayRef<Expr*> args, QualType t, +CallExpr::CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, + ArrayRef<Expr *> preargs, ArrayRef<Expr *> args, QualType t, ExprValueKind VK, SourceLocation rparenloc) - : Expr(SC, t, VK, OK_Ordinary, - fn->isTypeDependent(), - fn->isValueDependent(), - fn->isInstantiationDependent(), - fn->containsUnexpandedParameterPack()), - NumArgs(args.size()) { - - SubExprs = new (C) Stmt*[args.size()+PREARGS_START+NumPreArgs]; + : Expr(SC, t, VK, OK_Ordinary, fn->isTypeDependent(), + fn->isValueDependent(), fn->isInstantiationDependent(), + fn->containsUnexpandedParameterPack()), + NumArgs(args.size()) { + + unsigned NumPreArgs = preargs.size(); + SubExprs = new (C) Stmt *[args.size()+PREARGS_START+NumPreArgs]; SubExprs[FN] = fn; + for (unsigned i = 0; i != NumPreArgs; ++i) { + updateDependenciesFromArg(preargs[i]); + SubExprs[i+PREARGS_START] = preargs[i]; + } for (unsigned i = 0; i != args.size(); ++i) { - if (args[i]->isTypeDependent()) - ExprBits.TypeDependent = true; - if (args[i]->isValueDependent()) - ExprBits.ValueDependent = true; - if (args[i]->isInstantiationDependent()) - ExprBits.InstantiationDependent = true; - if (args[i]->containsUnexpandedParameterPack()) - ExprBits.ContainsUnexpandedParameterPack = true; - + updateDependenciesFromArg(args[i]); SubExprs[i+PREARGS_START+NumPreArgs] = args[i]; } @@ -1167,9 +1150,14 @@ CallExpr::CallExpr(const ASTContext& C, StmtClass SC, Expr *fn, RParenLoc = rparenloc; } +CallExpr::CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, + ArrayRef<Expr *> args, QualType t, ExprValueKind VK, + SourceLocation rparenloc) + : CallExpr(C, SC, fn, ArrayRef<Expr *>(), args, t, VK, rparenloc) {} + CallExpr::CallExpr(const ASTContext &C, Expr *fn, ArrayRef<Expr *> args, QualType t, ExprValueKind VK, SourceLocation rparenloc) - : CallExpr(C, CallExprClass, fn, /*NumPreArgs=*/0, args, t, VK, rparenloc) { + : CallExpr(C, CallExprClass, fn, ArrayRef<Expr *>(), args, t, VK, rparenloc) { } CallExpr::CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty) @@ -1179,10 +1167,21 @@ CallExpr::CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs, EmptyShell Empty) : Expr(SC, Empty), SubExprs(nullptr), NumArgs(0) { // FIXME: Why do we allocate this? - SubExprs = new (C) Stmt*[PREARGS_START+NumPreArgs]; + SubExprs = new (C) Stmt*[PREARGS_START+NumPreArgs](); CallExprBits.NumPreArgs = NumPreArgs; } +void CallExpr::updateDependenciesFromArg(Expr *Arg) { + if (Arg->isTypeDependent()) + ExprBits.TypeDependent = true; + if (Arg->isValueDependent()) + ExprBits.ValueDependent = true; + if (Arg->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; + if (Arg->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; +} + Decl *CallExpr::getCalleeDecl() { Expr *CEE = getCallee()->IgnoreParenImpCasts(); @@ -1597,120 +1596,9 @@ bool CastExpr::CastConsistency() const { const char *CastExpr::getCastKindName() const { switch (getCastKind()) { - case CK_Dependent: - return "Dependent"; - case CK_BitCast: - return "BitCast"; - case CK_LValueBitCast: - return "LValueBitCast"; - case CK_LValueToRValue: - return "LValueToRValue"; - case CK_NoOp: - return "NoOp"; - case CK_BaseToDerived: - return "BaseToDerived"; - case CK_DerivedToBase: - return "DerivedToBase"; - case CK_UncheckedDerivedToBase: - return "UncheckedDerivedToBase"; - case CK_Dynamic: - return "Dynamic"; - case CK_ToUnion: - return "ToUnion"; - case CK_ArrayToPointerDecay: - return "ArrayToPointerDecay"; - case CK_FunctionToPointerDecay: - return "FunctionToPointerDecay"; - case CK_NullToMemberPointer: - return "NullToMemberPointer"; - case CK_NullToPointer: - return "NullToPointer"; - case CK_BaseToDerivedMemberPointer: - return "BaseToDerivedMemberPointer"; - case CK_DerivedToBaseMemberPointer: - return "DerivedToBaseMemberPointer"; - case CK_ReinterpretMemberPointer: - return "ReinterpretMemberPointer"; - case CK_UserDefinedConversion: - return "UserDefinedConversion"; - case CK_ConstructorConversion: - return "ConstructorConversion"; - case CK_IntegralToPointer: - return "IntegralToPointer"; - case CK_PointerToIntegral: - return "PointerToIntegral"; - case CK_PointerToBoolean: - return "PointerToBoolean"; - case CK_ToVoid: - return "ToVoid"; - case CK_VectorSplat: - return "VectorSplat"; - case CK_IntegralCast: - return "IntegralCast"; - case CK_BooleanToSignedIntegral: - return "BooleanToSignedIntegral"; - case CK_IntegralToBoolean: - return "IntegralToBoolean"; - case CK_IntegralToFloating: - return "IntegralToFloating"; - case CK_FloatingToIntegral: - return "FloatingToIntegral"; - case CK_FloatingCast: - return "FloatingCast"; - case CK_FloatingToBoolean: - return "FloatingToBoolean"; - case CK_MemberPointerToBoolean: - return "MemberPointerToBoolean"; - case CK_CPointerToObjCPointerCast: - return "CPointerToObjCPointerCast"; - case CK_BlockPointerToObjCPointerCast: - return "BlockPointerToObjCPointerCast"; - case CK_AnyPointerToBlockPointerCast: - return "AnyPointerToBlockPointerCast"; - case CK_ObjCObjectLValueCast: - return "ObjCObjectLValueCast"; - case CK_FloatingRealToComplex: - return "FloatingRealToComplex"; - case CK_FloatingComplexToReal: - return "FloatingComplexToReal"; - case CK_FloatingComplexToBoolean: - return "FloatingComplexToBoolean"; - case CK_FloatingComplexCast: - return "FloatingComplexCast"; - case CK_FloatingComplexToIntegralComplex: - return "FloatingComplexToIntegralComplex"; - case CK_IntegralRealToComplex: - return "IntegralRealToComplex"; - case CK_IntegralComplexToReal: - return "IntegralComplexToReal"; - case CK_IntegralComplexToBoolean: - return "IntegralComplexToBoolean"; - case CK_IntegralComplexCast: - return "IntegralComplexCast"; - case CK_IntegralComplexToFloatingComplex: - return "IntegralComplexToFloatingComplex"; - case CK_ARCConsumeObject: - return "ARCConsumeObject"; - case CK_ARCProduceObject: - return "ARCProduceObject"; - case CK_ARCReclaimReturnedObject: - return "ARCReclaimReturnedObject"; - case CK_ARCExtendBlockObject: - return "ARCExtendBlockObject"; - case CK_AtomicToNonAtomic: - return "AtomicToNonAtomic"; - case CK_NonAtomicToAtomic: - return "NonAtomicToAtomic"; - case CK_CopyAndAutoreleaseBlockObject: - return "CopyAndAutoreleaseBlockObject"; - case CK_BuiltinFnToFnPtr: - return "BuiltinFnToFnPtr"; - case CK_ZeroToOCLEvent: - return "ZeroToOCLEvent"; - case CK_AddressSpaceConversion: - return "AddressSpaceConversion"; +#define CAST_OPERATION(Name) case CK_##Name: return #Name; +#include "clang/AST/OperationKinds.def" } - llvm_unreachable("Unhandled cast kind!"); } @@ -1733,8 +1621,13 @@ Expr *CastExpr::getSubExprAsWritten() { // subexpression describing the call; strip it off. if (E->getCastKind() == CK_ConstructorConversion) SubExpr = cast<CXXConstructExpr>(SubExpr)->getArg(0); - else if (E->getCastKind() == CK_UserDefinedConversion) - SubExpr = cast<CXXMemberCallExpr>(SubExpr)->getImplicitObjectArgument(); + else if (E->getCastKind() == CK_UserDefinedConversion) { + assert((isa<CXXMemberCallExpr>(SubExpr) || + isa<BlockExpr>(SubExpr)) && + "Unexpected SubExpr for CK_UserDefinedConversion."); + if (isa<CXXMemberCallExpr>(SubExpr)) + SubExpr = cast<CXXMemberCallExpr>(SubExpr)->getImplicitObjectArgument(); + } // If the subexpression we're left with is an implicit cast, look // through that, too. @@ -1802,40 +1695,9 @@ CStyleCastExpr *CStyleCastExpr::CreateEmpty(const ASTContext &C, /// corresponds to, e.g. "<<=". StringRef BinaryOperator::getOpcodeStr(Opcode Op) { switch (Op) { - case BO_PtrMemD: return ".*"; - case BO_PtrMemI: return "->*"; - case BO_Mul: return "*"; - case BO_Div: return "/"; - case BO_Rem: return "%"; - case BO_Add: return "+"; - case BO_Sub: return "-"; - case BO_Shl: return "<<"; - case BO_Shr: return ">>"; - case BO_LT: return "<"; - case BO_GT: return ">"; - case BO_LE: return "<="; - case BO_GE: return ">="; - case BO_EQ: return "=="; - case BO_NE: return "!="; - case BO_And: return "&"; - case BO_Xor: return "^"; - case BO_Or: return "|"; - case BO_LAnd: return "&&"; - case BO_LOr: return "||"; - case BO_Assign: return "="; - case BO_MulAssign: return "*="; - case BO_DivAssign: return "/="; - case BO_RemAssign: return "%="; - case BO_AddAssign: return "+="; - case BO_SubAssign: return "-="; - case BO_ShlAssign: return "<<="; - case BO_ShrAssign: return ">>="; - case BO_AndAssign: return "&="; - case BO_XorAssign: return "^="; - case BO_OrAssign: return "|="; - case BO_Comma: return ","; +#define BINARY_OPERATION(Name, Spelling) case BO_##Name: return Spelling; +#include "clang/AST/OperationKinds.def" } - llvm_unreachable("Invalid OpCode!"); } @@ -2994,6 +2856,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, case ObjCStringLiteralClass: case ObjCEncodeExprClass: case ObjCBoolLiteralExprClass: + case ObjCAvailabilityCheckExprClass: case CXXUuidofExprClass: case OpaqueValueExprClass: // These never have a side-effect. @@ -3028,7 +2891,6 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, case CXXThrowExprClass: case CXXNewExprClass: case CXXDeleteExprClass: - case ExprWithCleanupsClass: case CoawaitExprClass: case CoyieldExprClass: // These always have a side-effect. @@ -3041,6 +2903,12 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, return Finder.hasSideEffects(); } + case ExprWithCleanupsClass: + if (IncludePossibleEffects) + if (cast<ExprWithCleanups>(this)->cleanupsHaveSideEffects()) + return true; + break; + case ParenExprClass: case ArraySubscriptExprClass: case OMPArraySectionExprClass: @@ -3141,6 +3009,13 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, break; } + case CXXInheritedCtorInitExprClass: { + const auto *ICIE = cast<CXXInheritedCtorInitExpr>(this); + if (!ICIE->getConstructor()->isTrivial() && IncludePossibleEffects) + return true; + break; + } + case LambdaExprClass: { const LambdaExpr *LE = cast<LambdaExpr>(this); for (LambdaExpr::capture_iterator I = LE->capture_begin(), @@ -3643,8 +3518,7 @@ IdentifierInfo *DesignatedInitExpr::Designator::getFieldName() const { } DesignatedInitExpr::DesignatedInitExpr(const ASTContext &C, QualType Ty, - unsigned NumDesignators, - const Designator *Designators, + llvm::ArrayRef<Designator> Designators, SourceLocation EqualOrColonLoc, bool GNUSyntax, ArrayRef<Expr*> IndexExprs, @@ -3655,7 +3529,7 @@ DesignatedInitExpr::DesignatedInitExpr(const ASTContext &C, QualType Ty, Init->isInstantiationDependent(), Init->containsUnexpandedParameterPack()), EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax), - NumDesignators(NumDesignators), NumSubExprs(IndexExprs.size() + 1) { + NumDesignators(Designators.size()), NumSubExprs(IndexExprs.size() + 1) { this->Designators = new (C) Designator[NumDesignators]; // Record the initializer itself. @@ -3709,14 +3583,14 @@ DesignatedInitExpr::DesignatedInitExpr(const ASTContext &C, QualType Ty, } DesignatedInitExpr * -DesignatedInitExpr::Create(const ASTContext &C, Designator *Designators, - unsigned NumDesignators, +DesignatedInitExpr::Create(const ASTContext &C, + llvm::ArrayRef<Designator> Designators, ArrayRef<Expr*> IndexExprs, SourceLocation ColonOrEqualLoc, bool UsesColonSyntax, Expr *Init) { void *Mem = C.Allocate(totalSizeToAlloc<Stmt *>(IndexExprs.size() + 1), llvm::alignOf<DesignatedInitExpr>()); - return new (Mem) DesignatedInitExpr(C, C.VoidTy, NumDesignators, Designators, + return new (Mem) DesignatedInitExpr(C, C.VoidTy, Designators, ColonOrEqualLoc, UsesColonSyntax, IndexExprs, Init); } @@ -3747,8 +3621,8 @@ SourceRange DesignatedInitExpr::getDesignatorsSourceRange() const { SourceLocation DesignatedInitExpr::getLocStart() const { SourceLocation StartLoc; - Designator &First = - *const_cast<DesignatedInitExpr*>(this)->designators_begin(); + auto *DIE = const_cast<DesignatedInitExpr *>(this); + Designator &First = *DIE->getDesignator(0); if (First.isFieldDesignator()) { if (GNUSyntax) StartLoc = SourceLocation::getFromRawEncoding(First.Field.FieldLoc); @@ -4010,16 +3884,18 @@ unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) { llvm_unreachable("unknown atomic op"); } -QualType OMPArraySectionExpr::getBaseOriginalType(Expr *Base) { +QualType OMPArraySectionExpr::getBaseOriginalType(const Expr *Base) { unsigned ArraySectionCount = 0; while (auto *OASE = dyn_cast<OMPArraySectionExpr>(Base->IgnoreParens())) { Base = OASE->getBase(); ++ArraySectionCount; } - while (auto *ASE = dyn_cast<ArraySubscriptExpr>(Base->IgnoreParens())) { + while (auto *ASE = + dyn_cast<ArraySubscriptExpr>(Base->IgnoreParenImpCasts())) { Base = ASE->getBase(); ++ArraySectionCount; } + Base = Base->IgnoreParenImpCasts(); auto OriginalTy = Base->getType(); if (auto *DRE = dyn_cast<DeclRefExpr>(Base)) if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) diff --git a/contrib/llvm/tools/clang/lib/AST/ExprCXX.cpp b/contrib/llvm/tools/clang/lib/AST/ExprCXX.cpp index ea98334..a13033d 100644 --- a/contrib/llvm/tools/clang/lib/AST/ExprCXX.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ExprCXX.cpp @@ -54,79 +54,6 @@ QualType CXXUuidofExpr::getTypeOperand(ASTContext &Context) const { Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType(), Quals); } -// static -const UuidAttr *CXXUuidofExpr::GetUuidAttrOfType(QualType QT, - bool *RDHasMultipleGUIDsPtr) { - // Optionally remove one level of pointer, reference or array indirection. - const Type *Ty = QT.getTypePtr(); - if (QT->isPointerType() || QT->isReferenceType()) - Ty = QT->getPointeeType().getTypePtr(); - else if (QT->isArrayType()) - Ty = Ty->getBaseElementTypeUnsafe(); - - const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); - if (!RD) - return nullptr; - - if (const UuidAttr *Uuid = RD->getMostRecentDecl()->getAttr<UuidAttr>()) - return Uuid; - - // __uuidof can grab UUIDs from template arguments. - if (const ClassTemplateSpecializationDecl *CTSD = - dyn_cast<ClassTemplateSpecializationDecl>(RD)) { - const TemplateArgumentList &TAL = CTSD->getTemplateArgs(); - const UuidAttr *UuidForRD = nullptr; - - for (const TemplateArgument &TA : TAL.asArray()) { - bool SeenMultipleGUIDs = false; - - const UuidAttr *UuidForTA = nullptr; - if (TA.getKind() == TemplateArgument::Type) - UuidForTA = GetUuidAttrOfType(TA.getAsType(), &SeenMultipleGUIDs); - else if (TA.getKind() == TemplateArgument::Declaration) - UuidForTA = - GetUuidAttrOfType(TA.getAsDecl()->getType(), &SeenMultipleGUIDs); - - // If the template argument has a UUID, there are three cases: - // - This is the first UUID seen for this RecordDecl. - // - This is a different UUID than previously seen for this RecordDecl. - // - This is the same UUID than previously seen for this RecordDecl. - if (UuidForTA) { - if (!UuidForRD) - UuidForRD = UuidForTA; - else if (UuidForRD != UuidForTA) - SeenMultipleGUIDs = true; - } - - // Seeing multiple UUIDs means that we couldn't find a UUID - if (SeenMultipleGUIDs) { - if (RDHasMultipleGUIDsPtr) - *RDHasMultipleGUIDsPtr = true; - return nullptr; - } - } - - return UuidForRD; - } - - return nullptr; -} - -StringRef CXXUuidofExpr::getUuidAsStringRef(ASTContext &Context) const { - StringRef Uuid; - if (isTypeOperand()) - Uuid = CXXUuidofExpr::GetUuidAttrOfType(getTypeOperand(Context))->getGuid(); - else { - // Special case: __uuidof(0) means an all-zero GUID. - Expr *Op = getExprOperand(); - if (!Op->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) - Uuid = CXXUuidofExpr::GetUuidAttrOfType(Op->getType())->getGuid(); - else - Uuid = "00000000-0000-0000-0000-000000000000"; - } - return Uuid; -} - // CXXScalarValueInitExpr SourceLocation CXXScalarValueInitExpr::getLocStart() const { return TypeInfo ? TypeInfo->getTypeLoc().getBeginLoc() : RParenLoc; @@ -823,7 +750,8 @@ SourceLocation CXXTemporaryObjectExpr::getLocEnd() const { CXXConstructExpr *CXXConstructExpr::Create(const ASTContext &C, QualType T, SourceLocation Loc, - CXXConstructorDecl *D, bool Elidable, + CXXConstructorDecl *Ctor, + bool Elidable, ArrayRef<Expr*> Args, bool HadMultipleCandidates, bool ListInitialization, @@ -831,8 +759,8 @@ CXXConstructExpr *CXXConstructExpr::Create(const ASTContext &C, QualType T, bool ZeroInitialization, ConstructionKind ConstructKind, SourceRange ParenOrBraceRange) { - return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D, - Elidable, Args, + return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, + Ctor, Elidable, Args, HadMultipleCandidates, ListInitialization, StdInitListInitialization, ZeroInitialization, ConstructKind, @@ -841,8 +769,9 @@ CXXConstructExpr *CXXConstructExpr::Create(const ASTContext &C, QualType T, CXXConstructExpr::CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T, SourceLocation Loc, - CXXConstructorDecl *D, bool elidable, - ArrayRef<Expr*> args, + CXXConstructorDecl *Ctor, + bool Elidable, + ArrayRef<Expr*> Args, bool HadMultipleCandidates, bool ListInitialization, bool StdInitListInitialization, @@ -853,28 +782,28 @@ CXXConstructExpr::CXXConstructExpr(const ASTContext &C, StmtClass SC, T->isDependentType(), T->isDependentType(), T->isInstantiationDependentType(), T->containsUnexpandedParameterPack()), - Constructor(D), Loc(Loc), ParenOrBraceRange(ParenOrBraceRange), - NumArgs(args.size()), - Elidable(elidable), HadMultipleCandidates(HadMultipleCandidates), + Constructor(Ctor), Loc(Loc), ParenOrBraceRange(ParenOrBraceRange), + NumArgs(Args.size()), + Elidable(Elidable), HadMultipleCandidates(HadMultipleCandidates), ListInitialization(ListInitialization), StdInitListInitialization(StdInitListInitialization), ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind), Args(nullptr) { if (NumArgs) { - Args = new (C) Stmt*[args.size()]; + this->Args = new (C) Stmt*[Args.size()]; - for (unsigned i = 0; i != args.size(); ++i) { - assert(args[i] && "NULL argument in CXXConstructExpr"); + for (unsigned i = 0; i != Args.size(); ++i) { + assert(Args[i] && "NULL argument in CXXConstructExpr"); - if (args[i]->isValueDependent()) + if (Args[i]->isValueDependent()) ExprBits.ValueDependent = true; - if (args[i]->isInstantiationDependent()) + if (Args[i]->isInstantiationDependent()) ExprBits.InstantiationDependent = true; - if (args[i]->containsUnexpandedParameterPack()) + if (Args[i]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; - Args[i] = args[i]; + this->Args[i] = Args[i]; } } } @@ -889,8 +818,12 @@ LambdaCapture::LambdaCapture(SourceLocation Loc, bool Implicit, Bits |= Capture_Implicit; switch (Kind) { + case LCK_StarThis: + Bits |= Capture_ByCopy; + // Fall through case LCK_This: assert(!Var && "'this' capture cannot have a variable!"); + Bits |= Capture_This; break; case LCK_ByCopy: @@ -901,18 +834,17 @@ LambdaCapture::LambdaCapture(SourceLocation Loc, bool Implicit, break; case LCK_VLAType: assert(!Var && "VLA type capture cannot have a variable!"); - Bits |= Capture_ByCopy; break; } DeclAndBits.setInt(Bits); } LambdaCaptureKind LambdaCapture::getCaptureKind() const { - Decl *D = DeclAndBits.getPointer(); + if (capturesVLAType()) + return LCK_VLAType; bool CapByCopy = DeclAndBits.getInt() & Capture_ByCopy; - if (!D) - return CapByCopy ? LCK_VLAType : LCK_This; - + if (capturesThis()) + return CapByCopy ? LCK_StarThis : LCK_This; return CapByCopy ? LCK_ByCopy : LCK_ByRef; } @@ -1091,6 +1023,7 @@ bool LambdaExpr::isMutable() const { } ExprWithCleanups::ExprWithCleanups(Expr *subexpr, + bool CleanupsHaveSideEffects, ArrayRef<CleanupObject> objects) : Expr(ExprWithCleanupsClass, subexpr->getType(), subexpr->getValueKind(), subexpr->getObjectKind(), @@ -1098,16 +1031,19 @@ ExprWithCleanups::ExprWithCleanups(Expr *subexpr, subexpr->isInstantiationDependent(), subexpr->containsUnexpandedParameterPack()), SubExpr(subexpr) { + ExprWithCleanupsBits.CleanupsHaveSideEffects = CleanupsHaveSideEffects; ExprWithCleanupsBits.NumObjects = objects.size(); for (unsigned i = 0, e = objects.size(); i != e; ++i) getTrailingObjects<CleanupObject>()[i] = objects[i]; } ExprWithCleanups *ExprWithCleanups::Create(const ASTContext &C, Expr *subexpr, + bool CleanupsHaveSideEffects, ArrayRef<CleanupObject> objects) { void *buffer = C.Allocate(totalSizeToAlloc<CleanupObject>(objects.size()), llvm::alignOf<ExprWithCleanups>()); - return new (buffer) ExprWithCleanups(subexpr, objects); + return new (buffer) + ExprWithCleanups(subexpr, CleanupsHaveSideEffects, objects); } ExprWithCleanups::ExprWithCleanups(EmptyShell empty, unsigned numObjects) diff --git a/contrib/llvm/tools/clang/lib/AST/ExprClassification.cpp b/contrib/llvm/tools/clang/lib/AST/ExprClassification.cpp index a47b03c..89cc9bc 100644 --- a/contrib/llvm/tools/clang/lib/AST/ExprClassification.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ExprClassification.cpp @@ -178,6 +178,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::ObjCArrayLiteralClass: case Expr::ObjCDictionaryLiteralClass: case Expr::ObjCBoolLiteralExprClass: + case Expr::ObjCAvailabilityCheckExprClass: case Expr::ParenListExprClass: case Expr::SizeOfPackExprClass: case Expr::SubstNonTypeTemplateParmPackExprClass: @@ -360,6 +361,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { // Some C++ expressions are always class temporaries. case Expr::CXXConstructExprClass: + case Expr::CXXInheritedCtorInitExprClass: case Expr::CXXTemporaryObjectExprClass: case Expr::LambdaExprClass: case Expr::CXXStdInitializerListExprClass: diff --git a/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp b/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp index fa652ba..df944e8 100644 --- a/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp @@ -157,13 +157,13 @@ namespace { /// True if the subobject was named in a manner not supported by C++11. Such /// lvalues can still be folded, but they are not core constant expressions /// and we cannot perform lvalue-to-rvalue conversions on them. - bool Invalid : 1; + unsigned Invalid : 1; /// Is this a pointer one past the end of an object? - bool IsOnePastTheEnd : 1; + unsigned IsOnePastTheEnd : 1; /// Indicator of whether the most-derived object is an array element. - bool MostDerivedIsArrayElement : 1; + unsigned MostDerivedIsArrayElement : 1; /// The length of the path to the most-derived object of which this is a /// subobject. @@ -477,6 +477,9 @@ namespace { /// fold (not just why it's not strictly a constant expression)? bool HasFoldFailureDiagnostic; + /// \brief Whether or not we're currently speculatively evaluating. + bool IsSpeculativelyEvaluating; + enum EvaluationMode { /// Evaluate as a constant expression. Stop if we find that the expression /// is not a constant expression. @@ -541,7 +544,8 @@ namespace { BottomFrame(*this, SourceLocation(), nullptr, nullptr, nullptr), EvaluatingDecl((const ValueDecl *)nullptr), EvaluatingDeclValue(nullptr), HasActiveDiagnostic(false), - HasFoldFailureDiagnostic(false), EvalMode(Mode) {} + HasFoldFailureDiagnostic(false), IsSpeculativelyEvaluating(false), + EvalMode(Mode) {} void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value) { EvaluatingDecl = Base; @@ -557,12 +561,12 @@ namespace { return false; if (NextCallIndex == 0) { // NextCallIndex has wrapped around. - Diag(Loc, diag::note_constexpr_call_limit_exceeded); + FFDiag(Loc, diag::note_constexpr_call_limit_exceeded); return false; } if (CallStackDepth <= getLangOpts().ConstexprCallDepth) return true; - Diag(Loc, diag::note_constexpr_depth_limit_exceeded) + FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded) << getLangOpts().ConstexprCallDepth; return false; } @@ -579,7 +583,7 @@ namespace { bool nextStep(const Stmt *S) { if (!StepsLeft) { - Diag(S->getLocStart(), diag::note_constexpr_step_limit_exceeded); + FFDiag(S->getLocStart(), diag::note_constexpr_step_limit_exceeded); return false; } --StepsLeft; @@ -597,11 +601,10 @@ namespace { /// Add notes containing a call stack to the current point of evaluation. void addCallStack(unsigned Limit); - public: - /// Diagnose that the evaluation cannot be folded. - OptionalDiagnostic Diag(SourceLocation Loc, diag::kind DiagId - = diag::note_invalid_subexpr_in_const_expr, - unsigned ExtraNotes = 0, bool IsCCEDiag = false) { + private: + OptionalDiagnostic Diag(SourceLocation Loc, diag::kind DiagId, + unsigned ExtraNotes, bool IsCCEDiag) { + if (EvalStatus.Diag) { // If we have a prior diagnostic, it will be noting that the expression // isn't a constant expression. This diagnostic is more important, @@ -646,12 +649,20 @@ namespace { HasActiveDiagnostic = false; return OptionalDiagnostic(); } - - OptionalDiagnostic Diag(const Expr *E, diag::kind DiagId + public: + // Diagnose that the evaluation could not be folded (FF => FoldFailure) + OptionalDiagnostic + FFDiag(SourceLocation Loc, + diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr, + unsigned ExtraNotes = 0) { + return Diag(Loc, DiagId, ExtraNotes, false); + } + + OptionalDiagnostic FFDiag(const Expr *E, diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr, - unsigned ExtraNotes = 0, bool IsCCEDiag = false) { + unsigned ExtraNotes = 0) { if (EvalStatus.Diag) - return Diag(E->getExprLoc(), DiagId, ExtraNotes, IsCCEDiag); + return Diag(E->getExprLoc(), DiagId, ExtraNotes, /*IsCCEDiag*/false); HasActiveDiagnostic = false; return OptionalDiagnostic(); } @@ -661,8 +672,7 @@ namespace { /// /// FIXME: Stop evaluating if we're in EM_ConstantExpression or /// EM_PotentialConstantExpression mode and we produce one of these. - template<typename LocArg> - OptionalDiagnostic CCEDiag(LocArg Loc, diag::kind DiagId + OptionalDiagnostic CCEDiag(SourceLocation Loc, diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr, unsigned ExtraNotes = 0) { // Don't override a previous diagnostic. Don't bother collecting @@ -673,7 +683,11 @@ namespace { } return Diag(Loc, DiagId, ExtraNotes, true); } - + OptionalDiagnostic CCEDiag(const Expr *E, diag::kind DiagId + = diag::note_invalid_subexpr_in_const_expr, + unsigned ExtraNotes = 0) { + return CCEDiag(E->getExprLoc(), DiagId, ExtraNotes); + } /// Add a note to a prior diagnostic. OptionalDiagnostic Note(SourceLocation Loc, diag::kind DiagId) { if (!HasActiveDiagnostic) @@ -763,6 +777,29 @@ namespace { llvm_unreachable("Missed EvalMode case"); } + /// Notes that we failed to evaluate an expression that other expressions + /// directly depend on, and determine if we should keep evaluating. This + /// should only be called if we actually intend to keep evaluating. + /// + /// Call noteSideEffect() instead if we may be able to ignore the value that + /// we failed to evaluate, e.g. if we failed to evaluate Foo() in: + /// + /// (Foo(), 1) // use noteSideEffect + /// (Foo() || true) // use noteSideEffect + /// Foo() + 1 // use noteFailure + LLVM_ATTRIBUTE_UNUSED_RESULT bool noteFailure() { + // Failure when evaluating some expression often means there is some + // subexpression whose evaluation was skipped. Therefore, (because we + // don't track whether we skipped an expression when unwinding after an + // evaluation failure) every evaluation failure that bubbles up from a + // subexpression implies that a side-effect has potentially happened. We + // skip setting the HasSideEffects flag to true until we decide to + // continue evaluating after that point, which happens here. + bool KeepGoing = keepEvaluatingAfterFailure(); + EvalStatus.HasSideEffects |= KeepGoing; + return KeepGoing; + } + bool allowInvalidBaseExpr() const { return EvalMode == EM_DesignatorFold; } @@ -811,24 +848,52 @@ namespace { ~FoldOffsetRAII() { Info.EvalMode = OldMode; } }; - /// RAII object used to suppress diagnostics and side-effects from a - /// speculative evaluation. + /// RAII object used to optionally suppress diagnostics and side-effects from + /// a speculative evaluation. class SpeculativeEvaluationRAII { - EvalInfo &Info; + /// Pair of EvalInfo, and a bit that stores whether or not we were + /// speculatively evaluating when we created this RAII. + llvm::PointerIntPair<EvalInfo *, 1, bool> InfoAndOldSpecEval; Expr::EvalStatus Old; + void moveFromAndCancel(SpeculativeEvaluationRAII &&Other) { + InfoAndOldSpecEval = Other.InfoAndOldSpecEval; + Old = Other.Old; + Other.InfoAndOldSpecEval.setPointer(nullptr); + } + + void maybeRestoreState() { + EvalInfo *Info = InfoAndOldSpecEval.getPointer(); + if (!Info) + return; + + Info->EvalStatus = Old; + Info->IsSpeculativelyEvaluating = InfoAndOldSpecEval.getInt(); + } + public: - SpeculativeEvaluationRAII(EvalInfo &Info, - SmallVectorImpl<PartialDiagnosticAt> *NewDiag = nullptr) - : Info(Info), Old(Info.EvalStatus) { + SpeculativeEvaluationRAII() = default; + + SpeculativeEvaluationRAII( + EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag = nullptr) + : InfoAndOldSpecEval(&Info, Info.IsSpeculativelyEvaluating), + Old(Info.EvalStatus) { Info.EvalStatus.Diag = NewDiag; - // If we're speculatively evaluating, we may have skipped over some - // evaluations and missed out a side effect. - Info.EvalStatus.HasSideEffects = true; + Info.IsSpeculativelyEvaluating = true; } - ~SpeculativeEvaluationRAII() { - Info.EvalStatus = Old; + + SpeculativeEvaluationRAII(const SpeculativeEvaluationRAII &Other) = delete; + SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&Other) { + moveFromAndCancel(std::move(Other)); } + + SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&Other) { + maybeRestoreState(); + moveFromAndCancel(std::move(Other)); + return *this; + } + + ~SpeculativeEvaluationRAII() { maybeRestoreState(); } }; /// RAII object wrapping a full-expression or block scope, and handling @@ -941,6 +1006,16 @@ void EvalInfo::addCallStack(unsigned Limit) { continue; } + // Use a different note for an inheriting constructor, because from the + // user's perspective it's not really a function at all. + if (auto *CD = dyn_cast_or_null<CXXConstructorDecl>(Frame->Callee)) { + if (CD->isInheritingConstructor()) { + addDiag(Frame->CallLoc, diag::note_constexpr_inherited_ctor_call_here) + << CD->getParent(); + continue; + } + } + SmallVector<char, 128> Buffer; llvm::raw_svector_ostream Out(Buffer); describeCall(Frame, Out); @@ -992,7 +1067,7 @@ namespace { struct LValue { APValue::LValueBase Base; CharUnits Offset; - bool InvalidBase : 1; + unsigned InvalidBase : 1; unsigned CallIndex : 31; SubobjectDesignator Designator; @@ -1335,12 +1410,12 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, if (!IsGlobalLValue(Base)) { if (Info.getLangOpts().CPlusPlus11) { const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>(); - Info.Diag(Loc, diag::note_constexpr_non_global, 1) + Info.FFDiag(Loc, diag::note_constexpr_non_global, 1) << IsReferenceType << !Designator.Entries.empty() << !!VD << VD; NoteLValueLocation(Info, Base); } else { - Info.Diag(Loc); + Info.FFDiag(Loc); } // Don't allow references to temporaries to escape. return false; @@ -1390,7 +1465,7 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, // Does this refer one past the end of some object? if (!Designator.Invalid && Designator.isOnePastTheEnd()) { const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>(); - Info.Diag(Loc, diag::note_constexpr_past_end, 1) + Info.FFDiag(Loc, diag::note_constexpr_past_end, 1) << !Designator.Entries.empty() << !!VD << VD; NoteLValueLocation(Info, Base); } @@ -1414,10 +1489,10 @@ static bool CheckLiteralType(EvalInfo &Info, const Expr *E, // Prvalue constant expressions must be of literal types. if (Info.getLangOpts().CPlusPlus11) - Info.Diag(E, diag::note_constexpr_nonliteral) + Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->getType(); else - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); return false; } @@ -1427,7 +1502,7 @@ static bool CheckLiteralType(EvalInfo &Info, const Expr *E, static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value) { if (Value.isUninit()) { - Info.Diag(DiagLoc, diag::note_constexpr_uninitialized) + Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized) << true << Type; return false; } @@ -1637,7 +1712,7 @@ static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, // FIXME: In this case, we should provide the diagnostic for casting // a pointer to an integer. assert(Value.isLValue() && "integral value neither int nor lvalue?"); - Info.Diag(E); + Info.FFDiag(E); return false; } @@ -1679,7 +1754,7 @@ static bool EvalAndBitcastToAPInt(EvalInfo &Info, const Expr *E, } else { // Don't try to handle vectors of anything other than int or float // (not sure if it's possible to hit this case). - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); return false; } unsigned BaseEltSize = EltAsInt.getBitWidth(); @@ -1692,7 +1767,7 @@ static bool EvalAndBitcastToAPInt(EvalInfo &Info, const Expr *E, } // Give up if the input isn't an int, float, or vector. For example, we // reject "(v4i16)(intptr_t)&a". - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); return false; } @@ -1728,7 +1803,7 @@ static bool handleIntIntBinOp(EvalInfo &Info, const Expr *E, const APSInt &LHS, APSInt &Result) { switch (Opcode) { default: - Info.Diag(E); + Info.FFDiag(E); return false; case BO_Mul: return CheckedIntArithmetic(Info, E, LHS, RHS, LHS.getBitWidth() * 2, @@ -1745,7 +1820,7 @@ static bool handleIntIntBinOp(EvalInfo &Info, const Expr *E, const APSInt &LHS, case BO_Div: case BO_Rem: if (RHS == 0) { - Info.Diag(E, diag::note_expr_divide_by_zero); + Info.FFDiag(E, diag::note_expr_divide_by_zero); return false; } Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS); @@ -1826,7 +1901,7 @@ static bool handleFloatFloatBinOp(EvalInfo &Info, const Expr *E, const APFloat &RHS) { switch (Opcode) { default: - Info.Diag(E); + Info.FFDiag(E); return false; case BO_Mul: LHS.multiply(RHS, APFloat::rmNearestTiesToEven); @@ -1968,10 +2043,15 @@ static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, return true; } + if (Type->isDependentType()) { + Info.FFDiag(Loc); + return false; + } + if (!Type->isConstantSizeType()) { // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2. // FIXME: Better diagnostic. - Info.Diag(Loc); + Info.FFDiag(Loc); return false; } @@ -2035,7 +2115,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, if (Info.checkingPotentialConstantExpression()) return false; if (!Frame || !Frame->Arguments) { - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); return false; } Result = &Frame->Arguments[PVD->getFunctionScopeIndex()]; @@ -2055,7 +2135,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, // If we're checking a potential constant expression, the variable could be // initialized later. if (!Info.checkingPotentialConstantExpression()) - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); return false; } @@ -2069,7 +2149,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, // Never evaluate the initializer of a weak variable. We can't be sure that // this is the definition which will be used. if (VD->isWeak()) { - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); return false; } @@ -2077,7 +2157,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, // this in the cases where it matters for conformance. SmallVector<PartialDiagnosticAt, 8> Notes; if (!VD->evaluateValue(Notes)) { - Info.Diag(E, diag::note_constexpr_var_init_non_constant, + Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, Notes.size() + 1) << VD; Info.Note(VD->getLocation(), diag::note_declared_at); Info.addNotes(Notes); @@ -2218,7 +2298,7 @@ static bool diagnoseUnreadableFields(EvalInfo &Info, const Expr *E, // FIXME: Add core issue number for the union case. if (Field->isMutable() && (RD->isUnion() || isReadByLvalueToRvalueConversion(Field->getType()))) { - Info.Diag(E, diag::note_constexpr_ltor_mutable, 1) << Field; + Info.FFDiag(E, diag::note_constexpr_ltor_mutable, 1) << Field; Info.Note(Field->getLocation(), diag::note_declared_at); return true; } @@ -2272,10 +2352,10 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, return handler.failed(); if (Sub.isOnePastTheEnd()) { if (Info.getLangOpts().CPlusPlus11) - Info.Diag(E, diag::note_constexpr_access_past_end) + Info.FFDiag(E, diag::note_constexpr_access_past_end) << handler.AccessKind; else - Info.Diag(E); + Info.FFDiag(E); return handler.failed(); } @@ -2287,7 +2367,7 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, for (unsigned I = 0, N = Sub.Entries.size(); /**/; ++I) { if (O->isUninit()) { if (!Info.checkingPotentialConstantExpression()) - Info.Diag(E, diag::note_constexpr_access_uninit) << handler.AccessKind; + Info.FFDiag(E, diag::note_constexpr_access_uninit) << handler.AccessKind; return handler.failed(); } @@ -2322,10 +2402,10 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, // Note, it should not be possible to form a pointer with a valid // designator which points more than one past the end of the array. if (Info.getLangOpts().CPlusPlus11) - Info.Diag(E, diag::note_constexpr_access_past_end) + Info.FFDiag(E, diag::note_constexpr_access_past_end) << handler.AccessKind; else - Info.Diag(E); + Info.FFDiag(E); return handler.failed(); } @@ -2355,10 +2435,10 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, uint64_t Index = Sub.Entries[I].ArrayIndex; if (Index > 1) { if (Info.getLangOpts().CPlusPlus11) - Info.Diag(E, diag::note_constexpr_access_past_end) + Info.FFDiag(E, diag::note_constexpr_access_past_end) << handler.AccessKind; else - Info.Diag(E); + Info.FFDiag(E); return handler.failed(); } @@ -2378,7 +2458,7 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, } } else if (const FieldDecl *Field = getAsField(Sub.Entries[I])) { if (Field->isMutable() && handler.AccessKind == AK_Read) { - Info.Diag(E, diag::note_constexpr_ltor_mutable, 1) + Info.FFDiag(E, diag::note_constexpr_ltor_mutable, 1) << Field; Info.Note(Field->getLocation(), diag::note_declared_at); return handler.failed(); @@ -2390,7 +2470,7 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const FieldDecl *UnionField = O->getUnionField(); if (!UnionField || UnionField->getCanonicalDecl() != Field->getCanonicalDecl()) { - Info.Diag(E, diag::note_constexpr_access_inactive_union_member) + Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member) << handler.AccessKind << Field << !UnionField << UnionField; return handler.failed(); } @@ -2406,11 +2486,11 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, if (ObjType.isVolatileQualified()) { if (Info.getLangOpts().CPlusPlus) { // FIXME: Include a description of the path to the volatile subobject. - Info.Diag(E, diag::note_constexpr_access_volatile_obj, 1) + Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1) << handler.AccessKind << 2 << Field; Info.Note(Field->getLocation(), diag::note_declared_at); } else { - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); } return handler.failed(); } @@ -2482,7 +2562,7 @@ struct ModifySubobjectHandler { bool checkConst(QualType QT) { // Assigning to a const object has undefined behavior. if (QT.isConstQualified()) { - Info.Diag(E, diag::note_constexpr_modify_const_type) << QT; + Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT; return false; } return true; @@ -2501,7 +2581,7 @@ struct ModifySubobjectHandler { return false; if (!NewVal.isInt()) { // Maybe trying to write a cast pointer value into a complex? - Info.Diag(E); + Info.FFDiag(E); return false; } Value = NewVal.getInt(); @@ -2592,7 +2672,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType) { if (!LVal.Base) { - Info.Diag(E, diag::note_constexpr_access_null) << AK; + Info.FFDiag(E, diag::note_constexpr_access_null) << AK; return CompleteObject(); } @@ -2600,7 +2680,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, if (LVal.CallIndex) { Frame = Info.getCallFrame(LVal.CallIndex); if (!Frame) { - Info.Diag(E, diag::note_constexpr_lifetime_ended, 1) + Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1) << AK << LVal.Base.is<const ValueDecl*>(); NoteLValueLocation(Info, LVal.Base); return CompleteObject(); @@ -2613,10 +2693,10 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, // semantics. if (LValType.isVolatileQualified()) { if (Info.getLangOpts().CPlusPlus) - Info.Diag(E, diag::note_constexpr_access_volatile_type) + Info.FFDiag(E, diag::note_constexpr_access_volatile_type) << AK << LValType; else - Info.Diag(E); + Info.FFDiag(E); return CompleteObject(); } @@ -2638,18 +2718,18 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, VD = VDef; } if (!VD || VD->isInvalidDecl()) { - Info.Diag(E); + Info.FFDiag(E); return CompleteObject(); } // Accesses of volatile-qualified objects are not allowed. if (BaseType.isVolatileQualified()) { if (Info.getLangOpts().CPlusPlus) { - Info.Diag(E, diag::note_constexpr_access_volatile_obj, 1) + Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1) << AK << 1 << VD; Info.Note(VD->getLocation(), diag::note_declared_at); } else { - Info.Diag(E); + Info.FFDiag(E); } return CompleteObject(); } @@ -2664,17 +2744,20 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, // evaluation. } else if (AK != AK_Read) { // All the remaining cases only permit reading. - Info.Diag(E, diag::note_constexpr_modify_global); + Info.FFDiag(E, diag::note_constexpr_modify_global); return CompleteObject(); } else if (VD->isConstexpr()) { // OK, we can read this variable. } else if (BaseType->isIntegralOrEnumerationType()) { - if (!BaseType.isConstQualified()) { + // In OpenCL if a variable is in constant address space it is a const value. + if (!(BaseType.isConstQualified() || + (Info.getLangOpts().OpenCL && + BaseType.getAddressSpace() == LangAS::opencl_constant))) { if (Info.getLangOpts().CPlusPlus) { - Info.Diag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD; + Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD; Info.Note(VD->getLocation(), diag::note_declared_at); } else { - Info.Diag(E); + Info.FFDiag(E); } return CompleteObject(); } @@ -2690,11 +2773,15 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, } } else { // FIXME: Allow folding of values of any literal type in all languages. - if (Info.getLangOpts().CPlusPlus11) { - Info.Diag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD; + if (Info.checkingPotentialConstantExpression() && + VD->getType().isConstQualified() && !VD->hasDefinition(Info.Ctx)) { + // The definition of this variable could be constexpr. We can't + // access it right now, but may be able to in future. + } else if (Info.getLangOpts().CPlusPlus11) { + Info.FFDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD; Info.Note(VD->getLocation(), diag::note_declared_at); } else { - Info.Diag(E); + Info.FFDiag(E); } return CompleteObject(); } @@ -2730,7 +2817,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, if (!(BaseType.isConstQualified() && BaseType->isIntegralOrEnumerationType()) && !(VD && VD->getCanonicalDecl() == ED->getCanonicalDecl())) { - Info.Diag(E, diag::note_constexpr_access_static_temporary, 1) << AK; + Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK; Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here); return CompleteObject(); } @@ -2738,7 +2825,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, BaseVal = Info.Ctx.getMaterializedTemporaryValue(MTE, false); assert(BaseVal && "got reference to unevaluated temporary"); } else { - Info.Diag(E); + Info.FFDiag(E); return CompleteObject(); } } else { @@ -2749,11 +2836,11 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, // Volatile temporary objects cannot be accessed in constant expressions. if (BaseType.isVolatileQualified()) { if (Info.getLangOpts().CPlusPlus) { - Info.Diag(E, diag::note_constexpr_access_volatile_obj, 1) + Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1) << AK << 0; Info.Note(Base->getExprLoc(), diag::note_constexpr_temporary_here); } else { - Info.Diag(E); + Info.FFDiag(E); } return CompleteObject(); } @@ -2769,12 +2856,13 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, } // In C++1y, we can't safely access any mutable state when we might be - // evaluating after an unmodeled side effect or an evaluation failure. + // evaluating after an unmodeled side effect. // // FIXME: Not all local state is mutable. Allow local constant subobjects // to be read here (but take care with 'mutable' fields). - if (Frame && Info.getLangOpts().CPlusPlus14 && - (Info.EvalStatus.HasSideEffects || Info.keepEvaluatingAfterFailure())) + if ((Frame && Info.getLangOpts().CPlusPlus14 && + Info.EvalStatus.HasSideEffects) || + (AK != AK_Read && Info.IsSpeculativelyEvaluating)) return CompleteObject(); return CompleteObject(BaseVal, BaseType); @@ -2806,7 +2894,7 @@ static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, // an ICE in C, so this only matters for fold. assert(!Info.getLangOpts().CPlusPlus && "lvalue compound literal in c++?"); if (Type.isVolatileQualified()) { - Info.Diag(Conv); + Info.FFDiag(Conv); return false; } APValue Lit; @@ -2835,7 +2923,7 @@ static bool handleAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, return false; if (!Info.getLangOpts().CPlusPlus14) { - Info.Diag(E); + Info.FFDiag(E); return false; } @@ -2863,7 +2951,7 @@ struct CompoundAssignSubobjectHandler { bool checkConst(QualType QT) { // Assigning to a const object has undefined behavior. if (QT.isConstQualified()) { - Info.Diag(E, diag::note_constexpr_modify_const_type) << QT; + Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT; return false; } return true; @@ -2879,13 +2967,13 @@ struct CompoundAssignSubobjectHandler { case APValue::ComplexInt: case APValue::ComplexFloat: // FIXME: Implement complex compound assignment. - Info.Diag(E); + Info.FFDiag(E); return false; case APValue::LValue: return foundPointer(Subobj, SubobjType); default: // FIXME: can this happen? - Info.Diag(E); + Info.FFDiag(E); return false; } } @@ -2896,7 +2984,7 @@ struct CompoundAssignSubobjectHandler { if (!SubobjType->isIntegerType() || !RHS.isInt()) { // We don't support compound assignment on integer-cast-to-pointer // values. - Info.Diag(E); + Info.FFDiag(E); return false; } @@ -2924,7 +3012,7 @@ struct CompoundAssignSubobjectHandler { if (PointeeType.isNull() || !RHS.isInt() || (Opcode != BO_Add && Opcode != BO_Sub)) { - Info.Diag(E); + Info.FFDiag(E); return false; } @@ -2956,7 +3044,7 @@ static bool handleCompoundAssignment( return false; if (!Info.getLangOpts().CPlusPlus14) { - Info.Diag(E); + Info.FFDiag(E); return false; } @@ -2978,7 +3066,7 @@ struct IncDecSubobjectHandler { bool checkConst(QualType QT) { // Assigning to a const object has undefined behavior. if (QT.isConstQualified()) { - Info.Diag(E, diag::note_constexpr_modify_const_type) << QT; + Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT; return false; } return true; @@ -3010,7 +3098,7 @@ struct IncDecSubobjectHandler { return foundPointer(Subobj, SubobjType); default: // FIXME: can this happen? - Info.Diag(E); + Info.FFDiag(E); return false; } } @@ -3021,7 +3109,7 @@ struct IncDecSubobjectHandler { if (!SubobjType->isIntegerType()) { // We don't support increment / decrement on integer-cast-to-pointer // values. - Info.Diag(E); + Info.FFDiag(E); return false; } @@ -3080,7 +3168,7 @@ struct IncDecSubobjectHandler { if (const PointerType *PT = SubobjType->getAs<PointerType>()) PointeeType = PT->getPointeeType(); else { - Info.Diag(E); + Info.FFDiag(E); return false; } @@ -3105,7 +3193,7 @@ static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, return false; if (!Info.getLangOpts().CPlusPlus14) { - Info.Diag(E); + Info.FFDiag(E); return false; } @@ -3127,7 +3215,7 @@ static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, if (Object->getType()->isLiteralType(Info.Ctx)) return EvaluateTemporary(Object, This, Info); - Info.Diag(Object, diag::note_constexpr_nonliteral) << Object->getType(); + Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType(); return false; } @@ -3155,7 +3243,7 @@ static const ValueDecl *HandleMemberPointerAccess(EvalInfo &Info, // member value, the behavior is undefined. if (!MemPtr.getDecl()) { // FIXME: Specific diagnostic. - Info.Diag(RHS); + Info.FFDiag(RHS); return nullptr; } @@ -3165,7 +3253,7 @@ static const ValueDecl *HandleMemberPointerAccess(EvalInfo &Info, // derived-to-base path for the member pointer. if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() > LV.Designator.Entries.size()) { - Info.Diag(RHS); + Info.FFDiag(RHS); return nullptr; } unsigned PathLengthToMember = @@ -3175,7 +3263,7 @@ static const ValueDecl *HandleMemberPointerAccess(EvalInfo &Info, LV.Designator.Entries[PathLengthToMember + I]); const CXXRecordDecl *MPDecl = MemPtr.Path[I]; if (LVDecl->getCanonicalDecl() != MPDecl->getCanonicalDecl()) { - Info.Diag(RHS); + Info.FFDiag(RHS); return nullptr; } } @@ -3231,7 +3319,7 @@ static const ValueDecl *HandleMemberPointerAccess(EvalInfo &Info, assert(BO->getOpcode() == BO_PtrMemD || BO->getOpcode() == BO_PtrMemI); if (!EvaluateObjectArgument(Info, BO->getLHS(), LV)) { - if (Info.keepEvaluatingAfterFailure()) { + if (Info.noteFailure()) { MemberPtr MemPtr; EvaluateMemberPointer(BO->getRHS(), MemPtr, Info); } @@ -3309,7 +3397,7 @@ static bool EvaluateDecl(EvalInfo &Info, const Decl *D) { const Expr *InitE = VD->getInit(); if (!InitE) { - Info.Diag(D->getLocStart(), diag::note_constexpr_uninitialized) + Info.FFDiag(D->getLocStart(), diag::note_constexpr_uninitialized) << false << VD->getType(); Val = APValue(); return false; @@ -3338,6 +3426,7 @@ static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, return EvaluateAsBooleanCondition(Cond, Result, Info); } +namespace { /// \brief A location where the result (returned value) of evaluating a /// statement should be stored. struct StmtResult { @@ -3346,6 +3435,7 @@ struct StmtResult { /// The location containing the result, if any (used to support RVO). const LValue *Slot; }; +} static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, const Stmt *S, @@ -3379,6 +3469,11 @@ static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, APSInt Value; { FullExpressionRAII Scope(Info); + if (const Stmt *Init = SS->getInit()) { + EvalStmtResult ESR = EvaluateStmt(Result, Info, Init); + if (ESR != ESR_Succeeded) + return ESR; + } if (SS->getConditionVariable() && !EvaluateDecl(Info, SS->getConditionVariable())) return ESR_Failed; @@ -3421,7 +3516,7 @@ static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, case ESR_CaseNotFound: // This can only happen if the switch case is nested within a statement // expression. We have no intention of supporting that. - Info.Diag(Found->getLocStart(), diag::note_constexpr_stmt_expr_unsupported); + Info.FFDiag(Found->getLocStart(), diag::note_constexpr_stmt_expr_unsupported); return ESR_Failed; } llvm_unreachable("Invalid EvalStmtResult!"); @@ -3512,7 +3607,7 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, return ESR_Succeeded; } - Info.Diag(S->getLocStart()); + Info.FFDiag(S->getLocStart()); return ESR_Failed; case Stmt::NullStmtClass: @@ -3525,7 +3620,7 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, // FIXME: This isn't quite right; if we're performing aggregate // initialization, each braced subexpression is its own full-expression. FullExpressionRAII Scope(Info); - if (!EvaluateDecl(Info, DclIt) && !Info.keepEvaluatingAfterFailure()) + if (!EvaluateDecl(Info, DclIt) && !Info.noteFailure()) return ESR_Failed; } return ESR_Succeeded; @@ -3561,6 +3656,11 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, // Evaluate the condition, as either a var decl or as an expression. BlockScopeRAII Scope(Info); + if (const Stmt *Init = IS->getInit()) { + EvalStmtResult ESR = EvaluateStmt(Result, Info, Init); + if (ESR != ESR_Succeeded) + return ESR; + } bool Cond; if (!EvaluateCond(Info, IS->getConditionVariable(), IS->getCond(), Cond)) return ESR_Failed; @@ -3647,7 +3747,10 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, return ESR; // Create the __begin and __end iterators. - ESR = EvaluateStmt(Result, Info, FS->getBeginEndStmt()); + ESR = EvaluateStmt(Result, Info, FS->getBeginStmt()); + if (ESR != ESR_Succeeded) + return ESR; + ESR = EvaluateStmt(Result, Info, FS->getEndStmt()); if (ESR != ESR_Succeeded) return ESR; @@ -3736,7 +3839,8 @@ static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, /// expression. static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, - const FunctionDecl *Definition) { + const FunctionDecl *Definition, + const Stmt *Body) { // Potential constant expressions can contain calls to declared, but not yet // defined, constexpr functions. if (Info.checkingPotentialConstantExpression() && !Definition && @@ -3749,19 +3853,34 @@ static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, return false; // Can we evaluate this function call? - if (Definition && Definition->isConstexpr() && !Definition->isInvalidDecl()) + if (Definition && Definition->isConstexpr() && + !Definition->isInvalidDecl() && Body) return true; if (Info.getLangOpts().CPlusPlus11) { const FunctionDecl *DiagDecl = Definition ? Definition : Declaration; - // FIXME: If DiagDecl is an implicitly-declared special member function, we - // should be much more explicit about why it's not constexpr. - Info.Diag(CallLoc, diag::note_constexpr_invalid_function, 1) - << DiagDecl->isConstexpr() << isa<CXXConstructorDecl>(DiagDecl) - << DiagDecl; + + // If this function is not constexpr because it is an inherited + // non-constexpr constructor, diagnose that directly. + auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl); + if (CD && CD->isInheritingConstructor()) { + auto *Inherited = CD->getInheritedConstructor().getConstructor(); + if (!Inherited->isConstexpr()) + DiagDecl = CD = Inherited; + } + + // FIXME: If DiagDecl is an implicitly-declared special member function + // or an inheriting constructor, we should be much more explicit about why + // it's not constexpr. + if (CD && CD->isInheritingConstructor()) + Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1) + << CD->getInheritedConstructor().getConstructor()->getParent(); + else + Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1) + << DiagDecl->isConstexpr() << (bool)CD << DiagDecl; Info.Note(DiagDecl->getLocation(), diag::note_declared_at); } else { - Info.Diag(CallLoc, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr); } return false; } @@ -3795,7 +3914,7 @@ static bool EvaluateArgs(ArrayRef<const Expr*> Args, ArgVector &ArgValues, if (!Evaluate(ArgValues[I - Args.begin()], Info, *I)) { // If we're checking for a potential constant expression, evaluate all // initializers even if some of them fail. - if (!Info.keepEvaluatingAfterFailure()) + if (!Info.noteFailure()) return false; Success = false; } @@ -3848,37 +3967,34 @@ static bool HandleFunctionCall(SourceLocation CallLoc, if (ESR == ESR_Succeeded) { if (Callee->getReturnType()->isVoidType()) return true; - Info.Diag(Callee->getLocEnd(), diag::note_constexpr_no_return); + Info.FFDiag(Callee->getLocEnd(), diag::note_constexpr_no_return); } return ESR == ESR_Returned; } /// Evaluate a constructor call. -static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This, - ArrayRef<const Expr*> Args, +static bool HandleConstructorCall(const Expr *E, const LValue &This, + APValue *ArgValues, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result) { - ArgVector ArgValues(Args.size()); - if (!EvaluateArgs(Args, ArgValues, Info)) - return false; - + SourceLocation CallLoc = E->getExprLoc(); if (!Info.CheckCallLimit(CallLoc)) return false; const CXXRecordDecl *RD = Definition->getParent(); if (RD->getNumVBases()) { - Info.Diag(CallLoc, diag::note_constexpr_virtual_base) << RD; + Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD; return false; } - CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues.data()); + CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues); // FIXME: Creating an APValue just to hold a nonexistent return value is // wasteful. APValue RetVal; StmtResult Ret = {RetVal, nullptr}; - // If it's a delegating constructor, just delegate. + // If it's a delegating constructor, delegate. if (Definition->isDelegatingConstructor()) { CXXConstructorDecl::init_const_iterator I = Definition->init_begin(); { @@ -3902,8 +4018,9 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This, (Definition->isTrivial() && hasFields(Definition->getParent())))) { LValue RHS; RHS.setFrom(Info.Ctx, ArgValues[0]); - return handleLValueToRValueConversion(Info, Args[0], Args[0]->getType(), - RHS, Result); + return handleLValueToRValueConversion( + Info, E, Definition->getParamDecl(0)->getType().getNonReferenceType(), + RHS, Result); } // Reserve space for the struct members. @@ -3987,7 +4104,7 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This, *Value, FD))) { // If we're checking for a potential constant expression, evaluate all // initializers even if some of them fail. - if (!Info.keepEvaluatingAfterFailure()) + if (!Info.noteFailure()) return false; Success = false; } @@ -3997,6 +4114,18 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This, EvaluateStmt(Ret, Info, Definition->getBody()) != ESR_Failed; } +static bool HandleConstructorCall(const Expr *E, const LValue &This, + ArrayRef<const Expr*> Args, + const CXXConstructorDecl *Definition, + EvalInfo &Info, APValue &Result) { + ArgVector ArgValues(Args.size()); + if (!EvaluateArgs(Args, ArgValues, Info)) + return false; + + return HandleConstructorCall(E, This, ArgValues.data(), Definition, + Info, Result); +} + //===----------------------------------------------------------------------===// // Generic Evaluation //===----------------------------------------------------------------------===// @@ -4022,14 +4151,16 @@ private: assert(Info.checkingPotentialConstantExpression()); // Speculatively evaluate both arms. + SmallVector<PartialDiagnosticAt, 8> Diag; { - SmallVector<PartialDiagnosticAt, 8> Diag; SpeculativeEvaluationRAII Speculate(Info, &Diag); - StmtVisitorTy::Visit(E->getFalseExpr()); if (Diag.empty()) return; + } + { + SpeculativeEvaluationRAII Speculate(Info, &Diag); Diag.clear(); StmtVisitorTy::Visit(E->getTrueExpr()); if (Diag.empty()) @@ -4044,7 +4175,7 @@ private: bool HandleConditionalOperator(const ConditionalOperator *E) { bool BoolResult; if (!EvaluateAsBooleanCondition(E->getCond(), BoolResult, Info)) { - if (Info.checkingPotentialConstantExpression()) + if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) CheckPotentialConstantConditional(E); return false; } @@ -4072,7 +4203,7 @@ public: /// Report an evaluation error. This should only be called when an error is /// first discovered. When propagating an error, just return false. bool Error(const Expr *E, diag::kind D) { - Info.Diag(E, D); + Info.FFDiag(E, D); return false; } bool Error(const Expr *E) { @@ -4275,7 +4406,7 @@ public: const FunctionDecl *Definition = nullptr; Stmt *Body = FD->getBody(Definition); - if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition) || + if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body) || !HandleFunctionCall(E->getExprLoc(), Definition, This, Args, Body, Info, Result, ResultSlot)) return false; @@ -4397,7 +4528,7 @@ public: if (BI + 1 == BE) { const Expr *FinalExpr = dyn_cast<Expr>(*BI); if (!FinalExpr) { - Info.Diag((*BI)->getLocStart(), + Info.FFDiag((*BI)->getLocStart(), diag::note_constexpr_stmt_expr_unsupported); return false; } @@ -4412,7 +4543,7 @@ public: // 'break', or 'continue', it would be nice to propagate that to // the outer statement evaluation rather than bailing out. if (ESR != ESR_Failed) - Info.Diag((*BI)->getLocStart(), + Info.FFDiag((*BI)->getLocStart(), diag::note_constexpr_stmt_expr_unsupported); return false; } @@ -4425,6 +4556,15 @@ public: void VisitIgnoredValue(const Expr *E) { EvaluateIgnoredValue(Info, E); } + + /// Potentially visit a MemberExpr's base expression. + void VisitIgnoredBaseExpression(const Expr *E) { + // While MSVC doesn't evaluate the base expression, it does diagnose the + // presence of side-effecting behavior. + if (Info.getLangOpts().MSVCCompat && !E->HasSideEffects(Info.Ctx)) + return; + VisitIgnoredValue(E); + } }; } @@ -4651,7 +4791,7 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) { return false; if (V->isUninit()) { if (!Info.checkingPotentialConstantExpression()) - Info.Diag(E, diag::note_constexpr_use_uninit_reference); + Info.FFDiag(E, diag::note_constexpr_use_uninit_reference); return false; } return Success(*V, E); @@ -4735,7 +4875,7 @@ bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) { if (!E->isPotentiallyEvaluated()) return Success(E); - Info.Diag(E, diag::note_constexpr_typeid_polymorphic) + Info.FFDiag(E, diag::note_constexpr_typeid_polymorphic) << E->getExprOperand()->getType() << E->getExprOperand()->getSourceRange(); return false; @@ -4748,14 +4888,14 @@ bool LValueExprEvaluator::VisitCXXUuidofExpr(const CXXUuidofExpr *E) { bool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) { // Handle static data members. if (const VarDecl *VD = dyn_cast<VarDecl>(E->getMemberDecl())) { - VisitIgnoredValue(E->getBase()); + VisitIgnoredBaseExpression(E->getBase()); return VisitVarDecl(E, VD); } // Handle static member functions. if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->getMemberDecl())) { if (MD->isStatic()) { - VisitIgnoredValue(E->getBase()); + VisitIgnoredBaseExpression(E->getBase()); return Success(MD); } } @@ -4823,7 +4963,7 @@ bool LValueExprEvaluator::VisitCompoundAssignOperator( // The overall lvalue result is the result of evaluating the LHS. if (!this->Visit(CAO->getLHS())) { - if (Info.keepEvaluatingAfterFailure()) + if (Info.noteFailure()) Evaluate(RHS, this->Info, CAO->getRHS()); return false; } @@ -4844,7 +4984,7 @@ bool LValueExprEvaluator::VisitBinAssign(const BinaryOperator *E) { APValue NewVal; if (!this->Visit(E->getLHS())) { - if (Info.keepEvaluatingAfterFailure()) + if (Info.noteFailure()) Evaluate(NewVal, this->Info, E->getRHS()); return false; } @@ -4903,9 +5043,9 @@ public: return false; if (!Info.CurrentCall->This) { if (Info.getLangOpts().CPlusPlus11) - Info.Diag(E, diag::note_constexpr_this) << E->isImplicit(); + Info.FFDiag(E, diag::note_constexpr_this) << E->isImplicit(); else - Info.Diag(E); + Info.FFDiag(E); return false; } Result = *Info.CurrentCall->This; @@ -4932,7 +5072,7 @@ bool PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { std::swap(PExp, IExp); bool EvalPtrOK = EvaluatePointer(PExp, Result, Info); - if (!EvalPtrOK && !Info.keepEvaluatingAfterFailure()) + if (!EvalPtrOK && !Info.noteFailure()) return false; llvm::APSInt Offset; @@ -5135,7 +5275,7 @@ bool PointerExprEvaluator::VisitCallExpr(const CallExpr *E) { } // The offset must also have the correct alignment. - if (OffsetResult.Offset.RoundUpToAlignment(Align) != OffsetResult.Offset) { + if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) { Result.Designator.setInvalid(); APSInt Offset(64, false); Offset = OffsetResult.Offset.getQuantity(); @@ -5265,14 +5405,21 @@ namespace { Result = V; return true; } - bool ZeroInitialization(const Expr *E); + bool ZeroInitialization(const Expr *E) { + return ZeroInitialization(E, E->getType()); + } + bool ZeroInitialization(const Expr *E, QualType T); bool VisitCallExpr(const CallExpr *E) { return handleCallExpr(E, Result, &This); } bool VisitCastExpr(const CastExpr *E); bool VisitInitListExpr(const InitListExpr *E); - bool VisitCXXConstructExpr(const CXXConstructExpr *E); + bool VisitCXXConstructExpr(const CXXConstructExpr *E) { + return VisitCXXConstructExpr(E, E->getType()); + } + bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E); + bool VisitCXXConstructExpr(const CXXConstructExpr *E, QualType T); bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E); }; } @@ -5327,8 +5474,8 @@ static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E, return true; } -bool RecordExprEvaluator::ZeroInitialization(const Expr *E) { - const RecordDecl *RD = E->getType()->castAs<RecordType>()->getDecl(); +bool RecordExprEvaluator::ZeroInitialization(const Expr *E, QualType T) { + const RecordDecl *RD = T->castAs<RecordType>()->getDecl(); if (RD->isInvalidDecl()) return false; if (RD->isUnion()) { // C++11 [dcl.init]p5: If T is a (possibly cv-qualified) union type, the @@ -5348,7 +5495,7 @@ bool RecordExprEvaluator::ZeroInitialization(const Expr *E) { } if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) { - Info.Diag(E, diag::note_constexpr_virtual_base) << RD; + Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD; return false; } @@ -5417,12 +5564,34 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) { return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr); } - assert((!isa<CXXRecordDecl>(RD) || !cast<CXXRecordDecl>(RD)->getNumBases()) && - "initializer list for class with base classes"); - Result = APValue(APValue::UninitStruct(), 0, - std::distance(RD->field_begin(), RD->field_end())); + auto *CXXRD = dyn_cast<CXXRecordDecl>(RD); + if (Result.isUninit()) + Result = APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0, + std::distance(RD->field_begin(), RD->field_end())); unsigned ElementNo = 0; bool Success = true; + + // Initialize base classes. + if (CXXRD) { + for (const auto &Base : CXXRD->bases()) { + assert(ElementNo < E->getNumInits() && "missing init for base class"); + const Expr *Init = E->getInit(ElementNo); + + LValue Subobject = This; + if (!HandleLValueBase(Info, Init, Subobject, CXXRD, &Base)) + return false; + + APValue &FieldVal = Result.getStructBase(ElementNo); + if (!EvaluateInPlace(FieldVal, Info, Subobject, Init)) { + if (!Info.noteFailure()) + return false; + Success = false; + } + ++ElementNo; + } + } + + // Initialize members. for (const auto *Field : RD->fields()) { // Anonymous bit-fields are not considered members of the class for // purposes of aggregate initialization. @@ -5452,7 +5621,7 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) { if (!EvaluateInPlace(FieldVal, Info, Subobject, Init) || (Field->isBitField() && !truncateBitfieldValue(Info, Init, FieldVal, Field))) { - if (!Info.keepEvaluatingAfterFailure()) + if (!Info.noteFailure()) return false; Success = false; } @@ -5461,7 +5630,10 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) { return Success; } -bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) { +bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E, + QualType T) { + // Note that E's type is not necessarily the type of our class here; we might + // be initializing an array element instead. const CXXConstructorDecl *FD = E->getConstructor(); if (FD->isInvalidDecl() || FD->getParent()->isInvalidDecl()) return false; @@ -5479,13 +5651,13 @@ bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) { // lifetimes of all the base subobjects (there can be no data member // subobjects in this case) per [basic.life]p1. // Either way, ZeroInitialization is appropriate. - return ZeroInitialization(E); + return ZeroInitialization(E, T); } const FunctionDecl *Definition = nullptr; - FD->getBody(Definition); + auto Body = FD->getBody(Definition); - if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition)) + if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body)) return false; // Avoid materializing a temporary for an elidable copy/move constructor. @@ -5494,11 +5666,33 @@ bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) { = dyn_cast<MaterializeTemporaryExpr>(E->getArg(0))) return Visit(ME->GetTemporaryExpr()); - if (ZeroInit && !ZeroInitialization(E)) + if (ZeroInit && !ZeroInitialization(E, T)) return false; auto Args = llvm::makeArrayRef(E->getArgs(), E->getNumArgs()); - return HandleConstructorCall(E->getExprLoc(), This, Args, + return HandleConstructorCall(E, This, Args, + cast<CXXConstructorDecl>(Definition), Info, + Result); +} + +bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr( + const CXXInheritedCtorInitExpr *E) { + if (!Info.CurrentCall) { + assert(Info.checkingPotentialConstantExpression()); + return false; + } + + const CXXConstructorDecl *FD = E->getConstructor(); + if (FD->isInvalidDecl() || FD->getParent()->isInvalidDecl()) + return false; + + const FunctionDecl *Definition = nullptr; + auto Body = FD->getBody(Definition); + + if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body)) + return false; + + return HandleConstructorCall(E, This, Info.CurrentCall->Arguments, cast<CXXConstructorDecl>(Definition), Info, Result); } @@ -5902,7 +6096,7 @@ bool ArrayExprEvaluator::VisitInitListExpr(const InitListExpr *E) { Info, Subobject, Init) || !HandleLValueArrayAdjustment(Info, Init, Subobject, CAT->getElementType(), 1)) { - if (!Info.keepEvaluatingAfterFailure()) + if (!Info.noteFailure()) return false; Success = false; } @@ -5958,34 +6152,8 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E, if (!Type->isRecordType()) return Error(E); - const CXXConstructorDecl *FD = E->getConstructor(); - - bool ZeroInit = E->requiresZeroInitialization(); - if (CheckTrivialDefaultConstructor(Info, E->getExprLoc(), FD, ZeroInit)) { - if (HadZeroInit) - return true; - - // See RecordExprEvaluator::VisitCXXConstructExpr for explanation. - ImplicitValueInitExpr VIE(Type); - return EvaluateInPlace(*Value, Info, Subobject, &VIE); - } - - const FunctionDecl *Definition = nullptr; - FD->getBody(Definition); - - if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition)) - return false; - - if (ZeroInit && !HadZeroInit) { - ImplicitValueInitExpr VIE(Type); - if (!EvaluateInPlace(*Value, Info, Subobject, &VIE)) - return false; - } - - auto Args = llvm::makeArrayRef(E->getArgs(), E->getNumArgs()); - return HandleConstructorCall(E->getExprLoc(), Subobject, Args, - cast<CXXConstructorDecl>(Definition), - Info, *Value); + return RecordExprEvaluator(Info, Subobject, *Value) + .VisitCXXConstructExpr(E, Type); } //===----------------------------------------------------------------------===// @@ -6076,7 +6244,7 @@ public: } bool VisitMemberExpr(const MemberExpr *E) { if (CheckReferencedDecl(E, E->getMemberDecl())) { - VisitIgnoredValue(E->getBase()); + VisitIgnoredBaseExpression(E->getBase()); return true; } @@ -6149,7 +6317,7 @@ static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info) { if (!Val.isInt()) { // FIXME: It would be better to produce the diagnostic for casting // a pointer to an integer. - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); return false; } Result = Val.getInt(); @@ -6185,7 +6353,8 @@ bool IntExprEvaluator::CheckReferencedDecl(const Expr* E, const Decl* D) { /// EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way /// as GCC. -static int EvaluateBuiltinClassifyType(const CallExpr *E) { +static int EvaluateBuiltinClassifyType(const CallExpr *E, + const LangOptions &LangOpts) { // The following enum mimics the values returned by GCC. // FIXME: Does GCC differ between lvalue and rvalue references here? enum gcc_type_class { @@ -6205,37 +6374,123 @@ static int EvaluateBuiltinClassifyType(const CallExpr *E) { if (E->getNumArgs() == 0) return no_type_class; - QualType ArgTy = E->getArg(0)->getType(); - if (ArgTy->isVoidType()) - return void_type_class; - else if (ArgTy->isEnumeralType()) - return enumeral_type_class; - else if (ArgTy->isBooleanType()) - return boolean_type_class; - else if (ArgTy->isCharType()) - return string_type_class; // gcc doesn't appear to use char_type_class - else if (ArgTy->isIntegerType()) - return integer_type_class; - else if (ArgTy->isPointerType()) + QualType CanTy = E->getArg(0)->getType().getCanonicalType(); + const BuiltinType *BT = dyn_cast<BuiltinType>(CanTy); + + switch (CanTy->getTypeClass()) { +#define TYPE(ID, BASE) +#define DEPENDENT_TYPE(ID, BASE) case Type::ID: +#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID: +#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID: +#include "clang/AST/TypeNodes.def" + llvm_unreachable("CallExpr::isBuiltinClassifyType(): unimplemented type"); + + case Type::Builtin: + switch (BT->getKind()) { +#define BUILTIN_TYPE(ID, SINGLETON_ID) +#define SIGNED_TYPE(ID, SINGLETON_ID) case BuiltinType::ID: return integer_type_class; +#define FLOATING_TYPE(ID, SINGLETON_ID) case BuiltinType::ID: return real_type_class; +#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) case BuiltinType::ID: break; +#include "clang/AST/BuiltinTypes.def" + case BuiltinType::Void: + return void_type_class; + + case BuiltinType::Bool: + return boolean_type_class; + + case BuiltinType::Char_U: // gcc doesn't appear to use char_type_class + case BuiltinType::UChar: + case BuiltinType::UShort: + case BuiltinType::UInt: + case BuiltinType::ULong: + case BuiltinType::ULongLong: + case BuiltinType::UInt128: + return integer_type_class; + + case BuiltinType::NullPtr: + return pointer_type_class; + + case BuiltinType::WChar_U: + case BuiltinType::Char16: + case BuiltinType::Char32: + case BuiltinType::ObjCId: + case BuiltinType::ObjCClass: + case BuiltinType::ObjCSel: +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/Basic/OpenCLImageTypes.def" + case BuiltinType::OCLSampler: + case BuiltinType::OCLEvent: + case BuiltinType::OCLClkEvent: + case BuiltinType::OCLQueue: + case BuiltinType::OCLNDRange: + case BuiltinType::OCLReserveID: + case BuiltinType::Dependent: + llvm_unreachable("CallExpr::isBuiltinClassifyType(): unimplemented type"); + }; + + case Type::Enum: + return LangOpts.CPlusPlus ? enumeral_type_class : integer_type_class; + break; + + case Type::Pointer: return pointer_type_class; - else if (ArgTy->isReferenceType()) - return reference_type_class; - else if (ArgTy->isRealType()) - return real_type_class; - else if (ArgTy->isComplexType()) + break; + + case Type::MemberPointer: + if (CanTy->isMemberDataPointerType()) + return offset_type_class; + else { + // We expect member pointers to be either data or function pointers, + // nothing else. + assert(CanTy->isMemberFunctionPointerType()); + return method_type_class; + } + + case Type::Complex: return complex_type_class; - else if (ArgTy->isFunctionType()) - return function_type_class; - else if (ArgTy->isStructureOrClassType()) - return record_type_class; - else if (ArgTy->isUnionType()) - return union_type_class; - else if (ArgTy->isArrayType()) - return array_type_class; - else if (ArgTy->isUnionType()) - return union_type_class; - else // FIXME: offset_type_class, method_type_class, & lang_type_class? + + case Type::FunctionNoProto: + case Type::FunctionProto: + return LangOpts.CPlusPlus ? function_type_class : pointer_type_class; + + case Type::Record: + if (const RecordType *RT = CanTy->getAs<RecordType>()) { + switch (RT->getDecl()->getTagKind()) { + case TagTypeKind::TTK_Struct: + case TagTypeKind::TTK_Class: + case TagTypeKind::TTK_Interface: + return record_type_class; + + case TagTypeKind::TTK_Enum: + return LangOpts.CPlusPlus ? enumeral_type_class : integer_type_class; + + case TagTypeKind::TTK_Union: + return union_type_class; + } + } llvm_unreachable("CallExpr::isBuiltinClassifyType(): unimplemented type"); + + case Type::ConstantArray: + case Type::VariableArray: + case Type::IncompleteArray: + return LangOpts.CPlusPlus ? array_type_class : pointer_type_class; + + case Type::BlockPointer: + case Type::LValueReference: + case Type::RValueReference: + case Type::Vector: + case Type::ExtVector: + case Type::Auto: + case Type::ObjCObject: + case Type::ObjCInterface: + case Type::ObjCObjectPointer: + case Type::Pipe: + case Type::Atomic: + llvm_unreachable("CallExpr::isBuiltinClassifyType(): unimplemented type"); + } + + llvm_unreachable("CallExpr::isBuiltinClassifyType(): unimplemented type"); } /// EvaluateBuiltinConstantPForLValue - Determine the result of @@ -6346,25 +6601,32 @@ static const Expr *ignorePointerCastsAndParens(const Expr *E) { /// /// Please note: this function is specialized for how __builtin_object_size /// views "objects". +/// +/// If this encounters an invalid RecordDecl, it will always return true. static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal) { assert(!LVal.Designator.Invalid); - auto IsLastFieldDecl = [&Ctx](const FieldDecl *FD) { - if (FD->getParent()->isUnion()) + auto IsLastOrInvalidFieldDecl = [&Ctx](const FieldDecl *FD, bool &Invalid) { + const RecordDecl *Parent = FD->getParent(); + Invalid = Parent->isInvalidDecl(); + if (Invalid || Parent->isUnion()) return true; - const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(FD->getParent()); + const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Parent); return FD->getFieldIndex() + 1 == Layout.getFieldCount(); }; auto &Base = LVal.getLValueBase(); if (auto *ME = dyn_cast_or_null<MemberExpr>(Base.dyn_cast<const Expr *>())) { if (auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) { - if (!IsLastFieldDecl(FD)) - return false; + bool Invalid; + if (!IsLastOrInvalidFieldDecl(FD, Invalid)) + return Invalid; } else if (auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) { - for (auto *FD : IFD->chain()) - if (!IsLastFieldDecl(cast<FieldDecl>(FD))) - return false; + for (auto *FD : IFD->chain()) { + bool Invalid; + if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD), Invalid)) + return Invalid; + } } } @@ -6387,8 +6649,9 @@ static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal) { return false; BaseType = CT->getElementType(); } else if (auto *FD = getAsField(LVal.Designator.Entries[I])) { - if (!IsLastFieldDecl(FD)) - return false; + bool Invalid; + if (!IsLastOrInvalidFieldDecl(FD, Invalid)) + return Invalid; BaseType = FD->getType(); } else { assert(getAsBaseClass(LVal.Designator.Entries[I]) != nullptr && @@ -6607,7 +6870,7 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { } case Builtin::BI__builtin_classify_type: - return Success(EvaluateBuiltinClassifyType(E), E); + return Success(EvaluateBuiltinClassifyType(E, Info.getLangOpts()), E); // FIXME: BI__builtin_clrsb // FIXME: BI__builtin_clrsbl @@ -6899,23 +7162,14 @@ class DataRecursiveIntBinOpEvaluator { Job() = default; Job(Job &&J) : E(J.E), LHSResult(J.LHSResult), Kind(J.Kind), - StoredInfo(J.StoredInfo), OldEvalStatus(J.OldEvalStatus) { - J.StoredInfo = nullptr; - } + SpecEvalRAII(std::move(J.SpecEvalRAII)) {} void startSpeculativeEval(EvalInfo &Info) { - OldEvalStatus = Info.EvalStatus; - Info.EvalStatus.Diag = nullptr; - StoredInfo = &Info; - } - ~Job() { - if (StoredInfo) { - StoredInfo->EvalStatus = OldEvalStatus; - } + SpecEvalRAII = SpeculativeEvaluationRAII(Info); } + private: - EvalInfo *StoredInfo = nullptr; // non-null if status changed. - Expr::EvalStatus OldEvalStatus; + SpeculativeEvaluationRAII SpecEvalRAII; }; SmallVector<Job, 16> Queue; @@ -6935,7 +7189,9 @@ public: static bool shouldEnqueue(const BinaryOperator *E) { return E->getOpcode() == BO_Comma || E->isLogicalOp() || - (E->getLHS()->getType()->isIntegralOrEnumerationType() && + (E->isRValue() && + E->getType()->isIntegralOrEnumerationType() && + E->getLHS()->getType()->isIntegralOrEnumerationType() && E->getRHS()->getType()->isIntegralOrEnumerationType()); } @@ -7017,7 +7273,7 @@ bool DataRecursiveIntBinOpEvaluator:: LHSResult.Failed = true; // Since we weren't able to evaluate the left hand side, it - // must have had side effects. + // might have had side effects. if (!Info.noteSideEffect()) return false; @@ -7033,7 +7289,7 @@ bool DataRecursiveIntBinOpEvaluator:: assert(E->getLHS()->getType()->isIntegralOrEnumerationType() && E->getRHS()->getType()->isIntegralOrEnumerationType()); - if (LHSResult.Failed && !Info.keepEvaluatingAfterFailure()) + if (LHSResult.Failed && !Info.noteFailure()) return false; // Ignore RHS; return true; @@ -7185,10 +7441,34 @@ void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) { llvm_unreachable("Invalid Job::Kind!"); } +namespace { +/// Used when we determine that we should fail, but can keep evaluating prior to +/// noting that we had a failure. +class DelayedNoteFailureRAII { + EvalInfo &Info; + bool NoteFailure; + +public: + DelayedNoteFailureRAII(EvalInfo &Info, bool NoteFailure = true) + : Info(Info), NoteFailure(NoteFailure) {} + ~DelayedNoteFailureRAII() { + if (NoteFailure) { + bool ContinueAfterFailure = Info.noteFailure(); + (void)ContinueAfterFailure; + assert(ContinueAfterFailure && + "Shouldn't have kept evaluating on failure."); + } + } +}; +} + bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { + // We don't call noteFailure immediately because the assignment happens after + // we evaluate LHS and RHS. if (!Info.keepEvaluatingAfterFailure() && E->isAssignmentOp()) return Error(E); + DelayedNoteFailureRAII MaybeNoteFailureLater(Info, E->isAssignmentOp()); if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E)) return DataRecursiveIntBinOpEvaluator(*this, Result).Traverse(E); @@ -7211,7 +7491,7 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { } else { LHSOK = EvaluateComplex(E->getLHS(), LHS, Info); } - if (!LHSOK && !Info.keepEvaluatingAfterFailure()) + if (!LHSOK && !Info.noteFailure()) return false; if (E->getRHS()->getType()->isRealFloatingType()) { @@ -7259,7 +7539,7 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { APFloat RHS(0.0), LHS(0.0); bool LHSOK = EvaluateFloat(E->getRHS(), RHS, Info); - if (!LHSOK && !Info.keepEvaluatingAfterFailure()) + if (!LHSOK && !Info.noteFailure()) return false; if (!EvaluateFloat(E->getLHS(), LHS, Info) || !LHSOK) @@ -7293,7 +7573,7 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { LValue LHSValue, RHSValue; bool LHSOK = EvaluatePointer(E->getLHS(), LHSValue, Info); - if (!LHSOK && !Info.keepEvaluatingAfterFailure()) + if (!LHSOK && !Info.noteFailure()) return false; if (!EvaluatePointer(E->getRHS(), RHSValue, Info) || !LHSOK) @@ -7387,7 +7667,7 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { // C, array of zero length). Pointer subtraction in such cases has // undefined behavior, so is not constant. if (ElementSize.isZero()) { - Info.Diag(E, diag::note_constexpr_pointer_subtraction_zero_size) + Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size) << ElementType; return false; } @@ -7510,7 +7790,7 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { MemberPtr LHSValue, RHSValue; bool LHSOK = EvaluateMemberPointer(E->getLHS(), LHSValue, Info); - if (!LHSOK && Info.keepEvaluatingAfterFailure()) + if (!LHSOK && !Info.noteFailure()) return false; if (!EvaluateMemberPointer(E->getRHS(), RHSValue, Info) || !LHSOK) @@ -8082,7 +8362,7 @@ bool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { APFloat RHS(0.0); bool LHSOK = EvaluateFloat(E->getLHS(), Result, Info); - if (!LHSOK && !Info.keepEvaluatingAfterFailure()) + if (!LHSOK && !Info.noteFailure()) return false; return EvaluateFloat(E->getRHS(), RHS, Info) && LHSOK && handleFloatFloatBinOp(Info, E, Result, E->getOpcode(), RHS); @@ -8359,7 +8639,7 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { } else { LHSOK = Visit(E->getLHS()); } - if (!LHSOK && !Info.keepEvaluatingAfterFailure()) + if (!LHSOK && !Info.noteFailure()) return false; ComplexValue RHS; @@ -8513,12 +8793,14 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { APFloat MaxCD = maxnum(abs(C), abs(D)); if (MaxCD.isFinite()) { DenomLogB = ilogb(MaxCD); - C = scalbn(C, -DenomLogB); - D = scalbn(D, -DenomLogB); + C = scalbn(C, -DenomLogB, APFloat::rmNearestTiesToEven); + D = scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven); } APFloat Denom = C * C + D * D; - ResR = scalbn((A * C + B * D) / Denom, -DenomLogB); - ResI = scalbn((B * C - A * D) / Denom, -DenomLogB); + ResR = scalbn((A * C + B * D) / Denom, -DenomLogB, + APFloat::rmNearestTiesToEven); + ResI = scalbn((B * C - A * D) / Denom, -DenomLogB, + APFloat::rmNearestTiesToEven); if (ResR.isNaN() && ResI.isNaN()) { if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) { ResR = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * A; @@ -8758,10 +9040,10 @@ static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E) { if (!EvaluateAtomic(E, Result, Info)) return false; } else if (Info.getLangOpts().CPlusPlus11) { - Info.Diag(E, diag::note_constexpr_nonliteral) << E->getType(); + Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->getType(); return false; } else { - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); return false; } @@ -8885,6 +9167,20 @@ bool Expr::EvaluateAsInt(APSInt &Result, const ASTContext &Ctx, return true; } +bool Expr::EvaluateAsFloat(APFloat &Result, const ASTContext &Ctx, + SideEffectsKind AllowSideEffects) const { + if (!getType()->isRealFloatingType()) + return false; + + EvalResult ExprResult; + if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isFloat() || + hasUnacceptableSideEffect(ExprResult, AllowSideEffects)) + return false; + + Result = ExprResult.Val.getFloat(); + return true; +} + bool Expr::EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const { EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold); @@ -9070,6 +9366,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { case Expr::TypoExprClass: case Expr::DependentScopeDeclRefExprClass: case Expr::CXXConstructExprClass: + case Expr::CXXInheritedCtorInitExprClass: case Expr::CXXStdInitializerListExprClass: case Expr::CXXBindTemporaryExprClass: case Expr::ExprWithCleanupsClass: @@ -9089,6 +9386,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { case Expr::ObjCPropertyRefExprClass: case Expr::ObjCSubscriptRefExprClass: case Expr::ObjCIsaExprClass: + case Expr::ObjCAvailabilityCheckExprClass: case Expr::ShuffleVectorExprClass: case Expr::ConvertVectorExprClass: case Expr::BlockExprClass: @@ -9533,17 +9831,17 @@ bool Expr::isPotentialConstantExpr(const FunctionDecl *FD, ArrayRef<const Expr*> Args; - SourceLocation Loc = FD->getLocation(); - APValue Scratch; if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) { // Evaluate the call as a constant initializer, to allow the construction // of objects of non-literal types. Info.setEvaluatingDecl(This.getLValueBase(), Scratch); - HandleConstructorCall(Loc, This, Args, CD, Info, Scratch); - } else + HandleConstructorCall(&VIE, This, Args, CD, Info, Scratch); + } else { + SourceLocation Loc = FD->getLocation(); HandleFunctionCall(Loc, FD, (MD && MD->isInstance()) ? &This : nullptr, Args, FD->getBody(), Info, Scratch, nullptr); + } return Diags.empty(); } diff --git a/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp b/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp index 3f6b682..694fde3 100644 --- a/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp @@ -20,6 +20,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" @@ -66,8 +67,9 @@ static const DeclContext *getEffectiveDeclContext(const Decl *D) { } const DeclContext *DC = D->getDeclContext(); - if (const CapturedDecl *CD = dyn_cast<CapturedDecl>(DC)) - return getEffectiveDeclContext(CD); + if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC)) { + return getEffectiveDeclContext(cast<Decl>(DC)); + } if (const auto *VD = dyn_cast<VarDecl>(D)) if (VD->isExternC()) @@ -77,7 +79,7 @@ static const DeclContext *getEffectiveDeclContext(const Decl *D) { if (FD->isExternC()) return FD->getASTContext().getTranslationUnitDecl(); - return DC; + return DC->getRedeclContext(); } static const DeclContext *getEffectiveParentContext(const DeclContext *DC) { @@ -212,6 +214,12 @@ public: class CXXNameMangler { ItaniumMangleContextImpl &Context; raw_ostream &Out; + bool NullOut = false; + /// In the "DisableDerivedAbiTags" mode derived ABI tags are not calculated. + /// This mode is used when mangler creates another mangler recursively to + /// calculate ABI tags for the function return value or the variable type. + /// Also it is required to avoid infinite recursion in some cases. + bool DisableDerivedAbiTags = false; /// The "structor" is the top-level declaration being mangled, if /// that's not a template specialization; otherwise it's the pattern @@ -261,15 +269,126 @@ class CXXNameMangler { } FunctionTypeDepth; + // abi_tag is a gcc attribute, taking one or more strings called "tags". + // The goal is to annotate against which version of a library an object was + // built and to be able to provide backwards compatibility ("dual abi"). + // For more information see docs/ItaniumMangleAbiTags.rst. + typedef SmallVector<StringRef, 4> AbiTagList; + + // State to gather all implicit and explicit tags used in a mangled name. + // Must always have an instance of this while emitting any name to keep + // track. + class AbiTagState final { + public: + explicit AbiTagState(AbiTagState *&Head) : LinkHead(Head) { + Parent = LinkHead; + LinkHead = this; + } + + // No copy, no move. + AbiTagState(const AbiTagState &) = delete; + AbiTagState &operator=(const AbiTagState &) = delete; + + ~AbiTagState() { pop(); } + + void write(raw_ostream &Out, const NamedDecl *ND, + const AbiTagList *AdditionalAbiTags) { + ND = cast<NamedDecl>(ND->getCanonicalDecl()); + if (!isa<FunctionDecl>(ND) && !isa<VarDecl>(ND)) { + assert( + !AdditionalAbiTags && + "only function and variables need a list of additional abi tags"); + if (const auto *NS = dyn_cast<NamespaceDecl>(ND)) { + if (const auto *AbiTag = NS->getAttr<AbiTagAttr>()) { + UsedAbiTags.insert(UsedAbiTags.end(), AbiTag->tags().begin(), + AbiTag->tags().end()); + } + // Don't emit abi tags for namespaces. + return; + } + } + + AbiTagList TagList; + if (const auto *AbiTag = ND->getAttr<AbiTagAttr>()) { + UsedAbiTags.insert(UsedAbiTags.end(), AbiTag->tags().begin(), + AbiTag->tags().end()); + TagList.insert(TagList.end(), AbiTag->tags().begin(), + AbiTag->tags().end()); + } + + if (AdditionalAbiTags) { + UsedAbiTags.insert(UsedAbiTags.end(), AdditionalAbiTags->begin(), + AdditionalAbiTags->end()); + TagList.insert(TagList.end(), AdditionalAbiTags->begin(), + AdditionalAbiTags->end()); + } + + std::sort(TagList.begin(), TagList.end()); + TagList.erase(std::unique(TagList.begin(), TagList.end()), TagList.end()); + + writeSortedUniqueAbiTags(Out, TagList); + } + + const AbiTagList &getUsedAbiTags() const { return UsedAbiTags; } + void setUsedAbiTags(const AbiTagList &AbiTags) { + UsedAbiTags = AbiTags; + } + + const AbiTagList &getEmittedAbiTags() const { + return EmittedAbiTags; + } + + const AbiTagList &getSortedUniqueUsedAbiTags() { + std::sort(UsedAbiTags.begin(), UsedAbiTags.end()); + UsedAbiTags.erase(std::unique(UsedAbiTags.begin(), UsedAbiTags.end()), + UsedAbiTags.end()); + return UsedAbiTags; + } + + private: + //! All abi tags used implicitly or explicitly. + AbiTagList UsedAbiTags; + //! All explicit abi tags (i.e. not from namespace). + AbiTagList EmittedAbiTags; + + AbiTagState *&LinkHead; + AbiTagState *Parent = nullptr; + + void pop() { + assert(LinkHead == this && + "abi tag link head must point to us on destruction"); + if (Parent) { + Parent->UsedAbiTags.insert(Parent->UsedAbiTags.end(), + UsedAbiTags.begin(), UsedAbiTags.end()); + Parent->EmittedAbiTags.insert(Parent->EmittedAbiTags.end(), + EmittedAbiTags.begin(), + EmittedAbiTags.end()); + } + LinkHead = Parent; + } + + void writeSortedUniqueAbiTags(raw_ostream &Out, const AbiTagList &AbiTags) { + for (const auto &Tag : AbiTags) { + EmittedAbiTags.push_back(Tag); + Out << "B"; + Out << Tag.size(); + Out << Tag; + } + } + }; + + AbiTagState *AbiTags = nullptr; + AbiTagState AbiTagsRoot; + llvm::DenseMap<uintptr_t, unsigned> Substitutions; ASTContext &getASTContext() const { return Context.getASTContext(); } public: CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_, - const NamedDecl *D = nullptr) - : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(0), - SeqID(0) { + const NamedDecl *D = nullptr, bool NullOut_ = false) + : Context(C), Out(Out_), NullOut(NullOut_), Structor(getStructor(D)), + StructorType(0), SeqID(0), AbiTagsRoot(AbiTags) { // These can't be mangled without a ctor type or dtor type. assert(!D || (!isa<CXXDestructorDecl>(D) && !isa<CXXConstructorDecl>(D))); @@ -277,11 +396,21 @@ public: CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_, const CXXConstructorDecl *D, CXXCtorType Type) : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type), - SeqID(0) { } + SeqID(0), AbiTagsRoot(AbiTags) { } CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_, const CXXDestructorDecl *D, CXXDtorType Type) : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type), - SeqID(0) { } + SeqID(0), AbiTagsRoot(AbiTags) { } + + CXXNameMangler(CXXNameMangler &Outer, raw_ostream &Out_) + : Context(Outer.Context), Out(Out_), NullOut(false), + Structor(Outer.Structor), StructorType(Outer.StructorType), + SeqID(Outer.SeqID), AbiTagsRoot(AbiTags) {} + + CXXNameMangler(CXXNameMangler &Outer, llvm::raw_null_ostream &Out_) + : Context(Outer.Context), Out(Out_), NullOut(true), + Structor(Outer.Structor), StructorType(Outer.StructorType), + SeqID(Outer.SeqID), AbiTagsRoot(AbiTags) {} #if MANGLE_CHECKER ~CXXNameMangler() { @@ -296,6 +425,9 @@ public: #endif raw_ostream &getStream() { return Out; } + void disableDerivedAbiTags() { DisableDerivedAbiTags = true; } + static bool shouldHaveAbiTags(ItaniumMangleContextImpl &C, const VarDecl *VD); + void mangle(const NamedDecl *D); void mangleCallOffset(int64_t NonVirtual, int64_t Virtual); void mangleNumber(const llvm::APSInt &I); @@ -314,7 +446,6 @@ private: bool mangleSubstitution(TemplateName Template); bool mangleSubstitution(uintptr_t Ptr); - void mangleExistingSubstitution(QualType type); void mangleExistingSubstitution(TemplateName name); bool mangleStandardSubstitution(const NamedDecl *ND); @@ -334,23 +465,37 @@ private: DeclarationName name, unsigned KnownArity = UnknownArity); - void mangleName(const TemplateDecl *TD, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs); - void mangleUnqualifiedName(const NamedDecl *ND) { - mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity); + void mangleFunctionEncodingBareType(const FunctionDecl *FD); + + void mangleNameWithAbiTags(const NamedDecl *ND, + const AbiTagList *AdditionalAbiTags); + void mangleTemplateName(const TemplateDecl *TD, + const TemplateArgument *TemplateArgs, + unsigned NumTemplateArgs); + void mangleUnqualifiedName(const NamedDecl *ND, + const AbiTagList *AdditionalAbiTags) { + mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity, + AdditionalAbiTags); } void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name, - unsigned KnownArity); - void mangleUnscopedName(const NamedDecl *ND); - void mangleUnscopedTemplateName(const TemplateDecl *ND); - void mangleUnscopedTemplateName(TemplateName); + unsigned KnownArity, + const AbiTagList *AdditionalAbiTags); + void mangleUnscopedName(const NamedDecl *ND, + const AbiTagList *AdditionalAbiTags); + void mangleUnscopedTemplateName(const TemplateDecl *ND, + const AbiTagList *AdditionalAbiTags); + void mangleUnscopedTemplateName(TemplateName, + const AbiTagList *AdditionalAbiTags); void mangleSourceName(const IdentifierInfo *II); - void mangleLocalName(const Decl *D); + void mangleSourceNameWithAbiTags( + const NamedDecl *ND, const AbiTagList *AdditionalAbiTags = nullptr); + void mangleLocalName(const Decl *D, + const AbiTagList *AdditionalAbiTags); void mangleBlockForPrefix(const BlockDecl *Block); void mangleUnqualifiedBlock(const BlockDecl *Block); void mangleLambda(const CXXRecordDecl *Lambda); void mangleNestedName(const NamedDecl *ND, const DeclContext *DC, + const AbiTagList *AdditionalAbiTags, bool NoFunction=false); void mangleNestedName(const TemplateDecl *TD, const TemplateArgument *TemplateArgs, @@ -364,6 +509,7 @@ private: StringRef Prefix = ""); void mangleOperatorName(DeclarationName Name, unsigned Arity); void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity); + void mangleVendorQualifier(StringRef qualifier); void mangleQualifiers(Qualifiers Quals); void mangleRefQualifier(RefQualifierKind RefQualifier); @@ -377,7 +523,10 @@ private: void mangleType(const TagType*); void mangleType(TemplateName); - void mangleBareFunctionType(const FunctionType *T, bool MangleReturnType, + static StringRef getCallingConvQualifierName(CallingConv CC); + void mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo info); + void mangleExtFunctionInfo(const FunctionType *T); + void mangleBareFunctionType(const FunctionProtoType *T, bool MangleReturnType, const FunctionDecl *FD = nullptr); void mangleNeonVectorType(const VectorType *T); void mangleAArch64NeonVectorType(const VectorType *T); @@ -392,7 +541,7 @@ private: void mangleCastExpression(const Expr *E, StringRef CastEncoding); void mangleInitListElements(const InitListExpr *InitList); void mangleExpression(const Expr *E, unsigned Arity = UnknownArity); - void mangleCXXCtorType(CXXCtorType T); + void mangleCXXCtorType(CXXCtorType T, const CXXRecordDecl *InheritedFrom); void mangleCXXDtorType(CXXDtorType T); void mangleTemplateArgs(const TemplateArgumentLoc *TemplateArgs, @@ -405,6 +554,14 @@ private: void mangleTemplateParameter(unsigned Index); void mangleFunctionParam(const ParmVarDecl *parm); + + void writeAbiTags(const NamedDecl *ND, + const AbiTagList *AdditionalAbiTags); + + // Returns sorted unique list of ABI tags. + AbiTagList makeFunctionReturnTypeTags(const FunctionDecl *FD); + // Returns sorted unique list of ABI tags. + AbiTagList makeVariableTypeTags(const VarDecl *VD); }; } @@ -448,6 +605,7 @@ bool ItaniumMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) { while (!DC->isNamespace() && !DC->isTranslationUnit()) DC = getEffectiveParentContext(DC); if (DC->isTranslationUnit() && D->getFormalLinkage() != InternalLinkage && + !CXXNameMangler::shouldHaveAbiTags(*this, VD) && !isa<VarTemplateSpecializationDecl>(D)) return false; } @@ -455,6 +613,18 @@ bool ItaniumMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) { return true; } +void CXXNameMangler::writeAbiTags(const NamedDecl *ND, + const AbiTagList *AdditionalAbiTags) { + assert(AbiTags && "require AbiTagState"); + AbiTags->write(Out, ND, DisableDerivedAbiTags ? nullptr : AdditionalAbiTags); +} + +void CXXNameMangler::mangleSourceNameWithAbiTags( + const NamedDecl *ND, const AbiTagList *AdditionalAbiTags) { + mangleSourceName(ND->getIdentifier()); + writeAbiTags(ND, AdditionalAbiTags); +} + void CXXNameMangler::mangle(const NamedDecl *D) { // <mangled-name> ::= _Z <encoding> // ::= <data name> @@ -472,12 +642,52 @@ void CXXNameMangler::mangle(const NamedDecl *D) { void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { // <encoding> ::= <function name> <bare-function-type> - mangleName(FD); // Don't mangle in the type if this isn't a decl we should typically mangle. - if (!Context.shouldMangleDeclName(FD)) + if (!Context.shouldMangleDeclName(FD)) { + mangleName(FD); + return; + } + + AbiTagList ReturnTypeAbiTags = makeFunctionReturnTypeTags(FD); + if (ReturnTypeAbiTags.empty()) { + // There are no tags for return type, the simplest case. + mangleName(FD); + mangleFunctionEncodingBareType(FD); return; + } + // Mangle function name and encoding to temporary buffer. + // We have to output name and encoding to the same mangler to get the same + // substitution as it will be in final mangling. + SmallString<256> FunctionEncodingBuf; + llvm::raw_svector_ostream FunctionEncodingStream(FunctionEncodingBuf); + CXXNameMangler FunctionEncodingMangler(*this, FunctionEncodingStream); + // Output name of the function. + FunctionEncodingMangler.disableDerivedAbiTags(); + FunctionEncodingMangler.mangleNameWithAbiTags(FD, nullptr); + + // Remember length of the function name in the buffer. + size_t EncodingPositionStart = FunctionEncodingStream.str().size(); + FunctionEncodingMangler.mangleFunctionEncodingBareType(FD); + + // Get tags from return type that are not present in function name or + // encoding. + const AbiTagList &UsedAbiTags = + FunctionEncodingMangler.AbiTagsRoot.getSortedUniqueUsedAbiTags(); + AbiTagList AdditionalAbiTags(ReturnTypeAbiTags.size()); + AdditionalAbiTags.erase( + std::set_difference(ReturnTypeAbiTags.begin(), ReturnTypeAbiTags.end(), + UsedAbiTags.begin(), UsedAbiTags.end(), + AdditionalAbiTags.begin()), + AdditionalAbiTags.end()); + + // Output name with implicit tags and function encoding from temporary buffer. + mangleNameWithAbiTags(FD, &AdditionalAbiTags); + Out << FunctionEncodingStream.str().substr(EncodingPositionStart); +} + +void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) { if (FD->hasAttr<EnableIfAttr>()) { FunctionTypeDepthState Saved = FunctionTypeDepth.push(); Out << "Ua9enable_ifI"; @@ -497,6 +707,12 @@ void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { FunctionTypeDepth.pop(Saved); } + // When mangling an inheriting constructor, the bare function type used is + // that of the inherited constructor. + if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) + if (auto Inherited = CD->getInheritedConstructor()) + FD = Inherited.getConstructor(); + // Whether the mangling of a function type includes the return type depends on // the context and the nature of the function. The rules for deciding whether // the return type is included are: @@ -523,7 +739,7 @@ void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { FD = PrimaryTemplate->getTemplatedDecl(); } - mangleBareFunctionType(FD->getType()->getAs<FunctionType>(), + mangleBareFunctionType(FD->getType()->castAs<FunctionProtoType>(), MangleReturnType, FD); } @@ -557,7 +773,7 @@ static bool isStdNamespace(const DeclContext *DC) { static const TemplateDecl * isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) { // Check if we have a function template. - if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)){ + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { if (const TemplateDecl *TD = FD->getPrimaryTemplate()) { TemplateArgs = FD->getTemplateSpecializationArgs(); return TD; @@ -582,6 +798,40 @@ isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) { } void CXXNameMangler::mangleName(const NamedDecl *ND) { + if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) { + // Variables should have implicit tags from its type. + AbiTagList VariableTypeAbiTags = makeVariableTypeTags(VD); + if (VariableTypeAbiTags.empty()) { + // Simple case no variable type tags. + mangleNameWithAbiTags(VD, nullptr); + return; + } + + // Mangle variable name to null stream to collect tags. + llvm::raw_null_ostream NullOutStream; + CXXNameMangler VariableNameMangler(*this, NullOutStream); + VariableNameMangler.disableDerivedAbiTags(); + VariableNameMangler.mangleNameWithAbiTags(VD, nullptr); + + // Get tags from variable type that are not present in its name. + const AbiTagList &UsedAbiTags = + VariableNameMangler.AbiTagsRoot.getSortedUniqueUsedAbiTags(); + AbiTagList AdditionalAbiTags(VariableTypeAbiTags.size()); + AdditionalAbiTags.erase( + std::set_difference(VariableTypeAbiTags.begin(), + VariableTypeAbiTags.end(), UsedAbiTags.begin(), + UsedAbiTags.end(), AdditionalAbiTags.begin()), + AdditionalAbiTags.end()); + + // Output name with implicit tags. + mangleNameWithAbiTags(VD, &AdditionalAbiTags); + } else { + mangleNameWithAbiTags(ND, nullptr); + } +} + +void CXXNameMangler::mangleNameWithAbiTags(const NamedDecl *ND, + const AbiTagList *AdditionalAbiTags) { // <name> ::= <nested-name> // ::= <unscoped-name> // ::= <unscoped-template-name> <template-args> @@ -597,7 +847,7 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) { while (!DC->isNamespace() && !DC->isTranslationUnit()) DC = getEffectiveParentContext(DC); else if (GetLocalClassDecl(ND)) { - mangleLocalName(ND); + mangleLocalName(ND, AdditionalAbiTags); return; } @@ -607,76 +857,88 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) { // Check if we have a template. const TemplateArgumentList *TemplateArgs = nullptr; if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { - mangleUnscopedTemplateName(TD); + mangleUnscopedTemplateName(TD, AdditionalAbiTags); mangleTemplateArgs(*TemplateArgs); return; } - mangleUnscopedName(ND); + mangleUnscopedName(ND, AdditionalAbiTags); return; } if (isLocalContainerContext(DC)) { - mangleLocalName(ND); + mangleLocalName(ND, AdditionalAbiTags); return; } - mangleNestedName(ND, DC); + mangleNestedName(ND, DC, AdditionalAbiTags); } -void CXXNameMangler::mangleName(const TemplateDecl *TD, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs) { + +void CXXNameMangler::mangleTemplateName(const TemplateDecl *TD, + const TemplateArgument *TemplateArgs, + unsigned NumTemplateArgs) { const DeclContext *DC = IgnoreLinkageSpecDecls(getEffectiveDeclContext(TD)); if (DC->isTranslationUnit() || isStdNamespace(DC)) { - mangleUnscopedTemplateName(TD); + mangleUnscopedTemplateName(TD, nullptr); mangleTemplateArgs(TemplateArgs, NumTemplateArgs); } else { mangleNestedName(TD, TemplateArgs, NumTemplateArgs); } } -void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND) { +void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND, + const AbiTagList *AdditionalAbiTags) { // <unscoped-name> ::= <unqualified-name> // ::= St <unqualified-name> # ::std:: if (isStdNamespace(IgnoreLinkageSpecDecls(getEffectiveDeclContext(ND)))) Out << "St"; - mangleUnqualifiedName(ND); + mangleUnqualifiedName(ND, AdditionalAbiTags); } -void CXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *ND) { +void CXXNameMangler::mangleUnscopedTemplateName( + const TemplateDecl *ND, const AbiTagList *AdditionalAbiTags) { // <unscoped-template-name> ::= <unscoped-name> // ::= <substitution> if (mangleSubstitution(ND)) return; // <template-template-param> ::= <template-param> - if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(ND)) + if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(ND)) { + assert(!AdditionalAbiTags && + "template template param cannot have abi tags"); mangleTemplateParameter(TTP->getIndex()); - else - mangleUnscopedName(ND->getTemplatedDecl()); + } else if (isa<BuiltinTemplateDecl>(ND)) { + mangleUnscopedName(ND, AdditionalAbiTags); + } else { + mangleUnscopedName(ND->getTemplatedDecl(), AdditionalAbiTags); + } addSubstitution(ND); } -void CXXNameMangler::mangleUnscopedTemplateName(TemplateName Template) { +void CXXNameMangler::mangleUnscopedTemplateName( + TemplateName Template, const AbiTagList *AdditionalAbiTags) { // <unscoped-template-name> ::= <unscoped-name> // ::= <substitution> if (TemplateDecl *TD = Template.getAsTemplateDecl()) - return mangleUnscopedTemplateName(TD); + return mangleUnscopedTemplateName(TD, AdditionalAbiTags); if (mangleSubstitution(Template)) return; + assert(!AdditionalAbiTags && + "dependent template name cannot have abi tags"); + DependentTemplateName *Dependent = Template.getAsDependentTemplateName(); assert(Dependent && "Not a dependent template name?"); if (const IdentifierInfo *Id = Dependent->getIdentifier()) mangleSourceName(Id); else mangleOperatorName(Dependent->getOperator(), UnknownArity); - + addSubstitution(Template); } @@ -834,7 +1096,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, /*recursive*/ true); else Out << "sr"; - mangleSourceName(qualifier->getAsNamespace()->getIdentifier()); + mangleSourceNameWithAbiTags(qualifier->getAsNamespace()); break; case NestedNameSpecifier::NamespaceAlias: if (qualifier->getPrefix()) @@ -842,7 +1104,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, /*recursive*/ true); else Out << "sr"; - mangleSourceName(qualifier->getAsNamespaceAlias()->getIdentifier()); + mangleSourceNameWithAbiTags(qualifier->getAsNamespaceAlias()); break; case NestedNameSpecifier::TypeSpec: @@ -877,6 +1139,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, Out << "sr"; mangleSourceName(qualifier->getAsIdentifier()); + // An Identifier has no type information, so we can't emit abi tags for it. break; } @@ -922,7 +1185,8 @@ void CXXNameMangler::mangleUnresolvedName(NestedNameSpecifier *qualifier, void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name, - unsigned KnownArity) { + unsigned KnownArity, + const AbiTagList *AdditionalAbiTags) { unsigned Arity = KnownArity; // <unqualified-name> ::= <operator-name> // ::= <ctor-dtor-name> @@ -941,6 +1205,7 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, Out << 'L'; mangleSourceName(II); + writeAbiTags(ND, AdditionalAbiTags); break; } @@ -980,6 +1245,7 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, assert(FD->getIdentifier() && "Data member name isn't an identifier!"); mangleSourceName(FD->getIdentifier()); + // Not emitting abi tags: internal name anyway. break; } @@ -1000,6 +1266,10 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, assert(D->getDeclName().getAsIdentifierInfo() && "Typedef was not named!"); mangleSourceName(D->getDeclName().getAsIdentifierInfo()); + assert(!AdditionalAbiTags && "Type cannot have additional abi tags"); + // Explicit abi tags are still possible; take from underlying type, not + // from typedef. + writeAbiTags(TD, nullptr); break; } @@ -1009,6 +1279,8 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, // <lambda-sig> ::= <parameter-type>+ # Parameter types or 'v' for 'void'. if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) { if (Record->isLambda() && Record->getLambdaManglingNumber()) { + assert(!AdditionalAbiTags && + "Lambda type cannot have additional abi tags"); mangleLambda(Record); break; } @@ -1020,11 +1292,13 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, if (UnnamedMangle > 1) Out << UnnamedMangle - 2; Out << '_'; + writeAbiTags(TD, AdditionalAbiTags); break; } - // Get a unique id for the anonymous struct. - unsigned AnonStructId = Context.getAnonymousStructId(TD); + // Get a unique id for the anonymous struct. If it is not a real output + // ID doesn't matter so use fake one. + unsigned AnonStructId = NullOut ? 0 : Context.getAnonymousStructId(TD); // Mangle it as a source name in the form // [n] $_<id> @@ -1043,16 +1317,33 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, case DeclarationName::ObjCMultiArgSelector: llvm_unreachable("Can't mangle Objective-C selector names here!"); - case DeclarationName::CXXConstructorName: + case DeclarationName::CXXConstructorName: { + const CXXRecordDecl *InheritedFrom = nullptr; + const TemplateArgumentList *InheritedTemplateArgs = nullptr; + if (auto Inherited = + cast<CXXConstructorDecl>(ND)->getInheritedConstructor()) { + InheritedFrom = Inherited.getConstructor()->getParent(); + InheritedTemplateArgs = + Inherited.getConstructor()->getTemplateSpecializationArgs(); + } + if (ND == Structor) // If the named decl is the C++ constructor we're mangling, use the type // we were given. - mangleCXXCtorType(static_cast<CXXCtorType>(StructorType)); + mangleCXXCtorType(static_cast<CXXCtorType>(StructorType), InheritedFrom); else // Otherwise, use the complete constructor name. This is relevant if a // class with a constructor is declared within a constructor. - mangleCXXCtorType(Ctor_Complete); + mangleCXXCtorType(Ctor_Complete, InheritedFrom); + + // FIXME: The template arguments are part of the enclosing prefix or + // nested-name, but it's more convenient to mangle them here. + if (InheritedTemplateArgs) + mangleTemplateArgs(*InheritedTemplateArgs); + + writeAbiTags(ND, AdditionalAbiTags); break; + } case DeclarationName::CXXDestructorName: if (ND == Structor) @@ -1063,6 +1354,7 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, // Otherwise, use the complete destructor name. This is relevant if a // class with a destructor is declared within a destructor. mangleCXXDtorType(Dtor_Complete); + writeAbiTags(ND, AdditionalAbiTags); break; case DeclarationName::CXXOperatorName: @@ -1078,6 +1370,7 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, case DeclarationName::CXXConversionFunctionName: case DeclarationName::CXXLiteralOperatorName: mangleOperatorName(Name, Arity); + writeAbiTags(ND, AdditionalAbiTags); break; case DeclarationName::CXXUsingDirective: @@ -1094,6 +1387,7 @@ void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) { void CXXNameMangler::mangleNestedName(const NamedDecl *ND, const DeclContext *DC, + const AbiTagList *AdditionalAbiTags, bool NoFunction) { // <nested-name> // ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E @@ -1119,7 +1413,7 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND, } else { manglePrefix(DC, NoFunction); - mangleUnqualifiedName(ND); + mangleUnqualifiedName(ND, AdditionalAbiTags); } Out << 'E'; @@ -1137,7 +1431,8 @@ void CXXNameMangler::mangleNestedName(const TemplateDecl *TD, Out << 'E'; } -void CXXNameMangler::mangleLocalName(const Decl *D) { +void CXXNameMangler::mangleLocalName(const Decl *D, + const AbiTagList *AdditionalAbiTags) { // <local-name> := Z <function encoding> E <entity name> [<discriminator>] // := Z <function encoding> E s [<discriminator>] // <local-name> := Z <function encoding> E d [ <parameter number> ] @@ -1149,15 +1444,26 @@ void CXXNameMangler::mangleLocalName(const Decl *D) { Out << 'Z'; - if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC)) - mangleObjCMethodName(MD); - else if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) - mangleBlockForPrefix(BD); - else - mangleFunctionEncoding(cast<FunctionDecl>(DC)); + { + AbiTagState LocalAbiTags(AbiTags); + + if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC)) + mangleObjCMethodName(MD); + else if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) + mangleBlockForPrefix(BD); + else + mangleFunctionEncoding(cast<FunctionDecl>(DC)); + + // Implicit ABI tags (from namespace) are not available in the following + // entity; reset to actually emitted tags, which are available. + LocalAbiTags.setUsedAbiTags(LocalAbiTags.getEmittedAbiTags()); + } Out << 'E'; + // GCC 5.3.0 doesn't emit derived ABI tags for local names but that seems to + // be a bug that is fixed in trunk. + if (RD) { // The parameter number is omitted for the last parameter, 0 for the // second-to-last parameter, 1 for the third-to-last parameter, etc. The @@ -1182,13 +1488,15 @@ void CXXNameMangler::mangleLocalName(const Decl *D) { // Mangle the name relative to the closest enclosing function. // equality ok because RD derived from ND above if (D == RD) { - mangleUnqualifiedName(RD); + mangleUnqualifiedName(RD, AdditionalAbiTags); } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) { manglePrefix(getEffectiveDeclContext(BD), true /*NoFunction*/); + assert(!AdditionalAbiTags && "Block cannot have additional abi tags"); mangleUnqualifiedBlock(BD); } else { const NamedDecl *ND = cast<NamedDecl>(D); - mangleNestedName(ND, getEffectiveDeclContext(ND), true /*NoFunction*/); + mangleNestedName(ND, getEffectiveDeclContext(ND), AdditionalAbiTags, + true /*NoFunction*/); } } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) { // Mangle a block in a default parameter; see above explanation for @@ -1205,9 +1513,10 @@ void CXXNameMangler::mangleLocalName(const Decl *D) { } } + assert(!AdditionalAbiTags && "Block cannot have additional abi tags"); mangleUnqualifiedBlock(BD); } else { - mangleUnqualifiedName(cast<NamedDecl>(D)); + mangleUnqualifiedName(cast<NamedDecl>(D), AdditionalAbiTags); } if (const NamedDecl *ND = dyn_cast<NamedDecl>(RD ? RD : D)) { @@ -1223,12 +1532,12 @@ void CXXNameMangler::mangleLocalName(const Decl *D) { void CXXNameMangler::mangleBlockForPrefix(const BlockDecl *Block) { if (GetLocalClassDecl(Block)) { - mangleLocalName(Block); + mangleLocalName(Block, /* AdditionalAbiTags */ nullptr); return; } const DeclContext *DC = getEffectiveDeclContext(Block); if (isLocalContainerContext(DC)) { - mangleLocalName(Block); + mangleLocalName(Block, /* AdditionalAbiTags */ nullptr); return; } manglePrefix(getEffectiveDeclContext(Block)); @@ -1239,10 +1548,10 @@ void CXXNameMangler::mangleUnqualifiedBlock(const BlockDecl *Block) { if (Decl *Context = Block->getBlockManglingContextDecl()) { if ((isa<VarDecl>(Context) || isa<FieldDecl>(Context)) && Context->getDeclContext()->isRecord()) { - if (const IdentifierInfo *Name - = cast<NamedDecl>(Context)->getIdentifier()) { - mangleSourceName(Name); - Out << 'M'; + const auto *ND = cast<NamedDecl>(Context); + if (ND->getIdentifier()) { + mangleSourceNameWithAbiTags(ND); + Out << 'M'; } } } @@ -1275,7 +1584,7 @@ void CXXNameMangler::mangleLambda(const CXXRecordDecl *Lambda) { if (const IdentifierInfo *Name = cast<NamedDecl>(Context)->getIdentifier()) { mangleSourceName(Name); - Out << 'M'; + Out << 'M'; } } } @@ -1362,7 +1671,7 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) { mangleTemplateArgs(*TemplateArgs); } else { manglePrefix(getEffectiveDeclContext(ND), NoFunction); - mangleUnqualifiedName(ND); + mangleUnqualifiedName(ND, nullptr); } addSubstitution(ND); @@ -1377,19 +1686,19 @@ void CXXNameMangler::mangleTemplatePrefix(TemplateName Template) { if (QualifiedTemplateName *Qualified = Template.getAsQualifiedTemplateName()) manglePrefix(Qualified->getQualifier()); - + if (OverloadedTemplateStorage *Overloaded = Template.getAsOverloadedTemplate()) { mangleUnqualifiedName(nullptr, (*Overloaded->begin())->getDeclName(), - UnknownArity); + UnknownArity, nullptr); return; } - + DependentTemplateName *Dependent = Template.getAsDependentTemplateName(); assert(Dependent && "Unknown template name kind?"); if (NestedNameSpecifier *Qualifier = Dependent->getQualifier()) manglePrefix(Qualifier); - mangleUnscopedTemplateName(Template); + mangleUnscopedTemplateName(Template, /* AdditionalAbiTags */ nullptr); } void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND, @@ -1408,7 +1717,10 @@ void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND, mangleTemplateParameter(TTP->getIndex()); } else { manglePrefix(getEffectiveDeclContext(ND), NoFunction); - mangleUnqualifiedName(ND->getTemplatedDecl()); + if (isa<BuiltinTemplateDecl>(ND)) + mangleUnqualifiedName(ND, nullptr); + else + mangleUnqualifiedName(ND->getTemplatedDecl(), nullptr); } addSubstitution(ND); @@ -1543,17 +1855,17 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty, return true; case Type::Typedef: - mangleSourceName(cast<TypedefType>(Ty)->getDecl()->getIdentifier()); + mangleSourceNameWithAbiTags(cast<TypedefType>(Ty)->getDecl()); break; case Type::UnresolvedUsing: - mangleSourceName( - cast<UnresolvedUsingType>(Ty)->getDecl()->getIdentifier()); + mangleSourceNameWithAbiTags( + cast<UnresolvedUsingType>(Ty)->getDecl()); break; case Type::Enum: case Type::Record: - mangleSourceName(cast<TagType>(Ty)->getDecl()->getIdentifier()); + mangleSourceNameWithAbiTags(cast<TagType>(Ty)->getDecl()); break; case Type::TemplateSpecialization: { @@ -1571,7 +1883,7 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty, if (isa<TemplateTemplateParmDecl>(TD)) goto unresolvedType; - mangleSourceName(TD->getIdentifier()); + mangleSourceNameWithAbiTags(TD); break; } @@ -1601,8 +1913,8 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty, } case Type::InjectedClassName: - mangleSourceName( - cast<InjectedClassNameType>(Ty)->getDecl()->getIdentifier()); + mangleSourceNameWithAbiTags( + cast<InjectedClassNameType>(Ty)->getDecl()); break; case Type::DependentName: @@ -1653,8 +1965,6 @@ void CXXNameMangler::mangleOperatorName(DeclarationName Name, unsigned Arity) { } } - - void CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) { switch (OO) { @@ -1767,14 +2077,9 @@ CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) { } void CXXNameMangler::mangleQualifiers(Qualifiers Quals) { - // <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const - if (Quals.hasRestrict()) - Out << 'r'; - if (Quals.hasVolatile()) - Out << 'V'; - if (Quals.hasConst()) - Out << 'K'; + // Vendor qualifiers come first. + // Address space qualifiers start with an ordinary letter. if (Quals.hasAddressSpace()) { // Address space extension: // @@ -1788,7 +2093,7 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) { if (Context.getASTContext().addressSpaceMapManglingFor(AS)) { // <target-addrspace> ::= "AS" <address-space-number> unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS); - ASString = "AS" + llvm::utostr_32(TargetAS); + ASString = "AS" + llvm::utostr(TargetAS); } else { switch (AS) { default: llvm_unreachable("Not a language specific address space"); @@ -1802,10 +2107,10 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) { case LangAS::cuda_shared: ASString = "CUshared"; break; } } - Out << 'U' << ASString.size() << ASString; + mangleVendorQualifier(ASString); } - - StringRef LifetimeName; + + // The ARC ownership qualifiers start with underscores. switch (Quals.getObjCLifetime()) { // Objective-C ARC Extension: // @@ -1816,15 +2121,15 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) { break; case Qualifiers::OCL_Weak: - LifetimeName = "__weak"; + mangleVendorQualifier("__weak"); break; case Qualifiers::OCL_Strong: - LifetimeName = "__strong"; + mangleVendorQualifier("__strong"); break; case Qualifiers::OCL_Autoreleasing: - LifetimeName = "__autoreleasing"; + mangleVendorQualifier("__autoreleasing"); break; case Qualifiers::OCL_ExplicitNone: @@ -1837,8 +2142,18 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) { // in any type signatures that need to be mangled. break; } - if (!LifetimeName.empty()) - Out << 'U' << LifetimeName.size() << LifetimeName; + + // <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const + if (Quals.hasRestrict()) + Out << 'r'; + if (Quals.hasVolatile()) + Out << 'V'; + if (Quals.hasConst()) + Out << 'K'; +} + +void CXXNameMangler::mangleVendorQualifier(StringRef name) { + Out << 'U' << name.size() << name; } void CXXNameMangler::mangleRefQualifier(RefQualifierKind RefQualifier) { @@ -1981,7 +2296,7 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { // ::= f # float // ::= d # double // ::= e # long double, __float80 - // UNSUPPORTED: ::= g # __float128 + // ::= g # __float128 // UNSUPPORTED: ::= Dd # IEEE 754r decimal floating point (64 bits) // UNSUPPORTED: ::= De # IEEE 754r decimal floating point (128 bits) // UNSUPPORTED: ::= Df # IEEE 754r decimal floating point (32 bits) @@ -1990,6 +2305,7 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { // ::= Ds # char16_t // ::= Dn # std::nullptr_t (i.e., decltype(nullptr)) // ::= u <source-name> # vendor extended type + std::string type_name; switch (T->getKind()) { case BuiltinType::Void: Out << 'v'; @@ -2061,6 +2377,12 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { ? 'g' : 'e'); break; + case BuiltinType::Float128: + if (getASTContext().getTargetInfo().useFloat128ManglingForLongDouble()) + Out << "U10__float128"; // Match the GCC mangling + else + Out << 'g'; + break; case BuiltinType::NullPtr: Out << "Dn"; break; @@ -2070,7 +2392,9 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { case BuiltinType::Id: #include "clang/AST/BuiltinTypes.def" case BuiltinType::Dependent: - llvm_unreachable("mangling a placeholder type"); + if (!NullOut) + llvm_unreachable("mangling a placeholder type"); + break; case BuiltinType::ObjCId: Out << "11objc_object"; break; @@ -2080,42 +2404,12 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { case BuiltinType::ObjCSel: Out << "13objc_selector"; break; - case BuiltinType::OCLImage1d: - Out << "11ocl_image1d"; - break; - case BuiltinType::OCLImage1dArray: - Out << "16ocl_image1darray"; - break; - case BuiltinType::OCLImage1dBuffer: - Out << "17ocl_image1dbuffer"; - break; - case BuiltinType::OCLImage2d: - Out << "11ocl_image2d"; - break; - case BuiltinType::OCLImage2dArray: - Out << "16ocl_image2darray"; - break; - case BuiltinType::OCLImage2dDepth: - Out << "16ocl_image2ddepth"; - break; - case BuiltinType::OCLImage2dArrayDepth: - Out << "21ocl_image2darraydepth"; - break; - case BuiltinType::OCLImage2dMSAA: - Out << "15ocl_image2dmsaa"; - break; - case BuiltinType::OCLImage2dArrayMSAA: - Out << "20ocl_image2darraymsaa"; - break; - case BuiltinType::OCLImage2dMSAADepth: - Out << "20ocl_image2dmsaadepth"; - break; - case BuiltinType::OCLImage2dArrayMSAADepth: - Out << "35ocl_image2darraymsaadepth"; - break; - case BuiltinType::OCLImage3d: - Out << "11ocl_image3d"; +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: \ + type_name = "ocl_" #ImgType "_" #Suffix; \ + Out << type_name.size() << type_name; \ break; +#include "clang/Basic/OpenCLImageTypes.def" case BuiltinType::OCLSampler: Out << "11ocl_sampler"; break; @@ -2137,10 +2431,80 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { } } +StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) { + switch (CC) { + case CC_C: + return ""; + + case CC_X86StdCall: + case CC_X86FastCall: + case CC_X86ThisCall: + case CC_X86VectorCall: + case CC_X86Pascal: + case CC_X86_64Win64: + case CC_X86_64SysV: + case CC_AAPCS: + case CC_AAPCS_VFP: + case CC_IntelOclBicc: + case CC_SpirFunction: + case CC_OpenCLKernel: + case CC_PreserveMost: + case CC_PreserveAll: + // FIXME: we should be mangling all of the above. + return ""; + + case CC_Swift: + return "swiftcall"; + } + llvm_unreachable("bad calling convention"); +} + +void CXXNameMangler::mangleExtFunctionInfo(const FunctionType *T) { + // Fast path. + if (T->getExtInfo() == FunctionType::ExtInfo()) + return; + + // Vendor-specific qualifiers are emitted in reverse alphabetical order. + // This will get more complicated in the future if we mangle other + // things here; but for now, since we mangle ns_returns_retained as + // a qualifier on the result type, we can get away with this: + StringRef CCQualifier = getCallingConvQualifierName(T->getExtInfo().getCC()); + if (!CCQualifier.empty()) + mangleVendorQualifier(CCQualifier); + + // FIXME: regparm + // FIXME: noreturn +} + +void +CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) { + // Vendor-specific qualifiers are emitted in reverse alphabetical order. + + // Note that these are *not* substitution candidates. Demanglers might + // have trouble with this if the parameter type is fully substituted. + + switch (PI.getABI()) { + case ParameterABI::Ordinary: + break; + + // All of these start with "swift", so they come before "ns_consumed". + case ParameterABI::SwiftContext: + case ParameterABI::SwiftErrorResult: + case ParameterABI::SwiftIndirectResult: + mangleVendorQualifier(getParameterABISpelling(PI.getABI())); + break; + } + + if (PI.isConsumed()) + mangleVendorQualifier("ns_consumed"); +} + // <type> ::= <function-type> // <function-type> ::= [<CV-qualifiers>] F [Y] // <bare-function-type> [<ref-qualifier>] E void CXXNameMangler::mangleType(const FunctionProtoType *T) { + mangleExtFunctionInfo(T); + // Mangle CV-qualifiers, if present. These are 'this' qualifiers, // e.g. "const" in "int (A::*)() const". mangleQualifiers(Qualifiers::fromCVRMask(T->getTypeQuals())); @@ -2173,12 +2537,9 @@ void CXXNameMangler::mangleType(const FunctionNoProtoType *T) { Out << 'E'; } -void CXXNameMangler::mangleBareFunctionType(const FunctionType *T, +void CXXNameMangler::mangleBareFunctionType(const FunctionProtoType *Proto, bool MangleReturnType, const FunctionDecl *FD) { - // We should never be mangling something without a prototype. - const FunctionProtoType *Proto = cast<FunctionProtoType>(T); - // Record that we're in a function type. See mangleFunctionParam // for details on what we're trying to achieve here. FunctionTypeDepthState saved = FunctionTypeDepth.push(); @@ -2186,7 +2547,20 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionType *T, // <bare-function-type> ::= <signature type>+ if (MangleReturnType) { FunctionTypeDepth.enterResultType(); - mangleType(Proto->getReturnType()); + + // Mangle ns_returns_retained as an order-sensitive qualifier here. + if (Proto->getExtInfo().getProducesResult() && FD == nullptr) + mangleVendorQualifier("ns_returns_retained"); + + // Mangle the return type without any direct ARC ownership qualifiers. + QualType ReturnTy = Proto->getReturnType(); + if (ReturnTy.getObjCLifetime()) { + auto SplitReturnTy = ReturnTy.split(); + SplitReturnTy.Quals.removeObjCLifetime(); + ReturnTy = getASTContext().getQualifiedType(SplitReturnTy); + } + mangleType(ReturnTy); + FunctionTypeDepth.leaveResultType(); } @@ -2200,7 +2574,13 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionType *T, assert(!FD || FD->getNumParams() == Proto->getNumParams()); for (unsigned I = 0, E = Proto->getNumParams(); I != E; ++I) { - const auto &ParamTy = Proto->getParamType(I); + // Mangle extended parameter info as order-sensitive qualifiers here. + if (Proto->hasExtParameterInfos() && FD == nullptr) { + mangleExtParameterInfo(Proto->getExtParameterInfo(I)); + } + + // Mangle the type. + QualType ParamTy = Proto->getParamType(I); mangleType(Context.getASTContext().getSignatureParameterType(ParamTy)); if (FD) { @@ -2546,7 +2926,7 @@ void CXXNameMangler::mangleType(const InjectedClassNameType *T) { void CXXNameMangler::mangleType(const TemplateSpecializationType *T) { if (TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl()) { - mangleName(TD, T->getArgs(), T->getNumArgs()); + mangleTemplateName(TD, T->getArgs(), T->getNumArgs()); } else { if (mangleSubstitution(QualType(T, 0))) return; @@ -2662,7 +3042,7 @@ void CXXNameMangler::mangleType(const UnaryTransformType *T) { } } - mangleType(T->getUnderlyingType()); + mangleType(T->getBaseType()); } void CXXNameMangler::mangleType(const AutoType *T) { @@ -2836,6 +3216,7 @@ recurse: case Expr::MSPropertySubscriptExprClass: case Expr::TypoExprClass: // This should no longer exist in the AST by now. case Expr::OMPArraySectionExprClass: + case Expr::CXXInheritedCtorInitExprClass: llvm_unreachable("unexpected statement kind"); // FIXME: invent manglings for all these. @@ -2858,6 +3239,7 @@ recurse: case Expr::ObjCDictionaryLiteralClass: case Expr::ObjCSubscriptRefExprClass: case Expr::ObjCIndirectCopyRestoreExprClass: + case Expr::ObjCAvailabilityCheckExprClass: case Expr::OffsetOfExprClass: case Expr::PredefinedExprClass: case Expr::ShuffleVectorExprClass: @@ -2872,12 +3254,14 @@ recurse: case Expr::PseudoObjectExprClass: case Expr::AtomicExprClass: { - // As bad as this diagnostic is, it's better than crashing. - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot yet mangle expression type %0"); - Diags.Report(E->getExprLoc(), DiagID) - << E->getStmtClassName() << E->getSourceRange(); + if (!NullOut) { + // As bad as this diagnostic is, it's better than crashing. + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot yet mangle expression type %0"); + Diags.Report(E->getExprLoc(), DiagID) + << E->getStmtClassName() << E->getSourceRange(); + } break; } @@ -3615,25 +3999,33 @@ void CXXNameMangler::mangleFunctionParam(const ParmVarDecl *parm) { Out << '_'; } -void CXXNameMangler::mangleCXXCtorType(CXXCtorType T) { +void CXXNameMangler::mangleCXXCtorType(CXXCtorType T, + const CXXRecordDecl *InheritedFrom) { // <ctor-dtor-name> ::= C1 # complete object constructor // ::= C2 # base object constructor + // ::= CI1 <type> # complete inheriting constructor + // ::= CI2 <type> # base inheriting constructor // // In addition, C5 is a comdat name with C1 and C2 in it. + Out << 'C'; + if (InheritedFrom) + Out << 'I'; switch (T) { case Ctor_Complete: - Out << "C1"; + Out << '1'; break; case Ctor_Base: - Out << "C2"; + Out << '2'; break; case Ctor_Comdat: - Out << "C5"; + Out << '5'; break; case Ctor_DefaultClosure: case Ctor_CopyingClosure: llvm_unreachable("closure constructors don't exist for the Itanium ABI!"); } + if (InheritedFrom) + mangleName(InheritedFrom); } void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) { @@ -3745,7 +4137,7 @@ void CXXNameMangler::mangleTemplateArg(TemplateArgument A) { Out << 'L'; // References to external entities use the mangled name; if the name would - // not normally be manged then mangle it as unqualified. + // not normally be mangled then mangle it as unqualified. mangle(D); Out << 'E'; @@ -3801,12 +4193,6 @@ void CXXNameMangler::mangleSeqID(unsigned SeqID) { Out << '_'; } -void CXXNameMangler::mangleExistingSubstitution(QualType type) { - bool result = mangleSubstitution(type); - assert(result && "no existing substitution for type"); - (void) result; -} - void CXXNameMangler::mangleExistingSubstitution(TemplateName tname) { bool result = mangleSubstitution(tname); assert(result && "no existing substitution for template name"); @@ -4020,6 +4406,48 @@ void CXXNameMangler::addSubstitution(uintptr_t Ptr) { Substitutions[Ptr] = SeqID++; } +CXXNameMangler::AbiTagList +CXXNameMangler::makeFunctionReturnTypeTags(const FunctionDecl *FD) { + // When derived abi tags are disabled there is no need to make any list. + if (DisableDerivedAbiTags) + return AbiTagList(); + + llvm::raw_null_ostream NullOutStream; + CXXNameMangler TrackReturnTypeTags(*this, NullOutStream); + TrackReturnTypeTags.disableDerivedAbiTags(); + + const FunctionProtoType *Proto = + cast<FunctionProtoType>(FD->getType()->getAs<FunctionType>()); + TrackReturnTypeTags.FunctionTypeDepth.enterResultType(); + TrackReturnTypeTags.mangleType(Proto->getReturnType()); + TrackReturnTypeTags.FunctionTypeDepth.leaveResultType(); + + return TrackReturnTypeTags.AbiTagsRoot.getSortedUniqueUsedAbiTags(); +} + +CXXNameMangler::AbiTagList +CXXNameMangler::makeVariableTypeTags(const VarDecl *VD) { + // When derived abi tags are disabled there is no need to make any list. + if (DisableDerivedAbiTags) + return AbiTagList(); + + llvm::raw_null_ostream NullOutStream; + CXXNameMangler TrackVariableType(*this, NullOutStream); + TrackVariableType.disableDerivedAbiTags(); + + TrackVariableType.mangleType(VD->getType()); + + return TrackVariableType.AbiTagsRoot.getSortedUniqueUsedAbiTags(); +} + +bool CXXNameMangler::shouldHaveAbiTags(ItaniumMangleContextImpl &C, + const VarDecl *VD) { + llvm::raw_null_ostream NullOutStream; + CXXNameMangler TrackAbiTags(C, NullOutStream, nullptr, true); + TrackAbiTags.mangle(VD); + return TrackAbiTags.AbiTagsRoot.getUsedAbiTags().size(); +} + // /// Mangles the name of the declaration D and emits that name to the given @@ -4121,6 +4549,8 @@ void ItaniumMangleContextImpl::mangleStaticGuardVariable(const VarDecl *D, // <special-name> ::= GV <object name> # Guard variable for one-time // # initialization CXXNameMangler Mangler(*this, Out); + // GCC 5.3.0 doesn't emit derived ABI tags for local names but that seems to + // be a bug that is fixed in trunk. Mangler.getStream() << "_ZGV"; Mangler.mangleName(D); } diff --git a/contrib/llvm/tools/clang/lib/AST/Mangle.cpp b/contrib/llvm/tools/clang/lib/AST/Mangle.cpp index 014338f..ee24173 100644 --- a/contrib/llvm/tools/clang/lib/AST/Mangle.cpp +++ b/contrib/llvm/tools/clang/lib/AST/Mangle.cpp @@ -126,9 +126,9 @@ void MangleContext::mangleName(const NamedDecl *D, raw_ostream &Out) { // llvm mangler on ELF is a nop, so we can just avoid adding the \01 // marker. We also avoid adding the marker if this is an alias for an // LLVM intrinsic. - StringRef UserLabelPrefix = - getASTContext().getTargetInfo().getUserLabelPrefix(); - if (!UserLabelPrefix.empty() && !ALA->getLabel().startswith("llvm.")) + char GlobalPrefix = + getASTContext().getTargetInfo().getDataLayout().getGlobalPrefix(); + if (GlobalPrefix && !ALA->getLabel().startswith("llvm.")) Out << '\01'; // LLVM IR Marker for __asm("foo") Out << ALA->getLabel(); @@ -177,9 +177,9 @@ void MangleContext::mangleName(const NamedDecl *D, raw_ostream &Out) { ++ArgWords; for (const auto &AT : Proto->param_types()) // Size should be aligned to pointer size. - ArgWords += llvm::RoundUpToAlignment(ASTContext.getTypeSize(AT), - TI.getPointerWidth(0)) / - TI.getPointerWidth(0); + ArgWords += + llvm::alignTo(ASTContext.getTypeSize(AT), TI.getPointerWidth(0)) / + TI.getPointerWidth(0); Out << ((TI.getPointerWidth(0) / 8) * ArgWords); } @@ -254,11 +254,8 @@ void MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD, mangleFunctionBlock(*this, Buffer, BD, Out); } -void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD, - raw_ostream &Out) { - SmallString<64> Name; - llvm::raw_svector_ostream OS(Name); - +void MangleContext::mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, + raw_ostream &OS) { const ObjCContainerDecl *CD = dyn_cast<ObjCContainerDecl>(MD->getDeclContext()); assert (CD && "Missing container decl in GetNameForMethod"); @@ -268,6 +265,13 @@ void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD, OS << ' '; MD->getSelector().print(OS); OS << ']'; - +} + +void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD, + raw_ostream &Out) { + SmallString<64> Name; + llvm::raw_svector_ostream OS(Name); + + mangleObjCMethodNameWithoutSize(MD, OS); Out << OS.str().size() << OS.str(); } diff --git a/contrib/llvm/tools/clang/lib/AST/MicrosoftCXXABI.cpp b/contrib/llvm/tools/clang/lib/AST/MicrosoftCXXABI.cpp index 6ba31cc..3ae0453 100644 --- a/contrib/llvm/tools/clang/lib/AST/MicrosoftCXXABI.cpp +++ b/contrib/llvm/tools/clang/lib/AST/MicrosoftCXXABI.cpp @@ -262,7 +262,7 @@ std::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign( Align = Target.getIntAlign(); if (Target.getTriple().isArch64Bit()) - Width = llvm::RoundUpToAlignment(Width, Align); + Width = llvm::alignTo(Width, Align); return std::make_pair(Width, Align); } diff --git a/contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp b/contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp index 4a45f9e..351997e 100644 --- a/contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp +++ b/contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp @@ -19,6 +19,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" @@ -27,13 +28,44 @@ #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/Support/MathExtras.h" #include "llvm/Support/JamCRC.h" +#include "llvm/Support/MD5.h" +#include "llvm/Support/MathExtras.h" using namespace clang; namespace { +struct msvc_hashing_ostream : public llvm::raw_svector_ostream { + raw_ostream &OS; + llvm::SmallString<64> Buffer; + + msvc_hashing_ostream(raw_ostream &OS) + : llvm::raw_svector_ostream(Buffer), OS(OS) {} + ~msvc_hashing_ostream() override { + StringRef MangledName = str(); + bool StartsWithEscape = MangledName.startswith("\01"); + if (StartsWithEscape) + MangledName = MangledName.drop_front(1); + if (MangledName.size() <= 4096) { + OS << str(); + return; + } + + llvm::MD5 Hasher; + llvm::MD5::MD5Result Hash; + Hasher.update(MangledName); + Hasher.final(Hash); + + SmallString<32> HexString; + llvm::MD5::stringifyResult(Hash, HexString); + + if (StartsWithEscape) + OS << '\01'; + OS << "??@" << HexString << '@'; + } +}; + /// \brief Retrieve the declaration context that should be used when mangling /// the given declaration. static const DeclContext *getEffectiveDeclContext(const Decl *D) { @@ -58,10 +90,11 @@ static const DeclContext *getEffectiveDeclContext(const Decl *D) { } const DeclContext *DC = D->getDeclContext(); - if (const CapturedDecl *CD = dyn_cast<CapturedDecl>(DC)) - return getEffectiveDeclContext(CD); + if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC)) { + return getEffectiveDeclContext(cast<Decl>(DC)); + } - return DC; + return DC->getRedeclContext(); } static const DeclContext *getEffectiveParentContext(const DeclContext *DC) { @@ -120,7 +153,8 @@ public: const CXXRecordDecl *DstRD, raw_ostream &Out) override; void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile, - uint32_t NumEntries, raw_ostream &Out) override; + bool IsUnaligned, uint32_t NumEntries, + raw_ostream &Out) override; void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries, raw_ostream &Out) override; void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD, @@ -160,14 +194,17 @@ public: raw_ostream &Out) override; void mangleStringLiteral(const StringLiteral *SL, raw_ostream &Out) override; bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) { - // Lambda closure types are already numbered. - if (isLambda(ND)) - return false; - const DeclContext *DC = getEffectiveDeclContext(ND); if (!DC->isFunctionOrMethod()) return false; + // Lambda closure types are already numbered, give out a phony number so + // that they demangle nicely. + if (isLambda(ND)) { + disc = 1; + return true; + } + // Use the canonical number for externally visible decls. if (ND->isExternallyVisible()) { disc = getASTContext().getManglingNumber(ND); @@ -201,7 +238,7 @@ public: } private: - void mangleInitFiniStub(const VarDecl *D, raw_ostream &Out, char CharCode); + void mangleInitFiniStub(const VarDecl *D, char CharCode, raw_ostream &Out); }; /// MicrosoftCXXNameMangler - Manage the mangling of a single name for the @@ -1150,7 +1187,7 @@ void MicrosoftCXXNameMangler::mangleExpression(const Expr *E) { // This CXXUuidofExpr is mangled as-if it were actually a VarDecl from // const __s_GUID _GUID_{lower case UUID with underscores} - StringRef Uuid = UE->getUuidAsStringRef(Context.getASTContext()); + StringRef Uuid = UE->getUuidStr(); std::string Name = "_GUID_" + Uuid.lower(); std::replace(Name.begin(), Name.end(), '-', '_'); @@ -1410,6 +1447,10 @@ void MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals, if (HasRestrict) Out << 'I'; + + if (Quals.hasUnaligned() || + (!PointeeType.isNull() && PointeeType.getLocalQualifiers().hasUnaligned())) + Out << 'F'; } void MicrosoftCXXNameMangler::manglePointerCVQualifiers(Qualifiers Quals) { @@ -1541,6 +1582,8 @@ void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range, } break; case QMM_Result: + // Presence of __unaligned qualifier shouldn't affect mangling here. + Quals.removeUnaligned(); if ((!IsPointer && Quals) || isa<TagType>(T)) { Out << '?'; mangleQualifiers(Quals, false); @@ -1681,54 +1724,11 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers, mangleArtificalTagType(TTK_Struct, "objc_selector"); break; - case BuiltinType::OCLImage1d: - Out << "PA"; - mangleArtificalTagType(TTK_Struct, "ocl_image1d"); - break; - case BuiltinType::OCLImage1dArray: - Out << "PA"; - mangleArtificalTagType(TTK_Struct, "ocl_image1darray"); - break; - case BuiltinType::OCLImage1dBuffer: - Out << "PA"; - mangleArtificalTagType(TTK_Struct, "ocl_image1dbuffer"); - break; - case BuiltinType::OCLImage2d: - Out << "PA"; - mangleArtificalTagType(TTK_Struct, "ocl_image2d"); - break; - case BuiltinType::OCLImage2dArray: - Out << "PA"; - mangleArtificalTagType(TTK_Struct, "ocl_image2darray"); - break; - case BuiltinType::OCLImage2dDepth: - Out << "PA"; - mangleArtificalTagType(TTK_Struct, "ocl_image2ddepth"); - break; - case BuiltinType::OCLImage2dArrayDepth: - Out << "PA"; - mangleArtificalTagType(TTK_Struct, "ocl_image2darraydepth"); - break; - case BuiltinType::OCLImage2dMSAA: - Out << "PA"; - mangleArtificalTagType(TTK_Struct, "ocl_image2dmsaa"); - break; - case BuiltinType::OCLImage2dArrayMSAA: - Out << "PA"; - mangleArtificalTagType(TTK_Struct, "ocl_image2darraymsaa"); - break; - case BuiltinType::OCLImage2dMSAADepth: - Out << "PA"; - mangleArtificalTagType(TTK_Struct, "ocl_image2dmsaadepth"); - break; - case BuiltinType::OCLImage2dArrayMSAADepth: - Out << "PA"; - mangleArtificalTagType(TTK_Struct, "ocl_image2darraymsaadepth"); - break; - case BuiltinType::OCLImage3d: - Out << "PA"; - mangleArtificalTagType(TTK_Struct, "ocl_image3d"); +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: \ + Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \ break; +#include "clang/Basic/OpenCLImageTypes.def" case BuiltinType::OCLSampler: Out << "PA"; mangleArtificalTagType(TTK_Struct, "ocl_sampler"); @@ -1758,6 +1758,7 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers, Out << "$$T"; break; + case BuiltinType::Float128: case BuiltinType::Half: { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID( @@ -1799,9 +1800,12 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, SourceRange Range; if (D) Range = D->getSourceRange(); + bool IsInLambda = false; bool IsStructor = false, HasThisQuals = ForceThisQuals, IsCtorClosure = false; CallingConv CC = T->getCallConv(); if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) { + if (MD->getParent()->isLambda()) + IsInLambda = true; if (MD->isInstance()) HasThisQuals = true; if (isa<CXXDestructorDecl>(MD)) { @@ -1820,7 +1824,7 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, // If this is a C++ instance method, mangle the CVR qualifiers for the // this pointer. if (HasThisQuals) { - Qualifiers Quals = Qualifiers::fromCVRMask(Proto->getTypeQuals()); + Qualifiers Quals = Qualifiers::fromCVRUMask(Proto->getTypeQuals()); manglePointerExtQualifiers(Quals, /*PointeeType=*/QualType()); mangleRefQualifier(Proto->getRefQualifier()); mangleQualifiers(Quals, /*IsMember=*/false); @@ -1875,6 +1879,8 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, "shouldn't need to mangle __auto_type!"); mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>"); Out << '@'; + } else if (IsInLambda) { + Out << '@'; } else { if (ResultType->isVoidType()) ResultType = ResultType.getUnqualifiedType(); @@ -2448,7 +2454,8 @@ void MicrosoftMangleContextImpl::mangleCXXName(const NamedDecl *D, getASTContext().getSourceManager(), "Mangling declaration"); - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); return Mangler.mangle(D); } @@ -2548,7 +2555,8 @@ MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, const MicrosoftVTableContext::MethodVFTableLocation &ML = VTContext->getMethodVFTableLocation(GlobalDecl(MD)); - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01?"; Mangler.mangleVirtualMemPtrThunk(MD, ML); } @@ -2556,10 +2564,11 @@ MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, void MicrosoftMangleContextImpl::mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); - Out << "\01?"; + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); + Mangler.getStream() << "\01?"; Mangler.mangleName(MD); - mangleThunkThisAdjustment(MD, Thunk.This, Mangler, Out); + mangleThunkThisAdjustment(MD, Thunk.This, Mangler, MHO); if (!Thunk.Return.isEmpty()) assert(Thunk.Method != nullptr && "Thunk info should hold the overridee decl"); @@ -2576,10 +2585,11 @@ void MicrosoftMangleContextImpl::mangleCXXDtorThunk( // dtors rather than scalar deleting dtors. Just use the vector deleting dtor // mangling manually until we support both deleting dtor types. assert(Type == Dtor_Deleting); - MicrosoftCXXNameMangler Mangler(*this, Out, DD, Type); - Out << "\01??_E"; + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO, DD, Type); + Mangler.getStream() << "\01??_E"; Mangler.mangleName(DD->getParent()); - mangleThunkThisAdjustment(DD, Adjustment, Mangler, Out); + mangleThunkThisAdjustment(DD, Adjustment, Mangler, MHO); Mangler.mangleFunctionType(DD->getType()->castAs<FunctionProtoType>(), DD); } @@ -2590,8 +2600,12 @@ void MicrosoftMangleContextImpl::mangleCXXVFTable( // <cvr-qualifiers> [<name>] @ // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class> // is always '6' for vftables. - MicrosoftCXXNameMangler Mangler(*this, Out); - Mangler.getStream() << "\01??_7"; + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); + if (Derived->hasAttr<DLLImportAttr>()) + Mangler.getStream() << "\01??_S"; + else + Mangler.getStream() << "\01??_7"; Mangler.mangleName(Derived); Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const. for (const CXXRecordDecl *RD : BasePath) @@ -2606,7 +2620,8 @@ void MicrosoftMangleContextImpl::mangleCXXVBTable( // <cvr-qualifiers> [<name>] @ // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class> // is always '7' for vbtables. - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01??_8"; Mangler.mangleName(Derived); Mangler.getStream() << "7B"; // '7' for vbtable, 'B' for const. @@ -2616,7 +2631,8 @@ void MicrosoftMangleContextImpl::mangleCXXVBTable( } void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01??_R0"; Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result); Mangler.getStream() << "@8"; @@ -2631,31 +2647,36 @@ void MicrosoftMangleContextImpl::mangleCXXRTTIName(QualType T, void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap( const CXXRecordDecl *SrcRD, const CXXRecordDecl *DstRD, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01??_K"; Mangler.mangleName(SrcRD); Mangler.getStream() << "$C"; Mangler.mangleName(DstRD); } -void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType T, - bool IsConst, +void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile, + bool IsUnaligned, uint32_t NumEntries, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "_TI"; if (IsConst) Mangler.getStream() << 'C'; if (IsVolatile) Mangler.getStream() << 'V'; + if (IsUnaligned) + Mangler.getStream() << 'U'; Mangler.getStream() << NumEntries; Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result); } void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray( QualType T, uint32_t NumEntries, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "_CTA"; Mangler.getStream() << NumEntries; Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result); @@ -2671,17 +2692,20 @@ void MicrosoftMangleContextImpl::mangleCXXCatchableType( llvm::SmallString<64> RTTIMangling; { llvm::raw_svector_ostream Stream(RTTIMangling); - mangleCXXRTTI(T, Stream); + msvc_hashing_ostream MHO(Stream); + mangleCXXRTTI(T, MHO); } Mangler.getStream() << RTTIMangling.substr(1); // VS2015 CTP6 omits the copy-constructor in the mangled name. This name is, // in fact, superfluous but I'm not sure the change was made consciously. - // TODO: Revisit this when VS2015 gets released. llvm::SmallString<64> CopyCtorMangling; - if (CD) { + if (!getASTContext().getLangOpts().isCompatibleWithMSVC( + LangOptions::MSVC2015) && + CD) { llvm::raw_svector_ostream Stream(CopyCtorMangling); - mangleCXXCtor(CD, CT, Stream); + msvc_hashing_ostream MHO(Stream); + mangleCXXCtor(CD, CT, MHO); } Mangler.getStream() << CopyCtorMangling.substr(1); @@ -2700,7 +2724,8 @@ void MicrosoftMangleContextImpl::mangleCXXCatchableType( void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor( const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01??_R1"; Mangler.mangleNumber(NVOffset); Mangler.mangleNumber(VBPtrOffset); @@ -2712,7 +2737,8 @@ void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor( void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray( const CXXRecordDecl *Derived, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01??_R2"; Mangler.mangleName(Derived); Mangler.getStream() << "8"; @@ -2720,7 +2746,8 @@ void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray( void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor( const CXXRecordDecl *Derived, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01??_R3"; Mangler.mangleName(Derived); Mangler.getStream() << "8"; @@ -2733,18 +2760,26 @@ void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator( // <cvr-qualifiers> [<name>] @ // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class> // is always '6' for vftables. - MicrosoftCXXNameMangler Mangler(*this, Out); - Mangler.getStream() << "\01??_R4"; - Mangler.mangleName(Derived); - Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const. - for (const CXXRecordDecl *RD : BasePath) - Mangler.mangleName(RD); - Mangler.getStream() << '@'; + llvm::SmallString<64> VFTableMangling; + llvm::raw_svector_ostream Stream(VFTableMangling); + mangleCXXVFTable(Derived, BasePath, Stream); + + if (VFTableMangling.startswith("\01??@")) { + assert(VFTableMangling.endswith("@")); + Out << VFTableMangling << "??_R4@"; + return; + } + + assert(VFTableMangling.startswith("\01??_7") || + VFTableMangling.startswith("\01??_S")); + + Out << "\01??_R4" << StringRef(VFTableMangling).drop_front(5); } void MicrosoftMangleContextImpl::mangleSEHFilterExpression( const NamedDecl *EnclosingDecl, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); // The function body is in the same comdat as the function with the handler, // so the numbering here doesn't have to be the same across TUs. // @@ -2755,7 +2790,8 @@ void MicrosoftMangleContextImpl::mangleSEHFilterExpression( void MicrosoftMangleContextImpl::mangleSEHFinallyBlock( const NamedDecl *EnclosingDecl, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); // The function body is in the same comdat as the function with the handler, // so the numbering here doesn't have to be the same across TUs. // @@ -2775,20 +2811,23 @@ void MicrosoftMangleContextImpl::mangleTypeName(QualType T, raw_ostream &Out) { void MicrosoftMangleContextImpl::mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, raw_ostream &Out) { - MicrosoftCXXNameMangler mangler(*this, Out, D, Type); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler mangler(*this, MHO, D, Type); mangler.mangle(D); } void MicrosoftMangleContextImpl::mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, raw_ostream &Out) { - MicrosoftCXXNameMangler mangler(*this, Out, D, Type); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler mangler(*this, MHO, D, Type); mangler.mangle(D); } void MicrosoftMangleContextImpl::mangleReferenceTemporary( const VarDecl *VD, unsigned ManglingNumber, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01?$RT" << ManglingNumber << '@'; Mangler.mangle(VD, ""); @@ -2796,10 +2835,12 @@ void MicrosoftMangleContextImpl::mangleReferenceTemporary( void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable( const VarDecl *VD, unsigned GuardNum, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01?$TSS" << GuardNum << '@'; Mangler.mangleNestedName(VD); + Mangler.getStream() << "@4HA"; } void MicrosoftMangleContextImpl::mangleStaticGuardVariable(const VarDecl *VD, @@ -2814,7 +2855,8 @@ void MicrosoftMangleContextImpl::mangleStaticGuardVariable(const VarDecl *VD, // than 32 static locals. We don't fully implement the second mangling // because those guards are not externally visible, and instead use LLVM's // default renaming when creating a new guard variable. - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); bool Visible = VD->isExternallyVisible(); if (Visible) { @@ -2836,9 +2878,10 @@ void MicrosoftMangleContextImpl::mangleStaticGuardVariable(const VarDecl *VD, } void MicrosoftMangleContextImpl::mangleInitFiniStub(const VarDecl *D, - raw_ostream &Out, - char CharCode) { - MicrosoftCXXNameMangler Mangler(*this, Out); + char CharCode, + raw_ostream &Out) { + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01??__" << CharCode; Mangler.mangleName(D); if (D->isStaticDataMember()) { @@ -2853,14 +2896,14 @@ void MicrosoftMangleContextImpl::mangleInitFiniStub(const VarDecl *D, void MicrosoftMangleContextImpl::mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) { // <initializer-name> ::= ?__E <name> YAXXZ - mangleInitFiniStub(D, Out, 'E'); + mangleInitFiniStub(D, 'E', Out); } void MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(const VarDecl *D, raw_ostream &Out) { // <destructor-name> ::= ?__F <name> YAXXZ - mangleInitFiniStub(D, Out, 'F'); + mangleInitFiniStub(D, 'F', Out); } void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL, diff --git a/contrib/llvm/tools/clang/lib/AST/NSAPI.cpp b/contrib/llvm/tools/clang/lib/AST/NSAPI.cpp index c562dae..ac2a8d3 100644 --- a/contrib/llvm/tools/clang/lib/AST/NSAPI.cpp +++ b/contrib/llvm/tools/clang/lib/AST/NSAPI.cpp @@ -441,22 +441,14 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const { case BuiltinType::Int128: case BuiltinType::LongDouble: case BuiltinType::UInt128: + case BuiltinType::Float128: case BuiltinType::NullPtr: case BuiltinType::ObjCClass: case BuiltinType::ObjCId: case BuiltinType::ObjCSel: - case BuiltinType::OCLImage1d: - case BuiltinType::OCLImage1dArray: - case BuiltinType::OCLImage1dBuffer: - case BuiltinType::OCLImage2d: - case BuiltinType::OCLImage2dArray: - case BuiltinType::OCLImage2dDepth: - case BuiltinType::OCLImage2dArrayDepth: - case BuiltinType::OCLImage2dMSAA: - case BuiltinType::OCLImage2dArrayMSAA: - case BuiltinType::OCLImage2dMSAADepth: - case BuiltinType::OCLImage2dArrayMSAADepth: - case BuiltinType::OCLImage3d: +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/Basic/OpenCLImageTypes.def" case BuiltinType::OCLSampler: case BuiltinType::OCLEvent: case BuiltinType::OCLClkEvent: diff --git a/contrib/llvm/tools/clang/lib/AST/NestedNameSpecifier.cpp b/contrib/llvm/tools/clang/lib/AST/NestedNameSpecifier.cpp index d2370c8..82809d7 100644 --- a/contrib/llvm/tools/clang/lib/AST/NestedNameSpecifier.cpp +++ b/contrib/llvm/tools/clang/lib/AST/NestedNameSpecifier.cpp @@ -171,10 +171,19 @@ NamespaceAliasDecl *NestedNameSpecifier::getAsNamespaceAlias() const { /// \brief Retrieve the record declaration stored in this nested name specifier. CXXRecordDecl *NestedNameSpecifier::getAsRecordDecl() const { - if (Prefix.getInt() == StoredDecl) + switch (Prefix.getInt()) { + case StoredIdentifier: + return nullptr; + + case StoredDecl: return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier)); - return nullptr; + case StoredTypeSpec: + case StoredTypeSpecWithTemplate: + return getAsType()->getAsCXXRecordDecl(); + } + + llvm_unreachable("Invalid NNS Kind!"); } /// \brief Whether this nested name specifier refers to a dependent @@ -306,7 +315,7 @@ NestedNameSpecifier::print(raw_ostream &OS, // Print the template argument list. TemplateSpecializationType::PrintTemplateArgumentList( - OS, SpecType->getArgs(), SpecType->getNumArgs(), InnerPolicy); + OS, SpecType->template_arguments(), InnerPolicy); } else { // Print the type normally QualType(T, 0).print(OS, InnerPolicy); @@ -322,7 +331,7 @@ void NestedNameSpecifier::dump(const LangOptions &LO) const { print(llvm::errs(), PrintingPolicy(LO)); } -void NestedNameSpecifier::dump() const { +LLVM_DUMP_METHOD void NestedNameSpecifier::dump() const { LangOptions LO; print(llvm::errs(), PrintingPolicy(LO)); } diff --git a/contrib/llvm/tools/clang/lib/AST/OpenMPClause.cpp b/contrib/llvm/tools/clang/lib/AST/OpenMPClause.cpp index 1ef43f7..d04ba72 100644 --- a/contrib/llvm/tools/clang/lib/AST/OpenMPClause.cpp +++ b/contrib/llvm/tools/clang/lib/AST/OpenMPClause.cpp @@ -29,6 +29,139 @@ OMPClause::child_range OMPClause::children() { llvm_unreachable("unknown OMPClause"); } +OMPClauseWithPreInit *OMPClauseWithPreInit::get(OMPClause *C) { + auto *Res = OMPClauseWithPreInit::get(const_cast<const OMPClause *>(C)); + return Res ? const_cast<OMPClauseWithPreInit *>(Res) : nullptr; +} + +const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) { + switch (C->getClauseKind()) { + case OMPC_schedule: + return static_cast<const OMPScheduleClause *>(C); + case OMPC_dist_schedule: + return static_cast<const OMPDistScheduleClause *>(C); + case OMPC_firstprivate: + return static_cast<const OMPFirstprivateClause *>(C); + case OMPC_lastprivate: + return static_cast<const OMPLastprivateClause *>(C); + case OMPC_reduction: + return static_cast<const OMPReductionClause *>(C); + case OMPC_linear: + return static_cast<const OMPLinearClause *>(C); + case OMPC_default: + case OMPC_proc_bind: + case OMPC_if: + case OMPC_final: + case OMPC_num_threads: + case OMPC_safelen: + case OMPC_simdlen: + case OMPC_collapse: + case OMPC_private: + case OMPC_shared: + case OMPC_aligned: + case OMPC_copyin: + case OMPC_copyprivate: + case OMPC_ordered: + case OMPC_nowait: + case OMPC_untied: + case OMPC_mergeable: + case OMPC_threadprivate: + case OMPC_flush: + case OMPC_read: + case OMPC_write: + case OMPC_update: + case OMPC_capture: + case OMPC_seq_cst: + case OMPC_depend: + case OMPC_device: + case OMPC_threads: + case OMPC_simd: + case OMPC_map: + case OMPC_num_teams: + case OMPC_thread_limit: + case OMPC_priority: + case OMPC_grainsize: + case OMPC_nogroup: + case OMPC_num_tasks: + case OMPC_hint: + case OMPC_defaultmap: + case OMPC_unknown: + case OMPC_uniform: + case OMPC_to: + case OMPC_from: + case OMPC_use_device_ptr: + case OMPC_is_device_ptr: + break; + } + + return nullptr; +} + +OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(OMPClause *C) { + auto *Res = OMPClauseWithPostUpdate::get(const_cast<const OMPClause *>(C)); + return Res ? const_cast<OMPClauseWithPostUpdate *>(Res) : nullptr; +} + +const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) { + switch (C->getClauseKind()) { + case OMPC_lastprivate: + return static_cast<const OMPLastprivateClause *>(C); + case OMPC_reduction: + return static_cast<const OMPReductionClause *>(C); + case OMPC_linear: + return static_cast<const OMPLinearClause *>(C); + case OMPC_schedule: + case OMPC_dist_schedule: + case OMPC_firstprivate: + case OMPC_default: + case OMPC_proc_bind: + case OMPC_if: + case OMPC_final: + case OMPC_num_threads: + case OMPC_safelen: + case OMPC_simdlen: + case OMPC_collapse: + case OMPC_private: + case OMPC_shared: + case OMPC_aligned: + case OMPC_copyin: + case OMPC_copyprivate: + case OMPC_ordered: + case OMPC_nowait: + case OMPC_untied: + case OMPC_mergeable: + case OMPC_threadprivate: + case OMPC_flush: + case OMPC_read: + case OMPC_write: + case OMPC_update: + case OMPC_capture: + case OMPC_seq_cst: + case OMPC_depend: + case OMPC_device: + case OMPC_threads: + case OMPC_simd: + case OMPC_map: + case OMPC_num_teams: + case OMPC_thread_limit: + case OMPC_priority: + case OMPC_grainsize: + case OMPC_nogroup: + case OMPC_num_tasks: + case OMPC_hint: + case OMPC_defaultmap: + case OMPC_unknown: + case OMPC_uniform: + case OMPC_to: + case OMPC_from: + case OMPC_use_device_ptr: + case OMPC_is_device_ptr: + break; + } + + return nullptr; +} + void OMPPrivateClause::setPrivateCopies(ArrayRef<Expr *> VL) { assert(VL.size() == varlist_size() && "Number of private copies is not the same as the preallocated buffer"); @@ -70,13 +203,14 @@ OMPFirstprivateClause * OMPFirstprivateClause::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL, - ArrayRef<Expr *> InitVL) { + ArrayRef<Expr *> InitVL, Stmt *PreInit) { void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * VL.size())); OMPFirstprivateClause *Clause = new (Mem) OMPFirstprivateClause(StartLoc, LParenLoc, EndLoc, VL.size()); Clause->setVarRefs(VL); Clause->setPrivateCopies(PrivateVL); Clause->setInits(InitVL); + Clause->setPreInitStmt(PreInit); return Clause; } @@ -117,7 +251,8 @@ void OMPLastprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) { OMPLastprivateClause *OMPLastprivateClause::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs, - ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) { + ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps, Stmt *PreInit, + Expr *PostUpdate) { void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size())); OMPLastprivateClause *Clause = new (Mem) OMPLastprivateClause(StartLoc, LParenLoc, EndLoc, VL.size()); @@ -125,6 +260,8 @@ OMPLastprivateClause *OMPLastprivateClause::Create( Clause->setSourceExprs(SrcExprs); Clause->setDestinationExprs(DstExprs); Clause->setAssignmentOps(AssignmentOps); + Clause->setPreInitStmt(PreInit); + Clause->setPostUpdateExpr(PostUpdate); return Clause; } @@ -179,7 +316,8 @@ OMPLinearClause *OMPLinearClause::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL, - ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep) { + ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep, + Stmt *PreInit, Expr *PostUpdate) { // Allocate space for 4 lists (Vars, Inits, Updates, Finals) and 2 expressions // (Step and CalcStep). void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size() + 2)); @@ -196,6 +334,8 @@ OMPLinearClause *OMPLinearClause::Create( nullptr); Clause->setStep(Step); Clause->setCalcStep(CalcStep); + Clause->setPreInitStmt(PreInit); + Clause->setPostUpdateExpr(PostUpdate); return Clause; } @@ -340,7 +480,8 @@ OMPReductionClause *OMPReductionClause::Create( SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs, - ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps) { + ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit, + Expr *PostUpdate) { void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size())); OMPReductionClause *Clause = new (Mem) OMPReductionClause( StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo); @@ -349,6 +490,8 @@ OMPReductionClause *OMPReductionClause::Create( Clause->setLHSExprs(LHSExprs); Clause->setRHSExprs(RHSExprs); Clause->setReductionOps(ReductionOps); + Clause->setPreInitStmt(PreInit); + Clause->setPostUpdateExpr(PostUpdate); return Clause; } @@ -363,7 +506,7 @@ OMPFlushClause *OMPFlushClause::Create(const ASTContext &C, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL) { - void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size())); + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1)); OMPFlushClause *Clause = new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc, VL.size()); Clause->setVarRefs(VL); @@ -375,43 +518,252 @@ OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) { return new (Mem) OMPFlushClause(N); } -OMPDependClause * -OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc, - OpenMPDependClauseKind DepKind, SourceLocation DepLoc, - SourceLocation ColonLoc, ArrayRef<Expr *> VL) { - void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size())); +OMPDependClause *OMPDependClause::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, OpenMPDependClauseKind DepKind, + SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL) { + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1)); OMPDependClause *Clause = new (Mem) OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size()); Clause->setVarRefs(VL); Clause->setDependencyKind(DepKind); Clause->setDependencyLoc(DepLoc); Clause->setColonLoc(ColonLoc); + Clause->setCounterValue(nullptr); return Clause; } OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N) { - void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N)); + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N + 1)); return new (Mem) OMPDependClause(N); } -OMPMapClause *OMPMapClause::Create(const ASTContext &C, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc, ArrayRef<Expr *> VL, - OpenMPMapClauseKind TypeModifier, - OpenMPMapClauseKind Type, - SourceLocation TypeLoc) { - void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size())); +void OMPDependClause::setCounterValue(Expr *V) { + assert(getDependencyKind() == OMPC_DEPEND_sink || + getDependencyKind() == OMPC_DEPEND_source || V == nullptr); + *getVarRefs().end() = V; +} + +const Expr *OMPDependClause::getCounterValue() const { + auto *V = *getVarRefs().end(); + assert(getDependencyKind() == OMPC_DEPEND_sink || + getDependencyKind() == OMPC_DEPEND_source || V == nullptr); + return V; +} + +Expr *OMPDependClause::getCounterValue() { + auto *V = *getVarRefs().end(); + assert(getDependencyKind() == OMPC_DEPEND_sink || + getDependencyKind() == OMPC_DEPEND_source || V == nullptr); + return V; +} + +unsigned OMPClauseMappableExprCommon::getComponentsTotalNumber( + MappableExprComponentListsRef ComponentLists) { + unsigned TotalNum = 0u; + for (auto &C : ComponentLists) + TotalNum += C.size(); + return TotalNum; +} + +unsigned OMPClauseMappableExprCommon::getUniqueDeclarationsTotalNumber( + ArrayRef<ValueDecl *> Declarations) { + unsigned TotalNum = 0u; + llvm::SmallPtrSet<const ValueDecl *, 8> Cache; + for (auto *D : Declarations) { + const ValueDecl *VD = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr; + if (Cache.count(VD)) + continue; + ++TotalNum; + Cache.insert(VD); + } + return TotalNum; +} + +OMPMapClause * +OMPMapClause::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc, + ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations, + MappableExprComponentListsRef ComponentLists, + OpenMPMapClauseKind TypeModifier, OpenMPMapClauseKind Type, + bool TypeIsImplicit, SourceLocation TypeLoc) { + + unsigned NumVars = Vars.size(); + unsigned NumUniqueDeclarations = + getUniqueDeclarationsTotalNumber(Declarations); + unsigned NumComponentLists = ComponentLists.size(); + unsigned NumComponents = getComponentsTotalNumber(ComponentLists); + + // We need to allocate: + // NumVars x Expr* - we have an original list expression for each clause list + // entry. + // NumUniqueDeclarations x ValueDecl* - unique base declarations associated + // with each component list. + // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the + // number of lists for each unique declaration and the size of each component + // list. + // NumComponents x MappableComponent - the total of all the components in all + // the lists. + void *Mem = C.Allocate( + totalSizeToAlloc<Expr *, ValueDecl *, unsigned, + OMPClauseMappableExprCommon::MappableComponent>( + NumVars, NumUniqueDeclarations, + NumUniqueDeclarations + NumComponentLists, NumComponents)); OMPMapClause *Clause = new (Mem) OMPMapClause( - TypeModifier, Type, TypeLoc, StartLoc, LParenLoc, EndLoc, VL.size()); - Clause->setVarRefs(VL); + TypeModifier, Type, TypeIsImplicit, TypeLoc, StartLoc, LParenLoc, EndLoc, + NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents); + + Clause->setVarRefs(Vars); + Clause->setClauseInfo(Declarations, ComponentLists); Clause->setMapTypeModifier(TypeModifier); Clause->setMapType(Type); Clause->setMapLoc(TypeLoc); return Clause; } -OMPMapClause *OMPMapClause::CreateEmpty(const ASTContext &C, unsigned N) { +OMPMapClause *OMPMapClause::CreateEmpty(const ASTContext &C, unsigned NumVars, + unsigned NumUniqueDeclarations, + unsigned NumComponentLists, + unsigned NumComponents) { + void *Mem = C.Allocate( + totalSizeToAlloc<Expr *, ValueDecl *, unsigned, + OMPClauseMappableExprCommon::MappableComponent>( + NumVars, NumUniqueDeclarations, + NumUniqueDeclarations + NumComponentLists, NumComponents)); + return new (Mem) OMPMapClause(NumVars, NumUniqueDeclarations, + NumComponentLists, NumComponents); +} + +OMPToClause *OMPToClause::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, ArrayRef<Expr *> Vars, + ArrayRef<ValueDecl *> Declarations, + MappableExprComponentListsRef ComponentLists) { + unsigned NumVars = Vars.size(); + unsigned NumUniqueDeclarations = + getUniqueDeclarationsTotalNumber(Declarations); + unsigned NumComponentLists = ComponentLists.size(); + unsigned NumComponents = getComponentsTotalNumber(ComponentLists); + + // We need to allocate: + // NumVars x Expr* - we have an original list expression for each clause list + // entry. + // NumUniqueDeclarations x ValueDecl* - unique base declarations associated + // with each component list. + // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the + // number of lists for each unique declaration and the size of each component + // list. + // NumComponents x MappableComponent - the total of all the components in all + // the lists. + void *Mem = C.Allocate( + totalSizeToAlloc<Expr *, ValueDecl *, unsigned, + OMPClauseMappableExprCommon::MappableComponent>( + NumVars, NumUniqueDeclarations, + NumUniqueDeclarations + NumComponentLists, NumComponents)); + + OMPToClause *Clause = new (Mem) + OMPToClause(StartLoc, LParenLoc, EndLoc, NumVars, NumUniqueDeclarations, + NumComponentLists, NumComponents); + + Clause->setVarRefs(Vars); + Clause->setClauseInfo(Declarations, ComponentLists); + return Clause; +} + +OMPToClause *OMPToClause::CreateEmpty(const ASTContext &C, unsigned NumVars, + unsigned NumUniqueDeclarations, + unsigned NumComponentLists, + unsigned NumComponents) { + void *Mem = C.Allocate( + totalSizeToAlloc<Expr *, ValueDecl *, unsigned, + OMPClauseMappableExprCommon::MappableComponent>( + NumVars, NumUniqueDeclarations, + NumUniqueDeclarations + NumComponentLists, NumComponents)); + return new (Mem) OMPToClause(NumVars, NumUniqueDeclarations, + NumComponentLists, NumComponents); +} + +OMPFromClause * +OMPFromClause::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc, + ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations, + MappableExprComponentListsRef ComponentLists) { + unsigned NumVars = Vars.size(); + unsigned NumUniqueDeclarations = + getUniqueDeclarationsTotalNumber(Declarations); + unsigned NumComponentLists = ComponentLists.size(); + unsigned NumComponents = getComponentsTotalNumber(ComponentLists); + + // We need to allocate: + // NumVars x Expr* - we have an original list expression for each clause list + // entry. + // NumUniqueDeclarations x ValueDecl* - unique base declarations associated + // with each component list. + // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the + // number of lists for each unique declaration and the size of each component + // list. + // NumComponents x MappableComponent - the total of all the components in all + // the lists. + void *Mem = C.Allocate( + totalSizeToAlloc<Expr *, ValueDecl *, unsigned, + OMPClauseMappableExprCommon::MappableComponent>( + NumVars, NumUniqueDeclarations, + NumUniqueDeclarations + NumComponentLists, NumComponents)); + + OMPFromClause *Clause = new (Mem) + OMPFromClause(StartLoc, LParenLoc, EndLoc, NumVars, NumUniqueDeclarations, + NumComponentLists, NumComponents); + + Clause->setVarRefs(Vars); + Clause->setClauseInfo(Declarations, ComponentLists); + return Clause; +} + +OMPFromClause *OMPFromClause::CreateEmpty(const ASTContext &C, unsigned NumVars, + unsigned NumUniqueDeclarations, + unsigned NumComponentLists, + unsigned NumComponents) { + void *Mem = C.Allocate( + totalSizeToAlloc<Expr *, ValueDecl *, unsigned, + OMPClauseMappableExprCommon::MappableComponent>( + NumVars, NumUniqueDeclarations, + NumUniqueDeclarations + NumComponentLists, NumComponents)); + return new (Mem) OMPFromClause(NumVars, NumUniqueDeclarations, + NumComponentLists, NumComponents); +} + +OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, + ArrayRef<Expr *> VL) { + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size())); + OMPUseDevicePtrClause *Clause = + new (Mem) OMPUseDevicePtrClause(StartLoc, LParenLoc, EndLoc, VL.size()); + Clause->setVarRefs(VL); + return Clause; +} + +OMPUseDevicePtrClause *OMPUseDevicePtrClause::CreateEmpty(const ASTContext &C, + unsigned N) { + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N)); + return new (Mem) OMPUseDevicePtrClause(N); +} + +OMPIsDevicePtrClause *OMPIsDevicePtrClause::Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, + ArrayRef<Expr *> VL) { + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size())); + OMPIsDevicePtrClause *Clause = + new (Mem) OMPIsDevicePtrClause(StartLoc, LParenLoc, EndLoc, VL.size()); + Clause->setVarRefs(VL); + return Clause; +} + +OMPIsDevicePtrClause *OMPIsDevicePtrClause::CreateEmpty(const ASTContext &C, + unsigned N) { void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N)); - return new (Mem) OMPMapClause(N); + return new (Mem) OMPIsDevicePtrClause(N); } diff --git a/contrib/llvm/tools/clang/lib/AST/ParentMap.cpp b/contrib/llvm/tools/clang/lib/AST/ParentMap.cpp index d7d5f9c..d8882c9 100644 --- a/contrib/llvm/tools/clang/lib/AST/ParentMap.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ParentMap.cpp @@ -28,6 +28,8 @@ enum OpaqueValueMode { static void BuildParentMap(MapTy& M, Stmt* S, OpaqueValueMode OVMode = OV_Transparent) { + if (!S) + return; switch (S->getStmtClass()) { case Stmt::PseudoObjectExprClass: { diff --git a/contrib/llvm/tools/clang/lib/AST/RecordLayout.cpp b/contrib/llvm/tools/clang/lib/AST/RecordLayout.cpp index b2c244e..299fd111 100644 --- a/contrib/llvm/tools/clang/lib/AST/RecordLayout.cpp +++ b/contrib/llvm/tools/clang/lib/AST/RecordLayout.cpp @@ -18,8 +18,6 @@ using namespace clang; void ASTRecordLayout::Destroy(ASTContext &Ctx) { - if (FieldOffsets) - Ctx.Deallocate(FieldOffsets); if (CXXInfo) { CXXInfo->~CXXRecordLayoutInfo(); Ctx.Deallocate(CXXInfo); @@ -29,18 +27,13 @@ void ASTRecordLayout::Destroy(ASTContext &Ctx) { } ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size, - CharUnits alignment, + CharUnits alignment, CharUnits requiredAlignment, CharUnits datasize, - const uint64_t *fieldoffsets, - unsigned fieldcount) - : Size(size), DataSize(datasize), Alignment(alignment), - RequiredAlignment(requiredAlignment), FieldOffsets(nullptr), - FieldCount(fieldcount), CXXInfo(nullptr) { - if (FieldCount > 0) { - FieldOffsets = new (Ctx) uint64_t[FieldCount]; - memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets)); - } + ArrayRef<uint64_t> fieldoffsets) + : Size(size), DataSize(datasize), Alignment(alignment), + RequiredAlignment(requiredAlignment), CXXInfo(nullptr) { + FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end()); } // Constructor for C++ records. @@ -50,26 +43,21 @@ ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, bool hasOwnVFPtr, bool hasExtendableVFPtr, CharUnits vbptroffset, CharUnits datasize, - const uint64_t *fieldoffsets, - unsigned fieldcount, + ArrayRef<uint64_t> fieldoffsets, CharUnits nonvirtualsize, CharUnits nonvirtualalignment, CharUnits SizeOfLargestEmptySubobject, const CXXRecordDecl *PrimaryBase, bool IsPrimaryBaseVirtual, const CXXRecordDecl *BaseSharingVBPtr, - bool HasZeroSizedSubObject, + bool EndsWithZeroSizedObject, bool LeadsWithZeroSizedBase, const BaseOffsetsMapTy& BaseOffsets, const VBaseOffsetsMapTy& VBaseOffsets) : Size(size), DataSize(datasize), Alignment(alignment), - RequiredAlignment(requiredAlignment), FieldOffsets(nullptr), - FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo) + RequiredAlignment(requiredAlignment), CXXInfo(new (Ctx) CXXRecordLayoutInfo) { - if (FieldCount > 0) { - FieldOffsets = new (Ctx) uint64_t[FieldCount]; - memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets)); - } + FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end()); CXXInfo->PrimaryBase.setPointer(PrimaryBase); CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual); @@ -82,7 +70,7 @@ ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CXXInfo->VBPtrOffset = vbptroffset; CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr; CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr; - CXXInfo->HasZeroSizedSubObject = HasZeroSizedSubObject; + CXXInfo->EndsWithZeroSizedObject = EndsWithZeroSizedObject; CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase; diff --git a/contrib/llvm/tools/clang/lib/AST/RecordLayoutBuilder.cpp b/contrib/llvm/tools/clang/lib/AST/RecordLayoutBuilder.cpp index bc5ae0f..cf981be 100644 --- a/contrib/llvm/tools/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/contrib/llvm/tools/clang/lib/AST/RecordLayoutBuilder.cpp @@ -973,7 +973,7 @@ void ItaniumRecordLayoutBuilder::EnsureVTablePointerAlignment( } // Round up the current record size to pointer alignment. - setSize(getSize().RoundUpToAlignment(BaseAlign)); + setSize(getSize().alignTo(BaseAlign)); setDataSize(getSize()); // Update the alignment. @@ -1194,7 +1194,7 @@ ItaniumRecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) { if (!HasExternalLayout) { // Round up the current record size to the base's alignment boundary. - Offset = getDataSize().RoundUpToAlignment(BaseAlign); + Offset = getDataSize().alignTo(BaseAlign); // Try to place the base. while (!EmptySubobjects->CanPlaceBaseAtOffset(Base, Offset)) @@ -1204,7 +1204,7 @@ ItaniumRecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) { (void)Allowed; assert(Allowed && "Base subobject externally placed at overlapping offset"); - if (InferAlignment && Offset < getDataSize().RoundUpToAlignment(BaseAlign)){ + if (InferAlignment && Offset < getDataSize().alignTo(BaseAlign)) { // The externally-supplied base offset is before the base offset we // computed. Assume that the structure is packed. Alignment = CharUnits::One(); @@ -1292,8 +1292,7 @@ void ItaniumRecordLayoutBuilder::Layout(const CXXRecordDecl *RD) { LayoutFields(RD); NonVirtualSize = Context.toCharUnitsFromBits( - llvm::RoundUpToAlignment(getSizeInBits(), - Context.getTargetInfo().getCharAlign())); + llvm::alignTo(getSizeInBits(), Context.getTargetInfo().getCharAlign())); NonVirtualAlignment = Alignment; // Lay out the virtual bases and add the primary virtual base offsets. @@ -1364,7 +1363,7 @@ static uint64_t roundUpSizeToCharAlignment(uint64_t Size, const ASTContext &Context) { uint64_t CharAlignment = Context.getTargetInfo().getCharAlign(); - return llvm::RoundUpToAlignment(Size, CharAlignment); + return llvm::alignTo(Size, CharAlignment); } void ItaniumRecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize, @@ -1411,13 +1410,12 @@ void ItaniumRecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize, } else { // The bitfield is allocated starting at the next offset aligned // appropriately for T', with length n bits. - FieldOffset = llvm::RoundUpToAlignment(getDataSizeInBits(), - Context.toBits(TypeAlign)); + FieldOffset = llvm::alignTo(getDataSizeInBits(), Context.toBits(TypeAlign)); uint64_t NewSizeInBits = FieldOffset + FieldSize; - setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, - Context.getTargetInfo().getCharAlign())); + setDataSize( + llvm::alignTo(NewSizeInBits, Context.getTargetInfo().getCharAlign())); UnfilledBitsInLastUnit = getDataSizeInBits() - NewSizeInBits; } @@ -1560,10 +1558,13 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { // But, if there's a #pragma pack in play, that takes precedent over // even the 'aligned' attribute, for non-zero-width bitfields. + unsigned MaxFieldAlignmentInBits = Context.toBits(MaxFieldAlignment); if (!MaxFieldAlignment.isZero() && FieldSize) { - unsigned MaxFieldAlignmentInBits = Context.toBits(MaxFieldAlignment); - FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits); UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignmentInBits); + if (FieldPacked) + FieldAlign = UnpackedFieldAlign; + else + FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits); } // But, ms_struct just ignores all of that in unions, even explicit @@ -1587,9 +1588,9 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { // start a new storage unit), just do so, regardless of any other // other consideration. Otherwise, round up to the right alignment. if (FieldSize == 0 || FieldSize > UnfilledBitsInLastUnit) { - FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign); - UnpackedFieldOffset = llvm::RoundUpToAlignment(UnpackedFieldOffset, - UnpackedFieldAlign); + FieldOffset = llvm::alignTo(FieldOffset, FieldAlign); + UnpackedFieldOffset = + llvm::alignTo(UnpackedFieldOffset, UnpackedFieldAlign); UnfilledBitsInLastUnit = 0; } @@ -1601,22 +1602,28 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { if (FieldSize == 0 || (AllowPadding && (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)) { - FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign); - } else if (ExplicitFieldAlign) { + FieldOffset = llvm::alignTo(FieldOffset, FieldAlign); + } else if (ExplicitFieldAlign && + (MaxFieldAlignmentInBits == 0 || + ExplicitFieldAlign <= MaxFieldAlignmentInBits) && + Context.getTargetInfo().useExplicitBitFieldAlignment()) { // TODO: figure it out what needs to be done on targets that don't honor // bit-field type alignment like ARM APCS ABI. - FieldOffset = llvm::RoundUpToAlignment(FieldOffset, ExplicitFieldAlign); + FieldOffset = llvm::alignTo(FieldOffset, ExplicitFieldAlign); } // Repeat the computation for diagnostic purposes. if (FieldSize == 0 || (AllowPadding && (UnpackedFieldOffset & (UnpackedFieldAlign-1)) + FieldSize > TypeSize)) - UnpackedFieldOffset = llvm::RoundUpToAlignment(UnpackedFieldOffset, - UnpackedFieldAlign); - else if (ExplicitFieldAlign) - UnpackedFieldOffset = llvm::RoundUpToAlignment(UnpackedFieldOffset, - ExplicitFieldAlign); + UnpackedFieldOffset = + llvm::alignTo(UnpackedFieldOffset, UnpackedFieldAlign); + else if (ExplicitFieldAlign && + (MaxFieldAlignmentInBits == 0 || + ExplicitFieldAlign <= MaxFieldAlignmentInBits) && + Context.getTargetInfo().useExplicitBitFieldAlignment()) + UnpackedFieldOffset = + llvm::alignTo(UnpackedFieldOffset, ExplicitFieldAlign); } // If we're using external layout, give the external layout a chance @@ -1677,7 +1684,7 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { } else { uint64_t NewSizeInBits = FieldOffset + FieldSize; uint64_t CharAlignment = Context.getTargetInfo().getCharAlign(); - setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, CharAlignment)); + setDataSize(llvm::alignTo(NewSizeInBits, CharAlignment)); UnfilledBitsInLastUnit = getDataSizeInBits() - NewSizeInBits; // The only time we can get here for an ms_struct is if this is a @@ -1767,9 +1774,8 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D, } // Round up the current record size to the field's alignment boundary. - FieldOffset = FieldOffset.RoundUpToAlignment(FieldAlign); - UnpackedFieldOffset = - UnpackedFieldOffset.RoundUpToAlignment(UnpackedFieldAlign); + FieldOffset = FieldOffset.alignTo(FieldAlign); + UnpackedFieldOffset = UnpackedFieldOffset.alignTo(UnpackedFieldAlign); if (UseExternalLayout) { FieldOffset = Context.toCharUnitsFromBits( @@ -1840,11 +1846,10 @@ void ItaniumRecordLayoutBuilder::FinishLayout(const NamedDecl *D) { // record itself. uint64_t UnpaddedSize = getSizeInBits() - UnfilledBitsInLastUnit; uint64_t UnpackedSizeInBits = - llvm::RoundUpToAlignment(getSizeInBits(), - Context.toBits(UnpackedAlignment)); + llvm::alignTo(getSizeInBits(), Context.toBits(UnpackedAlignment)); CharUnits UnpackedSize = Context.toCharUnitsFromBits(UnpackedSizeInBits); - uint64_t RoundedSize - = llvm::RoundUpToAlignment(getSizeInBits(), Context.toBits(Alignment)); + uint64_t RoundedSize = + llvm::alignTo(getSizeInBits(), Context.toBits(Alignment)); if (UseExternalLayout) { // If we're inferring alignment, and the external size is smaller than @@ -2127,7 +2132,7 @@ static bool isMsLayout(const ASTContext &Context) { // function pointer) and a vbptr (virtual base pointer). They can each be // shared with a, non-virtual bases. These bases need not be the same. vfptrs // always occur at offset 0. vbptrs can occur at an arbitrary offset and are -// placed after the lexiographically last non-virtual base. This placement +// placed after the lexicographically last non-virtual base. This placement // is always before fields but can be in the middle of the non-virtual bases // due to the two-pass layout scheme for non-virtual-bases. // * Virtual bases sometimes require a 'vtordisp' field that is laid out before @@ -2148,7 +2153,7 @@ static bool isMsLayout(const ASTContext &Context) { // pushes all bases and fields back by the alignment imposed by those bases // and fields. This can potentially add a significant amount of padding. // vbptrs are injected immediately after the last non-virtual base as -// lexiographically ordered in the code. If this site isn't pointer aligned +// lexicographically ordered in the code. If this site isn't pointer aligned // the vbptr is placed at the next properly aligned location. Enough padding // is added to guarantee a fit. // * The last zero sized non-virtual base can be placed at the end of the @@ -2223,7 +2228,8 @@ public: /// laid out. void initializeCXXLayout(const CXXRecordDecl *RD); void layoutNonVirtualBases(const CXXRecordDecl *RD); - void layoutNonVirtualBase(const CXXRecordDecl *BaseDecl, + void layoutNonVirtualBase(const CXXRecordDecl *RD, + const CXXRecordDecl *BaseDecl, const ASTRecordLayout &BaseLayout, const ASTRecordLayout *&PreviousBaseLayout); void injectVFPtr(const CXXRecordDecl *RD); @@ -2329,7 +2335,7 @@ MicrosoftRecordLayoutBuilder::getAdjustedElementInfo( if (!MaxFieldAlignment.isZero()) Info.Alignment = std::min(Info.Alignment, MaxFieldAlignment); // Track zero-sized subobjects here where it's already available. - EndsWithZeroSizedObject = Layout.hasZeroSizedSubObject(); + EndsWithZeroSizedObject = Layout.endsWithZeroSizedObject(); // Respect required alignment, this is necessary because we may have adjusted // the alignment in the case of pragam pack. Note that the required alignment // doesn't actually apply to the struct alignment at this point. @@ -2364,7 +2370,7 @@ MicrosoftRecordLayoutBuilder::getAdjustedElementInfo( if (auto RT = FD->getType()->getBaseElementTypeUnsafe()->getAs<RecordType>()) { auto const &Layout = Context.getASTRecordLayout(RT->getDecl()); - EndsWithZeroSizedObject = Layout.hasZeroSizedSubObject(); + EndsWithZeroSizedObject = Layout.endsWithZeroSizedObject(); FieldRequiredAlignment = std::max(FieldRequiredAlignment, Layout.getRequiredAlignment()); } @@ -2385,7 +2391,7 @@ void MicrosoftRecordLayoutBuilder::layout(const RecordDecl *RD) { MinEmptyStructSize = CharUnits::fromQuantity(4); initializeLayout(RD); layoutFields(RD); - DataSize = Size = Size.RoundUpToAlignment(Alignment); + DataSize = Size = Size.alignTo(Alignment); RequiredAlignment = std::max( RequiredAlignment, Context.toCharUnitsFromBits(RD->getMaxAlignment())); finalizeLayout(RD); @@ -2405,7 +2411,7 @@ void MicrosoftRecordLayoutBuilder::cxxLayout(const CXXRecordDecl *RD) { auto RoundingAlignment = Alignment; if (!MaxFieldAlignment.isZero()) RoundingAlignment = std::min(RoundingAlignment, MaxFieldAlignment); - NonVirtualSize = Size = Size.RoundUpToAlignment(RoundingAlignment); + NonVirtualSize = Size = Size.alignTo(RoundingAlignment); RequiredAlignment = std::max( RequiredAlignment, Context.toCharUnitsFromBits(RD->getMaxAlignment())); layoutVirtualBases(RD); @@ -2471,7 +2477,7 @@ MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(const CXXRecordDecl *RD) { // out any bases that do not contain vfptrs. We implement this as two passes // over the bases. This approach guarantees that the primary base is laid out // first. We use these passes to calculate some additional aggregated - // information about the bases, such as reqruied alignment and the presence of + // information about the bases, such as required alignment and the presence of // zero sized members. const ASTRecordLayout *PreviousBaseLayout = nullptr; // Iterate through the bases and lay out the non-virtual ones. @@ -2483,7 +2489,7 @@ MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(const CXXRecordDecl *RD) { HasVBPtr = true; continue; } - // Check fo a base to share a VBPtr with. + // Check for a base to share a VBPtr with. if (!SharedVBPtrBase && BaseLayout.hasVBPtr()) { SharedVBPtrBase = BaseDecl; HasVBPtr = true; @@ -2497,7 +2503,7 @@ MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(const CXXRecordDecl *RD) { LeadsWithZeroSizedBase = BaseLayout.leadsWithZeroSizedBase(); } // Lay out the base. - layoutNonVirtualBase(BaseDecl, BaseLayout, PreviousBaseLayout); + layoutNonVirtualBase(RD, BaseDecl, BaseLayout, PreviousBaseLayout); } // Figure out if we need a fresh VFPtr for this class. if (!PrimaryBase && RD->isDynamicClass()) @@ -2526,7 +2532,7 @@ MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(const CXXRecordDecl *RD) { LeadsWithZeroSizedBase = BaseLayout.leadsWithZeroSizedBase(); } // Lay out the base. - layoutNonVirtualBase(BaseDecl, BaseLayout, PreviousBaseLayout); + layoutNonVirtualBase(RD, BaseDecl, BaseLayout, PreviousBaseLayout); VBPtrOffset = Bases[BaseDecl] + BaseLayout.getNonVirtualSize(); } // Set our VBPtroffset if we know it at this point. @@ -2538,15 +2544,32 @@ MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(const CXXRecordDecl *RD) { } } +static bool recordUsesEBO(const RecordDecl *RD) { + if (!isa<CXXRecordDecl>(RD)) + return false; + if (RD->hasAttr<EmptyBasesAttr>()) + return true; + if (auto *LVA = RD->getAttr<LayoutVersionAttr>()) + // TODO: Double check with the next version of MSVC. + if (LVA->getVersion() <= LangOptions::MSVC2015) + return false; + // TODO: Some later version of MSVC will change the default behavior of the + // compiler to enable EBO by default. When this happens, we will need an + // additional isCompatibleWithMSVC check. + return false; +} + void MicrosoftRecordLayoutBuilder::layoutNonVirtualBase( + const CXXRecordDecl *RD, const CXXRecordDecl *BaseDecl, const ASTRecordLayout &BaseLayout, const ASTRecordLayout *&PreviousBaseLayout) { // Insert padding between two bases if the left first one is zero sized or // contains a zero sized subobject and the right is zero sized or one leads // with a zero sized base. - if (PreviousBaseLayout && PreviousBaseLayout->hasZeroSizedSubObject() && - BaseLayout.leadsWithZeroSizedBase()) + bool MDCUsesEBO = recordUsesEBO(RD); + if (PreviousBaseLayout && PreviousBaseLayout->endsWithZeroSizedObject() && + BaseLayout.leadsWithZeroSizedBase() && !MDCUsesEBO) Size++; ElementInfo Info = getAdjustedElementInfo(BaseLayout); CharUnits BaseOffset; @@ -2555,14 +2578,23 @@ void MicrosoftRecordLayoutBuilder::layoutNonVirtualBase( bool FoundBase = false; if (UseExternalLayout) { FoundBase = External.getExternalNVBaseOffset(BaseDecl, BaseOffset); - if (FoundBase) + if (FoundBase) { assert(BaseOffset >= Size && "base offset already allocated"); + Size = BaseOffset; + } } - if (!FoundBase) - BaseOffset = Size.RoundUpToAlignment(Info.Alignment); + if (!FoundBase) { + if (MDCUsesEBO && BaseDecl->isEmpty() && + BaseLayout.getNonVirtualSize() == CharUnits::Zero()) { + BaseOffset = CharUnits::Zero(); + } else { + // Otherwise, lay the base out at the end of the MDC. + BaseOffset = Size = Size.alignTo(Info.Alignment); + } + } Bases.insert(std::make_pair(BaseDecl, BaseOffset)); - Size = BaseOffset + BaseLayout.getNonVirtualSize(); + Size += BaseLayout.getNonVirtualSize(); PreviousBaseLayout = &BaseLayout; } @@ -2590,7 +2622,7 @@ void MicrosoftRecordLayoutBuilder::layoutField(const FieldDecl *FD) { Context.toCharUnitsFromBits(External.getExternalFieldOffset(FD)); assert(FieldOffset >= Size && "field offset already allocated"); } else { - FieldOffset = Size.RoundUpToAlignment(Info.Alignment); + FieldOffset = Size.alignTo(Info.Alignment); } placeFieldAtOffset(FieldOffset); Size = FieldOffset + Info.Size; @@ -2625,7 +2657,7 @@ void MicrosoftRecordLayoutBuilder::layoutBitField(const FieldDecl *FD) { // TODO: Add a Sema warning that MS ignores bitfield alignment in unions. } else { // Allocate a new block of memory and place the bitfield in it. - CharUnits FieldOffset = Size.RoundUpToAlignment(Info.Alignment); + CharUnits FieldOffset = Size.alignTo(Info.Alignment); placeFieldAtOffset(FieldOffset); Size = FieldOffset + Info.Size; Alignment = std::max(Alignment, Info.Alignment); @@ -2651,7 +2683,7 @@ MicrosoftRecordLayoutBuilder::layoutZeroWidthBitField(const FieldDecl *FD) { // TODO: Add a Sema warning that MS ignores bitfield alignment in unions. } else { // Round up the current record size to the field's alignment boundary. - CharUnits FieldOffset = Size.RoundUpToAlignment(Info.Alignment); + CharUnits FieldOffset = Size.alignTo(Info.Alignment); placeFieldAtOffset(FieldOffset); Size = FieldOffset; Alignment = std::max(Alignment, Info.Alignment); @@ -2664,7 +2696,7 @@ void MicrosoftRecordLayoutBuilder::injectVBPtr(const CXXRecordDecl *RD) { // Inject the VBPointer at the injection site. CharUnits InjectionSite = VBPtrOffset; // But before we do, make sure it's properly aligned. - VBPtrOffset = VBPtrOffset.RoundUpToAlignment(PointerInfo.Alignment); + VBPtrOffset = VBPtrOffset.alignTo(PointerInfo.Alignment); // Shift everything after the vbptr down, unless we're using an external // layout. if (UseExternalLayout) @@ -2673,8 +2705,8 @@ void MicrosoftRecordLayoutBuilder::injectVBPtr(const CXXRecordDecl *RD) { CharUnits FieldStart = VBPtrOffset + PointerInfo.Size; // Make sure that the amount we push the fields back by is a multiple of the // alignment. - CharUnits Offset = (FieldStart - InjectionSite).RoundUpToAlignment( - std::max(RequiredAlignment, Alignment)); + CharUnits Offset = (FieldStart - InjectionSite) + .alignTo(std::max(RequiredAlignment, Alignment)); Size += Offset; for (uint64_t &FieldOffset : FieldOffsets) FieldOffset += Context.toBits(Offset); @@ -2688,8 +2720,8 @@ void MicrosoftRecordLayoutBuilder::injectVFPtr(const CXXRecordDecl *RD) { return; // Make sure that the amount we push the struct back by is a multiple of the // alignment. - CharUnits Offset = PointerInfo.Size.RoundUpToAlignment( - std::max(RequiredAlignment, Alignment)); + CharUnits Offset = + PointerInfo.Size.alignTo(std::max(RequiredAlignment, Alignment)); // Push back the vbptr, but increase the size of the object and push back // regular fields by the offset only if not using external record layout. if (HasVBPtr) @@ -2741,9 +2773,10 @@ void MicrosoftRecordLayoutBuilder::layoutVirtualBases(const CXXRecordDecl *RD) { // with a zero sized base. The padding between virtual bases is 4 // bytes (in both 32 and 64 bits modes) and always involves rounding up to // the required alignment, we don't know why. - if ((PreviousBaseLayout && PreviousBaseLayout->hasZeroSizedSubObject() && - BaseLayout.leadsWithZeroSizedBase()) || HasVtordisp) { - Size = Size.RoundUpToAlignment(VtorDispAlignment) + VtorDispSize; + if ((PreviousBaseLayout && PreviousBaseLayout->endsWithZeroSizedObject() && + BaseLayout.leadsWithZeroSizedBase() && !recordUsesEBO(RD)) || + HasVtordisp) { + Size = Size.alignTo(VtorDispAlignment) + VtorDispSize; Alignment = std::max(VtorDispAlignment, Alignment); } // Insert the virtual base. @@ -2758,7 +2791,7 @@ void MicrosoftRecordLayoutBuilder::layoutVirtualBases(const CXXRecordDecl *RD) { assert(BaseOffset >= Size && "base offset already allocated"); } if (!FoundBase) - BaseOffset = Size.RoundUpToAlignment(Info.Alignment); + BaseOffset = Size.alignTo(Info.Alignment); VBases.insert(std::make_pair(BaseDecl, ASTRecordLayout::VBaseInfo(BaseOffset, HasVtordisp))); @@ -2777,11 +2810,13 @@ void MicrosoftRecordLayoutBuilder::finalizeLayout(const RecordDecl *RD) { if (!MaxFieldAlignment.isZero()) RoundingAlignment = std::min(RoundingAlignment, MaxFieldAlignment); RoundingAlignment = std::max(RoundingAlignment, RequiredAlignment); - Size = Size.RoundUpToAlignment(RoundingAlignment); + Size = Size.alignTo(RoundingAlignment); } if (Size.isZero()) { - EndsWithZeroSizedObject = true; - LeadsWithZeroSizedBase = true; + if (!recordUsesEBO(RD) || !cast<CXXRecordDecl>(RD)->isEmpty()) { + EndsWithZeroSizedObject = true; + LeadsWithZeroSizedBase = true; + } // Zero-sized structures have size equal to their alignment if a // __declspec(align) came into play. if (RequiredAlignment >= MinEmptyStructSize) @@ -2914,8 +2949,7 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const { NewEntry = new (*this) ASTRecordLayout( *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment, Builder.HasOwnVFPtr, Builder.HasOwnVFPtr || Builder.PrimaryBase, - Builder.VBPtrOffset, Builder.NonVirtualSize, - Builder.FieldOffsets.data(), Builder.FieldOffsets.size(), + Builder.VBPtrOffset, Builder.DataSize, Builder.FieldOffsets, Builder.NonVirtualSize, Builder.Alignment, CharUnits::Zero(), Builder.PrimaryBase, false, Builder.SharedVBPtrBase, Builder.EndsWithZeroSizedObject, Builder.LeadsWithZeroSizedBase, @@ -2924,8 +2958,7 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const { Builder.layout(D); NewEntry = new (*this) ASTRecordLayout( *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment, - Builder.Size, Builder.FieldOffsets.data(), - Builder.FieldOffsets.size()); + Builder.Size, Builder.FieldOffsets); } } else { if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) { @@ -2948,9 +2981,8 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const { *this, Builder.getSize(), Builder.Alignment, /*RequiredAlignment : used by MS-ABI)*/ Builder.Alignment, Builder.HasOwnVFPtr, RD->isDynamicClass(), - CharUnits::fromQuantity(-1), DataSize, Builder.FieldOffsets.data(), - Builder.FieldOffsets.size(), NonVirtualSize, - Builder.NonVirtualAlignment, + CharUnits::fromQuantity(-1), DataSize, Builder.FieldOffsets, + NonVirtualSize, Builder.NonVirtualAlignment, EmptySubobjects.SizeOfLargestEmptySubobject, Builder.PrimaryBase, Builder.PrimaryBaseIsVirtual, nullptr, false, false, Builder.Bases, Builder.VBases); @@ -2961,8 +2993,7 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const { NewEntry = new (*this) ASTRecordLayout( *this, Builder.getSize(), Builder.Alignment, /*RequiredAlignment : used by MS-ABI)*/ - Builder.Alignment, Builder.getSize(), Builder.FieldOffsets.data(), - Builder.FieldOffsets.size()); + Builder.Alignment, Builder.getSize(), Builder.FieldOffsets); } } @@ -3065,7 +3096,7 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D, // Add in synthesized ivar count if laying out an implementation. if (Impl) { unsigned SynthCount = CountNonClassIvars(D); - // If there aren't any sythesized ivars then reuse the interface + // If there aren't any synthesized ivars then reuse the interface // entry. Note we can't cache this because we simply free all // entries later; however we shouldn't look up implementations // frequently. @@ -3077,13 +3108,12 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D, Builder.Layout(D); const ASTRecordLayout *NewEntry = - new (*this) ASTRecordLayout(*this, Builder.getSize(), + new (*this) ASTRecordLayout(*this, Builder.getSize(), Builder.Alignment, /*RequiredAlignment : used by MS-ABI)*/ Builder.Alignment, Builder.getDataSize(), - Builder.FieldOffsets.data(), - Builder.FieldOffsets.size()); + Builder.FieldOffsets); ObjCLayouts[Key] = NewEntry; diff --git a/contrib/llvm/tools/clang/lib/AST/Stmt.cpp b/contrib/llvm/tools/clang/lib/AST/Stmt.cpp index ca63d84..75c0763 100644 --- a/contrib/llvm/tools/clang/lib/AST/Stmt.cpp +++ b/contrib/llvm/tools/clang/lib/AST/Stmt.cpp @@ -503,6 +503,9 @@ unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces, bool HasVariants = !C.getTargetInfo().hasNoAsmVariants(); + unsigned LastAsmStringToken = 0; + unsigned LastAsmStringOffset = 0; + while (1) { // Done with the string? if (CurPtr == StrEnd) { @@ -589,10 +592,12 @@ unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces, // (BeginLoc, EndLoc) represents the range of the operand we are currently // processing. Unlike Str, the range includes the leading '%'. - SourceLocation BeginLoc = - getAsmString()->getLocationOfByte(Percent - StrStart, SM, LO, TI); - SourceLocation EndLoc = - getAsmString()->getLocationOfByte(CurPtr - StrStart, SM, LO, TI); + SourceLocation BeginLoc = getAsmString()->getLocationOfByte( + Percent - StrStart, SM, LO, TI, &LastAsmStringToken, + &LastAsmStringOffset); + SourceLocation EndLoc = getAsmString()->getLocationOfByte( + CurPtr - StrStart, SM, LO, TI, &LastAsmStringToken, + &LastAsmStringOffset); Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc); continue; @@ -623,10 +628,12 @@ unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces, // (BeginLoc, EndLoc) represents the range of the operand we are currently // processing. Unlike Str, the range includes the leading '%'. - SourceLocation BeginLoc = - getAsmString()->getLocationOfByte(Percent - StrStart, SM, LO, TI); - SourceLocation EndLoc = - getAsmString()->getLocationOfByte(NameEnd + 1 - StrStart, SM, LO, TI); + SourceLocation BeginLoc = getAsmString()->getLocationOfByte( + Percent - StrStart, SM, LO, TI, &LastAsmStringToken, + &LastAsmStringOffset); + SourceLocation EndLoc = getAsmString()->getLocationOfByte( + NameEnd + 1 - StrStart, SM, LO, TI, &LastAsmStringToken, + &LastAsmStringOffset); Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc); @@ -756,11 +763,13 @@ void MSAsmStmt::initialize(const ASTContext &C, StringRef asmstr, }); } -IfStmt::IfStmt(const ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, - Stmt *then, SourceLocation EL, Stmt *elsev) - : Stmt(IfStmtClass), IfLoc(IL), ElseLoc(EL) -{ +IfStmt::IfStmt(const ASTContext &C, SourceLocation IL, bool IsConstexpr, + Stmt *init, VarDecl *var, Expr *cond, Stmt *then, + SourceLocation EL, Stmt *elsev) + : Stmt(IfStmtClass), IfLoc(IL), ElseLoc(EL) { + setConstexpr(IsConstexpr); setConditionVariable(C, var); + SubExprs[INIT] = init; SubExprs[COND] = cond; SubExprs[THEN] = then; SubExprs[ELSE] = elsev; @@ -816,9 +825,11 @@ void ForStmt::setConditionVariable(const ASTContext &C, VarDecl *V) { VarRange.getEnd()); } -SwitchStmt::SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond) +SwitchStmt::SwitchStmt(const ASTContext &C, Stmt *init, VarDecl *Var, + Expr *cond) : Stmt(SwitchStmtClass), FirstCase(nullptr, false) { setConditionVariable(C, Var); + SubExprs[INIT] = init; SubExprs[COND] = cond; SubExprs[BODY] = nullptr; } @@ -987,8 +998,7 @@ CapturedStmt::Capture *CapturedStmt::getStoredCaptures() const { unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1); // Offset of the first Capture object. - unsigned FirstCaptureOffset = - llvm::RoundUpToAlignment(Size, llvm::alignOf<Capture>()); + unsigned FirstCaptureOffset = llvm::alignTo(Size, llvm::alignOf<Capture>()); return reinterpret_cast<Capture *>( reinterpret_cast<char *>(const_cast<CapturedStmt *>(this)) @@ -1045,7 +1055,7 @@ CapturedStmt *CapturedStmt::Create(const ASTContext &Context, Stmt *S, unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (Captures.size() + 1); if (!Captures.empty()) { // Realign for the following Capture array. - Size = llvm::RoundUpToAlignment(Size, llvm::alignOf<Capture>()); + Size = llvm::alignTo(Size, llvm::alignOf<Capture>()); Size += sizeof(Capture) * Captures.size(); } @@ -1058,7 +1068,7 @@ CapturedStmt *CapturedStmt::CreateDeserialized(const ASTContext &Context, unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1); if (NumCaptures > 0) { // Realign for the following Capture array. - Size = llvm::RoundUpToAlignment(Size, llvm::alignOf<Capture>()); + Size = llvm::alignTo(Size, llvm::alignOf<Capture>()); Size += sizeof(Capture) * NumCaptures; } diff --git a/contrib/llvm/tools/clang/lib/AST/StmtCXX.cpp b/contrib/llvm/tools/clang/lib/AST/StmtCXX.cpp index e39a01d..4692db8 100644 --- a/contrib/llvm/tools/clang/lib/AST/StmtCXX.cpp +++ b/contrib/llvm/tools/clang/lib/AST/StmtCXX.cpp @@ -49,7 +49,8 @@ CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, std::copy(handlers.begin(), handlers.end(), Stmts + 1); } -CXXForRangeStmt::CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEndStmt, +CXXForRangeStmt::CXXForRangeStmt(DeclStmt *Range, + DeclStmt *BeginStmt, DeclStmt *EndStmt, Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body, SourceLocation FL, SourceLocation CAL, SourceLocation CL, @@ -57,7 +58,8 @@ CXXForRangeStmt::CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEndStmt, : Stmt(CXXForRangeStmtClass), ForLoc(FL), CoawaitLoc(CAL), ColonLoc(CL), RParenLoc(RPL) { SubExprs[RANGE] = Range; - SubExprs[BEGINEND] = BeginEndStmt; + SubExprs[BEGINSTMT] = BeginStmt; + SubExprs[ENDSTMT] = EndStmt; SubExprs[COND] = Cond; SubExprs[INC] = Inc; SubExprs[LOOPVAR] = LoopVar; diff --git a/contrib/llvm/tools/clang/lib/AST/StmtOpenMP.cpp b/contrib/llvm/tools/clang/lib/AST/StmtOpenMP.cpp index 7f923d8..f1ddedb 100644 --- a/contrib/llvm/tools/clang/lib/AST/StmtOpenMP.cpp +++ b/contrib/llvm/tools/clang/lib/AST/StmtOpenMP.cpp @@ -57,8 +57,8 @@ void OMPLoopDirective::setFinals(ArrayRef<Expr *> A) { OMPParallelDirective *OMPParallelDirective::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPParallelDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *)); OMPParallelDirective *Dir = @@ -72,8 +72,8 @@ OMPParallelDirective *OMPParallelDirective::Create( OMPParallelDirective *OMPParallelDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPParallelDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *)); return new (Mem) OMPParallelDirective(NumClauses); @@ -84,8 +84,8 @@ OMPSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSimdDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPSimdDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_simd)); @@ -105,6 +105,7 @@ OMPSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc, Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -112,8 +113,8 @@ OMPSimdDirective *OMPSimdDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSimdDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPSimdDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_simd)); @@ -125,8 +126,8 @@ OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPForDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_for)); @@ -148,11 +149,15 @@ OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc, Dir->setEnsureUpperBound(Exprs.EUB); Dir->setNextLowerBound(Exprs.NLB); Dir->setNextUpperBound(Exprs.NUB); + Dir->setNumIterations(Exprs.NumIterations); + Dir->setPrevLowerBoundVariable(Exprs.PrevLB); + Dir->setPrevUpperBoundVariable(Exprs.PrevUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); Dir->setHasCancel(HasCancel); return Dir; } @@ -161,8 +166,8 @@ OMPForDirective *OMPForDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPForDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_for)); @@ -174,8 +179,8 @@ OMPForSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForSimdDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPForSimdDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_for_simd)); @@ -197,11 +202,15 @@ OMPForSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc, Dir->setEnsureUpperBound(Exprs.EUB); Dir->setNextLowerBound(Exprs.NLB); Dir->setNextUpperBound(Exprs.NUB); + Dir->setNumIterations(Exprs.NumIterations); + Dir->setPrevLowerBoundVariable(Exprs.PrevLB); + Dir->setPrevUpperBoundVariable(Exprs.PrevUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -209,8 +218,8 @@ OMPForSimdDirective *OMPForSimdDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForSimdDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPForSimdDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_for_simd)); @@ -220,8 +229,8 @@ OMPForSimdDirective *OMPForSimdDirective::CreateEmpty(const ASTContext &C, OMPSectionsDirective *OMPSectionsDirective::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPSectionsDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *)); OMPSectionsDirective *Dir = @@ -235,8 +244,8 @@ OMPSectionsDirective *OMPSectionsDirective::Create( OMPSectionsDirective *OMPSectionsDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPSectionsDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *)); return new (Mem) OMPSectionsDirective(NumClauses); @@ -247,8 +256,8 @@ OMPSectionDirective *OMPSectionDirective::Create(const ASTContext &C, SourceLocation EndLoc, Stmt *AssociatedStmt, bool HasCancel) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionDirective), - llvm::alignOf<Stmt *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPSectionDirective), llvm::alignOf<Stmt *>()); void *Mem = C.Allocate(Size + sizeof(Stmt *)); OMPSectionDirective *Dir = new (Mem) OMPSectionDirective(StartLoc, EndLoc); Dir->setAssociatedStmt(AssociatedStmt); @@ -258,8 +267,8 @@ OMPSectionDirective *OMPSectionDirective::Create(const ASTContext &C, OMPSectionDirective *OMPSectionDirective::CreateEmpty(const ASTContext &C, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionDirective), - llvm::alignOf<Stmt *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPSectionDirective), llvm::alignOf<Stmt *>()); void *Mem = C.Allocate(Size + sizeof(Stmt *)); return new (Mem) OMPSectionDirective(); } @@ -269,8 +278,8 @@ OMPSingleDirective *OMPSingleDirective::Create(const ASTContext &C, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSingleDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPSingleDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *)); OMPSingleDirective *Dir = @@ -283,8 +292,8 @@ OMPSingleDirective *OMPSingleDirective::Create(const ASTContext &C, OMPSingleDirective *OMPSingleDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSingleDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPSingleDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *)); return new (Mem) OMPSingleDirective(NumClauses); @@ -294,8 +303,8 @@ OMPMasterDirective *OMPMasterDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPMasterDirective), - llvm::alignOf<Stmt *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPMasterDirective), llvm::alignOf<Stmt *>()); void *Mem = C.Allocate(Size + sizeof(Stmt *)); OMPMasterDirective *Dir = new (Mem) OMPMasterDirective(StartLoc, EndLoc); Dir->setAssociatedStmt(AssociatedStmt); @@ -304,8 +313,8 @@ OMPMasterDirective *OMPMasterDirective::Create(const ASTContext &C, OMPMasterDirective *OMPMasterDirective::CreateEmpty(const ASTContext &C, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPMasterDirective), - llvm::alignOf<Stmt *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPMasterDirective), llvm::alignOf<Stmt *>()); void *Mem = C.Allocate(Size + sizeof(Stmt *)); return new (Mem) OMPMasterDirective(); } @@ -314,8 +323,8 @@ OMPCriticalDirective *OMPCriticalDirective::Create( const ASTContext &C, const DeclarationNameInfo &Name, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCriticalDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPCriticalDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *)); OMPCriticalDirective *Dir = @@ -328,8 +337,8 @@ OMPCriticalDirective *OMPCriticalDirective::Create( OMPCriticalDirective *OMPCriticalDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCriticalDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPCriticalDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *)); return new (Mem) OMPCriticalDirective(NumClauses); @@ -339,8 +348,8 @@ OMPParallelForDirective *OMPParallelForDirective::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = llvm::alignTo(sizeof(OMPParallelForDirective), + llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_parallel_for)); @@ -362,11 +371,15 @@ OMPParallelForDirective *OMPParallelForDirective::Create( Dir->setEnsureUpperBound(Exprs.EUB); Dir->setNextLowerBound(Exprs.NLB); Dir->setNextUpperBound(Exprs.NUB); + Dir->setNumIterations(Exprs.NumIterations); + Dir->setPrevLowerBoundVariable(Exprs.PrevLB); + Dir->setPrevUpperBoundVariable(Exprs.PrevUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); Dir->setHasCancel(HasCancel); return Dir; } @@ -374,8 +387,8 @@ OMPParallelForDirective *OMPParallelForDirective::Create( OMPParallelForDirective * OMPParallelForDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = llvm::alignTo(sizeof(OMPParallelForDirective), + llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_parallel_for)); @@ -386,8 +399,8 @@ OMPParallelForSimdDirective *OMPParallelForSimdDirective::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForSimdDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = llvm::alignTo(sizeof(OMPParallelForSimdDirective), + llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate( Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_parallel_for_simd)); @@ -409,11 +422,15 @@ OMPParallelForSimdDirective *OMPParallelForSimdDirective::Create( Dir->setEnsureUpperBound(Exprs.EUB); Dir->setNextLowerBound(Exprs.NLB); Dir->setNextUpperBound(Exprs.NUB); + Dir->setNumIterations(Exprs.NumIterations); + Dir->setPrevLowerBoundVariable(Exprs.PrevLB); + Dir->setPrevUpperBoundVariable(Exprs.PrevUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -421,8 +438,8 @@ OMPParallelForSimdDirective * OMPParallelForSimdDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForSimdDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = llvm::alignTo(sizeof(OMPParallelForSimdDirective), + llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate( Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_parallel_for_simd)); @@ -432,8 +449,8 @@ OMPParallelForSimdDirective::CreateEmpty(const ASTContext &C, OMPParallelSectionsDirective *OMPParallelSectionsDirective::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelSectionsDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = llvm::alignTo(sizeof(OMPParallelSectionsDirective), + llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *)); OMPParallelSectionsDirective *Dir = @@ -447,8 +464,8 @@ OMPParallelSectionsDirective *OMPParallelSectionsDirective::Create( OMPParallelSectionsDirective * OMPParallelSectionsDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelSectionsDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = llvm::alignTo(sizeof(OMPParallelSectionsDirective), + llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *)); return new (Mem) OMPParallelSectionsDirective(NumClauses); @@ -458,8 +475,8 @@ OMPTaskDirective * OMPTaskDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPTaskDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *)); OMPTaskDirective *Dir = @@ -473,8 +490,8 @@ OMPTaskDirective::Create(const ASTContext &C, SourceLocation StartLoc, OMPTaskDirective *OMPTaskDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPTaskDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *)); return new (Mem) OMPTaskDirective(NumClauses); @@ -527,8 +544,8 @@ OMPTaskgroupDirective *OMPTaskgroupDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskgroupDirective), - llvm::alignOf<Stmt *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPTaskgroupDirective), llvm::alignOf<Stmt *>()); void *Mem = C.Allocate(Size + sizeof(Stmt *)); OMPTaskgroupDirective *Dir = new (Mem) OMPTaskgroupDirective(StartLoc, EndLoc); @@ -538,8 +555,8 @@ OMPTaskgroupDirective *OMPTaskgroupDirective::Create(const ASTContext &C, OMPTaskgroupDirective *OMPTaskgroupDirective::CreateEmpty(const ASTContext &C, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskgroupDirective), - llvm::alignOf<Stmt *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPTaskgroupDirective), llvm::alignOf<Stmt *>()); void *Mem = C.Allocate(Size + sizeof(Stmt *)); return new (Mem) OMPTaskgroupDirective(); } @@ -547,8 +564,8 @@ OMPTaskgroupDirective *OMPTaskgroupDirective::CreateEmpty(const ASTContext &C, OMPCancellationPointDirective *OMPCancellationPointDirective::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion) { - unsigned Size = llvm::RoundUpToAlignment( - sizeof(OMPCancellationPointDirective), llvm::alignOf<Stmt *>()); + unsigned Size = llvm::alignTo(sizeof(OMPCancellationPointDirective), + llvm::alignOf<Stmt *>()); void *Mem = C.Allocate(Size); OMPCancellationPointDirective *Dir = new (Mem) OMPCancellationPointDirective(StartLoc, EndLoc); @@ -558,8 +575,8 @@ OMPCancellationPointDirective *OMPCancellationPointDirective::Create( OMPCancellationPointDirective * OMPCancellationPointDirective::CreateEmpty(const ASTContext &C, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment( - sizeof(OMPCancellationPointDirective), llvm::alignOf<Stmt *>()); + unsigned Size = llvm::alignTo(sizeof(OMPCancellationPointDirective), + llvm::alignOf<Stmt *>()); void *Mem = C.Allocate(Size); return new (Mem) OMPCancellationPointDirective(); } @@ -568,9 +585,9 @@ OMPCancelDirective * OMPCancelDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion) { - unsigned Size = llvm::RoundUpToAlignment( - sizeof(OMPCancelDirective) + sizeof(OMPClause *) * Clauses.size(), - llvm::alignOf<Stmt *>()); + unsigned Size = llvm::alignTo(sizeof(OMPCancelDirective) + + sizeof(OMPClause *) * Clauses.size(), + llvm::alignOf<Stmt *>()); void *Mem = C.Allocate(Size); OMPCancelDirective *Dir = new (Mem) OMPCancelDirective(StartLoc, EndLoc, Clauses.size()); @@ -582,9 +599,9 @@ OMPCancelDirective::Create(const ASTContext &C, SourceLocation StartLoc, OMPCancelDirective *OMPCancelDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCancelDirective) + - sizeof(OMPClause *) * NumClauses, - llvm::alignOf<Stmt *>()); + unsigned Size = llvm::alignTo(sizeof(OMPCancelDirective) + + sizeof(OMPClause *) * NumClauses, + llvm::alignOf<Stmt *>()); void *Mem = C.Allocate(Size); return new (Mem) OMPCancelDirective(NumClauses); } @@ -593,8 +610,8 @@ OMPFlushDirective *OMPFlushDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPFlushDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPFlushDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size()); OMPFlushDirective *Dir = new (Mem) OMPFlushDirective(StartLoc, EndLoc, Clauses.size()); @@ -605,8 +622,8 @@ OMPFlushDirective *OMPFlushDirective::Create(const ASTContext &C, OMPFlushDirective *OMPFlushDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPFlushDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPFlushDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses); return new (Mem) OMPFlushDirective(NumClauses); } @@ -616,8 +633,8 @@ OMPOrderedDirective *OMPOrderedDirective::Create(const ASTContext &C, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPOrderedDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPOrderedDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(Stmt *) + sizeof(OMPClause *) * Clauses.size()); OMPOrderedDirective *Dir = @@ -630,8 +647,8 @@ OMPOrderedDirective *OMPOrderedDirective::Create(const ASTContext &C, OMPOrderedDirective *OMPOrderedDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPOrderedDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPOrderedDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(Stmt *) + sizeof(OMPClause *) * NumClauses); return new (Mem) OMPOrderedDirective(NumClauses); @@ -641,8 +658,8 @@ OMPAtomicDirective *OMPAtomicDirective::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V, Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPAtomicDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPAtomicDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + 5 * sizeof(Stmt *)); OMPAtomicDirective *Dir = @@ -661,8 +678,8 @@ OMPAtomicDirective *OMPAtomicDirective::Create( OMPAtomicDirective *OMPAtomicDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPAtomicDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPAtomicDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses + 5 * sizeof(Stmt *)); return new (Mem) OMPAtomicDirective(NumClauses); @@ -673,8 +690,8 @@ OMPTargetDirective *OMPTargetDirective::Create(const ASTContext &C, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTargetDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPTargetDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *)); OMPTargetDirective *Dir = @@ -687,20 +704,95 @@ OMPTargetDirective *OMPTargetDirective::Create(const ASTContext &C, OMPTargetDirective *OMPTargetDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTargetDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPTargetDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *)); return new (Mem) OMPTargetDirective(NumClauses); } -OMPTargetDataDirective *OMPTargetDataDirective::Create( +OMPTargetParallelDirective *OMPTargetParallelDirective::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) { + unsigned Size = llvm::alignTo(sizeof(OMPTargetParallelDirective), + llvm::alignOf<OMPClause *>()); void *Mem = - C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPTargetDataDirective), - llvm::alignOf<OMPClause *>()) + - sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *)); + C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *)); + OMPTargetParallelDirective *Dir = + new (Mem) OMPTargetParallelDirective(StartLoc, EndLoc, Clauses.size()); + Dir->setClauses(Clauses); + Dir->setAssociatedStmt(AssociatedStmt); + return Dir; +} + +OMPTargetParallelDirective * +OMPTargetParallelDirective::CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell) { + unsigned Size = llvm::alignTo(sizeof(OMPTargetParallelDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = + C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *)); + return new (Mem) OMPTargetParallelDirective(NumClauses); +} + +OMPTargetParallelForDirective *OMPTargetParallelForDirective::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, + const HelperExprs &Exprs, bool HasCancel) { + unsigned Size = llvm::alignTo(sizeof(OMPTargetParallelForDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = C.Allocate( + Size + sizeof(OMPClause *) * Clauses.size() + + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_target_parallel_for)); + OMPTargetParallelForDirective *Dir = new (Mem) OMPTargetParallelForDirective( + StartLoc, EndLoc, CollapsedNum, Clauses.size()); + Dir->setClauses(Clauses); + Dir->setAssociatedStmt(AssociatedStmt); + Dir->setIterationVariable(Exprs.IterationVarRef); + Dir->setLastIteration(Exprs.LastIteration); + Dir->setCalcLastIteration(Exprs.CalcLastIteration); + Dir->setPreCond(Exprs.PreCond); + Dir->setCond(Exprs.Cond); + Dir->setInit(Exprs.Init); + Dir->setInc(Exprs.Inc); + Dir->setIsLastIterVariable(Exprs.IL); + Dir->setLowerBoundVariable(Exprs.LB); + Dir->setUpperBoundVariable(Exprs.UB); + Dir->setStrideVariable(Exprs.ST); + Dir->setEnsureUpperBound(Exprs.EUB); + Dir->setNextLowerBound(Exprs.NLB); + Dir->setNextUpperBound(Exprs.NUB); + Dir->setNumIterations(Exprs.NumIterations); + Dir->setPrevLowerBoundVariable(Exprs.PrevLB); + Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setCounters(Exprs.Counters); + Dir->setPrivateCounters(Exprs.PrivateCounters); + Dir->setInits(Exprs.Inits); + Dir->setUpdates(Exprs.Updates); + Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); + Dir->setHasCancel(HasCancel); + return Dir; +} + +OMPTargetParallelForDirective * +OMPTargetParallelForDirective::CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, EmptyShell) { + unsigned Size = llvm::alignTo(sizeof(OMPTargetParallelForDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = C.Allocate( + Size + sizeof(OMPClause *) * NumClauses + + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_target_parallel_for)); + return new (Mem) OMPTargetParallelForDirective(CollapsedNum, NumClauses); +} + +OMPTargetDataDirective *OMPTargetDataDirective::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) { + void *Mem = C.Allocate(llvm::alignTo(sizeof(OMPTargetDataDirective), + llvm::alignOf<OMPClause *>()) + + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *)); OMPTargetDataDirective *Dir = new (Mem) OMPTargetDataDirective(StartLoc, EndLoc, Clauses.size()); Dir->setClauses(Clauses); @@ -711,20 +803,62 @@ OMPTargetDataDirective *OMPTargetDataDirective::Create( OMPTargetDataDirective *OMPTargetDataDirective::CreateEmpty(const ASTContext &C, unsigned N, EmptyShell) { - void *Mem = - C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPTargetDataDirective), - llvm::alignOf<OMPClause *>()) + - sizeof(OMPClause *) * N + sizeof(Stmt *)); + void *Mem = C.Allocate(llvm::alignTo(sizeof(OMPTargetDataDirective), + llvm::alignOf<OMPClause *>()) + + sizeof(OMPClause *) * N + sizeof(Stmt *)); return new (Mem) OMPTargetDataDirective(N); } +OMPTargetEnterDataDirective *OMPTargetEnterDataDirective::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses) { + void *Mem = C.Allocate(llvm::alignTo(sizeof(OMPTargetEnterDataDirective), + llvm::alignOf<OMPClause *>()) + + sizeof(OMPClause *) * Clauses.size()); + OMPTargetEnterDataDirective *Dir = + new (Mem) OMPTargetEnterDataDirective(StartLoc, EndLoc, Clauses.size()); + Dir->setClauses(Clauses); + return Dir; +} + +OMPTargetEnterDataDirective * +OMPTargetEnterDataDirective::CreateEmpty(const ASTContext &C, unsigned N, + EmptyShell) { + void *Mem = C.Allocate(llvm::alignTo(sizeof(OMPTargetEnterDataDirective), + llvm::alignOf<OMPClause *>()) + + sizeof(OMPClause *) * N); + return new (Mem) OMPTargetEnterDataDirective(N); +} + +OMPTargetExitDataDirective * +OMPTargetExitDataDirective::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses) { + void *Mem = C.Allocate(llvm::alignTo(sizeof(OMPTargetExitDataDirective), + llvm::alignOf<OMPClause *>()) + + sizeof(OMPClause *) * Clauses.size()); + OMPTargetExitDataDirective *Dir = + new (Mem) OMPTargetExitDataDirective(StartLoc, EndLoc, Clauses.size()); + Dir->setClauses(Clauses); + return Dir; +} + +OMPTargetExitDataDirective * +OMPTargetExitDataDirective::CreateEmpty(const ASTContext &C, unsigned N, + EmptyShell) { + void *Mem = C.Allocate(llvm::alignTo(sizeof(OMPTargetExitDataDirective), + llvm::alignOf<OMPClause *>()) + + sizeof(OMPClause *) * N); + return new (Mem) OMPTargetExitDataDirective(N); +} + OMPTeamsDirective *OMPTeamsDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTeamsDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPTeamsDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *)); OMPTeamsDirective *Dir = @@ -737,8 +871,8 @@ OMPTeamsDirective *OMPTeamsDirective::Create(const ASTContext &C, OMPTeamsDirective *OMPTeamsDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTeamsDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPTeamsDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *)); return new (Mem) OMPTeamsDirective(NumClauses); @@ -748,8 +882,8 @@ OMPTaskLoopDirective *OMPTaskLoopDirective::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskLoopDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPTaskLoopDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_taskloop)); @@ -771,11 +905,15 @@ OMPTaskLoopDirective *OMPTaskLoopDirective::Create( Dir->setEnsureUpperBound(Exprs.EUB); Dir->setNextLowerBound(Exprs.NLB); Dir->setNextUpperBound(Exprs.NUB); + Dir->setNumIterations(Exprs.NumIterations); + Dir->setPrevLowerBoundVariable(Exprs.PrevLB); + Dir->setPrevUpperBoundVariable(Exprs.PrevUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -783,8 +921,8 @@ OMPTaskLoopDirective *OMPTaskLoopDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskLoopDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = + llvm::alignTo(sizeof(OMPTaskLoopDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_taskloop)); @@ -795,8 +933,8 @@ OMPTaskLoopSimdDirective *OMPTaskLoopSimdDirective::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskLoopSimdDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = llvm::alignTo(sizeof(OMPTaskLoopSimdDirective), + llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_taskloop_simd)); @@ -818,19 +956,23 @@ OMPTaskLoopSimdDirective *OMPTaskLoopSimdDirective::Create( Dir->setEnsureUpperBound(Exprs.EUB); Dir->setNextLowerBound(Exprs.NLB); Dir->setNextUpperBound(Exprs.NUB); + Dir->setNumIterations(Exprs.NumIterations); + Dir->setPrevLowerBoundVariable(Exprs.PrevLB); + Dir->setPrevUpperBoundVariable(Exprs.PrevUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); return Dir; } OMPTaskLoopSimdDirective * OMPTaskLoopSimdDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskLoopSimdDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = llvm::alignTo(sizeof(OMPTaskLoopSimdDirective), + llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_taskloop_simd)); @@ -841,8 +983,8 @@ OMPDistributeDirective *OMPDistributeDirective::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPDistributeDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = llvm::alignTo(sizeof(OMPDistributeDirective), + llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_distribute)); @@ -864,21 +1006,267 @@ OMPDistributeDirective *OMPDistributeDirective::Create( Dir->setEnsureUpperBound(Exprs.EUB); Dir->setNextLowerBound(Exprs.NLB); Dir->setNextUpperBound(Exprs.NUB); + Dir->setNumIterations(Exprs.NumIterations); + Dir->setPrevLowerBoundVariable(Exprs.PrevLB); + Dir->setPrevUpperBoundVariable(Exprs.PrevUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); return Dir; } OMPDistributeDirective * OMPDistributeDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, EmptyShell) { - unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPDistributeDirective), - llvm::alignOf<OMPClause *>()); + unsigned Size = llvm::alignTo(sizeof(OMPDistributeDirective), + llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_distribute)); return new (Mem) OMPDistributeDirective(CollapsedNum, NumClauses); } + +OMPTargetUpdateDirective * +OMPTargetUpdateDirective::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses) { + unsigned Size = llvm::alignTo(sizeof(OMPTargetUpdateDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size()); + OMPTargetUpdateDirective *Dir = + new (Mem) OMPTargetUpdateDirective(StartLoc, EndLoc, Clauses.size()); + Dir->setClauses(Clauses); + return Dir; +} + +OMPTargetUpdateDirective * +OMPTargetUpdateDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, + EmptyShell) { + unsigned Size = llvm::alignTo(sizeof(OMPTargetUpdateDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses); + return new (Mem) OMPTargetUpdateDirective(NumClauses); +} + +OMPDistributeParallelForDirective *OMPDistributeParallelForDirective::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, + const HelperExprs &Exprs) { + unsigned Size = llvm::alignTo(sizeof(OMPDistributeParallelForDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = C.Allocate( + Size + sizeof(OMPClause *) * Clauses.size() + + sizeof(Stmt *) * + numLoopChildren(CollapsedNum, OMPD_distribute_parallel_for)); + OMPDistributeParallelForDirective *Dir = + new (Mem) OMPDistributeParallelForDirective(StartLoc, EndLoc, + CollapsedNum, Clauses.size()); + Dir->setClauses(Clauses); + Dir->setAssociatedStmt(AssociatedStmt); + Dir->setIterationVariable(Exprs.IterationVarRef); + Dir->setLastIteration(Exprs.LastIteration); + Dir->setCalcLastIteration(Exprs.CalcLastIteration); + Dir->setPreCond(Exprs.PreCond); + Dir->setCond(Exprs.Cond); + Dir->setInit(Exprs.Init); + Dir->setInc(Exprs.Inc); + Dir->setIsLastIterVariable(Exprs.IL); + Dir->setLowerBoundVariable(Exprs.LB); + Dir->setUpperBoundVariable(Exprs.UB); + Dir->setStrideVariable(Exprs.ST); + Dir->setEnsureUpperBound(Exprs.EUB); + Dir->setNextLowerBound(Exprs.NLB); + Dir->setNextUpperBound(Exprs.NUB); + Dir->setNumIterations(Exprs.NumIterations); + Dir->setPrevLowerBoundVariable(Exprs.PrevLB); + Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setCounters(Exprs.Counters); + Dir->setPrivateCounters(Exprs.PrivateCounters); + Dir->setInits(Exprs.Inits); + Dir->setUpdates(Exprs.Updates); + Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); + return Dir; +} + +OMPDistributeParallelForDirective * +OMPDistributeParallelForDirective::CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell) { + unsigned Size = llvm::alignTo(sizeof(OMPDistributeParallelForDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = C.Allocate( + Size + sizeof(OMPClause *) * NumClauses + + sizeof(Stmt *) * + numLoopChildren(CollapsedNum, OMPD_distribute_parallel_for)); + return new (Mem) OMPDistributeParallelForDirective(CollapsedNum, NumClauses); +} + +OMPDistributeParallelForSimdDirective * +OMPDistributeParallelForSimdDirective::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, + const HelperExprs &Exprs) { + unsigned Size = llvm::alignTo(sizeof(OMPDistributeParallelForSimdDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = C.Allocate( + Size + sizeof(OMPClause *) * Clauses.size() + + sizeof(Stmt *) * + numLoopChildren(CollapsedNum, OMPD_distribute_parallel_for_simd)); + OMPDistributeParallelForSimdDirective *Dir = new (Mem) + OMPDistributeParallelForSimdDirective(StartLoc, EndLoc, CollapsedNum, + Clauses.size()); + Dir->setClauses(Clauses); + Dir->setAssociatedStmt(AssociatedStmt); + Dir->setIterationVariable(Exprs.IterationVarRef); + Dir->setLastIteration(Exprs.LastIteration); + Dir->setCalcLastIteration(Exprs.CalcLastIteration); + Dir->setPreCond(Exprs.PreCond); + Dir->setCond(Exprs.Cond); + Dir->setInit(Exprs.Init); + Dir->setInc(Exprs.Inc); + Dir->setIsLastIterVariable(Exprs.IL); + Dir->setLowerBoundVariable(Exprs.LB); + Dir->setUpperBoundVariable(Exprs.UB); + Dir->setStrideVariable(Exprs.ST); + Dir->setEnsureUpperBound(Exprs.EUB); + Dir->setNextLowerBound(Exprs.NLB); + Dir->setNextUpperBound(Exprs.NUB); + Dir->setNumIterations(Exprs.NumIterations); + Dir->setPrevLowerBoundVariable(Exprs.PrevLB); + Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setCounters(Exprs.Counters); + Dir->setPrivateCounters(Exprs.PrivateCounters); + Dir->setInits(Exprs.Inits); + Dir->setUpdates(Exprs.Updates); + Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); + return Dir; +} + +OMPDistributeParallelForSimdDirective * +OMPDistributeParallelForSimdDirective::CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell) { + unsigned Size = llvm::alignTo(sizeof(OMPDistributeParallelForSimdDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = C.Allocate( + Size + sizeof(OMPClause *) * NumClauses + + sizeof(Stmt *) * + numLoopChildren(CollapsedNum, OMPD_distribute_parallel_for_simd)); + return new (Mem) + OMPDistributeParallelForSimdDirective(CollapsedNum, NumClauses); +} + +OMPDistributeSimdDirective *OMPDistributeSimdDirective::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, + const HelperExprs &Exprs) { + unsigned Size = llvm::alignTo(sizeof(OMPDistributeSimdDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = C.Allocate( + Size + sizeof(OMPClause *) * Clauses.size() + + sizeof(Stmt *) * + numLoopChildren(CollapsedNum, OMPD_distribute_simd)); + OMPDistributeSimdDirective *Dir = new (Mem) OMPDistributeSimdDirective( + StartLoc, EndLoc, CollapsedNum, Clauses.size()); + Dir->setClauses(Clauses); + Dir->setAssociatedStmt(AssociatedStmt); + Dir->setIterationVariable(Exprs.IterationVarRef); + Dir->setLastIteration(Exprs.LastIteration); + Dir->setCalcLastIteration(Exprs.CalcLastIteration); + Dir->setPreCond(Exprs.PreCond); + Dir->setCond(Exprs.Cond); + Dir->setInit(Exprs.Init); + Dir->setInc(Exprs.Inc); + Dir->setIsLastIterVariable(Exprs.IL); + Dir->setLowerBoundVariable(Exprs.LB); + Dir->setUpperBoundVariable(Exprs.UB); + Dir->setStrideVariable(Exprs.ST); + Dir->setEnsureUpperBound(Exprs.EUB); + Dir->setNextLowerBound(Exprs.NLB); + Dir->setNextUpperBound(Exprs.NUB); + Dir->setNumIterations(Exprs.NumIterations); + Dir->setPrevLowerBoundVariable(Exprs.PrevLB); + Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setCounters(Exprs.Counters); + Dir->setPrivateCounters(Exprs.PrivateCounters); + Dir->setInits(Exprs.Inits); + Dir->setUpdates(Exprs.Updates); + Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); + return Dir; +} + +OMPDistributeSimdDirective * +OMPDistributeSimdDirective::CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, EmptyShell) { + unsigned Size = llvm::alignTo(sizeof(OMPDistributeSimdDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = C.Allocate( + Size + sizeof(OMPClause *) * NumClauses + + sizeof(Stmt *) * + numLoopChildren(CollapsedNum, OMPD_distribute_simd)); + return new (Mem) OMPDistributeSimdDirective(CollapsedNum, NumClauses); +} + +OMPTargetParallelForSimdDirective *OMPTargetParallelForSimdDirective::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, + const HelperExprs &Exprs) { + unsigned Size = llvm::alignTo(sizeof(OMPTargetParallelForSimdDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = C.Allocate( + Size + sizeof(OMPClause *) * Clauses.size() + + sizeof(Stmt *) * + numLoopChildren(CollapsedNum, OMPD_target_parallel_for_simd)); + OMPTargetParallelForSimdDirective *Dir = + new (Mem) OMPTargetParallelForSimdDirective(StartLoc, EndLoc, + CollapsedNum, Clauses.size()); + Dir->setClauses(Clauses); + Dir->setAssociatedStmt(AssociatedStmt); + Dir->setIterationVariable(Exprs.IterationVarRef); + Dir->setLastIteration(Exprs.LastIteration); + Dir->setCalcLastIteration(Exprs.CalcLastIteration); + Dir->setPreCond(Exprs.PreCond); + Dir->setCond(Exprs.Cond); + Dir->setInit(Exprs.Init); + Dir->setInc(Exprs.Inc); + Dir->setIsLastIterVariable(Exprs.IL); + Dir->setLowerBoundVariable(Exprs.LB); + Dir->setUpperBoundVariable(Exprs.UB); + Dir->setStrideVariable(Exprs.ST); + Dir->setEnsureUpperBound(Exprs.EUB); + Dir->setNextLowerBound(Exprs.NLB); + Dir->setNextUpperBound(Exprs.NUB); + Dir->setNumIterations(Exprs.NumIterations); + Dir->setPrevLowerBoundVariable(Exprs.PrevLB); + Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setCounters(Exprs.Counters); + Dir->setPrivateCounters(Exprs.PrivateCounters); + Dir->setInits(Exprs.Inits); + Dir->setUpdates(Exprs.Updates); + Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); + return Dir; +} + +OMPTargetParallelForSimdDirective * +OMPTargetParallelForSimdDirective::CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell) { + unsigned Size = llvm::alignTo(sizeof(OMPTargetParallelForSimdDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = C.Allocate( + Size + sizeof(OMPClause *) * NumClauses + + sizeof(Stmt *) * + numLoopChildren(CollapsedNum, OMPD_target_parallel_for_simd)); + return new (Mem) OMPTargetParallelForSimdDirective(CollapsedNum, NumClauses); +} diff --git a/contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp b/contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp index 69f52f5..8797a13 100644 --- a/contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp +++ b/contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp @@ -16,6 +16,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" @@ -496,6 +497,11 @@ void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) { OS << ";\n"; } +void StmtPrinter::VisitObjCAvailabilityCheckExpr( + ObjCAvailabilityCheckExpr *Node) { + OS << "@available(...)"; +} + void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) { Indent() << "@synchronized ("; PrintExpr(Node->getSynchExpr()); @@ -663,9 +669,9 @@ void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) { OS << ": "; } OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind()); - if (Node->getChunkSize()) { + if (auto *E = Node->getChunkSize()) { OS << ", "; - Node->getChunkSize()->printPretty(OS, nullptr, Policy); + E->printPretty(OS, nullptr, Policy); } OS << ")"; } @@ -763,15 +769,16 @@ template<typename T> void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) { for (typename T::varlist_iterator I = Node->varlist_begin(), E = Node->varlist_end(); - I != E; ++I) { + I != E; ++I) { assert(*I && "Expected non-null Stmt"); + OS << (I == Node->varlist_begin() ? StartSym : ','); if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(*I)) { - OS << (I == Node->varlist_begin() ? StartSym : ','); - cast<NamedDecl>(DRE->getDecl())->printQualifiedName(OS); - } else { - OS << (I == Node->varlist_begin() ? StartSym : ','); + if (isa<OMPCapturedExprDecl>(DRE->getDecl())) + DRE->printPretty(OS, nullptr, Policy, 0); + else + DRE->getDecl()->printQualifiedName(OS); + } else (*I)->printPretty(OS, nullptr, Policy, 0); - } } } @@ -909,6 +916,58 @@ void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) { OS << ")"; } } + +void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) { + if (!Node->varlist_empty()) { + OS << "to"; + VisitOMPClauseList(Node, '('); + OS << ")"; + } +} + +void OMPClausePrinter::VisitOMPFromClause(OMPFromClause *Node) { + if (!Node->varlist_empty()) { + OS << "from"; + VisitOMPClauseList(Node, '('); + OS << ")"; + } +} + +void OMPClausePrinter::VisitOMPDistScheduleClause(OMPDistScheduleClause *Node) { + OS << "dist_schedule(" << getOpenMPSimpleClauseTypeName( + OMPC_dist_schedule, Node->getDistScheduleKind()); + if (auto *E = Node->getChunkSize()) { + OS << ", "; + E->printPretty(OS, nullptr, Policy); + } + OS << ")"; +} + +void OMPClausePrinter::VisitOMPDefaultmapClause(OMPDefaultmapClause *Node) { + OS << "defaultmap("; + OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap, + Node->getDefaultmapModifier()); + OS << ": "; + OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap, + Node->getDefaultmapKind()); + OS << ")"; +} + +void OMPClausePrinter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *Node) { + if (!Node->varlist_empty()) { + OS << "use_device_ptr"; + VisitOMPClauseList(Node, '('); + OS << ")"; + } +} + +void OMPClausePrinter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *Node) { + if (!Node->varlist_empty()) { + OS << "is_device_ptr"; + VisitOMPClauseList(Node, '('); + OS << ")"; + } +} } //===----------------------------------------------------------------------===// @@ -1051,6 +1110,30 @@ void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) { PrintOMPExecutableDirective(Node); } +void StmtPrinter::VisitOMPTargetEnterDataDirective( + OMPTargetEnterDataDirective *Node) { + Indent() << "#pragma omp target enter data "; + PrintOMPExecutableDirective(Node); +} + +void StmtPrinter::VisitOMPTargetExitDataDirective( + OMPTargetExitDataDirective *Node) { + Indent() << "#pragma omp target exit data "; + PrintOMPExecutableDirective(Node); +} + +void StmtPrinter::VisitOMPTargetParallelDirective( + OMPTargetParallelDirective *Node) { + Indent() << "#pragma omp target parallel "; + PrintOMPExecutableDirective(Node); +} + +void StmtPrinter::VisitOMPTargetParallelForDirective( + OMPTargetParallelForDirective *Node) { + Indent() << "#pragma omp target parallel for "; + PrintOMPExecutableDirective(Node); +} + void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) { Indent() << "#pragma omp teams "; PrintOMPExecutableDirective(Node); @@ -1085,11 +1168,45 @@ void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) { PrintOMPExecutableDirective(Node); } +void StmtPrinter::VisitOMPTargetUpdateDirective( + OMPTargetUpdateDirective *Node) { + Indent() << "#pragma omp target update "; + PrintOMPExecutableDirective(Node); +} + +void StmtPrinter::VisitOMPDistributeParallelForDirective( + OMPDistributeParallelForDirective *Node) { + Indent() << "#pragma omp distribute parallel for "; + PrintOMPExecutableDirective(Node); +} + +void StmtPrinter::VisitOMPDistributeParallelForSimdDirective( + OMPDistributeParallelForSimdDirective *Node) { + Indent() << "#pragma omp distribute parallel for simd "; + PrintOMPExecutableDirective(Node); +} + +void StmtPrinter::VisitOMPDistributeSimdDirective( + OMPDistributeSimdDirective *Node) { + Indent() << "#pragma omp distribute simd "; + PrintOMPExecutableDirective(Node); +} + +void StmtPrinter::VisitOMPTargetParallelForSimdDirective( + OMPTargetParallelForSimdDirective *Node) { + Indent() << "#pragma omp target parallel for simd "; + PrintOMPExecutableDirective(Node); +} + //===----------------------------------------------------------------------===// // Expr printing methods. //===----------------------------------------------------------------------===// void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { + if (auto *OCED = dyn_cast<OMPCapturedExprDecl>(Node->getDecl())) { + OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy); + return; + } if (NestedNameSpecifier *Qualifier = Node->getQualifier()) Qualifier->print(OS, Policy); if (Node->hasTemplateKeyword()) @@ -1097,7 +1214,7 @@ void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { OS << Node->getNameInfo(); if (Node->hasExplicitTemplateArgs()) TemplateSpecializationType::PrintTemplateArgumentList( - OS, Node->getTemplateArgs(), Node->getNumTemplateArgs(), Policy); + OS, Node->template_arguments(), Policy); } void StmtPrinter::VisitDependentScopeDeclRefExpr( @@ -1109,7 +1226,7 @@ void StmtPrinter::VisitDependentScopeDeclRefExpr( OS << Node->getNameInfo(); if (Node->hasExplicitTemplateArgs()) TemplateSpecializationType::PrintTemplateArgumentList( - OS, Node->getTemplateArgs(), Node->getNumTemplateArgs(), Policy); + OS, Node->template_arguments(), Policy); } void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) { @@ -1120,7 +1237,7 @@ void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) { OS << Node->getNameInfo(); if (Node->hasExplicitTemplateArgs()) TemplateSpecializationType::PrintTemplateArgumentList( - OS, Node->getTemplateArgs(), Node->getNumTemplateArgs(), Policy); + OS, Node->template_arguments(), Policy); } void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { @@ -1204,6 +1321,12 @@ void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) { OS << "'\\v'"; break; default: + // A character literal might be sign-extended, which + // would result in an invalid \U escape sequence. + // FIXME: multicharacter literals such as '\xFF\xFF\xFF\xFF' + // are not correctly handled. + if ((value & ~0xFFu) == ~0xFFu && Node->getKind() == CharacterLiteral::Ascii) + value &= 0xFFu; if (value < 256 && isPrintable((unsigned char)value)) OS << "'" << (char)value << "'"; else if (value < 256) @@ -1254,6 +1377,7 @@ static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node, case BuiltinType::Double: break; // no suffix. case BuiltinType::Float: OS << 'F'; break; case BuiltinType::LongDouble: OS << 'L'; break; + case BuiltinType::Float128: OS << 'Q'; break; } } @@ -1340,9 +1464,9 @@ void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node){ OS << "sizeof"; break; case UETT_AlignOf: - if (Policy.LangOpts.CPlusPlus) + if (Policy.Alignof) OS << "alignof"; - else if (Policy.LangOpts.C11) + else if (Policy.UnderscoreAlignof) OS << "_Alignof"; else OS << "__alignof"; @@ -1440,7 +1564,7 @@ void StmtPrinter::VisitMemberExpr(MemberExpr *Node) { OS << Node->getMemberNameInfo(); if (Node->hasExplicitTemplateArgs()) TemplateSpecializationType::PrintTemplateArgumentList( - OS, Node->getTemplateArgs(), Node->getNumTemplateArgs(), Policy); + OS, Node->template_arguments(), Policy); } void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) { PrintExpr(Node->getBase()); @@ -1563,26 +1687,24 @@ void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) { void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) { bool NeedsEquals = true; - for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(), - DEnd = Node->designators_end(); - D != DEnd; ++D) { - if (D->isFieldDesignator()) { - if (D->getDotLoc().isInvalid()) { - if (IdentifierInfo *II = D->getFieldName()) { + for (const DesignatedInitExpr::Designator &D : Node->designators()) { + if (D.isFieldDesignator()) { + if (D.getDotLoc().isInvalid()) { + if (IdentifierInfo *II = D.getFieldName()) { OS << II->getName() << ":"; NeedsEquals = false; } } else { - OS << "." << D->getFieldName()->getName(); + OS << "." << D.getFieldName()->getName(); } } else { OS << "["; - if (D->isArrayDesignator()) { - PrintExpr(Node->getArrayIndex(*D)); + if (D.isArrayDesignator()) { + PrintExpr(Node->getArrayIndex(D)); } else { - PrintExpr(Node->getArrayRangeStart(*D)); + PrintExpr(Node->getArrayRangeStart(D)); OS << " ... "; - PrintExpr(Node->getArrayRangeEnd(*D)); + PrintExpr(Node->getArrayRangeEnd(D)); } OS << "]"; } @@ -1612,7 +1734,7 @@ void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) { } void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) { - if (Policy.LangOpts.CPlusPlus) { + if (Node->getType()->getAsCXXRecordDecl()) { OS << "/*implicit*/"; Node->getType().print(OS, Policy); OS << "()"; @@ -1822,7 +1944,7 @@ void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) { if (Args->size() != 1) { OS << "operator\"\"" << Node->getUDSuffix()->getName(); TemplateSpecializationType::PrintTemplateArgumentList( - OS, Args->data(), Args->size(), Policy); + OS, Args->asArray(), Policy); OS << "()"; return; } @@ -1952,7 +2074,9 @@ void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) { case LCK_This: OS << "this"; break; - + case LCK_StarThis: + OS << "*this"; + break; case LCK_ByRef: if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C)) OS << '&'; @@ -1975,7 +2099,7 @@ void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) { OS << " ("; CXXMethodDecl *Method = Node->getCallOperator(); NeedComma = false; - for (auto P : Method->params()) { + for (auto P : Method->parameters()) { if (NeedComma) { OS << ", "; } else { @@ -2103,6 +2227,11 @@ void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) { OS << "}"; } +void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) { + // Parens are printed by the surrounding context. + OS << "<forwarded>"; +} + void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { PrintExpr(E->getSubExpr()); } @@ -2140,7 +2269,7 @@ void StmtPrinter::VisitCXXDependentScopeMemberExpr( OS << Node->getMemberNameInfo(); if (Node->hasExplicitTemplateArgs()) TemplateSpecializationType::PrintTemplateArgumentList( - OS, Node->getTemplateArgs(), Node->getNumTemplateArgs(), Policy); + OS, Node->template_arguments(), Policy); } void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) { @@ -2155,7 +2284,7 @@ void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) { OS << Node->getMemberNameInfo(); if (Node->hasExplicitTemplateArgs()) TemplateSpecializationType::PrintTemplateArgumentList( - OS, Node->getTemplateArgs(), Node->getNumTemplateArgs(), Policy); + OS, Node->template_arguments(), Policy); } static const char *getTypeTraitName(TypeTrait TT) { @@ -2424,7 +2553,7 @@ void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) { void StmtPrinter::VisitTypoExpr(TypoExpr *Node) { // TODO: Print something reasonable for a TypoExpr, if necessary. - assert(false && "Cannot print TypoExpr nodes"); + llvm_unreachable("Cannot print TypoExpr nodes"); } void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) { diff --git a/contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp b/contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp index 175a43a..0a39413 100644 --- a/contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp +++ b/contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp @@ -69,6 +69,7 @@ namespace { } void StmtProfiler::VisitStmt(const Stmt *S) { + assert(S && "Requires non-null Stmt pointer"); ID.AddInteger(S->getStmtClass()); for (const Stmt *SubStmt : S->children()) { if (SubStmt) @@ -268,8 +269,23 @@ public: #define OPENMP_CLAUSE(Name, Class) \ void Visit##Class(const Class *C); #include "clang/Basic/OpenMPKinds.def" + void VistOMPClauseWithPreInit(const OMPClauseWithPreInit *C); + void VistOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C); }; +void OMPClauseProfiler::VistOMPClauseWithPreInit( + const OMPClauseWithPreInit *C) { + if (auto *S = C->getPreInitStmt()) + Profiler->VisitStmt(S); +} + +void OMPClauseProfiler::VistOMPClauseWithPostUpdate( + const OMPClauseWithPostUpdate *C) { + VistOMPClauseWithPreInit(C); + if (auto *E = C->getPostUpdateExpr()) + Profiler->VisitStmt(E); +} + void OMPClauseProfiler::VisitOMPIfClause(const OMPIfClause *C) { if (C->getCondition()) Profiler->VisitStmt(C->getCondition()); @@ -305,12 +321,9 @@ void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { } void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { } void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) { - if (C->getChunkSize()) { - Profiler->VisitStmt(C->getChunkSize()); - if (C->getHelperChunkSize()) { - Profiler->VisitStmt(C->getChunkSize()); - } - } + VistOMPClauseWithPreInit(C); + if (auto *S = C->getChunkSize()) + Profiler->VisitStmt(S); } void OMPClauseProfiler::VisitOMPOrderedClause(const OMPOrderedClause *C) { @@ -343,37 +356,46 @@ void OMPClauseProfiler::VisitOMPNogroupClause(const OMPNogroupClause *) {} template<typename T> void OMPClauseProfiler::VisitOMPClauseList(T *Node) { for (auto *E : Node->varlists()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } } void OMPClauseProfiler::VisitOMPPrivateClause(const OMPPrivateClause *C) { VisitOMPClauseList(C); for (auto *E : C->private_copies()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } } void OMPClauseProfiler::VisitOMPFirstprivateClause(const OMPFirstprivateClause *C) { VisitOMPClauseList(C); + VistOMPClauseWithPreInit(C); for (auto *E : C->private_copies()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } for (auto *E : C->inits()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } } void OMPClauseProfiler::VisitOMPLastprivateClause(const OMPLastprivateClause *C) { VisitOMPClauseList(C); + VistOMPClauseWithPostUpdate(C); for (auto *E : C->source_exprs()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } for (auto *E : C->destination_exprs()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } for (auto *E : C->assignment_ops()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } } void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause *C) { @@ -385,63 +407,82 @@ void OMPClauseProfiler::VisitOMPReductionClause( C->getQualifierLoc().getNestedNameSpecifier()); Profiler->VisitName(C->getNameInfo().getName()); VisitOMPClauseList(C); + VistOMPClauseWithPostUpdate(C); for (auto *E : C->privates()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } for (auto *E : C->lhs_exprs()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } for (auto *E : C->rhs_exprs()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } for (auto *E : C->reduction_ops()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } } void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) { VisitOMPClauseList(C); + VistOMPClauseWithPostUpdate(C); for (auto *E : C->privates()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } for (auto *E : C->inits()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } for (auto *E : C->updates()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } for (auto *E : C->finals()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } - Profiler->VisitStmt(C->getStep()); - Profiler->VisitStmt(C->getCalcStep()); + if (C->getStep()) + Profiler->VisitStmt(C->getStep()); + if (C->getCalcStep()) + Profiler->VisitStmt(C->getCalcStep()); } void OMPClauseProfiler::VisitOMPAlignedClause(const OMPAlignedClause *C) { VisitOMPClauseList(C); - Profiler->VisitStmt(C->getAlignment()); + if (C->getAlignment()) + Profiler->VisitStmt(C->getAlignment()); } void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) { VisitOMPClauseList(C); for (auto *E : C->source_exprs()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } for (auto *E : C->destination_exprs()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } for (auto *E : C->assignment_ops()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } } void OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) { VisitOMPClauseList(C); for (auto *E : C->source_exprs()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } for (auto *E : C->destination_exprs()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } for (auto *E : C->assignment_ops()) { - Profiler->VisitStmt(E); + if (E) + Profiler->VisitStmt(E); } } void OMPClauseProfiler::VisitOMPFlushClause(const OMPFlushClause *C) { @@ -451,29 +492,50 @@ void OMPClauseProfiler::VisitOMPDependClause(const OMPDependClause *C) { VisitOMPClauseList(C); } void OMPClauseProfiler::VisitOMPDeviceClause(const OMPDeviceClause *C) { - Profiler->VisitStmt(C->getDevice()); + if (C->getDevice()) + Profiler->VisitStmt(C->getDevice()); } void OMPClauseProfiler::VisitOMPMapClause(const OMPMapClause *C) { VisitOMPClauseList(C); } void OMPClauseProfiler::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) { - Profiler->VisitStmt(C->getNumTeams()); + if (C->getNumTeams()) + Profiler->VisitStmt(C->getNumTeams()); } void OMPClauseProfiler::VisitOMPThreadLimitClause( const OMPThreadLimitClause *C) { - Profiler->VisitStmt(C->getThreadLimit()); + if (C->getThreadLimit()) + Profiler->VisitStmt(C->getThreadLimit()); } void OMPClauseProfiler::VisitOMPPriorityClause(const OMPPriorityClause *C) { - Profiler->VisitStmt(C->getPriority()); + if (C->getPriority()) + Profiler->VisitStmt(C->getPriority()); } void OMPClauseProfiler::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) { - Profiler->VisitStmt(C->getGrainsize()); + if (C->getGrainsize()) + Profiler->VisitStmt(C->getGrainsize()); } void OMPClauseProfiler::VisitOMPNumTasksClause(const OMPNumTasksClause *C) { - Profiler->VisitStmt(C->getNumTasks()); + if (C->getNumTasks()) + Profiler->VisitStmt(C->getNumTasks()); } void OMPClauseProfiler::VisitOMPHintClause(const OMPHintClause *C) { - Profiler->VisitStmt(C->getHint()); + if (C->getHint()) + Profiler->VisitStmt(C->getHint()); +} +void OMPClauseProfiler::VisitOMPToClause(const OMPToClause *C) { + VisitOMPClauseList(C); +} +void OMPClauseProfiler::VisitOMPFromClause(const OMPFromClause *C) { + VisitOMPClauseList(C); +} +void OMPClauseProfiler::VisitOMPUseDevicePtrClause( + const OMPUseDevicePtrClause *C) { + VisitOMPClauseList(C); +} +void OMPClauseProfiler::VisitOMPIsDevicePtrClause( + const OMPIsDevicePtrClause *C) { + VisitOMPClauseList(C); } } @@ -584,6 +646,26 @@ void StmtProfiler::VisitOMPTargetDataDirective(const OMPTargetDataDirective *S) VisitOMPExecutableDirective(S); } +void StmtProfiler::VisitOMPTargetEnterDataDirective( + const OMPTargetEnterDataDirective *S) { + VisitOMPExecutableDirective(S); +} + +void StmtProfiler::VisitOMPTargetExitDataDirective( + const OMPTargetExitDataDirective *S) { + VisitOMPExecutableDirective(S); +} + +void StmtProfiler::VisitOMPTargetParallelDirective( + const OMPTargetParallelDirective *S) { + VisitOMPExecutableDirective(S); +} + +void StmtProfiler::VisitOMPTargetParallelForDirective( + const OMPTargetParallelForDirective *S) { + VisitOMPExecutableDirective(S); +} + void StmtProfiler::VisitOMPTeamsDirective(const OMPTeamsDirective *S) { VisitOMPExecutableDirective(S); } @@ -611,6 +693,40 @@ void StmtProfiler::VisitOMPDistributeDirective( VisitOMPLoopDirective(S); } +void OMPClauseProfiler::VisitOMPDistScheduleClause( + const OMPDistScheduleClause *C) { + VistOMPClauseWithPreInit(C); + if (auto *S = C->getChunkSize()) + Profiler->VisitStmt(S); +} + +void OMPClauseProfiler::VisitOMPDefaultmapClause(const OMPDefaultmapClause *) {} + +void StmtProfiler::VisitOMPTargetUpdateDirective( + const OMPTargetUpdateDirective *S) { + VisitOMPExecutableDirective(S); +} + +void StmtProfiler::VisitOMPDistributeParallelForDirective( + const OMPDistributeParallelForDirective *S) { + VisitOMPLoopDirective(S); +} + +void StmtProfiler::VisitOMPDistributeParallelForSimdDirective( + const OMPDistributeParallelForSimdDirective *S) { + VisitOMPLoopDirective(S); +} + +void StmtProfiler::VisitOMPDistributeSimdDirective( + const OMPDistributeSimdDirective *S) { + VisitOMPLoopDirective(S); +} + +void StmtProfiler::VisitOMPTargetParallelForSimdDirective( + const OMPTargetParallelForSimdDirective *S) { + VisitOMPLoopDirective(S); +} + void StmtProfiler::VisitExpr(const Expr *S) { VisitStmt(S); } @@ -810,22 +926,20 @@ void StmtProfiler::VisitInitListExpr(const InitListExpr *S) { void StmtProfiler::VisitDesignatedInitExpr(const DesignatedInitExpr *S) { VisitExpr(S); ID.AddBoolean(S->usesGNUSyntax()); - for (DesignatedInitExpr::const_designators_iterator D = - S->designators_begin(), DEnd = S->designators_end(); - D != DEnd; ++D) { - if (D->isFieldDesignator()) { + for (const DesignatedInitExpr::Designator &D : S->designators()) { + if (D.isFieldDesignator()) { ID.AddInteger(0); - VisitName(D->getFieldName()); + VisitName(D.getFieldName()); continue; } - if (D->isArrayDesignator()) { + if (D.isArrayDesignator()) { ID.AddInteger(1); } else { - assert(D->isArrayRangeDesignator()); + assert(D.isArrayRangeDesignator()); ID.AddInteger(2); } - ID.AddInteger(D->getFirstExprIndex()); + ID.AddInteger(D.getFirstExprIndex()); } } @@ -1196,6 +1310,12 @@ void StmtProfiler::VisitCXXConstructExpr(const CXXConstructExpr *S) { ID.AddBoolean(S->isElidable()); } +void StmtProfiler::VisitCXXInheritedCtorInitExpr( + const CXXInheritedCtorInitExpr *S) { + VisitExpr(S); + VisitDecl(S->getConstructor()); +} + void StmtProfiler::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *S) { VisitExplicitCastExpr(S); } @@ -1213,6 +1333,7 @@ StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) { C != CEnd; ++C) { ID.AddInteger(C->getCaptureKind()); switch (C->getCaptureKind()) { + case LCK_StarThis: case LCK_This: break; case LCK_ByRef: @@ -1511,6 +1632,11 @@ void StmtProfiler::VisitObjCBridgedCastExpr(const ObjCBridgedCastExpr *S) { ID.AddBoolean(S->getBridgeKind()); } +void StmtProfiler::VisitObjCAvailabilityCheckExpr( + const ObjCAvailabilityCheckExpr *S) { + VisitExpr(S); +} + void StmtProfiler::VisitDecl(const Decl *D) { ID.AddInteger(D? D->getKind() : 0); diff --git a/contrib/llvm/tools/clang/lib/AST/TemplateBase.cpp b/contrib/llvm/tools/clang/lib/AST/TemplateBase.cpp index e9edb0d..b75ede8 100644 --- a/contrib/llvm/tools/clang/lib/AST/TemplateBase.cpp +++ b/contrib/llvm/tools/clang/lib/AST/TemplateBase.cpp @@ -415,6 +415,15 @@ void TemplateArgument::print(const PrintingPolicy &Policy, } } +void TemplateArgument::dump(raw_ostream &Out) const { + LangOptions LO; // FIXME! see also TemplateName::dump(). + LO.CPlusPlus = true; + LO.Bool = true; + print(PrintingPolicy(LO), Out); +} + +LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); } + //===----------------------------------------------------------------------===// // TemplateArgumentLoc Implementation //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/tools/clang/lib/AST/TemplateName.cpp b/contrib/llvm/tools/clang/lib/AST/TemplateName.cpp index 47e0255..47a7d47 100644 --- a/contrib/llvm/tools/clang/lib/AST/TemplateName.cpp +++ b/contrib/llvm/tools/clang/lib/AST/TemplateName.cpp @@ -227,6 +227,6 @@ void TemplateName::dump(raw_ostream &OS) const { print(OS, PrintingPolicy(LO)); } -void TemplateName::dump() const { +LLVM_DUMP_METHOD void TemplateName::dump() const { dump(llvm::errs()); } diff --git a/contrib/llvm/tools/clang/lib/AST/Type.cpp b/contrib/llvm/tools/clang/lib/AST/Type.cpp index b467dac..99b0247 100644 --- a/contrib/llvm/tools/clang/lib/AST/Type.cpp +++ b/contrib/llvm/tools/clang/lib/AST/Type.cpp @@ -64,7 +64,7 @@ const IdentifierInfo* QualType::getBaseTypeIdentifier() const { return nullptr; } -bool QualType::isConstant(QualType T, ASTContext &Ctx) { +bool QualType::isConstant(QualType T, const ASTContext &Ctx) { if (T.isConstQualified()) return true; @@ -74,7 +74,7 @@ bool QualType::isConstant(QualType T, ASTContext &Ctx) { return T.getAddressSpace() == LangAS::opencl_constant; } -unsigned ConstantArrayType::getNumAddressingBits(ASTContext &Context, +unsigned ConstantArrayType::getNumAddressingBits(const ASTContext &Context, QualType ElementType, const llvm::APInt &NumElements) { uint64_t ElementSize = Context.getTypeSizeInChars(ElementType).getQuantity(); @@ -109,7 +109,7 @@ unsigned ConstantArrayType::getNumAddressingBits(ASTContext &Context, return TotalSize.getActiveBits(); } -unsigned ConstantArrayType::getMaxSizeBits(ASTContext &Context) { +unsigned ConstantArrayType::getMaxSizeBits(const ASTContext &Context) { unsigned Bits = Context.getTypeSize(Context.getSizeType()); // Limit the number of bits in size_t so that maximal bit size fits 64 bit @@ -1274,6 +1274,12 @@ QualType QualType::stripObjCKindOfType(const ASTContext &constCtx) const { }); } +QualType QualType::getAtomicUnqualifiedType() const { + if (auto AT = getTypePtr()->getAs<AtomicType>()) + return AT->getValueType().getUnqualifiedType(); + return getUnqualifiedType(); +} + Optional<ArrayRef<QualType>> Type::getObjCSubstitutions( const DeclContext *dc) const { // Look through method scopes. @@ -1616,7 +1622,7 @@ bool Type::hasIntegerRepresentation() const { /// \param Ctx The context in which this type occurs. /// /// \returns true if the type is considered an integral type, false otherwise. -bool Type::isIntegralType(ASTContext &Ctx) const { +bool Type::isIntegralType(const ASTContext &Ctx) const { if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) return BT->getKind() >= BuiltinType::Bool && BT->getKind() <= BuiltinType::Int128; @@ -1777,7 +1783,7 @@ bool Type::hasUnsignedIntegerRepresentation() const { bool Type::isFloatingType() const { if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) return BT->getKind() >= BuiltinType::Half && - BT->getKind() <= BuiltinType::LongDouble; + BT->getKind() <= BuiltinType::Float128; if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType)) return CT->getElementType()->isFloatingType(); return false; @@ -1799,7 +1805,7 @@ bool Type::isRealFloatingType() const { bool Type::isRealType() const { if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) return BT->getKind() >= BuiltinType::Bool && - BT->getKind() <= BuiltinType::LongDouble; + BT->getKind() <= BuiltinType::Float128; if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped(); return false; @@ -1808,7 +1814,7 @@ bool Type::isRealType() const { bool Type::isArithmeticType() const { if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) return BT->getKind() >= BuiltinType::Bool && - BT->getKind() <= BuiltinType::LongDouble; + BT->getKind() <= BuiltinType::Float128; if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) // GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2). // If a body isn't seen by the time we get here, return false. @@ -1958,7 +1964,7 @@ bool Type::isIncompleteType(NamedDecl **Def) const { } } -bool QualType::isPODType(ASTContext &Context) const { +bool QualType::isPODType(const ASTContext &Context) const { // C++11 has a more relaxed definition of POD. if (Context.getLangOpts().CPlusPlus11) return isCXX11PODType(Context); @@ -1966,7 +1972,7 @@ bool QualType::isPODType(ASTContext &Context) const { return isCXX98PODType(Context); } -bool QualType::isCXX98PODType(ASTContext &Context) const { +bool QualType::isCXX98PODType(const ASTContext &Context) const { // The compiler shouldn't query this for incomplete types, but the user might. // We return false for that case. Except for incomplete arrays of PODs, which // are PODs according to the standard. @@ -2026,7 +2032,7 @@ bool QualType::isCXX98PODType(ASTContext &Context) const { } } -bool QualType::isTrivialType(ASTContext &Context) const { +bool QualType::isTrivialType(const ASTContext &Context) const { // The compiler shouldn't query this for incomplete types, but the user might. // We return false for that case. Except for incomplete arrays of PODs, which // are PODs according to the standard. @@ -2089,7 +2095,7 @@ bool QualType::isTrivialType(ASTContext &Context) const { return false; } -bool QualType::isTriviallyCopyableType(ASTContext &Context) const { +bool QualType::isTriviallyCopyableType(const ASTContext &Context) const { if ((*this)->isArrayType()) return Context.getBaseElementType(*this).isTriviallyCopyableType(Context); @@ -2249,7 +2255,7 @@ bool Type::isStandardLayoutType() const { // This is effectively the intersection of isTrivialType and // isStandardLayoutType. We implement it directly to avoid redundant // conversions from a type to a CXXRecordDecl. -bool QualType::isCXX11PODType(ASTContext &Context) const { +bool QualType::isCXX11PODType(const ASTContext &Context) const { const Type *ty = getTypePtr(); if (ty->isDependentType()) return false; @@ -2454,19 +2460,20 @@ StringRef TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) { DependentTemplateSpecializationType::DependentTemplateSpecializationType( ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, - unsigned NumArgs, const TemplateArgument *Args, + ArrayRef<TemplateArgument> Args, QualType Canon) : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true, true, /*VariablyModified=*/false, NNS && NNS->containsUnexpandedParameterPack()), - NNS(NNS), Name(Name), NumArgs(NumArgs) { + NNS(NNS), Name(Name), NumArgs(Args.size()) { assert((!NNS || NNS->isDependent()) && "DependentTemplateSpecializatonType requires dependent qualifier"); - for (unsigned I = 0; I != NumArgs; ++I) { - if (Args[I].containsUnexpandedParameterPack()) + TemplateArgument *ArgBuffer = getArgBuffer(); + for (const TemplateArgument &Arg : Args) { + if (Arg.containsUnexpandedParameterPack()) setContainsUnexpandedParameterPack(); - new (&getArgBuffer()[I]) TemplateArgument(Args[I]); + new (ArgBuffer++) TemplateArgument(Arg); } } @@ -2476,13 +2483,12 @@ DependentTemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword, NestedNameSpecifier *Qualifier, const IdentifierInfo *Name, - unsigned NumArgs, - const TemplateArgument *Args) { + ArrayRef<TemplateArgument> Args) { ID.AddInteger(Keyword); ID.AddPointer(Qualifier); ID.AddPointer(Name); - for (unsigned Idx = 0; Idx < NumArgs; ++Idx) - Args[Idx].Profile(ID, Context); + for (const TemplateArgument &Arg : Args) + Arg.Profile(ID, Context); } bool Type::isElaboratedTypeSpecifier() const { @@ -2552,6 +2558,8 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const { return "double"; case LongDouble: return "long double"; + case Float128: + return "__float128"; case WChar_S: case WChar_U: return Policy.MSWChar ? "__wchar_t" : "wchar_t"; @@ -2581,30 +2589,10 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const { return "Class"; case ObjCSel: return "SEL"; - case OCLImage1d: - return "image1d_t"; - case OCLImage1dArray: - return "image1d_array_t"; - case OCLImage1dBuffer: - return "image1d_buffer_t"; - case OCLImage2d: - return "image2d_t"; - case OCLImage2dArray: - return "image2d_array_t"; - case OCLImage2dDepth: - return "image2d_depth_t"; - case OCLImage2dArrayDepth: - return "image2d_array_depth_t"; - case OCLImage2dMSAA: - return "image2d_msaa_t"; - case OCLImage2dArrayMSAA: - return "image2d_array_msaa_t"; - case OCLImage2dMSAADepth: - return "image2d_msaa_depth_t"; - case OCLImage2dArrayMSAADepth: - return "image2d_array_msaa_depth_t"; - case OCLImage3d: - return "image3d_t"; +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case Id: \ + return "__" #Access " " #ImgType "_t"; +#include "clang/Basic/OpenCLImageTypes.def" case OCLSampler: return "sampler_t"; case OCLEvent: @@ -2654,7 +2642,10 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) { case CC_AAPCS_VFP: return "aapcs-vfp"; case CC_IntelOclBicc: return "intel_ocl_bicc"; case CC_SpirFunction: return "spir_function"; - case CC_SpirKernel: return "spir_kernel"; + case CC_OpenCLKernel: return "opencl_kernel"; + case CC_Swift: return "swiftcall"; + case CC_PreserveMost: return "preserve_most"; + case CC_PreserveAll: return "preserve_all"; } llvm_unreachable("Invalid calling convention."); @@ -2671,7 +2662,7 @@ FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> params, NumParams(params.size()), NumExceptions(epi.ExceptionSpec.Exceptions.size()), ExceptionSpecType(epi.ExceptionSpec.Type), - HasAnyConsumedParams(epi.ConsumedParameters != nullptr), + HasExtParameterInfos(epi.ExtParameterInfos != nullptr), Variadic(epi.Variadic), HasTrailingReturn(epi.HasTrailingReturn) { assert(NumParams == params.size() && "function has too many parameters"); @@ -2737,10 +2728,11 @@ FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> params, slot[0] = epi.ExceptionSpec.SourceDecl; } - if (epi.ConsumedParameters) { - bool *consumedParams = const_cast<bool *>(getConsumedParamsBuffer()); + if (epi.ExtParameterInfos) { + ExtParameterInfo *extParamInfos = + const_cast<ExtParameterInfo *>(getExtParameterInfosBuffer()); for (unsigned i = 0; i != NumParams; ++i) - consumedParams[i] = epi.ConsumedParameters[i]; + extParamInfos[i] = epi.ExtParameterInfos[i]; } } @@ -2860,9 +2852,9 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result, epi.ExceptionSpec.Type == EST_Unevaluated) { ID.AddPointer(epi.ExceptionSpec.SourceDecl->getCanonicalDecl()); } - if (epi.ConsumedParameters) { + if (epi.ExtParameterInfos) { for (unsigned i = 0; i != NumParams; ++i) - ID.AddBoolean(epi.ConsumedParameters[i]); + ID.AddInteger(epi.ExtParameterInfos[i].getOpaqueValue()); } epi.ExtInfo.Profile(ID); ID.AddBoolean(epi.HasTrailingReturn); @@ -2931,6 +2923,24 @@ void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID, E->Profile(ID, Context, true); } +UnaryTransformType::UnaryTransformType(QualType BaseType, + QualType UnderlyingType, + UTTKind UKind, + QualType CanonicalType) + : Type(UnaryTransform, CanonicalType, BaseType->isDependentType(), + BaseType->isInstantiationDependentType(), + BaseType->isVariablyModifiedType(), + BaseType->containsUnexpandedParameterPack()) + , BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind) +{} + +DependentUnaryTransformType::DependentUnaryTransformType(const ASTContext &C, + QualType BaseType, + UTTKind UKind) + : UnaryTransformType(BaseType, C.DependentTy, UKind, QualType()) +{} + + TagType::TagType(TypeClass TC, const TagDecl *D, QualType can) : Type(TC, can, D->isDependentType(), /*InstantiationDependent=*/D->isDependentType(), @@ -2947,17 +2957,6 @@ static TagDecl *getInterestingTagDecl(TagDecl *decl) { return decl; } -UnaryTransformType::UnaryTransformType(QualType BaseType, - QualType UnderlyingType, - UTTKind UKind, - QualType CanonicalType) - : Type(UnaryTransform, CanonicalType, UnderlyingType->isDependentType(), - UnderlyingType->isInstantiationDependentType(), - UnderlyingType->isVariablyModifiedType(), - BaseType->containsUnexpandedParameterPack()) - , BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind) -{} - TagDecl *TagType::getDecl() const { return getInterestingTagDecl(decl); } @@ -2994,8 +2993,11 @@ bool AttributedType::isQualifier() const { case AttributedType::attr_stdcall: case AttributedType::attr_thiscall: case AttributedType::attr_pascal: + case AttributedType::attr_swiftcall: case AttributedType::attr_vectorcall: case AttributedType::attr_inteloclbicc: + case AttributedType::attr_preserve_most: + case AttributedType::attr_preserve_all: case AttributedType::attr_ms_abi: case AttributedType::attr_sysv_abi: case AttributedType::attr_ptr32: @@ -3047,11 +3049,14 @@ bool AttributedType::isCallingConv() const { case attr_fastcall: case attr_stdcall: case attr_thiscall: + case attr_swiftcall: case attr_vectorcall: case attr_pascal: case attr_ms_abi: case attr_sysv_abi: case attr_inteloclbicc: + case attr_preserve_most: + case attr_preserve_all: return true; } llvm_unreachable("invalid attr kind"); @@ -3095,20 +3100,20 @@ void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID, bool TemplateSpecializationType:: anyDependentTemplateArguments(const TemplateArgumentListInfo &Args, bool &InstantiationDependent) { - return anyDependentTemplateArguments(Args.getArgumentArray(), Args.size(), + return anyDependentTemplateArguments(Args.arguments(), InstantiationDependent); } bool TemplateSpecializationType:: -anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N, +anyDependentTemplateArguments(ArrayRef<TemplateArgumentLoc> Args, bool &InstantiationDependent) { - for (unsigned i = 0; i != N; ++i) { - if (Args[i].getArgument().isDependent()) { + for (const TemplateArgumentLoc &ArgLoc : Args) { + if (ArgLoc.getArgument().isDependent()) { InstantiationDependent = true; return true; } - - if (Args[i].getArgument().isInstantiationDependent()) + + if (ArgLoc.getArgument().isInstantiationDependent()) InstantiationDependent = true; } return false; @@ -3116,7 +3121,7 @@ anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N, TemplateSpecializationType:: TemplateSpecializationType(TemplateName T, - const TemplateArgument *Args, unsigned NumArgs, + ArrayRef<TemplateArgument> Args, QualType Canon, QualType AliasedType) : Type(TemplateSpecialization, Canon.isNull()? QualType(this, 0) : Canon, @@ -3124,7 +3129,7 @@ TemplateSpecializationType(TemplateName T, Canon.isNull()? true : Canon->isInstantiationDependentType(), false, T.containsUnexpandedParameterPack()), - Template(T), NumArgs(NumArgs), TypeAlias(!AliasedType.isNull()) { + Template(T), NumArgs(Args.size()), TypeAlias(!AliasedType.isNull()) { assert(!T.getAsDependentTemplateName() && "Use DependentTemplateSpecializationType for dependent template-name"); assert((T.getKind() == TemplateName::Template || @@ -3134,7 +3139,7 @@ TemplateSpecializationType(TemplateName T, TemplateArgument *TemplateArgs = reinterpret_cast<TemplateArgument *>(this + 1); - for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { + for (const TemplateArgument &Arg : Args) { // Update instantiation-dependent and variably-modified bits. // If the canonical type exists and is non-dependent, the template // specialization type can be non-dependent even if one of the type @@ -3143,14 +3148,14 @@ TemplateSpecializationType(TemplateName T, // U<T> is always non-dependent, irrespective of the type T. // However, U<Ts> contains an unexpanded parameter pack, even though // its expansion (and thus its desugared type) doesn't. - if (Args[Arg].isInstantiationDependent()) + if (Arg.isInstantiationDependent()) setInstantiationDependent(); - if (Args[Arg].getKind() == TemplateArgument::Type && - Args[Arg].getAsType()->isVariablyModifiedType()) + if (Arg.getKind() == TemplateArgument::Type && + Arg.getAsType()->isVariablyModifiedType()) setVariablyModified(); - if (Args[Arg].containsUnexpandedParameterPack()) + if (Arg.containsUnexpandedParameterPack()) setContainsUnexpandedParameterPack(); - new (&TemplateArgs[Arg]) TemplateArgument(Args[Arg]); + new (TemplateArgs++) TemplateArgument(Arg); } // Store the aliased type if this is a type alias template specialization. @@ -3163,12 +3168,11 @@ TemplateSpecializationType(TemplateName T, void TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID, TemplateName T, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef<TemplateArgument> Args, const ASTContext &Context) { T.Profile(ID); - for (unsigned Idx = 0; Idx < NumArgs; ++Idx) - Args[Idx].Profile(ID, Context); + for (const TemplateArgument &Arg : Args) + Arg.Profile(ID, Context); } QualType @@ -3561,18 +3565,9 @@ bool Type::canHaveNullability() const { case BuiltinType::ObjCId: case BuiltinType::ObjCClass: case BuiltinType::ObjCSel: - case BuiltinType::OCLImage1d: - case BuiltinType::OCLImage1dArray: - case BuiltinType::OCLImage1dBuffer: - case BuiltinType::OCLImage2d: - case BuiltinType::OCLImage2dArray: - case BuiltinType::OCLImage2dDepth: - case BuiltinType::OCLImage2dArrayDepth: - case BuiltinType::OCLImage2dMSAA: - case BuiltinType::OCLImage2dArrayMSAA: - case BuiltinType::OCLImage2dMSAADepth: - case BuiltinType::OCLImage2dArrayMSAADepth: - case BuiltinType::OCLImage3d: +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/Basic/OpenCLImageTypes.def" case BuiltinType::OCLSampler: case BuiltinType::OCLEvent: case BuiltinType::OCLClkEvent: diff --git a/contrib/llvm/tools/clang/lib/AST/TypeLoc.cpp b/contrib/llvm/tools/clang/lib/AST/TypeLoc.cpp index d08b07b..78947d1 100644 --- a/contrib/llvm/tools/clang/lib/AST/TypeLoc.cpp +++ b/contrib/llvm/tools/clang/lib/AST/TypeLoc.cpp @@ -80,11 +80,11 @@ unsigned TypeLoc::getFullDataSizeForType(QualType Ty) { while (!TyLoc.isNull()) { unsigned Align = getLocalAlignmentForType(TyLoc.getType()); MaxAlign = std::max(Align, MaxAlign); - Total = llvm::RoundUpToAlignment(Total, Align); + Total = llvm::alignTo(Total, Align); Total += TypeSizer().Visit(TyLoc); TyLoc = TyLoc.getNextTypeLoc(); } - Total = llvm::RoundUpToAlignment(Total, MaxAlign); + Total = llvm::alignTo(Total, MaxAlign); return Total; } @@ -149,12 +149,12 @@ void TypeLoc::copy(TypeLoc other) { // If both data pointers are aligned to the maximum alignment, we // can memcpy because getFullDataSize() accurately reflects the // layout of the data. - if (reinterpret_cast<uintptr_t>(Data) - == llvm::RoundUpToAlignment(reinterpret_cast<uintptr_t>(Data), - TypeLocMaxDataAlign) && - reinterpret_cast<uintptr_t>(other.Data) - == llvm::RoundUpToAlignment(reinterpret_cast<uintptr_t>(other.Data), - TypeLocMaxDataAlign)) { + if (reinterpret_cast<uintptr_t>(Data) == + llvm::alignTo(reinterpret_cast<uintptr_t>(Data), + TypeLocMaxDataAlign) && + reinterpret_cast<uintptr_t>(other.Data) == + llvm::alignTo(reinterpret_cast<uintptr_t>(other.Data), + TypeLocMaxDataAlign)) { memcpy(Data, other.Data, getFullDataSize()); return; } @@ -320,6 +320,7 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const { case BuiltinType::Float: case BuiltinType::Double: case BuiltinType::LongDouble: + case BuiltinType::Float128: llvm_unreachable("Builtin type needs extra local data!"); // Fall through, if the impossible happens. @@ -333,18 +334,9 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const { case BuiltinType::ObjCId: case BuiltinType::ObjCClass: case BuiltinType::ObjCSel: - case BuiltinType::OCLImage1d: - case BuiltinType::OCLImage1dArray: - case BuiltinType::OCLImage1dBuffer: - case BuiltinType::OCLImage2d: - case BuiltinType::OCLImage2dArray: - case BuiltinType::OCLImage2dDepth: - case BuiltinType::OCLImage2dArrayDepth: - case BuiltinType::OCLImage2dMSAA: - case BuiltinType::OCLImage2dArrayMSAA: - case BuiltinType::OCLImage2dMSAADepth: - case BuiltinType::OCLImage2dArrayMSAADepth: - case BuiltinType::OCLImage3d: +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/Basic/OpenCLImageTypes.def" case BuiltinType::OCLSampler: case BuiltinType::OCLEvent: case BuiltinType::OCLClkEvent: diff --git a/contrib/llvm/tools/clang/lib/AST/TypePrinter.cpp b/contrib/llvm/tools/clang/lib/AST/TypePrinter.cpp index b202523..065a2db 100644 --- a/contrib/llvm/tools/clang/lib/AST/TypePrinter.cpp +++ b/contrib/llvm/tools/clang/lib/AST/TypePrinter.cpp @@ -81,12 +81,14 @@ namespace { class TypePrinter { PrintingPolicy Policy; + unsigned Indentation; bool HasEmptyPlaceHolder; bool InsideCCAttribute; public: - explicit TypePrinter(const PrintingPolicy &Policy) - : Policy(Policy), HasEmptyPlaceHolder(false), InsideCCAttribute(false) { } + explicit TypePrinter(const PrintingPolicy &Policy, unsigned Indentation = 0) + : Policy(Policy), Indentation(Indentation), + HasEmptyPlaceHolder(false), InsideCCAttribute(false) { } void print(const Type *ty, Qualifiers qs, raw_ostream &OS, StringRef PlaceHolder); @@ -110,7 +112,8 @@ namespace { }; } -static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals, bool C99) { +static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals, + bool HasRestrictKeyword) { bool appendSpace = false; if (TypeQuals & Qualifiers::Const) { OS << "const"; @@ -123,7 +126,7 @@ static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals, bool C99) { } if (TypeQuals & Qualifiers::Restrict) { if (appendSpace) OS << ' '; - if (C99) { + if (HasRestrictKeyword) { OS << "restrict"; } else { OS << "__restrict"; @@ -411,7 +414,7 @@ void TypePrinter::printMemberPointerBefore(const MemberPointerType *T, OS << '('; PrintingPolicy InnerPolicy(Policy); - InnerPolicy.SuppressTag = false; + InnerPolicy.IncludeTagDefinition = false; TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef()); OS << "::*"; @@ -437,7 +440,8 @@ void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T, raw_ostream &OS) { OS << '['; if (T->getIndexTypeQualifiers().hasQualifiers()) { - AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.LangOpts.C99); + AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), + Policy.Restrict); OS << ' '; } @@ -470,7 +474,7 @@ void TypePrinter::printVariableArrayAfter(const VariableArrayType *T, raw_ostream &OS) { OS << '['; if (T->getIndexTypeQualifiers().hasQualifiers()) { - AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.LangOpts.C99); + AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.Restrict); OS << ' '; } @@ -629,6 +633,20 @@ void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T, } } +llvm::StringRef clang::getParameterABISpelling(ParameterABI ABI) { + switch (ABI) { + case ParameterABI::Ordinary: + llvm_unreachable("asking for spelling of ordinary parameter ABI"); + case ParameterABI::SwiftContext: + return "swift_context"; + case ParameterABI::SwiftErrorResult: + return "swift_error_result"; + case ParameterABI::SwiftIndirectResult: + return "swift_indirect_result"; + } + llvm_unreachable("bad parameter ABI kind"); +} + void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T, raw_ostream &OS) { // If needed for precedence reasons, wrap the inner part in grouping parens. @@ -641,6 +659,13 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T, ParamPolicyRAII ParamPolicy(Policy); for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) { if (i) OS << ", "; + + auto EPI = T->getExtParameterInfo(i); + if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) "; + auto ABI = EPI.getABI(); + if (ABI != ParameterABI::Ordinary) + OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) "; + print(T->getParamType(i), OS, StringRef()); } } @@ -649,7 +674,7 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T, if (T->getNumParams()) OS << ", "; OS << "..."; - } else if (T->getNumParams() == 0 && !Policy.LangOpts.CPlusPlus) { + } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) { // Do not emit int() if we have a proto, emit 'int(void)'. OS << "void"; } @@ -700,9 +725,18 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T, OS << " __attribute__((sysv_abi))"; break; case CC_SpirFunction: - case CC_SpirKernel: + case CC_OpenCLKernel: // Do nothing. These CCs are not available as attributes. break; + case CC_Swift: + OS << " __attribute__((swiftcall))"; + break; + case CC_PreserveMost: + OS << " __attribute__((preserve_most))"; + break; + case CC_PreserveAll: + OS << " __attribute__((preserve_all))"; + break; } } @@ -714,7 +748,7 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T, if (unsigned quals = T->getTypeQuals()) { OS << ' '; - AppendTypeQualList(OS, quals, Policy.LangOpts.C99); + AppendTypeQualList(OS, quals, Policy.Restrict); } switch (T->getRefQualifier()) { @@ -863,7 +897,8 @@ void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) { } void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) { IncludeStrongLifetimeRAII Strong(Policy); - OS << "pipe"; + OS << "pipe "; + print(T->getElementType(), OS, StringRef()); spaceBeforePlaceHolder(OS); } @@ -888,10 +923,8 @@ void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) { IncludeStrongLifetimeRAII Strong(Policy); OS << Spec->getIdentifier()->getName(); const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); - TemplateSpecializationType::PrintTemplateArgumentList(OS, - TemplateArgs.data(), - TemplateArgs.size(), - Policy); + TemplateSpecializationType::PrintTemplateArgumentList( + OS, TemplateArgs.asArray(), Policy); OS << "::"; } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) { if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl()) @@ -904,18 +937,19 @@ void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) { } void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) { - if (Policy.SuppressTag) + if (Policy.IncludeTagDefinition) { + PrintingPolicy SubPolicy = Policy; + SubPolicy.IncludeTagDefinition = false; + D->print(OS, SubPolicy, Indentation); + spaceBeforePlaceHolder(OS); return; + } bool HasKindDecoration = false; - // bool SuppressTagKeyword - // = Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword; - // We don't print tags unless this is an elaborated type. // In C, we just assume every RecordType is an elaborated type. - if (!(Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword || - D->getTypedefNameForAnonDecl())) { + if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) { HasKindDecoration = true; OS << D->getKindName(); OS << ' '; @@ -967,22 +1001,17 @@ void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) { // arguments. if (ClassTemplateSpecializationDecl *Spec = dyn_cast<ClassTemplateSpecializationDecl>(D)) { - const TemplateArgument *Args; - unsigned NumArgs; + ArrayRef<TemplateArgument> Args; if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) { const TemplateSpecializationType *TST = cast<TemplateSpecializationType>(TAW->getType()); - Args = TST->getArgs(); - NumArgs = TST->getNumArgs(); + Args = TST->template_arguments(); } else { const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); - Args = TemplateArgs.data(); - NumArgs = TemplateArgs.size(); + Args = TemplateArgs.asArray(); } IncludeStrongLifetimeRAII Strong(Policy); - TemplateSpecializationType::PrintTemplateArgumentList(OS, - Args, NumArgs, - Policy); + TemplateSpecializationType::PrintTemplateArgumentList(OS, Args, Policy); } spaceBeforePlaceHolder(OS); @@ -1040,11 +1069,9 @@ void TypePrinter::printTemplateSpecializationBefore( raw_ostream &OS) { IncludeStrongLifetimeRAII Strong(Policy); T->getTemplateName().print(OS, Policy); - - TemplateSpecializationType::PrintTemplateArgumentList(OS, - T->getArgs(), - T->getNumArgs(), - Policy); + + TemplateSpecializationType::PrintTemplateArgumentList( + OS, T->template_arguments(), Policy); spaceBeforePlaceHolder(OS); } void TypePrinter::printTemplateSpecializationAfter( @@ -1060,14 +1087,16 @@ void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T, void TypePrinter::printElaboratedBefore(const ElaboratedType *T, raw_ostream &OS) { - if (Policy.SuppressTag && isa<TagType>(T->getNamedType())) - return; - OS << TypeWithKeyword::getKeywordName(T->getKeyword()); - if (T->getKeyword() != ETK_None) - OS << " "; - NestedNameSpecifier* Qualifier = T->getQualifier(); - if (Qualifier) - Qualifier->print(OS, Policy); + // The tag definition will take care of these. + if (!Policy.IncludeTagDefinition) + { + OS << TypeWithKeyword::getKeywordName(T->getKeyword()); + if (T->getKeyword() != ETK_None) + OS << " "; + NestedNameSpecifier* Qualifier = T->getQualifier(); + if (Qualifier) + Qualifier->print(OS, Policy); + } ElaboratedTypePolicyRAII PolicyRAII(Policy); printBefore(T->getNamedType(), OS); @@ -1119,8 +1148,7 @@ void TypePrinter::printDependentTemplateSpecializationBefore( T->getQualifier()->print(OS, Policy); OS << T->getIdentifier()->getName(); TemplateSpecializationType::PrintTemplateArgumentList(OS, - T->getArgs(), - T->getNumArgs(), + T->template_arguments(), Policy); spaceBeforePlaceHolder(OS); } @@ -1305,6 +1333,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, case AttributedType::attr_fastcall: OS << "fastcall"; break; case AttributedType::attr_stdcall: OS << "stdcall"; break; case AttributedType::attr_thiscall: OS << "thiscall"; break; + case AttributedType::attr_swiftcall: OS << "swiftcall"; break; case AttributedType::attr_vectorcall: OS << "vectorcall"; break; case AttributedType::attr_pascal: OS << "pascal"; break; case AttributedType::attr_ms_abi: OS << "ms_abi"; break; @@ -1321,6 +1350,12 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, break; } case AttributedType::attr_inteloclbicc: OS << "inteloclbicc"; break; + case AttributedType::attr_preserve_most: + OS << "preserve_most"; + break; + case AttributedType::attr_preserve_all: + OS << "preserve_all"; + break; } OS << "))"; } @@ -1400,50 +1435,46 @@ void TemplateSpecializationType:: const TemplateArgumentListInfo &Args, const PrintingPolicy &Policy) { return PrintTemplateArgumentList(OS, - Args.getArgumentArray(), - Args.size(), + Args.arguments(), Policy); } -void -TemplateSpecializationType::PrintTemplateArgumentList( - raw_ostream &OS, - const TemplateArgument *Args, - unsigned NumArgs, - const PrintingPolicy &Policy, - bool SkipBrackets) { +void TemplateSpecializationType::PrintTemplateArgumentList( + raw_ostream &OS, ArrayRef<TemplateArgument> Args, + const PrintingPolicy &Policy, bool SkipBrackets) { const char *Comma = Policy.MSVCFormatting ? "," : ", "; if (!SkipBrackets) OS << '<'; - + bool needSpace = false; - for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { + bool FirstArg = true; + for (const TemplateArgument &Arg : Args) { // Print the argument into a string. SmallString<128> Buf; llvm::raw_svector_ostream ArgOS(Buf); - if (Args[Arg].getKind() == TemplateArgument::Pack) { - if (Args[Arg].pack_size() && Arg > 0) + if (Arg.getKind() == TemplateArgument::Pack) { + if (Arg.pack_size() && !FirstArg) OS << Comma; PrintTemplateArgumentList(ArgOS, - Args[Arg].pack_begin(), - Args[Arg].pack_size(), + Arg.getPackAsArray(), Policy, true); } else { - if (Arg > 0) + if (!FirstArg) OS << Comma; - Args[Arg].print(Policy, ArgOS); + Arg.print(Policy, ArgOS); } StringRef ArgString = ArgOS.str(); // If this is the first argument and its string representation // begins with the global scope specifier ('::foo'), add a space // to avoid printing the diagraph '<:'. - if (!Arg && !ArgString.empty() && ArgString[0] == ':') + if (FirstArg && !ArgString.empty() && ArgString[0] == ':') OS << ' '; OS << ArgString; needSpace = (!ArgString.empty() && ArgString.back() == '>'); + FirstArg = false; } // If the last character of our string is '>', add another space to @@ -1459,40 +1490,41 @@ TemplateSpecializationType::PrintTemplateArgumentList( // Sadly, repeat all that with TemplateArgLoc. void TemplateSpecializationType:: PrintTemplateArgumentList(raw_ostream &OS, - const TemplateArgumentLoc *Args, unsigned NumArgs, + ArrayRef<TemplateArgumentLoc> Args, const PrintingPolicy &Policy) { OS << '<'; const char *Comma = Policy.MSVCFormatting ? "," : ", "; bool needSpace = false; - for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { - if (Arg > 0) + bool FirstArg = true; + for (const TemplateArgumentLoc &Arg : Args) { + if (!FirstArg) OS << Comma; - + // Print the argument into a string. SmallString<128> Buf; llvm::raw_svector_ostream ArgOS(Buf); - if (Args[Arg].getArgument().getKind() == TemplateArgument::Pack) { + if (Arg.getArgument().getKind() == TemplateArgument::Pack) { PrintTemplateArgumentList(ArgOS, - Args[Arg].getArgument().pack_begin(), - Args[Arg].getArgument().pack_size(), + Arg.getArgument().getPackAsArray(), Policy, true); } else { - Args[Arg].getArgument().print(Policy, ArgOS); + Arg.getArgument().print(Policy, ArgOS); } StringRef ArgString = ArgOS.str(); - + // If this is the first argument and its string representation // begins with the global scope specifier ('::foo'), add a space // to avoid printing the diagraph '<:'. - if (!Arg && !ArgString.empty() && ArgString[0] == ':') + if (FirstArg && !ArgString.empty() && ArgString[0] == ':') OS << ' '; OS << ArgString; needSpace = (!ArgString.empty() && ArgString.back() == '>'); + FirstArg = false; } - + // If the last character of our string is '>', add another space to // keep the two '>''s separate tokens. We don't *have* to do this in // C++0x, but it's still good hygiene. @@ -1543,7 +1575,13 @@ void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy, unsigned quals = getCVRQualifiers(); if (quals) { - AppendTypeQualList(OS, quals, Policy.LangOpts.C99); + AppendTypeQualList(OS, quals, Policy.Restrict); + addSpace = true; + } + if (hasUnaligned()) { + if (addSpace) + OS << ' '; + OS << "__unaligned"; addSpace = true; } if (unsigned addrspace = getAddressSpace()) { @@ -1617,11 +1655,11 @@ std::string QualType::getAsString(const Type *ty, Qualifiers qs) { void QualType::print(const Type *ty, Qualifiers qs, raw_ostream &OS, const PrintingPolicy &policy, - const Twine &PlaceHolder) { + const Twine &PlaceHolder, unsigned Indentation) { SmallString<128> PHBuf; StringRef PH = PlaceHolder.toStringRef(PHBuf); - TypePrinter(policy).print(ty, qs, OS, PH); + TypePrinter(policy, Indentation).print(ty, qs, OS, PH); } void QualType::getAsStringInternal(const Type *ty, Qualifiers qs, diff --git a/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp b/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp index bae0186..640fbf4 100644 --- a/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp +++ b/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp @@ -2416,7 +2416,7 @@ private: MethodVFTableLocationsTy MethodVFTableLocations; /// \brief Does this class have an RTTI component? - bool HasRTTIComponent; + bool HasRTTIComponent = false; /// MethodInfo - Contains information about a method in a vtable. /// (Used for computing 'this' pointer adjustment thunks. @@ -2545,12 +2545,13 @@ public: MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)), WhichVFPtr(*Which), Overriders(MostDerivedClass, CharUnits(), MostDerivedClass) { - // Only include the RTTI component if we know that we will provide a - // definition of the vftable. - HasRTTIComponent = Context.getLangOpts().RTTIData && - !MostDerivedClass->hasAttr<DLLImportAttr>() && - MostDerivedClass->getTemplateSpecializationKind() != - TSK_ExplicitInstantiationDeclaration; + // Provide the RTTI component if RTTIData is enabled. If the vftable would + // be available externally, we should not provide the RTTI componenent. It + // is currently impossible to get available externally vftables with either + // dllimport or extern template instantiations, but eventually we may add a + // flag to support additional devirtualization that needs this. + if (Context.getLangOpts().RTTIData) + HasRTTIComponent = true; LayoutVFTable(); |