diff options
Diffstat (limited to 'include/clang/AST')
-rw-r--r-- | include/clang/AST/ASTContext.h | 35 | ||||
-rw-r--r-- | include/clang/AST/Attr.h | 42 | ||||
-rw-r--r-- | include/clang/AST/Decl.h | 46 | ||||
-rw-r--r-- | include/clang/AST/DeclBase.h | 4 | ||||
-rw-r--r-- | include/clang/AST/DeclCXX.h | 41 | ||||
-rw-r--r-- | include/clang/AST/DeclTemplate.h | 3 | ||||
-rw-r--r-- | include/clang/AST/DeclarationName.h | 26 | ||||
-rw-r--r-- | include/clang/AST/Expr.h | 86 | ||||
-rw-r--r-- | include/clang/AST/ExprCXX.h | 626 | ||||
-rw-r--r-- | include/clang/AST/RecordLayout.h | 112 | ||||
-rw-r--r-- | include/clang/AST/Redeclarable.h | 13 | ||||
-rw-r--r-- | include/clang/AST/Stmt.h | 95 | ||||
-rw-r--r-- | include/clang/AST/StmtCXX.h | 6 | ||||
-rw-r--r-- | include/clang/AST/StmtNodes.def | 9 | ||||
-rw-r--r-- | include/clang/AST/TemplateBase.h | 36 | ||||
-rw-r--r-- | include/clang/AST/Type.h | 30 |
16 files changed, 868 insertions, 342 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index f9d2f71..4f29e5d 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -120,8 +120,7 @@ class ASTContext { QualType ObjCIdTypedefType; /// ObjCSelType - another pseudo built-in typedef type (set by Sema). - QualType ObjCSelType; - const RecordType *SelStructType; + QualType ObjCSelTypedefType; /// ObjCProtoType - another pseudo built-in typedef type (set by Sema). QualType ObjCProtoType; @@ -244,6 +243,7 @@ public: // pseudo-builtins QualType ObjCIdRedefinitionType; QualType ObjCClassRedefinitionType; + QualType ObjCSelRedefinitionType; /// \brief Source ranges for all of the comments in the source file, /// sorted in order of appearance in the translation unit. @@ -316,7 +316,7 @@ public: CanQualType OverloadTy; CanQualType DependentTy; CanQualType UndeducedAutoTy; - CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy; + CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; ASTContext(const LangOptions& LOpts, SourceManager &SM, const TargetInfo &t, IdentifierTable &idents, SelectorTable &sels, @@ -532,8 +532,7 @@ public: QualType Canon = QualType()); QualType getTemplateSpecializationType(TemplateName T, - const TemplateArgumentLoc *Args, - unsigned NumArgs, + const TemplateArgumentListInfo &Args, QualType Canon = QualType()); QualType getQualifiedNameType(NestedNameSpecifier *NNS, @@ -696,7 +695,7 @@ public: void setObjCIdType(QualType T); void setObjCSelType(QualType T); - QualType getObjCSelType() const { return ObjCSelType; } + QualType getObjCSelType() const { return ObjCSelTypedefType; } void setObjCProtoType(QualType QT); QualType getObjCProtoType() const { return ObjCProtoType; } @@ -734,6 +733,8 @@ public: return getExtQualType(T, Qs); } + DeclarationName getNameForTemplate(TemplateName Name); + TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, TemplateDecl *Template); @@ -796,6 +797,20 @@ public: return getTypeInfo(T).first; } + /// getByteWidth - Return the size of a byte, in bits + uint64_t getByteSize() { + return getTypeSize(CharTy); + } + + /// getTypeSizeInBytes - Return the size of the specified type, in bytes. + /// This method does not work on incomplete types. + uint64_t getTypeSizeInBytes(QualType T) { + return getTypeSize(T) / getByteSize(); + } + uint64_t getTypeSizeInBytes(const Type *T) { + return getTypeSize(T) / getByteSize(); + } + /// getTypeAlign - Return the ABI-specified alignment of a type, in bits. /// This method does not work on incomplete types. unsigned getTypeAlign(QualType T) { @@ -811,10 +826,7 @@ public: /// a data type. unsigned getPreferredTypeAlign(const Type *T); - /// getDeclAlignInBytes - Return the alignment of the specified decl - /// that should be returned by __alignof(). Note that bitfields do - /// not have a valid alignment, so this method will assert on them. - unsigned getDeclAlignInBytes(const Decl *D); + unsigned getDeclAlignInBytes(const Decl *D, bool RefAsPointee = false); /// getASTRecordLayout - Get or compute information about the layout of the /// specified record (struct/union/class), which indicates its size and field @@ -1023,8 +1035,7 @@ public: return T == ObjCClassTypedefType; } bool isObjCSelType(QualType T) const { - assert(SelStructType && "isObjCSelType used before 'SEL' type is built"); - return T->getAsStructureType() == SelStructType; + return T == ObjCSelTypedefType; } bool QualifiedIdConformsQualifiedId(QualType LHS, QualType RHS); bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS, diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index b36ff12..2c7ab9d 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -15,12 +15,12 @@ #define LLVM_CLANG_AST_ATTR_H #include "llvm/Support/Casting.h" -using llvm::dyn_cast; - +#include "llvm/ADT/StringRef.h" #include <cassert> #include <cstring> #include <string> #include <algorithm> +using llvm::dyn_cast; namespace clang { class ASTContext; @@ -49,6 +49,7 @@ public: AnalyzerNoReturn, // Clang-specific. Annotate, AsmLabel, // Represent GCC asm label extension. + BaseCheck, Blocks, CDecl, Cleanup, @@ -59,9 +60,11 @@ public: Deprecated, Destructor, FastCall, + Final, Format, FormatArg, GNUInline, + Hiding, IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict with Malloc, NoDebug, @@ -71,6 +74,7 @@ public: NoThrow, ObjCException, ObjCNSObject, + Override, CFReturnsRetained, // Clang/Checker-specific. NSReturnsRetained, // Clang/Checker-specific. Overloadable, // Clang-specific @@ -184,12 +188,24 @@ public: class AlignedAttr : public Attr { unsigned Alignment; public: - AlignedAttr(unsigned alignment) : Attr(Aligned), Alignment(alignment) {} + AlignedAttr(unsigned alignment) + : Attr(Aligned), Alignment(alignment) {} /// getAlignment - The specified alignment in bits. unsigned getAlignment() const { return Alignment; } + + /// getMaxAlignment - Get the maximum alignment of attributes on this list. + unsigned getMaxAlignment() const { + const AlignedAttr *Next = getNext<AlignedAttr>(); + if (Next) + return std::max(Next->getMaxAlignment(), Alignment); + else + return Alignment; + } - virtual Attr* clone(ASTContext &C) const { return ::new (C) AlignedAttr(Alignment); } + virtual Attr* clone(ASTContext &C) const { + return ::new (C) AlignedAttr(Alignment); + } // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { @@ -201,7 +217,7 @@ public: class AnnotateAttr : public Attr { std::string Annotation; public: - AnnotateAttr(const std::string &ann) : Attr(Annotate), Annotation(ann) {} + AnnotateAttr(llvm::StringRef ann) : Attr(Annotate), Annotation(ann) {} const std::string& getAnnotation() const { return Annotation; } @@ -217,7 +233,7 @@ public: class AsmLabelAttr : public Attr { std::string Label; public: - AsmLabelAttr(const std::string &L) : Attr(AsmLabel), Label(L) {} + AsmLabelAttr(llvm::StringRef L) : Attr(AsmLabel), Label(L) {} const std::string& getLabel() const { return Label; } @@ -235,7 +251,7 @@ DEF_SIMPLE_ATTR(AlwaysInline); class AliasAttr : public Attr { std::string Aliasee; public: - AliasAttr(const std::string &aliasee) : Attr(Alias), Aliasee(aliasee) {} + AliasAttr(llvm::StringRef aliasee) : Attr(Alias), Aliasee(aliasee) {} const std::string& getAliasee() const { return Aliasee; } @@ -304,11 +320,12 @@ DEF_SIMPLE_ATTR(Malloc); DEF_SIMPLE_ATTR(NoReturn); DEF_SIMPLE_ATTR(AnalyzerNoReturn); DEF_SIMPLE_ATTR(Deprecated); +DEF_SIMPLE_ATTR(Final); class SectionAttr : public Attr { std::string Name; public: - SectionAttr(const std::string &N) : Attr(Section), Name(N) {} + SectionAttr(llvm::StringRef N) : Attr(Section), Name(N) {} const std::string& getName() const { return Name; } @@ -367,11 +384,11 @@ class FormatAttr : public Attr { std::string Type; int formatIdx, firstArg; public: - FormatAttr(const std::string &type, int idx, int first) : Attr(Format), + FormatAttr(llvm::StringRef type, int idx, int first) : Attr(Format), Type(type), formatIdx(idx), firstArg(first) {} const std::string& getType() const { return Type; } - void setType(const std::string &type) { Type = type; } + void setType(llvm::StringRef type) { Type = type; } int getFormatIdx() const { return formatIdx; } int getFirstArg() const { return firstArg; } @@ -544,6 +561,11 @@ public: DEF_SIMPLE_ATTR(CFReturnsRetained); DEF_SIMPLE_ATTR(NSReturnsRetained); +// C++0x member checking attributes. +DEF_SIMPLE_ATTR(BaseCheck); +DEF_SIMPLE_ATTR(Hiding); +DEF_SIMPLE_ATTR(Override); + #undef DEF_SIMPLE_ATTR } // end namespace clang diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index ac79a91..f794477 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -54,6 +54,32 @@ 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; @@ -172,6 +198,26 @@ public: /// \brief Determine whether this declaration has linkage. bool hasLinkage() const; + /// \brief Describes the different kinds of linkage + /// (C++ [basic.link], C99 6.2.2) that an entity may have. + enum Linkage { + /// \brief No linkage, which means that the entity is unique and + /// can only be referred to from within its scope. + NoLinkage = 0, + + /// \brief Internal linkage, which indicates that the entity can + /// be referred to from within the translation unit (but not other + /// translation units). + InternalLinkage, + + /// \brief External linkage, which indicates that the entity can + /// be referred to from other translation units. + ExternalLinkage + }; + + /// \brief Determine what kind of linkage this entity has. + Linkage getLinkage() const; + /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for /// the underlying named decl. NamedDecl *getUnderlyingDecl(); diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 79f7663..e1f948f 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -503,12 +503,12 @@ private: /// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when /// doing something to a specific decl. class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry { - Decl *TheDecl; + const Decl *TheDecl; SourceLocation Loc; SourceManager &SM; const char *Message; public: - PrettyStackTraceDecl(Decl *theDecl, SourceLocation L, + PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L, SourceManager &sm, const char *Msg) : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {} diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index e5bf78c..990403e7 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -376,13 +376,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. - OverloadedFunctionDecl Conversions; + UnresolvedSet 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. - OverloadedFunctionDecl VisibleConversions; + UnresolvedSet VisibleConversions; /// \brief The template or declaration that this declaration /// describes or was instantiated from, respectively. @@ -400,7 +400,7 @@ class CXXRecordDecl : public RecordDecl { const llvm::SmallPtrSet<CanQualType, 8> &TopConversionsTypeSet, const llvm::SmallPtrSet<CanQualType, 8> &HiddenConversionTypes); void collectConversionFunctions( - llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet); + llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet) const; protected: CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, @@ -581,22 +581,34 @@ public: /// getConversions - Retrieve the overload set containing all of the /// conversion functions in this class. - OverloadedFunctionDecl *getConversionFunctions() { + UnresolvedSet *getConversionFunctions() { assert((this->isDefinition() || cast<RecordType>(getTypeForDecl())->isBeingDefined()) && "getConversionFunctions() called on incomplete type"); return &Conversions; } - const OverloadedFunctionDecl *getConversionFunctions() const { + const UnresolvedSet *getConversionFunctions() const { assert((this->isDefinition() || cast<RecordType>(getTypeForDecl())->isBeingDefined()) && "getConversionFunctions() called on incomplete type"); return &Conversions; } + typedef UnresolvedSet::iterator conversion_iterator; + conversion_iterator conversion_begin() const { return Conversions.begin(); } + conversion_iterator conversion_end() const { return Conversions.end(); } + + /// Replaces a conversion function with a new declaration. + /// + /// Returns true if the old conversion was found. + bool replaceConversion(const NamedDecl* Old, NamedDecl *New) { + return Conversions.replace(Old, New); + } + /// getVisibleConversionFunctions - get all conversion functions visible /// in current class; including conversion function templates. - OverloadedFunctionDecl *getVisibleConversionFunctions(); + const UnresolvedSet *getVisibleConversionFunctions(); + /// addVisibleConversionFunction - Add a new conversion function to the /// list of visible conversion functions. void addVisibleConversionFunction(CXXConversionDecl *ConvDecl); @@ -1502,9 +1514,9 @@ class UsingDirectiveDecl : public NamedDecl { SourceLocation IdentLoc; /// NominatedNamespace - Namespace nominated by using-directive. - NamespaceDecl *NominatedNamespace; + NamedDecl *NominatedNamespace; - /// Enclosing context containing both using-directive and nomintated + /// Enclosing context containing both using-directive and nominated /// namespace. DeclContext *CommonAncestor; @@ -1520,12 +1532,12 @@ class UsingDirectiveDecl : public NamedDecl { SourceRange QualifierRange, NestedNameSpecifier *Qualifier, SourceLocation IdentLoc, - NamespaceDecl *Nominated, + NamedDecl *Nominated, DeclContext *CommonAncestor) : NamedDecl(Decl::UsingDirective, DC, L, getName()), NamespaceLoc(NamespcLoc), QualifierRange(QualifierRange), Qualifier(Qualifier), IdentLoc(IdentLoc), - NominatedNamespace(Nominated? Nominated->getOriginalNamespace() : 0), + NominatedNamespace(Nominated), CommonAncestor(CommonAncestor) { } @@ -1538,8 +1550,13 @@ public: /// name of the namespace. NestedNameSpecifier *getQualifier() const { return Qualifier; } + NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; } + const NamedDecl *getNominatedNamespaceAsWritten() const { + return NominatedNamespace; + } + /// getNominatedNamespace - Returns namespace nominated by using-directive. - NamespaceDecl *getNominatedNamespace() { return NominatedNamespace; } + NamespaceDecl *getNominatedNamespace(); const NamespaceDecl *getNominatedNamespace() const { return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace(); @@ -1562,7 +1579,7 @@ public: SourceRange QualifierRange, NestedNameSpecifier *Qualifier, SourceLocation IdentLoc, - NamespaceDecl *Nominated, + NamedDecl *Nominated, DeclContext *CommonAncestor); static bool classof(const Decl *D) { diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 14f6660..3ecc4bb 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -955,8 +955,7 @@ public: TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, TemplateArgumentListBuilder &Builder, - TemplateArgumentLoc *ArgInfos, - unsigned NumArgInfos, + const TemplateArgumentListInfo &ArgInfos, ClassTemplatePartialSpecializationDecl *PrevDecl); /// Get the list of template parameters diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index a30f6e8..676bd2c 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -25,6 +25,7 @@ namespace llvm { namespace clang { class CXXSpecialName; class CXXOperatorIdName; + class CXXLiteralOperatorIdName; class DeclarationNameExtra; class IdentifierInfo; class MultiKeywordSelector; @@ -48,6 +49,7 @@ public: CXXDestructorName, CXXConversionFunctionName, CXXOperatorName, + CXXLiteralOperatorName, CXXUsingDirective }; @@ -115,6 +117,12 @@ private: return 0; } + CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const { + if (getNameKind() == CXXLiteralOperatorName) + return reinterpret_cast<CXXLiteralOperatorIdName *>(Ptr & ~PtrMask); + return 0; + } + // Construct a declaration name from the name of a C++ constructor, // destructor, or conversion function. DeclarationName(CXXSpecialName *Name) @@ -131,6 +139,12 @@ private: Ptr |= StoredDeclarationNameExtra; } + DeclarationName(CXXLiteralOperatorIdName *Name) + : Ptr(reinterpret_cast<uintptr_t>(Name)) { + assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXLiteralOperatorId"); + Ptr |= StoredDeclarationNameExtra; + } + /// Construct a declaration name from a raw pointer. DeclarationName(uintptr_t Ptr) : Ptr(Ptr) { } @@ -201,7 +215,7 @@ public: N.Ptr = reinterpret_cast<uintptr_t> (P); return N; } - + static DeclarationName getFromOpaqueInteger(uintptr_t P) { DeclarationName N; N.Ptr = P; @@ -218,6 +232,10 @@ public: /// kind of overloaded operator. OverloadedOperatorKind getCXXOverloadedOperator() const; + /// getCXXLiteralIdentifier - If this name is the name of a literal + /// operator, retrieve the identifier associated with it. + IdentifierInfo *getCXXLiteralIdentifier() const; + /// getObjCSelector - Get the Objective-C selector stored in this /// declaration name. Selector getObjCSelector() const; @@ -293,7 +311,7 @@ public: /// getIdentifier - Create a declaration name that is a simple /// identifier. - DeclarationName getIdentifier(IdentifierInfo *ID) { + DeclarationName getIdentifier(const IdentifierInfo *ID) { return DeclarationName(ID); } @@ -324,6 +342,10 @@ public: /// getCXXOperatorName - Get the name of the overloadable C++ /// operator corresponding to Op. DeclarationName getCXXOperatorName(OverloadedOperatorKind Op); + + /// getCXXLiteralOperatorName - Get the name of the literal operator function + /// with II as the identifier. + DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II); }; /// Insertion operator for diagnostics. This allows sending DeclarationName's diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index dfc5b13..7cf9aab 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -35,6 +35,7 @@ namespace clang { class CXXOperatorCallExpr; class CXXMemberCallExpr; class TemplateArgumentLoc; + class TemplateArgumentListInfo; /// Expr - This represents one expression. Note that Expr's are subclasses of /// Stmt. This allows an expression to be transparently used any place a Stmt @@ -366,6 +367,10 @@ struct ExplicitTemplateArgumentList { const TemplateArgumentLoc *getTemplateArgs() const { return reinterpret_cast<const TemplateArgumentLoc *> (this + 1); } + + void initializeFrom(const TemplateArgumentListInfo &List); + void copyInto(TemplateArgumentListInfo &List) const; + static std::size_t sizeFor(const TemplateArgumentListInfo &List); }; /// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function, @@ -423,31 +428,24 @@ class DeclRefExpr : public Expr { DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange, NamedDecl *D, SourceLocation NameLoc, - bool HasExplicitTemplateArgumentList, - SourceLocation LAngleLoc, - const TemplateArgumentLoc *ExplicitTemplateArgs, - unsigned NumExplicitTemplateArgs, - SourceLocation RAngleLoc, - QualType T, bool TD, bool VD); + const TemplateArgumentListInfo *TemplateArgs, + QualType T); protected: - // FIXME: Eventually, this constructor will go away and all subclasses - // will have to provide the type- and value-dependent flags. - DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) : - Expr(SC, t), DecoratedD(d, 0), Loc(l) {} + /// \brief Computes the type- and value-dependence flags for this + /// declaration reference expression. + void computeDependence(); - DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l, bool TD, - bool VD) : - Expr(SC, t, TD, VD), DecoratedD(d, 0), Loc(l) {} + DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) : + Expr(SC, t, false, false), DecoratedD(d, 0), Loc(l) { + computeDependence(); + } public: - // FIXME: Eventually, this constructor will go away and all clients - // will have to provide the type- and value-dependent flags. DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l) : - Expr(DeclRefExprClass, t), DecoratedD(d, 0), Loc(l) {} - - DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l, bool TD, bool VD) : - Expr(DeclRefExprClass, t, TD, VD), DecoratedD(d, 0), Loc(l) {} + Expr(DeclRefExprClass, t, false, false), DecoratedD(d, 0), Loc(l) { + computeDependence(); + } /// \brief Construct an empty declaration reference expression. explicit DeclRefExpr(EmptyShell Empty) @@ -458,19 +456,8 @@ public: SourceRange QualifierRange, NamedDecl *D, SourceLocation NameLoc, - QualType T, bool TD, bool VD); - - static DeclRefExpr *Create(ASTContext &Context, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, - NamedDecl *D, - SourceLocation NameLoc, - bool HasExplicitTemplateArgumentList, - SourceLocation LAngleLoc, - const TemplateArgumentLoc *ExplicitTemplateArgs, - unsigned NumExplicitTemplateArgs, - SourceLocation RAngleLoc, - QualType T, bool TD, bool VD); + QualType T, + const TemplateArgumentListInfo *TemplateArgs = 0); NamedDecl *getDecl() { return DecoratedD.getPointer(); } const NamedDecl *getDecl() const { return DecoratedD.getPointer(); } @@ -508,6 +495,13 @@ public: bool hasExplicitTemplateArgumentList() const { return DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag; } + + /// \brief Copies the template arguments (if present) into the given + /// structure. + void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { + if (hasExplicitTemplateArgumentList()) + getExplicitTemplateArgumentList()->copyInto(List); + } /// \brief Retrieve the location of the left angle bracket following the /// member name ('<'), if any. @@ -546,8 +540,7 @@ public: } static bool classof(const Stmt *T) { - return T->getStmtClass() == DeclRefExprClass || - T->getStmtClass() == CXXConditionDeclExprClass; + return T->getStmtClass() == DeclRefExprClass; } static bool classof(const DeclRefExpr *) { return true; } @@ -1313,9 +1306,7 @@ class MemberExpr : public Expr { MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual, SourceRange qualrange, NamedDecl *memberdecl, SourceLocation l, - bool has_explicit, SourceLocation langle, - const TemplateArgumentLoc *targs, unsigned numtargs, - SourceLocation rangle, QualType ty); + const TemplateArgumentListInfo *targs, QualType ty); public: MemberExpr(Expr *base, bool isarrow, NamedDecl *memberdecl, SourceLocation l, @@ -1334,11 +1325,7 @@ public: NestedNameSpecifier *qual, SourceRange qualrange, NamedDecl *memberdecl, SourceLocation l, - bool has_explicit, - SourceLocation langle, - const TemplateArgumentLoc *targs, - unsigned numtargs, - SourceLocation rangle, + const TemplateArgumentListInfo *targs, QualType ty); void setBase(Expr *E) { Base = E; } @@ -1378,10 +1365,17 @@ public: /// \brief Determines whether this member expression actually had a C++ /// template argument list explicitly specified, e.g., x.f<int>. - bool hasExplicitTemplateArgumentList() { + bool hasExplicitTemplateArgumentList() const { return HasExplicitTemplateArgumentList; } + /// \brief Copies the template arguments (if present) into the given + /// structure. + void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { + if (hasExplicitTemplateArgumentList()) + getExplicitTemplateArgumentList()->copyInto(List); + } + /// \brief Retrieve the location of the left angle bracket following the /// member name ('<'), if any. SourceLocation getLAngleLoc() const { @@ -1579,7 +1573,11 @@ public: CK_FloatingToIntegral, /// CK_FloatingCast - Casting between floating types of different size. - CK_FloatingCast + CK_FloatingCast, + + /// CK_MemberPointerToBoolean - Member pointer to boolean + CK_MemberPointerToBoolean + }; private: diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 9e6fd4f..23844ce 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -17,6 +17,7 @@ #include "clang/Basic/TypeTraits.h" #include "clang/AST/Expr.h" #include "clang/AST/Decl.h" +#include "clang/AST/TemplateBase.h" namespace clang { @@ -24,6 +25,7 @@ namespace clang { class CXXDestructorDecl; class CXXMethodDecl; class CXXTemporary; + class TemplateArgumentListInfo; //===--------------------------------------------------------------------===// // C++ Expressions. @@ -669,40 +671,6 @@ public: virtual child_iterator child_end(); }; -/// CXXConditionDeclExpr - Condition declaration of a if/switch/while/for -/// statement, e.g: "if (int x = f()) {...}". -/// The main difference with DeclRefExpr is that CXXConditionDeclExpr owns the -/// decl that it references. -/// -class CXXConditionDeclExpr : public DeclRefExpr { -public: - CXXConditionDeclExpr(SourceLocation startLoc, - SourceLocation eqLoc, VarDecl *var) - : DeclRefExpr(CXXConditionDeclExprClass, var, - var->getType().getNonReferenceType(), startLoc, - var->getType()->isDependentType(), - /*FIXME:integral constant?*/ - var->getType()->isDependentType()) {} - - SourceLocation getStartLoc() const { return getLocation(); } - - VarDecl *getVarDecl() { return cast<VarDecl>(getDecl()); } - const VarDecl *getVarDecl() const { return cast<VarDecl>(getDecl()); } - - virtual SourceRange getSourceRange() const { - return SourceRange(getStartLoc(), getVarDecl()->getInit()->getLocEnd()); - } - - static bool classof(const Stmt *T) { - return T->getStmtClass() == CXXConditionDeclExprClass; - } - static bool classof(const CXXConditionDeclExpr *) { return true; } - - // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); -}; - /// CXXNewExpr - A new expression for memory allocation and constructor calls, /// e.g: "new CXXNewExpr(foo)". class CXXNewExpr : public Expr { @@ -975,52 +943,6 @@ public: virtual child_iterator child_end(); }; -/// \brief Represents the name of a function that has not been -/// resolved to any declaration. -/// -/// Unresolved function names occur when a function name is -/// encountered prior to an open parentheses ('(') in a C++ function -/// call, and the function name itself did not resolve to a -/// declaration. These function names can only be resolved when they -/// form the postfix-expression of a function call, so that -/// argument-dependent lookup finds declarations corresponding to -/// these functions. - -/// @code -/// template<typename T> void f(T x) { -/// g(x); // g is an unresolved function name (that is also a dependent name) -/// } -/// @endcode -class UnresolvedFunctionNameExpr : public Expr { - /// The name that was present in the source - DeclarationName Name; - - /// The location of this name in the source code - SourceLocation Loc; - -public: - UnresolvedFunctionNameExpr(DeclarationName N, QualType T, SourceLocation L) - : Expr(UnresolvedFunctionNameExprClass, T, false, false), Name(N), Loc(L) { } - - /// \brief Retrieves the name that occurred in the source code. - DeclarationName getName() const { return Name; } - - /// getLocation - Retrieves the location in the source code where - /// the name occurred. - SourceLocation getLocation() const { return Loc; } - - virtual SourceRange getSourceRange() const { return SourceRange(Loc); } - - static bool classof(const Stmt *T) { - return T->getStmtClass() == UnresolvedFunctionNameExprClass; - } - static bool classof(const UnresolvedFunctionNameExpr *) { return true; } - - // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); -}; - /// UnaryTypeTraitExpr - A GCC or MS unary type trait, as used in the /// implementation of TR1/C++0x type trait templates. /// Example: @@ -1063,21 +985,177 @@ public: virtual child_iterator child_end(); }; +/// \brief A reference to a name which we were able to look up during +/// parsing but could not resolve to a specific declaration. This +/// arises in several ways: +/// * we might be waiting for argument-dependent lookup +/// * the name might resolve to an overloaded function +/// and eventually: +/// * the lookup might have included a function template +/// These never include UnresolvedUsingValueDecls, which are always +/// class members and therefore appear only in +/// UnresolvedMemberLookupExprs. +class UnresolvedLookupExpr : public Expr { + /// The results. These are undesugared, which is to say, they may + /// include UsingShadowDecls. + UnresolvedSet Results; + + /// The name declared. + DeclarationName Name; + + /// The qualifier given, if any. + NestedNameSpecifier *Qualifier; + + /// The source range of the nested name specifier. + SourceRange QualifierRange; + + /// The location of the name. + SourceLocation NameLoc; + + /// True if these lookup results should be extended by + /// argument-dependent lookup if this is the operand of a function + /// call. + bool RequiresADL; + + /// True if these lookup results are overloaded. This is pretty + /// trivially rederivable if we urgently need to kill this field. + bool Overloaded; + + /// True if the name looked up had explicit template arguments. + /// This requires all the results to be function templates. + bool HasExplicitTemplateArgs; + + UnresolvedLookupExpr(QualType T, bool Dependent, + NestedNameSpecifier *Qualifier, SourceRange QRange, + DeclarationName Name, SourceLocation NameLoc, + bool RequiresADL, bool Overloaded, bool HasTemplateArgs) + : Expr(UnresolvedLookupExprClass, T, Dependent, Dependent), + Name(Name), Qualifier(Qualifier), QualifierRange(QRange), + NameLoc(NameLoc), RequiresADL(RequiresADL), Overloaded(Overloaded), + HasExplicitTemplateArgs(HasTemplateArgs) + {} + +public: + static UnresolvedLookupExpr *Create(ASTContext &C, + bool Dependent, + NestedNameSpecifier *Qualifier, + SourceRange QualifierRange, + DeclarationName Name, + SourceLocation NameLoc, + bool ADL, bool Overloaded) { + return new(C) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy, + Dependent, Qualifier, QualifierRange, + Name, NameLoc, ADL, Overloaded, false); + } + + static UnresolvedLookupExpr *Create(ASTContext &C, + bool Dependent, + NestedNameSpecifier *Qualifier, + SourceRange QualifierRange, + DeclarationName Name, + SourceLocation NameLoc, + bool ADL, + const TemplateArgumentListInfo &Args); + + /// 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, + const TemplateArgumentListInfo *Args); + + void addDecl(NamedDecl *Decl) { + Results.addDecl(Decl); + } + + typedef UnresolvedSet::iterator decls_iterator; + decls_iterator decls_begin() const { return Results.begin(); } + decls_iterator decls_end() const { return Results.end(); } + + /// True if this declaration should be extended by + /// argument-dependent lookup. + bool requiresADL() const { return RequiresADL; } + + /// True if this lookup is overloaded. + bool isOverloaded() const { return Overloaded; } + + /// Fetches the name looked up. + DeclarationName getName() const { return Name; } + + /// Gets the location of the name. + SourceLocation getNameLoc() const { return NameLoc; } + + /// Fetches the nested-name qualifier, if one was given. + NestedNameSpecifier *getQualifier() const { return Qualifier; } + + /// Fetches the range of the nested-name qualifier. + SourceRange getQualifierRange() const { return QualifierRange; } + + /// Determines whether this lookup had explicit template arguments. + bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; } + + // Note that, inconsistently with the explicit-template-argument AST + // nodes, users are *forbidden* from calling these methods on objects + // without explicit template arguments. + + /// Gets a reference to the explicit template argument list. + const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const { + assert(hasExplicitTemplateArgs()); + return *reinterpret_cast<const ExplicitTemplateArgumentList*>(this + 1); + } + + /// \brief Copies the template arguments (if present) into the given + /// structure. + void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { + getExplicitTemplateArgs().copyInto(List); + } + + SourceLocation getLAngleLoc() const { + return getExplicitTemplateArgs().LAngleLoc; + } + + SourceLocation getRAngleLoc() const { + return getExplicitTemplateArgs().RAngleLoc; + } + + TemplateArgumentLoc const *getTemplateArgs() const { + return getExplicitTemplateArgs().getTemplateArgs(); + } + + unsigned getNumTemplateArgs() const { + return getExplicitTemplateArgs().NumTemplateArgs; + } + + virtual SourceRange getSourceRange() const { + SourceRange Range(NameLoc); + if (Qualifier) Range.setBegin(QualifierRange.getBegin()); + if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc()); + return Range; + } + + virtual StmtIterator child_begin(); + virtual StmtIterator child_end(); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == UnresolvedLookupExprClass; + } + static bool classof(const UnresolvedLookupExpr *) { return true; } +}; + /// \brief A qualified reference to a name whose declaration cannot /// yet be resolved. /// -/// UnresolvedDeclRefExpr is similar to eclRefExpr in that +/// DependentScopeDeclRefExpr is similar to DeclRefExpr in that /// it expresses a reference to a declaration such as /// X<T>::value. The difference, however, is that an -/// UnresolvedDeclRefExpr node is used only within C++ templates when +/// DependentScopeDeclRefExpr node is used only within C++ templates when /// the qualification (e.g., X<T>::) refers to a dependent type. In /// this case, X<T>::value cannot resolve to a declaration because the /// declaration will differ from on instantiation of X<T> to the -/// next. Therefore, UnresolvedDeclRefExpr keeps track of the +/// next. Therefore, DependentScopeDeclRefExpr keeps track of the /// qualifier (X<T>::) and the name of the entity being referenced /// ("value"). Such expressions will instantiate to a DeclRefExpr once the /// declaration can be found. -class UnresolvedDeclRefExpr : public Expr { +class DependentScopeDeclRefExpr : public Expr { /// The name of the entity we will be referencing. DeclarationName Name; @@ -1090,19 +1168,30 @@ class UnresolvedDeclRefExpr : public Expr { /// \brief The nested-name-specifier that qualifies this unresolved /// declaration name. - NestedNameSpecifier *NNS; + NestedNameSpecifier *Qualifier; - /// \brief Whether this expr is an address of (&) operand. - /// FIXME: Stash this bit into NNS! - bool IsAddressOfOperand; + /// \brief Whether the name includes explicit template arguments. + bool HasExplicitTemplateArgs; + + DependentScopeDeclRefExpr(QualType T, + NestedNameSpecifier *Qualifier, + SourceRange QualifierRange, + DeclarationName Name, + SourceLocation NameLoc, + bool HasExplicitTemplateArgs) + : Expr(DependentScopeDeclRefExprClass, T, true, true), + Name(Name), Loc(NameLoc), + QualifierRange(QualifierRange), Qualifier(Qualifier), + HasExplicitTemplateArgs(HasExplicitTemplateArgs) + {} public: - UnresolvedDeclRefExpr(DeclarationName N, QualType T, SourceLocation L, - SourceRange R, NestedNameSpecifier *NNS, - bool IsAddressOfOperand) - : Expr(UnresolvedDeclRefExprClass, T, true, true), - Name(N), Loc(L), QualifierRange(R), NNS(NNS), - IsAddressOfOperand(IsAddressOfOperand) { } + static DependentScopeDeclRefExpr *Create(ASTContext &C, + NestedNameSpecifier *Qualifier, + SourceRange QualifierRange, + DeclarationName Name, + SourceLocation NameLoc, + const TemplateArgumentListInfo *TemplateArgs = 0); /// \brief Retrieve the name that this expression refers to. DeclarationName getDeclName() const { return Name; } @@ -1115,116 +1204,57 @@ public: /// \brief Retrieve the nested-name-specifier that qualifies this /// declaration. - NestedNameSpecifier *getQualifier() const { return NNS; } - - /// \brief Retrieve whether this is an address of (&) operand. - - bool isAddressOfOperand() const { return IsAddressOfOperand; } - virtual SourceRange getSourceRange() const { - return SourceRange(QualifierRange.getBegin(), getLocation()); - } - - static bool classof(const Stmt *T) { - return T->getStmtClass() == UnresolvedDeclRefExprClass; - } - static bool classof(const UnresolvedDeclRefExpr *) { return true; } - - virtual StmtIterator child_begin(); - virtual StmtIterator child_end(); -}; - -/// \brief An expression that refers to a C++ template-id, such as -/// @c isa<FunctionDecl>. -class TemplateIdRefExpr : public Expr { - /// \brief If this template-id was qualified-id, e.g., @c std::sort<int>, - /// this nested name specifier contains the @c std::. - NestedNameSpecifier *Qualifier; - - /// \brief If this template-id was a qualified-id, e.g., @c std::sort<int>, - /// this covers the source code range of the @c std::. - SourceRange QualifierRange; - - /// \brief The actual template to which this template-id refers. - TemplateName Template; - - /// \brief The source location of the template name. - SourceLocation TemplateNameLoc; - - /// \brief The source location of the left angle bracket ('<'); - SourceLocation LAngleLoc; - - /// \brief The source location of the right angle bracket ('>'); - SourceLocation RAngleLoc; - - /// \brief The number of template arguments in TemplateArgs. - unsigned NumTemplateArgs; - - TemplateIdRefExpr(QualType T, - NestedNameSpecifier *Qualifier, SourceRange QualifierRange, - TemplateName Template, SourceLocation TemplateNameLoc, - SourceLocation LAngleLoc, - const TemplateArgumentLoc *TemplateArgs, - unsigned NumTemplateArgs, - SourceLocation RAngleLoc); - - virtual void DoDestroy(ASTContext &Context); - -public: - static TemplateIdRefExpr * - Create(ASTContext &Context, QualType T, - NestedNameSpecifier *Qualifier, SourceRange QualifierRange, - TemplateName Template, SourceLocation TemplateNameLoc, - SourceLocation LAngleLoc, const TemplateArgumentLoc *TemplateArgs, - unsigned NumTemplateArgs, SourceLocation RAngleLoc); - - /// \brief Retrieve the nested name specifier used to qualify the name of - /// this template-id, e.g., the "std::sort" in @c std::sort<int>, or NULL - /// if this template-id was an unqualified-id. NestedNameSpecifier *getQualifier() const { return Qualifier; } - /// \brief Retrieve the source range describing the nested name specifier - /// used to qualified the name of this template-id, if the name was qualified. - SourceRange getQualifierRange() const { return QualifierRange; } + /// Determines whether this lookup had explicit template arguments. + bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; } - /// \brief Retrieve the name of the template referenced, e.g., "sort" in - /// @c std::sort<int>; - TemplateName getTemplateName() const { return Template; } + // Note that, inconsistently with the explicit-template-argument AST + // nodes, users are *forbidden* from calling these methods on objects + // without explicit template arguments. - /// \brief Retrieve the location of the name of the template referenced, e.g., - /// the location of "sort" in @c std::sort<int>. - SourceLocation getTemplateNameLoc() const { return TemplateNameLoc; } + /// Gets a reference to the explicit template argument list. + const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const { + assert(hasExplicitTemplateArgs()); + return *reinterpret_cast<const ExplicitTemplateArgumentList*>(this + 1); + } - /// \brief Retrieve the location of the left angle bracket following the - /// template name ('<'). - SourceLocation getLAngleLoc() const { return LAngleLoc; } + /// \brief Copies the template arguments (if present) into the given + /// structure. + void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { + getExplicitTemplateArgs().copyInto(List); + } + + SourceLocation getLAngleLoc() const { + return getExplicitTemplateArgs().LAngleLoc; + } - /// \brief Retrieve the template arguments provided as part of this - /// template-id. - const TemplateArgumentLoc *getTemplateArgs() const { - return reinterpret_cast<const TemplateArgumentLoc *>(this + 1); + SourceLocation getRAngleLoc() const { + return getExplicitTemplateArgs().RAngleLoc; } - /// \brief Retrieve the number of template arguments provided as part of this - /// template-id. - unsigned getNumTemplateArgs() const { return NumTemplateArgs; } + TemplateArgumentLoc const *getTemplateArgs() const { + return getExplicitTemplateArgs().getTemplateArgs(); + } - /// \brief Retrieve the location of the right angle bracket following the - /// template arguments ('>'). - SourceLocation getRAngleLoc() const { return RAngleLoc; } + unsigned getNumTemplateArgs() const { + return getExplicitTemplateArgs().NumTemplateArgs; + } virtual SourceRange getSourceRange() const { - return SourceRange(Qualifier? QualifierRange.getBegin() : TemplateNameLoc, - RAngleLoc); + SourceRange Range(QualifierRange.getBegin(), getLocation()); + if (hasExplicitTemplateArgs()) + Range.setEnd(getRAngleLoc()); + return Range; } - // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); - static bool classof(const Stmt *T) { - return T->getStmtClass() == TemplateIdRefExprClass; + return T->getStmtClass() == DependentScopeDeclRefExprClass; } - static bool classof(const TemplateIdRefExpr *) { return true; } + static bool classof(const DependentScopeDeclRefExpr *) { return true; } + + virtual StmtIterator child_begin(); + virtual StmtIterator child_end(); }; class CXXExprWithTemporaries : public Expr { @@ -1377,10 +1407,10 @@ public: virtual child_iterator child_end(); }; -/// \brief Represents a C++ member access expression where the actual member -/// referenced could not be resolved, e.g., because the base expression or the -/// member name was dependent. -class CXXUnresolvedMemberExpr : public Expr { +/// \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. +class CXXDependentScopeMemberExpr : public Expr { /// \brief The expression for the base pointer or class reference, /// e.g., the \c x in x.f. Stmt *Base; @@ -1408,7 +1438,7 @@ class CXXUnresolvedMemberExpr : public Expr { /// /// FIXME: This member, along with the Qualifier and QualifierRange, could /// be stuck into a structure that is optionally allocated at the end of - /// the CXXUnresolvedMemberExpr, to save space in the common case. + /// the CXXDependentScopeMemberExpr, to save space in the common case. NamedDecl *FirstQualifierFoundInScope; /// \brief The member to which this member expression refers, which @@ -1431,11 +1461,11 @@ class CXXUnresolvedMemberExpr : public Expr { /// \brief Retrieve the explicit template argument list that followed the /// member template name, if any. const ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() const { - return const_cast<CXXUnresolvedMemberExpr *>(this) + return const_cast<CXXDependentScopeMemberExpr *>(this) ->getExplicitTemplateArgumentList(); } - CXXUnresolvedMemberExpr(ASTContext &C, + CXXDependentScopeMemberExpr(ASTContext &C, Expr *Base, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifier *Qualifier, @@ -1443,14 +1473,10 @@ class CXXUnresolvedMemberExpr : public Expr { NamedDecl *FirstQualifierFoundInScope, DeclarationName Member, SourceLocation MemberLoc, - bool HasExplicitTemplateArgs, - SourceLocation LAngleLoc, - const TemplateArgumentLoc *TemplateArgs, - unsigned NumTemplateArgs, - SourceLocation RAngleLoc); + const TemplateArgumentListInfo *TemplateArgs); public: - CXXUnresolvedMemberExpr(ASTContext &C, + CXXDependentScopeMemberExpr(ASTContext &C, Expr *Base, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifier *Qualifier, @@ -1458,14 +1484,14 @@ public: NamedDecl *FirstQualifierFoundInScope, DeclarationName Member, SourceLocation MemberLoc) - : Expr(CXXUnresolvedMemberExprClass, C.DependentTy, true, true), + : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true), Base(Base), IsArrow(IsArrow), HasExplicitTemplateArgumentList(false), OperatorLoc(OperatorLoc), Qualifier(Qualifier), QualifierRange(QualifierRange), FirstQualifierFoundInScope(FirstQualifierFoundInScope), Member(Member), MemberLoc(MemberLoc) { } - static CXXUnresolvedMemberExpr * + static CXXDependentScopeMemberExpr * Create(ASTContext &C, Expr *Base, bool IsArrow, SourceLocation OperatorLoc, @@ -1474,11 +1500,7 @@ public: NamedDecl *FirstQualifierFoundInScope, DeclarationName Member, SourceLocation MemberLoc, - bool HasExplicitTemplateArgs, - SourceLocation LAngleLoc, - const TemplateArgumentLoc *TemplateArgs, - unsigned NumTemplateArgs, - SourceLocation RAngleLoc); + const TemplateArgumentListInfo *TemplateArgs); /// \brief Retrieve the base object of this member expressions, /// e.g., the \c x in \c x.m. @@ -1529,10 +1551,17 @@ public: /// \brief Determines whether this member expression actually had a C++ /// template argument list explicitly specified, e.g., x.f<int>. - bool hasExplicitTemplateArgumentList() { + bool hasExplicitTemplateArgumentList() const { return HasExplicitTemplateArgumentList; } + /// \brief Copies the template arguments (if present) into the given + /// structure. + void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { + if (hasExplicitTemplateArgumentList()) + getExplicitTemplateArgumentList()->copyInto(List); + } + /// \brief Retrieve the location of the left angle bracket following the /// member name ('<'), if any. SourceLocation getLAngleLoc() const { @@ -1579,9 +1608,182 @@ public: } static bool classof(const Stmt *T) { - return T->getStmtClass() == CXXUnresolvedMemberExprClass; + return T->getStmtClass() == CXXDependentScopeMemberExprClass; + } + static bool classof(const CXXDependentScopeMemberExpr *) { return true; } + + // Iterators + virtual child_iterator child_begin(); + virtual child_iterator child_end(); +}; + +/// \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. +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. + Stmt *Base; + + /// \brief Whether this member expression used the '->' operator or + /// the '.' operator. + bool IsArrow : 1; + + /// \brief Whether the lookup results contain an unresolved using + /// declaration. + bool HasUnresolvedUsing : 1; + + /// \brief Whether this member expression has explicitly-specified template + /// arguments. + bool HasExplicitTemplateArgs : 1; + + /// \brief The location of the '->' or '.' operator. + SourceLocation OperatorLoc; + + /// \brief The nested-name-specifier that precedes the member name, if any. + NestedNameSpecifier *Qualifier; + + /// \brief The source range covering the nested name specifier. + SourceRange QualifierRange; + + /// \brief The member to which this member expression refers, which + /// can be a name or an overloaded operator. + DeclarationName MemberName; + + /// \brief The location of the member name. + SourceLocation MemberLoc; + + /// \brief Retrieve the explicit template argument list that followed the + /// member template name. + ExplicitTemplateArgumentList *getExplicitTemplateArgs() { + assert(HasExplicitTemplateArgs); + return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1); + } + + /// \brief Retrieve the explicit template argument list that followed the + /// member template name, if any. + const ExplicitTemplateArgumentList *getExplicitTemplateArgs() const { + return const_cast<UnresolvedMemberExpr*>(this)->getExplicitTemplateArgs(); + } + + UnresolvedMemberExpr(QualType T, bool Dependent, + bool HasUnresolvedUsing, + Expr *Base, bool IsArrow, + SourceLocation OperatorLoc, + NestedNameSpecifier *Qualifier, + SourceRange QualifierRange, + DeclarationName Member, + SourceLocation MemberLoc, + const TemplateArgumentListInfo *TemplateArgs); + +public: + static UnresolvedMemberExpr * + Create(ASTContext &C, bool Dependent, bool HasUnresolvedUsing, + Expr *Base, bool IsArrow, + SourceLocation OperatorLoc, + NestedNameSpecifier *Qualifier, + SourceRange QualifierRange, + DeclarationName Member, + SourceLocation MemberLoc, + const TemplateArgumentListInfo *TemplateArgs); + + /// Adds a declaration to the unresolved set. By assumption, all of + /// these happen at initialization time and properties like + /// 'Dependent' and 'HasUnresolvedUsing' take them into account. + void addDecl(NamedDecl *Decl) { + Results.addDecl(Decl); + } + + typedef UnresolvedSet::iterator decls_iterator; + decls_iterator decls_begin() const { return Results.begin(); } + decls_iterator decls_end() const { return Results.end(); } + + unsigned getNumDecls() const { return Results.size(); } + + /// \brief Retrieve the base object of this member expressions, + /// e.g., the \c x in \c x.m. + Expr *getBase() { return cast<Expr>(Base); } + void setBase(Expr *E) { Base = E; } + + /// \brief Determine whether this member expression used the '->' + /// operator; otherwise, it used the '.' operator. + bool isArrow() const { return IsArrow; } + void setArrow(bool A) { IsArrow = A; } + + /// \brief Retrieve the location of the '->' or '.' operator. + SourceLocation getOperatorLoc() const { return OperatorLoc; } + void setOperatorLoc(SourceLocation L) { OperatorLoc = L; } + + /// \brief Retrieve the nested-name-specifier that qualifies the member + /// name. + NestedNameSpecifier *getQualifier() const { return Qualifier; } + + /// \brief Retrieve the source range covering the nested-name-specifier + /// that qualifies the member name. + SourceRange getQualifierRange() const { return QualifierRange; } + + /// \brief Retrieve the name of the member that this expression + /// refers to. + DeclarationName getMemberName() const { return MemberName; } + void setMemberName(DeclarationName N) { MemberName = N; } + + // \brief Retrieve the location of the name of the member that this + // expression refers to. + SourceLocation getMemberLoc() const { return MemberLoc; } + void setMemberLoc(SourceLocation L) { MemberLoc = L; } + + /// \brief Determines whether this member expression actually had a C++ + /// template argument list explicitly specified, e.g., x.f<int>. + bool hasExplicitTemplateArgs() const { + return HasExplicitTemplateArgs; + } + + /// \brief Copies the template arguments into the given structure. + void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { + getExplicitTemplateArgs()->copyInto(List); + } + + /// \brief Retrieve the location of the left angle bracket following + /// the member name ('<'). + SourceLocation getLAngleLoc() const { + return getExplicitTemplateArgs()->LAngleLoc; + } + + /// \brief Retrieve the template arguments provided as part of this + /// template-id. + const TemplateArgumentLoc *getTemplateArgs() const { + return getExplicitTemplateArgs()->getTemplateArgs(); + } + + /// \brief Retrieve the number of template arguments provided as + /// part of this template-id. + unsigned getNumTemplateArgs() const { + return getExplicitTemplateArgs()->NumTemplateArgs; + } + + /// \brief Retrieve the location of the right angle bracket + /// following the template arguments ('>'). + SourceLocation getRAngleLoc() const { + return getExplicitTemplateArgs()->RAngleLoc; + } + + virtual SourceRange getSourceRange() const { + SourceRange Range = Base->getSourceRange(); + if (hasExplicitTemplateArgs()) + Range.setEnd(getRAngleLoc()); + else + Range.setEnd(MemberLoc); + return Range; + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == UnresolvedMemberExprClass; } - static bool classof(const CXXUnresolvedMemberExpr *) { return true; } + static bool classof(const UnresolvedMemberExpr *) { return true; } // Iterators virtual child_iterator child_begin(); diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h index 9b1c640..5d2973e 100644 --- a/include/clang/AST/RecordLayout.h +++ b/include/clang/AST/RecordLayout.h @@ -47,6 +47,59 @@ class ASTRecordLayout { // FieldCount - Number of fields. unsigned FieldCount; +public: + /// PrimaryBaseInfo - Contains info about a primary base. + struct PrimaryBaseInfo { + PrimaryBaseInfo() {} + + PrimaryBaseInfo(const CXXRecordDecl *Base, bool IsVirtual) + : Value(Base, IsVirtual) {} + + /// Value - Points to the primary base. The single-bit value + /// will be non-zero when the primary base is virtual. + llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Value; + + /// getBase - Returns the primary base. + const CXXRecordDecl *getBase() const { return Value.getPointer(); } + + /// isVirtual - Returns whether the primary base is virtual or not. + bool isVirtual() const { return Value.getInt(); } + + friend bool operator==(const PrimaryBaseInfo &X, const PrimaryBaseInfo &Y) { + return X.Value == Y.Value; + } + }; + + /// primary_base_info_iterator - An iterator for iterating the primary base + /// class chain. + class primary_base_info_iterator { + /// Current - The current base class info. + PrimaryBaseInfo Current; + + public: + primary_base_info_iterator() {} + primary_base_info_iterator(PrimaryBaseInfo Info) : Current(Info) {} + + const PrimaryBaseInfo &operator*() const { return Current; } + + primary_base_info_iterator& operator++() { + const CXXRecordDecl *RD = Current.getBase(); + Current = RD->getASTContext().getASTRecordLayout(RD).getPrimaryBaseInfo(); + return *this; + } + + friend bool operator==(const primary_base_info_iterator &X, + const primary_base_info_iterator &Y) { + return X.Current == Y.Current; + } + friend bool operator!=(const primary_base_info_iterator &X, + const primary_base_info_iterator &Y) { + return !(X == Y); + } + }; + +private: + /// CXXRecordLayoutInfo - Contains C++ specific layout information. struct CXXRecordLayoutInfo { /// NonVirtualSize - The non-virtual size (in bits) of an object, which is /// the size of the object without virtual bases. @@ -56,11 +109,9 @@ class ASTRecordLayout { /// which is the alignment of the object without virtual bases. uint64_t NonVirtualAlign; - /// PrimaryBase - The primary base for our vtable. - const CXXRecordDecl *PrimaryBase; - /// PrimaryBase - Wether or not the primary base was a virtual base. - bool PrimaryBaseWasVirtual; - + /// PrimaryBase - The primary base info for this record. + PrimaryBaseInfo PrimaryBase; + /// BaseOffsets - Contains a map from base classes to their offset. /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :) llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsets; @@ -68,6 +119,13 @@ class ASTRecordLayout { /// 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 @@ -92,11 +150,12 @@ class ASTRecordLayout { ASTRecordLayout(uint64_t size, unsigned alignment, uint64_t datasize, const uint64_t *fieldoffsets, unsigned fieldcount, uint64_t nonvirtualsize, unsigned nonvirtualalign, - const CXXRecordDecl *PB, bool PBVirtual, + const PrimaryBaseInfo &PrimaryBase, const std::pair<const CXXRecordDecl *, uint64_t> *bases, unsigned numbases, const std::pair<const CXXRecordDecl *, uint64_t> *vbases, - unsigned numvbases) + unsigned numvbases, + const CXXMethodDecl *KeyFunction) : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment), FieldCount(fieldcount), CXXInfo(new CXXRecordLayoutInfo) { if (FieldCount > 0) { @@ -105,14 +164,14 @@ class ASTRecordLayout { FieldOffsets[i] = fieldoffsets[i]; } - CXXInfo->PrimaryBase = PB; - CXXInfo->PrimaryBaseWasVirtual = PBVirtual; + CXXInfo->PrimaryBase = PrimaryBase; CXXInfo->NonVirtualSize = nonvirtualsize; CXXInfo->NonVirtualAlign = nonvirtualalign; for (unsigned i = 0; i != numbases; ++i) 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() { @@ -162,17 +221,21 @@ public: return CXXInfo->NonVirtualAlign; } - /// getPrimaryBase - Get the primary base. - const CXXRecordDecl *getPrimaryBase() const { + /// getPrimaryBaseInfo - Get the primary base info. + const PrimaryBaseInfo &getPrimaryBaseInfo() const { assert(CXXInfo && "Record layout does not have C++ specific info!"); return CXXInfo->PrimaryBase; } - /// getPrimaryBaseWasVirtual - Indicates if the primary base was virtual. - bool getPrimaryBaseWasVirtual() const { - assert(CXXInfo && "Record layout does not have C++ specific info!"); - return CXXInfo->PrimaryBaseWasVirtual; + // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly. + const CXXRecordDecl *getPrimaryBase() const { + return getPrimaryBaseInfo().getBase(); + } + + // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly. + bool getPrimaryBaseWasVirtual() const { + return getPrimaryBaseInfo().isVirtual(); } /// getBaseClassOffset - Get the offset, in bits, for the given base class. @@ -190,6 +253,25 @@ 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!"); + + return primary_base_info_iterator(getPrimaryBaseInfo()); + } + + primary_base_info_iterator primary_base_end() const { + assert(CXXInfo && "Record layout does not have C++ specific info!"); + + return primary_base_info_iterator(); + } }; } // end namespace clang diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h index 8679323..01f4b29 100644 --- a/include/clang/AST/Redeclarable.h +++ b/include/clang/AST/Redeclarable.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_REDECLARABLE_H #include "llvm/ADT/PointerIntPair.h" +#include "llvm/Support/Casting.h" #include <iterator> namespace clang { @@ -92,6 +93,11 @@ public: } /// \brief Returns the most recent (re)declaration of this declaration. + decl_type *getMostRecentDeclaration() { + return getFirstDeclaration()->RedeclLink.getNext(); + } + + /// \brief Returns the most recent (re)declaration of this declaration. const decl_type *getMostRecentDeclaration() const { return getFirstDeclaration()->RedeclLink.getNext(); } @@ -102,8 +108,11 @@ public: decl_type *First; if (PrevDecl) { - // Point to previous. - RedeclLink = PreviousDeclLink(PrevDecl); + // Point to previous. Make sure that this is actually the most recent + // redeclaration, or we can build invalid chains. If the most recent + // redeclaration is invalid, it won't be PrevDecl, but we want it anyway. + RedeclLink = PreviousDeclLink(llvm::cast<decl_type>( + PrevDecl->getMostRecentDeclaration())); First = PrevDecl->getFirstDeclaration(); assert(First->RedeclLink.NextIsLatest() && "Expected first"); } else { diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 411f215e..d6f6a83 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -171,6 +171,14 @@ public: } virtual ~Stmt() {} +#ifndef NDEBUG + /// \brief True if this statement's refcount is in a valid state. + /// Should be used only in assertions. + bool isRetained() const { + return (RefCount >= 1); + } +#endif + /// \brief Destroy the current statement and its children. void Destroy(ASTContext &Ctx) { assert(RefCount >= 1); @@ -203,7 +211,7 @@ public: // global temp stats (until we have a per-module visitor) static void addStmtClass(const StmtClass s); - static bool CollectingStats(bool enable=false); + static bool CollectingStats(bool Enable = false); static void PrintStats(); /// dump - This does a local dump of the specified AST fragment. It dumps the @@ -604,22 +612,36 @@ public: class IfStmt : public Stmt { enum { COND, THEN, ELSE, END_EXPR }; Stmt* SubExprs[END_EXPR]; + + /// \brief If non-NULL, the declaration in the "if" statement. + VarDecl *Var; + SourceLocation IfLoc; SourceLocation ElseLoc; + public: - IfStmt(SourceLocation IL, Expr *cond, Stmt *then, + IfStmt(SourceLocation IL, VarDecl *Var, Expr *cond, Stmt *then, SourceLocation EL = SourceLocation(), Stmt *elsev = 0) - : Stmt(IfStmtClass) { + : Stmt(IfStmtClass), Var(Var), IfLoc(IL), ElseLoc(EL) { SubExprs[COND] = reinterpret_cast<Stmt*>(cond); SubExprs[THEN] = then; SubExprs[ELSE] = elsev; - IfLoc = IL; - ElseLoc = EL; } /// \brief Build an empty if/then/else statement explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { } + /// \brief Retrieve the variable declared in this "if" statement, if any. + /// + /// In the following example, "x" is the condition variable. + /// \code + /// if (int x = foo()) { + /// printf("x is %d", x); + /// } + /// \endcode + VarDecl *getConditionVariable() const { return Var; } + void setConditionVariable(VarDecl *V) { Var = V; } + const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); } const Stmt *getThen() const { return SubExprs[THEN]; } @@ -658,6 +680,7 @@ public: class SwitchStmt : public Stmt { enum { COND, BODY, END_EXPR }; Stmt* SubExprs[END_EXPR]; + VarDecl *Var; // This points to a linked list of case and default statements. SwitchCase *FirstCase; SourceLocation SwitchLoc; @@ -666,14 +689,28 @@ protected: virtual void DoDestroy(ASTContext &Ctx); public: - SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) { - SubExprs[COND] = reinterpret_cast<Stmt*>(cond); - SubExprs[BODY] = NULL; - } + SwitchStmt(VarDecl *Var, Expr *cond) + : Stmt(SwitchStmtClass), Var(Var), FirstCase(0) + { + SubExprs[COND] = reinterpret_cast<Stmt*>(cond); + SubExprs[BODY] = NULL; + } /// \brief Build a empty switch statement. explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { } + /// \brief Retrieve the variable declared in this "switch" statement, if any. + /// + /// In the following example, "x" is the condition variable. + /// \code + /// switch (int x = foo()) { + /// case 0: break; + /// // ... + /// } + /// \endcode + VarDecl *getConditionVariable() const { return Var; } + void setConditionVariable(VarDecl *V) { Var = V; } + const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} const Stmt *getBody() const { return SubExprs[BODY]; } const SwitchCase *getSwitchCaseList() const { return FirstCase; } @@ -721,10 +758,13 @@ public: /// class WhileStmt : public Stmt { enum { COND, BODY, END_EXPR }; + VarDecl *Var; Stmt* SubExprs[END_EXPR]; SourceLocation WhileLoc; public: - WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) { + WhileStmt(VarDecl *Var, Expr *cond, Stmt *body, SourceLocation WL) + : Stmt(WhileStmtClass), Var(Var) + { SubExprs[COND] = reinterpret_cast<Stmt*>(cond); SubExprs[BODY] = body; WhileLoc = WL; @@ -733,6 +773,17 @@ public: /// \brief Build an empty while statement. explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { } + /// \brief Retrieve the variable declared in this "while" statement, if any. + /// + /// In the following example, "x" is the condition variable. + /// \code + /// while (int x = random()) { + /// // ... + /// } + /// \endcode + VarDecl *getConditionVariable() const { return Var; } + void setConditionVariable(VarDecl *V) { Var = V; } + Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } @@ -812,26 +863,38 @@ public: class ForStmt : public Stmt { enum { INIT, COND, INC, BODY, END_EXPR }; Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. + VarDecl *CondVar; SourceLocation ForLoc; SourceLocation LParenLoc, RParenLoc; public: - ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL, - SourceLocation LP, SourceLocation RP) - : Stmt(ForStmtClass) { + ForStmt(Stmt *Init, Expr *Cond, VarDecl *CondVar, Expr *Inc, Stmt *Body, + SourceLocation FL, SourceLocation LP, SourceLocation RP) + : Stmt(ForStmtClass), CondVar(CondVar), ForLoc(FL), LParenLoc(LP), + RParenLoc(RP) + { SubExprs[INIT] = Init; SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); SubExprs[BODY] = Body; - ForLoc = FL; - LParenLoc = LP; - RParenLoc = RP; } /// \brief Build an empty for statement. explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { } Stmt *getInit() { return SubExprs[INIT]; } + + /// \brief Retrieve the variable declared in this "for" statement, if any. + /// + /// In the following example, "y" is the condition variable. + /// \code + /// for (int x = random(); int y = mangle(x); ++x) { + /// // ... + /// } + /// \endcode + VarDecl *getConditionVariable() const { return CondVar; } + void setConditionVariable(VarDecl *V) { CondVar = V; } + Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } Stmt *getBody() { return SubExprs[BODY]; } diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h index 28fe348..64eea24 100644 --- a/include/clang/AST/StmtCXX.h +++ b/include/clang/AST/StmtCXX.h @@ -42,9 +42,9 @@ public: } SourceLocation getCatchLoc() const { return CatchLoc; } - VarDecl *getExceptionDecl() { return ExceptionDecl; } - QualType getCaughtType(); - Stmt *getHandlerBlock() { return HandlerBlock; } + VarDecl *getExceptionDecl() const { return ExceptionDecl; } + QualType getCaughtType() const; + Stmt *getHandlerBlock() const { return HandlerBlock; } static bool classof(const Stmt *T) { return T->getStmtClass() == CXXCatchStmtClass; diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def index 034029a..7102336 100644 --- a/include/clang/AST/StmtNodes.def +++ b/include/clang/AST/StmtNodes.def @@ -121,20 +121,19 @@ EXPR(CXXThisExpr , Expr) EXPR(CXXThrowExpr , Expr) EXPR(CXXDefaultArgExpr , Expr) EXPR(CXXZeroInitValueExpr , Expr) -EXPR(CXXConditionDeclExpr , DeclRefExpr) EXPR(CXXNewExpr , Expr) EXPR(CXXDeleteExpr , Expr) EXPR(CXXPseudoDestructorExpr, Expr) -EXPR(UnresolvedFunctionNameExpr , Expr) +EXPR(UnresolvedLookupExpr , Expr) EXPR(UnaryTypeTraitExpr , Expr) -EXPR(UnresolvedDeclRefExpr , Expr) -EXPR(TemplateIdRefExpr , Expr) +EXPR(DependentScopeDeclRefExpr , Expr) EXPR(CXXConstructExpr , Expr) EXPR(CXXBindTemporaryExpr , Expr) EXPR(CXXExprWithTemporaries , Expr) EXPR(CXXTemporaryObjectExpr , CXXConstructExpr) EXPR(CXXUnresolvedConstructExpr, Expr) -EXPR(CXXUnresolvedMemberExpr, Expr) +EXPR(CXXDependentScopeMemberExpr, Expr) +EXPR(UnresolvedMemberExpr , Expr) // Obj-C Expressions. EXPR(ObjCStringLiteral , Expr) diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index 6db0958..b46b3dc 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_AST_TEMPLATEBASE_H #include "llvm/ADT/APSInt.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/ErrorHandling.h" #include "clang/AST/Type.h" #include "clang/AST/TemplateName.h" @@ -437,6 +438,41 @@ public: } }; +/// A convenient class for passing around template argument +/// information. Designed to be passed by reference. +class TemplateArgumentListInfo { + llvm::SmallVector<TemplateArgumentLoc, 8> Arguments; + SourceLocation LAngleLoc; + SourceLocation RAngleLoc; + +public: + TemplateArgumentListInfo() {} + + TemplateArgumentListInfo(SourceLocation LAngleLoc, + SourceLocation RAngleLoc) + : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {} + + SourceLocation getLAngleLoc() const { return LAngleLoc; } + SourceLocation getRAngleLoc() const { return RAngleLoc; } + + void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; } + void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; } + + unsigned size() const { return Arguments.size(); } + + const TemplateArgumentLoc *getArgumentArray() const { + return Arguments.data(); + } + + const TemplateArgumentLoc &operator[](unsigned I) const { + return Arguments[I]; + } + + void addArgument(const TemplateArgumentLoc &Loc) { + Arguments.push_back(Loc); + } +}; + } #endif diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index c28bafe..349487f 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -82,6 +82,7 @@ namespace clang { class StmtIteratorBase; class TemplateArgument; class TemplateArgumentLoc; + class TemplateArgumentListInfo; class QualifiedNameType; struct PrintingPolicy; @@ -859,6 +860,7 @@ public: bool isObjCQualifiedClassType() const; // Class<foo> bool isObjCIdType() const; // id bool isObjCClassType() const; // Class + bool isObjCSelType() const; // Class bool isObjCBuiltinType() const; // 'id' or 'Class' bool isTemplateTypeParmType() const; // C++ template type parameter bool isNullPtrType() const; // C++0x nullptr_t @@ -1000,7 +1002,8 @@ public: UndeducedAuto, // In C++0x, this represents the type of an auto variable // that has not been deduced yet. ObjCId, // This represents the ObjC 'id' type. - ObjCClass // This represents the ObjC 'Class' type. + ObjCClass, // This represents the ObjC 'Class' type. + ObjCSel // This represents the ObjC 'SEL' type. }; private: Kind TypeKind; @@ -1457,21 +1460,27 @@ public: /// DependentSizedArrayType - This type represents an array type in /// C++ whose size is a value-dependent expression. For example: -/// @code +/// +/// \code /// template<typename T, int Size> /// class array { /// T data[Size]; /// }; -/// @endcode +/// \endcode +/// /// For these types, we won't actually know what the array bound is /// until template instantiation occurs, at which point this will /// become either a ConstantArrayType or a VariableArrayType. class DependentSizedArrayType : public ArrayType { ASTContext &Context; - /// SizeExpr - An assignment expression that will instantiate to the + /// \brief An assignment expression that will instantiate to the /// size of the array. + /// + /// The expression itself might be NULL, in which case the array + /// type will have its size deduced from an initializer. Stmt *SizeExpr; + /// Brackets - The left and right array brackets. SourceRange Brackets; @@ -2272,6 +2281,8 @@ public: static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned NumArgs); + static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &); + /// \brief Print a template argument list, including the '<' and '>' /// enclosing the template arguments. static std::string PrintTemplateArgumentList(const TemplateArgument *Args, @@ -2282,6 +2293,9 @@ public: unsigned NumArgs, const PrintingPolicy &Policy); + static std::string PrintTemplateArgumentList(const TemplateArgumentListInfo &, + const PrintingPolicy &Policy); + typedef const TemplateArgument * iterator; iterator begin() const { return getArgs(); } @@ -2534,6 +2548,7 @@ public: return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) && !Protocols.size(); } + /// isObjCQualifiedIdType - true for "id <p>". bool isObjCQualifiedIdType() const { return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) && @@ -2881,8 +2896,13 @@ inline bool Type::isObjCClassType() const { return OPT->isObjCClassType(); return false; } +inline bool Type::isObjCSelType() const { + if (const PointerType *OPT = getAs<PointerType>()) + return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel); + return false; +} inline bool Type::isObjCBuiltinType() const { - return isObjCIdType() || isObjCClassType(); + return isObjCIdType() || isObjCClassType() || isObjCSelType(); } inline bool Type::isTemplateTypeParmType() const { return isa<TemplateTypeParmType>(CanonicalType); |