summaryrefslogtreecommitdiffstats
path: root/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST')
-rw-r--r--lib/AST/ASTConsumer.cpp1
-rw-r--r--lib/AST/ASTContext.cpp11
-rw-r--r--lib/AST/ASTImporter.cpp7
-rw-r--r--lib/AST/Decl.cpp3
-rw-r--r--lib/AST/DeclObjC.cpp8
-rw-r--r--lib/AST/DeclPrinter.cpp68
-rw-r--r--lib/AST/DeclTemplate.cpp34
-rw-r--r--lib/AST/Expr.cpp85
-rw-r--r--lib/AST/ExprClassification.cpp2
-rw-r--r--lib/AST/ExprConstant.cpp2
-rw-r--r--lib/AST/ItaniumMangle.cpp11
-rw-r--r--lib/AST/MicrosoftCXXABI.cpp5
-rw-r--r--lib/AST/MicrosoftMangle.cpp12
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp2
-rw-r--r--lib/AST/Stmt.cpp33
-rw-r--r--lib/AST/StmtPrinter.cpp21
-rw-r--r--lib/AST/StmtProfile.cpp16
-rw-r--r--lib/AST/Type.cpp152
-rw-r--r--lib/AST/TypePrinter.cpp37
19 files changed, 451 insertions, 59 deletions
diff --git a/lib/AST/ASTConsumer.cpp b/lib/AST/ASTConsumer.cpp
index 55033b2..cff82e9 100644
--- a/lib/AST/ASTConsumer.cpp
+++ b/lib/AST/ASTConsumer.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#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 4a831d9..049eebd 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -5610,8 +5610,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
// @encode(class_name)
ObjCInterfaceDecl *OI = OIT->getDecl();
S += '{';
- const IdentifierInfo *II = OI->getIdentifier();
- S += II->getName();
+ S += OI->getObjCRuntimeNameAsString();
S += '=';
SmallVector<const ObjCIvarDecl*, 32> Ivars;
DeepCollectObjCIvars(OI, true, Ivars);
@@ -5654,7 +5653,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
S += '"';
for (const auto *I : OPT->quals()) {
S += '<';
- S += I->getNameAsString();
+ S += I->getObjCRuntimeNameAsString();
S += '>';
}
S += '"';
@@ -5678,7 +5677,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
for (unsigned i = 0, e = Ivars.size(); i != e; ++i) {
if (cast<FieldDecl>(Ivars[i]) == FD) {
S += '{';
- S += OI->getIdentifier()->getName();
+ S += OI->getObjCRuntimeNameAsString();
S += '}';
return;
}
@@ -5696,10 +5695,10 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
if (OPT->getInterfaceDecl() &&
(FD || EncodingProperty || EncodeClassNames)) {
S += '"';
- S += OPT->getInterfaceDecl()->getIdentifier()->getName();
+ S += OPT->getInterfaceDecl()->getObjCRuntimeNameAsString();
for (const auto *I : OPT->quals()) {
S += '<';
- S += I->getNameAsString();
+ S += I->getObjCRuntimeNameAsString();
S += '>';
}
S += '"';
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 911f168..76e4e11 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -3922,8 +3922,8 @@ Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
}
// Import the type.
- TypeSourceInfo *T = Importer.Import(D->getTypeSourceInfo());
- if (!T)
+ TypeSourceInfo *TSI = Importer.Import(D->getTypeSourceInfo());
+ if (!TSI)
return nullptr;
// Create the new property.
@@ -3932,7 +3932,8 @@ Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
Name.getAsIdentifierInfo(),
Importer.Import(D->getAtLoc()),
Importer.Import(D->getLParenLoc()),
- T,
+ Importer.Import(D->getType()),
+ TSI,
D->getPropertyImplementation());
Importer.Imported(D, ToProperty);
ToProperty->setLexicalDeclContext(LexicalDC);
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 8eff4c4..d9a3389 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -3681,7 +3681,8 @@ void RecordDecl::LoadFieldsFromExternalStorage() const {
bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const {
ASTContext &Context = getASTContext();
- if (!Context.getLangOpts().Sanitize.has(SanitizerKind::Address) ||
+ if (!Context.getLangOpts().Sanitize.hasOneOf(
+ SanitizerKind::Address | SanitizerKind::KernelAddress) ||
!Context.getLangOpts().SanitizeAddressFieldPadding)
return false;
const auto &Blacklist = Context.getSanitizerBlacklist();
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index a63ba7e..a1600cb 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -1862,16 +1862,18 @@ ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id,
SourceLocation AtLoc,
SourceLocation LParenLoc,
- TypeSourceInfo *T,
+ QualType T,
+ TypeSourceInfo *TSI,
PropertyControl propControl) {
- return new (C, DC) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T);
+ return new (C, DC) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T, TSI,
+ propControl);
}
ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr,
SourceLocation(), SourceLocation(),
- nullptr);
+ QualType(), nullptr, None);
}
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index d8cd40e..c3ce476 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -37,6 +37,13 @@ namespace {
void Print(AccessSpecifier AS);
+ /// Print an Objective-C method type in parentheses.
+ ///
+ /// \param Quals The Objective-C declaration qualifiers.
+ /// \param T The type to print.
+ void PrintObjCMethodType(ASTContext &Ctx, Decl::ObjCDeclQualifier Quals,
+ QualType T);
+
public:
DeclPrinter(raw_ostream &Out, const PrintingPolicy &Policy,
unsigned Indentation = 0, bool PrintInstantiation = false)
@@ -930,24 +937,52 @@ void DeclPrinter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
// Objective-C declarations
//----------------------------------------------------------------------------
+void DeclPrinter::PrintObjCMethodType(ASTContext &Ctx,
+ Decl::ObjCDeclQualifier Quals,
+ QualType T) {
+ Out << '(';
+ if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_In)
+ Out << "in ";
+ if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_Inout)
+ Out << "inout ";
+ if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_Out)
+ Out << "out ";
+ if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_Bycopy)
+ Out << "bycopy ";
+ if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_Byref)
+ Out << "byref ";
+ if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_Oneway)
+ Out << "oneway ";
+ if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_CSNullability) {
+ if (auto nullability = AttributedType::stripOuterNullability(T)) {
+ Out << getNullabilitySpelling(*nullability).substr(2) << ' ';
+ }
+ }
+
+ Out << Ctx.getUnqualifiedObjCPointerType(T).getAsString(Policy);
+ Out << ')';
+}
+
void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) {
if (OMD->isInstanceMethod())
Out << "- ";
else
Out << "+ ";
- if (!OMD->getReturnType().isNull())
- Out << '(' << OMD->getASTContext()
- .getUnqualifiedObjCPointerType(OMD->getReturnType())
- .getAsString(Policy) << ")";
+ if (!OMD->getReturnType().isNull()) {
+ PrintObjCMethodType(OMD->getASTContext(), OMD->getObjCDeclQualifier(),
+ OMD->getReturnType());
+ }
std::string name = OMD->getSelector().getAsString();
std::string::size_type pos, lastPos = 0;
for (const auto *PI : OMD->params()) {
// FIXME: selector is missing here!
pos = name.find_first_of(':', lastPos);
- Out << " " << name.substr(lastPos, pos - lastPos);
- Out << ":(" << PI->getASTContext().getUnqualifiedObjCPointerType(PI->getType()).
- getAsString(Policy) << ')' << *PI;
+ Out << " " << name.substr(lastPos, pos - lastPos) << ':';
+ PrintObjCMethodType(OMD->getASTContext(),
+ PI->getObjCDeclQualifier(),
+ PI->getType());
+ Out << *PI;
lastPos = pos + 1;
}
@@ -1103,6 +1138,8 @@ void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
else if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Optional)
Out << "@optional\n";
+ QualType T = PDecl->getType();
+
Out << "@property";
if (PDecl->getPropertyAttributes() != ObjCPropertyDecl::OBJC_PR_noattr) {
bool first = true;
@@ -1161,10 +1198,25 @@ void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
first = false;
}
+ if (PDecl->getPropertyAttributes() &
+ ObjCPropertyDecl::OBJC_PR_nullability) {
+ if (auto nullability = AttributedType::stripOuterNullability(T)) {
+ if (*nullability == NullabilityKind::Unspecified &&
+ (PDecl->getPropertyAttributes() &
+ ObjCPropertyDecl::OBJC_PR_null_resettable)) {
+ Out << (first ? ' ' : ',') << "null_resettable";
+ } else {
+ Out << (first ? ' ' : ',')
+ << getNullabilitySpelling(*nullability).substr(2);
+ }
+ first = false;
+ }
+ }
+
(void) first; // Silence dead store warning due to idiomatic code.
Out << " )";
}
- Out << ' ' << PDecl->getASTContext().getUnqualifiedObjCPointerType(PDecl->getType()).
+ Out << ' ' << PDecl->getASTContext().getUnqualifiedObjCPointerType(T).
getAsString(Policy) << ' ' << *PDecl;
if (Policy.PolishForDeclaration)
Out << ';';
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 6374a92..cde497b 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -124,6 +124,12 @@ static void AdoptTemplateParameterList(TemplateParameterList *Params,
}
}
+namespace clang {
+void *allocateDefaultArgStorageChain(const ASTContext &C) {
+ return new (C) char[sizeof(void*) * 2];
+}
+}
+
//===----------------------------------------------------------------------===//
// RedeclarableTemplateDecl Implementation
//===----------------------------------------------------------------------===//
@@ -504,14 +510,14 @@ TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
return hasDefaultArgument()
- ? DefaultArgument->getTypeLoc().getBeginLoc()
- : SourceLocation();
+ ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
+ : SourceLocation();
}
SourceRange TemplateTypeParmDecl::getSourceRange() const {
if (hasDefaultArgument() && !defaultArgumentWasInherited())
return SourceRange(getLocStart(),
- DefaultArgument->getTypeLoc().getEndLoc());
+ getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
else
return TypeDecl::getSourceRange();
}
@@ -543,10 +549,8 @@ NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
unsigned NumExpandedTypes,
TypeSourceInfo **ExpandedTInfos)
: DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
- TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false),
- ParameterPack(true), ExpandedParameterPack(true),
- NumExpandedTypes(NumExpandedTypes)
-{
+ TemplateParmPosition(D, P), ParameterPack(true),
+ ExpandedParameterPack(true), NumExpandedTypes(NumExpandedTypes) {
if (ExpandedTypes && ExpandedTInfos) {
void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
for (unsigned I = 0; I != NumExpandedTypes; ++I) {
@@ -621,8 +625,7 @@ TemplateTemplateParmDecl::TemplateTemplateParmDecl(
IdentifierInfo *Id, TemplateParameterList *Params,
unsigned NumExpansions, TemplateParameterList * const *Expansions)
: TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
- TemplateParmPosition(D, P), DefaultArgument(),
- DefaultArgumentWasInherited(false), ParameterPack(true),
+ TemplateParmPosition(D, P), ParameterPack(true),
ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
if (Expansions)
std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
@@ -663,6 +666,19 @@ TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
nullptr, NumExpansions, nullptr);
}
+SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
+ return hasDefaultArgument() ? getDefaultArgument().getLocation()
+ : SourceLocation();
+}
+
+void TemplateTemplateParmDecl::setDefaultArgument(
+ const ASTContext &C, const TemplateArgumentLoc &DefArg) {
+ if (DefArg.getArgument().isNull())
+ DefaultArgument.set(nullptr);
+ else
+ DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
+}
+
//===----------------------------------------------------------------------===//
// TemplateArgumentList Implementation
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 76a4da2..36f4139 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1238,7 +1238,7 @@ unsigned CallExpr::getBuiltinCallee() const {
return FDecl->getBuiltinID();
}
-bool CallExpr::isUnevaluatedBuiltinCall(ASTContext &Ctx) const {
+bool CallExpr::isUnevaluatedBuiltinCall(const ASTContext &Ctx) const {
if (unsigned BI = getBuiltinCallee())
return Ctx.BuiltinInfo.isUnevaluated(BI);
return false;
@@ -2772,6 +2772,11 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
const Expr *Exp = cast<CompoundLiteralExpr>(this)->getInitializer();
return Exp->isConstantInitializer(Ctx, false, Culprit);
}
+ case DesignatedInitUpdateExprClass: {
+ const DesignatedInitUpdateExpr *DIUE = cast<DesignatedInitUpdateExpr>(this);
+ return DIUE->getBase()->isConstantInitializer(Ctx, false, Culprit) &&
+ DIUE->getUpdater()->isConstantInitializer(Ctx, false, Culprit);
+ }
case InitListExprClass: {
const InitListExpr *ILE = cast<InitListExpr>(this);
if (ILE->getType()->isArrayType()) {
@@ -2818,6 +2823,7 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
break;
}
case ImplicitValueInitExprClass:
+ case NoInitExprClass:
return true;
case ParenExprClass:
return cast<ParenExpr>(this)->getSubExpr()
@@ -2881,6 +2887,28 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
return false;
}
+namespace {
+ /// \brief Look for any side effects within a Stmt.
+ class SideEffectFinder : public ConstEvaluatedExprVisitor<SideEffectFinder> {
+ typedef ConstEvaluatedExprVisitor<SideEffectFinder> Inherited;
+ const bool IncludePossibleEffects;
+ bool HasSideEffects;
+
+ public:
+ explicit SideEffectFinder(const ASTContext &Context, bool IncludePossible)
+ : Inherited(Context),
+ IncludePossibleEffects(IncludePossible), HasSideEffects(false) { }
+
+ bool hasSideEffects() const { return HasSideEffects; }
+
+ void VisitExpr(const Expr *E) {
+ if (!HasSideEffects &&
+ E->HasSideEffects(Context, IncludePossibleEffects))
+ HasSideEffects = true;
+ }
+ };
+}
+
bool Expr::HasSideEffects(const ASTContext &Ctx,
bool IncludePossibleEffects) const {
// In circumstances where we care about definite side effects instead of
@@ -2925,6 +2953,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case UnaryExprOrTypeTraitExprClass:
case AddrLabelExprClass:
case GNUNullExprClass:
+ case NoInitExprClass:
case CXXBoolLiteralExprClass:
case CXXNullPtrLiteralExprClass:
case CXXThisExprClass:
@@ -2967,7 +2996,6 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case CompoundAssignOperatorClass:
case VAArgExprClass:
case AtomicExprClass:
- case StmtExprClass:
case CXXThrowExprClass:
case CXXNewExprClass:
case CXXDeleteExprClass:
@@ -2975,6 +3003,13 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
// These always have a side-effect.
return true;
+ case StmtExprClass: {
+ // StmtExprs have a side-effect if any substatement does.
+ SideEffectFinder Finder(Ctx, IncludePossibleEffects);
+ Finder.Visit(cast<StmtExpr>(this)->getSubStmt());
+ return Finder.hasSideEffects();
+ }
+
case ParenExprClass:
case ArraySubscriptExprClass:
case MemberExprClass:
@@ -2983,6 +3018,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case CompoundLiteralExprClass:
case ExtVectorElementExprClass:
case DesignatedInitExprClass:
+ case DesignatedInitUpdateExprClass:
case ParenListExprClass:
case CXXPseudoDestructorExprClass:
case CXXStdInitializerListExprClass:
@@ -3128,21 +3164,21 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
namespace {
/// \brief Look for a call to a non-trivial function within an expression.
- class NonTrivialCallFinder : public EvaluatedExprVisitor<NonTrivialCallFinder>
+ class NonTrivialCallFinder : public ConstEvaluatedExprVisitor<NonTrivialCallFinder>
{
- typedef EvaluatedExprVisitor<NonTrivialCallFinder> Inherited;
-
+ typedef ConstEvaluatedExprVisitor<NonTrivialCallFinder> Inherited;
+
bool NonTrivial;
public:
- explicit NonTrivialCallFinder(ASTContext &Context)
+ explicit NonTrivialCallFinder(const ASTContext &Context)
: Inherited(Context), NonTrivial(false) { }
bool hasNonTrivialCall() const { return NonTrivial; }
-
- void VisitCallExpr(CallExpr *E) {
- if (CXXMethodDecl *Method
- = dyn_cast_or_null<CXXMethodDecl>(E->getCalleeDecl())) {
+
+ void VisitCallExpr(const CallExpr *E) {
+ if (const CXXMethodDecl *Method
+ = dyn_cast_or_null<const CXXMethodDecl>(E->getCalleeDecl())) {
if (Method->isTrivial()) {
// Recurse to children of the call.
Inherited::VisitStmt(E);
@@ -3152,8 +3188,8 @@ namespace {
NonTrivial = true;
}
-
- void VisitCXXConstructExpr(CXXConstructExpr *E) {
+
+ void VisitCXXConstructExpr(const CXXConstructExpr *E) {
if (E->getConstructor()->isTrivial()) {
// Recurse to children of the call.
Inherited::VisitStmt(E);
@@ -3162,8 +3198,8 @@ namespace {
NonTrivial = true;
}
-
- void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
+
+ void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E) {
if (E->getTemporary()->getDestructor()->isTrivial()) {
Inherited::VisitStmt(E);
return;
@@ -3174,7 +3210,7 @@ namespace {
};
}
-bool Expr::hasNonTrivialCall(ASTContext &Ctx) {
+bool Expr::hasNonTrivialCall(const ASTContext &Ctx) const {
NonTrivialCallFinder Finder(Ctx);
Finder.Visit(this);
return Finder.hasNonTrivialCall();
@@ -3989,6 +4025,25 @@ void DesignatedInitExpr::ExpandDesignator(const ASTContext &C, unsigned Idx,
NumDesignators = NumDesignators - 1 + NumNewDesignators;
}
+DesignatedInitUpdateExpr::DesignatedInitUpdateExpr(const ASTContext &C,
+ SourceLocation lBraceLoc, Expr *baseExpr, SourceLocation rBraceLoc)
+ : Expr(DesignatedInitUpdateExprClass, baseExpr->getType(), VK_RValue,
+ OK_Ordinary, false, false, false, false) {
+ BaseAndUpdaterExprs[0] = baseExpr;
+
+ InitListExpr *ILE = new (C) InitListExpr(C, lBraceLoc, None, rBraceLoc);
+ ILE->setType(baseExpr->getType());
+ BaseAndUpdaterExprs[1] = ILE;
+}
+
+SourceLocation DesignatedInitUpdateExpr::getLocStart() const {
+ return getBase()->getLocStart();
+}
+
+SourceLocation DesignatedInitUpdateExpr::getLocEnd() const {
+ return getBase()->getLocEnd();
+}
+
ParenListExpr::ParenListExpr(const ASTContext& C, SourceLocation lparenloc,
ArrayRef<Expr*> exprs,
SourceLocation rparenloc)
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
index 5b320c2..9cc612e 100644
--- a/lib/AST/ExprClassification.cpp
+++ b/lib/AST/ExprClassification.cpp
@@ -183,6 +183,8 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
case Expr::ObjCIndirectCopyRestoreExprClass:
case Expr::AtomicExprClass:
case Expr::CXXFoldExprClass:
+ case Expr::NoInitExprClass:
+ case Expr::DesignatedInitUpdateExprClass:
return Cl::CL_PRValue;
// Next come the complicated cases.
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index be24a2a..8e472f1 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -8675,6 +8675,8 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
case Expr::CompoundLiteralExprClass:
case Expr::ExtVectorElementExprClass:
case Expr::DesignatedInitExprClass:
+ case Expr::NoInitExprClass:
+ case Expr::DesignatedInitUpdateExprClass:
case Expr::ImplicitValueInitExprClass:
case Expr::ParenListExprClass:
case Expr::VAArgExprClass:
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index d07efae..e5a31f8 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -2010,7 +2010,11 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
case BuiltinType::Half: Out << "Dh"; break;
case BuiltinType::Float: Out << 'f'; break;
case BuiltinType::Double: Out << 'd'; break;
- case BuiltinType::LongDouble: Out << 'e'; break;
+ case BuiltinType::LongDouble:
+ Out << (getASTContext().getTargetInfo().useFloat128ManglingForLongDouble()
+ ? 'g'
+ : 'e');
+ break;
case BuiltinType::NullPtr: Out << "Dn"; break;
#define BUILTIN_TYPE(Id, SingletonId)
@@ -2676,7 +2680,9 @@ recurse:
// These all can only appear in local or variable-initialization
// contexts and so should never appear in a mangling.
case Expr::AddrLabelExprClass:
+ case Expr::DesignatedInitUpdateExprClass:
case Expr::ImplicitValueInitExprClass:
+ case Expr::NoInitExprClass:
case Expr::ParenListExprClass:
case Expr::LambdaExprClass:
case Expr::MSPropertyRefExprClass:
@@ -4060,8 +4066,7 @@ void ItaniumMangleContextImpl::mangleTypeName(QualType Ty, raw_ostream &Out) {
void ItaniumMangleContextImpl::mangleCXXVTableBitSet(const CXXRecordDecl *RD,
raw_ostream &Out) {
- Linkage L = RD->getLinkageInternal();
- if (L == InternalLinkage || L == UniqueExternalLinkage) {
+ if (!RD->isExternallyVisible()) {
// This part of the identifier needs to be unique across all translation
// units in the linked program. The scheme fails if multiple translation
// units are compiled using the same relative source file path, or if
diff --git a/lib/AST/MicrosoftCXXABI.cpp b/lib/AST/MicrosoftCXXABI.cpp
index 93ff77a..aba6796 100644
--- a/lib/AST/MicrosoftCXXABI.cpp
+++ b/lib/AST/MicrosoftCXXABI.cpp
@@ -179,8 +179,9 @@ MSVtorDispAttr::Mode CXXRecordDecl::getMSVtorDispMode() const {
// // slot.
// void *FunctionPointerOrVirtualThunk;
//
-// // An offset to add to the address of the vbtable pointer after (possibly)
-// // selecting the virtual base but before resolving and calling the function.
+// // An offset to add to the address of the vbtable pointer after
+// // (possibly) selecting the virtual base but before resolving and calling
+// // the function.
// // Only needed if the class has any virtual bases or bases at a non-zero
// // offset.
// int NonVirtualBaseAdjustment;
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index db5b48e..29a95a5 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -2761,7 +2761,17 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
void MicrosoftMangleContextImpl::mangleCXXVTableBitSet(const CXXRecordDecl *RD,
raw_ostream &Out) {
- llvm::report_fatal_error("Cannot mangle bitsets yet");
+ if (!RD->isExternallyVisible()) {
+ // This part of the identifier needs to be unique across all translation
+ // units in the linked program. The scheme fails if multiple translation
+ // units are compiled using the same relative source file path, or if
+ // multiple translation units are built from the same source file.
+ SourceManager &SM = getASTContext().getSourceManager();
+ Out << "[" << SM.getFileEntryForID(SM.getMainFileID())->getName() << "]";
+ }
+
+ MicrosoftCXXNameMangler mangler(*this, Out);
+ mangler.mangleName(RD);
}
MicrosoftMangleContext *
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index 2101a55..388c91c 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -1467,7 +1467,7 @@ void RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
// ms_struct basically requests a complete replacement of the
// platform ABI's struct-layout algorithm, with the high-level goal
// of duplicating MSVC's layout. For non-bitfields, this follows
- // the the standard algorithm. The basic bitfield layout rule is to
+ // the standard algorithm. The basic bitfield layout rule is to
// allocate an entire unit of the bitfield's declared type
// (e.g. 'unsigned long'), then parcel it up among successive
// bitfields whose declared types have the same size, making a new
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index 09bb17b..6f4a89f 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -1636,7 +1636,7 @@ OMPSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc,
Dir->setLastIteration(Exprs.LastIteration);
Dir->setCalcLastIteration(Exprs.CalcLastIteration);
Dir->setPreCond(Exprs.PreCond);
- Dir->setCond(Exprs.Cond, Exprs.SeparatedCond);
+ Dir->setCond(Exprs.Cond);
Dir->setInit(Exprs.Init);
Dir->setInc(Exprs.Inc);
Dir->setCounters(Exprs.Counters);
@@ -1675,7 +1675,7 @@ OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
Dir->setLastIteration(Exprs.LastIteration);
Dir->setCalcLastIteration(Exprs.CalcLastIteration);
Dir->setPreCond(Exprs.PreCond);
- Dir->setCond(Exprs.Cond, Exprs.SeparatedCond);
+ Dir->setCond(Exprs.Cond);
Dir->setInit(Exprs.Init);
Dir->setInc(Exprs.Inc);
Dir->setIsLastIterVariable(Exprs.IL);
@@ -1721,7 +1721,7 @@ OMPForSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc,
Dir->setLastIteration(Exprs.LastIteration);
Dir->setCalcLastIteration(Exprs.CalcLastIteration);
Dir->setPreCond(Exprs.PreCond);
- Dir->setCond(Exprs.Cond, Exprs.SeparatedCond);
+ Dir->setCond(Exprs.Cond);
Dir->setInit(Exprs.Init);
Dir->setInc(Exprs.Inc);
Dir->setIsLastIterVariable(Exprs.IL);
@@ -1777,7 +1777,7 @@ OMPSectionDirective *OMPSectionDirective::Create(const ASTContext &C,
SourceLocation StartLoc,
SourceLocation EndLoc,
Stmt *AssociatedStmt) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionDirective),
llvm::alignOf<Stmt *>());
void *Mem = C.Allocate(Size + sizeof(Stmt *));
OMPSectionDirective *Dir = new (Mem) OMPSectionDirective(StartLoc, EndLoc);
@@ -1876,7 +1876,7 @@ OMPParallelForDirective *OMPParallelForDirective::Create(
Dir->setLastIteration(Exprs.LastIteration);
Dir->setCalcLastIteration(Exprs.CalcLastIteration);
Dir->setPreCond(Exprs.PreCond);
- Dir->setCond(Exprs.Cond, Exprs.SeparatedCond);
+ Dir->setCond(Exprs.Cond);
Dir->setInit(Exprs.Init);
Dir->setInc(Exprs.Inc);
Dir->setIsLastIterVariable(Exprs.IL);
@@ -1920,7 +1920,7 @@ OMPParallelForSimdDirective *OMPParallelForSimdDirective::Create(
Dir->setLastIteration(Exprs.LastIteration);
Dir->setCalcLastIteration(Exprs.CalcLastIteration);
Dir->setPreCond(Exprs.PreCond);
- Dir->setCond(Exprs.Cond, Exprs.SeparatedCond);
+ Dir->setCond(Exprs.Cond);
Dir->setInit(Exprs.Init);
Dir->setInc(Exprs.Inc);
Dir->setIsLastIterVariable(Exprs.IL);
@@ -2041,6 +2041,27 @@ OMPTaskwaitDirective *OMPTaskwaitDirective::CreateEmpty(const ASTContext &C,
return new (Mem) OMPTaskwaitDirective();
}
+OMPTaskgroupDirective *OMPTaskgroupDirective::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskgroupDirective),
+ llvm::alignOf<Stmt *>());
+ void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ OMPTaskgroupDirective *Dir =
+ new (Mem) OMPTaskgroupDirective(StartLoc, EndLoc);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPTaskgroupDirective *OMPTaskgroupDirective::CreateEmpty(const ASTContext &C,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskgroupDirective),
+ llvm::alignOf<Stmt *>());
+ void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ return new (Mem) OMPTaskgroupDirective();
+}
+
OMPFlushDirective *OMPFlushDirective::Create(const ASTContext &C,
SourceLocation StartLoc,
SourceLocation EndLoc,
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index db6d8c2..658e3df 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -910,6 +910,11 @@ void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {
PrintOMPExecutableDirective(Node);
}
+void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) {
+ Indent() << "#pragma omp taskgroup";
+ PrintOMPExecutableDirective(Node);
+}
+
void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
Indent() << "#pragma omp flush ";
PrintOMPExecutableDirective(Node);
@@ -1430,6 +1435,22 @@ void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
PrintExpr(Node->getInit());
}
+void StmtPrinter::VisitDesignatedInitUpdateExpr(
+ DesignatedInitUpdateExpr *Node) {
+ OS << "{";
+ OS << "/*base*/";
+ PrintExpr(Node->getBase());
+ OS << ", ";
+
+ OS << "/*updater*/";
+ PrintExpr(Node->getUpdater());
+ OS << "}";
+}
+
+void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) {
+ OS << "/*no init*/";
+}
+
void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
if (Policy.LangOpts.CPlusPlus) {
OS << "/*implicit*/";
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index c66b153..23f8d0c 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -510,6 +510,10 @@ void StmtProfiler::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *S) {
VisitOMPExecutableDirective(S);
}
+void StmtProfiler::VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective *S) {
VisitOMPExecutableDirective(S);
}
@@ -744,6 +748,18 @@ void StmtProfiler::VisitDesignatedInitExpr(const DesignatedInitExpr *S) {
}
}
+// Seems that if VisitInitListExpr() only works on the syntactic form of an
+// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
+void StmtProfiler::VisitDesignatedInitUpdateExpr(
+ const DesignatedInitUpdateExpr *S) {
+ llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
+ "initializer");
+}
+
+void StmtProfiler::VisitNoInitExpr(const NoInitExpr *S) {
+ llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
+}
+
void StmtProfiler::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *S) {
VisitExpr(S);
}
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 09bb769..3ac1171 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1919,7 +1919,10 @@ bool AttributedType::isCallingConv() const {
case attr_objc_gc:
case attr_objc_ownership:
case attr_noreturn:
- return false;
+ case attr_nonnull:
+ case attr_nullable:
+ case attr_null_unspecified:
+ return false;
case attr_pcs:
case attr_pcs_vfp:
case attr_cdecl:
@@ -2340,6 +2343,153 @@ LinkageInfo Type::getLinkageAndVisibility() const {
return LV;
}
+Optional<NullabilityKind> Type::getNullability(const ASTContext &context) const {
+ QualType type(this, 0);
+ do {
+ // Check whether this is an attributed type with nullability
+ // information.
+ if (auto attributed = dyn_cast<AttributedType>(type.getTypePtr())) {
+ if (auto nullability = attributed->getImmediateNullability())
+ return nullability;
+ }
+
+ // Desugar the type. If desugaring does nothing, we're done.
+ QualType desugared = type.getSingleStepDesugaredType(context);
+ if (desugared.getTypePtr() == type.getTypePtr())
+ return None;
+
+ type = desugared;
+ } while (true);
+}
+
+bool Type::canHaveNullability() const {
+ QualType type = getCanonicalTypeInternal();
+
+ switch (type->getTypeClass()) {
+ // We'll only see canonical types here.
+#define NON_CANONICAL_TYPE(Class, Parent) \
+ case Type::Class: \
+ llvm_unreachable("non-canonical type");
+#define TYPE(Class, Parent)
+#include "clang/AST/TypeNodes.def"
+
+ // Pointer types.
+ case Type::Pointer:
+ case Type::BlockPointer:
+ case Type::MemberPointer:
+ case Type::ObjCObjectPointer:
+ return true;
+
+ // Dependent types that could instantiate to pointer types.
+ case Type::UnresolvedUsing:
+ case Type::TypeOfExpr:
+ case Type::TypeOf:
+ case Type::Decltype:
+ case Type::UnaryTransform:
+ case Type::TemplateTypeParm:
+ case Type::SubstTemplateTypeParmPack:
+ case Type::DependentName:
+ case Type::DependentTemplateSpecialization:
+ return true;
+
+ // Dependent template specializations can instantiate to pointer
+ // types unless they're known to be specializations of a class
+ // template.
+ case Type::TemplateSpecialization:
+ if (TemplateDecl *templateDecl
+ = cast<TemplateSpecializationType>(type.getTypePtr())
+ ->getTemplateName().getAsTemplateDecl()) {
+ if (isa<ClassTemplateDecl>(templateDecl))
+ return false;
+ }
+ return true;
+
+ // auto is considered dependent when it isn't deduced.
+ case Type::Auto:
+ return !cast<AutoType>(type.getTypePtr())->isDeduced();
+
+ case Type::Builtin:
+ switch (cast<BuiltinType>(type.getTypePtr())->getKind()) {
+ // Signed, unsigned, and floating-point types cannot have nullability.
+#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
+#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
+#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
+#define BUILTIN_TYPE(Id, SingletonId)
+#include "clang/AST/BuiltinTypes.def"
+ return false;
+
+ // Dependent types that could instantiate to a pointer type.
+ case BuiltinType::Dependent:
+ case BuiltinType::Overload:
+ case BuiltinType::BoundMember:
+ case BuiltinType::PseudoObject:
+ case BuiltinType::UnknownAny:
+ case BuiltinType::ARCUnbridgedCast:
+ return true;
+
+ case BuiltinType::Void:
+ 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::OCLImage3d:
+ case BuiltinType::OCLSampler:
+ case BuiltinType::OCLEvent:
+ case BuiltinType::BuiltinFn:
+ case BuiltinType::NullPtr:
+ return false;
+ }
+
+ // Non-pointer types.
+ case Type::Complex:
+ case Type::LValueReference:
+ case Type::RValueReference:
+ case Type::ConstantArray:
+ case Type::IncompleteArray:
+ case Type::VariableArray:
+ case Type::DependentSizedArray:
+ case Type::DependentSizedExtVector:
+ case Type::Vector:
+ case Type::ExtVector:
+ case Type::FunctionProto:
+ case Type::FunctionNoProto:
+ case Type::Record:
+ case Type::Enum:
+ case Type::InjectedClassName:
+ case Type::PackExpansion:
+ case Type::ObjCObject:
+ case Type::ObjCInterface:
+ case Type::Atomic:
+ return false;
+ }
+ llvm_unreachable("bad type kind!");
+}
+
+llvm::Optional<NullabilityKind> AttributedType::getImmediateNullability() const {
+ if (getAttrKind() == AttributedType::attr_nonnull)
+ return NullabilityKind::NonNull;
+ if (getAttrKind() == AttributedType::attr_nullable)
+ return NullabilityKind::Nullable;
+ if (getAttrKind() == AttributedType::attr_null_unspecified)
+ return NullabilityKind::Unspecified;
+ return None;
+}
+
+Optional<NullabilityKind> AttributedType::stripOuterNullability(QualType &T) {
+ if (auto attributed = dyn_cast<AttributedType>(T.getTypePtr())) {
+ if (auto nullability = attributed->getImmediateNullability()) {
+ T = attributed->getModifiedType();
+ return nullability;
+ }
+ }
+
+ return None;
+}
+
Qualifiers::ObjCLifetime Type::getObjCARCImplicitLifetime() const {
if (isObjCARCImplicitlyUnretainedType())
return Qualifiers::OCL_ExplicitNone;
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 3928fe8..ebe09d8 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -1141,6 +1141,21 @@ void TypePrinter::printAttributedBefore(const AttributedType *T,
}
spaceBeforePlaceHolder(OS);
}
+
+ // Print nullability type specifiers.
+ if (T->getAttrKind() == AttributedType::attr_nonnull ||
+ T->getAttrKind() == AttributedType::attr_nullable ||
+ T->getAttrKind() == AttributedType::attr_null_unspecified) {
+ if (T->getAttrKind() == AttributedType::attr_nonnull)
+ OS << " __nonnull";
+ else if (T->getAttrKind() == AttributedType::attr_nullable)
+ OS << " __nullable";
+ else if (T->getAttrKind() == AttributedType::attr_null_unspecified)
+ OS << " __null_unspecified";
+ else
+ llvm_unreachable("unhandled nullability");
+ spaceBeforePlaceHolder(OS);
+ }
}
void TypePrinter::printAttributedAfter(const AttributedType *T,
@@ -1154,12 +1169,34 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
if (T->isMSTypeSpec())
return;
+ // Nothing to print after.
+ if (T->getAttrKind() == AttributedType::attr_nonnull ||
+ T->getAttrKind() == AttributedType::attr_nullable ||
+ T->getAttrKind() == AttributedType::attr_null_unspecified)
+ return printAfter(T->getModifiedType(), OS);
+
// If this is a calling convention attribute, don't print the implicit CC from
// the modified type.
SaveAndRestore<bool> MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
printAfter(T->getModifiedType(), OS);
+ // Print nullability type specifiers that occur after
+ if (T->getAttrKind() == AttributedType::attr_nonnull ||
+ T->getAttrKind() == AttributedType::attr_nullable ||
+ T->getAttrKind() == AttributedType::attr_null_unspecified) {
+ if (T->getAttrKind() == AttributedType::attr_nonnull)
+ OS << " __nonnull";
+ else if (T->getAttrKind() == AttributedType::attr_nullable)
+ OS << " __nullable";
+ else if (T->getAttrKind() == AttributedType::attr_null_unspecified)
+ OS << " __null_unspecified";
+ else
+ llvm_unreachable("unhandled nullability");
+
+ return;
+ }
+
OS << " __attribute__((";
switch (T->getAttrKind()) {
default: llvm_unreachable("This attribute should have been handled already");
OpenPOWER on IntegriCloud