diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-05-27 15:17:06 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-05-27 15:17:06 +0000 |
commit | 53992adde3eda3ccf9da63bc7e45673f043de18f (patch) | |
tree | 3558f327a6f9ab59c5d7a06528d84e1560445247 /include/clang | |
parent | 7e411337c0ed226dace6e07f1420486768161308 (diff) | |
download | FreeBSD-src-53992adde3eda3ccf9da63bc7e45673f043de18f.zip FreeBSD-src-53992adde3eda3ccf9da63bc7e45673f043de18f.tar.gz |
Update clang to r104832.
Diffstat (limited to 'include/clang')
77 files changed, 3233 insertions, 722 deletions
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h index 53bb785..0611395 100644 --- a/include/clang/AST/ASTConsumer.h +++ b/include/clang/AST/ASTConsumer.h @@ -16,6 +16,7 @@ namespace clang { class ASTContext; + class CXXRecordDecl; class DeclGroupRef; class TagDecl; class HandleTagDeclDefinition; @@ -68,6 +69,17 @@ public: /// modified by the introduction of an implicit zero initializer. virtual void CompleteTentativeDefinition(VarDecl *D) {} + /// \brief Callback involved at the end of a translation unit to + /// notify the consumer that a vtable for the given C++ class is + /// required. + /// + /// \param RD The class whose vtable was used. + /// + /// \param DefinitionRequired Whether a definition of this vtable is + /// required in this translation unit; otherwise, it is only needed if + /// it was actually used. + virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {} + /// PrintStats - If desired, print any statistics. virtual void PrintStats() {} diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index f8a8f17..87a12cde 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -96,11 +96,10 @@ class ASTContext { llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes; llvm::FoldingSet<SubstTemplateTypeParmType> SubstTemplateTypeParmTypes; llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes; - llvm::FoldingSet<QualifiedNameType> QualifiedNameTypes; + llvm::FoldingSet<ElaboratedType> ElaboratedTypes; llvm::FoldingSet<DependentNameType> DependentNameTypes; - llvm::FoldingSet<ObjCInterfaceType> ObjCInterfaceTypes; + llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes; llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes; - llvm::FoldingSet<ElaboratedType> ElaboratedTypes; llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames; llvm::FoldingSet<DependentTemplateName> DependentTemplateNames; @@ -483,7 +482,7 @@ public: /// This gets the struct used to keep track of pointer to blocks, complete /// with captured variables. QualType getBlockParmType(bool BlockHasCopyDispose, - llvm::SmallVector<const Expr *, 8> &BDRDs); + llvm::SmallVectorImpl<const Expr *> &Layout); /// This builds the struct used for __block variables. QualType BuildByRefType(const char *DeclName, QualType Ty); @@ -613,8 +612,9 @@ public: const TemplateArgumentListInfo &Args, QualType Canon = QualType()); - QualType getQualifiedNameType(NestedNameSpecifier *NNS, - QualType NamedType); + QualType getElaboratedType(ElaboratedTypeKeyword Keyword, + NestedNameSpecifier *NNS, + QualType NamedType); QualType getDependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, @@ -623,19 +623,16 @@ public: NestedNameSpecifier *NNS, const TemplateSpecializationType *TemplateId, QualType Canon = QualType()); - QualType getElaboratedType(QualType UnderlyingType, - ElaboratedType::TagKind Tag); - QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, - ObjCProtocolDecl **Protocols = 0, - unsigned NumProtocols = 0); + QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl); + + QualType getObjCObjectType(QualType Base, + ObjCProtocolDecl * const *Protocols, + unsigned NumProtocols); - /// getObjCObjectPointerType - Return a ObjCObjectPointerType type for the - /// given interface decl and the conforming protocol list. - QualType getObjCObjectPointerType(QualType OIT, - ObjCProtocolDecl **ProtocolList = 0, - unsigned NumProtocols = 0, - unsigned Quals = 0); + /// getObjCObjectPointerType - Return a ObjCObjectPointerType type + /// for the given ObjCObjectType. + QualType getObjCObjectPointerType(QualType OIT); /// getTypeOfType - GCC extension. QualType getTypeOfExprType(Expr *e); @@ -913,6 +910,9 @@ public: CharUnits getTypeAlignInChars(QualType T); CharUnits getTypeAlignInChars(const Type *T); + std::pair<CharUnits, CharUnits> getTypeInfoInChars(const Type *T); + std::pair<CharUnits, CharUnits> getTypeInfoInChars(QualType T); + /// getPreferredTypeAlign - Return the "preferred" alignment of the specified /// type for the current target in bits. This can be different than the ABI /// alignment in cases where it is beneficial for performance to overalign @@ -1184,8 +1184,8 @@ public: // Check the safety of assignment from LHS to RHS bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT); - bool canAssignObjCInterfaces(const ObjCInterfaceType *LHS, - const ObjCInterfaceType *RHS); + bool canAssignObjCInterfaces(const ObjCObjectType *LHS, + const ObjCObjectType *RHS); bool canAssignObjCInterfacesInBlockPointer( const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT); @@ -1196,6 +1196,8 @@ public: // Functions for calculating composite types QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false); QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false); + + QualType mergeObjCGCQualifiers(QualType, QualType); /// UsualArithmeticConversionsType - handles the various conversions /// that are common to binary operators (C99 6.3.1.8, C++ [expr]p9) @@ -1270,6 +1272,15 @@ public: TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc = SourceLocation()); + /// \brief Add a deallocation callback that will be invoked when the + /// ASTContext is destroyed. + /// + /// \brief Callback A callback function that will be invoked on destruction. + /// + /// \brief Data Pointer data that will be provided to the callback function + /// when it is called. + void AddDeallocation(void (*Callback)(void*), void *Data); + private: ASTContext(const ASTContext&); // DO NOT IMPLEMENT void operator=(const ASTContext&); // DO NOT IMPLEMENT @@ -1284,16 +1295,21 @@ private: const FieldDecl *Field, bool OutermostType = false, bool EncodingProperty = false); - + const ASTRecordLayout &getObjCLayout(const ObjCInterfaceDecl *D, const ObjCImplementationDecl *Impl); private: + /// \brief A set of deallocations that should be performed when the + /// ASTContext is destroyed. + llvm::SmallVector<std::pair<void (*)(void*), void *>, 16> Deallocations; + // FIXME: This currently contains the set of StoredDeclMaps used // by DeclContext objects. This probably should not be in ASTContext, // but we include it here so that ASTContext can quickly deallocate them. llvm::PointerIntPair<StoredDeclsMap*,1> LastSDM; friend class DeclContext; + friend class DeclarationNameTable; void ReleaseDeclContextMaps(); }; diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 1974493..3240e50 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -23,9 +23,10 @@ using llvm::dyn_cast; namespace clang { class ASTContext; + class IdentifierInfo; + class ObjCInterfaceDecl; } - // Defined in ASTContext.h void *operator new(size_t Bytes, clang::ASTContext &C, size_t Alignment = 16) throw (); @@ -44,6 +45,7 @@ public: enum Kind { Alias, Aligned, + AlignMac68k, AlwaysInline, AnalyzerNoReturn, // Clang-specific. Annotate, @@ -63,8 +65,10 @@ public: GNUInline, Hiding, IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro. + IBOutletCollectionKind, // Clang-specific. IBActionKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro. Malloc, + MaxFieldAlignment, NoDebug, NoInline, NonNull, @@ -79,13 +83,13 @@ public: NSReturnsNotRetained, // Clang/Checker-specific. Overloadable, // Clang-specific Packed, - PragmaPack, Pure, Regparm, ReqdWorkGroupSize, // OpenCL-specific Section, Sentinel, StdCall, + ThisCall, TransparentUnion, Unavailable, Unused, @@ -183,11 +187,14 @@ public: \ DEF_SIMPLE_ATTR(Packed); -class PragmaPackAttr : public Attr { +/// \brief Attribute for specifying a maximum field alignment; this is only +/// valid on record decls. +class MaxFieldAlignmentAttr : public Attr { unsigned Alignment; public: - PragmaPackAttr(unsigned alignment) : Attr(PragmaPack), Alignment(alignment) {} + MaxFieldAlignmentAttr(unsigned alignment) + : Attr(MaxFieldAlignment), Alignment(alignment) {} /// getAlignment - The specified alignment in bits. unsigned getAlignment() const { return Alignment; } @@ -196,11 +203,13 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { - return A->getKind() == PragmaPack; + return A->getKind() == MaxFieldAlignment; } - static bool classof(const PragmaPackAttr *A) { return true; } + static bool classof(const MaxFieldAlignmentAttr *A) { return true; } }; +DEF_SIMPLE_ATTR(AlignMac68k); + class AlignedAttr : public Attr { unsigned Alignment; public: @@ -317,6 +326,23 @@ public: static bool classof(const IBOutletAttr *A) { return true; } }; +class IBOutletCollectionAttr : public Attr { + const ObjCInterfaceDecl *D; +public: + IBOutletCollectionAttr(const ObjCInterfaceDecl *d = 0) + : Attr(IBOutletCollectionKind), D(d) {} + + const ObjCInterfaceDecl *getClass() const { return D; } + + virtual Attr *clone(ASTContext &C) const; + + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *A) { + return A->getKind() == IBOutletCollectionKind; + } + static bool classof(const IBOutletCollectionAttr *A) { return true; } +}; + class IBActionAttr : public Attr { public: IBActionAttr() : Attr(IBActionKind) {} @@ -457,6 +483,7 @@ public: DEF_SIMPLE_ATTR(FastCall); DEF_SIMPLE_ATTR(StdCall); +DEF_SIMPLE_ATTR(ThisCall); DEF_SIMPLE_ATTR(CDecl); DEF_SIMPLE_ATTR(TransparentUnion); DEF_SIMPLE_ATTR(ObjCNSObject); diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt new file mode 100644 index 0000000..c24ea06 --- /dev/null +++ b/include/clang/AST/CMakeLists.txt @@ -0,0 +1,5 @@ +set(LLVM_TARGET_DEFINITIONS StmtNodes.td) +tablegen(StmtNodes.inc + -gen-clang-stmt-nodes) +add_custom_target(ClangStmtNodes + DEPENDS StmtNodes.inc) diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h index edd633e..5a84e40 100644 --- a/include/clang/AST/CXXInheritance.h +++ b/include/clang/AST/CXXInheritance.h @@ -196,7 +196,7 @@ public: /// \brief Determine whether the path from the most-derived type to the /// given base type is ambiguous (i.e., it refers to multiple subobjects of /// the same base type). - bool isAmbiguous(QualType BaseType); + bool isAmbiguous(CanQualType BaseType); /// \brief Whether we are finding multiple paths to detect ambiguities. bool isFindingAmbiguities() const { return FindAmbiguities; } diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index 93dcad7..4afb81d 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -643,6 +643,24 @@ struct CanProxyAdaptor<TemplateTypeParmType> }; template<> +struct CanProxyAdaptor<ObjCObjectType> + : public CanProxyBase<ObjCObjectType> { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *, + getInterface) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass) + + typedef ObjCObjectPointerType::qual_iterator qual_iterator; + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols) +}; + +template<> struct CanProxyAdaptor<ObjCObjectPointerType> : public CanProxyBase<ObjCObjectPointerType> { LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 834c9a0..7d5b66e 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -55,7 +55,7 @@ public: QualType getType() const { return Ty; } /// \brief Return the TypeLoc wrapper for the type source info. - TypeLoc getTypeLoc() const; + TypeLoc getTypeLoc() const; // implemented in TypeLoc.h }; /// TranslationUnitDecl - The top declaration context. @@ -138,6 +138,8 @@ public: // FIXME: Deprecated, move clients to getName(). std::string getNameAsString() const { return Name.getAsString(); } + void printName(llvm::raw_ostream &os) const { return Name.printName(os); } + /// getDeclName - Get the actual, stored name of the declaration, /// which may be a special name. DeclarationName getDeclName() const { return Name; } @@ -265,18 +267,25 @@ public: // \brief Returns true if this is an anonymous namespace declaration. // // For example: + /// \code // namespace { // ... // }; + // \endcode // q.v. C++ [namespace.unnamed] bool isAnonymousNamespace() const { return !getIdentifier(); } + /// \brief Return the next extended namespace declaration or null if this + /// is none. NamespaceDecl *getNextNamespace() { return NextNamespace; } const NamespaceDecl *getNextNamespace() const { return NextNamespace; } + + /// \brief Set the next extended namespace declaration. void setNextNamespace(NamespaceDecl *ND) { NextNamespace = ND; } + /// \brief Get the original (first) namespace declaration. NamespaceDecl *getOriginalNamespace() const { if (OrigOrAnonNamespace.getInt()) return const_cast<NamespaceDecl *>(this); @@ -284,6 +293,14 @@ public: return OrigOrAnonNamespace.getPointer(); } + /// \brief Return true if this declaration is an original (first) declaration + /// of the namespace. This is false for non-original (subsequent) namespace + /// declarations and anonymous namespaces. + bool isOriginalNamespace() const { + return getOriginalNamespace() == this; + } + + /// \brief Set the original (first) namespace declaration. void setOriginalNamespace(NamespaceDecl *ND) { if (ND != this) { OrigOrAnonNamespace.setPointer(ND); @@ -502,6 +519,10 @@ private: /// or an Objective-C @catch statement. bool ExceptionVar : 1; + /// \brief Whether this local variable could be allocated in the return + /// slot of its function, enabling the named return value optimization (NRVO). + bool NRVOVariable : 1; + friend class StmtIteratorBase; protected: VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, @@ -509,7 +530,7 @@ protected: StorageClass SCAsWritten) : DeclaratorDecl(DK, DC, L, Id, T, TInfo), Init(), ThreadSpecified(false), HasCXXDirectInit(false), - DeclaredInCondition(false), ExceptionVar(false) { + DeclaredInCondition(false), ExceptionVar(false), NRVOVariable(false) { SClass = SC; SClassAsWritten = SCAsWritten; } @@ -852,6 +873,19 @@ public: } void setExceptionVariable(bool EV) { ExceptionVar = EV; } + /// \brief Determine whether this local variable can be used with the named + /// return value optimization (NRVO). + /// + /// The named return value optimization (NRVO) works by marking certain + /// non-volatile local variables of class type as NRVO objects. These + /// locals can be allocated within the return slot of their containing + /// function, in which case there is no need to copy the object to the + /// return slot when returning from the function. Within the function body, + /// each return that returns the NRVO object will have this variable as its + /// NRVO candidate. + bool isNRVOVariable() const { return NRVOVariable; } + void setNRVOVariable(bool NRVO) { NRVOVariable = NRVO; } + /// \brief If this variable is an instantiated static data member of a /// class template specialization, returns the templated static data member /// from which it was instantiated. @@ -1390,6 +1424,16 @@ public: /// returns NULL. const TemplateArgumentList *getTemplateSpecializationArgs() const; + /// \brief Retrieve the template argument list as written in the sources, + /// if any. + /// + /// If this function declaration is not a function template specialization + /// or if it had no explicit template argument list, returns NULL. + /// Note that it an explicit template argument list may be written empty, + /// e.g., template<> void foo<>(char* s); + const TemplateArgumentListInfo* + getTemplateSpecializationArgsAsWritten() const; + /// \brief Specify that this function declaration is actually a function /// template specialization. /// @@ -1409,7 +1453,8 @@ public: void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template, const TemplateArgumentList *TemplateArgs, void *InsertPos, - TemplateSpecializationKind TSK = TSK_ImplicitInstantiation); + TemplateSpecializationKind TSK = TSK_ImplicitInstantiation, + const TemplateArgumentListInfo *TemplateArgsAsWritten = 0); /// \brief Specifies that this function declaration is actually a /// dependent function template specialization. @@ -1593,7 +1638,19 @@ class TypedefDecl : public TypeDecl, public Redeclarable<TypedefDecl> { : TypeDecl(Typedef, DC, L, Id), TInfo(TInfo) {} virtual ~TypedefDecl(); + +protected: + typedef Redeclarable<TypedefDecl> redeclarable_base; + virtual TypedefDecl *getNextRedeclaration() { return RedeclLink.getNext(); } + public: + typedef redeclarable_base::redecl_iterator redecl_iterator; + redecl_iterator redecls_begin() const { + return redeclarable_base::redecls_begin(); + } + redecl_iterator redecls_end() const { + return redeclarable_base::redecls_end(); + } static TypedefDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, @@ -1631,11 +1688,7 @@ class TagDecl : public TypeDecl, public DeclContext, public Redeclarable<TagDecl> { public: // This is really ugly. - typedef ElaboratedType::TagKind TagKind; - static const TagKind TK_struct = ElaboratedType::TK_struct; - static const TagKind TK_union = ElaboratedType::TK_union; - static const TagKind TK_class = ElaboratedType::TK_class; - static const TagKind TK_enum = ElaboratedType::TK_enum; + typedef TagTypeKind TagKind; private: // FIXME: This can be packed into the bitfields in Decl. @@ -1651,6 +1704,12 @@ private: /// in the syntax of a declarator. bool IsEmbeddedInDeclarator : 1; +protected: + // These are used by (and only defined for) EnumDecl. + unsigned NumPositiveBits : 8; + unsigned NumNegativeBits : 8; + +private: SourceLocation TagKeywordLoc; SourceLocation RBraceLoc; @@ -1680,7 +1739,8 @@ protected: TagDecl *PrevDecl, SourceLocation TKL = SourceLocation()) : TypeDecl(DK, DC, L, Id), DeclContext(DK), TagKeywordLoc(TKL), TypedefDeclOrQualifier((TypedefDecl*) 0) { - assert((DK != Enum || TK == TK_enum) &&"EnumDecl not matched with TK_enum"); + assert((DK != Enum || TK == TTK_Enum) && + "EnumDecl not matched with TTK_Enum"); TagDeclKind = TK; IsDefinition = false; IsEmbeddedInDeclarator = false; @@ -1753,30 +1813,26 @@ public: void setDefinition(bool V) { IsDefinition = V; } const char *getKindName() const { - return ElaboratedType::getNameForTagKind(getTagKind()); + return TypeWithKeyword::getTagTypeKindName(getTagKind()); } - /// getTagKindForTypeSpec - Converts a type specifier (DeclSpec::TST) - /// into a tag kind. It is an error to provide a type specifier - /// which *isn't* a tag kind here. - static TagKind getTagKindForTypeSpec(unsigned TypeSpec); - TagKind getTagKind() const { return TagKind(TagDeclKind); } void setTagKind(TagKind TK) { TagDeclKind = TK; } - bool isStruct() const { return getTagKind() == TK_struct; } - bool isClass() const { return getTagKind() == TK_class; } - bool isUnion() const { return getTagKind() == TK_union; } - bool isEnum() const { return getTagKind() == TK_enum; } + bool isStruct() const { return getTagKind() == TTK_Struct; } + bool isClass() const { return getTagKind() == TTK_Class; } + bool isUnion() const { return getTagKind() == TTK_Union; } + bool isEnum() const { return getTagKind() == TTK_Enum; } TypedefDecl *getTypedefForAnonDecl() const { return hasExtInfo() ? 0 : TypedefDeclOrQualifier.get<TypedefDecl*>(); } - void setTypedefForAnonDecl(TypedefDecl *TDD) { TypedefDeclOrQualifier = TDD; } - + + void setTypedefForAnonDecl(TypedefDecl *TDD); + NestedNameSpecifier *getQualifier() const { return hasExtInfo() ? TypedefDeclOrQualifier.get<ExtInfo*>()->NNS : 0; } @@ -1820,9 +1876,16 @@ class EnumDecl : public TagDecl { /// enumeration declared within the template. EnumDecl *InstantiatedFrom; + // The number of positive and negative bits required by the + // enumerators are stored in the SubclassBits field. + enum { + NumBitsWidth = 8, + NumBitsMask = (1 << NumBitsWidth) - 1 + }; + EnumDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, EnumDecl *PrevDecl, SourceLocation TKL) - : TagDecl(Enum, TK_enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) { + : TagDecl(Enum, TTK_Enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) { IntegerType = QualType(); } public: @@ -1845,7 +1908,9 @@ public: /// added (via DeclContext::addDecl). NewType is the new underlying /// type of the enumeration type. void completeDefinition(QualType NewType, - QualType PromotionType); + QualType PromotionType, + unsigned NumPositiveBits, + unsigned NumNegativeBits); // enumerator_iterator - Iterates through the enumerators of this // enumeration. @@ -1873,6 +1938,32 @@ public: /// \brief Set the underlying integer type. void setIntegerType(QualType T) { IntegerType = T; } + /// \brief Returns the width in bits requred to store all the + /// non-negative enumerators of this enum. + unsigned getNumPositiveBits() const { + return NumPositiveBits; + } + void setNumPositiveBits(unsigned Num) { + NumPositiveBits = Num; + assert(NumPositiveBits == Num && "can't store this bitcount"); + } + + /// \brief Returns the width in bits requred to store all the + /// negative enumerators of this enum. These widths include + /// the rightmost leading 1; that is: + /// + /// MOST NEGATIVE ENUMERATOR PATTERN NUM NEGATIVE BITS + /// ------------------------ ------- ----------------- + /// -1 1111111 1 + /// -10 1110110 5 + /// -101 1001011 8 + unsigned getNumNegativeBits() const { + return NumNegativeBits; + } + void setNumNegativeBits(unsigned Num) { + NumNegativeBits = Num; + } + /// \brief Returns the enumeration (declared within the template) /// from which this enumeration type was instantiated, or NULL if /// this enumeration was not instantiated from any template. @@ -1942,6 +2033,11 @@ public: AnonymousStructOrUnion = Anon; } + ValueDecl *getAnonymousStructOrUnionObject(); + const ValueDecl *getAnonymousStructOrUnionObject() const { + return const_cast<RecordDecl*>(this)->getAnonymousStructOrUnionObject(); + } + bool hasObjectMember() const { return HasObjectMember; } void setHasObjectMember (bool val) { HasObjectMember = val; } diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index a9b948e..c15aeef 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -76,6 +76,11 @@ public: #include "clang/AST/DeclNodes.def" }; + /// \brief A placeholder type used to construct an empty shell of a + /// decl-derived type that will be filled in later (e.g., by some + /// deserialization method). + struct EmptyShell { }; + /// IdentifierNamespace - The different namespaces in which /// declarations may appear. According to C99 6.2.3, there are /// four namespaces, labels, tags, members and ordinary diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index aa649c8..c19c200 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -1061,10 +1061,6 @@ class CXXBaseOrMemberInitializer { /// In above example, BaseOrMember holds the field decl. for anonymous union /// and AnonUnionMember holds field decl for au_i1. FieldDecl *AnonUnionMember; - - /// IsVirtual - If the initializer is a base initializer, this keeps track - /// of whether the base is virtual or not. - bool IsVirtual; /// LParenLoc - Location of the left paren of the ctor-initializer. SourceLocation LParenLoc; @@ -1072,6 +1068,28 @@ class CXXBaseOrMemberInitializer { /// RParenLoc - Location of the right paren of the ctor-initializer. SourceLocation RParenLoc; + /// IsVirtual - If the initializer is a base initializer, this keeps track + /// of whether the base is virtual or not. + bool IsVirtual : 1; + + /// IsWritten - Whether or not the initializer is explicitly written + /// in the sources. + bool IsWritten : 1; + /// SourceOrderOrNumArrayIndices - If IsWritten is true, then this + /// number keeps track of the textual order of this initializer in the + /// original sources, counting from 0; otherwise, if IsWritten is false, + /// it stores the number of array index variables stored after this + /// object in memory. + unsigned SourceOrderOrNumArrayIndices : 14; + + CXXBaseOrMemberInitializer(ASTContext &Context, + FieldDecl *Member, SourceLocation MemberLoc, + SourceLocation L, + Expr *Init, + SourceLocation R, + VarDecl **Indices, + unsigned NumIndices); + public: /// CXXBaseOrMemberInitializer - Creates a new base-class initializer. explicit @@ -1089,6 +1107,17 @@ public: Expr *Init, SourceLocation R); + /// \brief Creates a new member initializer that optionally contains + /// array indices used to describe an elementwise initialization. + static CXXBaseOrMemberInitializer *Create(ASTContext &Context, + FieldDecl *Member, + SourceLocation MemberLoc, + SourceLocation L, + Expr *Init, + SourceLocation R, + VarDecl **Indices, + unsigned NumIndices); + /// \brief Destroy the base or member initializer. void Destroy(ASTContext &Context); @@ -1146,6 +1175,30 @@ public: /// \brief Determine the source range covering the entire initializer. SourceRange getSourceRange() const; + + /// isWritten - Returns true if this initializer is explicitly written + /// in the source code. + bool isWritten() const { return IsWritten; } + + /// \brief Return the source position of the initializer, counting from 0. + /// If the initializer was implicit, -1 is returned. + int getSourceOrder() const { + return IsWritten ? static_cast<int>(SourceOrderOrNumArrayIndices) : -1; + } + + /// \brief Set the source order of this initializer. This method can only + /// be called once for each initializer; it cannot be called on an + /// initializer having a positive number of (implicit) array indices. + void setSourceOrder(int pos) { + assert(!IsWritten && + "calling twice setSourceOrder() on the same initializer"); + assert(SourceOrderOrNumArrayIndices == 0 && + "setSourceOrder() used when there are implicit array indices"); + assert(pos >= 0 && + "setSourceOrder() used to make an initializer implicit"); + IsWritten = true; + SourceOrderOrNumArrayIndices = static_cast<unsigned>(pos); + } FieldDecl *getAnonUnionMember() const { return AnonUnionMember; @@ -1154,9 +1207,31 @@ public: AnonUnionMember = anonMember; } + SourceLocation getLParenLoc() const { return LParenLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } + /// \brief Determine the number of implicit array indices used while + /// described an array member initialization. + unsigned getNumArrayIndices() const { + return IsWritten ? 0 : SourceOrderOrNumArrayIndices; + } + + /// \brief Retrieve a particular array index variable used to + /// describe an array member initialization. + VarDecl *getArrayIndex(unsigned I) { + assert(I < getNumArrayIndices() && "Out of bounds member array index"); + return reinterpret_cast<VarDecl **>(this + 1)[I]; + } + const VarDecl *getArrayIndex(unsigned I) const { + assert(I < getNumArrayIndices() && "Out of bounds member array index"); + return reinterpret_cast<const VarDecl * const *>(this + 1)[I]; + } + void setArrayIndex(unsigned I, VarDecl *Index) { + assert(I < getNumArrayIndices() && "Out of bounds member array index"); + reinterpret_cast<VarDecl **>(this + 1)[I] = Index; + } + Expr *getInit() { return static_cast<Expr *>(Init); } }; @@ -1201,6 +1276,7 @@ class CXXConstructorDecl : public CXXMethodDecl { virtual void Destroy(ASTContext& C); public: + static CXXConstructorDecl *Create(ASTContext &C, EmptyShell Empty); static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, @@ -1343,6 +1419,7 @@ class CXXDestructorDecl : public CXXMethodDecl { } public: + static CXXDestructorDecl *Create(ASTContext& C, EmptyShell Empty); static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation L, DeclarationName N, QualType T, bool isInline, @@ -1398,6 +1475,7 @@ class CXXConversionDecl : public CXXMethodDecl { IsExplicitSpecified(isExplicitSpecified) { } public: + static CXXConversionDecl *Create(ASTContext &C, EmptyShell Empty); static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, @@ -1438,8 +1516,10 @@ public: /// ASTs and cannot be changed without altering that abi. To help /// ensure a stable abi for this, we choose the DW_LANG_ encodings /// from the dwarf standard. - enum LanguageIDs { lang_c = /* DW_LANG_C */ 0x0002, - lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004 }; + enum LanguageIDs { + lang_c = /* DW_LANG_C */ 0x0002, + lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004 + }; private: /// Language - The language for this linkage specification. LanguageIDs Language; @@ -1457,12 +1537,20 @@ public: SourceLocation L, LanguageIDs Lang, bool Braces); + /// \brief Return the language specified by this linkage specification. LanguageIDs getLanguage() const { return Language; } - /// hasBraces - Determines whether this linkage specification had - /// braces in its syntactic form. + /// \brief Set the language specified by this linkage specification. + void setLanguage(LanguageIDs L) { Language = L; } + + /// \brief Determines whether this linkage specification had braces in + /// its syntactic form. bool hasBraces() const { return HadBraces; } + /// \brief Set whether this linkage specification has braces in its + /// syntactic form. + void setHasBraces(bool B) { HadBraces = B; } + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const LinkageSpecDecl *D) { return true; } static bool classofKind(Kind K) { return K == LinkageSpec; } @@ -1528,13 +1616,21 @@ class UsingDirectiveDecl : public NamedDecl { public: /// \brief Retrieve the source range of the nested-name-specifier - /// that qualifiers the namespace name. + /// that qualifies the namespace name. SourceRange getQualifierRange() const { return QualifierRange; } + /// \brief Set the source range of the nested-name-specifier that + /// qualifies the namespace name. + void setQualifierRange(SourceRange R) { QualifierRange = R; } + /// \brief Retrieve the nested-name-specifier that qualifies the /// name of the namespace. NestedNameSpecifier *getQualifier() const { return Qualifier; } + /// \brief Set the nested-name-specifier that qualifes the name of the + /// namespace. + void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; } + NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; } const NamedDecl *getNominatedNamespaceAsWritten() const { return NominatedNamespace; @@ -1547,17 +1643,32 @@ public: return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace(); } - /// getCommonAncestor - returns common ancestor context of using-directive, - /// and nominated by it namespace. + /// setNominatedNamespace - Set the namespace nominataed by the + /// using-directive. + void setNominatedNamespace(NamedDecl* NS); + + /// \brief Returns the common ancestor context of this using-directive and + /// its nominated namespace. DeclContext *getCommonAncestor() { return CommonAncestor; } const DeclContext *getCommonAncestor() const { return CommonAncestor; } + /// \brief Set the common ancestor context of this using-directive and its + /// nominated namespace. + void setCommonAncestor(DeclContext* Cxt) { CommonAncestor = Cxt; } + + // FIXME: Could omit 'Key' in name. /// getNamespaceKeyLocation - Returns location of namespace keyword. SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; } + /// setNamespaceKeyLocation - Set the the location of the namespacekeyword. + void setNamespaceKeyLocation(SourceLocation L) { NamespaceLoc = L; } + /// getIdentLocation - Returns location of identifier. SourceLocation getIdentLocation() const { return IdentLoc; } + /// setIdentLocation - set the location of the identifier. + void setIdentLocation(SourceLocation L) { IdentLoc = L; } + static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, SourceLocation NamespaceLoc, @@ -1591,7 +1702,7 @@ class NamespaceAliasDecl : public NamedDecl { /// name, if any. NestedNameSpecifier *Qualifier; - /// IdentLoc - Location of namespace identifier. + /// IdentLoc - Location of namespace identifier. Accessed by TargetNameLoc. SourceLocation IdentLoc; /// Namespace - The Decl that this alias points to. Can either be a @@ -1612,10 +1723,19 @@ public: /// that qualifiers the namespace name. SourceRange getQualifierRange() const { return QualifierRange; } + /// \brief Set the source range of the nested-name-specifier that qualifies + /// the namespace name. + void setQualifierRange(SourceRange R) { QualifierRange = R; } + /// \brief Retrieve the nested-name-specifier that qualifies the /// name of the namespace. NestedNameSpecifier *getQualifier() const { return Qualifier; } + /// \brief Set the nested-name-specifier that qualifies the name of the + /// namespace. + void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; } + + /// \brief Retrieve the namespace declaration aliased by this directive. NamespaceDecl *getNamespace() { if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(Namespace)) return AD->getNamespace(); @@ -1631,16 +1751,31 @@ public: /// "namespace foo = ns::bar;". SourceLocation getAliasLoc() const { return AliasLoc; } + /// Set the location o;f the alias name, e.e., 'foo' in + /// "namespace foo = ns::bar;". + void setAliasLoc(SourceLocation L) { AliasLoc = L; } + /// Returns the location of the 'namespace' keyword. SourceLocation getNamespaceLoc() const { return getLocation(); } /// Returns the location of the identifier in the named namespace. SourceLocation getTargetNameLoc() const { return IdentLoc; } + /// Set the location of the identifier in the named namespace. + void setTargetNameLoc(SourceLocation L) { IdentLoc = L; } + /// \brief Retrieve the namespace that this alias refers to, which /// may either be a NamespaceDecl or a NamespaceAliasDecl. NamedDecl *getAliasedNamespace() const { return Namespace; } + /// \brief Set the namespace or namespace alias pointed to by this + /// alias decl. + void setAliasedNamespace(NamedDecl *ND) { + assert((isa<NamespaceAliasDecl>(ND) || isa<NamespaceDecl>(ND)) && + "expecting namespace or namespace alias decl"); + Namespace = ND; + } + static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, SourceLocation AliasLoc, IdentifierInfo *Alias, @@ -1687,16 +1822,20 @@ public: return new (C) UsingShadowDecl(DC, Loc, Using, Target); } - /// Gets the underlying declaration which has been brought into the + /// \brief Gets the underlying declaration which has been brought into the /// local scope. - NamedDecl *getTargetDecl() const { - return Underlying; - } + NamedDecl *getTargetDecl() const { return Underlying; } - /// Gets the using declaration to which this declaration is tied. - UsingDecl *getUsingDecl() const { - return Using; - } + /// \brief Sets the underlying declaration which has been brought into the + /// local scope. + void setTargetDecl(NamedDecl* ND) { Underlying = ND; } + + /// \brief Gets the using declaration to which this declaration is tied. + UsingDecl *getUsingDecl() const { return Using; } + + /// \brief Sets the using declaration that introduces this target + /// declaration. + void setUsingDecl(UsingDecl* UD) { Using = UD; } static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const UsingShadowDecl *D) { return true; } @@ -1733,21 +1872,39 @@ class UsingDecl : public NamedDecl { } public: + // FIXME: Should be const? /// \brief Returns the source range that covers the nested-name-specifier /// preceding the namespace name. SourceRange getNestedNameRange() { return NestedNameRange; } - /// \brief Returns the source location of the "using" location itself. + /// \brief Set the source range of the nested-name-specifier. + void setNestedNameRange(SourceRange R) { NestedNameRange = R; } + + // FIXME; Should be const? + // FIXME: Naming is inconsistent with other get*Loc functions. + /// \brief Returns the source location of the "using" keyword. SourceLocation getUsingLocation() { return UsingLocation; } - /// \brief Get target nested name declaration. + /// \brief Set the source location of the 'using' keyword. + void setUsingLocation(SourceLocation L) { UsingLocation = L; } + + + /// \brief Get the target nested name declaration. NestedNameSpecifier* getTargetNestedNameDecl() { return TargetNestedName; } - /// isTypeName - Return true if using decl has 'typename'. + /// \brief Set the target nested name declaration. + void setTargetNestedNameDecl(NestedNameSpecifier *NNS) { + TargetNestedName = NNS; + } + + /// \brief Return true if the using declaration has 'typename'. bool isTypeName() const { return IsTypeName; } + /// \brief Sets whether the using declaration has 'typename'. + void setTypeName(bool TN) { IsTypeName = TN; } + typedef llvm::SmallPtrSet<UsingShadowDecl*,8>::const_iterator shadow_iterator; shadow_iterator shadow_begin() const { return Shadows.begin(); } shadow_iterator shadow_end() const { return Shadows.end(); } @@ -1765,6 +1922,12 @@ public: } } + /// \brief Return the number of shadowed declarations associated with this + /// using declaration. + unsigned getNumShadowDecls() const { + return Shadows.size(); + } + static UsingDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL, NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg); @@ -1807,14 +1970,26 @@ public: /// preceding the namespace name. SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; } + /// \brief Set the source range coverting the nested-name-specifier preceding + /// the namespace name. + void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; } + /// \brief Get target nested name declaration. NestedNameSpecifier* getTargetNestedNameSpecifier() { return TargetNestedNameSpecifier; } + /// \brief Set the nested name declaration. + void setTargetNestedNameSpecifier(NestedNameSpecifier* NNS) { + TargetNestedNameSpecifier = NNS; + } + /// \brief Returns the source location of the 'using' keyword. SourceLocation getUsingLoc() const { return UsingLocation; } + /// \brief Set the source location of the 'using' keyword. + void setUsingLoc(SourceLocation L) { UsingLocation = L; } + static UnresolvedUsingValueDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc, SourceRange TargetNNR, NestedNameSpecifier *TargetNNS, @@ -1861,17 +2036,32 @@ public: /// preceding the namespace name. SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; } + /// \brief Set the source range coverting the nested-name-specifier preceding + /// the namespace name. + void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; } + /// \brief Get target nested name declaration. NestedNameSpecifier* getTargetNestedNameSpecifier() { return TargetNestedNameSpecifier; } + /// \brief Set the nested name declaration. + void setTargetNestedNameSpecifier(NestedNameSpecifier* NNS) { + TargetNestedNameSpecifier = NNS; + } + /// \brief Returns the source location of the 'using' keyword. SourceLocation getUsingLoc() const { return UsingLocation; } + /// \brief Set the source location of the 'using' keyword. + void setUsingLoc(SourceLocation L) { UsingLocation = L; } + /// \brief Returns the source location of the 'typename' keyword. SourceLocation getTypenameLoc() const { return TypenameLocation; } + /// \brief Set the source location of the 'typename' keyword. + void setTypenameLoc(SourceLocation L) { TypenameLocation = L; } + static UnresolvedUsingTypenameDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc, SourceLocation TypenameLoc, diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h index 2a4b12a..9602b67 100644 --- a/include/clang/AST/DeclContextInternals.h +++ b/include/clang/AST/DeclContextInternals.h @@ -156,7 +156,8 @@ public: /// represents. DeclContext::lookup_result getLookupResult(ASTContext &Context) { if (isNull()) - return DeclContext::lookup_result(0, 0); + return DeclContext::lookup_result(DeclContext::lookup_iterator(0), + DeclContext::lookup_iterator(0)); if (hasDeclarationIDs()) materializeDecls(Context); diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index e34ec9f..97d1656 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -1421,13 +1421,21 @@ private: /// Null for @dynamic. Required for @synthesize. ObjCIvarDecl *PropertyIvarDecl; + + /// Null for @dynamic. Non-null if property must be copy-constructed in getter + Expr *GetterCXXConstructor; + + /// Null for @dynamic. Non-null if property has assignment operator to call + /// in Setter synthesis. + Expr *SetterCXXAssignment; ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L, ObjCPropertyDecl *property, Kind PK, ObjCIvarDecl *ivarDecl) : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc), - PropertyDecl(property), PropertyIvarDecl(ivarDecl) { + PropertyDecl(property), PropertyIvarDecl(ivarDecl), + GetterCXXConstructor(0), SetterCXXAssignment(0) { assert (PK == Dynamic || PropertyIvarDecl); } @@ -1457,7 +1465,21 @@ public: return PropertyIvarDecl; } void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { PropertyIvarDecl = Ivar; } + + Expr *getGetterCXXConstructor() const { + return GetterCXXConstructor; + } + void setGetterCXXConstructor(Expr *getterCXXConstructor) { + GetterCXXConstructor = getterCXXConstructor; + } + Expr *getSetterCXXAssignment() const { + return SetterCXXAssignment; + } + void setSetterCXXAssignment(Expr *setterCXXAssignment) { + SetterCXXAssignment = setterCXXAssignment; + } + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const ObjCPropertyImplDecl *D) { return true; } static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; } diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 1ec38ba..b7b90b1 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -112,7 +112,7 @@ class TemplateArgumentListBuilder { unsigned MaxStructuredArgs; unsigned NumStructuredArgs; - TemplateArgument *FlatArgs; + llvm::SmallVector<TemplateArgument, 4> FlatArgs; unsigned MaxFlatArgs; unsigned NumFlatArgs; @@ -127,18 +127,12 @@ public: MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0), AddingToPack(false), PackBeginIndex(0) { } - void Append(const TemplateArgument& Arg); + void Append(const TemplateArgument &Arg); void BeginPack(); void EndPack(); - void ReleaseArgs(); - - unsigned flatSize() const { - return NumFlatArgs; - } - const TemplateArgument *getFlatArguments() const { - return FlatArgs; - } + unsigned flatSize() const { return FlatArgs.size(); } + const TemplateArgument *getFlatArguments() const { return FlatArgs.data(); } unsigned structuredSize() const { // If we don't have any structured args, just reuse the flat size. @@ -165,7 +159,7 @@ class TemplateArgumentList { /// \brief The template argument list. /// /// The integer value will be non-zero to indicate that this - /// template argument list does not own the pointer. + /// template argument list does own the pointer. llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments; /// \brief The number of template arguments in this template @@ -175,14 +169,28 @@ class TemplateArgumentList { llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments; unsigned NumStructuredArguments; + TemplateArgumentList(const TemplateArgumentList &Other); // DO NOT IMPL + void operator=(const TemplateArgumentList &Other); // DO NOT IMPL public: + /// TemplateArgumentList - If this constructor is passed "true" for 'TakeArgs' + /// it copies them into a locally new[]'d array. If passed "false", then it + /// just references the array passed in. This is only safe if the builder + /// outlives it, but saves a copy. TemplateArgumentList(ASTContext &Context, TemplateArgumentListBuilder &Builder, bool TakeArgs); - /// \brief Produces a shallow copy of the given template argument list - TemplateArgumentList(const TemplateArgumentList &Other); + /// Produces a shallow copy of the given template argument list. This + /// assumes that the input argument list outlives it. This takes the list as + /// a pointer to avoid looking like a copy constructor, since this really + /// really isn't safe to use that way. + explicit TemplateArgumentList(const TemplateArgumentList *Other); + /// Used to release the memory associated with a TemplateArgumentList + /// object. FIXME: This is currently not called anywhere, but the + /// memory will still be freed when using a BumpPtrAllocator. + void Destroy(ASTContext &C); + ~TemplateArgumentList(); /// \brief Retrieve the template argument at a given index. @@ -280,6 +288,9 @@ public: /// specialization from the function template. const TemplateArgumentList *TemplateArguments; + /// \brief The template arguments as written in the sources, if provided. + const TemplateArgumentListInfo *TemplateArgumentsAsWritten; + /// \brief The point at which this function template specialization was /// first instantiated. SourceLocation PointOfInstantiation; @@ -454,6 +465,8 @@ public: /// Declaration of a template function. class FunctionTemplateDecl : public TemplateDecl { + static void DeallocateCommon(void *Ptr); + protected: /// \brief Data that is common to all of the declarations of a given /// function template. @@ -862,7 +875,7 @@ class ClassTemplateSpecializationDecl unsigned SpecializationKind : 3; protected: - ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, + ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, ClassTemplateDecl *SpecializedTemplate, TemplateArgumentListBuilder &Builder, @@ -870,7 +883,7 @@ protected: public: static ClassTemplateSpecializationDecl * - Create(ASTContext &Context, DeclContext *DC, SourceLocation L, + Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L, ClassTemplateDecl *SpecializedTemplate, TemplateArgumentListBuilder &Builder, ClassTemplateSpecializationDecl *PrevDecl); @@ -1024,7 +1037,7 @@ class ClassTemplatePartialSpecializationDecl llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool> InstantiatedFromMember; - ClassTemplatePartialSpecializationDecl(ASTContext &Context, + ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, @@ -1035,7 +1048,7 @@ class ClassTemplatePartialSpecializationDecl unsigned SequenceNumber) : ClassTemplateSpecializationDecl(Context, ClassTemplatePartialSpecialization, - DC, L, SpecializedTemplate, Builder, + TK, DC, L, SpecializedTemplate, Builder, PrevDecl), TemplateParams(Params), ArgsAsWritten(ArgInfos), NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber), @@ -1043,7 +1056,7 @@ class ClassTemplatePartialSpecializationDecl public: static ClassTemplatePartialSpecializationDecl * - Create(ASTContext &Context, DeclContext *DC, SourceLocation L, + Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, TemplateArgumentListBuilder &Builder, @@ -1158,6 +1171,8 @@ public: /// Declaration of a class template. class ClassTemplateDecl : public TemplateDecl { + static void DeallocateCommon(void *Ptr); + protected: /// \brief Data that is common to all of the declarations of a given /// class template. diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index 9401786..8a771d5 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -314,15 +314,16 @@ inline bool operator>=(DeclarationName LHS, DeclarationName RHS) { /// retrieved using its member functions (e.g., /// getCXXConstructorName). class DeclarationNameTable { + ASTContext &Ctx; void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> * CXXOperatorIdName *CXXOperatorNames; // Operator names - void *CXXLiteralOperatorNames; // Actually a FoldingSet<...> * + void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName* DeclarationNameTable(const DeclarationNameTable&); // NONCOPYABLE DeclarationNameTable& operator=(const DeclarationNameTable&); // NONCOPYABLE public: - DeclarationNameTable(); + DeclarationNameTable(ASTContext &C); ~DeclarationNameTable(); /// getIdentifier - Create a declaration name that is a simple diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 2946e46..66639e2 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -51,6 +51,7 @@ typedef UsuallyTinyPtrVector<const CXXBaseSpecifier> CXXBaseSpecifierArray; class Expr : public Stmt { QualType TR; + virtual void ANCHOR(); // key function. protected: /// TypeDependent - Whether this expression is type-dependent /// (C++ [temp.dep.expr]). @@ -247,6 +248,15 @@ public: SourceLocation DiagLoc; EvalResult() : HasSideEffects(false), Diag(0), DiagExpr(0) {} + + // isGlobalLValue - Return true if the evaluated lvalue expression + // is global. + bool isGlobalLValue() const; + // hasSideEffects - Return true if the evaluated expression has + // side effects. + bool hasSideEffects() const { + return HasSideEffects; + } }; /// Evaluate - Return true if this is a constant which we can fold using @@ -255,10 +265,6 @@ public: /// in Result. bool Evaluate(EvalResult &Result, ASTContext &Ctx) const; - /// EvaluateAsAny - The same as Evaluate, except that it also succeeds on - /// stack based objects. - bool EvaluateAsAny(EvalResult &Result, ASTContext &Ctx) const; - /// EvaluateAsBooleanCondition - Return true if this is a constant /// which we we can fold and convert to a boolean condition using /// any crazy technique that we want to. @@ -282,8 +288,7 @@ public: /// with link time known address. bool EvaluateAsLValue(EvalResult &Result, ASTContext &Ctx) const; - /// EvaluateAsAnyLValue - The same as EvaluateAsLValue, except that it - /// also succeeds on stack based, immutable address lvalues. + /// EvaluateAsLValue - Evaluate an expression to see if it's a lvalue. bool EvaluateAsAnyLValue(EvalResult &Result, ASTContext &Ctx) const; /// \brief Enumeration used to describe how \c isNullPointerConstant() @@ -321,6 +326,10 @@ public: /// or CastExprs, returning their operand. Expr *IgnoreParenCasts(); + /// IgnoreParenImpCasts - Ignore parentheses and implicit casts. Strip off any + /// ParenExpr or ImplicitCastExprs, returning their operand. + Expr *IgnoreParenImpCasts(); + /// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the /// value (including ptr->int casts of the same size). Strip off any /// ParenExpr or CastExprs, returning their operand. @@ -1468,13 +1477,10 @@ public: } static bool classof(const Stmt *T) { - return T->getStmtClass() == CallExprClass || - T->getStmtClass() == CXXOperatorCallExprClass || - T->getStmtClass() == CXXMemberCallExprClass; + return T->getStmtClass() >= firstCallExprConstant && + T->getStmtClass() <= lastCallExprConstant; } static bool classof(const CallExpr *) { return true; } - static bool classof(const CXXOperatorCallExpr *) { return true; } - static bool classof(const CXXMemberCallExpr *) { return true; } // Iterators virtual child_iterator child_begin(); @@ -1933,14 +1939,8 @@ public: const CXXBaseSpecifierArray& getBasePath() const { return BasePath; } static bool classof(const Stmt *T) { - StmtClass SC = T->getStmtClass(); - if (SC >= CXXStaticCastExprClass && SC <= CXXFunctionalCastExprClass) - return true; - - if (SC >= ImplicitCastExprClass && SC <= CStyleCastExprClass) - return true; - - return false; + return T->getStmtClass() >= firstCastExprConstant && + T->getStmtClass() <= lastCastExprConstant; } static bool classof(const CastExpr *) { return true; } @@ -2037,13 +2037,8 @@ public: QualType getTypeAsWritten() const { return TInfo->getType(); } static bool classof(const Stmt *T) { - StmtClass SC = T->getStmtClass(); - if (SC >= CStyleCastExprClass && SC <= CStyleCastExprClass) - return true; - if (SC >= CXXStaticCastExprClass && SC <= CXXFunctionalCastExprClass) - return true; - - return false; + return T->getStmtClass() >= firstExplicitCastExprConstant && + T->getStmtClass() <= lastExplicitCastExprConstant; } static bool classof(const ExplicitCastExpr *) { return true; } }; @@ -2198,8 +2193,8 @@ public: bool isShiftAssignOp() const { return Opc == ShlAssign || Opc == ShrAssign; } static bool classof(const Stmt *S) { - return S->getStmtClass() == BinaryOperatorClass || - S->getStmtClass() == CompoundAssignOperatorClass; + return S->getStmtClass() >= firstBinaryOperatorConstant && + S->getStmtClass() <= lastBinaryOperatorConstant; } static bool classof(const BinaryOperator *) { return true; } diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index f9ca78a..0c493f3 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -88,10 +88,13 @@ public: /// the object argument). class CXXMemberCallExpr : public CallExpr { public: - CXXMemberCallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, + CXXMemberCallExpr(ASTContext &C, Expr *fn, Expr **args, unsigned numargs, QualType t, SourceLocation rparenloc) : CallExpr(C, CXXMemberCallExprClass, fn, args, numargs, t, rparenloc) {} + CXXMemberCallExpr(ASTContext &C, EmptyShell Empty) + : CallExpr(C, CXXMemberCallExprClass, Empty) { } + /// getImplicitObjectArgument - Retrieves the implicit object /// argument for the member call. For example, in "x.f(5)", this /// operation would return "x". @@ -318,6 +321,14 @@ public: Operand->isTypeDependent() || Operand->isValueDependent()), Operand(Operand), Range(R) { } + CXXTypeidExpr(EmptyShell Empty, bool isExpr) + : Expr(CXXTypeidExprClass, Empty) { + if (isExpr) + Operand = (Expr*)0; + else + Operand = (TypeSourceInfo*)0; + } + bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); } /// \brief Retrieves the type operand of this typeid() expression after @@ -329,15 +340,25 @@ public: assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)"); return Operand.get<TypeSourceInfo *>(); } + + void setTypeOperandSourceInfo(TypeSourceInfo *TSI) { + assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)"); + Operand = TSI; + } - Expr* getExprOperand() const { + Expr *getExprOperand() const { assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)"); return static_cast<Expr*>(Operand.get<Stmt *>()); } - - virtual SourceRange getSourceRange() const { - return Range; + + void setExprOperand(Expr *E) { + assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)"); + Operand = E; } + + virtual SourceRange getSourceRange() const { return Range; } + void setSourceRange(SourceRange R) { Range = R; } + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXTypeidExprClass; } @@ -371,6 +392,11 @@ public: Type->isDependentType(), Type->isDependentType()), Loc(L), Implicit(isImplicit) { } + CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {} + + SourceLocation getLocation() const { return Loc; } + void setLocation(SourceLocation L) { Loc = L; } + virtual SourceRange getSourceRange() const { return SourceRange(Loc); } bool isImplicit() const { return Implicit; } @@ -399,6 +425,8 @@ public: // can by null, if the optional expression to throw isn't present. CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l) : Expr(CXXThrowExprClass, Ty, false, false), Op(expr), ThrowLoc(l) {} + CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {} + const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); } Expr *getSubExpr() { return cast_or_null<Expr>(Op); } void setSubExpr(Expr *E) { Op = E; } @@ -448,8 +476,7 @@ protected: CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param, Expr *SubExpr) - : Expr(SC, SubExpr->getType(), false, false), Param(param, true), Loc(Loc) - { + : Expr(SC, SubExpr->getType(), false, false), Param(param, true), Loc(Loc) { *reinterpret_cast<Expr **>(this + 1) = SubExpr; } @@ -457,6 +484,9 @@ protected: virtual void DoDestroy(ASTContext &C); public: + CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {} + + // Param is the parameter whose default argument is used by this // expression. static CXXDefaultArgExpr *Create(ASTContext &C, SourceLocation Loc, @@ -475,6 +505,9 @@ public: const ParmVarDecl *getParam() const { return Param.getPointer(); } ParmVarDecl *getParam() { return Param.getPointer(); } + /// isExprStored - Return true if this expression owns the expression. + bool isExprStored() const { return Param.getInt(); } + // Retrieve the actual argument to the function call. const Expr *getExpr() const { if (Param.getInt()) @@ -486,10 +519,16 @@ public: return *reinterpret_cast<Expr **> (this + 1); return getParam()->getDefaultArg(); } + + void setExpr(Expr *E) { + Param.setInt(true); + Param.setPointer((ParmVarDecl*)E); + } /// \brief Retrieve the location where this default argument was actually /// used. SourceLocation getUsedLocation() const { return Loc; } + void setUsedLocation(SourceLocation L) { Loc = L; } virtual SourceRange getSourceRange() const { // Default argument expressions have no representation in the @@ -525,8 +564,20 @@ public: const CXXDestructorDecl *getDestructor() const { return Destructor; } }; -/// CXXBindTemporaryExpr - Represents binding an expression to a temporary, -/// so its destructor can be called later. +/// \brief Represents binding an expression to a temporary. +/// +/// This ensures the destructor is called for the temporary. It should only be +/// needed for non-POD, non-trivially destructable class types. For example: +/// +/// \code +/// struct S { +/// S() { } // User defined constructor makes S non-POD. +/// ~S() { } // User defined destructor makes it non-trivial. +/// }; +/// void test() { +/// const S &s_ref = S(); // Requires a CXXBindTemporaryExpr. +/// } +/// \endcode class CXXBindTemporaryExpr : public Expr { CXXTemporary *Temp; @@ -541,11 +592,15 @@ protected: virtual void DoDestroy(ASTContext &C); public: + CXXBindTemporaryExpr(EmptyShell Empty) + : Expr(CXXBindTemporaryExprClass, Empty), Temp(0), SubExpr(0) {} + static CXXBindTemporaryExpr *Create(ASTContext &C, CXXTemporary *Temp, Expr* SubExpr); CXXTemporary *getTemporary() { return Temp; } const CXXTemporary *getTemporary() const { return Temp; } + void setTemporary(CXXTemporary *T) { Temp = T; } const Expr *getSubExpr() const { return cast<Expr>(SubExpr); } Expr *getSubExpr() { return cast<Expr>(SubExpr); } @@ -572,8 +627,8 @@ public: /// const int &i = 10; /// /// a bind reference expression is inserted to indicate that 10 is bound to -/// a reference. (Ans also that a temporary needs to be created to hold the -/// value). +/// a reference, and that a temporary needs to be created to hold the +/// value. class CXXBindReferenceExpr : public Expr { // SubExpr - The expression being bound. Stmt *SubExpr; @@ -827,10 +882,15 @@ public: SourceLocation rParenLoc ) : Expr(CXXZeroInitValueExprClass, ty, false, false), TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {} + explicit CXXZeroInitValueExpr(EmptyShell Shell) + : Expr(CXXZeroInitValueExprClass, Shell) { } SourceLocation getTypeBeginLoc() const { return TyBeginLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } + void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } + /// @brief Whether this initialization expression was /// implicitly-generated. bool isImplicit() const { @@ -891,6 +951,11 @@ public: Expr **constructorArgs, unsigned numConsArgs, FunctionDecl *operatorDelete, QualType ty, SourceLocation startLoc, SourceLocation endLoc); + explicit CXXNewExpr(EmptyShell Shell) + : Expr(CXXNewExprClass, Shell), SubExprs(0) { } + + void AllocateArgsArray(ASTContext &C, bool isArray, unsigned numPlaceArgs, + unsigned numConsArgs); virtual void DoDestroy(ASTContext &C); @@ -900,8 +965,11 @@ public: } FunctionDecl *getOperatorNew() const { return OperatorNew; } + void setOperatorNew(FunctionDecl *D) { OperatorNew = D; } FunctionDecl *getOperatorDelete() const { return OperatorDelete; } + void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; } CXXConstructorDecl *getConstructor() const { return Constructor; } + void setConstructor(CXXConstructorDecl *D) { Constructor = D; } bool isArray() const { return Array; } Expr *getArraySize() { @@ -922,8 +990,11 @@ public: } bool isGlobalNew() const { return GlobalNew; } + void setGlobalNew(bool V) { GlobalNew = V; } bool isParenTypeId() const { return ParenTypeId; } + void setParenTypeId(bool V) { ParenTypeId = V; } bool hasInitializer() const { return Initializer; } + void setHasInitializer(bool V) { Initializer = V; } unsigned getNumConstructorArgs() const { return NumConstructorArgs; } Expr *getConstructorArg(unsigned i) { @@ -963,7 +1034,21 @@ public: const_arg_iterator constructor_arg_end() const { return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs(); } + + typedef Stmt **raw_arg_iterator; + raw_arg_iterator raw_arg_begin() { return SubExprs; } + raw_arg_iterator raw_arg_end() { + return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs(); + } + const_arg_iterator raw_arg_begin() const { return SubExprs; } + const_arg_iterator raw_arg_end() const { return constructor_arg_end(); } + + SourceLocation getStartLoc() const { return StartLoc; } + void setStartLoc(SourceLocation L) { StartLoc = L; } + SourceLocation getEndLoc() const { return EndLoc; } + void setEndLoc(SourceLocation L) { EndLoc = L; } + virtual SourceRange getSourceRange() const { return SourceRange(StartLoc, EndLoc); } @@ -1260,7 +1345,9 @@ class OverloadExpr : public Expr { /// The results. These are undesugared, which is to say, they may /// include UsingShadowDecls. Access is relative to the naming /// class. - UnresolvedSet<4> Results; + // FIXME: Allocate this data after the OverloadExpr subclass. + DeclAccessPair *Results; + unsigned NumResults; /// The common name of these declarations. DeclarationName Name; @@ -1278,14 +1365,11 @@ class OverloadExpr : public Expr { bool HasExplicitTemplateArgs; protected: - OverloadExpr(StmtClass K, QualType T, bool Dependent, + OverloadExpr(StmtClass K, ASTContext &C, QualType T, bool Dependent, NestedNameSpecifier *Qualifier, SourceRange QRange, DeclarationName Name, SourceLocation NameLoc, - bool HasTemplateArgs) - : Expr(K, T, Dependent, Dependent), - Name(Name), Qualifier(Qualifier), QualifierRange(QRange), - NameLoc(NameLoc), HasExplicitTemplateArgs(HasTemplateArgs) - {} + bool HasTemplateArgs, + UnresolvedSetIterator Begin, UnresolvedSetIterator End); public: /// Computes whether an unresolved lookup on the given declarations @@ -1309,22 +1393,17 @@ public: return llvm::PointerIntPair<OverloadExpr*,1>(cast<OverloadExpr>(E), op); } - void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) { - Results.append(Begin, End); - } - /// Gets the naming class of this lookup, if any. CXXRecordDecl *getNamingClass() const; typedef UnresolvedSetImpl::iterator decls_iterator; - decls_iterator decls_begin() const { return Results.begin(); } - decls_iterator decls_end() const { return Results.end(); } - - /// Gets the decls as an unresolved set. - const UnresolvedSetImpl &getDecls() { return Results; } + decls_iterator decls_begin() const { return UnresolvedSetIterator(Results); } + decls_iterator decls_end() const { + return UnresolvedSetIterator(Results + NumResults); + } /// Gets the number of declarations in the unresolved set. - unsigned getNumDecls() const { return Results.size(); } + unsigned getNumDecls() const { return NumResults; } /// Gets the name looked up. DeclarationName getName() const { return Name; } @@ -1390,12 +1469,14 @@ class UnresolvedLookupExpr : public OverloadExpr { /// against the qualified-lookup bits. CXXRecordDecl *NamingClass; - UnresolvedLookupExpr(QualType T, bool Dependent, CXXRecordDecl *NamingClass, + UnresolvedLookupExpr(ASTContext &C, QualType T, bool Dependent, + CXXRecordDecl *NamingClass, NestedNameSpecifier *Qualifier, SourceRange QRange, DeclarationName Name, SourceLocation NameLoc, - bool RequiresADL, bool Overloaded, bool HasTemplateArgs) - : OverloadExpr(UnresolvedLookupExprClass, T, Dependent, Qualifier, QRange, - Name, NameLoc, HasTemplateArgs), + bool RequiresADL, bool Overloaded, bool HasTemplateArgs, + UnresolvedSetIterator Begin, UnresolvedSetIterator End) + : OverloadExpr(UnresolvedLookupExprClass, C, T, Dependent, Qualifier, + QRange, Name, NameLoc, HasTemplateArgs, Begin, End), RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass) {} @@ -1407,11 +1488,15 @@ public: SourceRange QualifierRange, DeclarationName Name, SourceLocation NameLoc, - bool ADL, bool Overloaded) { - return new(C) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy, + bool ADL, bool Overloaded, + UnresolvedSetIterator Begin, + UnresolvedSetIterator End) { + return new(C) UnresolvedLookupExpr(C, + Dependent ? C.DependentTy : C.OverloadTy, Dependent, NamingClass, Qualifier, QualifierRange, - Name, NameLoc, ADL, Overloaded, false); + Name, NameLoc, ADL, Overloaded, false, + Begin, End); } static UnresolvedLookupExpr *Create(ASTContext &C, @@ -1422,7 +1507,9 @@ public: DeclarationName Name, SourceLocation NameLoc, bool ADL, - const TemplateArgumentListInfo &Args); + const TemplateArgumentListInfo &Args, + UnresolvedSetIterator Begin, + UnresolvedSetIterator End); /// True if this declaration should be extended by /// argument-dependent lookup. @@ -1611,7 +1698,7 @@ class CXXExprWithTemporaries : public Expr { CXXTemporary **Temps; unsigned NumTemps; - CXXExprWithTemporaries(Expr *SubExpr, CXXTemporary **Temps, + CXXExprWithTemporaries(ASTContext &C, Expr *SubExpr, CXXTemporary **Temps, unsigned NumTemps); ~CXXExprWithTemporaries(); @@ -1619,11 +1706,17 @@ protected: virtual void DoDestroy(ASTContext &C); public: + CXXExprWithTemporaries(EmptyShell Empty) + : Expr(CXXExprWithTemporariesClass, Empty), + SubExpr(0), Temps(0), NumTemps(0) {} + static CXXExprWithTemporaries *Create(ASTContext &C, Expr *SubExpr, CXXTemporary **Temps, unsigned NumTemps); unsigned getNumTemporaries() const { return NumTemps; } + void setNumTemporaries(ASTContext &C, unsigned N); + CXXTemporary *getTemporary(unsigned i) { assert(i < NumTemps && "Index out of range"); return Temps[i]; @@ -1631,6 +1724,10 @@ public: const CXXTemporary *getTemporary(unsigned i) const { return const_cast<CXXExprWithTemporaries*>(this)->getTemporary(i); } + void setTemporary(unsigned i, CXXTemporary *T) { + assert(i < NumTemps && "Index out of range"); + Temps[i] = T; + } Expr *getSubExpr() { return cast<Expr>(SubExpr); } const Expr *getSubExpr() const { return cast<Expr>(SubExpr); } @@ -2020,7 +2117,7 @@ class UnresolvedMemberExpr : public OverloadExpr { /// \brief The location of the '->' or '.' operator. SourceLocation OperatorLoc; - UnresolvedMemberExpr(QualType T, bool Dependent, + UnresolvedMemberExpr(ASTContext &C, QualType T, bool Dependent, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, @@ -2028,7 +2125,8 @@ class UnresolvedMemberExpr : public OverloadExpr { SourceRange QualifierRange, DeclarationName Member, SourceLocation MemberLoc, - const TemplateArgumentListInfo *TemplateArgs); + const TemplateArgumentListInfo *TemplateArgs, + UnresolvedSetIterator Begin, UnresolvedSetIterator End); public: static UnresolvedMemberExpr * @@ -2039,7 +2137,8 @@ public: SourceRange QualifierRange, DeclarationName Member, SourceLocation MemberLoc, - const TemplateArgumentListInfo *TemplateArgs); + const TemplateArgumentListInfo *TemplateArgs, + UnresolvedSetIterator Begin, UnresolvedSetIterator End); /// \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 diff --git a/include/clang/AST/Makefile b/include/clang/AST/Makefile new file mode 100644 index 0000000..a25977c --- /dev/null +++ b/include/clang/AST/Makefile @@ -0,0 +1,13 @@ +LEVEL = ../../../../.. +BUILT_SOURCES = StmtNodes.inc + +TABLEGEN_INC_FILES_COMMON = 1 + +include $(LEVEL)/Makefile.common + +INPUT_TDS = $(PROJ_SRC_DIR)/StmtNodes.td + +$(ObjDir)/StmtNodes.inc.tmp : StmtNodes.td $(TBLGEN) $(ObjDir)/.dir + $(Echo) "Building Clang statement node tables with tblgen" + $(Verb) $(TableGen) -gen-clang-stmt-nodes -o $(call SYSPATH, $@) $< + diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h index e78476e..2b3229e 100644 --- a/include/clang/AST/RecordLayout.h +++ b/include/clang/AST/RecordLayout.h @@ -109,6 +109,11 @@ private: /// which is the alignment of the object without virtual bases. uint64_t NonVirtualAlign; + /// SizeOfLargestEmptySubobject - The size of the largest empty subobject + /// (either a base or a member). Will be zero if the class doesn't contain + /// any empty subobjects. + uint64_t SizeOfLargestEmptySubobject; + /// PrimaryBase - The primary base info for this record. PrimaryBaseInfo PrimaryBase; @@ -127,7 +132,6 @@ private: CXXRecordLayoutInfo *CXXInfo; friend class ASTContext; - friend class ASTRecordLayoutBuilder; ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignment, unsigned datasize, const uint64_t *fieldoffsets, @@ -139,7 +143,9 @@ private: uint64_t size, unsigned alignment, uint64_t datasize, const uint64_t *fieldoffsets, unsigned fieldcount, uint64_t nonvirtualsize, unsigned nonvirtualalign, - const PrimaryBaseInfo &PrimaryBase, + uint64_t SizeOfLargestEmptySubobject, + const CXXRecordDecl *PrimaryBase, + bool PrimaryBaseIsVirtual, const BaseOffsetsMapTy& BaseOffsets, const BaseOffsetsMapTy& VBaseOffsets); @@ -222,6 +228,11 @@ public: return CXXInfo->VBaseOffsets[VBase]; } + uint64_t getSizeOfLargestEmptySubobject() const { + assert(CXXInfo && "Record layout does not have C++ specific info!"); + return CXXInfo->SizeOfLargestEmptySubobject; + } + primary_base_info_iterator primary_base_begin() const { assert(CXXInfo && "Record layout does not have C++ specific info!"); diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h new file mode 100644 index 0000000..07865e0 --- /dev/null +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -0,0 +1,768 @@ +//===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the RecursiveASTVisitor interface, which recursively +// traverses the entire AST. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H +#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H + +#include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclFriend.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" +#include "clang/AST/ExprObjC.h" +#include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/Stmt.h" +#include "clang/AST/StmtCXX.h" +#include "clang/AST/StmtObjC.h" +#include "clang/AST/TemplateBase.h" +#include "clang/AST/TemplateName.h" +#include "clang/AST/Type.h" + +namespace clang { + +#define DISPATCH(NAME, CLASS, Var) \ +return getDerived().Visit ## NAME(static_cast<CLASS*>(Var)) + +// We use preprocessor meta-programming to generate the Visit*() +// methods for all subclasses of Stmt, Decl, and Type. Some of the +// generated definitions, however, need to be customized. The +// meta-programming technique we use doesn't let us select which +// methods to generate. Therefore we have to generate ALL of them in +// a helper class RecursiveASTVisitorImpl, and override the ones we +// don't like in a child class RecursiveASTVisitor (C++ doesn't allow +// overriding a method in the same class). +// +// Do not use this class directly - use RecursiveASTVisitor instead. +template<typename Derived> +class RecursiveASTVisitorImpl { +public: + /// \brief Return a reference to the derived class. + Derived &getDerived() { return *static_cast<Derived*>(this); } + + /// \brief Recursively visit a statement or expression, by + /// dispatching to Visit*() based on the argument's dynamic type. + /// This is NOT meant to be overridden by a subclass. + /// + /// \returns true if the visitation was terminated early, false + /// otherwise (including when the argument is NULL). + bool Visit(Stmt *S); + + /// \brief Recursively visit a type, by dispatching to + /// Visit*Type() based on the argument's getTypeClass() property. + /// This is NOT meant to be overridden by a subclass. + /// + /// \returns true if the visitation was terminated early, false + /// otherwise (including when the argument is a Null type). + bool Visit(QualType T); + + /// \brief Recursively visit a declaration, by dispatching to + /// Visit*Decl() based on the argument's dynamic type. This is + /// NOT meant to be overridden by a subclass. + /// + /// \returns true if the visitation was terminated early, false + /// otherwise (including when the argument is NULL). + bool Visit(Decl *D); + + /// \brief Recursively visit a C++ nested-name-specifier. + /// + /// \returns true if the visitation was terminated early, false otherwise. + bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS); + + /// \brief Recursively visit a template name. + /// + /// \returns true if the visitation was terminated early, false otherwise. + bool VisitTemplateName(TemplateName Template); + + /// \brief Recursively visit a template argument. + /// + /// \returns true if the visitation was terminated early, false otherwise. + bool VisitTemplateArgument(const TemplateArgument &Arg); + + /// \brief Recursively visit a set of template arguments. + /// + /// \returns true if the visitation was terminated early, false otherwise. + bool VisitTemplateArguments(const TemplateArgument *Args, unsigned NumArgs); + + // If the implementation chooses not to implement a certain visit method, fall + // back on VisitExpr or whatever else is the superclass. +#define STMT(CLASS, PARENT) \ +bool Visit ## CLASS(CLASS *S) { DISPATCH(PARENT, PARENT, S); } +#include "clang/AST/StmtNodes.inc" + + // If the implementation doesn't implement binary operator methods, fall back + // on VisitBinaryOperator. +#define BINOP_FALLBACK(NAME) \ +bool VisitBin ## NAME(BinaryOperator *S) { \ +DISPATCH(BinaryOperator, BinaryOperator, S); \ +} + BINOP_FALLBACK(PtrMemD) BINOP_FALLBACK(PtrMemI) + BINOP_FALLBACK(Mul) BINOP_FALLBACK(Div) BINOP_FALLBACK(Rem) + BINOP_FALLBACK(Add) BINOP_FALLBACK(Sub) BINOP_FALLBACK(Shl) + BINOP_FALLBACK(Shr) + + BINOP_FALLBACK(LT) BINOP_FALLBACK(GT) BINOP_FALLBACK(LE) + BINOP_FALLBACK(GE) BINOP_FALLBACK(EQ) BINOP_FALLBACK(NE) + BINOP_FALLBACK(And) BINOP_FALLBACK(Xor) BINOP_FALLBACK(Or) + BINOP_FALLBACK(LAnd) BINOP_FALLBACK(LOr) + + BINOP_FALLBACK(Assign) + BINOP_FALLBACK(Comma) +#undef BINOP_FALLBACK + + // If the implementation doesn't implement compound assignment operator + // methods, fall back on VisitCompoundAssignOperator. +#define CAO_FALLBACK(NAME) \ +bool VisitBin ## NAME(CompoundAssignOperator *S) { \ +DISPATCH(CompoundAssignOperator, CompoundAssignOperator, S); \ +} + CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign) + CAO_FALLBACK(AddAssign) CAO_FALLBACK(SubAssign) CAO_FALLBACK(ShlAssign) + CAO_FALLBACK(ShrAssign) CAO_FALLBACK(AndAssign) CAO_FALLBACK(OrAssign) + CAO_FALLBACK(XorAssign) +#undef CAO_FALLBACK + + // If the implementation doesn't implement unary operator methods, fall back + // on VisitUnaryOperator. +#define UNARYOP_FALLBACK(NAME) \ +bool VisitUnary ## NAME(UnaryOperator *S) { \ +DISPATCH(UnaryOperator, UnaryOperator, S); \ +} + UNARYOP_FALLBACK(PostInc) UNARYOP_FALLBACK(PostDec) + UNARYOP_FALLBACK(PreInc) UNARYOP_FALLBACK(PreDec) + UNARYOP_FALLBACK(AddrOf) UNARYOP_FALLBACK(Deref) + + UNARYOP_FALLBACK(Plus) UNARYOP_FALLBACK(Minus) + UNARYOP_FALLBACK(Not) UNARYOP_FALLBACK(LNot) + UNARYOP_FALLBACK(Real) UNARYOP_FALLBACK(Imag) + UNARYOP_FALLBACK(Extension) UNARYOP_FALLBACK(OffsetOf) +#undef UNARYOP_FALLBACK + + /// \brief Basis for statement and expression visitation, which + /// visits all of the substatements and subexpressions. + /// + /// The relation between Visit(Stmt *S) and this method is that + /// the former dispatches to Visit*() based on S's dynamic type, + /// which forwards the call up the inheritance chain until + /// reaching VisitStmt(), which then calls Visit() on each + /// substatement/subexpression. + bool VisitStmt(Stmt *S); + + /// \brief Basis for type visitation, which by default does nothing. + /// + /// The relation between Visit(QualType T) and this method is + /// that the former dispatches to Visit*Type(), which forwards the + /// call up the inheritance chain until reaching VisitType(). + bool VisitType(Type *T); + +#define TYPE(Class, Base) \ + bool Visit##Class##Type(Class##Type *T); +#include "clang/AST/TypeNodes.def" + + /// \brief Basis for declaration and definition visitation, which + /// visits all of the subnodes. + /// + /// The relation between Visit(Decl *) and this method is that the + /// former dispatches to Visit*Decl(), which forwards the call up + /// the inheritance chain until reaching VisitDecl(). + bool VisitDecl(Decl *D); + +#define DECL(Class, Base) \ + bool Visit##Class##Decl(Class##Decl *D) { \ + return getDerived().Visit##Base(D); \ + } +#define ABSTRACT_DECL(Class, Base) DECL(Class, Base) +#include "clang/AST/DeclNodes.def" +}; + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::Visit(Stmt *S) { + if (!S) + return false; + + // If we have a binary expr, dispatch to the subcode of the binop. A smart + // optimizer (e.g. LLVM) will fold this comparison into the switch stmt + // below. + if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) { + switch (BinOp->getOpcode()) { + case BinaryOperator::PtrMemD: DISPATCH(BinPtrMemD, BinaryOperator, S); + case BinaryOperator::PtrMemI: DISPATCH(BinPtrMemI, BinaryOperator, S); + case BinaryOperator::Mul: DISPATCH(BinMul, BinaryOperator, S); + case BinaryOperator::Div: DISPATCH(BinDiv, BinaryOperator, S); + case BinaryOperator::Rem: DISPATCH(BinRem, BinaryOperator, S); + case BinaryOperator::Add: DISPATCH(BinAdd, BinaryOperator, S); + case BinaryOperator::Sub: DISPATCH(BinSub, BinaryOperator, S); + case BinaryOperator::Shl: DISPATCH(BinShl, BinaryOperator, S); + case BinaryOperator::Shr: DISPATCH(BinShr, BinaryOperator, S); + + case BinaryOperator::LT: DISPATCH(BinLT, BinaryOperator, S); + case BinaryOperator::GT: DISPATCH(BinGT, BinaryOperator, S); + case BinaryOperator::LE: DISPATCH(BinLE, BinaryOperator, S); + case BinaryOperator::GE: DISPATCH(BinGE, BinaryOperator, S); + case BinaryOperator::EQ: DISPATCH(BinEQ, BinaryOperator, S); + case BinaryOperator::NE: DISPATCH(BinNE, BinaryOperator, S); + + case BinaryOperator::And: DISPATCH(BinAnd, BinaryOperator, S); + case BinaryOperator::Xor: DISPATCH(BinXor, BinaryOperator, S); + case BinaryOperator::Or : DISPATCH(BinOr, BinaryOperator, S); + case BinaryOperator::LAnd: DISPATCH(BinLAnd, BinaryOperator, S); + case BinaryOperator::LOr : DISPATCH(BinLOr, BinaryOperator, S); + case BinaryOperator::Assign: DISPATCH(BinAssign, BinaryOperator, S); + case BinaryOperator::MulAssign: + DISPATCH(BinMulAssign, CompoundAssignOperator, S); + case BinaryOperator::DivAssign: + DISPATCH(BinDivAssign, CompoundAssignOperator, S); + case BinaryOperator::RemAssign: + DISPATCH(BinRemAssign, CompoundAssignOperator, S); + case BinaryOperator::AddAssign: + DISPATCH(BinAddAssign, CompoundAssignOperator, S); + case BinaryOperator::SubAssign: + DISPATCH(BinSubAssign, CompoundAssignOperator, S); + case BinaryOperator::ShlAssign: + DISPATCH(BinShlAssign, CompoundAssignOperator, S); + case BinaryOperator::ShrAssign: + DISPATCH(BinShrAssign, CompoundAssignOperator, S); + case BinaryOperator::AndAssign: + DISPATCH(BinAndAssign, CompoundAssignOperator, S); + case BinaryOperator::OrAssign: + DISPATCH(BinOrAssign, CompoundAssignOperator, S); + case BinaryOperator::XorAssign: + DISPATCH(BinXorAssign, CompoundAssignOperator, S); + case BinaryOperator::Comma: DISPATCH(BinComma, BinaryOperator, S); + } + } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) { + switch (UnOp->getOpcode()) { + case UnaryOperator::PostInc: DISPATCH(UnaryPostInc, UnaryOperator, S); + case UnaryOperator::PostDec: DISPATCH(UnaryPostDec, UnaryOperator, S); + case UnaryOperator::PreInc: DISPATCH(UnaryPreInc, UnaryOperator, S); + case UnaryOperator::PreDec: DISPATCH(UnaryPreDec, UnaryOperator, S); + case UnaryOperator::AddrOf: DISPATCH(UnaryAddrOf, UnaryOperator, S); + case UnaryOperator::Deref: DISPATCH(UnaryDeref, UnaryOperator, S); + case UnaryOperator::Plus: DISPATCH(UnaryPlus, UnaryOperator, S); + case UnaryOperator::Minus: DISPATCH(UnaryMinus, UnaryOperator, S); + case UnaryOperator::Not: DISPATCH(UnaryNot, UnaryOperator, S); + case UnaryOperator::LNot: DISPATCH(UnaryLNot, UnaryOperator, S); + case UnaryOperator::Real: DISPATCH(UnaryReal, UnaryOperator, S); + case UnaryOperator::Imag: DISPATCH(UnaryImag, UnaryOperator, S); + case UnaryOperator::Extension: DISPATCH(UnaryExtension, UnaryOperator, S); + case UnaryOperator::OffsetOf: DISPATCH(UnaryOffsetOf, UnaryOperator, S); + } + } + + // Top switch stmt: dispatch to VisitFooStmt for each FooStmt. + switch (S->getStmtClass()) { + case Stmt::NoStmtClass: break; +#define ABSTRACT_STMT(STMT) +#define STMT(CLASS, PARENT) \ +case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS, S); +#include "clang/AST/StmtNodes.inc" + } + + return false; +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::Visit(QualType T) { + if (T.isNull()) + return false; + + switch (T->getTypeClass()) { +#define ABSTRACT_TYPE(Class, Base) +#define TYPE(Class, Base) \ + case Type::Class: DISPATCH(Class##Type, Class##Type, T.getTypePtr()); +#include "clang/AST/TypeNodes.def" + } + + return false; +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::Visit(Decl *D) { + if (!D) + return false; + + switch (D->getKind()) { +#define ABSTRACT_DECL(Class, Base) +#define DECL(Class, Base) \ + case Decl::Class: DISPATCH(Class##Decl, Class##Decl, D); +#include "clang/AST/DeclNodes.def" + } + + return false; +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitNestedNameSpecifier( + NestedNameSpecifier *NNS) { + if (NNS->getPrefix() && + getDerived().VisitNestedNameSpecifier(NNS->getPrefix())) + return true; + + switch (NNS->getKind()) { + case NestedNameSpecifier::Identifier: + case NestedNameSpecifier::Namespace: + case NestedNameSpecifier::Global: + return false; + + case NestedNameSpecifier::TypeSpec: + case NestedNameSpecifier::TypeSpecWithTemplate: + return Visit(QualType(NNS->getAsType(), 0)); + } + + return false; +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitTemplateName(TemplateName Template) { + if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) + return DTN->getQualifier() && + getDerived().VisitNestedNameSpecifier(DTN->getQualifier()); + + if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) + return getDerived().VisitNestedNameSpecifier(QTN->getQualifier()); + + return false; +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitTemplateArgument( + const TemplateArgument &Arg) { + switch (Arg.getKind()) { + case TemplateArgument::Null: + case TemplateArgument::Declaration: + case TemplateArgument::Integral: + return false; + + case TemplateArgument::Type: + return Visit(Arg.getAsType()); + + case TemplateArgument::Template: + return getDerived().VisitTemplateName(Arg.getAsTemplate()); + + case TemplateArgument::Expression: + return getDerived().Visit(Arg.getAsExpr()); + + case TemplateArgument::Pack: + return getDerived().VisitTemplateArguments(Arg.pack_begin(), + Arg.pack_size()); + } + + return false; +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitTemplateArguments( + const TemplateArgument *Args, + unsigned NumArgs) { + for (unsigned I = 0; I != NumArgs; ++I) + if (getDerived().VisitTemplateArgument(Args[I])) + return true; + + return false; +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitStmt(Stmt *Node) { + for (Stmt::child_iterator C = Node->child_begin(), CEnd = Node->child_end(); + C != CEnd; ++C) { + if (Visit(*C)) + return true; + } + + return false; +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitType(Type *T) { + return false; +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitBuiltinType(BuiltinType *T) { + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitComplexType(ComplexType *T) { + if (Visit(T->getElementType())) + return true; + + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitPointerType(PointerType *T) { + if (Visit(T->getPointeeType())) + return true; + + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitBlockPointerType( + BlockPointerType *T) { + if (Visit(T->getPointeeType())) + return true; + + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitReferenceType(ReferenceType *T) { + if (Visit(T->getPointeeType())) + return true; + + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitLValueReferenceType( + LValueReferenceType *T) { + return getDerived().VisitReferenceType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitRValueReferenceType( + RValueReferenceType *T) { + return getDerived().VisitReferenceType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitMemberPointerType( + MemberPointerType *T) { + if (Visit(QualType(T->getClass(), 0)) || Visit(T->getPointeeType())) + return true; + + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitArrayType(ArrayType *T) { + if (Visit(T->getElementType())) + return true; + + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitConstantArrayType( + ConstantArrayType *T) { + return getDerived().VisitArrayType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitIncompleteArrayType( + IncompleteArrayType *T) { + return getDerived().VisitArrayType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitVariableArrayType( + VariableArrayType *T) { + if (Visit(T->getSizeExpr())) + return true; + + return getDerived().VisitArrayType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitDependentSizedArrayType( + DependentSizedArrayType *T) { + if (T->getSizeExpr() && Visit(T->getSizeExpr())) + return true; + + return getDerived().VisitArrayType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitDependentSizedExtVectorType( + DependentSizedExtVectorType *T) { + if ((T->getSizeExpr() && Visit(T->getSizeExpr())) || + Visit(T->getElementType())) + return true; + + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitVectorType(VectorType *T) { + if (Visit(T->getElementType())) + return true; + + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitExtVectorType(ExtVectorType *T) { + return getDerived().VisitVectorType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitFunctionType(FunctionType *T) { + if (Visit(T->getResultType())) + return true; + + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitFunctionNoProtoType( + FunctionNoProtoType *T) { + return getDerived().VisitFunctionType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitFunctionProtoType( + FunctionProtoType *T) { + for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(), + AEnd = T->arg_type_end(); + A != AEnd; ++A) { + if (Visit(*A)) + return true; + } + + for (FunctionProtoType::exception_iterator E = T->exception_begin(), + EEnd = T->exception_end(); + E != EEnd; ++E) { + if (Visit(*E)) + return true; + } + + return getDerived().VisitFunctionType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitUnresolvedUsingType( + UnresolvedUsingType *T) { + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitTypedefType(TypedefType *T) { + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitTypeOfExprType(TypeOfExprType *T) { + if (Visit(T->getUnderlyingExpr())) + return true; + + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitTypeOfType(TypeOfType *T) { + if (Visit(T->getUnderlyingType())) + return true; + + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitDecltypeType(DecltypeType *T) { + if (Visit(T->getUnderlyingExpr())) + return true; + + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitTagType(TagType *T) { + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitRecordType(RecordType *T) { + return getDerived().VisitTagType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitEnumType(EnumType *T) { + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitTemplateTypeParmType( + TemplateTypeParmType *T) { + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitSubstTemplateTypeParmType( + SubstTemplateTypeParmType *T) { + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitTemplateSpecializationType( + TemplateSpecializationType *T) { + if (getDerived().VisitTemplateName(T->getTemplateName()) || + getDerived().VisitTemplateArguments(T->getArgs(), T->getNumArgs())) + return true; + + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitInjectedClassNameType( + InjectedClassNameType *T) { + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitElaboratedType(ElaboratedType *T) { + if (T->getQualifier() && + getDerived().VisitNestedNameSpecifier(T->getQualifier())) + return true; + if (Visit(T->getNamedType())) + return true; + + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitDependentNameType( + DependentNameType *T) { + if (T->getQualifier() && + getDerived().VisitNestedNameSpecifier(T->getQualifier())) + return true; + + if (T->getTemplateId() && + getDerived().VisitTemplateSpecializationType( + const_cast<TemplateSpecializationType *>(T->getTemplateId()))) + return true; + + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitObjCInterfaceType( + ObjCInterfaceType *T) { + return getDerived().VisitObjCObjectType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitObjCObjectType(ObjCObjectType *T) { + // We have to watch out here because an ObjCInterfaceType's base + // type is itself. + if (T->getBaseType().getTypePtr() != T) + if (Visit(T->getBaseType())) + return true; + + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitObjCObjectPointerType( + ObjCObjectPointerType *T) { + if (Visit(T->getPointeeType())) + return true; + + return getDerived().VisitType(T); +} + +template<typename Derived> +bool RecursiveASTVisitorImpl<Derived>::VisitDecl(Decl *D) { + if (DeclContext *DC = dyn_cast<DeclContext>(D)) { + for (DeclContext::decl_iterator Child = DC->decls_begin(), + ChildEnd = DC->decls_end(); + Child != ChildEnd; ++Child) + if (Visit(*Child)) + return true; + + return false; + } + + return false; +} + +/// \brief A visitor that recursively walks the entire Clang AST. +/// +/// Clients of this visitor should subclass the visitor (providing +/// themselves as the template argument, using the curiously +/// recurring template pattern) and override any of the Visit* +/// methods (except Visit()) for declaration, type, statement, +/// expression, or other AST nodes where the visitor should customize +/// behavior. Returning "true" from one of these overridden functions +/// will abort the entire traversal. An overridden Visit* method +/// will not descend further into the AST for that node unless +/// Base::Visit* is called. +template<typename Derived> +class RecursiveASTVisitor : public RecursiveASTVisitorImpl<Derived> { + typedef RecursiveASTVisitorImpl<Derived> Impl; +public: + typedef RecursiveASTVisitor<Derived> Base; + + bool VisitDeclaratorDecl(DeclaratorDecl *D); + bool VisitFunctionDecl(FunctionDecl *D); + bool VisitVarDecl(VarDecl *D); + bool VisitBlockDecl(BlockDecl *D); + bool VisitDeclStmt(DeclStmt *S); + bool VisitFunctionType(FunctionType *F); + bool VisitFunctionProtoType(FunctionProtoType *F); +}; + +#define DEFINE_VISIT(Type, Name, Statement) \ + template<typename Derived> \ + bool RecursiveASTVisitor<Derived>::Visit ## Type (Type *Name) { \ + if (Impl::Visit ## Type (Name)) return true; \ + { Statement; } \ + return false; \ + } + +DEFINE_VISIT(DeclaratorDecl, D, { + if (TypeSourceInfo *TInfo = D->getTypeSourceInfo()) + return this->Visit(TInfo->getType()); + }) + +DEFINE_VISIT(FunctionDecl, D, { + if (D->isThisDeclarationADefinition()) + return this->Visit(D->getBody()); + }) + +DEFINE_VISIT(VarDecl, D, return this->Visit(D->getInit())) + +DEFINE_VISIT(BlockDecl, D, return this->Visit(D->getBody())) + +DEFINE_VISIT(DeclStmt, S, { + for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end(); + I != E; ++I) { + if (this->Visit(*I)) + return true; + } + }) + +// FunctionType is the common base class of FunctionNoProtoType (a +// K&R-style function declaration that has no information about +// its arguments) and FunctionProtoType. +DEFINE_VISIT(FunctionType, F, return this->Visit(F->getResultType())) + +DEFINE_VISIT(FunctionProtoType, F, { + for (unsigned i = 0; i != F->getNumArgs(); ++i) { + if (this->Visit(F->getArgType(i))) + return true; + } + for (unsigned i = 0; i != F->getNumExceptions(); ++i) { + if (this->Visit(F->getExceptionType(i))) + return true; + } + }) + +#undef DEFINE_VISIT + +#undef DISPATCH + +} // end namespace clang + +#endif // LLVM_CLANG_AST_RECURSIVEASTVISITOR_H diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 0b68a40..9deae15 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -98,12 +98,14 @@ public: enum StmtClass { NoStmtClass = 0, #define STMT(CLASS, PARENT) CLASS##Class, -#define FIRST_STMT(CLASS) firstStmtConstant = CLASS##Class, -#define LAST_STMT(CLASS) lastStmtConstant = CLASS##Class, -#define FIRST_EXPR(CLASS) firstExprConstant = CLASS##Class, -#define LAST_EXPR(CLASS) lastExprConstant = CLASS##Class -#define ABSTRACT_EXPR(CLASS, PARENT) -#include "clang/AST/StmtNodes.def" +#define STMT_RANGE(BASE, FIRST, LAST) \ + first##BASE##Constant = FIRST##Class, \ + last##BASE##Constant = LAST##Class, +#define LAST_STMT_RANGE(BASE, FIRST, LAST) \ + first##BASE##Constant = FIRST##Class, \ + last##BASE##Constant = LAST##Class +#define ABSTRACT_STMT(STMT) +#include "clang/AST/StmtNodes.inc" }; private: /// \brief The statement class. @@ -1083,9 +1085,15 @@ public: class ReturnStmt : public Stmt { Stmt *RetExpr; SourceLocation RetLoc; + const VarDecl *NRVOCandidate; + public: - ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass), - RetExpr((Stmt*) E), RetLoc(RL) {} + ReturnStmt(SourceLocation RL) + : Stmt(ReturnStmtClass), RetExpr(0), RetLoc(RL), NRVOCandidate(0) { } + + ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate) + : Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL), + NRVOCandidate(NRVOCandidate) {} /// \brief Build an empty return expression. explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { } @@ -1097,6 +1105,14 @@ public: SourceLocation getReturnLoc() const { return RetLoc; } void setReturnLoc(SourceLocation L) { RetLoc = L; } + /// \brief Retrieve the variable that might be used for the named return + /// value optimization. + /// + /// The optimization itself can only be performed if the variable is + /// also marked as an NRVO object. + const VarDecl *getNRVOCandidate() const { return NRVOCandidate; } + void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; } + virtual SourceRange getSourceRange() const; static bool classof(const Stmt *T) { diff --git a/include/clang/AST/StmtNodes.td b/include/clang/AST/StmtNodes.td new file mode 100644 index 0000000..60c94a6 --- /dev/null +++ b/include/clang/AST/StmtNodes.td @@ -0,0 +1,127 @@ +class Stmt<bit abstract = 0> { + bit Abstract = abstract; +} + +class DStmt<Stmt base, bit abstract = 0> : Stmt<abstract> { + Stmt Base = base; +} + +// Statements +def NullStmt : Stmt; +def CompoundStmt : Stmt; +def LabelStmt : Stmt; +def IfStmt : Stmt; +def SwitchStmt : Stmt; +def WhileStmt : Stmt; +def DoStmt : Stmt; +def ForStmt : Stmt; +def GotoStmt : Stmt; +def IndirectGotoStmt : Stmt; +def ContinueStmt : Stmt; +def BreakStmt : Stmt; +def ReturnStmt : Stmt; +def DeclStmt : Stmt; +def SwitchCase : Stmt; +def CaseStmt : DStmt<SwitchCase>; +def DefaultStmt : DStmt<SwitchCase>; + +// GNU Extensions +def AsmStmt : Stmt; + +// Obj-C statements +def ObjCAtTryStmt : Stmt; +def ObjCAtCatchStmt : Stmt; +def ObjCAtFinallyStmt : Stmt; +def ObjCAtThrowStmt : Stmt; +def ObjCAtSynchronizedStmt : Stmt; +def ObjCForCollectionStmt : Stmt; + +// C++ statments +def CXXCatchStmt : Stmt; +def CXXTryStmt : Stmt; + +// Expressions +def Expr : Stmt<1>; +def PredefinedExpr : DStmt<Expr>; +def DeclRefExpr : DStmt<Expr>; +def IntegerLiteral : DStmt<Expr>; +def FloatingLiteral : DStmt<Expr>; +def ImaginaryLiteral : DStmt<Expr>; +def StringLiteral : DStmt<Expr>; +def CharacterLiteral : DStmt<Expr>; +def ParenExpr : DStmt<Expr>; +def UnaryOperator : DStmt<Expr>; +def OffsetOfExpr : DStmt<Expr>; +def SizeOfAlignOfExpr : DStmt<Expr>; +def ArraySubscriptExpr : DStmt<Expr>; +def CallExpr : DStmt<Expr>; +def MemberExpr : DStmt<Expr>; +def CastExpr : DStmt<Expr, 1>; +def BinaryOperator : DStmt<Expr>; +def CompoundAssignOperator : DStmt<BinaryOperator>; +def ConditionalOperator : DStmt<Expr>; +def ImplicitCastExpr : DStmt<CastExpr>; +def ExplicitCastExpr : DStmt<CastExpr, 1>; +def CStyleCastExpr : DStmt<ExplicitCastExpr>; +def CompoundLiteralExpr : DStmt<Expr>; +def ExtVectorElementExpr : DStmt<Expr>; +def InitListExpr : DStmt<Expr>; +def DesignatedInitExpr : DStmt<Expr>; +def ImplicitValueInitExpr : DStmt<Expr>; +def ParenListExpr : DStmt<Expr>; +def VAArgExpr : DStmt<Expr>; + +// GNU Extensions. +def AddrLabelExpr : DStmt<Expr>; +def StmtExpr : DStmt<Expr>; +def TypesCompatibleExpr : DStmt<Expr>; +def ChooseExpr : DStmt<Expr>; +def GNUNullExpr : DStmt<Expr>; + +// C++ Expressions. +def CXXOperatorCallExpr : DStmt<CallExpr>; +def CXXMemberCallExpr : DStmt<CallExpr>; +def CXXNamedCastExpr : DStmt<ExplicitCastExpr, 1>; +def CXXStaticCastExpr : DStmt<CXXNamedCastExpr>; +def CXXDynamicCastExpr : DStmt<CXXNamedCastExpr>; +def CXXReinterpretCastExpr : DStmt<CXXNamedCastExpr>; +def CXXConstCastExpr : DStmt<CXXNamedCastExpr>; +def CXXFunctionalCastExpr : DStmt<ExplicitCastExpr>; +def CXXTypeidExpr : DStmt<Expr>; +def CXXBoolLiteralExpr : DStmt<Expr>; +def CXXNullPtrLiteralExpr : DStmt<Expr>; +def CXXThisExpr : DStmt<Expr>; +def CXXThrowExpr : DStmt<Expr>; +def CXXDefaultArgExpr : DStmt<Expr>; +def CXXZeroInitValueExpr : DStmt<Expr>; +def CXXNewExpr : DStmt<Expr>; +def CXXDeleteExpr : DStmt<Expr>; +def CXXPseudoDestructorExpr : DStmt<Expr>; +def UnresolvedLookupExpr : DStmt<Expr>; +def UnaryTypeTraitExpr : DStmt<Expr>; +def DependentScopeDeclRefExpr : DStmt<Expr>; +def CXXConstructExpr : DStmt<Expr>; +def CXXBindTemporaryExpr : DStmt<Expr>; +def CXXBindReferenceExpr : DStmt<Expr>; +def CXXExprWithTemporaries : DStmt<Expr>; +def CXXTemporaryObjectExpr : DStmt<CXXConstructExpr>; +def CXXUnresolvedConstructExpr : DStmt<Expr>; +def CXXDependentScopeMemberExpr : DStmt<Expr>; +def UnresolvedMemberExpr : DStmt<Expr>; + +// Obj-C Expressions. +def ObjCStringLiteral : DStmt<Expr>; +def ObjCEncodeExpr : DStmt<Expr>; +def ObjCMessageExpr : DStmt<Expr>; +def ObjCSelectorExpr : DStmt<Expr>; +def ObjCProtocolExpr : DStmt<Expr>; +def ObjCIvarRefExpr : DStmt<Expr>; +def ObjCPropertyRefExpr : DStmt<Expr>; +def ObjCImplicitSetterGetterRefExpr : DStmt<Expr>; +def ObjCSuperExpr : DStmt<Expr>; +def ObjCIsaExpr : DStmt<Expr>; + +// Clang Extensions. +def ShuffleVectorExpr : DStmt<Expr>; +def BlockExpr : DStmt<Expr>; +def BlockDeclRefExpr : DStmt<Expr>; diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h index 4986f08..8078451 100644 --- a/include/clang/AST/StmtVisitor.h +++ b/include/clang/AST/StmtVisitor.h @@ -105,10 +105,10 @@ public: // Top switch stmt: dispatch to VisitFooStmt for each FooStmt. switch (S->getStmtClass()) { default: assert(0 && "Unknown stmt kind!"); -#define ABSTRACT_EXPR(CLASS, PARENT) +#define ABSTRACT_STMT(STMT) #define STMT(CLASS, PARENT) \ case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS); -#include "clang/AST/StmtNodes.def" +#include "clang/AST/StmtNodes.inc" } } @@ -116,7 +116,7 @@ public: // back on VisitExpr or whatever else is the superclass. #define STMT(CLASS, PARENT) \ RetTy Visit ## CLASS(CLASS *S) { DISPATCH(PARENT, PARENT); } -#include "clang/AST/StmtNodes.def" +#include "clang/AST/StmtNodes.inc" // If the implementation doesn't implement binary operator methods, fall back // on VisitBinaryOperator. diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index 50a100c..8b38001 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -28,6 +28,7 @@ namespace llvm { namespace clang { class Decl; +class DiagnosticBuilder; class Expr; class TypeSourceInfo; @@ -473,6 +474,9 @@ public: } }; -} +const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + const TemplateArgument &Arg); + +} // end namespace clang #endif diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h index f3de9fa..2e3b6df 100644 --- a/include/clang/AST/TemplateName.h +++ b/include/clang/AST/TemplateName.h @@ -188,7 +188,7 @@ const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, /// declaration for "vector". The QualifiedTemplateName class is only /// used to provide "sugar" for template names that were expressed /// with a qualified name, and has no semantic meaning. In this -/// manner, it is to TemplateName what QualifiedNameType is to Type, +/// manner, it is to TemplateName what ElaboratedType is to Type, /// providing extra syntactic sugar for downstream clients. class QualifiedTemplateName : public llvm::FoldingSetNode { /// \brief The nested name specifier that qualifies the template name. diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 030c74c..c24bddb 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -92,7 +92,7 @@ namespace clang { class TemplateArgumentLoc; class TemplateArgumentListInfo; class Type; - class QualifiedNameType; + class ElaboratedType; struct PrintingPolicy; template <typename> class CanQual; @@ -396,7 +396,8 @@ enum CallingConv { CC_Default, CC_C, // __attribute__((cdecl)) CC_X86StdCall, // __attribute__((stdcall)) - CC_X86FastCall // __attribute__((fastcall)) + CC_X86FastCall, // __attribute__((fastcall)) + CC_X86ThisCall // __attribute__((thiscall)) }; @@ -755,6 +756,9 @@ public: }; private: + Type(const Type&); // DO NOT IMPLEMENT. + void operator=(const Type&); // DO NOT IMPLEMENT. + QualType CanonicalType; /// TypeClass bitfield - Enum that specifies what subclass this belongs to. @@ -764,15 +768,25 @@ private: /// Note that this should stay at the end of the ivars for Type so that /// subclasses can pack their bitfields into the same word. bool Dependent : 1; - - Type(const Type&); // DO NOT IMPLEMENT. - void operator=(const Type&); // DO NOT IMPLEMENT. + + /// \brief Whether the linkage of this type is already known. + mutable bool LinkageKnown : 1; + + /// \brief Linkage of this type. + mutable unsigned CachedLinkage : 2; + protected: + /// \brief Compute the linkage of this type. + virtual Linkage getLinkageImpl() const; + + enum { BitsRemainingInType = 20 }; + // silence VC++ warning C4355: 'this' : used in base member initializer list Type *this_() { return this; } Type(TypeClass tc, QualType Canonical, bool dependent) : CanonicalType(Canonical.isNull() ? QualType(this_(), 0) : Canonical), - TC(tc), Dependent(dependent) {} + TC(tc), Dependent(dependent), LinkageKnown(false), + CachedLinkage(NoLinkage) {} virtual ~Type() {} virtual void Destroy(ASTContext& C); friend class ASTContext; @@ -879,7 +893,7 @@ public: bool isObjCObjectPointerType() const; // Pointer to *any* ObjC object. // FIXME: change this to 'raw' interface type, so we can used 'interface' type // for the common case. - bool isObjCInterfaceType() const; // NSString or NSString<foo> + bool isObjCObjectType() const; // NSString or typeof(*(id)0) bool isObjCQualifiedInterfaceType() const; // NSString<foo> bool isObjCQualifiedIdType() const; // id<foo> bool isObjCQualifiedClassType() const; // Class<foo> @@ -920,7 +934,7 @@ public: // for object declared using an interface. const ObjCObjectPointerType *getAsObjCInterfacePointerType() const; const ObjCObjectPointerType *getAsObjCQualifiedIdType() const; - const ObjCInterfaceType *getAsObjCQualifiedInterfaceType() const; + const ObjCObjectType *getAsObjCQualifiedInterfaceType() const; const CXXRecordDecl *getCXXRecordDeclForPointerType() const; /// \brief Retrieves the CXXRecordDecl that this type refers to, either @@ -935,10 +949,6 @@ public: // immediately following this class. template <typename T> const T *getAs() const; - /// getAsPointerToObjCInterfaceType - If this is a pointer to an ObjC - /// interface, return the interface type, otherwise return null. - const ObjCInterfaceType *getAsPointerToObjCInterfaceType() const; - /// getArrayElementTypeNoTypeQual - If this is an array type, return the /// element type of the array, potentially with type qualifiers missing. /// This method should never be used when type qualifiers are meaningful. @@ -977,10 +987,13 @@ public: /// set of type specifiers. bool isSpecifierType() const; - const char *getTypeClassName() const; - /// \brief Determine the linkage of this type. - virtual Linkage getLinkage() const; + Linkage getLinkage() const; + + /// \brief Note that the linkage is no longer known. + void ClearLinkageCache(); + + const char *getTypeClassName() const; QualType getCanonicalTypeInternal() const { return CanonicalType; @@ -1040,12 +1053,25 @@ 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. + + /// The primitive Objective C 'id' type. The type pointed to by the + /// user-visible 'id' type. Only ever shows up in an AST as the base + /// type of an ObjCObjectType. + ObjCId, + + /// The primitive Objective C 'Class' type. The type pointed to by the + /// user-visible 'Class' type. Only ever shows up in an AST as the + /// base type of an ObjCObjectType. + ObjCClass, + ObjCSel // This represents the ObjC 'SEL' type. }; private: Kind TypeKind; + +protected: + virtual Linkage getLinkageImpl() const; + public: BuiltinType(Kind K) : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent)), @@ -1073,8 +1099,6 @@ public: return TypeKind >= Float && TypeKind <= LongDouble; } - virtual Linkage getLinkage() const; - static bool classof(const Type *T) { return T->getTypeClass() == Builtin; } static bool classof(const BuiltinType *) { return true; } }; @@ -1089,6 +1113,10 @@ class ComplexType : public Type, public llvm::FoldingSetNode { ElementType(Element) { } friend class ASTContext; // ASTContext creates these. + +protected: + virtual Linkage getLinkageImpl() const; + public: QualType getElementType() const { return ElementType; } @@ -1102,8 +1130,6 @@ public: ID.AddPointer(Element.getAsOpaquePtr()); } - virtual Linkage getLinkage() const; - static bool classof(const Type *T) { return T->getTypeClass() == Complex; } static bool classof(const ComplexType *) { return true; } }; @@ -1117,6 +1143,10 @@ class PointerType : public Type, public llvm::FoldingSetNode { Type(Pointer, CanonicalPtr, Pointee->isDependentType()), PointeeType(Pointee) { } friend class ASTContext; // ASTContext creates these. + +protected: + virtual Linkage getLinkageImpl() const; + public: QualType getPointeeType() const { return PointeeType; } @@ -1131,8 +1161,6 @@ public: ID.AddPointer(Pointee.getAsOpaquePtr()); } - virtual Linkage getLinkage() const; - static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } static bool classof(const PointerType *) { return true; } }; @@ -1148,6 +1176,10 @@ class BlockPointerType : public Type, public llvm::FoldingSetNode { PointeeType(Pointee) { } friend class ASTContext; // ASTContext creates these. + +protected: + virtual Linkage getLinkageImpl() const; + public: // Get the pointee type. Pointee is required to always be a function type. @@ -1163,8 +1195,6 @@ public: ID.AddPointer(Pointee.getAsOpaquePtr()); } - virtual Linkage getLinkage() const; - static bool classof(const Type *T) { return T->getTypeClass() == BlockPointer; } @@ -1200,6 +1230,9 @@ protected: PointeeType(Referencee), SpelledAsLValue(SpelledAsLValue), InnerRef(Referencee->isReferenceType()) { } + + virtual Linkage getLinkageImpl() const; + public: bool isSpelledAsLValue() const { return SpelledAsLValue; } bool isInnerRef() const { return InnerRef; } @@ -1223,8 +1256,6 @@ public: ID.AddBoolean(SpelledAsLValue); } - virtual Linkage getLinkage() const; - static bool classof(const Type *T) { return T->getTypeClass() == LValueReference || T->getTypeClass() == RValueReference; @@ -1281,6 +1312,10 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode { PointeeType(Pointee), Class(Cls) { } friend class ASTContext; // ASTContext creates these. + +protected: + virtual Linkage getLinkageImpl() const; + public: QualType getPointeeType() const { return PointeeType; } @@ -1299,8 +1334,6 @@ public: ID.AddPointer(Class); } - virtual Linkage getLinkage() const; - static bool classof(const Type *T) { return T->getTypeClass() == MemberPointer; } @@ -1342,6 +1375,9 @@ protected: ElementType(et), SizeModifier(sm), IndexTypeQuals(tq) {} friend class ASTContext; // ASTContext creates these. + + virtual Linkage getLinkageImpl() const; + public: QualType getElementType() const { return ElementType; } ArraySizeModifier getSizeModifier() const { @@ -1352,8 +1388,6 @@ public: } unsigned getIndexTypeCVRQualifiers() const { return IndexTypeQuals; } - virtual Linkage getLinkage() const; - static bool classof(const Type *T) { return T->getTypeClass() == ConstantArray || T->getTypeClass() == VariableArray || @@ -1629,6 +1663,9 @@ protected: : Type(tc, canonType, vecType->isDependentType()), ElementType(vecType), NumElements(nElements), AltiVec(isAltiVec), Pixel(isPixel) {} friend class ASTContext; // ASTContext creates these. + + virtual Linkage getLinkageImpl() const; + public: QualType getElementType() const { return ElementType; } @@ -1655,8 +1692,6 @@ public: ID.AddBoolean(isPixel); } - virtual Linkage getLinkage() const; - static bool classof(const Type *T) { return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector; } @@ -1733,6 +1768,8 @@ public: /// class of FunctionNoProtoType and FunctionProtoType. /// class FunctionType : public Type { + virtual void ANCHOR(); // Key function for FunctionType. + /// SubClassData - This field is owned by the subclass, put here to pack /// tightly with the ivars in Type. bool SubClassData : 1; @@ -1753,7 +1790,7 @@ class FunctionType : public Type { unsigned RegParm : 3; /// CallConv - The calling convention used by the function. - unsigned CallConv : 2; + unsigned CallConv : 3; // The type returned by the function. QualType ResultType; @@ -1821,7 +1858,7 @@ class FunctionType : public Type { // The value passed to __attribute__((regparm(x))) unsigned RegParm; // The calling convention as specified via - // __attribute__((cdecl|stdcall||fastcall)) + // __attribute__((cdecl|stdcall|fastcall|thiscall)) CallingConv CC; }; @@ -1862,6 +1899,10 @@ class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { : FunctionType(FunctionNoProto, Result, false, 0, Canonical, /*Dependent=*/false, Info) {} friend class ASTContext; // ASTContext creates these. + +protected: + virtual Linkage getLinkageImpl() const; + public: // No additional state past what FunctionType provides. @@ -1879,8 +1920,6 @@ public: ID.AddPointer(ResultType.getAsOpaquePtr()); } - virtual Linkage getLinkage() const; - static bool classof(const Type *T) { return T->getTypeClass() == FunctionNoProto; } @@ -1944,6 +1983,9 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these. +protected: + virtual Linkage getLinkageImpl() const; + public: unsigned getNumArgs() const { return NumArgs; } QualType getArgType(unsigned i) const { @@ -1984,8 +2026,6 @@ public: bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } - virtual Linkage getLinkage() const; - static bool classof(const Type *T) { return T->getTypeClass() == FunctionProto; } @@ -2190,6 +2230,8 @@ class TagType : public Type { protected: TagType(TypeClass TC, const TagDecl *D, QualType can); + virtual Linkage getLinkageImpl() const; + public: TagDecl *getDecl() const { return decl.getPointer(); } @@ -2198,8 +2240,6 @@ public: bool isBeingDefined() const { return decl.getInt(); } void setBeingDefined(bool Def) const { decl.setInt(Def? 1 : 0); } - virtual Linkage getLinkage() const; - static bool classof(const Type *T) { return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast; } @@ -2264,68 +2304,6 @@ public: static bool classof(const EnumType *) { return true; } }; -/// ElaboratedType - A non-canonical type used to represents uses of -/// elaborated type specifiers in C++. For example: -/// -/// void foo(union MyUnion); -/// ^^^^^^^^^^^^^ -/// -/// At the moment, for efficiency we do not create elaborated types in -/// C, since outside of typedefs all references to structs would -/// necessarily be elaborated. -class ElaboratedType : public Type, public llvm::FoldingSetNode { -public: - enum TagKind { - TK_struct, - TK_union, - TK_class, - TK_enum - }; - -private: - /// The tag that was used in this elaborated type specifier. - TagKind Tag; - - /// The underlying type. - QualType UnderlyingType; - - explicit ElaboratedType(QualType Ty, TagKind Tag, QualType Canon) - : Type(Elaborated, Canon, Canon->isDependentType()), - Tag(Tag), UnderlyingType(Ty) { } - friend class ASTContext; // ASTContext creates these. - -public: - TagKind getTagKind() const { return Tag; } - QualType getUnderlyingType() const { return UnderlyingType; } - - /// \brief Remove a single level of sugar. - QualType desugar() const { return getUnderlyingType(); } - - /// \brief Returns whether this type directly provides sugar. - bool isSugared() const { return true; } - - static const char *getNameForTagKind(TagKind Kind) { - switch (Kind) { - default: assert(0 && "Unknown TagKind!"); - case TK_struct: return "struct"; - case TK_union: return "union"; - case TK_class: return "class"; - case TK_enum: return "enum"; - } - } - - void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getUnderlyingType(), getTagKind()); - } - static void Profile(llvm::FoldingSetNodeID &ID, QualType T, TagKind Tag) { - ID.AddPointer(T.getAsOpaquePtr()); - ID.AddInteger(Tag); - } - - static bool classof(const ElaboratedType*) { return true; } - static bool classof(const Type *T) { return T->getTypeClass() == Elaborated; } -}; - class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { unsigned Depth : 15; unsigned Index : 16; @@ -2592,46 +2570,116 @@ public: static bool classof(const InjectedClassNameType *T) { return true; } }; +/// \brief The kind of a tag type. +enum TagTypeKind { + /// \brief The "struct" keyword. + TTK_Struct, + /// \brief The "union" keyword. + TTK_Union, + /// \brief The "class" keyword. + TTK_Class, + /// \brief The "enum" keyword. + TTK_Enum +}; + /// \brief The elaboration keyword that precedes a qualified type name or /// introduces an elaborated-type-specifier. enum ElaboratedTypeKeyword { - /// \brief No keyword precedes the qualified type name. - ETK_None, - /// \brief The "typename" keyword precedes the qualified type name, e.g., - /// \c typename T::type. - ETK_Typename, - /// \brief The "class" keyword introduces the elaborated-type-specifier. - ETK_Class, /// \brief The "struct" keyword introduces the elaborated-type-specifier. ETK_Struct, /// \brief The "union" keyword introduces the elaborated-type-specifier. ETK_Union, + /// \brief The "class" keyword introduces the elaborated-type-specifier. + ETK_Class, /// \brief The "enum" keyword introduces the elaborated-type-specifier. - ETK_Enum + ETK_Enum, + /// \brief The "typename" keyword precedes the qualified type name, e.g., + /// \c typename T::type. + ETK_Typename, + /// \brief No keyword precedes the qualified type name. + ETK_None }; - -/// \brief Represents a type that was referred to via a qualified -/// name, e.g., N::M::type. + +/// A helper class for Type nodes having an ElaboratedTypeKeyword. +/// The keyword in stored in the free bits of the base class. +/// Also provides a few static helpers for converting and printing +/// elaborated type keyword and tag type kind enumerations. +class TypeWithKeyword : public Type { + /// Keyword - Encodes an ElaboratedTypeKeyword enumeration constant. + unsigned Keyword : 3; + +protected: + TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc, + QualType Canonical, bool dependent) + : Type(tc, Canonical, dependent), Keyword(Keyword) {} + +public: + virtual ~TypeWithKeyword(); // pin vtable to Type.cpp + + ElaboratedTypeKeyword getKeyword() const { + return static_cast<ElaboratedTypeKeyword>(Keyword); + } + + /// getKeywordForTypeSpec - Converts a type specifier (DeclSpec::TST) + /// into an elaborated type keyword. + static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec); + + /// getTagTypeKindForTypeSpec - Converts a type specifier (DeclSpec::TST) + /// into a tag type kind. It is an error to provide a type specifier + /// which *isn't* a tag kind here. + static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec); + + /// getKeywordForTagDeclKind - Converts a TagTypeKind into an + /// elaborated type keyword. + static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag); + + /// getTagTypeKindForKeyword - Converts an elaborated type keyword into + // a TagTypeKind. It is an error to provide an elaborated type keyword + /// which *isn't* a tag kind here. + static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword); + + static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword); + + static const char *getKeywordName(ElaboratedTypeKeyword Keyword); + + static const char *getTagTypeKindName(TagTypeKind Kind) { + return getKeywordName(getKeywordForTagTypeKind(Kind)); + } + + class CannotCastToThisType {}; + static CannotCastToThisType classof(const Type *); +}; + +/// \brief Represents a type that was referred to using an elaborated type +/// keyword, e.g., struct S, or via a qualified name, e.g., N::M::type, +/// or both. /// /// This type is used to keep track of a type name as written in the -/// source code, including any nested-name-specifiers. The type itself -/// is always "sugar", used to express what was written in the source -/// code but containing no additional semantic information. -class QualifiedNameType : public Type, public llvm::FoldingSetNode { +/// source code, including tag keywords and any nested-name-specifiers. +/// The type itself is always "sugar", used to express what was written +/// in the source code but containing no additional semantic information. +class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode { + /// \brief The nested name specifier containing the qualifier. NestedNameSpecifier *NNS; /// \brief The type that this qualified name refers to. QualType NamedType; - QualifiedNameType(NestedNameSpecifier *NNS, QualType NamedType, - QualType CanonType) - : Type(QualifiedName, CanonType, NamedType->isDependentType()), - NNS(NNS), NamedType(NamedType) { } + ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, + QualType NamedType, QualType CanonType) + : TypeWithKeyword(Keyword, Elaborated, CanonType, + NamedType->isDependentType()), + NNS(NNS), NamedType(NamedType) { + assert(!(Keyword == ETK_None && NNS == 0) && + "ElaboratedType cannot have elaborated type keyword " + "and name qualifier both null."); + } friend class ASTContext; // ASTContext creates these public: + /// \brief Retrieve the qualification on this type. NestedNameSpecifier *getQualifier() const { return NNS; } @@ -2645,19 +2693,20 @@ public: bool isSugared() const { return true; } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, NNS, NamedType); + Profile(ID, getKeyword(), NNS, NamedType); } - static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, - QualType NamedType) { + static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword, + NestedNameSpecifier *NNS, QualType NamedType) { + ID.AddInteger(Keyword); ID.AddPointer(NNS); NamedType.Profile(ID); } static bool classof(const Type *T) { - return T->getTypeClass() == QualifiedName; + return T->getTypeClass() == Elaborated; } - static bool classof(const QualifiedNameType *T) { return true; } + static bool classof(const ElaboratedType *T) { return true; } }; /// \brief Represents a qualified type name for which the type name is @@ -2669,10 +2718,8 @@ public: /// typename-specifier), "class", "struct", "union", or "enum" (for a /// dependent elaborated-type-specifier), or nothing (in contexts where we /// know that we must be referring to a type, e.g., in a base class specifier). -class DependentNameType : public Type, public llvm::FoldingSetNode { - /// \brief The keyword used to elaborate this type. - ElaboratedTypeKeyword Keyword; - +class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode { + /// \brief The nested name specifier containing the qualifier. NestedNameSpecifier *NNS; @@ -2684,16 +2731,16 @@ class DependentNameType : public Type, public llvm::FoldingSetNode { DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, QualType CanonType) - : Type(DependentName, CanonType, true), - Keyword(Keyword), NNS(NNS), Name(Name) { + : TypeWithKeyword(Keyword, DependentName, CanonType, true), + NNS(NNS), Name(Name) { assert(NNS->isDependent() && "DependentNameType requires a dependent nested-name-specifier"); } DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const TemplateSpecializationType *Ty, QualType CanonType) - : Type(DependentName, CanonType, true), - Keyword(Keyword), NNS(NNS), Name(Ty) { + : TypeWithKeyword(Keyword, DependentName, CanonType, true), + NNS(NNS), Name(Ty) { assert(NNS->isDependent() && "DependentNameType requires a dependent nested-name-specifier"); } @@ -2701,9 +2748,7 @@ class DependentNameType : public Type, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these public: - /// \brief Retrieve the keyword used to elaborate this type. - ElaboratedTypeKeyword getKeyword() const { return Keyword; } - + /// \brief Retrieve the qualification on this type. NestedNameSpecifier *getQualifier() const { return NNS; } @@ -2727,7 +2772,7 @@ public: QualType desugar() const { return QualType(this, 0); } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, Keyword, NNS, Name); + Profile(ID, getKeyword(), NNS, Name); } static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword, @@ -2743,153 +2788,333 @@ public: static bool classof(const DependentNameType *T) { return true; } }; -/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for -/// object oriented design. They basically correspond to C++ classes. There -/// are two kinds of interface types, normal interfaces like "NSString" and -/// qualified interfaces, which are qualified with a protocol list like -/// "NSString<NSCopyable, NSAmazing>". -class ObjCInterfaceType : public Type, public llvm::FoldingSetNode { - ObjCInterfaceDecl *Decl; +/// ObjCObjectType - Represents a class type in Objective C. +/// Every Objective C type is a combination of a base type and a +/// list of protocols. +/// +/// Given the following declarations: +/// @class C; +/// @protocol P; +/// +/// 'C' is an ObjCInterfaceType C. It is sugar for an ObjCObjectType +/// with base C and no protocols. +/// +/// 'C<P>' is an ObjCObjectType with base C and protocol list [P]. +/// +/// 'id' is a TypedefType which is sugar for an ObjCPointerType whose +/// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType +/// and no protocols. +/// +/// 'id<P>' is an ObjCPointerType whose pointee is an ObjCObjecType +/// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually +/// this should get its own sugar class to better represent the source. +class ObjCObjectType : public Type { + // Pad the bit count up so that NumProtocols is 2-byte aligned + unsigned : BitsRemainingInType - 16; + + /// \brief The number of protocols stored after the + /// ObjCObjectPointerType node. + /// + /// These protocols are those written directly on the type. If + /// protocol qualifiers ever become additive, the iterators will + /// get kindof complicated. + /// + /// In the canonical object type, these are sorted alphabetically + /// and uniqued. + unsigned NumProtocols : 16; - /// \brief The number of protocols stored after the ObjCInterfaceType node. - /// The list of protocols is sorted on protocol name. No protocol is enterred - /// more than once. - unsigned NumProtocols; + /// Either a BuiltinType or an InterfaceType or sugar for either. + QualType BaseType; - ObjCInterfaceType(QualType Canonical, ObjCInterfaceDecl *D, - ObjCProtocolDecl **Protos, unsigned NumP); - friend class ASTContext; // ASTContext creates these. + ObjCProtocolDecl * const *getProtocolStorage() const { + return const_cast<ObjCObjectType*>(this)->getProtocolStorage(); + } + + ObjCProtocolDecl **getProtocolStorage(); + +protected: + ObjCObjectType(QualType Canonical, QualType Base, + ObjCProtocolDecl * const *Protocols, unsigned NumProtocols); + + enum Nonce_ObjCInterface { Nonce_ObjCInterface }; + ObjCObjectType(enum Nonce_ObjCInterface) + : Type(ObjCInterface, QualType(), false), + NumProtocols(0), + BaseType(QualType(this_(), 0)) {} + +protected: + Linkage getLinkageImpl() const; // key function + public: - void Destroy(ASTContext& C); + /// getBaseType - Gets the base type of this object type. This is + /// always (possibly sugar for) one of: + /// - the 'id' builtin type (as opposed to the 'id' type visible to the + /// user, which is a typedef for an ObjCPointerType) + /// - the 'Class' builtin type (same caveat) + /// - an ObjCObjectType (currently always an ObjCInterfaceType) + QualType getBaseType() const { return BaseType; } + + bool isObjCId() const { + return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId); + } + bool isObjCClass() const { + return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass); + } + bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); } + bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); } + bool isObjCUnqualifiedIdOrClass() const { + if (!qual_empty()) return false; + if (const BuiltinType *T = getBaseType()->getAs<BuiltinType>()) + return T->getKind() == BuiltinType::ObjCId || + T->getKind() == BuiltinType::ObjCClass; + return false; + } + bool isObjCQualifiedId() const { return !qual_empty() && isObjCId(); } + bool isObjCQualifiedClass() const { return !qual_empty() && isObjCClass(); } - ObjCInterfaceDecl *getDecl() const { return Decl; } + /// Gets the interface declaration for this object type, if the base type + /// really is an interface. + ObjCInterfaceDecl *getInterface() const; + + typedef ObjCProtocolDecl * const *qual_iterator; + + qual_iterator qual_begin() const { return getProtocolStorage(); } + qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); } + + bool qual_empty() const { return getNumProtocols() == 0; } /// getNumProtocols - Return the number of qualifying protocols in this /// interface type, or 0 if there are none. unsigned getNumProtocols() const { return NumProtocols; } - /// \brief Retrieve the Ith protocol. + /// \brief Fetch a protocol by index. ObjCProtocolDecl *getProtocol(unsigned I) const { assert(I < getNumProtocols() && "Out-of-range protocol access"); return qual_begin()[I]; } - /// qual_iterator and friends: this provides access to the (potentially empty) - /// list of protocols qualifying this interface. - typedef ObjCProtocolDecl* const * qual_iterator; - qual_iterator qual_begin() const { - return reinterpret_cast<qual_iterator>(this + 1); - } - qual_iterator qual_end() const { - return qual_begin() + NumProtocols; - } - bool qual_empty() const { return NumProtocols == 0; } - bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } + static bool classof(const Type *T) { + return T->getTypeClass() == ObjCObject || + T->getTypeClass() == ObjCInterface; + } + static bool classof(const ObjCObjectType *) { return true; } +}; + +/// ObjCObjectTypeImpl - A class providing a concrete implementation +/// of ObjCObjectType, so as to not increase the footprint of +/// ObjCInterfaceType. Code outside of ASTContext and the core type +/// system should not reference this type. +class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode { + friend class ASTContext; + + // If anyone adds fields here, ObjCObjectType::getProtocolStorage() + // will need to be modified. + + ObjCObjectTypeImpl(QualType Canonical, QualType Base, + ObjCProtocolDecl * const *Protocols, + unsigned NumProtocols) + : ObjCObjectType(Canonical, Base, Protocols, NumProtocols) {} + +public: + void Destroy(ASTContext& C); // key function + void Profile(llvm::FoldingSetNodeID &ID); static void Profile(llvm::FoldingSetNodeID &ID, - const ObjCInterfaceDecl *Decl, - ObjCProtocolDecl * const *protocols, - unsigned NumProtocols); + QualType Base, + ObjCProtocolDecl *const *protocols, + unsigned NumProtocols); +}; - virtual Linkage getLinkage() const; +inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() { + return reinterpret_cast<ObjCProtocolDecl**>( + static_cast<ObjCObjectTypeImpl*>(this) + 1); +} + +/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for +/// object oriented design. They basically correspond to C++ classes. There +/// are two kinds of interface types, normal interfaces like "NSString" and +/// qualified interfaces, which are qualified with a protocol list like +/// "NSString<NSCopyable, NSAmazing>". +/// +/// ObjCInterfaceType guarantees the following properties when considered +/// as a subtype of its superclass, ObjCObjectType: +/// - There are no protocol qualifiers. To reinforce this, code which +/// tries to invoke the protocol methods via an ObjCInterfaceType will +/// fail to compile. +/// - It is its own base type. That is, if T is an ObjCInterfaceType*, +/// T->getBaseType() == QualType(T, 0). +class ObjCInterfaceType : public ObjCObjectType { + ObjCInterfaceDecl *Decl; + + ObjCInterfaceType(const ObjCInterfaceDecl *D) + : ObjCObjectType(Nonce_ObjCInterface), + Decl(const_cast<ObjCInterfaceDecl*>(D)) {} + friend class ASTContext; // ASTContext creates these. +public: + void Destroy(ASTContext& C); // key function + + /// getDecl - Get the declaration of this interface. + ObjCInterfaceDecl *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() == ObjCInterface; } static bool classof(const ObjCInterfaceType *) { return true; } + + // Nonsense to "hide" certain members of ObjCObjectType within this + // class. People asking for protocols on an ObjCInterfaceType are + // not going to get what they want: ObjCInterfaceTypes are + // guaranteed to have no protocols. + enum { + qual_iterator, + qual_begin, + qual_end, + getNumProtocols, + getProtocol + }; }; -/// ObjCObjectPointerType - Used to represent 'id', 'Interface *', 'id <p>', -/// and 'Interface <p> *'. +inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const { + if (const ObjCInterfaceType *T = + getBaseType()->getAs<ObjCInterfaceType>()) + return T->getDecl(); + return 0; +} + +/// ObjCObjectPointerType - Used to represent a pointer to an +/// Objective C object. These are constructed from pointer +/// declarators when the pointee type is an ObjCObjectType (or sugar +/// for one). In addition, the 'id' and 'Class' types are typedefs +/// for these, and the protocol-qualified types 'id<P>' and 'Class<P>' +/// are translated into these. /// -/// Duplicate protocols are removed and protocol list is canonicalized to be in -/// alphabetical order. +/// Pointers to pointers to Objective C objects are still PointerTypes; +/// only the first level of pointer gets it own type implementation. class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { - QualType PointeeType; // A builtin or interface type. - - /// \brief The number of protocols stored after the ObjCObjectPointerType - /// node. - /// - /// The list of protocols is sorted on protocol name. No protocol is enterred - /// more than once. - unsigned NumProtocols; + QualType PointeeType; - ObjCObjectPointerType(QualType Canonical, QualType T, - ObjCProtocolDecl **Protos, unsigned NumP); + ObjCObjectPointerType(QualType Canonical, QualType Pointee) + : Type(ObjCObjectPointer, Canonical, false), + PointeeType(Pointee) {} friend class ASTContext; // ASTContext creates these. +protected: + virtual Linkage getLinkageImpl() const; + public: void Destroy(ASTContext& C); - // Get the pointee type. Pointee will either be: - // - a built-in type (for 'id' and 'Class'). - // - an interface type (for user-defined types). - // - a TypedefType whose canonical type is an interface (as in 'T' below). - // For example: typedef NSObject T; T *var; + /// getPointeeType - Gets the type pointed to by this ObjC pointer. + /// The result will always be an ObjCObjectType or sugar thereof. QualType getPointeeType() const { return PointeeType; } + /// getObjCObjectType - Gets the type pointed to by this ObjC + /// pointer. This method always returns non-null. + /// + /// This method is equivalent to getPointeeType() except that + /// it discards any typedefs (or other sugar) between this + /// type and the "outermost" object type. So for: + /// @class A; @protocol P; @protocol Q; + /// typedef A<P> AP; + /// typedef A A1; + /// typedef A1<P> A1P; + /// typedef A1P<Q> A1PQ; + /// For 'A*', getObjectType() will return 'A'. + /// For 'A<P>*', getObjectType() will return 'A<P>'. + /// For 'AP*', getObjectType() will return 'A<P>'. + /// For 'A1*', getObjectType() will return 'A'. + /// For 'A1<P>*', getObjectType() will return 'A1<P>'. + /// For 'A1P*', getObjectType() will return 'A1<P>'. + /// For 'A1PQ*', getObjectType() will return 'A1<Q>', because + /// adding protocols to a protocol-qualified base discards the + /// old qualifiers (for now). But if it didn't, getObjectType() + /// would return 'A1P<Q>' (and we'd have to make iterating over + /// qualifiers more complicated). + const ObjCObjectType *getObjectType() const { + return PointeeType->getAs<ObjCObjectType>(); + } + + /// getInterfaceType - If this pointer points to an Objective C + /// @interface type, gets the type for that interface. Any protocol + /// qualifiers on the interface are ignored. + /// + /// \return null if the base type for this pointer is 'id' or 'Class' const ObjCInterfaceType *getInterfaceType() const { - return PointeeType->getAs<ObjCInterfaceType>(); + return getObjectType()->getBaseType()->getAs<ObjCInterfaceType>(); } - /// getInterfaceDecl - returns an interface decl for user-defined types. + + /// getInterfaceDecl - If this pointer points to an Objective @interface + /// type, gets the declaration for that interface. + /// + /// \return null if the base type for this pointer is 'id' or 'Class' ObjCInterfaceDecl *getInterfaceDecl() const { - return getInterfaceType() ? getInterfaceType()->getDecl() : 0; + return getObjectType()->getInterface(); } - /// isObjCIdType - true for "id". + + /// isObjCIdType - True if this is equivalent to the 'id' type, i.e. if + /// its object type is the primitive 'id' type with no protocols. bool isObjCIdType() const { - return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) && - !NumProtocols; + return getObjectType()->isObjCUnqualifiedId(); } - /// isObjCClassType - true for "Class". + + /// isObjCClassType - True if this is equivalent to the 'Class' type, + /// i.e. if its object tive is the primitive 'Class' type with no protocols. bool isObjCClassType() const { - return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) && - !NumProtocols; + return getObjectType()->isObjCUnqualifiedClass(); } - /// isObjCQualifiedIdType - true for "id <p>". + /// isObjCQualifiedIdType - True if this is equivalent to 'id<P>' for some + /// non-empty set of protocols. bool isObjCQualifiedIdType() const { - return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) && - NumProtocols; + return getObjectType()->isObjCQualifiedId(); } - /// isObjCQualifiedClassType - true for "Class <p>". + + /// isObjCQualifiedClassType - True if this is equivalent to 'Class<P>' for + /// some non-empty set of protocols. bool isObjCQualifiedClassType() const { - return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) && - NumProtocols; + return getObjectType()->isObjCQualifiedClass(); } - /// qual_iterator and friends: this provides access to the (potentially empty) - /// list of protocols qualifying this interface. - typedef ObjCProtocolDecl* const * qual_iterator; + + /// An iterator over the qualifiers on the object type. Provided + /// for convenience. This will always iterate over the full set of + /// protocols on a type, not just those provided directly. + typedef ObjCObjectType::qual_iterator qual_iterator; qual_iterator qual_begin() const { - return reinterpret_cast<qual_iterator> (this + 1); + return getObjectType()->qual_begin(); } - qual_iterator qual_end() const { - return qual_begin() + NumProtocols; + qual_iterator qual_end() const { + return getObjectType()->qual_end(); } - bool qual_empty() const { return NumProtocols == 0; } + bool qual_empty() const { return getObjectType()->qual_empty(); } - /// getNumProtocols - Return the number of qualifying protocols in this - /// interface type, or 0 if there are none. - unsigned getNumProtocols() const { return NumProtocols; } + /// getNumProtocols - Return the number of qualifying protocols on + /// the object type. + unsigned getNumProtocols() const { + return getObjectType()->getNumProtocols(); + } - /// \brief Retrieve the Ith protocol. + /// \brief Retrieve a qualifying protocol by index on the object + /// type. ObjCProtocolDecl *getProtocol(unsigned I) const { - assert(I < getNumProtocols() && "Out-of-range protocol access"); - return qual_begin()[I]; + return getObjectType()->getProtocol(I); } bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } - virtual Linkage getLinkage() const; - - void Profile(llvm::FoldingSetNodeID &ID); - static void Profile(llvm::FoldingSetNodeID &ID, QualType T, - ObjCProtocolDecl *const *protocols, - unsigned NumProtocols); + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, getPointeeType()); + } + static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { + ID.AddPointer(T.getAsOpaquePtr()); + } static bool classof(const Type *T) { return T->getTypeClass() == ObjCObjectPointer; } @@ -3128,12 +3353,6 @@ inline QualType QualType::getNonReferenceType() const { return *this; } -inline const ObjCInterfaceType *Type::getAsPointerToObjCInterfaceType() const { - if (const PointerType *PT = getAs<PointerType>()) - return PT->getPointeeType()->getAs<ObjCInterfaceType>(); - return 0; -} - inline bool Type::isFunctionType() const { return isa<FunctionType>(CanonicalType); } @@ -3200,8 +3419,8 @@ inline bool Type::isExtVectorType() const { inline bool Type::isObjCObjectPointerType() const { return isa<ObjCObjectPointerType>(CanonicalType); } -inline bool Type::isObjCInterfaceType() const { - return isa<ObjCInterfaceType>(CanonicalType); +inline bool Type::isObjCObjectType() const { + return isa<ObjCObjectType>(CanonicalType); } inline bool Type::isObjCQualifiedIdType() const { if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) @@ -3250,13 +3469,11 @@ inline bool Type::isOverloadableType() const { inline bool Type::hasPointerRepresentation() const { return (isPointerType() || isReferenceType() || isBlockPointerType() || - isObjCInterfaceType() || isObjCObjectPointerType() || - isObjCQualifiedInterfaceType() || isNullPtrType()); + isObjCObjectPointerType() || isNullPtrType()); } inline bool Type::hasObjCPointerRepresentation() const { - return (isObjCInterfaceType() || isObjCObjectPointerType() || - isObjCQualifiedInterfaceType()); + return isObjCObjectPointerType(); } /// Insertion operator for diagnostics. This allows sending QualType's into a diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index a51da74..f988f0e 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_TYPELOC_H #include "clang/AST/Type.h" +#include "clang/AST/Decl.h" #include "clang/AST/TemplateBase.h" #include "clang/Basic/Specifiers.h" @@ -84,21 +85,20 @@ public: return Data; } + /// \brief Get the begin source location. + SourceLocation getBeginLoc() const; + + /// \brief Get the end source location. + SourceLocation getEndLoc() const; + /// \brief Get the full source range. - SourceRange getFullSourceRange() const { - SourceLocation End = getSourceRange().getEnd(); - TypeLoc Cur = *this; - while (true) { - TypeLoc Next = Cur.getNextTypeLoc(); - if (Next.isNull()) break; - Cur = Next; - } - return SourceRange(Cur.getSourceRange().getBegin(), End); + SourceRange getSourceRange() const { + return SourceRange(getBeginLoc(), getEndLoc()); } /// \brief Get the local source range. - SourceRange getSourceRange() const { - return getSourceRangeImpl(*this); + SourceRange getLocalSourceRange() const { + return getLocalSourceRangeImpl(*this); } /// \brief Returns the size of the type source info data block. @@ -137,9 +137,14 @@ public: private: static void initializeImpl(TypeLoc TL, SourceLocation Loc); static TypeLoc getNextTypeLocImpl(TypeLoc TL); - static SourceRange getSourceRangeImpl(TypeLoc TL); + static SourceRange getLocalSourceRangeImpl(TypeLoc TL); }; +/// \brief Return the TypeLoc for a type source info. +inline TypeLoc TypeSourceInfo::getTypeLoc() const { + return TypeLoc(Ty, (void*)(this + 1)); +} + /// \brief Wrapper of type source information for a type with /// no direct quqlaifiers. class UnqualTypeLoc : public TypeLoc { @@ -168,7 +173,7 @@ public: /// type qualifiers. class QualifiedTypeLoc : public TypeLoc { public: - SourceRange getSourceRange() const { + SourceRange getLocalSourceRange() const { return SourceRange(); } @@ -263,6 +268,16 @@ public: return TypeClass::classof(Ty); } + static bool classof(const TypeLoc *TL) { + return Derived::classofType(TL->getTypePtr()); + } + static bool classof(const UnqualTypeLoc *TL) { + return Derived::classofType(TL->getTypePtr()); + } + static bool classof(const Derived *TL) { + return true; + } + TypeLoc getNextTypeLoc() const { return getNextTypeLoc(asDerived()->getInnerType()); } @@ -361,7 +376,7 @@ public: void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; } - SourceRange getSourceRange() const { + SourceRange getLocalSourceRange() const { return SourceRange(getNameLoc(), getNameLoc()); } void initializeLocal(SourceLocation Loc) { @@ -413,7 +428,7 @@ public: return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0; } - SourceRange getSourceRange() const { + SourceRange getLocalSourceRange() const { return SourceRange(getBuiltinLoc(), getBuiltinLoc()); } @@ -553,6 +568,7 @@ class SubstTemplateTypeParmTypeLoc : struct ObjCProtocolListLocInfo { SourceLocation LAngleLoc; SourceLocation RAngleLoc; + bool HasBaseTypeAsWritten; }; // A helper class for defining ObjC TypeLocs that can qualified with @@ -560,24 +576,15 @@ struct ObjCProtocolListLocInfo { // // TypeClass basically has to be either ObjCInterfaceType or // ObjCObjectPointerType. -template <class Derived, class TypeClass, class LocalData> -class ObjCProtocolListTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, - Derived, - TypeClass, - LocalData> { +class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, + ObjCObjectTypeLoc, + ObjCObjectType, + ObjCProtocolListLocInfo> { // SourceLocations are stored after Info, one for each Protocol. SourceLocation *getProtocolLocArray() const { return (SourceLocation*) this->getExtraLocalData(); } -protected: - void initializeLocalBase(SourceLocation Loc) { - setLAngleLoc(Loc); - setRAngleLoc(Loc); - for (unsigned i = 0, e = getNumProtocols(); i != e; ++i) - setProtocolLoc(i, Loc); - } - public: SourceLocation getLAngleLoc() const { return this->getLocalData()->LAngleLoc; @@ -611,29 +618,49 @@ public: return *(this->getTypePtr()->qual_begin() + i); } - SourceRange getSourceRange() const { + bool hasBaseTypeAsWritten() const { + return getLocalData()->HasBaseTypeAsWritten; + } + + void setHasBaseTypeAsWritten(bool HasBaseType) { + getLocalData()->HasBaseTypeAsWritten = HasBaseType; + } + + TypeLoc getBaseLoc() const { + return getInnerTypeLoc(); + } + + SourceRange getLocalSourceRange() const { return SourceRange(getLAngleLoc(), getRAngleLoc()); } void initializeLocal(SourceLocation Loc) { - initializeLocalBase(Loc); + setHasBaseTypeAsWritten(true); + setLAngleLoc(Loc); + setRAngleLoc(Loc); + for (unsigned i = 0, e = getNumProtocols(); i != e; ++i) + setProtocolLoc(i, Loc); } unsigned getExtraLocalDataSize() const { return this->getNumProtocols() * sizeof(SourceLocation); } + + QualType getInnerType() const { + return getTypePtr()->getBaseType(); + } }; -struct ObjCInterfaceLocInfo : ObjCProtocolListLocInfo { +struct ObjCInterfaceLocInfo { SourceLocation NameLoc; }; /// \brief Wrapper for source info for ObjC interfaces. -class ObjCInterfaceTypeLoc : - public ObjCProtocolListTypeLoc<ObjCInterfaceTypeLoc, - ObjCInterfaceType, - ObjCInterfaceLocInfo> { +class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, + ObjCInterfaceTypeLoc, + ObjCInterfaceType, + ObjCInterfaceLocInfo> { public: ObjCInterfaceDecl *getIFaceDecl() const { return getTypePtr()->getDecl(); @@ -647,85 +674,16 @@ public: getLocalData()->NameLoc = Loc; } - SourceRange getSourceRange() const { - if (getNumProtocols()) - return SourceRange(getNameLoc(), getRAngleLoc()); - else - return SourceRange(getNameLoc(), getNameLoc()); + SourceRange getLocalSourceRange() const { + return SourceRange(getNameLoc()); } void initializeLocal(SourceLocation Loc) { - initializeLocalBase(Loc); setNameLoc(Loc); } }; -struct ObjCObjectPointerLocInfo : ObjCProtocolListLocInfo { - SourceLocation StarLoc; - bool HasProtocols; - bool HasBaseType; -}; - -/// Wraps an ObjCPointerType with source location information. Note -/// that not all ObjCPointerTypes actually have a star location; nor -/// are protocol locations necessarily written in the source just -/// because they're present on the type. -class ObjCObjectPointerTypeLoc : - public ObjCProtocolListTypeLoc<ObjCObjectPointerTypeLoc, - ObjCObjectPointerType, - ObjCObjectPointerLocInfo> { -public: - bool hasProtocolsAsWritten() const { - return getLocalData()->HasProtocols; - } - - void setHasProtocolsAsWritten(bool HasProtocols) { - getLocalData()->HasProtocols = HasProtocols; - } - - bool hasBaseTypeAsWritten() const { - return getLocalData()->HasBaseType; - } - - void setHasBaseTypeAsWritten(bool HasBaseType) { - getLocalData()->HasBaseType = HasBaseType; - } - - SourceLocation getStarLoc() const { - return getLocalData()->StarLoc; - } - - void setStarLoc(SourceLocation Loc) { - getLocalData()->StarLoc = Loc; - } - - SourceRange getSourceRange() const { - // Being written with protocols is incompatible with being written - // with a star. - if (hasProtocolsAsWritten()) - return SourceRange(getLAngleLoc(), getRAngleLoc()); - else - return SourceRange(getStarLoc(), getStarLoc()); - } - - void initializeLocal(SourceLocation Loc) { - initializeLocalBase(Loc); - setHasProtocolsAsWritten(false); - setHasBaseTypeAsWritten(false); - setStarLoc(Loc); - } - - TypeLoc getBaseTypeLoc() const { - return getInnerTypeLoc(); - } - - QualType getInnerType() const { - return getTypePtr()->getPointeeType(); - } -}; - - struct PointerLikeLocInfo { SourceLocation StarLoc; }; @@ -746,7 +704,7 @@ public: return this->getInnerTypeLoc(); } - SourceRange getSourceRange() const { + SourceRange getLocalSourceRange() const { return SourceRange(getSigilLoc(), getSigilLoc()); } @@ -798,6 +756,20 @@ public: } }; +/// Wraps an ObjCPointerType with source location information. +class ObjCObjectPointerTypeLoc : + public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc, + ObjCObjectPointerType> { +public: + SourceLocation getStarLoc() const { + return getSigilLoc(); + } + + void setStarLoc(SourceLocation Loc) { + setSigilLoc(Loc); + } +}; + class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc, ReferenceType> { @@ -871,13 +843,11 @@ public: ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; } void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; } - TypeLoc getArgLoc(unsigned i) const; - TypeLoc getResultLoc() const { return getInnerTypeLoc(); } - SourceRange getSourceRange() const { + SourceRange getLocalSourceRange() const { return SourceRange(getLParenLoc(), getRParenLoc()); } @@ -950,7 +920,7 @@ public: return getInnerTypeLoc(); } - SourceRange getSourceRange() const { + SourceRange getLocalSourceRange() const { return SourceRange(getLBracketLoc(), getRBracketLoc()); } @@ -1055,7 +1025,7 @@ public: memcpy(Data, Loc.Data, size); } - SourceRange getSourceRange() const { + SourceRange getLocalSourceRange() const { return SourceRange(getTemplateNameLoc(), getRAngleLoc()); } @@ -1183,7 +1153,7 @@ public: setRParenLoc(range.getEnd()); } - SourceRange getSourceRange() const { + SourceRange getLocalSourceRange() const { return SourceRange(getTypeofLoc(), getRParenLoc()); } @@ -1204,7 +1174,7 @@ public: // Reimplemented to account for GNU/C++ extension // typeof unary-expression // where there are no parentheses. - SourceRange getSourceRange() const; + SourceRange getLocalSourceRange() const; }; class TypeOfTypeLoc @@ -1227,24 +1197,110 @@ class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DecltypeType> { }; -// FIXME: location of the tag keyword. -class ElaboratedTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, - ElaboratedTypeLoc, - ElaboratedType> { +struct ElaboratedLocInfo { + SourceLocation KeywordLoc; + SourceRange QualifierRange; }; -// FIXME: locations for the nested name specifier; at the very least, -// a SourceRange. -class QualifiedNameTypeLoc : - public InheritingConcreteTypeLoc<TypeSpecTypeLoc, - QualifiedNameTypeLoc, - QualifiedNameType> { +class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, + ElaboratedTypeLoc, + ElaboratedType, + ElaboratedLocInfo> { +public: + SourceLocation getKeywordLoc() const { + return this->getLocalData()->KeywordLoc; + } + void setKeywordLoc(SourceLocation Loc) { + this->getLocalData()->KeywordLoc = Loc; + } + + SourceRange getQualifierRange() const { + return this->getLocalData()->QualifierRange; + } + void setQualifierRange(SourceRange Range) { + this->getLocalData()->QualifierRange = Range; + } + + SourceRange getLocalSourceRange() const { + if (getKeywordLoc().isValid()) + if (getQualifierRange().getEnd().isValid()) + return SourceRange(getKeywordLoc(), getQualifierRange().getEnd()); + else + return SourceRange(getKeywordLoc()); + else + return getQualifierRange(); + } + + void initializeLocal(SourceLocation Loc) { + setKeywordLoc(Loc); + setQualifierRange(SourceRange(Loc)); + } + + TypeLoc getNamedTypeLoc() const { + return getInnerTypeLoc(); + } + + QualType getInnerType() const { + return getTypePtr()->getNamedType(); + } + + void copy(ElaboratedTypeLoc Loc) { + unsigned size = getFullDataSize(); + assert(size == Loc.getFullDataSize()); + memcpy(Data, Loc.Data, size); + } }; -// FIXME: locations for the typename keyword and nested name specifier. -class DependentNameTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, - DependentNameTypeLoc, - DependentNameType> { +struct DependentNameLocInfo { + SourceLocation KeywordLoc; + SourceRange QualifierRange; + SourceLocation NameLoc; +}; + +class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, + DependentNameTypeLoc, + DependentNameType, + DependentNameLocInfo> { +public: + SourceLocation getKeywordLoc() const { + return this->getLocalData()->KeywordLoc; + } + void setKeywordLoc(SourceLocation Loc) { + this->getLocalData()->KeywordLoc = Loc; + } + + SourceRange getQualifierRange() const { + return this->getLocalData()->QualifierRange; + } + void setQualifierRange(SourceRange Range) { + this->getLocalData()->QualifierRange = Range; + } + + SourceLocation getNameLoc() const { + return this->getLocalData()->NameLoc; + } + void setNameLoc(SourceLocation Loc) { + this->getLocalData()->NameLoc = Loc; + } + + SourceRange getLocalSourceRange() const { + if (getKeywordLoc().isValid()) + return SourceRange(getKeywordLoc(), getNameLoc()); + else + return SourceRange(getQualifierRange().getBegin(), getNameLoc()); + } + + void copy(DependentNameTypeLoc Loc) { + unsigned size = getFullDataSize(); + assert(size == Loc.getFullDataSize()); + memcpy(Data, Loc.Data, size); + } + + void initializeLocal(SourceLocation Loc) { + setKeywordLoc(Loc); + setQualifierRange(SourceRange(Loc)); + setNameLoc(Loc); + } }; } diff --git a/include/clang/AST/TypeLocBuilder.h b/include/clang/AST/TypeLocBuilder.h index c3b1c68..e729488 100644 --- a/include/clang/AST/TypeLocBuilder.h +++ b/include/clang/AST/TypeLocBuilder.h @@ -59,6 +59,20 @@ class TypeLocBuilder { grow(Requested); } + /// Pushes a copy of the given TypeLoc onto this builder. The builder + /// must be empty for this to work. + void pushFullCopy(TypeLoc L) { +#ifndef NDEBUG + assert(LastTy.isNull() && "pushing copy on non-empty TypeLocBuilder"); + LastTy = L.getNextTypeLoc().getType(); +#endif + assert(Index == Capacity && "pushing copy on non-empty TypeLocBuilder"); + + unsigned Size = L.getFullDataSize(); + TypeLoc Copy = pushImpl(L.getType(), Size); + memcpy(Copy.getOpaqueData(), L.getOpaqueData(), Size); + } + /// Pushes space for a typespec TypeLoc. Invalidates any TypeLocs /// previously retrieved from this builder. TypeSpecTypeLoc pushTypeSpec(QualType T) { diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def index c665073..02508af 100644 --- a/include/clang/AST/TypeNodes.def +++ b/include/clang/AST/TypeNodes.def @@ -90,10 +90,10 @@ NON_CANONICAL_TYPE(Elaborated, Type) DEPENDENT_TYPE(TemplateTypeParm, Type) NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type) NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type) -NON_CANONICAL_TYPE(QualifiedName, Type) DEPENDENT_TYPE(InjectedClassName, Type) DEPENDENT_TYPE(DependentName, Type) -TYPE(ObjCInterface, Type) +TYPE(ObjCObject, Type) +TYPE(ObjCInterface, ObjCObjectType) TYPE(ObjCObjectPointer, Type) #ifdef LAST_TYPE diff --git a/include/clang/AST/TypeVisitor.h b/include/clang/AST/TypeVisitor.h index 19f7f42..5c9c5285 100644 --- a/include/clang/AST/TypeVisitor.h +++ b/include/clang/AST/TypeVisitor.h @@ -1,4 +1,4 @@ -//===--- TypeVisitor.h - Visitor for Stmt subclasses ------------*- C++ -*-===// +//===--- TypeVisitor.h - Visitor for Type subclasses ------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -25,7 +25,7 @@ template<typename ImplClass, typename RetTy=void> class TypeVisitor { public: RetTy Visit(Type *T) { - // Top switch stmt: dispatch to VisitFooStmt for each FooStmt. + // Top switch stmt: dispatch to VisitFooType for each FooType. switch (T->getTypeClass()) { default: assert(0 && "Unknown type class!"); #define ABSTRACT_TYPE(CLASS, PARENT) diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h index cbe0082..a548b0b 100644 --- a/include/clang/AST/UnresolvedSet.h +++ b/include/clang/AST/UnresolvedSet.h @@ -31,9 +31,13 @@ private: IteratorTy ir; friend class UnresolvedSetImpl; + friend class OverloadExpr; explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {} explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) : ir(const_cast<DeclsTy::iterator>(ir)) {} + + IteratorTy getIterator() const { return ir; } + public: UnresolvedSetIterator() {} @@ -81,9 +85,7 @@ public: bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; } }; -/// UnresolvedSet - A set of unresolved declarations. This is needed -/// in a lot of places, but isn't really worth breaking into its own -/// header right now. +/// UnresolvedSet - A set of unresolved declarations. class UnresolvedSetImpl { typedef UnresolvedSetIterator::DeclsTy DeclsTy; diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h index fb8d4d5..075838d 100644 --- a/include/clang/Analysis/ProgramPoint.h +++ b/include/clang/Analysis/ProgramPoint.h @@ -59,7 +59,7 @@ private: protected: ProgramPoint(const void* P, Kind k, const LocationContext *l, const void *tag = 0) - : Data(P, NULL), K(k), L(l), Tag(tag) {} + : Data(P, static_cast<const void*>(NULL)), K(k), L(l), Tag(tag) {} ProgramPoint(const void* P1, const void* P2, Kind k, const LocationContext *l, const void *tag = 0) diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index 6b2912e..62f06ed 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -423,6 +423,14 @@ public: /// the diagnostic, this returns null. static const char *getWarningOptionForDiag(unsigned DiagID); + /// getWarningOptionForDiag - Return the category number that a specified + /// DiagID belongs to, or 0 if no category. + static unsigned getCategoryNumberForDiag(unsigned DiagID); + + /// getCategoryNameFromID - Given a category ID, return the name of the + /// category. + static const char *getCategoryNameFromID(unsigned CategoryID); + /// \brief Enumeration describing how the the emission of a diagnostic should /// be treated when it occurs during C++ template argument deduction. enum SFINAEResponse { diff --git a/include/clang/Basic/Diagnostic.td b/include/clang/Basic/Diagnostic.td index f6b5d9c..fabf9eb 100644 --- a/include/clang/Basic/Diagnostic.td +++ b/include/clang/Basic/Diagnostic.td @@ -42,7 +42,10 @@ class InGroup<DiagGroup G> { DiagGroup Group = G; } //class IsGroup<string Name> { DiagGroup Group = DiagGroup<Name>; } -// This defines the diagnostic groups that have references to them. +// This defines all of the named diagnostic categories. +include "DiagnosticCategories.td" + +// This defines all of the named diagnostic groups. include "DiagnosticGroups.td" diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td index cc89c7c..d755d99 100644 --- a/include/clang/Basic/DiagnosticASTKinds.td +++ b/include/clang/Basic/DiagnosticASTKinds.td @@ -14,17 +14,20 @@ let Component = "AST" in { def note_expr_divide_by_zero : Note<"division by zero">; // inline asm related. -def err_asm_invalid_escape : Error< - "invalid %% escape in inline assembly string">; -def err_asm_unknown_symbolic_operand_name : Error< - "unknown symbolic operand name in inline assembly string">; +let CategoryName = "Inline Assembly Issue" in { + def err_asm_invalid_escape : Error< + "invalid %% escape in inline assembly string">; + def err_asm_unknown_symbolic_operand_name : Error< + "unknown symbolic operand name in inline assembly string">; + + def err_asm_unterminated_symbolic_operand_name : Error< + "unterminated symbolic operand name in inline assembly string">; + def err_asm_empty_symbolic_operand_name : Error< + "empty symbolic operand name in inline assembly string">; + def err_asm_invalid_operand_number : Error< + "invalid operand number in inline asm string">; +} -def err_asm_unterminated_symbolic_operand_name : Error< - "unterminated symbolic operand name in inline assembly string">; -def err_asm_empty_symbolic_operand_name : Error< - "empty symbolic operand name in inline assembly string">; -def err_asm_invalid_operand_number : Error< - "invalid operand number in inline asm string">; // Importing ASTs def err_odr_variable_type_inconsistent : Error< diff --git a/include/clang/Basic/DiagnosticCategories.td b/include/clang/Basic/DiagnosticCategories.td new file mode 100644 index 0000000..a02fbdf --- /dev/null +++ b/include/clang/Basic/DiagnosticCategories.td @@ -0,0 +1,10 @@ +//==--- DiagnosticCategories.td - Diagnostic Category Definitions ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +class CatInlineAsm : DiagCategory<"Inline Assembly Issue">; diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index 3b7272e..f4a31cc 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -49,6 +49,8 @@ def err_drv_no_ast_support : Error< "'%0': unable to use AST files with this tool">; def err_drv_clang_unsupported : Error< "the clang compiler does not support '%0'">; +def err_drv_clang_unsupported_opt_cxx_darwin_i386 : Error< + "the clang compiler does not support '%0' for C++ on Darwin/i386">; def err_drv_command_failed : Error< "%0 command failed with exit code %1 (use -v to see invocation)">; def err_drv_command_signalled : Error< diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td index b731030..c7cad73 100644 --- a/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/include/clang/Basic/DiagnosticFrontendKinds.td @@ -16,7 +16,8 @@ def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal; def err_fe_invalid_ast_file : Error<"invalid AST file: '%0'">, DefaultFatal; def err_fe_invalid_ast_action : Error<"invalid action for AST input">, DefaultFatal; -def err_fe_inline_asm : Error<"%0">; // Error generated by the backend. +// Error generated by the backend. +def err_fe_inline_asm : Error<"%0">, CatInlineAsm; def note_fe_inline_asm_here : Note<"generated from here">; def err_fe_invalid_code_complete_file : Error< "cannot locate code-completion file %0">, DefaultFatal; diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 1012e91..b79bf8e 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -40,6 +40,9 @@ def ExtraTokens : DiagGroup<"extra-tokens">; def FormatExtraArgs : DiagGroup<"format-extra-args">; def FormatZeroLength : DiagGroup<"format-zero-length">; +def CXXHexFloats : DiagGroup<"c++-hex-floats">; + +def : DiagGroup<"c++0x-compat", [CXXHexFloats]>; def FourByteMultiChar : DiagGroup<"four-char-constants">; def : DiagGroup<"idiomatic-parentheses">; def : DiagGroup<"import">; @@ -120,6 +123,7 @@ def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">; def : DiagGroup<"variadic-macros">; def VariadicMacros : DiagGroup<"variadic-macros">; def VectorConversions : DiagGroup<"vector-conversions">; // clang specific +def VLA : DiagGroup<"vla">; def VolatileRegisterVar : DiagGroup<"volatile-register-var">; def : DiagGroup<"write-strings">; def CharSubscript : DiagGroup<"char-subscripts">; @@ -134,16 +138,17 @@ def Parentheses : DiagGroup<"parentheses", [DiagGroup<"idiomatic-parentheses">]> // legacy reasons. def Conversion : DiagGroup<"conversion", [DiagGroup<"shorten-64-to-32">]>, - DiagCategory<"Value Conversion">; + DiagCategory<"Value Conversion Issue">; def Unused : DiagGroup<"unused", [UnusedArgument, UnusedFunction, UnusedLabel, // UnusedParameter, (matches GCC's behavior) - UnusedValue, UnusedVariable]>; + UnusedValue, UnusedVariable]>, + DiagCategory<"Unused Entity Issue">; // Format settings. def Format : DiagGroup<"format", [FormatExtraArgs, FormatZeroLength, NonNull]>, - DiagCategory<"Format String">; + DiagCategory<"Format String Issue">; def FormatSecurity : DiagGroup<"format-security", [Format]>; def FormatNonLiteral : DiagGroup<"format-nonliteral", [FormatSecurity]>; def FormatY2K : DiagGroup<"format-y2k", [Format]>; @@ -190,4 +195,4 @@ def NonGCC : DiagGroup<"non-gcc", [SignCompare, Conversion, LiteralRange]>; // A warning group for warnings about GCC extensions. -def GNU : DiagGroup<"gnu", [GNUDesignator]>; +def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>; diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index 3f765bd..848e85c 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -11,7 +11,7 @@ // Lexer Diagnostics //===----------------------------------------------------------------------===// -let Component = "Lex" in { +let Component = "Lex", CategoryName = "Lexical or Preprocessor Issue" in { def null_in_string : Warning<"null character(s) preserved in string literal">; def null_in_char : Warning<"null character(s) preserved in character literal">; @@ -84,9 +84,9 @@ def err_exponent_has_no_digits : Error<"exponent has no digits">; def ext_imaginary_constant : Extension<"imaginary constants are an extension">; def err_hexconstant_requires_exponent : Error< "hexadecimal floating constants require an exponent">; -def ext_hexconstant_cplusplus : ExtWarn< +def ext_hexconstant_cplusplus : Extension< "hexadecimal floating constants are a C99 feature that is incompatible with " - "C++0x">; + "C++0x">, InGroup<CXXHexFloats>; def ext_hexconstant_invalid : Extension< "hexadecimal floating constants are a C99 feature">; def ext_binary_literal : Extension< diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 2795851..934bd0d 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -13,9 +13,12 @@ let Component = "Parse" in { -def w_asm_qualifier_ignored : Warning<"ignored %0 qualifier on asm">; +def w_asm_qualifier_ignored : Warning<"ignored %0 qualifier on asm">, + CatInlineAsm; def warn_file_asm_volatile : Warning< - "meaningless 'volatile' on asm outside function">; + "meaningless 'volatile' on asm outside function">, CatInlineAsm; + +let CategoryName = "Parse Issue" in { def ext_empty_source_file : Extension<"ISO C forbids an empty source file">; def ext_top_level_semi : Extension< @@ -119,6 +122,8 @@ def err_expected_semi_after_namespace_name : Error< "expected ';' after namespace name">; def err_unexpected_namespace_attributes_alias : Error< "attributes can not be specified on namespace alias">; +def err_namespace_nonnamespace_scope : Error< + "namespaces can only be defined in global or namespace scope">; def err_expected_semi_after_attribute_list : Error< "expected ';' after attribute list">; def err_expected_semi_after_static_assert : Error< @@ -129,7 +134,7 @@ def err_label_end_of_compound_statement : Error< "label at end of compound statement: expected statement">; def err_expected_string_literal : Error<"expected string literal">; def err_expected_asm_operand : Error< - "expected string literal or '[' for asm operand">; + "expected string literal or '[' for asm operand">, CatInlineAsm; def err_expected_selector_for_method : Error< "expected selector for Objective-C method">; def err_expected_property_name : Error<"expected property name">; @@ -311,6 +316,9 @@ def err_explicit_instantiation_with_definition : Error< "'template' keyword">; def err_enum_template : Error<"enumeration cannot be a template">; +def err_missing_dependent_template_keyword : Error< + "use 'template' keyword to treat '%0' as a dependent template name">; + // Constructor template diagnostics. def err_out_of_line_constructor_template_id : Error< "out-of-line constructor for %0 cannot have template arguments">; @@ -355,6 +363,13 @@ def warn_pragma_expected_identifier : Warning< "expected identifier in '#pragma %0' - ignored">; def warn_pragma_extra_tokens_at_eol : Warning< "extra tokens at end of '#pragma %0' - ignored">; +// - #pragma options +def warn_pragma_options_expected_align : Warning< + "expected 'align' following '#pragma options' - ignored">; +def warn_pragma_options_expected_equal : Warning< + "expected '=' following '#pragma options align' - ignored">; +def warn_pragma_options_invalid_option : Warning< + "invalid alignment option in '#pragma options align' - ignored">; // - #pragma pack def warn_pragma_pack_invalid_action : Warning< "unknown action for '#pragma pack' - ignored">; @@ -368,4 +383,5 @@ def warn_pragma_unused_expected_var : Warning< def warn_pragma_unused_expected_punc : Warning< "expected ')' or ',' in '#pragma unused'">; +} // end of Parse Issue category. } // end of Parser diagnostics diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 6b40820..0ba31ae 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// let Component = "Sema" in { +let CategoryName = "Semantic Issue" in { // Constant expressions def err_expr_not_ice : Error< @@ -36,6 +37,28 @@ def warn_float_underflow : Warning< "magnitude of floating-point constant too small for type %0; minimum is %1">, InGroup<LiteralRange>; +// C99 variable-length arrays +def ext_vla : Extension< + "variable length arrays are a C99 feature, accepted as an extension">, + InGroup<VLA>; +def err_vla_non_pod : Error<"variable length array of non-POD element type %0">; +def err_vla_in_sfinae : Error< + "variable length array cannot be formed during template argument deduction">; +def err_array_star_in_function_definition : Error< + "variable length array must be bound in function definition">; +def err_vla_decl_in_file_scope : Error< + "variable length array declaration not allowed at file scope">; +def err_vla_decl_has_static_storage : Error< + "variable length array declaration can not have 'static' storage duration">; +def err_vla_decl_has_extern_linkage : Error< + "variable length array declaration can not have 'extern' linkage">; + +// C99 variably modified types +def err_variably_modified_template_arg : Error< + "variably modified type %0 cannot be used as a template argument">; +def err_variably_modified_nontype_template_param : Error< + "non-type template parameter of variably modified type %0">; + // C99 Designated Initializers def err_array_designator_negative : Error< "array designator value '%0' is negative">; @@ -71,11 +94,6 @@ def ext_flexible_array_init : Extension< "flexible array initialization is a GNU extension">, InGroup<GNU>; // Declarations. -def ext_vla : Extension< - "variable length arrays are a C99 feature, accepted as an extension">; -def err_vla_cxx : Error< - "variable length arrays are not permitted in C++">; - def ext_anon_param_requires_type_specifier : Extension< "type specifier required for unnamed parameter, defaults to int">; def err_bad_variable_name : Error< @@ -89,8 +107,6 @@ def warn_unused_exception_param : Warning<"unused exception parameter %0">, InGroup<UnusedExceptionParameter>, DefaultIgnore; def warn_decl_in_param_list : Warning< "declaration of %0 will not be visible outside of this function">; -def err_array_star_in_function_definition : Error< - "variable length array must be bound in function definition">; def warn_unused_function : Warning<"unused function %0">, InGroup<UnusedFunction>, DefaultIgnore; @@ -220,6 +236,12 @@ def err_object_cannot_be_passed_returned_by_value : Error< "interface type %1 cannot be %select{returned|passed}0 by value" "; did you forget * in %1">; def warn_enum_value_overflow : Warning<"overflow in enumeration value">; +def warn_pragma_options_align_unsupported_option : Warning< + "unsupported alignment option in '#pragma options align'">; +def warn_pragma_options_align_reset_failed : Warning< + "#pragma options align=reset failed: %0">; +def err_pragma_options_align_mac68k_target_unsupported : Error< + "mac68k alignment pragma is not supported on this target">; def warn_pragma_pack_invalid_alignment : Warning< "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">; // Follow the MSVC implementation. @@ -293,6 +315,8 @@ def warn_conflicting_ret_types : Warning< def warn_conflicting_param_types : Warning< "conflicting parameter types in implementation of %0: %1 vs %2">; +def warn_conflicting_variadic :Warning< + "conflicting variadic declaration of method and its implementation">; def warn_implements_nscopying : Warning< "default assign attribute on property %0 which implements " @@ -503,6 +527,10 @@ def err_access_copy_field : def err_access_copy_base : Error<"base class %0 has %select{private|protected}1 copy constructor">, NoSFINAE; +def err_access_dtor_ivar : + Error<"instance variable of type %0 has %select{private|protected}1 " + "destructor">, + NoSFINAE; def note_previous_access_declaration : Note< "previously declared '%1' here">; def err_access_outside_class : Error< @@ -709,6 +737,7 @@ def note_uninit_reference_member : Note< "uninitialized reference member is here">; def warn_field_is_uninit : Warning<"field is uninitialized when used here">, InGroup<DiagGroup<"uninitialized">>; +def err_init_incomplete_type : Error<"initialization of incomplete type %0">; def err_temp_copy_no_viable : Error< "no viable constructor %select{copying variable|copying parameter|" @@ -883,6 +912,12 @@ def warn_impcast_float_precision : Warning< def warn_impcast_float_integer : Warning< "implicit cast turns floating-point number into integer: %0 to %1">, InGroup<DiagGroup<"conversion">>, DefaultIgnore; +def warn_impcast_integer_sign : Warning< + "implicit cast changes signedness: %0 to %1">, + InGroup<DiagGroup<"conversion">>, DefaultIgnore; +def warn_impcast_integer_sign_conditional : Warning< + "operand of ? changes signedness: %0 to %1">, + InGroup<DiagGroup<"conversion">>, DefaultIgnore; def warn_impcast_integer_precision : Warning< "implicit cast loses integer precision: %0 to %1">, InGroup<DiagGroup<"conversion">>, DefaultIgnore; @@ -951,8 +986,7 @@ def err_attribute_regparm_invalid_number : Error< // Clang-Specific Attributes def err_attribute_iboutlet : Error< - "iboutlet attribute can only be applied to instance variables or " - "properties">; + "%0 attribute can only be applied to instance variables or properties">; def err_attribute_ibaction: Error< "ibaction attribute can only be applied to Objective-C instance methods">; def err_attribute_overloadable_not_function : Error< @@ -1054,15 +1088,29 @@ def note_ovl_candidate_bad_deduction : Note< "candidate template ignored: failed template argument deduction">; def note_ovl_candidate_incomplete_deduction : Note<"candidate template ignored: " "couldn't infer template argument %0">; - +def note_ovl_candidate_inconsistent_deduction : Note< + "candidate template ignored: deduced conflicting %select{types|values|" + "templates}0 for parameter %1 (%2 vs. %3)">; +def note_ovl_candidate_explicit_arg_mismatch_named : Note< + "candidate template ignored: invalid explicitly-specified argument " + "for template parameter %0">; +def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note< + "candidate template ignored: invalid explicitly-specified argument " + "for %ordinal0 template parameter">; +def note_ovl_candidate_instantiation_depth : Note< + "candidate template ignored: substitution exceeded maximum template " + "instantiation depth">; +def note_ovl_candidate_substitution_failure : Note< + "candidate template ignored: substitution failure %0">; + // Note that we don't treat templates differently for this diagnostic. def note_ovl_candidate_arity : Note<"candidate " "%select{function|function|constructor|function|function|constructor|" "constructor (the implicit default constructor)|" "constructor (the implicit copy constructor)|" - "function (the implicit copy assignment operator)}0 not viable: requires" - "%select{ at least| at most|}2 %3 argument%s3, but %4 %plural{1:was|:were}4 " - "provided">; + "function (the implicit copy assignment operator)}0 %select{|template }1" + "not viable: requires%select{ at least| at most|}2 %3 argument%s3, but %4 " + "%plural{1:was|:were}4 provided">; def note_ovl_candidate_deleted : Note< "candidate %select{function|function|constructor|" @@ -1484,6 +1532,12 @@ def err_explicit_instantiation_out_of_scope : Error< "explicit instantiation of %0 not in a namespace enclosing %1">; def err_explicit_instantiation_must_be_global : Error< "explicit instantiation of %0 must occur at global scope">; +def warn_explicit_instantiation_out_of_scope_0x : Warning< + "explicit instantiation of %0 not in a namespace enclosing %1">, + InGroup<DiagGroup<"-Wc++0x-compat"> >; +def warn_explicit_instantiation_must_be_global_0x : Warning< + "explicit instantiation of %0 must occur at global scope">, + InGroup<DiagGroup<"-Wc++0x-compat"> >; def err_explicit_instantiation_requires_name : Error< "explicit instantiation declaration requires a name">; @@ -1512,6 +1566,9 @@ def err_explicit_instantiation_without_qualified_id_quals : Error< "qualifier in explicit instantiation of '%0%1' requires a template-id">; def err_explicit_instantiation_unqualified_wrong_namespace : Error< "explicit instantiation of %q0 must occur in %1">; +def warn_explicit_instantiation_unqualified_wrong_namespace_0x : Warning< + "explicit instantiation of %q0 must occur in %1">, + InGroup<DiagGroup<"c++0x-compat"> >; def err_explicit_instantiation_undefined_member : Error< "explicit instantiation of undefined %select{member class|member function|" "static data member}0 %1 of class template %2">; @@ -1631,12 +1688,6 @@ def warn_enumerator_too_large : Warning< def warn_illegal_constant_array_size : Extension< "size of static array must be an integer constant expression">; -def err_vla_decl_in_file_scope : Error< - "variable length array declaration not allowed at file scope">; -def err_vla_decl_has_static_storage : Error< - "variable length array declaration can not have 'static' storage duration">; -def err_vla_decl_has_extern_linkage : Error< - "variable length array declaration can not have 'extern' linkage">; def err_vm_decl_in_file_scope : Error< "variably modified type declaration not allowed at file scope">; def err_vm_decl_has_extern_linkage : Error< @@ -1725,20 +1776,20 @@ def err_undeclared_label_use : Error<"use of undeclared label '%0'">; def err_goto_into_protected_scope : Error<"illegal goto into protected scope">; def err_switch_into_protected_scope : Error< "illegal switch case into protected scope">; -def err_indirect_goto_in_protected_scope : Warning< - "illegal indirect goto in protected scope, unknown effect on scopes">, - InGroup<DiagGroup<"label-address-scope">>; -def err_addr_of_label_in_protected_scope : Warning< - "address taken of label in protected scope, jump to it would have " - "unknown effect on scope">, InGroup<DiagGroup<"label-address-scope">>; +def err_indirect_goto_without_addrlabel : Error< + "indirect goto in function with no address-of-label expressions">; +def warn_indirect_goto_in_protected_scope : Warning< + "indirect goto might cross protected scopes">, + InGroup<DiagGroup<"label-address-scope">>; +def note_indirect_goto_target : Note<"possible target of indirect goto">; def note_protected_by_variable_init : Note< "jump bypasses variable initialization">; +def note_protected_by_cleanup : Note< + "jump bypasses initialization of variable with __attribute__((cleanup))">; def note_protected_by_vla_typedef : Note< "jump bypasses initialization of VLA typedef">; def note_protected_by_vla : Note< "jump bypasses initialization of variable length array">; -def note_protected_by_cleanup : Note< - "jump bypasses initialization of declaration with __attribute__((cleanup))">; def note_protected_by_objc_try : Note< "jump bypasses initialization of @try block">; def note_protected_by_objc_catch : Note< @@ -1754,6 +1805,25 @@ def note_protected_by_cxx_catch : Note< def note_protected_by___block : Note< "jump bypasses setup of __block variable">; +def note_exits_cleanup : Note< + "jump exits scope of variable with __attribute__((cleanup))">; +def note_exits_dtor : Note< + "jump exits scope of variable with non-trivial destructor">; +def note_exits___block : Note< + "jump exits scope of __block variable">; +def note_exits_objc_try : Note< + "jump exits @try block">; +def note_exits_objc_catch : Note< + "jump exits @catch block">; +def note_exits_objc_finally : Note< + "jump exits @finally block">; +def note_exits_objc_synchronized : Note< + "jump exits @synchronized block">; +def note_exits_cxx_try : Note< + "jump exits try block">; +def note_exits_cxx_catch : Note< + "jump exits catch block">; + def err_func_returning_array_function : Error< "function cannot return %select{array|function}0 type %1">; def err_field_declared_as_function : Error<"field %0 declared as a function">; @@ -1764,6 +1834,8 @@ def ext_variable_sized_type_in_struct : ExtWarn< def err_flexible_array_empty_struct : Error< "flexible array %0 not allowed in otherwise empty struct">; +def err_flexible_array_has_nonpod_type : Error< + "flexible array member %0 of non-POD element type %1">; def ext_flexible_array_in_struct : Extension< "%0 may not be nested in a struct due to flexible array member">; def ext_flexible_array_in_array : Extension< @@ -1806,6 +1878,9 @@ def err_func_def_incomplete_result : Error< // Expressions. def ext_sizeof_function_type : Extension< "invalid application of 'sizeof' to a function type">, InGroup<PointerArith>; +def err_sizeof_alignof_overloaded_function_type : Error< + "invalid application of '%select{sizeof|__alignof}0' to an overloaded " + "function">; def ext_sizeof_void_type : Extension< "invalid application of '%0' to a void type">, InGroup<PointerArith>; def err_sizeof_alignof_incomplete_type : Error< @@ -2196,6 +2271,8 @@ def err_default_init_const : Error< "default initialization of an object of const type %0" "%select{| requires a user-provided default constructor}1">; def err_delete_operand : Error<"cannot delete expression of type %0">; +def ext_delete_void_ptr_operand : ExtWarn< + "cannot delete expression with pointer-to-'void' type %0">; def err_ambiguous_delete_operand : Error<"ambiguous conversion of delete " "expression of type %0 to a pointer">; def warn_delete_incomplete : Warning< @@ -2293,7 +2370,9 @@ def err_cannot_form_pointer_to_member_of_reference_type : Error< "cannot form a pointer-to-member to member %0 of reference type %1">; def err_incomplete_object_call : Error< "incomplete type in call to object of type %0">; - +def err_incomplete_pointer_to_member_return : Error< + "incomplete return type %0 of pointer-to-member constant">; + def warn_condition_is_assignment : Warning<"using the result of an " "assignment as a condition without parentheses">, InGroup<Parentheses>; @@ -2510,31 +2589,35 @@ def warn_unused_call : Warning< def err_incomplete_type_used_in_type_trait_expr : Error< "incomplete type %0 used in type trait expression">; def err_expected_ident_or_lparen : Error<"expected identifier or '('">; - -// inline asm. -def err_asm_wide_character : Error<"wide string is invalid in 'asm'">; -def err_asm_invalid_lvalue_in_output : Error<"invalid lvalue in asm output">; -def err_asm_invalid_output_constraint : Error< - "invalid output constraint '%0' in asm">; -def err_asm_invalid_lvalue_in_input : Error< - "invalid lvalue in asm input for constraint '%0'">; -def err_asm_invalid_input_constraint : Error< - "invalid input constraint '%0' in asm">; -def err_asm_invalid_type_in_input : Error< - "invalid type %0 in asm input for constraint '%1'">; -def err_asm_tying_incompatible_types : Error< - "unsupported inline asm: input with type %0 matching output with type %1">; -def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">; -def err_invalid_asm_cast_lvalue : Error< - "invalid use of a cast in a inline asm context requiring an l-value: " - "remove the cast or build with -fheinous-gnu-extensions">; - -def warn_invalid_asm_cast_lvalue : Warning< - "invalid use of a cast in a inline asm context requiring an l-value: " - "accepted due to -fheinous-gnu-extensions, but clang may remove support " - "for this in the future">; +} // End of general sema category. +// inline asm. +let CategoryName = "Inline Assembly Issue" in { + def err_asm_wide_character : Error<"wide string is invalid in 'asm'">; + def err_asm_invalid_lvalue_in_output : Error<"invalid lvalue in asm output">; + def err_asm_invalid_output_constraint : Error< + "invalid output constraint '%0' in asm">; + def err_asm_invalid_lvalue_in_input : Error< + "invalid lvalue in asm input for constraint '%0'">; + def err_asm_invalid_input_constraint : Error< + "invalid input constraint '%0' in asm">; + def err_asm_invalid_type_in_input : Error< + "invalid type %0 in asm input for constraint '%1'">; + def err_asm_tying_incompatible_types : Error< + "unsupported inline asm: input with type %0 matching output with type %1">; + def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">; + def err_invalid_asm_cast_lvalue : Error< + "invalid use of a cast in a inline asm context requiring an l-value: " + "remove the cast or build with -fheinous-gnu-extensions">; + + def warn_invalid_asm_cast_lvalue : Warning< + "invalid use of a cast in a inline asm context requiring an l-value: " + "accepted due to -fheinous-gnu-extensions, but clang may remove support " + "for this in the future">; +} + +let CategoryName = "Semantic Issue" in { def err_invalid_conversion_between_vectors : Error< "invalid conversion between vector type %0 and %1 of different size">; @@ -2842,9 +2925,11 @@ def warn_case_value_overflow : Warning< InGroup<DiagGroup<"switch">>; def err_duplicate_case : Error<"duplicate case value '%0'">; def warn_case_empty_range : Warning<"empty case range specified">; +def warn_missing_case_for_condition : + Warning<"no case matching constant switch condition '%0'">; def warn_missing_cases : Warning<"enumeration value %0 not handled in switch">, InGroup<DiagGroup<"switch-enum"> >; -def not_in_enum : Warning<"case value not in enumerated type %0">, +def warn_not_in_enum : Warning<"case value not in enumerated type %0">, InGroup<DiagGroup<"switch-enum"> >; def err_typecheck_statement_requires_scalar : Error< "statement requires expression of scalar type (%0 invalid)">; @@ -3010,6 +3095,6 @@ def err_undeclared_protocol_suggest : Error< def note_base_class_specified_here : Note< "base class %0 specified here">; -} - +} // end of sema category +} // end of sema component. diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index 930fb52..6a4be46 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -280,6 +280,57 @@ public: /// \brief Read the source location entry with index ID. virtual void ReadSLocEntry(unsigned ID) = 0; }; + + +/// IsBeforeInTranslationUnitCache - This class holds the cache used by +/// isBeforeInTranslationUnit. The cache structure is complex enough to be +/// worth breaking out of SourceManager. +class IsBeforeInTranslationUnitCache { + /// L/R QueryFID - These are the FID's of the cached query. If these match up + /// with a subsequent query, the result can be reused. + FileID LQueryFID, RQueryFID; + + /// CommonFID - This is the file found in common between the two #include + /// traces. It is the nearest common ancestor of the #include tree. + FileID CommonFID; + + /// L/R CommonOffset - This is the offset of the previous query in CommonFID. + /// Usually, this represents the location of the #include for QueryFID, but if + /// LQueryFID is a parent of RQueryFID (or vise versa) then these can be a + /// random token in the parent. + unsigned LCommonOffset, RCommonOffset; +public: + + /// isCacheValid - Return true if the currently cached values match up with + /// the specified LHS/RHS query. If not, we can't use the cache. + bool isCacheValid(FileID LHS, FileID RHS) const { + return LQueryFID == LHS && RQueryFID == RHS; + } + + /// getCachedResult - If the cache is valid, compute the result given the + /// specified offsets in the LHS/RHS FID's. + bool getCachedResult(unsigned LOffset, unsigned ROffset) const { + // If one of the query files is the common file, use the offset. Otherwise, + // use the #include loc in the common file. + if (LQueryFID != CommonFID) LOffset = LCommonOffset; + if (RQueryFID != CommonFID) ROffset = RCommonOffset; + return LOffset < ROffset; + } + + // Set up a new query. + void setQueryFIDs(FileID LHS, FileID RHS) { + LQueryFID = LHS; + RQueryFID = RHS; + } + + void setCommonLoc(FileID commonFID, unsigned lCommonOffset, + unsigned rCommonOffset) { + CommonFID = commonFID; + LCommonOffset = lCommonOffset; + RCommonOffset = rCommonOffset; + } + +}; /// SourceManager - This file handles loading and caching of source files into /// memory. This object owns the MemoryBuffer objects for all of the loaded @@ -347,9 +398,7 @@ class SourceManager { mutable unsigned NumLinearScans, NumBinaryProbes; // Cache results for the isBeforeInTranslationUnit method. - mutable FileID LastLFIDForBeforeTUCheck; - mutable FileID LastRFIDForBeforeTUCheck; - mutable bool LastResForBeforeTUCheck; + mutable IsBeforeInTranslationUnitCache IsBeforeInTUCache; // SourceManager doesn't support copy construction. explicit SourceManager(const SourceManager&); diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 1998750..00fd9b9 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -58,6 +58,8 @@ protected: const llvm::fltSemantics *FloatFormat, *DoubleFormat, *LongDoubleFormat; unsigned char RegParmMax, SSERegParmMax; + unsigned HasAlignMac68kSupport : 1; + // TargetInfo Constructor. Default initializes all fields. TargetInfo(const std::string &T); @@ -210,6 +212,12 @@ public: return UseBitFieldTypeAlignment; } + /// hasAlignMac68kSupport - Check whether this target support '#pragma options + /// align=mac68k'. + bool hasAlignMac68kSupport() const { + return HasAlignMac68kSupport; + } + /// getTypeName - Return the user string for the specified integer type enum. /// For example, SignedShort -> "short". static const char *getTypeName(IntType T); diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def index 52e83f4..b16b828 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -220,7 +220,7 @@ KEYWORD(unsigned , KEYALL) KEYWORD(void , KEYALL) KEYWORD(volatile , KEYALL) KEYWORD(while , KEYALL) -KEYWORD(_Bool , KEYALL) +KEYWORD(_Bool , KEYNOMS) KEYWORD(_Complex , KEYALL) KEYWORD(_Imaginary , KEYALL) KEYWORD(__func__ , KEYALL) @@ -336,6 +336,7 @@ KEYWORD(__declspec , KEYALL) KEYWORD(__cdecl , KEYALL) KEYWORD(__stdcall , KEYALL) KEYWORD(__fastcall , KEYALL) +KEYWORD(__thiscall , KEYALL) KEYWORD(__forceinline , KEYALL) // Altivec Extension. @@ -372,6 +373,7 @@ ALIAS("_asm" , asm , KEYMS) ALIAS("_cdecl" , __cdecl , KEYMS) ALIAS("_fastcall" , __fastcall , KEYMS) ALIAS("_stdcall" , __stdcall , KEYMS) +ALIAS("_thiscall" , __thiscall , KEYMS) //===----------------------------------------------------------------------===// // Objective-C @-preceeded keywords. diff --git a/include/clang/CMakeLists.txt b/include/clang/CMakeLists.txt index 61d2bf6..c288048 100644 --- a/include/clang/CMakeLists.txt +++ b/include/clang/CMakeLists.txt @@ -1,2 +1,3 @@ +add_subdirectory(AST) add_subdirectory(Basic) add_subdirectory(Driver) diff --git a/include/clang/Checker/PathSensitive/AnalysisManager.h b/include/clang/Checker/PathSensitive/AnalysisManager.h index 0c59d7b..3c7cb68 100644 --- a/include/clang/Checker/PathSensitive/AnalysisManager.h +++ b/include/clang/Checker/PathSensitive/AnalysisManager.h @@ -37,8 +37,12 @@ class AnalysisManager : public BugReporterData { enum AnalysisScope { ScopeTU, ScopeDecl } AScope; + // The maximum number of exploded nodes the analyzer will generate. unsigned MaxNodes; + // The maximum number of times the analyzer will go through a loop. + unsigned MaxLoop; + bool VisualizeEGDot; bool VisualizeEGUbi; bool PurgeDead; @@ -52,19 +56,22 @@ class AnalysisManager : public BugReporterData { // bifurcates paths. bool EagerlyAssume; bool TrimGraph; + bool InlineCall; public: AnalysisManager(ASTContext &ctx, Diagnostic &diags, const LangOptions &lang, PathDiagnosticClient *pd, StoreManagerCreator storemgr, ConstraintManagerCreator constraintmgr, unsigned maxnodes, - bool vizdot, bool vizubi, bool purge, bool eager, bool trim) + unsigned maxloop, + bool vizdot, bool vizubi, bool purge, bool eager, bool trim, + bool inlinecall) : Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd), CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr), - AScope(ScopeDecl), MaxNodes(maxnodes), + AScope(ScopeDecl), MaxNodes(maxnodes), MaxLoop(maxloop), VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge), - EagerlyAssume(eager), TrimGraph(trim) {} + EagerlyAssume(eager), TrimGraph(trim), InlineCall(inlinecall) {} ~AnalysisManager() { FlushDiagnostics(); } @@ -108,6 +115,8 @@ public: unsigned getMaxNodes() const { return MaxNodes; } + unsigned getMaxLoop() const { return MaxLoop; } + bool shouldVisualizeGraphviz() const { return VisualizeEGDot; } bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; } @@ -122,6 +131,8 @@ public: bool shouldEagerlyAssume() const { return EagerlyAssume; } + bool shouldInlineCall() const { return InlineCall; } + CFG *getCFG(Decl const *D) { return AnaCtxMgr.getContext(D)->getCFG(); } diff --git a/include/clang/Checker/PathSensitive/GRExprEngine.h b/include/clang/Checker/PathSensitive/GRExprEngine.h index f04ca75..ac407f6 100644 --- a/include/clang/Checker/PathSensitive/GRExprEngine.h +++ b/include/clang/Checker/PathSensitive/GRExprEngine.h @@ -456,6 +456,8 @@ private: void EvalLocation(ExplodedNodeSet &Dst, Stmt *S, ExplodedNode* Pred, const GRState* St, SVal location, const void *tag, bool isLoad); + + bool InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, ExplodedNode *Pred); }; } // end clang namespace diff --git a/include/clang/Checker/PathSensitive/Store.h b/include/clang/Checker/PathSensitive/Store.h index 41d7c2b..f3155b9 100644 --- a/include/clang/Checker/PathSensitive/Store.h +++ b/include/clang/Checker/PathSensitive/Store.h @@ -18,6 +18,7 @@ #include "clang/Checker/PathSensitive/SVals.h" #include "clang/Checker/PathSensitive/ValueManager.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/Optional.h" namespace clang { @@ -143,9 +144,9 @@ public: return UnknownVal(); } - virtual Store RemoveDeadBindings(Store store, Stmt* Loc, - const StackFrameContext *LCtx, - SymbolReaper& SymReaper, + virtual const GRState *RemoveDeadBindings(GRState &state, Stmt* Loc, + const StackFrameContext *LCtx, + SymbolReaper& SymReaper, llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0; virtual Store BindDecl(Store store, const VarRegion *VR, SVal initVal) = 0; @@ -167,10 +168,15 @@ public: // FIXME: Make out-of-line. virtual const GRState *setExtent(const GRState *state, - const MemRegion *region, SVal extent) { + const MemRegion *region, SVal extent) { return state; } + virtual llvm::Optional<SVal> getExtent(const GRState *state, + const MemRegion *R) { + return llvm::Optional<SVal>(); + } + /// EnterStackFrame - Let the StoreManager to do something when execution /// engine is about to execute into a callee. virtual const GRState *EnterStackFrame(const GRState *state, diff --git a/include/clang/CodeGen/CodeGenOptions.h b/include/clang/CodeGen/CodeGenOptions.h index 54d3ba0..6241230 100644 --- a/include/clang/CodeGen/CodeGenOptions.h +++ b/include/clang/CodeGen/CodeGenOptions.h @@ -54,6 +54,7 @@ public: unsigned ObjCDispatchMethod : 2; /// Method of Objective-C dispatch to use. unsigned OptimizationLevel : 3; /// The -O[0-4] option specified. unsigned OptimizeSize : 1; /// If -Os is specified. + unsigned RelaxAll : 1; /// Relax all machine code instructions. unsigned SoftFloat : 1; /// -soft-float. unsigned TimePasses : 1; /// Set when -ftime-report is enabled. unsigned UnitAtATime : 1; /// Unused. For mirroring GCC optimization @@ -108,6 +109,7 @@ public: ObjCDispatchMethod = Legacy; OptimizationLevel = 0; OptimizeSize = 0; + RelaxAll = 0; SoftFloat = 0; TimePasses = 0; UnitAtATime = 1; diff --git a/include/clang/Driver/ArgList.h b/include/clang/Driver/ArgList.h index 0a8eaea..7a14ae8 100644 --- a/include/clang/Driver/ArgList.h +++ b/include/clang/Driver/ArgList.h @@ -17,12 +17,15 @@ #include <list> #include <string> +#include <vector> namespace llvm { class Twine; } namespace clang { + class Diagnostic; + namespace driver { class Arg; class ArgList; @@ -175,6 +178,25 @@ namespace driver { /// getArgString - Return the input argument string at \arg Index. virtual const char *getArgString(unsigned Index) const = 0; + + /// @} + /// @name Argument Lookup Utilities + /// @{ + + /// getLastArgValue - Return the value of the last argument, or a default. + llvm::StringRef getLastArgValue(OptSpecifier Id, + llvm::StringRef Default = "") const; + + /// getLastArgValue - Return the value of the last argument as an integer, + /// or a default. Emits an error if the argument is given, but non-integral. + int getLastArgIntValue(OptSpecifier Id, int Default, + Diagnostic &Diags) const; + + /// getAllArgValues - Get the values of all instances of the given argument + /// as strings. + std::vector<std::string> getAllArgValues(OptSpecifier Id) const; + + /// @} /// @name Translation Utilities /// @{ diff --git a/include/clang/Driver/CC1AsOptions.h b/include/clang/Driver/CC1AsOptions.h new file mode 100644 index 0000000..0508213 --- /dev/null +++ b/include/clang/Driver/CC1AsOptions.h @@ -0,0 +1,32 @@ +//===--- CC1AsOptions.h - Clang Assembler Options Table ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_DRIVER_CC1ASOPTIONS_H +#define CLANG_DRIVER_CC1ASOPTIONS_H + +namespace clang { +namespace driver { + class OptTable; + +namespace cc1asoptions { + enum ID { + OPT_INVALID = 0, // This is not an option ID. +#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ + HELPTEXT, METAVAR) OPT_##ID, +#include "clang/Driver/CC1AsOptions.inc" + LastOption +#undef OPTION + }; +} + + OptTable *createCC1AsOptTable(); +} +} + +#endif diff --git a/include/clang/Driver/CC1AsOptions.td b/include/clang/Driver/CC1AsOptions.td new file mode 100644 index 0000000..5c08dc6 --- /dev/null +++ b/include/clang/Driver/CC1AsOptions.td @@ -0,0 +1,71 @@ +//===--- CC1AsOptions.td - Options for clang -cc1as -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the options accepted by clang -cc1as. +// +//===----------------------------------------------------------------------===// + +// Include the common option parsing interfaces. +include "OptParser.td" + +//===----------------------------------------------------------------------===// +// Target Options +//===----------------------------------------------------------------------===// + +def triple : Separate<"-triple">, + HelpText<"Specify target triple (e.g. x86_64-pc-linux-gnu)">; + +//===----------------------------------------------------------------------===// +// Language Options +//===----------------------------------------------------------------------===// + +def I : JoinedOrSeparate<"-I">, MetaVarName<"<directory>">, + HelpText<"Add directory to include search path">; +def n : Flag<"-n">, + HelpText<"Don't automatically start assembly file with a text section">; + +//===----------------------------------------------------------------------===// +// Frontend Options +//===----------------------------------------------------------------------===// + +def o : Separate<"-o">, MetaVarName<"<path>">, HelpText<"Specify output file">; + +def filetype : Separate<"-filetype">, + HelpText<"Specify the output file type ('asm', 'null', or 'obj')">; + +def help : Flag<"-help">, + HelpText<"Print this help text">; +def _help : Flag<"--help">, Alias<help>; + +def version : Flag<"-version">, + HelpText<"Print the assembler version">; +def _version : Flag<"--version">, Alias<version>; + +// Generic forwarding to LLVM options. This should only be used for debugging +// and experimental features. +def mllvm : Separate<"-mllvm">, + HelpText<"Additional arguments to forward to LLVM's option processing">; + +//===----------------------------------------------------------------------===// +// Transliterate Options +//===----------------------------------------------------------------------===// + +def output_asm_variant : Separate<"-output-asm-variant">, + HelpText<"Select the asm variant index to use for output">; +def show_encoding : Flag<"-show-encoding">, + HelpText<"Show instruction encoding information in transliterate mode">; +def show_inst : Flag<"-show-inst">, + HelpText<"Show internal instruction representation in transliterate mode">; + +//===----------------------------------------------------------------------===// +// Assemble Options +//===----------------------------------------------------------------------===// + +def relax_all : Flag<"-relax-all">, + HelpText<"Relax all fixups (for performance testing)">; diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 0badeb9..fd8322b 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -56,8 +56,6 @@ def analysis_ObjCMemChecker : Flag<"-analyzer-check-objc-mem">, HelpText<"Run the [Core] Foundation reference count checker">; def analysis_WarnSizeofPointer : Flag<"-warn-sizeof-pointer">, HelpText<"Warn about unintended use of sizeof() on pointer expressions">; -def analysis_InlineCall : Flag<"-inline-call">, - HelpText<"Experimental transfer function inlining callees when its definition is available.">; def analyzer_store : Separate<"-analyzer-store">, HelpText<"Source Code Analysis - Abstract Memory Store Models">; @@ -97,8 +95,12 @@ def analyzer_viz_egraph_graphviz : Flag<"-analyzer-viz-egraph-graphviz">, HelpText<"Display exploded graph using GraphViz">; def analyzer_viz_egraph_ubigraph : Flag<"-analyzer-viz-egraph-ubigraph">, HelpText<"Display exploded graph using Ubigraph">; +def analyzer_inline_call : Flag<"-analyzer-inline-call">, + HelpText<"Experimental transfer function inlining callees when its definition is available.">; def analyzer_max_nodes : Separate<"-analyzer-max-nodes">, HelpText<"The maximum number of nodes the analyzer can generate">; +def analyzer_max_loop : Separate<"-analyzer-max-loop">, + HelpText<"The maximum number of times the analyzer will go through a loop">; //===----------------------------------------------------------------------===// // CodeGen Options @@ -145,6 +147,8 @@ def mno_zero_initialized_in_bss : Flag<"-mno-zero-initialized-in-bss">, HelpText<"Do not put zero initialized data in the BSS">; def msoft_float : Flag<"-msoft-float">, HelpText<"Use software floating point">; +def mrelax_all : Flag<"-mrelax-all">, + HelpText<"Relax all machine instructions">; def mrelocation_model : Separate<"-mrelocation-model">, HelpText<"The relocation model to use">; def munwind_tables : Flag<"-munwind-tables">, @@ -196,6 +200,9 @@ def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-rang HelpText<"Print source range spans in numeric form">; def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, HelpText<"Print diagnostic name with mappable diagnostics">; +def fdiagnostics_show_category : Separate<"-fdiagnostics-show-category">, + HelpText<"Print diagnostic category">; + def ftabstop : Separate<"-ftabstop">, MetaVarName<"<N>">, HelpText<"Set the tab stop distance.">; def ferror_limit : Separate<"-ferror-limit">, MetaVarName<"<N>">, @@ -238,6 +245,8 @@ def no_code_completion_debug_printer : Flag<"-no-code-completion-debug-printer"> HelpText<"Don't use the \"debug\" code-completion print">; def code_completion_macros : Flag<"-code-completion-macros">, HelpText<"Include macros in code-completion results">; +def code_completion_patterns : Flag<"-code-completion-patterns">, + HelpText<"Include code patterns in code-completion results">; def disable_free : Flag<"-disable-free">, HelpText<"Disable freeing of memory on exit">; def help : Flag<"-help">, @@ -293,6 +302,8 @@ def ast_dump : Flag<"-ast-dump">, HelpText<"Build ASTs and then debug dump them">; def ast_view : Flag<"-ast-view">, HelpText<"Build ASTs and view them with GraphViz">; +def boostcon : Flag<"-boostcon">, + HelpText<"BoostCon workshop mode">; def print_decl_contexts : Flag<"-print-decl-contexts">, HelpText<"Print DeclContexts and their Decls">; def emit_pth : Flag<"-emit-pth">, @@ -307,6 +318,8 @@ def emit_llvm_bc : Flag<"-emit-llvm-bc">, HelpText<"Build ASTs then convert to LLVM, emit .bc file">; def emit_llvm_only : Flag<"-emit-llvm-only">, HelpText<"Build ASTs and convert to LLVM, discarding output">; +def emit_codegen_only : Flag<"-emit-codegen-only">, + HelpText<"Generate machine code, but discard output">; def emit_obj : Flag<"-emit-obj">, HelpText<"Emit native object files">; def rewrite_test : Flag<"-rewrite-test">, diff --git a/include/clang/Driver/CMakeLists.txt b/include/clang/Driver/CMakeLists.txt index ed9825b..99be53f 100644 --- a/include/clang/Driver/CMakeLists.txt +++ b/include/clang/Driver/CMakeLists.txt @@ -9,3 +9,9 @@ tablegen(CC1Options.inc -gen-opt-parser-defs) add_custom_target(ClangCC1Options DEPENDS CC1Options.inc) + +set(LLVM_TARGET_DEFINITIONS CC1AsOptions.td) +tablegen(CC1AsOptions.inc + -gen-opt-parser-defs) +add_custom_target(ClangCC1AsOptions + DEPENDS CC1AsOptions.inc) diff --git a/include/clang/Driver/Makefile b/include/clang/Driver/Makefile index 18f3e58..b462aaa 100644 --- a/include/clang/Driver/Makefile +++ b/include/clang/Driver/Makefile @@ -1,5 +1,5 @@ LEVEL = ../../../../.. -BUILT_SOURCES = Options.inc CC1Options.inc +BUILT_SOURCES = Options.inc CC1Options.inc CC1AsOptions.inc TABLEGEN_INC_FILES_COMMON = 1 @@ -13,4 +13,6 @@ $(ObjDir)/CC1Options.inc.tmp : CC1Options.td OptParser.td $(TBLGEN) $(ObjDir)/.d $(Echo) "Building Clang CC1 Option tables with tblgen" $(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $< - +$(ObjDir)/CC1AsOptions.inc.tmp : CC1AsOptions.td OptParser.td $(TBLGEN) $(ObjDir)/.dir + $(Echo) "Building Clang CC1 Assembler Option tables with tblgen" + $(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $< diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index f6e69e0..a9a52c0 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -139,6 +139,7 @@ def MQ : JoinedOrSeparate<"-MQ">, Group<M_Group>; def MT : JoinedOrSeparate<"-MT">, Group<M_Group>; def Mach : Flag<"-Mach">; def M : Flag<"-M">, Group<M_Group>; +def O0 : Joined<"-O0">, Group<O_Group>; def O4 : Joined<"-O4">, Group<O_Group>; def ObjCXX : Flag<"-ObjC++">, Flags<[DriverOption]>, HelpText<"Treat source input files as Objective-C++ inputs">; @@ -231,6 +232,7 @@ def fPIC : Flag<"-fPIC">, Group<f_Group>; def fPIE : Flag<"-fPIE">, Group<f_Group>; def faccess_control : Flag<"-faccess-control">, Group<f_Group>; def fapple_kext : Flag<"-fapple-kext">, Group<f_Group>; +def fasm : Flag<"-fasm">, Group<f_Group>; def fasm_blocks : Flag<"-fasm-blocks">, Group<clang_ignored_f_Group>; def fassume_sane_operator_new : Flag<"-fassume-sane-operator-new">, Group<f_Group>; def fastcp : Flag<"-fastcp">, Group<f_Group>; @@ -257,6 +259,7 @@ def fdiagnostics_binary : Flag<"-fdiagnostics-binary">, Group<f_Group>, Flags<[H def fdiagnostics_fixit_info : Flag<"-fdiagnostics-fixit-info">, Group<f_Group>; def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-range-info">, Group<f_Group>; def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, Group<f_Group>; +def fdiagnostics_show_category_EQ : Joined<"-fdiagnostics-show-category=">, Group<f_Group>; def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">, Group<f_Group>; def feliminate_unused_debug_symbols : Flag<"-feliminate-unused-debug-symbols">, Group<f_Group>; def femit_all_decls : Flag<"-femit-all-decls">, Group<f_Group>; @@ -265,10 +268,7 @@ def fexceptions : Flag<"-fexceptions">, Group<f_Group>; def fextdirs_EQ : Joined<"-fextdirs=">, Group<f_Group>; def fhosted : Flag<"-fhosted">, Group<f_Group>; def ffreestanding : Flag<"-ffreestanding">, Group<f_Group>; - def fgnu_keywords : Flag<"-fgnu-keywords">, Group<f_Group>; -def fasm : Flag<"-fasm">, Alias<fgnu_keywords>; - def fgnu_runtime : Flag<"-fgnu-runtime">, Group<f_Group>; def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">; def filelist : Separate<"-filelist">, Flags<[LinkerInput]>; @@ -291,6 +291,7 @@ def fmudflap : Flag<"-fmudflap">, Group<f_Group>; def fnested_functions : Flag<"-fnested-functions">, Group<f_Group>; def fnext_runtime : Flag<"-fnext-runtime">, Group<f_Group>; def fno_access_control : Flag<"-fno-access-control">, Group<f_Group>; +def fno_asm : Flag<"-fno-asm">, Group<f_Group>; def fno_asynchronous_unwind_tables : Flag<"-fno-asynchronous-unwind-tables">, Group<f_Group>; def fno_assume_sane_operator_new : Flag<"-fno-assume-sane-operator-new">, Group<f_Group>; def fno_blocks : Flag<"-fno-blocks">, Group<f_Group>; @@ -306,10 +307,7 @@ def fno_diagnostics_show_option : Flag<"-fno-diagnostics-show-option">, Group<f_ def fno_dollars_in_identifiers : Flag<"-fno-dollars-in-identifiers">, Group<f_Group>; def fno_eliminate_unused_debug_symbols : Flag<"-fno-eliminate-unused-debug-symbols">, Group<f_Group>; def fno_exceptions : Flag<"-fno-exceptions">, Group<f_Group>; - def fno_gnu_keywords : Flag<"-fno-gnu-keywords">, Group<f_Group>; -def fno_asm : Flag<"-fno-asm">, Alias<fno_gnu_keywords>; - def fno_inline_functions : Flag<"-fno-inline-functions">, Group<clang_ignored_f_Group>; def fno_inline : Flag<"-fno-inline">, Group<clang_ignored_f_Group>; def fno_keep_inline_functions : Flag<"-fno-keep-inline-functions">, Group<clang_ignored_f_Group>; @@ -329,6 +327,7 @@ def fno_threadsafe_statics : Flag<"-fno-threadsafe-statics">, Group<f_Group>; def fno_use_cxa_atexit : Flag<"-fno-use-cxa-atexit">, Group<f_Group>; def fno_unit_at_a_time : Flag<"-fno-unit-at-a-time">, Group<f_Group>; def fno_unwind_tables : Flag<"-fno-unwind-tables">, Group<f_Group>; +def fno_verbose_asm : Flag<"-fno-verbose-asm">, Group<f_Group>; def fno_working_directory : Flag<"-fno-working-directory">, Group<f_Group>; def fno_zero_initialized_in_bss : Flag<"-fno-zero-initialized-in-bss">, Group<f_Group>; def fobjc_abi_version_EQ : Joined<"-fobjc-abi-version=">, Group<f_Group>; @@ -384,6 +383,8 @@ def fverbose_asm : Flag<"-fverbose-asm">, Group<f_Group>; def fvisibility_EQ : Joined<"-fvisibility=">, Group<f_Group>; def fwritable_strings : Flag<"-fwritable-strings">, Group<f_Group>; def fzero_initialized_in_bss : Flag<"-fzero-initialized-in-bss">, Group<f_Group>; +def ffunction_sections: Flag <"-ffunction-sections">, Group<f_Group>; +def fdata_sections : Flag <"-fdata-sections">, Group<f_Group>; def f : Joined<"-f">, Group<f_Group>; def g0 : Joined<"-g0">, Group<g_Group>; def g3 : Joined<"-g3">, Group<g_Group>; @@ -436,6 +437,7 @@ def mno_constant_cfstrings : Flag<"-mno-constant-cfstrings">, Group<m_Group>; def mno_mmx : Flag<"-mno-mmx">, Group<m_x86_Features_Group>; def mno_pascal_strings : Flag<"-mno-pascal-strings">, Group<m_Group>; def mno_red_zone : Flag<"-mno-red-zone">, Group<m_Group>; +def mno_relax_all : Flag<"-mno-relax-all">, Group<m_Group>; def mno_soft_float : Flag<"-mno-soft-float">, Group<m_Group>; def mno_sse2 : Flag<"-mno-sse2">, Group<m_x86_Features_Group>; def mno_sse3 : Flag<"-mno-sse3">, Group<m_x86_Features_Group>; @@ -453,6 +455,7 @@ def marm : Flag<"-marm">, Alias<mno_thumb>; def mno_warn_nonportable_cfstrings : Flag<"-mno-warn-nonportable-cfstrings">, Group<m_Group>; def mpascal_strings : Flag<"-mpascal-strings">, Group<m_Group>; def mred_zone : Flag<"-mred-zone">, Group<m_Group>; +def mrelax_all : Flag<"-mrelax-all">, Group<m_Group>; def msoft_float : Flag<"-msoft-float">, Group<m_Group>; def msse2 : Flag<"-msse2">, Group<m_x86_Features_Group>; def msse3 : Flag<"-msse3">, Group<m_x86_Features_Group>; @@ -667,6 +670,7 @@ def _pipe : Flag<"--pipe">, Alias<pipe>, Flags<[DriverOption]>; def _prefix_EQ : Joined<"--prefix=">, Alias<B>, Flags<[RenderSeparate]>; def _prefix : Separate<"--prefix">, Alias<B>; def _preprocess : Flag<"--preprocess">, Alias<E>; +def _print_diagnostic_categories : Flag<"--print-diagnostic-categories">; def _print_file_name_EQ : Joined<"--print-file-name=">, Alias<print_file_name_EQ>; def _print_file_name : Separate<"--print-file-name">, Alias<print_file_name_EQ>; def _print_libgcc_file_name : Flag<"--print-libgcc-file-name">, Alias<print_libgcc_file_name>; diff --git a/include/clang/Driver/Tool.h b/include/clang/Driver/Tool.h index ef77206..4368a81 100644 --- a/include/clang/Driver/Tool.h +++ b/include/clang/Driver/Tool.h @@ -30,17 +30,23 @@ class Tool { /// The tool name (for debugging). const char *Name; + /// The human readable name for the tool, for use in diagnostics. + const char *ShortName; + /// The tool chain this tool is a part of. const ToolChain &TheToolChain; public: - Tool(const char *Name, const ToolChain &TC); + Tool(const char *Name, const char *ShortName, + const ToolChain &TC); public: virtual ~Tool(); const char *getName() const { return Name; } + const char *getShortName() const { return ShortName; } + const ToolChain &getToolChain() const { return TheToolChain; } virtual bool acceptsPipedInput() const = 0; diff --git a/include/clang/Frontend/AnalysisConsumer.h b/include/clang/Frontend/AnalysisConsumer.h index 3341bb0..2cbdf36 100644 --- a/include/clang/Frontend/AnalysisConsumer.h +++ b/include/clang/Frontend/AnalysisConsumer.h @@ -61,6 +61,7 @@ public: AnalysisDiagClients AnalysisDiagOpt; std::string AnalyzeSpecificFunction; unsigned MaxNodes; + unsigned MaxLoop; unsigned AnalyzeAll : 1; unsigned AnalyzerDisplayProgress : 1; unsigned AnalyzeNestedBlocks : 1; @@ -71,6 +72,8 @@ public: unsigned VisualizeEGUbi : 1; unsigned EnableExperimentalChecks : 1; unsigned EnableExperimentalInternalChecks : 1; + unsigned InlineCall : 1; + public: AnalyzerOptions() { AnalysisStoreOpt = BasicStoreModel; diff --git a/include/clang/Frontend/CodeGenAction.h b/include/clang/Frontend/CodeGenAction.h index a1e3c42..dfc117a 100644 --- a/include/clang/Frontend/CodeGenAction.h +++ b/include/clang/Frontend/CodeGenAction.h @@ -57,6 +57,11 @@ public: EmitLLVMOnlyAction(); }; +class EmitCodeGenOnlyAction : public CodeGenAction { +public: + EmitCodeGenOnlyAction(); +}; + class EmitObjAction : public CodeGenAction { public: EmitObjAction(); diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h index 36720c9..06dc800 100644 --- a/include/clang/Frontend/CompilerInstance.h +++ b/include/clang/Frontend/CompilerInstance.h @@ -519,7 +519,7 @@ public: createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename, unsigned Line, unsigned Column, bool UseDebugPrinter, bool ShowMacros, - llvm::raw_ostream &OS); + bool ShowCodePatterns, llvm::raw_ostream &OS); /// Create the frontend timer and replace any existing one with it. void createFrontendTimer(); diff --git a/include/clang/Frontend/DeclXML.def b/include/clang/Frontend/DeclXML.def index e839a8c..16551ee 100644 --- a/include/clang/Frontend/DeclXML.def +++ b/include/clang/Frontend/DeclXML.def @@ -84,6 +84,7 @@ NODE_XML(Decl, "FIXME_Decl") ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclKindName(), "unhandled_decl_name") END_NODE_XML NODE_XML(FunctionDecl, "Function") @@ -106,7 +107,7 @@ NODE_XML(FunctionDecl, "Function") SUB_NODE_FN_BODY_XML END_NODE_XML -NODE_XML(CXXMethodDecl, "CXXMethodDecl") +NODE_XML(CXXMethodDecl, "CXXMethod") ID_ATTRIBUTE_XML ATTRIBUTE_FILE_LOCATION_XML ATTRIBUTE_XML(getDeclContext(), "context") @@ -116,6 +117,79 @@ NODE_XML(CXXMethodDecl, "CXXMethodDecl") ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline") ATTRIBUTE_OPT_XML(isStatic(), "static") ATTRIBUTE_OPT_XML(isVirtual(), "virtual") + ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access") + ENUM_XML(AS_none, "") + ENUM_XML(AS_public, "public") + ENUM_XML(AS_protected, "protected") + ENUM_XML(AS_private, "private") + END_ENUM_XML + ATTRIBUTE_XML(getNumParams(), "num_args") + SUB_NODE_SEQUENCE_XML(ParmVarDecl) + SUB_NODE_FN_BODY_XML +END_NODE_XML + +NODE_XML(CXXConstructorDecl, "CXXConstructor") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") + TYPE_ATTRIBUTE_XML(getType()->getAs<FunctionType>()->getResultType()) + ATTRIBUTE_XML(getType()->getAs<FunctionType>(), "function_type") + ATTRIBUTE_OPT_XML(isExplicit(), "is_explicit") + ATTRIBUTE_OPT_XML(isDefaultConstructor(), "is_default_ctor") + ATTRIBUTE_OPT_XML(isCopyConstructor(), "is_copy_ctor") + ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline") + ATTRIBUTE_OPT_XML(isStatic(), "static") + ATTRIBUTE_OPT_XML(isVirtual(), "virtual") + ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access") + ENUM_XML(AS_none, "") + ENUM_XML(AS_public, "public") + ENUM_XML(AS_protected, "protected") + ENUM_XML(AS_private, "private") + END_ENUM_XML + ATTRIBUTE_XML(getNumParams(), "num_args") + SUB_NODE_SEQUENCE_XML(ParmVarDecl) + SUB_NODE_FN_BODY_XML +END_NODE_XML + +NODE_XML(CXXDestructorDecl, "CXXDestructor") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") + TYPE_ATTRIBUTE_XML(getType()->getAs<FunctionType>()->getResultType()) + ATTRIBUTE_XML(getType()->getAs<FunctionType>(), "function_type") + ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline") + ATTRIBUTE_OPT_XML(isStatic(), "static") + ATTRIBUTE_OPT_XML(isVirtual(), "virtual") + ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access") + ENUM_XML(AS_none, "") + ENUM_XML(AS_public, "public") + ENUM_XML(AS_protected, "protected") + ENUM_XML(AS_private, "private") + END_ENUM_XML + ATTRIBUTE_XML(getNumParams(), "num_args") + SUB_NODE_SEQUENCE_XML(ParmVarDecl) + SUB_NODE_FN_BODY_XML +END_NODE_XML + +NODE_XML(CXXConversionDecl, "CXXConversion") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") + TYPE_ATTRIBUTE_XML(getType()->getAs<FunctionType>()->getResultType()) + ATTRIBUTE_XML(getType()->getAs<FunctionType>(), "function_type") + ATTRIBUTE_OPT_XML(isExplicit(), "is_explicit") + ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline") + ATTRIBUTE_OPT_XML(isStatic(), "static") + ATTRIBUTE_OPT_XML(isVirtual(), "virtual") + ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access") + ENUM_XML(AS_none, "") + ENUM_XML(AS_public, "public") + ENUM_XML(AS_protected, "protected") + ENUM_XML(AS_private, "private") + END_ENUM_XML ATTRIBUTE_XML(getNumParams(), "num_args") SUB_NODE_SEQUENCE_XML(ParmVarDecl) SUB_NODE_FN_BODY_XML @@ -126,6 +200,7 @@ NODE_XML(NamespaceDecl, "Namespace") ATTRIBUTE_FILE_LOCATION_XML ATTRIBUTE_XML(getDeclContext(), "context") ATTRIBUTE_XML(getNameAsString(), "name") + SUB_NODE_SEQUENCE_XML(DeclContext) END_NODE_XML NODE_XML(UsingDirectiveDecl, "UsingDirective") @@ -189,6 +264,12 @@ NODE_XML(FieldDecl, "Field") ATTRIBUTE_XML(getNameAsString(), "name") TYPE_ATTRIBUTE_XML(getType()) ATTRIBUTE_OPT_XML(isMutable(), "mutable") + ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access") + ENUM_XML(AS_none, "") + ENUM_XML(AS_public, "public") + ENUM_XML(AS_protected, "protected") + ENUM_XML(AS_private, "private") + END_ENUM_XML ATTRIBUTE_OPT_XML(isBitField(), "bitfield") SUB_NODE_OPT_XML(Expr) // init expr of a bit field END_NODE_XML @@ -237,6 +318,35 @@ NODE_XML(LinkageSpecDecl, "LinkageSpec") END_ENUM_XML END_NODE_XML +NODE_XML(TemplateDecl, "Template") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") +END_NODE_XML + +NODE_XML(TemplateTypeParmDecl, "TemplateTypeParm") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") +END_NODE_XML + +NODE_XML(UsingShadowDecl, "UsingShadow") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getTargetDecl(), "target_decl") + ATTRIBUTE_XML(getUsingDecl(), "using_decl") +END_NODE_XML + +NODE_XML(UsingDecl, "Using") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getTargetNestedNameDecl(), "target_nested_namespace_decl") + ATTRIBUTE_XML(isTypeName(), "is_typename") +END_NODE_XML //===----------------------------------------------------------------------===// #undef NODE_XML diff --git a/include/clang/Frontend/DiagnosticOptions.h b/include/clang/Frontend/DiagnosticOptions.h index b4f147b..8eb66e5 100644 --- a/include/clang/Frontend/DiagnosticOptions.h +++ b/include/clang/Frontend/DiagnosticOptions.h @@ -30,6 +30,8 @@ public: unsigned ShowSourceRanges : 1; /// Show source ranges in numeric form. unsigned ShowOptionNames : 1; /// Show the diagnostic name for mappable /// diagnostics. + unsigned ShowCategories : 2; /// Show categories: 0 -> none, 1 -> Number, + /// 2 -> Full Name. unsigned ShowColors : 1; /// Show diagnostics with ANSI color sequences. unsigned VerifyDiagnostics: 1; /// Check that diagnostics match the expected /// diagnostics, indicated by markers in the @@ -74,12 +76,13 @@ public: ShowFixits = 1; ShowLocation = 1; ShowOptionNames = 0; + ShowCategories = 0; ShowSourceRanges = 0; VerifyDiagnostics = 0; BinaryOutput = 0; ErrorLimit = 0; - TemplateBacktraceLimit = 0; - MacroBacktraceLimit = 0; + TemplateBacktraceLimit = DefaultTemplateBacktraceLimit; + MacroBacktraceLimit = DefaultMacroBacktraceLimit; } }; diff --git a/include/clang/Frontend/DocumentXML.h b/include/clang/Frontend/DocumentXML.h index 6693ddb..73d8921 100644 --- a/include/clang/Frontend/DocumentXML.h +++ b/include/clang/Frontend/DocumentXML.h @@ -114,6 +114,7 @@ private: void addPtrAttribute(const char* pName, const NamedDecl* D); void addPtrAttribute(const char* pName, const DeclContext* D); void addPtrAttribute(const char* pName, const NamespaceDecl* D); // disambiguation + void addPtrAttribute(const char* pName, const NestedNameSpecifier* N); void addPtrAttribute(const char* pName, const LabelStmt* L); void addPtrAttribute(const char* pName, const char* text); @@ -145,12 +146,23 @@ inline void DocumentXML::initialize(ASTContext &Context) { //--------------------------------------------------------- template<class T> inline void DocumentXML::addAttribute(const char* pName, const T& value) { - Out << ' ' << pName << "=\"" << value << "\""; + std::string repr; + { + llvm::raw_string_ostream buf(repr); + buf << value; + buf.flush(); + } + + Out << ' ' << pName << "=\"" + << DocumentXML::escapeString(repr.c_str(), repr.size()) + << "\""; } //--------------------------------------------------------- inline void DocumentXML::addPtrAttribute(const char* pName, const char* text) { - Out << ' ' << pName << "=\"" << text << "\""; + Out << ' ' << pName << "=\"" + << DocumentXML::escapeString(text, strlen(text)) + << "\""; } //--------------------------------------------------------- diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h index 3ddd77d..cee1c1d 100644 --- a/include/clang/Frontend/FrontendActions.h +++ b/include/clang/Frontend/FrontendActions.h @@ -75,12 +75,10 @@ protected: }; class FixItAction : public ASTFrontendAction { -private: +protected: llvm::OwningPtr<FixItRewriter> Rewriter; llvm::OwningPtr<FixItPathRewriter> PathRewriter; -protected: - virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile); @@ -133,6 +131,12 @@ public: virtual bool hasCodeCompletionSupport() const { return true; } }; +class BoostConAction : public SyntaxOnlyAction { +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); +}; + /** * \brief Frontend action adaptor that merges ASTs together. * diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h index 60512ed..c43e680 100644 --- a/include/clang/Frontend/FrontendOptions.h +++ b/include/clang/Frontend/FrontendOptions.h @@ -23,13 +23,15 @@ namespace frontend { ASTPrint, ///< Parse ASTs and print them. ASTPrintXML, ///< Parse ASTs and print them in XML. ASTView, ///< Parse ASTs and view them in Graphviz. + BoostCon, ///< BoostCon mode. DumpRawTokens, ///< Dump out raw tokens. DumpTokens, ///< Dump out preprocessed tokens. EmitAssembly, ///< Emit a .s file. EmitBC, ///< Emit a .bc file. EmitHTML, ///< Translate input source into HTML. EmitLLVM, ///< Emit a .ll file. - EmitLLVMOnly, ///< Generate LLVM IR, but do not + EmitLLVMOnly, ///< Generate LLVM IR, but do not emit anything. + EmitCodeGenOnly, ///< Generate machine code, but don't emit anything. EmitObj, ///< Emit a .o file. FixIt, ///< Parse and apply any fixits to the source. GeneratePCH, ///< Generate pre-compiled header. @@ -77,6 +79,8 @@ public: unsigned ShowHelp : 1; ///< Show the -help text. unsigned ShowMacrosInCodeCompletion : 1; ///< Show macros in code completion /// results. + unsigned ShowCodePatternsInCodeCompletion : 1; ///< Show code patterns in code + /// completion results. unsigned ShowStats : 1; ///< Show frontend performance /// metrics and statistics. unsigned ShowTimers : 1; ///< Show timers for individual @@ -123,6 +127,7 @@ public: RelocatablePCH = 0; ShowHelp = 0; ShowMacrosInCodeCompletion = 0; + ShowCodePatternsInCodeCompletion = 0; ShowStats = 0; ShowTimers = 0; ShowVersion = 0; diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index 1640afb..2493cfd 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -415,7 +415,9 @@ namespace clang { /// \brief An UnresolvedUsingType record. TYPE_UNRESOLVED_USING = 26, /// \brief An InjectedClassNameType record. - TYPE_INJECTED_CLASS_NAME = 27 + TYPE_INJECTED_CLASS_NAME = 27, + /// \brief An ObjCObjectType record. + TYPE_OBJC_OBJECT = 28 }; /// \brief The type IDs for special types constructed by semantic @@ -534,8 +536,46 @@ namespace clang { /// IDs. This data is used when performing qualified name lookup /// into a DeclContext via DeclContext::lookup. DECL_CONTEXT_VISIBLE, - /// \brief A NamespaceDecl record. - DECL_NAMESPACE + /// \brief A NamespaceDecl rcord. + DECL_NAMESPACE, + /// \brief A NamespaceAliasDecl record. + DECL_NAMESPACE_ALIAS, + /// \brief A UsingDecl record. + DECL_USING, + /// \brief A UsingShadowDecl record. + DECL_USING_SHADOW, + /// \brief A UsingDirecitveDecl record. + DECL_USING_DIRECTIVE, + /// \brief An UnresolvedUsingValueDecl record. + DECL_UNRESOLVED_USING_VALUE, + /// \brief An UnresolvedUsingTypenameDecl record. + DECL_UNRESOLVED_USING_TYPENAME, + /// \brief A LinkageSpecDecl record. + DECL_LINKAGE_SPEC, + /// \brief A CXXRecordDecl record. + DECL_CXX_RECORD, + /// \brief A CXXMethodDecl record. + DECL_CXX_METHOD, + /// \brief A CXXConstructorDecl record. + DECL_CXX_CONSTRUCTOR, + /// \brief A CXXDestructorDecl record. + DECL_CXX_DESTRUCTOR, + /// \brief A CXXConversionDecl record. + DECL_CXX_CONVERSION, + + // FIXME: Implement serialization for these decl types. This just + // allocates the order in which + DECL_FRIEND, + DECL_FRIEND_TEMPLATE, + DECL_TEMPLATE, + DECL_CLASS_TEMPLATE, + DECL_CLASS_TEMPLATE_SPECIALIZATION, + DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION, + DECL_FUNCTION_TEMPLATE, + DECL_TEMPLATE_TYPE_PARM, + DECL_NON_TYPE_TEMPLATE_PARM, + DECL_TEMPLATE_TEMPLATE_PARM, + DECL_STATIC_ASSERT }; /// \brief Record codes for each kind of statement or expression. @@ -692,6 +732,8 @@ namespace clang { /// \brief A CXXOperatorCallExpr record. EXPR_CXX_OPERATOR_CALL, + /// \brief A CXXMemberCallExpr record. + EXPR_CXX_MEMBER_CALL, /// \brief A CXXConstructExpr record. EXPR_CXX_CONSTRUCT, // \brief A CXXStaticCastExpr record. @@ -706,8 +748,18 @@ namespace clang { EXPR_CXX_FUNCTIONAL_CAST, // \brief A CXXBoolLiteralExpr record. EXPR_CXX_BOOL_LITERAL, - // \brief A CXXNullPtrLiteralExpr record. - EXPR_CXX_NULL_PTR_LITERAL + EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr + EXPR_CXX_TYPEID_EXPR, // CXXTypeidExpr (of expr). + EXPR_CXX_TYPEID_TYPE, // CXXTypeidExpr (of type). + EXPR_CXX_THIS, // CXXThisExpr + EXPR_CXX_THROW, // CXXThrowExpr + EXPR_CXX_DEFAULT_ARG, // CXXDefaultArgExpr + EXPR_CXX_BIND_TEMPORARY, // CXXBindTemporaryExpr + // + EXPR_CXX_ZERO_INIT_VALUE, // CXXZeroInitValueExpr + EXPR_CXX_NEW, // CXXNewExpr + + EXPR_CXX_EXPR_WITH_TEMPORARIES // CXXExprWithTemporaries }; /// \brief The kinds of designators that can occur in a diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h index c235230..e144738 100644 --- a/include/clang/Frontend/PCHReader.h +++ b/include/clang/Frontend/PCHReader.h @@ -52,6 +52,9 @@ class ASTContext; class Attr; class Decl; class DeclContext; +class NestedNameSpecifier; +class CXXBaseSpecifier; +class CXXBaseOrMemberInitializer; class GotoStmt; class LabelStmt; class MacroDefinition; @@ -649,8 +652,8 @@ public: /// declarations with this name are visible from translation unit scope, their /// declarations will be deserialized and introduced into the declaration /// chain of the identifier. - virtual IdentifierInfo* get(const char *NameStart, const char *NameEnd); - IdentifierInfo* get(llvm::StringRef Name) { + virtual IdentifierInfo *get(const char *NameStart, const char *NameEnd); + IdentifierInfo *get(llvm::StringRef Name) { return get(Name.begin(), Name.end()); } @@ -694,8 +697,21 @@ public: Selector GetSelector(const RecordData &Record, unsigned &Idx) { return DecodeSelector(Record[Idx++]); } + + /// \brief Read a declaration name. DeclarationName ReadDeclarationName(const RecordData &Record, unsigned &Idx); + NestedNameSpecifier *ReadNestedNameSpecifier(const RecordData &Record, + unsigned &Idx); + + /// \brief Read a source location. + SourceLocation ReadSourceLocation(const RecordData &Record, unsigned& Idx) { + return SourceLocation::getFromRawEncoding(Record[Idx++]); + } + + /// \brief Read a source range. + SourceRange ReadSourceRange(const RecordData &Record, unsigned& Idx); + /// \brief Read an integral value llvm::APInt ReadAPInt(const RecordData &Record, unsigned &Idx); @@ -708,6 +724,8 @@ public: // \brief Read a string std::string ReadString(const RecordData &Record, unsigned &Idx); + CXXTemporary *ReadCXXTemporary(const RecordData &Record, unsigned &Idx); + /// \brief Reads attributes from the current stream position. Attr *ReadAttributes(); diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h index e006de5..85f53b9 100644 --- a/include/clang/Frontend/PCHWriter.h +++ b/include/clang/Frontend/PCHWriter.h @@ -32,6 +32,9 @@ namespace llvm { namespace clang { class ASTContext; +class NestedNameSpecifier; +class CXXBaseSpecifier; +class CXXBaseOrMemberInitializer; class LabelStmt; class MacroDefinition; class MemorizeStatCalls; @@ -251,6 +254,9 @@ public: /// \brief Emit a source location. void AddSourceLocation(SourceLocation Loc, RecordData &Record); + /// \brief Emit a source range. + void AddSourceRange(SourceRange Range, RecordData &Record); + /// \brief Emit an integral value. void AddAPInt(const llvm::APInt &Value, RecordData &Record); @@ -260,12 +266,15 @@ public: /// \brief Emit a floating-point value. void AddAPFloat(const llvm::APFloat &Value, RecordData &Record); - /// \brief Emit a reference to an identifier + /// \brief Emit a reference to an identifier. void AddIdentifierRef(const IdentifierInfo *II, RecordData &Record); - /// \brief Emit a Selector (which is a smart pointer reference) - void AddSelectorRef(const Selector, RecordData &Record); + /// \brief Emit a Selector (which is a smart pointer reference). + void AddSelectorRef(Selector, RecordData &Record); + /// \brief Emit a CXXTemporary. + void AddCXXTemporary(const CXXTemporary *Temp, RecordData &Record); + /// \brief Get the unique number used to refer to the given /// identifier. pch::IdentID getIdentifierRef(const IdentifierInfo *II); @@ -304,6 +313,9 @@ public: /// \brief Emit a declaration name. void AddDeclarationName(DeclarationName Name, RecordData &Record); + /// \brief Emit a nested name specifier. + void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordData &Record); + /// \brief Add a string to the given record. void AddString(const std::string &Str, RecordData &Record); diff --git a/include/clang/Frontend/TypeXML.def b/include/clang/Frontend/TypeXML.def index 3add99a..069d718 100644 --- a/include/clang/Frontend/TypeXML.def +++ b/include/clang/Frontend/TypeXML.def @@ -61,6 +61,10 @@ # define CONTEXT_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "context") #endif +NODE_XML(Type, "FIXME_Type") + ID_ATTRIBUTE_XML + ATTRIBUTE_XML(getTypeClassName(), "unhandled_type_name") +END_NODE_XML NODE_XML(QualType, "CvQualifiedType") ID_ATTRIBUTE_XML @@ -207,9 +211,9 @@ NODE_XML(RecordType, "Record") ID_ATTRIBUTE_XML ATTRIBUTE_XML(getDecl()->getNameAsString(), "name") // string ATTRIBUTE_ENUM_XML(getDecl()->getTagKind(), "kind") - ENUM_XML(TagDecl::TK_struct, "struct") - ENUM_XML(TagDecl::TK_union, "union") - ENUM_XML(TagDecl::TK_class, "class") + ENUM_XML(TTK_Struct, "struct") + ENUM_XML(TTK_Union, "union") + ENUM_XML(TTK_Class, "class") END_ENUM_XML CONTEXT_ATTRIBUTE_XML(getDecl()->getDeclContext()) END_NODE_XML @@ -228,11 +232,23 @@ NODE_XML(TemplateSpecializationType, "TemplateSpecializationType") ID_ATTRIBUTE_XML END_NODE_XML -NODE_XML(QualifiedNameType, "QualifiedNameType") +NODE_XML(ElaboratedType, "ElaboratedType") ID_ATTRIBUTE_XML + ATTRIBUTE_ENUM_XML(getKeyword(), "keyword") + ENUM_XML(ETK_None, "none") + ENUM_XML(ETK_Typename, "typename") + ENUM_XML(ETK_Struct, "struct") + ENUM_XML(ETK_Union, "union") + ENUM_XML(ETK_Class, "class") + ENUM_XML(ETK_Enum, "enum") + END_ENUM_XML TYPE_ATTRIBUTE_XML(getNamedType()) END_NODE_XML +NODE_XML(InjectedClassNameType, "InjectedClassNameType") + ID_ATTRIBUTE_XML +END_NODE_XML + NODE_XML(DependentNameType, "DependentNameType") ID_ATTRIBUTE_XML END_NODE_XML @@ -245,6 +261,29 @@ NODE_XML(ObjCObjectPointerType, "ObjCObjectPointerType") ID_ATTRIBUTE_XML END_NODE_XML +NODE_XML(SubstTemplateTypeParmType, "SubstTemplateTypeParm") + ID_ATTRIBUTE_XML +END_NODE_XML + +NODE_XML(DependentSizedExtVectorType, "DependentSizedExtVector") + ID_ATTRIBUTE_XML +END_NODE_XML + +NODE_XML(UnresolvedUsingType, "UnresolvedUsing") + ID_ATTRIBUTE_XML +END_NODE_XML + +NODE_XML(DependentTypeOfExprType, "DependentTypeOfExpr") + ID_ATTRIBUTE_XML +END_NODE_XML + +NODE_XML(DecltypeType, "Decltype") + ID_ATTRIBUTE_XML +END_NODE_XML + +NODE_XML(DependentDecltypeType, "DependentDecltype") + ID_ATTRIBUTE_XML +END_NODE_XML //===----------------------------------------------------------------------===// #undef NODE_XML diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h index 2334d72..ba46fb1 100644 --- a/include/clang/Lex/LiteralSupport.h +++ b/include/clang/Lex/LiteralSupport.h @@ -147,7 +147,7 @@ class StringLiteralParser { char *ResultPtr; // cursor public: StringLiteralParser(const Token *StringToks, unsigned NumStringToks, - Preprocessor &PP); + Preprocessor &PP, bool Complain = true); bool hadError; bool AnyWide; bool Pascal; @@ -164,7 +164,7 @@ public: /// specified byte of the string data represented by Token. This handles /// advancing over escape sequences in the string. static unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo, - Preprocessor &PP); + Preprocessor &PP, bool Complain = true); }; } // end namespace clang diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 20d9fc5..f01b3af 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -290,8 +290,8 @@ public: /// expansions going on at the time. PreprocessorLexer *getCurrentLexer() const { return CurPPLexer; } - /// getCurrentFileLexer - Return the current file lexer being lexed from. Note - /// that this ignores any potentially active macro expansions and _Pragma + /// getCurrentFileLexer - Return the current file lexer being lexed from. + /// Note that this ignores any potentially active macro expansions and _Pragma /// expansions going on at the time. PreprocessorLexer *getCurrentFileLexer() const; @@ -753,9 +753,9 @@ public: /// #include FOO /// because in this case, "<a/b.h>" is returned as 7 tokens, not one. /// - /// This code concatenates and consumes tokens up to the '>' token. It returns - /// false if the > was found, otherwise it returns true if it finds and consumes - /// the EOM marker. + /// This code concatenates and consumes tokens up to the '>' token. It + /// returns false if the > was found, otherwise it returns true if it finds + /// and consumes the EOM marker. bool ConcatenateIncludeName(llvm::SmallString<128> &FilenameBuffer); private: @@ -900,8 +900,6 @@ private: // Macro handling. void HandleDefineDirective(Token &Tok); void HandleUndefDirective(Token &Tok); - // HandleAssertDirective(Token &Tok); - // HandleUnassertDirective(Token &Tok); // Conditional Inclusion. void HandleIfdefDirective(Token &Tok, bool isIfndef, diff --git a/include/clang/Makefile b/include/clang/Makefile index d76e0a9..6abe375 100644 --- a/include/clang/Makefile +++ b/include/clang/Makefile @@ -1,5 +1,5 @@ LEVEL = ../../../.. -DIRS := Basic Driver +DIRS := AST Basic Driver include $(LEVEL)/Makefile.common @@ -10,7 +10,7 @@ install-local:: cd $(PROJ_SRC_ROOT)/tools/clang/include && \ for hdr in `find clang -type f '!' '(' -name '*~' \ -o -name '.#*' -o -name '*.in' -o -name '*.txt' \ - -o -name 'Makefile' -o -name '*.td' ')' -print \ + -o -name 'Makefile' -o -name '*.td' -o -name '*.orig' ')' -print \ | grep -v CVS | grep -v .svn | grep -v .dir` ; do \ instdir=$(DESTDIR)`dirname "$(PROJ_includedir)/$$hdr"` ; \ if test \! -d "$$instdir" ; then \ diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 3d68d80..e21da81 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -105,12 +105,19 @@ public: class FullExprArg { public: + FullExprArg(ActionBase &actions) : Expr(actions) { } + // FIXME: The const_cast here is ugly. RValue references would make this // much nicer (or we could duplicate a bunch of the move semantics // emulation code from Ownership.h). FullExprArg(const FullExprArg& Other) : Expr(move(const_cast<FullExprArg&>(Other).Expr)) {} + FullExprArg &operator=(const FullExprArg& Other) { + Expr.operator=(move(const_cast<FullExprArg&>(Other).Expr)); + return *this; + } + OwningExprResult release() { return move(Expr); } @@ -279,13 +286,18 @@ public: /// \param Template if the name does refer to a template, the declaration /// of the template that the name refers to. /// + /// \param MemberOfUnknownSpecialization Will be set true if the resulting + /// member would be a member of an unknown specialization, in which case this + /// lookup cannot possibly pass at this time. + /// /// \returns the kind of template that this name refers to. virtual TemplateNameKind isTemplateName(Scope *S, CXXScopeSpec &SS, UnqualifiedId &Name, TypeTy *ObjectType, bool EnteringContext, - TemplateTy &Template) = 0; + TemplateTy &Template, + bool &MemberOfUnknownSpecialization) = 0; /// \brief Action called as part of error recovery when the parser has /// determined that the given name must refer to a template, but @@ -566,7 +578,9 @@ public: /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with /// no declarator (e.g. "struct foo;") is parsed. - virtual DeclPtrTy ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) { + virtual DeclPtrTy ParsedFreeStandingDeclSpec(Scope *S, + AccessSpecifier Access, + DeclSpec &DS) { return DeclPtrTy(); } @@ -826,21 +840,19 @@ public: /// \brief Parsed the start of a "switch" statement. /// + /// \param SwitchLoc The location of the "switch" keyword. + /// /// \param Cond if the "switch" condition was parsed as an expression, /// the expression itself. /// /// \param CondVar if the "switch" condition was parsed as a condition /// variable, the condition variable itself. - virtual OwningStmtResult ActOnStartOfSwitchStmt(FullExprArg Cond, + virtual OwningStmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, + ExprArg Cond, DeclPtrTy CondVar) { return StmtEmpty(); } - /// ActOnSwitchBodyError - This is called if there is an error parsing the - /// body of the switch stmt instead of ActOnFinishSwitchStmt. - virtual void ActOnSwitchBodyError(SourceLocation SwitchLoc, StmtArg Switch, - StmtArg Body) {} - virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch, StmtArg Body) { return StmtEmpty(); @@ -1609,6 +1621,22 @@ public: return DeclResult(); } + /// \brief Parsed an expression that will be handled as the condition in + /// an if/while/for statement. + /// + /// This routine handles the conversion of the expression to 'bool'. + /// + /// \param S The scope in which the expression occurs. + /// + /// \param Loc The location of the construct that requires the conversion to + /// a boolean value. + /// + /// \param SubExpr The expression that is being converted to bool. + virtual OwningExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc, + ExprArg SubExpr) { + return move(SubExpr); + } + /// ActOnCXXNew - Parsed a C++ 'new' expression. UseGlobal is true if the /// new was qualified (::new). In a full new like /// @code new (p1, p2) type(c1, c2) @endcode @@ -2303,6 +2331,7 @@ public: } // ActOnPropertyImplDecl - called for every property implementation virtual DeclPtrTy ActOnPropertyImplDecl( + Scope *S, SourceLocation AtLoc, // location of the @synthesize/@dynamic SourceLocation PropertyNameLoc, // location for the property name bool ImplKind, // true for @synthesize, false for @@ -2346,7 +2375,7 @@ public: // protocols, categories), the parser passes all methods/properties. // For class implementations, these values default to 0. For implementations, // methods are processed incrementally (by ActOnMethodDeclaration above). - virtual void ActOnAtEnd(SourceRange AtEnd, + virtual void ActOnAtEnd(Scope *S, SourceRange AtEnd, DeclPtrTy classDecl, DeclPtrTy *allMethods = 0, unsigned allNum = 0, @@ -2535,6 +2564,21 @@ public: //===---------------------------- Pragmas -------------------------------===// + enum PragmaOptionsAlignKind { + POAK_Natural, // #pragma options align=natural + POAK_Power, // #pragma options align=power + POAK_Mac68k, // #pragma options align=mac68k + POAK_Reset // #pragma options align=reset + }; + + /// ActOnPragmaOptionsAlign - Called on well formed #pragma options + /// align={...}. + virtual void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, + SourceLocation PragmaLoc, + SourceLocation KindLoc) { + return; + } + enum PragmaPackKind { PPK_Default, // #pragma pack([n]) PPK_Show, // #pragma pack(show), only supported by MSVC. @@ -2620,9 +2664,13 @@ public: /// \brief Code completion occurs at the beginning of the /// initialization statement (or expression) in a for loop. CCC_ForInit, - /// \brief Code completion ocurs within the condition of an if, + /// \brief Code completion occurs within the condition of an if, /// while, switch, or for statement. - CCC_Condition + CCC_Condition, + /// \brief Code completion occurs within the body of a function on a + /// recovery path, where we do not have a specific handle on our position + /// in the grammar. + CCC_RecoveryInFunction }; /// \brief Code completion for an ordinary name that occurs within the given @@ -3003,7 +3051,9 @@ public: UnqualifiedId &Name, TypeTy *ObjectType, bool EnteringContext, - TemplateTy &Template); + TemplateTy &Template, + bool &MemberOfUnknownSpecialization); + /// ActOnDeclarator - If this is a typedef declarator, we modify the /// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h index 12512f3..1e6d3ab 100644 --- a/include/clang/Parse/AttributeList.h +++ b/include/clang/Parse/AttributeList.h @@ -55,6 +55,7 @@ public: enum Kind { // Please keep this list alphabetized. AT_IBAction, // Clang-specific. AT_IBOutlet, // Clang-specific. + AT_IBOutletCollection, // Clang-specific. AT_address_space, AT_alias, AT_aligned, @@ -102,6 +103,7 @@ public: AT_section, AT_sentinel, AT_stdcall, + AT_thiscall, AT_transparent_union, AT_unavailable, AT_unused, diff --git a/include/clang/Parse/Ownership.h b/include/clang/Parse/Ownership.h index 5eb9635..e9a20b7 100644 --- a/include/clang/Parse/Ownership.h +++ b/include/clang/Parse/Ownership.h @@ -166,7 +166,7 @@ namespace llvm { // conversions. // Flip this switch to measure performance impact of the smart pointers. -//#define DISABLE_SMART_POINTERS +// #define DISABLE_SMART_POINTERS namespace llvm { template<> @@ -403,8 +403,10 @@ namespace clang { friend class moving::ASTResultMover<Destroyer>; +#if !(defined(_MSC_VER) && _MSC_VER >= 1600) ASTOwningResult(ASTOwningResult&); // DO NOT IMPLEMENT ASTOwningResult& operator =(ASTOwningResult&); // DO NOT IMPLEMENT +#endif void destroy() { if (Ptr) { @@ -444,6 +446,19 @@ namespace clang { return *this; } +#if defined(_MSC_VER) && _MSC_VER >= 1600 + // Emulated move semantics don't work with msvc. + ASTOwningResult(ASTOwningResult &&mover) + : ActionInv(mover.ActionInv), + Ptr(mover.Ptr) { + mover.Ptr = 0; + } + ASTOwningResult &operator=(ASTOwningResult &&mover) { + *this = moving::ASTResultMover<Destroyer>(mover); + return *this; + } +#endif + /// Assignment from a raw pointer. Takes ownership - beware! ASTOwningResult &operator=(void *raw) { destroy(); diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 42a41d6..8081c24 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -110,6 +110,7 @@ class Parser { IdentifierInfo *Ident_vector; IdentifierInfo *Ident_pixel; + llvm::OwningPtr<PragmaHandler> OptionsHandler; llvm::OwningPtr<PragmaHandler> PackHandler; llvm::OwningPtr<PragmaHandler> UnusedHandler; llvm::OwningPtr<PragmaHandler> WeakHandler; @@ -234,6 +235,11 @@ private: assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() && !isTokenBrace() && "Should consume special tokens with Consume*Token"); + if (Tok.is(tok::code_completion)) { + CodeCompletionRecovery(); + return ConsumeCodeCompletionToken(); + } + PrevTokLocation = Tok.getLocation(); PP.Lex(Tok); return PrevTokLocation; @@ -308,6 +314,22 @@ private: return PrevTokLocation; } + /// \brief Consume the current code-completion token. + /// + /// This routine should be called to consume the code-completion token once + /// a code-completion action has already been invoked. + SourceLocation ConsumeCodeCompletionToken() { + assert(Tok.is(tok::code_completion)); + PrevTokLocation = Tok.getLocation(); + PP.Lex(Tok); + return PrevTokLocation; + } + + ///\ brief When we are consuming a code-completion token within having + /// matched specific position in the grammar, provide code-completion results + /// based on context. + void CodeCompletionRecovery(); + /// GetLookAheadToken - This peeks ahead N tokens and returns that token /// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1) /// returns the token after Tok, etc. @@ -1004,7 +1026,8 @@ private: //===--------------------------------------------------------------------===// // C++ if/switch/while condition expression. - bool ParseCXXCondition(OwningExprResult &ExprResult, DeclPtrTy &DeclResult); + bool ParseCXXCondition(OwningExprResult &ExprResult, DeclPtrTy &DeclResult, + SourceLocation Loc, bool ConvertToBoolean); //===--------------------------------------------------------------------===// // C++ types @@ -1060,7 +1083,9 @@ private: bool isStmtExpr = false); OwningStmtResult ParseCompoundStatementBody(bool isStmtExpr = false); bool ParseParenExprOrCondition(OwningExprResult &ExprResult, - DeclPtrTy &DeclResult); + DeclPtrTy &DeclResult, + SourceLocation Loc, + bool ConvertToBoolean); OwningStmtResult ParseIfStatement(AttributeList *Attr); OwningStmtResult ParseSwitchStatement(AttributeList *Attr); OwningStmtResult ParseWhileStatement(AttributeList *Attr); @@ -1348,6 +1373,8 @@ private: AttributeList *AttrList = 0, bool RequiresArg = false); void ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc, + IdentifierInfo *FirstIdent, + SourceLocation FirstIdentLoc, Declarator &D); void ParseBracketDeclarator(Declarator &D); @@ -1403,7 +1430,8 @@ private: bool EnteringContext, TypeTy *ObjectType, UnqualifiedId &Id, - bool AssumeTemplateId = false); + bool AssumeTemplateId, + SourceLocation TemplateKWLoc); bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, TypeTy *ObjectType, UnqualifiedId &Result); @@ -1457,6 +1485,7 @@ private: SourceLocation TemplateKWLoc = SourceLocation(), bool AllowTypeAnnotation = true); void AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS = 0); + bool IsTemplateArgumentList(unsigned Skip = 0); bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs); ParsedTemplateArgument ParseTemplateTemplateArgument(); ParsedTemplateArgument ParseTemplateArgument(); diff --git a/include/clang/Parse/Scope.h b/include/clang/Parse/Scope.h index d7a0e35..023f40d 100644 --- a/include/clang/Parse/Scope.h +++ b/include/clang/Parse/Scope.h @@ -74,7 +74,7 @@ public: /// It always has FnScope and DeclScope set as well. ObjCMethodScope = 0x400, - /// ElseScope - This scoep corresponds to an 'else' scope of an if/then/else + /// ElseScope - This scope corresponds to an 'else' scope of an if/then/else /// statement. ElseScope = 0x800 }; diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h index 348917a..1f1c0cc 100644 --- a/include/clang/Sema/CodeCompleteConsumer.h +++ b/include/clang/Sema/CodeCompleteConsumer.h @@ -24,6 +24,41 @@ class raw_ostream; namespace clang { +/// \brief Default priority values for code-completion results based +/// on their kind. +enum { + /// \brief Priority for a declaration that is in the local scope. + CCP_LocalDeclaration = 8, + /// \brief Priority for a member declaration found from the current + /// method or member function. + CCP_MemberDeclaration = 20, + /// \brief Priority for a language keyword (that isn't any of the other + /// categories). + CCP_Keyword = 30, + /// \brief Priority for a code pattern. + CCP_CodePattern = 30, + /// \brief Priority for a type. + CCP_Type = 40, + /// \brief Priority for a non-type declaration. + CCP_Declaration = 50, + /// \brief Priority for a constant value (e.g., enumerator). + CCP_Constant = 60, + /// \brief Priority for a preprocessor macro. + CCP_Macro = 70, + /// \brief Priority for a nested-name-specifier. + CCP_NestedNameSpecifier = 75, + /// \brief Priority for a result that isn't likely to be what the user wants, + /// but is included for completeness. + CCP_Unlikely = 80 +}; + +/// \brief Priority value deltas that are applied to code-completion results +/// based on the context of the result. +enum { + /// \brief The result is in a base class. + CCD_InBaseClass = 2 +}; + class FunctionDecl; class FunctionType; class FunctionTemplateDecl; @@ -156,13 +191,14 @@ private: public: CodeCompletionString() { } - ~CodeCompletionString(); + ~CodeCompletionString() { clear(); } typedef llvm::SmallVector<Chunk, 4>::const_iterator iterator; iterator begin() const { return Chunks.begin(); } iterator end() const { return Chunks.end(); } bool empty() const { return Chunks.empty(); } unsigned size() const { return Chunks.size(); } + void clear(); Chunk &operator[](unsigned I) { assert(I < size() && "Chunk index out-of-range"); @@ -232,8 +268,9 @@ public: void Serialize(llvm::raw_ostream &OS) const; /// \brief Deserialize a code-completion string from the given string. - static CodeCompletionString *Deserialize(const char *&Str, - const char *StrEnd); + /// + /// \returns true if successful, false otherwise. + bool Deserialize(const char *&Str, const char *StrEnd); }; llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, @@ -246,6 +283,10 @@ protected: /// \brief Whether to include macros in the code-completion results. bool IncludeMacros; + /// \brief Whether to include code patterns (such as for loops) within + /// the completion results. + bool IncludeCodePatterns; + /// \brief Whether the output format for the code-completion consumer is /// binary. bool OutputIsBinary; @@ -280,8 +321,11 @@ public: /// \brief When Kind == RK_Macro, the identifier that refers to a macro. IdentifierInfo *Macro; }; - - /// \brief Specifiers which parameter (of a function, Objective-C method, + + /// \brief The priority of this particular code-completion result. + unsigned Priority; + + /// \brief Specifies which parameter (of a function, Objective-C method, /// macro, etc.) we should start with when formatting the result. unsigned StartParameter; @@ -309,29 +353,30 @@ public: NestedNameSpecifier *Qualifier = 0, bool QualifierIsInformative = false) : Kind(RK_Declaration), Declaration(Declaration), - StartParameter(0), Hidden(false), - QualifierIsInformative(QualifierIsInformative), + Priority(getPriorityFromDecl(Declaration)), StartParameter(0), + Hidden(false), QualifierIsInformative(QualifierIsInformative), StartsNestedNameSpecifier(false), AllParametersAreInformative(false), - Qualifier(Qualifier) { } + Qualifier(Qualifier) { + } /// \brief Build a result that refers to a keyword or symbol. - Result(const char *Keyword) - : Kind(RK_Keyword), Keyword(Keyword), StartParameter(0), - Hidden(false), QualifierIsInformative(0), + Result(const char *Keyword, unsigned Priority = CCP_Keyword) + : Kind(RK_Keyword), Keyword(Keyword), Priority(Priority), + StartParameter(0), Hidden(false), QualifierIsInformative(0), StartsNestedNameSpecifier(false), AllParametersAreInformative(false), Qualifier(0) { } /// \brief Build a result that refers to a macro. - Result(IdentifierInfo *Macro) - : Kind(RK_Macro), Macro(Macro), StartParameter(0), + Result(IdentifierInfo *Macro, unsigned Priority = CCP_Macro) + : Kind(RK_Macro), Macro(Macro), Priority(Priority), StartParameter(0), Hidden(false), QualifierIsInformative(0), StartsNestedNameSpecifier(false), AllParametersAreInformative(false), Qualifier(0) { } /// \brief Build a result that refers to a pattern. - Result(CodeCompletionString *Pattern) - : Kind(RK_Pattern), Pattern(Pattern), StartParameter(0), - Hidden(false), QualifierIsInformative(0), + Result(CodeCompletionString *Pattern, unsigned Priority = CCP_CodePattern) + : Kind(RK_Pattern), Pattern(Pattern), Priority(Priority), + StartParameter(0), Hidden(false), QualifierIsInformative(0), StartsNestedNameSpecifier(false), AllParametersAreInformative(false), Qualifier(0) { } @@ -352,6 +397,9 @@ public: CodeCompletionString *CreateCodeCompletionString(Sema &S); void Destroy(); + + /// brief Determine a base priority for the given declaration. + static unsigned getPriorityFromDecl(NamedDecl *ND); }; class OverloadCandidate { @@ -420,12 +468,17 @@ public: CodeCompleteConsumer() : IncludeMacros(false), OutputIsBinary(false) { } - CodeCompleteConsumer(bool IncludeMacros, bool OutputIsBinary) - : IncludeMacros(IncludeMacros), OutputIsBinary(OutputIsBinary) { } + CodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns, + bool OutputIsBinary) + : IncludeMacros(IncludeMacros), IncludeCodePatterns(IncludeCodePatterns), + OutputIsBinary(OutputIsBinary) { } /// \brief Whether the code-completion consumer wants to see macros. bool includeMacros() const { return IncludeMacros; } + /// \brief Whether the code-completion consumer wants to see code patterns. + bool includeCodePatterns() const { return IncludeCodePatterns; } + /// \brief Determine whether the output of this consumer is binary. bool isOutputBinary() const { return OutputIsBinary; } @@ -461,9 +514,9 @@ class PrintingCodeCompleteConsumer : public CodeCompleteConsumer { public: /// \brief Create a new printing code-completion consumer that prints its /// results to the given raw output stream. - PrintingCodeCompleteConsumer(bool IncludeMacros, + PrintingCodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns, llvm::raw_ostream &OS) - : CodeCompleteConsumer(IncludeMacros, false), OS(OS) { } + : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, false), OS(OS) {} /// \brief Prints the finalized code-completion results. virtual void ProcessCodeCompleteResults(Sema &S, Result *Results, @@ -484,8 +537,9 @@ public: /// \brief Create a new CIndex code-completion consumer that prints its /// results to the given raw output stream in a format readable to the CIndex /// library. - CIndexCodeCompleteConsumer(bool IncludeMacros, llvm::raw_ostream &OS) - : CodeCompleteConsumer(IncludeMacros, true), OS(OS) { } + CIndexCodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns, + llvm::raw_ostream &OS) + : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, true), OS(OS) {} /// \brief Prints the finalized code-completion results. virtual void ProcessCodeCompleteResults(Sema &S, Result *Results, |