diff options
Diffstat (limited to 'include/clang/AST')
-rw-r--r-- | include/clang/AST/ASTContext.h | 16 | ||||
-rw-r--r-- | include/clang/AST/CXXInheritance.h | 16 | ||||
-rw-r--r-- | include/clang/AST/Decl.h | 26 | ||||
-rw-r--r-- | include/clang/AST/DeclBase.h | 12 | ||||
-rw-r--r-- | include/clang/AST/DeclCXX.h | 22 | ||||
-rw-r--r-- | include/clang/AST/DeclObjC.h | 150 | ||||
-rw-r--r-- | include/clang/AST/Expr.h | 39 | ||||
-rw-r--r-- | include/clang/AST/ExprCXX.h | 48 | ||||
-rw-r--r-- | include/clang/AST/Type.h | 108 | ||||
-rw-r--r-- | include/clang/AST/TypeLoc.h | 112 | ||||
-rw-r--r-- | include/clang/AST/TypeLocVisitor.h | 1 | ||||
-rw-r--r-- | include/clang/AST/UnresolvedSet.h | 211 |
12 files changed, 614 insertions, 147 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 5db8e20..e5429be 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -61,6 +61,7 @@ namespace clang { class TypedefDecl; class UsingDecl; class UsingShadowDecl; + class UnresolvedSetIterator; namespace Builtin { class Context; } @@ -397,6 +398,11 @@ public: /// BlockPointer. QualType getNoReturnType(QualType T, bool AddNoReturn = true); + /// getCallConvType - Adds the specified calling convention attribute to + /// the given type, which must be a FunctionType or a pointer to an + /// allowable type. + QualType getCallConvType(QualType T, CallingConv CallConv); + /// getComplexType - Return the uniqued reference to the type for a complex /// number with the specified element type. QualType getComplexType(QualType T); @@ -513,7 +519,8 @@ public: /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. /// - QualType getFunctionNoProtoType(QualType ResultTy, bool NoReturn = false); + QualType getFunctionNoProtoType(QualType ResultTy, bool NoReturn = false, + CallingConv CallConv = CC_Default); /// getFunctionType - Return a normal function type with a typed argument /// list. isVariadic indicates whether the argument list includes '...'. @@ -522,7 +529,8 @@ public: unsigned TypeQuals, bool hasExceptionSpec = false, bool hasAnyExceptionSpec = false, unsigned NumExs = 0, const QualType *ExArray = 0, - bool NoReturn = false); + bool NoReturn = false, + CallingConv CallConv = CC_Default); /// getTypeDeclType - Return the unique reference to the type for /// the specified type declaration. @@ -746,8 +754,8 @@ public: DeclarationName getNameForTemplate(TemplateName Name); - TemplateName getOverloadedTemplateName(NamedDecl * const *Begin, - NamedDecl * const *End); + TemplateName getOverloadedTemplateName(UnresolvedSetIterator Begin, + UnresolvedSetIterator End); TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h index 7c826fe..1491b1e 100644 --- a/include/clang/AST/CXXInheritance.h +++ b/include/clang/AST/CXXInheritance.h @@ -65,9 +65,21 @@ struct CXXBasePathElement { /// subobject is being used. class CXXBasePath : public llvm::SmallVector<CXXBasePathElement, 4> { public: + CXXBasePath() : Access(AS_public) {} + + /// \brief The access along this inheritance path. This is only + /// calculated when recording paths. AS_none is a special value + /// used to indicate a path which permits no legal access. + AccessSpecifier Access; + /// \brief The set of declarations found inside this base class /// subobject. DeclContext::lookup_result Decls; + + void clear() { + llvm::SmallVectorImpl<CXXBasePathElement>::clear(); + Access = AS_public; + } }; /// BasePaths - Represents the set of paths from a derived class to @@ -131,10 +143,10 @@ class CXXBasePaths { /// is also recorded. bool DetectVirtual; - /// ScratchPath - A BasePath that is used by Sema::IsDerivedFrom + /// ScratchPath - A BasePath that is used by Sema::lookupInBases /// to help build the set of paths. CXXBasePath ScratchPath; - + /// DetectedVirtual - The base class that is virtual. const RecordType *DetectedVirtual; diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 21b5909..6d52b2b 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -55,32 +55,6 @@ public: TypeLoc getTypeLoc() const; }; -/// UnresolvedSet - A set of unresolved declarations. This is needed -/// in a lot of places, but isn't really worth breaking into its own -/// header right now. -class UnresolvedSet { - typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy; - DeclsTy Decls; - -public: - void addDecl(NamedDecl *D) { - Decls.push_back(D); - } - - bool replace(const NamedDecl* Old, NamedDecl *New) { - for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) - if (*I == Old) - return (*I = New, true); - return false; - } - - unsigned size() const { return Decls.size(); } - - typedef DeclsTy::const_iterator iterator; - iterator begin() const { return Decls.begin(); } - iterator end() const { return Decls.end(); } -}; - /// TranslationUnitDecl - The top declaration context. class TranslationUnitDecl : public Decl, public DeclContext { ASTContext &Ctx; diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 497f863..775bce2 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -16,8 +16,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/Type.h" -// FIXME: Layering violation -#include "clang/Parse/AccessSpecifier.h" +#include "clang/Basic/Specifiers.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/ADT/PointerUnion.h" @@ -1017,13 +1016,8 @@ private: }; inline bool Decl::isTemplateParameter() const { - return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm; -} - -inline bool Decl::isDefinedOutsideFunctionOrMethod() const { - if (getDeclContext()) - return !getDeclContext()->getLookupContext()->isFunctionOrMethod(); - return true; + return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm || + getKind() == TemplateTemplateParm; } } // end clang. diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 336a895..73ebf52 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -16,6 +16,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/Decl.h" +#include "clang/AST/UnresolvedSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallPtrSet.h" @@ -275,13 +276,13 @@ class CXXRecordDecl : public RecordDecl { /// of this C++ class (but not its inherited conversion /// functions). Each of the entries in this overload set is a /// CXXConversionDecl. - UnresolvedSet Conversions; + UnresolvedSet<4> Conversions; /// VisibleConversions - Overload set containing the conversion functions /// of this C++ class and all those inherited conversion functions that /// are visible in this class. Each of the entries in this overload set is /// a CXXConversionDecl or a FunctionTemplateDecl. - UnresolvedSet VisibleConversions; + UnresolvedSet<4> VisibleConversions; /// \brief The template or declaration that this declaration /// describes or was instantiated from, respectively. @@ -483,20 +484,20 @@ public: /// getConversions - Retrieve the overload set containing all of the /// conversion functions in this class. - UnresolvedSet *getConversionFunctions() { + UnresolvedSetImpl *getConversionFunctions() { assert((this->isDefinition() || cast<RecordType>(getTypeForDecl())->isBeingDefined()) && "getConversionFunctions() called on incomplete type"); return &Conversions; } - const UnresolvedSet *getConversionFunctions() const { + const UnresolvedSetImpl *getConversionFunctions() const { assert((this->isDefinition() || cast<RecordType>(getTypeForDecl())->isBeingDefined()) && "getConversionFunctions() called on incomplete type"); return &Conversions; } - typedef UnresolvedSet::iterator conversion_iterator; + typedef UnresolvedSetImpl::iterator conversion_iterator; conversion_iterator conversion_begin() const { return Conversions.begin(); } conversion_iterator conversion_end() const { return Conversions.end(); } @@ -509,7 +510,7 @@ public: /// getVisibleConversionFunctions - get all conversion functions visible /// in current class; including conversion function templates. - const UnresolvedSet *getVisibleConversionFunctions(); + const UnresolvedSetImpl *getVisibleConversionFunctions(); /// addVisibleConversionFunction - Add a new conversion function to the /// list of visible conversion functions. @@ -816,6 +817,15 @@ public: /// GraphViz. void viewInheritance(ASTContext& Context) const; + /// MergeAccess - Calculates the access of a decl that is reached + /// along a path. + static AccessSpecifier MergeAccess(AccessSpecifier PathAccess, + AccessSpecifier DeclAccess) { + assert(DeclAccess != AS_none); + if (DeclAccess == AS_private) return AS_none; + return (PathAccess > DeclAccess ? PathAccess : DeclAccess); + } + static bool classof(const Decl *D) { return D->getKind() == CXXRecord || D->getKind() == ClassTemplateSpecialization || diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 920d31f..0fb0db1 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -75,6 +75,24 @@ public: } }; +/// \brief A list of Objective-C protocols, along with the source +/// locations at which they were referenced. +class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> { + SourceLocation *Locations; + + using ObjCList<ObjCProtocolDecl>::set; + +public: + ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(0) { } + + typedef const SourceLocation *loc_iterator; + loc_iterator loc_begin() const { return Locations; } + loc_iterator loc_end() const { return Locations + size(); } + + void set(ObjCProtocolDecl* const* InList, unsigned Elts, + const SourceLocation *Locs, ASTContext &Ctx); + void Destroy(ASTContext &Ctx); +}; /// ObjCMethodDecl - Represents an instance or class method declaration. @@ -410,9 +428,9 @@ class ObjCInterfaceDecl : public ObjCContainerDecl { ObjCInterfaceDecl *SuperClass; /// Protocols referenced in interface header declaration - ObjCList<ObjCProtocolDecl> ReferencedProtocols; + ObjCProtocolList ReferencedProtocols; - /// Instance variables in the interface. + /// Instance variables in the interface. This list is completely redundant. ObjCList<ObjCIvarDecl> IVars; /// List of categories defined for this class. @@ -442,7 +460,7 @@ public: SourceLocation ClassLoc = SourceLocation(), bool ForwardDecl = false, bool isInternal = false); - const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const { + const ObjCProtocolList &getReferencedProtocols() const { return ReferencedProtocols; } @@ -459,9 +477,16 @@ public: : getClassMethod(Sel); } - typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator; + typedef ObjCProtocolList::iterator protocol_iterator; protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } + typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; + protocol_loc_iterator protocol_loc_begin() const { + return ReferencedProtocols.loc_begin(); + } + protocol_loc_iterator protocol_loc_end() const { + return ReferencedProtocols.loc_end(); + } unsigned protocol_size() const { return ReferencedProtocols.size(); } typedef ObjCList<ObjCIvarDecl>::iterator ivar_iterator; @@ -473,14 +498,16 @@ public: /// setProtocolList - Set the list of protocols that this interface /// implements. void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num, - ASTContext &C) { - ReferencedProtocols.set(List, Num, C); + const SourceLocation *Locs, ASTContext &C) { + ReferencedProtocols.set(List, Num, Locs, C); } /// mergeClassExtensionProtocolList - Merge class extension's protocol list /// into the protocol list for this class. - void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List, unsigned Num, - ASTContext &C); + void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List, + unsigned Num, + const SourceLocation *Locs, + ASTContext &C); void setIVarList(ObjCIvarDecl * const *List, unsigned Num, ASTContext &C) { IVars.set(List, Num, C); @@ -660,7 +687,7 @@ public: /// class ObjCProtocolDecl : public ObjCContainerDecl { /// Referenced protocols - ObjCList<ObjCProtocolDecl> ReferencedProtocols; + ObjCProtocolList ReferencedProtocols; bool isForwardProtoDecl; // declared with @protocol. @@ -680,19 +707,26 @@ public: /// Destroy - Call destructors and release memory. virtual void Destroy(ASTContext& C); - const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const { + const ObjCProtocolList &getReferencedProtocols() const { return ReferencedProtocols; } - typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator; + typedef ObjCProtocolList::iterator protocol_iterator; protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } + typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; + protocol_loc_iterator protocol_loc_begin() const { + return ReferencedProtocols.loc_begin(); + } + protocol_loc_iterator protocol_loc_end() const { + return ReferencedProtocols.loc_end(); + } unsigned protocol_size() const { return ReferencedProtocols.size(); } /// setProtocolList - Set the list of protocols that this interface /// implements. void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, - ASTContext &C) { - ReferencedProtocols.set(List, Num, C); + const SourceLocation *Locs, ASTContext &C) { + ReferencedProtocols.set(List, Num, Locs, C); } ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName); @@ -772,31 +806,45 @@ public: /// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo; /// class ObjCForwardProtocolDecl : public Decl { - ObjCList<ObjCProtocolDecl> ReferencedProtocols; + ObjCProtocolList ReferencedProtocols; ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L, ObjCProtocolDecl *const *Elts, unsigned nElts, - ASTContext &C); + const SourceLocation *Locs, ASTContext &C); virtual ~ObjCForwardProtocolDecl() {} public: static ObjCForwardProtocolDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, - ObjCProtocolDecl *const *Elts = 0, - unsigned Num = 0); + ObjCProtocolDecl *const *Elts, + unsigned Num, + const SourceLocation *Locs); + + static ObjCForwardProtocolDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L) { + return Create(C, DC, L, 0, 0, 0); + } /// Destroy - Call destructors and release memory. virtual void Destroy(ASTContext& C); - typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator; + typedef ObjCProtocolList::iterator protocol_iterator; protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } + typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; + protocol_loc_iterator protocol_loc_begin() const { + return ReferencedProtocols.loc_begin(); + } + protocol_loc_iterator protocol_loc_end() const { + return ReferencedProtocols.loc_end(); + } + unsigned protocol_size() const { return ReferencedProtocols.size(); } /// setProtocolList - Set the list of forward protocols. void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, - ASTContext &C) { - ReferencedProtocols.set(List, Num, C); + const SourceLocation *Locs, ASTContext &C) { + ReferencedProtocols.set(List, Num, Locs, C); } static bool classof(const Decl *D) { return D->getKind() == ObjCForwardProtocol; @@ -826,22 +874,32 @@ class ObjCCategoryDecl : public ObjCContainerDecl { ObjCInterfaceDecl *ClassInterface; /// referenced protocols in this category. - ObjCList<ObjCProtocolDecl> ReferencedProtocols; + ObjCProtocolList ReferencedProtocols; /// Next category belonging to this class. /// FIXME: this should not be a singly-linked list. Move storage elsewhere. ObjCCategoryDecl *NextClassCategory; - SourceLocation EndLoc; // marks the '>' or identifier. + /// \brief The location of the '@' in '@interface' + SourceLocation AtLoc; - ObjCCategoryDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id) - : ObjCContainerDecl(ObjCCategory, DC, L, Id), - ClassInterface(0), NextClassCategory(0){ + /// \brief The location of the category name in this declaration. + SourceLocation CategoryNameLoc; + + ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc, + SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, + IdentifierInfo *Id) + : ObjCContainerDecl(ObjCCategory, DC, ClassNameLoc, Id), + ClassInterface(0), NextClassCategory(0), AtLoc(AtLoc), + CategoryNameLoc(CategoryNameLoc) { } public: static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id); + SourceLocation AtLoc, + SourceLocation ClassNameLoc, + SourceLocation CategoryNameLoc, + IdentifierInfo *Id); ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } @@ -853,18 +911,25 @@ public: /// setProtocolList - Set the list of protocols that this interface /// implements. void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, - ASTContext &C) { - ReferencedProtocols.set(List, Num, C); + const SourceLocation *Locs, ASTContext &C) { + ReferencedProtocols.set(List, Num, Locs, C); } - const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const { + const ObjCProtocolList &getReferencedProtocols() const { return ReferencedProtocols; } - typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator; + typedef ObjCProtocolList::iterator protocol_iterator; protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } unsigned protocol_size() const { return ReferencedProtocols.size(); } + typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; + protocol_loc_iterator protocol_loc_begin() const { + return ReferencedProtocols.loc_begin(); + } + protocol_loc_iterator protocol_loc_end() const { + return ReferencedProtocols.loc_end(); + } ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; } void setNextClassCategory(ObjCCategoryDecl *Cat) { @@ -874,10 +939,16 @@ public: NextClassCategory = ClassInterface->getCategoryList(); ClassInterface->setCategoryList(this); } - // Location information, modeled after the Stmt API. - SourceLocation getLocStart() const { return getLocation(); } // '@'interface - SourceLocation getLocEnd() const { return EndLoc; } - void setLocEnd(SourceLocation LE) { EndLoc = LE; } + + SourceLocation getAtLoc() const { return AtLoc; } + void setAtLoc(SourceLocation At) { AtLoc = At; } + + SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; } + void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; } + + virtual SourceRange getSourceRange() const { + return SourceRange(AtLoc, getAtEndRange().getEnd()); + } static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; } static bool classof(const ObjCCategoryDecl *D) { return true; } @@ -1133,6 +1204,7 @@ public: enum SetterKind { Assign, Retain, Copy }; enum PropertyControl { None, Required, Optional }; private: + SourceLocation AtLoc; // location of @property QualType DeclType; unsigned PropertyAttributes : 8; @@ -1147,8 +1219,8 @@ private: ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, - QualType T) - : NamedDecl(ObjCProperty, DC, L, Id), DeclType(T), + SourceLocation AtLocation, QualType T) + : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), DeclType(T), PropertyAttributes(OBJC_PR_noattr), PropertyImplementation(None), GetterName(Selector()), SetterName(Selector()), @@ -1156,8 +1228,12 @@ private: public: static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, QualType T, + IdentifierInfo *Id, SourceLocation AtLocation, + QualType T, PropertyControl propControl = None); + SourceLocation getAtLoc() const { return AtLoc; } + void setAtLoc(SourceLocation L) { AtLoc = L; } + QualType getType() const { return DeclType; } void setType(QualType T) { DeclType = T; } diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index cfbae9f..2527817 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -1462,14 +1462,19 @@ class CompoundLiteralExpr : public Expr { /// compound literal like "(int){4}". This can be null if this is a /// synthesized compound expression. SourceLocation LParenLoc; + + /// The type as written. This can be an incomplete array type, in + /// which case the actual expression type will be different. + TypeSourceInfo *TInfo; Stmt *Init; bool FileScope; public: // FIXME: Can compound literals be value-dependent? - CompoundLiteralExpr(SourceLocation lparenloc, QualType ty, Expr *init, - bool fileScope) - : Expr(CompoundLiteralExprClass, ty, ty->isDependentType(), false), - LParenLoc(lparenloc), Init(init), FileScope(fileScope) {} + CompoundLiteralExpr(SourceLocation lparenloc, TypeSourceInfo *tinfo, + QualType T, Expr *init, bool fileScope) + : Expr(CompoundLiteralExprClass, T, + tinfo->getType()->isDependentType(), false), + LParenLoc(lparenloc), TInfo(tinfo), Init(init), FileScope(fileScope) {} /// \brief Construct an empty compound literal. explicit CompoundLiteralExpr(EmptyShell Empty) @@ -1485,6 +1490,9 @@ public: SourceLocation getLParenLoc() const { return LParenLoc; } void setLParenLoc(SourceLocation L) { LParenLoc = L; } + TypeSourceInfo *getTypeSourceInfo() const { return TInfo; } + void setTypeSourceInfo(TypeSourceInfo* tinfo) { TInfo = tinfo; } + virtual SourceRange getSourceRange() const { // FIXME: Init should never be null. if (!Init) @@ -1712,24 +1720,28 @@ public: /// expression will be an lvalue. The reference type, however, will /// not be used as the type of the expression. class ExplicitCastExpr : public CastExpr { - /// TypeAsWritten - The type that this expression is casting to, as - /// written in the source code. - QualType TypeAsWritten; + /// TInfo - Source type info for the (written) type + /// this expression is casting to. + TypeSourceInfo *TInfo; protected: ExplicitCastExpr(StmtClass SC, QualType exprTy, CastKind kind, - Expr *op, QualType writtenTy) - : CastExpr(SC, exprTy, kind, op), TypeAsWritten(writtenTy) {} + Expr *op, TypeSourceInfo *writtenTy) + : CastExpr(SC, exprTy, kind, op), TInfo(writtenTy) {} /// \brief Construct an empty explicit cast. ExplicitCastExpr(StmtClass SC, EmptyShell Shell) : CastExpr(SC, Shell) { } public: + /// getTypeInfoAsWritten - Returns the type source info for the type + /// that this expression is casting to. + TypeSourceInfo *getTypeInfoAsWritten() const { return TInfo; } + void setTypeInfoAsWritten(TypeSourceInfo *writtenTy) { TInfo = writtenTy; } + /// getTypeAsWritten - Returns the type that this expression is /// casting to, as written in the source code. - QualType getTypeAsWritten() const { return TypeAsWritten; } - void setTypeAsWritten(QualType T) { TypeAsWritten = T; } + QualType getTypeAsWritten() const { return TInfo->getType(); } static bool classof(const Stmt *T) { StmtClass SC = T->getStmtClass(); @@ -1750,8 +1762,9 @@ class CStyleCastExpr : public ExplicitCastExpr { SourceLocation LPLoc; // the location of the left paren SourceLocation RPLoc; // the location of the right paren public: - CStyleCastExpr(QualType exprTy, CastKind kind, Expr *op, QualType writtenTy, - SourceLocation l, SourceLocation r) : + CStyleCastExpr(QualType exprTy, CastKind kind, Expr *op, + TypeSourceInfo *writtenTy, + SourceLocation l, SourceLocation r) : ExplicitCastExpr(CStyleCastExprClass, exprTy, kind, op, writtenTy), LPLoc(l), RPLoc(r) {} diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 55d5108e..6ce95ac 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -16,7 +16,7 @@ #include "clang/Basic/TypeTraits.h" #include "clang/AST/Expr.h" -#include "clang/AST/Decl.h" +#include "clang/AST/UnresolvedSet.h" #include "clang/AST/TemplateBase.h" namespace clang { @@ -118,9 +118,12 @@ private: protected: CXXNamedCastExpr(StmtClass SC, QualType ty, CastKind kind, Expr *op, - QualType writtenTy, SourceLocation l) + TypeSourceInfo *writtenTy, SourceLocation l) : ExplicitCastExpr(SC, ty, kind, op, writtenTy), Loc(l) {} + explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell) + : ExplicitCastExpr(SC, Shell) { } + public: const char *getCastName() const; @@ -154,9 +157,12 @@ public: class CXXStaticCastExpr : public CXXNamedCastExpr { public: CXXStaticCastExpr(QualType ty, CastKind kind, Expr *op, - QualType writtenTy, SourceLocation l) + TypeSourceInfo *writtenTy, SourceLocation l) : CXXNamedCastExpr(CXXStaticCastExprClass, ty, kind, op, writtenTy, l) {} + explicit CXXStaticCastExpr(EmptyShell Empty) + : CXXNamedCastExpr(CXXStaticCastExprClass, Empty) { } + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXStaticCastExprClass; } @@ -171,10 +177,13 @@ public: /// @c dynamic_cast<Derived*>(BasePtr). class CXXDynamicCastExpr : public CXXNamedCastExpr { public: - CXXDynamicCastExpr(QualType ty, CastKind kind, Expr *op, QualType writtenTy, - SourceLocation l) + CXXDynamicCastExpr(QualType ty, CastKind kind, Expr *op, + TypeSourceInfo *writtenTy, SourceLocation l) : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, kind, op, writtenTy, l) {} + explicit CXXDynamicCastExpr(EmptyShell Empty) + : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty) { } + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXDynamicCastExprClass; } @@ -190,10 +199,13 @@ public: class CXXReinterpretCastExpr : public CXXNamedCastExpr { public: CXXReinterpretCastExpr(QualType ty, CastKind kind, Expr *op, - QualType writtenTy, SourceLocation l) + TypeSourceInfo *writtenTy, SourceLocation l) : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, kind, op, writtenTy, l) {} + explicit CXXReinterpretCastExpr(EmptyShell Empty) + : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty) { } + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXReinterpretCastExprClass; } @@ -207,10 +219,13 @@ public: /// @c const_cast<char*>(PtrToConstChar). class CXXConstCastExpr : public CXXNamedCastExpr { public: - CXXConstCastExpr(QualType ty, Expr *op, QualType writtenTy, + CXXConstCastExpr(QualType ty, Expr *op, TypeSourceInfo *writtenTy, SourceLocation l) : CXXNamedCastExpr(CXXConstCastExprClass, ty, CK_NoOp, op, writtenTy, l) {} + explicit CXXConstCastExpr(EmptyShell Empty) + : CXXNamedCastExpr(CXXConstCastExprClass, Empty) { } + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXConstCastExprClass; } @@ -625,15 +640,20 @@ class CXXFunctionalCastExpr : public ExplicitCastExpr { SourceLocation TyBeginLoc; SourceLocation RParenLoc; public: - CXXFunctionalCastExpr(QualType ty, QualType writtenTy, + CXXFunctionalCastExpr(QualType ty, TypeSourceInfo *writtenTy, SourceLocation tyBeginLoc, CastKind kind, Expr *castExpr, SourceLocation rParenLoc) : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, kind, castExpr, writtenTy), TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {} + explicit CXXFunctionalCastExpr(EmptyShell Shell) + : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell) { } + SourceLocation getTypeBeginLoc() const { return TyBeginLoc; } + void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; } SourceLocation getRParenLoc() const { return RParenLoc; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } virtual SourceRange getSourceRange() const { return SourceRange(TyBeginLoc, RParenLoc); @@ -1052,7 +1072,7 @@ public: class UnresolvedLookupExpr : public Expr { /// The results. These are undesugared, which is to say, they may /// include UsingShadowDecls. - UnresolvedSet Results; + UnresolvedSet<4> Results; /// The name declared. DeclarationName Name; @@ -1113,15 +1133,15 @@ public: /// Computes whether an unresolved lookup on the given declarations /// and optional template arguments is type- and value-dependent. - static bool ComputeDependence(NamedDecl * const *Begin, - NamedDecl * const *End, + static bool ComputeDependence(UnresolvedSetImpl::const_iterator Begin, + UnresolvedSetImpl::const_iterator End, const TemplateArgumentListInfo *Args); void addDecl(NamedDecl *Decl) { Results.addDecl(Decl); } - typedef UnresolvedSet::iterator decls_iterator; + typedef UnresolvedSetImpl::iterator decls_iterator; decls_iterator decls_begin() const { return Results.begin(); } decls_iterator decls_end() const { return Results.end(); } @@ -1696,7 +1716,7 @@ public: class UnresolvedMemberExpr : public Expr { /// The results. These are undesugared, which is to say, they may /// include UsingShadowDecls. - UnresolvedSet Results; + UnresolvedSet<4> Results; /// \brief The expression for the base pointer or class reference, /// e.g., the \c x in x.f. This can be null if this is an 'unbased' @@ -1775,7 +1795,7 @@ public: Results.addDecl(Decl); } - typedef UnresolvedSet::iterator decls_iterator; + typedef UnresolvedSetImpl::iterator decls_iterator; decls_iterator decls_begin() const { return Results.begin(); } decls_iterator decls_end() const { return Results.end(); } diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 9b0cdc3..b7b60df 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -385,6 +385,14 @@ public: } }; +/// CallingConv - Specifies the calling convention that a function uses. +enum CallingConv { + CC_Default, + CC_C, // __attribute__((cdecl)) + CC_X86StdCall, // __attribute__((stdcall)) + CC_X86FastCall // __attribute__((fastcall)) +}; + /// QualType - For efficiency, we don't store CV-qualified types as nodes on /// their own: instead each reference to a type stores the qualifiers. This @@ -669,6 +677,10 @@ public: /// false otherwise. bool getNoReturnAttr() const; + /// getCallConv - Returns the calling convention of the type if the type + /// is a function type, CC_Default otherwise. + CallingConv getCallConv() const; + private: // These methods are implemented in a separate translation unit; // "static"-ize them to avoid creating temporary QualTypes in the @@ -1691,21 +1703,25 @@ class FunctionType : public Type { /// NoReturn - Indicates if the function type is attribute noreturn. unsigned NoReturn : 1; + /// CallConv - The calling convention used by the function. + unsigned CallConv : 2; + // The type returned by the function. QualType ResultType; protected: FunctionType(TypeClass tc, QualType res, bool SubclassInfo, unsigned typeQuals, QualType Canonical, bool Dependent, - bool noReturn = false) + bool noReturn = false, CallingConv callConv = CC_Default) : Type(tc, Canonical, Dependent), SubClassData(SubclassInfo), TypeQuals(typeQuals), NoReturn(noReturn), - ResultType(res) {} + CallConv(callConv), ResultType(res) {} bool getSubClassData() const { return SubClassData; } unsigned getTypeQuals() const { return TypeQuals; } public: QualType getResultType() const { return ResultType; } bool getNoReturnAttr() const { return NoReturn; } + CallingConv getCallConv() const { return (CallingConv)CallConv; } static bool classof(const Type *T) { return T->getTypeClass() == FunctionNoProto || @@ -1718,9 +1734,9 @@ public: /// no information available about its arguments. class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { FunctionNoProtoType(QualType Result, QualType Canonical, - bool NoReturn = false) + bool NoReturn = false, CallingConv CallConv = CC_Default) : FunctionType(FunctionNoProto, Result, false, 0, Canonical, - /*Dependent=*/false, NoReturn) {} + /*Dependent=*/false, NoReturn, CallConv) {} friend class ASTContext; // ASTContext creates these. public: // No additional state past what FunctionType provides. @@ -1762,10 +1778,12 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode { FunctionProtoType(QualType Result, const QualType *ArgArray, unsigned numArgs, bool isVariadic, unsigned typeQuals, bool hasExs, bool hasAnyExs, const QualType *ExArray, - unsigned numExs, QualType Canonical, bool NoReturn) + unsigned numExs, QualType Canonical, bool NoReturn, + CallingConv CallConv) : FunctionType(FunctionProto, Result, isVariadic, typeQuals, Canonical, (Result->isDependentType() || - hasAnyDependentType(ArgArray, numArgs)), NoReturn), + hasAnyDependentType(ArgArray, numArgs)), NoReturn, + CallConv), NumArgs(numArgs), NumExceptions(numExs), HasExceptionSpec(hasExs), AnyExceptionSpec(hasAnyExs) { // Fill in the trailing argument array. @@ -2496,26 +2514,31 @@ class ObjCInterfaceType : public Type, public llvm::FoldingSetNode { // List of protocols for this protocol conforming object type // List is sorted on protocol name. No protocol is enterred more than once. - llvm::SmallVector<ObjCProtocolDecl*, 4> Protocols; + ObjCProtocolDecl **Protocols; + unsigned NumProtocols; - ObjCInterfaceType(QualType Canonical, ObjCInterfaceDecl *D, - ObjCProtocolDecl **Protos, unsigned NumP) : - Type(ObjCInterface, Canonical, /*Dependent=*/false), - Decl(D), Protocols(Protos, Protos+NumP) { } + ObjCInterfaceType(ASTContext &Ctx, QualType Canonical, ObjCInterfaceDecl *D, + ObjCProtocolDecl **Protos, unsigned NumP); friend class ASTContext; // ASTContext creates these. public: + void Destroy(ASTContext& C); + ObjCInterfaceDecl *getDecl() const { return Decl; } /// getNumProtocols - Return the number of qualifying protocols in this /// interface type, or 0 if there are none. - unsigned getNumProtocols() const { return Protocols.size(); } + unsigned getNumProtocols() const { return NumProtocols; } /// qual_iterator and friends: this provides access to the (potentially empty) /// list of protocols qualifying this interface. - typedef llvm::SmallVector<ObjCProtocolDecl*, 8>::const_iterator qual_iterator; - qual_iterator qual_begin() const { return Protocols.begin(); } - qual_iterator qual_end() const { return Protocols.end(); } - bool qual_empty() const { return Protocols.size() == 0; } + typedef ObjCProtocolDecl* const * qual_iterator; + qual_iterator qual_begin() const { + return Protocols; + } + qual_iterator qual_end() const { + return Protocols ? Protocols + NumProtocols : 0; + } + bool qual_empty() const { return NumProtocols == 0; } bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -2541,15 +2564,16 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { // List of protocols for this protocol conforming object type // List is sorted on protocol name. No protocol is entered more than once. - llvm::SmallVector<ObjCProtocolDecl*, 8> Protocols; + ObjCProtocolDecl **Protocols; + unsigned NumProtocols; - ObjCObjectPointerType(QualType Canonical, QualType T, - ObjCProtocolDecl **Protos, unsigned NumP) : - Type(ObjCObjectPointer, Canonical, /*Dependent=*/false), - PointeeType(T), Protocols(Protos, Protos+NumP) { } + ObjCObjectPointerType(ASTContext &Ctx, QualType Canonical, QualType T, + ObjCProtocolDecl **Protos, unsigned NumP); friend class ASTContext; // ASTContext creates these. public: + void Destroy(ASTContext& C); + // Get the pointee type. Pointee will either be: // - a built-in type (for 'id' and 'Class'). // - an interface type (for user-defined types). @@ -2567,35 +2591,39 @@ public: /// isObjCIdType - true for "id". bool isObjCIdType() const { return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) && - !Protocols.size(); + !NumProtocols; } /// isObjCClassType - true for "Class". bool isObjCClassType() const { return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) && - !Protocols.size(); + !NumProtocols; } /// isObjCQualifiedIdType - true for "id <p>". bool isObjCQualifiedIdType() const { return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) && - Protocols.size(); + NumProtocols; } /// isObjCQualifiedClassType - true for "Class <p>". bool isObjCQualifiedClassType() const { return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) && - Protocols.size(); + NumProtocols; } /// qual_iterator and friends: this provides access to the (potentially empty) /// list of protocols qualifying this interface. - typedef llvm::SmallVector<ObjCProtocolDecl*, 8>::const_iterator qual_iterator; + typedef ObjCProtocolDecl* const * qual_iterator; - qual_iterator qual_begin() const { return Protocols.begin(); } - qual_iterator qual_end() const { return Protocols.end(); } - bool qual_empty() const { return Protocols.size() == 0; } + qual_iterator qual_begin() const { + return Protocols; + } + qual_iterator qual_end() const { + return Protocols ? Protocols + NumProtocols : NULL; + } + bool qual_empty() const { return NumProtocols == 0; } /// getNumProtocols - Return the number of qualifying protocols in this /// interface type, or 0 if there are none. - unsigned getNumProtocols() const { return Protocols.size(); } + unsigned getNumProtocols() const { return NumProtocols; } bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -2797,6 +2825,26 @@ inline bool QualType::getNoReturnAttr() const { return false; } +/// getCallConv - Returns the calling convention of the type if the type +/// is a function type, CC_Default otherwise. +inline CallingConv QualType::getCallConv() const { + if (const PointerType *PT = getTypePtr()->getAs<PointerType>()) + return PT->getPointeeType().getCallConv(); + else if (const ReferenceType *RT = getTypePtr()->getAs<ReferenceType>()) + return RT->getPointeeType().getCallConv(); + else if (const MemberPointerType *MPT = + getTypePtr()->getAs<MemberPointerType>()) + return MPT->getPointeeType().getCallConv(); + else if (const BlockPointerType *BPT = + getTypePtr()->getAs<BlockPointerType>()) { + if (const FunctionType *FT = BPT->getPointeeType()->getAs<FunctionType>()) + return FT->getCallConv(); + } else if (const FunctionType *FT = getTypePtr()->getAs<FunctionType>()) + return FT->getCallConv(); + + return CC_Default; +} + /// isMoreQualifiedThan - Determine whether this type is more /// qualified than the Other type. For example, "const volatile int" /// is more qualified than "const int", "volatile int", and diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index c36c0ff..6fb51ed 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -16,6 +16,7 @@ #include "clang/AST/Type.h" #include "clang/AST/TemplateBase.h" +#include "clang/Basic/Specifiers.h" namespace clang { class ParmVarDecl; @@ -372,6 +373,111 @@ public: }; +struct BuiltinLocInfo { + SourceLocation BuiltinLoc; +}; + +/// \brief Wrapper for source info for builtin types. +class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, + BuiltinTypeLoc, + BuiltinType, + BuiltinLocInfo> { +public: + enum { LocalDataSize = sizeof(BuiltinLocInfo) }; + + SourceLocation getBuiltinLoc() const { + return getLocalData()->BuiltinLoc; + } + void setBuiltinLoc(SourceLocation Loc) { + getLocalData()->BuiltinLoc = Loc; + } + + SourceLocation getNameLoc() const { return getBuiltinLoc(); } + + WrittenBuiltinSpecs& getWrittenBuiltinSpecs() { + return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); + } + const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const { + return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); + } + + bool needsExtraLocalData() const { + BuiltinType::Kind bk = getTypePtr()->getKind(); + return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128) + || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble) + || bk == BuiltinType::UChar + || bk == BuiltinType::SChar; + } + + unsigned getExtraLocalDataSize() const { + return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0; + } + + SourceRange getSourceRange() const { + return SourceRange(getBuiltinLoc(), getBuiltinLoc()); + } + + TypeSpecifierSign getWrittenSignSpec() const { + if (needsExtraLocalData()) + return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign); + else + return TSS_unspecified; + } + bool hasWrittenSignSpec() const { + return getWrittenSignSpec() != TSS_unspecified; + } + void setWrittenSignSpec(TypeSpecifierSign written) { + if (needsExtraLocalData()) + getWrittenBuiltinSpecs().Sign = written; + } + + TypeSpecifierWidth getWrittenWidthSpec() const { + if (needsExtraLocalData()) + return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width); + else + return TSW_unspecified; + } + bool hasWrittenWidthSpec() const { + return getWrittenWidthSpec() != TSW_unspecified; + } + void setWrittenWidthSpec(TypeSpecifierWidth written) { + if (needsExtraLocalData()) + getWrittenBuiltinSpecs().Width = written; + } + + TypeSpecifierType getWrittenTypeSpec() const; + bool hasWrittenTypeSpec() const { + return getWrittenTypeSpec() != TST_unspecified; + } + void setWrittenTypeSpec(TypeSpecifierType written) { + if (needsExtraLocalData()) + getWrittenBuiltinSpecs().Type = written; + } + + bool hasModeAttr() const { + if (needsExtraLocalData()) + return getWrittenBuiltinSpecs().ModeAttr; + else + return false; + } + void setModeAttr(bool written) { + if (needsExtraLocalData()) + getWrittenBuiltinSpecs().ModeAttr = written; + } + + void initializeLocal(SourceLocation Loc) { + setBuiltinLoc(Loc); + if (needsExtraLocalData()) { + WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs(); + wbs.Sign = TSS_unspecified; + wbs.Width = TSW_unspecified; + wbs.Type = TST_unspecified; + wbs.ModeAttr = false; + } + } +}; + + /// \brief Wrapper for source info for typedefs. class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, TypedefTypeLoc, @@ -421,12 +527,6 @@ public: EnumDecl *getDecl() const { return getTypePtr()->getDecl(); } }; -/// \brief Wrapper for source info for builtin types. -class BuiltinTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, - BuiltinTypeLoc, - BuiltinType> { -}; - /// \brief Wrapper for template type parameters. class TemplateTypeParmTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, diff --git a/include/clang/AST/TypeLocVisitor.h b/include/clang/AST/TypeLocVisitor.h index 95ec175..50fc439 100644 --- a/include/clang/AST/TypeLocVisitor.h +++ b/include/clang/AST/TypeLocVisitor.h @@ -43,6 +43,7 @@ public: case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc); #include "clang/AST/TypeLocNodes.def" } + llvm_unreachable("unexpected type loc class!"); } #define TYPELOC(CLASS, PARENT) \ diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h new file mode 100644 index 0000000..055d152 --- /dev/null +++ b/include/clang/AST/UnresolvedSet.h @@ -0,0 +1,211 @@ +//===-- UnresolvedSet.h - Unresolved sets of declarations ------*- 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 UnresolvedSet class, which is used to store +// collections of declarations in the AST. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_UNRESOLVEDSET_H +#define LLVM_CLANG_AST_UNRESOLVEDSET_H + +#include <iterator> +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SmallVector.h" +#include "clang/Basic/Specifiers.h" + +namespace clang { + +class NamedDecl; + +/// The iterator over UnresolvedSets. Serves as both the const and +/// non-const iterator. +class UnresolvedSetIterator { + + typedef llvm::PointerIntPair<NamedDecl*, 2> DeclEntry; + typedef llvm::SmallVectorImpl<DeclEntry> DeclsTy; + typedef DeclsTy::iterator IteratorTy; + + IteratorTy ir; + + friend class UnresolvedSetImpl; + explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {} + explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) : + ir(const_cast<DeclsTy::iterator>(ir)) {} +public: + UnresolvedSetIterator() {} + + typedef std::iterator_traits<IteratorTy>::difference_type difference_type; + typedef NamedDecl *value_type; + typedef NamedDecl **pointer; + typedef NamedDecl *reference; + typedef std::iterator_traits<IteratorTy>::iterator_category iterator_category; + + NamedDecl *getDecl() const { return ir->getPointer(); } + AccessSpecifier getAccess() const { return AccessSpecifier(ir->getInt()); } + + NamedDecl *operator*() const { return getDecl(); } + + UnresolvedSetIterator &operator++() { ++ir; return *this; } + UnresolvedSetIterator operator++(int) { return UnresolvedSetIterator(ir++); } + UnresolvedSetIterator &operator--() { --ir; return *this; } + UnresolvedSetIterator operator--(int) { return UnresolvedSetIterator(ir--); } + + UnresolvedSetIterator &operator+=(difference_type d) { + ir += d; return *this; + } + UnresolvedSetIterator operator+(difference_type d) const { + return UnresolvedSetIterator(ir + d); + } + UnresolvedSetIterator &operator-=(difference_type d) { + ir -= d; return *this; + } + UnresolvedSetIterator operator-(difference_type d) const { + return UnresolvedSetIterator(ir - d); + } + value_type operator[](difference_type d) const { return *(*this + d); } + + difference_type operator-(const UnresolvedSetIterator &o) const { + return ir - o.ir; + } + + bool operator==(const UnresolvedSetIterator &o) const { return ir == o.ir; } + bool operator!=(const UnresolvedSetIterator &o) const { return ir != o.ir; } + bool operator<(const UnresolvedSetIterator &o) const { return ir < o.ir; } + bool operator<=(const UnresolvedSetIterator &o) const { return ir <= o.ir; } + bool operator>=(const UnresolvedSetIterator &o) const { return ir >= o.ir; } + bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; } +}; + +/// UnresolvedSet - A set of unresolved declarations. This is needed +/// in a lot of places, but isn't really worth breaking into its own +/// header right now. +class UnresolvedSetImpl { + typedef UnresolvedSetIterator::DeclEntry DeclEntry; + typedef UnresolvedSetIterator::DeclsTy DeclsTy; + + // Don't allow direct construction, and only permit subclassing by + // UnresolvedSet. +private: + template <unsigned N> friend class UnresolvedSet; + UnresolvedSetImpl() {} + UnresolvedSetImpl(const UnresolvedSetImpl &) {} + +public: + // We don't currently support assignment through this iterator, so we might + // as well use the same implementation twice. + typedef UnresolvedSetIterator iterator; + typedef UnresolvedSetIterator const_iterator; + + iterator begin() { return iterator(decls().begin()); } + iterator end() { return iterator(decls().end()); } + + const_iterator begin() const { return const_iterator(decls().begin()); } + const_iterator end() const { return const_iterator(decls().end()); } + + void addDecl(NamedDecl *D) { + addDecl(D, AS_none); + } + + void addDecl(NamedDecl *D, AccessSpecifier AS) { + decls().push_back(DeclEntry(D, AS)); + } + + /// Replaces the given declaration with the new one, once. + /// + /// \return true if the set changed + bool replace(const NamedDecl* Old, NamedDecl *New) { + for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I) + if (I->getPointer() == Old) + return (I->setPointer(New), true); + return false; + } + + /// Replaces the declaration at the given iterator with the new one, + /// preserving the original access bits. + void replace(iterator I, NamedDecl *New) { + I.ir->setPointer(New); + } + + void replace(iterator I, NamedDecl *New, AccessSpecifier AS) { + *I.ir = DeclEntry(New, AS); + } + + void erase(iterator I) { + *I.ir = decls().back(); + decls().pop_back(); + } + + void clear() { decls().clear(); } + void set_size(unsigned N) { decls().set_size(N); } + + bool empty() const { return decls().empty(); } + unsigned size() const { return decls().size(); } + + void append(iterator I, iterator E) { + decls().append(I.ir, E.ir); + } + + /// A proxy reference for implementing operator[]. + class Proxy { + DeclEntry &Ref; + + friend class UnresolvedSetImpl; + Proxy(DeclEntry &Ref) : Ref(Ref) {} + + public: + NamedDecl *getDecl() const { return Ref.getPointer(); } + void setDecl(NamedDecl *D) { Ref.setPointer(D); } + + AccessSpecifier getAccess() const { return AccessSpecifier(Ref.getInt()); } + void setAccess(AccessSpecifier AS) const { Ref.setInt(AS); } + + NamedDecl* operator->() const { return getDecl(); } + operator NamedDecl*() const { return getDecl(); } + Proxy &operator=(const Proxy &D) { Ref = D.Ref; return *this; } + }; + Proxy operator[](unsigned I) { return Proxy(decls()[I]); } + + /// A proxy reference for implementing operator[] const. + class ConstProxy { + const DeclEntry &Ref; + + friend class UnresolvedSetImpl; + ConstProxy(const DeclEntry &Ref) : Ref(Ref) {} + + public: + NamedDecl *getDecl() const { return Ref.getPointer(); } + AccessSpecifier getAccess() const { return AccessSpecifier(Ref.getInt()); } + + NamedDecl *operator->() const { return getDecl(); } + operator NamedDecl*() const { return getDecl(); } + }; + ConstProxy operator[](unsigned I) const { return ConstProxy(decls()[I]); } + +private: + // These work because the only permitted subclass is UnresolvedSetImpl + + DeclsTy &decls() { + return *reinterpret_cast<DeclsTy*>(this); + } + const DeclsTy &decls() const { + return *reinterpret_cast<const DeclsTy*>(this); + } +}; + +/// A set of unresolved declarations +template <unsigned InlineCapacity> class UnresolvedSet : + public UnresolvedSetImpl { + llvm::SmallVector<UnresolvedSetImpl::DeclEntry, InlineCapacity> Decls; +}; + + +} // namespace clang + +#endif |