diff options
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/Decl.cpp | 22 | ||||
-rw-r--r-- | clang/lib/AST/Expr.cpp | 34 | ||||
-rw-r--r-- | clang/lib/AST/JSONNodeDumper.cpp | 6 | ||||
-rw-r--r-- | clang/lib/AST/TextNodeDumper.cpp | 6 |
5 files changed, 51 insertions, 19 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index e0a9da5d2ad..c4ae3b80b96 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -6189,7 +6189,7 @@ ExpectedStmt ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) { auto *ToE = DeclRefExpr::Create( Importer.getToContext(), ToQualifierLoc, ToTemplateKeywordLoc, ToDecl, E->refersToEnclosingVariableOrCapture(), ToLocation, ToType, - E->getValueKind(), ToFoundD, ToResInfo); + E->getValueKind(), ToFoundD, ToResInfo, E->isNonOdrUse()); if (E->hadMultipleCandidates()) ToE->setHadMultipleCandidates(true); return ToE; diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 8b77e01f4e8..1b744c82a09 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2245,12 +2245,16 @@ void VarDecl::setInit(Expr *I) { Init = I; } -bool VarDecl::isUsableInConstantExpressions(ASTContext &C) const { +bool VarDecl::mightBeUsableInConstantExpressions(ASTContext &C) const { const LangOptions &Lang = C.getLangOpts(); if (!Lang.CPlusPlus) return false; + // Function parameters are never usable in constant expressions. + if (isa<ParmVarDecl>(this)) + return false; + // In C++11, any variable of reference type can be used in a constant // expression if it is initialized by a constant expression. if (Lang.CPlusPlus11 && getType()->isReferenceType()) @@ -2272,6 +2276,22 @@ bool VarDecl::isUsableInConstantExpressions(ASTContext &C) const { return Lang.CPlusPlus11 && isConstexpr(); } +bool VarDecl::isUsableInConstantExpressions(ASTContext &Context) const { + // C++2a [expr.const]p3: + // A variable is usable in constant expressions after its initializing + // declaration is encountered... + const VarDecl *DefVD = nullptr; + const Expr *Init = getAnyInitializer(DefVD); + if (!Init || Init->isValueDependent()) + return false; + // ... if it is a constexpr variable, or it is of reference type or of + // const-qualified integral or enumeration type, ... + if (!DefVD->mightBeUsableInConstantExpressions(Context)) + return false; + // ... and its initializer is a constant initializer. + return DefVD->checkInitIsICE(); +} + /// Convert the initializer for this declaration to the elaborated EvaluatedStmt /// form, which contains extra information on the evaluated value of the /// initializer. diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index ee9d853f9f8..b772518fc70 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -344,7 +344,8 @@ void DeclRefExpr::computeDependence(const ASTContext &Ctx) { DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, QualType T, ExprValueKind VK, SourceLocation L, - const DeclarationNameLoc &LocInfo) + const DeclarationNameLoc &LocInfo, + NonOdrUseReason NOUR) : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false), D(D), DNLoc(LocInfo) { DeclRefExprBits.HasQualifier = false; @@ -353,6 +354,7 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, ValueDecl *D, DeclRefExprBits.HadMultipleCandidates = false; DeclRefExprBits.RefersToEnclosingVariableOrCapture = RefersToEnclosingVariableOrCapture; + DeclRefExprBits.NonOdrUseReason = NOUR; DeclRefExprBits.Loc = L; computeDependence(Ctx); } @@ -363,7 +365,7 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, bool RefersToEnclosingVariableOrCapture, const DeclarationNameInfo &NameInfo, NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs, - QualType T, ExprValueKind VK) + QualType T, ExprValueKind VK, NonOdrUseReason NOUR) : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false), D(D), DNLoc(NameInfo.getInfo()) { DeclRefExprBits.Loc = NameInfo.getLoc(); @@ -384,6 +386,7 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, = (TemplateArgs || TemplateKWLoc.isValid()) ? 1 : 0; DeclRefExprBits.RefersToEnclosingVariableOrCapture = RefersToEnclosingVariableOrCapture; + DeclRefExprBits.NonOdrUseReason = NOUR; if (TemplateArgs) { bool Dependent = false; bool InstantiationDependent = false; @@ -405,30 +408,27 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, DeclRefExpr *DeclRefExpr::Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - ValueDecl *D, + SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, - SourceLocation NameLoc, - QualType T, - ExprValueKind VK, - NamedDecl *FoundD, - const TemplateArgumentListInfo *TemplateArgs) { + SourceLocation NameLoc, QualType T, + ExprValueKind VK, NamedDecl *FoundD, + const TemplateArgumentListInfo *TemplateArgs, + NonOdrUseReason NOUR) { return Create(Context, QualifierLoc, TemplateKWLoc, D, RefersToEnclosingVariableOrCapture, DeclarationNameInfo(D->getDeclName(), NameLoc), - T, VK, FoundD, TemplateArgs); + T, VK, FoundD, TemplateArgs, NOUR); } DeclRefExpr *DeclRefExpr::Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - ValueDecl *D, + SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, const DeclarationNameInfo &NameInfo, - QualType T, - ExprValueKind VK, + QualType T, ExprValueKind VK, NamedDecl *FoundD, - const TemplateArgumentListInfo *TemplateArgs) { + const TemplateArgumentListInfo *TemplateArgs, + NonOdrUseReason NOUR) { // Filter out cases where the found Decl is the same as the value refenenced. if (D == FoundD) FoundD = nullptr; @@ -443,8 +443,8 @@ DeclRefExpr *DeclRefExpr::Create(const ASTContext &Context, void *Mem = Context.Allocate(Size, alignof(DeclRefExpr)); return new (Mem) DeclRefExpr(Context, QualifierLoc, TemplateKWLoc, D, - RefersToEnclosingVariableOrCapture, - NameInfo, FoundD, TemplateArgs, T, VK); + RefersToEnclosingVariableOrCapture, NameInfo, + FoundD, TemplateArgs, T, VK, NOUR); } DeclRefExpr *DeclRefExpr::CreateEmpty(const ASTContext &Context, diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index 991cf096142..1290847e1aa 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -805,6 +805,12 @@ void JSONNodeDumper::VisitDeclRefExpr(const DeclRefExpr *DRE) { if (DRE->getDecl() != DRE->getFoundDecl()) JOS.attribute("foundReferencedDecl", createBareDeclRef(DRE->getFoundDecl())); + switch (DRE->isNonOdrUse()) { + case NOUR_None: break; + case NOUR_Unevaluated: JOS.attribute("nonOdrUseReason", "unevaluated"); break; + case NOUR_Constant: JOS.attribute("nonOdrUseReason", "constant"); break; + case NOUR_Discarded: JOS.attribute("nonOdrUseReason", "discarded"); break; + } } void JSONNodeDumper::VisitPredefinedExpr(const PredefinedExpr *PE) { diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index c15713b50db..3b8c8f22c37 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -715,6 +715,12 @@ void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) { dumpBareDeclRef(Node->getFoundDecl()); OS << ")"; } + switch (Node->isNonOdrUse()) { + case NOUR_None: break; + case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break; + case NOUR_Constant: OS << " non_odr_use_constant"; break; + case NOUR_Discarded: OS << " non_odr_use_discarded"; break; + } } void TextNodeDumper::VisitUnresolvedLookupExpr( |