diff options
Diffstat (limited to 'include/clang')
28 files changed, 474 insertions, 187 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index cf9aa50af2a1..d12a182078e4 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -40,6 +40,7 @@ namespace clang { class ASTRecordLayout; class BlockExpr; class CharUnits; + class Diagnostic; class Expr; class ExternalASTSource; class IdentifierTable; @@ -950,8 +951,6 @@ public: llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars); void CollectNonClassIvars(const ObjCInterfaceDecl *OI, llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars); - void CollectProtocolSynthesizedIvars(const ObjCProtocolDecl *PD, - llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars); unsigned CountSynthesizedIvars(const ObjCInterfaceDecl *OI); unsigned CountProtocolSynthesizedIvars(const ObjCProtocolDecl *PD); void CollectInheritedProtocols(const Decl *CDecl, diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index bd9f01b0b5ef..e23811d8f9c0 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -319,7 +319,19 @@ public: /// \brief Represents a ValueDecl that came out of a declarator. /// Contains type source information through TypeSourceInfo. class DeclaratorDecl : public ValueDecl { - TypeSourceInfo *DeclInfo; + // A struct representing both a TInfo and a syntactic qualifier, + // to be used for the (uncommon) case of out-of-line declarations. + struct ExtInfo { + TypeSourceInfo *TInfo; + NestedNameSpecifier *NNS; + SourceRange NNSRange; + }; + + llvm::PointerUnion<TypeSourceInfo*, ExtInfo*> DeclInfo; + + bool hasExtInfo() const { return DeclInfo.is<ExtInfo*>(); } + ExtInfo *getExtInfo() { return DeclInfo.get<ExtInfo*>(); } + const ExtInfo *getExtInfo() const { return DeclInfo.get<ExtInfo*>(); } protected: DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L, @@ -327,8 +339,29 @@ protected: : ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo) {} public: - TypeSourceInfo *getTypeSourceInfo() const { return DeclInfo; } - void setTypeSourceInfo(TypeSourceInfo *TInfo) { DeclInfo = TInfo; } + virtual ~DeclaratorDecl(); + virtual void Destroy(ASTContext &C); + + TypeSourceInfo *getTypeSourceInfo() const { + return hasExtInfo() + ? DeclInfo.get<ExtInfo*>()->TInfo + : DeclInfo.get<TypeSourceInfo*>(); + } + void setTypeSourceInfo(TypeSourceInfo *TI) { + if (hasExtInfo()) + DeclInfo.get<ExtInfo*>()->TInfo = TI; + else + DeclInfo = TI; + } + + NestedNameSpecifier *getQualifier() const { + return hasExtInfo() ? DeclInfo.get<ExtInfo*>()->NNS : 0; + } + SourceRange getQualifierRange() const { + return hasExtInfo() ? DeclInfo.get<ExtInfo*>()->NNSRange : SourceRange(); + } + void setQualifierInfo(NestedNameSpecifier *Qualifier, + SourceRange QualifierRange); SourceLocation getTypeSpecStartLoc() const; @@ -500,7 +533,8 @@ public: bool isExternC() const; /// isBlockVarDecl - Returns true for local variable declarations. Note that - /// this includes static variables inside of functions. + /// this includes static variables inside of functions. It also includes + /// variables inside blocks. /// /// void foo() { int x; static int y; extern int z; } /// @@ -512,6 +546,17 @@ public: return false; } + /// isFunctionOrMethodVarDecl - Similar to isBlockVarDecl, but excludes + /// variables declared in blocks. + bool isFunctionOrMethodVarDecl() const { + if (getKind() != Decl::Var) + return false; + if (const DeclContext *DC = getDeclContext()) + return DC->getLookupContext()->isFunctionOrMethod() && + DC->getLookupContext()->getDeclKind() != Decl::Block; + return false; + } + /// \brief Determines whether this is a static data member. /// /// This will only be true in C++, and applies to, e.g., the @@ -797,12 +842,14 @@ class ParmVarDecl : public VarDecl { /// FIXME: Also can be paced into the bitfields in Decl. /// in, inout, etc. unsigned objcDeclQualifier : 6; + bool HasInheritedDefaultArg : 1; protected: ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg) - : VarDecl(DK, DC, L, Id, T, TInfo, S), objcDeclQualifier(OBJC_TQ_None) { + : VarDecl(DK, DC, L, Id, T, TInfo, S), + objcDeclQualifier(OBJC_TQ_None), HasInheritedDefaultArg(false) { setDefaultArg(DefArg); } @@ -881,6 +928,14 @@ public: Init = (UnparsedDefaultArgument *)0; } + bool hasInheritedDefaultArg() const { + return HasInheritedDefaultArg; + } + + void setHasInheritedDefaultArg(bool I = true) { + HasInheritedDefaultArg = I; + } + QualType getOriginalType() const { if (getTypeSourceInfo()) return getTypeSourceInfo()->getType(); @@ -1512,22 +1567,38 @@ private: /// IsEmbeddedInDeclarator - True if this tag declaration is /// "embedded" (i.e., defined or declared for the very first time) - /// in the syntax of a declarator, + /// in the syntax of a declarator. bool IsEmbeddedInDeclarator : 1; - /// TypedefForAnonDecl - If a TagDecl is anonymous and part of a typedef, - /// this points to the TypedefDecl. Used for mangling. - TypedefDecl *TypedefForAnonDecl; - SourceLocation TagKeywordLoc; SourceLocation RBraceLoc; + // A struct representing syntactic qualifier info, + // to be used for the (uncommon) case of out-of-line declarations. + struct ExtInfo { + NestedNameSpecifier *NNS; + SourceRange NNSRange; + }; + + /// TypedefDeclOrQualifier - If the (out-of-line) tag declaration name + /// is qualified, it points to the qualifier info (nns and range); + /// otherwise, if the tag declaration is anonymous and it is part of + /// a typedef, it points to the TypedefDecl (used for mangling); + /// otherwise, it is a null (TypedefDecl) pointer. + llvm::PointerUnion<TypedefDecl*, ExtInfo*> TypedefDeclOrQualifier; + + bool hasExtInfo() const { return TypedefDeclOrQualifier.is<ExtInfo*>(); } + ExtInfo *getExtInfo() { return TypedefDeclOrQualifier.get<ExtInfo*>(); } + const ExtInfo *getExtInfo() const { + return TypedefDeclOrQualifier.get<ExtInfo*>(); + } + protected: - TagDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, TagDecl *PrevDecl, - SourceLocation TKL = SourceLocation()) - : TypeDecl(DK, DC, L, Id), DeclContext(DK), TypedefForAnonDecl(0), - TagKeywordLoc(TKL) { + TagDecl(Kind DK, TagKind TK, DeclContext *DC, + SourceLocation L, IdentifierInfo *Id, + 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"); TagDeclKind = TK; IsDefinition = false; @@ -1539,6 +1610,8 @@ protected: virtual TagDecl *getNextRedeclaration() { return RedeclLink.getNext(); } public: + void Destroy(ASTContext &C); + typedef redeclarable_base::redecl_iterator redecl_iterator; redecl_iterator redecls_begin() const { return redeclarable_base::redecls_begin(); @@ -1618,8 +1691,21 @@ public: bool isUnion() const { return getTagKind() == TK_union; } bool isEnum() const { return getTagKind() == TK_enum; } - TypedefDecl *getTypedefForAnonDecl() const { return TypedefForAnonDecl; } - void setTypedefForAnonDecl(TypedefDecl *TDD) { TypedefForAnonDecl = TDD; } + TypedefDecl *getTypedefForAnonDecl() const { + return hasExtInfo() ? 0 : TypedefDeclOrQualifier.get<TypedefDecl*>(); + } + void setTypedefForAnonDecl(TypedefDecl *TDD) { TypedefDeclOrQualifier = TDD; } + + NestedNameSpecifier *getQualifier() const { + return hasExtInfo() ? TypedefDeclOrQualifier.get<ExtInfo*>()->NNS : 0; + } + SourceRange getQualifierRange() const { + return hasExtInfo() + ? TypedefDeclOrQualifier.get<ExtInfo*>()->NNSRange + : SourceRange(); + } + void setQualifierInfo(NestedNameSpecifier *Qualifier, + SourceRange QualifierRange); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 0bdc6f54b7ca..6f8284458f2b 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -660,7 +660,7 @@ public: /// \brief Determine whether this declaration context is equivalent /// to the declaration context DC. bool Equals(DeclContext *DC) { - return this->getPrimaryContext() == DC->getPrimaryContext(); + return DC && this->getPrimaryContext() == DC->getPrimaryContext(); } /// \brief Determine whether this declaration context encloses the diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index af00c8d7e8ad..6b04ed54109a 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -7,7 +7,8 @@ // //===----------------------------------------------------------------------===// // -// This file defines the C++ Decl subclasses. +// This file defines the C++ Decl subclasses, other than those for +// templates (in DeclTemplate.h) and friends (in DeclFriend.h). // //===----------------------------------------------------------------------===// @@ -32,6 +33,7 @@ class CXXDestructorDecl; class CXXMethodDecl; class CXXRecordDecl; class CXXMemberLookupCriteria; +class FriendDecl; /// \brief Represents any kind of function declaration, whether it is a /// concrete function or a function template. @@ -298,6 +300,11 @@ class CXXRecordDecl : public RecordDecl { /// Definition - The declaration which defines this record. CXXRecordDecl *Definition; + /// FirstFriend - The first friend declaration in this class, or + /// null if there aren't any. This is actually currently stored + /// in reverse order. + FriendDecl *FirstFriend; + } *DefinitionData; struct DefinitionData &data() { @@ -322,12 +329,6 @@ class CXXRecordDecl : public RecordDecl { llvm::PointerUnion<ClassTemplateDecl*, MemberSpecializationInfo*> TemplateOrInstantiation; - void getNestedVisibleConversionFunctions(CXXRecordDecl *RD, - const llvm::SmallPtrSet<CanQualType, 8> &TopConversionsTypeSet, - const llvm::SmallPtrSet<CanQualType, 8> &HiddenConversionTypes); - void collectConversionFunctions( - llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet) const; - protected: CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, @@ -458,6 +459,13 @@ public: return ctor_iterator(decls_end()); } + /// An iterator over friend declarations. All of these are defined + /// in DeclFriend.h. + class friend_iterator; + friend_iterator friend_begin() const; + friend_iterator friend_end() const; + void pushFriendDecl(FriendDecl *FD); + /// hasConstCopyConstructor - Determines whether this class has a /// copy constructor that accepts a const-qualified argument. bool hasConstCopyConstructor(ASTContext &Context) const; @@ -545,14 +553,6 @@ public: /// in current class; including conversion function templates. const UnresolvedSetImpl *getVisibleConversionFunctions(); - /// addVisibleConversionFunction - Add a new conversion function to the - /// list of visible conversion functions. - void addVisibleConversionFunction(CXXConversionDecl *ConvDecl); - - /// \brief Add a new conversion function template to the list of visible - /// conversion functions. - void addVisibleConversionFunction(FunctionTemplateDecl *ConvDecl); - /// addConversionFunction - Add a new conversion function to the /// list of conversion functions. void addConversionFunction(CXXConversionDecl *ConvDecl); @@ -1385,77 +1385,6 @@ public: static bool classofKind(Kind K) { return K == CXXConversion; } }; -/// FriendDecl - Represents the declaration of a friend entity, -/// which can be a function, a type, or a templated function or type. -// For example: -/// -/// @code -/// template <typename T> class A { -/// friend int foo(T); -/// friend class B; -/// friend T; // only in C++0x -/// template <typename U> friend class C; -/// template <typename U> friend A& operator+=(A&, const U&) { ... } -/// }; -/// @endcode -/// -/// The semantic context of a friend decl is its declaring class. -class FriendDecl : public Decl { -public: - typedef llvm::PointerUnion<NamedDecl*,Type*> FriendUnion; - -private: - // The declaration that's a friend of this class. - FriendUnion Friend; - - // Location of the 'friend' specifier. - SourceLocation FriendLoc; - - // FIXME: Hack to keep track of whether this was a friend function - // template specialization. - bool WasSpecialization; - - FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend, - SourceLocation FriendL) - : Decl(Decl::Friend, DC, L), - Friend(Friend), - FriendLoc(FriendL), - WasSpecialization(false) { - } - -public: - static FriendDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, FriendUnion Friend_, - SourceLocation FriendL); - - /// If this friend declaration names an (untemplated but - /// possibly dependent) type, return the type; otherwise - /// return null. This is used only for C++0x's unelaborated - /// friend type declarations. - Type *getFriendType() const { - return Friend.dyn_cast<Type*>(); - } - - /// If this friend declaration doesn't name an unelaborated - /// type, return the inner declaration. - NamedDecl *getFriendDecl() const { - return Friend.dyn_cast<NamedDecl*>(); - } - - /// Retrieves the location of the 'friend' keyword. - SourceLocation getFriendLoc() const { - return FriendLoc; - } - - bool wasSpecialization() const { return WasSpecialization; } - void setSpecialization(bool WS) { WasSpecialization = WS; } - - // Implement isa/cast/dyncast/etc. - static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const FriendDecl *D) { return true; } - static bool classofKind(Kind K) { return K == Decl::Friend; } -}; - /// LinkageSpecDecl - This represents a linkage specification. For example: /// extern "C" void foo(); /// diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h new file mode 100644 index 000000000000..5022ad018f4f --- /dev/null +++ b/include/clang/AST/DeclFriend.h @@ -0,0 +1,167 @@ +//===-- DeclFriend.h - Classes for C++ friend declarations -*- C++ -*------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the section of the AST representing C++ friend +// declarations. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_DECLFRIEND_H +#define LLVM_CLANG_AST_DECLFRIEND_H + +#include "clang/AST/DeclCXX.h" + +namespace clang { + +/// FriendDecl - Represents the declaration of a friend entity, +/// which can be a function, a type, or a templated function or type. +// For example: +/// +/// @code +/// template <typename T> class A { +/// friend int foo(T); +/// friend class B; +/// friend T; // only in C++0x +/// template <typename U> friend class C; +/// template <typename U> friend A& operator+=(A&, const U&) { ... } +/// }; +/// @endcode +/// +/// The semantic context of a friend decl is its declaring class. +class FriendDecl : public Decl { +public: + typedef llvm::PointerUnion<NamedDecl*,Type*> FriendUnion; + +private: + // The declaration that's a friend of this class. + FriendUnion Friend; + + // A pointer to the next friend in the sequence. + FriendDecl *NextFriend; + + // Location of the 'friend' specifier. + SourceLocation FriendLoc; + + // FIXME: Hack to keep track of whether this was a friend function + // template specialization. + bool WasSpecialization; + + friend class CXXRecordDecl::friend_iterator; + friend class CXXRecordDecl; + + FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend, + SourceLocation FriendL) + : Decl(Decl::Friend, DC, L), + Friend(Friend), + NextFriend(0), + FriendLoc(FriendL), + WasSpecialization(false) { + } + +public: + static FriendDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, FriendUnion Friend_, + SourceLocation FriendL); + + /// If this friend declaration names an (untemplated but + /// possibly dependent) type, return the type; otherwise + /// return null. This is used only for C++0x's unelaborated + /// friend type declarations. + Type *getFriendType() const { + return Friend.dyn_cast<Type*>(); + } + + /// If this friend declaration doesn't name an unelaborated + /// type, return the inner declaration. + NamedDecl *getFriendDecl() const { + return Friend.dyn_cast<NamedDecl*>(); + } + + /// Retrieves the location of the 'friend' keyword. + SourceLocation getFriendLoc() const { + return FriendLoc; + } + + bool wasSpecialization() const { return WasSpecialization; } + void setSpecialization(bool WS) { WasSpecialization = WS; } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const FriendDecl *D) { return true; } + static bool classofKind(Kind K) { return K == Decl::Friend; } +}; + +/// An iterator over the friend declarations of a class. +class CXXRecordDecl::friend_iterator { + FriendDecl *Ptr; + + friend class CXXRecordDecl; + explicit friend_iterator(FriendDecl *Ptr) : Ptr(Ptr) {} +public: + friend_iterator() {} + + typedef FriendDecl *value_type; + typedef FriendDecl *reference; + typedef FriendDecl *pointer; + typedef int difference_type; + typedef std::forward_iterator_tag iterator_category; + + reference operator*() const { return Ptr; } + + friend_iterator &operator++() { + assert(Ptr && "attempt to increment past end of friend list"); + Ptr = Ptr->NextFriend; + return *this; + } + + friend_iterator operator++(int) { + friend_iterator tmp = *this; + ++*this; + return tmp; + } + + bool operator==(const friend_iterator &Other) const { + return Ptr == Other.Ptr; + } + + bool operator!=(const friend_iterator &Other) const { + return Ptr != Other.Ptr; + } + + friend_iterator &operator+=(difference_type N) { + assert(N >= 0 && "cannot rewind a CXXRecordDecl::friend_iterator"); + while (N--) + ++*this; + return *this; + } + + friend_iterator operator+(difference_type N) const { + friend_iterator tmp = *this; + tmp += N; + return tmp; + } +}; + +inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_begin() const { + return friend_iterator(data().FirstFriend); +} + +inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const { + return friend_iterator(0); +} + +inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) { + assert(FD->NextFriend == 0 && "friend already has next friend?"); + FD->NextFriend = data().FirstFriend; + data().FirstFriend = FD; +} + +} + +#endif diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 889e0d6c1be8..a1f565341e2c 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -381,8 +381,6 @@ public: ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const; ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const; - ObjCPropertyDecl *FindPropertyVisibleInPrimaryClass( - IdentifierInfo *PropertyId) const; // Marks the end of the container. SourceRange getAtEndRange() const { @@ -445,9 +443,6 @@ class ObjCInterfaceDecl : public ObjCContainerDecl { /// Protocols referenced in interface header declaration ObjCProtocolList ReferencedProtocols; - /// Instance variables in the interface. This list is completely redundant. - ObjCList<ObjCIvarDecl> IVars; - /// List of categories defined for this class. /// FIXME: Why is this a linked list?? ObjCCategoryDecl *CategoryList; @@ -538,7 +533,10 @@ public: } ObjCCategoryDecl* getClassExtension() const; - + + ObjCPropertyDecl + *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const; + /// isSuperClassOf - Return true if this class is the specified class or is a /// super class of the specified interface class. bool isSuperClassOf(const ObjCInterfaceDecl *I) const { @@ -1330,6 +1328,10 @@ public: return PropertyIvarDecl; } + /// Lookup a property by name in the specified DeclContext. + static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC, + IdentifierInfo *propertyID); + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const ObjCPropertyDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCProperty; } diff --git a/include/clang/AST/DeclVisitor.h b/include/clang/AST/DeclVisitor.h index 9423c319c3e3..140e5c0a2a99 100644 --- a/include/clang/AST/DeclVisitor.h +++ b/include/clang/AST/DeclVisitor.h @@ -16,6 +16,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclFriend.h" #include "clang/AST/DeclTemplate.h" namespace clang { diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h index cd25969db0b0..e78476ef51bb 100644 --- a/include/clang/AST/RecordLayout.h +++ b/include/clang/AST/RecordLayout.h @@ -112,13 +112,14 @@ private: /// PrimaryBase - The primary base info for this record. PrimaryBaseInfo PrimaryBase; - /// BaseOffsets - Contains a map from base classes to their offset. /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :) - llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsets; + typedef llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsetsMapTy; + + /// BaseOffsets - Contains a map from base classes to their offset. + BaseOffsetsMapTy BaseOffsets; /// VBaseOffsets - Contains a map from vbase classes to their offset. - /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :) - llvm::DenseMap<const CXXRecordDecl *, uint64_t> VBaseOffsets; + BaseOffsetsMapTy VBaseOffsets; }; /// CXXInfo - If the record layout is for a C++ record, this will have @@ -133,15 +134,14 @@ private: unsigned fieldcount); // Constructor for C++ records. + typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy; ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignment, uint64_t datasize, const uint64_t *fieldoffsets, unsigned fieldcount, uint64_t nonvirtualsize, unsigned nonvirtualalign, const PrimaryBaseInfo &PrimaryBase, - const std::pair<const CXXRecordDecl *, uint64_t> *bases, - unsigned numbases, - const std::pair<const CXXRecordDecl *, uint64_t> *vbases, - unsigned numvbases); + const BaseOffsetsMapTy& BaseOffsets, + const BaseOffsetsMapTy& VBaseOffsets); ~ASTRecordLayout() {} diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h index 528cf878031e..b7256c9dc3db 100644 --- a/include/clang/Analysis/CFG.h +++ b/include/clang/Analysis/CFG.h @@ -286,7 +286,8 @@ public: /// constructed CFG belongs to the caller. static CFG* buildCFG(const Decl *D, Stmt* AST, ASTContext *C, bool AddEHEdges = false, - bool AddScopes = false); + bool AddScopes = false /* NOT FULLY IMPLEMENTED. + NOT READY FOR GENERAL USE. */); /// createBlock - Create a new block in the CFG. The CFG owns the block; /// the caller should not directly free it. diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def index af233b81e0a5..3afdaf5b0eb1 100644 --- a/include/clang/Basic/Builtins.def +++ b/include/clang/Basic/Builtins.def @@ -46,8 +46,8 @@ // U -> unsigned // // Types may be postfixed with the following modifiers: -// * -> pointer -// & -> reference +// * -> pointer (optionally followed by an address space number) +// & -> reference (optionally followed by an address space number) // C -> const // D -> volatile diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def index 880b4bab6e26..9a79f90d1e52 100644 --- a/include/clang/Basic/BuiltinsX86.def +++ b/include/clang/Basic/BuiltinsX86.def @@ -287,6 +287,10 @@ BUILTIN(__builtin_ia32_roundpd, "V2dV2di", "") BUILTIN(__builtin_ia32_dpps, "V4fV4fV4fi", "") BUILTIN(__builtin_ia32_dppd, "V2dV2dV2di", "") BUILTIN(__builtin_ia32_movntdqa, "V2LLiV2LLi*", "") - +BUILTIN(__builtin_ia32_ptestz128, "iV2LLiV2LLi", "") +BUILTIN(__builtin_ia32_ptestc128, "iV2LLiV2LLi", "") +BUILTIN(__builtin_ia32_ptestnzc128, "iV2LLiV2LLi", "") +BUILTIN(__builtin_ia32_pcmpeqq, "V2LLiV2LLiV2LLi", "") +BUILTIN(__builtin_ia32_mpsadbw128, "V16cV16cV16ci", "") #undef BUILTIN diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td index 66f84dbbbabe..849e6437fbe6 100644 --- a/include/clang/Basic/DiagnosticCommonKinds.td +++ b/include/clang/Basic/DiagnosticCommonKinds.td @@ -63,4 +63,12 @@ def err_target_unknown_cpu : Error<"unknown target CPU '%0'">; def err_target_unknown_abi : Error<"unknown target ABI '%0'">; def err_target_invalid_feature : Error<"invalid target feature '%0'">; +// Source manager +def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal; +def err_file_size_changed : Error< + "size of file '%0' changed since it was first processed (from %1 to %2)">, + DefaultFatal; +def err_file_modified : Error< + "file '%0' modified since it was first processed">, DefaultFatal; + } diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 17bad64e9c82..e5793fa58b04 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -59,7 +59,7 @@ def : DiagGroup<"nested-externs">; def : DiagGroup<"newline-eof">; def LongLong : DiagGroup<"long-long">; def MismatchedTags : DiagGroup<"mismatched-tags">; -def : DiagGroup<"missing-field-initializers">; +def MissingFieldInitializers : DiagGroup<"missing-field-initializers">; def NonNull : DiagGroup<"nonnull">; def : DiagGroup<"nonportable-cfstrings">; def : DiagGroup<"non-virtual-dtor">; @@ -147,6 +147,7 @@ def Format2 : DiagGroup<"format=2", [FormatNonLiteral, FormatSecurity, FormatY2K]>; def Extra : DiagGroup<"extra", [ + MissingFieldInitializers, SemiBeforeMethodBody, SignCompare, UnusedParameter diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 80a4eaee1120..9d001d48cc2a 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -183,6 +183,7 @@ def err_objc_no_attributes_on_category : Error< def err_objc_missing_end : Error<"missing @end">; def warn_objc_protocol_qualifier_missing_id : Warning< "protocol qualifiers without 'id' is archaic">; +def err_objc_unknown_at : Error<"expected an Objective-C directive after '@'">; def err_objc_illegal_visibility_spec : Error< "illegal visibility specification">; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 13ac9ece542b..9a9b7cc85f6a 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -428,11 +428,39 @@ def err_deep_exception_specs_differ : Error< // C++ access checking def err_class_redeclared_with_different_access : Error< "%0 redeclared with '%1' access">; -def err_access_private : Error<"%0 is a private member of %1">; -def err_access_ctor_private : Error<"calling a private constructor of %0">; -// Say something about the context for these? -def err_access_protected : Error<"%0 is a protected member of %1">; -def err_access_ctor_protected : Error<"calling a protected constructor of %0">; +def err_access : + Error<"%1 is a %select{private|protected}0 member of %3">, + NoSFINAE; +def err_access_ctor : + Error<"calling a %select{private|protected}0 constructor of class %2">, + NoSFINAE; +def err_access_dtor_base : + Error<"base class %0 has %select{private|protected}1 destructor">, + NoSFINAE; +def err_access_dtor_vbase : + Error<"inherited virtual base class %0 has " + "%select{private|protected}1 destructor">, + NoSFINAE; +def err_access_dtor_field : + Error<"field of type %1 has %select{private|protected}2 destructor">, + NoSFINAE; +def err_access_dtor_var : + Error<"variable of type %1 has %select{private|protected}2 destructor">, + NoSFINAE; +def err_access_assign_field : + Error<"field of type %1 has %select{private|protected}2 copy assignment" + " operator">, + NoSFINAE; +def err_access_assign_base : + Error<"base class %0 has %select{private|protected}1 copy assignment" + " operator">, + NoSFINAE; +def err_access_copy_field : + Error<"field of type %1 has %select{private|protected}2 copy constructor">, + NoSFINAE; +def err_access_copy_base : + Error<"base class %0 has %select{private|protected}1 copy constructor">, + NoSFINAE; def note_previous_access_declaration : Note< "previously declared '%1' here">; def err_access_outside_class : Error< @@ -1251,7 +1279,7 @@ def err_not_class_template_specialization : Error< def err_template_spec_needs_header : Error< "template specialization requires 'template<>'">; def err_template_spec_needs_template_parameters : Error< - "template specialization or definition requires a template parameter list" + "template specialization or definition requires a template parameter list " "corresponding to the nested type %0">; def err_template_param_list_matches_nontemplate : Error< "template parameter list matching the non-templated nested type %0 should " @@ -1562,6 +1590,9 @@ def warn_excess_initializers_in_char_array_initializer : ExtWarn< "excess elements in char array initializer">; def warn_initializer_string_for_char_array_too_long : ExtWarn< "initializer-string for char array is too long">; +def warn_missing_field_initializers : Warning< + "missing field '%0' initializer">, + InGroup<MissingFieldInitializers>, DefaultIgnore; def warn_braces_around_scalar_init : Warning< "braces around scalar initializer">; def err_many_braces_around_scalar_init : Error< @@ -1854,6 +1885,12 @@ def warn_mixed_sign_comparison : Warning< def warn_mixed_sign_conditional : Warning< "operands of ? are integers of different signs: %0 and %1">, InGroup<DiagGroup<"sign-compare">>, DefaultIgnore; +def warn_lunsigned_always_true_comparison : Warning< + "comparison of unsigned expression %0 is always %1">, + InGroup<DiagGroup<"sign-compare">>, DefaultIgnore; +def warn_runsigned_always_true_comparison : Warning< + "comparison of %0 unsigned expression is always %1">, + InGroup<DiagGroup<"sign-compare">>, DefaultIgnore; def err_invalid_this_use : Error< "invalid use of 'this' outside of a nonstatic member function">; diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index 75a7b8192c5a..582d59c18a37 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -18,6 +18,7 @@ #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/TokenKinds.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/PointerLikeTypeTraits.h" @@ -236,9 +237,7 @@ public: /// Unlike the version in IdentifierTable, this returns a pointer instead /// of a reference. If the pointer is NULL then the IdentifierInfo cannot /// be found. - // - // FIXME: Move to StringRef API. - virtual IdentifierInfo* get(const char *NameStart, const char *NameEnd) = 0; + virtual IdentifierInfo* get(llvm::StringRef Name) = 0; }; /// \brief An abstract class used to resolve numerical identifier @@ -283,16 +282,16 @@ public: /// get - Return the identifier token info for the specified named identifier. /// - IdentifierInfo &get(const char *NameStart, const char *NameEnd) { + IdentifierInfo &get(llvm::StringRef Name) { llvm::StringMapEntry<IdentifierInfo*> &Entry = - HashTable.GetOrCreateValue(NameStart, NameEnd); + HashTable.GetOrCreateValue(Name); IdentifierInfo *II = Entry.getValue(); if (II) return *II; // No entry; if we have an external lookup, look there first. if (ExternalLookup) { - II = ExternalLookup->get(NameStart, NameEnd); + II = ExternalLookup->get(Name); if (II) { // Cache in the StringMap for subsequent lookups. Entry.setValue(II); @@ -312,6 +311,14 @@ public: return *II; } + IdentifierInfo &get(const char *NameStart, const char *NameEnd) { + return get(llvm::StringRef(NameStart, NameEnd-NameStart)); + } + + IdentifierInfo &get(const char *Name, size_t NameLen) { + return get(llvm::StringRef(Name, NameLen)); + } + /// \brief Creates a new IdentifierInfo from the given string. /// /// This is a lower-level version of get() that requires that this @@ -343,10 +350,6 @@ public: return CreateIdentifierInfo(Name.begin(), Name.end()); } - IdentifierInfo &get(llvm::StringRef Name) { - return get(Name.begin(), Name.end()); - } - typedef HashTableTy::const_iterator iterator; typedef HashTableTy::const_iterator const_iterator; @@ -474,9 +477,7 @@ public: SelectorName = "set"; SelectorName += Name->getName(); SelectorName[3] = toupper(SelectorName[3]); - IdentifierInfo *SetterName = - &Idents.get(SelectorName.data(), - SelectorName.data() + SelectorName.size()); + IdentifierInfo *SetterName = &Idents.get(SelectorName); return SelTable.getUnarySelector(SetterName); } }; @@ -533,7 +534,7 @@ struct DenseMapInfo<clang::Selector> { return LHS == RHS; } }; - + template <> struct isPodLike<clang::Selector> { static const bool value = true; }; diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index 23e6efe8bd70..fdf69d063f4d 100644 --- a/include/clang/Basic/LangOptions.h +++ b/include/clang/Basic/LangOptions.h @@ -44,6 +44,7 @@ public: unsigned PascalStrings : 1; // Allow Pascal strings unsigned WritableStrings : 1; // Allow writable strings + unsigned ConstStrings : 1; // Add const qualifier to strings (-Wwrite-strings) unsigned LaxVectorConversions : 1; unsigned AltiVec : 1; // Support AltiVec-style vector initializers. unsigned Exceptions : 1; // Support exception handling. @@ -129,7 +130,7 @@ public: HexFloats = 0; GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCNonFragileABI2 = 0; C99 = Microsoft = CPlusPlus = CPlusPlus0x = 0; - CXXOperatorNames = PascalStrings = WritableStrings = 0; + CXXOperatorNames = PascalStrings = WritableStrings = ConstStrings = 0; Exceptions = SjLjExceptions = Freestanding = NoBuiltin = 0; NeXTRuntime = 1; RTTI = 1; diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h index 873aaeecb6bf..fb861dcf934d 100644 --- a/include/clang/Basic/PartialDiagnostic.h +++ b/include/clang/Basic/PartialDiagnostic.h @@ -69,6 +69,10 @@ class PartialDiagnostic { CodeModificationHint CodeModificationHints[MaxCodeModificationHints]; }; + // NOTE: Sema assumes that PartialDiagnostic is location-invariant + // in the sense that its bits can be safely memcpy'ed and destructed + // in the new location. + /// DiagID - The diagnostic ID. mutable unsigned DiagID; diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h index d4f557b57d0b..34dfecd9b6a8 100644 --- a/include/clang/Basic/SourceLocation.h +++ b/include/clang/Basic/SourceLocation.h @@ -20,6 +20,7 @@ namespace llvm { class MemoryBuffer; class raw_ostream; + class StringRef; template <typename T> struct DenseMapInfo; template <typename T> struct isPodLike; } @@ -209,9 +210,9 @@ public: const llvm::MemoryBuffer* getBuffer() const; - /// getBufferData - Return a pointer to the start and end of the source buffer - /// data for the specified FileID. - std::pair<const char*, const char*> getBufferData() const; + /// getBufferData - Return a StringRef to the source buffer data for the + /// specified FileID. + llvm::StringRef getBufferData() const; /// getDecomposedLoc - Decompose the specified location into a raw FileID + /// Offset pair. The first element is the FileID, the second is the diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index 15ece685104c..ef51a5888379 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -17,22 +17,24 @@ #include "clang/Basic/SourceLocation.h" #include "llvm/Support/Allocator.h" #include "llvm/System/DataTypes.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/DenseMap.h" #include <vector> #include <cassert> namespace llvm { class MemoryBuffer; +class StringRef; } namespace clang { +class Diagnostic; class SourceManager; class FileManager; class FileEntry; -class IdentifierTokenInfo; class LineTableInfo; - + /// SrcMgr - Public enums and private classes that are part of the /// SourceManager implementation. /// @@ -69,10 +71,14 @@ namespace SrcMgr { /// if SourceLineCache is non-null. unsigned NumLines; - /// getBuffer - Returns the memory buffer for the associated content. If - /// there is an error opening this buffer the first time, this manufactures - /// a temporary buffer and returns a non-empty error string. - const llvm::MemoryBuffer *getBuffer(std::string *ErrorStr = 0) const; + /// getBuffer - Returns the memory buffer for the associated content. + /// + /// \param Diag Object through which diagnostics will be emitted it the + /// buffer cannot be retrieved. + /// + /// \param Invalid If non-NULL, will be set \c true if an error occurred. + const llvm::MemoryBuffer *getBuffer(Diagnostic &Diag, + bool *Invalid = 0) const; /// getSize - Returns the size of the content encapsulated by this /// ContentCache. This can be the size of the source file or the size of an @@ -277,6 +283,9 @@ public: /// location indicates where the expanded token came from and the instantiation /// location specifies where it was expanded. class SourceManager { + /// \brief Diagnostic object. + Diagnostic &Diag; + mutable llvm::BumpPtrAllocator ContentCacheAlloc; /// FileInfos - Memoized information about all of the files tracked by this @@ -336,8 +345,8 @@ class SourceManager { explicit SourceManager(const SourceManager&); void operator=(const SourceManager&); public: - SourceManager() - : ExternalSLocEntries(0), LineTable(0), NumLinearScans(0), + SourceManager(Diagnostic &Diag) + : Diag(Diag), ExternalSLocEntries(0), LineTable(0), NumLinearScans(0), NumBinaryProbes(0) { clearIDTables(); } @@ -408,7 +417,11 @@ public: unsigned Offset = 0); /// \brief Retrieve the memory buffer associated with the given file. - const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File); + /// + /// \param Invalid If non-NULL, will be set \c true if an error + /// occurs while retrieving the memory buffer. + const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File, + bool *Invalid = 0); /// \brief Override the contents of the given source file by providing an /// already-allocated buffer. @@ -429,8 +442,9 @@ public: /// getBuffer - Return the buffer for the specified FileID. If there is an /// error opening this buffer the first time, this manufactures a temporary /// buffer and returns a non-empty error string. - const llvm::MemoryBuffer *getBuffer(FileID FID, std::string *Error = 0) const{ - return getSLocEntry(FID).getFile().getContentCache()->getBuffer(Error); + const llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = 0) const { + return getSLocEntry(FID).getFile().getContentCache()->getBuffer(Diag, + Invalid); } /// getFileEntryForID - Returns the FileEntry record for the provided FileID. @@ -438,9 +452,12 @@ public: return getSLocEntry(FID).getFile().getContentCache()->Entry; } - /// getBufferData - Return a pointer to the start and end of the source buffer - /// data for the specified FileID. - std::pair<const char*, const char*> getBufferData(FileID FID) const; + /// getBufferData - Return a StringRef to the source buffer data for the + /// specified FileID. + /// + /// \param FID The file ID whose contents will be returned. + /// \param Invalid If non-NULL, will be set true if an error occurred. + llvm::StringRef getBufferData(FileID FID, bool *Invalid = 0) const; //===--------------------------------------------------------------------===// @@ -558,31 +575,37 @@ public: /// getCharacterData - Return a pointer to the start of the specified location /// in the appropriate spelling MemoryBuffer. - const char *getCharacterData(SourceLocation SL) const; + /// + /// \param Invalid If non-NULL, will be set \c true if an error occurs. + const char *getCharacterData(SourceLocation SL, bool *Invalid = 0) const; /// getColumnNumber - Return the column # for the specified file position. /// This is significantly cheaper to compute than the line number. This /// returns zero if the column number isn't known. This may only be called on /// a file sloc, so you must choose a spelling or instantiation location /// before calling this method. - unsigned getColumnNumber(FileID FID, unsigned FilePos) const; - unsigned getSpellingColumnNumber(SourceLocation Loc) const; - unsigned getInstantiationColumnNumber(SourceLocation Loc) const; + unsigned getColumnNumber(FileID FID, unsigned FilePos, + bool *Invalid = 0) const; + unsigned getSpellingColumnNumber(SourceLocation Loc, + bool *Invalid = 0) const; + unsigned getInstantiationColumnNumber(SourceLocation Loc, + bool *Invalid = 0) const; /// getLineNumber - Given a SourceLocation, return the spelling line number /// for the position indicated. This requires building and caching a table of /// line offsets for the MemoryBuffer, so this is not cheap: use only when /// about to emit a diagnostic. - unsigned getLineNumber(FileID FID, unsigned FilePos) const; + unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid = 0) const; - unsigned getInstantiationLineNumber(SourceLocation Loc) const; - unsigned getSpellingLineNumber(SourceLocation Loc) const; + unsigned getInstantiationLineNumber(SourceLocation Loc, + bool *Invalid = 0) const; + unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = 0) const; /// Return the filename or buffer identifier of the buffer the location is in. /// Note that this name does not respect #line directives. Use getPresumedLoc /// for normal clients. - const char *getBufferName(SourceLocation Loc) const; + const char *getBufferName(SourceLocation Loc, bool *Invalid = 0) const; /// getFileCharacteristic - return the file characteristic of the specified /// source location, indicating whether this is a normal file, a system @@ -678,7 +701,7 @@ public: void PrintStats() const; unsigned sloc_entry_size() const { return SLocEntryTable.size(); } - + // FIXME: Exposing this is a little gross; what we want is a good way // to iterate the entries that were not defined in a PCH file (or // any other external source). @@ -692,8 +715,8 @@ public: ExternalSLocEntries->ReadSLocEntry(ID); return SLocEntryTable[ID]; } - - const SrcMgr::SLocEntry &getSLocEntry(FileID FID) const { + + const SrcMgr::SLocEntry &getSLocEntry(FileID FID) const { return getSLocEntry(FID.ID); } diff --git a/include/clang/Checker/PathSensitive/GRExprEngine.h b/include/clang/Checker/PathSensitive/GRExprEngine.h index 763bbcc9e1da..916511e8bd09 100644 --- a/include/clang/Checker/PathSensitive/GRExprEngine.h +++ b/include/clang/Checker/PathSensitive/GRExprEngine.h @@ -347,7 +347,10 @@ protected: void VisitCXXThisExpr(CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet & Dst); - + + void VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest, + ExplodedNode *Pred, + ExplodedNodeSet &Dst); /// Create a C++ temporary object for an rvalue. void CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst); diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h index 679704c39587..ab3162a04707 100644 --- a/include/clang/Driver/Action.h +++ b/include/clang/Driver/Action.h @@ -66,17 +66,23 @@ private: ActionList Inputs; + unsigned OwnsInputs : 1; + protected: - Action(ActionClass _Kind, types::ID _Type) : Kind(_Kind), Type(_Type) {} + Action(ActionClass _Kind, types::ID _Type) + : Kind(_Kind), Type(_Type), OwnsInputs(true) {} Action(ActionClass _Kind, Action *Input, types::ID _Type) - : Kind(_Kind), Type(_Type), Inputs(&Input, &Input + 1) {} + : Kind(_Kind), Type(_Type), Inputs(&Input, &Input + 1), OwnsInputs(true) {} Action(ActionClass _Kind, const ActionList &_Inputs, types::ID _Type) - : Kind(_Kind), Type(_Type), Inputs(_Inputs) {} + : Kind(_Kind), Type(_Type), Inputs(_Inputs), OwnsInputs(true) {} public: virtual ~Action(); const char *getClassName() const { return Action::getClassName(getKind()); } + bool getOwnsInputs() { return OwnsInputs; } + void setOwnsInputs(bool Value) { OwnsInputs = Value; } + ActionClass getKind() const { return Kind; } types::ID getType() const { return Type; } diff --git a/include/clang/Driver/ArgList.h b/include/clang/Driver/ArgList.h index ab1abff7409b..0a8eaeaf238f 100644 --- a/include/clang/Driver/ArgList.h +++ b/include/clang/Driver/ArgList.h @@ -287,7 +287,7 @@ namespace driver { arglist_type ActualArgs; /// The list of arguments we synthesized. - arglist_type SynthesizedArgs; + mutable arglist_type SynthesizedArgs; /// Is this only a proxy for the base ArgList? bool OnlyProxy; diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 7cd26ef04cc2..1ecd8d6adaf6 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -197,6 +197,8 @@ def fcolor_diagnostics : Flag<"-fcolor-diagnostics">, HelpText<"Use colors in diagnostics">; def Wno_rewrite_macros : Flag<"-Wno-rewrite-macros">, HelpText<"Silence ObjC rewriting warnings">; +def Wwrite_strings : Flag<"-Wwrite-strings">, + HelpText<"Add const qualifier to string literals">; def verify : Flag<"-verify">, HelpText<"Verify emitted diagnostics and warnings">; diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h index 74ca083417a6..5a789fbb8f41 100644 --- a/include/clang/Driver/Job.h +++ b/include/clang/Driver/Job.h @@ -100,7 +100,9 @@ private: public: PipedJob(); + virtual ~PipedJob(); + /// Add a command to the piped job (taking ownership). void addCommand(Command *C) { Commands.push_back(C); } const list_type &getCommands() const { return Commands; } @@ -130,7 +132,9 @@ private: public: JobList(); + virtual ~JobList(); + /// Add a job to the list (taking ownership). void addJob(Job *J) { Jobs.push_back(J); } const list_type &getJobs() const { return Jobs; } diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 7f11c85ae35b..27ec12e4e4cd 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -121,7 +121,7 @@ public: }; friend class ConcurrencyCheck; - ASTUnit(bool MainFileIsAST); + ASTUnit(Diagnostic &Diag, bool MainFileIsAST); ~ASTUnit(); bool isMainFileAST() const { return MainFileIsAST; } diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h index ac5594e55d7d..5e8a4f144c96 100644 --- a/include/clang/Lex/PTHManager.h +++ b/include/clang/Lex/PTHManager.h @@ -115,7 +115,7 @@ public: /// Unlike the version in IdentifierTable, this returns a pointer instead /// of a reference. If the pointer is NULL then the IdentifierInfo cannot /// be found. - IdentifierInfo *get(const char *NameStart, const char *NameEnd); + IdentifierInfo *get(llvm::StringRef Name); /// Create - This method creates PTHManager objects. The 'file' argument /// is the name of the PTH file. This method returns NULL upon failure. diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 532d8e4b46f3..2b27a06070f8 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -547,7 +547,9 @@ public: /// after trigraph expansion and escaped-newline folding. In particular, this /// wants to get the true, uncanonicalized, spelling of things like digraphs /// UCNs, etc. - std::string getSpelling(const Token &Tok) const; + /// + /// \param Invalid If non-NULL, will be set \c true if an error occurs. + std::string getSpelling(const Token &Tok, bool *Invalid = 0) const; /// getSpelling() - Return the 'spelling' of the Tok token. The spelling of a /// token is the characters used to represent the token in the source file @@ -556,7 +558,8 @@ public: /// UCNs, etc. static std::string getSpelling(const Token &Tok, const SourceManager &SourceMgr, - const LangOptions &Features); + const LangOptions &Features, + bool *Invalid = 0); /// getSpelling - This method is used to get the spelling of a token into a /// preallocated buffer, instead of as an std::string. The caller is required @@ -568,17 +571,20 @@ public: /// to point to a constant buffer with the data already in it (avoiding a /// copy). The caller is not allowed to modify the returned buffer pointer /// if an internal buffer is returned. - unsigned getSpelling(const Token &Tok, const char *&Buffer) const; + unsigned getSpelling(const Token &Tok, const char *&Buffer, + bool *Invalid = 0) const; /// getSpelling - This method is used to get the spelling of a token into a /// SmallVector. Note that the returned StringRef may not point to the /// supplied buffer if a copy can be avoided. llvm::StringRef getSpelling(const Token &Tok, - llvm::SmallVectorImpl<char> &Buffer) const; + llvm::SmallVectorImpl<char> &Buffer, + bool *Invalid = 0) const; /// getSpellingOfSingleCharacterNumericConstant - Tok is a numeric constant /// with length 1, return the character. - char getSpellingOfSingleCharacterNumericConstant(const Token &Tok) const { + char getSpellingOfSingleCharacterNumericConstant(const Token &Tok, + bool *Invalid = 0) const { assert(Tok.is(tok::numeric_constant) && Tok.getLength() == 1 && "Called on unsupported token"); assert(!Tok.needsCleaning() && "Token can't need cleaning with length 1"); @@ -730,7 +736,7 @@ public: /// 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::SmallVector<char, 128> &FilenameBuffer); + bool ConcatenateIncludeName(llvm::SmallString<128> &FilenameBuffer); private: |