diff options
author | Ed Schouten <ed@FreeBSD.org> | 2009-06-27 10:45:02 +0000 |
---|---|---|
committer | Ed Schouten <ed@FreeBSD.org> | 2009-06-27 10:45:02 +0000 |
commit | 4ebdf5c4f587daef4e0be499802eac3a7a49bf2f (patch) | |
tree | 2c5a83521a20c02e7805581a174008aa9bc23579 /include | |
parent | f698f7e71940663e26a4806a96fb0bdfa160c886 (diff) | |
download | src-4ebdf5c4f587daef4e0be499802eac3a7a49bf2f.tar.gz src-4ebdf5c4f587daef4e0be499802eac3a7a49bf2f.zip |
Import Clang r74383.vendor/clang/clang-r74383
Notes
Notes:
svn path=/vendor/clang/dist/; revision=195099
svn path=/vendor/clang/clang-r74383/; revision=195101; tag=vendor/clang/clang-r74383
Diffstat (limited to 'include')
31 files changed, 554 insertions, 257 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index b686b0edd30a..aa01b7fdf06f 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -192,6 +192,7 @@ public: QualType VoidPtrTy, NullPtrTy; QualType OverloadTy; QualType DependentTy; + QualType UndeducedAutoTy; ASTContext(const LangOptions& LOpts, SourceManager &SM, TargetInfo &t, IdentifierTable &idents, SelectorTable &sels, @@ -360,6 +361,9 @@ public: QualType getTypeOfExprType(Expr *e); QualType getTypeOfType(QualType t); + /// getDecltypeType - C++0x decltype. + QualType getDecltypeType(Expr *e); + /// getTagDeclType - Return the unique reference to the type for the /// specified TagDecl (struct/union/class/enum) decl. QualType getTagDeclType(TagDecl *Decl); diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index a5b7ad4ca382..7d3009b01129 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -72,6 +72,7 @@ public: Packed, Pure, Regparm, + ReqdWorkGroupSize, // OpenCL-specific Section, Sentinel, StdCall, @@ -501,6 +502,27 @@ public: static bool classof(const RegparmAttr *A) { return true; } }; +class ReqdWorkGroupSizeAttr : public Attr { + unsigned X, Y, Z; +public: + ReqdWorkGroupSizeAttr(unsigned X, unsigned Y, unsigned Z) + : Attr(ReqdWorkGroupSize), X(X), Y(Y), Z(Z) {} + + unsigned getXDim() const { return X; } + unsigned getYDim() const { return Y; } + unsigned getZDim() const { return Z; } + + virtual Attr *clone(ASTContext &C) const { + return ::new (C) ReqdWorkGroupSizeAttr(X, Y, Z); + } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *A) { + return A->getKind() == ReqdWorkGroupSize; + } + static bool classof(const ReqdWorkGroupSizeAttr *A) { return true; } +}; + // Checker-specific attributes. DEF_SIMPLE_ATTR(CFReturnsRetained); DEF_SIMPLE_ATTR(NSReturnsRetained); diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index f594db27bc8f..3de01f3baeb5 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -25,7 +25,8 @@ class FunctionTemplateDecl; class Stmt; class CompoundStmt; class StringLiteral; - +class TemplateArgumentList; + /// TranslationUnitDecl - The top declaration context. class TranslationUnitDecl : public Decl, public DeclContext { TranslationUnitDecl() @@ -105,6 +106,13 @@ public: /// \brief Determine whether this declaration has linkage. bool hasLinkage() const; + /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for + /// the underlying named decl. + NamedDecl *getUnderlyingDecl(); + const NamedDecl *getUnderlyingDecl() const { + return const_cast<NamedDecl*>(this)->getUnderlyingDecl(); + } + static bool classof(const Decl *D) { return D->getKind() >= NamedFirst && D->getKind() <= NamedLast; } @@ -614,10 +622,17 @@ public: None, Extern, Static, PrivateExtern }; private: + /// \brief Provides information about a function template specialization, + /// which is a FunctionDecl that has been explicitly specialization or + /// instantiated from a function template. + struct TemplateSpecializationInfo { + FunctionTemplateDecl *Template; + const TemplateArgumentList *TemplateArguments; + }; + /// ParamInfo - new[]'d array of pointers to VarDecls for the formal /// parameters of this function. This is null if a prototype or if there are - /// no formals. TODO: we could allocate this space immediately after the - /// FunctionDecl object to save an allocation like FunctionType does. + /// no formals. ParmVarDecl **ParamInfo; LazyDeclStmtPtr Body; @@ -664,8 +679,12 @@ private: /// pointer to a FunctionTemplateDecl. For member functions /// of class template specializations, this will be the /// FunctionDecl from which the member function was instantiated. - llvm::PointerUnion<FunctionTemplateDecl*, FunctionDecl*> - TemplateOrInstantiation; + /// For function template specializations, this will be a + /// FunctionTemplateSpecializationInfo, which contains information about + /// the template being specialized and the template arguments involved in + /// that specialization. + llvm::PointerUnion3<FunctionTemplateDecl*, FunctionDecl*, + TemplateSpecializationInfo*> TemplateOrSpecialization; protected: FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L, @@ -678,7 +697,7 @@ protected: SClass(S), IsInline(isInline), C99InlineDefinition(false), IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true), IsDeleted(false), TypeSpecStartLoc(TSSL), - EndRangeLoc(L), TemplateOrInstantiation() {} + EndRangeLoc(L), TemplateOrSpecialization() {} virtual ~FunctionDecl() {} virtual void Destroy(ASTContext& C); @@ -887,13 +906,13 @@ public: /// X<int>::A is required, it will be instantiated from the /// declaration returned by getInstantiatedFromMemberFunction(). FunctionDecl *getInstantiatedFromMemberFunction() const { - return TemplateOrInstantiation.dyn_cast<FunctionDecl*>(); + return TemplateOrSpecialization.dyn_cast<FunctionDecl*>(); } /// \brief Specify that this record is an instantiation of the /// member function RD. void setInstantiationOfMemberFunction(FunctionDecl *RD) { - TemplateOrInstantiation = RD; + TemplateOrSpecialization = RD; } /// \brief Retrieves the function template that is described by this @@ -909,13 +928,54 @@ public: /// getDescribedFunctionTemplate() retrieves the /// FunctionTemplateDecl from a FunctionDecl. FunctionTemplateDecl *getDescribedFunctionTemplate() const { - return TemplateOrInstantiation.dyn_cast<FunctionTemplateDecl*>(); + return TemplateOrSpecialization.dyn_cast<FunctionTemplateDecl*>(); } void setDescribedFunctionTemplate(FunctionTemplateDecl *Template) { - TemplateOrInstantiation = Template; + TemplateOrSpecialization = Template; } + /// \brief Retrieve the primary template that this function template + /// specialization either specializes or was instantiated from. + /// + /// If this function declaration is not a function template specialization, + /// returns NULL. + FunctionTemplateDecl *getPrimaryTemplate() const { + if (TemplateSpecializationInfo *Info + = TemplateOrSpecialization.dyn_cast<TemplateSpecializationInfo*>()) { + return Info->Template; + } + return 0; + } + + /// \brief Retrieve the template arguments used to produce this function + /// template specialization from the primary template. + /// + /// If this function declaration is not a function template specialization, + /// returns NULL. + const TemplateArgumentList *getTemplateSpecializationArgs() const { + if (TemplateSpecializationInfo *Info + = TemplateOrSpecialization.dyn_cast<TemplateSpecializationInfo*>()) { + return Info->TemplateArguments; + } + return 0; + } + + + /// \brief Specify that this function declaration is actually a function + /// template specialization. + /// + /// \param Context the AST context in which this function resides. + /// + /// \param Template the function template that this function template + /// specialization specializes. + /// + /// \param TemplateArgs the template arguments that produced this + /// function template specialization from the template. + void setFunctionTemplateSpecialization(ASTContext &Context, + FunctionTemplateDecl *Template, + const TemplateArgumentList *TemplateArgs); + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() >= FunctionFirst && D->getKind() <= FunctionLast; diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index a75eecd02220..c959b05473fe 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -329,6 +329,9 @@ public: /// template parameter pack. bool isTemplateParameterPack() const; + /// \brief Whether this declaration is a function or function template. + bool isFunctionOrFunctionTemplate() const; + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *) { return true; } static DeclContext *castToDeclContext(const Decl *); diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 52ed0ec8535e..a2fe24e83105 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -27,6 +27,40 @@ class CXXConversionDecl; class CXXMethodDecl; class ClassTemplateSpecializationDecl; +/// \brief Represents any kind of function declaration, whether it is a +/// concrete function or a function template. +class AnyFunctionDecl { + NamedDecl *Function; + +public: + AnyFunctionDecl(FunctionDecl *FD) : Function(FD) { } + AnyFunctionDecl(FunctionTemplateDecl *FTD); + + /// \brief Implicily converts any function or function template into a + /// named declaration. + operator NamedDecl *() const { return Function; } + + /// \brief Retrieve the underlying function or function template. + NamedDecl *get() const { return Function; } +}; + +} // end namespace clang + +namespace llvm { + /// Implement simplify_type for AnyFunctionDecl, so that we can dyn_cast from + /// AnyFunctionDecl to any function or function template declaration. + template<> struct simplify_type<const ::clang::AnyFunctionDecl> { + typedef ::clang::NamedDecl* SimpleType; + static SimpleType getSimplifiedValue(const ::clang::AnyFunctionDecl &Val) { + return Val; + } + }; + template<> struct simplify_type< ::clang::AnyFunctionDecl> + : public simplify_type<const ::clang::AnyFunctionDecl> {}; +} // end namespace llvm + +namespace clang { + /// OverloadedFunctionDecl - An instance of this class represents a /// set of overloaded functions. All of the functions have the same /// name and occur within the same scope. @@ -43,15 +77,15 @@ protected: /// Functions - the set of overloaded functions contained in this /// overload set. - llvm::SmallVector<FunctionDecl *, 4> Functions; + llvm::SmallVector<AnyFunctionDecl, 4> Functions; // FIXME: This should go away when we stop using // OverloadedFunctionDecl to store conversions in CXXRecordDecl. friend class CXXRecordDecl; public: - typedef llvm::SmallVector<FunctionDecl *, 4>::iterator function_iterator; - typedef llvm::SmallVector<FunctionDecl *, 4>::const_iterator + typedef llvm::SmallVector<AnyFunctionDecl, 4>::iterator function_iterator; + typedef llvm::SmallVector<AnyFunctionDecl, 4>::const_iterator function_const_iterator; static OverloadedFunctionDecl *Create(ASTContext &C, DeclContext *DC, @@ -71,30 +105,18 @@ public: this->setLocation(FD->getLocation()); } + /// addOverload - Add an overloaded function template FTD to this set of + /// overloaded functions. + void addOverload(FunctionTemplateDecl *FTD); + function_iterator function_begin() { return Functions.begin(); } function_iterator function_end() { return Functions.end(); } function_const_iterator function_begin() const { return Functions.begin(); } function_const_iterator function_end() const { return Functions.end(); } - /// getNumFunctions - the number of overloaded functions stored in + /// \brief Returns the number of overloaded functions stored in /// this set. - unsigned getNumFunctions() const { return Functions.size(); } - - /// getFunction - retrieve the ith function in the overload set. - const FunctionDecl *getFunction(unsigned i) const { - assert(i < getNumFunctions() && "Illegal function #"); - return Functions[i]; - } - FunctionDecl *getFunction(unsigned i) { - assert(i < getNumFunctions() && "Illegal function #"); - return Functions[i]; - } - - // getDeclContext - Get the context of these overloaded functions. - DeclContext *getDeclContext() { - assert(getNumFunctions() > 0 && "Context of an empty overload set"); - return getFunction(0)->getDeclContext(); - } + unsigned size() const { return Functions.size(); } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { @@ -449,6 +471,15 @@ public: /// getDestructor - Returns the destructor decl for this class. const CXXDestructorDecl *getDestructor(ASTContext &Context); + /// isLocalClass - If the class is a local class [class.local], returns + /// the enclosing function declaration. + const FunctionDecl *isLocalClass() const { + if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(getDeclContext())) + return RD->isLocalClass(); + + return dyn_cast<FunctionDecl>(getDeclContext()); + } + /// viewInheritance - Renders and displays an inheritance diagram /// for this C++ class and all of its base classes (transitively) using /// GraphViz. @@ -1070,17 +1101,25 @@ class UsingDecl : public NamedDecl { public: /// \brief Returns the source range that covers the nested-name-specifier /// preceding the namespace name. - SourceRange getNestedNameRange() { return(NestedNameRange); } + SourceRange getNestedNameRange() { return NestedNameRange; } + /// \brief Returns the source location of the target declaration name. - SourceLocation getTargetNameLocation() { return(TargetNameLocation); } + SourceLocation getTargetNameLocation() { return TargetNameLocation; } + /// \brief Returns the source location of the "using" location itself. - SourceLocation getUsingLocation() { return(UsingLocation); } + SourceLocation getUsingLocation() { return UsingLocation; } + /// \brief getTargetDecl - Returns target specified by using-decl. - NamedDecl *getTargetDecl() { return(TargetDecl); } + NamedDecl *getTargetDecl() { return TargetDecl; } + const NamedDecl *getTargetDecl() const { return TargetDecl; } + /// \brief Get target nested name declaration. - NestedNameSpecifier* getTargetNestedNameDecl() { return(TargetNestedNameDecl); } + NestedNameSpecifier* getTargetNestedNameDecl() { + return TargetNestedNameDecl; + } + /// isTypeName - Return true if using decl had 'typename'. - bool isTypeName() const { return(IsTypeName); } + bool isTypeName() const { return IsTypeName; } static UsingDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, SourceRange NNR, SourceLocation TargetNL, diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 2608dd9d3157..aad19a63ef0f 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -153,7 +153,7 @@ protected: NamedDecl *TemplatedDecl; TemplateParameterList* TemplateParams; }; - + /// Declaration of a template function. class FunctionTemplateDecl : public TemplateDecl { protected: @@ -580,6 +580,30 @@ public: return reinterpret_cast<Expr *>(TypeOrValue); } + /// \brief Iterator that traverses the elements of a template argument pack. + typedef const TemplateArgument * pack_iterator; + + /// \brief Iterator referencing the first argument of a template argument + /// pack. + pack_iterator pack_begin() const { + assert(Kind == Pack); + return Args.Args; + } + + /// \brief Iterator referencing one past the last argument of a template + /// argument pack. + pack_iterator pack_end() const { + assert(Kind == Pack); + return Args.Args + Args.NumArgs; + } + + /// \brief The number of template arguments in the given template argument + /// pack. + unsigned pack_size() const { + assert(Kind == Pack); + return Args.NumArgs; + } + /// \brief Retrieve the location where the template argument starts. SourceLocation getLocation() const { return StartLoc; } @@ -957,6 +981,10 @@ public: virtual void Destroy(ASTContext& C); }; +/// Implementation of inline functions that require the template declarations +inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD) + : Function(FTD) { } + } /* end of namespace clang */ #endif diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index ca55ea670b24..321b1f204fcf 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -572,7 +572,10 @@ public: NullPtr, // This is the type of C++0x 'nullptr'. Overload, // This represents the type of an overloaded function declaration. - Dependent // This represents the type of a type-dependent expression. + Dependent, // This represents the type of a type-dependent expression. + + UndeducedAuto // In C++0x, this represents the type of an auto variable + // that has not been deduced yet. }; private: Kind TypeKind; @@ -1103,11 +1106,17 @@ public: case '7': return 7; case '8': return 8; case '9': return 9; + case 'A': case 'a': return 10; + case 'B': case 'b': return 11; + case 'C': case 'c': return 12; + case 'D': case 'd': return 13; + case 'E': case 'e': return 14; + case 'F': case 'f': return 15; } } @@ -1358,6 +1367,21 @@ public: static bool classof(const TypeOfType *) { return true; } }; +/// DecltypeType (C++0x) +class DecltypeType : public Type { + Expr *E; + DecltypeType(Expr *E, QualType can); + friend class ASTContext; // ASTContext creates these. +public: + Expr *getUnderlyingExpr() const { return E; } + + virtual void getAsStringInternal(std::string &InnerString, + const PrintingPolicy &Policy) const; + + static bool classof(const Type *T) { return T->getTypeClass() == Decltype; } + static bool classof(const DecltypeType *) { return true; } +}; + class TagType : public Type { /// Stores the TagDecl associated with this type. The decl will /// point to the TagDecl that actually defines the entity (or is a diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def index 5555a9b0ae7e..64a09d800270 100644 --- a/include/clang/AST/TypeNodes.def +++ b/include/clang/AST/TypeNodes.def @@ -69,6 +69,7 @@ TYPE(FunctionNoProto, FunctionType) NON_CANONICAL_TYPE(Typedef, Type) NON_CANONICAL_TYPE(TypeOfExpr, Type) NON_CANONICAL_TYPE(TypeOf, Type) +NON_CANONICAL_TYPE(Decltype, Type) ABSTRACT_TYPE(Tag, Type) TYPE(Record, TagType) TYPE(Enum, TagType) diff --git a/include/clang/Analysis/LocalCheckers.h b/include/clang/Analysis/LocalCheckers.h index 23610f9a2d97..9ff3f52f89aa 100644 --- a/include/clang/Analysis/LocalCheckers.h +++ b/include/clang/Analysis/LocalCheckers.h @@ -37,7 +37,6 @@ void CheckDeadStores(LiveVariables& L, BugReporter& BR); void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags, bool FullUninitTaint=false); -GRTransferFuncs* MakeGRSimpleValsTF(); GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled, const LangOptions& lopts); diff --git a/include/clang/Analysis/PathSensitive/ConstraintManager.h b/include/clang/Analysis/PathSensitive/ConstraintManager.h index eb519e0e7431..689bebb450f4 100644 --- a/include/clang/Analysis/PathSensitive/ConstraintManager.h +++ b/include/clang/Analysis/PathSensitive/ConstraintManager.h @@ -45,7 +45,7 @@ public: virtual const GRState *RemoveDeadBindings(const GRState *state, SymbolReaper& SymReaper) = 0; - virtual void print(const GRState *state, std::ostream& Out, + virtual void print(const GRState *state, llvm::raw_ostream& Out, const char* nl, const char *sep) = 0; virtual void EndPath(const GRState *state) {} diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 5db666c4b83f..f05bc680a7e2 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -20,6 +20,7 @@ #include "clang/Analysis/PathSensitive/GRState.h" #include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h" #include "clang/Analysis/PathSensitive/GRTransferFuncs.h" +#include "clang/Analysis/PathSensitive/SValuator.h" #include "clang/Analysis/PathSensitive/BugReporter.h" #include "clang/AST/Type.h" #include "clang/AST/ExprObjC.h" @@ -67,6 +68,9 @@ protected: /// ValMgr - Object that manages/creates SVals. ValueManager &ValMgr; + /// SVator - SValuator object that creates SVals from expressions. + llvm::OwningPtr<SValuator> SVator; + /// EntryNode - The immediate predecessor node. NodeTy* EntryNode; @@ -603,41 +607,32 @@ protected: return X; if (isa<Loc>(X)) - return getTF().EvalCast(*this, cast<Loc>(X), CastT); + return SVator->EvalCast(cast<Loc>(X), CastT); else - return getTF().EvalCast(*this, cast<NonLoc>(X), CastT); + return SVator->EvalCast(cast<NonLoc>(X), CastT); } - SVal EvalMinus(UnaryOperator* U, SVal X) { - return X.isValid() ? getTF().EvalMinus(*this, U, cast<NonLoc>(X)) : X; + SVal EvalMinus(SVal X) { + return X.isValid() ? SVator->EvalMinus(cast<NonLoc>(X)) : X; } SVal EvalComplement(SVal X) { - return X.isValid() ? getTF().EvalComplement(*this, cast<NonLoc>(X)) : X; + return X.isValid() ? SVator->EvalComplement(cast<NonLoc>(X)) : X; } public: - SVal EvalBinOp(BinaryOperator::Opcode Op, NonLoc L, NonLoc R, QualType T) { - return R.isValid() ? getTF().DetermEvalBinOpNN(*this, Op, L, R, T) - : R; + SVal EvalBinOp(BinaryOperator::Opcode op, NonLoc L, NonLoc R, QualType T) { + return SVator->EvalBinOpNN(op, L, R, T); } - SVal EvalBinOp(BinaryOperator::Opcode Op, NonLoc L, SVal R, QualType T) { - return R.isValid() ? getTF().DetermEvalBinOpNN(*this, Op, L, - cast<NonLoc>(R), T) : R; + SVal EvalBinOp(BinaryOperator::Opcode op, NonLoc L, SVal R, QualType T) { + return R.isValid() ? SVator->EvalBinOpNN(op, L, cast<NonLoc>(R), T) : R; } - void EvalBinOp(ExplodedNodeSet<GRState>& Dst, Expr* Ex, - BinaryOperator::Opcode Op, NonLoc L, NonLoc R, - ExplodedNode<GRState>* Pred, QualType T); - - void EvalBinOp(GRStateSet& OStates, const GRState* St, Expr* Ex, - BinaryOperator::Opcode Op, NonLoc L, NonLoc R, QualType T); - - SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op, SVal L,SVal R, - QualType T); - + SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op, + SVal lhs, SVal rhs, QualType T); + protected: void EvalCall(NodeSet& Dst, CallExpr* CE, SVal L, NodeTy* Pred); diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index 98f1242ad81e..0da8f5243e9c 100644 --- a/include/clang/Analysis/PathSensitive/GRState.h +++ b/include/clang/Analysis/PathSensitive/GRState.h @@ -34,7 +34,7 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/Streams.h" +#include "llvm/Support/raw_ostream.h" #include <functional> @@ -199,6 +199,14 @@ public: bool assumption) const; //==---------------------------------------------------------------------==// + // Utility methods for getting regions. + //==---------------------------------------------------------------------==// + + const VarRegion* getRegion(const VarDecl* D) const; + + const MemRegion* getSelfRegion() const; + + //==---------------------------------------------------------------------==// // Binding and retrieving values to/from the environment and symbolic store. //==---------------------------------------------------------------------==// @@ -218,6 +226,10 @@ public: return bindExpr(Ex, V, true, false); } + const GRState *bindDecl(const VarDecl* VD, SVal IVal) const; + + const GRState *bindDeclWithNoInit(const VarDecl* VD) const; + const GRState *bindLoc(Loc location, SVal V) const; const GRState *bindLoc(SVal location, SVal V) const; @@ -314,17 +326,17 @@ public: class Printer { public: virtual ~Printer() {} - virtual void Print(std::ostream& Out, const GRState* state, + virtual void Print(llvm::raw_ostream& Out, const GRState* state, const char* nl, const char* sep) = 0; }; // Pretty-printing. - void print(std::ostream& Out, const char *nl = "\n", + void print(llvm::raw_ostream& Out, const char *nl = "\n", const char *sep = "") const; void printStdErr() const; - void printDOT(std::ostream& Out) const; + void printDOT(llvm::raw_ostream& Out) const; // Tags used for the Generic Data Map. struct NullDerefTag { @@ -427,18 +439,7 @@ private: /// Liveness - live-variables information of the ValueDecl* and block-level /// Expr* in the CFG. Used to get initial store and prune out dead state. LiveVariables& Liveness; - -private: - - Environment RemoveBlkExpr(const Environment& Env, Expr* E) { - return EnvMgr.RemoveBlkExpr(Env, E); - } - // FIXME: Remove when we do lazy initializaton of variable bindings. -// const GRState* BindVar(const GRState* St, VarDecl* D, SVal V) { -// return SetSVal(St, getLoc(D), V); -// } - public: GRStateManager(ASTContext& Ctx, @@ -460,7 +461,7 @@ public: ~GRStateManager(); - const GRState* getInitialState(); + const GRState *getInitialState(); ASTContext &getContext() { return ValueMgr.getContext(); } const ASTContext &getContext() const { return ValueMgr.getContext(); } @@ -498,16 +499,6 @@ public: StoreManager& getStoreManager() { return *StoreMgr; } ConstraintManager& getConstraintManager() { return *ConstraintMgr; } - const GRState* BindDecl(const GRState* St, const VarDecl* VD, SVal IVal) { - // Store manager should return a persistent state. - return StoreMgr->BindDecl(St, VD, IVal); - } - - const GRState* BindDeclWithNoInit(const GRState* St, const VarDecl* VD) { - // Store manager should return a persistent state. - return StoreMgr->BindDeclWithNoInit(St, VD); - } - const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc, SymbolReaper& SymReaper); @@ -516,55 +507,7 @@ public: NewSt.Env = EnvMgr.RemoveSubExprBindings(NewSt.Env); return getPersistentState(NewSt); } - - - // Utility methods for getting regions. - - VarRegion* getRegion(const VarDecl* D) { - return getRegionManager().getVarRegion(D); - } - - const MemRegion* getSelfRegion(const GRState* state) { - return StoreMgr->getSelfRegion(state->getStore()); - } - -private: - - SVal GetBlkExprSVal(const GRState* St, const Stmt* Ex) { - return St->getEnvironment().GetBlkExprSVal(Ex, ValueMgr); - } - - const GRState* BindExpr(const GRState* St, const Stmt* Ex, SVal V, - bool isBlkExpr, bool Invalidate) { - - const Environment& OldEnv = St->getEnvironment(); - Environment NewEnv = EnvMgr.BindExpr(OldEnv, Ex, V, isBlkExpr, Invalidate); - - if (NewEnv == OldEnv) - return St; - - GRState NewSt = *St; - NewSt.Env = NewEnv; - return getPersistentState(NewSt); - } - const GRState* BindExpr(const GRState* St, const Stmt* Ex, SVal V, - bool Invalidate = true) { - - bool isBlkExpr = false; - - if (Ex == CurrentStmt) { - // FIXME: Should this just be an assertion? When would we want to set - // the value of a block-level expression if it wasn't CurrentStmt? - isBlkExpr = cfg.isBlkExpr(Ex); - - if (!isBlkExpr) - return St; - } - - return BindExpr(St, Ex, V, isBlkExpr, Invalidate); - } - public: SVal ArrayToPointer(Loc Array) { @@ -579,37 +522,7 @@ public: void iterBindings(const GRState* state, StoreManager::BindingsHandler& F) { StoreMgr->iterBindings(state->getStore(), F); } - - SVal GetSVal(const GRState* state, const MemRegion* R) { - return StoreMgr->Retrieve(state, loc::MemRegionVal(R)); - } - - SVal GetSValAsScalarOrLoc(const GRState* state, const MemRegion *R) { - // We only want to do fetches from regions that we can actually bind - // values. For example, SymbolicRegions of type 'id<...>' cannot - // have direct bindings (but their can be bindings on their subregions). - if (!R->isBoundable()) - return UnknownVal(); - - if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) { - QualType T = TR->getValueType(getContext()); - if (Loc::IsLocType(T) || T->isIntegerType()) - return GetSVal(state, R); - } - - return UnknownVal(); - } - - const GRState* BindLoc(const GRState* St, Loc LV, SVal V) { - return StoreMgr->Bind(St, LV, V); - } - void Unbind(GRState& St, Loc LV) { - St.St = StoreMgr->Remove(St.St, LV); - } - - const GRState* Unbind(const GRState* St, Loc LV); - const GRState* getPersistentState(GRState& Impl); bool isEqual(const GRState* state, Expr* Ex, const llvm::APSInt& V); @@ -695,6 +608,14 @@ public: // Out-of-line method definitions for GRState. //===----------------------------------------------------------------------===// +inline const VarRegion* GRState::getRegion(const VarDecl* D) const { + return Mgr->getRegionManager().getVarRegion(D); +} + +inline const MemRegion* GRState::getSelfRegion() const { + return Mgr->StoreMgr->getSelfRegion(getStore()); +} + inline const GRState *GRState::assume(SVal Cond, bool Assumption) const { return Mgr->ConstraintMgr->Assume(this, Cond, Assumption); } @@ -709,18 +630,16 @@ inline const GRState *GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL return Mgr->StoreMgr->BindCompoundLiteral(this, CL, V); } -inline const GRState *GRState::bindExpr(const Stmt* Ex, SVal V, bool isBlkExpr, - bool Invalidate) const { - return Mgr->BindExpr(this, Ex, V, isBlkExpr, Invalidate); +inline const GRState *GRState::bindDecl(const VarDecl* VD, SVal IVal) const { + return Mgr->StoreMgr->BindDecl(this, VD, IVal); } -inline const GRState *GRState::bindExpr(const Stmt* Ex, SVal V, - bool Invalidate) const { - return Mgr->BindExpr(this, Ex, V, Invalidate); +inline const GRState *GRState::bindDeclWithNoInit(const VarDecl* VD) const { + return Mgr->StoreMgr->BindDeclWithNoInit(this, VD); } inline const GRState *GRState::bindLoc(Loc LV, SVal V) const { - return Mgr->BindLoc(this, LV, V); + return Mgr->StoreMgr->Bind(this, LV, V); } inline const GRState *GRState::bindLoc(SVal LV, SVal V) const { @@ -756,11 +675,11 @@ inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) const { } inline SVal GRState::getSVal(const Stmt* Ex) const { - return getEnvironment().GetSVal(Ex, Mgr->ValueMgr); + return Env.GetSVal(Ex, Mgr->ValueMgr); } inline SVal GRState::getBlkExprSVal(const Stmt* Ex) const { - return Mgr->GetBlkExprSVal(this, Ex); + return Env.GetBlkExprSVal(Ex, Mgr->ValueMgr); } inline SVal GRState::getSValAsScalarOrLoc(const Stmt *S) const { @@ -778,11 +697,7 @@ inline SVal GRState::getSVal(Loc LV, QualType T) const { } inline SVal GRState::getSVal(const MemRegion* R) const { - return Mgr->GetSVal(this, R); -} - -inline SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const { - return Mgr->GetSValAsScalarOrLoc(this, R); + return Mgr->StoreMgr->Retrieve(this, loc::MemRegionVal(R)); } inline BasicValueFactory &GRState::getBasicVals() const { @@ -842,10 +757,6 @@ CB GRState::scanReachableSymbols(SVal val) const { scanReachableSymbols(val, cb); return cb; } - -inline const GRState *GRState::unbindLoc(Loc LV) const { - return Mgr->Unbind(this, LV); -} } // end clang namespace diff --git a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h index c2f8f5aae0e9..db23f81e2d67 100644 --- a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h +++ b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h @@ -22,20 +22,12 @@ namespace clang { - class GRExprEngine; - class BugReporter; - class ObjCMessageExpr; - class GRStmtNodeBuilderRef; +class GRExprEngine; +class BugReporter; +class ObjCMessageExpr; +class GRStmtNodeBuilderRef; class GRTransferFuncs { - friend class GRExprEngine; -protected: - virtual SVal DetermEvalBinOpNN(GRExprEngine& Eng, - BinaryOperator::Opcode Op, - NonLoc L, NonLoc R, QualType T) { - return UnknownVal(); - } - public: GRTransferFuncs() {} virtual ~GRTransferFuncs() {} @@ -43,33 +35,7 @@ public: virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {} virtual void RegisterChecks(BugReporter& BR) {} - // Casts. - - virtual SVal EvalCast(GRExprEngine& Engine, NonLoc V, QualType CastT) =0; - virtual SVal EvalCast(GRExprEngine& Engine, Loc V, QualType CastT) = 0; - - // Unary Operators. - - virtual SVal EvalMinus(GRExprEngine& Engine, UnaryOperator* U, NonLoc X) = 0; - - virtual SVal EvalComplement(GRExprEngine& Engine, NonLoc X) = 0; - // Binary Operators. - // FIXME: We're moving back towards using GREXprEngine directly. No need - // for OStates - virtual void EvalBinOpNN(GRStateSet& OStates, GRExprEngine& Eng, - const GRState* St, Expr* Ex, - BinaryOperator::Opcode Op, NonLoc L, NonLoc R, - QualType T); - - virtual SVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op, - Loc L, Loc R) = 0; - - // Pointer arithmetic. - - virtual SVal EvalBinOp(GRExprEngine& Engine, const GRState *state, - BinaryOperator::Opcode Op, Loc L, NonLoc R) = 0; - // Calls. virtual void EvalCall(ExplodedNodeSet<GRState>& Dst, @@ -108,8 +74,7 @@ public: ReturnStmt* S, ExplodedNode<GRState>* Pred) {} - // Assumptions. - + // Assumptions. virtual const GRState* EvalAssume(const GRState *state, SVal Cond, bool Assumption) { return state; diff --git a/include/clang/Analysis/PathSensitive/SVals.h b/include/clang/Analysis/PathSensitive/SVals.h index de74dbdb17b0..36137fb117b3 100644 --- a/include/clang/Analysis/PathSensitive/SVals.h +++ b/include/clang/Analysis/PathSensitive/SVals.h @@ -111,7 +111,6 @@ public: /// return that expression. Otherwise return NULL. const SymExpr *getAsSymbolicExpression() const; - void print(std::ostream& OS) const; void print(llvm::raw_ostream& OS) const; void printStdErr() const; @@ -255,12 +254,12 @@ public: } // Transfer functions for binary/unary operations on ConcreteInts. - SVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op, + SVal evalBinOp(ValueManager &ValMgr, BinaryOperator::Opcode Op, const ConcreteInt& R) const; - ConcreteInt EvalComplement(BasicValueFactory& BasicVals) const; + ConcreteInt evalComplement(ValueManager &ValMgr) const; - ConcreteInt EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const; + ConcreteInt evalMinus(ValueManager &ValMgr) const; // Implement isa<T> support. static inline bool classof(const SVal* V) { diff --git a/include/clang/Analysis/PathSensitive/SValuator.h b/include/clang/Analysis/PathSensitive/SValuator.h new file mode 100644 index 000000000000..490c04e5978e --- /dev/null +++ b/include/clang/Analysis/PathSensitive/SValuator.h @@ -0,0 +1,55 @@ +// SValuator.h - Construction of SVals from evaluating expressions -*- 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 SValuator, a class that defines the interface for +// "symbolical evaluators" which construct an SVal from an expression. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_SVALUATOR +#define LLVM_CLANG_ANALYSIS_SVALUATOR + +#include "clang/AST/Expr.h" +#include "clang/Analysis/PathSensitive/SVals.h" + +namespace clang { + +class GRState; +class ValueManager; + +class SValuator { +protected: + ValueManager &ValMgr; + +public: + SValuator(ValueManager &valMgr) : ValMgr(valMgr) {} + virtual ~SValuator() {} + + virtual SVal EvalCast(NonLoc val, QualType castTy) = 0; + + virtual SVal EvalCast(Loc val, QualType castTy) = 0; + + virtual SVal EvalMinus(NonLoc val) = 0; + + virtual SVal EvalComplement(NonLoc val) = 0; + + virtual SVal EvalBinOpNN(BinaryOperator::Opcode Op, NonLoc lhs, + NonLoc rhs, QualType resultTy) = 0; + + virtual SVal EvalBinOpLL(BinaryOperator::Opcode Op, Loc lhs, Loc rhs, + QualType resultTy) = 0; + + virtual SVal EvalBinOpLN(const GRState *state, BinaryOperator::Opcode Op, + Loc lhs, NonLoc rhs, QualType resultTy) = 0; +}; + +SValuator* CreateSimpleSValuator(ValueManager &valMgr); + +} // end clang namespace +#endif diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index 0c5df2e98e17..5aa53507fd14 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -21,7 +21,6 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" -#include <iosfwd> namespace clang { @@ -139,7 +138,7 @@ public: /// EvalBinOp - Perform pointer arithmetic. virtual SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op, - Loc lhs, NonLoc rhs) { + Loc lhs, NonLoc rhs, QualType resultTy) { return UnknownVal(); } @@ -171,7 +170,7 @@ public: return state; } - virtual void print(Store store, std::ostream& Out, + virtual void print(Store store, llvm::raw_ostream& Out, const char* nl, const char *sep) = 0; class BindingsHandler { diff --git a/include/clang/Analysis/PathSensitive/SymbolManager.h b/include/clang/Analysis/PathSensitive/SymbolManager.h index d074e30333d4..f32a7e3481dd 100644 --- a/include/clang/Analysis/PathSensitive/SymbolManager.h +++ b/include/clang/Analysis/PathSensitive/SymbolManager.h @@ -328,9 +328,4 @@ namespace llvm { llvm::raw_ostream& operator<<(llvm::raw_ostream& Out, const clang::SymExpr *SE); } -namespace std { - std::ostream& operator<<(std::ostream& Out, - const clang::SymExpr *SE); -} - #endif diff --git a/include/clang/Analysis/PathSensitive/ValueManager.h b/include/clang/Analysis/PathSensitive/ValueManager.h index d8e557f76036..de318a0f03e8 100644 --- a/include/clang/Analysis/PathSensitive/ValueManager.h +++ b/include/clang/Analysis/PathSensitive/ValueManager.h @@ -87,14 +87,18 @@ public: return nonloc::ConcreteInt(BasicVals.getZeroWithPtrWidth(false)); } - NonLoc makeIntVal(const IntegerLiteral* I) { + nonloc::ConcreteInt makeIntVal(const IntegerLiteral* I) { return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(), I->getType()->isUnsignedIntegerType())); } - NonLoc makeIntVal(const llvm::APSInt& V) { + nonloc::ConcreteInt makeIntVal(const llvm::APSInt& V) { return nonloc::ConcreteInt(BasicVals.getValue(V)); } + + loc::ConcreteInt makeIntLocVal(const llvm::APSInt &v) { + return loc::ConcreteInt(BasicVals.getValue(v)); + } NonLoc makeIntVal(const llvm::APInt& V, bool isUnsigned) { return nonloc::ConcreteInt(BasicVals.getValue(V, isUnsigned)); diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td index 9c439851b182..815ae8d70003 100644 --- a/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/include/clang/Basic/DiagnosticFrontendKinds.td @@ -60,6 +60,12 @@ def warn_pch_heinous_extensions : Error< def warn_pch_lax_vector_conversions : Error< "lax vector conversions were %select{disabled|enabled}0 in PCH file but " "are currently %select{disabled|enabled}1">; +def warn_pch_altivec : Error< + "AltiVec initializers were %select{disabled|enabled}0 in PCH file but " + "are currently %select{disabled|enabled}1">; +def warn_pch_opencl : Error< + "OpenCL language extensions were %select{disabled|enabled}0 in PCH file " + "but are currently %select{disabled|enabled}1">; def warn_pch_exceptions : Error< "exceptions were %select{disabled|enabled}0 in PCH file but " "are currently %select{disabled|enabled}1">; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 79a9efac8554..4ba1083089e6 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -398,6 +398,15 @@ def err_init_reference_member_uninitialized : Error< def note_uninit_reference_member : Note< "uninitialized reference member is here">; +// C++0x auto +def err_auto_variable_cannot_appear_in_own_initializer : Error< + "variable %0 declared with 'auto' type cannot appear in its own initializer">; +def err_illegal_decl_array_of_auto : Error< + "'%0' declared as array of 'auto'">; +def err_auto_not_allowed : Error< + "'auto' not allowed in %select{function prototype|struct member|union member" + "|class member|exception declaration|template parameter|block literal}0">; + // Objective-C++ def err_objc_decls_may_only_appear_in_global_scope : Error< "Objective-C declarations may only appear in global scope">; @@ -584,6 +593,12 @@ def err_defining_default_ctor : Error< "%2 does not have any default constructor">; def note_previous_class_decl : Note< "%0 declared here">; +def err_uninitialized_member_for_assign : Error< + "cannot define the implicit default assignment operator for %0, because " + "non-static %select{reference|const}1 member %2 can't use default " + "assignment operator">; +def note_first_required_here : Note< + "synthesized method is first required here">; def err_unintialized_member : Error< "cannot define the implicit default constructor for %0, because " "%select{reference|const}1 member %2 cannot be default-initialized">; @@ -651,6 +666,7 @@ def note_template_export_unsupported : Note< def err_template_outside_namespace_or_class_scope : Error< "templates can only be declared in namespace or class scope">; def err_template_linkage : Error<"templates must have C++ linkage">; +def err_template_typedef : Error<"a typedef cannot be a template">; def err_template_unnamed_class : Error< "cannot declare a class template with no name">; def err_template_param_list_different_arity : Error< @@ -697,14 +713,15 @@ def err_template_arg_must_be_expr : Error< def err_template_arg_nontype_ambig : Error< "template argument for non-type template parameter is treated as type %0">; def err_template_arg_must_be_template : Error< - "template argument for template template parameter must be a template">; + "template argument for template template parameter must be a class template">; def err_template_arg_local_type : Error<"template argument uses local type %0">; def err_template_arg_unnamed_type : Error< "template argument uses unnamed type">; def note_template_unnamed_type_here : Note< "unnamed type used in template argument was declared here">; def err_template_arg_not_class_template : Error< - "template argument does not refer to a class template">; + "template argument does not refer to a class template or template " + "template parameter">; def note_template_arg_refers_here_func : Note< "template argument refers to function template %0, here">; def err_template_arg_template_params_mismatch : Error< @@ -813,6 +830,9 @@ def note_template_member_class_here : Note< "in instantiation of member class %0 requested here">; def note_template_member_function_here : Note< "in instantiation of member function %q0 requested here">; +def note_function_template_spec_here : Note< + "in instantiation of function template specialization %q0 requested here">; + def note_default_arg_instantiation_here : Note< "in instantiation of default argument for '%0' required here">; def note_partial_spec_deduct_instantiation_here : Note< @@ -1602,6 +1622,14 @@ def err_anonymous_record_nonpublic_member : Error< "anonymous %select{struct|union}0 cannot contain a " "%select{private|protected}1 data member">; +// C++ local classes +def err_reference_to_local_var_in_enclosing_function : Error< + "reference to local variable %0 declared in enclosed function %1">; +def note_local_variable_declared_here : Note< + "%0 declared here">; +def err_static_data_member_not_allowed_in_local_class : Error< + "static data member %0 not allowed in local class %1">; + // C++ derived classes def err_base_clause_on_union : Error<"unions cannot have base classes">; def err_base_must_be_class : Error<"base specifier must name a class">; @@ -1841,6 +1869,9 @@ def err_selector_element_type : Error< def err_collection_expr_type : Error< "collection expression type %0 is not a valid object">; +def err_invalid_conversion_between_ext_vectors : Error< + "invalid conversion between ext-vector type %0 and %1">; + // Type def ext_invalid_sign_spec : Extension<"'%0' cannot be signed or unsigned">; def warn_receiver_forward_class : Warning< diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index 7c578e32f814..543a0fff8e7b 100644 --- a/include/clang/Basic/LangOptions.h +++ b/include/clang/Basic/LangOptions.h @@ -43,6 +43,7 @@ public: unsigned PascalStrings : 1; // Allow Pascal strings unsigned WritableStrings : 1; // Allow writable strings unsigned LaxVectorConversions : 1; + unsigned AltiVec : 1; // Support AltiVec-style vector initializers. unsigned Exceptions : 1; // Support exception handling. unsigned NeXTRuntime : 1; // Use NeXT runtime. @@ -80,6 +81,10 @@ public: unsigned AccessControl : 1; // Whether C++ access control should // be enabled. unsigned CharIsSigned : 1; // Whether char is a signed or unsigned type + + unsigned OpenCL : 1; // OpenCL C99 language extensions. + + private: unsigned GC : 2; // Objective-C Garbage Collection modes. We declare // this enum as unsigned because MSVC insists on making enums @@ -111,6 +116,7 @@ public: Exceptions = NeXTRuntime = Freestanding = NoBuiltin = 0; LaxVectorConversions = 1; HeinousExtensions = 0; + AltiVec = OpenCL = 0; SymbolVisibility = (unsigned) Default; diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index bcfb83b8942c..249ca89f717d 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -326,6 +326,11 @@ class SourceManager { // Statistics for -print-stats. mutable unsigned NumLinearScans, NumBinaryProbes; + // Cache results for the isBeforeInTranslationUnit method. + mutable FileID LastLFIDForBeforeTUCheck; + mutable FileID LastRFIDForBeforeTUCheck; + mutable bool LastResForBeforeTUCheck; + // SourceManager doesn't support copy construction. explicit SourceManager(const SourceManager&); void operator=(const SourceManager&); @@ -637,6 +642,11 @@ public: SourceLocation getLocation(const FileEntry *SourceFile, unsigned Line, unsigned Col) const; + /// \brief Determines the order of 2 source locations in the translation unit. + /// + /// \returns true if LHS source location comes before RHS, false otherwise. + bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const; + // Iterators over FileInfos. typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> ::const_iterator fileinfo_iterator; diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def index 497b1884a3d8..ed0270acd0dd 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -224,7 +224,7 @@ KEYWORD(__func__ , KEYALL) // C++ 2.11p1: Keywords. KEYWORD(asm , KEYCXX|KEYGNU) -KEYWORD(bool , KEYCXX) +KEYWORD(bool , KEYCXX|BOOLSUPPORT) KEYWORD(catch , KEYCXX) KEYWORD(class , KEYCXX) KEYWORD(const_cast , KEYCXX) @@ -232,7 +232,7 @@ KEYWORD(delete , KEYCXX) KEYWORD(dynamic_cast , KEYCXX) KEYWORD(explicit , KEYCXX) KEYWORD(export , KEYCXX) -KEYWORD(false , KEYCXX) +KEYWORD(false , KEYCXX|BOOLSUPPORT) KEYWORD(friend , KEYCXX) KEYWORD(mutable , KEYCXX) KEYWORD(namespace , KEYCXX) @@ -246,7 +246,7 @@ KEYWORD(static_cast , KEYCXX) KEYWORD(template , KEYCXX) KEYWORD(this , KEYCXX) KEYWORD(throw , KEYCXX) -KEYWORD(true , KEYCXX) +KEYWORD(true , KEYCXX|BOOLSUPPORT) KEYWORD(try , KEYCXX) KEYWORD(typename , KEYCXX) KEYWORD(typeid , KEYCXX) diff --git a/include/clang/Frontend/Analyses.def b/include/clang/Frontend/Analyses.def index 3492d09c10aa..ad799c3a8b25 100644 --- a/include/clang/Frontend/Analyses.def +++ b/include/clang/Frontend/Analyses.def @@ -41,13 +41,9 @@ ANALYSIS(WarnObjCDealloc, "warn-objc-missing-dealloc", ANALYSIS(WarnObjCUnusedIvars, "warn-objc-unused-ivars", "Warn about private ivars that are never used", ObjCImplementation) -ANALYSIS(CheckerSimple, "checker-simple", - "Perform simple path-sensitive checks.", Code) - ANALYSIS(CheckerCFRef, "checker-cfref", "Run the [Core] Foundation reference count checker", Code) - #ifndef ANALYSIS_STORE #define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) #endif diff --git a/include/clang/Frontend/CommandLineSourceLoc.h b/include/clang/Frontend/CommandLineSourceLoc.h new file mode 100644 index 000000000000..1eaa958995f5 --- /dev/null +++ b/include/clang/Frontend/CommandLineSourceLoc.h @@ -0,0 +1,85 @@ +//===--- CommandLineSourceLoc.h - Parsing for source locations-*- C++ -*---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Command line parsing for source locations. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H +#define LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H + +#include "llvm/Support/CommandLine.h" +#include <cstdio> + +namespace clang { + +/// \brief A source location that has been parsed on the command line. +struct ParsedSourceLocation { + std::string FileName; + unsigned Line; + unsigned Column; +}; + +} + +namespace llvm { + namespace cl { + /// \brief Command-line option parser that parses source locations. + /// + /// Source locations are of the form filename:line:column. + template<> + class parser<clang::ParsedSourceLocation> + : public basic_parser<clang::ParsedSourceLocation> { + public: + bool parse(Option &O, const char *ArgName, + const std::string &ArgValue, + clang::ParsedSourceLocation &Val); + }; + + bool + parser<clang::ParsedSourceLocation>:: + parse(Option &O, const char *ArgName, const std::string &ArgValue, + clang::ParsedSourceLocation &Val) { + using namespace clang; + + const char *ExpectedFormat + = "source location must be of the form filename:line:column"; + std::string::size_type SecondColon = ArgValue.rfind(':'); + if (SecondColon == std::string::npos) { + std::fprintf(stderr, "%s\n", ExpectedFormat); + return true; + } + char *EndPtr; + long Column + = std::strtol(ArgValue.c_str() + SecondColon + 1, &EndPtr, 10); + if (EndPtr != ArgValue.c_str() + ArgValue.size()) { + std::fprintf(stderr, "%s\n", ExpectedFormat); + return true; + } + + std::string::size_type FirstColon = ArgValue.rfind(':', SecondColon-1); + if (FirstColon == std::string::npos) { + std::fprintf(stderr, "%s\n", ExpectedFormat); + return true; + } + long Line = std::strtol(ArgValue.c_str() + FirstColon + 1, &EndPtr, 10); + if (EndPtr != ArgValue.c_str() + SecondColon) { + std::fprintf(stderr, "%s\n", ExpectedFormat); + return true; + } + + Val.FileName = ArgValue.substr(0, FirstColon); + Val.Line = Line; + Val.Column = Column; + return false; + } + } +} + +#endif diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index e546a12c49e9..63222725d529 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -387,7 +387,9 @@ namespace clang { /// \brief An ObjCQualifiedInterfaceType record. TYPE_OBJC_QUALIFIED_INTERFACE = 22, /// \brief An ObjCObjectPointerType record. - TYPE_OBJC_OBJECT_POINTER = 23 + TYPE_OBJC_OBJECT_POINTER = 23, + /// \brief a DecltypeType record. + TYPE_DECLTYPE = 24 }; /// \brief The type IDs for special types constructed by semantic diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h index 41eb31a0fc35..77df60cd7210 100644 --- a/include/clang/Frontend/Utils.h +++ b/include/clang/Frontend/Utils.h @@ -32,6 +32,10 @@ class IdentifierTable; class SourceManager; class PreprocessorFactory; class LangOptions; +class Decl; +class Stmt; +class ASTContext; +class SourceLocation; /// ProcessWarningOptions - Initialize the diagnostic client and process the /// warning options specified on the command line. @@ -74,6 +78,33 @@ void AttachDependencyFileGen(Preprocessor *PP, llvm::raw_ostream *OS, /// a seekable stream. void CacheTokens(Preprocessor& PP, llvm::raw_fd_ostream* OS); +/// \brief Returns the AST node that a source location points to. +/// +/// Returns a pair of Decl* and Stmt*. If no AST node is found for the source +/// location, the pair will contain null pointers. +/// +/// If the source location points to just a declaration, the statement part of +/// the pair will be null, e.g., +/// @code +/// int foo; +/// @endcode +/// If the source location points at 'foo', the pair will contain the VarDecl +/// of foo and a null Stmt. +/// +/// If the source location points to a statement node, the returned declaration +/// will be the immediate 'parent' declaration of the statement node, e.g., +/// @code +/// void f() { +/// int foo = 100; +/// ++foo; +/// } +/// @endcode +/// Pointing at '100' will return a <VarDecl 'foo', IntegerLiteral '100'> pair. +/// Pointing at '++foo' will return a <FunctionDecl 'f', UnaryOperator> pair. +/// +std::pair<Decl *, Stmt *> ResolveLocationInAST(ASTContext &Ctx, + SourceLocation Loc); + } // end namespace clang #endif diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 8c85ba60ac2e..bfb74748c5f1 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -967,12 +967,13 @@ public: /// ActOnUsingDirective - This is called when using-directive is parsed. virtual DeclPtrTy ActOnUsingDeclaration(Scope *CurScope, - SourceLocation UsingLoc, - const CXXScopeSpec &SS, - SourceLocation IdentLoc, - IdentifierInfo *TargetName, - AttributeList *AttrList, - bool IsTypeName); + SourceLocation UsingLoc, + const CXXScopeSpec &SS, + SourceLocation IdentLoc, + IdentifierInfo *TargetName, + OverloadedOperatorKind Op, + AttributeList *AttrList, + bool IsTypeName); /// ActOnParamDefaultArgument - Parse default argument for function parameter virtual void ActOnParamDefaultArgument(DeclPtrTy param, @@ -1453,6 +1454,26 @@ public: return DeclResult(); } + /// \brief Invoked when a declarator that has one or more template parameter + /// lists has been parsed. + /// + /// This action is similar to ActOnDeclarator(), except that the declaration + /// being created somehow involves a template, e.g., it is a template + /// declaration or specialization. + virtual DeclPtrTy ActOnTemplateDeclarator(Scope *S, + MultiTemplateParamsArg TemplateParameterLists, + Declarator &D) { + return DeclPtrTy(); + } + + /// \brief Invoked when the parser is beginning to parse a function template + /// or function template specialization definition. + virtual DeclPtrTy ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope, + MultiTemplateParamsArg TemplateParameterLists, + Declarator &D) { + return DeclPtrTy(); + } + /// \brief Process the explicit instantiation of a class template /// specialization. /// diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h index 26cebf0915b4..50ca88acbce9 100644 --- a/include/clang/Parse/AttributeList.h +++ b/include/clang/Parse/AttributeList.h @@ -97,6 +97,7 @@ public: AT_warn_unused_result, AT_weak, AT_weak_import, + AT_reqd_wg_size, IgnoredAttribute, UnknownAttribute }; diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h index a0b9b1e7cc23..300602e5147c 100644 --- a/include/clang/Parse/DeclSpec.h +++ b/include/clang/Parse/DeclSpec.h @@ -82,6 +82,8 @@ public: TST_typename, // Typedef, C++ class-name or enum name, etc. TST_typeofType, TST_typeofExpr, + TST_decltype, // C++0x decltype + TST_auto, // C++0x auto TST_error // erroneous type }; diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 75587936065b..e5f62ec683e3 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -636,7 +636,8 @@ private: DeclGroupPtrTy ParseDeclarationOrFunctionDefinition( AccessSpecifier AS = AS_none); - DeclPtrTy ParseFunctionDefinition(Declarator &D); + DeclPtrTy ParseFunctionDefinition(Declarator &D, + const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo()); void ParseKNRParamDeclarations(Declarator &D); // EndLoc, if non-NULL, is filled with the location of the last token of // the simple-asm. @@ -909,7 +910,8 @@ private: DeclGroupPtrTy ParseSimpleDeclaration(unsigned Context, SourceLocation &DeclEnd, bool RequireSemi = true); - DeclPtrTy ParseDeclarationAfterDeclarator(Declarator &D); + DeclPtrTy ParseDeclarationAfterDeclarator(Declarator &D, + const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo()); DeclGroupPtrTy ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D); DeclPtrTy ParseFunctionStatementBody(DeclPtrTy Decl); DeclPtrTy ParseFunctionTryBlock(DeclPtrTy Decl); @@ -1069,6 +1071,7 @@ private: AttributeList *ParseMicrosoftDeclSpec(AttributeList* CurrAttr = 0); AttributeList *ParseMicrosoftTypeAttributes(AttributeList* CurrAttr = 0); void ParseTypeofSpecifier(DeclSpec &DS); + void ParseDecltypeSpecifier(DeclSpec &DS); /// DeclaratorScopeObj - RAII object used in Parser::ParseDirectDeclarator to /// enter a new C++ declarator scope and exit it when the function is @@ -1190,7 +1193,7 @@ private: TemplateArgLocationList &TemplateArgLocations, SourceLocation &RAngleLoc); - void AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, + bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, const CXXScopeSpec *SS, SourceLocation TemplateKWLoc = SourceLocation(), bool AllowTypeAnnotation = true); |