2006-08-23 14:42:10 +08:00
|
|
|
//===--- Expr.cpp - Expression AST Node Implementation --------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 03:59:25 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2006-08-23 14:42:10 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements the Expr class and subclasses.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2008-08-11 13:35:13 +08:00
|
|
|
#include "clang/AST/Expr.h"
|
2009-09-01 05:41:48 +08:00
|
|
|
#include "clang/AST/ExprCXX.h"
|
2008-10-06 14:40:35 +08:00
|
|
|
#include "clang/AST/APValue.h"
|
2007-07-16 07:32:58 +08:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2008-10-06 14:40:35 +08:00
|
|
|
#include "clang/AST/DeclObjC.h"
|
2008-10-22 07:43:52 +08:00
|
|
|
#include "clang/AST/DeclCXX.h"
|
2009-02-05 03:02:06 +08:00
|
|
|
#include "clang/AST/DeclTemplate.h"
|
2009-07-19 03:43:29 +08:00
|
|
|
#include "clang/AST/RecordLayout.h"
|
2006-11-04 14:21:51 +08:00
|
|
|
#include "clang/AST/StmtVisitor.h"
|
2010-11-17 15:37:15 +08:00
|
|
|
#include "clang/Lex/LiteralSupport.h"
|
|
|
|
#include "clang/Lex/Lexer.h"
|
2011-06-12 01:19:42 +08:00
|
|
|
#include "clang/Sema/SemaDiagnostic.h"
|
2009-06-14 09:54:56 +08:00
|
|
|
#include "clang/Basic/Builtins.h"
|
2010-11-17 15:37:15 +08:00
|
|
|
#include "clang/Basic/SourceManager.h"
|
2007-11-28 02:22:04 +08:00
|
|
|
#include "clang/Basic/TargetInfo.h"
|
2009-11-02 04:32:48 +08:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2009-09-09 02:24:21 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2009-04-15 14:41:24 +08:00
|
|
|
#include <algorithm>
|
2006-08-23 14:42:10 +08:00
|
|
|
using namespace clang;
|
|
|
|
|
2010-04-17 07:34:13 +08:00
|
|
|
/// isKnownToHaveBooleanValue - Return true if this is an integer expression
|
|
|
|
/// that is known to return 0 or 1. This happens for _Bool/bool expressions
|
|
|
|
/// but also int expressions which are produced by things like comparisons in
|
|
|
|
/// C.
|
|
|
|
bool Expr::isKnownToHaveBooleanValue() const {
|
2011-04-15 08:35:48 +08:00
|
|
|
const Expr *E = IgnoreParens();
|
|
|
|
|
2010-04-17 07:34:13 +08:00
|
|
|
// If this value has _Bool type, it is obvious 0/1.
|
2011-04-15 08:35:48 +08:00
|
|
|
if (E->getType()->isBooleanType()) return true;
|
2010-05-05 23:23:54 +08:00
|
|
|
// If this is a non-scalar-integer type, we don't care enough to try.
|
2011-04-15 08:35:48 +08:00
|
|
|
if (!E->getType()->isIntegralOrEnumerationType()) return false;
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2011-04-15 08:35:48 +08:00
|
|
|
if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
|
2010-04-17 07:34:13 +08:00
|
|
|
switch (UO->getOpcode()) {
|
2010-08-25 19:45:40 +08:00
|
|
|
case UO_Plus:
|
2010-04-17 07:34:13 +08:00
|
|
|
return UO->getSubExpr()->isKnownToHaveBooleanValue();
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2010-06-12 09:56:02 +08:00
|
|
|
// Only look through implicit casts. If the user writes
|
|
|
|
// '(int) (a && b)' treat it as an arbitrary int.
|
2011-04-15 08:35:48 +08:00
|
|
|
if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
|
2010-04-17 07:34:13 +08:00
|
|
|
return CE->getSubExpr()->isKnownToHaveBooleanValue();
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2011-04-15 08:35:48 +08:00
|
|
|
if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
|
2010-04-17 07:34:13 +08:00
|
|
|
switch (BO->getOpcode()) {
|
|
|
|
default: return false;
|
2010-08-25 19:45:40 +08:00
|
|
|
case BO_LT: // Relational operators.
|
|
|
|
case BO_GT:
|
|
|
|
case BO_LE:
|
|
|
|
case BO_GE:
|
|
|
|
case BO_EQ: // Equality operators.
|
|
|
|
case BO_NE:
|
|
|
|
case BO_LAnd: // AND operator.
|
|
|
|
case BO_LOr: // Logical OR operator.
|
2010-04-17 07:34:13 +08:00
|
|
|
return true;
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2010-08-25 19:45:40 +08:00
|
|
|
case BO_And: // Bitwise AND operator.
|
|
|
|
case BO_Xor: // Bitwise XOR operator.
|
|
|
|
case BO_Or: // Bitwise OR operator.
|
2010-04-17 07:34:13 +08:00
|
|
|
// Handle things like (x==2)|(y==12).
|
|
|
|
return BO->getLHS()->isKnownToHaveBooleanValue() &&
|
|
|
|
BO->getRHS()->isKnownToHaveBooleanValue();
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2010-08-25 19:45:40 +08:00
|
|
|
case BO_Comma:
|
|
|
|
case BO_Assign:
|
2010-04-17 07:34:13 +08:00
|
|
|
return BO->getRHS()->isKnownToHaveBooleanValue();
|
|
|
|
}
|
|
|
|
}
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2011-04-15 08:35:48 +08:00
|
|
|
if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E))
|
2010-04-17 07:34:13 +08:00
|
|
|
return CO->getTrueExpr()->isKnownToHaveBooleanValue() &&
|
|
|
|
CO->getFalseExpr()->isKnownToHaveBooleanValue();
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2010-04-17 07:34:13 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-02-09 16:16:59 +08:00
|
|
|
// Amusing macro metaprogramming hack: check whether a class provides
|
|
|
|
// a more specific implementation of getExprLoc().
|
|
|
|
namespace {
|
|
|
|
/// This implementation is used when a class provides a custom
|
|
|
|
/// implementation of getExprLoc.
|
|
|
|
template <class E, class T>
|
|
|
|
SourceLocation getExprLocImpl(const Expr *expr,
|
|
|
|
SourceLocation (T::*v)() const) {
|
|
|
|
return static_cast<const E*>(expr)->getExprLoc();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// This implementation is used when a class doesn't provide
|
|
|
|
/// a custom implementation of getExprLoc. Overload resolution
|
|
|
|
/// should pick it over the implementation above because it's
|
|
|
|
/// more specialized according to function template partial ordering.
|
|
|
|
template <class E>
|
|
|
|
SourceLocation getExprLocImpl(const Expr *expr,
|
|
|
|
SourceLocation (Expr::*v)() const) {
|
|
|
|
return static_cast<const E*>(expr)->getSourceRange().getBegin();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SourceLocation Expr::getExprLoc() const {
|
|
|
|
switch (getStmtClass()) {
|
|
|
|
case Stmt::NoStmtClass: llvm_unreachable("statement without class");
|
|
|
|
#define ABSTRACT_STMT(type)
|
|
|
|
#define STMT(type, base) \
|
|
|
|
case Stmt::type##Class: llvm_unreachable(#type " is not an Expr"); break;
|
|
|
|
#define EXPR(type, base) \
|
|
|
|
case Stmt::type##Class: return getExprLocImpl<type>(this, &type::getExprLoc);
|
|
|
|
#include "clang/AST/StmtNodes.inc"
|
|
|
|
}
|
|
|
|
llvm_unreachable("unknown statement kind");
|
|
|
|
return SourceLocation();
|
|
|
|
}
|
|
|
|
|
2006-08-24 12:56:27 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Primary Expressions.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2009-11-23 09:53:49 +08:00
|
|
|
void ExplicitTemplateArgumentList::initializeFrom(
|
|
|
|
const TemplateArgumentListInfo &Info) {
|
|
|
|
LAngleLoc = Info.getLAngleLoc();
|
|
|
|
RAngleLoc = Info.getRAngleLoc();
|
|
|
|
NumTemplateArgs = Info.size();
|
|
|
|
|
|
|
|
TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
|
|
|
|
for (unsigned i = 0; i != NumTemplateArgs; ++i)
|
|
|
|
new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
|
|
|
|
}
|
|
|
|
|
2010-12-15 09:34:56 +08:00
|
|
|
void ExplicitTemplateArgumentList::initializeFrom(
|
2011-07-01 09:22:09 +08:00
|
|
|
const TemplateArgumentListInfo &Info,
|
|
|
|
bool &Dependent,
|
|
|
|
bool &InstantiationDependent,
|
|
|
|
bool &ContainsUnexpandedParameterPack) {
|
2010-12-15 09:34:56 +08:00
|
|
|
LAngleLoc = Info.getLAngleLoc();
|
|
|
|
RAngleLoc = Info.getRAngleLoc();
|
|
|
|
NumTemplateArgs = Info.size();
|
|
|
|
|
|
|
|
TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
|
|
|
|
for (unsigned i = 0; i != NumTemplateArgs; ++i) {
|
|
|
|
Dependent = Dependent || Info[i].getArgument().isDependent();
|
2011-07-01 09:22:09 +08:00
|
|
|
InstantiationDependent = InstantiationDependent ||
|
|
|
|
Info[i].getArgument().isInstantiationDependent();
|
2010-12-15 09:34:56 +08:00
|
|
|
ContainsUnexpandedParameterPack
|
|
|
|
= ContainsUnexpandedParameterPack ||
|
|
|
|
Info[i].getArgument().containsUnexpandedParameterPack();
|
|
|
|
|
|
|
|
new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-23 09:53:49 +08:00
|
|
|
void ExplicitTemplateArgumentList::copyInto(
|
|
|
|
TemplateArgumentListInfo &Info) const {
|
|
|
|
Info.setLAngleLoc(LAngleLoc);
|
|
|
|
Info.setRAngleLoc(RAngleLoc);
|
|
|
|
for (unsigned I = 0; I != NumTemplateArgs; ++I)
|
|
|
|
Info.addArgument(getTemplateArgs()[I]);
|
|
|
|
}
|
|
|
|
|
2010-06-24 16:57:31 +08:00
|
|
|
std::size_t ExplicitTemplateArgumentList::sizeFor(unsigned NumTemplateArgs) {
|
|
|
|
return sizeof(ExplicitTemplateArgumentList) +
|
|
|
|
sizeof(TemplateArgumentLoc) * NumTemplateArgs;
|
|
|
|
}
|
|
|
|
|
2009-11-23 09:53:49 +08:00
|
|
|
std::size_t ExplicitTemplateArgumentList::sizeFor(
|
|
|
|
const TemplateArgumentListInfo &Info) {
|
2010-06-24 16:57:31 +08:00
|
|
|
return sizeFor(Info.size());
|
2009-11-23 09:53:49 +08:00
|
|
|
}
|
|
|
|
|
2011-07-01 09:22:09 +08:00
|
|
|
/// \brief Compute the type-, value-, and instantiation-dependence of a
|
|
|
|
/// declaration reference
|
2011-01-20 05:52:31 +08:00
|
|
|
/// based on the declaration being referenced.
|
|
|
|
static void computeDeclRefDependence(NamedDecl *D, QualType T,
|
|
|
|
bool &TypeDependent,
|
2011-07-01 09:22:09 +08:00
|
|
|
bool &ValueDependent,
|
|
|
|
bool &InstantiationDependent) {
|
2011-01-20 05:52:31 +08:00
|
|
|
TypeDependent = false;
|
|
|
|
ValueDependent = false;
|
2011-07-01 09:22:09 +08:00
|
|
|
InstantiationDependent = false;
|
2009-11-23 19:41:28 +08:00
|
|
|
|
|
|
|
// (TD) C++ [temp.dep.expr]p3:
|
|
|
|
// An id-expression is type-dependent if it contains:
|
|
|
|
//
|
2010-05-05 23:23:54 +08:00
|
|
|
// and
|
2009-11-23 19:41:28 +08:00
|
|
|
//
|
|
|
|
// (VD) C++ [temp.dep.constexpr]p2:
|
|
|
|
// An identifier is value-dependent if it is:
|
2011-01-20 05:52:31 +08:00
|
|
|
|
2009-11-23 19:41:28 +08:00
|
|
|
// (TD) - an identifier that was declared with dependent type
|
|
|
|
// (VD) - a name declared with a dependent type,
|
2011-01-20 05:52:31 +08:00
|
|
|
if (T->isDependentType()) {
|
|
|
|
TypeDependent = true;
|
|
|
|
ValueDependent = true;
|
2011-07-01 09:22:09 +08:00
|
|
|
InstantiationDependent = true;
|
2011-01-20 05:52:31 +08:00
|
|
|
return;
|
2011-07-01 09:22:09 +08:00
|
|
|
} else if (T->isInstantiationDependentType()) {
|
|
|
|
InstantiationDependent = true;
|
2009-11-23 19:41:28 +08:00
|
|
|
}
|
2011-01-20 05:52:31 +08:00
|
|
|
|
2009-11-23 19:41:28 +08:00
|
|
|
// (TD) - a conversion-function-id that specifies a dependent type
|
2011-01-20 05:52:31 +08:00
|
|
|
if (D->getDeclName().getNameKind()
|
2011-07-01 09:22:09 +08:00
|
|
|
== DeclarationName::CXXConversionFunctionName) {
|
|
|
|
QualType T = D->getDeclName().getCXXNameType();
|
|
|
|
if (T->isDependentType()) {
|
|
|
|
TypeDependent = true;
|
|
|
|
ValueDependent = true;
|
|
|
|
InstantiationDependent = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (T->isInstantiationDependentType())
|
|
|
|
InstantiationDependent = true;
|
2009-11-23 19:41:28 +08:00
|
|
|
}
|
2011-07-01 09:22:09 +08:00
|
|
|
|
2009-11-23 19:41:28 +08:00
|
|
|
// (VD) - the name of a non-type template parameter,
|
2011-01-20 05:52:31 +08:00
|
|
|
if (isa<NonTypeTemplateParmDecl>(D)) {
|
|
|
|
ValueDependent = true;
|
2011-07-01 09:22:09 +08:00
|
|
|
InstantiationDependent = true;
|
2011-01-20 05:52:31 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-11-23 19:41:28 +08:00
|
|
|
// (VD) - a constant with integral or enumeration type and is
|
|
|
|
// initialized with an expression that is value-dependent.
|
2011-01-20 05:52:31 +08:00
|
|
|
if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
|
2010-06-16 08:17:44 +08:00
|
|
|
if (Var->getType()->isIntegralOrEnumerationType() &&
|
2010-01-16 00:21:02 +08:00
|
|
|
Var->getType().getCVRQualifiers() == Qualifiers::Const) {
|
2010-02-02 04:16:42 +08:00
|
|
|
if (const Expr *Init = Var->getAnyInitializer())
|
2011-07-01 09:22:09 +08:00
|
|
|
if (Init->isValueDependent()) {
|
2011-01-20 05:52:31 +08:00
|
|
|
ValueDependent = true;
|
2011-07-01 09:22:09 +08:00
|
|
|
InstantiationDependent = true;
|
|
|
|
}
|
2010-05-11 16:41:30 +08:00
|
|
|
}
|
2011-01-20 05:52:31 +08:00
|
|
|
|
2010-05-11 16:41:30 +08:00
|
|
|
// (VD) - FIXME: Missing from the standard:
|
|
|
|
// - a member function or a static data member of the current
|
|
|
|
// instantiation
|
|
|
|
else if (Var->isStaticDataMember() &&
|
2011-07-01 09:22:09 +08:00
|
|
|
Var->getDeclContext()->isDependentContext()) {
|
2011-01-20 05:52:31 +08:00
|
|
|
ValueDependent = true;
|
2011-07-01 09:22:09 +08:00
|
|
|
InstantiationDependent = true;
|
|
|
|
}
|
2011-01-20 05:52:31 +08:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-05-11 16:41:30 +08:00
|
|
|
// (VD) - FIXME: Missing from the standard:
|
|
|
|
// - a member function or a static data member of the current
|
|
|
|
// instantiation
|
2011-01-20 05:52:31 +08:00
|
|
|
if (isa<CXXMethodDecl>(D) && D->getDeclContext()->isDependentContext()) {
|
|
|
|
ValueDependent = true;
|
2011-07-01 09:22:09 +08:00
|
|
|
InstantiationDependent = true;
|
2011-01-20 05:52:31 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DeclRefExpr::computeDependence() {
|
|
|
|
bool TypeDependent = false;
|
|
|
|
bool ValueDependent = false;
|
2011-07-01 09:22:09 +08:00
|
|
|
bool InstantiationDependent = false;
|
|
|
|
computeDeclRefDependence(getDecl(), getType(), TypeDependent, ValueDependent,
|
|
|
|
InstantiationDependent);
|
2011-01-20 05:52:31 +08:00
|
|
|
|
|
|
|
// (TD) C++ [temp.dep.expr]p3:
|
|
|
|
// An id-expression is type-dependent if it contains:
|
|
|
|
//
|
|
|
|
// and
|
|
|
|
//
|
|
|
|
// (VD) C++ [temp.dep.constexpr]p2:
|
|
|
|
// An identifier is value-dependent if it is:
|
|
|
|
if (!TypeDependent && !ValueDependent &&
|
|
|
|
hasExplicitTemplateArgs() &&
|
|
|
|
TemplateSpecializationType::anyDependentTemplateArguments(
|
|
|
|
getTemplateArgs(),
|
2011-07-01 09:22:09 +08:00
|
|
|
getNumTemplateArgs(),
|
|
|
|
InstantiationDependent)) {
|
2011-01-20 05:52:31 +08:00
|
|
|
TypeDependent = true;
|
|
|
|
ValueDependent = true;
|
2011-07-01 09:22:09 +08:00
|
|
|
InstantiationDependent = true;
|
2011-01-20 05:52:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ExprBits.TypeDependent = TypeDependent;
|
|
|
|
ExprBits.ValueDependent = ValueDependent;
|
2011-07-01 09:22:09 +08:00
|
|
|
ExprBits.InstantiationDependent = InstantiationDependent;
|
2011-01-20 05:52:31 +08:00
|
|
|
|
2010-12-24 07:51:58 +08:00
|
|
|
// Is the declaration a parameter pack?
|
2011-01-20 05:52:31 +08:00
|
|
|
if (getDecl()->isParameterPack())
|
2011-01-06 05:11:38 +08:00
|
|
|
ExprBits.ContainsUnexpandedParameterPack = true;
|
2009-11-23 19:41:28 +08:00
|
|
|
}
|
|
|
|
|
2011-03-01 05:54:11 +08:00
|
|
|
DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
|
2010-08-12 06:01:17 +08:00
|
|
|
ValueDecl *D, const DeclarationNameInfo &NameInfo,
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
NamedDecl *FoundD,
|
2010-08-12 06:01:17 +08:00
|
|
|
const TemplateArgumentListInfo *TemplateArgs,
|
2010-11-18 14:31:45 +08:00
|
|
|
QualType T, ExprValueKind VK)
|
2011-07-01 09:22:09 +08:00
|
|
|
: Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
|
2011-05-02 05:29:53 +08:00
|
|
|
D(D), Loc(NameInfo.getLoc()), DNLoc(NameInfo.getInfo()) {
|
|
|
|
DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0;
|
2011-05-02 05:55:21 +08:00
|
|
|
if (QualifierLoc)
|
2011-05-02 06:14:37 +08:00
|
|
|
getInternalQualifierLoc() = QualifierLoc;
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
DeclRefExprBits.HasFoundDecl = FoundD ? 1 : 0;
|
|
|
|
if (FoundD)
|
|
|
|
getInternalFoundDecl() = FoundD;
|
2011-05-02 05:29:53 +08:00
|
|
|
DeclRefExprBits.HasExplicitTemplateArgs = TemplateArgs ? 1 : 0;
|
2011-07-01 09:22:09 +08:00
|
|
|
if (TemplateArgs) {
|
|
|
|
bool Dependent = false;
|
|
|
|
bool InstantiationDependent = false;
|
|
|
|
bool ContainsUnexpandedParameterPack = false;
|
|
|
|
getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent,
|
|
|
|
InstantiationDependent,
|
|
|
|
ContainsUnexpandedParameterPack);
|
|
|
|
if (InstantiationDependent)
|
|
|
|
setInstantiationDependent(true);
|
|
|
|
}
|
|
|
|
|
2010-08-12 06:01:17 +08:00
|
|
|
computeDependence();
|
|
|
|
}
|
|
|
|
|
2009-10-24 02:54:35 +08:00
|
|
|
DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
|
2011-03-01 05:54:11 +08:00
|
|
|
NestedNameSpecifierLoc QualifierLoc,
|
2009-12-08 17:08:17 +08:00
|
|
|
ValueDecl *D,
|
2009-10-24 02:54:35 +08:00
|
|
|
SourceLocation NameLoc,
|
2009-11-23 19:41:28 +08:00
|
|
|
QualType T,
|
2010-11-18 14:31:45 +08:00
|
|
|
ExprValueKind VK,
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
NamedDecl *FoundD,
|
2009-11-23 19:41:28 +08:00
|
|
|
const TemplateArgumentListInfo *TemplateArgs) {
|
2011-03-01 05:54:11 +08:00
|
|
|
return Create(Context, QualifierLoc, D,
|
2010-08-12 06:01:17 +08:00
|
|
|
DeclarationNameInfo(D->getDeclName(), NameLoc),
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
T, VK, FoundD, TemplateArgs);
|
2010-08-12 06:01:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
|
2011-03-01 05:54:11 +08:00
|
|
|
NestedNameSpecifierLoc QualifierLoc,
|
2010-08-12 06:01:17 +08:00
|
|
|
ValueDecl *D,
|
|
|
|
const DeclarationNameInfo &NameInfo,
|
|
|
|
QualType T,
|
2010-11-18 14:31:45 +08:00
|
|
|
ExprValueKind VK,
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
NamedDecl *FoundD,
|
2010-08-12 06:01:17 +08:00
|
|
|
const TemplateArgumentListInfo *TemplateArgs) {
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
// Filter out cases where the found Decl is the same as the value refenenced.
|
|
|
|
if (D == FoundD)
|
|
|
|
FoundD = 0;
|
|
|
|
|
2009-10-24 02:54:35 +08:00
|
|
|
std::size_t Size = sizeof(DeclRefExpr);
|
2011-03-01 05:54:11 +08:00
|
|
|
if (QualifierLoc != 0)
|
2011-05-02 06:14:37 +08:00
|
|
|
Size += sizeof(NestedNameSpecifierLoc);
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
if (FoundD)
|
|
|
|
Size += sizeof(NamedDecl *);
|
2009-11-23 09:53:49 +08:00
|
|
|
if (TemplateArgs)
|
|
|
|
Size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
|
2010-10-30 13:14:06 +08:00
|
|
|
void *Mem = Context.Allocate(Size, llvm::alignOf<DeclRefExpr>());
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
return new (Mem) DeclRefExpr(QualifierLoc, D, NameInfo, FoundD, TemplateArgs,
|
|
|
|
T, VK);
|
2009-10-24 02:54:35 +08:00
|
|
|
}
|
|
|
|
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
DeclRefExpr *DeclRefExpr::CreateEmpty(ASTContext &Context,
|
2011-02-04 20:01:24 +08:00
|
|
|
bool HasQualifier,
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
bool HasFoundDecl,
|
2011-02-04 20:01:24 +08:00
|
|
|
bool HasExplicitTemplateArgs,
|
2010-07-08 21:09:47 +08:00
|
|
|
unsigned NumTemplateArgs) {
|
|
|
|
std::size_t Size = sizeof(DeclRefExpr);
|
|
|
|
if (HasQualifier)
|
2011-05-02 06:14:37 +08:00
|
|
|
Size += sizeof(NestedNameSpecifierLoc);
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
if (HasFoundDecl)
|
|
|
|
Size += sizeof(NamedDecl *);
|
2011-02-04 20:01:24 +08:00
|
|
|
if (HasExplicitTemplateArgs)
|
2010-07-08 21:09:47 +08:00
|
|
|
Size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
|
2010-10-30 13:14:06 +08:00
|
|
|
void *Mem = Context.Allocate(Size, llvm::alignOf<DeclRefExpr>());
|
2010-07-08 21:09:47 +08:00
|
|
|
return new (Mem) DeclRefExpr(EmptyShell());
|
|
|
|
}
|
|
|
|
|
2009-10-24 02:54:35 +08:00
|
|
|
SourceRange DeclRefExpr::getSourceRange() const {
|
2010-08-12 06:01:17 +08:00
|
|
|
SourceRange R = getNameInfo().getSourceRange();
|
2009-10-24 02:54:35 +08:00
|
|
|
if (hasQualifier())
|
2011-03-01 05:54:11 +08:00
|
|
|
R.setBegin(getQualifierLoc().getBeginLoc());
|
2010-08-20 07:49:38 +08:00
|
|
|
if (hasExplicitTemplateArgs())
|
2009-10-24 02:54:35 +08:00
|
|
|
R.setEnd(getRAngleLoc());
|
|
|
|
return R;
|
|
|
|
}
|
|
|
|
|
2009-09-09 02:24:21 +08:00
|
|
|
// FIXME: Maybe this should use DeclPrinter with a special "print predefined
|
|
|
|
// expr" policy instead.
|
2010-02-12 02:20:28 +08:00
|
|
|
std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
|
|
|
|
ASTContext &Context = CurrentDecl->getASTContext();
|
|
|
|
|
2009-09-09 02:24:21 +08:00
|
|
|
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) {
|
2010-02-12 02:20:28 +08:00
|
|
|
if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual)
|
2009-09-09 02:24:21 +08:00
|
|
|
return FD->getNameAsString();
|
|
|
|
|
|
|
|
llvm::SmallString<256> Name;
|
|
|
|
llvm::raw_svector_ostream Out(Name);
|
|
|
|
|
|
|
|
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
|
2010-02-12 02:20:28 +08:00
|
|
|
if (MD->isVirtual() && IT != PrettyFunctionNoVirtual)
|
2009-09-09 02:24:21 +08:00
|
|
|
Out << "virtual ";
|
2009-12-27 09:38:20 +08:00
|
|
|
if (MD->isStatic())
|
|
|
|
Out << "static ";
|
2009-09-09 02:24:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
PrintingPolicy Policy(Context.getLangOptions());
|
|
|
|
|
|
|
|
std::string Proto = FD->getQualifiedNameAsString(Policy);
|
|
|
|
|
2009-09-22 07:43:11 +08:00
|
|
|
const FunctionType *AFT = FD->getType()->getAs<FunctionType>();
|
2009-09-09 02:24:21 +08:00
|
|
|
const FunctionProtoType *FT = 0;
|
|
|
|
if (FD->hasWrittenPrototype())
|
|
|
|
FT = dyn_cast<FunctionProtoType>(AFT);
|
|
|
|
|
|
|
|
Proto += "(";
|
|
|
|
if (FT) {
|
|
|
|
llvm::raw_string_ostream POut(Proto);
|
|
|
|
for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
|
|
|
|
if (i) POut << ", ";
|
|
|
|
std::string Param;
|
|
|
|
FD->getParamDecl(i)->getType().getAsStringInternal(Param, Policy);
|
|
|
|
POut << Param;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FT->isVariadic()) {
|
|
|
|
if (FD->getNumParams()) POut << ", ";
|
|
|
|
POut << "...";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Proto += ")";
|
|
|
|
|
2009-12-27 09:38:20 +08:00
|
|
|
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
|
|
|
|
Qualifiers ThisQuals = Qualifiers::fromCVRMask(MD->getTypeQualifiers());
|
|
|
|
if (ThisQuals.hasConst())
|
|
|
|
Proto += " const";
|
|
|
|
if (ThisQuals.hasVolatile())
|
|
|
|
Proto += " volatile";
|
|
|
|
}
|
|
|
|
|
2009-12-07 07:55:13 +08:00
|
|
|
if (!isa<CXXConstructorDecl>(FD) && !isa<CXXDestructorDecl>(FD))
|
|
|
|
AFT->getResultType().getAsStringInternal(Proto, Policy);
|
2009-09-09 02:24:21 +08:00
|
|
|
|
|
|
|
Out << Proto;
|
|
|
|
|
|
|
|
Out.flush();
|
|
|
|
return Name.str().str();
|
|
|
|
}
|
|
|
|
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CurrentDecl)) {
|
|
|
|
llvm::SmallString<256> Name;
|
|
|
|
llvm::raw_svector_ostream Out(Name);
|
|
|
|
Out << (MD->isInstanceMethod() ? '-' : '+');
|
|
|
|
Out << '[';
|
2010-03-19 05:23:08 +08:00
|
|
|
|
|
|
|
// For incorrect code, there might not be an ObjCInterfaceDecl. Do
|
|
|
|
// a null check to avoid a crash.
|
|
|
|
if (const ObjCInterfaceDecl *ID = MD->getClassInterface())
|
2010-04-17 17:33:03 +08:00
|
|
|
Out << ID;
|
2010-03-19 05:23:08 +08:00
|
|
|
|
2009-09-09 02:24:21 +08:00
|
|
|
if (const ObjCCategoryImplDecl *CID =
|
2010-04-17 17:33:03 +08:00
|
|
|
dyn_cast<ObjCCategoryImplDecl>(MD->getDeclContext()))
|
|
|
|
Out << '(' << CID << ')';
|
|
|
|
|
2009-09-09 02:24:21 +08:00
|
|
|
Out << ' ';
|
|
|
|
Out << MD->getSelector().getAsString();
|
|
|
|
Out << ']';
|
|
|
|
|
|
|
|
Out.flush();
|
|
|
|
return Name.str().str();
|
|
|
|
}
|
|
|
|
if (isa<TranslationUnitDecl>(CurrentDecl) && IT == PrettyFunction) {
|
|
|
|
// __PRETTY_FUNCTION__ -> "top level", the others produce an empty string.
|
|
|
|
return "top level";
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2010-08-28 17:06:06 +08:00
|
|
|
void APNumericStorage::setIntValue(ASTContext &C, const llvm::APInt &Val) {
|
|
|
|
if (hasAllocation())
|
|
|
|
C.Deallocate(pVal);
|
|
|
|
|
|
|
|
BitWidth = Val.getBitWidth();
|
|
|
|
unsigned NumWords = Val.getNumWords();
|
|
|
|
const uint64_t* Words = Val.getRawData();
|
|
|
|
if (NumWords > 1) {
|
|
|
|
pVal = new (C) uint64_t[NumWords];
|
|
|
|
std::copy(Words, Words + NumWords, pVal);
|
|
|
|
} else if (NumWords == 1)
|
|
|
|
VAL = Words[0];
|
|
|
|
else
|
|
|
|
VAL = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
IntegerLiteral *
|
|
|
|
IntegerLiteral::Create(ASTContext &C, const llvm::APInt &V,
|
|
|
|
QualType type, SourceLocation l) {
|
|
|
|
return new (C) IntegerLiteral(C, V, type, l);
|
|
|
|
}
|
|
|
|
|
|
|
|
IntegerLiteral *
|
|
|
|
IntegerLiteral::Create(ASTContext &C, EmptyShell Empty) {
|
|
|
|
return new (C) IntegerLiteral(Empty);
|
|
|
|
}
|
|
|
|
|
|
|
|
FloatingLiteral *
|
|
|
|
FloatingLiteral::Create(ASTContext &C, const llvm::APFloat &V,
|
|
|
|
bool isexact, QualType Type, SourceLocation L) {
|
|
|
|
return new (C) FloatingLiteral(C, V, isexact, Type, L);
|
|
|
|
}
|
|
|
|
|
|
|
|
FloatingLiteral *
|
|
|
|
FloatingLiteral::Create(ASTContext &C, EmptyShell Empty) {
|
|
|
|
return new (C) FloatingLiteral(Empty);
|
|
|
|
}
|
|
|
|
|
2008-06-08 06:13:43 +08:00
|
|
|
/// getValueAsApproximateDouble - This returns the value as an inaccurate
|
|
|
|
/// double. Note that this may cause loss of precision, but is useful for
|
|
|
|
/// debugging dumps, etc.
|
|
|
|
double FloatingLiteral::getValueAsApproximateDouble() const {
|
|
|
|
llvm::APFloat V = getValue();
|
2008-10-10 07:02:32 +08:00
|
|
|
bool ignored;
|
|
|
|
V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven,
|
|
|
|
&ignored);
|
2008-06-08 06:13:43 +08:00
|
|
|
return V.convertToDouble();
|
|
|
|
}
|
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
StringLiteral *StringLiteral::Create(ASTContext &C, StringRef Str,
|
2011-07-27 13:40:30 +08:00
|
|
|
StringKind Kind, bool Pascal, QualType Ty,
|
2009-09-09 23:08:12 +08:00
|
|
|
const SourceLocation *Loc,
|
2009-03-16 02:34:13 +08:00
|
|
|
unsigned NumStrs) {
|
2009-02-18 14:40:38 +08:00
|
|
|
// 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),
|
2010-10-30 13:14:06 +08:00
|
|
|
llvm::alignOf<StringLiteral>());
|
2009-02-18 14:40:38 +08:00
|
|
|
StringLiteral *SL = new (Mem) StringLiteral(Ty);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2007-02-22 07:46:25 +08:00
|
|
|
// OPTIMIZE: could allocate this appended to the StringLiteral.
|
2011-06-21 23:13:30 +08:00
|
|
|
char *AStrData = new (C, 1) char[Str.size()];
|
|
|
|
memcpy(AStrData, Str.data(), Str.size());
|
2009-02-18 14:40:38 +08:00
|
|
|
SL->StrData = AStrData;
|
2011-06-21 23:13:30 +08:00
|
|
|
SL->ByteLength = Str.size();
|
2011-07-27 13:40:30 +08:00
|
|
|
SL->Kind = Kind;
|
2011-04-14 08:40:03 +08:00
|
|
|
SL->IsPascal = Pascal;
|
2009-02-18 14:40:38 +08:00
|
|
|
SL->TokLocs[0] = Loc[0];
|
|
|
|
SL->NumConcatenated = NumStrs;
|
2006-10-06 13:22:26 +08:00
|
|
|
|
2009-02-18 13:49:11 +08:00
|
|
|
if (NumStrs != 1)
|
2009-02-18 14:40:38 +08:00
|
|
|
memcpy(&SL->TokLocs[1], Loc+1, sizeof(SourceLocation)*(NumStrs-1));
|
|
|
|
return SL;
|
2009-02-18 13:49:11 +08:00
|
|
|
}
|
|
|
|
|
2009-04-16 00:35:07 +08:00
|
|
|
StringLiteral *StringLiteral::CreateEmpty(ASTContext &C, unsigned NumStrs) {
|
|
|
|
void *Mem = C.Allocate(sizeof(StringLiteral)+
|
|
|
|
sizeof(SourceLocation)*(NumStrs-1),
|
2010-10-30 13:14:06 +08:00
|
|
|
llvm::alignOf<StringLiteral>());
|
2009-04-16 00:35:07 +08:00
|
|
|
StringLiteral *SL = new (Mem) StringLiteral(QualType());
|
|
|
|
SL->StrData = 0;
|
|
|
|
SL->ByteLength = 0;
|
|
|
|
SL->NumConcatenated = NumStrs;
|
|
|
|
return SL;
|
|
|
|
}
|
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
void StringLiteral::setString(ASTContext &C, StringRef Str) {
|
2009-09-22 11:27:33 +08:00
|
|
|
char *AStrData = new (C, 1) char[Str.size()];
|
|
|
|
memcpy(AStrData, Str.data(), Str.size());
|
2009-04-16 00:35:07 +08:00
|
|
|
StrData = AStrData;
|
2009-09-22 11:27:33 +08:00
|
|
|
ByteLength = Str.size();
|
2009-04-16 00:35:07 +08:00
|
|
|
}
|
|
|
|
|
2010-11-17 15:37:15 +08:00
|
|
|
/// getLocationOfByte - Return a source location that points to the specified
|
|
|
|
/// byte of this string literal.
|
|
|
|
///
|
|
|
|
/// Strings are amazingly complex. They can be formed from multiple tokens and
|
|
|
|
/// can have escape sequences in them in addition to the usual trigraph and
|
|
|
|
/// escaped newline business. This routine handles this complexity.
|
|
|
|
///
|
|
|
|
SourceLocation StringLiteral::
|
|
|
|
getLocationOfByte(unsigned ByteNo, const SourceManager &SM,
|
|
|
|
const LangOptions &Features, const TargetInfo &Target) const {
|
2011-07-27 13:40:30 +08:00
|
|
|
assert(Kind == StringLiteral::Ascii && "This only works for ASCII strings");
|
|
|
|
|
2010-11-17 15:37:15 +08:00
|
|
|
// Loop over all of the tokens in this string until we find the one that
|
|
|
|
// contains the byte we're looking for.
|
|
|
|
unsigned TokNo = 0;
|
|
|
|
while (1) {
|
|
|
|
assert(TokNo < getNumConcatenated() && "Invalid byte number!");
|
|
|
|
SourceLocation StrTokLoc = getStrTokenLoc(TokNo);
|
|
|
|
|
|
|
|
// Get the spelling of the string so that we can get the data that makes up
|
|
|
|
// the string literal, not the identifier for the macro it is potentially
|
|
|
|
// expanded through.
|
|
|
|
SourceLocation StrTokSpellingLoc = SM.getSpellingLoc(StrTokLoc);
|
|
|
|
|
|
|
|
// Re-lex the token to get its length and original spelling.
|
|
|
|
std::pair<FileID, unsigned> LocInfo =SM.getDecomposedLoc(StrTokSpellingLoc);
|
|
|
|
bool Invalid = false;
|
2011-07-23 18:55:15 +08:00
|
|
|
StringRef Buffer = SM.getBufferData(LocInfo.first, &Invalid);
|
2010-11-17 15:37:15 +08:00
|
|
|
if (Invalid)
|
|
|
|
return StrTokSpellingLoc;
|
|
|
|
|
|
|
|
const char *StrData = Buffer.data()+LocInfo.second;
|
|
|
|
|
|
|
|
// Create a langops struct and enable trigraphs. This is sufficient for
|
|
|
|
// relexing tokens.
|
|
|
|
LangOptions LangOpts;
|
|
|
|
LangOpts.Trigraphs = true;
|
|
|
|
|
|
|
|
// Create a lexer starting at the beginning of this token.
|
|
|
|
Lexer TheLexer(StrTokSpellingLoc, Features, Buffer.begin(), StrData,
|
|
|
|
Buffer.end());
|
|
|
|
Token TheTok;
|
|
|
|
TheLexer.LexFromRawLexer(TheTok);
|
|
|
|
|
|
|
|
// Use the StringLiteralParser to compute the length of the string in bytes.
|
|
|
|
StringLiteralParser SLP(&TheTok, 1, SM, Features, Target);
|
|
|
|
unsigned TokNumBytes = SLP.GetStringLength();
|
|
|
|
|
|
|
|
// If the byte is in this token, return the location of the byte.
|
|
|
|
if (ByteNo < TokNumBytes ||
|
2011-07-01 04:17:41 +08:00
|
|
|
(ByteNo == TokNumBytes && TokNo == getNumConcatenated() - 1)) {
|
2010-11-17 15:37:15 +08:00
|
|
|
unsigned Offset = SLP.getOffsetOfStringByte(TheTok, ByteNo);
|
|
|
|
|
|
|
|
// Now that we know the offset of the token in the spelling, use the
|
|
|
|
// preprocessor to get the offset in the original source.
|
|
|
|
return Lexer::AdvanceToTokenCharacter(StrTokLoc, Offset, SM, Features);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Move to the next string token.
|
|
|
|
++TokNo;
|
|
|
|
ByteNo -= TokNumBytes;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2006-08-23 14:42:10 +08:00
|
|
|
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
|
|
|
|
/// corresponds to, e.g. "sizeof" or "[pre]++".
|
|
|
|
const char *UnaryOperator::getOpcodeStr(Opcode Op) {
|
|
|
|
switch (Op) {
|
2006-10-25 13:45:55 +08:00
|
|
|
default: assert(0 && "Unknown unary operator");
|
2010-08-25 19:45:40 +08:00
|
|
|
case UO_PostInc: return "++";
|
|
|
|
case UO_PostDec: return "--";
|
|
|
|
case UO_PreInc: return "++";
|
|
|
|
case UO_PreDec: return "--";
|
|
|
|
case UO_AddrOf: return "&";
|
|
|
|
case UO_Deref: return "*";
|
|
|
|
case UO_Plus: return "+";
|
|
|
|
case UO_Minus: return "-";
|
|
|
|
case UO_Not: return "~";
|
|
|
|
case UO_LNot: return "!";
|
|
|
|
case UO_Real: return "__real";
|
|
|
|
case UO_Imag: return "__imag";
|
|
|
|
case UO_Extension: return "__extension__";
|
2006-08-23 14:42:10 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-25 19:45:40 +08:00
|
|
|
UnaryOperatorKind
|
2009-03-14 07:49:33 +08:00
|
|
|
UnaryOperator::getOverloadedOpcode(OverloadedOperatorKind OO, bool Postfix) {
|
|
|
|
switch (OO) {
|
|
|
|
default: assert(false && "No unary operator for overloaded function");
|
2010-08-25 19:45:40 +08:00
|
|
|
case OO_PlusPlus: return Postfix ? UO_PostInc : UO_PreInc;
|
|
|
|
case OO_MinusMinus: return Postfix ? UO_PostDec : UO_PreDec;
|
|
|
|
case OO_Amp: return UO_AddrOf;
|
|
|
|
case OO_Star: return UO_Deref;
|
|
|
|
case OO_Plus: return UO_Plus;
|
|
|
|
case OO_Minus: return UO_Minus;
|
|
|
|
case OO_Tilde: return UO_Not;
|
|
|
|
case OO_Exclaim: return UO_LNot;
|
2009-03-14 07:49:33 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
OverloadedOperatorKind UnaryOperator::getOverloadedOperator(Opcode Opc) {
|
|
|
|
switch (Opc) {
|
2010-08-25 19:45:40 +08:00
|
|
|
case UO_PostInc: case UO_PreInc: return OO_PlusPlus;
|
|
|
|
case UO_PostDec: case UO_PreDec: return OO_MinusMinus;
|
|
|
|
case UO_AddrOf: return OO_Amp;
|
|
|
|
case UO_Deref: return OO_Star;
|
|
|
|
case UO_Plus: return OO_Plus;
|
|
|
|
case UO_Minus: return OO_Minus;
|
|
|
|
case UO_Not: return OO_Tilde;
|
|
|
|
case UO_LNot: return OO_Exclaim;
|
2009-03-14 07:49:33 +08:00
|
|
|
default: return OO_None;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-24 12:56:27 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Postfix Operators.
|
|
|
|
//===----------------------------------------------------------------------===//
|
2006-08-24 12:40:38 +08:00
|
|
|
|
2011-02-09 05:18:02 +08:00
|
|
|
CallExpr::CallExpr(ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs,
|
|
|
|
Expr **args, unsigned numargs, QualType t, ExprValueKind VK,
|
2010-11-18 14:31:45 +08:00
|
|
|
SourceLocation rparenloc)
|
|
|
|
: Expr(SC, t, VK, OK_Ordinary,
|
2010-12-15 09:34:56 +08:00
|
|
|
fn->isTypeDependent(),
|
|
|
|
fn->isValueDependent(),
|
2011-07-01 09:22:09 +08:00
|
|
|
fn->isInstantiationDependent(),
|
2010-12-15 09:34:56 +08:00
|
|
|
fn->containsUnexpandedParameterPack()),
|
2008-12-06 07:32:09 +08:00
|
|
|
NumArgs(numargs) {
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2011-02-09 05:18:02 +08:00
|
|
|
SubExprs = new (C) Stmt*[numargs+PREARGS_START+NumPreArgs];
|
2008-11-15 00:09:21 +08:00
|
|
|
SubExprs[FN] = fn;
|
2010-12-15 09:34:56 +08:00
|
|
|
for (unsigned i = 0; i != numargs; ++i) {
|
|
|
|
if (args[i]->isTypeDependent())
|
|
|
|
ExprBits.TypeDependent = true;
|
|
|
|
if (args[i]->isValueDependent())
|
|
|
|
ExprBits.ValueDependent = true;
|
2011-07-01 09:22:09 +08:00
|
|
|
if (args[i]->isInstantiationDependent())
|
|
|
|
ExprBits.InstantiationDependent = true;
|
2010-12-15 09:34:56 +08:00
|
|
|
if (args[i]->containsUnexpandedParameterPack())
|
|
|
|
ExprBits.ContainsUnexpandedParameterPack = true;
|
|
|
|
|
2011-02-09 05:18:02 +08:00
|
|
|
SubExprs[i+PREARGS_START+NumPreArgs] = args[i];
|
2010-12-15 09:34:56 +08:00
|
|
|
}
|
2009-02-10 04:51:47 +08:00
|
|
|
|
2011-02-09 05:18:02 +08:00
|
|
|
CallExprBits.NumPreArgs = NumPreArgs;
|
2008-11-15 00:09:21 +08:00
|
|
|
RParenLoc = rparenloc;
|
|
|
|
}
|
2008-01-18 01:46:27 +08:00
|
|
|
|
2009-02-10 04:51:47 +08:00
|
|
|
CallExpr::CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs,
|
2010-11-18 14:31:45 +08:00
|
|
|
QualType t, ExprValueKind VK, SourceLocation rparenloc)
|
|
|
|
: Expr(CallExprClass, t, VK, OK_Ordinary,
|
2010-12-15 09:34:56 +08:00
|
|
|
fn->isTypeDependent(),
|
|
|
|
fn->isValueDependent(),
|
2011-07-01 09:22:09 +08:00
|
|
|
fn->isInstantiationDependent(),
|
2010-12-15 09:34:56 +08:00
|
|
|
fn->containsUnexpandedParameterPack()),
|
2008-12-06 07:32:09 +08:00
|
|
|
NumArgs(numargs) {
|
2009-02-10 04:51:47 +08:00
|
|
|
|
2011-02-09 05:18:02 +08:00
|
|
|
SubExprs = new (C) Stmt*[numargs+PREARGS_START];
|
2007-08-25 02:13:47 +08:00
|
|
|
SubExprs[FN] = fn;
|
2010-12-15 09:34:56 +08:00
|
|
|
for (unsigned i = 0; i != numargs; ++i) {
|
|
|
|
if (args[i]->isTypeDependent())
|
|
|
|
ExprBits.TypeDependent = true;
|
|
|
|
if (args[i]->isValueDependent())
|
|
|
|
ExprBits.ValueDependent = true;
|
2011-07-01 09:22:09 +08:00
|
|
|
if (args[i]->isInstantiationDependent())
|
|
|
|
ExprBits.InstantiationDependent = true;
|
2010-12-15 09:34:56 +08:00
|
|
|
if (args[i]->containsUnexpandedParameterPack())
|
|
|
|
ExprBits.ContainsUnexpandedParameterPack = true;
|
|
|
|
|
2011-02-09 05:18:02 +08:00
|
|
|
SubExprs[i+PREARGS_START] = args[i];
|
2010-12-15 09:34:56 +08:00
|
|
|
}
|
2009-02-10 04:51:47 +08:00
|
|
|
|
2011-02-09 05:18:02 +08:00
|
|
|
CallExprBits.NumPreArgs = 0;
|
2007-06-27 14:08:24 +08:00
|
|
|
RParenLoc = rparenloc;
|
2006-08-24 12:40:38 +08:00
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
CallExpr::CallExpr(ASTContext &C, StmtClass SC, EmptyShell Empty)
|
|
|
|
: Expr(SC, Empty), SubExprs(0), NumArgs(0) {
|
2010-12-15 09:34:56 +08:00
|
|
|
// FIXME: Why do we allocate this?
|
2011-02-09 05:18:02 +08:00
|
|
|
SubExprs = new (C) Stmt*[PREARGS_START];
|
|
|
|
CallExprBits.NumPreArgs = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CallExpr::CallExpr(ASTContext &C, StmtClass SC, unsigned NumPreArgs,
|
|
|
|
EmptyShell Empty)
|
|
|
|
: Expr(SC, Empty), SubExprs(0), NumArgs(0) {
|
|
|
|
// FIXME: Why do we allocate this?
|
|
|
|
SubExprs = new (C) Stmt*[PREARGS_START+NumPreArgs];
|
|
|
|
CallExprBits.NumPreArgs = NumPreArgs;
|
2009-04-16 01:43:59 +08:00
|
|
|
}
|
|
|
|
|
2009-12-21 07:11:08 +08:00
|
|
|
Decl *CallExpr::getCalleeDecl() {
|
2011-09-14 07:08:34 +08:00
|
|
|
Expr *CEE = getCallee()->IgnoreParenImpCasts();
|
2011-09-07 05:41:04 +08:00
|
|
|
|
|
|
|
while (SubstNonTypeTemplateParmExpr *NTTP
|
|
|
|
= dyn_cast<SubstNonTypeTemplateParmExpr>(CEE)) {
|
|
|
|
CEE = NTTP->getReplacement()->IgnoreParenCasts();
|
|
|
|
}
|
|
|
|
|
2010-09-11 04:55:30 +08:00
|
|
|
// If we're calling a dereference, look at the pointer instead.
|
|
|
|
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(CEE)) {
|
|
|
|
if (BO->isPtrMemOp())
|
|
|
|
CEE = BO->getRHS()->IgnoreParenCasts();
|
|
|
|
} else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(CEE)) {
|
|
|
|
if (UO->getOpcode() == UO_Deref)
|
|
|
|
CEE = UO->getSubExpr()->IgnoreParenCasts();
|
|
|
|
}
|
2009-07-17 23:46:27 +08:00
|
|
|
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE))
|
2009-12-21 07:11:08 +08:00
|
|
|
return DRE->getDecl();
|
2009-12-24 08:28:18 +08:00
|
|
|
if (MemberExpr *ME = dyn_cast<MemberExpr>(CEE))
|
|
|
|
return ME->getMemberDecl();
|
2009-07-17 15:29:51 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-12-21 07:11:08 +08:00
|
|
|
FunctionDecl *CallExpr::getDirectCallee() {
|
2009-12-21 09:10:56 +08:00
|
|
|
return dyn_cast_or_null<FunctionDecl>(getCalleeDecl());
|
2009-12-21 07:11:08 +08:00
|
|
|
}
|
|
|
|
|
2007-12-28 13:25:02 +08:00
|
|
|
/// 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.
|
2009-02-07 09:47:29 +08:00
|
|
|
void CallExpr::setNumArgs(ASTContext& C, unsigned NumArgs) {
|
2007-12-28 13:25:02 +08:00
|
|
|
// No change, just return.
|
|
|
|
if (NumArgs == getNumArgs()) return;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2007-12-28 13:25:02 +08:00
|
|
|
// 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.
|
2011-02-09 05:18:02 +08:00
|
|
|
unsigned NumPreArgs = getNumPreArgs();
|
|
|
|
Stmt **NewSubExprs = new (C) Stmt*[NumArgs+PREARGS_START+NumPreArgs];
|
2007-12-28 13:25:02 +08:00
|
|
|
// Copy over args.
|
2011-02-09 05:18:02 +08:00
|
|
|
for (unsigned i = 0; i != getNumArgs()+PREARGS_START+NumPreArgs; ++i)
|
2007-12-28 13:25:02 +08:00
|
|
|
NewSubExprs[i] = SubExprs[i];
|
|
|
|
// Null out new args.
|
2011-02-09 05:18:02 +08:00
|
|
|
for (unsigned i = getNumArgs()+PREARGS_START+NumPreArgs;
|
|
|
|
i != NumArgs+PREARGS_START+NumPreArgs; ++i)
|
2007-12-28 13:25:02 +08:00
|
|
|
NewSubExprs[i] = 0;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-04-18 05:46:47 +08:00
|
|
|
if (SubExprs) C.Deallocate(SubExprs);
|
2007-12-28 13:25:02 +08:00
|
|
|
SubExprs = NewSubExprs;
|
|
|
|
this->NumArgs = NumArgs;
|
|
|
|
}
|
|
|
|
|
2008-10-06 13:00:53 +08:00
|
|
|
/// isBuiltinCall - If this is a call to a builtin, return the builtin ID. If
|
|
|
|
/// not, return 0.
|
2011-01-12 17:06:06 +08:00
|
|
|
unsigned CallExpr::isBuiltinCall(const ASTContext &Context) const {
|
2008-01-31 09:07:12 +08:00
|
|
|
// All simple function calls (e.g. func()) are implicitly cast to pointer to
|
2009-09-09 23:08:12 +08:00
|
|
|
// function. As a result, we try and obtain the DeclRefExpr from the
|
2008-01-31 09:07:12 +08:00
|
|
|
// ImplicitCastExpr.
|
|
|
|
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(getCallee());
|
|
|
|
if (!ICE) // FIXME: deal with more complex calls (e.g. (func)(), (*func)()).
|
2008-10-06 13:00:53 +08:00
|
|
|
return 0;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2008-01-31 09:07:12 +08:00
|
|
|
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr());
|
|
|
|
if (!DRE)
|
2008-10-06 13:00:53 +08:00
|
|
|
return 0;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2008-01-31 10:13:57 +08:00
|
|
|
const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
|
|
|
|
if (!FDecl)
|
2008-10-06 13:00:53 +08:00
|
|
|
return 0;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2008-11-21 23:30:19 +08:00
|
|
|
if (!FDecl->getIdentifier())
|
|
|
|
return 0;
|
|
|
|
|
2009-09-12 08:22:50 +08:00
|
|
|
return FDecl->getBuiltinID();
|
2008-10-06 13:00:53 +08:00
|
|
|
}
|
2008-01-31 10:13:57 +08:00
|
|
|
|
2009-05-26 12:57:27 +08:00
|
|
|
QualType CallExpr::getCallReturnType() const {
|
|
|
|
QualType CalleeType = getCallee()->getType();
|
2009-07-30 05:53:49 +08:00
|
|
|
if (const PointerType *FnTypePtr = CalleeType->getAs<PointerType>())
|
2009-05-26 12:57:27 +08:00
|
|
|
CalleeType = FnTypePtr->getPointeeType();
|
2009-07-30 05:53:49 +08:00
|
|
|
else if (const BlockPointerType *BPT = CalleeType->getAs<BlockPointerType>())
|
2009-05-26 12:57:27 +08:00
|
|
|
CalleeType = BPT->getPointeeType();
|
2011-04-27 04:42:42 +08:00
|
|
|
else if (CalleeType->isSpecificPlaceholderType(BuiltinType::BoundMember))
|
|
|
|
// This should never be overloaded and so should never return null.
|
|
|
|
CalleeType = Expr::findBoundMemberType(getCallee());
|
2010-07-13 16:18:22 +08:00
|
|
|
|
2011-04-27 04:42:42 +08:00
|
|
|
const FunctionType *FnType = CalleeType->castAs<FunctionType>();
|
2009-05-26 12:57:27 +08:00
|
|
|
return FnType->getResultType();
|
|
|
|
}
|
2008-10-06 13:00:53 +08:00
|
|
|
|
2011-02-21 14:23:05 +08:00
|
|
|
SourceRange CallExpr::getSourceRange() const {
|
|
|
|
if (isa<CXXOperatorCallExpr>(this))
|
|
|
|
return cast<CXXOperatorCallExpr>(this)->getSourceRange();
|
|
|
|
|
|
|
|
SourceLocation begin = getCallee()->getLocStart();
|
|
|
|
if (begin.isInvalid() && getNumArgs() > 0)
|
|
|
|
begin = getArg(0)->getLocStart();
|
|
|
|
SourceLocation end = getRParenLoc();
|
|
|
|
if (end.isInvalid() && getNumArgs() > 0)
|
|
|
|
end = getArg(getNumArgs() - 1)->getLocEnd();
|
|
|
|
return SourceRange(begin, end);
|
|
|
|
}
|
|
|
|
|
2010-05-05 23:23:54 +08:00
|
|
|
OffsetOfExpr *OffsetOfExpr::Create(ASTContext &C, QualType type,
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
SourceLocation OperatorLoc,
|
2010-05-05 23:23:54 +08:00
|
|
|
TypeSourceInfo *tsi,
|
|
|
|
OffsetOfNode* compsPtr, unsigned numComps,
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
Expr** exprsPtr, unsigned numExprs,
|
|
|
|
SourceLocation RParenLoc) {
|
|
|
|
void *Mem = C.Allocate(sizeof(OffsetOfExpr) +
|
2010-05-05 23:23:54 +08:00
|
|
|
sizeof(OffsetOfNode) * numComps +
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
sizeof(Expr*) * numExprs);
|
|
|
|
|
|
|
|
return new (Mem) OffsetOfExpr(C, type, OperatorLoc, tsi, compsPtr, numComps,
|
|
|
|
exprsPtr, numExprs, RParenLoc);
|
|
|
|
}
|
|
|
|
|
|
|
|
OffsetOfExpr *OffsetOfExpr::CreateEmpty(ASTContext &C,
|
|
|
|
unsigned numComps, unsigned numExprs) {
|
|
|
|
void *Mem = C.Allocate(sizeof(OffsetOfExpr) +
|
|
|
|
sizeof(OffsetOfNode) * numComps +
|
|
|
|
sizeof(Expr*) * numExprs);
|
|
|
|
return new (Mem) OffsetOfExpr(numComps, numExprs);
|
|
|
|
}
|
|
|
|
|
2010-05-05 23:23:54 +08:00
|
|
|
OffsetOfExpr::OffsetOfExpr(ASTContext &C, QualType type,
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
SourceLocation OperatorLoc, TypeSourceInfo *tsi,
|
2010-05-05 23:23:54 +08:00
|
|
|
OffsetOfNode* compsPtr, unsigned numComps,
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
Expr** exprsPtr, unsigned numExprs,
|
|
|
|
SourceLocation RParenLoc)
|
2010-11-18 14:31:45 +08:00
|
|
|
: Expr(OffsetOfExprClass, type, VK_RValue, OK_Ordinary,
|
|
|
|
/*TypeDependent=*/false,
|
2010-12-15 09:34:56 +08:00
|
|
|
/*ValueDependent=*/tsi->getType()->isDependentType(),
|
2011-07-01 09:22:09 +08:00
|
|
|
tsi->getType()->isInstantiationDependentType(),
|
2010-12-15 09:34:56 +08:00
|
|
|
tsi->getType()->containsUnexpandedParameterPack()),
|
2010-05-05 23:23:54 +08:00
|
|
|
OperatorLoc(OperatorLoc), RParenLoc(RParenLoc), TSInfo(tsi),
|
|
|
|
NumComps(numComps), NumExprs(numExprs)
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
{
|
|
|
|
for(unsigned i = 0; i < numComps; ++i) {
|
|
|
|
setComponent(i, compsPtr[i]);
|
|
|
|
}
|
2010-05-05 23:23:54 +08:00
|
|
|
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
for(unsigned i = 0; i < numExprs; ++i) {
|
2010-12-15 09:34:56 +08:00
|
|
|
if (exprsPtr[i]->isTypeDependent() || exprsPtr[i]->isValueDependent())
|
|
|
|
ExprBits.ValueDependent = true;
|
|
|
|
if (exprsPtr[i]->containsUnexpandedParameterPack())
|
|
|
|
ExprBits.ContainsUnexpandedParameterPack = true;
|
|
|
|
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
setIndexExpr(i, exprsPtr[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IdentifierInfo *OffsetOfExpr::OffsetOfNode::getFieldName() const {
|
|
|
|
assert(getKind() == Field || getKind() == Identifier);
|
|
|
|
if (getKind() == Field)
|
|
|
|
return getField()->getIdentifier();
|
2010-05-05 23:23:54 +08:00
|
|
|
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
return reinterpret_cast<IdentifierInfo *> (Data & ~(uintptr_t)Mask);
|
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow,
|
2011-03-01 05:54:11 +08:00
|
|
|
NestedNameSpecifierLoc QualifierLoc,
|
2009-12-04 14:40:45 +08:00
|
|
|
ValueDecl *memberdecl,
|
2010-04-07 05:38:20 +08:00
|
|
|
DeclAccessPair founddecl,
|
2010-08-12 06:01:17 +08:00
|
|
|
DeclarationNameInfo nameinfo,
|
2009-11-23 09:53:49 +08:00
|
|
|
const TemplateArgumentListInfo *targs,
|
2010-11-18 14:31:45 +08:00
|
|
|
QualType ty,
|
|
|
|
ExprValueKind vk,
|
|
|
|
ExprObjectKind ok) {
|
2009-09-01 07:41:50 +08:00
|
|
|
std::size_t Size = sizeof(MemberExpr);
|
2010-03-31 05:47:33 +08:00
|
|
|
|
2011-03-01 05:54:11 +08:00
|
|
|
bool hasQualOrFound = (QualifierLoc ||
|
2010-04-07 05:38:20 +08:00
|
|
|
founddecl.getDecl() != memberdecl ||
|
|
|
|
founddecl.getAccess() != memberdecl->getAccess());
|
2010-03-31 05:47:33 +08:00
|
|
|
if (hasQualOrFound)
|
|
|
|
Size += sizeof(MemberNameQualifier);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-11-23 09:53:49 +08:00
|
|
|
if (targs)
|
|
|
|
Size += ExplicitTemplateArgumentList::sizeFor(*targs);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-10-30 13:14:06 +08:00
|
|
|
void *Mem = C.Allocate(Size, llvm::alignOf<MemberExpr>());
|
2010-11-18 14:31:45 +08:00
|
|
|
MemberExpr *E = new (Mem) MemberExpr(base, isarrow, memberdecl, nameinfo,
|
|
|
|
ty, vk, ok);
|
2010-03-31 05:47:33 +08:00
|
|
|
|
|
|
|
if (hasQualOrFound) {
|
2011-03-01 05:54:11 +08:00
|
|
|
// FIXME: Wrong. We should be looking at the member declaration we found.
|
|
|
|
if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isDependent()) {
|
2010-03-31 05:47:33 +08:00
|
|
|
E->setValueDependent(true);
|
|
|
|
E->setTypeDependent(true);
|
2011-07-01 09:22:09 +08:00
|
|
|
E->setInstantiationDependent(true);
|
|
|
|
}
|
|
|
|
else if (QualifierLoc &&
|
|
|
|
QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())
|
|
|
|
E->setInstantiationDependent(true);
|
|
|
|
|
2010-03-31 05:47:33 +08:00
|
|
|
E->HasQualifierOrFoundDecl = true;
|
|
|
|
|
|
|
|
MemberNameQualifier *NQ = E->getMemberQualifier();
|
2011-03-01 05:54:11 +08:00
|
|
|
NQ->QualifierLoc = QualifierLoc;
|
2010-03-31 05:47:33 +08:00
|
|
|
NQ->FoundDecl = founddecl;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (targs) {
|
2011-07-01 09:22:09 +08:00
|
|
|
bool Dependent = false;
|
|
|
|
bool InstantiationDependent = false;
|
|
|
|
bool ContainsUnexpandedParameterPack = false;
|
2010-03-31 05:47:33 +08:00
|
|
|
E->HasExplicitTemplateArgumentList = true;
|
2011-07-01 09:22:09 +08:00
|
|
|
E->getExplicitTemplateArgs().initializeFrom(*targs, Dependent,
|
|
|
|
InstantiationDependent,
|
|
|
|
ContainsUnexpandedParameterPack);
|
|
|
|
if (InstantiationDependent)
|
|
|
|
E->setInstantiationDependent(true);
|
2010-03-31 05:47:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return E;
|
2009-09-01 07:41:50 +08:00
|
|
|
}
|
|
|
|
|
2011-03-03 05:06:53 +08:00
|
|
|
SourceRange MemberExpr::getSourceRange() const {
|
|
|
|
SourceLocation StartLoc;
|
|
|
|
if (isImplicitAccess()) {
|
|
|
|
if (hasQualifier())
|
|
|
|
StartLoc = getQualifierLoc().getBeginLoc();
|
|
|
|
else
|
|
|
|
StartLoc = MemberLoc;
|
|
|
|
} else {
|
|
|
|
// FIXME: We don't want this to happen. Rather, we should be able to
|
|
|
|
// detect all kinds of implicit accesses more cleanly.
|
|
|
|
StartLoc = getBase()->getLocStart();
|
|
|
|
if (StartLoc.isInvalid())
|
|
|
|
StartLoc = MemberLoc;
|
|
|
|
}
|
|
|
|
|
|
|
|
SourceLocation EndLoc =
|
|
|
|
HasExplicitTemplateArgumentList? getRAngleLoc()
|
|
|
|
: getMemberNameInfo().getEndLoc();
|
|
|
|
|
|
|
|
return SourceRange(StartLoc, EndLoc);
|
|
|
|
}
|
|
|
|
|
2011-09-09 13:25:32 +08:00
|
|
|
void CastExpr::CheckCastConsistency() const {
|
|
|
|
switch (getCastKind()) {
|
|
|
|
case CK_DerivedToBase:
|
|
|
|
case CK_UncheckedDerivedToBase:
|
|
|
|
case CK_DerivedToBaseMemberPointer:
|
|
|
|
case CK_BaseToDerived:
|
|
|
|
case CK_BaseToDerivedMemberPointer:
|
|
|
|
assert(!path_empty() && "Cast kind should have a base path!");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CK_CPointerToObjCPointerCast:
|
|
|
|
assert(getType()->isObjCObjectPointerType());
|
|
|
|
assert(getSubExpr()->getType()->isPointerType());
|
|
|
|
goto CheckNoBasePath;
|
|
|
|
|
|
|
|
case CK_BlockPointerToObjCPointerCast:
|
|
|
|
assert(getType()->isObjCObjectPointerType());
|
|
|
|
assert(getSubExpr()->getType()->isBlockPointerType());
|
|
|
|
goto CheckNoBasePath;
|
|
|
|
|
|
|
|
case CK_BitCast:
|
|
|
|
// Arbitrary casts to C pointer types count as bitcasts.
|
|
|
|
// Otherwise, we should only have block and ObjC pointer casts
|
|
|
|
// here if they stay within the type kind.
|
|
|
|
if (!getType()->isPointerType()) {
|
|
|
|
assert(getType()->isObjCObjectPointerType() ==
|
|
|
|
getSubExpr()->getType()->isObjCObjectPointerType());
|
|
|
|
assert(getType()->isBlockPointerType() ==
|
|
|
|
getSubExpr()->getType()->isBlockPointerType());
|
|
|
|
}
|
|
|
|
goto CheckNoBasePath;
|
|
|
|
|
|
|
|
case CK_AnyPointerToBlockPointerCast:
|
|
|
|
assert(getType()->isBlockPointerType());
|
|
|
|
assert(getSubExpr()->getType()->isAnyPointerType() &&
|
|
|
|
!getSubExpr()->getType()->isBlockPointerType());
|
|
|
|
goto CheckNoBasePath;
|
|
|
|
|
|
|
|
// These should not have an inheritance path.
|
|
|
|
case CK_Dynamic:
|
|
|
|
case CK_ToUnion:
|
|
|
|
case CK_ArrayToPointerDecay:
|
|
|
|
case CK_FunctionToPointerDecay:
|
|
|
|
case CK_NullToMemberPointer:
|
|
|
|
case CK_NullToPointer:
|
|
|
|
case CK_ConstructorConversion:
|
|
|
|
case CK_IntegralToPointer:
|
|
|
|
case CK_PointerToIntegral:
|
|
|
|
case CK_ToVoid:
|
|
|
|
case CK_VectorSplat:
|
|
|
|
case CK_IntegralCast:
|
|
|
|
case CK_IntegralToFloating:
|
|
|
|
case CK_FloatingToIntegral:
|
|
|
|
case CK_FloatingCast:
|
|
|
|
case CK_ObjCObjectLValueCast:
|
|
|
|
case CK_FloatingRealToComplex:
|
|
|
|
case CK_FloatingComplexToReal:
|
|
|
|
case CK_FloatingComplexCast:
|
|
|
|
case CK_FloatingComplexToIntegralComplex:
|
|
|
|
case CK_IntegralRealToComplex:
|
|
|
|
case CK_IntegralComplexToReal:
|
|
|
|
case CK_IntegralComplexCast:
|
|
|
|
case CK_IntegralComplexToFloatingComplex:
|
2011-09-10 14:18:15 +08:00
|
|
|
case CK_ARCProduceObject:
|
|
|
|
case CK_ARCConsumeObject:
|
|
|
|
case CK_ARCReclaimReturnedObject:
|
|
|
|
case CK_ARCExtendBlockObject:
|
2011-09-09 13:25:32 +08:00
|
|
|
assert(!getType()->isBooleanType() && "unheralded conversion to bool");
|
|
|
|
goto CheckNoBasePath;
|
|
|
|
|
|
|
|
case CK_Dependent:
|
|
|
|
case CK_LValueToRValue:
|
|
|
|
case CK_GetObjCProperty:
|
|
|
|
case CK_NoOp:
|
|
|
|
case CK_PointerToBoolean:
|
|
|
|
case CK_IntegralToBoolean:
|
|
|
|
case CK_FloatingToBoolean:
|
|
|
|
case CK_MemberPointerToBoolean:
|
|
|
|
case CK_FloatingComplexToBoolean:
|
|
|
|
case CK_IntegralComplexToBoolean:
|
|
|
|
case CK_LValueBitCast: // -> bool&
|
|
|
|
case CK_UserDefinedConversion: // operator bool()
|
|
|
|
CheckNoBasePath:
|
|
|
|
assert(path_empty() && "Cast kind should not have a base path!");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-03 08:59:21 +08:00
|
|
|
const char *CastExpr::getCastKindName() const {
|
|
|
|
switch (getCastKind()) {
|
2010-11-15 17:13:47 +08:00
|
|
|
case CK_Dependent:
|
|
|
|
return "Dependent";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_BitCast:
|
2009-09-03 08:59:21 +08:00
|
|
|
return "BitCast";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_LValueBitCast:
|
2010-07-14 07:17:26 +08:00
|
|
|
return "LValueBitCast";
|
2010-12-01 12:43:34 +08:00
|
|
|
case CK_LValueToRValue:
|
|
|
|
return "LValueToRValue";
|
2010-12-04 11:47:34 +08:00
|
|
|
case CK_GetObjCProperty:
|
|
|
|
return "GetObjCProperty";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_NoOp:
|
2009-09-03 08:59:21 +08:00
|
|
|
return "NoOp";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_BaseToDerived:
|
2009-11-13 00:43:42 +08:00
|
|
|
return "BaseToDerived";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_DerivedToBase:
|
2009-09-03 08:59:21 +08:00
|
|
|
return "DerivedToBase";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_UncheckedDerivedToBase:
|
2010-03-31 07:58:03 +08:00
|
|
|
return "UncheckedDerivedToBase";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_Dynamic:
|
2009-09-03 08:59:21 +08:00
|
|
|
return "Dynamic";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_ToUnion:
|
2009-09-03 08:59:21 +08:00
|
|
|
return "ToUnion";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_ArrayToPointerDecay:
|
2009-09-03 08:59:21 +08:00
|
|
|
return "ArrayToPointerDecay";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_FunctionToPointerDecay:
|
2009-09-03 08:59:21 +08:00
|
|
|
return "FunctionToPointerDecay";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_NullToMemberPointer:
|
2009-09-03 08:59:21 +08:00
|
|
|
return "NullToMemberPointer";
|
2010-11-13 09:35:44 +08:00
|
|
|
case CK_NullToPointer:
|
|
|
|
return "NullToPointer";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_BaseToDerivedMemberPointer:
|
2009-09-03 08:59:21 +08:00
|
|
|
return "BaseToDerivedMemberPointer";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_DerivedToBaseMemberPointer:
|
2009-10-30 08:46:35 +08:00
|
|
|
return "DerivedToBaseMemberPointer";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_UserDefinedConversion:
|
2009-09-03 08:59:21 +08:00
|
|
|
return "UserDefinedConversion";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_ConstructorConversion:
|
2009-09-03 08:59:21 +08:00
|
|
|
return "ConstructorConversion";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_IntegralToPointer:
|
2009-09-15 12:48:33 +08:00
|
|
|
return "IntegralToPointer";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_PointerToIntegral:
|
2009-09-15 12:48:33 +08:00
|
|
|
return "PointerToIntegral";
|
2010-11-15 17:13:47 +08:00
|
|
|
case CK_PointerToBoolean:
|
|
|
|
return "PointerToBoolean";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_ToVoid:
|
2009-10-16 10:35:04 +08:00
|
|
|
return "ToVoid";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_VectorSplat:
|
2009-10-16 13:23:41 +08:00
|
|
|
return "VectorSplat";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_IntegralCast:
|
2009-10-19 02:12:03 +08:00
|
|
|
return "IntegralCast";
|
2010-11-15 17:13:47 +08:00
|
|
|
case CK_IntegralToBoolean:
|
|
|
|
return "IntegralToBoolean";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_IntegralToFloating:
|
2009-10-19 02:12:03 +08:00
|
|
|
return "IntegralToFloating";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_FloatingToIntegral:
|
2009-10-19 02:12:03 +08:00
|
|
|
return "FloatingToIntegral";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_FloatingCast:
|
2009-10-19 03:02:15 +08:00
|
|
|
return "FloatingCast";
|
2010-11-15 17:13:47 +08:00
|
|
|
case CK_FloatingToBoolean:
|
|
|
|
return "FloatingToBoolean";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_MemberPointerToBoolean:
|
2009-11-24 04:04:44 +08:00
|
|
|
return "MemberPointerToBoolean";
|
2011-09-09 13:25:32 +08:00
|
|
|
case CK_CPointerToObjCPointerCast:
|
|
|
|
return "CPointerToObjCPointerCast";
|
|
|
|
case CK_BlockPointerToObjCPointerCast:
|
|
|
|
return "BlockPointerToObjCPointerCast";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_AnyPointerToBlockPointerCast:
|
2009-12-12 06:40:48 +08:00
|
|
|
return "AnyPointerToBlockPointerCast";
|
2010-08-25 19:45:40 +08:00
|
|
|
case CK_ObjCObjectLValueCast:
|
2010-08-07 19:51:51 +08:00
|
|
|
return "ObjCObjectLValueCast";
|
2010-11-13 17:02:35 +08:00
|
|
|
case CK_FloatingRealToComplex:
|
|
|
|
return "FloatingRealToComplex";
|
2010-11-14 16:17:51 +08:00
|
|
|
case CK_FloatingComplexToReal:
|
|
|
|
return "FloatingComplexToReal";
|
|
|
|
case CK_FloatingComplexToBoolean:
|
|
|
|
return "FloatingComplexToBoolean";
|
2010-11-13 17:02:35 +08:00
|
|
|
case CK_FloatingComplexCast:
|
|
|
|
return "FloatingComplexCast";
|
2010-11-14 16:17:51 +08:00
|
|
|
case CK_FloatingComplexToIntegralComplex:
|
|
|
|
return "FloatingComplexToIntegralComplex";
|
2010-11-13 17:02:35 +08:00
|
|
|
case CK_IntegralRealToComplex:
|
|
|
|
return "IntegralRealToComplex";
|
2010-11-14 16:17:51 +08:00
|
|
|
case CK_IntegralComplexToReal:
|
|
|
|
return "IntegralComplexToReal";
|
|
|
|
case CK_IntegralComplexToBoolean:
|
|
|
|
return "IntegralComplexToBoolean";
|
2010-11-13 17:02:35 +08:00
|
|
|
case CK_IntegralComplexCast:
|
|
|
|
return "IntegralComplexCast";
|
2010-11-14 16:17:51 +08:00
|
|
|
case CK_IntegralComplexToFloatingComplex:
|
|
|
|
return "IntegralComplexToFloatingComplex";
|
2011-09-10 14:18:15 +08:00
|
|
|
case CK_ARCConsumeObject:
|
|
|
|
return "ARCConsumeObject";
|
|
|
|
case CK_ARCProduceObject:
|
|
|
|
return "ARCProduceObject";
|
|
|
|
case CK_ARCReclaimReturnedObject:
|
|
|
|
return "ARCReclaimReturnedObject";
|
|
|
|
case CK_ARCExtendBlockObject:
|
|
|
|
return "ARCCExtendBlockObject";
|
2009-09-03 08:59:21 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-11-13 17:02:35 +08:00
|
|
|
llvm_unreachable("Unhandled cast kind!");
|
2009-09-03 08:59:21 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-12-15 03:27:10 +08:00
|
|
|
Expr *CastExpr::getSubExprAsWritten() {
|
|
|
|
Expr *SubExpr = 0;
|
|
|
|
CastExpr *E = this;
|
|
|
|
do {
|
|
|
|
SubExpr = E->getSubExpr();
|
2011-06-22 01:03:29 +08:00
|
|
|
|
|
|
|
// Skip through reference binding to temporary.
|
|
|
|
if (MaterializeTemporaryExpr *Materialize
|
|
|
|
= dyn_cast<MaterializeTemporaryExpr>(SubExpr))
|
|
|
|
SubExpr = Materialize->GetTemporaryExpr();
|
|
|
|
|
2009-12-15 03:27:10 +08:00
|
|
|
// Skip any temporary bindings; they're implicit.
|
|
|
|
if (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(SubExpr))
|
|
|
|
SubExpr = Binder->getSubExpr();
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2009-12-15 03:27:10 +08:00
|
|
|
// Conversions by constructor and conversion functions have a
|
|
|
|
// subexpression describing the call; strip it off.
|
2010-08-25 19:45:40 +08:00
|
|
|
if (E->getCastKind() == CK_ConstructorConversion)
|
2009-12-15 03:27:10 +08:00
|
|
|
SubExpr = cast<CXXConstructExpr>(SubExpr)->getArg(0);
|
2010-08-25 19:45:40 +08:00
|
|
|
else if (E->getCastKind() == CK_UserDefinedConversion)
|
2009-12-15 03:27:10 +08:00
|
|
|
SubExpr = cast<CXXMemberCallExpr>(SubExpr)->getImplicitObjectArgument();
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2009-12-15 03:27:10 +08:00
|
|
|
// If the subexpression we're left with is an implicit cast, look
|
|
|
|
// through that, too.
|
2010-05-05 23:23:54 +08:00
|
|
|
} while ((E = dyn_cast<ImplicitCastExpr>(SubExpr)));
|
|
|
|
|
2009-12-15 03:27:10 +08:00
|
|
|
return SubExpr;
|
|
|
|
}
|
|
|
|
|
2010-08-07 14:22:56 +08:00
|
|
|
CXXBaseSpecifier **CastExpr::path_buffer() {
|
|
|
|
switch (getStmtClass()) {
|
|
|
|
#define ABSTRACT_STMT(x)
|
|
|
|
#define CASTEXPR(Type, Base) \
|
|
|
|
case Stmt::Type##Class: \
|
|
|
|
return reinterpret_cast<CXXBaseSpecifier**>(static_cast<Type*>(this)+1);
|
|
|
|
#define STMT(Type, Base)
|
|
|
|
#include "clang/AST/StmtNodes.inc"
|
|
|
|
default:
|
|
|
|
llvm_unreachable("non-cast expressions not possible here");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CastExpr::setCastPath(const CXXCastPath &Path) {
|
|
|
|
assert(Path.size() == path_size());
|
|
|
|
memcpy(path_buffer(), Path.data(), Path.size() * sizeof(CXXBaseSpecifier*));
|
|
|
|
}
|
|
|
|
|
|
|
|
ImplicitCastExpr *ImplicitCastExpr::Create(ASTContext &C, QualType T,
|
|
|
|
CastKind Kind, Expr *Operand,
|
|
|
|
const CXXCastPath *BasePath,
|
2010-08-25 18:28:54 +08:00
|
|
|
ExprValueKind VK) {
|
2010-08-07 14:22:56 +08:00
|
|
|
unsigned PathSize = (BasePath ? BasePath->size() : 0);
|
|
|
|
void *Buffer =
|
|
|
|
C.Allocate(sizeof(ImplicitCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
|
|
|
|
ImplicitCastExpr *E =
|
2010-08-25 18:28:54 +08:00
|
|
|
new (Buffer) ImplicitCastExpr(T, Kind, Operand, PathSize, VK);
|
2010-08-07 14:22:56 +08:00
|
|
|
if (PathSize) E->setCastPath(*BasePath);
|
|
|
|
return E;
|
|
|
|
}
|
|
|
|
|
|
|
|
ImplicitCastExpr *ImplicitCastExpr::CreateEmpty(ASTContext &C,
|
|
|
|
unsigned PathSize) {
|
|
|
|
void *Buffer =
|
|
|
|
C.Allocate(sizeof(ImplicitCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
|
|
|
|
return new (Buffer) ImplicitCastExpr(EmptyShell(), PathSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CStyleCastExpr *CStyleCastExpr::Create(ASTContext &C, QualType T,
|
2010-11-18 14:31:45 +08:00
|
|
|
ExprValueKind VK, CastKind K, Expr *Op,
|
2010-08-07 14:22:56 +08:00
|
|
|
const CXXCastPath *BasePath,
|
|
|
|
TypeSourceInfo *WrittenTy,
|
|
|
|
SourceLocation L, SourceLocation R) {
|
|
|
|
unsigned PathSize = (BasePath ? BasePath->size() : 0);
|
|
|
|
void *Buffer =
|
|
|
|
C.Allocate(sizeof(CStyleCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
|
|
|
|
CStyleCastExpr *E =
|
2010-11-18 14:31:45 +08:00
|
|
|
new (Buffer) CStyleCastExpr(T, VK, K, Op, PathSize, WrittenTy, L, R);
|
2010-08-07 14:22:56 +08:00
|
|
|
if (PathSize) E->setCastPath(*BasePath);
|
|
|
|
return E;
|
|
|
|
}
|
|
|
|
|
|
|
|
CStyleCastExpr *CStyleCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) {
|
|
|
|
void *Buffer =
|
|
|
|
C.Allocate(sizeof(CStyleCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
|
|
|
|
return new (Buffer) CStyleCastExpr(EmptyShell(), PathSize);
|
|
|
|
}
|
|
|
|
|
2006-08-23 14:42:10 +08:00
|
|
|
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
|
|
|
|
/// corresponds to, e.g. "<<=".
|
|
|
|
const char *BinaryOperator::getOpcodeStr(Opcode Op) {
|
|
|
|
switch (Op) {
|
2010-08-25 19:45:40 +08:00
|
|
|
case BO_PtrMemD: return ".*";
|
|
|
|
case BO_PtrMemI: return "->*";
|
|
|
|
case BO_Mul: return "*";
|
|
|
|
case BO_Div: return "/";
|
|
|
|
case BO_Rem: return "%";
|
|
|
|
case BO_Add: return "+";
|
|
|
|
case BO_Sub: return "-";
|
|
|
|
case BO_Shl: return "<<";
|
|
|
|
case BO_Shr: return ">>";
|
|
|
|
case BO_LT: return "<";
|
|
|
|
case BO_GT: return ">";
|
|
|
|
case BO_LE: return "<=";
|
|
|
|
case BO_GE: return ">=";
|
|
|
|
case BO_EQ: return "==";
|
|
|
|
case BO_NE: return "!=";
|
|
|
|
case BO_And: return "&";
|
|
|
|
case BO_Xor: return "^";
|
|
|
|
case BO_Or: return "|";
|
|
|
|
case BO_LAnd: return "&&";
|
|
|
|
case BO_LOr: return "||";
|
|
|
|
case BO_Assign: return "=";
|
|
|
|
case BO_MulAssign: return "*=";
|
|
|
|
case BO_DivAssign: return "/=";
|
|
|
|
case BO_RemAssign: return "%=";
|
|
|
|
case BO_AddAssign: return "+=";
|
|
|
|
case BO_SubAssign: return "-=";
|
|
|
|
case BO_ShlAssign: return "<<=";
|
|
|
|
case BO_ShrAssign: return ">>=";
|
|
|
|
case BO_AndAssign: return "&=";
|
|
|
|
case BO_XorAssign: return "^=";
|
|
|
|
case BO_OrAssign: return "|=";
|
|
|
|
case BO_Comma: return ",";
|
2006-08-23 14:42:10 +08:00
|
|
|
}
|
2009-03-13 06:51:37 +08:00
|
|
|
|
|
|
|
return "";
|
2006-08-23 14:42:10 +08:00
|
|
|
}
|
2007-04-20 07:00:49 +08:00
|
|
|
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOperatorKind
|
2009-03-14 02:40:31 +08:00
|
|
|
BinaryOperator::getOverloadedOpcode(OverloadedOperatorKind OO) {
|
|
|
|
switch (OO) {
|
2009-03-22 08:10:22 +08:00
|
|
|
default: assert(false && "Not an overloadable binary operator");
|
2010-08-25 19:45:40 +08:00
|
|
|
case OO_Plus: return BO_Add;
|
|
|
|
case OO_Minus: return BO_Sub;
|
|
|
|
case OO_Star: return BO_Mul;
|
|
|
|
case OO_Slash: return BO_Div;
|
|
|
|
case OO_Percent: return BO_Rem;
|
|
|
|
case OO_Caret: return BO_Xor;
|
|
|
|
case OO_Amp: return BO_And;
|
|
|
|
case OO_Pipe: return BO_Or;
|
|
|
|
case OO_Equal: return BO_Assign;
|
|
|
|
case OO_Less: return BO_LT;
|
|
|
|
case OO_Greater: return BO_GT;
|
|
|
|
case OO_PlusEqual: return BO_AddAssign;
|
|
|
|
case OO_MinusEqual: return BO_SubAssign;
|
|
|
|
case OO_StarEqual: return BO_MulAssign;
|
|
|
|
case OO_SlashEqual: return BO_DivAssign;
|
|
|
|
case OO_PercentEqual: return BO_RemAssign;
|
|
|
|
case OO_CaretEqual: return BO_XorAssign;
|
|
|
|
case OO_AmpEqual: return BO_AndAssign;
|
|
|
|
case OO_PipeEqual: return BO_OrAssign;
|
|
|
|
case OO_LessLess: return BO_Shl;
|
|
|
|
case OO_GreaterGreater: return BO_Shr;
|
|
|
|
case OO_LessLessEqual: return BO_ShlAssign;
|
|
|
|
case OO_GreaterGreaterEqual: return BO_ShrAssign;
|
|
|
|
case OO_EqualEqual: return BO_EQ;
|
|
|
|
case OO_ExclaimEqual: return BO_NE;
|
|
|
|
case OO_LessEqual: return BO_LE;
|
|
|
|
case OO_GreaterEqual: return BO_GE;
|
|
|
|
case OO_AmpAmp: return BO_LAnd;
|
|
|
|
case OO_PipePipe: return BO_LOr;
|
|
|
|
case OO_Comma: return BO_Comma;
|
|
|
|
case OO_ArrowStar: return BO_PtrMemI;
|
2009-03-14 02:40:31 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
OverloadedOperatorKind BinaryOperator::getOverloadedOperator(Opcode Opc) {
|
|
|
|
static const OverloadedOperatorKind OverOps[] = {
|
|
|
|
/* .* Cannot be overloaded */OO_None, OO_ArrowStar,
|
|
|
|
OO_Star, OO_Slash, OO_Percent,
|
|
|
|
OO_Plus, OO_Minus,
|
|
|
|
OO_LessLess, OO_GreaterGreater,
|
|
|
|
OO_Less, OO_Greater, OO_LessEqual, OO_GreaterEqual,
|
|
|
|
OO_EqualEqual, OO_ExclaimEqual,
|
|
|
|
OO_Amp,
|
|
|
|
OO_Caret,
|
|
|
|
OO_Pipe,
|
|
|
|
OO_AmpAmp,
|
|
|
|
OO_PipePipe,
|
|
|
|
OO_Equal, OO_StarEqual,
|
|
|
|
OO_SlashEqual, OO_PercentEqual,
|
|
|
|
OO_PlusEqual, OO_MinusEqual,
|
|
|
|
OO_LessLessEqual, OO_GreaterGreaterEqual,
|
|
|
|
OO_AmpEqual, OO_CaretEqual,
|
|
|
|
OO_PipeEqual,
|
|
|
|
OO_Comma
|
|
|
|
};
|
|
|
|
return OverOps[Opc];
|
|
|
|
}
|
|
|
|
|
2010-04-14 07:39:13 +08:00
|
|
|
InitListExpr::InitListExpr(ASTContext &C, SourceLocation lbraceloc,
|
2008-10-27 07:43:26 +08:00
|
|
|
Expr **initExprs, unsigned numInits,
|
2009-01-29 05:54:33 +08:00
|
|
|
SourceLocation rbraceloc)
|
2010-12-15 09:34:56 +08:00
|
|
|
: Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false,
|
2011-07-01 09:22:09 +08:00
|
|
|
false, false),
|
2010-04-14 07:39:13 +08:00
|
|
|
InitExprs(C, numInits),
|
2009-09-09 23:08:12 +08:00
|
|
|
LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0),
|
2011-04-21 08:27:41 +08:00
|
|
|
HadArrayRangeDesignator(false)
|
2010-05-05 23:23:54 +08:00
|
|
|
{
|
2010-02-19 09:50:18 +08:00
|
|
|
for (unsigned I = 0; I != numInits; ++I) {
|
|
|
|
if (initExprs[I]->isTypeDependent())
|
2010-10-26 16:39:16 +08:00
|
|
|
ExprBits.TypeDependent = true;
|
2010-02-19 09:50:18 +08:00
|
|
|
if (initExprs[I]->isValueDependent())
|
2010-10-26 16:39:16 +08:00
|
|
|
ExprBits.ValueDependent = true;
|
2011-07-01 09:22:09 +08:00
|
|
|
if (initExprs[I]->isInstantiationDependent())
|
|
|
|
ExprBits.InstantiationDependent = true;
|
2010-12-15 09:34:56 +08:00
|
|
|
if (initExprs[I]->containsUnexpandedParameterPack())
|
|
|
|
ExprBits.ContainsUnexpandedParameterPack = true;
|
2009-11-20 07:25:22 +08:00
|
|
|
}
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2010-04-14 07:39:13 +08:00
|
|
|
InitExprs.insert(C, InitExprs.end(), initExprs, initExprs+numInits);
|
2007-08-31 12:56:16 +08:00
|
|
|
}
|
2007-06-27 13:38:08 +08:00
|
|
|
|
2010-04-14 07:39:13 +08:00
|
|
|
void InitListExpr::reserveInits(ASTContext &C, unsigned NumInits) {
|
2010-02-19 09:50:18 +08:00
|
|
|
if (NumInits > InitExprs.size())
|
2010-04-14 07:39:13 +08:00
|
|
|
InitExprs.reserve(C, NumInits);
|
2009-03-21 07:58:33 +08:00
|
|
|
}
|
|
|
|
|
2010-04-14 07:39:13 +08:00
|
|
|
void InitListExpr::resizeInits(ASTContext &C, unsigned NumInits) {
|
|
|
|
InitExprs.resize(C, NumInits, 0);
|
2009-01-29 05:54:33 +08:00
|
|
|
}
|
|
|
|
|
2010-04-14 07:39:13 +08:00
|
|
|
Expr *InitListExpr::updateInit(ASTContext &C, unsigned Init, Expr *expr) {
|
2010-02-19 09:50:18 +08:00
|
|
|
if (Init >= InitExprs.size()) {
|
2010-04-14 07:39:13 +08:00
|
|
|
InitExprs.insert(C, InitExprs.end(), Init - InitExprs.size() + 1, 0);
|
2010-02-19 09:50:18 +08:00
|
|
|
InitExprs.back() = expr;
|
|
|
|
return 0;
|
2009-01-29 05:54:33 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-01-29 05:54:33 +08:00
|
|
|
Expr *Result = cast_or_null<Expr>(InitExprs[Init]);
|
|
|
|
InitExprs[Init] = expr;
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2011-04-22 04:03:38 +08:00
|
|
|
void InitListExpr::setArrayFiller(Expr *filler) {
|
|
|
|
ArrayFillerOrUnionFieldInit = filler;
|
|
|
|
// Fill out any "holes" in the array due to designated initializers.
|
|
|
|
Expr **inits = getInits();
|
|
|
|
for (unsigned i = 0, e = getNumInits(); i != e; ++i)
|
|
|
|
if (inits[i] == 0)
|
|
|
|
inits[i] = filler;
|
|
|
|
}
|
|
|
|
|
2010-11-09 10:11:40 +08:00
|
|
|
SourceRange InitListExpr::getSourceRange() const {
|
|
|
|
if (SyntacticForm)
|
|
|
|
return SyntacticForm->getSourceRange();
|
|
|
|
SourceLocation Beg = LBraceLoc, End = RBraceLoc;
|
|
|
|
if (Beg.isInvalid()) {
|
|
|
|
// Find the first non-null initializer.
|
|
|
|
for (InitExprsTy::const_iterator I = InitExprs.begin(),
|
|
|
|
E = InitExprs.end();
|
|
|
|
I != E; ++I) {
|
|
|
|
if (Stmt *S = *I) {
|
|
|
|
Beg = S->getLocStart();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (End.isInvalid()) {
|
|
|
|
// Find the first non-null initializer from the end.
|
|
|
|
for (InitExprsTy::const_reverse_iterator I = InitExprs.rbegin(),
|
|
|
|
E = InitExprs.rend();
|
|
|
|
I != E; ++I) {
|
|
|
|
if (Stmt *S = *I) {
|
|
|
|
End = S->getSourceRange().getEnd();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return SourceRange(Beg, End);
|
|
|
|
}
|
|
|
|
|
2008-09-04 23:31:07 +08:00
|
|
|
/// getFunctionType - Return the underlying function type for this block.
|
2008-09-04 02:15:37 +08:00
|
|
|
///
|
|
|
|
const FunctionType *BlockExpr::getFunctionType() const {
|
2009-07-30 05:53:49 +08:00
|
|
|
return getType()->getAs<BlockPointerType>()->
|
2009-09-22 07:43:11 +08:00
|
|
|
getPointeeType()->getAs<FunctionType>();
|
2008-09-04 02:15:37 +08:00
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
SourceLocation BlockExpr::getCaretLocation() const {
|
|
|
|
return TheBlock->getCaretLocation();
|
2008-10-09 01:01:13 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
const Stmt *BlockExpr::getBody() const {
|
2009-04-18 08:02:19 +08:00
|
|
|
return TheBlock->getBody();
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
Stmt *BlockExpr::getBody() {
|
|
|
|
return TheBlock->getBody();
|
2009-04-18 08:02:19 +08:00
|
|
|
}
|
2008-10-09 01:01:13 +08:00
|
|
|
|
|
|
|
|
2007-06-27 13:38:08 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Generic Expression Routines
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2009-02-14 15:37:35 +08:00
|
|
|
/// isUnusedResultAWarning - Return true if this immediate expression should
|
|
|
|
/// be warned about if the result is unused. If so, fill in Loc and Ranges
|
|
|
|
/// with location to warn on and the source range[s] to report with the
|
|
|
|
/// warning.
|
|
|
|
bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
|
2009-11-04 07:25:48 +08:00
|
|
|
SourceRange &R2, ASTContext &Ctx) const {
|
2009-05-16 07:10:19 +08:00
|
|
|
// Don't warn if the expr is type dependent. The type could end up
|
|
|
|
// instantiating to void.
|
|
|
|
if (isTypeDependent())
|
|
|
|
return false;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2007-06-27 13:38:08 +08:00
|
|
|
switch (getStmtClass()) {
|
|
|
|
default:
|
2010-03-12 15:11:26 +08:00
|
|
|
if (getType()->isVoidType())
|
|
|
|
return false;
|
2009-02-14 15:37:35 +08:00
|
|
|
Loc = getExprLoc();
|
|
|
|
R1 = getSourceRange();
|
|
|
|
return true;
|
2007-06-27 13:38:08 +08:00
|
|
|
case ParenExprClass:
|
2009-02-14 15:37:35 +08:00
|
|
|
return cast<ParenExpr>(this)->getSubExpr()->
|
2009-11-04 07:25:48 +08:00
|
|
|
isUnusedResultAWarning(Loc, R1, R2, Ctx);
|
2011-04-15 08:35:48 +08:00
|
|
|
case GenericSelectionExprClass:
|
|
|
|
return cast<GenericSelectionExpr>(this)->getResultExpr()->
|
|
|
|
isUnusedResultAWarning(Loc, R1, R2, Ctx);
|
2007-06-27 13:38:08 +08:00
|
|
|
case UnaryOperatorClass: {
|
|
|
|
const UnaryOperator *UO = cast<UnaryOperator>(this);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2007-06-27 13:38:08 +08:00
|
|
|
switch (UO->getOpcode()) {
|
2009-02-14 15:37:35 +08:00
|
|
|
default: break;
|
2010-08-25 19:45:40 +08:00
|
|
|
case UO_PostInc:
|
|
|
|
case UO_PostDec:
|
|
|
|
case UO_PreInc:
|
|
|
|
case UO_PreDec: // ++/--
|
2009-02-14 15:37:35 +08:00
|
|
|
return false; // Not a warning.
|
2010-08-25 19:45:40 +08:00
|
|
|
case UO_Deref:
|
2007-06-27 13:58:59 +08:00
|
|
|
// Dereferencing a volatile pointer is a side-effect.
|
2009-11-04 07:25:48 +08:00
|
|
|
if (Ctx.getCanonicalType(getType()).isVolatileQualified())
|
2009-02-14 15:37:35 +08:00
|
|
|
return false;
|
|
|
|
break;
|
2010-08-25 19:45:40 +08:00
|
|
|
case UO_Real:
|
|
|
|
case UO_Imag:
|
2007-06-27 13:58:59 +08:00
|
|
|
// accessing a piece of a volatile complex is a side-effect.
|
2009-11-04 07:25:48 +08:00
|
|
|
if (Ctx.getCanonicalType(UO->getSubExpr()->getType())
|
|
|
|
.isVolatileQualified())
|
2009-02-14 15:37:35 +08:00
|
|
|
return false;
|
|
|
|
break;
|
2010-08-25 19:45:40 +08:00
|
|
|
case UO_Extension:
|
2009-11-04 07:25:48 +08:00
|
|
|
return UO->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx);
|
2007-06-27 13:38:08 +08:00
|
|
|
}
|
2009-02-14 15:37:35 +08:00
|
|
|
Loc = UO->getOperatorLoc();
|
|
|
|
R1 = UO->getSubExpr()->getSourceRange();
|
|
|
|
return true;
|
2007-06-27 13:38:08 +08:00
|
|
|
}
|
2007-12-01 14:07:34 +08:00
|
|
|
case BinaryOperatorClass: {
|
2009-02-14 15:37:35 +08:00
|
|
|
const BinaryOperator *BO = cast<BinaryOperator>(this);
|
2010-04-08 02:49:21 +08:00
|
|
|
switch (BO->getOpcode()) {
|
|
|
|
default:
|
|
|
|
break;
|
2010-06-30 18:53:14 +08:00
|
|
|
// Consider the RHS of comma for side effects. LHS was checked by
|
|
|
|
// Sema::CheckCommaOperands.
|
2010-08-25 19:45:40 +08:00
|
|
|
case BO_Comma:
|
2010-04-08 02:49:21 +08:00
|
|
|
// ((foo = <blah>), 0) is an idiom for hiding the result (and
|
|
|
|
// lvalue-ness) of an assignment written in a macro.
|
|
|
|
if (IntegerLiteral *IE =
|
|
|
|
dyn_cast<IntegerLiteral>(BO->getRHS()->IgnoreParens()))
|
|
|
|
if (IE->getValue() == 0)
|
|
|
|
return false;
|
2010-06-30 18:53:14 +08:00
|
|
|
return BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx);
|
|
|
|
// Consider '||', '&&' to have side effects if the LHS or RHS does.
|
2010-08-25 19:45:40 +08:00
|
|
|
case BO_LAnd:
|
|
|
|
case BO_LOr:
|
2010-06-30 18:53:14 +08:00
|
|
|
if (!BO->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx) ||
|
|
|
|
!BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx))
|
|
|
|
return false;
|
|
|
|
break;
|
2010-02-16 12:10:53 +08:00
|
|
|
}
|
2009-02-14 15:37:35 +08:00
|
|
|
if (BO->isAssignmentOp())
|
|
|
|
return false;
|
|
|
|
Loc = BO->getOperatorLoc();
|
|
|
|
R1 = BO->getLHS()->getSourceRange();
|
|
|
|
R2 = BO->getRHS()->getSourceRange();
|
|
|
|
return true;
|
2007-12-01 14:07:34 +08:00
|
|
|
}
|
2007-08-25 10:00:02 +08:00
|
|
|
case CompoundAssignOperatorClass:
|
2010-05-09 06:41:50 +08:00
|
|
|
case VAArgExprClass:
|
2009-02-14 15:37:35 +08:00
|
|
|
return false;
|
2007-06-27 13:38:08 +08:00
|
|
|
|
2007-12-02 03:58:28 +08:00
|
|
|
case ConditionalOperatorClass: {
|
2011-03-02 04:34:48 +08:00
|
|
|
// If only one of the LHS or RHS is a warning, the operator might
|
|
|
|
// be being used for control flow. Only warn if both the LHS and
|
|
|
|
// RHS are warnings.
|
2007-12-02 03:58:28 +08:00
|
|
|
const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
|
2011-03-02 04:34:48 +08:00
|
|
|
if (!Exp->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx))
|
|
|
|
return false;
|
|
|
|
if (!Exp->getLHS())
|
2009-02-14 15:37:35 +08:00
|
|
|
return true;
|
2011-03-02 04:34:48 +08:00
|
|
|
return Exp->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx);
|
2007-12-02 03:58:28 +08:00
|
|
|
}
|
|
|
|
|
2007-06-27 13:58:59 +08:00
|
|
|
case MemberExprClass:
|
2009-02-14 15:37:35 +08:00
|
|
|
// If the base pointer or element is to a volatile pointer/field, accessing
|
|
|
|
// it is a side effect.
|
2009-11-04 07:25:48 +08:00
|
|
|
if (Ctx.getCanonicalType(getType()).isVolatileQualified())
|
2009-02-14 15:37:35 +08:00
|
|
|
return false;
|
|
|
|
Loc = cast<MemberExpr>(this)->getMemberLoc();
|
|
|
|
R1 = SourceRange(Loc, Loc);
|
|
|
|
R2 = cast<MemberExpr>(this)->getBase()->getSourceRange();
|
|
|
|
return true;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2007-06-27 13:38:08 +08:00
|
|
|
case ArraySubscriptExprClass:
|
2007-06-27 13:58:59 +08:00
|
|
|
// If the base pointer or element is to a volatile pointer/field, accessing
|
2009-02-14 15:37:35 +08:00
|
|
|
// it is a side effect.
|
2009-11-04 07:25:48 +08:00
|
|
|
if (Ctx.getCanonicalType(getType()).isVolatileQualified())
|
2009-02-14 15:37:35 +08:00
|
|
|
return false;
|
|
|
|
Loc = cast<ArraySubscriptExpr>(this)->getRBracketLoc();
|
|
|
|
R1 = cast<ArraySubscriptExpr>(this)->getLHS()->getSourceRange();
|
|
|
|
R2 = cast<ArraySubscriptExpr>(this)->getRHS()->getSourceRange();
|
|
|
|
return true;
|
2008-05-27 23:24:04 +08:00
|
|
|
|
2011-08-17 17:49:44 +08:00
|
|
|
case CXXOperatorCallExprClass: {
|
|
|
|
// We warn about operator== and operator!= even when user-defined operator
|
|
|
|
// overloads as there is no reasonable way to define these such that they
|
|
|
|
// have non-trivial, desirable side-effects. See the -Wunused-comparison
|
|
|
|
// warning: these operators are commonly typo'ed, and so warning on them
|
|
|
|
// provides additional value as well. If this list is updated,
|
|
|
|
// DiagnoseUnusedComparison should be as well.
|
|
|
|
const CXXOperatorCallExpr *Op = cast<CXXOperatorCallExpr>(this);
|
|
|
|
if (Op->getOperator() == OO_EqualEqual ||
|
|
|
|
Op->getOperator() == OO_ExclaimEqual)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Fallthrough for generic call handling.
|
|
|
|
}
|
2007-06-27 13:38:08 +08:00
|
|
|
case CallExprClass:
|
2009-04-30 00:35:53 +08:00
|
|
|
case CXXMemberCallExprClass: {
|
2009-02-14 15:37:35 +08:00
|
|
|
// If this is a direct call, get the callee.
|
|
|
|
const CallExpr *CE = cast<CallExpr>(this);
|
2009-12-21 07:11:08 +08:00
|
|
|
if (const Decl *FD = CE->getCalleeDecl()) {
|
2009-02-14 15:37:35 +08:00
|
|
|
// If the callee has attribute pure, const, or warn_unused_result, warn
|
|
|
|
// about it. void foo() { strlen("bar"); } should warn.
|
2009-10-13 12:53:48 +08:00
|
|
|
//
|
|
|
|
// Note: If new cases are added here, DiagnoseUnusedExprResult should be
|
|
|
|
// updated to match for QoI.
|
|
|
|
if (FD->getAttr<WarnUnusedResultAttr>() ||
|
|
|
|
FD->getAttr<PureAttr>() || FD->getAttr<ConstAttr>()) {
|
|
|
|
Loc = CE->getCallee()->getLocStart();
|
|
|
|
R1 = CE->getCallee()->getSourceRange();
|
|
|
|
|
|
|
|
if (unsigned NumArgs = CE->getNumArgs())
|
|
|
|
R2 = SourceRange(CE->getArg(0)->getLocStart(),
|
|
|
|
CE->getArg(NumArgs-1)->getLocEnd());
|
|
|
|
return true;
|
|
|
|
}
|
2009-02-14 15:37:35 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2009-11-18 01:11:23 +08:00
|
|
|
|
|
|
|
case CXXTemporaryObjectExprClass:
|
|
|
|
case CXXConstructExprClass:
|
|
|
|
return false;
|
|
|
|
|
2010-03-31 02:22:15 +08:00
|
|
|
case ObjCMessageExprClass: {
|
|
|
|
const ObjCMessageExpr *ME = cast<ObjCMessageExpr>(this);
|
2011-06-16 07:02:42 +08:00
|
|
|
if (Ctx.getLangOptions().ObjCAutoRefCount &&
|
|
|
|
ME->isInstanceMessage() &&
|
|
|
|
!ME->getType()->isVoidType() &&
|
|
|
|
ME->getSelector().getIdentifierInfoForSlot(0) &&
|
|
|
|
ME->getSelector().getIdentifierInfoForSlot(0)
|
|
|
|
->getName().startswith("init")) {
|
|
|
|
Loc = getExprLoc();
|
|
|
|
R1 = ME->getSourceRange();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-03-31 02:22:15 +08:00
|
|
|
const ObjCMethodDecl *MD = ME->getMethodDecl();
|
|
|
|
if (MD && MD->getAttr<WarnUnusedResultAttr>()) {
|
|
|
|
Loc = getExprLoc();
|
|
|
|
return true;
|
|
|
|
}
|
2009-02-14 15:37:35 +08:00
|
|
|
return false;
|
2010-03-31 02:22:15 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-12-02 09:19:52 +08:00
|
|
|
case ObjCPropertyRefExprClass:
|
2009-08-17 00:51:50 +08:00
|
|
|
Loc = getExprLoc();
|
|
|
|
R1 = getSourceRange();
|
2009-08-17 00:45:18 +08:00
|
|
|
return true;
|
2010-12-02 09:19:52 +08:00
|
|
|
|
2008-07-27 03:51:01 +08:00
|
|
|
case StmtExprClass: {
|
|
|
|
// Statement exprs don't logically have side effects themselves, but are
|
|
|
|
// sometimes used in macros in ways that give them a type that is unused.
|
|
|
|
// For example ({ blah; foo(); }) will end up with a type if foo has a type.
|
|
|
|
// however, if the result of the stmt expr is dead, we don't want to emit a
|
|
|
|
// warning.
|
|
|
|
const CompoundStmt *CS = cast<StmtExpr>(this)->getSubStmt();
|
2010-09-20 05:21:10 +08:00
|
|
|
if (!CS->body_empty()) {
|
2008-07-27 03:51:01 +08:00
|
|
|
if (const Expr *E = dyn_cast<Expr>(CS->body_back()))
|
2009-11-04 07:25:48 +08:00
|
|
|
return E->isUnusedResultAWarning(Loc, R1, R2, Ctx);
|
2010-09-20 05:21:10 +08:00
|
|
|
if (const LabelStmt *Label = dyn_cast<LabelStmt>(CS->body_back()))
|
|
|
|
if (const Expr *E = dyn_cast<Expr>(Label->getSubStmt()))
|
|
|
|
return E->isUnusedResultAWarning(Loc, R1, R2, Ctx);
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-03-12 15:11:26 +08:00
|
|
|
if (getType()->isVoidType())
|
|
|
|
return false;
|
2009-02-14 15:37:35 +08:00
|
|
|
Loc = cast<StmtExpr>(this)->getLParenLoc();
|
|
|
|
R1 = getSourceRange();
|
|
|
|
return true;
|
2008-07-27 03:51:01 +08:00
|
|
|
}
|
2008-10-28 23:36:24 +08:00
|
|
|
case CStyleCastExprClass:
|
2009-07-29 02:25:28 +08:00
|
|
|
// If this is an explicit cast to void, allow it. People do this when they
|
|
|
|
// think they know what they're doing :).
|
2009-02-14 15:37:35 +08:00
|
|
|
if (getType()->isVoidType())
|
2009-07-29 02:25:28 +08:00
|
|
|
return false;
|
2009-02-14 15:37:35 +08:00
|
|
|
Loc = cast<CStyleCastExpr>(this)->getLParenLoc();
|
|
|
|
R1 = cast<CStyleCastExpr>(this)->getSubExpr()->getSourceRange();
|
|
|
|
return true;
|
2009-11-18 01:11:23 +08:00
|
|
|
case CXXFunctionalCastExprClass: {
|
2010-03-12 15:11:26 +08:00
|
|
|
if (getType()->isVoidType())
|
|
|
|
return false;
|
2009-11-18 01:11:23 +08:00
|
|
|
const CastExpr *CE = cast<CastExpr>(this);
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2009-11-18 01:11:23 +08:00
|
|
|
// If this is a cast to void or a constructor conversion, check the operand.
|
|
|
|
// Otherwise, the result of the cast is unused.
|
2010-08-25 19:45:40 +08:00
|
|
|
if (CE->getCastKind() == CK_ToVoid ||
|
|
|
|
CE->getCastKind() == CK_ConstructorConversion)
|
2009-11-04 07:25:48 +08:00
|
|
|
return (cast<CastExpr>(this)->getSubExpr()
|
|
|
|
->isUnusedResultAWarning(Loc, R1, R2, Ctx));
|
2009-02-14 15:37:35 +08:00
|
|
|
Loc = cast<CXXFunctionalCastExpr>(this)->getTypeBeginLoc();
|
|
|
|
R1 = cast<CXXFunctionalCastExpr>(this)->getSubExpr()->getSourceRange();
|
|
|
|
return true;
|
2009-11-18 01:11:23 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2008-05-20 05:24:43 +08:00
|
|
|
case ImplicitCastExprClass:
|
|
|
|
// Check the operand, since implicit casts are inserted by Sema
|
2009-11-04 07:25:48 +08:00
|
|
|
return (cast<ImplicitCastExpr>(this)
|
|
|
|
->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
|
2008-05-20 05:24:43 +08:00
|
|
|
|
2008-04-08 12:40:51 +08:00
|
|
|
case CXXDefaultArgExprClass:
|
2009-11-04 07:25:48 +08:00
|
|
|
return (cast<CXXDefaultArgExpr>(this)
|
|
|
|
->getExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
|
2008-11-22 03:14:01 +08:00
|
|
|
|
|
|
|
case CXXNewExprClass:
|
|
|
|
// FIXME: In theory, there might be new expressions that don't have side
|
|
|
|
// effects (e.g. a placement new with an uninitialized POD).
|
|
|
|
case CXXDeleteExprClass:
|
2009-02-14 15:37:35 +08:00
|
|
|
return false;
|
2009-08-16 12:11:06 +08:00
|
|
|
case CXXBindTemporaryExprClass:
|
2009-11-04 07:25:48 +08:00
|
|
|
return (cast<CXXBindTemporaryExpr>(this)
|
|
|
|
->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
|
2010-12-06 16:20:24 +08:00
|
|
|
case ExprWithCleanupsClass:
|
|
|
|
return (cast<ExprWithCleanups>(this)
|
2009-11-04 07:25:48 +08:00
|
|
|
->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
|
2008-11-22 03:14:01 +08:00
|
|
|
}
|
2007-06-27 13:38:08 +08:00
|
|
|
}
|
|
|
|
|
2009-02-23 02:40:18 +08:00
|
|
|
/// isOBJCGCCandidate - Check if an expression is objc gc'able.
|
2009-09-09 07:38:54 +08:00
|
|
|
/// returns true, if it is; false otherwise.
|
2009-06-02 05:29:32 +08:00
|
|
|
bool Expr::isOBJCGCCandidate(ASTContext &Ctx) const {
|
2011-04-15 08:35:48 +08:00
|
|
|
const Expr *E = IgnoreParens();
|
|
|
|
switch (E->getStmtClass()) {
|
2009-02-23 02:40:18 +08:00
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
case ObjCIvarRefExprClass:
|
|
|
|
return true;
|
2009-02-24 02:59:50 +08:00
|
|
|
case Expr::UnaryOperatorClass:
|
2011-04-15 08:35:48 +08:00
|
|
|
return cast<UnaryOperator>(E)->getSubExpr()->isOBJCGCCandidate(Ctx);
|
2009-02-23 02:40:18 +08:00
|
|
|
case ImplicitCastExprClass:
|
2011-04-15 08:35:48 +08:00
|
|
|
return cast<ImplicitCastExpr>(E)->getSubExpr()->isOBJCGCCandidate(Ctx);
|
2011-06-22 01:03:29 +08:00
|
|
|
case MaterializeTemporaryExprClass:
|
|
|
|
return cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr()
|
|
|
|
->isOBJCGCCandidate(Ctx);
|
2009-05-06 07:28:21 +08:00
|
|
|
case CStyleCastExprClass:
|
2011-04-15 08:35:48 +08:00
|
|
|
return cast<CStyleCastExpr>(E)->getSubExpr()->isOBJCGCCandidate(Ctx);
|
2009-10-24 02:54:35 +08:00
|
|
|
case DeclRefExprClass: {
|
2011-04-15 08:35:48 +08:00
|
|
|
const Decl *D = cast<DeclRefExpr>(E)->getDecl();
|
2009-06-02 05:29:32 +08:00
|
|
|
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
|
|
|
|
if (VD->hasGlobalStorage())
|
|
|
|
return true;
|
|
|
|
QualType T = VD->getType();
|
2009-09-17 02:09:18 +08:00
|
|
|
// dereferencing to a pointer is always a gc'able candidate,
|
|
|
|
// unless it is __weak.
|
2009-09-17 14:31:17 +08:00
|
|
|
return T->isPointerType() &&
|
2009-09-25 03:53:00 +08:00
|
|
|
(Ctx.getObjCGCAttrKind(T) != Qualifiers::Weak);
|
2009-06-02 05:29:32 +08:00
|
|
|
}
|
2009-02-23 02:40:18 +08:00
|
|
|
return false;
|
|
|
|
}
|
2009-09-01 07:41:50 +08:00
|
|
|
case MemberExprClass: {
|
2011-04-15 08:35:48 +08:00
|
|
|
const MemberExpr *M = cast<MemberExpr>(E);
|
2009-06-02 05:29:32 +08:00
|
|
|
return M->getBase()->isOBJCGCCandidate(Ctx);
|
2009-02-23 02:40:18 +08:00
|
|
|
}
|
|
|
|
case ArraySubscriptExprClass:
|
2011-04-15 08:35:48 +08:00
|
|
|
return cast<ArraySubscriptExpr>(E)->getBase()->isOBJCGCCandidate(Ctx);
|
2009-02-23 02:40:18 +08:00
|
|
|
}
|
|
|
|
}
|
2010-09-11 04:55:33 +08:00
|
|
|
|
2010-11-02 02:49:26 +08:00
|
|
|
bool Expr::isBoundMemberFunction(ASTContext &Ctx) const {
|
|
|
|
if (isTypeDependent())
|
|
|
|
return false;
|
2010-11-24 13:12:34 +08:00
|
|
|
return ClassifyLValue(Ctx) == Expr::LV_MemberFunction;
|
2010-11-02 02:49:26 +08:00
|
|
|
}
|
|
|
|
|
2011-04-27 04:42:42 +08:00
|
|
|
QualType Expr::findBoundMemberType(const Expr *expr) {
|
|
|
|
assert(expr->getType()->isSpecificPlaceholderType(BuiltinType::BoundMember));
|
|
|
|
|
|
|
|
// Bound member expressions are always one of these possibilities:
|
|
|
|
// x->m x.m x->*y x.*y
|
|
|
|
// (possibly parenthesized)
|
|
|
|
|
|
|
|
expr = expr->IgnoreParens();
|
|
|
|
if (const MemberExpr *mem = dyn_cast<MemberExpr>(expr)) {
|
|
|
|
assert(isa<CXXMethodDecl>(mem->getMemberDecl()));
|
|
|
|
return mem->getMemberDecl()->getType();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const BinaryOperator *op = dyn_cast<BinaryOperator>(expr)) {
|
|
|
|
QualType type = op->getRHS()->getType()->castAs<MemberPointerType>()
|
|
|
|
->getPointeeType();
|
|
|
|
assert(type->isFunctionType());
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(isa<UnresolvedMemberExpr>(expr));
|
|
|
|
return QualType();
|
|
|
|
}
|
|
|
|
|
2010-09-11 04:55:33 +08:00
|
|
|
static Expr::CanThrowResult MergeCanThrow(Expr::CanThrowResult CT1,
|
|
|
|
Expr::CanThrowResult CT2) {
|
|
|
|
// CanThrowResult constants are ordered so that the maximum is the correct
|
|
|
|
// merge result.
|
|
|
|
return CT1 > CT2 ? CT1 : CT2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Expr::CanThrowResult CanSubExprsThrow(ASTContext &C, const Expr *CE) {
|
|
|
|
Expr *E = const_cast<Expr*>(CE);
|
|
|
|
Expr::CanThrowResult R = Expr::CT_Cannot;
|
2011-02-13 12:07:26 +08:00
|
|
|
for (Expr::child_range I = E->children(); I && R != Expr::CT_Can; ++I) {
|
2010-09-11 04:55:33 +08:00
|
|
|
R = MergeCanThrow(R, cast<Expr>(*I)->CanThrow(C));
|
|
|
|
}
|
|
|
|
return R;
|
|
|
|
}
|
|
|
|
|
2011-06-12 01:19:42 +08:00
|
|
|
static Expr::CanThrowResult CanCalleeThrow(ASTContext &Ctx, const Expr *E,
|
|
|
|
const Decl *D,
|
2010-09-11 04:55:33 +08:00
|
|
|
bool NullThrows = true) {
|
|
|
|
if (!D)
|
|
|
|
return NullThrows ? Expr::CT_Can : Expr::CT_Cannot;
|
|
|
|
|
|
|
|
// See if we can get a function type from the decl somehow.
|
|
|
|
const ValueDecl *VD = dyn_cast<ValueDecl>(D);
|
|
|
|
if (!VD) // If we have no clue what we're calling, assume the worst.
|
|
|
|
return Expr::CT_Can;
|
|
|
|
|
2010-09-11 06:34:40 +08:00
|
|
|
// As an extension, we assume that __attribute__((nothrow)) functions don't
|
|
|
|
// throw.
|
|
|
|
if (isa<FunctionDecl>(D) && D->hasAttr<NoThrowAttr>())
|
|
|
|
return Expr::CT_Cannot;
|
|
|
|
|
2010-09-11 04:55:33 +08:00
|
|
|
QualType T = VD->getType();
|
|
|
|
const FunctionProtoType *FT;
|
|
|
|
if ((FT = T->getAs<FunctionProtoType>())) {
|
|
|
|
} else if (const PointerType *PT = T->getAs<PointerType>())
|
|
|
|
FT = PT->getPointeeType()->getAs<FunctionProtoType>();
|
|
|
|
else if (const ReferenceType *RT = T->getAs<ReferenceType>())
|
|
|
|
FT = RT->getPointeeType()->getAs<FunctionProtoType>();
|
|
|
|
else if (const MemberPointerType *MT = T->getAs<MemberPointerType>())
|
|
|
|
FT = MT->getPointeeType()->getAs<FunctionProtoType>();
|
|
|
|
else if (const BlockPointerType *BT = T->getAs<BlockPointerType>())
|
|
|
|
FT = BT->getPointeeType()->getAs<FunctionProtoType>();
|
|
|
|
|
|
|
|
if (!FT)
|
|
|
|
return Expr::CT_Can;
|
|
|
|
|
2011-06-12 01:19:42 +08:00
|
|
|
if (FT->getExceptionSpecType() == EST_Delayed) {
|
|
|
|
assert(isa<CXXConstructorDecl>(D) &&
|
|
|
|
"only constructor exception specs can be unknown");
|
|
|
|
Ctx.getDiagnostics().Report(E->getLocStart(),
|
|
|
|
diag::err_exception_spec_unknown)
|
|
|
|
<< E->getSourceRange();
|
|
|
|
return Expr::CT_Can;
|
|
|
|
}
|
|
|
|
|
2011-03-14 01:09:40 +08:00
|
|
|
return FT->isNothrow(Ctx) ? Expr::CT_Cannot : Expr::CT_Can;
|
2010-09-11 04:55:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static Expr::CanThrowResult CanDynamicCastThrow(const CXXDynamicCastExpr *DC) {
|
|
|
|
if (DC->isTypeDependent())
|
|
|
|
return Expr::CT_Dependent;
|
|
|
|
|
2010-09-11 04:55:47 +08:00
|
|
|
if (!DC->getTypeAsWritten()->isReferenceType())
|
|
|
|
return Expr::CT_Cannot;
|
|
|
|
|
2011-05-11 13:22:44 +08:00
|
|
|
if (DC->getSubExpr()->isTypeDependent())
|
|
|
|
return Expr::CT_Dependent;
|
|
|
|
|
2010-09-11 04:55:33 +08:00
|
|
|
return DC->getCastKind() == clang::CK_Dynamic? Expr::CT_Can : Expr::CT_Cannot;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Expr::CanThrowResult CanTypeidThrow(ASTContext &C,
|
|
|
|
const CXXTypeidExpr *DC) {
|
|
|
|
if (DC->isTypeOperand())
|
|
|
|
return Expr::CT_Cannot;
|
|
|
|
|
|
|
|
Expr *Op = DC->getExprOperand();
|
|
|
|
if (Op->isTypeDependent())
|
|
|
|
return Expr::CT_Dependent;
|
|
|
|
|
|
|
|
const RecordType *RT = Op->getType()->getAs<RecordType>();
|
|
|
|
if (!RT)
|
|
|
|
return Expr::CT_Cannot;
|
|
|
|
|
|
|
|
if (!cast<CXXRecordDecl>(RT->getDecl())->isPolymorphic())
|
|
|
|
return Expr::CT_Cannot;
|
|
|
|
|
|
|
|
if (Op->Classify(C).isPRValue())
|
|
|
|
return Expr::CT_Cannot;
|
|
|
|
|
|
|
|
return Expr::CT_Can;
|
|
|
|
}
|
|
|
|
|
|
|
|
Expr::CanThrowResult Expr::CanThrow(ASTContext &C) const {
|
|
|
|
// C++ [expr.unary.noexcept]p3:
|
|
|
|
// [Can throw] if in a potentially-evaluated context the expression would
|
|
|
|
// contain:
|
|
|
|
switch (getStmtClass()) {
|
|
|
|
case CXXThrowExprClass:
|
|
|
|
// - a potentially evaluated throw-expression
|
|
|
|
return CT_Can;
|
|
|
|
|
|
|
|
case CXXDynamicCastExprClass: {
|
|
|
|
// - a potentially evaluated dynamic_cast expression dynamic_cast<T>(v),
|
|
|
|
// where T is a reference type, that requires a run-time check
|
|
|
|
CanThrowResult CT = CanDynamicCastThrow(cast<CXXDynamicCastExpr>(this));
|
|
|
|
if (CT == CT_Can)
|
|
|
|
return CT;
|
|
|
|
return MergeCanThrow(CT, CanSubExprsThrow(C, this));
|
|
|
|
}
|
|
|
|
|
|
|
|
case CXXTypeidExprClass:
|
|
|
|
// - a potentially evaluated typeid expression applied to a glvalue
|
|
|
|
// expression whose type is a polymorphic class type
|
|
|
|
return CanTypeidThrow(C, cast<CXXTypeidExpr>(this));
|
|
|
|
|
|
|
|
// - a potentially evaluated call to a function, member function, function
|
|
|
|
// pointer, or member function pointer that does not have a non-throwing
|
|
|
|
// exception-specification
|
|
|
|
case CallExprClass:
|
|
|
|
case CXXOperatorCallExprClass:
|
|
|
|
case CXXMemberCallExprClass: {
|
2011-05-12 10:11:32 +08:00
|
|
|
const CallExpr *CE = cast<CallExpr>(this);
|
2011-05-11 13:22:44 +08:00
|
|
|
CanThrowResult CT;
|
|
|
|
if (isTypeDependent())
|
|
|
|
CT = CT_Dependent;
|
2011-05-12 10:11:32 +08:00
|
|
|
else if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens()))
|
|
|
|
CT = CT_Cannot;
|
2011-05-11 13:22:44 +08:00
|
|
|
else
|
2011-06-12 01:19:42 +08:00
|
|
|
CT = CanCalleeThrow(C, this, CE->getCalleeDecl());
|
2010-09-11 04:55:33 +08:00
|
|
|
if (CT == CT_Can)
|
|
|
|
return CT;
|
|
|
|
return MergeCanThrow(CT, CanSubExprsThrow(C, this));
|
|
|
|
}
|
|
|
|
|
2010-09-11 04:55:47 +08:00
|
|
|
case CXXConstructExprClass:
|
|
|
|
case CXXTemporaryObjectExprClass: {
|
2011-06-12 01:19:42 +08:00
|
|
|
CanThrowResult CT = CanCalleeThrow(C, this,
|
2010-09-11 04:55:33 +08:00
|
|
|
cast<CXXConstructExpr>(this)->getConstructor());
|
|
|
|
if (CT == CT_Can)
|
|
|
|
return CT;
|
|
|
|
return MergeCanThrow(CT, CanSubExprsThrow(C, this));
|
|
|
|
}
|
|
|
|
|
|
|
|
case CXXNewExprClass: {
|
2011-05-11 13:22:44 +08:00
|
|
|
CanThrowResult CT;
|
|
|
|
if (isTypeDependent())
|
|
|
|
CT = CT_Dependent;
|
|
|
|
else
|
|
|
|
CT = MergeCanThrow(
|
2011-06-12 01:19:42 +08:00
|
|
|
CanCalleeThrow(C, this, cast<CXXNewExpr>(this)->getOperatorNew()),
|
|
|
|
CanCalleeThrow(C, this, cast<CXXNewExpr>(this)->getConstructor(),
|
2010-09-11 04:55:33 +08:00
|
|
|
/*NullThrows*/false));
|
|
|
|
if (CT == CT_Can)
|
|
|
|
return CT;
|
|
|
|
return MergeCanThrow(CT, CanSubExprsThrow(C, this));
|
|
|
|
}
|
|
|
|
|
|
|
|
case CXXDeleteExprClass: {
|
2011-05-11 13:22:44 +08:00
|
|
|
CanThrowResult CT;
|
|
|
|
QualType DTy = cast<CXXDeleteExpr>(this)->getDestroyedType();
|
|
|
|
if (DTy.isNull() || DTy->isDependentType()) {
|
|
|
|
CT = CT_Dependent;
|
|
|
|
} else {
|
2011-06-12 01:19:42 +08:00
|
|
|
CT = CanCalleeThrow(C, this,
|
|
|
|
cast<CXXDeleteExpr>(this)->getOperatorDelete());
|
2011-05-11 13:22:44 +08:00
|
|
|
if (const RecordType *RT = DTy->getAs<RecordType>()) {
|
|
|
|
const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
|
2011-06-12 01:19:42 +08:00
|
|
|
CT = MergeCanThrow(CT, CanCalleeThrow(C, this, RD->getDestructor()));
|
2010-09-11 07:27:10 +08:00
|
|
|
}
|
2011-05-11 13:22:44 +08:00
|
|
|
if (CT == CT_Can)
|
|
|
|
return CT;
|
2010-09-11 07:27:10 +08:00
|
|
|
}
|
|
|
|
return MergeCanThrow(CT, CanSubExprsThrow(C, this));
|
|
|
|
}
|
|
|
|
|
|
|
|
case CXXBindTemporaryExprClass: {
|
|
|
|
// The bound temporary has to be destroyed again, which might throw.
|
2011-06-12 01:19:42 +08:00
|
|
|
CanThrowResult CT = CanCalleeThrow(C, this,
|
2010-09-11 07:27:10 +08:00
|
|
|
cast<CXXBindTemporaryExpr>(this)->getTemporary()->getDestructor());
|
|
|
|
if (CT == CT_Can)
|
|
|
|
return CT;
|
2010-09-11 04:55:33 +08:00
|
|
|
return MergeCanThrow(CT, CanSubExprsThrow(C, this));
|
|
|
|
}
|
|
|
|
|
|
|
|
// ObjC message sends are like function calls, but never have exception
|
|
|
|
// specs.
|
|
|
|
case ObjCMessageExprClass:
|
|
|
|
case ObjCPropertyRefExprClass:
|
|
|
|
return CT_Can;
|
|
|
|
|
|
|
|
// Many other things have subexpressions, so we have to test those.
|
|
|
|
// Some are simple:
|
|
|
|
case ParenExprClass:
|
|
|
|
case MemberExprClass:
|
|
|
|
case CXXReinterpretCastExprClass:
|
|
|
|
case CXXConstCastExprClass:
|
|
|
|
case ConditionalOperatorClass:
|
|
|
|
case CompoundLiteralExprClass:
|
|
|
|
case ExtVectorElementExprClass:
|
|
|
|
case InitListExprClass:
|
|
|
|
case DesignatedInitExprClass:
|
|
|
|
case ParenListExprClass:
|
|
|
|
case VAArgExprClass:
|
|
|
|
case CXXDefaultArgExprClass:
|
2010-12-06 16:20:24 +08:00
|
|
|
case ExprWithCleanupsClass:
|
2010-09-11 04:55:33 +08:00
|
|
|
case ObjCIvarRefExprClass:
|
|
|
|
case ObjCIsaExprClass:
|
|
|
|
case ShuffleVectorExprClass:
|
|
|
|
return CanSubExprsThrow(C, this);
|
|
|
|
|
|
|
|
// Some might be dependent for other reasons.
|
|
|
|
case UnaryOperatorClass:
|
|
|
|
case ArraySubscriptExprClass:
|
|
|
|
case ImplicitCastExprClass:
|
|
|
|
case CStyleCastExprClass:
|
|
|
|
case CXXStaticCastExprClass:
|
|
|
|
case CXXFunctionalCastExprClass:
|
|
|
|
case BinaryOperatorClass:
|
2011-06-22 01:03:29 +08:00
|
|
|
case CompoundAssignOperatorClass:
|
|
|
|
case MaterializeTemporaryExprClass: {
|
2010-09-11 04:55:33 +08:00
|
|
|
CanThrowResult CT = isTypeDependent() ? CT_Dependent : CT_Cannot;
|
|
|
|
return MergeCanThrow(CT, CanSubExprsThrow(C, this));
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: We should handle StmtExpr, but that opens a MASSIVE can of worms.
|
|
|
|
case StmtExprClass:
|
|
|
|
return CT_Can;
|
|
|
|
|
|
|
|
case ChooseExprClass:
|
|
|
|
if (isTypeDependent() || isValueDependent())
|
|
|
|
return CT_Dependent;
|
|
|
|
return cast<ChooseExpr>(this)->getChosenSubExpr(C)->CanThrow(C);
|
|
|
|
|
2011-04-15 08:35:48 +08:00
|
|
|
case GenericSelectionExprClass:
|
|
|
|
if (cast<GenericSelectionExpr>(this)->isResultDependent())
|
|
|
|
return CT_Dependent;
|
|
|
|
return cast<GenericSelectionExpr>(this)->getResultExpr()->CanThrow(C);
|
|
|
|
|
2010-09-11 04:55:33 +08:00
|
|
|
// Some expressions are always dependent.
|
|
|
|
case DependentScopeDeclRefExprClass:
|
|
|
|
case CXXUnresolvedConstructExprClass:
|
|
|
|
case CXXDependentScopeMemberExprClass:
|
|
|
|
return CT_Dependent;
|
|
|
|
|
|
|
|
default:
|
|
|
|
// All other expressions don't have subexpressions, or else they are
|
|
|
|
// unevaluated.
|
|
|
|
return CT_Cannot;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-01-18 00:57:34 +08:00
|
|
|
Expr* Expr::IgnoreParens() {
|
|
|
|
Expr* E = this;
|
2010-10-15 15:51:18 +08:00
|
|
|
while (true) {
|
|
|
|
if (ParenExpr* P = dyn_cast<ParenExpr>(E)) {
|
|
|
|
E = P->getSubExpr();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (UnaryOperator* P = dyn_cast<UnaryOperator>(E)) {
|
|
|
|
if (P->getOpcode() == UO_Extension) {
|
|
|
|
E = P->getSubExpr();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2011-04-15 08:35:48 +08:00
|
|
|
if (GenericSelectionExpr* P = dyn_cast<GenericSelectionExpr>(E)) {
|
|
|
|
if (!P->isResultDependent()) {
|
|
|
|
E = P->getResultExpr();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2010-10-15 15:51:18 +08:00
|
|
|
return E;
|
|
|
|
}
|
2008-01-18 00:57:34 +08:00
|
|
|
}
|
|
|
|
|
2008-02-13 09:02:39 +08:00
|
|
|
/// IgnoreParenCasts - Ignore parentheses and casts. Strip off any ParenExpr
|
|
|
|
/// or CastExprs or ImplicitCastExprs, returning their operand.
|
|
|
|
Expr *Expr::IgnoreParenCasts() {
|
|
|
|
Expr *E = this;
|
|
|
|
while (true) {
|
2010-10-15 15:51:18 +08:00
|
|
|
if (ParenExpr* P = dyn_cast<ParenExpr>(E)) {
|
2008-02-13 09:02:39 +08:00
|
|
|
E = P->getSubExpr();
|
2010-10-15 15:51:18 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (CastExpr *P = dyn_cast<CastExpr>(E)) {
|
2008-02-13 09:02:39 +08:00
|
|
|
E = P->getSubExpr();
|
2010-10-15 15:51:18 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (UnaryOperator* P = dyn_cast<UnaryOperator>(E)) {
|
|
|
|
if (P->getOpcode() == UO_Extension) {
|
|
|
|
E = P->getSubExpr();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2011-04-15 08:35:48 +08:00
|
|
|
if (GenericSelectionExpr* P = dyn_cast<GenericSelectionExpr>(E)) {
|
|
|
|
if (!P->isResultDependent()) {
|
|
|
|
E = P->getResultExpr();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2011-06-22 01:03:29 +08:00
|
|
|
if (MaterializeTemporaryExpr *Materialize
|
|
|
|
= dyn_cast<MaterializeTemporaryExpr>(E)) {
|
|
|
|
E = Materialize->GetTemporaryExpr();
|
|
|
|
continue;
|
|
|
|
}
|
2011-09-09 01:56:33 +08:00
|
|
|
if (SubstNonTypeTemplateParmExpr *NTTP
|
|
|
|
= dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
|
|
|
|
E = NTTP->getReplacement();
|
|
|
|
continue;
|
|
|
|
}
|
2010-10-15 15:51:18 +08:00
|
|
|
return E;
|
2008-02-13 09:02:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-04 16:24:19 +08:00
|
|
|
/// IgnoreParenLValueCasts - Ignore parentheses and lvalue-to-rvalue
|
|
|
|
/// casts. This is intended purely as a temporary workaround for code
|
|
|
|
/// that hasn't yet been rewritten to do the right thing about those
|
|
|
|
/// casts, and may disappear along with the last internal use.
|
2010-12-04 11:47:34 +08:00
|
|
|
Expr *Expr::IgnoreParenLValueCasts() {
|
|
|
|
Expr *E = this;
|
2010-12-04 16:24:19 +08:00
|
|
|
while (true) {
|
2010-12-04 11:47:34 +08:00
|
|
|
if (ParenExpr *P = dyn_cast<ParenExpr>(E)) {
|
|
|
|
E = P->getSubExpr();
|
|
|
|
continue;
|
2010-12-04 16:24:19 +08:00
|
|
|
} else if (CastExpr *P = dyn_cast<CastExpr>(E)) {
|
2010-12-04 11:47:34 +08:00
|
|
|
if (P->getCastKind() == CK_LValueToRValue) {
|
|
|
|
E = P->getSubExpr();
|
|
|
|
continue;
|
|
|
|
}
|
2010-12-04 16:24:19 +08:00
|
|
|
} else if (UnaryOperator* P = dyn_cast<UnaryOperator>(E)) {
|
|
|
|
if (P->getOpcode() == UO_Extension) {
|
|
|
|
E = P->getSubExpr();
|
|
|
|
continue;
|
|
|
|
}
|
2011-04-15 08:35:48 +08:00
|
|
|
} else if (GenericSelectionExpr* P = dyn_cast<GenericSelectionExpr>(E)) {
|
|
|
|
if (!P->isResultDependent()) {
|
|
|
|
E = P->getResultExpr();
|
|
|
|
continue;
|
|
|
|
}
|
2011-06-22 01:03:29 +08:00
|
|
|
} else if (MaterializeTemporaryExpr *Materialize
|
|
|
|
= dyn_cast<MaterializeTemporaryExpr>(E)) {
|
|
|
|
E = Materialize->GetTemporaryExpr();
|
|
|
|
continue;
|
2011-09-09 01:56:33 +08:00
|
|
|
} else if (SubstNonTypeTemplateParmExpr *NTTP
|
|
|
|
= dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
|
|
|
|
E = NTTP->getReplacement();
|
|
|
|
continue;
|
2010-12-04 11:47:34 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return E;
|
|
|
|
}
|
|
|
|
|
2010-05-06 06:59:52 +08:00
|
|
|
Expr *Expr::IgnoreParenImpCasts() {
|
|
|
|
Expr *E = this;
|
|
|
|
while (true) {
|
2010-10-15 15:51:18 +08:00
|
|
|
if (ParenExpr *P = dyn_cast<ParenExpr>(E)) {
|
2010-05-06 06:59:52 +08:00
|
|
|
E = P->getSubExpr();
|
2010-10-15 15:51:18 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (ImplicitCastExpr *P = dyn_cast<ImplicitCastExpr>(E)) {
|
2010-05-06 06:59:52 +08:00
|
|
|
E = P->getSubExpr();
|
2010-10-15 15:51:18 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (UnaryOperator* P = dyn_cast<UnaryOperator>(E)) {
|
|
|
|
if (P->getOpcode() == UO_Extension) {
|
|
|
|
E = P->getSubExpr();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2011-04-15 08:35:48 +08:00
|
|
|
if (GenericSelectionExpr* P = dyn_cast<GenericSelectionExpr>(E)) {
|
|
|
|
if (!P->isResultDependent()) {
|
|
|
|
E = P->getResultExpr();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2011-06-22 01:03:29 +08:00
|
|
|
if (MaterializeTemporaryExpr *Materialize
|
|
|
|
= dyn_cast<MaterializeTemporaryExpr>(E)) {
|
|
|
|
E = Materialize->GetTemporaryExpr();
|
|
|
|
continue;
|
|
|
|
}
|
2011-09-09 01:56:33 +08:00
|
|
|
if (SubstNonTypeTemplateParmExpr *NTTP
|
|
|
|
= dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
|
|
|
|
E = NTTP->getReplacement();
|
|
|
|
continue;
|
|
|
|
}
|
2010-10-15 15:51:18 +08:00
|
|
|
return E;
|
2010-05-06 06:59:52 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-10 01:06:51 +08:00
|
|
|
Expr *Expr::IgnoreConversionOperator() {
|
|
|
|
if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(this)) {
|
2011-06-22 01:22:09 +08:00
|
|
|
if (MCE->getMethodDecl() && isa<CXXConversionDecl>(MCE->getMethodDecl()))
|
2011-06-10 01:06:51 +08:00
|
|
|
return MCE->getImplicitObjectArgument();
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2009-03-14 01:28:01 +08:00
|
|
|
/// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
|
|
|
|
/// value (including ptr->int casts of the same size). Strip off any
|
|
|
|
/// ParenExpr or CastExprs, returning their operand.
|
|
|
|
Expr *Expr::IgnoreParenNoopCasts(ASTContext &Ctx) {
|
|
|
|
Expr *E = this;
|
|
|
|
while (true) {
|
|
|
|
if (ParenExpr *P = dyn_cast<ParenExpr>(E)) {
|
|
|
|
E = P->getSubExpr();
|
|
|
|
continue;
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-03-14 01:28:01 +08:00
|
|
|
if (CastExpr *P = dyn_cast<CastExpr>(E)) {
|
|
|
|
// We ignore integer <-> casts that are of the same width, ptr<->ptr and
|
2010-06-16 08:17:44 +08:00
|
|
|
// ptr<->int casts of the same width. We also ignore all identity casts.
|
2009-03-14 01:28:01 +08:00
|
|
|
Expr *SE = P->getSubExpr();
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-03-14 01:28:01 +08:00
|
|
|
if (Ctx.hasSameUnqualifiedType(E->getType(), SE->getType())) {
|
|
|
|
E = SE;
|
|
|
|
continue;
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-10-15 15:51:18 +08:00
|
|
|
if ((E->getType()->isPointerType() ||
|
2010-06-16 08:35:25 +08:00
|
|
|
E->getType()->isIntegralType(Ctx)) &&
|
2010-10-15 15:51:18 +08:00
|
|
|
(SE->getType()->isPointerType() ||
|
2010-06-16 08:35:25 +08:00
|
|
|
SE->getType()->isIntegralType(Ctx)) &&
|
2009-03-14 01:28:01 +08:00
|
|
|
Ctx.getTypeSize(E->getType()) == Ctx.getTypeSize(SE->getType())) {
|
|
|
|
E = SE;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-10-15 15:51:18 +08:00
|
|
|
if (UnaryOperator* P = dyn_cast<UnaryOperator>(E)) {
|
|
|
|
if (P->getOpcode() == UO_Extension) {
|
|
|
|
E = P->getSubExpr();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-15 08:35:48 +08:00
|
|
|
if (GenericSelectionExpr* P = dyn_cast<GenericSelectionExpr>(E)) {
|
|
|
|
if (!P->isResultDependent()) {
|
|
|
|
E = P->getResultExpr();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-09 01:56:33 +08:00
|
|
|
if (SubstNonTypeTemplateParmExpr *NTTP
|
|
|
|
= dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
|
|
|
|
E = NTTP->getReplacement();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2009-03-14 01:28:01 +08:00
|
|
|
return E;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-15 03:27:10 +08:00
|
|
|
bool Expr::isDefaultArgument() const {
|
|
|
|
const Expr *E = this;
|
2011-06-22 01:03:29 +08:00
|
|
|
if (const MaterializeTemporaryExpr *M = dyn_cast<MaterializeTemporaryExpr>(E))
|
|
|
|
E = M->GetTemporaryExpr();
|
|
|
|
|
2009-12-15 03:27:10 +08:00
|
|
|
while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
|
|
|
|
E = ICE->getSubExprAsWritten();
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2009-12-15 03:27:10 +08:00
|
|
|
return isa<CXXDefaultArgExpr>(E);
|
|
|
|
}
|
2009-03-14 01:28:01 +08:00
|
|
|
|
Rework our handling of copy construction of temporaries, which was a
poor (and wrong) approximation of the actual rules governing when to
build a copy and when it can be elided.
The correct implementation is actually simpler than the
approximation. When we only enumerate constructors as part of
initialization (e.g., for direct initialization or when we're copying
from a class type or one of its derived classes), we don't create a
copy. When we enumerate all conversion functions, we do create a
copy. Before, we created some extra copies and missed some
others. The new test copy-initialization.cpp shows a case where we
missed creating a (required, non-elidable) copy as part of a
user-defined conversion, which resulted in a miscompile. This commit
also fixes PR6757, where the missing copy made us reject well-formed
code in the ternary operator.
This commit also cleans up our handling of copy elision in the case
where we create an extra copy of a temporary object, which became
necessary now that we produce the right copies. The code that seeks to
find the temporary object being copied has moved into
Expr::getTemporaryObject(); it used to have two different
not-quite-the-same implementations, one in Sema and one in CodeGen.
Note that we still do not attempt to perform the named return value
optimization, so we miss copy elisions for return values and throw
expressions.
llvm-svn: 100196
2010-04-03 02:24:57 +08:00
|
|
|
/// \brief Skip over any no-op casts and any temporary-binding
|
|
|
|
/// expressions.
|
2010-11-29 00:40:49 +08:00
|
|
|
static const Expr *skipTemporaryBindingsNoOpCastsAndParens(const Expr *E) {
|
2011-06-22 01:03:29 +08:00
|
|
|
if (const MaterializeTemporaryExpr *M = dyn_cast<MaterializeTemporaryExpr>(E))
|
|
|
|
E = M->GetTemporaryExpr();
|
|
|
|
|
Rework our handling of copy construction of temporaries, which was a
poor (and wrong) approximation of the actual rules governing when to
build a copy and when it can be elided.
The correct implementation is actually simpler than the
approximation. When we only enumerate constructors as part of
initialization (e.g., for direct initialization or when we're copying
from a class type or one of its derived classes), we don't create a
copy. When we enumerate all conversion functions, we do create a
copy. Before, we created some extra copies and missed some
others. The new test copy-initialization.cpp shows a case where we
missed creating a (required, non-elidable) copy as part of a
user-defined conversion, which resulted in a miscompile. This commit
also fixes PR6757, where the missing copy made us reject well-formed
code in the ternary operator.
This commit also cleans up our handling of copy elision in the case
where we create an extra copy of a temporary object, which became
necessary now that we produce the right copies. The code that seeks to
find the temporary object being copied has moved into
Expr::getTemporaryObject(); it used to have two different
not-quite-the-same implementations, one in Sema and one in CodeGen.
Note that we still do not attempt to perform the named return value
optimization, so we miss copy elisions for return values and throw
expressions.
llvm-svn: 100196
2010-04-03 02:24:57 +08:00
|
|
|
while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
|
2010-08-25 19:45:40 +08:00
|
|
|
if (ICE->getCastKind() == CK_NoOp)
|
Rework our handling of copy construction of temporaries, which was a
poor (and wrong) approximation of the actual rules governing when to
build a copy and when it can be elided.
The correct implementation is actually simpler than the
approximation. When we only enumerate constructors as part of
initialization (e.g., for direct initialization or when we're copying
from a class type or one of its derived classes), we don't create a
copy. When we enumerate all conversion functions, we do create a
copy. Before, we created some extra copies and missed some
others. The new test copy-initialization.cpp shows a case where we
missed creating a (required, non-elidable) copy as part of a
user-defined conversion, which resulted in a miscompile. This commit
also fixes PR6757, where the missing copy made us reject well-formed
code in the ternary operator.
This commit also cleans up our handling of copy elision in the case
where we create an extra copy of a temporary object, which became
necessary now that we produce the right copies. The code that seeks to
find the temporary object being copied has moved into
Expr::getTemporaryObject(); it used to have two different
not-quite-the-same implementations, one in Sema and one in CodeGen.
Note that we still do not attempt to perform the named return value
optimization, so we miss copy elisions for return values and throw
expressions.
llvm-svn: 100196
2010-04-03 02:24:57 +08:00
|
|
|
E = ICE->getSubExpr();
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (const CXXBindTemporaryExpr *BE = dyn_cast<CXXBindTemporaryExpr>(E))
|
|
|
|
E = BE->getSubExpr();
|
|
|
|
|
|
|
|
while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
|
2010-08-25 19:45:40 +08:00
|
|
|
if (ICE->getCastKind() == CK_NoOp)
|
Rework our handling of copy construction of temporaries, which was a
poor (and wrong) approximation of the actual rules governing when to
build a copy and when it can be elided.
The correct implementation is actually simpler than the
approximation. When we only enumerate constructors as part of
initialization (e.g., for direct initialization or when we're copying
from a class type or one of its derived classes), we don't create a
copy. When we enumerate all conversion functions, we do create a
copy. Before, we created some extra copies and missed some
others. The new test copy-initialization.cpp shows a case where we
missed creating a (required, non-elidable) copy as part of a
user-defined conversion, which resulted in a miscompile. This commit
also fixes PR6757, where the missing copy made us reject well-formed
code in the ternary operator.
This commit also cleans up our handling of copy elision in the case
where we create an extra copy of a temporary object, which became
necessary now that we produce the right copies. The code that seeks to
find the temporary object being copied has moved into
Expr::getTemporaryObject(); it used to have two different
not-quite-the-same implementations, one in Sema and one in CodeGen.
Note that we still do not attempt to perform the named return value
optimization, so we miss copy elisions for return values and throw
expressions.
llvm-svn: 100196
2010-04-03 02:24:57 +08:00
|
|
|
E = ICE->getSubExpr();
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
2010-11-29 00:40:49 +08:00
|
|
|
|
|
|
|
return E->IgnoreParens();
|
Rework our handling of copy construction of temporaries, which was a
poor (and wrong) approximation of the actual rules governing when to
build a copy and when it can be elided.
The correct implementation is actually simpler than the
approximation. When we only enumerate constructors as part of
initialization (e.g., for direct initialization or when we're copying
from a class type or one of its derived classes), we don't create a
copy. When we enumerate all conversion functions, we do create a
copy. Before, we created some extra copies and missed some
others. The new test copy-initialization.cpp shows a case where we
missed creating a (required, non-elidable) copy as part of a
user-defined conversion, which resulted in a miscompile. This commit
also fixes PR6757, where the missing copy made us reject well-formed
code in the ternary operator.
This commit also cleans up our handling of copy elision in the case
where we create an extra copy of a temporary object, which became
necessary now that we produce the right copies. The code that seeks to
find the temporary object being copied has moved into
Expr::getTemporaryObject(); it used to have two different
not-quite-the-same implementations, one in Sema and one in CodeGen.
Note that we still do not attempt to perform the named return value
optimization, so we miss copy elisions for return values and throw
expressions.
llvm-svn: 100196
2010-04-03 02:24:57 +08:00
|
|
|
}
|
|
|
|
|
2010-09-15 18:14:12 +08:00
|
|
|
/// isTemporaryObject - Determines if this expression produces a
|
|
|
|
/// temporary of the given class type.
|
|
|
|
bool Expr::isTemporaryObject(ASTContext &C, const CXXRecordDecl *TempTy) const {
|
|
|
|
if (!C.hasSameUnqualifiedType(getType(), C.getTypeDeclType(TempTy)))
|
|
|
|
return false;
|
Rework our handling of copy construction of temporaries, which was a
poor (and wrong) approximation of the actual rules governing when to
build a copy and when it can be elided.
The correct implementation is actually simpler than the
approximation. When we only enumerate constructors as part of
initialization (e.g., for direct initialization or when we're copying
from a class type or one of its derived classes), we don't create a
copy. When we enumerate all conversion functions, we do create a
copy. Before, we created some extra copies and missed some
others. The new test copy-initialization.cpp shows a case where we
missed creating a (required, non-elidable) copy as part of a
user-defined conversion, which resulted in a miscompile. This commit
also fixes PR6757, where the missing copy made us reject well-formed
code in the ternary operator.
This commit also cleans up our handling of copy elision in the case
where we create an extra copy of a temporary object, which became
necessary now that we produce the right copies. The code that seeks to
find the temporary object being copied has moved into
Expr::getTemporaryObject(); it used to have two different
not-quite-the-same implementations, one in Sema and one in CodeGen.
Note that we still do not attempt to perform the named return value
optimization, so we miss copy elisions for return values and throw
expressions.
llvm-svn: 100196
2010-04-03 02:24:57 +08:00
|
|
|
|
2010-11-29 00:40:49 +08:00
|
|
|
const Expr *E = skipTemporaryBindingsNoOpCastsAndParens(this);
|
Rework our handling of copy construction of temporaries, which was a
poor (and wrong) approximation of the actual rules governing when to
build a copy and when it can be elided.
The correct implementation is actually simpler than the
approximation. When we only enumerate constructors as part of
initialization (e.g., for direct initialization or when we're copying
from a class type or one of its derived classes), we don't create a
copy. When we enumerate all conversion functions, we do create a
copy. Before, we created some extra copies and missed some
others. The new test copy-initialization.cpp shows a case where we
missed creating a (required, non-elidable) copy as part of a
user-defined conversion, which resulted in a miscompile. This commit
also fixes PR6757, where the missing copy made us reject well-formed
code in the ternary operator.
This commit also cleans up our handling of copy elision in the case
where we create an extra copy of a temporary object, which became
necessary now that we produce the right copies. The code that seeks to
find the temporary object being copied has moved into
Expr::getTemporaryObject(); it used to have two different
not-quite-the-same implementations, one in Sema and one in CodeGen.
Note that we still do not attempt to perform the named return value
optimization, so we miss copy elisions for return values and throw
expressions.
llvm-svn: 100196
2010-04-03 02:24:57 +08:00
|
|
|
|
2010-09-16 04:59:13 +08:00
|
|
|
// Temporaries are by definition pr-values of class type.
|
2010-09-28 01:30:38 +08:00
|
|
|
if (!E->Classify(C).isPRValue()) {
|
|
|
|
// In this context, property reference is a message call and is pr-value.
|
2010-12-02 09:19:52 +08:00
|
|
|
if (!isa<ObjCPropertyRefExpr>(E))
|
2010-09-28 01:30:38 +08:00
|
|
|
return false;
|
|
|
|
}
|
Rework our handling of copy construction of temporaries, which was a
poor (and wrong) approximation of the actual rules governing when to
build a copy and when it can be elided.
The correct implementation is actually simpler than the
approximation. When we only enumerate constructors as part of
initialization (e.g., for direct initialization or when we're copying
from a class type or one of its derived classes), we don't create a
copy. When we enumerate all conversion functions, we do create a
copy. Before, we created some extra copies and missed some
others. The new test copy-initialization.cpp shows a case where we
missed creating a (required, non-elidable) copy as part of a
user-defined conversion, which resulted in a miscompile. This commit
also fixes PR6757, where the missing copy made us reject well-formed
code in the ternary operator.
This commit also cleans up our handling of copy elision in the case
where we create an extra copy of a temporary object, which became
necessary now that we produce the right copies. The code that seeks to
find the temporary object being copied has moved into
Expr::getTemporaryObject(); it used to have two different
not-quite-the-same implementations, one in Sema and one in CodeGen.
Note that we still do not attempt to perform the named return value
optimization, so we miss copy elisions for return values and throw
expressions.
llvm-svn: 100196
2010-04-03 02:24:57 +08:00
|
|
|
|
2010-09-16 14:57:56 +08:00
|
|
|
// Black-list a few cases which yield pr-values of class type that don't
|
|
|
|
// refer to temporaries of that type:
|
|
|
|
|
|
|
|
// - implicit derived-to-base conversions
|
2010-09-15 18:14:12 +08:00
|
|
|
if (isa<ImplicitCastExpr>(E)) {
|
|
|
|
switch (cast<ImplicitCastExpr>(E)->getCastKind()) {
|
|
|
|
case CK_DerivedToBase:
|
|
|
|
case CK_UncheckedDerivedToBase:
|
|
|
|
return false;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
Rework our handling of copy construction of temporaries, which was a
poor (and wrong) approximation of the actual rules governing when to
build a copy and when it can be elided.
The correct implementation is actually simpler than the
approximation. When we only enumerate constructors as part of
initialization (e.g., for direct initialization or when we're copying
from a class type or one of its derived classes), we don't create a
copy. When we enumerate all conversion functions, we do create a
copy. Before, we created some extra copies and missed some
others. The new test copy-initialization.cpp shows a case where we
missed creating a (required, non-elidable) copy as part of a
user-defined conversion, which resulted in a miscompile. This commit
also fixes PR6757, where the missing copy made us reject well-formed
code in the ternary operator.
This commit also cleans up our handling of copy elision in the case
where we create an extra copy of a temporary object, which became
necessary now that we produce the right copies. The code that seeks to
find the temporary object being copied has moved into
Expr::getTemporaryObject(); it used to have two different
not-quite-the-same implementations, one in Sema and one in CodeGen.
Note that we still do not attempt to perform the named return value
optimization, so we miss copy elisions for return values and throw
expressions.
llvm-svn: 100196
2010-04-03 02:24:57 +08:00
|
|
|
}
|
|
|
|
|
2010-09-16 14:57:56 +08:00
|
|
|
// - member expressions (all)
|
|
|
|
if (isa<MemberExpr>(E))
|
|
|
|
return false;
|
|
|
|
|
2011-02-17 18:25:35 +08:00
|
|
|
// - opaque values (all)
|
|
|
|
if (isa<OpaqueValueExpr>(E))
|
|
|
|
return false;
|
|
|
|
|
2010-09-15 18:14:12 +08:00
|
|
|
return true;
|
Rework our handling of copy construction of temporaries, which was a
poor (and wrong) approximation of the actual rules governing when to
build a copy and when it can be elided.
The correct implementation is actually simpler than the
approximation. When we only enumerate constructors as part of
initialization (e.g., for direct initialization or when we're copying
from a class type or one of its derived classes), we don't create a
copy. When we enumerate all conversion functions, we do create a
copy. Before, we created some extra copies and missed some
others. The new test copy-initialization.cpp shows a case where we
missed creating a (required, non-elidable) copy as part of a
user-defined conversion, which resulted in a miscompile. This commit
also fixes PR6757, where the missing copy made us reject well-formed
code in the ternary operator.
This commit also cleans up our handling of copy elision in the case
where we create an extra copy of a temporary object, which became
necessary now that we produce the right copies. The code that seeks to
find the temporary object being copied has moved into
Expr::getTemporaryObject(); it used to have two different
not-quite-the-same implementations, one in Sema and one in CodeGen.
Note that we still do not attempt to perform the named return value
optimization, so we miss copy elisions for return values and throw
expressions.
llvm-svn: 100196
2010-04-03 02:24:57 +08:00
|
|
|
}
|
|
|
|
|
2011-03-03 05:06:53 +08:00
|
|
|
bool Expr::isImplicitCXXThis() const {
|
|
|
|
const Expr *E = this;
|
|
|
|
|
|
|
|
// Strip away parentheses and casts we don't care about.
|
|
|
|
while (true) {
|
|
|
|
if (const ParenExpr *Paren = dyn_cast<ParenExpr>(E)) {
|
|
|
|
E = Paren->getSubExpr();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
|
|
|
|
if (ICE->getCastKind() == CK_NoOp ||
|
|
|
|
ICE->getCastKind() == CK_LValueToRValue ||
|
|
|
|
ICE->getCastKind() == CK_DerivedToBase ||
|
|
|
|
ICE->getCastKind() == CK_UncheckedDerivedToBase) {
|
|
|
|
E = ICE->getSubExpr();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const UnaryOperator* UnOp = dyn_cast<UnaryOperator>(E)) {
|
|
|
|
if (UnOp->getOpcode() == UO_Extension) {
|
|
|
|
E = UnOp->getSubExpr();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-22 01:03:29 +08:00
|
|
|
if (const MaterializeTemporaryExpr *M
|
|
|
|
= dyn_cast<MaterializeTemporaryExpr>(E)) {
|
|
|
|
E = M->GetTemporaryExpr();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2011-03-03 05:06:53 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const CXXThisExpr *This = dyn_cast<CXXThisExpr>(E))
|
|
|
|
return This->isImplicit();
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2008-12-06 07:32:09 +08:00
|
|
|
/// hasAnyTypeDependentArguments - Determines if any of the expressions
|
|
|
|
/// in Exprs is type-dependent.
|
|
|
|
bool Expr::hasAnyTypeDependentArguments(Expr** Exprs, unsigned NumExprs) {
|
|
|
|
for (unsigned I = 0; I < NumExprs; ++I)
|
|
|
|
if (Exprs[I]->isTypeDependent())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// hasAnyValueDependentArguments - Determines if any of the expressions
|
|
|
|
/// in Exprs is value-dependent.
|
|
|
|
bool Expr::hasAnyValueDependentArguments(Expr** Exprs, unsigned NumExprs) {
|
|
|
|
for (unsigned I = 0; I < NumExprs; ++I)
|
|
|
|
if (Exprs[I]->isValueDependent())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-08-03 05:13:48 +08:00
|
|
|
bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef) const {
|
2009-01-25 11:12:18 +08:00
|
|
|
// This function is attempting whether an expression is an initializer
|
|
|
|
// which can be evaluated at compile-time. isEvaluatable handles most
|
|
|
|
// of the cases, but it can't deal with some initializer-specific
|
|
|
|
// expressions, and it can't deal with aggregates; we deal with those here,
|
|
|
|
// and fall back to isEvaluatable for the other cases.
|
|
|
|
|
2010-08-03 05:13:48 +08:00
|
|
|
// If we ever capture reference-binding directly in the AST, we can
|
|
|
|
// kill the second parameter.
|
|
|
|
|
|
|
|
if (IsForRef) {
|
|
|
|
EvalResult Result;
|
|
|
|
return EvaluateAsLValue(Result, Ctx) && !Result.HasSideEffects;
|
|
|
|
}
|
2009-02-20 10:36:22 +08:00
|
|
|
|
2008-11-24 13:23:59 +08:00
|
|
|
switch (getStmtClass()) {
|
2009-01-25 11:12:18 +08:00
|
|
|
default: break;
|
2008-11-24 13:23:59 +08:00
|
|
|
case StringLiteralClass:
|
2009-07-11 07:34:53 +08:00
|
|
|
case ObjCStringLiteralClass:
|
2009-02-25 06:18:39 +08:00
|
|
|
case ObjCEncodeExprClass:
|
2008-11-24 13:23:59 +08:00
|
|
|
return true;
|
2010-08-02 05:51:45 +08:00
|
|
|
case CXXTemporaryObjectExprClass:
|
|
|
|
case CXXConstructExprClass: {
|
|
|
|
const CXXConstructExpr *CE = cast<CXXConstructExpr>(this);
|
2010-08-03 05:13:48 +08:00
|
|
|
|
|
|
|
// Only if it's
|
|
|
|
// 1) an application of the trivial default constructor or
|
2010-08-02 05:51:45 +08:00
|
|
|
if (!CE->getConstructor()->isTrivial()) return false;
|
2010-08-03 05:13:48 +08:00
|
|
|
if (!CE->getNumArgs()) return true;
|
|
|
|
|
|
|
|
// 2) an elidable trivial copy construction of an operand which is
|
|
|
|
// itself a constant initializer. Note that we consider the
|
|
|
|
// operand on its own, *not* as a reference binding.
|
|
|
|
return CE->isElidable() &&
|
|
|
|
CE->getArg(0)->isConstantInitializer(Ctx, false);
|
2010-08-02 05:51:45 +08:00
|
|
|
}
|
2009-01-18 11:20:47 +08:00
|
|
|
case CompoundLiteralExprClass: {
|
2009-02-20 10:36:22 +08:00
|
|
|
// This handles gcc's extension that allows global initializers like
|
|
|
|
// "struct x {int x;} x = (struct x) {};".
|
|
|
|
// FIXME: This accepts other cases it shouldn't!
|
2009-01-18 11:20:47 +08:00
|
|
|
const Expr *Exp = cast<CompoundLiteralExpr>(this)->getInitializer();
|
2010-08-03 05:13:48 +08:00
|
|
|
return Exp->isConstantInitializer(Ctx, false);
|
2009-01-18 11:20:47 +08:00
|
|
|
}
|
2008-11-24 13:23:59 +08:00
|
|
|
case InitListExprClass: {
|
2009-02-20 10:36:22 +08:00
|
|
|
// FIXME: This doesn't deal with fields with reference types correctly.
|
|
|
|
// FIXME: This incorrectly allows pointers cast to integers to be assigned
|
|
|
|
// to bitfields.
|
2008-11-24 13:23:59 +08:00
|
|
|
const InitListExpr *Exp = cast<InitListExpr>(this);
|
|
|
|
unsigned numInits = Exp->getNumInits();
|
|
|
|
for (unsigned i = 0; i < numInits; i++) {
|
2010-08-03 05:13:48 +08:00
|
|
|
if (!Exp->getInit(i)->isConstantInitializer(Ctx, false))
|
2008-11-24 13:23:59 +08:00
|
|
|
return false;
|
|
|
|
}
|
2009-01-25 11:12:18 +08:00
|
|
|
return true;
|
2008-11-24 13:23:59 +08:00
|
|
|
}
|
2009-01-30 01:44:32 +08:00
|
|
|
case ImplicitValueInitExprClass:
|
|
|
|
return true;
|
2009-10-13 15:14:16 +08:00
|
|
|
case ParenExprClass:
|
2010-08-03 05:13:48 +08:00
|
|
|
return cast<ParenExpr>(this)->getSubExpr()
|
|
|
|
->isConstantInitializer(Ctx, IsForRef);
|
2011-04-15 08:35:48 +08:00
|
|
|
case GenericSelectionExprClass:
|
|
|
|
if (cast<GenericSelectionExpr>(this)->isResultDependent())
|
|
|
|
return false;
|
|
|
|
return cast<GenericSelectionExpr>(this)->getResultExpr()
|
|
|
|
->isConstantInitializer(Ctx, IsForRef);
|
2010-09-27 15:13:32 +08:00
|
|
|
case ChooseExprClass:
|
|
|
|
return cast<ChooseExpr>(this)->getChosenSubExpr(Ctx)
|
|
|
|
->isConstantInitializer(Ctx, IsForRef);
|
2009-01-25 11:12:18 +08:00
|
|
|
case UnaryOperatorClass: {
|
|
|
|
const UnaryOperator* Exp = cast<UnaryOperator>(this);
|
2010-08-25 19:45:40 +08:00
|
|
|
if (Exp->getOpcode() == UO_Extension)
|
2010-08-03 05:13:48 +08:00
|
|
|
return Exp->getSubExpr()->isConstantInitializer(Ctx, false);
|
2009-01-25 11:12:18 +08:00
|
|
|
break;
|
|
|
|
}
|
2009-10-13 15:14:16 +08:00
|
|
|
case BinaryOperatorClass: {
|
|
|
|
// Special case &&foo - &&bar. It would be nice to generalize this somehow
|
|
|
|
// but this handles the common case.
|
|
|
|
const BinaryOperator *Exp = cast<BinaryOperator>(this);
|
2010-08-25 19:45:40 +08:00
|
|
|
if (Exp->getOpcode() == BO_Sub &&
|
2009-10-13 15:14:16 +08:00
|
|
|
isa<AddrLabelExpr>(Exp->getLHS()->IgnoreParenNoopCasts(Ctx)) &&
|
|
|
|
isa<AddrLabelExpr>(Exp->getRHS()->IgnoreParenNoopCasts(Ctx)))
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
}
|
2010-08-03 05:13:48 +08:00
|
|
|
case CXXFunctionalCastExprClass:
|
2010-08-02 05:51:45 +08:00
|
|
|
case CXXStaticCastExprClass:
|
2009-04-21 13:19:11 +08:00
|
|
|
case ImplicitCastExprClass:
|
2009-01-25 11:12:18 +08:00
|
|
|
case CStyleCastExprClass:
|
|
|
|
// Handle casts with a destination that's a struct or union; this
|
|
|
|
// deals with both the gcc no-op struct cast extension and the
|
|
|
|
// cast-to-union extension.
|
|
|
|
if (getType()->isRecordType())
|
2010-08-03 05:13:48 +08:00
|
|
|
return cast<CastExpr>(this)->getSubExpr()
|
|
|
|
->isConstantInitializer(Ctx, false);
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2009-10-14 06:12:09 +08:00
|
|
|
// Integer->integer casts can be handled here, which is important for
|
|
|
|
// things like (int)(&&x-&&y). Scary but true.
|
|
|
|
if (getType()->isIntegerType() &&
|
|
|
|
cast<CastExpr>(this)->getSubExpr()->getType()->isIntegerType())
|
2010-08-03 05:13:48 +08:00
|
|
|
return cast<CastExpr>(this)->getSubExpr()
|
|
|
|
->isConstantInitializer(Ctx, false);
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2009-01-25 11:12:18 +08:00
|
|
|
break;
|
2011-06-22 01:03:29 +08:00
|
|
|
|
|
|
|
case MaterializeTemporaryExprClass:
|
2011-07-23 18:55:15 +08:00
|
|
|
return cast<MaterializeTemporaryExpr>(this)->GetTemporaryExpr()
|
2011-06-22 01:03:29 +08:00
|
|
|
->isConstantInitializer(Ctx, false);
|
2008-11-24 13:23:59 +08:00
|
|
|
}
|
2009-01-25 11:12:18 +08:00
|
|
|
return isEvaluatable(Ctx);
|
2007-09-03 04:30:18 +08:00
|
|
|
}
|
|
|
|
|
2011-02-19 07:54:50 +08:00
|
|
|
/// isNullPointerConstant - C99 6.3.2.3p3 - Return whether this is a null
|
|
|
|
/// pointer constant or not, as well as the specific kind of constant detected.
|
|
|
|
/// Null pointer constants can be integer constant expressions with the
|
|
|
|
/// value zero, casts of zero to void*, nullptr (C++0X), or __null
|
|
|
|
/// (a GNU extension).
|
|
|
|
Expr::NullPointerConstantKind
|
|
|
|
Expr::isNullPointerConstant(ASTContext &Ctx,
|
|
|
|
NullPointerConstantValueDependence NPC) const {
|
2009-09-25 12:25:58 +08:00
|
|
|
if (isValueDependent()) {
|
|
|
|
switch (NPC) {
|
|
|
|
case NPC_NeverValueDependent:
|
|
|
|
assert(false && "Unexpected value dependent expression!");
|
|
|
|
// If the unthinkable happens, fall through to the safest alternative.
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2009-09-25 12:25:58 +08:00
|
|
|
case NPC_ValueDependentIsNull:
|
2011-02-19 07:54:50 +08:00
|
|
|
if (isTypeDependent() || getType()->isIntegralType(Ctx))
|
|
|
|
return NPCK_ZeroInteger;
|
|
|
|
else
|
|
|
|
return NPCK_NotNull;
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2009-09-25 12:25:58 +08:00
|
|
|
case NPC_ValueDependentIsNotNull:
|
2011-02-19 07:54:50 +08:00
|
|
|
return NPCK_NotNull;
|
2009-09-25 12:25:58 +08:00
|
|
|
}
|
|
|
|
}
|
2009-09-18 16:46:16 +08:00
|
|
|
|
2008-10-31 22:43:28 +08:00
|
|
|
// Strip off a cast to void*, if it exists. Except in C++.
|
2008-08-19 07:01:59 +08:00
|
|
|
if (const ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(this)) {
|
2008-11-04 19:45:54 +08:00
|
|
|
if (!Ctx.getLangOptions().CPlusPlus) {
|
2008-10-31 22:43:28 +08:00
|
|
|
// Check that it is a cast to void*.
|
2009-07-30 05:53:49 +08:00
|
|
|
if (const PointerType *PT = CE->getType()->getAs<PointerType>()) {
|
2008-10-31 22:43:28 +08:00
|
|
|
QualType Pointee = PT->getPointeeType();
|
2009-09-25 03:53:00 +08:00
|
|
|
if (!Pointee.hasQualifiers() &&
|
2008-10-31 22:43:28 +08:00
|
|
|
Pointee->isVoidType() && // to void*
|
|
|
|
CE->getSubExpr()->getType()->isIntegerType()) // from int.
|
2009-09-25 12:25:58 +08:00
|
|
|
return CE->getSubExpr()->isNullPointerConstant(Ctx, NPC);
|
2008-10-31 22:43:28 +08:00
|
|
|
}
|
2007-05-21 01:54:12 +08:00
|
|
|
}
|
2008-01-15 00:10:57 +08:00
|
|
|
} else if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(this)) {
|
|
|
|
// Ignore the ImplicitCastExpr type entirely.
|
2009-09-25 12:25:58 +08:00
|
|
|
return ICE->getSubExpr()->isNullPointerConstant(Ctx, NPC);
|
2008-01-15 00:10:57 +08:00
|
|
|
} else if (const ParenExpr *PE = dyn_cast<ParenExpr>(this)) {
|
|
|
|
// Accept ((void*)0) as a null pointer constant, as many other
|
|
|
|
// implementations do.
|
2009-09-25 12:25:58 +08:00
|
|
|
return PE->getSubExpr()->isNullPointerConstant(Ctx, NPC);
|
2011-04-15 08:35:48 +08:00
|
|
|
} else if (const GenericSelectionExpr *GE =
|
|
|
|
dyn_cast<GenericSelectionExpr>(this)) {
|
|
|
|
return GE->getResultExpr()->isNullPointerConstant(Ctx, NPC);
|
2009-09-09 23:08:12 +08:00
|
|
|
} else if (const CXXDefaultArgExpr *DefaultArg
|
2008-04-10 10:22:51 +08:00
|
|
|
= dyn_cast<CXXDefaultArgExpr>(this)) {
|
2008-04-08 12:40:51 +08:00
|
|
|
// See through default argument expressions
|
2009-09-25 12:25:58 +08:00
|
|
|
return DefaultArg->getExpr()->isNullPointerConstant(Ctx, NPC);
|
2008-11-29 12:51:27 +08:00
|
|
|
} else if (isa<GNUNullExpr>(this)) {
|
|
|
|
// The GNU __null extension is always a null pointer constant.
|
2011-02-19 07:54:50 +08:00
|
|
|
return NPCK_GNUNull;
|
2011-06-22 01:03:29 +08:00
|
|
|
} else if (const MaterializeTemporaryExpr *M
|
|
|
|
= dyn_cast<MaterializeTemporaryExpr>(this)) {
|
|
|
|
return M->GetTemporaryExpr()->isNullPointerConstant(Ctx, NPC);
|
2008-01-14 10:53:34 +08:00
|
|
|
}
|
2008-11-29 12:51:27 +08:00
|
|
|
|
2009-05-11 02:38:11 +08:00
|
|
|
// C++0x nullptr_t is always a null pointer constant.
|
|
|
|
if (getType()->isNullPtrType())
|
2011-02-19 07:54:50 +08:00
|
|
|
return NPCK_CXX0X_nullptr;
|
2009-05-11 02:38:11 +08:00
|
|
|
|
2010-09-28 06:42:37 +08:00
|
|
|
if (const RecordType *UT = getType()->getAsUnionType())
|
|
|
|
if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>())
|
|
|
|
if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(this)){
|
|
|
|
const Expr *InitExpr = CLE->getInitializer();
|
|
|
|
if (const InitListExpr *ILE = dyn_cast<InitListExpr>(InitExpr))
|
|
|
|
return ILE->getInit(0)->isNullPointerConstant(Ctx, NPC);
|
|
|
|
}
|
2008-01-15 00:10:57 +08:00
|
|
|
// This expression must be an integer type.
|
2010-05-05 23:23:54 +08:00
|
|
|
if (!getType()->isIntegerType() ||
|
2009-10-06 08:09:31 +08:00
|
|
|
(Ctx.getLangOptions().CPlusPlus && getType()->isEnumeralType()))
|
2011-02-19 07:54:50 +08:00
|
|
|
return NPCK_NotNull;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2007-06-09 01:58:43 +08:00
|
|
|
// If we have an integer constant expression, we need to *evaluate* it and
|
|
|
|
// test for the value 0.
|
2009-04-26 06:37:12 +08:00
|
|
|
llvm::APSInt Result;
|
2011-02-19 07:54:50 +08:00
|
|
|
bool IsNull = isIntegerConstantExpr(Result, Ctx) && Result == 0;
|
|
|
|
|
|
|
|
return (IsNull ? NPCK_ZeroInteger : NPCK_NotNull);
|
Bug #:
Submitted by:
Reviewed by:
Implemented type checking for compound assignments (*=, /=, etc.).
This encouraged me to do a fairly dramatic refactoring of the Check* functions.
(since I wanted to reuse the existing work, rather than duplicate the logic).
For example, I changed all the Check* functions to return a QualType (instead
of returning an Expr). This had a very nice side benefit...there is now
only one instantiation point for BinaryOperator()! (A property I've always
wanted...separating type checking from AST building is *much* nicer). Another
change is to remove "code" from all the Check* functions (this allowed
me to remove the weird comment about enums/unsigned:-). Removing the
code forced me to add a few functions, however. For example,
< ExprResult CheckAdditiveOperands( // C99 6.5.6
< Expr *lex, Expr *rex, SourceLocation OpLoc, unsigned OpCode);
> inline QualType CheckAdditionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
> inline QualType CheckSubtractionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
While this isn't as terse, it more closely reflects the differences in
the typechecking logic. For example, I disliked having to check the code again
in CheckMultiplicativeOperands/CheckAdditiveOperands.
Created the following helper functions:
- Expr::isNullPointerConstant().
- SemaExpr.cpp: static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode().
This was purely asethetic, since ParseBinOp() is now larger. I didn't feel
like looking at 2 huge switch statements. ParseBinOp() now avoids using
any of the BinaryOperator predicates (since I switched to a switch statement:-)
Only one regret (minor). I couldn't figure out how to avoid having two assign functions,
CheckCompoundAssignmentOperands, CheckSimpleAssignmentOperands. Conceptually,
the two functions make sense. Unfortunately, their implementation contains a lot of
duplication (thought they aren't that be in the first place).
llvm-svn: 39433
2007-05-05 05:54:46 +08:00
|
|
|
}
|
2007-07-29 07:10:27 +08:00
|
|
|
|
2010-12-04 11:47:34 +08:00
|
|
|
/// \brief If this expression is an l-value for an Objective C
|
|
|
|
/// property, find the underlying property reference expression.
|
|
|
|
const ObjCPropertyRefExpr *Expr::getObjCProperty() const {
|
|
|
|
const Expr *E = this;
|
|
|
|
while (true) {
|
|
|
|
assert((E->getValueKind() == VK_LValue &&
|
|
|
|
E->getObjectKind() == OK_ObjCProperty) &&
|
|
|
|
"expression is not a property reference");
|
|
|
|
E = E->IgnoreParenCasts();
|
|
|
|
if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
|
|
|
|
if (BO->getOpcode() == BO_Comma) {
|
|
|
|
E = BO->getRHS();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cast<ObjCPropertyRefExpr>(E);
|
|
|
|
}
|
|
|
|
|
2009-05-02 10:18:30 +08:00
|
|
|
FieldDecl *Expr::getBitField() {
|
2009-07-06 23:38:40 +08:00
|
|
|
Expr *E = this->IgnoreParens();
|
2009-05-02 10:18:30 +08:00
|
|
|
|
2010-01-30 03:14:02 +08:00
|
|
|
while (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
|
2010-12-04 11:47:34 +08:00
|
|
|
if (ICE->getCastKind() == CK_LValueToRValue ||
|
|
|
|
(ICE->getValueKind() != VK_RValue && ICE->getCastKind() == CK_NoOp))
|
2010-01-30 03:14:02 +08:00
|
|
|
E = ICE->getSubExpr()->IgnoreParens();
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-10-29 08:13:59 +08:00
|
|
|
if (MemberExpr *MemRef = dyn_cast<MemberExpr>(E))
|
2008-12-21 07:49:58 +08:00
|
|
|
if (FieldDecl *Field = dyn_cast<FieldDecl>(MemRef->getMemberDecl()))
|
2009-05-02 10:18:30 +08:00
|
|
|
if (Field->isBitField())
|
|
|
|
return Field;
|
|
|
|
|
2010-10-31 03:52:22 +08:00
|
|
|
if (DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(E))
|
|
|
|
if (FieldDecl *Field = dyn_cast<FieldDecl>(DeclRef->getDecl()))
|
|
|
|
if (Field->isBitField())
|
|
|
|
return Field;
|
|
|
|
|
2011-07-13 10:05:57 +08:00
|
|
|
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(E)) {
|
2009-05-02 10:18:30 +08:00
|
|
|
if (BinOp->isAssignmentOp() && BinOp->getLHS())
|
|
|
|
return BinOp->getLHS()->getBitField();
|
|
|
|
|
2011-07-13 10:05:57 +08:00
|
|
|
if (BinOp->getOpcode() == BO_Comma && BinOp->getRHS())
|
|
|
|
return BinOp->getRHS()->getBitField();
|
|
|
|
}
|
|
|
|
|
2009-05-02 10:18:30 +08:00
|
|
|
return 0;
|
2008-10-29 08:13:59 +08:00
|
|
|
}
|
|
|
|
|
2010-02-01 01:18:49 +08:00
|
|
|
bool Expr::refersToVectorElement() const {
|
|
|
|
const Expr *E = this->IgnoreParens();
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2010-02-01 01:18:49 +08:00
|
|
|
while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
|
2010-08-25 18:28:54 +08:00
|
|
|
if (ICE->getValueKind() != VK_RValue &&
|
2010-08-25 19:45:40 +08:00
|
|
|
ICE->getCastKind() == CK_NoOp)
|
2010-02-01 01:18:49 +08:00
|
|
|
E = ICE->getSubExpr()->IgnoreParens();
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2010-02-01 01:18:49 +08:00
|
|
|
if (const ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E))
|
|
|
|
return ASE->getBase()->getType()->isVectorType();
|
|
|
|
|
|
|
|
if (isa<ExtVectorElementExpr>(E))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-02-17 06:14:05 +08:00
|
|
|
/// isArrow - Return true if the base expression is a pointer to vector,
|
|
|
|
/// return false if the base expression is a vector.
|
|
|
|
bool ExtVectorElementExpr::isArrow() const {
|
|
|
|
return getBase()->getType()->isPointerType();
|
|
|
|
}
|
|
|
|
|
2008-04-19 07:10:10 +08:00
|
|
|
unsigned ExtVectorElementExpr::getNumElements() const {
|
2009-09-22 07:43:11 +08:00
|
|
|
if (const VectorType *VT = getType()->getAs<VectorType>())
|
2008-05-09 14:41:27 +08:00
|
|
|
return VT->getNumElements();
|
|
|
|
return 1;
|
2007-08-04 00:00:20 +08:00
|
|
|
}
|
|
|
|
|
2008-05-09 14:41:27 +08:00
|
|
|
/// containsDuplicateElements - Return true if any element access is repeated.
|
2008-04-19 07:10:10 +08:00
|
|
|
bool ExtVectorElementExpr::containsDuplicateElements() const {
|
2009-10-18 10:09:09 +08:00
|
|
|
// FIXME: Refactor this code to an accessor on the AST node which returns the
|
|
|
|
// "type" of component access, and share with code below and in Sema.
|
2011-07-23 18:55:15 +08:00
|
|
|
StringRef Comp = Accessor->getName();
|
2009-01-18 10:01:21 +08:00
|
|
|
|
|
|
|
// Halving swizzles do not contain duplicate elements.
|
2009-10-18 07:53:04 +08:00
|
|
|
if (Comp == "hi" || Comp == "lo" || Comp == "even" || Comp == "odd")
|
2009-01-18 10:01:21 +08:00
|
|
|
return false;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-01-18 10:01:21 +08:00
|
|
|
// Advance past s-char prefix on hex swizzles.
|
2009-10-18 07:53:04 +08:00
|
|
|
if (Comp[0] == 's' || Comp[0] == 'S')
|
|
|
|
Comp = Comp.substr(1);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-10-18 07:53:04 +08:00
|
|
|
for (unsigned i = 0, e = Comp.size(); i != e; ++i)
|
2011-07-23 18:55:15 +08:00
|
|
|
if (Comp.substr(i + 1).find(Comp[i]) != StringRef::npos)
|
2007-07-30 11:29:09 +08:00
|
|
|
return true;
|
2009-10-18 07:53:04 +08:00
|
|
|
|
2007-07-30 11:29:09 +08:00
|
|
|
return false;
|
|
|
|
}
|
2007-08-03 07:36:59 +08:00
|
|
|
|
2008-05-09 14:41:27 +08:00
|
|
|
/// getEncodedElementAccess - We encode the fields as a llvm ConstantArray.
|
2008-05-14 05:03:02 +08:00
|
|
|
void ExtVectorElementExpr::getEncodedElementAccess(
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<unsigned> &Elts) const {
|
|
|
|
StringRef Comp = Accessor->getName();
|
2009-10-18 10:09:31 +08:00
|
|
|
if (Comp[0] == 's' || Comp[0] == 'S')
|
|
|
|
Comp = Comp.substr(1);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-10-18 10:09:31 +08:00
|
|
|
bool isHi = Comp == "hi";
|
|
|
|
bool isLo = Comp == "lo";
|
|
|
|
bool isEven = Comp == "even";
|
|
|
|
bool isOdd = Comp == "odd";
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2008-05-09 14:41:27 +08:00
|
|
|
for (unsigned i = 0, e = getNumElements(); i != e; ++i) {
|
|
|
|
uint64_t Index;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2008-05-09 14:41:27 +08:00
|
|
|
if (isHi)
|
|
|
|
Index = e + i;
|
|
|
|
else if (isLo)
|
|
|
|
Index = i;
|
|
|
|
else if (isEven)
|
|
|
|
Index = 2 * i;
|
|
|
|
else if (isOdd)
|
|
|
|
Index = 2 * i + 1;
|
|
|
|
else
|
2009-10-18 10:09:31 +08:00
|
|
|
Index = ExtVectorType::getAccessorIdx(Comp[i]);
|
2007-08-03 07:36:59 +08:00
|
|
|
|
2008-05-14 05:03:02 +08:00
|
|
|
Elts.push_back(Index);
|
2007-08-03 07:36:59 +08:00
|
|
|
}
|
2008-05-09 14:41:27 +08:00
|
|
|
}
|
|
|
|
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
ObjCMessageExpr::ObjCMessageExpr(QualType T,
|
2010-11-18 14:31:45 +08:00
|
|
|
ExprValueKind VK,
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
SourceLocation LBracLoc,
|
|
|
|
SourceLocation SuperLoc,
|
|
|
|
bool IsInstanceSuper,
|
|
|
|
QualType SuperType,
|
2010-05-05 23:23:54 +08:00
|
|
|
Selector Sel,
|
2010-12-11 04:08:27 +08:00
|
|
|
SourceLocation SelLoc,
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
ObjCMethodDecl *Method,
|
|
|
|
Expr **Args, unsigned NumArgs,
|
|
|
|
SourceLocation RBracLoc)
|
2010-11-18 14:31:45 +08:00
|
|
|
: Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
|
2010-12-15 09:34:56 +08:00
|
|
|
/*TypeDependent=*/false, /*ValueDependent=*/false,
|
2011-07-01 09:22:09 +08:00
|
|
|
/*InstantiationDependent=*/false,
|
2010-12-15 09:34:56 +08:00
|
|
|
/*ContainsUnexpandedParameterPack=*/false),
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
NumArgs(NumArgs), Kind(IsInstanceSuper? SuperInstance : SuperClass),
|
2011-06-16 07:02:42 +08:00
|
|
|
HasMethod(Method != 0), IsDelegateInitCall(false), SuperLoc(SuperLoc),
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
|
|
|
|
: Sel.getAsOpaquePtr())),
|
2010-12-11 04:08:27 +08:00
|
|
|
SelectorLoc(SelLoc), LBracLoc(LBracLoc), RBracLoc(RBracLoc)
|
2010-03-09 00:40:19 +08:00
|
|
|
{
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
setReceiverPointer(SuperType.getAsOpaquePtr());
|
|
|
|
if (NumArgs)
|
|
|
|
memcpy(getArgs(), Args, NumArgs * sizeof(Expr *));
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjCMessageExpr::ObjCMessageExpr(QualType T,
|
2010-11-18 14:31:45 +08:00
|
|
|
ExprValueKind VK,
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
SourceLocation LBracLoc,
|
|
|
|
TypeSourceInfo *Receiver,
|
2010-12-11 04:08:27 +08:00
|
|
|
Selector Sel,
|
|
|
|
SourceLocation SelLoc,
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
ObjCMethodDecl *Method,
|
|
|
|
Expr **Args, unsigned NumArgs,
|
|
|
|
SourceLocation RBracLoc)
|
2010-11-18 14:31:45 +08:00
|
|
|
: Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(),
|
2011-07-01 09:22:09 +08:00
|
|
|
T->isDependentType(), T->isInstantiationDependentType(),
|
|
|
|
T->containsUnexpandedParameterPack()),
|
2011-06-16 07:02:42 +08:00
|
|
|
NumArgs(NumArgs), Kind(Class),
|
|
|
|
HasMethod(Method != 0), IsDelegateInitCall(false),
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
|
|
|
|
: Sel.getAsOpaquePtr())),
|
2010-12-11 04:08:27 +08:00
|
|
|
SelectorLoc(SelLoc), LBracLoc(LBracLoc), RBracLoc(RBracLoc)
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
{
|
|
|
|
setReceiverPointer(Receiver);
|
2011-01-04 03:04:46 +08:00
|
|
|
Expr **MyArgs = getArgs();
|
2010-12-15 09:34:56 +08:00
|
|
|
for (unsigned I = 0; I != NumArgs; ++I) {
|
|
|
|
if (Args[I]->isTypeDependent())
|
|
|
|
ExprBits.TypeDependent = true;
|
|
|
|
if (Args[I]->isValueDependent())
|
|
|
|
ExprBits.ValueDependent = true;
|
2011-07-01 09:22:09 +08:00
|
|
|
if (Args[I]->isInstantiationDependent())
|
|
|
|
ExprBits.InstantiationDependent = true;
|
2010-12-15 09:34:56 +08:00
|
|
|
if (Args[I]->containsUnexpandedParameterPack())
|
|
|
|
ExprBits.ContainsUnexpandedParameterPack = true;
|
|
|
|
|
|
|
|
MyArgs[I] = Args[I];
|
|
|
|
}
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ObjCMessageExpr::ObjCMessageExpr(QualType T,
|
2010-11-18 14:31:45 +08:00
|
|
|
ExprValueKind VK,
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
SourceLocation LBracLoc,
|
|
|
|
Expr *Receiver,
|
2010-05-05 23:23:54 +08:00
|
|
|
Selector Sel,
|
2010-12-11 04:08:27 +08:00
|
|
|
SourceLocation SelLoc,
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
ObjCMethodDecl *Method,
|
|
|
|
Expr **Args, unsigned NumArgs,
|
|
|
|
SourceLocation RBracLoc)
|
2010-11-18 14:31:45 +08:00
|
|
|
: Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, Receiver->isTypeDependent(),
|
2010-12-15 09:34:56 +08:00
|
|
|
Receiver->isTypeDependent(),
|
2011-07-01 09:22:09 +08:00
|
|
|
Receiver->isInstantiationDependent(),
|
2010-12-15 09:34:56 +08:00
|
|
|
Receiver->containsUnexpandedParameterPack()),
|
2011-06-16 07:02:42 +08:00
|
|
|
NumArgs(NumArgs), Kind(Instance),
|
|
|
|
HasMethod(Method != 0), IsDelegateInitCall(false),
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
|
|
|
|
: Sel.getAsOpaquePtr())),
|
2010-12-11 04:08:27 +08:00
|
|
|
SelectorLoc(SelLoc), LBracLoc(LBracLoc), RBracLoc(RBracLoc)
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
{
|
|
|
|
setReceiverPointer(Receiver);
|
2011-01-04 03:04:46 +08:00
|
|
|
Expr **MyArgs = getArgs();
|
2010-12-15 09:34:56 +08:00
|
|
|
for (unsigned I = 0; I != NumArgs; ++I) {
|
|
|
|
if (Args[I]->isTypeDependent())
|
|
|
|
ExprBits.TypeDependent = true;
|
|
|
|
if (Args[I]->isValueDependent())
|
|
|
|
ExprBits.ValueDependent = true;
|
2011-07-01 09:22:09 +08:00
|
|
|
if (Args[I]->isInstantiationDependent())
|
|
|
|
ExprBits.InstantiationDependent = true;
|
2010-12-15 09:34:56 +08:00
|
|
|
if (Args[I]->containsUnexpandedParameterPack())
|
|
|
|
ExprBits.ContainsUnexpandedParameterPack = true;
|
|
|
|
|
|
|
|
MyArgs[I] = Args[I];
|
|
|
|
}
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T,
|
2010-11-18 14:31:45 +08:00
|
|
|
ExprValueKind VK,
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
SourceLocation LBracLoc,
|
|
|
|
SourceLocation SuperLoc,
|
|
|
|
bool IsInstanceSuper,
|
|
|
|
QualType SuperType,
|
2010-05-05 23:23:54 +08:00
|
|
|
Selector Sel,
|
2010-12-11 04:08:27 +08:00
|
|
|
SourceLocation SelLoc,
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
ObjCMethodDecl *Method,
|
|
|
|
Expr **Args, unsigned NumArgs,
|
|
|
|
SourceLocation RBracLoc) {
|
2010-05-05 23:23:54 +08:00
|
|
|
unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) +
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
NumArgs * sizeof(Expr *);
|
|
|
|
void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
|
2010-11-18 14:31:45 +08:00
|
|
|
return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
|
2010-12-11 04:08:27 +08:00
|
|
|
SuperType, Sel, SelLoc, Method, Args,NumArgs,
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
RBracLoc);
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T,
|
2010-11-18 14:31:45 +08:00
|
|
|
ExprValueKind VK,
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
SourceLocation LBracLoc,
|
|
|
|
TypeSourceInfo *Receiver,
|
2010-05-05 23:23:54 +08:00
|
|
|
Selector Sel,
|
2010-12-11 04:08:27 +08:00
|
|
|
SourceLocation SelLoc,
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
ObjCMethodDecl *Method,
|
|
|
|
Expr **Args, unsigned NumArgs,
|
|
|
|
SourceLocation RBracLoc) {
|
2010-05-05 23:23:54 +08:00
|
|
|
unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) +
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
NumArgs * sizeof(Expr *);
|
|
|
|
void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
|
2010-12-11 04:08:27 +08:00
|
|
|
return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLoc,
|
|
|
|
Method, Args, NumArgs, RBracLoc);
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T,
|
2010-11-18 14:31:45 +08:00
|
|
|
ExprValueKind VK,
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
SourceLocation LBracLoc,
|
|
|
|
Expr *Receiver,
|
2010-12-11 04:08:27 +08:00
|
|
|
Selector Sel,
|
|
|
|
SourceLocation SelLoc,
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
ObjCMethodDecl *Method,
|
|
|
|
Expr **Args, unsigned NumArgs,
|
|
|
|
SourceLocation RBracLoc) {
|
2010-05-05 23:23:54 +08:00
|
|
|
unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) +
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
NumArgs * sizeof(Expr *);
|
|
|
|
void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
|
2010-12-11 04:08:27 +08:00
|
|
|
return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLoc,
|
|
|
|
Method, Args, NumArgs, RBracLoc);
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
}
|
|
|
|
|
2010-05-05 23:23:54 +08:00
|
|
|
ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(ASTContext &Context,
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
unsigned NumArgs) {
|
2010-05-05 23:23:54 +08:00
|
|
|
unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) +
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
NumArgs * sizeof(Expr *);
|
|
|
|
void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
|
|
|
|
return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
|
|
|
|
}
|
2010-12-11 04:08:30 +08:00
|
|
|
|
|
|
|
SourceRange ObjCMessageExpr::getReceiverRange() const {
|
|
|
|
switch (getReceiverKind()) {
|
|
|
|
case Instance:
|
|
|
|
return getInstanceReceiver()->getSourceRange();
|
|
|
|
|
|
|
|
case Class:
|
|
|
|
return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
|
|
|
|
|
|
|
|
case SuperInstance:
|
|
|
|
case SuperClass:
|
|
|
|
return getSuperLoc();
|
|
|
|
}
|
|
|
|
|
|
|
|
return SourceLocation();
|
|
|
|
}
|
|
|
|
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
Selector ObjCMessageExpr::getSelector() const {
|
|
|
|
if (HasMethod)
|
|
|
|
return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
|
|
|
|
->getSelector();
|
2010-05-05 23:23:54 +08:00
|
|
|
return Selector(SelectorOrMethod);
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
|
|
|
|
switch (getReceiverKind()) {
|
|
|
|
case Instance:
|
|
|
|
if (const ObjCObjectPointerType *Ptr
|
|
|
|
= getInstanceReceiver()->getType()->getAs<ObjCObjectPointerType>())
|
|
|
|
return Ptr->getInterfaceDecl();
|
|
|
|
break;
|
2008-06-24 23:50:53 +08:00
|
|
|
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
case Class:
|
2010-05-15 19:32:37 +08:00
|
|
|
if (const ObjCObjectType *Ty
|
|
|
|
= getClassReceiver()->getAs<ObjCObjectType>())
|
|
|
|
return Ty->getInterface();
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
break;
|
2008-06-24 23:50:53 +08:00
|
|
|
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
case SuperInstance:
|
|
|
|
if (const ObjCObjectPointerType *Ptr
|
|
|
|
= getSuperType()->getAs<ObjCObjectPointerType>())
|
|
|
|
return Ptr->getInterfaceDecl();
|
|
|
|
break;
|
2010-03-09 00:40:19 +08:00
|
|
|
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
case SuperClass:
|
2011-01-25 08:03:48 +08:00
|
|
|
if (const ObjCObjectType *Iface
|
|
|
|
= getSuperType()->getAs<ObjCObjectType>())
|
|
|
|
return Iface->getInterface();
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
break;
|
|
|
|
}
|
2009-04-26 08:44:05 +08:00
|
|
|
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
return 0;
|
2010-02-12 06:41:21 +08:00
|
|
|
}
|
2009-04-26 08:44:05 +08:00
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
|
2011-06-16 07:02:42 +08:00
|
|
|
switch (getBridgeKind()) {
|
|
|
|
case OBC_Bridge:
|
|
|
|
return "__bridge";
|
|
|
|
case OBC_BridgeTransfer:
|
|
|
|
return "__bridge_transfer";
|
|
|
|
case OBC_BridgeRetained:
|
|
|
|
return "__bridge_retained";
|
|
|
|
}
|
|
|
|
|
|
|
|
return "__bridge";
|
|
|
|
}
|
|
|
|
|
2011-01-12 17:06:06 +08:00
|
|
|
bool ChooseExpr::isConditionTrue(const ASTContext &C) const {
|
2009-04-27 03:19:15 +08:00
|
|
|
return getCond()->EvaluateAsInt(C) != 0;
|
2007-10-25 08:29:32 +08:00
|
|
|
}
|
|
|
|
|
2010-12-15 09:34:56 +08:00
|
|
|
ShuffleVectorExpr::ShuffleVectorExpr(ASTContext &C, Expr **args, unsigned nexpr,
|
|
|
|
QualType Type, SourceLocation BLoc,
|
|
|
|
SourceLocation RP)
|
|
|
|
: Expr(ShuffleVectorExprClass, Type, VK_RValue, OK_Ordinary,
|
|
|
|
Type->isDependentType(), Type->isDependentType(),
|
2011-07-01 09:22:09 +08:00
|
|
|
Type->isInstantiationDependentType(),
|
2010-12-15 09:34:56 +08:00
|
|
|
Type->containsUnexpandedParameterPack()),
|
|
|
|
BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(nexpr)
|
|
|
|
{
|
|
|
|
SubExprs = new (C) Stmt*[nexpr];
|
|
|
|
for (unsigned i = 0; i < nexpr; i++) {
|
|
|
|
if (args[i]->isTypeDependent())
|
|
|
|
ExprBits.TypeDependent = true;
|
|
|
|
if (args[i]->isValueDependent())
|
|
|
|
ExprBits.ValueDependent = true;
|
2011-07-01 09:22:09 +08:00
|
|
|
if (args[i]->isInstantiationDependent())
|
|
|
|
ExprBits.InstantiationDependent = true;
|
2010-12-15 09:34:56 +08:00
|
|
|
if (args[i]->containsUnexpandedParameterPack())
|
|
|
|
ExprBits.ContainsUnexpandedParameterPack = true;
|
|
|
|
|
|
|
|
SubExprs[i] = args[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-12 10:28:50 +08:00
|
|
|
void ShuffleVectorExpr::setExprs(ASTContext &C, Expr ** Exprs,
|
|
|
|
unsigned NumExprs) {
|
|
|
|
if (SubExprs) C.Deallocate(SubExprs);
|
|
|
|
|
|
|
|
SubExprs = new (C) Stmt* [NumExprs];
|
2009-04-16 08:01:45 +08:00
|
|
|
this->NumExprs = NumExprs;
|
|
|
|
memcpy(SubExprs, Exprs, sizeof(Expr *) * NumExprs);
|
2009-09-09 23:08:12 +08:00
|
|
|
}
|
2009-08-12 10:28:50 +08:00
|
|
|
|
2011-04-15 08:35:48 +08:00
|
|
|
GenericSelectionExpr::GenericSelectionExpr(ASTContext &Context,
|
|
|
|
SourceLocation GenericLoc, Expr *ControllingExpr,
|
|
|
|
TypeSourceInfo **AssocTypes, Expr **AssocExprs,
|
|
|
|
unsigned NumAssocs, SourceLocation DefaultLoc,
|
|
|
|
SourceLocation RParenLoc,
|
|
|
|
bool ContainsUnexpandedParameterPack,
|
|
|
|
unsigned ResultIndex)
|
|
|
|
: Expr(GenericSelectionExprClass,
|
|
|
|
AssocExprs[ResultIndex]->getType(),
|
|
|
|
AssocExprs[ResultIndex]->getValueKind(),
|
|
|
|
AssocExprs[ResultIndex]->getObjectKind(),
|
|
|
|
AssocExprs[ResultIndex]->isTypeDependent(),
|
|
|
|
AssocExprs[ResultIndex]->isValueDependent(),
|
2011-07-01 09:22:09 +08:00
|
|
|
AssocExprs[ResultIndex]->isInstantiationDependent(),
|
2011-04-15 08:35:48 +08:00
|
|
|
ContainsUnexpandedParameterPack),
|
|
|
|
AssocTypes(new (Context) TypeSourceInfo*[NumAssocs]),
|
|
|
|
SubExprs(new (Context) Stmt*[END_EXPR+NumAssocs]), NumAssocs(NumAssocs),
|
|
|
|
ResultIndex(ResultIndex), GenericLoc(GenericLoc), DefaultLoc(DefaultLoc),
|
|
|
|
RParenLoc(RParenLoc) {
|
|
|
|
SubExprs[CONTROLLING] = ControllingExpr;
|
|
|
|
std::copy(AssocTypes, AssocTypes+NumAssocs, this->AssocTypes);
|
|
|
|
std::copy(AssocExprs, AssocExprs+NumAssocs, SubExprs+END_EXPR);
|
|
|
|
}
|
|
|
|
|
|
|
|
GenericSelectionExpr::GenericSelectionExpr(ASTContext &Context,
|
|
|
|
SourceLocation GenericLoc, Expr *ControllingExpr,
|
|
|
|
TypeSourceInfo **AssocTypes, Expr **AssocExprs,
|
|
|
|
unsigned NumAssocs, SourceLocation DefaultLoc,
|
|
|
|
SourceLocation RParenLoc,
|
|
|
|
bool ContainsUnexpandedParameterPack)
|
|
|
|
: Expr(GenericSelectionExprClass,
|
|
|
|
Context.DependentTy,
|
|
|
|
VK_RValue,
|
|
|
|
OK_Ordinary,
|
2011-07-01 09:22:09 +08:00
|
|
|
/*isTypeDependent=*/true,
|
|
|
|
/*isValueDependent=*/true,
|
|
|
|
/*isInstantiationDependent=*/true,
|
2011-04-15 08:35:48 +08:00
|
|
|
ContainsUnexpandedParameterPack),
|
|
|
|
AssocTypes(new (Context) TypeSourceInfo*[NumAssocs]),
|
|
|
|
SubExprs(new (Context) Stmt*[END_EXPR+NumAssocs]), NumAssocs(NumAssocs),
|
|
|
|
ResultIndex(-1U), GenericLoc(GenericLoc), DefaultLoc(DefaultLoc),
|
|
|
|
RParenLoc(RParenLoc) {
|
|
|
|
SubExprs[CONTROLLING] = ControllingExpr;
|
|
|
|
std::copy(AssocTypes, AssocTypes+NumAssocs, this->AssocTypes);
|
|
|
|
std::copy(AssocExprs, AssocExprs+NumAssocs, SubExprs+END_EXPR);
|
|
|
|
}
|
|
|
|
|
2009-01-22 08:58:24 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// DesignatedInitExpr
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
IdentifierInfo *DesignatedInitExpr::Designator::getFieldName() const {
|
2009-01-22 08:58:24 +08:00
|
|
|
assert(Kind == FieldDesignator && "Only valid on a field designator");
|
|
|
|
if (Field.NameOrField & 0x01)
|
|
|
|
return reinterpret_cast<IdentifierInfo *>(Field.NameOrField&~0x01);
|
|
|
|
else
|
|
|
|
return getField()->getIdentifier();
|
|
|
|
}
|
|
|
|
|
2010-05-05 23:23:54 +08:00
|
|
|
DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty,
|
2010-01-07 07:17:19 +08:00
|
|
|
unsigned NumDesignators,
|
2009-04-15 14:41:24 +08:00
|
|
|
const Designator *Designators,
|
2009-09-09 23:08:12 +08:00
|
|
|
SourceLocation EqualOrColonLoc,
|
2009-04-15 14:41:24 +08:00
|
|
|
bool GNUSyntax,
|
2009-09-09 23:08:12 +08:00
|
|
|
Expr **IndexExprs,
|
2009-05-22 07:17:49 +08:00
|
|
|
unsigned NumIndexExprs,
|
|
|
|
Expr *Init)
|
2009-09-09 23:08:12 +08:00
|
|
|
: Expr(DesignatedInitExprClass, Ty,
|
2010-11-18 14:31:45 +08:00
|
|
|
Init->getValueKind(), Init->getObjectKind(),
|
2010-12-15 09:34:56 +08:00
|
|
|
Init->isTypeDependent(), Init->isValueDependent(),
|
2011-07-01 09:22:09 +08:00
|
|
|
Init->isInstantiationDependent(),
|
2010-12-15 09:34:56 +08:00
|
|
|
Init->containsUnexpandedParameterPack()),
|
2009-09-09 23:08:12 +08:00
|
|
|
EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax),
|
|
|
|
NumDesignators(NumDesignators), NumSubExprs(NumIndexExprs + 1) {
|
2010-01-07 07:17:19 +08:00
|
|
|
this->Designators = new (C) Designator[NumDesignators];
|
2009-05-22 07:17:49 +08:00
|
|
|
|
|
|
|
// Record the initializer itself.
|
2011-02-13 12:07:26 +08:00
|
|
|
child_range Child = children();
|
2009-05-22 07:17:49 +08:00
|
|
|
*Child++ = Init;
|
|
|
|
|
|
|
|
// Copy the designators and their subexpressions, computing
|
|
|
|
// value-dependence along the way.
|
|
|
|
unsigned IndexIdx = 0;
|
|
|
|
for (unsigned I = 0; I != NumDesignators; ++I) {
|
2009-04-15 14:41:24 +08:00
|
|
|
this->Designators[I] = Designators[I];
|
2009-05-22 07:17:49 +08:00
|
|
|
|
|
|
|
if (this->Designators[I].isArrayDesignator()) {
|
|
|
|
// Compute type- and value-dependence.
|
|
|
|
Expr *Index = IndexExprs[IndexIdx];
|
2010-12-15 09:34:56 +08:00
|
|
|
if (Index->isTypeDependent() || Index->isValueDependent())
|
|
|
|
ExprBits.ValueDependent = true;
|
2011-07-01 09:22:09 +08:00
|
|
|
if (Index->isInstantiationDependent())
|
|
|
|
ExprBits.InstantiationDependent = true;
|
2010-12-15 09:34:56 +08:00
|
|
|
// Propagate unexpanded parameter packs.
|
|
|
|
if (Index->containsUnexpandedParameterPack())
|
|
|
|
ExprBits.ContainsUnexpandedParameterPack = true;
|
2009-05-22 07:17:49 +08:00
|
|
|
|
|
|
|
// Copy the index expressions into permanent storage.
|
|
|
|
*Child++ = IndexExprs[IndexIdx++];
|
|
|
|
} else if (this->Designators[I].isArrayRangeDesignator()) {
|
|
|
|
// Compute type- and value-dependence.
|
|
|
|
Expr *Start = IndexExprs[IndexIdx];
|
|
|
|
Expr *End = IndexExprs[IndexIdx + 1];
|
2010-12-15 09:34:56 +08:00
|
|
|
if (Start->isTypeDependent() || Start->isValueDependent() ||
|
2011-07-01 09:22:09 +08:00
|
|
|
End->isTypeDependent() || End->isValueDependent()) {
|
2010-12-15 09:34:56 +08:00
|
|
|
ExprBits.ValueDependent = true;
|
2011-07-01 09:22:09 +08:00
|
|
|
ExprBits.InstantiationDependent = true;
|
|
|
|
} else if (Start->isInstantiationDependent() ||
|
|
|
|
End->isInstantiationDependent()) {
|
|
|
|
ExprBits.InstantiationDependent = true;
|
|
|
|
}
|
|
|
|
|
2010-12-15 09:34:56 +08:00
|
|
|
// Propagate unexpanded parameter packs.
|
|
|
|
if (Start->containsUnexpandedParameterPack() ||
|
|
|
|
End->containsUnexpandedParameterPack())
|
|
|
|
ExprBits.ContainsUnexpandedParameterPack = true;
|
2009-05-22 07:17:49 +08:00
|
|
|
|
|
|
|
// Copy the start/end expressions into permanent storage.
|
|
|
|
*Child++ = IndexExprs[IndexIdx++];
|
|
|
|
*Child++ = IndexExprs[IndexIdx++];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(IndexIdx == NumIndexExprs && "Wrong number of index expressions");
|
2009-04-15 14:41:24 +08:00
|
|
|
}
|
|
|
|
|
2009-01-22 08:58:24 +08:00
|
|
|
DesignatedInitExpr *
|
2009-09-09 23:08:12 +08:00
|
|
|
DesignatedInitExpr::Create(ASTContext &C, Designator *Designators,
|
2009-01-22 08:58:24 +08:00
|
|
|
unsigned NumDesignators,
|
|
|
|
Expr **IndexExprs, unsigned NumIndexExprs,
|
|
|
|
SourceLocation ColonOrEqualLoc,
|
|
|
|
bool UsesColonSyntax, Expr *Init) {
|
2009-01-28 07:20:32 +08:00
|
|
|
void *Mem = C.Allocate(sizeof(DesignatedInitExpr) +
|
|
|
|
sizeof(Stmt *) * (NumIndexExprs + 1), 8);
|
2010-01-07 07:17:19 +08:00
|
|
|
return new (Mem) DesignatedInitExpr(C, C.VoidTy, NumDesignators, Designators,
|
2009-05-22 07:17:49 +08:00
|
|
|
ColonOrEqualLoc, UsesColonSyntax,
|
|
|
|
IndexExprs, NumIndexExprs, Init);
|
2009-01-22 08:58:24 +08:00
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
DesignatedInitExpr *DesignatedInitExpr::CreateEmpty(ASTContext &C,
|
2009-04-16 08:55:48 +08:00
|
|
|
unsigned NumIndexExprs) {
|
|
|
|
void *Mem = C.Allocate(sizeof(DesignatedInitExpr) +
|
|
|
|
sizeof(Stmt *) * (NumIndexExprs + 1), 8);
|
|
|
|
return new (Mem) DesignatedInitExpr(NumIndexExprs + 1);
|
|
|
|
}
|
|
|
|
|
2010-01-07 07:17:19 +08:00
|
|
|
void DesignatedInitExpr::setDesignators(ASTContext &C,
|
|
|
|
const Designator *Desigs,
|
2009-04-16 08:55:48 +08:00
|
|
|
unsigned NumDesigs) {
|
2010-01-07 07:17:19 +08:00
|
|
|
Designators = new (C) Designator[NumDesigs];
|
2009-04-16 08:55:48 +08:00
|
|
|
NumDesignators = NumDesigs;
|
|
|
|
for (unsigned I = 0; I != NumDesigs; ++I)
|
|
|
|
Designators[I] = Desigs[I];
|
|
|
|
}
|
|
|
|
|
2011-03-16 23:08:46 +08:00
|
|
|
SourceRange DesignatedInitExpr::getDesignatorsSourceRange() const {
|
|
|
|
DesignatedInitExpr *DIE = const_cast<DesignatedInitExpr*>(this);
|
|
|
|
if (size() == 1)
|
|
|
|
return DIE->getDesignator(0)->getSourceRange();
|
|
|
|
return SourceRange(DIE->getDesignator(0)->getStartLocation(),
|
|
|
|
DIE->getDesignator(size()-1)->getEndLocation());
|
|
|
|
}
|
|
|
|
|
2009-01-22 08:58:24 +08:00
|
|
|
SourceRange DesignatedInitExpr::getSourceRange() const {
|
|
|
|
SourceLocation StartLoc;
|
2009-02-17 06:33:34 +08:00
|
|
|
Designator &First =
|
|
|
|
*const_cast<DesignatedInitExpr*>(this)->designators_begin();
|
2009-01-22 08:58:24 +08:00
|
|
|
if (First.isFieldDesignator()) {
|
2009-03-28 08:41:23 +08:00
|
|
|
if (GNUSyntax)
|
2009-01-22 08:58:24 +08:00
|
|
|
StartLoc = SourceLocation::getFromRawEncoding(First.Field.FieldLoc);
|
|
|
|
else
|
|
|
|
StartLoc = SourceLocation::getFromRawEncoding(First.Field.DotLoc);
|
|
|
|
} else
|
2009-02-17 06:33:34 +08:00
|
|
|
StartLoc =
|
|
|
|
SourceLocation::getFromRawEncoding(First.ArrayOrRange.LBracketLoc);
|
2009-01-22 08:58:24 +08:00
|
|
|
return SourceRange(StartLoc, getInit()->getSourceRange().getEnd());
|
|
|
|
}
|
|
|
|
|
|
|
|
Expr *DesignatedInitExpr::getArrayIndex(const Designator& D) {
|
|
|
|
assert(D.Kind == Designator::ArrayDesignator && "Requires array designator");
|
|
|
|
char* Ptr = static_cast<char*>(static_cast<void *>(this));
|
|
|
|
Ptr += sizeof(DesignatedInitExpr);
|
|
|
|
Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr));
|
|
|
|
return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
Expr *DesignatedInitExpr::getArrayRangeStart(const Designator& D) {
|
2009-09-09 23:08:12 +08:00
|
|
|
assert(D.Kind == Designator::ArrayRangeDesignator &&
|
2009-01-22 08:58:24 +08:00
|
|
|
"Requires array range designator");
|
|
|
|
char* Ptr = static_cast<char*>(static_cast<void *>(this));
|
|
|
|
Ptr += sizeof(DesignatedInitExpr);
|
|
|
|
Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr));
|
|
|
|
return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
Expr *DesignatedInitExpr::getArrayRangeEnd(const Designator& D) {
|
2009-09-09 23:08:12 +08:00
|
|
|
assert(D.Kind == Designator::ArrayRangeDesignator &&
|
2009-01-22 08:58:24 +08:00
|
|
|
"Requires array range designator");
|
|
|
|
char* Ptr = static_cast<char*>(static_cast<void *>(this));
|
|
|
|
Ptr += sizeof(DesignatedInitExpr);
|
|
|
|
Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr));
|
|
|
|
return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 2));
|
|
|
|
}
|
|
|
|
|
2009-04-15 14:41:24 +08:00
|
|
|
/// \brief Replaces the designator at index @p Idx with the series
|
|
|
|
/// of designators in [First, Last).
|
2010-01-07 07:17:19 +08:00
|
|
|
void DesignatedInitExpr::ExpandDesignator(ASTContext &C, unsigned Idx,
|
2009-09-09 23:08:12 +08:00
|
|
|
const Designator *First,
|
2009-04-15 14:41:24 +08:00
|
|
|
const Designator *Last) {
|
|
|
|
unsigned NumNewDesignators = Last - First;
|
|
|
|
if (NumNewDesignators == 0) {
|
|
|
|
std::copy_backward(Designators + Idx + 1,
|
|
|
|
Designators + NumDesignators,
|
|
|
|
Designators + Idx);
|
|
|
|
--NumNewDesignators;
|
|
|
|
return;
|
|
|
|
} else if (NumNewDesignators == 1) {
|
|
|
|
Designators[Idx] = *First;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
Designator *NewDesignators
|
2010-01-07 07:17:19 +08:00
|
|
|
= new (C) Designator[NumDesignators - 1 + NumNewDesignators];
|
2009-04-15 14:41:24 +08:00
|
|
|
std::copy(Designators, Designators + Idx, NewDesignators);
|
|
|
|
std::copy(First, Last, NewDesignators + Idx);
|
|
|
|
std::copy(Designators + Idx + 1, Designators + NumDesignators,
|
|
|
|
NewDesignators + Idx + NumNewDesignators);
|
|
|
|
Designators = NewDesignators;
|
|
|
|
NumDesignators = NumDesignators - 1 + NumNewDesignators;
|
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc,
|
2009-08-11 07:49:36 +08:00
|
|
|
Expr **exprs, unsigned nexprs,
|
2011-06-23 04:02:16 +08:00
|
|
|
SourceLocation rparenloc, QualType T)
|
|
|
|
: Expr(ParenListExprClass, T, VK_RValue, OK_Ordinary,
|
2011-07-01 09:22:09 +08:00
|
|
|
false, false, false, false),
|
2010-12-15 09:34:56 +08:00
|
|
|
NumExprs(nexprs), LParenLoc(lparenloc), RParenLoc(rparenloc) {
|
2011-06-23 04:02:16 +08:00
|
|
|
assert(!T.isNull() && "ParenListExpr must have a valid type");
|
2009-08-11 07:49:36 +08:00
|
|
|
Exprs = new (C) Stmt*[nexprs];
|
2010-12-15 09:34:56 +08:00
|
|
|
for (unsigned i = 0; i != nexprs; ++i) {
|
|
|
|
if (exprs[i]->isTypeDependent())
|
|
|
|
ExprBits.TypeDependent = true;
|
|
|
|
if (exprs[i]->isValueDependent())
|
|
|
|
ExprBits.ValueDependent = true;
|
2011-07-01 09:22:09 +08:00
|
|
|
if (exprs[i]->isInstantiationDependent())
|
|
|
|
ExprBits.InstantiationDependent = true;
|
2010-12-15 09:34:56 +08:00
|
|
|
if (exprs[i]->containsUnexpandedParameterPack())
|
|
|
|
ExprBits.ContainsUnexpandedParameterPack = true;
|
|
|
|
|
2009-08-11 07:49:36 +08:00
|
|
|
Exprs[i] = exprs[i];
|
2010-12-15 09:34:56 +08:00
|
|
|
}
|
2009-08-11 07:49:36 +08:00
|
|
|
}
|
|
|
|
|
2011-02-16 16:02:54 +08:00
|
|
|
const OpaqueValueExpr *OpaqueValueExpr::findInCopyConstruct(const Expr *e) {
|
|
|
|
if (const ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(e))
|
|
|
|
e = ewc->getSubExpr();
|
2011-06-22 01:03:29 +08:00
|
|
|
if (const MaterializeTemporaryExpr *m = dyn_cast<MaterializeTemporaryExpr>(e))
|
|
|
|
e = m->GetTemporaryExpr();
|
2011-02-16 16:02:54 +08:00
|
|
|
e = cast<CXXConstructExpr>(e)->getArg(0);
|
|
|
|
while (const ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
|
|
|
|
e = ice->getSubExpr();
|
|
|
|
return cast<OpaqueValueExpr>(e);
|
|
|
|
}
|
|
|
|
|
2008-10-28 02:40:21 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// ExprIterator.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
Expr* ExprIterator::operator[](size_t idx) { return cast<Expr>(I[idx]); }
|
|
|
|
Expr* ExprIterator::operator*() const { return cast<Expr>(*I); }
|
|
|
|
Expr* ExprIterator::operator->() const { return cast<Expr>(*I); }
|
|
|
|
const Expr* ConstExprIterator::operator[](size_t idx) const {
|
|
|
|
return cast<Expr>(I[idx]);
|
|
|
|
}
|
|
|
|
const Expr* ConstExprIterator::operator*() const { return cast<Expr>(*I); }
|
|
|
|
const Expr* ConstExprIterator::operator->() const { return cast<Expr>(*I); }
|
|
|
|
|
2007-08-25 02:13:47 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Child Iterators for iterating over subexpressions/substatements
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2011-03-12 03:24:49 +08:00
|
|
|
// UnaryExprOrTypeTraitExpr
|
|
|
|
Stmt::child_range UnaryExprOrTypeTraitExpr::children() {
|
2008-11-12 01:56:53 +08:00
|
|
|
// If this is of a type and the type is a VLA type (and not a typedef), the
|
|
|
|
// size expression of the VLA needs to be treated as an executable expression.
|
|
|
|
// Why isn't this weirdness documented better in StmtIterator?
|
|
|
|
if (isArgumentType()) {
|
2011-01-19 14:33:43 +08:00
|
|
|
if (const VariableArrayType* T = dyn_cast<VariableArrayType>(
|
2008-11-12 01:56:53 +08:00
|
|
|
getArgumentType().getTypePtr()))
|
2011-02-09 16:16:59 +08:00
|
|
|
return child_range(child_iterator(T), child_iterator());
|
|
|
|
return child_range();
|
2008-11-12 01:56:53 +08:00
|
|
|
}
|
2011-02-09 16:16:59 +08:00
|
|
|
return child_range(&Argument.Ex, &Argument.Ex + 1);
|
2007-10-19 07:28:49 +08:00
|
|
|
}
|
2007-10-18 00:58:11 +08:00
|
|
|
|
2007-09-19 07:55:05 +08:00
|
|
|
// ObjCMessageExpr
|
2011-02-09 16:16:59 +08:00
|
|
|
Stmt::child_range ObjCMessageExpr::children() {
|
|
|
|
Stmt **begin;
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
if (getReceiverKind() == Instance)
|
2011-02-09 16:16:59 +08:00
|
|
|
begin = reinterpret_cast<Stmt **>(this + 1);
|
|
|
|
else
|
|
|
|
begin = reinterpret_cast<Stmt **>(getArgs());
|
|
|
|
return child_range(begin,
|
|
|
|
reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
|
2007-09-19 07:55:05 +08:00
|
|
|
}
|
|
|
|
|
2008-09-04 02:15:37 +08:00
|
|
|
// Blocks
|
2011-02-07 18:33:21 +08:00
|
|
|
BlockDeclRefExpr::BlockDeclRefExpr(VarDecl *d, QualType t, ExprValueKind VK,
|
2011-01-20 05:32:01 +08:00
|
|
|
SourceLocation l, bool ByRef,
|
2011-02-07 18:33:21 +08:00
|
|
|
bool constAdded)
|
2011-07-01 09:22:09 +08:00
|
|
|
: Expr(BlockDeclRefExprClass, t, VK, OK_Ordinary, false, false, false,
|
2011-01-20 05:32:01 +08:00
|
|
|
d->isParameterPack()),
|
2011-02-07 18:33:21 +08:00
|
|
|
D(d), Loc(l), IsByRef(ByRef), ConstQualAdded(constAdded)
|
2011-01-20 05:32:01 +08:00
|
|
|
{
|
2011-01-20 05:52:31 +08:00
|
|
|
bool TypeDependent = false;
|
|
|
|
bool ValueDependent = false;
|
2011-07-01 09:22:09 +08:00
|
|
|
bool InstantiationDependent = false;
|
|
|
|
computeDeclRefDependence(D, getType(), TypeDependent, ValueDependent,
|
|
|
|
InstantiationDependent);
|
2011-01-20 05:52:31 +08:00
|
|
|
ExprBits.TypeDependent = TypeDependent;
|
|
|
|
ExprBits.ValueDependent = ValueDependent;
|
2011-07-01 09:22:09 +08:00
|
|
|
ExprBits.InstantiationDependent = InstantiationDependent;
|
2011-01-20 05:32:01 +08:00
|
|
|
}
|