diff options
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/ASTContext.cpp | 101 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 35 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 48 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 73 | ||||
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 41 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 37 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 9 | ||||
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 8 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 107 |
9 files changed, 291 insertions, 168 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 7ed9e45..b80142f 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -222,7 +222,7 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { unsigned ASTContext::getDeclAlignInBytes(const Decl *D) { unsigned Align = Target.getCharWidth(); - if (const AlignedAttr* AA = D->getAttr<AlignedAttr>()) + if (const AlignedAttr* AA = D->getAttr<AlignedAttr>(*this)) Align = std::max(Align, AA->getAlignment()); if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) { @@ -369,7 +369,7 @@ ASTContext::getTypeInfo(const Type *T) { // FIXME: Pointers into different addr spaces could have different sizes and // alignment requirements: getPointerInfo should take an AddrSpace. return getTypeInfo(QualType(cast<ExtQualType>(T)->getBaseType(), 0)); - case Type::ObjCQualifiedId: + case Type::ObjCObjectPointer: case Type::ObjCQualifiedInterface: Width = Target.getPointerWidth(0); Align = Target.getPointerAlign(0); @@ -445,7 +445,7 @@ ASTContext::getTypeInfo(const Type *T) { case Type::Typedef: { const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl(); - if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) { + if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>(*this)) { Align = Aligned->getAlignment(); Width = getTypeSize(Typedef->getUnderlyingType().getTypePtr()); } else @@ -505,7 +505,7 @@ void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo, // FIXME: Should this override struct packing? Probably we want to // take the minimum? - if (const PackedAttr *PA = FD->getAttr<PackedAttr>()) + if (const PackedAttr *PA = FD->getAttr<PackedAttr>(Context)) FieldPacking = PA->getAlignment(); if (const Expr *BitWidthExpr = FD->getBitWidth()) { @@ -525,7 +525,7 @@ void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo, FieldAlign = FieldInfo.second; if (FieldPacking) FieldAlign = std::min(FieldAlign, FieldPacking); - if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>()) + if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>(Context)) FieldAlign = std::max(FieldAlign, AA->getAlignment()); // Check if we need to add padding to give the field the correct @@ -565,7 +565,7 @@ void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo, // is smaller than the specified packing? if (FieldPacking) FieldAlign = std::min(FieldAlign, std::max(8U, FieldPacking)); - if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>()) + if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>(Context)) FieldAlign = std::max(FieldAlign, AA->getAlignment()); // Round up the current record size to the field's alignment boundary. @@ -731,10 +731,10 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D, } unsigned StructPacking = 0; - if (const PackedAttr *PA = D->getAttr<PackedAttr>()) + if (const PackedAttr *PA = D->getAttr<PackedAttr>(*this)) StructPacking = PA->getAlignment(); - if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) + if (const AlignedAttr *AA = D->getAttr<AlignedAttr>(*this)) NewEntry->SetAlignment(std::max(NewEntry->getAlignment(), AA->getAlignment())); @@ -783,10 +783,10 @@ const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) { bool IsUnion = D->isUnion(); unsigned StructPacking = 0; - if (const PackedAttr *PA = D->getAttr<PackedAttr>()) + if (const PackedAttr *PA = D->getAttr<PackedAttr>(*this)) StructPacking = PA->getAlignment(); - if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) + if (const AlignedAttr *AA = D->getAttr<AlignedAttr>(*this)) NewEntry->SetAlignment(std::max(NewEntry->getAlignment(), AA->getAlignment())); @@ -1269,6 +1269,18 @@ QualType ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) { return QualType(New, 0); } +QualType ASTContext::getDependentSizedExtVectorType(QualType vecType, + Expr *SizeExpr, + SourceLocation AttrLoc) { + DependentSizedExtVectorType *New = + new (*this,8) DependentSizedExtVectorType(vecType, QualType(), + SizeExpr, AttrLoc); + + DependentSizedExtVectorTypes.push_back(New); + Types.push_back(New); + return QualType(New, 0); +} + /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. /// QualType ASTContext::getFunctionNoProtoType(QualType ResultTy) { @@ -1414,11 +1426,13 @@ QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl) { } /// \brief Retrieve the template type parameter type for a template -/// parameter with the given depth, index, and (optionally) name. +/// parameter or parameter pack with the given depth, index, and (optionally) +/// name. QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index, + bool ParameterPack, IdentifierInfo *Name) { llvm::FoldingSetNodeID ID; - TemplateTypeParmType::Profile(ID, Depth, Index, Name); + TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, Name); void *InsertPos = 0; TemplateTypeParmType *TypeParm = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos); @@ -1426,11 +1440,12 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index, if (TypeParm) return QualType(TypeParm, 0); - if (Name) - TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index, Name, - getTemplateTypeParmType(Depth, Index)); - else - TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index); + if (Name) { + QualType Canon = getTemplateTypeParmType(Depth, Index, ParameterPack); + TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index, ParameterPack, + Name, Canon); + } else + TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index, ParameterPack); Types.push_back(TypeParm); TemplateTypeParmTypes.InsertNode(TypeParm, InsertPos); @@ -1563,6 +1578,31 @@ static void SortAndUniqueProtocols(ObjCProtocolDecl **&Protocols, NumProtocols = ProtocolsEnd-Protocols; } +/// getObjCObjectPointerType - Return a ObjCObjectPointerType type for +/// the given interface decl and the conforming protocol list. +QualType ASTContext::getObjCObjectPointerType(ObjCInterfaceDecl *Decl, + ObjCProtocolDecl **Protocols, + unsigned NumProtocols) { + // Sort the protocol list alphabetically to canonicalize it. + if (NumProtocols) + SortAndUniqueProtocols(Protocols, NumProtocols); + + llvm::FoldingSetNodeID ID; + ObjCObjectPointerType::Profile(ID, Decl, Protocols, NumProtocols); + + void *InsertPos = 0; + if (ObjCObjectPointerType *QT = + ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos)) + return QualType(QT, 0); + + // No Match; + ObjCObjectPointerType *QType = + new (*this,8) ObjCObjectPointerType(Decl, Protocols, NumProtocols); + + Types.push_back(QType); + ObjCObjectPointerTypes.InsertNode(QType, InsertPos); + return QualType(QType, 0); +} /// getObjCQualifiedInterfaceType - Return a ObjCQualifiedInterfaceType type for /// the given interface decl and the conforming protocol list. @@ -1592,23 +1632,7 @@ QualType ASTContext::getObjCQualifiedInterfaceType(ObjCInterfaceDecl *Decl, /// and the conforming protocol list. QualType ASTContext::getObjCQualifiedIdType(ObjCProtocolDecl **Protocols, unsigned NumProtocols) { - // Sort the protocol list alphabetically to canonicalize it. - SortAndUniqueProtocols(Protocols, NumProtocols); - - llvm::FoldingSetNodeID ID; - ObjCQualifiedIdType::Profile(ID, Protocols, NumProtocols); - - void *InsertPos = 0; - if (ObjCQualifiedIdType *QT = - ObjCQualifiedIdTypes.FindNodeOrInsertPos(ID, InsertPos)) - return QualType(QT, 0); - - // No Match; - ObjCQualifiedIdType *QType = - new (*this,8) ObjCQualifiedIdType(Protocols, NumProtocols); - Types.push_back(QType); - ObjCQualifiedIdTypes.InsertNode(QType, InsertPos); - return QualType(QType, 0); + return getObjCObjectPointerType(0, Protocols, NumProtocols); } /// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique @@ -2398,9 +2422,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, if (FD || EncodingProperty) { // Note that we do extended encoding of protocol qualifer list // Only when doing ivar or property encoding. - const ObjCQualifiedIdType *QIDT = T->getAsObjCQualifiedIdType(); + const ObjCObjectPointerType *QIDT = T->getAsObjCQualifiedIdType(); S += '"'; - for (ObjCQualifiedIdType::qual_iterator I = QIDT->qual_begin(), + for (ObjCObjectPointerType::qual_iterator I = QIDT->qual_begin(), E = QIDT->qual_end(); I != E; ++I) { S += '<'; S += (*I)->getNameAsString(); @@ -2758,7 +2782,7 @@ QualType ASTContext::getFromTargetType(unsigned Type) const { bool ASTContext::isObjCNSObjectType(QualType Ty) const { if (TypedefType *TDT = dyn_cast<TypedefType>(Ty)) { if (TypedefDecl *TD = TDT->getDecl()) - if (TD->getAttr<ObjCNSObjectAttr>()) + if (TD->getAttr<ObjCNSObjectAttr>(*const_cast<ASTContext*>(this))) return true; } return false; @@ -3283,7 +3307,8 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) { return QualType(); } - case Type::ObjCQualifiedId: + case Type::ObjCObjectPointer: + // FIXME: finish // Distinct qualified id's are not compatible. return QualType(); case Type::FixedWidthInt: diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index a3e406b..bf63932 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -315,6 +315,12 @@ void VarDecl::Destroy(ASTContext& C) { VarDecl::~VarDecl() { } +SourceRange VarDecl::getSourceRange() const { + if (getInit()) + return SourceRange(getLocation(), getInit()->getLocEnd()); + return SourceRange(getLocation(), getLocation()); +} + bool VarDecl::isTentativeDefinition(ASTContext &Context) const { if (!isFileVarDecl() || Context.getLangOptions().CPlusPlus) return false; @@ -371,6 +377,12 @@ Stmt *FunctionDecl::getBodyIfAvailable() const { return 0; } +void FunctionDecl::setBody(Stmt *B) { + Body = B; + if (B && EndRangeLoc < B->getLocEnd()) + EndRangeLoc = B->getLocEnd(); +} + bool FunctionDecl::isMain() const { return getDeclContext()->getLookupContext()->isTranslationUnit() && getIdentifier() && getIdentifier()->isStr("main"); @@ -380,13 +392,14 @@ bool FunctionDecl::isExternC(ASTContext &Context) const { // In C, any non-static, non-overloadable function has external // linkage. if (!Context.getLangOptions().CPlusPlus) - return getStorageClass() != Static && !getAttr<OverloadableAttr>(); + return getStorageClass() != Static && !getAttr<OverloadableAttr>(Context); for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit(); DC = DC->getParent()) { if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) { if (Linkage->getLanguage() == LinkageSpecDecl::lang_c) - return getStorageClass() != Static && !getAttr<OverloadableAttr>(); + return getStorageClass() != Static && + !getAttr<OverloadableAttr>(Context); break; } @@ -451,7 +464,7 @@ unsigned FunctionDecl::getBuiltinID(ASTContext &Context) const { if (isa<LinkageSpecDecl>(getDeclContext()) && cast<LinkageSpecDecl>(getDeclContext())->getLanguage() == LinkageSpecDecl::lang_c && - !getAttr<OverloadableAttr>()) + !getAttr<OverloadableAttr>(Context)) return BuiltinID; // Not a builtin @@ -480,6 +493,10 @@ void FunctionDecl::setParams(ASTContext& C, ParmVarDecl **NewParamInfo, void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams); ParamInfo = new (Mem) ParmVarDecl*[NumParams]; memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); + + // Update source range. + if (EndRangeLoc < NewParamInfo[NumParams-1]->getLocEnd()) + EndRangeLoc = NewParamInfo[NumParams-1]->getLocEnd(); } } @@ -496,25 +513,25 @@ unsigned FunctionDecl::getMinRequiredArguments() const { return NumRequiredArgs; } -bool FunctionDecl::hasActiveGNUInlineAttribute() const { - if (!isInline() || !hasAttr<GNUInlineAttr>()) +bool FunctionDecl::hasActiveGNUInlineAttribute(ASTContext &Context) const { + if (!isInline() || !hasAttr<GNUInlineAttr>(Context)) return false; for (const FunctionDecl *FD = getPreviousDeclaration(); FD; FD = FD->getPreviousDeclaration()) { - if (FD->isInline() && !FD->hasAttr<GNUInlineAttr>()) + if (FD->isInline() && !FD->hasAttr<GNUInlineAttr>(Context)) return false; } return true; } -bool FunctionDecl::isExternGNUInline() const { - if (!hasActiveGNUInlineAttribute()) +bool FunctionDecl::isExternGNUInline(ASTContext &Context) const { + if (!hasActiveGNUInlineAttribute(Context)) return false; for (const FunctionDecl *FD = this; FD; FD = FD->getPreviousDeclaration()) - if (FD->getStorageClass() == Extern && FD->hasAttr<GNUInlineAttr>()) + if (FD->getStorageClass() == Extern && FD->hasAttr<GNUInlineAttr>(Context)) return true; return false; diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index a39a506..02e71d7 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -38,12 +38,6 @@ using namespace clang; static bool StatSwitch = false; -// This keeps track of all decl attributes. Since so few decls have attrs, we -// keep them in a hash map instead of wasting space in the Decl class. -typedef llvm::DenseMap<const Decl*, Attr*> DeclAttrMapTy; - -static DeclAttrMapTy *DeclAttrs = 0; - const char *Decl::getDeclKindName() const { switch (DeclKind) { default: assert(0 && "Declaration not in DeclNodes.def!"); @@ -170,6 +164,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case ParmVar: case OriginalParmVar: case NonTypeTemplateParm: + case Using: case ObjCMethod: case ObjCContainer: case ObjCCategory: @@ -224,11 +219,8 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { } } -void Decl::addAttr(Attr *NewAttr) { - if (!DeclAttrs) - DeclAttrs = new DeclAttrMapTy(); - - Attr *&ExistingAttr = (*DeclAttrs)[this]; +void Decl::addAttr(ASTContext &Context, Attr *NewAttr) { + Attr *&ExistingAttr = Context.getDeclAttrs(this); NewAttr->setNext(ExistingAttr); ExistingAttr = NewAttr; @@ -236,25 +228,19 @@ void Decl::addAttr(Attr *NewAttr) { HasAttrs = true; } -void Decl::invalidateAttrs() { +void Decl::invalidateAttrs(ASTContext &Context) { if (!HasAttrs) return; - + HasAttrs = false; - (*DeclAttrs)[this] = 0; - DeclAttrs->erase(this); - - if (DeclAttrs->empty()) { - delete DeclAttrs; - DeclAttrs = 0; - } + Context.eraseDeclAttrs(this); } -const Attr *Decl::getAttrsImpl() const { +const Attr *Decl::getAttrsImpl(ASTContext &Context) const { assert(HasAttrs && "getAttrs() should verify this!"); - return (*DeclAttrs)[this]; + return Context.getDeclAttrs(this); } -void Decl::swapAttrs(Decl *RHS) { +void Decl::swapAttrs(ASTContext &Context, Decl *RHS) { bool HasLHSAttr = this->HasAttrs; bool HasRHSAttr = RHS->HasAttrs; @@ -263,17 +249,17 @@ void Decl::swapAttrs(Decl *RHS) { // If 'this' has no attrs, swap the other way. if (!HasLHSAttr) - return RHS->swapAttrs(this); + return RHS->swapAttrs(Context, this); // Handle the case when both decls have attrs. if (HasRHSAttr) { - std::swap((*DeclAttrs)[this], (*DeclAttrs)[RHS]); + std::swap(Context.getDeclAttrs(this), Context.getDeclAttrs(RHS)); return; } // Otherwise, LHS has an attr and RHS doesn't. - (*DeclAttrs)[RHS] = (*DeclAttrs)[this]; - (*DeclAttrs).erase(this); + Context.getDeclAttrs(RHS) = Context.getDeclAttrs(this); + Context.eraseDeclAttrs(this); this->HasAttrs = false; RHS->HasAttrs = true; } @@ -282,12 +268,8 @@ void Decl::swapAttrs(Decl *RHS) { void Decl::Destroy(ASTContext &C) { // Free attributes for this decl. if (HasAttrs) { - DeclAttrMapTy::iterator it = DeclAttrs->find(this); - assert(it != DeclAttrs->end() && "No attrs found but HasAttrs is true!"); - - // release attributes. - it->second->Destroy(C); - invalidateAttrs(); + C.getDeclAttrs(this)->Destroy(C); + invalidateAttrs(C); HasAttrs = false; } diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 8430da2..7a930d7 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -128,36 +128,33 @@ bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context) const { void CXXRecordDecl::addedConstructor(ASTContext &Context, CXXConstructorDecl *ConDecl) { - if (!ConDecl->isImplicit()) { - // Note that we have a user-declared constructor. - UserDeclaredConstructor = true; - - // C++ [dcl.init.aggr]p1: - // An aggregate is an array or a class (clause 9) with no - // user-declared constructors (12.1) [...]. - Aggregate = false; - - // C++ [class]p4: - // A POD-struct is an aggregate class [...] - PlainOldData = false; - - // C++ [class.ctor]p5: - // A constructor is trivial if it is an implicitly-declared default - // constructor. - HasTrivialConstructor = false; + assert(!ConDecl->isImplicit() && "addedConstructor - not for implicit decl"); + // Note that we have a user-declared constructor. + UserDeclaredConstructor = true; + + // C++ [dcl.init.aggr]p1: + // An aggregate is an array or a class (clause 9) with no + // user-declared constructors (12.1) [...]. + Aggregate = false; + + // C++ [class]p4: + // A POD-struct is an aggregate class [...] + PlainOldData = false; + + // C++ [class.ctor]p5: + // A constructor is trivial if it is an implicitly-declared default + // constructor. + HasTrivialConstructor = false; - // Note when we have a user-declared copy constructor, which will - // suppress the implicit declaration of a copy constructor. - if (ConDecl->isCopyConstructor(Context)) - UserDeclaredCopyConstructor = true; - } + // Note when we have a user-declared copy constructor, which will + // suppress the implicit declaration of a copy constructor. + if (ConDecl->isCopyConstructor(Context)) + UserDeclaredCopyConstructor = true; } void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context, CXXMethodDecl *OpDecl) { // We're interested specifically in copy assignment operators. - // Unlike addedConstructor, this method is not called for implicit - // declarations. const FunctionProtoType *FnType = OpDecl->getType()->getAsFunctionProtoType(); assert(FnType && "Overloaded operator has no proto function type."); assert(FnType->getNumArgs() == 1 && !FnType->isVariadic()); @@ -187,10 +184,28 @@ void CXXRecordDecl::addConversionFunction(ASTContext &Context, Conversions.addOverload(ConvDecl); } + +CXXConstructorDecl * +CXXRecordDecl::getDefaultConstructor(ASTContext &Context) { + QualType ClassType = Context.getTypeDeclType(this); + DeclarationName ConstructorName + = Context.DeclarationNames.getCXXConstructorName( + Context.getCanonicalType(ClassType.getUnqualifiedType())); + + DeclContext::lookup_const_iterator Con, ConEnd; + for (llvm::tie(Con, ConEnd) = lookup(Context, ConstructorName); + Con != ConEnd; ++Con) { + CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con); + if (Constructor->isDefaultConstructor()) + return Constructor; + } + return 0; +} + const CXXDestructorDecl * CXXRecordDecl::getDestructor(ASTContext &Context) { QualType ClassType = Context.getTypeDeclType(this); - + DeclarationName Name = Context.DeclarationNames.getCXXDestructorName(ClassType); @@ -428,6 +443,14 @@ NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, Qualifier, IdentLoc, Namespace); } +UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, + SourceLocation L, SourceRange NNR, SourceLocation TargetNL, + SourceLocation UL, NamedDecl* Target, + NestedNameSpecifier* TargetNNS, bool IsTypeNameArg) { + return new (C) UsingDecl(DC, L, NNR, TargetNL, UL, Target, + TargetNNS, IsTypeNameArg); +} + StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, Expr *AssertExpr, StringLiteral *Message) { diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index 5b1bf9b..23c2637 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -190,7 +190,7 @@ TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack) { - QualType Type = C.getTemplateTypeParmType(D, P, Id); + QualType Type = C.getTemplateTypeParmType(D, P, ParameterPack, Id); return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack); } @@ -238,6 +238,22 @@ TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) { StartLoc = E->getSourceRange().getBegin(); } +/// \brief Construct a template argument pack. +TemplateArgument::TemplateArgument(SourceLocation Loc, TemplateArgument *args, + unsigned NumArgs, bool CopyArgs) + : Kind(Pack) { + Args.NumArgs = NumArgs; + Args.CopyArgs = CopyArgs; + if (!Args.CopyArgs) { + Args.Args = args; + return; + } + + Args.Args = new TemplateArgument[NumArgs]; + for (unsigned I = 0; I != NumArgs; ++I) + Args.Args[I] = args[I]; +} + //===----------------------------------------------------------------------===// // TemplateArgumentListBuilder Implementation //===----------------------------------------------------------------------===// @@ -249,25 +265,28 @@ void TemplateArgumentListBuilder::push_back(const TemplateArgument& Arg) { break; } - if (!isAddingFromParameterPack()) { - // Add begin and end indicies. - Indices.push_back(Args.size()); - Indices.push_back(Args.size()); - } - - Args.push_back(Arg); + FlatArgs.push_back(Arg); + + if (!isAddingFromParameterPack()) + StructuredArgs.push_back(Arg); } void TemplateArgumentListBuilder::BeginParameterPack() { assert(!isAddingFromParameterPack() && "Already adding to parameter pack!"); - - Indices.push_back(Args.size()); + + PackBeginIndex = FlatArgs.size(); } void TemplateArgumentListBuilder::EndParameterPack() { assert(isAddingFromParameterPack() && "Not adding to parameter pack!"); + + unsigned NumArgs = FlatArgs.size() - PackBeginIndex; + TemplateArgument *Args = NumArgs ? &FlatArgs[PackBeginIndex] : 0; + + StructuredArgs.push_back(TemplateArgument(SourceLocation(), Args, NumArgs, + /*CopyArgs=*/false)); - Indices.push_back(Args.size()); + PackBeginIndex = std::numeric_limits<unsigned>::max(); } //===----------------------------------------------------------------------===// diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 309be41..4a3ad26 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -456,7 +456,7 @@ Stmt *BlockExpr::getBody() { /// with location to warn on and the source range[s] to report with the /// warning. bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, - SourceRange &R2) const { + SourceRange &R2, ASTContext &Context) const { // Don't warn if the expr is type dependent. The type could end up // instantiating to void. if (isTypeDependent()) @@ -469,7 +469,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, return true; case ParenExprClass: return cast<ParenExpr>(this)->getSubExpr()-> - isUnusedResultAWarning(Loc, R1, R2); + isUnusedResultAWarning(Loc, R1, R2, Context); case UnaryOperatorClass: { const UnaryOperator *UO = cast<UnaryOperator>(this); @@ -492,7 +492,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, return false; break; case UnaryOperator::Extension: - return UO->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2); + return UO->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Context); } Loc = UO->getOperatorLoc(); R1 = UO->getSubExpr()->getSourceRange(); @@ -502,8 +502,8 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, const BinaryOperator *BO = cast<BinaryOperator>(this); // Consider comma to have side effects if the LHS or RHS does. if (BO->getOpcode() == BinaryOperator::Comma) - return BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2) || - BO->getLHS()->isUnusedResultAWarning(Loc, R1, R2); + return BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Context) || + BO->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Context); if (BO->isAssignmentOp()) return false; @@ -519,9 +519,10 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, // The condition must be evaluated, but if either the LHS or RHS is a // warning, warn about them. const ConditionalOperator *Exp = cast<ConditionalOperator>(this); - if (Exp->getLHS() && Exp->getLHS()->isUnusedResultAWarning(Loc, R1, R2)) + if (Exp->getLHS() && + Exp->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Context)) return true; - return Exp->getRHS()->isUnusedResultAWarning(Loc, R1, R2); + return Exp->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Context); } case MemberExprClass: @@ -554,8 +555,8 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, // If the callee has attribute pure, const, or warn_unused_result, warn // about it. void foo() { strlen("bar"); } should warn. if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CalleeDRE->getDecl())) - if (FD->getAttr<WarnUnusedResultAttr>() || - FD->getAttr<PureAttr>() || FD->getAttr<ConstAttr>()) { + if (FD->getAttr<WarnUnusedResultAttr>(Context) || + FD->getAttr<PureAttr>(Context) || FD->getAttr<ConstAttr>(Context)) { Loc = CE->getCallee()->getLocStart(); R1 = CE->getCallee()->getSourceRange(); @@ -578,7 +579,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, const CompoundStmt *CS = cast<StmtExpr>(this)->getSubStmt(); if (!CS->body_empty()) if (const Expr *E = dyn_cast<Expr>(CS->body_back())) - return E->isUnusedResultAWarning(Loc, R1, R2); + return E->isUnusedResultAWarning(Loc, R1, R2, Context); Loc = cast<StmtExpr>(this)->getLParenLoc(); R1 = getSourceRange(); @@ -588,8 +589,8 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, // If this is a cast to void, check the operand. Otherwise, the result of // the cast is unused. if (getType()->isVoidType()) - return cast<CastExpr>(this)->getSubExpr()->isUnusedResultAWarning(Loc, - R1, R2); + return cast<CastExpr>(this)->getSubExpr() + ->isUnusedResultAWarning(Loc, R1, R2, Context); Loc = cast<CStyleCastExpr>(this)->getLParenLoc(); R1 = cast<CStyleCastExpr>(this)->getSubExpr()->getSourceRange(); return true; @@ -597,8 +598,8 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, // If this is a cast to void, check the operand. Otherwise, the result of // the cast is unused. if (getType()->isVoidType()) - return cast<CastExpr>(this)->getSubExpr()->isUnusedResultAWarning(Loc, - R1, R2); + return cast<CastExpr>(this)->getSubExpr() + ->isUnusedResultAWarning(Loc, R1, R2, Context); Loc = cast<CXXFunctionalCastExpr>(this)->getTypeBeginLoc(); R1 = cast<CXXFunctionalCastExpr>(this)->getSubExpr()->getSourceRange(); return true; @@ -606,11 +607,11 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, case ImplicitCastExprClass: // Check the operand, since implicit casts are inserted by Sema return cast<ImplicitCastExpr>(this) - ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2); + ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Context); case CXXDefaultArgExprClass: return cast<CXXDefaultArgExpr>(this) - ->getExpr()->isUnusedResultAWarning(Loc, R1, R2); + ->getExpr()->isUnusedResultAWarning(Loc, R1, R2, Context); case CXXNewExprClass: // FIXME: In theory, there might be new expressions that don't have side @@ -619,7 +620,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, return false; case CXXExprWithTemporariesClass: return cast<CXXExprWithTemporaries>(this) - ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2); + ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Context); } } @@ -1570,7 +1571,7 @@ ObjCSelectorExpr *ObjCSelectorExpr::Clone(ASTContext &C) const { } ObjCProtocolExpr *ObjCProtocolExpr::Clone(ASTContext &C) const { - return new (C) ObjCProtocolExpr(getType(), Protocol, AtLoc, RParenLoc); + return new (C) ObjCProtocolExpr(getType(), TheProtocol, AtLoc, RParenLoc); } // constructor for class messages. diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 8fd66a2..18c0f77 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -306,10 +306,11 @@ void CXXConstructExpr::Destroy(ASTContext &C) { CXXExprWithTemporaries::CXXExprWithTemporaries(Expr *subexpr, CXXTemporary **temps, unsigned numtemps, - bool destroytemps) + bool shoulddestroytemps) : Expr(CXXExprWithTemporariesClass, subexpr->getType(), subexpr->isTypeDependent(), subexpr->isValueDependent()), - SubExpr(subexpr), Temps(0), NumTemps(numtemps), DestroyTemps(destroytemps) { + SubExpr(subexpr), Temps(0), NumTemps(numtemps), + ShouldDestroyTemps(shoulddestroytemps) { if (NumTemps > 0) { Temps = new CXXTemporary*[NumTemps]; for (unsigned i = 0; i < NumTemps; ++i) @@ -321,9 +322,9 @@ CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C, Expr *SubExpr, CXXTemporary **Temps, unsigned NumTemps, - bool DestroyTemps) { + bool ShouldDestroyTemps){ return new (C) CXXExprWithTemporaries(SubExpr, Temps, NumTemps, - DestroyTemps); + ShouldDestroyTemps); } void CXXExprWithTemporaries::Destroy(ASTContext &C) { diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 710da63..b300940 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -643,7 +643,8 @@ void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) { if (!Node->isPostfix()) { OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); - // Print a space if this is an "identifier operator" like __real. + // Print a space if this is an "identifier operator" like __real, or if + // it might be concatenated incorrectly like '+'. switch (Node->getOpcode()) { default: break; case UnaryOperator::Real: @@ -651,6 +652,11 @@ void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) { case UnaryOperator::Extension: OS << ' '; break; + case UnaryOperator::Plus: + case UnaryOperator::Minus: + if (isa<UnaryOperator>(Node->getSubExpr())) + OS << ' '; + break; } } PrintExpr(Node->getSubExpr()); diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index e304f54..7b45b21 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -50,6 +50,13 @@ void DependentSizedArrayType::Destroy(ASTContext& C) { C.Deallocate(this); } +void DependentSizedExtVectorType::Destroy(ASTContext& C) { + if (SizeExpr) + SizeExpr->Destroy(C); + this->~DependentSizedExtVectorType(); + C.Deallocate(this); +} + /// getArrayElementTypeNoTypeQual - If this is an array type, return the /// element type of the array, potentially with type qualifiers missing. /// This method should never be used when type qualifiers are meaningful. @@ -555,6 +562,12 @@ const ObjCInterfaceType *Type::getAsObjCInterfaceType() const { return dyn_cast<ObjCInterfaceType>(CanonicalType.getUnqualifiedType()); } +const ObjCObjectPointerType *Type::getAsObjCObjectPointerType() const { + // There is no sugar for ObjCObjectPointerType's, just return the + // canonical type pointer if it is the right class. + return dyn_cast<ObjCObjectPointerType>(CanonicalType.getUnqualifiedType()); +} + const ObjCQualifiedInterfaceType * Type::getAsObjCQualifiedInterfaceType() const { // There is no sugar for ObjCQualifiedInterfaceType's, just return the @@ -562,10 +575,14 @@ Type::getAsObjCQualifiedInterfaceType() const { return dyn_cast<ObjCQualifiedInterfaceType>(CanonicalType.getUnqualifiedType()); } -const ObjCQualifiedIdType *Type::getAsObjCQualifiedIdType() const { +const ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const { // There is no sugar for ObjCQualifiedIdType's, just return the canonical // type pointer if it is the right class. - return dyn_cast<ObjCQualifiedIdType>(CanonicalType.getUnqualifiedType()); + if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType()) { + if (OPT->isObjCQualifiedIdType()) + return OPT; + } + return 0; } const TemplateTypeParmType *Type::getAsTemplateTypeParmType() const { @@ -770,7 +787,7 @@ bool Type::isScalarType() const { isa<BlockPointerType>(CanonicalType) || isa<MemberPointerType>(CanonicalType) || isa<ComplexType>(CanonicalType) || - isa<ObjCQualifiedIdType>(CanonicalType); + isa<ObjCObjectPointerType>(CanonicalType); } /// \brief Determines whether the type is a C++ aggregate type or C @@ -857,7 +874,7 @@ bool Type::isPODType() const { case MemberPointer: case Vector: case ExtVector: - case ObjCQualifiedId: + case ObjCObjectPointer: return true; case Enum: @@ -912,7 +929,7 @@ bool Type::isSpecifierType() const { case Typename: case ObjCInterface: case ObjCQualifiedInterface: - case ObjCQualifiedId: + case ObjCObjectPointer: return true; default: return false; @@ -973,28 +990,30 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID) { getNumExceptions(), exception_begin()); } -void ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID, - const ObjCInterfaceDecl *Decl, - ObjCProtocolDecl **protocols, - unsigned NumProtocols) { +void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID, + const ObjCInterfaceDecl *Decl, + ObjCProtocolDecl **protocols, + unsigned NumProtocols) { ID.AddPointer(Decl); for (unsigned i = 0; i != NumProtocols; i++) ID.AddPointer(protocols[i]); } -void ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID) { +void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getDecl(), &Protocols[0], getNumProtocols()); } -void ObjCQualifiedIdType::Profile(llvm::FoldingSetNodeID &ID, - ObjCProtocolDecl **protocols, - unsigned NumProtocols) { +void ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID, + const ObjCInterfaceDecl *Decl, + ObjCProtocolDecl **protocols, + unsigned NumProtocols) { + ID.AddPointer(Decl); for (unsigned i = 0; i != NumProtocols; i++) ID.AddPointer(protocols[i]); } -void ObjCQualifiedIdType::Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, &Protocols[0], getNumProtocols()); +void ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, getDecl(), &Protocols[0], getNumProtocols()); } /// LookThroughTypedefs - Return the ultimate type this typedef corresponds to @@ -1068,6 +1087,10 @@ anyDependentTemplateArguments(const TemplateArgument *Args, unsigned NumArgs) { Args[Idx].getAsExpr()->isValueDependent()) return true; break; + + case TemplateArgument::Pack: + assert(0 && "FIXME: Implement!"); + break; } } @@ -1352,6 +1375,19 @@ void DependentSizedArrayType::getAsStringInternal(std::string &S, const Printing getElementType().getAsStringInternal(S, Policy); } +void DependentSizedExtVectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { + getElementType().getAsStringInternal(S, Policy); + + S += " __attribute__((ext_vector_type("; + if (getSizeExpr()) { + std::string SStr; + llvm::raw_string_ostream s(SStr); + getSizeExpr()->printPretty(s, 0, Policy); + S += s.str(); + } + S += ")))"; +} + void VectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { // FIXME: We prefer to print the size directly here, but have no way // to get the size of the type. @@ -1476,6 +1512,9 @@ TemplateSpecializationType::PrintTemplateArgumentList( Args[Arg].getAsExpr()->printPretty(s, 0, Policy); break; } + case TemplateArgument::Pack: + assert(0 && "FIXME: Implement!"); + break; } // If this is the first argument and its string representation @@ -1566,6 +1605,30 @@ void ObjCInterfaceType::getAsStringInternal(std::string &InnerString, const Prin InnerString = getDecl()->getIdentifier()->getName() + InnerString; } +void ObjCObjectPointerType::getAsStringInternal(std::string &InnerString, + const PrintingPolicy &Policy) const { + if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'. + InnerString = ' ' + InnerString; + + std::string ObjCQIString; + + if (getDecl()) + ObjCQIString = getDecl()->getNameAsString(); + else + ObjCQIString = "id"; + + if (!qual_empty()) { + ObjCQIString += '<'; + for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) { + ObjCQIString += (*I)->getNameAsString(); + if (I+1 != E) + ObjCQIString += ','; + } + ObjCQIString += '>'; + } + InnerString = ObjCQIString + InnerString; +} + void ObjCQualifiedInterfaceType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { @@ -1585,20 +1648,6 @@ ObjCQualifiedInterfaceType::getAsStringInternal(std::string &InnerString, InnerString = ObjCQIString + InnerString; } -void ObjCQualifiedIdType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { - if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'. - InnerString = ' ' + InnerString; - std::string ObjCQIString = "id"; - ObjCQIString += '<'; - for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) { - ObjCQIString += (*I)->getNameAsString(); - if (I+1 != E) - ObjCQIString += ','; - } - ObjCQIString += '>'; - InnerString = ObjCQIString + InnerString; -} - void TagType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { if (Policy.SuppressTag) return; |