diff options
author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-01-01 10:34:51 +0000 |
---|---|---|
committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-01-01 10:34:51 +0000 |
commit | abe15e553e58165e7692c0d0842865c488ed7b45 (patch) | |
tree | 1e68501209c9133fbda8d45171e59f8d6f12dd55 /lib/AST | |
parent | 34d02d0b37f16015f317a935c48ce8b7b64ae77b (diff) |
Notes
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/ASTContext.cpp | 125 | ||||
-rw-r--r-- | lib/AST/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 79 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 16 | ||||
-rw-r--r-- | lib/AST/DeclGroup.cpp | 1 | ||||
-rw-r--r-- | lib/AST/DeclarationName.cpp | 2 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 56 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 73 | ||||
-rw-r--r-- | lib/AST/ExprConstant.cpp | 72 | ||||
-rw-r--r-- | lib/AST/FullExpr.cpp | 58 | ||||
-rw-r--r-- | lib/AST/Stmt.cpp | 128 | ||||
-rw-r--r-- | lib/AST/StmtIterator.cpp | 16 | ||||
-rw-r--r-- | lib/AST/StmtProfile.cpp | 1 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 23 | ||||
-rw-r--r-- | lib/AST/TypePrinter.cpp | 15 |
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; |