aboutsummaryrefslogtreecommitdiff
path: root/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST')
-rw-r--r--lib/AST/APValue.cpp2
-rw-r--r--lib/AST/ASTConsumer.cpp1
-rw-r--r--lib/AST/ASTContext.cpp501
-rw-r--r--lib/AST/ASTDiagnostic.cpp50
-rw-r--r--lib/AST/ASTDumper.cpp163
-rw-r--r--lib/AST/ASTImporter.cpp915
-rw-r--r--lib/AST/ASTTypeTraits.cpp8
-rw-r--r--lib/AST/CXXInheritance.cpp15
-rw-r--r--lib/AST/Comment.cpp6
-rw-r--r--lib/AST/CommentLexer.cpp16
-rw-r--r--lib/AST/CommentSema.cpp11
-rw-r--r--lib/AST/Decl.cpp165
-rw-r--r--lib/AST/DeclBase.cpp68
-rw-r--r--lib/AST/DeclCXX.cpp240
-rw-r--r--lib/AST/DeclObjC.cpp115
-rw-r--r--lib/AST/DeclOpenMP.cpp50
-rw-r--r--lib/AST/DeclPrinter.cpp86
-rw-r--r--lib/AST/DeclTemplate.cpp285
-rw-r--r--lib/AST/DeclarationName.cpp79
-rw-r--r--lib/AST/Expr.cpp266
-rw-r--r--lib/AST/ExprCXX.cpp124
-rw-r--r--lib/AST/ExprClassification.cpp2
-rw-r--r--lib/AST/ExprConstant.cpp846
-rw-r--r--lib/AST/ItaniumMangle.cpp754
-rw-r--r--lib/AST/Makefile18
-rw-r--r--lib/AST/Mangle.cpp28
-rw-r--r--lib/AST/MicrosoftCXXABI.cpp2
-rw-r--r--lib/AST/MicrosoftMangle.cpp247
-rw-r--r--lib/AST/NSAPI.cpp16
-rw-r--r--lib/AST/NestedNameSpecifier.cpp17
-rw-r--r--lib/AST/OpenMPClause.cpp398
-rw-r--r--lib/AST/ParentMap.cpp2
-rw-r--r--lib/AST/RecordLayout.cpp32
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp182
-rw-r--r--lib/AST/Stmt.cpp44
-rw-r--r--lib/AST/StmtCXX.cpp6
-rw-r--r--lib/AST/StmtOpenMP.cpp600
-rw-r--r--lib/AST/StmtPrinter.cpp193
-rw-r--r--lib/AST/StmtProfile.cpp216
-rw-r--r--lib/AST/TemplateBase.cpp9
-rw-r--r--lib/AST/TemplateName.cpp2
-rw-r--r--lib/AST/Type.cpp181
-rw-r--r--lib/AST/TypeLoc.cpp32
-rw-r--r--lib/AST/TypePrinter.cpp192
-rw-r--r--lib/AST/VTableBuilder.cpp15
45 files changed, 5132 insertions, 2068 deletions
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp
index 91f1e20d73b6..3c587331ed07 100644
--- a/lib/AST/APValue.cpp
+++ b/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/lib/AST/ASTConsumer.cpp b/lib/AST/ASTConsumer.cpp
index cff82e9b1003..55033b238c66 100644
--- a/lib/AST/ASTConsumer.cpp
+++ b/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/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 64386967b220..6aad4d1d570b 100644
--- a/lib/AST/ASTContext.cpp
+++ b/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/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index 2ab5a32917ae..22de8bc0dd05 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/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.");
@@ -990,19 +990,22 @@ class TemplateDiff {
}
};
+ 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 +1027,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 +1060,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 +1527,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 +1545,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 +1632,6 @@ class TemplateDiff {
Unbold();
OS << "]";
}
- return;
}
/// PrintExpr - Prints out the expr template arguments, highlighting argument
@@ -1695,7 +1704,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 +1737,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 +1843,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 +1869,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 +2024,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/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 4622a75ac2c6..872ba356a9b2 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/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/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 916f1081798d..bc1f9f96a06b 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/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/lib/AST/ASTTypeTraits.cpp b/lib/AST/ASTTypeTraits.cpp
index ec0671ceb1b5..2336c98fe049 100644
--- a/lib/AST/ASTTypeTraits.cpp
+++ b/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/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index 6785a0c2935a..6a6ca76a0165 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/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/lib/AST/Comment.cpp b/lib/AST/Comment.cpp
index d05c5de543ff..893bdc5c17bf 100644
--- a/lib/AST/Comment.cpp
+++ b/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/lib/AST/CommentLexer.cpp b/lib/AST/CommentLexer.cpp
index 98b7e367950c..57bfef08df6e 100644
--- a/lib/AST/CommentLexer.cpp
+++ b/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/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp
index 12823c37dfc6..f5f4f70dcbbf 100644
--- a/lib/AST/CommentSema.cpp
+++ b/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/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 427ca5efcd69..d1e8d25ea044 100644
--- a/lib/AST/Decl.cpp
+++ b/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/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 72587e388e47..bfb7d02b2955 100644
--- a/lib/AST/DeclBase.cpp
+++ b/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/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 4f24fdc28f71..d069bfdc3dc2 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/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;
@@ -910,7 +955,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 +975,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 +1651,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 +1669,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 +1807,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 +1824,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 +1948,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 +2143,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 +2171,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/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 050a0f53f1e5..d2701211beae 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/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/lib/AST/DeclOpenMP.cpp b/lib/AST/DeclOpenMP.cpp
index 493e2cd41226..5b06ce0778a7 100644
--- a/lib/AST/DeclOpenMP.cpp
+++ b/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/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 5c6002d55c0f..7e786990becb 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/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/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index de3ebd23ef4f..37943cdd5b7b 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/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/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index b2f27275f49c..2a988e1d22d0 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/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/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 52f34df43565..091e8787d8b6 100644
--- a/lib/AST/Expr.cpp
+++ b/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/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index ea983340a293..a13033d47467 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/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/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
index a47b03c0afba..89cc9bc18ef0 100644
--- a/lib/AST/ExprClassification.cpp
+++ b/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/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index fa652ba1b0ab..a25a6c7e5135 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -36,6 +36,7 @@
#include "clang/AST/APValue.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
+#include "clang/AST/ASTLambda.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Expr.h"
#include "clang/AST/RecordLayout.h"
@@ -157,13 +158,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 +478,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 +545,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 +562,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 +584,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 +602,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 +650,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 +673,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 +684,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 +778,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 +849,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 +1007,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 +1068,7 @@ namespace {
struct LValue {
APValue::LValueBase Base;
CharUnits Offset;
- bool InvalidBase : 1;
+ unsigned InvalidBase : 1;
unsigned CallIndex : 31;
SubobjectDesignator Designator;
@@ -1335,12 +1411,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 +1466,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 +1490,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 +1503,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 +1713,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 +1755,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 +1768,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 +1804,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 +1821,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 +1902,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 +2044,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 +2116,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()];
@@ -2045,7 +2126,22 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
// If this is a local variable, dig out its value.
if (Frame) {
Result = Frame->getTemporary(VD);
- assert(Result && "missing value for local variable");
+ if (!Result) {
+ // Assume variables referenced within a lambda's call operator that were
+ // not declared within the call operator are captures and during checking
+ // of a potential constant expression, assume they are unknown constant
+ // expressions.
+ assert(isLambdaCallOperator(Frame->Callee) &&
+ (VD->getDeclContext() != Frame->Callee || VD->isInitCapture()) &&
+ "missing value for local variable");
+ if (Info.checkingPotentialConstantExpression())
+ return false;
+ // FIXME: implement capture evaluation during constant expr evaluation.
+ Info.FFDiag(E->getLocStart(),
+ diag::note_unimplemented_constexpr_lambda_feature_ast)
+ << "captures not currently allowed";
+ return false;
+ }
return true;
}
@@ -2055,7 +2151,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 +2165,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 +2173,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 +2314,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 +2368,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 +2383,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 +2418,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 +2451,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 +2474,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 +2486,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 +2502,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 +2578,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 +2597,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 +2688,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 +2696,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 +2709,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 +2734,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 +2760,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 +2789,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 +2833,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 +2841,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 +2852,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 +2872,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 +2910,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 +2939,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 +2967,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 +2983,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 +3000,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 +3028,7 @@ struct CompoundAssignSubobjectHandler {
if (PointeeType.isNull() || !RHS.isInt() ||
(Opcode != BO_Add && Opcode != BO_Sub)) {
- Info.Diag(E);
+ Info.FFDiag(E);
return false;
}
@@ -2956,7 +3060,7 @@ static bool handleCompoundAssignment(
return false;
if (!Info.getLangOpts().CPlusPlus14) {
- Info.Diag(E);
+ Info.FFDiag(E);
return false;
}
@@ -2978,7 +3082,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 +3114,7 @@ struct IncDecSubobjectHandler {
return foundPointer(Subobj, SubobjType);
default:
// FIXME: can this happen?
- Info.Diag(E);
+ Info.FFDiag(E);
return false;
}
}
@@ -3021,7 +3125,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 +3184,7 @@ struct IncDecSubobjectHandler {
if (const PointerType *PT = SubobjType->getAs<PointerType>())
PointeeType = PT->getPointeeType();
else {
- Info.Diag(E);
+ Info.FFDiag(E);
return false;
}
@@ -3105,7 +3209,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 +3231,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 +3259,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 +3269,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 +3279,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 +3335,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 +3413,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 +3442,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 +3451,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 +3485,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 +3532,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 +3623,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 +3636,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 +3672,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 +3763,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 +3855,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 +3869,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 +3930,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 +3983,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 +4034,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 +4120,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 +4130,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 +4167,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 +4191,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 +4219,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 +4422,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 +4544,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 +4559,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 +4572,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 +4807,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 +4891,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 +4904,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 +4979,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 +5000,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 +5059,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 +5088,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 +5291,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 +5421,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 +5490,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 +5511,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 +5580,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 +5637,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 +5646,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 +5667,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 +5682,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 +6112,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 +6168,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 +6260,7 @@ public:
}
bool VisitMemberExpr(const MemberExpr *E) {
if (CheckReferencedDecl(E, E->getMemberDecl())) {
- VisitIgnoredValue(E->getBase());
+ VisitIgnoredBaseExpression(E->getBase());
return true;
}
@@ -6149,7 +6333,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 +6369,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 +6390,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 +6617,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 +6665,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 +6886,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 +7178,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 +7205,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 +7289,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 +7305,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 +7457,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 +7507,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 +7555,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 +7589,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 +7683,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 +7806,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 +8378,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 +8655,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 +8809,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 +9056,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 +9183,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 +9382,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 +9402,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 +9847,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/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 3f6b682f238f..694fde317542 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/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/lib/AST/Makefile b/lib/AST/Makefile
deleted file mode 100644
index 65383c5552d4..000000000000
--- a/lib/AST/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-##===- clang/lib/AST/Makefile ------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This implements the AST library for the C-Language front-end.
-#
-##===----------------------------------------------------------------------===##
-
-CLANG_LEVEL := ../..
-LIBRARYNAME := clangAST
-
-include $(CLANG_LEVEL)/Makefile
-
diff --git a/lib/AST/Mangle.cpp b/lib/AST/Mangle.cpp
index 014338f0490f..ee241732e8ad 100644
--- a/lib/AST/Mangle.cpp
+++ b/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/lib/AST/MicrosoftCXXABI.cpp b/lib/AST/MicrosoftCXXABI.cpp
index 6ba31ccf1e37..3ae04538d626 100644
--- a/lib/AST/MicrosoftCXXABI.cpp
+++ b/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/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index 4a45f9e4051f..351997e02a9d 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/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/lib/AST/NSAPI.cpp b/lib/AST/NSAPI.cpp
index c562dae63231..ac2a8d354247 100644
--- a/lib/AST/NSAPI.cpp
+++ b/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/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index d2370c88b9c5..82809d7ea7b5 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/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/lib/AST/OpenMPClause.cpp b/lib/AST/OpenMPClause.cpp
index 1ef43f7694cf..d04ba727bb05 100644
--- a/lib/AST/OpenMPClause.cpp
+++ b/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/lib/AST/ParentMap.cpp b/lib/AST/ParentMap.cpp
index d7d5f9c69205..d8882c9030b2 100644
--- a/lib/AST/ParentMap.cpp
+++ b/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/lib/AST/RecordLayout.cpp b/lib/AST/RecordLayout.cpp
index b2c244e3790e..299fd111bf6a 100644
--- a/lib/AST/RecordLayout.cpp
+++ b/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/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index bc5ae0ffc469..cf981be0a4dd 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/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/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index ca63d8486d82..75c076399511 100644
--- a/lib/AST/Stmt.cpp
+++ b/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/lib/AST/StmtCXX.cpp b/lib/AST/StmtCXX.cpp
index e39a01daf96c..4692db84b505 100644
--- a/lib/AST/StmtCXX.cpp
+++ b/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/lib/AST/StmtOpenMP.cpp b/lib/AST/StmtOpenMP.cpp
index 7f923d8a8251..f1ddedb2b0f2 100644
--- a/lib/AST/StmtOpenMP.cpp
+++ b/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/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 69f52f52b669..8797a13335c4 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/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/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 175a43abbf61..0a39413853a0 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/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/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
index e9edb0df66df..b75ede862f7a 100644
--- a/lib/AST/TemplateBase.cpp
+++ b/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/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp
index 47e0255d52ef..47a7d47e7a48 100644
--- a/lib/AST/TemplateName.cpp
+++ b/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/lib/AST/Type.cpp b/lib/AST/Type.cpp
index b467dac66b57..99b024701aa3 100644
--- a/lib/AST/Type.cpp
+++ b/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/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index d08b07b2ccd6..78947d18f953 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/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/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index b202523bdaf3..065a2db09141 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/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/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp
index bae018652f91..640fbf47aeab 100644
--- a/lib/AST/VTableBuilder.cpp
+++ b/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();