Update Clang for rebase to r212749.
This also fixes a small issue with arm_neon.h not being generated always.
Includes a cherry-pick of:
r213450 - fixes mac-specific header issue
r213126 - removes a default -Bsymbolic on Android
Change-Id: I2a790a0f5d3b2aab11de596fc3a74e7cbc99081d
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp
index e7b5a6b..0fa0216 100644
--- a/lib/AST/APValue.cpp
+++ b/lib/AST/APValue.cpp
@@ -403,9 +403,13 @@
if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
Out << *VD;
- else
+ else {
+ assert(Base.get<const Expr *>() != nullptr &&
+ "Expecting non-null Expr");
Base.get<const Expr*>()->printPretty(Out, nullptr,
Ctx.getPrintingPolicy());
+ }
+
if (!O.isZero()) {
Out << " + " << (O / S);
if (IsReference)
@@ -426,6 +430,7 @@
ElemTy = VD->getType();
} else {
const Expr *E = Base.get<const Expr*>();
+ assert(E != nullptr && "Expecting non-null Expr");
E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
ElemTy = E->getType();
}
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 2ea93ba..a1a9438 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1309,13 +1309,14 @@
} else if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
QualType T = VD->getType();
- if (const ReferenceType* RT = T->getAs<ReferenceType>()) {
+ if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
if (ForAlignof)
T = RT->getPointeeType();
else
T = getPointerType(RT->getPointeeType());
}
- if (!T->isIncompleteType() && !T->isFunctionType()) {
+ QualType BaseT = getBaseElementType(T);
+ if (!BaseT->isIncompleteType() && !T->isFunctionType()) {
// Adjust alignments of declarations with array type by the
// large-array alignment on the target.
if (const ArrayType *arrayType = getAsArrayType(T)) {
@@ -1327,11 +1328,6 @@
MinWidth <= getTypeSize(cast<ConstantArrayType>(arrayType)))
Align = std::max(Align, Target->getLargeArrayAlign());
}
-
- // Keep track of extra alignment requirements on the array itself, then
- // work with the element type.
- Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
- T = getBaseElementType(arrayType);
}
Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
@@ -1783,6 +1779,7 @@
const TypedefType *TT = T->getAs<TypedefType>();
// Double and long long should be naturally aligned if possible.
+ T = T->getBaseElementTypeUnsafe();
if (const ComplexType *CT = T->getAs<ComplexType>())
T = CT->getElementType().getTypePtr();
if (T->isSpecificBuiltinType(BuiltinType::Double) ||
@@ -3318,8 +3315,6 @@
NestedNameSpecifier *NNS,
const IdentifierInfo *Name,
QualType Canon) const {
- assert(NNS->isDependent() && "nested-name-specifier must be dependent");
-
if (Canon.isNull()) {
NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
ElaboratedTypeKeyword CanonKeyword = Keyword;
@@ -3433,7 +3428,7 @@
// contains an alias template specialization which ignores one of its
// parameters.
if (Canon->containsUnexpandedParameterPack()) {
- Canon = getPackExpansionType(getCanonicalType(Pattern), NumExpansions);
+ Canon = getPackExpansionType(Canon, NumExpansions);
// Find the insert position again, in case we inserted an element into
// PackExpansionTypes and invalidated our insert position.
@@ -3444,7 +3439,7 @@
T = new (*this) PackExpansionType(Pattern, Canon, NumExpansions);
Types.push_back(T);
PackExpansionTypes.InsertNode(T, InsertPos);
- return QualType(T, 0);
+ return QualType(T, 0);
}
/// CmpProtocolNames - Comparison predicate for sorting protocols
@@ -3687,10 +3682,10 @@
}
/// getTypeOfType - Unlike many "get<Type>" functions, we don't unique
-/// TypeOfType AST's. The only motivation to unique these nodes would be
+/// TypeOfType nodes. The only motivation to unique these nodes would be
/// memory savings. Since typeof(t) is fairly uncommon, space shouldn't be
-/// an issue. This doesn't effect the type checker, since it operates
-/// on canonical type's (which are always unique).
+/// an issue. This doesn't affect the type checker, since it operates
+/// on canonical types (which are always unique).
QualType ASTContext::getTypeOfType(QualType tofType) const {
QualType Canonical = getCanonicalType(tofType);
TypeOfType *tot = new (*this, TypeAlignment) TypeOfType(tofType, Canonical);
@@ -3699,18 +3694,17 @@
}
-/// getDecltypeType - Unlike many "get<Type>" functions, we don't unique
-/// DecltypeType AST's. The only motivation to unique these nodes would be
-/// memory savings. Since decltype(t) is fairly uncommon, space shouldn't be
-/// an issue. This doesn't effect the type checker, since it operates
-/// on canonical types (which are always unique).
+/// \brief Unlike many "get<Type>" functions, we don't unique DecltypeType
+/// nodes. This would never be helpful, since each such type has its own
+/// expression, and would not give a significant memory saving, since there
+/// is an Expr tree under each such type.
QualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType) const {
DecltypeType *dt;
-
- // C++0x [temp.type]p2:
+
+ // C++11 [temp.type]p2:
// If an expression e involves a template parameter, decltype(e) denotes a
- // unique dependent type. Two such decltype-specifiers refer to the same
- // type only if their expressions are equivalent (14.5.6.1).
+ // unique dependent type. Two such decltype-specifiers refer to the same
+ // type only if their expressions are equivalent (14.5.6.1).
if (e->isInstantiationDependent()) {
llvm::FoldingSetNodeID ID;
DependentDecltypeType::Profile(ID, *this, e);
@@ -3718,20 +3712,16 @@
void *InsertPos = nullptr;
DependentDecltypeType *Canon
= DependentDecltypeTypes.FindNodeOrInsertPos(ID, InsertPos);
- if (Canon) {
- // We already have a "canonical" version of an equivalent, dependent
- // decltype type. Use that as our canonical type.
- dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType,
- QualType((DecltypeType*)Canon, 0));
- } else {
+ if (!Canon) {
// Build a new, canonical typeof(expr) type.
Canon = new (*this, TypeAlignment) DependentDecltypeType(*this, e);
DependentDecltypeTypes.InsertNode(Canon, InsertPos);
- dt = Canon;
}
+ dt = new (*this, TypeAlignment)
+ DecltypeType(e, UnderlyingType, QualType((DecltypeType *)Canon, 0));
} else {
- dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType,
- getCanonicalType(UnderlyingType));
+ dt = new (*this, TypeAlignment)
+ DecltypeType(e, UnderlyingType, getCanonicalType(UnderlyingType));
}
Types.push_back(dt);
return QualType(dt, 0);
@@ -5032,9 +5022,7 @@
// Encode result type.
// GCC has some special rules regarding encoding of properties which
// closely resembles encoding of ivars.
- getObjCEncodingForTypeImpl(PD->getType(), S, true, true, nullptr,
- true /* outermost type */,
- true /* encoding for property */);
+ getObjCEncodingForPropertyType(PD->getType(), S);
if (PD->isReadOnly()) {
S += ",R";
@@ -5107,6 +5095,16 @@
true /* outermost type */);
}
+void ASTContext::getObjCEncodingForPropertyType(QualType T,
+ std::string& S) const {
+ // Encode result type.
+ // GCC has some special rules regarding encoding of properties which
+ // closely resembles encoding of ivars.
+ getObjCEncodingForTypeImpl(T, S, true, true, nullptr,
+ true /* outermost type */,
+ true /* encoding property */);
+}
+
static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
BuiltinType::Kind kind) {
switch (kind) {
@@ -7853,14 +7851,6 @@
: StaticLocalLinkage;
}
- // On Darwin, the backing variable for a C++11 thread_local variable always
- // has internal linkage; all accesses should just be calls to the
- // Itanium-specified entry point, which has the normal linkage of the
- // variable.
- if (VD->getTLSKind() == VarDecl::TLS_Dynamic &&
- Context.getTargetInfo().getTriple().isMacOSX())
- return GVA_Internal;
-
switch (VD->getTemplateSpecializationKind()) {
case TSK_Undeclared:
case TSK_ExplicitSpecialization:
@@ -8177,10 +8167,12 @@
if (!Node)
return true;
if (ParentStack.size() > 0) {
- // FIXME: Currently we add the same parent multiple times, for example
- // when we visit all subexpressions of template instantiations; this is
- // suboptimal, bug benign: the only way to visit those is with
- // hasAncestor / hasParent, and those do not create new matches.
+ // FIXME: Currently we add the same parent multiple times, but only
+ // when no memoization data is available for the type.
+ // For example when we visit all subexpressions of template
+ // instantiations; this is suboptimal, but benign: the only way to
+ // visit those is with hasAncestor / hasParent, and those do not create
+ // new matches.
// The plan is to enable DynTypedNode to be storable in a map or hash
// map. The main problem there is to implement hash functions /
// comparison operators for all types that DynTypedNode supports that
@@ -8188,18 +8180,27 @@
auto &NodeOrVector = (*Parents)[Node];
if (NodeOrVector.isNull()) {
NodeOrVector = new ast_type_traits::DynTypedNode(ParentStack.back());
- } else if (NodeOrVector
- .template is<ast_type_traits::DynTypedNode *>()) {
- auto *Node =
- NodeOrVector.template get<ast_type_traits::DynTypedNode *>();
- auto *Vector = new ASTContext::ParentVector(1, *Node);
- Vector->push_back(ParentStack.back());
- NodeOrVector = Vector;
- delete Node;
} else {
+ if (NodeOrVector.template is<ast_type_traits::DynTypedNode *>()) {
+ auto *Node =
+ NodeOrVector.template get<ast_type_traits::DynTypedNode *>();
+ auto *Vector = new ASTContext::ParentVector(1, *Node);
+ NodeOrVector = Vector;
+ delete Node;
+ }
assert(NodeOrVector.template is<ASTContext::ParentVector *>());
- NodeOrVector.template get<ASTContext::ParentVector *>()->push_back(
- ParentStack.back());
+
+ auto *Vector =
+ NodeOrVector.template get<ASTContext::ParentVector *>();
+ // Skip duplicates for types that have memoization data.
+ // We must check that the type has memoization data before calling
+ // std::find() because DynTypedNode::operator== can't compare all
+ // types.
+ bool Found = ParentStack.back().getMemoizationData() &&
+ std::find(Vector->begin(), Vector->end(),
+ ParentStack.back()) != Vector->end();
+ if (!Found)
+ Vector->push_back(ParentStack.back());
}
}
ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node));
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index bd5c209..2ee26fb 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
@@ -161,9 +162,8 @@
/// diagnostic message
static std::string
ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
- const DiagnosticsEngine::ArgumentValue *PrevArgs,
- unsigned NumPrevArgs,
- ArrayRef<intptr_t> QualTypeVals) {
+ ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
+ ArrayRef<intptr_t> QualTypeVals) {
// FIXME: Playing with std::string is really slow.
bool ForceAKA = false;
QualType CanTy = Ty.getCanonicalType();
@@ -201,7 +201,7 @@
// Check to see if we already desugared this type in this
// diagnostic. If so, don't do it again.
bool Repeated = false;
- for (unsigned i = 0; i != NumPrevArgs; ++i) {
+ for (unsigned i = 0, e = PrevArgs.size(); i != e; ++i) {
// TODO: Handle ak_declcontext case.
if (PrevArgs[i].first == DiagnosticsEngine::ak_qualtype) {
void *Ptr = (void*)PrevArgs[i].second;
@@ -256,12 +256,9 @@
void clang::FormatASTNodeDiagnosticArgument(
DiagnosticsEngine::ArgumentKind Kind,
intptr_t Val,
- const char *Modifier,
- unsigned ModLen,
- const char *Argument,
- unsigned ArgLen,
- const DiagnosticsEngine::ArgumentValue *PrevArgs,
- unsigned NumPrevArgs,
+ StringRef Modifier,
+ StringRef Argument,
+ ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
SmallVectorImpl<char> &Output,
void *Cookie,
ArrayRef<intptr_t> QualTypeVals) {
@@ -296,28 +293,26 @@
// Attempting to do a template diff on non-templates. Set the variables
// and continue with regular type printing of the appropriate type.
Val = TDT.PrintFromType ? TDT.FromType : TDT.ToType;
- ModLen = 0;
- ArgLen = 0;
+ Modifier = StringRef();
+ Argument = StringRef();
// Fall through
}
case DiagnosticsEngine::ak_qualtype: {
- assert(ModLen == 0 && ArgLen == 0 &&
+ assert(Modifier.empty() && Argument.empty() &&
"Invalid modifier for QualType argument");
QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(Val)));
- OS << ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, NumPrevArgs,
- QualTypeVals);
+ OS << ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, QualTypeVals);
NeedQuotes = false;
break;
}
case DiagnosticsEngine::ak_declarationname: {
- if (ModLen == 9 && !memcmp(Modifier, "objcclass", 9) && ArgLen == 0)
+ if (Modifier == "objcclass" && Argument.empty())
OS << '+';
- else if (ModLen == 12 && !memcmp(Modifier, "objcinstance", 12)
- && ArgLen==0)
+ else if (Modifier == "objcinstance" && Argument.empty())
OS << '-';
else
- assert(ModLen == 0 && ArgLen == 0 &&
+ assert(Modifier.empty() && Argument.empty() &&
"Invalid modifier for DeclarationName argument");
OS << DeclarationName::getFromOpaqueInteger(Val);
@@ -325,10 +320,10 @@
}
case DiagnosticsEngine::ak_nameddecl: {
bool Qualified;
- if (ModLen == 1 && Modifier[0] == 'q' && ArgLen == 0)
+ if (Modifier == "q" && Argument.empty())
Qualified = true;
else {
- assert(ModLen == 0 && ArgLen == 0 &&
+ assert(Modifier.empty() && Argument.empty() &&
"Invalid modifier for NamedDecl* argument");
Qualified = false;
}
@@ -345,7 +340,8 @@
case DiagnosticsEngine::ak_declcontext: {
DeclContext *DC = reinterpret_cast<DeclContext *> (Val);
assert(DC && "Should never have a null declaration context");
-
+ NeedQuotes = false;
+
if (DC->isTranslationUnit()) {
// FIXME: Get these strings from some localized place
if (Context.getLangOpts().CPlusPlus)
@@ -355,10 +351,17 @@
} else if (TypeDecl *Type = dyn_cast<TypeDecl>(DC)) {
OS << ConvertTypeToDiagnosticString(Context,
Context.getTypeDeclType(Type),
- PrevArgs, NumPrevArgs,
- QualTypeVals);
+ PrevArgs, QualTypeVals);
} else {
// FIXME: Get these strings from some localized place
+ if (isa<BlockDecl>(DC)) {
+ OS << "block literal";
+ break;
+ }
+ if (isLambdaCallOperator(DC)) {
+ OS << "lambda expression";
+ break;
+ }
NamedDecl *ND = cast<NamedDecl>(DC);
if (isa<NamespaceDecl>(ND))
OS << "namespace ";
@@ -371,7 +374,6 @@
ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), true);
OS << '\'';
}
- NeedQuotes = false;
break;
}
case DiagnosticsEngine::ak_attr: {
@@ -957,25 +959,27 @@
ToIter.isEnd() && ToExpr);
if (DefaultNTTPD->getType()->isIntegralOrEnumerationType()) {
if (FromExpr)
- FromInt = GetInt(FromIter, FromExpr);
+ HasFromInt = GetInt(FromIter, FromExpr, FromInt);
if (ToExpr)
- ToInt = GetInt(ToIter, ToExpr);
- Tree.SetNode(FromInt, ToInt, FromExpr, ToExpr);
+ HasToInt = GetInt(ToIter, ToExpr, ToInt);
+ }
+ if (HasFromInt && HasToInt) {
+ Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt));
Tree.SetKind(DiffTree::Integer);
+ } else if (HasFromInt || HasToInt) {
+ Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
+ Tree.SetSame(false);
+ Tree.SetKind(DiffTree::Integer);
} else {
Tree.SetSame(IsEqualExpr(Context, ParamWidth, FromExpr, ToExpr));
Tree.SetKind(DiffTree::Expression);
}
} else if (HasFromInt || HasToInt) {
- if (!HasFromInt && FromExpr) {
- FromInt = GetInt(FromIter, FromExpr);
- HasFromInt = true;
- }
- if (!HasToInt && ToExpr) {
- ToInt = GetInt(ToIter, ToExpr);
- HasToInt = true;
- }
+ if (!HasFromInt && FromExpr)
+ HasFromInt = GetInt(FromIter, FromExpr, FromInt);
+ if (!HasToInt && ToExpr)
+ HasToInt = GetInt(ToIter, ToExpr, ToInt);
Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt));
Tree.SetDefault(FromIter.isEnd() && HasFromInt,
@@ -1119,20 +1123,28 @@
/// GetInt - Retrieves the template integer argument, including evaluating
/// default arguments.
- llvm::APInt GetInt(const TSTiterator &Iter, Expr *ArgExpr) {
+ bool GetInt(const TSTiterator &Iter, Expr *ArgExpr, llvm::APInt &Int) {
// Default, value-depenedent expressions require fetching
- // from the desugared TemplateArgument
- if (Iter.isEnd() && ArgExpr->isValueDependent())
+ // from the desugared TemplateArgument, otherwise expression needs to
+ // be evaluatable.
+ if (Iter.isEnd() && ArgExpr->isValueDependent()) {
switch (Iter.getDesugar().getKind()) {
case TemplateArgument::Integral:
- return Iter.getDesugar().getAsIntegral();
+ Int = Iter.getDesugar().getAsIntegral();
+ return true;
case TemplateArgument::Expression:
ArgExpr = Iter.getDesugar().getAsExpr();
- return ArgExpr->EvaluateKnownConstInt(Context);
+ Int = ArgExpr->EvaluateKnownConstInt(Context);
+ return true;
default:
- assert(0 && "Unexpected template argument kind");
+ llvm_unreachable("Unexpected template argument kind");
}
- return ArgExpr->EvaluateKnownConstInt(Context);
+ } else if (ArgExpr->isEvaluatable(Context)) {
+ Int = ArgExpr->EvaluateKnownConstInt(Context);
+ return true;
+ }
+
+ return false;
}
/// GetValueDecl - Retrieves the template Decl argument, including
@@ -1148,7 +1160,7 @@
ArgExpr = Iter.getDesugar().getAsExpr();
return cast<DeclRefExpr>(ArgExpr)->getDecl();
default:
- assert(0 && "Unexpected template argument kind");
+ llvm_unreachable("Unexpected template argument kind");
}
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ArgExpr);
if (!DRE) {
@@ -1515,6 +1527,8 @@
Bold();
}
OS << Val.toString(10);
+ } else if (E) {
+ PrintExpr(E);
} else {
OS << "(no argument)";
}
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 14e0e01..9ece41d 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -315,6 +315,7 @@
void VisitIntegerLiteral(const IntegerLiteral *Node);
void VisitFloatingLiteral(const FloatingLiteral *Node);
void VisitStringLiteral(const StringLiteral *Str);
+ void VisitInitListExpr(const InitListExpr *ILE);
void VisitUnaryOperator(const UnaryOperator *Node);
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
void VisitMemberExpr(const MemberExpr *Node);
@@ -629,9 +630,11 @@
}
dumpPointer(A);
dumpSourceRange(A->getRange());
-#include "clang/AST/AttrDump.inc"
+ if (A->isInherited())
+ OS << " Inherited";
if (A->isImplicit())
OS << " Implicit";
+#include "clang/AST/AttrDump.inc"
}
static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
@@ -804,6 +807,12 @@
OS << " hidden";
if (D->isImplicit())
OS << " implicit";
+ if (D->isUsed())
+ OS << " used";
+ else if (D->isReferenced())
+ OS << " referenced";
+ if (D->isInvalidDecl())
+ OS << " invalid";
bool HasAttrs = D->hasAttrs();
const FullComment *Comment =
@@ -827,9 +836,6 @@
lastChild();
dumpFullComment(Comment);
- if (D->isInvalidDecl())
- OS << " invalid";
-
setMoreChildren(false);
if (HasDeclContext)
dumpDeclContext(cast<DeclContext>(D));
@@ -1720,6 +1726,22 @@
Str->outputString(OS);
}
+void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) {
+ VisitExpr(ILE);
+ if (auto *Filler = ILE->getArrayFiller()) {
+ if (!ILE->getNumInits())
+ lastChild();
+ IndentScope Indent(*this);
+ OS << "array filler";
+ lastChild();
+ dumpStmt(Filler);
+ }
+ if (auto *Field = ILE->getInitializedFieldInUnion()) {
+ OS << " field ";
+ dumpBareDeclRef(Field);
+ }
+}
+
void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) {
VisitExpr(Node);
OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index b180326..b0e0b1d 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -4090,8 +4090,7 @@
// Try to find an existing specialization with these template arguments.
void *InsertPos = nullptr;
ClassTemplateSpecializationDecl *D2
- = ClassTemplate->findSpecialization(TemplateArgs.data(),
- TemplateArgs.size(), InsertPos);
+ = ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
if (D2) {
// We already have a class template specialization with these template
// arguments.
@@ -4284,7 +4283,7 @@
// Try to find an existing specialization with these template arguments.
void *InsertPos = nullptr;
VarTemplateSpecializationDecl *D2 = VarTemplate->findSpecialization(
- TemplateArgs.data(), TemplateArgs.size(), InsertPos);
+ TemplateArgs, InsertPos);
if (D2) {
// We already have a variable template specialization with these template
// arguments.
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 1c3a538..7448de2 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -471,6 +471,58 @@
LV.mergeExternalVisibility(argsLV);
}
+/// Should we consider visibility associated with the template
+/// arguments and parameters of the given variable template
+/// specialization? As usual, follow class template specialization
+/// logic up to initialization.
+static bool shouldConsiderTemplateVisibility(
+ const VarTemplateSpecializationDecl *spec,
+ LVComputationKind computation) {
+ // Include visibility from the template parameters and arguments
+ // only if this is not an explicit instantiation or specialization
+ // with direct explicit visibility (and note that implicit
+ // instantiations won't have a direct attribute).
+ if (!spec->isExplicitInstantiationOrSpecialization())
+ return true;
+
+ // An explicit variable specialization is an independent, top-level
+ // declaration. As such, if it has an explicit visibility attribute,
+ // that must directly express the user's intent, and we should honor
+ // it.
+ if (spec->isExplicitSpecialization() &&
+ hasExplicitVisibilityAlready(computation))
+ return false;
+
+ return !hasDirectVisibilityAttribute(spec, computation);
+}
+
+/// Merge in template-related linkage and visibility for the given
+/// variable template specialization. As usual, follow class template
+/// specialization logic up to initialization.
+static void mergeTemplateLV(LinkageInfo &LV,
+ const VarTemplateSpecializationDecl *spec,
+ LVComputationKind computation) {
+ bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation);
+
+ // Merge information from the template parameters, but ignore
+ // visibility if we're only considering template arguments.
+
+ VarTemplateDecl *temp = spec->getSpecializedTemplate();
+ LinkageInfo tempLV =
+ getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
+ LV.mergeMaybeWithVisibility(tempLV,
+ considerVisibility && !hasExplicitVisibilityAlready(computation));
+
+ // Merge information from the template arguments. We ignore
+ // template-argument visibility if we've got an explicit
+ // instantiation with a visibility attribute.
+ const TemplateArgumentList &templateArgs = spec->getTemplateArgs();
+ LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs, computation);
+ if (considerVisibility)
+ LV.mergeVisibility(argsLV);
+ LV.mergeExternalVisibility(argsLV);
+}
+
static bool useInlineVisibilityHidden(const NamedDecl *D) {
// FIXME: we should warn if -fvisibility-inlines-hidden is used with c.
const LangOptions &Opts = D->getASTContext().getLangOpts();
@@ -662,6 +714,14 @@
// C99 6.2.2p4 and propagating the visibility attribute, so we don't have
// to do it here.
+ // As per function and class template specializations (below),
+ // consider LV for the template and template arguments. We're at file
+ // scope, so we do not need to worry about nested specializations.
+ if (const VarTemplateSpecializationDecl *spec
+ = dyn_cast<VarTemplateSpecializationDecl>(Var)) {
+ mergeTemplateLV(LV, spec, computation);
+ }
+
// - a function, unless it has internal linkage; or
} else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
// In theory, we can modify the function's LV by the LV of its
@@ -869,6 +929,10 @@
// Static data members.
} else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const VarTemplateSpecializationDecl *spec
+ = dyn_cast<VarTemplateSpecializationDecl>(VD))
+ mergeTemplateLV(LV, spec, computation);
+
// Modify the variable's linkage by its type, but ignore the
// type's visibility unless it's a definition.
LinkageInfo typeLV = getLVForType(*VD->getType(), computation);
@@ -1303,6 +1367,9 @@
TemplateArgs.size(),
P);
} else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(*I)) {
+ if (P.SuppressUnwrittenScope &&
+ (ND->isAnonymousNamespace() || ND->isInline()))
+ continue;
if (ND->isAnonymousNamespace())
OS << "(anonymous namespace)";
else
@@ -1676,7 +1743,7 @@
}
template<typename T>
-static LanguageLinkage getLanguageLinkageTemplate(const T &D) {
+static LanguageLinkage getDeclLanguageLinkage(const T &D) {
// C++ [dcl.link]p1: All function types, function names with external linkage,
// and variable names with external linkage have a language linkage.
if (!D.hasExternalFormalLinkage())
@@ -1704,7 +1771,7 @@
}
template<typename T>
-static bool isExternCTemplate(const T &D) {
+static bool isDeclExternC(const T &D) {
// Since the context is ignored for class members, they can only have C++
// language linkage or no language linkage.
const DeclContext *DC = D.getDeclContext();
@@ -1717,11 +1784,11 @@
}
LanguageLinkage VarDecl::getLanguageLinkage() const {
- return getLanguageLinkageTemplate(*this);
+ return getDeclLanguageLinkage(*this);
}
bool VarDecl::isExternC() const {
- return isExternCTemplate(*this);
+ return isDeclExternC(*this);
}
bool VarDecl::isInExternCContext() const {
@@ -2345,7 +2412,7 @@
return false;
const FunctionProtoType *FPT = getType()->castAs<FunctionProtoType>();
- if (FPT->getNumParams() > 2 || FPT->isVariadic())
+ if (FPT->getNumParams() == 0 || FPT->getNumParams() > 2 || FPT->isVariadic())
return false;
// If this is a single-parameter function, it must be a replaceable global
@@ -2403,11 +2470,11 @@
}
LanguageLinkage FunctionDecl::getLanguageLinkage() const {
- return getLanguageLinkageTemplate(*this);
+ return getDeclLanguageLinkage(*this);
}
bool FunctionDecl::isExternC() const {
- return isExternCTemplate(*this);
+ return isDeclExternC(*this);
}
bool FunctionDecl::isInExternCContext() const {
@@ -2541,6 +2608,18 @@
NamedDecl **A = new (getASTContext()) NamedDecl*[NewDecls.size()];
std::copy(NewDecls.begin(), NewDecls.end(), A);
DeclsInPrototypeScope = ArrayRef<NamedDecl *>(A, NewDecls.size());
+ // Move declarations introduced in prototype to the function context.
+ for (auto I : NewDecls) {
+ DeclContext *DC = I->getDeclContext();
+ // Forward-declared reference to an enumeration is not added to
+ // declaration scope, so skip declaration that is absent from its
+ // declaration contexts.
+ if (DC->containsDecl(I)) {
+ DC->removeDecl(I);
+ I->setDeclContext(this);
+ addDecl(I);
+ }
+ }
}
}
@@ -2672,6 +2751,26 @@
return FoundBody;
}
+SourceRange FunctionDecl::getReturnTypeSourceRange() const {
+ const TypeSourceInfo *TSI = getTypeSourceInfo();
+ if (!TSI)
+ return SourceRange();
+ FunctionTypeLoc FTL =
+ TSI->getTypeLoc().IgnoreParens().getAs<FunctionTypeLoc>();
+ if (!FTL)
+ return SourceRange();
+
+ // Skip self-referential return types.
+ const SourceManager &SM = getASTContext().getSourceManager();
+ SourceRange RTRange = FTL.getReturnLoc().getSourceRange();
+ SourceLocation Boundary = getNameInfo().getLocStart();
+ if (RTRange.isInvalid() || Boundary.isInvalid() ||
+ !SM.isBeforeInTranslationUnit(RTRange.getEnd(), Boundary))
+ return SourceRange();
+
+ return RTRange;
+}
+
/// \brief For an inline function definition in C, or for a gnu_inline function
/// in C++, determine whether the definition will be externally visible.
///
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 0ac8b73..43d0fca 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -70,7 +70,8 @@
ImplicitCopyAssignmentHasConstParam(true),
HasDeclaredCopyConstructorWithConstParam(false),
HasDeclaredCopyAssignmentWithConstParam(false),
- IsLambda(false), NumBases(0), NumVBases(0), Bases(), VBases(),
+ IsLambda(false), IsParsingBaseSpecifiers(false), NumBases(0), NumVBases(0),
+ Bases(), VBases(),
Definition(D), FirstFriend() {
}
@@ -334,8 +335,10 @@
addedClassSubobject(BaseClassDecl);
}
- if (VBases.empty())
+ if (VBases.empty()) {
+ data().IsParsingBaseSpecifiers = false;
return;
+ }
// Create base specifier for any direct or indirect virtual bases.
data().VBases = new (C) CXXBaseSpecifier[VBases.size()];
@@ -346,6 +349,8 @@
addedClassSubobject(Type->getAsCXXRecordDecl());
data().getVBases()[I] = *VBases[I];
}
+
+ data().IsParsingBaseSpecifiers = false;
}
void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 558654d..e5e5130 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -536,6 +536,7 @@
SimpleInit->printPretty(Out, nullptr, Policy, Indentation);
else {
for (unsigned I = 0; I != NumArgs; ++I) {
+ assert(Args[I] != nullptr && "Expected non-null Expr");
if (isa<CXXDefaultArgExpr>(Args[I]))
break;
@@ -586,7 +587,8 @@
} else
Out << ' ';
- D->getBody()->printPretty(Out, nullptr, SubPolicy, Indentation);
+ if (D->getBody())
+ D->getBody()->printPretty(Out, nullptr, SubPolicy, Indentation);
Out << '\n';
}
}
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index a69146b..0d1d2a4 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -164,11 +164,11 @@
typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
RedeclarableTemplateDecl::findSpecializationImpl(
llvm::FoldingSetVector<EntryType> &Specs,
- const TemplateArgument *Args, unsigned NumArgs,
+ ArrayRef<TemplateArgument> Args,
void *&InsertPos) {
typedef SpecEntryTraits<EntryType> SETraits;
llvm::FoldingSetNodeID ID;
- EntryType::Profile(ID,Args,NumArgs, getASTContext());
+ EntryType::Profile(ID,Args, getASTContext());
EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
return Entry ? SETraits::getMostRecentDecl(Entry) : nullptr;
}
@@ -263,9 +263,9 @@
}
FunctionDecl *
-FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
- unsigned NumArgs, void *&InsertPos) {
- return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
+FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
+ void *&InsertPos) {
+ return findSpecializationImpl(getSpecializations(), Args, InsertPos);
}
void FunctionTemplateDecl::addSpecialization(
@@ -350,9 +350,9 @@
}
ClassTemplateSpecializationDecl *
-ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
- unsigned NumArgs, void *&InsertPos) {
- return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
+ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
+ void *&InsertPos) {
+ return findSpecializationImpl(getSpecializations(), Args, InsertPos);
}
void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
@@ -370,11 +370,9 @@
}
ClassTemplatePartialSpecializationDecl *
-ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
- unsigned NumArgs,
+ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
void *&InsertPos) {
- return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
- InsertPos);
+ return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
}
void ClassTemplateDecl::AddPartialSpecialization(
@@ -985,9 +983,9 @@
}
VarTemplateSpecializationDecl *
-VarTemplateDecl::findSpecialization(const TemplateArgument *Args,
- unsigned NumArgs, void *&InsertPos) {
- return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
+VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
+ void *&InsertPos) {
+ return findSpecializationImpl(getSpecializations(), Args, InsertPos);
}
void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
@@ -1005,10 +1003,9 @@
}
VarTemplatePartialSpecializationDecl *
-VarTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
- unsigned NumArgs, void *&InsertPos) {
- return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
- InsertPos);
+VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
+ void *&InsertPos) {
+ return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
}
void VarTemplateDecl::AddPartialSpecialization(
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 7e1b2d9..0cc046c 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -998,7 +998,7 @@
TheLexer.LexFromRawLexer(TheTok);
// Use the StringLiteralParser to compute the length of the string in bytes.
- StringLiteralParser SLP(&TheTok, 1, SM, Features, Target);
+ StringLiteralParser SLP(TheTok, SM, Features, Target);
unsigned TokNumBytes = SLP.GetStringLength();
// If the byte is in this token, return the location of the byte.
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index c1468cb..3552d65 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -1269,11 +1269,29 @@
LVal.getLValueCallIndex() == 0) &&
"have call index for global lvalue");
- // Check if this is a thread-local variable.
if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
if (const VarDecl *Var = dyn_cast<const VarDecl>(VD)) {
+ // Check if this is a thread-local variable.
if (Var->getTLSKind())
return false;
+
+ // A dllimport variable never acts like a constant.
+ if (Var->hasAttr<DLLImportAttr>())
+ return false;
+ }
+ if (const auto *FD = dyn_cast<const FunctionDecl>(VD)) {
+ // __declspec(dllimport) must be handled very carefully:
+ // We must never initialize an expression with the thunk in C++.
+ // Doing otherwise would allow the same id-expression to yield
+ // different addresses for the same function in different translation
+ // units. However, this means that we must dynamically initialize the
+ // expression with the contents of the import address table at runtime.
+ //
+ // The C language has no notion of ODR; furthermore, it has no notion of
+ // dynamic initialization. This means that we are permitted to
+ // perform initialization with the address of the thunk.
+ if (Info.getLangOpts().CPlusPlus && FD->hasAttr<DLLImportAttr>())
+ return false;
}
}
@@ -2938,6 +2956,7 @@
if (Object->getType()->isLiteralType(Info.Ctx))
return EvaluateTemporary(Object, This, Info);
+ Info.Diag(Object, diag::note_constexpr_nonliteral) << Object->getType();
return false;
}
@@ -4647,8 +4666,13 @@
// Can't look at 'this' when checking a potential constant expression.
if (Info.checkingPotentialConstantExpression())
return false;
- if (!Info.CurrentCall->This)
- return Error(E);
+ if (!Info.CurrentCall->This) {
+ if (Info.getLangOpts().CPlusPlus11)
+ Info.Diag(E, diag::note_constexpr_this) << E->isImplicit();
+ else
+ Info.Diag(E);
+ return false;
+ }
Result = *Info.CurrentCall->This;
return true;
}
@@ -6029,7 +6053,8 @@
case Builtin::BI__builtin_clz:
case Builtin::BI__builtin_clzl:
- case Builtin::BI__builtin_clzll: {
+ case Builtin::BI__builtin_clzll:
+ case Builtin::BI__builtin_clzs: {
APSInt Val;
if (!EvaluateInteger(E->getArg(0), Val, Info))
return false;
@@ -6044,7 +6069,8 @@
case Builtin::BI__builtin_ctz:
case Builtin::BI__builtin_ctzl:
- case Builtin::BI__builtin_ctzll: {
+ case Builtin::BI__builtin_ctzll:
+ case Builtin::BI__builtin_ctzs: {
APSInt Val;
if (!EvaluateInteger(E->getArg(0), Val, Info))
return false;
@@ -6910,8 +6936,9 @@
}
CharUnits IntExprEvaluator::GetAlignOfType(QualType T) {
- // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
- // result shall be the alignment of the referenced type."
+ // C++ [expr.alignof]p3:
+ // When alignof is applied to a reference type, the result is the
+ // alignment of the referenced type.
if (const ReferenceType *Ref = T->getAs<ReferenceType>())
T = Ref->getPointeeType();
@@ -6930,7 +6957,7 @@
// alignof decl is always accepted, even if it doesn't make sense: we default
// to 1 in those cases.
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
- return Info.Ctx.getDeclAlign(DRE->getDecl(),
+ return Info.Ctx.getDeclAlign(DRE->getDecl(),
/*RefAsPointee*/true);
if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
@@ -8702,7 +8729,7 @@
bool Expr::EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
const FunctionDecl *Callee,
- llvm::ArrayRef<const Expr*> Args) const {
+ ArrayRef<const Expr*> Args) const {
Expr::EvalStatus Status;
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
diff --git a/lib/AST/InheritViz.cpp b/lib/AST/InheritViz.cpp
index 84cc167..eb3020c 100644
--- a/lib/AST/InheritViz.cpp
+++ b/lib/AST/InheritViz.cpp
@@ -139,7 +139,7 @@
int FD;
SmallString<128> Filename;
- error_code EC =
+ std::error_code EC =
sys::fs::createTemporaryFile(Self.getAsString(), "dot", FD, Filename);
if (EC) {
llvm::errs() << "Error: " << EC.message() << "\n";
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 58a44b7..1cb6ab5 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -2674,7 +2674,6 @@
llvm_unreachable("cannot mangle opaque value; mangling wrong thing?");
case Expr::InitListExprClass: {
- // Proposal by Jason Merrill, 2012-01-03
Out << "il";
const InitListExpr *InitList = cast<InitListExpr>(E);
for (unsigned i = 0, e = InitList->getNumInits(); i != e; ++i)
@@ -2739,7 +2738,6 @@
Out << '_';
mangleType(New->getAllocatedType());
if (New->hasInitializer()) {
- // Proposal by Jason Merrill, 2012-01-03
if (New->getInitializationStyle() == CXXNewExpr::ListInit)
Out << "il";
else
@@ -2825,7 +2823,6 @@
const CXXConstructExpr *CE = cast<CXXConstructExpr>(E);
unsigned N = CE->getNumArgs();
- // Proposal by Jason Merrill, 2012-01-03
if (CE->isListInitialization())
Out << "tl";
else
@@ -3425,8 +3422,8 @@
// <seq-id> is encoded in base-36, using digits and upper case letters.
char Buffer[7]; // log(2**32) / log(36) ~= 7
- llvm::MutableArrayRef<char> BufferRef(Buffer);
- llvm::MutableArrayRef<char>::reverse_iterator I = BufferRef.rbegin();
+ MutableArrayRef<char> BufferRef(Buffer);
+ MutableArrayRef<char>::reverse_iterator I = BufferRef.rbegin();
for (; SeqID != 0; SeqID /= 36) {
unsigned C = SeqID % 36;
diff --git a/lib/AST/MicrosoftCXXABI.cpp b/lib/AST/MicrosoftCXXABI.cpp
index 359e864..6870315 100644
--- a/lib/AST/MicrosoftCXXABI.cpp
+++ b/lib/AST/MicrosoftCXXABI.cpp
@@ -93,7 +93,7 @@
}
MSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const {
- if (!hasDefinition())
+ if (!hasDefinition() || isParsingBaseSpecifiers())
return MSInheritanceAttr::Keyword_unspecified_inheritance;
if (getNumVBases() > 0)
return MSInheritanceAttr::Keyword_virtual_inheritance;
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index d064b15..e6a6d09 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -193,7 +193,6 @@
typedef llvm::StringMap<unsigned> BackRefMap;
BackRefMap NameBackReferences;
- bool UseNameBackReferences;
typedef llvm::DenseMap<void *, unsigned> ArgBackRefMap;
ArgBackRefMap TypeBackReferences;
@@ -209,14 +208,12 @@
MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_)
: Context(C), Out(Out_), Structor(nullptr), StructorType(-1),
- UseNameBackReferences(true),
PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
64) {}
MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
const CXXDestructorDecl *D, CXXDtorType Type)
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
- UseNameBackReferences(true),
PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
64) {}
@@ -241,7 +238,6 @@
void mangleNestedName(const NamedDecl *ND);
private:
- void disableBackReferences() { UseNameBackReferences = false; }
void mangleUnqualifiedName(const NamedDecl *ND) {
mangleUnqualifiedName(ND, ND->getDeclName());
}
@@ -422,11 +418,11 @@
// ::= <type> <pointee-cvr-qualifiers> # pointers, references
// Pointers and references are odd. The type of 'int * const foo;' gets
// mangled as 'QAHA' instead of 'PAHB', for example.
- TypeLoc TL = VD->getTypeSourceInfo()->getTypeLoc();
+ SourceRange SR = VD->getSourceRange();
QualType Ty = VD->getType();
if (Ty->isPointerType() || Ty->isReferenceType() ||
Ty->isMemberPointerType()) {
- mangleType(Ty, TL.getSourceRange(), QMM_Drop);
+ mangleType(Ty, SR, QMM_Drop);
manglePointerExtQualifiers(
Ty.getDesugaredType(getASTContext()).getLocalQualifiers(), nullptr);
if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>()) {
@@ -444,7 +440,7 @@
else
mangleQualifiers(Ty.getQualifiers(), false);
} else {
- mangleType(Ty, TL.getSourceRange(), QMM_Drop);
+ mangleType(Ty, SR, QMM_Drop);
mangleQualifiers(Ty.getLocalQualifiers(), false);
}
}
@@ -499,18 +495,9 @@
// ::= $H? <name> <number>
// ::= $I? <name> <number> <number>
// ::= $J? <name> <number> <number> <number>
- // ::= $0A@
MSInheritanceAttr::Spelling IM = RD->getMSInheritanceModel();
- // The null member function pointer is $0A@ in function templates and crashes
- // MSVC when used in class templates, so we don't know what they really look
- // like.
- if (!MD) {
- Out << "$0A@";
- return;
- }
-
char Code = '\0';
switch (IM) {
case MSInheritanceAttr::Keyword_single_inheritance: Code = '1'; break;
@@ -519,28 +506,38 @@
case MSInheritanceAttr::Keyword_unspecified_inheritance: Code = 'J'; break;
}
- Out << '$' << Code << '?';
-
// If non-virtual, mangle the name. If virtual, mangle as a virtual memptr
// thunk.
uint64_t NVOffset = 0;
uint64_t VBTableOffset = 0;
uint64_t VBPtrOffset = 0;
- if (MD->isVirtual()) {
- MicrosoftVTableContext *VTContext =
- cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
- const MicrosoftVTableContext::MethodVFTableLocation &ML =
- VTContext->getMethodVFTableLocation(GlobalDecl(MD));
- mangleVirtualMemPtrThunk(MD, ML);
- NVOffset = ML.VFPtrOffset.getQuantity();
- VBTableOffset = ML.VBTableIndex * 4;
- if (ML.VBase) {
- const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
- VBPtrOffset = Layout.getVBPtrOffset().getQuantity();
+ if (MD) {
+ Out << '$' << Code << '?';
+ if (MD->isVirtual()) {
+ MicrosoftVTableContext *VTContext =
+ cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
+ const MicrosoftVTableContext::MethodVFTableLocation &ML =
+ VTContext->getMethodVFTableLocation(GlobalDecl(MD));
+ mangleVirtualMemPtrThunk(MD, ML);
+ NVOffset = ML.VFPtrOffset.getQuantity();
+ VBTableOffset = ML.VBTableIndex * 4;
+ if (ML.VBase) {
+ const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
+ VBPtrOffset = Layout.getVBPtrOffset().getQuantity();
+ }
+ } else {
+ mangleName(MD);
+ mangleFunctionEncoding(MD);
}
} else {
- mangleName(MD);
- mangleFunctionEncoding(MD);
+ // Null single inheritance member functions are encoded as a simple nullptr.
+ if (IM == MSInheritanceAttr::Keyword_single_inheritance) {
+ Out << "$0A@";
+ return;
+ }
+ if (IM == MSInheritanceAttr::Keyword_unspecified_inheritance)
+ VBTableOffset = -1;
+ Out << '$' << Code;
}
if (MSInheritanceAttr::hasNVOffsetField(/*IsMemberFunction=*/true, IM))
@@ -601,8 +598,8 @@
// in the range of ASCII characters 'A' to 'P'.
// The number 0x123450 would be encoded as 'BCDEFA'
char EncodedNumberBuffer[sizeof(uint64_t) * 2];
- llvm::MutableArrayRef<char> BufferRef(EncodedNumberBuffer);
- llvm::MutableArrayRef<char>::reverse_iterator I = BufferRef.rbegin();
+ MutableArrayRef<char> BufferRef(EncodedNumberBuffer);
+ MutableArrayRef<char>::reverse_iterator I = BufferRef.rbegin();
for (; Value != 0; Value >>= 4)
*I++ = 'A' + (Value & 0xf);
Out.write(I.base(), I - BufferRef.rbegin());
@@ -653,6 +650,7 @@
// FIXME: Test alias template mangling with MSVC 2013.
if (!isa<ClassTemplateDecl>(TD)) {
mangleTemplateInstantiationName(TD, *TemplateArgs);
+ Out << '@';
return;
}
@@ -667,30 +665,17 @@
// type [ -> template-parameters]
// \-> namespace[s]
// What we do is we create a new mangler, mangle the same type (without
- // a namespace suffix) using the extra mangler with back references
- // disabled (to avoid infinite recursion) and then use the mangled type
- // name as a key to check the mangling of different types for aliasing.
+ // a namespace suffix) to a string using the extra mangler and then use
+ // the mangled type name as a key to check the mangling of different types
+ // for aliasing.
- std::string BackReferenceKey;
- BackRefMap::iterator Found;
- if (UseNameBackReferences) {
- llvm::raw_string_ostream Stream(BackReferenceKey);
- MicrosoftCXXNameMangler Extra(Context, Stream);
- Extra.disableBackReferences();
- Extra.mangleUnqualifiedName(ND, Name);
- Stream.flush();
+ llvm::SmallString<64> TemplateMangling;
+ llvm::raw_svector_ostream Stream(TemplateMangling);
+ MicrosoftCXXNameMangler Extra(Context, Stream);
+ Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
+ Stream.flush();
- Found = NameBackReferences.find(BackReferenceKey);
- }
- if (!UseNameBackReferences || Found == NameBackReferences.end()) {
- mangleTemplateInstantiationName(TD, *TemplateArgs);
- if (UseNameBackReferences && NameBackReferences.size() < 10) {
- size_t Size = NameBackReferences.size();
- NameBackReferences[BackReferenceKey] = Size;
- }
- } else {
- Out << Found->second;
- }
+ mangleSourceName(TemplateMangling);
return;
}
@@ -803,11 +788,8 @@
break;
case DeclarationName::CXXLiteralOperatorName: {
- // FIXME: Was this added in VS2010? Does MS even know how to mangle this?
- DiagnosticsEngine &Diags = Context.getDiags();
- unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
- "cannot mangle this literal operator yet");
- Diags.Report(ND->getLocation(), DiagID);
+ Out << "?__K";
+ mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
break;
}
@@ -1013,14 +995,19 @@
void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
// <source name> ::= <identifier> @
BackRefMap::iterator Found;
- if (UseNameBackReferences)
+ if (NameBackReferences.size() < 10) {
+ size_t Size = NameBackReferences.size();
+ bool Inserted;
+ std::tie(Found, Inserted) =
+ NameBackReferences.insert(std::make_pair(Name, Size));
+ if (Inserted)
+ Found = NameBackReferences.end();
+ } else {
Found = NameBackReferences.find(Name);
- if (!UseNameBackReferences || Found == NameBackReferences.end()) {
+ }
+
+ if (Found == NameBackReferences.end()) {
Out << Name << '@';
- if (UseNameBackReferences && NameBackReferences.size() < 10) {
- size_t Size = NameBackReferences.size();
- NameBackReferences[Name] = Size;
- }
} else {
Out << Found->second;
}
@@ -1076,6 +1063,9 @@
return;
}
+ // Look through no-op casts like template parameter substitutions.
+ E = E->IgnoreParenNoopCasts(Context.getASTContext());
+
const CXXUuidofExpr *UE = nullptr;
if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
if (UO->getOpcode() == UO_AddrOf)
@@ -1113,10 +1103,9 @@
void MicrosoftCXXNameMangler::mangleTemplateArgs(
const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs) {
- // <template-args> ::= <template-arg>+ @
+ // <template-args> ::= <template-arg>+
for (const TemplateArgument &TA : TemplateArgs.asArray())
mangleTemplateArg(TD, TA);
- Out << '@';
}
void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
@@ -1165,23 +1154,31 @@
QualType T = TA.getNullPtrType();
if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) {
const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
- if (MPT->isMemberFunctionPointerType())
+ if (MPT->isMemberFunctionPointerType() && isa<ClassTemplateDecl>(TD)) {
mangleMemberFunctionPointer(RD, nullptr);
- else
+ return;
+ }
+ if (MPT->isMemberDataPointer()) {
mangleMemberDataPointer(RD, nullptr);
- } else {
- Out << "$0A@";
+ return;
+ }
}
+ Out << "$0A@";
break;
}
case TemplateArgument::Expression:
mangleExpression(TA.getAsExpr());
break;
- case TemplateArgument::Pack:
- // Unlike Itanium, there is no character code to indicate an argument pack.
- for (const TemplateArgument &PA : TA.getPackAsArray())
- mangleTemplateArg(TD, PA);
+ case TemplateArgument::Pack: {
+ ArrayRef<TemplateArgument> TemplateArgs = TA.getPackAsArray();
+ if (TemplateArgs.empty()) {
+ Out << "$S";
+ } else {
+ for (const TemplateArgument &PA : TemplateArgs)
+ mangleTemplateArg(TD, PA);
+ }
break;
+ }
case TemplateArgument::Template:
mangleType(cast<TagDecl>(
TA.getAsTemplate().getAsTemplateDecl()->getTemplatedDecl()));
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index db64f31..caa7cd1 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -2860,11 +2860,20 @@
assert(RD->getDefinition() && "Cannot get key function for forward decl!");
RD = cast<CXXRecordDecl>(RD->getDefinition());
- LazyDeclPtr &Entry = KeyFunctions[RD];
- if (!Entry)
- Entry = const_cast<CXXMethodDecl*>(computeKeyFunction(*this, RD));
+ // Beware:
+ // 1) computing the key function might trigger deserialization, which might
+ // invalidate iterators into KeyFunctions
+ // 2) 'get' on the LazyDeclPtr might also trigger deserialization and
+ // invalidate the LazyDeclPtr within the map itself
+ LazyDeclPtr Entry = KeyFunctions[RD];
+ const Decl *Result =
+ Entry ? Entry.get(getExternalSource()) : computeKeyFunction(*this, RD);
- return cast_or_null<CXXMethodDecl>(Entry.get(getExternalSource()));
+ // Store it back if it changed.
+ if (Entry.isOffset() || Entry.isValid() != bool(Result))
+ KeyFunctions[RD] = const_cast<Decl*>(Result);
+
+ return cast_or_null<CXXMethodDecl>(Result);
}
void ASTContext::setNonKeyFunction(const CXXMethodDecl *Method) {
@@ -2881,10 +2890,12 @@
if (I == KeyFunctions.end()) return;
// If it is cached, check whether it's the target method, and if so,
- // remove it from the cache.
- if (I->second.get(getExternalSource()) == Method) {
+ // remove it from the cache. Note, the call to 'get' might invalidate
+ // the iterator and the LazyDeclPtr object within the map.
+ LazyDeclPtr Ptr = I->second;
+ if (Ptr.get(getExternalSource()) == Method) {
// FIXME: remember that we did this for module / chained PCH state?
- KeyFunctions.erase(I);
+ KeyFunctions.erase(Method->getParent());
}
}
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index 8588dda..9cd3831 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -1168,6 +1168,28 @@
return new (Mem) OMPFirstprivateClause(N);
}
+OMPLastprivateClause *OMPLastprivateClause::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc,
+ ArrayRef<Expr *> VL) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLastprivateClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * VL.size());
+ OMPLastprivateClause *Clause =
+ new (Mem) OMPLastprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ return Clause;
+}
+
+OMPLastprivateClause *OMPLastprivateClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLastprivateClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * N);
+ return new (Mem) OMPLastprivateClause(N);
+}
+
OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -1214,6 +1236,28 @@
return new (Mem) OMPLinearClause(NumVars);
}
+OMPAlignedClause *
+OMPAlignedClause::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation ColonLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * (VL.size() + 1));
+ OMPAlignedClause *Clause = new (Mem)
+ OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ Clause->setAlignment(A);
+ return Clause;
+}
+
+OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,
+ unsigned NumVars) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * (NumVars + 1));
+ return new (Mem) OMPAlignedClause(NumVars);
+}
+
OMPCopyinClause *OMPCopyinClause::Create(const ASTContext &C,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -1236,12 +1280,55 @@
return new (Mem) OMPCopyinClause(N);
}
+OMPCopyprivateClause *OMPCopyprivateClause::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc,
+ ArrayRef<Expr *> VL) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyprivateClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * VL.size());
+ OMPCopyprivateClause *Clause =
+ new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ return Clause;
+}
+
+OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyprivateClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * N);
+ return new (Mem) OMPCopyprivateClause(N);
+}
+
void OMPExecutableDirective::setClauses(ArrayRef<OMPClause *> Clauses) {
assert(Clauses.size() == getNumClauses() &&
"Number of clauses is not the same as the preallocated buffer");
std::copy(Clauses.begin(), Clauses.end(), getClauses().begin());
}
+OMPReductionClause *OMPReductionClause::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
+ NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPReductionClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * VL.size());
+ OMPReductionClause *Clause = new (Mem) OMPReductionClause(
+ StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
+ Clause->setVarRefs(VL);
+ return Clause;
+}
+
+OMPReductionClause *OMPReductionClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPReductionClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * N);
+ return new (Mem) OMPReductionClause(N);
+}
+
OMPParallelDirective *OMPParallelDirective::Create(
const ASTContext &C,
SourceLocation StartLoc,
@@ -1269,17 +1356,16 @@
return new (Mem) OMPParallelDirective(NumClauses);
}
-OMPSimdDirective *OMPSimdDirective::Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt) {
+OMPSimdDirective *
+OMPSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc, unsigned CollapsedNum,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSimdDirective),
llvm::alignOf<OMPClause *>());
- void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
- sizeof(Stmt *));
- OMPSimdDirective *Dir = new (Mem) OMPSimdDirective(StartLoc, EndLoc,
- 1, Clauses.size());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPSimdDirective *Dir = new (Mem)
+ OMPSimdDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
Dir->setClauses(Clauses);
Dir->setAssociatedStmt(AssociatedStmt);
return Dir;
@@ -1291,8 +1377,154 @@
EmptyShell) {
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSimdDirective),
llvm::alignOf<OMPClause *>());
- void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses +
- sizeof(Stmt *));
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
return new (Mem) OMPSimdDirective(CollapsedNum, NumClauses);
}
+OMPForDirective *
+OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc, unsigned CollapsedNum,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPForDirective *Dir =
+ new (Mem) OMPForDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPForDirective *OMPForDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPForDirective(CollapsedNum, NumClauses);
+}
+
+OMPSectionsDirective *OMPSectionsDirective::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPSectionsDirective *Dir =
+ new (Mem) OMPSectionsDirective(StartLoc, EndLoc, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPSectionsDirective *OMPSectionsDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPSectionsDirective(NumClauses);
+}
+
+OMPSectionDirective *OMPSectionDirective::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
+ llvm::alignOf<Stmt *>());
+ void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ OMPSectionDirective *Dir = new (Mem) OMPSectionDirective(StartLoc, EndLoc);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPSectionDirective *OMPSectionDirective::CreateEmpty(const ASTContext &C,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionDirective),
+ llvm::alignOf<Stmt *>());
+ void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ return new (Mem) OMPSectionDirective();
+}
+
+OMPSingleDirective *OMPSingleDirective::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSingleDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPSingleDirective *Dir =
+ new (Mem) OMPSingleDirective(StartLoc, EndLoc, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPSingleDirective *OMPSingleDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSingleDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPSingleDirective(NumClauses);
+}
+
+OMPParallelForDirective *
+OMPParallelForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc, unsigned CollapsedNum,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPParallelForDirective *Dir = new (Mem)
+ OMPParallelForDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPParallelForDirective *
+OMPParallelForDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses,
+ unsigned CollapsedNum, EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPParallelForDirective(CollapsedNum, NumClauses);
+}
+
+OMPParallelSectionsDirective *OMPParallelSectionsDirective::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelSectionsDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPParallelSectionsDirective *Dir =
+ new (Mem) OMPParallelSectionsDirective(StartLoc, EndLoc, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPParallelSectionsDirective *
+OMPParallelSectionsDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelSectionsDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPParallelSectionsDirective(NumClauses);
+}
+
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 0804d40..1d01e65 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -168,8 +168,10 @@
}
void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
- for (const auto *Attr : Node->getAttrs())
+ for (const auto *Attr : Node->getAttrs()) {
Attr->printPretty(OS, Policy);
+ }
+
PrintStmt(Node->getSubStmt(), 0);
}
@@ -571,6 +573,11 @@
OS << "\n";
}
+void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) {
+ Indent() << "__leave;";
+ if (Policy.IncludeNewlines) OS << "\n";
+}
+
//===----------------------------------------------------------------------===//
// OpenMP clauses printing methods
//===----------------------------------------------------------------------===//
@@ -626,11 +633,30 @@
<< ")";
}
+void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
+ OS << "schedule("
+ << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind());
+ if (Node->getChunkSize()) {
+ OS << ", ";
+ Node->getChunkSize()->printPretty(OS, nullptr, Policy);
+ }
+ OS << ")";
+}
+
+void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *) {
+ OS << "ordered";
+}
+
+void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *) {
+ OS << "nowait";
+}
+
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) {
+ assert(*I && "Expected non-null Stmt");
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(*I)) {
OS << (I == Node->varlist_begin() ? StartSym : ',');
cast<NamedDecl>(DRE->getDecl())->printQualifiedName(OS);
@@ -657,6 +683,14 @@
}
}
+void OMPClausePrinter::VisitOMPLastprivateClause(OMPLastprivateClause *Node) {
+ if (!Node->varlist_empty()) {
+ OS << "lastprivate";
+ VisitOMPClauseList(Node, '(');
+ OS << ")";
+ }
+}
+
void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
if (!Node->varlist_empty()) {
OS << "shared";
@@ -665,6 +699,28 @@
}
}
+void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
+ if (!Node->varlist_empty()) {
+ OS << "reduction(";
+ NestedNameSpecifier *QualifierLoc =
+ Node->getQualifierLoc().getNestedNameSpecifier();
+ OverloadedOperatorKind OOK =
+ Node->getNameInfo().getName().getCXXOverloadedOperator();
+ if (QualifierLoc == nullptr && OOK != OO_None) {
+ // Print reduction identifier in C format
+ OS << getOperatorSpelling(OOK);
+ } else {
+ // Use C++ format
+ if (QualifierLoc != nullptr)
+ QualifierLoc->print(OS, Policy);
+ OS << Node->getNameInfo();
+ }
+ OS << ":";
+ VisitOMPClauseList(Node, ' ');
+ OS << ")";
+ }
+}
+
void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
if (!Node->varlist_empty()) {
OS << "linear";
@@ -677,6 +733,18 @@
}
}
+void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {
+ if (!Node->varlist_empty()) {
+ OS << "aligned";
+ VisitOMPClauseList(Node, '(');
+ if (Node->getAlignment() != nullptr) {
+ OS << ": ";
+ Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
+ }
+ OS << ")";
+ }
+}
+
void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
if (!Node->varlist_empty()) {
OS << "copyin";
@@ -685,6 +753,14 @@
}
}
+void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {
+ if (!Node->varlist_empty()) {
+ OS << "copyprivate";
+ VisitOMPClauseList(Node, '(');
+ OS << ")";
+ }
+}
+
}
//===----------------------------------------------------------------------===//
@@ -719,6 +795,37 @@
PrintOMPExecutableDirective(Node);
}
+void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) {
+ Indent() << "#pragma omp for ";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) {
+ Indent() << "#pragma omp sections ";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) {
+ Indent() << "#pragma omp section";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {
+ Indent() << "#pragma omp single ";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {
+ Indent() << "#pragma omp parallel for ";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPParallelSectionsDirective(
+ OMPParallelSectionsDirective *Node) {
+ Indent() << "#pragma omp parallel sections ";
+ PrintOMPExecutableDirective(Node);
+}
+
//===----------------------------------------------------------------------===//
// Expr printing methods.
//===----------------------------------------------------------------------===//
@@ -876,11 +983,10 @@
// Emit suffixes. Integer literals are always a builtin integer type.
switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
default: llvm_unreachable("Unexpected type for integer literal!");
- // FIXME: The Short and UShort cases are to handle cases where a short
- // integeral literal is formed during template instantiation. They should
- // be removed when template instantiation no longer needs integer literals.
- case BuiltinType::Short:
- case BuiltinType::UShort:
+ case BuiltinType::SChar: OS << "i8"; break;
+ case BuiltinType::UChar: OS << "Ui8"; break;
+ case BuiltinType::Short: OS << "i16"; break;
+ case BuiltinType::UShort: OS << "Ui16"; break;
case BuiltinType::Int: break; // no suffix.
case BuiltinType::UInt: OS << 'U'; break;
case BuiltinType::Long: OS << 'L'; break;
@@ -1206,10 +1312,12 @@
DEnd = Node->designators_end();
D != DEnd; ++D) {
if (D->isFieldDesignator()) {
- if (D->getDotLoc().isInvalid())
- OS << D->getFieldName()->getName() << ":";
- else
+ if (D->getDotLoc().isInvalid()) {
+ if (IdentifierInfo *II = D->getFieldName())
+ OS << II->getName() << ":";
+ } else {
OS << "." << D->getFieldName()->getName();
+ }
} else {
OS << "[";
if (D->isArrayDesignator()) {
@@ -1991,11 +2099,6 @@
PrinterHelper *Helper,
const PrintingPolicy &Policy,
unsigned Indentation) const {
- if (this == nullptr) {
- OS << "<NULL>";
- return;
- }
-
StmtPrinter P(OS, Helper, Policy, Indentation);
P.Visit(const_cast<Stmt*>(this));
}
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 9cff6d6..db691a9 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -214,6 +214,10 @@
VisitStmt(S);
}
+void StmtProfiler::VisitSEHLeaveStmt(const SEHLeaveStmt *S) {
+ VisitStmt(S);
+}
+
void StmtProfiler::VisitCapturedStmt(const CapturedStmt *S) {
VisitStmt(S);
}
@@ -288,6 +292,15 @@
void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
+void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) {
+ if (C->getChunkSize())
+ Profiler->VisitStmt(C->getChunkSize());
+}
+
+void OMPClauseProfiler::VisitOMPOrderedClause(const OMPOrderedClause *) {}
+
+void OMPClauseProfiler::VisitOMPNowaitClause(const OMPNowaitClause *) {}
+
template<typename T>
void OMPClauseProfiler::VisitOMPClauseList(T *Node) {
for (auto *I : Node->varlists())
@@ -301,16 +314,35 @@
const OMPFirstprivateClause *C) {
VisitOMPClauseList(C);
}
+void
+OMPClauseProfiler::VisitOMPLastprivateClause(const OMPLastprivateClause *C) {
+ VisitOMPClauseList(C);
+}
void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause *C) {
VisitOMPClauseList(C);
}
+void OMPClauseProfiler::VisitOMPReductionClause(
+ const OMPReductionClause *C) {
+ Profiler->VisitNestedNameSpecifier(
+ C->getQualifierLoc().getNestedNameSpecifier());
+ Profiler->VisitName(C->getNameInfo().getName());
+ VisitOMPClauseList(C);
+}
void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) {
VisitOMPClauseList(C);
Profiler->VisitStmt(C->getStep());
}
+void OMPClauseProfiler::VisitOMPAlignedClause(const OMPAlignedClause *C) {
+ VisitOMPClauseList(C);
+ Profiler->VisitStmt(C->getAlignment());
+}
void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) {
VisitOMPClauseList(C);
}
+void
+OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
+ VisitOMPClauseList(C);
+}
}
void
@@ -332,6 +364,32 @@
VisitOMPExecutableDirective(S);
}
+void StmtProfiler::VisitOMPForDirective(const OMPForDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPSectionsDirective(const OMPSectionsDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPSectionDirective(const OMPSectionDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPSingleDirective(const OMPSingleDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void
+StmtProfiler::VisitOMPParallelForDirective(const OMPParallelForDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPParallelSectionsDirective(
+ const OMPParallelSectionsDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
void StmtProfiler::VisitExpr(const Expr *S) {
VisitStmt(S);
}
@@ -619,11 +677,11 @@
case OO_Star:
if (S->getNumArgs() == 1) {
- UnaryOp = UO_Minus;
+ UnaryOp = UO_Deref;
return Stmt::UnaryOperatorClass;
}
- BinaryOp = BO_Sub;
+ BinaryOp = BO_Mul;
return Stmt::BinaryOperatorClass;
case OO_Slash:
@@ -768,7 +826,7 @@
llvm_unreachable("Invalid overloaded operator expression");
}
-
+
void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
if (S->isTypeDependent()) {
@@ -777,7 +835,7 @@
UnaryOperatorKind UnaryOp = UO_Extension;
BinaryOperatorKind BinaryOp = BO_Comma;
Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp);
-
+
ID.AddInteger(SC);
for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
Visit(S->getArg(I));
@@ -788,10 +846,10 @@
ID.AddInteger(BinaryOp);
else
assert(SC == Stmt::ArraySubscriptExprClass);
-
+
return;
}
-
+
VisitCallExpr(S);
ID.AddInteger(S->getOperator());
}
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index dfb43a0..8e2cea3 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -593,7 +593,8 @@
OS << " noexcept";
if (getExceptionSpecType() == EST_ComputedNoexcept) {
OS << '(';
- getNoexceptExpr()->printPretty(OS, nullptr, Policy);
+ if (getNoexceptExpr())
+ getNoexceptExpr()->printPretty(OS, nullptr, Policy);
OS << ')';
}
}
@@ -761,7 +762,8 @@
void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
raw_ostream &OS) {
OS << "typeof ";
- T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
+ if (T->getUnderlyingExpr())
+ T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
spaceBeforePlaceHolder(OS);
}
void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
@@ -777,7 +779,8 @@
void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
OS << "decltype(";
- T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
+ if (T->getUnderlyingExpr())
+ T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
OS << ')';
spaceBeforePlaceHolder(OS);
}
diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp
index 6dc3956..fa1127f 100644
--- a/lib/AST/VTableBuilder.cpp
+++ b/lib/AST/VTableBuilder.cpp
@@ -2446,6 +2446,9 @@
MethodVFTableLocationsTy MethodVFTableLocations;
+ /// \brief Does this class have an RTTI component?
+ bool HasRTTIComponent;
+
/// MethodInfo - Contains information about a method in a vtable.
/// (Used for computing 'this' pointer adjustment thunks.
struct MethodInfo {
@@ -2574,6 +2577,13 @@
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>();
+ if (HasRTTIComponent)
+ Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass));
+
LayoutVFTable();
if (Context.getLangOpts().DumpVTableLayouts)
@@ -2915,7 +2925,8 @@
// it requires return adjustment. Insert the method info for this method.
unsigned VBIndex =
LastVBase ? VTables.getVBTableIndex(MostDerivedClass, LastVBase) : 0;
- MethodInfo MI(VBIndex, Components.size());
+ MethodInfo MI(VBIndex,
+ HasRTTIComponent ? Components.size() - 1 : Components.size());
assert(!MethodInfoMap.count(MD) &&
"Should not have method info for this method yet!");
@@ -3120,9 +3131,8 @@
}
static bool setsIntersect(const llvm::SmallPtrSet<const CXXRecordDecl *, 4> &A,
- const llvm::ArrayRef<const CXXRecordDecl *> &B) {
- for (llvm::ArrayRef<const CXXRecordDecl *>::iterator I = B.begin(),
- E = B.end();
+ const ArrayRef<const CXXRecordDecl *> &B) {
+ for (ArrayRef<const CXXRecordDecl *>::iterator I = B.begin(), E = B.end();
I != E; ++I) {
if (A.count(*I))
return true;