diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-12-15 18:49:47 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-12-15 18:49:47 +0000 |
commit | 77212133072dc40f070a280af8217032f55a9eb4 (patch) | |
tree | 2fd5819f49caecc5f520219b6b9254fe94ebb138 /include/clang/AST | |
parent | 4b08eb6308ca90a6c08e2fc79d100821b1b1f6aa (diff) | |
download | FreeBSD-src-77212133072dc40f070a280af8217032f55a9eb4.zip FreeBSD-src-77212133072dc40f070a280af8217032f55a9eb4.tar.gz |
Update clang to 91430.
Diffstat (limited to 'include/clang/AST')
-rw-r--r-- | include/clang/AST/ASTContext.h | 66 | ||||
-rw-r--r-- | include/clang/AST/CanonicalType.h | 6 | ||||
-rw-r--r-- | include/clang/AST/Decl.h | 152 | ||||
-rw-r--r-- | include/clang/AST/DeclBase.h | 7 | ||||
-rw-r--r-- | include/clang/AST/DeclCXX.h | 256 | ||||
-rw-r--r-- | include/clang/AST/DeclContextInternals.h | 53 | ||||
-rw-r--r-- | include/clang/AST/DeclNodes.def | 3 | ||||
-rw-r--r-- | include/clang/AST/DeclObjC.h | 8 | ||||
-rw-r--r-- | include/clang/AST/DeclTemplate.h | 12 | ||||
-rw-r--r-- | include/clang/AST/DeclarationName.h | 5 | ||||
-rw-r--r-- | include/clang/AST/Expr.h | 75 | ||||
-rw-r--r-- | include/clang/AST/ExprCXX.h | 126 | ||||
-rw-r--r-- | include/clang/AST/RecordLayout.h | 18 | ||||
-rw-r--r-- | include/clang/AST/StmtCXX.h | 3 | ||||
-rw-r--r-- | include/clang/AST/TemplateBase.h | 28 | ||||
-rw-r--r-- | include/clang/AST/TemplateName.h | 69 | ||||
-rw-r--r-- | include/clang/AST/Type.h | 47 | ||||
-rw-r--r-- | include/clang/AST/TypeLoc.h | 161 | ||||
-rw-r--r-- | include/clang/AST/TypeLocBuilder.h | 45 | ||||
-rw-r--r-- | include/clang/AST/TypeLocVisitor.h | 2 | ||||
-rw-r--r-- | include/clang/AST/TypeNodes.def | 1 | ||||
-rw-r--r-- | include/clang/AST/TypeOrdering.h | 7 |
22 files changed, 704 insertions, 446 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 4f29e5d..3fc5aab 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -45,6 +45,8 @@ namespace clang { class SourceManager; class TargetInfo; // Decls + class CXXMethodDecl; + class CXXRecordDecl; class Decl; class FieldDecl; class ObjCIvarDecl; @@ -57,6 +59,7 @@ namespace clang { class TypeDecl; class TypedefDecl; class UsingDecl; + class UsingShadowDecl; namespace Builtin { class Context; } @@ -105,6 +108,9 @@ class ASTContext { llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*> ASTRecordLayouts; llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*> ObjCLayouts; + /// KeyFunctions - A cache mapping from CXXRecordDecls to key functions. + llvm::DenseMap<const CXXRecordDecl*, const CXXMethodDecl*> KeyFunctions; + /// \brief Mapping from ObjCContainers to their ObjCImplementations. llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls; @@ -183,8 +189,10 @@ class ASTContext { llvm::DenseMap<const VarDecl *, MemberSpecializationInfo *> InstantiatedFromStaticDataMember; - /// \brief Keeps track of the UnresolvedUsingDecls from which UsingDecls - /// where created during instantiation. + /// \brief Keeps track of the declaration from which a UsingDecl was + /// created during instantiation. The source declaration is always + /// a UsingDecl, an UnresolvedUsingValueDecl, or an + /// UnresolvedUsingTypenameDecl. /// /// For example: /// \code @@ -203,8 +211,10 @@ class ASTContext { /// /// This mapping will contain an entry that maps from the UsingDecl in /// B<int> to the UnresolvedUsingDecl in B<T>. - llvm::DenseMap<UsingDecl *, NamedDecl *> - InstantiatedFromUnresolvedUsingDecl; + llvm::DenseMap<UsingDecl *, NamedDecl *> InstantiatedFromUsingDecl; + + llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*> + InstantiatedFromUsingShadowDecl; llvm::DenseMap<FieldDecl *, FieldDecl *> InstantiatedFromUnnamedFieldDecl; @@ -282,14 +292,18 @@ public: void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl, TemplateSpecializationKind TSK); - /// \brief If this using decl is instantiated from an unresolved using decl, + /// \brief If the given using decl is an instantiation of a + /// (possibly unresolved) using decl from a template instantiation, /// return it. - NamedDecl *getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD); + NamedDecl *getInstantiatedFromUsingDecl(UsingDecl *Inst); - /// \brief Note that the using decl \p Inst is an instantiation of - /// the unresolved using decl \p Tmpl of a class template. - void setInstantiatedFromUnresolvedUsingDecl(UsingDecl *Inst, NamedDecl *Tmpl); + /// \brief Remember that the using decl \p Inst is an instantiation + /// of the using decl \p Pattern of a class template. + void setInstantiatedFromUsingDecl(UsingDecl *Inst, NamedDecl *Pattern); + void setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst, + UsingShadowDecl *Pattern); + UsingShadowDecl *getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst); FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field); @@ -380,9 +394,10 @@ public: /// equivalent to calling T.withConst(). QualType getConstType(QualType T) { return T.withConst(); } - /// getNoReturnType - Add the noreturn attribute to the given type which must - /// be a FunctionType or a pointer to an allowable type or a BlockPointer. - QualType getNoReturnType(QualType T); + /// getNoReturnType - Add or remove the noreturn attribute to the given type + /// which must be a FunctionType or a pointer to an allowable type or a + /// BlockPointer. + QualType getNoReturnType(QualType T, bool AddNoReturn = true); /// getComplexType - Return the uniqued reference to the type for a complex /// number with the specified element type. @@ -569,7 +584,7 @@ public: /// getSizeType - Return the unique type for "size_t" (C99 7.17), defined /// in <stddef.h>. The sizeof operator requires this (C99 6.5.3.4p4). - QualType getSizeType() const; + CanQualType getSizeType() const; /// getWCharType - In C++, this returns the unique wchar_t type. In C99, this /// returns a type compatible with the type defined in <stddef.h> as defined @@ -735,12 +750,12 @@ public: DeclarationName getNameForTemplate(TemplateName Name); + TemplateName getOverloadedTemplateName(NamedDecl * const *Begin, + NamedDecl * const *End); + TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, TemplateDecl *Template); - TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, - bool TemplateKeyword, - OverloadedFunctionDecl *Template); TemplateName getDependentTemplateName(NestedNameSpecifier *NNS, const IdentifierInfo *Name); @@ -843,6 +858,13 @@ public: const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D); + /// getKeyFunction - Get the key function for the given record decl. + /// The key function is, according to the Itanium C++ ABI section 5.2.3: + /// + /// ...the first non-pure virtual function that is not inline at the point + /// of class definition. + const CXXMethodDecl *getKeyFunction(const CXXRecordDecl *RD); + void CollectObjCIvars(const ObjCInterfaceDecl *OI, llvm::SmallVectorImpl<FieldDecl*> &Fields); @@ -1108,9 +1130,9 @@ public: void setObjCImplementation(ObjCCategoryDecl *CatD, ObjCCategoryImplDecl *ImplD); - /// \brief Allocate an uninitialized DeclaratorInfo. + /// \brief Allocate an uninitialized TypeSourceInfo. /// - /// The caller should initialize the memory held by DeclaratorInfo using + /// The caller should initialize the memory held by TypeSourceInfo using /// the TypeLoc wrappers. /// /// \param T the type that will be the basis for type source info. This type @@ -1119,13 +1141,13 @@ public: /// /// \param Size the size of the type info to create, or 0 if the size /// should be calculated based on the type. - DeclaratorInfo *CreateDeclaratorInfo(QualType T, unsigned Size = 0); + TypeSourceInfo *CreateTypeSourceInfo(QualType T, unsigned Size = 0); - /// \brief Allocate a DeclaratorInfo where all locations have been + /// \brief Allocate a TypeSourceInfo where all locations have been /// initialized to a given location, which defaults to the empty /// location. - DeclaratorInfo * - getTrivialDeclaratorInfo(QualType T, SourceLocation Loc = SourceLocation()); + TypeSourceInfo * + getTrivialTypeSourceInfo(QualType T, SourceLocation Loc = SourceLocation()); private: ASTContext(const ASTContext&); // DO NOT IMPLEMENT diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index 9b11877..af8d236 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -172,6 +172,12 @@ inline bool operator!=(CanQual<T> x, CanQual<U> y) { /// \brief Represents a canonical, potentially-qualified type. typedef CanQual<Type> CanQualType; +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + CanQualType T) { + DB << static_cast<QualType>(T); + return DB; +} + //----------------------------------------------------------------------------// // Internal proxy classes used by canonical types //----------------------------------------------------------------------------// diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index f794477..ff2b302 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -35,17 +35,17 @@ class TypeLoc; /// /// A client can read the relevant info using TypeLoc wrappers, e.g: /// @code -/// TypeLoc TL = DeclaratorInfo->getTypeLoc(); +/// TypeLoc TL = TypeSourceInfo->getTypeLoc(); /// if (PointerLoc *PL = dyn_cast<PointerLoc>(&TL)) /// PL->getStarLoc().print(OS, SrcMgr); /// @endcode /// -class DeclaratorInfo { +class TypeSourceInfo { QualType Ty; // Contains a memory block after the class, used for type source information, // allocated by ASTContext. friend class ASTContext; - DeclaratorInfo(QualType ty) : Ty(ty) { } + TypeSourceInfo(QualType ty) : Ty(ty) { } public: /// \brief Return the type wrapped by this type source info. QualType getType() const { return Ty; } @@ -322,18 +322,18 @@ public: }; /// \brief Represents a ValueDecl that came out of a declarator. -/// Contains type source information through DeclaratorInfo. +/// Contains type source information through TypeSourceInfo. class DeclaratorDecl : public ValueDecl { - DeclaratorInfo *DeclInfo; + TypeSourceInfo *DeclInfo; protected: DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L, - DeclarationName N, QualType T, DeclaratorInfo *DInfo) - : ValueDecl(DK, DC, L, N, T), DeclInfo(DInfo) {} + DeclarationName N, QualType T, TypeSourceInfo *TInfo) + : ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo) {} public: - DeclaratorInfo *getDeclaratorInfo() const { return DeclInfo; } - void setDeclaratorInfo(DeclaratorInfo *DInfo) { DeclInfo = DInfo; } + TypeSourceInfo *getTypeSourceInfo() const { return DeclInfo; } + void setTypeSourceInfo(TypeSourceInfo *TInfo) { DeclInfo = TInfo; } SourceLocation getTypeSpecStartLoc() const; @@ -348,15 +348,23 @@ public: /// which it was evaluated (if any), and whether or not the statement /// is an integral constant expression (if known). struct EvaluatedStmt { - EvaluatedStmt() : WasEvaluated(false), CheckedICE(false), IsICE(false) { } + EvaluatedStmt() : WasEvaluated(false), IsEvaluating(false), CheckedICE(false), + CheckingICE(false), IsICE(false) { } /// \brief Whether this statement was already evaluated. bool WasEvaluated : 1; + /// \brief Whether this statement is being evaluated. + bool IsEvaluating : 1; + /// \brief Whether we already checked whether this statement was an /// integral constant expression. bool CheckedICE : 1; + /// \brief Whether we are checking whether this statement is an + /// integral constant expression. + bool CheckingICE : 1; + /// \brief Whether this statement is an integral constant /// expression. Only valid if CheckedICE is true. bool IsICE : 1; @@ -432,8 +440,8 @@ private: friend class StmtIteratorBase; protected: VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, - QualType T, DeclaratorInfo *DInfo, StorageClass SC) - : DeclaratorDecl(DK, DC, L, Id, T, DInfo), Init(), + QualType T, TypeSourceInfo *TInfo, StorageClass SC) + : DeclaratorDecl(DK, DC, L, Id, T, TInfo), Init(), ThreadSpecified(false), HasCXXDirectInit(false), DeclaredInCondition(false) { SClass = SC; @@ -453,7 +461,7 @@ public: static VarDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, - QualType T, DeclaratorInfo *DInfo, StorageClass S); + QualType T, TypeSourceInfo *TInfo, StorageClass S); virtual ~VarDecl(); virtual void Destroy(ASTContext& C); @@ -504,23 +512,45 @@ public: void setInit(ASTContext &C, Expr *I); - /// \brief Note that constant evaluation has computed the given - /// value for this variable's initializer. - void setEvaluatedValue(ASTContext &C, const APValue &Value) const { + EvaluatedStmt *EnsureEvaluatedStmt() const { EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>(); if (!Eval) { Stmt *S = Init.get<Stmt *>(); - Eval = new (C) EvaluatedStmt; + Eval = new (getASTContext()) EvaluatedStmt; Eval->Value = S; Init = Eval; } + return Eval; + } + + /// \brief Check whether we are in the process of checking whether the + /// initializer can be evaluated. + bool isEvaluatingValue() const { + if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) + return Eval->IsEvaluating; + return false; + } + + /// \brief Note that we now are checking whether the initializer can be + /// evaluated. + void setEvaluatingValue() const { + EvaluatedStmt *Eval = EnsureEvaluatedStmt(); + Eval->IsEvaluating = true; + } + + /// \brief Note that constant evaluation has computed the given + /// value for this variable's initializer. + void setEvaluatedValue(const APValue &Value) const { + EvaluatedStmt *Eval = EnsureEvaluatedStmt(); + Eval->IsEvaluating = false; Eval->WasEvaluated = true; Eval->Evaluated = Value; } /// \brief Return the already-evaluated value of this variable's - /// initializer, or NULL if the value is not yet known. + /// initializer, or NULL if the value is not yet known. Returns pointer + /// to untyped APValue if the value could not be evaluated. APValue *getEvaluatedValue() const { if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) if (Eval->WasEvaluated) @@ -548,17 +578,27 @@ public: return Init.get<EvaluatedStmt *>()->IsICE; } - /// \brief Note that we now know whether the initializer is an + /// \brief Check whether we are in the process of checking the initializer + /// is an integral constant expression. + bool isCheckingICE() const { + if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) + return Eval->CheckingICE; + + return false; + } + + /// \brief Note that we now are checking whether the initializer is an /// integral constant expression. - void setInitKnownICE(ASTContext &C, bool IsICE) const { - EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>(); - if (!Eval) { - Stmt *S = Init.get<Stmt *>(); - Eval = new (C) EvaluatedStmt; - Eval->Value = S; - Init = Eval; - } + void setCheckingICE() const { + EvaluatedStmt *Eval = EnsureEvaluatedStmt(); + Eval->CheckingICE = true; + } + /// \brief Note that we now know whether the initializer is an + /// integral constant expression. + void setInitKnownICE(bool IsICE) const { + EvaluatedStmt *Eval = EnsureEvaluatedStmt(); + Eval->CheckingICE = false; Eval->CheckedICE = true; Eval->IsICE = IsICE; } @@ -712,7 +752,7 @@ class ImplicitParamDecl : public VarDecl { protected: ImplicitParamDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType Tw) - : VarDecl(DK, DC, L, Id, Tw, /*DInfo=*/0, VarDecl::None) {} + : VarDecl(DK, DC, L, Id, Tw, /*TInfo=*/0, VarDecl::None) {} public: static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, @@ -739,16 +779,16 @@ class ParmVarDecl : public VarDecl { protected: ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, QualType T, DeclaratorInfo *DInfo, + IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg) - : VarDecl(DK, DC, L, Id, T, DInfo, S), objcDeclQualifier(OBJC_TQ_None) { + : VarDecl(DK, DC, L, Id, T, TInfo, S), objcDeclQualifier(OBJC_TQ_None) { setDefaultArg(DefArg); } public: static ParmVarDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,IdentifierInfo *Id, - QualType T, DeclaratorInfo *DInfo, + QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg); ObjCDeclQualifier getObjCDeclQualifier() const { @@ -822,8 +862,8 @@ public: } QualType getOriginalType() const { - if (getDeclaratorInfo()) - return getDeclaratorInfo()->getType(); + if (getTypeSourceInfo()) + return getTypeSourceInfo()->getType(); return getType(); } @@ -907,9 +947,9 @@ private: protected: FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L, - DeclarationName N, QualType T, DeclaratorInfo *DInfo, + DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass S, bool isInline) - : DeclaratorDecl(DK, DC, L, N, T, DInfo), + : DeclaratorDecl(DK, DC, L, N, T, TInfo), DeclContext(DK), ParamInfo(0), Body(), SClass(S), IsInline(isInline), @@ -936,7 +976,7 @@ public: static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T, - DeclaratorInfo *DInfo, + TypeSourceInfo *TInfo, StorageClass S = None, bool isInline = false, bool hasWrittenPrototype = true); @@ -1272,15 +1312,15 @@ class FieldDecl : public DeclaratorDecl { Expr *BitWidth; protected: FieldDecl(Kind DK, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, QualType T, DeclaratorInfo *DInfo, + IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable) - : DeclaratorDecl(DK, DC, L, Id, T, DInfo), Mutable(Mutable), BitWidth(BW) { + : DeclaratorDecl(DK, DC, L, Id, T, TInfo), Mutable(Mutable), BitWidth(BW) { } public: static FieldDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, - DeclaratorInfo *DInfo, Expr *BW, bool Mutable); + TypeSourceInfo *TInfo, Expr *BW, bool Mutable); /// isMutable - Determines whether this field is mutable (C++ only). bool isMutable() const { return Mutable; } @@ -1383,28 +1423,28 @@ public: class TypedefDecl : public TypeDecl { /// UnderlyingType - This is the type the typedef is set to. - DeclaratorInfo *DInfo; + TypeSourceInfo *TInfo; TypedefDecl(DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, DeclaratorInfo *DInfo) - : TypeDecl(Typedef, DC, L, Id), DInfo(DInfo) {} + IdentifierInfo *Id, TypeSourceInfo *TInfo) + : TypeDecl(Typedef, DC, L, Id), TInfo(TInfo) {} virtual ~TypedefDecl() {} public: static TypedefDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, - DeclaratorInfo *DInfo); + TypeSourceInfo *TInfo); - DeclaratorInfo *getTypeDeclaratorInfo() const { - return DInfo; + TypeSourceInfo *getTypeSourceInfo() const { + return TInfo; } QualType getUnderlyingType() const { - return DInfo->getType(); + return TInfo->getType(); } - void setTypeDeclaratorInfo(DeclaratorInfo *newType) { - DInfo = newType; + void setTypeSourceInfo(TypeSourceInfo *newType) { + TInfo = newType; } // Implement isa/cast/dyncast/etc. @@ -1554,6 +1594,12 @@ class EnumDecl : public TagDecl { /// have a different type than this does. QualType IntegerType; + /// PromotionType - The integer type that values of this type should + /// promote to. In C, enumerators are generally of an integer type + /// directly, but gcc-style large enumerators (and all enumerators + /// in C++) are of the enum type instead. + QualType PromotionType; + /// \brief If the enumeration was instantiated from an enumeration /// within a class or function template, this pointer refers to the /// enumeration declared within the template. @@ -1583,7 +1629,8 @@ public: /// declaration as being defined; it's enumerators have already been /// added (via DeclContext::addDecl). NewType is the new underlying /// type of the enumeration type. - void completeDefinition(ASTContext &C, QualType NewType); + void completeDefinition(ASTContext &C, QualType NewType, + QualType PromotionType); // enumerator_iterator - Iterates through the enumerators of this // enumeration. @@ -1597,6 +1644,13 @@ public: return enumerator_iterator(this->decls_end()); } + /// getPromotionType - Return the integer type that enumerators + /// should promote to. + QualType getPromotionType() const { return PromotionType; } + + /// \brief Set the promotion type. + void setPromotionType(QualType T) { PromotionType = T; } + /// getIntegerType - Return the integer type this enum decl corresponds to. /// This returns a null qualtype for an enum forward definition. QualType getIntegerType() const { return IntegerType; } diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index e1f948f..497f863 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -91,7 +91,7 @@ public: IDNS_Ordinary = 0x8, IDNS_ObjCProtocol = 0x10, IDNS_ObjCImplementation = 0x20, - IDNS_ObjCCategoryImpl = 0x40, + IDNS_ObjCCategoryName = 0x40, IDNS_OrdinaryFriend = 0x80, IDNS_TagFriend = 0x100, IDNS_Using = 0x200 @@ -916,6 +916,9 @@ public: /// only happens with friends. void addHiddenDecl(Decl *D); + /// @brief Removes a declaration from this context. + void removeDecl(Decl *D); + /// lookup_iterator - An iterator that provides access to the results /// of looking up a name within this context. typedef NamedDecl **lookup_iterator; @@ -1003,6 +1006,8 @@ public: static bool classof(const Name##Decl *D) { return true; } #include "clang/AST/DeclNodes.def" + void dumpDeclContext() const; + private: void LoadLexicalDeclsFromExternalStorage() const; void LoadVisibleDeclsFromExternalStorage() const; diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 990403e7..5507e99 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -88,108 +88,6 @@ namespace llvm { namespace clang { -/// OverloadedFunctionDecl - An instance of this class represents a -/// set of overloaded functions. All of the functions have the same -/// name and occur within the same scope. -/// -/// An OverloadedFunctionDecl has no ownership over the FunctionDecl -/// nodes it contains. Rather, the FunctionDecls are owned by the -/// enclosing scope (which also owns the OverloadedFunctionDecl -/// node). OverloadedFunctionDecl is used primarily to store a set of -/// overloaded functions for name lookup. -class OverloadedFunctionDecl : public NamedDecl { -protected: - OverloadedFunctionDecl(DeclContext *DC, DeclarationName N) - : NamedDecl(OverloadedFunction, DC, SourceLocation(), N) { } - - /// Functions - the set of overloaded functions contained in this - /// overload set. - llvm::SmallVector<AnyFunctionDecl, 4> Functions; - - // FIXME: This should go away when we stop using - // OverloadedFunctionDecl to store conversions in CXXRecordDecl. - friend class CXXRecordDecl; - -public: - typedef llvm::SmallVector<AnyFunctionDecl, 4>::iterator function_iterator; - typedef llvm::SmallVector<AnyFunctionDecl, 4>::const_iterator - function_const_iterator; - - static OverloadedFunctionDecl *Create(ASTContext &C, DeclContext *DC, - DeclarationName N); - - /// \brief Add a new overloaded function or function template to the set - /// of overloaded function templates. - void addOverload(AnyFunctionDecl F); - - function_iterator function_begin() { return Functions.begin(); } - function_iterator function_end() { return Functions.end(); } - function_const_iterator function_begin() const { return Functions.begin(); } - function_const_iterator function_end() const { return Functions.end(); } - - /// \brief Returns the number of overloaded functions stored in - /// this set. - unsigned size() const { return Functions.size(); } - - // Implement isa/cast/dyncast/etc. - static bool classof(const Decl *D) { - return D->getKind() == OverloadedFunction; - } - static bool classof(const OverloadedFunctionDecl *D) { return true; } -}; - -/// \brief Provides uniform iteration syntax for an overload set, function, -/// or function template. -class OverloadIterator { - /// \brief An overloaded function set, function declaration, or - /// function template declaration. - NamedDecl *D; - - /// \brief If the declaration is an overloaded function set, this is the - /// iterator pointing to the current position within that overloaded - /// function set. - OverloadedFunctionDecl::function_iterator Iter; - -public: - typedef AnyFunctionDecl value_type; - typedef value_type reference; - typedef NamedDecl *pointer; - typedef int difference_type; - typedef std::forward_iterator_tag iterator_category; - - OverloadIterator() : D(0) { } - - OverloadIterator(FunctionDecl *FD) : D(FD) { } - OverloadIterator(FunctionTemplateDecl *FTD) - : D(reinterpret_cast<NamedDecl*>(FTD)) { } - OverloadIterator(OverloadedFunctionDecl *Ovl) - : D(Ovl), Iter(Ovl->function_begin()) { } - - OverloadIterator(NamedDecl *ND); - - reference operator*() const; - - pointer operator->() const { return (**this).get(); } - - OverloadIterator &operator++(); - - OverloadIterator operator++(int) { - OverloadIterator Temp(*this); - ++(*this); - return Temp; - } - - bool Equals(const OverloadIterator &Other) const; -}; - -inline bool operator==(const OverloadIterator &X, const OverloadIterator &Y) { - return X.Equals(Y); -} - -inline bool operator!=(const OverloadIterator &X, const OverloadIterator &Y) { - return !(X == Y); -} - /// CXXBaseSpecifier - A base class of a C++ class. /// /// Each CXXBaseSpecifier represents a single, direct base class (or @@ -210,6 +108,7 @@ class CXXBaseSpecifier { /// Range - The source code range that covers the full base /// specifier, including the "virtual" (if present) and access /// specifier (if present). + // FIXME: Move over to a TypeLoc! SourceRange Range; /// Virtual - Whether this is a virtual base class or not. @@ -635,6 +534,10 @@ public: /// [dcl.init.aggr]). void setAggregate(bool Agg) { Aggregate = Agg; } + /// setMethodAsVirtual - Make input method virtual and set the necesssary + /// special function bits and other bits accordingly. + void setMethodAsVirtual(FunctionDecl *Method); + /// isPOD - Whether this class is a POD-type (C++ [class]p4), which is a class /// that is an aggregate that has no non-static non-POD data members, no /// reference data members, no user-defined copy assignment operator and no @@ -753,7 +656,7 @@ public: /// \brief Determine whether this particular class is a specialization or /// instantiation of a class template or member class of a class template, /// and how it was instantiated or specialized. - TemplateSpecializationKind getTemplateSpecializationKind(); + TemplateSpecializationKind getTemplateSpecializationKind() const; /// \brief Set the kind of specialization or template instantiation this is. void setTemplateSpecializationKind(TemplateSpecializationKind TSK); @@ -762,7 +665,7 @@ public: CXXConstructorDecl *getDefaultConstructor(ASTContext &Context); /// getDestructor - Returns the destructor decl for this class. - const CXXDestructorDecl *getDestructor(ASTContext &Context); + CXXDestructorDecl *getDestructor(ASTContext &Context); /// isLocalClass - If the class is a local class [class.local], returns /// the enclosing function declaration. @@ -802,6 +705,30 @@ public: /// \todo add a separate paramaeter to configure IsDerivedFrom, rather than /// tangling input and output in \p Paths bool isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) const; + + /// \brief Determine whether this class is provably not derived from + /// the type \p Base. + bool isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const; + + /// \brief Function type used by forallBases() as a callback. + /// + /// \param Base the definition of the base class + /// + /// \returns true if this base matched the search criteria + typedef bool ForallBasesCallback(const CXXRecordDecl *BaseDefinition, + void *UserData); + + /// \brief Determines if the given callback holds for all the direct + /// or indirect base classes of this type. + /// + /// The class itself does not count as a base class. This routine + /// returns false if the class has non-computable base classes. + /// + /// \param AllowShortCircuit if false, forces the callback to be called + /// for every base class, even if a dependent or non-matching base was + /// found. + bool forallBases(ForallBasesCallback *BaseMatches, void *UserData, + bool AllowShortCircuit = true) const; /// \brief Function type used by lookupInBases() to determine whether a /// specific base class subobject matches the lookup criteria. @@ -902,15 +829,15 @@ public: class CXXMethodDecl : public FunctionDecl { protected: CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation L, - DeclarationName N, QualType T, DeclaratorInfo *DInfo, + DeclarationName N, QualType T, TypeSourceInfo *TInfo, bool isStatic, bool isInline) - : FunctionDecl(DK, RD, L, N, T, DInfo, (isStatic ? Static : None), + : FunctionDecl(DK, RD, L, N, T, TInfo, (isStatic ? Static : None), isInline) {} public: static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation L, DeclarationName N, - QualType T, DeclaratorInfo *DInfo, + QualType T, TypeSourceInfo *TInfo, bool isStatic = false, bool isInline = false); @@ -968,6 +895,8 @@ public: return getType()->getAs<FunctionProtoType>()->getTypeQuals(); } + bool hasInlineBody() const; + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() >= CXXMethod && D->getKind() <= CXXConversion; @@ -990,12 +919,13 @@ public: /// }; /// @endcode class CXXBaseOrMemberInitializer { - /// BaseOrMember - This points to the entity being initialized, - /// which is either a base class (a Type) or a non-static data - /// member. When the low bit is 1, it's a base - /// class; when the low bit is 0, it's a member. - uintptr_t BaseOrMember; - + /// \brief Either the base class name (stored as a TypeSourceInfo*) or the + /// field being initialized. + llvm::PointerUnion<TypeSourceInfo *, FieldDecl *> BaseOrMember; + + /// \brief The source location for the field name. + SourceLocation MemberLocation; + /// Args - The arguments used to initialize the base or member. Stmt **Args; unsigned NumArgs; @@ -1020,8 +950,8 @@ class CXXBaseOrMemberInitializer { /// and AnonUnionMember holds field decl for au_i1. llvm::PointerUnion<CXXConstructorDecl *, FieldDecl *> CtorOrAnonUnion; - /// IdLoc - Location of the id in ctor-initializer list. - SourceLocation IdLoc; + /// LParenLoc - Location of the left paren of the ctor-initializer. + SourceLocation LParenLoc; /// RParenLoc - Location of the right paren of the ctor-initializer. SourceLocation RParenLoc; @@ -1029,18 +959,22 @@ class CXXBaseOrMemberInitializer { public: /// CXXBaseOrMemberInitializer - Creates a new base-class initializer. explicit - CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs, - CXXConstructorDecl *C, - SourceLocation L, SourceLocation R); + CXXBaseOrMemberInitializer(ASTContext &Context, + TypeSourceInfo *TInfo, CXXConstructorDecl *C, + SourceLocation L, + Expr **Args, unsigned NumArgs, + SourceLocation R); /// CXXBaseOrMemberInitializer - Creates a new member initializer. explicit - CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs, - CXXConstructorDecl *C, - SourceLocation L, SourceLocation R); + CXXBaseOrMemberInitializer(ASTContext &Context, + FieldDecl *Member, SourceLocation MemberLoc, + CXXConstructorDecl *C, SourceLocation L, + Expr **Args, unsigned NumArgs, + SourceLocation R); - /// ~CXXBaseOrMemberInitializer - Destroy the base or member initializer. - ~CXXBaseOrMemberInitializer(); + /// \brief Destroy the base or member initializer. + void Destroy(ASTContext &Context); /// arg_iterator - Iterates through the member initialization /// arguments. @@ -1050,54 +984,54 @@ public: /// arguments. typedef ConstExprIterator const_arg_iterator; - /// getBaseOrMember - get the generic 'member' representing either the field - /// or a base class. - void* getBaseOrMember() const { return reinterpret_cast<void*>(BaseOrMember); } - /// isBaseInitializer - Returns true when this initializer is /// initializing a base class. - bool isBaseInitializer() const { return (BaseOrMember & 0x1) != 0; } + bool isBaseInitializer() const { return BaseOrMember.is<TypeSourceInfo*>(); } /// isMemberInitializer - Returns true when this initializer is /// initializing a non-static data member. - bool isMemberInitializer() const { return (BaseOrMember & 0x1) == 0; } - - /// getBaseClass - If this is a base class initializer, returns the - /// type used to specify the initializer. The resulting type will be - /// a class type or a typedef of a class type. If this is not a base - /// class initializer, returns NULL. - Type *getBaseClass() { - if (isBaseInitializer()) - return reinterpret_cast<Type*>(BaseOrMember & ~0x01); - else - return 0; - } + bool isMemberInitializer() const { return BaseOrMember.is<FieldDecl*>(); } - /// getBaseClass - If this is a base class initializer, returns the - /// type used to specify the initializer. The resulting type will be - /// a class type or a typedef of a class type. If this is not a base - /// class initializer, returns NULL. - const Type *getBaseClass() const { - if (isBaseInitializer()) - return reinterpret_cast<const Type*>(BaseOrMember & ~0x01); - else - return 0; - } + /// If this is a base class initializer, returns the type of the + /// base class with location information. Otherwise, returns an NULL + /// type location. + TypeLoc getBaseClassLoc() const; + /// If this is a base class initializer, returns the type of the base class. + /// Otherwise, returns NULL. + const Type *getBaseClass() const; + Type *getBaseClass(); + + /// \brief Returns the declarator information for a base class initializer. + TypeSourceInfo *getBaseClassInfo() const { + return BaseOrMember.dyn_cast<TypeSourceInfo *>(); + } + /// getMember - If this is a member initializer, returns the /// declaration of the non-static data member being /// initialized. Otherwise, returns NULL. FieldDecl *getMember() { if (isMemberInitializer()) - return reinterpret_cast<FieldDecl *>(BaseOrMember); + return BaseOrMember.get<FieldDecl*>(); else return 0; } - void setMember(FieldDecl * anonUnionField) { - BaseOrMember = reinterpret_cast<uintptr_t>(anonUnionField); + SourceLocation getMemberLocation() const { + return MemberLocation; } + void setMember(FieldDecl *Member) { + assert(isMemberInitializer()); + BaseOrMember = Member; + } + + /// \brief Determine the source location of the initializer. + SourceLocation getSourceLocation() const; + + /// \brief Determine the source range covering the entire initializer. + SourceRange getSourceRange() const; + FieldDecl *getAnonUnionMember() const { return CtorOrAnonUnion.dyn_cast<FieldDecl *>(); } @@ -1109,7 +1043,7 @@ public: return CtorOrAnonUnion.dyn_cast<CXXConstructorDecl *>(); } - SourceLocation getSourceLocation() const { return IdLoc; } + SourceLocation getLParenLoc() const { return LParenLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } /// arg_begin() - Retrieve an iterator to the first initializer argument. @@ -1155,9 +1089,9 @@ class CXXConstructorDecl : public CXXMethodDecl { unsigned NumBaseOrMemberInitializers; CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation L, - DeclarationName N, QualType T, DeclaratorInfo *DInfo, + DeclarationName N, QualType T, TypeSourceInfo *TInfo, bool isExplicit, bool isInline, bool isImplicitlyDeclared) - : CXXMethodDecl(CXXConstructor, RD, L, N, T, DInfo, false, isInline), + : CXXMethodDecl(CXXConstructor, RD, L, N, T, TInfo, false, isInline), Explicit(isExplicit), ImplicitlyDefined(false), BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) { setImplicit(isImplicitlyDeclared); @@ -1167,7 +1101,7 @@ class CXXConstructorDecl : public CXXMethodDecl { public: static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation L, DeclarationName N, - QualType T, DeclaratorInfo *DInfo, + QualType T, TypeSourceInfo *TInfo, bool isExplicit, bool isInline, bool isImplicitlyDeclared); @@ -1294,7 +1228,7 @@ class CXXDestructorDecl : public CXXMethodDecl { CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L, DeclarationName N, QualType T, bool isInline, bool isImplicitlyDeclared) - : CXXMethodDecl(CXXDestructor, RD, L, N, T, /*DInfo=*/0, false, isInline), + : CXXMethodDecl(CXXDestructor, RD, L, N, T, /*TInfo=*/0, false, isInline), ImplicitlyDefined(false), OperatorDelete(0) { setImplicit(isImplicitlyDeclared); } @@ -1349,15 +1283,15 @@ class CXXConversionDecl : public CXXMethodDecl { bool Explicit : 1; CXXConversionDecl(CXXRecordDecl *RD, SourceLocation L, - DeclarationName N, QualType T, DeclaratorInfo *DInfo, + DeclarationName N, QualType T, TypeSourceInfo *TInfo, bool isInline, bool isExplicit) - : CXXMethodDecl(CXXConversion, RD, L, N, T, DInfo, false, isInline), + : CXXMethodDecl(CXXConversion, RD, L, N, T, TInfo, false, isInline), Explicit(isExplicit) { } public: static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation L, DeclarationName N, - QualType T, DeclaratorInfo *DInfo, + QualType T, TypeSourceInfo *TInfo, bool isInline, bool isExplicit); /// isExplicit - Whether this is an explicit conversion operator diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h index c2b48ce..32405ee 100644 --- a/include/clang/AST/DeclContextInternals.h +++ b/include/clang/AST/DeclContextInternals.h @@ -131,6 +131,25 @@ public: return DK == DK_DeclID || DK == DK_ID_Vector; } + void remove(NamedDecl *D) { + assert(!isNull() && "removing from empty list"); + if (NamedDecl *Singleton = getAsDecl()) { + assert(Singleton == D && "list is different singleton"); + (void)Singleton; + Data = 0; + return; + } + + VectorTy &Vec = *getAsVector(); + VectorTy::iterator I = std::find(Vec.begin(), Vec.end(), + reinterpret_cast<uintptr_t>(D)); + assert(I != Vec.end() && "list does not contain decl"); + Vec.erase(I); + + assert(std::find(Vec.begin(), Vec.end(), reinterpret_cast<uintptr_t>(D)) + == Vec.end() && "list still contains decl"); + } + /// getLookupResult - Return an array of all the decls that this list /// represents. DeclContext::lookup_result getLookupResult(ASTContext &Context) { @@ -200,11 +219,37 @@ public: } VectorTy &Vec = *getAsVector(); - if (isa<UsingDirectiveDecl>(D) || - D->getIdentifierNamespace() == Decl::IDNS_Tag) + + // Using directives end up in a special entry which contains only + // other using directives, so all this logic is wasted for them. + // But avoiding the logic wastes time in the far-more-common case + // that we're *not* adding a new using directive. + + // Tag declarations always go at the end of the list so that an + // iterator which points at the first tag will start a span of + // decls that only contains tags. + if (D->getIdentifierNamespace() == Decl::IDNS_Tag) Vec.push_back(reinterpret_cast<uintptr_t>(D)); - else if (reinterpret_cast<NamedDecl *>(Vec.back()) - ->getIdentifierNamespace() == Decl::IDNS_Tag) { + + // Resolved using declarations go at the front of the list so that + // they won't show up in other lookup results. Unresolved using + // declarations (which are always in IDNS_Using | IDNS_Ordinary) + // follow that so that the using declarations will be contiguous. + else if (D->getIdentifierNamespace() & Decl::IDNS_Using) { + VectorTy::iterator I = Vec.begin(); + if (D->getIdentifierNamespace() != Decl::IDNS_Using) { + while (I != Vec.end() && + reinterpret_cast<NamedDecl *>(*I) + ->getIdentifierNamespace() == Decl::IDNS_Using) + ++I; + } + Vec.insert(I, reinterpret_cast<uintptr_t>(D)); + + // All other declarations go at the end of the list, but before any + // tag declarations. But we can be clever about tag declarations + // because there can only ever be one in a scope. + } else if (reinterpret_cast<NamedDecl *>(Vec.back()) + ->getIdentifierNamespace() == Decl::IDNS_Tag) { uintptr_t TagD = Vec.back(); Vec.back() = reinterpret_cast<uintptr_t>(D); Vec.push_back(TagD); diff --git a/include/clang/AST/DeclNodes.def b/include/clang/AST/DeclNodes.def index ec1b3b0..082299c 100644 --- a/include/clang/AST/DeclNodes.def +++ b/include/clang/AST/DeclNodes.def @@ -75,7 +75,6 @@ DECL(TranslationUnit, Decl) ABSTRACT_DECL(Named, Decl) - DECL(OverloadedFunction, NamedDecl) DECL(Namespace, NamedDecl) DECL(UsingDirective, NamedDecl) DECL(NamespaceAlias, NamedDecl) @@ -143,7 +142,7 @@ DECL_CONTEXT_BASE(ObjCContainer) LAST_DECL_CONTEXT(Block) // Declaration ranges -DECL_RANGE(Named, OverloadedFunction, ObjCCompatibleAlias) +DECL_RANGE(Named, Namespace, ObjCCompatibleAlias) DECL_RANGE(ObjCContainer, ObjCContainer, ObjCImplementation) DECL_RANGE(Field, Field, ObjCAtDefsField) DECL_RANGE(Type, Typedef, TemplateTypeParm) diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 897776c..fd8c3ef 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -578,14 +578,14 @@ public: private: ObjCIvarDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, - QualType T, DeclaratorInfo *DInfo, AccessControl ac, Expr *BW) - : FieldDecl(ObjCIvar, DC, L, Id, T, DInfo, BW, /*Mutable=*/false), + QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW) + : FieldDecl(ObjCIvar, DC, L, Id, T, TInfo, BW, /*Mutable=*/false), DeclAccess(ac) {} public: static ObjCIvarDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, - DeclaratorInfo *DInfo, + TypeSourceInfo *TInfo, AccessControl ac, Expr *BW = NULL); void setAccessControl(AccessControl ac) { DeclAccess = ac; } @@ -612,7 +612,7 @@ private: ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, Expr *BW) : FieldDecl(ObjCAtDefsField, DC, L, Id, T, - /*DInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ? + /*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ? BW, /*Mutable=*/false) {} public: diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 3ecc4bb..d8b004a 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -573,7 +573,7 @@ class TemplateTypeParmDecl : public TypeDecl { bool ParameterPack : 1; /// \brief The default template argument, if any. - DeclaratorInfo *DefaultArgument; + TypeSourceInfo *DefaultArgument; TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, bool Typename, QualType Type, bool ParameterPack) @@ -601,7 +601,7 @@ public: QualType getDefaultArgument() const { return DefaultArgument->getType(); } /// \brief Retrieves the default argument's source information, if any. - DeclaratorInfo *getDefaultArgumentInfo() const { return DefaultArgument; } + TypeSourceInfo *getDefaultArgumentInfo() const { return DefaultArgument; } /// \brief Retrieves the location of the default argument declaration. SourceLocation getDefaultArgumentLoc() const; @@ -613,7 +613,7 @@ public: /// \brief Set the default argument for this template parameter, and /// whether that default argument was inherited from another /// declaration. - void setDefaultArgument(DeclaratorInfo *DefArg, bool Inherited) { + void setDefaultArgument(TypeSourceInfo *DefArg, bool Inherited) { DefaultArgument = DefArg; InheritedDefault = Inherited; } @@ -652,15 +652,15 @@ class NonTypeTemplateParmDecl NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, unsigned P, IdentifierInfo *Id, QualType T, - DeclaratorInfo *DInfo) - : VarDecl(NonTypeTemplateParm, DC, L, Id, T, DInfo, VarDecl::None), + TypeSourceInfo *TInfo) + : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, VarDecl::None), TemplateParmPosition(D, P), DefaultArgument(0) { } public: static NonTypeTemplateParmDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, - unsigned P, IdentifierInfo *Id, QualType T, DeclaratorInfo *DInfo); + unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo); using TemplateParmPosition::getDepth; using TemplateParmPosition::getPosition; diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index 676bd2c..fcb4ae5 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -387,10 +387,11 @@ struct DenseMapInfo<clang::DeclarationName> { isEqual(clang::DeclarationName LHS, clang::DeclarationName RHS) { return LHS == RHS; } - - static inline bool isPod() { return true; } }; +template <> +struct isPodLike<clang::DeclarationName> { static const bool value = true; }; + } // end namespace llvm #endif diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 7cf9aab..469598f 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -309,6 +309,15 @@ public: /// ParenExpr or CastExprs, returning their operand. Expr *IgnoreParenNoopCasts(ASTContext &Ctx); + /// \brief Determine whether this expression is a default function argument. + /// + /// Default arguments are implicitly generated in the abstract syntax tree + /// by semantic analysis for function calls, object constructions, etc. in + /// C++. Default arguments are represented by \c CXXDefaultArgExpr nodes; + /// this routine also looks through any implicit casts to determine whether + /// the expression is a default argument. + bool isDefaultArgument() const; + const Expr* IgnoreParens() const { return const_cast<Expr*>(this)->IgnoreParens(); } @@ -389,7 +398,7 @@ class DeclRefExpr : public Expr { // indicate whether (1) the declaration's name was explicitly qualified and // (2) the declaration's name was followed by an explicit template // argument list. - llvm::PointerIntPair<NamedDecl *, 2> DecoratedD; + llvm::PointerIntPair<ValueDecl *, 2> DecoratedD; // Loc - The location of the declaration name itself. SourceLocation Loc; @@ -427,7 +436,7 @@ class DeclRefExpr : public Expr { } DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange, - NamedDecl *D, SourceLocation NameLoc, + ValueDecl *D, SourceLocation NameLoc, const TemplateArgumentListInfo *TemplateArgs, QualType T); @@ -436,13 +445,13 @@ protected: /// declaration reference expression. void computeDependence(); - DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) : + DeclRefExpr(StmtClass SC, ValueDecl *d, QualType t, SourceLocation l) : Expr(SC, t, false, false), DecoratedD(d, 0), Loc(l) { computeDependence(); } public: - DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l) : + DeclRefExpr(ValueDecl *d, QualType t, SourceLocation l) : Expr(DeclRefExprClass, t, false, false), DecoratedD(d, 0), Loc(l) { computeDependence(); } @@ -454,14 +463,14 @@ public: static DeclRefExpr *Create(ASTContext &Context, NestedNameSpecifier *Qualifier, SourceRange QualifierRange, - NamedDecl *D, + ValueDecl *D, SourceLocation NameLoc, QualType T, const TemplateArgumentListInfo *TemplateArgs = 0); - NamedDecl *getDecl() { return DecoratedD.getPointer(); } - const NamedDecl *getDecl() const { return DecoratedD.getPointer(); } - void setDecl(NamedDecl *NewD) { DecoratedD.setPointer(NewD); } + ValueDecl *getDecl() { return DecoratedD.getPointer(); } + const ValueDecl *getDecl() const { return DecoratedD.getPointer(); } + void setDecl(ValueDecl *NewD) { DecoratedD.setPointer(NewD); } SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } @@ -686,11 +695,6 @@ public: SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } - // FIXME: The logic for computing the value of a predefined expr should go - // into a method here that takes the inner-most code decl (a block, function - // or objc method) that the expr lives in. This would allow sema and codegen - // to be consistent for things like sizeof(__func__) etc. - virtual SourceRange getSourceRange() const { return SourceRange(Loc); } static bool classof(const Stmt *T) { @@ -975,7 +979,7 @@ class SizeOfAlignOfExpr : public Expr { bool isSizeof : 1; // true if sizeof, false if alignof. bool isType : 1; // true if operand is a type, false if an expression union { - DeclaratorInfo *Ty; + TypeSourceInfo *Ty; Stmt *Ex; } Argument; SourceLocation OpLoc, RParenLoc; @@ -984,15 +988,15 @@ protected: virtual void DoDestroy(ASTContext& C); public: - SizeOfAlignOfExpr(bool issizeof, DeclaratorInfo *DInfo, + SizeOfAlignOfExpr(bool issizeof, TypeSourceInfo *TInfo, QualType resultType, SourceLocation op, SourceLocation rp) : Expr(SizeOfAlignOfExprClass, resultType, false, // Never type-dependent (C++ [temp.dep.expr]p3). // Value-dependent if the argument is type-dependent. - DInfo->getType()->isDependentType()), + TInfo->getType()->isDependentType()), isSizeof(issizeof), isType(true), OpLoc(op), RParenLoc(rp) { - Argument.Ty = DInfo; + Argument.Ty = TInfo; } SizeOfAlignOfExpr(bool issizeof, Expr *E, @@ -1017,7 +1021,7 @@ public: QualType getArgumentType() const { return getArgumentTypeInfo()->getType(); } - DeclaratorInfo *getArgumentTypeInfo() const { + TypeSourceInfo *getArgumentTypeInfo() const { assert(isArgumentType() && "calling getArgumentType() when arg is expr"); return Argument.Ty; } @@ -1030,8 +1034,8 @@ public: } void setArgument(Expr *E) { Argument.Ex = E; isType = false; } - void setArgument(DeclaratorInfo *DInfo) { - Argument.Ty = DInfo; + void setArgument(TypeSourceInfo *TInfo) { + Argument.Ty = TInfo; isType = true; } @@ -1252,7 +1256,7 @@ class MemberExpr : public Expr { /// MemberDecl - This is the decl being referenced by the field/member name. /// In X.F, this is the decl referenced by F. - NamedDecl *MemberDecl; + ValueDecl *MemberDecl; /// MemberLoc - This is the location of the member name. SourceLocation MemberLoc; @@ -1305,12 +1309,12 @@ class MemberExpr : public Expr { } MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual, - SourceRange qualrange, NamedDecl *memberdecl, SourceLocation l, + SourceRange qualrange, ValueDecl *memberdecl, SourceLocation l, const TemplateArgumentListInfo *targs, QualType ty); public: - MemberExpr(Expr *base, bool isarrow, NamedDecl *memberdecl, SourceLocation l, - QualType ty) + MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl, + SourceLocation l, QualType ty) : Expr(MemberExprClass, ty, base->isTypeDependent(), base->isValueDependent()), Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow), @@ -1323,7 +1327,7 @@ public: static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow, NestedNameSpecifier *qual, SourceRange qualrange, - NamedDecl *memberdecl, + ValueDecl *memberdecl, SourceLocation l, const TemplateArgumentListInfo *targs, QualType ty); @@ -1335,8 +1339,8 @@ public: /// /// The returned declaration will either be a FieldDecl or (in C++) /// a CXXMethodDecl. - NamedDecl *getMemberDecl() const { return MemberDecl; } - void setMemberDecl(NamedDecl *D) { MemberDecl = D; } + ValueDecl *getMemberDecl() const { return MemberDecl; } + void setMemberDecl(ValueDecl *D) { MemberDecl = D; } /// \brief Determines whether this member expression actually had /// a C++ nested-name-specifier prior to the name of the member, e.g., @@ -1576,7 +1580,14 @@ public: CK_FloatingCast, /// CK_MemberPointerToBoolean - Member pointer to boolean - CK_MemberPointerToBoolean + CK_MemberPointerToBoolean, + + /// CK_AnyPointerToObjCPointerCast - Casting any pointer to objective-c + /// pointer + CK_AnyPointerToObjCPointerCast, + /// CK_AnyPointerToBlockPointerCast - Casting any pointer to block + /// pointer + CK_AnyPointerToBlockPointerCast }; @@ -1607,6 +1618,14 @@ public: const Expr *getSubExpr() const { return cast<Expr>(Op); } void setSubExpr(Expr *E) { Op = E; } + /// \brief Retrieve the cast subexpression as it was written in the source + /// code, looking through any implicit casts or other intermediate nodes + /// introduced by semantic analysis. + Expr *getSubExprAsWritten(); + const Expr *getSubExprAsWritten() const { + return const_cast<CastExpr *>(this)->getSubExprAsWritten(); + } + static bool classof(const Stmt *T) { StmtClass SC = T->getStmtClass(); if (SC >= CXXNamedCastExprClass && SC <= CXXFunctionalCastExprClass) diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 23844ce..00ea202 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -527,6 +527,7 @@ public: const_arg_iterator arg_begin() const { return Args; } const_arg_iterator arg_end() const { return Args + NumArgs; } + Expr **getArgs() const { return reinterpret_cast<Expr **>(Args); } unsigned getNumArgs() const { return NumArgs; } /// getArg - Return the specified argument. @@ -1410,18 +1411,26 @@ public: /// \brief Represents a C++ member access expression where the actual /// member referenced could not be resolved because the base /// expression or the member name was dependent. +/// +/// Like UnresolvedMemberExprs, these can be either implicit or +/// explicit accesses. It is only possible to get one of these with +/// an implicit access if a qualifier is provided. class CXXDependentScopeMemberExpr : public Expr { /// \brief The expression for the base pointer or class reference, - /// e.g., the \c x in x.f. + /// e.g., the \c x in x.f. Can be null in implicit accesses. Stmt *Base; + /// \brief The type of the base expression. Never null, even for + /// implicit accesses. + QualType BaseType; + /// \brief Whether this member expression used the '->' operator or /// the '.' operator. bool IsArrow : 1; /// \brief Whether this member expression has explicitly-specified template /// arguments. - bool HasExplicitTemplateArgumentList : 1; + bool HasExplicitTemplateArgs : 1; /// \brief The location of the '->' or '.' operator. SourceLocation OperatorLoc; @@ -1452,9 +1461,7 @@ class CXXDependentScopeMemberExpr : public Expr { /// \brief Retrieve the explicit template argument list that followed the /// member template name, if any. ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() { - if (!HasExplicitTemplateArgumentList) - return 0; - + assert(HasExplicitTemplateArgs); return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1); } @@ -1466,7 +1473,7 @@ class CXXDependentScopeMemberExpr : public Expr { } CXXDependentScopeMemberExpr(ASTContext &C, - Expr *Base, bool IsArrow, + Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifier *Qualifier, SourceRange QualifierRange, @@ -1477,7 +1484,8 @@ class CXXDependentScopeMemberExpr : public Expr { public: CXXDependentScopeMemberExpr(ASTContext &C, - Expr *Base, bool IsArrow, + Expr *Base, QualType BaseType, + bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifier *Qualifier, SourceRange QualifierRange, @@ -1485,15 +1493,15 @@ public: DeclarationName Member, SourceLocation MemberLoc) : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true), - Base(Base), IsArrow(IsArrow), HasExplicitTemplateArgumentList(false), - OperatorLoc(OperatorLoc), + Base(Base), BaseType(BaseType), IsArrow(IsArrow), + HasExplicitTemplateArgs(false), OperatorLoc(OperatorLoc), Qualifier(Qualifier), QualifierRange(QualifierRange), FirstQualifierFoundInScope(FirstQualifierFoundInScope), Member(Member), MemberLoc(MemberLoc) { } static CXXDependentScopeMemberExpr * Create(ASTContext &C, - Expr *Base, bool IsArrow, + Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifier *Qualifier, SourceRange QualifierRange, @@ -1502,11 +1510,21 @@ public: SourceLocation MemberLoc, const TemplateArgumentListInfo *TemplateArgs); + /// \brief True if this is an implicit access, i.e. one in which the + /// member being accessed was not written in the source. The source + /// location of the operator is invalid in this case. + bool isImplicitAccess() const { return Base == 0; } + /// \brief Retrieve the base object of this member expressions, /// e.g., the \c x in \c x.m. - Expr *getBase() { return cast<Expr>(Base); } + Expr *getBase() const { + assert(!isImplicitAccess()); + return cast<Expr>(Base); + } void setBase(Expr *E) { Base = E; } + QualType getBaseType() const { return BaseType; } + /// \brief Determine whether this member expression used the '->' /// operator; otherwise, it used the '.' operator. bool isArrow() const { return IsArrow; } @@ -1551,60 +1569,59 @@ public: /// \brief Determines whether this member expression actually had a C++ /// template argument list explicitly specified, e.g., x.f<int>. - bool hasExplicitTemplateArgumentList() const { - return HasExplicitTemplateArgumentList; + bool hasExplicitTemplateArgs() const { + return HasExplicitTemplateArgs; } /// \brief Copies the template arguments (if present) into the given /// structure. void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { - if (hasExplicitTemplateArgumentList()) - getExplicitTemplateArgumentList()->copyInto(List); + assert(HasExplicitTemplateArgs); + getExplicitTemplateArgumentList()->copyInto(List); } /// \brief Retrieve the location of the left angle bracket following the /// member name ('<'), if any. SourceLocation getLAngleLoc() const { - if (!HasExplicitTemplateArgumentList) - return SourceLocation(); - + assert(HasExplicitTemplateArgs); return getExplicitTemplateArgumentList()->LAngleLoc; } /// \brief Retrieve the template arguments provided as part of this /// template-id. const TemplateArgumentLoc *getTemplateArgs() const { - if (!HasExplicitTemplateArgumentList) - return 0; - + assert(HasExplicitTemplateArgs); return getExplicitTemplateArgumentList()->getTemplateArgs(); } /// \brief Retrieve the number of template arguments provided as part of this /// template-id. unsigned getNumTemplateArgs() const { - if (!HasExplicitTemplateArgumentList) - return 0; - + assert(HasExplicitTemplateArgs); return getExplicitTemplateArgumentList()->NumTemplateArgs; } /// \brief Retrieve the location of the right angle bracket following the /// template arguments ('>'). SourceLocation getRAngleLoc() const { - if (!HasExplicitTemplateArgumentList) - return SourceLocation(); - + assert(HasExplicitTemplateArgs); return getExplicitTemplateArgumentList()->RAngleLoc; } virtual SourceRange getSourceRange() const { - if (HasExplicitTemplateArgumentList) - return SourceRange(Base->getSourceRange().getBegin(), - getRAngleLoc()); + SourceRange Range; + if (!isImplicitAccess()) + Range.setBegin(Base->getSourceRange().getBegin()); + else if (getQualifier()) + Range.setBegin(getQualifierRange().getBegin()); + else + Range.setBegin(MemberLoc); - return SourceRange(Base->getSourceRange().getBegin(), - MemberLoc); + if (hasExplicitTemplateArgs()) + Range.setEnd(getRAngleLoc()); + else + Range.setEnd(MemberLoc); + return Range; } static bool classof(const Stmt *T) { @@ -1618,17 +1635,31 @@ public: }; /// \brief Represents a C++ member access expression for which lookup -/// produced a set of overloaded functions. These are replaced with -/// MemberExprs in the final AST. +/// produced a set of overloaded functions. +/// +/// The member access may be explicit or implicit: +/// struct A { +/// int a, b; +/// int explicitAccess() { return this->a + this->A::b; } +/// int implicitAccess() { return a + A::b; } +/// }; +/// +/// In the final AST, an explicit access always becomes a MemberExpr. +/// An implicit access may become either a MemberExpr or a +/// DeclRefExpr, depending on whether the member is static. class UnresolvedMemberExpr : public Expr { /// The results. These are undesugared, which is to say, they may /// include UsingShadowDecls. UnresolvedSet Results; /// \brief The expression for the base pointer or class reference, - /// e.g., the \c x in x.f. + /// e.g., the \c x in x.f. This can be null if this is an 'unbased' + /// member expression Stmt *Base; + /// \brief The type of the base expression; never null. + QualType BaseType; + /// \brief Whether this member expression used the '->' operator or /// the '.' operator. bool IsArrow : 1; @@ -1672,7 +1703,7 @@ class UnresolvedMemberExpr : public Expr { UnresolvedMemberExpr(QualType T, bool Dependent, bool HasUnresolvedUsing, - Expr *Base, bool IsArrow, + Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifier *Qualifier, SourceRange QualifierRange, @@ -1683,7 +1714,7 @@ class UnresolvedMemberExpr : public Expr { public: static UnresolvedMemberExpr * Create(ASTContext &C, bool Dependent, bool HasUnresolvedUsing, - Expr *Base, bool IsArrow, + Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifier *Qualifier, SourceRange QualifierRange, @@ -1704,11 +1735,21 @@ public: unsigned getNumDecls() const { return Results.size(); } + /// \brief True if this is an implicit access, i.e. one in which the + /// member being accessed was not written in the source. The source + /// location of the operator is invalid in this case. + bool isImplicitAccess() const { return Base == 0; } + /// \brief Retrieve the base object of this member expressions, /// e.g., the \c x in \c x.m. - Expr *getBase() { return cast<Expr>(Base); } + Expr *getBase() { + assert(!isImplicitAccess()); + return cast<Expr>(Base); + } void setBase(Expr *E) { Base = E; } + QualType getBaseType() const { return BaseType; } + /// \brief Determine whether this member expression used the '->' /// operator; otherwise, it used the '.' operator. bool isArrow() const { return IsArrow; } @@ -1772,7 +1813,14 @@ public: } virtual SourceRange getSourceRange() const { - SourceRange Range = Base->getSourceRange(); + SourceRange Range; + if (!isImplicitAccess()) + Range.setBegin(Base->getSourceRange().getBegin()); + else if (getQualifier()) + Range.setBegin(getQualifierRange().getBegin()); + else + Range.setBegin(MemberLoc); + if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc()); else diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h index 5d2973e..a8334b6 100644 --- a/include/clang/AST/RecordLayout.h +++ b/include/clang/AST/RecordLayout.h @@ -119,13 +119,6 @@ private: /// VBaseOffsets - Contains a map from vbase classes to their offset. /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :) llvm::DenseMap<const CXXRecordDecl *, uint64_t> VBaseOffsets; - - /// KeyFunction - The key function, according to the Itanium C++ ABI, - /// section 5.2.3: - /// - /// ...the first non-pure virtual function that is not inline at the point - /// of class definition. - const CXXMethodDecl *KeyFunction; }; /// CXXInfo - If the record layout is for a C++ record, this will have @@ -154,8 +147,7 @@ private: const std::pair<const CXXRecordDecl *, uint64_t> *bases, unsigned numbases, const std::pair<const CXXRecordDecl *, uint64_t> *vbases, - unsigned numvbases, - const CXXMethodDecl *KeyFunction) + unsigned numvbases) : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment), FieldCount(fieldcount), CXXInfo(new CXXRecordLayoutInfo) { if (FieldCount > 0) { @@ -171,7 +163,6 @@ private: CXXInfo->BaseOffsets[bases[i].first] = bases[i].second; for (unsigned i = 0; i != numvbases; ++i) CXXInfo->VBaseOffsets[vbases[i].first] = vbases[i].second; - CXXInfo->KeyFunction = KeyFunction; } ~ASTRecordLayout() { @@ -254,13 +245,6 @@ public: return CXXInfo->VBaseOffsets[VBase]; } - /// getKeyFunction - Get the key function. - const CXXMethodDecl *getKeyFunction() const { - assert(CXXInfo && "Record layout does not have C++ specific info!"); - - return CXXInfo->KeyFunction; - } - primary_base_info_iterator primary_base_begin() const { assert(CXXInfo && "Record layout does not have C++ specific info!"); diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h index 64eea24..09ea4ca 100644 --- a/include/clang/AST/StmtCXX.h +++ b/include/clang/AST/StmtCXX.h @@ -68,10 +68,11 @@ public: Stmt **handlers, unsigned numHandlers); virtual SourceRange getSourceRange() const { - return SourceRange(TryLoc, Stmts.back()->getLocEnd()); + return SourceRange(getTryLoc(), getEndLoc()); } SourceLocation getTryLoc() const { return TryLoc; } + SourceLocation getEndLoc() const { return Stmts.back()->getLocEnd(); } CompoundStmt *getTryBlock() { return llvm::cast<CompoundStmt>(Stmts[0]); } const CompoundStmt *getTryBlock() const { diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index b46b3dc..fe03799 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -29,7 +29,7 @@ namespace clang { class Decl; class Expr; -class DeclaratorInfo; +class TypeSourceInfo; /// \brief Represents a template argument within a class template /// specialization. @@ -267,7 +267,7 @@ struct TemplateArgumentLocInfo { private: union { Expr *Expression; - DeclaratorInfo *Declarator; + TypeSourceInfo *Declarator; struct { unsigned QualifierRange[2]; unsigned TemplateNameLoc; @@ -277,7 +277,7 @@ private: #ifndef NDEBUG enum Kind { K_None, - K_DeclaratorInfo, + K_TypeSourceInfo, K_Expression, K_Template } Kind; @@ -291,10 +291,10 @@ public: #endif {} - TemplateArgumentLocInfo(DeclaratorInfo *DInfo) - : Declarator(DInfo) + TemplateArgumentLocInfo(TypeSourceInfo *TInfo) + : Declarator(TInfo) #ifndef NDEBUG - , Kind(K_DeclaratorInfo) + , Kind(K_TypeSourceInfo) #endif {} @@ -316,8 +316,8 @@ public: Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding(); } - DeclaratorInfo *getAsDeclaratorInfo() const { - assert(Kind == K_DeclaratorInfo); + TypeSourceInfo *getAsTypeSourceInfo() const { + assert(Kind == K_TypeSourceInfo); return Declarator; } @@ -342,7 +342,7 @@ public: void validateForArgument(const TemplateArgument &Arg) { switch (Arg.getKind()) { case TemplateArgument::Type: - assert(Kind == K_DeclaratorInfo); + assert(Kind == K_TypeSourceInfo); break; case TemplateArgument::Expression: case TemplateArgument::Declaration: @@ -356,7 +356,7 @@ public: assert(Kind == K_None); break; case TemplateArgument::Null: - llvm::llvm_unreachable("source info for null template argument?"); + llvm_unreachable("source info for null template argument?"); } } #endif @@ -376,8 +376,8 @@ public: : Argument(Argument), LocInfo(Opaque) { } - TemplateArgumentLoc(const TemplateArgument &Argument, DeclaratorInfo *DInfo) - : Argument(Argument), LocInfo(DInfo) { + TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo) + : Argument(Argument), LocInfo(TInfo) { assert(Argument.getKind() == TemplateArgument::Type); } @@ -412,9 +412,9 @@ public: return LocInfo; } - DeclaratorInfo *getSourceDeclaratorInfo() const { + TypeSourceInfo *getTypeSourceInfo() const { assert(Argument.getKind() == TemplateArgument::Type); - return LocInfo.getAsDeclaratorInfo(); + return LocInfo.getAsTypeSourceInfo(); } Expr *getSourceExpression() const { diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h index 8ef8fb5..aafe963 100644 --- a/include/clang/AST/TemplateName.h +++ b/include/clang/AST/TemplateName.h @@ -31,7 +31,34 @@ struct PrintingPolicy; class QualifiedTemplateName; class NamedDecl; class TemplateDecl; -class OverloadedFunctionDecl; + +/// \brief A structure for storing the information associated with an +/// overloaded template name. +class OverloadedTemplateStorage { + union { + unsigned Size; + NamedDecl *Storage[1]; + }; + + friend class ASTContext; + + OverloadedTemplateStorage(unsigned Size) : Size(Size) {} + + NamedDecl **getStorage() { + return &Storage[1]; + } + NamedDecl * const *getStorage() const { + return &Storage[1]; + } + +public: + typedef NamedDecl *const *iterator; + + unsigned size() const { return Size; } + + iterator begin() const { return getStorage(); } + iterator end() const { return getStorage() + size(); } +}; /// \brief Represents a C++ template name within the type system. /// @@ -61,7 +88,8 @@ class OverloadedFunctionDecl; /// specifier in the typedef. "apply" is a nested template, and can /// only be understood in the context of class TemplateName { - typedef llvm::PointerUnion4<TemplateDecl *, OverloadedFunctionDecl *, + typedef llvm::PointerUnion4<TemplateDecl *, + OverloadedTemplateStorage *, QualifiedTemplateName *, DependentTemplateName *> StorageType; @@ -74,8 +102,8 @@ class TemplateName { public: TemplateName() : Storage() { } explicit TemplateName(TemplateDecl *Template) : Storage(Template) { } - explicit TemplateName(OverloadedFunctionDecl *FunctionTemplates) - : Storage(FunctionTemplates) { } + explicit TemplateName(OverloadedTemplateStorage *Storage) + : Storage(Storage) { } explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { } explicit TemplateName(DependentTemplateName *Dep) : Storage(Dep) { } @@ -98,7 +126,9 @@ public: /// name refers to, if known. If the template name does not refer to a /// specific set of function templates because it is a dependent name or /// refers to a single template, returns NULL. - OverloadedFunctionDecl *getAsOverloadedFunctionDecl() const; + OverloadedTemplateStorage *getAsOverloadedTemplate() const { + return Storage.dyn_cast<OverloadedTemplateStorage *>(); + } /// \brief Retrieve the underlying qualified template name /// structure, if any. @@ -166,19 +196,14 @@ class QualifiedTemplateName : public llvm::FoldingSetNode { /// \brief The template declaration or set of overloaded function templates /// that this qualified name refers to. - NamedDecl *Template; + TemplateDecl *Template; friend class ASTContext; QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, TemplateDecl *Template) : Qualifier(NNS, TemplateKeyword? 1 : 0), - Template(reinterpret_cast<NamedDecl *>(Template)) { } - - QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, - OverloadedFunctionDecl *Template) - : Qualifier(NNS, TemplateKeyword? 1 : 0), - Template(reinterpret_cast<NamedDecl *>(Template)) { } + Template(Template) { } public: /// \brief Return the nested name specifier that qualifies this name. @@ -188,26 +213,20 @@ public: /// keyword. bool hasTemplateKeyword() const { return Qualifier.getInt(); } - /// \brief The template declaration or set of overloaded functions that - /// that qualified name refers to. - NamedDecl *getDecl() const { return Template; } + /// \brief The template declaration that this qualified name refers + /// to. + TemplateDecl *getDecl() const { return Template; } /// \brief The template declaration to which this qualified name - /// refers, or NULL if this qualified name refers to a set of overloaded - /// function templates. - TemplateDecl *getTemplateDecl() const; - - /// \brief The set of overloaded function tempaltes to which this qualified - /// name refers, or NULL if this qualified name refers to a single - /// template declaration. - OverloadedFunctionDecl *getOverloadedFunctionDecl() const; + /// refers. + TemplateDecl *getTemplateDecl() const { return Template; } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getQualifier(), hasTemplateKeyword(), getDecl()); + Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl()); } static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, - bool TemplateKeyword, NamedDecl *Template) { + bool TemplateKeyword, TemplateDecl *Template) { ID.AddPointer(NNS); ID.AddBoolean(TemplateKeyword); ID.AddPointer(Template); diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 349487f..d22a646 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -35,7 +35,9 @@ namespace clang { TypeAlignmentInBits = 3, TypeAlignment = 1 << TypeAlignmentInBits }; - class Type; class ExtQuals; + class Type; + class ExtQuals; + class QualType; } namespace llvm { @@ -59,6 +61,9 @@ namespace llvm { } enum { NumLowBitsAvailable = clang::TypeAlignmentInBits }; }; + + template <> + struct isPodLike<clang::QualType> { static const bool value = true; }; } namespace clang { @@ -76,6 +81,7 @@ namespace clang { class ObjCInterfaceDecl; class ObjCProtocolDecl; class ObjCMethodDecl; + class UnresolvedUsingTypenameDecl; class Expr; class Stmt; class SourceLocation; @@ -791,6 +797,10 @@ public: /// isPODType - Return true if this is a plain-old-data type (C++ 3.9p10). bool isPODType() const; + /// isLiteralType - Return true if this is a literal type + /// (C++0x [basic.types]p10) + bool isLiteralType() const; + /// isVariablyModifiedType (C99 6.7.5.2p2) - Return true for variable array /// types that have a non-constant expression. This does not include "[]". bool isVariablyModifiedType() const; @@ -808,8 +818,9 @@ public: bool isBooleanType() const; bool isCharType() const; bool isWideCharType() const; + bool isAnyCharacterType() const; bool isIntegralType() const; - + /// Floating point categories. bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double) /// isComplexType() does *not* include complex integers (a GCC extension). @@ -1859,6 +1870,38 @@ public: }; +/// \brief Represents the dependent type named by a dependently-scoped +/// typename using declaration, e.g. +/// using typename Base<T>::foo; +/// Template instantiation turns these into the underlying type. +class UnresolvedUsingType : public Type { + UnresolvedUsingTypenameDecl *Decl; + + UnresolvedUsingType(UnresolvedUsingTypenameDecl *D) + : Type(UnresolvedUsing, QualType(), true), Decl(D) {} + friend class ASTContext; // ASTContext creates these. +public: + + UnresolvedUsingTypenameDecl *getDecl() const { return Decl; } + + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + + static bool classof(const Type *T) { + return T->getTypeClass() == UnresolvedUsing; + } + static bool classof(const UnresolvedUsingType *) { return true; } + + void Profile(llvm::FoldingSetNodeID &ID) { + return Profile(ID, Decl); + } + static void Profile(llvm::FoldingSetNodeID &ID, + UnresolvedUsingTypenameDecl *D) { + ID.AddPointer(D); + } +}; + + class TypedefType : public Type { TypedefDecl *Decl; protected: diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index f08ca6b..a9b7f7e 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -19,7 +19,7 @@ namespace clang { class ParmVarDecl; - class DeclaratorInfo; + class TypeSourceInfo; class UnqualTypeLoc; // Predeclare all the type nodes. @@ -340,16 +340,20 @@ public: } }; + struct TypeSpecLocInfo { SourceLocation NameLoc; }; /// \brief A reasonable base class for TypeLocs that correspond to /// types that are written as a type-specifier. -template <class Derived, class TypeClass, class LocalData = TypeSpecLocInfo> -class TypeSpecTypeLoc - : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> { +class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, + TypeSpecTypeLoc, + Type, + TypeSpecLocInfo> { public: + enum { LocalDataSize = sizeof(TypeSpecLocInfo) }; + SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; } @@ -362,31 +366,79 @@ public: void initializeLocal(SourceLocation Loc) { setNameLoc(Loc); } + + static bool classof(const TypeLoc *TL); + static bool classof(const TypeSpecTypeLoc *TL) { return true; } }; + /// \brief Wrapper for source info for typedefs. -class TypedefTypeLoc : public TypeSpecTypeLoc<TypedefTypeLoc,TypedefType> { +class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, + TypedefTypeLoc, + TypedefType> { public: TypedefDecl *getTypedefDecl() const { return getTypePtr()->getDecl(); } }; +/// \brief Wrapper for source info for unresolved typename using decls. +class UnresolvedUsingTypeLoc : + public InheritingConcreteTypeLoc<TypeSpecTypeLoc, + UnresolvedUsingTypeLoc, + UnresolvedUsingType> { +public: + UnresolvedUsingTypenameDecl *getDecl() const { + return getTypePtr()->getDecl(); + } +}; + +/// \brief Wrapper for source info for tag types. Note that this only +/// records source info for the name itself; a type written 'struct foo' +/// should be represented as an ElaboratedTypeLoc. We currently +/// only do that when C++ is enabled because of the expense of +/// creating an ElaboratedType node for so many type references in C. +class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, + TagTypeLoc, + TagType> { +public: + TagDecl *getDecl() const { return getTypePtr()->getDecl(); } +}; + +/// \brief Wrapper for source info for record types. +class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, + RecordTypeLoc, + RecordType> { +public: + RecordDecl *getDecl() const { return getTypePtr()->getDecl(); } +}; + +/// \brief Wrapper for source info for enum types. +class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, + EnumTypeLoc, + EnumType> { +public: + EnumDecl *getDecl() const { return getTypePtr()->getDecl(); } +}; /// \brief Wrapper for source info for builtin types. -class BuiltinTypeLoc : public TypeSpecTypeLoc<BuiltinTypeLoc, - BuiltinType> { +class BuiltinTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, + BuiltinTypeLoc, + BuiltinType> { }; /// \brief Wrapper for template type parameters. -class TemplateTypeParmTypeLoc : public TypeSpecTypeLoc<TemplateTypeParmTypeLoc, - TemplateTypeParmType> { +class TemplateTypeParmTypeLoc : + public InheritingConcreteTypeLoc<TypeSpecTypeLoc, + TemplateTypeParmTypeLoc, + TemplateTypeParmType> { }; /// \brief Wrapper for substituted template type parameters. class SubstTemplateTypeParmTypeLoc : - public TypeSpecTypeLoc<SubstTemplateTypeParmTypeLoc, - SubstTemplateTypeParmType> { + public InheritingConcreteTypeLoc<TypeSpecTypeLoc, + SubstTemplateTypeParmTypeLoc, + SubstTemplateTypeParmType> { }; @@ -889,7 +941,7 @@ public: assert(size == Loc.getFullDataSize()); // We're potentially copying Expr references here. We don't - // bother retaining them because DeclaratorInfos live forever, so + // bother retaining them because TypeSourceInfos live forever, so // as long as the Expr was retained when originally written into // the TypeLoc, we're okay. memcpy(Data, Loc.Data, size); @@ -916,7 +968,7 @@ public: break; case TemplateArgument::Type: - Info = TemplateArgumentLocInfo((DeclaratorInfo*) 0); + Info = TemplateArgumentLocInfo((TypeSourceInfo*) 0); break; case TemplateArgument::Template: @@ -944,63 +996,84 @@ private: } }; -// None of these types have proper implementations yet. +//===----------------------------------------------------------------------===// +// +// All of these need proper implementations. +// +//===----------------------------------------------------------------------===// -class VectorTypeLoc : public TypeSpecTypeLoc<VectorTypeLoc, VectorType> { +// FIXME: size expression and attribute locations (or keyword if we +// ever fully support altivec syntax). +class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, + VectorTypeLoc, + VectorType> { }; +// FIXME: size expression and attribute locations. class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc, ExtVectorTypeLoc, ExtVectorType> { }; +// FIXME: attribute locations. // For some reason, this isn't a subtype of VectorType. class DependentSizedExtVectorTypeLoc : - public TypeSpecTypeLoc<DependentSizedExtVectorTypeLoc, - DependentSizedExtVectorType> { + public InheritingConcreteTypeLoc<TypeSpecTypeLoc, + DependentSizedExtVectorTypeLoc, + DependentSizedExtVectorType> { }; -class FixedWidthIntTypeLoc : public TypeSpecTypeLoc<FixedWidthIntTypeLoc, - FixedWidthIntType> { +// FIXME: I'm not sure how you actually specify these; with attributes? +class FixedWidthIntTypeLoc : + public InheritingConcreteTypeLoc<TypeSpecTypeLoc, + FixedWidthIntTypeLoc, + FixedWidthIntType> { }; -class ComplexTypeLoc : public TypeSpecTypeLoc<ComplexTypeLoc, - ComplexType> { +// FIXME: location of the '_Complex' keyword. +class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, + ComplexTypeLoc, + ComplexType> { }; -class TypeOfExprTypeLoc : public TypeSpecTypeLoc<TypeOfExprTypeLoc, - TypeOfExprType> { +// FIXME: location of the 'typeof' and parens (the expression is +// carried by the type). +class TypeOfExprTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, + TypeOfExprTypeLoc, + TypeOfExprType> { }; -class TypeOfTypeLoc : public TypeSpecTypeLoc<TypeOfTypeLoc, TypeOfType> { +// FIXME: location of the 'typeof' and parens; also the TypeSourceInfo +// for the inner type, or (maybe) just express that inline to the TypeLoc. +class TypeOfTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, + TypeOfTypeLoc, + TypeOfType> { }; -class DecltypeTypeLoc : public TypeSpecTypeLoc<DecltypeTypeLoc, DecltypeType> { -}; - -class TagTypeLoc : public TypeSpecTypeLoc<TagTypeLoc, TagType> { -}; - -class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, - RecordTypeLoc, - RecordType> { -}; - -class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, - EnumTypeLoc, - EnumType> { +// FIXME: location of the 'decltype' and parens. +class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, + DecltypeTypeLoc, + DecltypeType> { }; -class ElaboratedTypeLoc : public TypeSpecTypeLoc<ElaboratedTypeLoc, - ElaboratedType> { +// FIXME: location of the tag keyword. +class ElaboratedTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, + ElaboratedTypeLoc, + ElaboratedType> { }; -class QualifiedNameTypeLoc : public TypeSpecTypeLoc<QualifiedNameTypeLoc, - QualifiedNameType> { +// FIXME: locations for the nested name specifier; at the very least, +// a SourceRange. +class QualifiedNameTypeLoc : + public InheritingConcreteTypeLoc<TypeSpecTypeLoc, + QualifiedNameTypeLoc, + QualifiedNameType> { }; -class TypenameTypeLoc : public TypeSpecTypeLoc<TypenameTypeLoc, - TypenameType> { +// FIXME: locations for the typename keyword and nested name specifier. +class TypenameTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, + TypenameTypeLoc, + TypenameType> { }; } diff --git a/include/clang/AST/TypeLocBuilder.h b/include/clang/AST/TypeLocBuilder.h index 00e2b7f..c3b1c68 100644 --- a/include/clang/AST/TypeLocBuilder.h +++ b/include/clang/AST/TypeLocBuilder.h @@ -59,9 +59,35 @@ class TypeLocBuilder { grow(Requested); } - /// Pushes space for a new TypeLoc onto the given type. Invalidates + /// Pushes space for a typespec TypeLoc. Invalidates any TypeLocs + /// previously retrieved from this builder. + TypeSpecTypeLoc pushTypeSpec(QualType T) { + size_t LocalSize = TypeSpecTypeLoc::LocalDataSize; + return cast<TypeSpecTypeLoc>(pushImpl(T, LocalSize)); + } + + + /// Pushes space for a new TypeLoc of the given type. Invalidates /// any TypeLocs previously retrieved from this builder. template <class TyLocType> TyLocType push(QualType T) { + size_t LocalSize = cast<TyLocType>(TypeLoc(T, 0)).getLocalDataSize(); + return cast<TyLocType>(pushImpl(T, LocalSize)); + } + + /// Creates a TypeSourceInfo for the given type. + TypeSourceInfo *getTypeSourceInfo(ASTContext& Context, QualType T) { +#ifndef NDEBUG + assert(T == LastTy && "type doesn't match last type pushed!"); +#endif + + size_t FullDataSize = Capacity - Index; + TypeSourceInfo *DI = Context.CreateTypeSourceInfo(T, FullDataSize); + memcpy(DI->getTypeLoc().getOpaqueData(), &Buffer[Index], FullDataSize); + return DI; + } + +private: + TypeLoc pushImpl(QualType T, size_t LocalSize) { #ifndef NDEBUG QualType TLast = TypeLoc(T, 0).getNextTypeLoc().getType(); assert(TLast == LastTy && @@ -69,8 +95,6 @@ class TypeLocBuilder { LastTy = T; #endif - size_t LocalSize = cast<TyLocType>(TypeLoc(T, 0)).getLocalDataSize(); - // If we need to grow, grow by a factor of 2. if (LocalSize > Index) { size_t RequiredCapacity = Capacity + (LocalSize - Index); @@ -82,22 +106,9 @@ class TypeLocBuilder { Index -= LocalSize; - return cast<TyLocType>(TypeLoc(T, &Buffer[Index])); - } - - /// Creates a DeclaratorInfo for the given type. - DeclaratorInfo *getDeclaratorInfo(ASTContext& Context, QualType T) { -#ifndef NDEBUG - assert(T == LastTy && "type doesn't match last type pushed!"); -#endif - - size_t FullDataSize = Capacity - Index; - DeclaratorInfo *DI = Context.CreateDeclaratorInfo(T, FullDataSize); - memcpy(DI->getTypeLoc().getOpaqueData(), &Buffer[Index], FullDataSize); - return DI; + return TypeLoc(T, &Buffer[Index]); } - private: /// Grow to the given capacity. void grow(size_t NewCapacity) { assert(NewCapacity > Capacity); diff --git a/include/clang/AST/TypeLocVisitor.h b/include/clang/AST/TypeLocVisitor.h index a62bb3f..95ec175 100644 --- a/include/clang/AST/TypeLocVisitor.h +++ b/include/clang/AST/TypeLocVisitor.h @@ -33,7 +33,7 @@ public: case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc); #include "clang/AST/TypeLocNodes.def" } - llvm::llvm_unreachable("unexpected type loc class!"); + llvm_unreachable("unexpected type loc class!"); } RetTy Visit(UnqualTypeLoc TyLoc) { diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def index c272123..b9d3799 100644 --- a/include/clang/AST/TypeNodes.def +++ b/include/clang/AST/TypeNodes.def @@ -71,6 +71,7 @@ TYPE(ExtVector, VectorType) ABSTRACT_TYPE(Function, Type) TYPE(FunctionProto, FunctionType) TYPE(FunctionNoProto, FunctionType) +DEPENDENT_TYPE(UnresolvedUsing, Type) NON_CANONICAL_TYPE(Typedef, Type) NON_CANONICAL_TYPE(TypeOfExpr, Type) NON_CANONICAL_TYPE(TypeOf, Type) diff --git a/include/clang/AST/TypeOrdering.h b/include/clang/AST/TypeOrdering.h index 652f4f7..1a050d2 100644 --- a/include/clang/AST/TypeOrdering.h +++ b/include/clang/AST/TypeOrdering.h @@ -50,13 +50,6 @@ namespace llvm { static bool isEqual(clang::QualType LHS, clang::QualType RHS) { return LHS == RHS; } - - static bool isPod() { - // QualType isn't *technically* a POD type. However, we can get - // away with calling it a POD type since its copy constructor, - // copy assignment operator, and destructor are all trivial. - return true; - } }; } |