diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-01-15 15:39:40 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-01-15 15:39:40 +0000 |
commit | a3fa5c7f1b5e2ba4d6ec033dc0e2376326b05824 (patch) | |
tree | a6082d4d1d1e9ddaea09a6a04bb4a47da95d642d /lib/AST | |
parent | bb1e3bc1e0be2b8f891db46457a8943451bf4d8b (diff) | |
download | FreeBSD-src-a3fa5c7f1b5e2ba4d6ec033dc0e2376326b05824.zip FreeBSD-src-a3fa5c7f1b5e2ba4d6ec033dc0e2376326b05824.tar.gz |
Update clang to r93512.
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/APValue.cpp | 33 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 62 | ||||
-rw-r--r-- | lib/AST/AttrImpl.cpp | 143 | ||||
-rw-r--r-- | lib/AST/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 11 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 35 | ||||
-rw-r--r-- | lib/AST/DeclarationName.cpp | 51 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 30 | ||||
-rw-r--r-- | lib/AST/ExprConstant.cpp | 108 | ||||
-rw-r--r-- | lib/AST/RecordLayoutBuilder.cpp | 11 | ||||
-rw-r--r-- | lib/AST/Stmt.cpp | 4 | ||||
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 12 | ||||
-rw-r--r-- | lib/AST/TypeLoc.cpp | 12 | ||||
-rw-r--r-- | lib/AST/TypePrinter.cpp | 9 |
14 files changed, 396 insertions, 126 deletions
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp index 772a884..50a6e0a 100644 --- a/lib/AST/APValue.cpp +++ b/lib/AST/APValue.cpp @@ -12,9 +12,20 @@ //===----------------------------------------------------------------------===// #include "clang/AST/APValue.h" +#include "clang/AST/CharUnits.h" #include "llvm/Support/raw_ostream.h" using namespace clang; +namespace { + struct LV { + Expr* Base; + CharUnits Offset; + }; +} + +APValue::APValue(Expr* B) : Kind(Uninitialized) { + MakeLValue(); setLValue(B, CharUnits::Zero()); +} const APValue &APValue::operator=(const APValue &RHS) { if (Kind != RHS.Kind) { @@ -106,3 +117,25 @@ void APValue::print(llvm::raw_ostream &OS) const { } } +Expr* APValue::getLValueBase() const { + assert(isLValue() && "Invalid accessor"); + return ((const LV*)(const void*)Data)->Base; +} + +CharUnits APValue::getLValueOffset() const { + assert(isLValue() && "Invalid accessor"); + return ((const LV*)(const void*)Data)->Offset; +} + +void APValue::setLValue(Expr *B, const CharUnits &O) { + assert(isLValue() && "Invalid accessor"); + ((LV*)(char*)Data)->Base = B; + ((LV*)(char*)Data)->Offset = O; +} + +void APValue::MakeLValue() { + assert(isUninit() && "Bad state change"); + new ((void*)(char*)Data) LV(); + Kind = LValue; +} + diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 74e74e7..76ec852 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -814,10 +814,10 @@ ASTContext::getTypeInfo(const Type *T) { /// 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()); + return CharUnits::fromQuantity(getTypeSize(T) / getCharWidth()); } CharUnits ASTContext::getTypeSizeInChars(const Type *T) { - return CharUnits::fromRaw(getTypeSize(T) / getCharWidth()); + return CharUnits::fromQuantity(getTypeSize(T) / getCharWidth()); } /// getPreferredTypeAlign - Return the "preferred" alignment of the specified @@ -2374,16 +2374,14 @@ CanQualType ASTContext::getCanonicalType(QualType T) { QualType ASTContext::getUnqualifiedArrayType(QualType T, Qualifiers &Quals) { - assert(T.isCanonical() && "Only operates on canonical types"); + Quals = T.getQualifiers(); if (!isa<ArrayType>(T)) { - Quals = T.getLocalQualifiers(); - return T.getLocalUnqualifiedType(); + return T.getUnqualifiedType(); } - assert(!T.hasQualifiers() && "canonical array type has qualifiers!"); const ArrayType *AT = cast<ArrayType>(T); QualType Elt = AT->getElementType(); - QualType UnqualElt = getUnqualifiedArrayType(getCanonicalType(Elt), Quals); + QualType UnqualElt = getUnqualifiedArrayType(Elt, Quals); if (Elt == UnqualElt) return T; @@ -2396,12 +2394,6 @@ QualType ASTContext::getUnqualifiedArrayType(QualType 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, @@ -3143,16 +3135,21 @@ static bool isTypeTypedefedAsBOOL(QualType T) { /// getObjCEncodingTypeSize returns size of type for objective-c encoding /// purpose. -int ASTContext::getObjCEncodingTypeSize(QualType type) { - uint64_t sz = getTypeSize(type); +CharUnits ASTContext::getObjCEncodingTypeSize(QualType type) { + CharUnits sz = getTypeSizeInChars(type); // Make all integer and enum types at least as large as an int - if (sz > 0 && type->isIntegralType()) - sz = std::max(sz, getTypeSize(IntTy)); + if (sz.isPositive() && type->isIntegralType()) + sz = std::max(sz, getTypeSizeInChars(IntTy)); // Treat arrays as pointers, since that's how they're passed in. else if (type->isArrayType()) - sz = getTypeSize(VoidPtrTy); - return sz / getTypeSize(CharTy); + sz = getTypeSizeInChars(VoidPtrTy); + return sz; +} + +static inline +std::string charUnitsToString(const CharUnits &CU) { + return llvm::itostr(CU.getQuantity()); } /// getObjCEncodingForBlockDecl - Return the encoded type for this method @@ -3168,17 +3165,17 @@ void ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr, // Start with computing size of a pointer in number of bytes. // FIXME: There might(should) be a better way of doing this computation! SourceLocation Loc; - int PtrSize = getTypeSize(VoidPtrTy) / getTypeSize(CharTy); - int ParmOffset = PtrSize; + CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy); + CharUnits ParmOffset = PtrSize; for (ObjCMethodDecl::param_iterator PI = Decl->param_begin(), E = Decl->param_end(); PI != E; ++PI) { QualType PType = (*PI)->getType(); - int sz = getObjCEncodingTypeSize(PType); - assert (sz > 0 && "BlockExpr - Incomplete param type"); + CharUnits sz = getObjCEncodingTypeSize(PType); + assert (sz.isPositive() && "BlockExpr - Incomplete param type"); ParmOffset += sz; } // Size of the argument frame - S += llvm::utostr(ParmOffset); + S += charUnitsToString(ParmOffset); // Block pointer and offset. S += "@?0"; ParmOffset = PtrSize; @@ -3198,7 +3195,7 @@ void ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr, } else if (PType->isFunctionType()) PType = PVDecl->getType(); getObjCEncodingForType(PType, S); - S += llvm::utostr(ParmOffset); + S += charUnitsToString(ParmOffset); ParmOffset += getObjCEncodingTypeSize(PType); } } @@ -3216,20 +3213,21 @@ void ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, // Start with computing size of a pointer in number of bytes. // FIXME: There might(should) be a better way of doing this computation! SourceLocation Loc; - int PtrSize = getTypeSize(VoidPtrTy) / getTypeSize(CharTy); + CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy); // The first two arguments (self and _cmd) are pointers; account for // their size. - int ParmOffset = 2 * PtrSize; + CharUnits ParmOffset = 2 * PtrSize; for (ObjCMethodDecl::param_iterator PI = Decl->param_begin(), E = Decl->param_end(); PI != E; ++PI) { QualType PType = (*PI)->getType(); - int sz = getObjCEncodingTypeSize(PType); - assert (sz > 0 && "getObjCEncodingForMethodDecl - Incomplete param type"); + CharUnits sz = getObjCEncodingTypeSize(PType); + assert (sz.isPositive() && + "getObjCEncodingForMethodDecl - Incomplete param type"); ParmOffset += sz; } - S += llvm::utostr(ParmOffset); + S += charUnitsToString(ParmOffset); S += "@0:"; - S += llvm::utostr(PtrSize); + S += charUnitsToString(PtrSize); // Argument types. ParmOffset = 2 * PtrSize; @@ -3249,7 +3247,7 @@ void ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, // 'in', 'inout', etc. getObjCEncodingForTypeQualifier(PVDecl->getObjCDeclQualifier(), S); getObjCEncodingForType(PType, S); - S += llvm::utostr(ParmOffset); + S += charUnitsToString(ParmOffset); ParmOffset += getObjCEncodingTypeSize(PType); } } diff --git a/lib/AST/AttrImpl.cpp b/lib/AST/AttrImpl.cpp new file mode 100644 index 0000000..02c70b6 --- /dev/null +++ b/lib/AST/AttrImpl.cpp @@ -0,0 +1,143 @@ +//===--- AttrImpl.cpp - Classes for representing attributes -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains out-of-line virtual methods for Attr classes. +// +//===----------------------------------------------------------------------===// + + +#include "clang/AST/Attr.h" +#include "clang/AST/ASTContext.h" +using namespace clang; + +#define DEF_SIMPLE_ATTR_CLONE(ATTR) \ + Attr *ATTR##Attr::clone(ASTContext &C) const { \ + return ::new (C) ATTR##Attr; \ + } + +// FIXME: Can we use variadic macro to define DEF_SIMPLE_ATTR_CLONE for +// "non-simple" classes? + +DEF_SIMPLE_ATTR_CLONE(Packed) +DEF_SIMPLE_ATTR_CLONE(AlwaysInline) +DEF_SIMPLE_ATTR_CLONE(Malloc) +DEF_SIMPLE_ATTR_CLONE(NoReturn) +DEF_SIMPLE_ATTR_CLONE(AnalyzerNoReturn) +DEF_SIMPLE_ATTR_CLONE(Deprecated) +DEF_SIMPLE_ATTR_CLONE(Final) +DEF_SIMPLE_ATTR_CLONE(Unavailable) +DEF_SIMPLE_ATTR_CLONE(Unused) +DEF_SIMPLE_ATTR_CLONE(Used) +DEF_SIMPLE_ATTR_CLONE(Weak) +DEF_SIMPLE_ATTR_CLONE(WeakImport) +DEF_SIMPLE_ATTR_CLONE(NoThrow) +DEF_SIMPLE_ATTR_CLONE(Const) +DEF_SIMPLE_ATTR_CLONE(Pure) +DEF_SIMPLE_ATTR_CLONE(FastCall) +DEF_SIMPLE_ATTR_CLONE(StdCall) +DEF_SIMPLE_ATTR_CLONE(CDecl) +DEF_SIMPLE_ATTR_CLONE(TransparentUnion) +DEF_SIMPLE_ATTR_CLONE(ObjCNSObject) +DEF_SIMPLE_ATTR_CLONE(ObjCException) +DEF_SIMPLE_ATTR_CLONE(NoDebug) +DEF_SIMPLE_ATTR_CLONE(WarnUnusedResult) +DEF_SIMPLE_ATTR_CLONE(NoInline) +DEF_SIMPLE_ATTR_CLONE(CFReturnsRetained) +DEF_SIMPLE_ATTR_CLONE(NSReturnsRetained) +DEF_SIMPLE_ATTR_CLONE(BaseCheck) +DEF_SIMPLE_ATTR_CLONE(Hiding) +DEF_SIMPLE_ATTR_CLONE(Override) +DEF_SIMPLE_ATTR_CLONE(DLLImport) +DEF_SIMPLE_ATTR_CLONE(DLLExport) + +Attr* PragmaPackAttr::clone(ASTContext &C) const { + return ::new (C) PragmaPackAttr(Alignment); +} + +Attr* AlignedAttr::clone(ASTContext &C) const { + return ::new (C) AlignedAttr(Alignment); +} + +Attr* AnnotateAttr::clone(ASTContext &C) const { + return ::new (C) AnnotateAttr(Annotation); +} + +Attr *AsmLabelAttr::clone(ASTContext &C) const { + return ::new (C) AsmLabelAttr(Label); +} + +Attr *AliasAttr::clone(ASTContext &C) const { + return ::new (C) AliasAttr(Aliasee); +} + +Attr *ConstructorAttr::clone(ASTContext &C) const { + return ::new (C) ConstructorAttr(priority); +} + +Attr *DestructorAttr::clone(ASTContext &C) const { + return ::new (C) DestructorAttr(priority); +} + +Attr *IBOutletAttr::clone(ASTContext &C) const { + return ::new (C) IBOutletAttr; +} + +Attr *GNUInlineAttr::clone(ASTContext &C) const { + return ::new (C) GNUInlineAttr; +} + +Attr *SectionAttr::clone(ASTContext &C) const { + return ::new (C) SectionAttr(Name); +} + +Attr *NonNullAttr::clone(ASTContext &C) const { + return ::new (C) NonNullAttr(ArgNums, Size); +} + +Attr *FormatAttr::clone(ASTContext &C) const { + return ::new (C) FormatAttr(Type, formatIdx, firstArg); +} + +Attr *FormatArgAttr::clone(ASTContext &C) const { + return ::new (C) FormatArgAttr(formatIdx); +} + +Attr *SentinelAttr::clone(ASTContext &C) const { + return ::new (C) SentinelAttr(sentinel, NullPos); +} + +Attr *VisibilityAttr::clone(ASTContext &C) const { + return ::new (C) VisibilityAttr(VisibilityType); +} + +Attr *OverloadableAttr::clone(ASTContext &C) const { + return ::new (C) OverloadableAttr; +} + +Attr *BlocksAttr::clone(ASTContext &C) const { + return ::new (C) BlocksAttr(BlocksAttrType); +} + +Attr *CleanupAttr::clone(ASTContext &C) const { + return ::new (C) CleanupAttr(FD); +} + +Attr *RegparmAttr::clone(ASTContext &C) const { + return ::new (C) RegparmAttr(NumParams); +} + +Attr *ReqdWorkGroupSizeAttr::clone(ASTContext &C) const { + return ::new (C) ReqdWorkGroupSizeAttr(X, Y, Z); +} + +Attr *MSP430InterruptAttr::clone(ASTContext &C) const { + return ::new (C) MSP430InterruptAttr(Number); +} + + diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt index 5aecf87..dea96e7 100644 --- a/lib/AST/CMakeLists.txt +++ b/lib/AST/CMakeLists.txt @@ -4,6 +4,7 @@ add_clang_library(clangAST APValue.cpp ASTConsumer.cpp ASTContext.cpp + AttrImpl.cpp CXXInheritance.cpp Decl.cpp DeclBase.cpp diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index e112fa3..e77661a 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -957,7 +957,7 @@ bool FunctionDecl::isInlined() const { /// "externally" visible to other translation units in the program. /// /// In C99, inline definitions are not externally visible by default. However, -/// if even one of the globa-scope declarations is marked "extern inline", the +/// if even one of the global-scope declarations is marked "extern inline", the /// inline definition becomes externally visible (C99 6.7.4p6). /// /// In GNU89 mode, or if the gnu_inline attribute is attached to the function @@ -1039,6 +1039,15 @@ OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const { return OO_None; } +/// getLiteralIdentifier - The literal suffix identifier this function +/// represents, if any. +const IdentifierInfo *FunctionDecl::getLiteralIdentifier() const { + if (getDeclName().getNameKind() == DeclarationName::CXXLiteralOperatorName) + return getDeclName().getCXXLiteralIdentifier(); + else + return 0; +} + FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const { if (MemberSpecializationInfo *Info = getMemberSpecializationInfo()) return cast<FunctionDecl>(Info->getInstantiatedFrom()); diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index bbbb19a..1cce35c 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -144,6 +144,19 @@ CXXRecordDecl::setBases(ASTContext &C, } } +/// Callback function for CXXRecordDecl::forallBases that acknowledges +/// that it saw a base class. +static bool SawBase(const CXXRecordDecl *, void *) { + return true; +} + +bool CXXRecordDecl::hasAnyDependentBases() const { + if (!isDependentContext()) + return false; + + return !forallBases(SawBase, 0); +} + bool CXXRecordDecl::hasConstCopyConstructor(ASTContext &Context) const { return getCopyConstructor(Context, Qualifiers::Const) != 0; } @@ -643,23 +656,15 @@ QualType CXXMethodDecl::getThisType(ASTContext &C) const { return C.getPointerType(ClassTy); } -static bool MethodHasBody(const CXXMethodDecl *MD, const FunctionDecl *&fn) { - // Simple case: function has a body - if (MD->getBody(fn)) - return true; - - // Complex case: function is an instantiation of a function which has a - // body, but the definition hasn't been instantiated. - const FunctionDecl *PatternDecl = MD->getTemplateInstantiationPattern(); - if (PatternDecl && PatternDecl->getBody(fn)) - return true; - - return false; -} - bool CXXMethodDecl::hasInlineBody() const { + // If this function is a template instantiation, look at the template from + // which it was instantiated. + const FunctionDecl *CheckFn = getTemplateInstantiationPattern(); + if (!CheckFn) + CheckFn = this; + const FunctionDecl *fn; - return MethodHasBody(this, fn) && !fn->isOutOfLine(); + return CheckFn->getBody(fn) && !fn->isOutOfLine(); } CXXBaseOrMemberInitializer:: diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp index 60c40e2..ff81073 100644 --- a/lib/AST/DeclarationName.cpp +++ b/lib/AST/DeclarationName.cpp @@ -56,9 +56,14 @@ public: /// This identifier is stored here rather than directly in DeclarationName so as /// to allow Objective-C selectors, which are about a million times more common, /// to consume minimal memory. -class CXXLiteralOperatorIdName : public DeclarationNameExtra { +class CXXLiteralOperatorIdName + : public DeclarationNameExtra, public llvm::FoldingSetNode { public: IdentifierInfo *ID; + + void Profile(llvm::FoldingSetNodeID &FSID) { + FSID.AddPointer(ID); + } }; bool operator<(DeclarationName LHS, DeclarationName RHS) { @@ -180,6 +185,11 @@ DeclarationName::NameKind DeclarationName::getNameKind() const { return Identifier; } +bool DeclarationName::isDependentName() const { + QualType T = getCXXNameType(); + return !T.isNull() && T->isDependentType(); +} + std::string DeclarationName::getAsString() const { switch (getNameKind()) { case Identifier: @@ -353,6 +363,7 @@ void DeclarationName::dump() const { DeclarationNameTable::DeclarationNameTable() { CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>; + CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>; // Initialize the overloaded operator names. CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS]; @@ -364,16 +375,30 @@ DeclarationNameTable::DeclarationNameTable() { } DeclarationNameTable::~DeclarationNameTable() { - llvm::FoldingSet<CXXSpecialName> *set = + llvm::FoldingSet<CXXSpecialName> *SpecialNames = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); - llvm::FoldingSetIterator<CXXSpecialName> I = set->begin(), E = set->end(); + llvm::FoldingSetIterator<CXXSpecialName> + SI = SpecialNames->begin(), SE = SpecialNames->end(); + + while (SI != SE) { + CXXSpecialName *n = &*SI++; + delete n; + } - while (I != E) { - CXXSpecialName *n = &*I++; + + llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames + = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> + (CXXLiteralOperatorNames); + llvm::FoldingSetIterator<CXXLiteralOperatorIdName> + LI = LiteralNames->begin(), LE = LiteralNames->end(); + + while (LI != LE) { + CXXLiteralOperatorIdName *n = &*LI++; delete n; } - delete set; + delete SpecialNames; + delete LiteralNames; delete [] CXXOperatorNames; } @@ -428,9 +453,23 @@ DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) { DeclarationName DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) { + llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames + = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> + (CXXLiteralOperatorNames); + + llvm::FoldingSetNodeID ID; + ID.AddPointer(II); + + void *InsertPos = 0; + if (CXXLiteralOperatorIdName *Name = + LiteralNames->FindNodeOrInsertPos(ID, InsertPos)) + return DeclarationName (Name); + CXXLiteralOperatorIdName *LiteralName = new CXXLiteralOperatorIdName; LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator; LiteralName->ID = II; + + LiteralNames->InsertNode(LiteralName, InsertPos); return DeclarationName(LiteralName); } diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 04a6abc..4c3046b 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -2154,7 +2154,8 @@ IdentifierInfo *DesignatedInitExpr::Designator::getFieldName() { return getField()->getIdentifier(); } -DesignatedInitExpr::DesignatedInitExpr(QualType Ty, unsigned NumDesignators, +DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty, + unsigned NumDesignators, const Designator *Designators, SourceLocation EqualOrColonLoc, bool GNUSyntax, @@ -2165,7 +2166,7 @@ DesignatedInitExpr::DesignatedInitExpr(QualType Ty, unsigned NumDesignators, Init->isTypeDependent(), Init->isValueDependent()), EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax), NumDesignators(NumDesignators), NumSubExprs(NumIndexExprs + 1) { - this->Designators = new Designator[NumDesignators]; + this->Designators = new (C) Designator[NumDesignators]; // Record the initializer itself. child_iterator Child = child_begin(); @@ -2210,7 +2211,7 @@ DesignatedInitExpr::Create(ASTContext &C, Designator *Designators, bool UsesColonSyntax, Expr *Init) { void *Mem = C.Allocate(sizeof(DesignatedInitExpr) + sizeof(Stmt *) * (NumIndexExprs + 1), 8); - return new (Mem) DesignatedInitExpr(C.VoidTy, NumDesignators, Designators, + return new (Mem) DesignatedInitExpr(C, C.VoidTy, NumDesignators, Designators, ColonOrEqualLoc, UsesColonSyntax, IndexExprs, NumIndexExprs, Init); } @@ -2222,12 +2223,12 @@ DesignatedInitExpr *DesignatedInitExpr::CreateEmpty(ASTContext &C, return new (Mem) DesignatedInitExpr(NumIndexExprs + 1); } -void DesignatedInitExpr::setDesignators(const Designator *Desigs, +void DesignatedInitExpr::setDesignators(ASTContext &C, + const Designator *Desigs, unsigned NumDesigs) { - if (Designators) - delete [] Designators; + DestroyDesignators(C); - Designators = new Designator[NumDesigs]; + Designators = new (C) Designator[NumDesigs]; NumDesignators = NumDesigs; for (unsigned I = 0; I != NumDesigs; ++I) Designators[I] = Desigs[I]; @@ -2276,7 +2277,7 @@ Expr *DesignatedInitExpr::getArrayRangeEnd(const Designator& D) { /// \brief Replaces the designator at index @p Idx with the series /// of designators in [First, Last). -void DesignatedInitExpr::ExpandDesignator(unsigned Idx, +void DesignatedInitExpr::ExpandDesignator(ASTContext &C, unsigned Idx, const Designator *First, const Designator *Last) { unsigned NumNewDesignators = Last - First; @@ -2292,21 +2293,28 @@ void DesignatedInitExpr::ExpandDesignator(unsigned Idx, } Designator *NewDesignators - = new Designator[NumDesignators - 1 + NumNewDesignators]; + = new (C) Designator[NumDesignators - 1 + NumNewDesignators]; std::copy(Designators, Designators + Idx, NewDesignators); std::copy(First, Last, NewDesignators + Idx); std::copy(Designators + Idx + 1, Designators + NumDesignators, NewDesignators + Idx + NumNewDesignators); - delete [] Designators; + DestroyDesignators(C); Designators = NewDesignators; NumDesignators = NumDesignators - 1 + NumNewDesignators; } void DesignatedInitExpr::DoDestroy(ASTContext &C) { - delete [] Designators; + DestroyDesignators(C); Expr::DoDestroy(C); } +void DesignatedInitExpr::DestroyDesignators(ASTContext &C) { + for (unsigned I = 0; I != NumDesignators; ++I) + Designators[I].~Designator(); + C.Deallocate(Designators); + Designators = 0; +} + ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs, unsigned nexprs, SourceLocation rparenloc) diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 06afec7..dfff209 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -13,6 +13,7 @@ #include "clang/AST/APValue.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/CharUnits.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/ASTDiagnostic.h" @@ -69,11 +70,12 @@ static bool EvaluateComplex(const Expr *E, APValue &Result, EvalInfo &Info); static bool EvalPointerValueAsBool(APValue& Value, bool& Result) { // FIXME: Is this accurate for all kinds of bases? If not, what would // the check look like? - Result = Value.getLValueBase() || Value.getLValueOffset(); + Result = Value.getLValueBase() || !Value.getLValueOffset().isZero(); return true; } -static bool HandleConversionToBool(Expr* E, bool& Result, EvalInfo &Info) { +static bool HandleConversionToBool(const Expr* E, bool& Result, + EvalInfo &Info) { if (E->getType()->isIntegralType()) { APSInt IntResult; if (!EvaluateInteger(E, IntResult, Info)) @@ -222,11 +224,11 @@ public: APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } APValue VisitDeclRefExpr(DeclRefExpr *E); - APValue VisitPredefinedExpr(PredefinedExpr *E) { return APValue(E, 0); } + APValue VisitPredefinedExpr(PredefinedExpr *E) { return APValue(E); } APValue VisitCompoundLiteralExpr(CompoundLiteralExpr *E); APValue VisitMemberExpr(MemberExpr *E); - APValue VisitStringLiteral(StringLiteral *E) { return APValue(E, 0); } - APValue VisitObjCEncodeExpr(ObjCEncodeExpr *E) { return APValue(E, 0); } + APValue VisitStringLiteral(StringLiteral *E) { return APValue(E); } + APValue VisitObjCEncodeExpr(ObjCEncodeExpr *E) { return APValue(E); } APValue VisitArraySubscriptExpr(ArraySubscriptExpr *E); APValue VisitUnaryDeref(UnaryOperator *E); APValue VisitUnaryExtension(const UnaryOperator *E) @@ -254,12 +256,12 @@ static bool EvaluateLValue(const Expr* E, APValue& Result, EvalInfo &Info) { APValue LValueExprEvaluator::VisitDeclRefExpr(DeclRefExpr *E) { if (isa<FunctionDecl>(E->getDecl())) { - return APValue(E, 0); + return APValue(E); } else if (VarDecl* VD = dyn_cast<VarDecl>(E->getDecl())) { if (!Info.AnyLValue && !VD->hasGlobalStorage()) return APValue(); if (!VD->getType()->isReferenceType()) - return APValue(E, 0); + return APValue(E); // FIXME: Check whether VD might be overridden! const VarDecl *Def = 0; if (const Expr *Init = VD->getDefinition(Def)) @@ -272,7 +274,7 @@ APValue LValueExprEvaluator::VisitDeclRefExpr(DeclRefExpr *E) { APValue LValueExprEvaluator::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { if (!Info.AnyLValue && !E->isFileScope()) return APValue(); - return APValue(E, 0); + return APValue(E); } APValue LValueExprEvaluator::VisitMemberExpr(MemberExpr *E) { @@ -309,7 +311,8 @@ APValue LValueExprEvaluator::VisitMemberExpr(MemberExpr *E) { } result.setLValue(result.getLValueBase(), - result.getLValueOffset() + RL.getFieldOffset(i) / 8); + result.getLValueOffset() + + CharUnits::fromQuantity(RL.getFieldOffset(i) / 8)); return result; } @@ -324,9 +327,9 @@ APValue LValueExprEvaluator::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { if (!EvaluateInteger(E->getIdx(), Index, Info)) return APValue(); - uint64_t ElementSize = Info.Ctx.getTypeSize(E->getType()) / 8; + CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(E->getType()); - uint64_t Offset = Index.getSExtValue() * ElementSize; + CharUnits Offset = Index.getSExtValue() * ElementSize; Result.setLValue(Result.getLValueBase(), Result.getLValueOffset() + Offset); return Result; @@ -363,22 +366,22 @@ public: { return Visit(E->getSubExpr()); } APValue VisitUnaryAddrOf(const UnaryOperator *E); APValue VisitObjCStringLiteral(ObjCStringLiteral *E) - { return APValue(E, 0); } + { return APValue(E); } APValue VisitAddrLabelExpr(AddrLabelExpr *E) - { return APValue(E, 0); } + { return APValue(E); } APValue VisitCallExpr(CallExpr *E); APValue VisitBlockExpr(BlockExpr *E) { if (!E->hasBlockDeclRefExprs()) - return APValue(E, 0); + return APValue(E); return APValue(); } APValue VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) - { return APValue((Expr*)0, 0); } + { return APValue((Expr*)0); } APValue VisitConditionalOperator(ConditionalOperator *E); APValue VisitChooseExpr(ChooseExpr *E) { return Visit(E->getChosenSubExpr(Info.Ctx)); } APValue VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) - { return APValue((Expr*)0, 0); } + { return APValue((Expr*)0); } // FIXME: Missing: @protocol, @selector }; } // end anonymous namespace @@ -409,15 +412,15 @@ APValue PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { return APValue(); QualType PointeeType = PExp->getType()->getAs<PointerType>()->getPointeeType(); - uint64_t SizeOfPointee; + CharUnits SizeOfPointee; // Explicitly handle GNU void* and function pointer arithmetic extensions. if (PointeeType->isVoidType() || PointeeType->isFunctionType()) - SizeOfPointee = 1; + SizeOfPointee = CharUnits::One(); else - SizeOfPointee = Info.Ctx.getTypeSize(PointeeType) / 8; + SizeOfPointee = Info.Ctx.getTypeSizeInChars(PointeeType); - uint64_t Offset = ResultLValue.getLValueOffset(); + CharUnits Offset = ResultLValue.getLValueOffset(); if (E->getOpcode() == BinaryOperator::Add) Offset += AdditionalOffset.getLimitedValue() * SizeOfPointee; @@ -459,7 +462,8 @@ APValue PointerExprEvaluator::VisitCastExpr(CastExpr* E) { if (Result.isInt()) { Result.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType())); - return APValue(0, Result.getInt().getZExtValue()); + return APValue(0, + CharUnits::fromQuantity(Result.getInt().getZExtValue())); } // Cast is of an lvalue, no need to change value. @@ -481,7 +485,8 @@ APValue PointerExprEvaluator::VisitCastExpr(CastExpr* E) { if (Result.isInt()) { Result.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType())); - return APValue(0, Result.getInt().getZExtValue()); + return APValue(0, + CharUnits::fromQuantity(Result.getInt().getZExtValue())); } // Cast is of an lvalue, no need to change value. @@ -502,7 +507,7 @@ APValue PointerExprEvaluator::VisitCastExpr(CastExpr* E) { APValue PointerExprEvaluator::VisitCallExpr(CallExpr *E) { if (E->isBuiltinCall(Info.Ctx) == Builtin::BI__builtin___CFStringMakeConstantString) - return APValue(E, 0); + return APValue(E); return APValue(); } @@ -976,20 +981,20 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { && VD->getType()->isObjectType() && !VD->getType()->isVariablyModifiedType() && !VD->getType()->isDependentType()) { - uint64_t Size = Info.Ctx.getTypeSize(VD->getType()) / 8; - uint64_t Offset = Base.Val.getLValueOffset(); - if (Offset <= Size) - Size -= Base.Val.getLValueOffset(); + CharUnits Size = Info.Ctx.getTypeSizeInChars(VD->getType()); + CharUnits Offset = Base.Val.getLValueOffset(); + if (!Offset.isNegative() && Offset <= Size) + Size -= Offset; else - Size = 0; - return Success(Size, E); + Size = CharUnits::Zero(); + return Success(Size.getQuantity(), E); } } } // TODO: Perhaps we should let LLVM lower this? if (E->getArg(0)->HasSideEffects(Info.Ctx)) { - if (E->getArg(1)->EvaluateAsInt(Info.Ctx).getZExtValue() == 0) + if (E->getArg(1)->EvaluateAsInt(Info.Ctx).getZExtValue() <= 1) return Success(-1ULL, E); return Success(0, E); } @@ -1151,7 +1156,7 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { if (LHSValue.getLValueBase()) { if (!E->isEqualityOp()) return false; - if (RHSValue.getLValueBase() || RHSValue.getLValueOffset()) + if (RHSValue.getLValueBase() || !RHSValue.getLValueOffset().isZero()) return false; bool bres; if (!EvalPointerValueAsBool(LHSValue, bres)) @@ -1160,7 +1165,7 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { } else if (RHSValue.getLValueBase()) { if (!E->isEqualityOp()) return false; - if (LHSValue.getLValueBase() || LHSValue.getLValueOffset()) + if (LHSValue.getLValueBase() || !LHSValue.getLValueOffset().isZero()) return false; bool bres; if (!EvalPointerValueAsBool(RHSValue, bres)) @@ -1172,11 +1177,13 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { const QualType Type = E->getLHS()->getType(); const QualType ElementType = Type->getAs<PointerType>()->getPointeeType(); - uint64_t D = LHSValue.getLValueOffset() - RHSValue.getLValueOffset(); + CharUnits ElementSize = CharUnits::One(); if (!ElementType->isVoidType() && !ElementType->isFunctionType()) - D /= Info.Ctx.getTypeSize(ElementType) / 8; + ElementSize = Info.Ctx.getTypeSizeInChars(ElementType); - return Success(D, E); + CharUnits Diff = LHSValue.getLValueOffset() - + RHSValue.getLValueOffset(); + return Success(Diff / ElementSize, E); } bool Result; if (E->getOpcode() == BinaryOperator::EQ) { @@ -1204,21 +1211,23 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { // Handle cases like (unsigned long)&a + 4. if (E->isAdditiveOp() && Result.isLValue() && RHSVal.isInt()) { - uint64_t offset = Result.getLValueOffset(); + CharUnits Offset = Result.getLValueOffset(); + CharUnits AdditionalOffset = CharUnits::fromQuantity( + RHSVal.getInt().getZExtValue()); if (E->getOpcode() == BinaryOperator::Add) - offset += RHSVal.getInt().getZExtValue(); + Offset += AdditionalOffset; else - offset -= RHSVal.getInt().getZExtValue(); - Result = APValue(Result.getLValueBase(), offset); + Offset -= AdditionalOffset; + Result = APValue(Result.getLValueBase(), Offset); return true; } // Handle cases like 4 + (unsigned long)&a if (E->getOpcode() == BinaryOperator::Add && RHSVal.isLValue() && Result.isInt()) { - uint64_t offset = RHSVal.getLValueOffset(); - offset += Result.getInt().getZExtValue(); - Result = APValue(RHSVal.getLValueBase(), offset); + CharUnits Offset = RHSVal.getLValueOffset(); + Offset += CharUnits::fromQuantity(Result.getInt().getZExtValue()); + Result = APValue(RHSVal.getLValueBase(), Offset); return true; } @@ -1334,8 +1343,7 @@ bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) { return false; // Get information about the size. - unsigned BitWidth = Info.Ctx.getTypeSize(SrcTy); - return Success(BitWidth / Info.Ctx.Target.getCharWidth(), E); + return Success(Info.Ctx.getTypeSizeInChars(SrcTy).getQuantity(), E); } bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { @@ -1349,7 +1357,7 @@ bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { return false; if (LV.getLValueBase()) return false; - return Success(LV.getLValueOffset(), E); + return Success(LV.getLValueOffset().getQuantity(), E); } if (E->getOpcode() == UnaryOperator::LNot) { @@ -1432,7 +1440,8 @@ bool IntExprEvaluator::VisitCastExpr(CastExpr *E) { return true; } - APSInt AsInt = Info.Ctx.MakeIntValue(LV.getLValueOffset(), SrcType); + APSInt AsInt = Info.Ctx.MakeIntValue(LV.getLValueOffset().getQuantity(), + SrcType); return Success(HandleIntToIntCast(DestType, SrcType, AsInt, Info.Ctx), E); } @@ -1978,6 +1987,13 @@ bool Expr::EvaluateAsAny(EvalResult &Result, ASTContext &Ctx) const { return true; } +bool Expr::EvaluateAsBooleanCondition(bool &Result, ASTContext &Ctx) const { + EvalResult Scratch; + EvalInfo Info(Ctx, Scratch); + + return HandleConversionToBool(this, Result, Info); +} + bool Expr::EvaluateAsLValue(EvalResult &Result, ASTContext &Ctx) const { EvalInfo Info(Ctx, Result); diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index c914f3f..cfd89ea 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -719,11 +719,6 @@ ASTRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) { // If a class isnt' polymorphic it doesn't have a key function. if (!RD->isPolymorphic()) return 0; - - // A class template specialization or instantation does not have a key - // function. - if (RD->getTemplateSpecializationKind() != TSK_Undeclared) - return 0; // A class inside an anonymous namespace doesn't have a key function. (Or // at least, there's no point to assigning a key function to such a class; @@ -741,13 +736,13 @@ ASTRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) { if (MD->isPure()) continue; - if (MD->isInlineSpecified()) - continue; - // Ignore implicit member functions, they are always marked as inline, but // they don't have a body until they're defined. if (MD->isImplicit()) continue; + + if (MD->isInlineSpecified()) + continue; if (MD->hasInlineBody()) continue; diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 7c7aeb8..104e336 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -337,12 +337,12 @@ unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces, //===----------------------------------------------------------------------===// AsmStmt::AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, - unsigned numoutputs, unsigned numinputs, + bool msasm, unsigned numoutputs, unsigned numinputs, std::string *names, StringLiteral **constraints, Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, StringLiteral **clobbers, SourceLocation rparenloc) : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr) - , IsSimple(issimple), IsVolatile(isvolatile) + , IsSimple(issimple), IsVolatile(isvolatile), MSAsm(msasm) , NumOutputs(numoutputs), NumInputs(numinputs) { for (unsigned i = 0, e = numinputs + numoutputs; i != e; i++) { Names.push_back(names[i]); diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index a7e42af..bbb904d 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -739,9 +739,10 @@ void StmtPrinter::VisitCallExpr(CallExpr *Call) { void StmtPrinter::VisitMemberExpr(MemberExpr *Node) { // FIXME: Suppress printing implicit bases (like "this") PrintExpr(Node->getBase()); + if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl())) + if (FD->isAnonymousStructOrUnion()) + return; OS << (Node->isArrow() ? "->" : "."); - // FIXME: Suppress printing references to unnamed objects - // representing anonymous unions/structs if (NestedNameSpecifier *Qualifier = Node->getQualifier()) Qualifier->print(OS, Policy); @@ -1120,6 +1121,13 @@ void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { } void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) { + // FIXME. For now we just print a trivial constructor call expression, + // constructing its first argument object. + if (E->getNumArgs() == 1) { + CXXConstructorDecl *CD = E->getConstructor(); + if (CD->isTrivial()) + PrintExpr(E->getArg(0)); + } // Nothing to print. } diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp index 3ccb7a9..0840c52 100644 --- a/lib/AST/TypeLoc.cpp +++ b/lib/AST/TypeLoc.cpp @@ -13,6 +13,7 @@ #include "llvm/Support/raw_ostream.h" #include "clang/AST/TypeLocVisitor.h" +#include "clang/AST/Expr.h" using namespace clang; //===----------------------------------------------------------------------===// @@ -123,3 +124,14 @@ bool TypeSpecTypeLoc::classof(const TypeLoc *TL) { if (TL->getType().hasLocalQualifiers()) return false; return TSTChecker().Visit(*TL); } + +// Reimplemented to account for GNU/C++ extension +// typeof unary-expression +// where there are no parentheses. +SourceRange TypeOfExprTypeLoc::getSourceRange() const { + if (getRParenLoc().isValid()) + return SourceRange(getTypeofLoc(), getRParenLoc()); + else + return SourceRange(getTypeofLoc(), + getUnderlyingExpr()->getSourceRange().getEnd()); +} diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp index 818657c..00b74bc 100644 --- a/lib/AST/TypePrinter.cpp +++ b/lib/AST/TypePrinter.cpp @@ -271,6 +271,10 @@ void TypePrinter::PrintFunctionProto(const FunctionProtoType *T, S += ")"; + if (T->getNoReturnAttr()) + S += " __attribute__((noreturn))"; + + if (T->hasExceptionSpec()) { S += " throw("; if (T->hasAnyExceptionSpec()) @@ -287,10 +291,9 @@ void TypePrinter::PrintFunctionProto(const FunctionProtoType *T, S += ")"; } - if (T->getNoReturnAttr()) - S += " __attribute__((noreturn))"; - Print(T->getResultType(), S); + AppendTypeQualList(S, T->getTypeQuals()); + Print(T->getResultType(), S); } void TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T, |