summaryrefslogtreecommitdiff
path: root/lib/AST
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2010-01-01 10:34:51 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2010-01-01 10:34:51 +0000
commitabe15e553e58165e7692c0d0842865c488ed7b45 (patch)
tree1e68501209c9133fbda8d45171e59f8d6f12dd55 /lib/AST
parent34d02d0b37f16015f317a935c48ce8b7b64ae77b (diff)
Notes
Diffstat (limited to 'lib/AST')
-rw-r--r--lib/AST/ASTContext.cpp125
-rw-r--r--lib/AST/CMakeLists.txt1
-rw-r--r--lib/AST/Decl.cpp79
-rw-r--r--lib/AST/DeclCXX.cpp16
-rw-r--r--lib/AST/DeclGroup.cpp1
-rw-r--r--lib/AST/DeclarationName.cpp2
-rw-r--r--lib/AST/Expr.cpp56
-rw-r--r--lib/AST/ExprCXX.cpp73
-rw-r--r--lib/AST/ExprConstant.cpp72
-rw-r--r--lib/AST/FullExpr.cpp58
-rw-r--r--lib/AST/Stmt.cpp128
-rw-r--r--lib/AST/StmtIterator.cpp16
-rw-r--r--lib/AST/StmtProfile.cpp1
-rw-r--r--lib/AST/Type.cpp23
-rw-r--r--lib/AST/TypePrinter.cpp15
15 files changed, 456 insertions, 210 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index cc7055dc68b85..74e74e7aba0bd 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTContext.h"
+#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
@@ -55,44 +56,43 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM,
}
ASTContext::~ASTContext() {
- // Deallocate all the types.
- while (!Types.empty()) {
- Types.back()->Destroy(*this);
- Types.pop_back();
- }
+ if (FreeMemory) {
+ // Deallocate all the types.
+ while (!Types.empty()) {
+ Types.back()->Destroy(*this);
+ Types.pop_back();
+ }
- {
- llvm::FoldingSet<ExtQuals>::iterator
- I = ExtQualNodes.begin(), E = ExtQualNodes.end();
- while (I != E)
+ for (llvm::FoldingSet<ExtQuals>::iterator
+ I = ExtQualNodes.begin(), E = ExtQualNodes.end(); I != E; ) {
+ // Increment in loop to prevent using deallocated memory.
Deallocate(&*I++);
+ }
}
- {
- llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>::iterator
- I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end();
- while (I != E) {
- ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second);
- delete R;
- }
+ for (llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>::iterator
+ I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); I != E; ) {
+ // Increment in loop to prevent using deallocated memory.
+ ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second);
+ delete R;
}
- {
- llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*>::iterator
- I = ObjCLayouts.begin(), E = ObjCLayouts.end();
- while (I != E) {
- ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second);
- delete R;
- }
+ for (llvm::DenseMap<const ObjCContainerDecl*,
+ const ASTRecordLayout*>::iterator
+ I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; ) {
+ // Increment in loop to prevent using deallocated memory.
+ ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second);
+ delete R;
}
// Destroy nested-name-specifiers.
for (llvm::FoldingSet<NestedNameSpecifier>::iterator
NNS = NestedNameSpecifiers.begin(),
NNSEnd = NestedNameSpecifiers.end();
- NNS != NNSEnd;
- /* Increment in loop */)
+ NNS != NNSEnd; ) {
+ // Increment in loop to prevent using deallocated memory.
(*NNS++).Destroy(*this);
+ }
if (GlobalNestedNameSpecifier)
GlobalNestedNameSpecifier->Destroy(*this);
@@ -694,13 +694,6 @@ ASTContext::getTypeInfo(const Type *T) {
break;
}
break;
- case Type::FixedWidthInt:
- // FIXME: This isn't precisely correct; the width/alignment should depend
- // on the available types for the target
- Width = cast<FixedWidthIntType>(T)->getWidth();
- Width = std::max(llvm::NextPowerOf2(Width - 1), (uint64_t)8);
- Align = Width;
- break;
case Type::ObjCObjectPointer:
Width = Target.getPointerWidth(0);
Align = Target.getPointerAlign(0);
@@ -818,6 +811,15 @@ ASTContext::getTypeInfo(const Type *T) {
return std::make_pair(Width, Align);
}
+/// getTypeSizeInChars - Return the size of the specified type, in characters.
+/// This method does not work on incomplete types.
+CharUnits ASTContext::getTypeSizeInChars(QualType T) {
+ return CharUnits::fromRaw(getTypeSize(T) / getCharWidth());
+}
+CharUnits ASTContext::getTypeSizeInChars(const Type *T) {
+ return CharUnits::fromRaw(getTypeSize(T) / getCharWidth());
+}
+
/// getPreferredTypeAlign - Return the "preferred" alignment of the specified
/// type for the current target in bits. This can be different than the ABI
/// alignment in cases where it is beneficial for performance to overalign
@@ -1056,9 +1058,7 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
// Add in synthesized ivar count if laying out an implementation.
if (Impl) {
- unsigned FieldCount = D->ivar_size();
unsigned SynthCount = CountSynthesizedIvars(D);
- FieldCount += SynthCount;
// If there aren't any sythesized ivars then reuse the interface
// entry. Note we can't cache this because we simply free all
// entries later; however we shouldn't look up implementations
@@ -1267,15 +1267,6 @@ QualType ASTContext::getComplexType(QualType T) {
return QualType(New, 0);
}
-QualType ASTContext::getFixedWidthIntType(unsigned Width, bool Signed) {
- llvm::DenseMap<unsigned, FixedWidthIntType*> &Map = Signed ?
- SignedFixedWidthIntTypes : UnsignedFixedWidthIntTypes;
- FixedWidthIntType *&Entry = Map[Width];
- if (!Entry)
- Entry = new FixedWidthIntType(Width, Signed);
- return QualType(Entry, 0);
-}
-
/// getPointerType - Return the uniqued reference to the type for a pointer to
/// the specified type.
QualType ASTContext::getPointerType(QualType T) {
@@ -2381,6 +2372,42 @@ CanQualType ASTContext::getCanonicalType(QualType T) {
VAT->getBracketsRange()));
}
+QualType ASTContext::getUnqualifiedArrayType(QualType T,
+ Qualifiers &Quals) {
+ assert(T.isCanonical() && "Only operates on canonical types");
+ if (!isa<ArrayType>(T)) {
+ Quals = T.getLocalQualifiers();
+ return T.getLocalUnqualifiedType();
+ }
+
+ assert(!T.hasQualifiers() && "canonical array type has qualifiers!");
+ const ArrayType *AT = cast<ArrayType>(T);
+ QualType Elt = AT->getElementType();
+ QualType UnqualElt = getUnqualifiedArrayType(getCanonicalType(Elt), Quals);
+ if (Elt == UnqualElt)
+ return T;
+
+ if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(T)) {
+ return getConstantArrayType(UnqualElt, CAT->getSize(),
+ CAT->getSizeModifier(), 0);
+ }
+
+ if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(T)) {
+ return getIncompleteArrayType(UnqualElt, IAT->getSizeModifier(), 0);
+ }
+
+ if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(T)) {
+ return getVariableArrayType(UnqualElt, VAT->getSizeExpr()->Retain(),
+ VAT->getSizeModifier(), 0,
+ SourceRange());
+ }
+
+ const DependentSizedArrayType *DSAT = cast<DependentSizedArrayType>(T);
+ return getDependentSizedArrayType(UnqualElt, DSAT->getSizeExpr()->Retain(),
+ DSAT->getSizeModifier(), 0,
+ SourceRange());
+}
+
DeclarationName ASTContext::getNameForTemplate(TemplateName Name) {
if (TemplateDecl *TD = Name.getAsTemplateDecl())
return TD->getDeclName();
@@ -2682,12 +2709,6 @@ unsigned ASTContext::getIntegerRank(Type *T) {
if (T->isSpecificBuiltinType(BuiltinType::Char32))
T = getFromTargetType(Target.getChar32Type()).getTypePtr();
- // There are two things which impact the integer rank: the width, and
- // the ordering of builtins. The builtin ordering is encoded in the
- // bottom three bits; the width is encoded in the bits above that.
- if (FixedWidthIntType* FWIT = dyn_cast<FixedWidthIntType>(T))
- return FWIT->getWidth() << 3;
-
switch (cast<BuiltinType>(T)->getKind()) {
default: assert(0 && "getIntegerRank(): not a built-in integer");
case BuiltinType::Bool:
@@ -4500,9 +4521,6 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
return QualType();
}
- case Type::FixedWidthInt:
- // Distinct fixed-width integers are not compatible.
- return QualType();
case Type::TemplateSpecialization:
assert(false && "Dependent types have no size");
break;
@@ -4518,9 +4536,6 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
unsigned ASTContext::getIntWidth(QualType T) {
if (T->isBooleanType())
return 1;
- if (FixedWidthIntType *FWIT = dyn_cast<FixedWidthIntType>(T)) {
- return FWIT->getWidth();
- }
if (EnumType *ET = dyn_cast<EnumType>(T))
T = ET->getDecl()->getIntegerType();
// For builtin types, just use the standard type sizing method
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index 0f0b22d65f6f9..5aecf878c920b 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangAST
Expr.cpp
ExprCXX.cpp
ExprConstant.cpp
+ FullExpr.cpp
InheritViz.cpp
NestedNameSpecifier.cpp
ParentMap.cpp
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 4d0d4225ce738..e112fa3928ded 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -19,6 +19,7 @@
#include "clang/AST/TypeLoc.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/IdentifierTable.h"
@@ -91,6 +92,34 @@ ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC,
return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, TInfo, S, DefArg);
}
+Expr *ParmVarDecl::getDefaultArg() {
+ assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!");
+ assert(!hasUninstantiatedDefaultArg() &&
+ "Default argument is not yet instantiated!");
+
+ Expr *Arg = getInit();
+ if (CXXExprWithTemporaries *E = dyn_cast_or_null<CXXExprWithTemporaries>(Arg))
+ return E->getSubExpr();
+
+ return Arg;
+}
+
+unsigned ParmVarDecl::getNumDefaultArgTemporaries() const {
+ if (const CXXExprWithTemporaries *E =
+ dyn_cast<CXXExprWithTemporaries>(getInit()))
+ return E->getNumTemporaries();
+
+ return 0;
+}
+
+CXXTemporary *ParmVarDecl::getDefaultArgTemporary(unsigned i) {
+ assert(getNumDefaultArgTemporaries() &&
+ "Default arguments does not have any temporaries!");
+
+ CXXExprWithTemporaries *E = cast<CXXExprWithTemporaries>(getInit());
+ return E->getTemporary(i);
+}
+
SourceRange ParmVarDecl::getDefaultArgRange() const {
if (const Expr *E = getInit())
return E->getSourceRange();
@@ -183,6 +212,9 @@ TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
return new (C) TypedefDecl(DC, L, Id, TInfo);
}
+// Anchor TypedefDecl's vtable here.
+TypedefDecl::~TypedefDecl() {}
+
EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, SourceLocation TKL,
EnumDecl *PrevDecl) {
@@ -426,11 +458,6 @@ std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const {
return getNameAsString();
while (Ctx) {
- if (Ctx->isFunctionOrMethod())
- // FIXME: That probably will happen, when D was member of local
- // scope class/struct/union. How do we handle this case?
- break;
-
if (const ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) {
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
@@ -440,6 +467,48 @@ std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const {
TemplateArgs.flat_size(),
P);
Names.push_back(Spec->getIdentifier()->getNameStart() + TemplateArgsStr);
+ } else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(Ctx)) {
+ if (ND->isAnonymousNamespace())
+ Names.push_back("<anonymous namespace>");
+ else
+ Names.push_back(ND->getNameAsString());
+ } else if (const RecordDecl *RD = dyn_cast<RecordDecl>(Ctx)) {
+ if (!RD->getIdentifier()) {
+ std::string RecordString = "<anonymous ";
+ RecordString += RD->getKindName();
+ RecordString += ">";
+ Names.push_back(RecordString);
+ } else {
+ Names.push_back(RD->getNameAsString());
+ }
+ } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Ctx)) {
+ std::string Proto = FD->getNameAsString();
+
+ const FunctionProtoType *FT = 0;
+ if (FD->hasWrittenPrototype())
+ FT = dyn_cast<FunctionProtoType>(FD->getType()->getAs<FunctionType>());
+
+ Proto += "(";
+ if (FT) {
+ llvm::raw_string_ostream POut(Proto);
+ unsigned NumParams = FD->getNumParams();
+ for (unsigned i = 0; i < NumParams; ++i) {
+ if (i)
+ POut << ", ";
+ std::string Param;
+ FD->getParamDecl(i)->getType().getAsStringInternal(Param, P);
+ POut << Param;
+ }
+
+ if (FT->isVariadic()) {
+ if (NumParams > 0)
+ POut << ", ";
+ POut << "...";
+ }
+ }
+ Proto += ")";
+
+ Names.push_back(Proto);
} else if (const NamedDecl *ND = dyn_cast<NamedDecl>(Ctx))
Names.push_back(ND->getNameAsString());
else
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 292a3ed630cac..bbbb19a35b4a8 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -164,8 +164,7 @@ CXXConstructorDecl *CXXRecordDecl::getCopyConstructor(ASTContext &Context,
if (isa<FunctionTemplateDecl>(*Con))
continue;
- if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(Context,
- FoundTQs)) {
+ if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(FoundTQs)) {
if (((TypeQuals & Qualifiers::Const) == (FoundTQs & Qualifiers::Const)) ||
(!(TypeQuals & Qualifiers::Const) && (FoundTQs & Qualifiers::Const)))
return cast<CXXConstructorDecl>(*Con);
@@ -246,7 +245,7 @@ CXXRecordDecl::addedConstructor(ASTContext &Context,
// Note when we have a user-declared copy constructor, which will
// suppress the implicit declaration of a copy constructor.
- if (ConDecl->isCopyConstructor(Context)) {
+ if (ConDecl->isCopyConstructor()) {
UserDeclaredCopyConstructor = true;
// C++ [class.copy]p6:
@@ -757,8 +756,7 @@ bool CXXConstructorDecl::isDefaultConstructor() const {
}
bool
-CXXConstructorDecl::isCopyConstructor(ASTContext &Context,
- unsigned &TypeQuals) const {
+CXXConstructorDecl::isCopyConstructor(unsigned &TypeQuals) const {
// C++ [class.copy]p2:
// A non-template constructor for class X is a copy constructor
// if its first parameter is of type X&, const X&, volatile X& or
@@ -779,6 +777,8 @@ CXXConstructorDecl::isCopyConstructor(ASTContext &Context,
return false;
// Is it a reference to our class type?
+ ASTContext &Context = getASTContext();
+
CanQualType PointeeType
= Context.getCanonicalType(ParamRefType->getPointeeType());
CanQualType ClassTy
@@ -874,7 +874,11 @@ FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC,
isa<CXXRecordDecl>(D) ||
isa<FunctionTemplateDecl>(D) ||
isa<ClassTemplateDecl>(D));
- assert(D->getFriendObjectKind());
+
+ // As a temporary hack, we permit template instantiation to point
+ // to the original declaration when instantiating members.
+ assert(D->getFriendObjectKind() ||
+ (cast<CXXRecordDecl>(DC)->getTemplateSpecializationKind()));
}
#endif
diff --git a/lib/AST/DeclGroup.cpp b/lib/AST/DeclGroup.cpp
index 5bdc881734613..434bf00d354e3 100644
--- a/lib/AST/DeclGroup.cpp
+++ b/lib/AST/DeclGroup.cpp
@@ -32,6 +32,7 @@ DeclGroup::DeclGroup(unsigned numdecls, Decl** decls) : NumDecls(numdecls) {
}
void DeclGroup::Destroy(ASTContext& C) {
+ // Decls are destroyed by the DeclContext.
this->~DeclGroup();
C.Deallocate((void*) this);
}
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index 0ce03c2140543..60c40e24fb31c 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/lib/AST/DeclarationName.cpp
@@ -210,7 +210,7 @@ std::string DeclarationName::getAsString() const {
}
case CXXOperatorName: {
- static const char *OperatorNames[NUM_OVERLOADED_OPERATORS] = {
+ static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
0,
#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
Spelling,
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 139e04b2ed5e1..04a6abca87c96 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -174,6 +174,8 @@ std::string PredefinedExpr::ComputeName(ASTContext &Context, IdentType IT,
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
if (MD->isVirtual())
Out << "virtual ";
+ if (MD->isStatic())
+ Out << "static ";
}
PrintingPolicy Policy(Context.getLangOptions());
@@ -203,6 +205,14 @@ std::string PredefinedExpr::ComputeName(ASTContext &Context, IdentType IT,
}
Proto += ")";
+ if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+ Qualifiers ThisQuals = Qualifiers::fromCVRMask(MD->getTypeQualifiers());
+ if (ThisQuals.hasConst())
+ Proto += " const";
+ if (ThisQuals.hasVolatile())
+ Proto += " volatile";
+ }
+
if (!isa<CXXConstructorDecl>(FD) && !isa<CXXDestructorDecl>(FD))
AFT->getResultType().getAsStringInternal(Proto, Policy);
@@ -398,14 +408,20 @@ void CallExpr::DoDestroy(ASTContext& C) {
C.Deallocate(this);
}
-FunctionDecl *CallExpr::getDirectCallee() {
+Decl *CallExpr::getCalleeDecl() {
Expr *CEE = getCallee()->IgnoreParenCasts();
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE))
- return dyn_cast<FunctionDecl>(DRE->getDecl());
+ return DRE->getDecl();
+ if (MemberExpr *ME = dyn_cast<MemberExpr>(CEE))
+ return ME->getMemberDecl();
return 0;
}
+FunctionDecl *CallExpr::getDirectCallee() {
+ return dyn_cast_or_null<FunctionDecl>(getCalleeDecl());
+}
+
/// 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.
@@ -858,7 +874,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
case CXXMemberCallExprClass: {
// If this is a direct call, get the callee.
const CallExpr *CE = cast<CallExpr>(this);
- if (const FunctionDecl *FD = CE->getDirectCallee()) {
+ if (const Decl *FD = CE->getCalleeDecl()) {
// If the callee has attribute pure, const, or warn_unused_result, warn
// about it. void foo() { strlen("bar"); } should warn.
//
@@ -1047,8 +1063,13 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const {
// -- If E2 is a non-static data member [...]. If E1 is an
// lvalue, then E1.E2 is an lvalue.
- if (isa<FieldDecl>(Member))
- return m->isArrow() ? LV_Valid : m->getBase()->isLvalue(Ctx);
+ if (isa<FieldDecl>(Member)) {
+ if (m->isArrow())
+ return LV_Valid;
+ Expr *BaseExp = m->getBase();
+ return (BaseExp->getStmtClass() == ObjCPropertyRefExprClass) ?
+ LV_SubObjCPropertySetting : BaseExp->isLvalue(Ctx);
+ }
// -- If it refers to a static member function [...], then
// E1.E2 is an lvalue.
@@ -1065,9 +1086,13 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const {
// Not an lvalue.
return LV_InvalidExpression;
}
-
+
// C99 6.5.2.3p4
- return m->isArrow() ? LV_Valid : m->getBase()->isLvalue(Ctx);
+ if (m->isArrow())
+ return LV_Valid;
+ Expr *BaseExp = m->getBase();
+ return (BaseExp->getStmtClass() == ObjCPropertyRefExprClass) ?
+ LV_SubObjCPropertySetting : BaseExp->isLvalue(Ctx);
}
case UnaryOperatorClass:
if (cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::Deref)
@@ -1204,6 +1229,16 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const {
return LV_Valid;
}
+ case Expr::CXXExprWithTemporariesClass:
+ return cast<CXXExprWithTemporaries>(this)->getSubExpr()->isLvalue(Ctx);
+
+ case Expr::ObjCMessageExprClass:
+ if (const ObjCMethodDecl *Method
+ = cast<ObjCMessageExpr>(this)->getMethodDecl())
+ if (Method->getResultType()->isLValueReferenceType())
+ return LV_Valid;
+ break;
+
default:
break;
}
@@ -1244,6 +1279,7 @@ Expr::isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc) const {
}
return MLV_InvalidExpression;
case LV_MemberFunction: return MLV_MemberFunction;
+ case LV_SubObjCPropertySetting: return MLV_SubObjCPropertySetting;
}
// The following is illegal:
@@ -1996,7 +2032,7 @@ ObjCMessageExpr::ObjCMessageExpr(Expr *receiver, Selector selInfo,
QualType retType, ObjCMethodDecl *mproto,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned nargs)
- : Expr(ObjCMessageExprClass, retType), SelName(selInfo),
+ : Expr(ObjCMessageExprClass, retType, false, false), SelName(selInfo),
MethodProto(mproto) {
NumArgs = nargs;
SubExprs = new Stmt*[NumArgs+1];
@@ -2015,7 +2051,7 @@ ObjCMessageExpr::ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
QualType retType, ObjCMethodDecl *mproto,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned nargs)
- : Expr(ObjCMessageExprClass, retType), SelName(selInfo),
+ : Expr(ObjCMessageExprClass, retType, false, false), SelName(selInfo),
MethodProto(mproto) {
NumArgs = nargs;
SubExprs = new Stmt*[NumArgs+1];
@@ -2033,7 +2069,7 @@ ObjCMessageExpr::ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo,
QualType retType, ObjCMethodDecl *mproto,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned nargs)
-: Expr(ObjCMessageExprClass, retType), SelName(selInfo),
+: Expr(ObjCMessageExprClass, retType, false, false), SelName(selInfo),
MethodProto(mproto) {
NumArgs = nargs;
SubExprs = new Stmt*[NumArgs+1];
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index a9f96adae137b..81584b700270b 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -282,6 +282,18 @@ bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const {
}
}
+SourceRange CXXConstructExpr::getSourceRange() const {
+ // FIXME: Should we know where the parentheses are, if there are any?
+ for (std::reverse_iterator<Stmt**> I(&Args[NumArgs]), E(&Args[0]); I!=E;++I) {
+ // Ignore CXXDefaultExprs when computing the range, as they don't
+ // have a range.
+ if (!isa<CXXDefaultArgExpr>(*I))
+ return SourceRange(Loc, (*I)->getLocEnd());
+ }
+
+ return SourceRange(Loc);
+}
+
SourceRange CXXOperatorCallExpr::getSourceRange() const {
OverloadedOperatorKind Kind = getOperator();
if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
@@ -340,6 +352,21 @@ const char *CXXNamedCastExpr::getCastName() const {
}
}
+CXXDefaultArgExpr *
+CXXDefaultArgExpr::Create(ASTContext &C, SourceLocation Loc,
+ ParmVarDecl *Param, Expr *SubExpr) {
+ void *Mem = C.Allocate(sizeof(CXXDefaultArgExpr) + sizeof(Stmt *));
+ return new (Mem) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param,
+ SubExpr);
+}
+
+void CXXDefaultArgExpr::DoDestroy(ASTContext &C) {
+ if (Param.getInt())
+ getExpr()->Destroy(C);
+ this->~CXXDefaultArgExpr();
+ C.Deallocate(this);
+}
+
CXXTemporary *CXXTemporary::Create(ASTContext &C,
const CXXDestructorDecl *Destructor) {
return new (C) CXXTemporary(Destructor);
@@ -372,34 +399,40 @@ CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C,
Expr **Args,
unsigned NumArgs,
SourceLocation rParenLoc)
- : CXXConstructExpr(C, CXXTemporaryObjectExprClass, writtenTy, Cons,
- false, Args, NumArgs),
+ : CXXConstructExpr(C, CXXTemporaryObjectExprClass, writtenTy, tyBeginLoc,
+ Cons, false, Args, NumArgs),
TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {
}
CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T,
+ SourceLocation Loc,
CXXConstructorDecl *D, bool Elidable,
- Expr **Args, unsigned NumArgs) {
- return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, D, Elidable,
- Args, NumArgs);
+ Expr **Args, unsigned NumArgs,
+ bool ZeroInitialization) {
+ return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D,
+ Elidable, Args, NumArgs, ZeroInitialization);
}
CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
+ SourceLocation Loc,
CXXConstructorDecl *D, bool elidable,
- Expr **args, unsigned numargs)
+ Expr **args, unsigned numargs,
+ bool ZeroInitialization)
: Expr(SC, T,
T->isDependentType(),
(T->isDependentType() ||
CallExpr::hasAnyValueDependentArguments(args, numargs))),
- Constructor(D), Elidable(elidable), Args(0), NumArgs(numargs) {
- if (NumArgs) {
- Args = new (C) Stmt*[NumArgs];
-
- for (unsigned i = 0; i != NumArgs; ++i) {
- assert(args[i] && "NULL argument in CXXConstructExpr");
- Args[i] = args[i];
- }
+ Constructor(D), Loc(Loc), Elidable(elidable),
+ ZeroInitialization(ZeroInitialization), Args(0), NumArgs(numargs)
+{
+ if (NumArgs) {
+ Args = new (C) Stmt*[NumArgs];
+
+ for (unsigned i = 0; i != NumArgs; ++i) {
+ assert(args[i] && "NULL argument in CXXConstructExpr");
+ Args[i] = args[i];
}
+ }
}
CXXConstructExpr::CXXConstructExpr(EmptyShell Empty, ASTContext &C,
@@ -420,12 +453,10 @@ void CXXConstructExpr::DoDestroy(ASTContext &C) {
CXXExprWithTemporaries::CXXExprWithTemporaries(Expr *subexpr,
CXXTemporary **temps,
- unsigned numtemps,
- bool shoulddestroytemps)
+ unsigned numtemps)
: Expr(CXXExprWithTemporariesClass, subexpr->getType(),
subexpr->isTypeDependent(), subexpr->isValueDependent()),
- SubExpr(subexpr), Temps(0), NumTemps(numtemps),
- ShouldDestroyTemps(shoulddestroytemps) {
+ SubExpr(subexpr), Temps(0), NumTemps(numtemps) {
if (NumTemps > 0) {
Temps = new CXXTemporary*[NumTemps];
for (unsigned i = 0; i < NumTemps; ++i)
@@ -436,10 +467,8 @@ CXXExprWithTemporaries::CXXExprWithTemporaries(Expr *subexpr,
CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C,
Expr *SubExpr,
CXXTemporary **Temps,
- unsigned NumTemps,
- bool ShouldDestroyTemps){
- return new (C) CXXExprWithTemporaries(SubExpr, Temps, NumTemps,
- ShouldDestroyTemps);
+ unsigned NumTemps) {
+ return new (C) CXXExprWithTemporaries(SubExpr, Temps, NumTemps);
}
void CXXExprWithTemporaries::DoDestroy(ASTContext &C) {
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 13831dc1f52cd..06afec7675f12 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -222,7 +222,6 @@ public:
APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
APValue VisitDeclRefExpr(DeclRefExpr *E);
- APValue VisitBlockExpr(BlockExpr *E);
APValue VisitPredefinedExpr(PredefinedExpr *E) { return APValue(E, 0); }
APValue VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
APValue VisitMemberExpr(MemberExpr *E);
@@ -270,13 +269,6 @@ APValue LValueExprEvaluator::VisitDeclRefExpr(DeclRefExpr *E) {
return APValue();
}
-APValue LValueExprEvaluator::VisitBlockExpr(BlockExpr *E) {
- if (E->hasBlockDeclRefExprs())
- return APValue();
-
- return APValue(E, 0);
-}
-
APValue LValueExprEvaluator::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
if (!Info.AnyLValue && !E->isFileScope())
return APValue();
@@ -366,7 +358,7 @@ public:
APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
APValue VisitBinaryOperator(const BinaryOperator *E);
- APValue VisitCastExpr(const CastExpr* E);
+ APValue VisitCastExpr(CastExpr* E);
APValue VisitUnaryExtension(const UnaryOperator *E)
{ return Visit(E->getSubExpr()); }
APValue VisitUnaryAddrOf(const UnaryOperator *E);
@@ -443,23 +435,49 @@ APValue PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) {
}
-APValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
- const Expr* SubExpr = E->getSubExpr();
+APValue PointerExprEvaluator::VisitCastExpr(CastExpr* E) {
+ Expr* SubExpr = E->getSubExpr();
- // Check for pointer->pointer cast
- if (SubExpr->getType()->isPointerType() ||
- SubExpr->getType()->isObjCObjectPointerType() ||
- SubExpr->getType()->isNullPtrType()) {
- APValue Result;
- if (EvaluatePointer(SubExpr, Result, Info))
+ switch (E->getCastKind()) {
+ default:
+ break;
+
+ case CastExpr::CK_Unknown: {
+ // FIXME: The handling for CK_Unknown is ugly/shouldn't be necessary!
+
+ // Check for pointer->pointer cast
+ if (SubExpr->getType()->isPointerType() ||
+ SubExpr->getType()->isObjCObjectPointerType() ||
+ SubExpr->getType()->isNullPtrType() ||
+ SubExpr->getType()->isBlockPointerType())
+ return Visit(SubExpr);
+
+ if (SubExpr->getType()->isIntegralType()) {
+ APValue Result;
+ if (!EvaluateIntegerOrLValue(SubExpr, Result, Info))
+ break;
+
+ if (Result.isInt()) {
+ Result.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
+ return APValue(0, Result.getInt().getZExtValue());
+ }
+
+ // Cast is of an lvalue, no need to change value.
return Result;
- return APValue();
+ }
+ break;
}
- if (SubExpr->getType()->isIntegralType()) {
+ case CastExpr::CK_NoOp:
+ case CastExpr::CK_BitCast:
+ case CastExpr::CK_AnyPointerToObjCPointerCast:
+ case CastExpr::CK_AnyPointerToBlockPointerCast:
+ return Visit(SubExpr);
+
+ case CastExpr::CK_IntegralToPointer: {
APValue Result;
if (!EvaluateIntegerOrLValue(SubExpr, Result, Info))
- return APValue();
+ break;
if (Result.isInt()) {
Result.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
@@ -469,14 +487,13 @@ APValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
// Cast is of an lvalue, no need to change value.
return Result;
}
-
- if (SubExpr->getType()->isFunctionType() ||
- SubExpr->getType()->isBlockPointerType() ||
- SubExpr->getType()->isArrayType()) {
+ case CastExpr::CK_ArrayToPointerDecay:
+ case CastExpr::CK_FunctionToPointerDecay: {
APValue Result;
if (EvaluateLValue(SubExpr, Result, Info))
return Result;
- return APValue();
+ break;
+ }
}
return APValue();
@@ -970,8 +987,9 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
}
}
+ // TODO: Perhaps we should let LLVM lower this?
if (E->getArg(0)->HasSideEffects(Info.Ctx)) {
- if (E->getArg(1)->EvaluateAsInt(Info.Ctx).getZExtValue() < 2)
+ if (E->getArg(1)->EvaluateAsInt(Info.Ctx).getZExtValue() == 0)
return Success(-1ULL, E);
return Success(0, E);
}
@@ -1290,8 +1308,6 @@ unsigned IntExprEvaluator::GetAlignOfExpr(const Expr *E) {
/// VisitSizeAlignOfExpr - Evaluate a sizeof or alignof with a result as the
/// expression's type.
bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
- QualType DstTy = E->getType();
-
// Handle alignof separately.
if (!E->isSizeOf()) {
if (E->isArgumentType())
diff --git a/lib/AST/FullExpr.cpp b/lib/AST/FullExpr.cpp
new file mode 100644
index 0000000000000..f47284f3d0604
--- /dev/null
+++ b/lib/AST/FullExpr.cpp
@@ -0,0 +1,58 @@
+//===--- FullExpr.cpp - C++ full expression class ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the FullExpr interface, to be used for type safe handling
+// of full expressions.
+//
+// Full expressions are described in C++ [intro.execution]p12.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/FullExpr.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "llvm/Support/AlignOf.h"
+using namespace clang;
+
+FullExpr FullExpr::Create(ASTContext &Context, Expr *SubExpr,
+ CXXTemporary **Temporaries, unsigned NumTemporaries) {
+ FullExpr E;
+
+ if (!NumTemporaries) {
+ E.SubExpr = SubExpr;
+ return E;
+ }
+
+ unsigned Size = sizeof(FullExpr)
+ + sizeof(CXXTemporary *) * NumTemporaries;
+
+ unsigned Align = llvm::AlignOf<ExprAndTemporaries>::Alignment;
+ ExprAndTemporaries *ET =
+ static_cast<ExprAndTemporaries *>(Context.Allocate(Size, Align));
+
+ ET->SubExpr = SubExpr;
+ std::copy(Temporaries, Temporaries + NumTemporaries, ET->temps_begin());
+
+ return E;
+}
+
+void FullExpr::Destroy(ASTContext &Context) {
+ if (Expr *E = SubExpr.dyn_cast<Expr *>()) {
+ E->Destroy(Context);
+ return;
+ }
+
+ ExprAndTemporaries *ET = SubExpr.get<ExprAndTemporaries *>();
+ for (ExprAndTemporaries::temps_iterator i = ET->temps_begin(),
+ e = ET->temps_end(); i != e; ++i)
+ (*i)->Destroy(Context);
+
+ Context.Deallocate(ET);
+}
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index fad80ec0cf23d..7c7aeb8d3e1df 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -47,17 +47,6 @@ const char *Stmt::getStmtClassName() const {
return getStmtInfoTableEntry((StmtClass)sClass).Name;
}
-void Stmt::DestroyChildren(ASTContext &C) {
- for (child_iterator I = child_begin(), E = child_end(); I !=E; )
- if (Stmt* Child = *I++) Child->Destroy(C);
-}
-
-void Stmt::DoDestroy(ASTContext &C) {
- DestroyChildren(C);
- this->~Stmt();
- C.Deallocate((void *)this);
-}
-
void Stmt::PrintStats() {
// Ensure the table is primed.
getStmtInfoTableEntry(Stmt::NullStmtClass);
@@ -93,20 +82,6 @@ bool Stmt::CollectingStats(bool Enable) {
return StatSwitch;
}
-void SwitchStmt::DoDestroy(ASTContext &Ctx) {
- // Destroy the SwitchCase statements in this switch. In the normal
- // case, this loop will merely decrement the reference counts from
- // the Retain() calls in addSwitchCase();
- SwitchCase *SC = FirstCase;
- while (SC) {
- SwitchCase *Next = SC->getNextSwitchCase();
- SC->Destroy(Ctx);
- SC = Next;
- }
-
- Stmt::DoDestroy(Ctx);
-}
-
void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
if (this->Body)
C.Deallocate(Body);
@@ -412,6 +387,71 @@ ObjCAtCatchStmt::ObjCAtCatchStmt(SourceLocation atCatchLoc,
RParenLoc = rparenloc;
}
+//===----------------------------------------------------------------------===//
+// AST Destruction.
+//===----------------------------------------------------------------------===//
+
+void Stmt::DestroyChildren(ASTContext &C) {
+ for (child_iterator I = child_begin(), E = child_end(); I !=E; )
+ if (Stmt* Child = *I++) Child->Destroy(C);
+}
+
+static void BranchDestroy(ASTContext &C, Stmt *S, Stmt **SubExprs,
+ unsigned NumExprs) {
+ // We do not use child_iterator here because that will include
+ // the expressions referenced by the condition variable.
+ for (Stmt **I = SubExprs, **E = SubExprs + NumExprs; I != E; ++I)
+ if (Stmt *Child = *I) Child->Destroy(C);
+
+ S->~Stmt();
+ C.Deallocate((void *) S);
+}
+
+void Stmt::DoDestroy(ASTContext &C) {
+ DestroyChildren(C);
+ this->~Stmt();
+ C.Deallocate((void *)this);
+}
+
+void CXXCatchStmt::DoDestroy(ASTContext& C) {
+ if (ExceptionDecl)
+ ExceptionDecl->Destroy(C);
+ Stmt::DoDestroy(C);
+}
+
+void DeclStmt::DoDestroy(ASTContext &C) {
+ // Don't use StmtIterator to iterate over the Decls, as that can recurse
+ // into VLA size expressions (which are owned by the VLA). Further, Decls
+ // are owned by the DeclContext, and will be destroyed with them.
+ if (DG.isDeclGroup())
+ DG.getDeclGroup().Destroy(C);
+}
+
+void IfStmt::DoDestroy(ASTContext &C) {
+ BranchDestroy(C, this, SubExprs, END_EXPR);
+}
+
+void ForStmt::DoDestroy(ASTContext &C) {
+ BranchDestroy(C, this, SubExprs, END_EXPR);
+}
+
+void SwitchStmt::DoDestroy(ASTContext &C) {
+ // Destroy the SwitchCase statements in this switch. In the normal
+ // case, this loop will merely decrement the reference counts from
+ // the Retain() calls in addSwitchCase();
+ SwitchCase *SC = FirstCase;
+ while (SC) {
+ SwitchCase *Next = SC->getNextSwitchCase();
+ SC->Destroy(C);
+ SC = Next;
+ }
+
+ BranchDestroy(C, this, SubExprs, END_EXPR);
+}
+
+void WhileStmt::DoDestroy(ASTContext &C) {
+ BranchDestroy(C, this, SubExprs, END_EXPR);
+}
//===----------------------------------------------------------------------===//
// Child Iterators for iterating over subexpressions/substatements
@@ -447,24 +487,40 @@ Stmt::child_iterator LabelStmt::child_begin() { return &SubStmt; }
Stmt::child_iterator LabelStmt::child_end() { return &SubStmt+1; }
// IfStmt
-Stmt::child_iterator IfStmt::child_begin() { return &SubExprs[0]; }
-Stmt::child_iterator IfStmt::child_end() { return &SubExprs[0]+END_EXPR; }
+Stmt::child_iterator IfStmt::child_begin() {
+ return child_iterator(Var, &SubExprs[0]);
+}
+Stmt::child_iterator IfStmt::child_end() {
+ return child_iterator(0, &SubExprs[0]+END_EXPR);
+}
// SwitchStmt
-Stmt::child_iterator SwitchStmt::child_begin() { return &SubExprs[0]; }
-Stmt::child_iterator SwitchStmt::child_end() { return &SubExprs[0]+END_EXPR; }
+Stmt::child_iterator SwitchStmt::child_begin() {
+ return child_iterator(Var, &SubExprs[0]);
+}
+Stmt::child_iterator SwitchStmt::child_end() {
+ return child_iterator(0, &SubExprs[0]+END_EXPR);
+}
// WhileStmt
-Stmt::child_iterator WhileStmt::child_begin() { return &SubExprs[0]; }
-Stmt::child_iterator WhileStmt::child_end() { return &SubExprs[0]+END_EXPR; }
+Stmt::child_iterator WhileStmt::child_begin() {
+ return child_iterator(Var, &SubExprs[0]);
+}
+Stmt::child_iterator WhileStmt::child_end() {
+ return child_iterator(0, &SubExprs[0]+END_EXPR);
+}
// DoStmt
Stmt::child_iterator DoStmt::child_begin() { return &SubExprs[0]; }
Stmt::child_iterator DoStmt::child_end() { return &SubExprs[0]+END_EXPR; }
// ForStmt
-Stmt::child_iterator ForStmt::child_begin() { return &SubExprs[0]; }
-Stmt::child_iterator ForStmt::child_end() { return &SubExprs[0]+END_EXPR; }
+Stmt::child_iterator ForStmt::child_begin() {
+ return child_iterator(CondVar, &SubExprs[0]);
+}
+Stmt::child_iterator ForStmt::child_end() {
+ return child_iterator(0, &SubExprs[0]+END_EXPR);
+}
// ObjCForCollectionStmt
Stmt::child_iterator ObjCForCollectionStmt::child_begin() {
@@ -565,12 +621,6 @@ QualType CXXCatchStmt::getCaughtType() const {
return QualType();
}
-void CXXCatchStmt::DoDestroy(ASTContext& C) {
- if (ExceptionDecl)
- ExceptionDecl->Destroy(C);
- Stmt::DoDestroy(C);
-}
-
// CXXTryStmt
Stmt::child_iterator CXXTryStmt::child_begin() { return &Stmts[0]; }
Stmt::child_iterator CXXTryStmt::child_end() { return &Stmts[0]+Stmts.size(); }
diff --git a/lib/AST/StmtIterator.cpp b/lib/AST/StmtIterator.cpp
index 4f62b66e257df..7fc7c96750ded 100644
--- a/lib/AST/StmtIterator.cpp
+++ b/lib/AST/StmtIterator.cpp
@@ -65,7 +65,7 @@ void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
assert (getVAPtr() == NULL);
if (inDecl()) {
- assert (decl);
+ assert(decl);
// FIXME: SIMPLIFY AWAY.
if (ImmediateAdvance)
@@ -74,7 +74,7 @@ void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
return;
}
else {
- assert (inDeclGroup());
+ assert(inDeclGroup());
if (ImmediateAdvance)
++DGI;
@@ -113,19 +113,19 @@ bool StmtIteratorBase::HandleDecl(Decl* D) {
return false;
}
-StmtIteratorBase::StmtIteratorBase(Decl* d)
- : decl(d), RawVAPtr(DeclMode) {
- assert (decl);
- NextDecl(false);
+StmtIteratorBase::StmtIteratorBase(Decl *d, Stmt **s)
+ : stmt(s), decl(d), RawVAPtr(d ? DeclMode : 0) {
+ if (decl)
+ NextDecl(false);
}
StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge)
- : DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
+ : stmt(0), DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
NextDecl(false);
}
StmtIteratorBase::StmtIteratorBase(VariableArrayType* t)
-: decl(0), RawVAPtr(SizeOfTypeVAMode) {
+ : stmt(0), decl(0), RawVAPtr(SizeOfTypeVAMode) {
RawVAPtr |= reinterpret_cast<uintptr_t>(t);
}
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index e2d772b7dd12a..b74e1ef0bab46 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -540,7 +540,6 @@ StmtProfiler::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *S) {
void StmtProfiler::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *S) {
VisitExpr(S);
- ID.AddBoolean(S->shouldDestroyTemporaries());
for (unsigned I = 0, N = S->getNumTemporaries(); I != N; ++I)
VisitDecl(
const_cast<CXXDestructorDecl *>(S->getTemporary(I)->getDestructor()));
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 687beaea08c26..e0055f1878259 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -387,8 +387,6 @@ bool Type::isIntegerType() const {
// FIXME: In C++, enum types are never integer types.
if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
return true;
- if (isa<FixedWidthIntType>(CanonicalType))
- return true;
if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
return VT->getElementType()->isIntegerType();
return false;
@@ -397,13 +395,11 @@ bool Type::isIntegerType() const {
bool Type::isIntegralType() const {
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() >= BuiltinType::Bool &&
- BT->getKind() <= BuiltinType::LongLong;
+ BT->getKind() <= BuiltinType::Int128;
if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
return true; // Complete enum types are integral.
// FIXME: In C++, enum types are never integral.
- if (isa<FixedWidthIntType>(CanonicalType))
- return true;
return false;
}
@@ -453,16 +449,12 @@ bool Type::isAnyCharacterType() const {
bool Type::isSignedIntegerType() const {
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
return BT->getKind() >= BuiltinType::Char_S &&
- BT->getKind() <= BuiltinType::LongLong;
+ BT->getKind() <= BuiltinType::Int128;
}
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
return ET->getDecl()->getIntegerType()->isSignedIntegerType();
- if (const FixedWidthIntType *FWIT =
- dyn_cast<FixedWidthIntType>(CanonicalType))
- return FWIT->isSigned();
-
if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
return VT->getElementType()->isSignedIntegerType();
return false;
@@ -481,10 +473,6 @@ bool Type::isUnsignedIntegerType() const {
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
- if (const FixedWidthIntType *FWIT =
- dyn_cast<FixedWidthIntType>(CanonicalType))
- return !FWIT->isSigned();
-
if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
return VT->getElementType()->isUnsignedIntegerType();
return false;
@@ -515,8 +503,6 @@ bool Type::isRealType() const {
BT->getKind() <= BuiltinType::LongDouble;
if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
return TT->getDecl()->isEnum() && TT->getDecl()->isDefinition();
- if (isa<FixedWidthIntType>(CanonicalType))
- return true;
if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
return VT->getElementType()->isRealType();
return false;
@@ -530,8 +516,6 @@ bool Type::isArithmeticType() const {
// GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2).
// If a body isn't seen by the time we get here, return false.
return ET->getDecl()->isDefinition();
- if (isa<FixedWidthIntType>(CanonicalType))
- return true;
return isa<ComplexType>(CanonicalType) || isa<VectorType>(CanonicalType);
}
@@ -545,8 +529,6 @@ bool Type::isScalarType() const {
return true;
return false;
}
- if (isa<FixedWidthIntType>(CanonicalType))
- return true;
return isa<PointerType>(CanonicalType) ||
isa<BlockPointerType>(CanonicalType) ||
isa<MemberPointerType>(CanonicalType) ||
@@ -725,6 +707,7 @@ bool Type::isSpecifierType() const {
case Typename:
case ObjCInterface:
case ObjCObjectPointer:
+ case Elaborated:
return true;
default:
return false;
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 4a2b956172907..818657c2a7634 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -94,21 +94,6 @@ void TypePrinter::PrintBuiltin(const BuiltinType *T, std::string &S) {
}
}
-void TypePrinter::PrintFixedWidthInt(const FixedWidthIntType *T,
- std::string &S) {
- // FIXME: Once we get bitwidth attribute, write as
- // "int __attribute__((bitwidth(x)))".
- std::string prefix = "__clang_fixedwidth";
- prefix += llvm::utostr_32(T->getWidth());
- prefix += (char)(T->isSigned() ? 'S' : 'U');
- if (S.empty()) {
- S = prefix;
- } else {
- // Prefix the basic type, e.g. 'int X'.
- S = prefix + S;
- }
-}
-
void TypePrinter::PrintComplex(const ComplexType *T, std::string &S) {
Print(T->getElementType(), S);
S = "_Complex " + S;