diff options
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/ASTConsumer.cpp | 1 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 11 | ||||
-rw-r--r-- | lib/AST/ASTImporter.cpp | 7 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 3 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 8 | ||||
-rw-r--r-- | lib/AST/DeclPrinter.cpp | 68 | ||||
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 34 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 85 | ||||
-rw-r--r-- | lib/AST/ExprClassification.cpp | 2 | ||||
-rw-r--r-- | lib/AST/ExprConstant.cpp | 2 | ||||
-rw-r--r-- | lib/AST/ItaniumMangle.cpp | 11 | ||||
-rw-r--r-- | lib/AST/MicrosoftCXXABI.cpp | 5 | ||||
-rw-r--r-- | lib/AST/MicrosoftMangle.cpp | 12 | ||||
-rw-r--r-- | lib/AST/RecordLayoutBuilder.cpp | 2 | ||||
-rw-r--r-- | lib/AST/Stmt.cpp | 33 | ||||
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 21 | ||||
-rw-r--r-- | lib/AST/StmtProfile.cpp | 16 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 152 | ||||
-rw-r--r-- | lib/AST/TypePrinter.cpp | 37 |
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"); |