aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/Expr.cpp')
-rw-r--r--lib/AST/Expr.cpp669
1 files changed, 380 insertions, 289 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 7556c76c38bd..7cdd3b2c2a30 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -28,7 +28,6 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/LiteralSupport.h"
-#include "clang/Sema/SemaDiagnostic.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -192,7 +191,7 @@ bool Expr::isKnownToHaveBooleanValue() const {
// Amusing macro metaprogramming hack: check whether a class provides
// a more specific implementation of getExprLoc().
//
-// See also Stmt.cpp:{getLocStart(),getLocEnd()}.
+// See also Stmt.cpp:{getBeginLoc(),getEndLoc()}.
namespace {
/// This implementation is used when a class provides a custom
/// implementation of getExprLoc.
@@ -209,7 +208,7 @@ namespace {
template <class E>
SourceLocation getExprLocImpl(const Expr *expr,
SourceLocation (Expr::*v)() const) {
- return static_cast<const E*>(expr)->getLocStart();
+ return static_cast<const E *>(expr)->getBeginLoc();
}
}
@@ -342,16 +341,32 @@ void DeclRefExpr::computeDependence(const ASTContext &Ctx) {
ExprBits.ContainsUnexpandedParameterPack = true;
}
+DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, ValueDecl *D,
+ bool RefersToEnclosingVariableOrCapture, QualType T,
+ ExprValueKind VK, SourceLocation L,
+ const DeclarationNameLoc &LocInfo)
+ : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
+ D(D), DNLoc(LocInfo) {
+ DeclRefExprBits.HasQualifier = false;
+ DeclRefExprBits.HasTemplateKWAndArgsInfo = false;
+ DeclRefExprBits.HasFoundDecl = false;
+ DeclRefExprBits.HadMultipleCandidates = false;
+ DeclRefExprBits.RefersToEnclosingVariableOrCapture =
+ RefersToEnclosingVariableOrCapture;
+ DeclRefExprBits.Loc = L;
+ computeDependence(Ctx);
+}
+
DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- ValueDecl *D, bool RefersToEnclosingVariableOrCapture,
- const DeclarationNameInfo &NameInfo,
- NamedDecl *FoundD,
+ SourceLocation TemplateKWLoc, ValueDecl *D,
+ bool RefersToEnclosingVariableOrCapture,
+ const DeclarationNameInfo &NameInfo, NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs,
QualType T, ExprValueKind VK)
- : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
- D(D), Loc(NameInfo.getLoc()), DNLoc(NameInfo.getInfo()) {
+ : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
+ D(D), DNLoc(NameInfo.getInfo()) {
+ DeclRefExprBits.Loc = NameInfo.getLoc();
DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0;
if (QualifierLoc) {
new (getTrailingObjects<NestedNameSpecifierLoc>())
@@ -447,31 +462,56 @@ DeclRefExpr *DeclRefExpr::CreateEmpty(const ASTContext &Context,
return new (Mem) DeclRefExpr(EmptyShell());
}
-SourceLocation DeclRefExpr::getLocStart() const {
+SourceLocation DeclRefExpr::getBeginLoc() const {
if (hasQualifier())
return getQualifierLoc().getBeginLoc();
- return getNameInfo().getLocStart();
+ return getNameInfo().getBeginLoc();
}
-SourceLocation DeclRefExpr::getLocEnd() const {
+SourceLocation DeclRefExpr::getEndLoc() const {
if (hasExplicitTemplateArgs())
return getRAngleLoc();
- return getNameInfo().getLocEnd();
+ return getNameInfo().getEndLoc();
}
-PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy, IdentType IT,
+PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
StringLiteral *SL)
: Expr(PredefinedExprClass, FNTy, VK_LValue, OK_Ordinary,
FNTy->isDependentType(), FNTy->isDependentType(),
FNTy->isInstantiationDependentType(),
- /*ContainsUnexpandedParameterPack=*/false),
- Loc(L), Type(IT), FnName(SL) {}
+ /*ContainsUnexpandedParameterPack=*/false) {
+ PredefinedExprBits.Kind = IK;
+ assert((getIdentKind() == IK) &&
+ "IdentKind do not fit in PredefinedExprBitfields!");
+ bool HasFunctionName = SL != nullptr;
+ PredefinedExprBits.HasFunctionName = HasFunctionName;
+ PredefinedExprBits.Loc = L;
+ if (HasFunctionName)
+ setFunctionName(SL);
+}
+
+PredefinedExpr::PredefinedExpr(EmptyShell Empty, bool HasFunctionName)
+ : Expr(PredefinedExprClass, Empty) {
+ PredefinedExprBits.HasFunctionName = HasFunctionName;
+}
-StringLiteral *PredefinedExpr::getFunctionName() {
- return cast_or_null<StringLiteral>(FnName);
+PredefinedExpr *PredefinedExpr::Create(const ASTContext &Ctx, SourceLocation L,
+ QualType FNTy, IdentKind IK,
+ StringLiteral *SL) {
+ bool HasFunctionName = SL != nullptr;
+ void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *>(HasFunctionName),
+ alignof(PredefinedExpr));
+ return new (Mem) PredefinedExpr(L, FNTy, IK, SL);
}
-StringRef PredefinedExpr::getIdentTypeName(PredefinedExpr::IdentType IT) {
- switch (IT) {
+PredefinedExpr *PredefinedExpr::CreateEmpty(const ASTContext &Ctx,
+ bool HasFunctionName) {
+ void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *>(HasFunctionName),
+ alignof(PredefinedExpr));
+ return new (Mem) PredefinedExpr(EmptyShell(), HasFunctionName);
+}
+
+StringRef PredefinedExpr::getIdentKindName(PredefinedExpr::IdentKind IK) {
+ switch (IK) {
case Func:
return "__func__";
case Function:
@@ -489,15 +529,15 @@ StringRef PredefinedExpr::getIdentTypeName(PredefinedExpr::IdentType IT) {
case PrettyFunctionNoVirtual:
break;
}
- llvm_unreachable("Unknown ident type for PredefinedExpr");
+ llvm_unreachable("Unknown ident kind for PredefinedExpr");
}
// FIXME: Maybe this should use DeclPrinter with a special "print predefined
// expr" policy instead.
-std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
+std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) {
ASTContext &Context = CurrentDecl->getASTContext();
- if (IT == PredefinedExpr::FuncDName) {
+ if (IK == PredefinedExpr::FuncDName) {
if (const NamedDecl *ND = dyn_cast<NamedDecl>(CurrentDecl)) {
std::unique_ptr<MangleContext> MC;
MC.reset(Context.createMangleContext());
@@ -532,21 +572,21 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
llvm::raw_svector_ostream Out(Buffer);
if (auto *DCBlock = dyn_cast<BlockDecl>(DC))
// For nested blocks, propagate up to the parent.
- Out << ComputeName(IT, DCBlock);
+ Out << ComputeName(IK, DCBlock);
else if (auto *DCDecl = dyn_cast<Decl>(DC))
- Out << ComputeName(IT, DCDecl) << "_block_invoke";
+ Out << ComputeName(IK, DCDecl) << "_block_invoke";
return Out.str();
}
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) {
- if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual &&
- IT != FuncSig && IT != LFuncSig)
+ if (IK != PrettyFunction && IK != PrettyFunctionNoVirtual &&
+ IK != FuncSig && IK != LFuncSig)
return FD->getNameAsString();
SmallString<256> Name;
llvm::raw_svector_ostream Out(Name);
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
- if (MD->isVirtual() && IT != PrettyFunctionNoVirtual)
+ if (MD->isVirtual() && IK != PrettyFunctionNoVirtual)
Out << "virtual ";
if (MD->isStatic())
Out << "static ";
@@ -564,7 +604,7 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
if (FD->hasWrittenPrototype())
FT = dyn_cast<FunctionProtoType>(AFT);
- if (IT == FuncSig || IT == LFuncSig) {
+ if (IK == FuncSig || IK == LFuncSig) {
switch (AFT->getCallConv()) {
case CC_C: POut << "__cdecl "; break;
case CC_X86StdCall: POut << "__stdcall "; break;
@@ -589,7 +629,7 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
if (FT->isVariadic()) {
if (FD->getNumParams()) POut << ", ";
POut << "...";
- } else if ((IT == FuncSig || IT == LFuncSig ||
+ } else if ((IK == FuncSig || IK == LFuncSig ||
!Context.getLangOpts().CPlusPlus) &&
!Decl->getNumParams()) {
POut << "void";
@@ -688,7 +728,7 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
// CapturedDecl.
if (DC->isFunctionOrMethod() && (DC->getDeclKind() != Decl::Captured)) {
const Decl *D = Decl::castFromDeclContext(DC);
- return ComputeName(IT, D);
+ return ComputeName(IK, D);
}
llvm_unreachable("CapturedDecl not inside a function or method");
}
@@ -713,7 +753,7 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
return Name.str().str();
}
- if (isa<TranslationUnitDecl>(CurrentDecl) && IT == PrettyFunction) {
+ if (isa<TranslationUnitDecl>(CurrentDecl) && IK == PrettyFunction) {
// __PRETTY_FUNCTION__ -> "top level", the others produce an empty string.
return "top level";
}
@@ -785,7 +825,7 @@ std::string FixedPointLiteral::getValueAsString(unsigned Radix) const {
// which is 43 characters.
SmallString<64> S;
FixedPointValueToString(
- S, llvm::APSInt::getUnsigned(getValue().getZExtValue()), Scale, Radix);
+ S, llvm::APSInt::getUnsigned(getValue().getZExtValue()), Scale);
return S.str();
}
@@ -861,66 +901,105 @@ double FloatingLiteral::getValueAsApproximateDouble() const {
return V.convertToDouble();
}
-int StringLiteral::mapCharByteWidth(TargetInfo const &target,StringKind k) {
- int CharByteWidth = 0;
- switch(k) {
- case Ascii:
- case UTF8:
- CharByteWidth = target.getCharWidth();
- break;
- case Wide:
- CharByteWidth = target.getWCharWidth();
- break;
- case UTF16:
- CharByteWidth = target.getChar16Width();
- break;
- case UTF32:
- CharByteWidth = target.getChar32Width();
- break;
+unsigned StringLiteral::mapCharByteWidth(TargetInfo const &Target,
+ StringKind SK) {
+ unsigned CharByteWidth = 0;
+ switch (SK) {
+ case Ascii:
+ case UTF8:
+ CharByteWidth = Target.getCharWidth();
+ break;
+ case Wide:
+ CharByteWidth = Target.getWCharWidth();
+ break;
+ case UTF16:
+ CharByteWidth = Target.getChar16Width();
+ break;
+ case UTF32:
+ CharByteWidth = Target.getChar32Width();
+ break;
}
assert((CharByteWidth & 7) == 0 && "Assumes character size is byte multiple");
CharByteWidth /= 8;
- assert((CharByteWidth==1 || CharByteWidth==2 || CharByteWidth==4)
- && "character byte widths supported are 1, 2, and 4 only");
+ assert((CharByteWidth == 1 || CharByteWidth == 2 || CharByteWidth == 4) &&
+ "The only supported character byte widths are 1,2 and 4!");
return CharByteWidth;
}
-StringLiteral *StringLiteral::Create(const ASTContext &C, StringRef Str,
- StringKind Kind, bool Pascal, QualType Ty,
- const SourceLocation *Loc,
- unsigned NumStrs) {
- assert(C.getAsConstantArrayType(Ty) &&
+StringLiteral::StringLiteral(const ASTContext &Ctx, StringRef Str,
+ StringKind Kind, bool Pascal, QualType Ty,
+ const SourceLocation *Loc,
+ unsigned NumConcatenated)
+ : Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false,
+ false) {
+ assert(Ctx.getAsConstantArrayType(Ty) &&
"StringLiteral must be of constant array type!");
+ unsigned CharByteWidth = mapCharByteWidth(Ctx.getTargetInfo(), Kind);
+ unsigned ByteLength = Str.size();
+ assert((ByteLength % CharByteWidth == 0) &&
+ "The size of the data must be a multiple of CharByteWidth!");
+
+ // Avoid the expensive division. The compiler should be able to figure it
+ // out by itself. However as of clang 7, even with the appropriate
+ // llvm_unreachable added just here, it is not able to do so.
+ unsigned Length;
+ switch (CharByteWidth) {
+ case 1:
+ Length = ByteLength;
+ break;
+ case 2:
+ Length = ByteLength / 2;
+ break;
+ case 4:
+ Length = ByteLength / 4;
+ break;
+ default:
+ llvm_unreachable("Unsupported character width!");
+ }
- // Allocate enough space for the StringLiteral plus an array of locations for
- // any concatenated string tokens.
- void *Mem =
- C.Allocate(sizeof(StringLiteral) + sizeof(SourceLocation) * (NumStrs - 1),
- alignof(StringLiteral));
- StringLiteral *SL = new (Mem) StringLiteral(Ty);
+ StringLiteralBits.Kind = Kind;
+ StringLiteralBits.CharByteWidth = CharByteWidth;
+ StringLiteralBits.IsPascal = Pascal;
+ StringLiteralBits.NumConcatenated = NumConcatenated;
+ *getTrailingObjects<unsigned>() = Length;
- // OPTIMIZE: could allocate this appended to the StringLiteral.
- SL->setString(C,Str,Kind,Pascal);
+ // Initialize the trailing array of SourceLocation.
+ // This is safe since SourceLocation is POD-like.
+ std::memcpy(getTrailingObjects<SourceLocation>(), Loc,
+ NumConcatenated * sizeof(SourceLocation));
- SL->TokLocs[0] = Loc[0];
- SL->NumConcatenated = NumStrs;
+ // Initialize the trailing array of char holding the string data.
+ std::memcpy(getTrailingObjects<char>(), Str.data(), ByteLength);
+}
- if (NumStrs != 1)
- memcpy(&SL->TokLocs[1], Loc+1, sizeof(SourceLocation)*(NumStrs-1));
- return SL;
+StringLiteral::StringLiteral(EmptyShell Empty, unsigned NumConcatenated,
+ unsigned Length, unsigned CharByteWidth)
+ : Expr(StringLiteralClass, Empty) {
+ StringLiteralBits.CharByteWidth = CharByteWidth;
+ StringLiteralBits.NumConcatenated = NumConcatenated;
+ *getTrailingObjects<unsigned>() = Length;
}
-StringLiteral *StringLiteral::CreateEmpty(const ASTContext &C,
- unsigned NumStrs) {
- void *Mem =
- C.Allocate(sizeof(StringLiteral) + sizeof(SourceLocation) * (NumStrs - 1),
- alignof(StringLiteral));
- StringLiteral *SL =
- new (Mem) StringLiteral(C.adjustStringLiteralBaseType(QualType()));
- SL->CharByteWidth = 0;
- SL->Length = 0;
- SL->NumConcatenated = NumStrs;
- return SL;
+StringLiteral *StringLiteral::Create(const ASTContext &Ctx, StringRef Str,
+ StringKind Kind, bool Pascal, QualType Ty,
+ const SourceLocation *Loc,
+ unsigned NumConcatenated) {
+ void *Mem = Ctx.Allocate(totalSizeToAlloc<unsigned, SourceLocation, char>(
+ 1, NumConcatenated, Str.size()),
+ alignof(StringLiteral));
+ return new (Mem)
+ StringLiteral(Ctx, Str, Kind, Pascal, Ty, Loc, NumConcatenated);
+}
+
+StringLiteral *StringLiteral::CreateEmpty(const ASTContext &Ctx,
+ unsigned NumConcatenated,
+ unsigned Length,
+ unsigned CharByteWidth) {
+ void *Mem = Ctx.Allocate(totalSizeToAlloc<unsigned, SourceLocation, char>(
+ 1, NumConcatenated, Length * CharByteWidth),
+ alignof(StringLiteral));
+ return new (Mem)
+ StringLiteral(EmptyShell(), NumConcatenated, Length, CharByteWidth);
}
void StringLiteral::outputString(raw_ostream &OS) const {
@@ -1019,42 +1098,6 @@ void StringLiteral::outputString(raw_ostream &OS) const {
OS << '"';
}
-void StringLiteral::setString(const ASTContext &C, StringRef Str,
- StringKind Kind, bool IsPascal) {
- //FIXME: we assume that the string data comes from a target that uses the same
- // code unit size and endianness for the type of string.
- this->Kind = Kind;
- this->IsPascal = IsPascal;
-
- CharByteWidth = mapCharByteWidth(C.getTargetInfo(),Kind);
- assert((Str.size()%CharByteWidth == 0)
- && "size of data must be multiple of CharByteWidth");
- Length = Str.size()/CharByteWidth;
-
- switch(CharByteWidth) {
- case 1: {
- char *AStrData = new (C) char[Length];
- std::memcpy(AStrData,Str.data(),Length*sizeof(*AStrData));
- StrData.asChar = AStrData;
- break;
- }
- case 2: {
- uint16_t *AStrData = new (C) uint16_t[Length];
- std::memcpy(AStrData,Str.data(),Length*sizeof(*AStrData));
- StrData.asUInt16 = AStrData;
- break;
- }
- case 4: {
- uint32_t *AStrData = new (C) uint32_t[Length];
- std::memcpy(AStrData,Str.data(),Length*sizeof(*AStrData));
- StrData.asUInt32 = AStrData;
- break;
- }
- default:
- llvm_unreachable("unsupported CharByteWidth");
- }
-}
-
/// getLocationOfByte - Return a source location that points to the specified
/// byte of this string literal.
///
@@ -1076,7 +1119,8 @@ StringLiteral::getLocationOfByte(unsigned ByteNo, const SourceManager &SM,
const LangOptions &Features,
const TargetInfo &Target, unsigned *StartToken,
unsigned *StartTokenByteOffset) const {
- assert((Kind == StringLiteral::Ascii || Kind == StringLiteral::UTF8) &&
+ assert((getKind() == StringLiteral::Ascii ||
+ getKind() == StringLiteral::UTF8) &&
"Only narrow string literals are currently supported");
// Loop over all of the tokens in this string until we find the one that
@@ -1144,8 +1188,6 @@ StringLiteral::getLocationOfByte(unsigned ByteNo, const SourceManager &SM,
}
}
-
-
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
/// corresponds to, e.g. "sizeof" or "[pre]++".
StringRef UnaryOperator::getOpcodeStr(Opcode Op) {
@@ -1192,49 +1234,98 @@ OverloadedOperatorKind UnaryOperator::getOverloadedOperator(Opcode Opc) {
// Postfix Operators.
//===----------------------------------------------------------------------===//
-CallExpr::CallExpr(const ASTContext &C, StmtClass SC, Expr *fn,
- ArrayRef<Expr *> preargs, ArrayRef<Expr *> args, QualType t,
- ExprValueKind VK, SourceLocation rparenloc)
- : Expr(SC, t, VK, OK_Ordinary, fn->isTypeDependent(),
- fn->isValueDependent(), fn->isInstantiationDependent(),
- fn->containsUnexpandedParameterPack()),
- NumArgs(args.size()) {
+CallExpr::CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs,
+ ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
+ SourceLocation RParenLoc, unsigned MinNumArgs,
+ ADLCallKind UsesADL)
+ : Expr(SC, Ty, VK, OK_Ordinary, Fn->isTypeDependent(),
+ Fn->isValueDependent(), Fn->isInstantiationDependent(),
+ Fn->containsUnexpandedParameterPack()),
+ RParenLoc(RParenLoc) {
+ NumArgs = std::max<unsigned>(Args.size(), MinNumArgs);
+ unsigned NumPreArgs = PreArgs.size();
+ CallExprBits.NumPreArgs = NumPreArgs;
+ assert((NumPreArgs == getNumPreArgs()) && "NumPreArgs overflow!");
+
+ unsigned OffsetToTrailingObjects = offsetToTrailingObjects(SC);
+ CallExprBits.OffsetToTrailingObjects = OffsetToTrailingObjects;
+ assert((CallExprBits.OffsetToTrailingObjects == OffsetToTrailingObjects) &&
+ "OffsetToTrailingObjects overflow!");
- unsigned NumPreArgs = preargs.size();
- SubExprs = new (C) Stmt *[args.size()+PREARGS_START+NumPreArgs];
- SubExprs[FN] = fn;
- for (unsigned i = 0; i != NumPreArgs; ++i) {
- updateDependenciesFromArg(preargs[i]);
- SubExprs[i+PREARGS_START] = preargs[i];
+ CallExprBits.UsesADL = static_cast<bool>(UsesADL);
+
+ setCallee(Fn);
+ for (unsigned I = 0; I != NumPreArgs; ++I) {
+ updateDependenciesFromArg(PreArgs[I]);
+ setPreArg(I, PreArgs[I]);
+ }
+ for (unsigned I = 0; I != Args.size(); ++I) {
+ updateDependenciesFromArg(Args[I]);
+ setArg(I, Args[I]);
}
- for (unsigned i = 0; i != args.size(); ++i) {
- updateDependenciesFromArg(args[i]);
- SubExprs[i+PREARGS_START+NumPreArgs] = args[i];
+ for (unsigned I = Args.size(); I != NumArgs; ++I) {
+ setArg(I, nullptr);
}
+}
+CallExpr::CallExpr(StmtClass SC, unsigned NumPreArgs, unsigned NumArgs,
+ EmptyShell Empty)
+ : Expr(SC, Empty), NumArgs(NumArgs) {
CallExprBits.NumPreArgs = NumPreArgs;
- RParenLoc = rparenloc;
+ assert((NumPreArgs == getNumPreArgs()) && "NumPreArgs overflow!");
+
+ unsigned OffsetToTrailingObjects = offsetToTrailingObjects(SC);
+ CallExprBits.OffsetToTrailingObjects = OffsetToTrailingObjects;
+ assert((CallExprBits.OffsetToTrailingObjects == OffsetToTrailingObjects) &&
+ "OffsetToTrailingObjects overflow!");
}
-CallExpr::CallExpr(const ASTContext &C, StmtClass SC, Expr *fn,
- ArrayRef<Expr *> args, QualType t, ExprValueKind VK,
- SourceLocation rparenloc)
- : CallExpr(C, SC, fn, ArrayRef<Expr *>(), args, t, VK, rparenloc) {}
+CallExpr *CallExpr::Create(const ASTContext &Ctx, Expr *Fn,
+ ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
+ SourceLocation RParenLoc, unsigned MinNumArgs,
+ ADLCallKind UsesADL) {
+ unsigned NumArgs = std::max<unsigned>(Args.size(), MinNumArgs);
+ unsigned SizeOfTrailingObjects =
+ CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs);
+ void *Mem =
+ Ctx.Allocate(sizeof(CallExpr) + SizeOfTrailingObjects, alignof(CallExpr));
+ return new (Mem) CallExpr(CallExprClass, Fn, /*PreArgs=*/{}, Args, Ty, VK,
+ RParenLoc, MinNumArgs, UsesADL);
+}
-CallExpr::CallExpr(const ASTContext &C, Expr *fn, ArrayRef<Expr *> args,
- QualType t, ExprValueKind VK, SourceLocation rparenloc)
- : CallExpr(C, CallExprClass, fn, ArrayRef<Expr *>(), args, t, VK, rparenloc) {
+CallExpr *CallExpr::CreateTemporary(void *Mem, Expr *Fn, QualType Ty,
+ ExprValueKind VK, SourceLocation RParenLoc,
+ ADLCallKind UsesADL) {
+ assert(!(reinterpret_cast<uintptr_t>(Mem) % alignof(CallExpr)) &&
+ "Misaligned memory in CallExpr::CreateTemporary!");
+ return new (Mem) CallExpr(CallExprClass, Fn, /*PreArgs=*/{}, /*Args=*/{}, Ty,
+ VK, RParenLoc, /*MinNumArgs=*/0, UsesADL);
}
-CallExpr::CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty)
- : CallExpr(C, SC, /*NumPreArgs=*/0, Empty) {}
+CallExpr *CallExpr::CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
+ EmptyShell Empty) {
+ unsigned SizeOfTrailingObjects =
+ CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs);
+ void *Mem =
+ Ctx.Allocate(sizeof(CallExpr) + SizeOfTrailingObjects, alignof(CallExpr));
+ return new (Mem) CallExpr(CallExprClass, /*NumPreArgs=*/0, NumArgs, Empty);
+}
-CallExpr::CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
- EmptyShell Empty)
- : Expr(SC, Empty), SubExprs(nullptr), NumArgs(0) {
- // FIXME: Why do we allocate this?
- SubExprs = new (C) Stmt*[PREARGS_START+NumPreArgs]();
- CallExprBits.NumPreArgs = NumPreArgs;
+unsigned CallExpr::offsetToTrailingObjects(StmtClass SC) {
+ switch (SC) {
+ case CallExprClass:
+ return sizeof(CallExpr);
+ case CXXOperatorCallExprClass:
+ return sizeof(CXXOperatorCallExpr);
+ case CXXMemberCallExprClass:
+ return sizeof(CXXMemberCallExpr);
+ case UserDefinedLiteralClass:
+ return sizeof(UserDefinedLiteral);
+ case CUDAKernelCallExprClass:
+ return sizeof(CUDAKernelCallExpr);
+ default:
+ llvm_unreachable("unexpected class deriving from CallExpr!");
+ }
}
void CallExpr::updateDependenciesFromArg(Expr *Arg) {
@@ -1248,14 +1339,6 @@ void CallExpr::updateDependenciesFromArg(Expr *Arg) {
ExprBits.ContainsUnexpandedParameterPack = true;
}
-FunctionDecl *CallExpr::getDirectCallee() {
- return dyn_cast_or_null<FunctionDecl>(getCalleeDecl());
-}
-
-Decl *CallExpr::getCalleeDecl() {
- return getCallee()->getReferencedDeclOfCallee();
-}
-
Decl *Expr::getReferencedDeclOfCallee() {
Expr *CEE = IgnoreParenImpCasts();
@@ -1280,35 +1363,6 @@ Decl *Expr::getReferencedDeclOfCallee() {
return nullptr;
}
-/// setNumArgs - This changes the number of arguments present in this call.
-/// Any orphaned expressions are deleted by this, and any new operands are set
-/// to null.
-void CallExpr::setNumArgs(const ASTContext& C, unsigned NumArgs) {
- // No change, just return.
- if (NumArgs == getNumArgs()) return;
-
- // If shrinking # arguments, just delete the extras and forgot them.
- if (NumArgs < getNumArgs()) {
- this->NumArgs = NumArgs;
- return;
- }
-
- // Otherwise, we are growing the # arguments. New an bigger argument array.
- unsigned NumPreArgs = getNumPreArgs();
- Stmt **NewSubExprs = new (C) Stmt*[NumArgs+PREARGS_START+NumPreArgs];
- // Copy over args.
- for (unsigned i = 0; i != getNumArgs()+PREARGS_START+NumPreArgs; ++i)
- NewSubExprs[i] = SubExprs[i];
- // Null out new args.
- for (unsigned i = getNumArgs()+PREARGS_START+NumPreArgs;
- i != NumArgs+PREARGS_START+NumPreArgs; ++i)
- NewSubExprs[i] = nullptr;
-
- if (SubExprs) C.Deallocate(SubExprs);
- SubExprs = NewSubExprs;
- this->NumArgs = NumArgs;
-}
-
/// getBuiltinCallee - If this is a call to a builtin, return the builtin ID. If
/// not, return 0.
unsigned CallExpr::getBuiltinCallee() const {
@@ -1358,22 +1412,35 @@ QualType CallExpr::getCallReturnType(const ASTContext &Ctx) const {
return FnType->getReturnType();
}
-SourceLocation CallExpr::getLocStart() const {
+const Attr *CallExpr::getUnusedResultAttr(const ASTContext &Ctx) const {
+ // If the return type is a struct, union, or enum that is marked nodiscard,
+ // then return the return type attribute.
+ if (const TagDecl *TD = getCallReturnType(Ctx)->getAsTagDecl())
+ if (const auto *A = TD->getAttr<WarnUnusedResultAttr>())
+ return A;
+
+ // Otherwise, see if the callee is marked nodiscard and return that attribute
+ // instead.
+ const Decl *D = getCalleeDecl();
+ return D ? D->getAttr<WarnUnusedResultAttr>() : nullptr;
+}
+
+SourceLocation CallExpr::getBeginLoc() const {
if (isa<CXXOperatorCallExpr>(this))
- return cast<CXXOperatorCallExpr>(this)->getLocStart();
+ return cast<CXXOperatorCallExpr>(this)->getBeginLoc();
- SourceLocation begin = getCallee()->getLocStart();
+ SourceLocation begin = getCallee()->getBeginLoc();
if (begin.isInvalid() && getNumArgs() > 0 && getArg(0))
- begin = getArg(0)->getLocStart();
+ begin = getArg(0)->getBeginLoc();
return begin;
}
-SourceLocation CallExpr::getLocEnd() const {
+SourceLocation CallExpr::getEndLoc() const {
if (isa<CXXOperatorCallExpr>(this))
- return cast<CXXOperatorCallExpr>(this)->getLocEnd();
+ return cast<CXXOperatorCallExpr>(this)->getEndLoc();
SourceLocation end = getRParenLoc();
if (end.isInvalid() && getNumArgs() > 0 && getArg(getNumArgs() - 1))
- end = getArg(getNumArgs() - 1)->getLocEnd();
+ end = getArg(getNumArgs() - 1)->getEndLoc();
return end;
}
@@ -1446,7 +1513,7 @@ UnaryExprOrTypeTraitExpr::UnaryExprOrTypeTraitExpr(
// Check to see if we are in the situation where alignof(decl) should be
// dependent because decl's alignment is dependent.
- if (ExprKind == UETT_AlignOf) {
+ if (ExprKind == UETT_AlignOf || ExprKind == UETT_PreferredAlignOf) {
if (!isValueDependent() || !isInstantiationDependent()) {
E = E->IgnoreParens();
@@ -1502,7 +1569,7 @@ MemberExpr *MemberExpr::Create(
QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())
E->setInstantiationDependent(true);
- E->HasQualifierOrFoundDecl = true;
+ E->MemberExprBits.HasQualifierOrFoundDecl = true;
MemberExprNameQualifier *NQ =
E->getTrailingObjects<MemberExprNameQualifier>();
@@ -1510,7 +1577,8 @@ MemberExpr *MemberExpr::Create(
NQ->FoundDecl = founddecl;
}
- E->HasTemplateKWAndArgsInfo = (targs || TemplateKWLoc.isValid());
+ E->MemberExprBits.HasTemplateKWAndArgsInfo =
+ (targs || TemplateKWLoc.isValid());
if (targs) {
bool Dependent = false;
@@ -1529,7 +1597,7 @@ MemberExpr *MemberExpr::Create(
return E;
}
-SourceLocation MemberExpr::getLocStart() const {
+SourceLocation MemberExpr::getBeginLoc() const {
if (isImplicitAccess()) {
if (hasQualifier())
return getQualifierLoc().getBeginLoc();
@@ -1538,17 +1606,17 @@ SourceLocation MemberExpr::getLocStart() const {
// FIXME: We don't want this to happen. Rather, we should be able to
// detect all kinds of implicit accesses more cleanly.
- SourceLocation BaseStartLoc = getBase()->getLocStart();
+ SourceLocation BaseStartLoc = getBase()->getBeginLoc();
if (BaseStartLoc.isValid())
return BaseStartLoc;
return MemberLoc;
}
-SourceLocation MemberExpr::getLocEnd() const {
+SourceLocation MemberExpr::getEndLoc() const {
SourceLocation EndLoc = getMemberNameInfo().getEndLoc();
if (hasExplicitTemplateArgs())
EndLoc = getRAngleLoc();
else if (EndLoc.isInvalid())
- EndLoc = getBase()->getLocEnd();
+ EndLoc = getBase()->getEndLoc();
return EndLoc;
}
@@ -1605,13 +1673,18 @@ bool CastExpr::CastConsistency() const {
assert(getSubExpr()->getType()->isFunctionType());
goto CheckNoBasePath;
- case CK_AddressSpaceConversion:
- assert(getType()->isPointerType() || getType()->isBlockPointerType());
- assert(getSubExpr()->getType()->isPointerType() ||
- getSubExpr()->getType()->isBlockPointerType());
- assert(getType()->getPointeeType().getAddressSpace() !=
- getSubExpr()->getType()->getPointeeType().getAddressSpace());
- LLVM_FALLTHROUGH;
+ case CK_AddressSpaceConversion: {
+ auto Ty = getType();
+ auto SETy = getSubExpr()->getType();
+ assert(getValueKindForType(Ty) == Expr::getValueKindForType(SETy));
+ if (isRValue()) {
+ Ty = Ty->getPointeeType();
+ SETy = SETy->getPointeeType();
+ }
+ assert(!Ty.isNull() && !SETy.isNull() &&
+ Ty.getAddressSpace() != SETy.getAddressSpace());
+ goto CheckNoBasePath;
+ }
// These should not have an inheritance path.
case CK_Dynamic:
case CK_ToUnion:
@@ -1641,9 +1714,9 @@ bool CastExpr::CastConsistency() const {
case CK_ARCConsumeObject:
case CK_ARCReclaimReturnedObject:
case CK_ARCExtendBlockObject:
- case CK_ZeroToOCLEvent:
- case CK_ZeroToOCLQueue:
+ case CK_ZeroToOCLOpaqueType:
case CK_IntToOCLSampler:
+ case CK_FixedPointCast:
assert(!getType()->isBooleanType() && "unheralded conversion to bool");
goto CheckNoBasePath;
@@ -1661,6 +1734,7 @@ bool CastExpr::CastConsistency() const {
case CK_LValueBitCast: // -> bool&
case CK_UserDefinedConversion: // operator bool()
case CK_BuiltinFnToFnPtr:
+ case CK_FixedPointToBoolean:
CheckNoBasePath:
assert(path_empty() && "Cast kind should not have a base path!");
break;
@@ -1734,21 +1808,6 @@ NamedDecl *CastExpr::getConversionFunction() const {
return nullptr;
}
-CastExpr::BasePathSizeTy *CastExpr::BasePathSize() {
- assert(!path_empty());
- switch (getStmtClass()) {
-#define ABSTRACT_STMT(x)
-#define CASTEXPR(Type, Base) \
- case Stmt::Type##Class: \
- return static_cast<Type *>(this) \
- ->getTrailingObjects<CastExpr::BasePathSizeTy>();
-#define STMT(Type, Base)
-#include "clang/AST/StmtNodes.inc"
- default:
- llvm_unreachable("non-cast expressions not possible here");
- }
-}
-
CXXBaseSpecifier **CastExpr::path_buffer() {
switch (getStmtClass()) {
#define ABSTRACT_STMT(x)
@@ -1787,9 +1846,7 @@ ImplicitCastExpr *ImplicitCastExpr::Create(const ASTContext &C, QualType T,
const CXXCastPath *BasePath,
ExprValueKind VK) {
unsigned PathSize = (BasePath ? BasePath->size() : 0);
- void *Buffer =
- C.Allocate(totalSizeToAlloc<CastExpr::BasePathSizeTy, CXXBaseSpecifier *>(
- PathSize ? 1 : 0, PathSize));
+ void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
ImplicitCastExpr *E =
new (Buffer) ImplicitCastExpr(T, Kind, Operand, PathSize, VK);
if (PathSize)
@@ -1800,9 +1857,7 @@ ImplicitCastExpr *ImplicitCastExpr::Create(const ASTContext &C, QualType T,
ImplicitCastExpr *ImplicitCastExpr::CreateEmpty(const ASTContext &C,
unsigned PathSize) {
- void *Buffer =
- C.Allocate(totalSizeToAlloc<CastExpr::BasePathSizeTy, CXXBaseSpecifier *>(
- PathSize ? 1 : 0, PathSize));
+ void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
return new (Buffer) ImplicitCastExpr(EmptyShell(), PathSize);
}
@@ -1813,9 +1868,7 @@ CStyleCastExpr *CStyleCastExpr::Create(const ASTContext &C, QualType T,
TypeSourceInfo *WrittenTy,
SourceLocation L, SourceLocation R) {
unsigned PathSize = (BasePath ? BasePath->size() : 0);
- void *Buffer =
- C.Allocate(totalSizeToAlloc<CastExpr::BasePathSizeTy, CXXBaseSpecifier *>(
- PathSize ? 1 : 0, PathSize));
+ void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
CStyleCastExpr *E =
new (Buffer) CStyleCastExpr(T, VK, K, Op, PathSize, WrittenTy, L, R);
if (PathSize)
@@ -1826,9 +1879,7 @@ CStyleCastExpr *CStyleCastExpr::Create(const ASTContext &C, QualType T,
CStyleCastExpr *CStyleCastExpr::CreateEmpty(const ASTContext &C,
unsigned PathSize) {
- void *Buffer =
- C.Allocate(totalSizeToAlloc<CastExpr::BasePathSizeTy, CXXBaseSpecifier *>(
- PathSize ? 1 : 0, PathSize));
+ void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
return new (Buffer) CStyleCastExpr(EmptyShell(), PathSize);
}
@@ -2039,9 +2090,9 @@ bool InitListExpr::isIdiomaticZeroInitializer(const LangOptions &LangOpts) const
return Lit && Lit->getValue() == 0;
}
-SourceLocation InitListExpr::getLocStart() const {
+SourceLocation InitListExpr::getBeginLoc() const {
if (InitListExpr *SyntacticForm = getSyntacticForm())
- return SyntacticForm->getLocStart();
+ return SyntacticForm->getBeginLoc();
SourceLocation Beg = LBraceLoc;
if (Beg.isInvalid()) {
// Find the first non-null initializer.
@@ -2049,7 +2100,7 @@ SourceLocation InitListExpr::getLocStart() const {
E = InitExprs.end();
I != E; ++I) {
if (Stmt *S = *I) {
- Beg = S->getLocStart();
+ Beg = S->getBeginLoc();
break;
}
}
@@ -2057,9 +2108,9 @@ SourceLocation InitListExpr::getLocStart() const {
return Beg;
}
-SourceLocation InitListExpr::getLocEnd() const {
+SourceLocation InitListExpr::getEndLoc() const {
if (InitListExpr *SyntacticForm = getSyntacticForm())
- return SyntacticForm->getLocEnd();
+ return SyntacticForm->getEndLoc();
SourceLocation End = RBraceLoc;
if (End.isInvalid()) {
// Find the first non-null initializer from the end.
@@ -2067,7 +2118,7 @@ SourceLocation InitListExpr::getLocEnd() const {
E = InitExprs.rend();
I != E; ++I) {
if (Stmt *S = *I) {
- End = S->getLocEnd();
+ End = S->getEndLoc();
break;
}
}
@@ -2262,24 +2313,20 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
// If this is a direct call, get the callee.
const CallExpr *CE = cast<CallExpr>(this);
if (const Decl *FD = CE->getCalleeDecl()) {
- const FunctionDecl *Func = dyn_cast<FunctionDecl>(FD);
- bool HasWarnUnusedResultAttr = Func ? Func->hasUnusedResultAttr()
- : FD->hasAttr<WarnUnusedResultAttr>();
-
// If the callee has attribute pure, const, or warn_unused_result, warn
// about it. void foo() { strlen("bar"); } should warn.
//
// Note: If new cases are added here, DiagnoseUnusedExprResult should be
// updated to match for QoI.
- if (HasWarnUnusedResultAttr ||
+ if (CE->hasUnusedResultAttr(Ctx) ||
FD->hasAttr<PureAttr>() || FD->hasAttr<ConstAttr>()) {
WarnE = this;
- Loc = CE->getCallee()->getLocStart();
+ Loc = CE->getCallee()->getBeginLoc();
R1 = CE->getCallee()->getSourceRange();
if (unsigned NumArgs = CE->getNumArgs())
- R2 = SourceRange(CE->getArg(0)->getLocStart(),
- CE->getArg(NumArgs-1)->getLocEnd());
+ R2 = SourceRange(CE->getArg(0)->getBeginLoc(),
+ CE->getArg(NumArgs - 1)->getEndLoc());
return true;
}
}
@@ -2296,7 +2343,7 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
if (const CXXRecordDecl *Type = getType()->getAsCXXRecordDecl()) {
if (Type->hasAttr<WarnUnusedAttr>()) {
WarnE = this;
- Loc = getLocStart();
+ Loc = getBeginLoc();
R1 = getSourceRange();
return true;
}
@@ -2396,7 +2443,7 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
WarnE = this;
if (const CXXFunctionalCastExpr *CXXCE =
dyn_cast<CXXFunctionalCastExpr>(this)) {
- Loc = CXXCE->getLocStart();
+ Loc = CXXCE->getBeginLoc();
R1 = CXXCE->getSubExpr()->getSourceRange();
} else {
const CStyleCastExpr *CStyleCE = cast<CStyleCastExpr>(this);
@@ -2535,6 +2582,10 @@ Expr* Expr::IgnoreParens() {
continue;
}
}
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) {
+ E = CE->getSubExpr();
+ continue;
+ }
return E;
}
}
@@ -2559,6 +2610,10 @@ Expr *Expr::IgnoreParenCasts() {
E = NTTP->getReplacement();
continue;
}
+ if (FullExpr *FE = dyn_cast<FullExpr>(E)) {
+ E = FE->getSubExpr();
+ continue;
+ }
return E;
}
}
@@ -2580,6 +2635,10 @@ Expr *Expr::IgnoreCasts() {
E = NTTP->getReplacement();
continue;
}
+ if (FullExpr *FE = dyn_cast<FullExpr>(E)) {
+ E = FE->getSubExpr();
+ continue;
+ }
return E;
}
}
@@ -2605,6 +2664,9 @@ Expr *Expr::IgnoreParenLValueCasts() {
= dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
E = NTTP->getReplacement();
continue;
+ } else if (FullExpr *FE = dyn_cast<FullExpr>(E)) {
+ E = FE->getSubExpr();
+ continue;
}
break;
}
@@ -2870,6 +2932,12 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
break;
}
+ case ConstantExprClass: {
+ // FIXME: We should be able to return "true" here, but it can lead to extra
+ // error messages. E.g. in Sema/array-init.c.
+ const Expr *Exp = cast<ConstantExpr>(this)->getSubExpr();
+ return Exp->isConstantInitializer(Ctx, false, Culprit);
+ }
case CompoundLiteralExprClass: {
// This handles gcc's extension that allows global initializers like
// "struct x {int x;} x = (struct x) {};".
@@ -2909,8 +2977,8 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
const Expr *Elt = ILE->getInit(ElementNo++);
if (Field->isBitField()) {
// Bitfields have to evaluate to an integer.
- llvm::APSInt ResultTmp;
- if (!Elt->EvaluateAsInt(ResultTmp, Ctx)) {
+ EvalResult Result;
+ if (!Elt->EvaluateAsInt(Result, Ctx)) {
if (Culprit)
*Culprit = Elt;
return false;
@@ -3095,6 +3163,11 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
// These never have a side-effect.
return false;
+ case ConstantExprClass:
+ // FIXME: Move this into the "return false;" block above.
+ return cast<ConstantExpr>(this)->getSubExpr()->HasSideEffects(
+ Ctx, IncludePossibleEffects);
+
case CallExprClass:
case CXXOperatorCallExprClass:
case CXXMemberCallExprClass:
@@ -3254,11 +3327,8 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case LambdaExprClass: {
const LambdaExpr *LE = cast<LambdaExpr>(this);
- for (LambdaExpr::capture_iterator I = LE->capture_begin(),
- E = LE->capture_end(); I != E; ++I)
- if (I->getCaptureKind() == LCK_ByCopy)
- // FIXME: Only has a side-effect if the variable is volatile or if
- // the copy would invoke a non-trivial copy constructor.
+ for (Expr *E : LE->capture_inits())
+ if (E->HasSideEffects(Ctx, IncludePossibleEffects))
return true;
return false;
}
@@ -3389,20 +3459,20 @@ Expr::isNullPointerConstant(ASTContext &Ctx,
// Check that it is a cast to void*.
if (const PointerType *PT = CE->getType()->getAs<PointerType>()) {
QualType Pointee = PT->getPointeeType();
+ Qualifiers Qs = Pointee.getQualifiers();
// Only (void*)0 or equivalent are treated as nullptr. If pointee type
// has non-default address space it is not treated as nullptr.
// (__generic void*)0 in OpenCL 2.0 should not be treated as nullptr
// since it cannot be assigned to a pointer to constant address space.
- bool PointeeHasDefaultAS =
- Pointee.getAddressSpace() == LangAS::Default ||
- (Ctx.getLangOpts().OpenCLVersion >= 200 &&
+ if ((Ctx.getLangOpts().OpenCLVersion >= 200 &&
Pointee.getAddressSpace() == LangAS::opencl_generic) ||
(Ctx.getLangOpts().OpenCL &&
Ctx.getLangOpts().OpenCLVersion < 200 &&
- Pointee.getAddressSpace() == LangAS::opencl_private);
+ Pointee.getAddressSpace() == LangAS::opencl_private))
+ Qs.removeAddressSpace();
- if (PointeeHasDefaultAS && Pointee->isVoidType() && // to void*
- CE->getSubExpr()->getType()->isIntegerType()) // from int.
+ if (Pointee->isVoidType() && Qs.empty() && // to void*
+ CE->getSubExpr()->getType()->isIntegerType()) // from int
return CE->getSubExpr()->isNullPointerConstant(Ctx, NPC);
}
}
@@ -3866,11 +3936,11 @@ SourceRange DesignatedInitExpr::getDesignatorsSourceRange() const {
DesignatedInitExpr *DIE = const_cast<DesignatedInitExpr*>(this);
if (size() == 1)
return DIE->getDesignator(0)->getSourceRange();
- return SourceRange(DIE->getDesignator(0)->getLocStart(),
- DIE->getDesignator(size()-1)->getLocEnd());
+ return SourceRange(DIE->getDesignator(0)->getBeginLoc(),
+ DIE->getDesignator(size() - 1)->getEndLoc());
}
-SourceLocation DesignatedInitExpr::getLocStart() const {
+SourceLocation DesignatedInitExpr::getBeginLoc() const {
SourceLocation StartLoc;
auto *DIE = const_cast<DesignatedInitExpr *>(this);
Designator &First = *DIE->getDesignator(0);
@@ -3885,8 +3955,8 @@ SourceLocation DesignatedInitExpr::getLocStart() const {
return StartLoc;
}
-SourceLocation DesignatedInitExpr::getLocEnd() const {
- return getInit()->getLocEnd();
+SourceLocation DesignatedInitExpr::getEndLoc() const {
+ return getInit()->getEndLoc();
}
Expr *DesignatedInitExpr::getArrayIndex(const Designator& D) const {
@@ -3944,35 +4014,56 @@ DesignatedInitUpdateExpr::DesignatedInitUpdateExpr(const ASTContext &C,
BaseAndUpdaterExprs[1] = ILE;
}
-SourceLocation DesignatedInitUpdateExpr::getLocStart() const {
- return getBase()->getLocStart();
+SourceLocation DesignatedInitUpdateExpr::getBeginLoc() const {
+ return getBase()->getBeginLoc();
}
-SourceLocation DesignatedInitUpdateExpr::getLocEnd() const {
- return getBase()->getLocEnd();
+SourceLocation DesignatedInitUpdateExpr::getEndLoc() const {
+ return getBase()->getEndLoc();
}
-ParenListExpr::ParenListExpr(const ASTContext& C, SourceLocation lparenloc,
- ArrayRef<Expr*> exprs,
- SourceLocation rparenloc)
- : Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary,
- false, false, false, false),
- NumExprs(exprs.size()), LParenLoc(lparenloc), RParenLoc(rparenloc) {
- Exprs = new (C) Stmt*[exprs.size()];
- for (unsigned i = 0; i != exprs.size(); ++i) {
- if (exprs[i]->isTypeDependent())
+ParenListExpr::ParenListExpr(SourceLocation LParenLoc, ArrayRef<Expr *> Exprs,
+ SourceLocation RParenLoc)
+ : Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false,
+ false, false),
+ LParenLoc(LParenLoc), RParenLoc(RParenLoc) {
+ ParenListExprBits.NumExprs = Exprs.size();
+
+ for (unsigned I = 0, N = Exprs.size(); I != N; ++I) {
+ if (Exprs[I]->isTypeDependent())
ExprBits.TypeDependent = true;
- if (exprs[i]->isValueDependent())
+ if (Exprs[I]->isValueDependent())
ExprBits.ValueDependent = true;
- if (exprs[i]->isInstantiationDependent())
+ if (Exprs[I]->isInstantiationDependent())
ExprBits.InstantiationDependent = true;
- if (exprs[i]->containsUnexpandedParameterPack())
+ if (Exprs[I]->containsUnexpandedParameterPack())
ExprBits.ContainsUnexpandedParameterPack = true;
- Exprs[i] = exprs[i];
+ getTrailingObjects<Stmt *>()[I] = Exprs[I];
}
}
+ParenListExpr::ParenListExpr(EmptyShell Empty, unsigned NumExprs)
+ : Expr(ParenListExprClass, Empty) {
+ ParenListExprBits.NumExprs = NumExprs;
+}
+
+ParenListExpr *ParenListExpr::Create(const ASTContext &Ctx,
+ SourceLocation LParenLoc,
+ ArrayRef<Expr *> Exprs,
+ SourceLocation RParenLoc) {
+ void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *>(Exprs.size()),
+ alignof(ParenListExpr));
+ return new (Mem) ParenListExpr(LParenLoc, Exprs, RParenLoc);
+}
+
+ParenListExpr *ParenListExpr::CreateEmpty(const ASTContext &Ctx,
+ unsigned NumExprs) {
+ void *Mem =
+ Ctx.Allocate(totalSizeToAlloc<Stmt *>(NumExprs), alignof(ParenListExpr));
+ return new (Mem) ParenListExpr(EmptyShell(), NumExprs);
+}
+
const OpaqueValueExpr *OpaqueValueExpr::findInCopyConstruct(const Expr *e) {
if (const ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(e))
e = ewc->getSubExpr();