aboutsummaryrefslogtreecommitdiff
path: root/include/clang/AST/Expr.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/Expr.h')
-rw-r--r--include/clang/AST/Expr.h1308
1 files changed, 761 insertions, 547 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index c18fbf05df68..3de73428829b 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -32,6 +32,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/TrailingObjects.h"
namespace clang {
class APValue;
@@ -99,10 +100,9 @@ struct SubobjectAdjustment {
}
};
-/// Expr - This represents one expression. Note that Expr's are subclasses of
-/// Stmt. This allows an expression to be transparently used any place a Stmt
-/// is required.
-///
+/// This represents one expression. Note that Expr's are subclasses of Stmt.
+/// This allows an expression to be transparently used any place a Stmt is
+/// required.
class Expr : public Stmt {
QualType TR;
@@ -583,7 +583,8 @@ public:
/// this function returns true, it returns the folded constant in Result. If
/// the expression is a glvalue, an lvalue-to-rvalue conversion will be
/// applied.
- bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const;
+ bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx,
+ bool InConstantContext = false) const;
/// EvaluateAsBooleanCondition - Return true if this is a constant
/// which we can fold and convert to a boolean condition using
@@ -600,7 +601,7 @@ public:
/// EvaluateAsInt - Return true if this is a constant which we can fold and
/// convert to an integer, using any crazy technique that we want to.
- bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx,
+ bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx,
SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;
/// EvaluateAsFloat - Return true if this is a constant which we can fold and
@@ -632,8 +633,13 @@ public:
/// EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded
/// integer. This must be called on an expression that constant folds to an
/// integer.
- llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx,
- SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const;
+ llvm::APSInt EvaluateKnownConstInt(
+ const ASTContext &Ctx,
+ SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const;
+
+ llvm::APSInt EvaluateKnownConstIntCheckOverflow(
+ const ASTContext &Ctx,
+ SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const;
void EvaluateForOverflow(const ASTContext &Ctx) const;
@@ -864,6 +870,70 @@ public:
};
//===----------------------------------------------------------------------===//
+// Wrapper Expressions.
+//===----------------------------------------------------------------------===//
+
+/// FullExpr - Represents a "full-expression" node.
+class FullExpr : public Expr {
+protected:
+ Stmt *SubExpr;
+
+ FullExpr(StmtClass SC, Expr *subexpr)
+ : Expr(SC, subexpr->getType(),
+ subexpr->getValueKind(), subexpr->getObjectKind(),
+ subexpr->isTypeDependent(), subexpr->isValueDependent(),
+ subexpr->isInstantiationDependent(),
+ subexpr->containsUnexpandedParameterPack()), SubExpr(subexpr) {}
+ FullExpr(StmtClass SC, EmptyShell Empty)
+ : Expr(SC, Empty) {}
+public:
+ const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
+ Expr *getSubExpr() { return cast<Expr>(SubExpr); }
+
+ /// As with any mutator of the AST, be very careful when modifying an
+ /// existing AST to preserve its invariants.
+ void setSubExpr(Expr *E) { SubExpr = E; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() >= firstFullExprConstant &&
+ T->getStmtClass() <= lastFullExprConstant;
+ }
+};
+
+/// ConstantExpr - An expression that occurs in a constant context.
+class ConstantExpr : public FullExpr {
+ ConstantExpr(Expr *subexpr)
+ : FullExpr(ConstantExprClass, subexpr) {}
+
+public:
+ static ConstantExpr *Create(const ASTContext &Context, Expr *E) {
+ assert(!isa<ConstantExpr>(E));
+ return new (Context) ConstantExpr(E);
+ }
+
+ /// Build an empty constant expression wrapper.
+ explicit ConstantExpr(EmptyShell Empty)
+ : FullExpr(ConstantExprClass, Empty) {}
+
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return SubExpr->getBeginLoc();
+ }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return SubExpr->getEndLoc();
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ConstantExprClass;
+ }
+
+ // Iterators
+ child_range children() { return child_range(&SubExpr, &SubExpr+1); }
+ const_child_range children() const {
+ return const_child_range(&SubExpr, &SubExpr + 1);
+ }
+};
+
+//===----------------------------------------------------------------------===//
// Primary Expressions.
//===----------------------------------------------------------------------===//
@@ -875,7 +945,6 @@ public:
class OpaqueValueExpr : public Expr {
friend class ASTStmtReader;
Expr *SourceExpr;
- SourceLocation Loc;
public:
OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK,
@@ -889,8 +958,9 @@ public:
T->isInstantiationDependentType() ||
(SourceExpr && SourceExpr->isInstantiationDependent()),
false),
- SourceExpr(SourceExpr), Loc(Loc) {
+ SourceExpr(SourceExpr) {
setIsUnique(false);
+ OpaqueValueExprBits.Loc = Loc;
}
/// Given an expression which invokes a copy constructor --- i.e. a
@@ -899,20 +969,19 @@ public:
static const OpaqueValueExpr *findInCopyConstruct(const Expr *expr);
explicit OpaqueValueExpr(EmptyShell Empty)
- : Expr(OpaqueValueExprClass, Empty) { }
+ : Expr(OpaqueValueExprClass, Empty) {}
/// Retrieve the location of this expression.
- SourceLocation getLocation() const { return Loc; }
+ SourceLocation getLocation() const { return OpaqueValueExprBits.Loc; }
- SourceLocation getLocStart() const LLVM_READONLY {
- return SourceExpr ? SourceExpr->getLocStart() : Loc;
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return SourceExpr ? SourceExpr->getBeginLoc() : getLocation();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SourceExpr ? SourceExpr->getLocEnd() : Loc;
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return SourceExpr ? SourceExpr->getEndLoc() : getLocation();
}
SourceLocation getExprLoc() const LLVM_READONLY {
- if (SourceExpr) return SourceExpr->getExprLoc();
- return Loc;
+ return SourceExpr ? SourceExpr->getExprLoc() : getLocation();
}
child_range children() {
@@ -974,63 +1043,52 @@ class DeclRefExpr final
private llvm::TrailingObjects<DeclRefExpr, NestedNameSpecifierLoc,
NamedDecl *, ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc> {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
/// The declaration that we are referencing.
ValueDecl *D;
- /// The location of the declaration name itself.
- SourceLocation Loc;
-
/// Provides source/type location info for the declaration name
/// embedded in D.
DeclarationNameLoc DNLoc;
size_t numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const {
- return hasQualifier() ? 1 : 0;
+ return hasQualifier();
}
size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
- return hasFoundDecl() ? 1 : 0;
+ return hasFoundDecl();
}
size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return hasTemplateKWAndArgsInfo() ? 1 : 0;
+ return hasTemplateKWAndArgsInfo();
}
/// Test whether there is a distinct FoundDecl attached to the end of
/// this DRE.
bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; }
- DeclRefExpr(const ASTContext &Ctx,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- ValueDecl *D, bool RefersToEnlosingVariableOrCapture,
- const DeclarationNameInfo &NameInfo,
- NamedDecl *FoundD,
- const TemplateArgumentListInfo *TemplateArgs,
- QualType T, ExprValueKind VK);
+ DeclRefExpr(const ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKWLoc, ValueDecl *D,
+ bool RefersToEnlosingVariableOrCapture,
+ const DeclarationNameInfo &NameInfo, NamedDecl *FoundD,
+ const TemplateArgumentListInfo *TemplateArgs, QualType T,
+ ExprValueKind VK);
/// Construct an empty declaration reference expression.
- explicit DeclRefExpr(EmptyShell Empty)
- : Expr(DeclRefExprClass, Empty) { }
+ explicit DeclRefExpr(EmptyShell Empty) : Expr(DeclRefExprClass, Empty) {}
/// Computes the type- and value-dependence flags for this
/// declaration reference expression.
- void computeDependence(const ASTContext &C);
+ void computeDependence(const ASTContext &Ctx);
public:
- DeclRefExpr(ValueDecl *D, bool RefersToEnclosingVariableOrCapture, QualType T,
+ DeclRefExpr(const ASTContext &Ctx, ValueDecl *D,
+ bool RefersToEnclosingVariableOrCapture, QualType T,
ExprValueKind VK, SourceLocation L,
- const DeclarationNameLoc &LocInfo = DeclarationNameLoc())
- : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
- D(D), Loc(L), DNLoc(LocInfo) {
- DeclRefExprBits.HasQualifier = 0;
- DeclRefExprBits.HasTemplateKWAndArgsInfo = 0;
- DeclRefExprBits.HasFoundDecl = 0;
- DeclRefExprBits.HadMultipleCandidates = 0;
- DeclRefExprBits.RefersToEnclosingVariableOrCapture =
- RefersToEnclosingVariableOrCapture;
- computeDependence(D->getASTContext());
- }
+ const DeclarationNameLoc &LocInfo = DeclarationNameLoc());
static DeclRefExpr *
Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
@@ -1048,8 +1106,7 @@ public:
const TemplateArgumentListInfo *TemplateArgs = nullptr);
/// Construct an empty declaration reference expression.
- static DeclRefExpr *CreateEmpty(const ASTContext &Context,
- bool HasQualifier,
+ static DeclRefExpr *CreateEmpty(const ASTContext &Context, bool HasQualifier,
bool HasFoundDecl,
bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs);
@@ -1059,13 +1116,13 @@ public:
void setDecl(ValueDecl *NewD) { D = NewD; }
DeclarationNameInfo getNameInfo() const {
- return DeclarationNameInfo(getDecl()->getDeclName(), Loc, DNLoc);
+ return DeclarationNameInfo(getDecl()->getDeclName(), getLocation(), DNLoc);
}
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getLocation() const { return DeclRefExprBits.Loc; }
+ void setLocation(SourceLocation L) { DeclRefExprBits.Loc = L; }
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const LLVM_READONLY;
/// Determine whether this declaration reference was preceded by a
/// C++ nested-name-specifier, e.g., \c N::foo.
@@ -1108,21 +1165,24 @@ public:
/// Retrieve the location of the template keyword preceding
/// this name, if any.
SourceLocation getTemplateKeywordLoc() const {
- if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
}
/// Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the name, if any.
SourceLocation getLAngleLoc() const {
- if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
}
/// Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the name, if any.
SourceLocation getRAngleLoc() const {
- if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
}
@@ -1147,7 +1207,6 @@ public:
const TemplateArgumentLoc *getTemplateArgs() const {
if (!hasExplicitTemplateArgs())
return nullptr;
-
return getTrailingObjects<TemplateArgumentLoc>();
}
@@ -1156,7 +1215,6 @@ public:
unsigned getNumTemplateArgs() const {
if (!hasExplicitTemplateArgs())
return 0;
-
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
}
@@ -1194,68 +1252,6 @@ public:
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// [C99 6.4.2.2] - A predefined identifier such as __func__.
-class PredefinedExpr : public Expr {
-public:
- enum IdentType {
- Func,
- Function,
- LFunction, // Same as Function, but as wide string.
- FuncDName,
- FuncSig,
- LFuncSig, // Same as FuncSig, but as as wide string
- PrettyFunction,
- /// The same as PrettyFunction, except that the
- /// 'virtual' keyword is omitted for virtual member functions.
- PrettyFunctionNoVirtual
- };
-
-private:
- SourceLocation Loc;
- IdentType Type;
- Stmt *FnName;
-
-public:
- PredefinedExpr(SourceLocation L, QualType FNTy, IdentType IT,
- StringLiteral *SL);
-
- /// Construct an empty predefined expression.
- explicit PredefinedExpr(EmptyShell Empty)
- : Expr(PredefinedExprClass, Empty), Loc(), Type(Func), FnName(nullptr) {}
-
- IdentType getIdentType() const { return Type; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- StringLiteral *getFunctionName();
- const StringLiteral *getFunctionName() const {
- return const_cast<PredefinedExpr *>(this)->getFunctionName();
- }
-
- static StringRef getIdentTypeName(IdentType IT);
- static std::string ComputeName(IdentType IT, const Decl *CurrentDecl);
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == PredefinedExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&FnName, &FnName + 1); }
- const_child_range children() const {
- return const_child_range(&FnName, &FnName + 1);
- }
-
- friend class ASTStmtReader;
};
/// Used by IntegerLiteral/FloatingLiteral to store the numeric without
@@ -1331,8 +1327,8 @@ public:
/// Returns a new empty integer literal.
static IntegerLiteral *Create(const ASTContext &C, EmptyShell Empty);
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
/// Retrieve the location of the literal.
SourceLocation getLocation() const { return Loc; }
@@ -1370,8 +1366,8 @@ class FixedPointLiteral : public Expr, public APIntStorage {
QualType type, SourceLocation l,
unsigned Scale);
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
/// \brief Retrieve the location of the literal.
SourceLocation getLocation() const { return Loc; }
@@ -1424,8 +1420,8 @@ public:
return static_cast<CharacterKind>(CharacterLiteralBits.Kind);
}
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
unsigned getValue() const { return Value; }
@@ -1497,8 +1493,8 @@ public:
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == FloatingLiteralClass;
@@ -1534,8 +1530,10 @@ public:
Expr *getSubExpr() { return cast<Expr>(Val); }
void setSubExpr(Expr *E) { Val = E; }
- SourceLocation getLocStart() const LLVM_READONLY { return Val->getLocStart(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Val->getLocEnd(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return Val->getBeginLoc();
+ }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Val->getEndLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ImaginaryLiteralClass;
@@ -1549,14 +1547,15 @@ public:
};
/// StringLiteral - This represents a string literal expression, e.g. "foo"
-/// or L"bar" (wide strings). The actual string is returned by getBytes()
-/// is NOT null-terminated, and the length of the string is determined by
-/// calling getByteLength(). The C type for a string is always a
-/// ConstantArrayType. In C++, the char type is const qualified, in C it is
-/// not.
+/// or L"bar" (wide strings). The actual string data can be obtained with
+/// getBytes() and is NOT null-terminated. The length of the string data is
+/// determined by calling getByteLength().
+///
+/// The C type for a string is always a ConstantArrayType. In C++, the char
+/// type is const qualified, in C it is not.
///
/// Note that strings in C can be formed by concatenation of multiple string
-/// literal pptokens in translation phase #6. This keeps track of the locations
+/// literal pptokens in translation phase #6. This keeps track of the locations
/// of each of these pieces.
///
/// Strings in C can also be truncated and extended by assigning into arrays,
@@ -1564,131 +1563,156 @@ public:
/// char X[2] = "foobar";
/// In this case, getByteLength() will return 6, but the string literal will
/// have type "char[2]".
-class StringLiteral : public Expr {
+class StringLiteral final
+ : public Expr,
+ private llvm::TrailingObjects<StringLiteral, unsigned, SourceLocation,
+ char> {
+ friend class ASTStmtReader;
+ friend TrailingObjects;
+
+ /// StringLiteral is followed by several trailing objects. They are in order:
+ ///
+ /// * A single unsigned storing the length in characters of this string. The
+ /// length in bytes is this length times the width of a single character.
+ /// Always present and stored as a trailing objects because storing it in
+ /// StringLiteral would increase the size of StringLiteral by sizeof(void *)
+ /// due to alignment requirements. If you add some data to StringLiteral,
+ /// consider moving it inside StringLiteral.
+ ///
+ /// * An array of getNumConcatenated() SourceLocation, one for each of the
+ /// token this string is made of.
+ ///
+ /// * An array of getByteLength() char used to store the string data.
+
public:
- enum StringKind {
- Ascii,
- Wide,
- UTF8,
- UTF16,
- UTF32
- };
+ enum StringKind { Ascii, Wide, UTF8, UTF16, UTF32 };
private:
- friend class ASTStmtReader;
+ unsigned numTrailingObjects(OverloadToken<unsigned>) const { return 1; }
+ unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
+ return getNumConcatenated();
+ }
- union {
- const char *asChar;
- const uint16_t *asUInt16;
- const uint32_t *asUInt32;
- } StrData;
- unsigned Length;
- unsigned CharByteWidth : 4;
- unsigned Kind : 3;
- unsigned IsPascal : 1;
- unsigned NumConcatenated;
- SourceLocation TokLocs[1];
+ unsigned numTrailingObjects(OverloadToken<char>) const {
+ return getByteLength();
+ }
+
+ char *getStrDataAsChar() { return getTrailingObjects<char>(); }
+ const char *getStrDataAsChar() const { return getTrailingObjects<char>(); }
- StringLiteral(QualType Ty) :
- Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false,
- false) {}
+ const uint16_t *getStrDataAsUInt16() const {
+ return reinterpret_cast<const uint16_t *>(getTrailingObjects<char>());
+ }
+
+ const uint32_t *getStrDataAsUInt32() const {
+ return reinterpret_cast<const uint32_t *>(getTrailingObjects<char>());
+ }
+
+ /// Build a string literal.
+ StringLiteral(const ASTContext &Ctx, StringRef Str, StringKind Kind,
+ bool Pascal, QualType Ty, const SourceLocation *Loc,
+ unsigned NumConcatenated);
+
+ /// Build an empty string literal.
+ StringLiteral(EmptyShell Empty, unsigned NumConcatenated, unsigned Length,
+ unsigned CharByteWidth);
- static int mapCharByteWidth(TargetInfo const &target,StringKind k);
+ /// Map a target and string kind to the appropriate character width.
+ static unsigned mapCharByteWidth(TargetInfo const &Target, StringKind SK);
+
+ /// Set one of the string literal token.
+ void setStrTokenLoc(unsigned TokNum, SourceLocation L) {
+ assert(TokNum < getNumConcatenated() && "Invalid tok number");
+ getTrailingObjects<SourceLocation>()[TokNum] = L;
+ }
public:
/// This is the "fully general" constructor that allows representation of
/// strings formed from multiple concatenated tokens.
- static StringLiteral *Create(const ASTContext &C, StringRef Str,
+ static StringLiteral *Create(const ASTContext &Ctx, StringRef Str,
StringKind Kind, bool Pascal, QualType Ty,
- const SourceLocation *Loc, unsigned NumStrs);
+ const SourceLocation *Loc,
+ unsigned NumConcatenated);
/// Simple constructor for string literals made from one token.
- static StringLiteral *Create(const ASTContext &C, StringRef Str,
+ static StringLiteral *Create(const ASTContext &Ctx, StringRef Str,
StringKind Kind, bool Pascal, QualType Ty,
SourceLocation Loc) {
- return Create(C, Str, Kind, Pascal, Ty, &Loc, 1);
+ return Create(Ctx, Str, Kind, Pascal, Ty, &Loc, 1);
}
/// Construct an empty string literal.
- static StringLiteral *CreateEmpty(const ASTContext &C, unsigned NumStrs);
+ static StringLiteral *CreateEmpty(const ASTContext &Ctx,
+ unsigned NumConcatenated, unsigned Length,
+ unsigned CharByteWidth);
StringRef getString() const {
- assert(CharByteWidth==1
- && "This function is used in places that assume strings use char");
- return StringRef(StrData.asChar, getByteLength());
+ assert(getCharByteWidth() == 1 &&
+ "This function is used in places that assume strings use char");
+ return StringRef(getStrDataAsChar(), getByteLength());
}
/// Allow access to clients that need the byte representation, such as
/// ASTWriterStmt::VisitStringLiteral().
StringRef getBytes() const {
// FIXME: StringRef may not be the right type to use as a result for this.
- if (CharByteWidth == 1)
- return StringRef(StrData.asChar, getByteLength());
- if (CharByteWidth == 4)
- return StringRef(reinterpret_cast<const char*>(StrData.asUInt32),
- getByteLength());
- assert(CharByteWidth == 2 && "unsupported CharByteWidth");
- return StringRef(reinterpret_cast<const char*>(StrData.asUInt16),
- getByteLength());
+ return StringRef(getStrDataAsChar(), getByteLength());
}
void outputString(raw_ostream &OS) const;
uint32_t getCodeUnit(size_t i) const {
- assert(i < Length && "out of bounds access");
- if (CharByteWidth == 1)
- return static_cast<unsigned char>(StrData.asChar[i]);
- if (CharByteWidth == 4)
- return StrData.asUInt32[i];
- assert(CharByteWidth == 2 && "unsupported CharByteWidth");
- return StrData.asUInt16[i];
+ assert(i < getLength() && "out of bounds access");
+ switch (getCharByteWidth()) {
+ case 1:
+ return static_cast<unsigned char>(getStrDataAsChar()[i]);
+ case 2:
+ return getStrDataAsUInt16()[i];
+ case 4:
+ return getStrDataAsUInt32()[i];
+ }
+ llvm_unreachable("Unsupported character width!");
}
- unsigned getByteLength() const { return CharByteWidth*Length; }
- unsigned getLength() const { return Length; }
- unsigned getCharByteWidth() const { return CharByteWidth; }
-
- /// Sets the string data to the given string data.
- void setString(const ASTContext &C, StringRef Str,
- StringKind Kind, bool IsPascal);
-
- StringKind getKind() const { return static_cast<StringKind>(Kind); }
+ unsigned getByteLength() const { return getCharByteWidth() * getLength(); }
+ unsigned getLength() const { return *getTrailingObjects<unsigned>(); }
+ unsigned getCharByteWidth() const { return StringLiteralBits.CharByteWidth; }
+ StringKind getKind() const {
+ return static_cast<StringKind>(StringLiteralBits.Kind);
+ }
- bool isAscii() const { return Kind == Ascii; }
- bool isWide() const { return Kind == Wide; }
- bool isUTF8() const { return Kind == UTF8; }
- bool isUTF16() const { return Kind == UTF16; }
- bool isUTF32() const { return Kind == UTF32; }
- bool isPascal() const { return IsPascal; }
+ bool isAscii() const { return getKind() == Ascii; }
+ bool isWide() const { return getKind() == Wide; }
+ bool isUTF8() const { return getKind() == UTF8; }
+ bool isUTF16() const { return getKind() == UTF16; }
+ bool isUTF32() const { return getKind() == UTF32; }
+ bool isPascal() const { return StringLiteralBits.IsPascal; }
bool containsNonAscii() const {
- StringRef Str = getString();
- for (unsigned i = 0, e = Str.size(); i != e; ++i)
- if (!isASCII(Str[i]))
+ for (auto c : getString())
+ if (!isASCII(c))
return true;
return false;
}
bool containsNonAsciiOrNull() const {
- StringRef Str = getString();
- for (unsigned i = 0, e = Str.size(); i != e; ++i)
- if (!isASCII(Str[i]) || !Str[i])
+ for (auto c : getString())
+ if (!isASCII(c) || !c)
return true;
return false;
}
/// getNumConcatenated - Get the number of string literal tokens that were
/// concatenated in translation phase #6 to form this string literal.
- unsigned getNumConcatenated() const { return NumConcatenated; }
+ unsigned getNumConcatenated() const {
+ return StringLiteralBits.NumConcatenated;
+ }
+ /// Get one of the string literal token.
SourceLocation getStrTokenLoc(unsigned TokNum) const {
- assert(TokNum < NumConcatenated && "Invalid tok number");
- return TokLocs[TokNum];
- }
- void setStrTokenLoc(unsigned TokNum, SourceLocation L) {
- assert(TokNum < NumConcatenated && "Invalid tok number");
- TokLocs[TokNum] = L;
+ assert(TokNum < getNumConcatenated() && "Invalid tok number");
+ return getTrailingObjects<SourceLocation>()[TokNum];
}
/// getLocationOfByte - Return a source location that points to the specified
@@ -1705,14 +1729,18 @@ public:
unsigned *StartTokenByteOffset = nullptr) const;
typedef const SourceLocation *tokloc_iterator;
- tokloc_iterator tokloc_begin() const { return TokLocs; }
- tokloc_iterator tokloc_end() const { return TokLocs + NumConcatenated; }
- SourceLocation getLocStart() const LLVM_READONLY { return TokLocs[0]; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return TokLocs[NumConcatenated - 1];
+ tokloc_iterator tokloc_begin() const {
+ return getTrailingObjects<SourceLocation>();
}
+ tokloc_iterator tokloc_end() const {
+ return getTrailingObjects<SourceLocation>() + getNumConcatenated();
+ }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY { return *tokloc_begin(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return *(tokloc_end() - 1); }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == StringLiteralClass;
}
@@ -1726,6 +1754,91 @@ public:
}
};
+/// [C99 6.4.2.2] - A predefined identifier such as __func__.
+class PredefinedExpr final
+ : public Expr,
+ private llvm::TrailingObjects<PredefinedExpr, Stmt *> {
+ friend class ASTStmtReader;
+ friend TrailingObjects;
+
+ // PredefinedExpr is optionally followed by a single trailing
+ // "Stmt *" for the predefined identifier. It is present if and only if
+ // hasFunctionName() is true and is always a "StringLiteral *".
+
+public:
+ enum IdentKind {
+ Func,
+ Function,
+ LFunction, // Same as Function, but as wide string.
+ FuncDName,
+ FuncSig,
+ LFuncSig, // Same as FuncSig, but as as wide string
+ PrettyFunction,
+ /// The same as PrettyFunction, except that the
+ /// 'virtual' keyword is omitted for virtual member functions.
+ PrettyFunctionNoVirtual
+ };
+
+private:
+ PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
+ StringLiteral *SL);
+
+ explicit PredefinedExpr(EmptyShell Empty, bool HasFunctionName);
+
+ /// True if this PredefinedExpr has storage for a function name.
+ bool hasFunctionName() const { return PredefinedExprBits.HasFunctionName; }
+
+ void setFunctionName(StringLiteral *SL) {
+ assert(hasFunctionName() &&
+ "This PredefinedExpr has no storage for a function name!");
+ *getTrailingObjects<Stmt *>() = SL;
+ }
+
+public:
+ /// Create a PredefinedExpr.
+ static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L,
+ QualType FNTy, IdentKind IK, StringLiteral *SL);
+
+ /// Create an empty PredefinedExpr.
+ static PredefinedExpr *CreateEmpty(const ASTContext &Ctx,
+ bool HasFunctionName);
+
+ IdentKind getIdentKind() const {
+ return static_cast<IdentKind>(PredefinedExprBits.Kind);
+ }
+
+ SourceLocation getLocation() const { return PredefinedExprBits.Loc; }
+ void setLocation(SourceLocation L) { PredefinedExprBits.Loc = L; }
+
+ StringLiteral *getFunctionName() {
+ return hasFunctionName()
+ ? static_cast<StringLiteral *>(*getTrailingObjects<Stmt *>())
+ : nullptr;
+ }
+
+ const StringLiteral *getFunctionName() const {
+ return hasFunctionName()
+ ? static_cast<StringLiteral *>(*getTrailingObjects<Stmt *>())
+ : nullptr;
+ }
+
+ static StringRef getIdentKindName(IdentKind IK);
+ static std::string ComputeName(IdentKind IK, const Decl *CurrentDecl);
+
+ SourceLocation getBeginLoc() const { return getLocation(); }
+ SourceLocation getEndLoc() const { return getLocation(); }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == PredefinedExprClass;
+ }
+
+ // Iterators
+ child_range children() {
+ return child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() + hasFunctionName());
+ }
+};
+
/// ParenExpr - This represents a parethesized expression, e.g. "(1)". This
/// AST node is only formed if full location information is requested.
class ParenExpr : public Expr {
@@ -1748,8 +1861,8 @@ public:
Expr *getSubExpr() { return cast<Expr>(Val); }
void setSubExpr(Expr *E) { Val = E; }
- SourceLocation getLocStart() const LLVM_READONLY { return L; }
- SourceLocation getLocEnd() const LLVM_READONLY { return R; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return L; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return R; }
/// Get the location of the left parentheses '('.
SourceLocation getLParen() const { return L; }
@@ -1781,15 +1894,11 @@ public:
/// later returns zero in the type of the operand.
///
class UnaryOperator : public Expr {
+ Stmt *Val;
+
public:
typedef UnaryOperatorKind Opcode;
-private:
- unsigned Opc : 5;
- unsigned CanOverflow : 1;
- SourceLocation Loc;
- Stmt *Val;
-public:
UnaryOperator(Expr *input, Opcode opc, QualType type, ExprValueKind VK,
ExprObjectKind OK, SourceLocation l, bool CanOverflow)
: Expr(UnaryOperatorClass, type, VK, OK,
@@ -1798,21 +1907,28 @@ public:
(input->isInstantiationDependent() ||
type->isInstantiationDependentType()),
input->containsUnexpandedParameterPack()),
- Opc(opc), CanOverflow(CanOverflow), Loc(l), Val(input) {}
+ Val(input) {
+ UnaryOperatorBits.Opc = opc;
+ UnaryOperatorBits.CanOverflow = CanOverflow;
+ UnaryOperatorBits.Loc = l;
+ }
/// Build an empty unary operator.
- explicit UnaryOperator(EmptyShell Empty)
- : Expr(UnaryOperatorClass, Empty), Opc(UO_AddrOf) { }
+ explicit UnaryOperator(EmptyShell Empty) : Expr(UnaryOperatorClass, Empty) {
+ UnaryOperatorBits.Opc = UO_AddrOf;
+ }
- Opcode getOpcode() const { return static_cast<Opcode>(Opc); }
- void setOpcode(Opcode O) { Opc = O; }
+ Opcode getOpcode() const {
+ return static_cast<Opcode>(UnaryOperatorBits.Opc);
+ }
+ void setOpcode(Opcode Opc) { UnaryOperatorBits.Opc = Opc; }
Expr *getSubExpr() const { return cast<Expr>(Val); }
void setSubExpr(Expr *E) { Val = E; }
/// getOperatorLoc - Return the location of the operator.
- SourceLocation getOperatorLoc() const { return Loc; }
- void setOperatorLoc(SourceLocation L) { Loc = L; }
+ SourceLocation getOperatorLoc() const { return UnaryOperatorBits.Loc; }
+ void setOperatorLoc(SourceLocation L) { UnaryOperatorBits.Loc = L; }
/// Returns true if the unary operator can cause an overflow. For instance,
/// signed int i = INT_MAX; i++;
@@ -1820,8 +1936,8 @@ public:
/// Due to integer promotions, c++ is promoted to an int before the postfix
/// increment, and the result is an int that cannot overflow. However, i++
/// can overflow.
- bool canOverflow() const { return CanOverflow; }
- void setCanOverflow(bool C) { CanOverflow = C; }
+ bool canOverflow() const { return UnaryOperatorBits.CanOverflow; }
+ void setCanOverflow(bool C) { UnaryOperatorBits.CanOverflow = C; }
/// isPostfix - Return true if this is a postfix operation, like x++.
static bool isPostfix(Opcode Op) {
@@ -1872,13 +1988,13 @@ public:
/// the given unary opcode.
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
- SourceLocation getLocStart() const LLVM_READONLY {
- return isPostfix() ? Val->getLocStart() : Loc;
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return isPostfix() ? Val->getBeginLoc() : getOperatorLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return isPostfix() ? Loc : Val->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return isPostfix() ? getOperatorLoc() : Val->getEndLoc();
}
- SourceLocation getExprLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getExprLoc() const { return getOperatorLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == UnaryOperatorClass;
@@ -1980,8 +2096,8 @@ public:
/// contains the location of the period (if there is one) and the
/// identifier.
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
};
/// OffsetOfExpr - [C99 7.17] - This represents an expression of the form
@@ -2080,8 +2196,8 @@ public:
return NumExprs;
}
- SourceLocation getLocStart() const LLVM_READONLY { return OperatorLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return OperatorLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == OffsetOfExprClass;
@@ -2176,8 +2292,8 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return OpLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return OpLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == UnaryExprOrTypeTraitExprClass;
@@ -2194,9 +2310,11 @@ public:
/// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
class ArraySubscriptExpr : public Expr {
- enum { LHS, RHS, END_EXPR=2 };
- Stmt* SubExprs[END_EXPR];
- SourceLocation RBracketLoc;
+ enum { LHS, RHS, END_EXPR };
+ Stmt *SubExprs[END_EXPR];
+
+ bool lhsIsBase() const { return getRHS()->getType()->isIntegerType(); }
+
public:
ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t,
ExprValueKind VK, ExprObjectKind OK,
@@ -2207,10 +2325,10 @@ public:
(lhs->isInstantiationDependent() ||
rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())),
- RBracketLoc(rbracketloc) {
+ rhs->containsUnexpandedParameterPack())) {
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
+ ArraySubscriptExprBits.RBracketLoc = rbracketloc;
}
/// Create an empty array subscript expression.
@@ -2234,29 +2352,23 @@ public:
const Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
void setRHS(Expr *E) { SubExprs[RHS] = E; }
- Expr *getBase() {
- return getRHS()->getType()->isIntegerType() ? getLHS() : getRHS();
- }
+ Expr *getBase() { return lhsIsBase() ? getLHS() : getRHS(); }
+ const Expr *getBase() const { return lhsIsBase() ? getLHS() : getRHS(); }
- const Expr *getBase() const {
- return getRHS()->getType()->isIntegerType() ? getLHS() : getRHS();
- }
+ Expr *getIdx() { return lhsIsBase() ? getRHS() : getLHS(); }
+ const Expr *getIdx() const { return lhsIsBase() ? getRHS() : getLHS(); }
- Expr *getIdx() {
- return getRHS()->getType()->isIntegerType() ? getRHS() : getLHS();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getLHS()->getBeginLoc();
}
+ SourceLocation getEndLoc() const { return getRBracketLoc(); }
- const Expr *getIdx() const {
- return getRHS()->getType()->isIntegerType() ? getRHS() : getLHS();
+ SourceLocation getRBracketLoc() const {
+ return ArraySubscriptExprBits.RBracketLoc;
}
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getLHS()->getLocStart();
+ void setRBracketLoc(SourceLocation L) {
+ ArraySubscriptExprBits.RBracketLoc = L;
}
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; }
-
- SourceLocation getRBracketLoc() const { return RBracketLoc; }
- void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
SourceLocation getExprLoc() const LLVM_READONLY {
return getBase()->getExprLoc();
@@ -2282,127 +2394,221 @@ public:
/// a subclass for overloaded operator calls that use operator syntax, e.g.,
/// "str1 + str2" to resolve to a function call.
class CallExpr : public Expr {
- enum { FN=0, PREARGS_START=1 };
- Stmt **SubExprs;
+ enum { FN = 0, PREARGS_START = 1 };
+
+ /// The number of arguments in the call expression.
unsigned NumArgs;
+
+ /// The location of the right parenthese. This has a different meaning for
+ /// the derived classes of CallExpr.
SourceLocation RParenLoc;
void updateDependenciesFromArg(Expr *Arg);
+ // CallExpr store some data in trailing objects. However since CallExpr
+ // is used a base of other expression classes we cannot use
+ // llvm::TrailingObjects. Instead we manually perform the pointer arithmetic
+ // and casts.
+ //
+ // The trailing objects are in order:
+ //
+ // * A single "Stmt *" for the callee expression.
+ //
+ // * An array of getNumPreArgs() "Stmt *" for the pre-argument expressions.
+ //
+ // * An array of getNumArgs() "Stmt *" for the argument expressions.
+ //
+ // Note that we store the offset in bytes from the this pointer to the start
+ // of the trailing objects. It would be perfectly possible to compute it
+ // based on the dynamic kind of the CallExpr. However 1.) we have plenty of
+ // space in the bit-fields of Stmt. 2.) It was benchmarked to be faster to
+ // compute this once and then load the offset from the bit-fields of Stmt,
+ // instead of re-computing the offset each time the trailing objects are
+ // accessed.
+
+ /// Return a pointer to the start of the trailing array of "Stmt *".
+ Stmt **getTrailingStmts() {
+ return reinterpret_cast<Stmt **>(reinterpret_cast<char *>(this) +
+ CallExprBits.OffsetToTrailingObjects);
+ }
+ Stmt *const *getTrailingStmts() const {
+ return const_cast<CallExpr *>(this)->getTrailingStmts();
+ }
+
+ /// Map a statement class to the appropriate offset in bytes from the
+ /// this pointer to the trailing objects.
+ static unsigned offsetToTrailingObjects(StmtClass SC);
+
+public:
+ enum class ADLCallKind : bool { NotADL, UsesADL };
+ static constexpr ADLCallKind NotADL = ADLCallKind::NotADL;
+ static constexpr ADLCallKind UsesADL = ADLCallKind::UsesADL;
+
protected:
- // These versions of the constructor are for derived classes.
- CallExpr(const ASTContext &C, StmtClass SC, Expr *fn,
- ArrayRef<Expr *> preargs, ArrayRef<Expr *> args, QualType t,
- ExprValueKind VK, SourceLocation rparenloc);
- CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, ArrayRef<Expr *> args,
- QualType t, ExprValueKind VK, SourceLocation rparenloc);
- CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
+ /// Build a call expression, assuming that appropriate storage has been
+ /// allocated for the trailing objects.
+ CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs,
+ ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
+ SourceLocation RParenLoc, unsigned MinNumArgs, ADLCallKind UsesADL);
+
+ /// Build an empty call expression, for deserialization.
+ CallExpr(StmtClass SC, unsigned NumPreArgs, unsigned NumArgs,
EmptyShell Empty);
- Stmt *getPreArg(unsigned i) {
- assert(i < getNumPreArgs() && "Prearg access out of range!");
- return SubExprs[PREARGS_START+i];
+ /// Return the size in bytes needed for the trailing objects.
+ /// Used by the derived classes to allocate the right amount of storage.
+ static unsigned sizeOfTrailingObjects(unsigned NumPreArgs, unsigned NumArgs) {
+ return (1 + NumPreArgs + NumArgs) * sizeof(Stmt *);
}
- const Stmt *getPreArg(unsigned i) const {
- assert(i < getNumPreArgs() && "Prearg access out of range!");
- return SubExprs[PREARGS_START+i];
+
+ Stmt *getPreArg(unsigned I) {
+ assert(I < getNumPreArgs() && "Prearg access out of range!");
+ return getTrailingStmts()[PREARGS_START + I];
+ }
+ const Stmt *getPreArg(unsigned I) const {
+ assert(I < getNumPreArgs() && "Prearg access out of range!");
+ return getTrailingStmts()[PREARGS_START + I];
}
- void setPreArg(unsigned i, Stmt *PreArg) {
- assert(i < getNumPreArgs() && "Prearg access out of range!");
- SubExprs[PREARGS_START+i] = PreArg;
+ void setPreArg(unsigned I, Stmt *PreArg) {
+ assert(I < getNumPreArgs() && "Prearg access out of range!");
+ getTrailingStmts()[PREARGS_START + I] = PreArg;
}
unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; }
public:
- CallExpr(const ASTContext& C, Expr *fn, ArrayRef<Expr*> args, QualType t,
- ExprValueKind VK, SourceLocation rparenloc);
+ /// Create a call expression. Fn is the callee expression, Args is the
+ /// argument array, Ty is the type of the call expression (which is *not*
+ /// the return type in general), VK is the value kind of the call expression
+ /// (lvalue, rvalue, ...), and RParenLoc is the location of the right
+ /// parenthese in the call expression. MinNumArgs specifies the minimum
+ /// number of arguments. The actual number of arguments will be the greater
+ /// of Args.size() and MinNumArgs. This is used in a few places to allocate
+ /// enough storage for the default arguments. UsesADL specifies whether the
+ /// callee was found through argument-dependent lookup.
+ ///
+ /// Note that you can use CreateTemporary if you need a temporary call
+ /// expression on the stack.
+ static CallExpr *Create(const ASTContext &Ctx, Expr *Fn,
+ ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
+ SourceLocation RParenLoc, unsigned MinNumArgs = 0,
+ ADLCallKind UsesADL = NotADL);
- /// Build an empty call expression.
- CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty);
+ /// Create a temporary call expression with no arguments in the memory
+ /// pointed to by Mem. Mem must points to at least sizeof(CallExpr)
+ /// + sizeof(Stmt *) bytes of storage, aligned to alignof(CallExpr):
+ ///
+ /// \code{.cpp}
+ /// llvm::AlignedCharArray<alignof(CallExpr),
+ /// sizeof(CallExpr) + sizeof(Stmt *)> Buffer;
+ /// CallExpr *TheCall = CallExpr::CreateTemporary(Buffer.buffer, etc);
+ /// \endcode
+ static CallExpr *CreateTemporary(void *Mem, Expr *Fn, QualType Ty,
+ ExprValueKind VK, SourceLocation RParenLoc,
+ ADLCallKind UsesADL = NotADL);
- const Expr *getCallee() const { return cast<Expr>(SubExprs[FN]); }
- Expr *getCallee() { return cast<Expr>(SubExprs[FN]); }
- void setCallee(Expr *F) { SubExprs[FN] = F; }
+ /// Create an empty call expression, for deserialization.
+ static CallExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
+ EmptyShell Empty);
+
+ Expr *getCallee() { return cast<Expr>(getTrailingStmts()[FN]); }
+ const Expr *getCallee() const { return cast<Expr>(getTrailingStmts()[FN]); }
+ void setCallee(Expr *F) { getTrailingStmts()[FN] = F; }
+
+ ADLCallKind getADLCallKind() const {
+ return static_cast<ADLCallKind>(CallExprBits.UsesADL);
+ }
+ void setADLCallKind(ADLCallKind V = UsesADL) {
+ CallExprBits.UsesADL = static_cast<bool>(V);
+ }
+ bool usesADL() const { return getADLCallKind() == UsesADL; }
- Decl *getCalleeDecl();
+ Decl *getCalleeDecl() { return getCallee()->getReferencedDeclOfCallee(); }
const Decl *getCalleeDecl() const {
- return const_cast<CallExpr*>(this)->getCalleeDecl();
+ return getCallee()->getReferencedDeclOfCallee();
}
- /// If the callee is a FunctionDecl, return it. Otherwise return 0.
- FunctionDecl *getDirectCallee();
+ /// If the callee is a FunctionDecl, return it. Otherwise return null.
+ FunctionDecl *getDirectCallee() {
+ return dyn_cast_or_null<FunctionDecl>(getCalleeDecl());
+ }
const FunctionDecl *getDirectCallee() const {
- return const_cast<CallExpr*>(this)->getDirectCallee();
+ return dyn_cast_or_null<FunctionDecl>(getCalleeDecl());
}
/// getNumArgs - Return the number of actual arguments to this call.
- ///
unsigned getNumArgs() const { return NumArgs; }
/// Retrieve the call arguments.
Expr **getArgs() {
- return reinterpret_cast<Expr **>(SubExprs+getNumPreArgs()+PREARGS_START);
+ return reinterpret_cast<Expr **>(getTrailingStmts() + PREARGS_START +
+ getNumPreArgs());
}
const Expr *const *getArgs() const {
- return reinterpret_cast<Expr **>(SubExprs + getNumPreArgs() +
- PREARGS_START);
+ return reinterpret_cast<const Expr *const *>(
+ getTrailingStmts() + PREARGS_START + getNumPreArgs());
}
/// getArg - Return the specified argument.
Expr *getArg(unsigned Arg) {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
+ assert(Arg < getNumArgs() && "Arg access out of range!");
+ return getArgs()[Arg];
}
const Expr *getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
+ assert(Arg < getNumArgs() && "Arg access out of range!");
+ return getArgs()[Arg];
}
/// setArg - Set the specified argument.
void setArg(unsigned Arg, Expr *ArgExpr) {
- assert(Arg < NumArgs && "Arg access out of range!");
- SubExprs[Arg+getNumPreArgs()+PREARGS_START] = ArgExpr;
+ assert(Arg < getNumArgs() && "Arg access out of range!");
+ getArgs()[Arg] = ArgExpr;
}
- /// 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 setNumArgs(const ASTContext& C, unsigned NumArgs);
+ /// Reduce the number of arguments in this call expression. This is used for
+ /// example during error recovery to drop extra arguments. There is no way
+ /// to perform the opposite because: 1.) We don't track how much storage
+ /// we have for the argument array 2.) This would potentially require growing
+ /// the argument array, something we cannot support since the arguments are
+ /// stored in a trailing array.
+ void shrinkNumArgs(unsigned NewNumArgs) {
+ assert((NewNumArgs <= getNumArgs()) &&
+ "shrinkNumArgs cannot increase the number of arguments!");
+ NumArgs = NewNumArgs;
+ }
typedef ExprIterator arg_iterator;
typedef ConstExprIterator const_arg_iterator;
typedef llvm::iterator_range<arg_iterator> arg_range;
- typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
+ typedef llvm::iterator_range<const_arg_iterator> const_arg_range;
arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
- arg_const_range arguments() const {
- return arg_const_range(arg_begin(), arg_end());
+ const_arg_range arguments() const {
+ return const_arg_range(arg_begin(), arg_end());
}
- arg_iterator arg_begin() { return SubExprs+PREARGS_START+getNumPreArgs(); }
- arg_iterator arg_end() {
- return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs();
+ arg_iterator arg_begin() {
+ return getTrailingStmts() + PREARGS_START + getNumPreArgs();
}
+ arg_iterator arg_end() { return arg_begin() + getNumArgs(); }
+
const_arg_iterator arg_begin() const {
- return SubExprs+PREARGS_START+getNumPreArgs();
- }
- const_arg_iterator arg_end() const {
- return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs();
+ return getTrailingStmts() + PREARGS_START + getNumPreArgs();
}
+ const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); }
/// This method provides fast access to all the subexpressions of
/// a CallExpr without going through the slower virtual child_iterator
/// interface. This provides efficient reverse iteration of the
/// subexpressions. This is currently used for CFG construction.
- ArrayRef<Stmt*> getRawSubExprs() {
- return llvm::makeArrayRef(SubExprs,
- getNumPreArgs() + PREARGS_START + getNumArgs());
+ ArrayRef<Stmt *> getRawSubExprs() {
+ return llvm::makeArrayRef(getTrailingStmts(),
+ PREARGS_START + getNumPreArgs() + getNumArgs());
}
/// getNumCommas - Return the number of commas that must have been present in
/// this function call.
- unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; }
+ unsigned getNumCommas() const { return getNumArgs() ? getNumArgs() - 1 : 0; }
/// getBuiltinCallee - If this is a call to a builtin, return the builtin ID
/// of the callee. If not, return 0.
@@ -2417,18 +2623,27 @@ public:
/// type.
QualType getCallReturnType(const ASTContext &Ctx) const;
+ /// Returns the WarnUnusedResultAttr that is either declared on the called
+ /// function, or its return type declaration.
+ const Attr *getUnusedResultAttr(const ASTContext &Ctx) const;
+
+ /// Returns true if this call expression should warn on unused results.
+ bool hasUnusedResultAttr(const ASTContext &Ctx) const {
+ return getUnusedResultAttr(Ctx) != nullptr;
+ }
+
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const LLVM_READONLY;
/// Return true if this is a call to __assume() or __builtin_assume() with
/// a non-value-dependent constant parameter evaluating as false.
bool isBuiltinAssumeFalse(const ASTContext &Ctx) const;
bool isCallToStdMove() const {
- const FunctionDecl* FD = getDirectCallee();
+ const FunctionDecl *FD = getDirectCallee();
return getNumArgs() == 1 && FD && FD->isInStdNamespace() &&
FD->getIdentifier() && FD->getIdentifier()->isStr("move");
}
@@ -2440,13 +2655,14 @@ public:
// Iterators
child_range children() {
- return child_range(&SubExprs[0],
- &SubExprs[0]+NumArgs+getNumPreArgs()+PREARGS_START);
+ return child_range(getTrailingStmts(), getTrailingStmts() + PREARGS_START +
+ getNumPreArgs() + getNumArgs());
}
const_child_range children() const {
- return const_child_range(&SubExprs[0], &SubExprs[0] + NumArgs +
- getNumPreArgs() + PREARGS_START);
+ return const_child_range(getTrailingStmts(),
+ getTrailingStmts() + PREARGS_START +
+ getNumPreArgs() + getNumArgs());
}
};
@@ -2468,6 +2684,10 @@ class MemberExpr final
private llvm::TrailingObjects<MemberExpr, MemberExprNameQualifier,
ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc> {
+ friend class ASTReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
/// Base - the expression for the base pointer or structure references. In
/// X.F, this is "X".
Stmt *Base;
@@ -2483,35 +2703,20 @@ class MemberExpr final
/// MemberLoc - This is the location of the member name.
SourceLocation MemberLoc;
- /// This is the location of the -> or . in the expression.
- SourceLocation OperatorLoc;
-
- /// IsArrow - True if this is "X->F", false if this is "X.F".
- bool IsArrow : 1;
-
- /// True if this member expression used a nested-name-specifier to
- /// refer to the member, e.g., "x->Base::f", or found its member via a using
- /// declaration. When true, a MemberExprNameQualifier
- /// structure is allocated immediately after the MemberExpr.
- bool HasQualifierOrFoundDecl : 1;
-
- /// True if this member expression specified a template keyword
- /// and/or a template argument list explicitly, e.g., x->f<int>,
- /// x->template f, x->template f<int>.
- /// When true, an ASTTemplateKWAndArgsInfo structure and its
- /// TemplateArguments (if any) are present.
- bool HasTemplateKWAndArgsInfo : 1;
-
- /// True if this member expression refers to a method that
- /// was resolved from an overloaded set having size greater than 1.
- bool HadMultipleCandidates : 1;
-
size_t numTrailingObjects(OverloadToken<MemberExprNameQualifier>) const {
- return HasQualifierOrFoundDecl ? 1 : 0;
+ return hasQualifierOrFoundDecl();
}
size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
+ return hasTemplateKWAndArgsInfo();
+ }
+
+ bool hasQualifierOrFoundDecl() const {
+ return MemberExprBits.HasQualifierOrFoundDecl;
+ }
+
+ bool hasTemplateKWAndArgsInfo() const {
+ return MemberExprBits.HasTemplateKWAndArgsInfo;
}
public:
@@ -2522,10 +2727,13 @@ public:
base->isValueDependent(), base->isInstantiationDependent(),
base->containsUnexpandedParameterPack()),
Base(base), MemberDecl(memberdecl), MemberDNLoc(NameInfo.getInfo()),
- MemberLoc(NameInfo.getLoc()), OperatorLoc(operatorloc),
- IsArrow(isarrow), HasQualifierOrFoundDecl(false),
- HasTemplateKWAndArgsInfo(false), HadMultipleCandidates(false) {
+ MemberLoc(NameInfo.getLoc()) {
assert(memberdecl->getDeclName() == NameInfo.getName());
+ MemberExprBits.IsArrow = isarrow;
+ MemberExprBits.HasQualifierOrFoundDecl = false;
+ MemberExprBits.HasTemplateKWAndArgsInfo = false;
+ MemberExprBits.HadMultipleCandidates = false;
+ MemberExprBits.OperatorLoc = operatorloc;
}
// NOTE: this constructor should be used only when it is known that
@@ -2538,10 +2746,13 @@ public:
: Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(),
base->isValueDependent(), base->isInstantiationDependent(),
base->containsUnexpandedParameterPack()),
- Base(base), MemberDecl(memberdecl), MemberDNLoc(), MemberLoc(l),
- OperatorLoc(operatorloc), IsArrow(isarrow),
- HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false),
- HadMultipleCandidates(false) {}
+ Base(base), MemberDecl(memberdecl), MemberDNLoc(), MemberLoc(l) {
+ MemberExprBits.IsArrow = isarrow;
+ MemberExprBits.HasQualifierOrFoundDecl = false;
+ MemberExprBits.HasTemplateKWAndArgsInfo = false;
+ MemberExprBits.HadMultipleCandidates = false;
+ MemberExprBits.OperatorLoc = operatorloc;
+ }
static MemberExpr *Create(const ASTContext &C, Expr *base, bool isarrow,
SourceLocation OperatorLoc,
@@ -2564,7 +2775,7 @@ public:
/// Retrieves the declaration found by lookup.
DeclAccessPair getFoundDecl() const {
- if (!HasQualifierOrFoundDecl)
+ if (!hasQualifierOrFoundDecl())
return DeclAccessPair::make(getMemberDecl(),
getMemberDecl()->getAccess());
return getTrailingObjects<MemberExprNameQualifier>()->FoundDecl;
@@ -2579,9 +2790,8 @@ public:
/// nested-name-specifier that precedes the member name, with source-location
/// information.
NestedNameSpecifierLoc getQualifierLoc() const {
- if (!HasQualifierOrFoundDecl)
+ if (!hasQualifierOrFoundDecl())
return NestedNameSpecifierLoc();
-
return getTrailingObjects<MemberExprNameQualifier>()->QualifierLoc;
}
@@ -2595,21 +2805,24 @@ public:
/// Retrieve the location of the template keyword preceding
/// the member name, if any.
SourceLocation getTemplateKeywordLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
}
/// Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the member name, if any.
SourceLocation getLAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
}
/// Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the member name, if any.
SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
}
@@ -2656,18 +2869,18 @@ public:
MemberLoc, MemberDNLoc);
}
- SourceLocation getOperatorLoc() const LLVM_READONLY { return OperatorLoc; }
+ SourceLocation getOperatorLoc() const { return MemberExprBits.OperatorLoc; }
- bool isArrow() const { return IsArrow; }
- void setArrow(bool A) { IsArrow = A; }
+ bool isArrow() const { return MemberExprBits.IsArrow; }
+ void setArrow(bool A) { MemberExprBits.IsArrow = A; }
/// getMemberLoc - Return the location of the "member", in X->F, it is the
/// location of 'F'.
SourceLocation getMemberLoc() const { return MemberLoc; }
void setMemberLoc(SourceLocation L) { MemberLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const LLVM_READONLY;
SourceLocation getExprLoc() const LLVM_READONLY { return MemberLoc; }
@@ -2679,13 +2892,13 @@ public:
/// Returns true if this member expression refers to a method that
/// was resolved from an overloaded set having size greater than 1.
bool hadMultipleCandidates() const {
- return HadMultipleCandidates;
+ return MemberExprBits.HadMultipleCandidates;
}
/// Sets the flag telling whether this expression refers to
/// a method that was resolved from an overloaded set having size
/// greater than 1.
void setHadMultipleCandidates(bool V = true) {
- HadMultipleCandidates = V;
+ MemberExprBits.HadMultipleCandidates = V;
}
/// Returns true if virtual dispatch is performed.
@@ -2705,10 +2918,6 @@ public:
const_child_range children() const {
return const_child_range(&Base, &Base + 1);
}
-
- friend TrailingObjects;
- friend class ASTReader;
- friend class ASTStmtWriter;
};
/// CompoundLiteralExpr - [C99 6.5.2.5]
@@ -2756,19 +2965,19 @@ public:
TInfoAndScope.setPointer(tinfo);
}
- SourceLocation getLocStart() const LLVM_READONLY {
+ SourceLocation getBeginLoc() const LLVM_READONLY {
// FIXME: Init should never be null.
if (!Init)
return SourceLocation();
if (LParenLoc.isInvalid())
- return Init->getLocStart();
+ return Init->getBeginLoc();
return LParenLoc;
}
- SourceLocation getLocEnd() const LLVM_READONLY {
+ SourceLocation getEndLoc() const LLVM_READONLY {
// FIXME: Init should never be null.
if (!Init)
return SourceLocation();
- return Init->getLocEnd();
+ return Init->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -2787,28 +2996,15 @@ public:
/// representation in the source code (ExplicitCastExpr's derived
/// classes).
class CastExpr : public Expr {
-public:
- using BasePathSizeTy = unsigned int;
- static_assert(std::numeric_limits<BasePathSizeTy>::max() >= 16384,
- "[implimits] Direct and indirect base classes [16384].");
-
-private:
Stmt *Op;
bool CastConsistency() const;
- BasePathSizeTy *BasePathSize();
-
const CXXBaseSpecifier * const *path_buffer() const {
return const_cast<CastExpr*>(this)->path_buffer();
}
CXXBaseSpecifier **path_buffer();
- void setBasePathSize(BasePathSizeTy basePathSize) {
- assert(!path_empty() && basePathSize != 0);
- *(BasePathSize()) = basePathSize;
- }
-
protected:
CastExpr(StmtClass SC, QualType ty, ExprValueKind VK, const CastKind kind,
Expr *op, unsigned BasePathSize)
@@ -2829,9 +3025,9 @@ protected:
Op(op) {
CastExprBits.Kind = kind;
CastExprBits.PartOfExplicitCast = false;
- CastExprBits.BasePathIsEmpty = BasePathSize == 0;
- if (!path_empty())
- setBasePathSize(BasePathSize);
+ CastExprBits.BasePathSize = BasePathSize;
+ assert((CastExprBits.BasePathSize == BasePathSize) &&
+ "BasePathSize overflow!");
assert(CastConsistency());
}
@@ -2839,9 +3035,9 @@ protected:
CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize)
: Expr(SC, Empty) {
CastExprBits.PartOfExplicitCast = false;
- CastExprBits.BasePathIsEmpty = BasePathSize == 0;
- if (!path_empty())
- setBasePathSize(BasePathSize);
+ CastExprBits.BasePathSize = BasePathSize;
+ assert((CastExprBits.BasePathSize == BasePathSize) &&
+ "BasePathSize overflow!");
}
public:
@@ -2868,13 +3064,9 @@ public:
NamedDecl *getConversionFunction() const;
typedef CXXBaseSpecifier **path_iterator;
- typedef const CXXBaseSpecifier * const *path_const_iterator;
- bool path_empty() const { return CastExprBits.BasePathIsEmpty; }
- unsigned path_size() const {
- if (path_empty())
- return 0U;
- return *(const_cast<CastExpr *>(this)->BasePathSize());
- }
+ typedef const CXXBaseSpecifier *const *path_const_iterator;
+ bool path_empty() const { return path_size() == 0; }
+ unsigned path_size() const { return CastExprBits.BasePathSize; }
path_iterator path_begin() { return path_buffer(); }
path_iterator path_end() { return path_buffer() + path_size(); }
path_const_iterator path_begin() const { return path_buffer(); }
@@ -2922,17 +3114,11 @@ public:
/// @endcode
class ImplicitCastExpr final
: public CastExpr,
- private llvm::TrailingObjects<ImplicitCastExpr, CastExpr::BasePathSizeTy,
- CXXBaseSpecifier *> {
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
+ private llvm::TrailingObjects<ImplicitCastExpr, CXXBaseSpecifier *> {
-private:
ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
unsigned BasePathLength, ExprValueKind VK)
- : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) {
- }
+ : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) { }
/// Construct an empty implicit cast.
explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize)
@@ -2958,11 +3144,11 @@ public:
static ImplicitCastExpr *CreateEmpty(const ASTContext &Context,
unsigned PathSize);
- SourceLocation getLocStart() const LLVM_READONLY {
- return getSubExpr()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getSubExpr()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSubExpr()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getSubExpr()->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -2975,8 +3161,13 @@ public:
inline Expr *Expr::IgnoreImpCasts() {
Expr *e = this;
- while (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
- e = ice->getSubExpr();
+ while (true)
+ if (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
+ e = ice->getSubExpr();
+ else if (FullExpr *fe = dyn_cast<FullExpr>(e))
+ e = fe->getSubExpr();
+ else
+ break;
return e;
}
@@ -3032,8 +3223,7 @@ public:
/// (Type)expr. For example: @c (int)f.
class CStyleCastExpr final
: public ExplicitCastExpr,
- private llvm::TrailingObjects<CStyleCastExpr, CastExpr::BasePathSizeTy,
- CXXBaseSpecifier *> {
+ private llvm::TrailingObjects<CStyleCastExpr, CXXBaseSpecifier *> {
SourceLocation LPLoc; // the location of the left paren
SourceLocation RPLoc; // the location of the right paren
@@ -3047,10 +3237,6 @@ class CStyleCastExpr final
explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize)
: ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { }
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
-
public:
static CStyleCastExpr *Create(const ASTContext &Context, QualType T,
ExprValueKind VK, CastKind K,
@@ -3067,9 +3253,9 @@ public:
SourceLocation getRParenLoc() const { return RPLoc; }
void setRParenLoc(SourceLocation L) { RPLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return LPLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSubExpr()->getLocEnd();
+ SourceLocation getBeginLoc() const LLVM_READONLY { return LPLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getSubExpr()->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -3099,20 +3285,11 @@ public:
/// "+" resolves to an overloaded operator, CXXOperatorCallExpr will
/// be used to express the computation.
class BinaryOperator : public Expr {
-public:
- typedef BinaryOperatorKind Opcode;
-
-private:
- unsigned Opc : 6;
-
- // This is only meaningful for operations on floating point types and 0
- // otherwise.
- unsigned FPFeatures : 2;
- SourceLocation OpLoc;
-
enum { LHS, RHS, END_EXPR };
- Stmt* SubExprs[END_EXPR];
+ Stmt *SubExprs[END_EXPR];
+
public:
+ typedef BinaryOperatorKind Opcode;
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
ExprValueKind VK, ExprObjectKind OK,
@@ -3123,8 +3300,10 @@ public:
(lhs->isInstantiationDependent() ||
rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())),
- Opc(opc), FPFeatures(FPFeatures.getInt()), OpLoc(opLoc) {
+ rhs->containsUnexpandedParameterPack())) {
+ BinaryOperatorBits.Opc = opc;
+ BinaryOperatorBits.FPFeatures = FPFeatures.getInt();
+ BinaryOperatorBits.OpLoc = opLoc;
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
assert(!isCompoundAssignmentOp() &&
@@ -3132,26 +3311,29 @@ public:
}
/// Construct an empty binary operator.
- explicit BinaryOperator(EmptyShell Empty)
- : Expr(BinaryOperatorClass, Empty), Opc(BO_Comma) { }
+ explicit BinaryOperator(EmptyShell Empty) : Expr(BinaryOperatorClass, Empty) {
+ BinaryOperatorBits.Opc = BO_Comma;
+ }
- SourceLocation getExprLoc() const LLVM_READONLY { return OpLoc; }
- SourceLocation getOperatorLoc() const { return OpLoc; }
- void setOperatorLoc(SourceLocation L) { OpLoc = L; }
+ SourceLocation getExprLoc() const { return getOperatorLoc(); }
+ SourceLocation getOperatorLoc() const { return BinaryOperatorBits.OpLoc; }
+ void setOperatorLoc(SourceLocation L) { BinaryOperatorBits.OpLoc = L; }
- Opcode getOpcode() const { return static_cast<Opcode>(Opc); }
- void setOpcode(Opcode O) { Opc = O; }
+ Opcode getOpcode() const {
+ return static_cast<Opcode>(BinaryOperatorBits.Opc);
+ }
+ void setOpcode(Opcode Opc) { BinaryOperatorBits.Opc = Opc; }
Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
void setLHS(Expr *E) { SubExprs[LHS] = E; }
Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
void setRHS(Expr *E) { SubExprs[RHS] = E; }
- SourceLocation getLocStart() const LLVM_READONLY {
- return getLHS()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getLHS()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getRHS()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getRHS()->getEndLoc();
}
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
@@ -3169,7 +3351,11 @@ public:
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
/// predicates to categorize the respective opcodes.
- bool isPtrMemOp() const { return Opc == BO_PtrMemD || Opc == BO_PtrMemI; }
+ static bool isPtrMemOp(Opcode Opc) {
+ return Opc == BO_PtrMemD || Opc == BO_PtrMemI;
+ }
+ bool isPtrMemOp() const { return isPtrMemOp(getOpcode()); }
+
static bool isMultiplicativeOp(Opcode Opc) {
return Opc >= BO_Mul && Opc <= BO_Rem;
}
@@ -3268,16 +3454,24 @@ public:
// Set the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
- void setFPFeatures(FPOptions F) { FPFeatures = F.getInt(); }
+ void setFPFeatures(FPOptions F) {
+ BinaryOperatorBits.FPFeatures = F.getInt();
+ }
- FPOptions getFPFeatures() const { return FPOptions(FPFeatures); }
+ FPOptions getFPFeatures() const {
+ return FPOptions(BinaryOperatorBits.FPFeatures);
+ }
// Get the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
bool isFPContractableWithinStatement() const {
- return FPOptions(FPFeatures).allowFPContractWithinStatement();
+ return getFPFeatures().allowFPContractWithinStatement();
}
+ // Get the FENV_ACCESS status of this operator. Only meaningful for
+ // operations on floating point types.
+ bool isFEnvAccessOn() const { return getFPFeatures().allowFEnvAccess(); }
+
protected:
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
ExprValueKind VK, ExprObjectKind OK,
@@ -3288,14 +3482,17 @@ protected:
(lhs->isInstantiationDependent() ||
rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())),
- Opc(opc), FPFeatures(FPFeatures.getInt()), OpLoc(opLoc) {
+ rhs->containsUnexpandedParameterPack())) {
+ BinaryOperatorBits.Opc = opc;
+ BinaryOperatorBits.FPFeatures = FPFeatures.getInt();
+ BinaryOperatorBits.OpLoc = opLoc;
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
}
- BinaryOperator(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty), Opc(BO_MulAssign) { }
+ BinaryOperator(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
+ BinaryOperatorBits.Opc = BO_MulAssign;
+ }
};
/// CompoundAssignOperator - For compound assignments (e.g. +=), we keep
@@ -3430,11 +3627,11 @@ public:
Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
- SourceLocation getLocStart() const LLVM_READONLY {
- return getCond()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getCond()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getRHS()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getRHS()->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -3518,11 +3715,11 @@ public:
return cast<Expr>(SubExprs[RHS]);
}
- SourceLocation getLocStart() const LLVM_READONLY {
- return getCommon()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getCommon()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getFalseExpr()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getFalseExpr()->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -3576,8 +3773,8 @@ public:
SourceLocation getLabelLoc() const { return LabelLoc; }
void setLabelLoc(SourceLocation L) { LabelLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return AmpAmpLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return LabelLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AmpAmpLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return LabelLoc; }
LabelDecl *getLabel() const { return Label; }
void setLabel(LabelDecl *L) { Label = L; }
@@ -3621,8 +3818,8 @@ public:
const CompoundStmt *getSubStmt() const { return cast<CompoundStmt>(SubStmt); }
void setSubStmt(CompoundStmt *S) { SubStmt = S; }
- SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
SourceLocation getLParenLoc() const { return LParenLoc; }
void setLParenLoc(SourceLocation L) { LParenLoc = L; }
@@ -3670,8 +3867,8 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ShuffleVectorExprClass;
@@ -3754,8 +3951,8 @@ public:
/// getRParenLoc - Return the location of final right parenthesis.
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ConvertVectorExprClass;
@@ -3835,8 +4032,8 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ChooseExprClass;
@@ -3874,8 +4071,8 @@ public:
SourceLocation getTokenLocation() const { return TokenLoc; }
void setTokenLocation(SourceLocation L) { TokenLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return TokenLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return TokenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return TokenLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return TokenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == GNUNullExprClass;
@@ -3926,8 +4123,8 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == VAArgExprClass;
@@ -4160,8 +4357,8 @@ public:
InitListExprBits.HadArrayRangeDesignator = ARD;
}
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == InitListExprClass;
@@ -4395,17 +4592,17 @@ public:
return ArrayOrRange.Index;
}
- SourceLocation getLocStart() const LLVM_READONLY {
+ SourceLocation getBeginLoc() const LLVM_READONLY {
if (Kind == FieldDesignator)
return getDotLoc().isInvalid()? getFieldLoc() : getDotLoc();
else
return getLBracketLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
+ SourceLocation getEndLoc() const LLVM_READONLY {
return Kind == FieldDesignator ? getFieldLoc() : getRBracketLoc();
}
SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getLocStart(), getLocEnd());
+ return SourceRange(getBeginLoc(), getEndLoc());
}
};
@@ -4484,8 +4681,8 @@ public:
SourceRange getDesignatorsSourceRange() const;
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == DesignatedInitExprClass;
@@ -4526,8 +4723,8 @@ public:
return T->getStmtClass() == NoInitExprClass;
}
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return SourceLocation(); }
// Iterators
child_range children() {
@@ -4561,8 +4758,8 @@ public:
explicit DesignatedInitUpdateExpr(EmptyShell Empty)
: Expr(DesignatedInitUpdateExprClass, Empty) { }
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == DesignatedInitUpdateExprClass;
@@ -4636,11 +4833,11 @@ public:
return S->getStmtClass() == ArrayInitLoopExprClass;
}
- SourceLocation getLocStart() const LLVM_READONLY {
- return getCommonExpr()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getCommonExpr()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getCommonExpr()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getCommonExpr()->getEndLoc();
}
child_range children() {
@@ -4671,8 +4868,8 @@ public:
return S->getStmtClass() == ArrayInitIndexExprClass;
}
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return SourceLocation(); }
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -4707,8 +4904,8 @@ public:
return T->getStmtClass() == ImplicitValueInitExprClass;
}
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return SourceLocation(); }
// Iterators
child_range children() {
@@ -4719,31 +4916,46 @@ public:
}
};
-class ParenListExpr : public Expr {
- Stmt **Exprs;
- unsigned NumExprs;
+class ParenListExpr final
+ : public Expr,
+ private llvm::TrailingObjects<ParenListExpr, Stmt *> {
+ friend class ASTStmtReader;
+ friend TrailingObjects;
+
+ /// The location of the left and right parentheses.
SourceLocation LParenLoc, RParenLoc;
-public:
- ParenListExpr(const ASTContext& C, SourceLocation lparenloc,
- ArrayRef<Expr*> exprs, SourceLocation rparenloc);
+ /// Build a paren list.
+ ParenListExpr(SourceLocation LParenLoc, ArrayRef<Expr *> Exprs,
+ SourceLocation RParenLoc);
/// Build an empty paren list.
- explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
+ ParenListExpr(EmptyShell Empty, unsigned NumExprs);
+
+public:
+ /// Create a paren list.
+ static ParenListExpr *Create(const ASTContext &Ctx, SourceLocation LParenLoc,
+ ArrayRef<Expr *> Exprs,
+ SourceLocation RParenLoc);
- unsigned getNumExprs() const { return NumExprs; }
+ /// Create an empty paren list.
+ static ParenListExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumExprs);
- const Expr* getExpr(unsigned Init) const {
+ /// Return the number of expressions in this paren list.
+ unsigned getNumExprs() const { return ParenListExprBits.NumExprs; }
+
+ Expr *getExpr(unsigned Init) {
assert(Init < getNumExprs() && "Initializer access out of range!");
- return cast_or_null<Expr>(Exprs[Init]);
+ return getExprs()[Init];
}
- Expr* getExpr(unsigned Init) {
- assert(Init < getNumExprs() && "Initializer access out of range!");
- return cast_or_null<Expr>(Exprs[Init]);
+ const Expr *getExpr(unsigned Init) const {
+ return const_cast<ParenListExpr *>(this)->getExpr(Init);
}
- Expr **getExprs() { return reinterpret_cast<Expr **>(Exprs); }
+ Expr **getExprs() {
+ return reinterpret_cast<Expr **>(getTrailingObjects<Stmt *>());
+ }
ArrayRef<Expr *> exprs() {
return llvm::makeArrayRef(getExprs(), getNumExprs());
@@ -4751,9 +4963,8 @@ public:
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const { return getLParenLoc(); }
+ SourceLocation getEndLoc() const { return getRParenLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ParenListExprClass;
@@ -4761,14 +4972,13 @@ public:
// Iterators
child_range children() {
- return child_range(&Exprs[0], &Exprs[0]+NumExprs);
+ return child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() + getNumExprs());
}
const_child_range children() const {
- return const_child_range(&Exprs[0], &Exprs[0] + NumExprs);
+ return const_child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() + getNumExprs());
}
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
};
/// Represents a C11 generic selection.
@@ -4876,8 +5086,8 @@ public:
const Expr *getResultExpr() const { return getAssocExpr(getResultIndex()); }
Expr *getResultExpr() { return getAssocExpr(getResultIndex()); }
- SourceLocation getLocStart() const LLVM_READONLY { return GenericLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return GenericLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == GenericSelectionExprClass;
@@ -4942,10 +5152,10 @@ public:
/// aggregate Constant of ConstantInt(s).
void getEncodedElementAccess(SmallVectorImpl<uint32_t> &Elts) const;
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBase()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getBase()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY { return AccessorLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return AccessorLoc; }
/// isArrow - Return true if the base expression is a pointer to vector,
/// return false if the base expression is a vector.
@@ -4987,8 +5197,12 @@ public:
const Stmt *getBody() const;
Stmt *getBody();
- SourceLocation getLocStart() const LLVM_READONLY { return getCaretLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getBody()->getLocEnd(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getCaretLocation();
+ }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getBody()->getEndLoc();
+ }
/// getFunctionType - Return the underlying function type for this block.
const FunctionProtoType *getFunctionType() const;
@@ -5040,8 +5254,8 @@ public:
/// getRParenLoc - Return the location of final right parenthesis.
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == AsTypeExprClass;
@@ -5182,11 +5396,11 @@ public:
return getSyntacticForm()->getExprLoc();
}
- SourceLocation getLocStart() const LLVM_READONLY {
- return getSyntacticForm()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getSyntacticForm()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSyntacticForm()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getSyntacticForm()->getEndLoc();
}
child_range children() {
@@ -5309,8 +5523,8 @@ public:
SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == AtomicExprClass;
@@ -5363,8 +5577,8 @@ public:
return const_child_range(const_child_iterator(), const_child_iterator());
}
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return SourceLocation(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == TypoExprClass;