diff options
author | Ed Schouten <ed@FreeBSD.org> | 2009-06-22 08:08:35 +0000 |
---|---|---|
committer | Ed Schouten <ed@FreeBSD.org> | 2009-06-22 08:08:35 +0000 |
commit | b897c8660c4ff7037dde81b9645737bc1c992abe (patch) | |
tree | b6403365e77095a79062d3379c9e6aea0df5f088 /include/clang | |
parent | 7ef7bab7e3d06f660b059b903c231f100bb13cc5 (diff) |
Update Clang sources to r73879.vendor/clang/clang-r73879
Notes
Notes:
svn path=/vendor/clang/dist/; revision=194613
svn path=/vendor/clang/clang-r73879/; revision=194615; tag=vendor/clang/clang-r73879
Diffstat (limited to 'include/clang')
42 files changed, 2397 insertions, 547 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index f4313f4dbfff..b686b0edd30a 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -71,6 +71,7 @@ class ASTContext { llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes; std::vector<VariableArrayType*> VariableArrayTypes; std::vector<DependentSizedArrayType*> DependentSizedArrayTypes; + std::vector<DependentSizedExtVectorType*> DependentSizedExtVectorTypes; llvm::FoldingSet<VectorType> VectorTypes; llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes; llvm::FoldingSet<FunctionProtoType> FunctionProtoTypes; @@ -79,7 +80,7 @@ class ASTContext { llvm::FoldingSet<QualifiedNameType> QualifiedNameTypes; llvm::FoldingSet<TypenameType> TypenameTypes; llvm::FoldingSet<ObjCQualifiedInterfaceType> ObjCQualifiedInterfaceTypes; - llvm::FoldingSet<ObjCQualifiedIdType> ObjCQualifiedIdTypes; + llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes; llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames; llvm::FoldingSet<DependentTemplateName> DependentTemplateNames; @@ -103,7 +104,7 @@ class ASTContext { /// This is initially null and set by Sema::LazilyCreateBuiltin when /// a builtin that takes a valist is encountered. QualType BuiltinVaListType; - + /// ObjCIdType - a pseudo built-in typedef type (set by Sema). QualType ObjCIdType; const RecordType *IdStructType; @@ -125,6 +126,12 @@ class ASTContext { RecordDecl *ObjCFastEnumerationStateTypeDecl; + /// \brief Keeps track of all declaration attributes. + /// + /// Since so few decls have attrs, we keep them in a hash map instead of + /// wasting space in the Decl class. + llvm::DenseMap<const Decl*, Attr*> DeclAttrs; + TranslationUnitDecl *TUDecl; /// SourceMgr - The associated SourceManager object. @@ -163,6 +170,12 @@ public: return FullSourceLoc(Loc,SourceMgr); } + /// \brief Retrieve the attributes for the given declaration. + Attr*& getDeclAttrs(const Decl *D) { return DeclAttrs[D]; } + + /// \brief Erase the attributes corresponding to the given declaration. + void eraseDeclAttrs(const Decl *D) { DeclAttrs.erase(D); } + TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; } @@ -277,6 +290,14 @@ public: /// type. QualType getExtVectorType(QualType VectorType, unsigned NumElts); + /// getDependentSizedExtVectorType - Returns a non-unique reference to + /// the type for a dependently-sized vector of the specified element + /// type. FIXME: We will need these to be uniqued, or at least + /// comparable, at some point. + QualType getDependentSizedExtVectorType(QualType VectorType, + Expr *SizeExpr, + SourceLocation AttrLoc); + /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. /// QualType getFunctionNoProtoType(QualType ResultTy); @@ -299,6 +320,7 @@ public: QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl); QualType getTemplateTypeParmType(unsigned Depth, unsigned Index, + bool ParameterPack, IdentifierInfo *Name = 0); QualType getTemplateSpecializationType(TemplateName T, @@ -315,6 +337,12 @@ public: const TemplateSpecializationType *TemplateId, QualType Canon = QualType()); + /// getObjCObjectPointerType - Return a ObjCObjectPointerType type for the + /// given interface decl and the conforming protocol list. + QualType getObjCObjectPointerType(ObjCInterfaceDecl *Decl, + ObjCProtocolDecl **ProtocolList = 0, + unsigned NumProtocols = 0); + /// getObjCQualifiedInterfaceType - Return a /// ObjCQualifiedInterfaceType type for the given interface decl and /// the conforming protocol list. @@ -416,7 +444,7 @@ public: /// getObjCEncodingTypeSize returns size of type for objective-c encoding /// purpose. int getObjCEncodingTypeSize(QualType t); - + /// This setter/getter represents the ObjC 'id' type. It is setup lazily, by /// Sema. id is always a (typedef for a) pointer type, a pointer to a struct. QualType getObjCIdType() const { return ObjCIdType; } diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 7440e7b5f150..77b7bf6a9520 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -146,8 +146,8 @@ public: } void setOriginalNamespace(NamespaceDecl *ND) { OrigNamespace = ND; } - SourceRange getSourceRange() const { - return SourceRange(LBracLoc, RBracLoc); + virtual SourceRange getSourceRange() const { + return SourceRange(getLocation(), RBracLoc); } SourceLocation getLBracLoc() const { return LBracLoc; } @@ -259,6 +259,8 @@ public: StorageClass getStorageClass() const { return (StorageClass)SClass; } void setStorageClass(StorageClass SC) { SClass = SC; } + + virtual SourceRange getSourceRange() const; SourceLocation getTypeSpecStartLoc() const { return TypeSpecStartLoc; } void setTypeSpecStartLoc(SourceLocation SL) { @@ -644,6 +646,8 @@ private: // Move to DeclGroup when it is implemented. SourceLocation TypeSpecStartLoc; + + SourceLocation EndRangeLoc; /// \brief The template or declaration that this declaration /// describes or was instantiated from, respectively. @@ -667,7 +671,7 @@ protected: SClass(S), IsInline(isInline), C99InlineDefinition(false), IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true), IsDeleted(false), TypeSpecStartLoc(TSSL), - TemplateOrInstantiation() {} + EndRangeLoc(L), TemplateOrInstantiation() {} virtual ~FunctionDecl() {} virtual void Destroy(ASTContext& C); @@ -677,7 +681,15 @@ public: DeclarationName N, QualType T, StorageClass S = None, bool isInline = false, bool hasWrittenPrototype = true, - SourceLocation TSStartLoc = SourceLocation()); + SourceLocation TSStartLoc = SourceLocation()); + + virtual SourceRange getSourceRange() const { + return SourceRange(getLocation(), EndRangeLoc); + } + void setLocEnd(SourceLocation E) { + assert(getLocation() <= E && "Invalid end location"); + EndRangeLoc = E; + } SourceLocation getTypeSpecStartLoc() const { return TypeSpecStartLoc; } void setTypeSpecStartLoc(SourceLocation TS) { TypeSpecStartLoc = TS; } @@ -706,7 +718,7 @@ public: /// CodeGenModule.cpp uses it, and I don't know if this would break it. bool isThisDeclarationADefinition() const { return Body; } - void setBody(Stmt *B) { Body = B; } + void setBody(Stmt *B); void setLazyBody(uint64_t Offset) { Body = Offset; } /// Whether this function is marked as virtual explicitly. @@ -832,12 +844,12 @@ public: /// The gnu_inline attribute only introduces GNU inline semantics /// when all of the inline declarations of the function are marked /// gnu_inline. - bool hasActiveGNUInlineAttribute() const; + bool hasActiveGNUInlineAttribute(ASTContext &Context) const; /// \brief Determines whether this function is a GNU "extern /// inline", which is roughly the opposite of a C99 "extern inline" /// function. - bool isExternGNUInline() const; + bool isExternGNUInline(ASTContext &Context) const; /// isOverloadedOperator - Whether this function declaration /// represents an C++ overloaded operator, e.g., "operator+". diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 5c9fd342fa96..a75eecd02220 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -156,9 +156,15 @@ private: /// the implementation rather than explicitly written by the user. bool Implicit : 1; + /// \brief Whether this declaration was "used", meaning that a definition is + /// required. + bool Used : 1; + +protected: /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in. unsigned IdentifierNamespace : 8; +private: #ifndef NDEBUG void CheckAccessDeclContext() const; #else @@ -174,7 +180,7 @@ protected: Decl(Kind DK, DeclContext *DC, SourceLocation L) : NextDeclInContext(0), DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(0), - HasAttrs(false), Implicit(false), + HasAttrs(false), Implicit(false), Used(false), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), Access(AS_none) { if (Decl::CollectingStats()) addDeclKind(DK); } @@ -182,6 +188,14 @@ protected: virtual ~Decl(); public: + + /// \brief Source range that this declaration covers. + virtual SourceRange getSourceRange() const { + return SourceRange(getLocation(), getLocation()); + } + SourceLocation getLocStart() const { return getSourceRange().getBegin(); } + SourceLocation getLocEnd() const { return getSourceRange().getEnd(); } + SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } @@ -211,23 +225,23 @@ public: } bool hasAttrs() const { return HasAttrs; } - void addAttr(Attr *attr); - const Attr *getAttrs() const { + void addAttr(ASTContext &Context, Attr *attr); + const Attr *getAttrs(ASTContext &Context) const { if (!HasAttrs) return 0; // common case, no attributes. - return getAttrsImpl(); // Uncommon case, out of line hash lookup. + return getAttrsImpl(Context); // Uncommon case, out of line hash lookup. } - void swapAttrs(Decl *D); - void invalidateAttrs(); + void swapAttrs(ASTContext &Context, Decl *D); + void invalidateAttrs(ASTContext &Context); - template<typename T> const T *getAttr() const { - for (const Attr *attr = getAttrs(); attr; attr = attr->getNext()) + template<typename T> const T *getAttr(ASTContext &Context) const { + for (const Attr *attr = getAttrs(Context); attr; attr = attr->getNext()) if (const T *V = dyn_cast<T>(attr)) return V; return 0; } - template<typename T> bool hasAttr() const { - return getAttr<T>() != 0; + template<typename T> bool hasAttr(ASTContext &Context) const { + return getAttr<T>(Context) != 0; } /// setInvalidDecl - Indicates the Decl had a semantic error. This @@ -241,6 +255,11 @@ public: bool isImplicit() const { return Implicit; } void setImplicit(bool I = true) { Implicit = I; } + /// \brief Whether this declaration was used, meaning that a definition + /// is required. + bool isUsed() const { return Used; } + void setUsed(bool U = true) { Used = U; } + unsigned getIdentifierNamespace() const { return IdentifierNamespace; } @@ -268,6 +287,10 @@ public: const DeclContext *getLexicalDeclContext() const { return const_cast<Decl*>(this)->getLexicalDeclContext(); } + + bool isOutOfLine() const { + return getLexicalDeclContext() != getDeclContext(); + } /// setDeclContext - Set both the semantic and lexical DeclContext /// to DC. @@ -325,7 +348,7 @@ public: void dump(ASTContext &Context); private: - const Attr *getAttrsImpl() const; + const Attr *getAttrsImpl(ASTContext &Context) const; }; diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 4a74a2c2cbc4..9ca1823f3822 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -439,6 +439,9 @@ public: TemplateOrInstantiation = Template; } + /// getDefaultConstructor - Returns the default constructor for this class + CXXConstructorDecl *getDefaultConstructor(ASTContext &Context); + /// getDestructor - Returns the destructor decl for this class. const CXXDestructorDecl *getDestructor(ASTContext &Context); @@ -477,10 +480,6 @@ public: bool isStatic() const { return getStorageClass() == Static; } bool isInstance() const { return !isStatic(); } - bool isOutOfLineDefinition() const { - return getLexicalDeclContext() != getDeclContext(); - } - bool isVirtual() const { return isVirtualAsWritten() || (begin_overridden_methods() != end_overridden_methods()); @@ -535,6 +534,7 @@ public: /// public: /// B(A& a) : A(a), f(3.14159) { } /// }; +/// @endcode class CXXBaseOrMemberInitializer { /// BaseOrMember - This points to the entity being initialized, /// which is either a base class (a Type) or a non-static data @@ -641,6 +641,10 @@ class CXXConstructorDecl : public CXXMethodDecl { /// explicitly defaulted (i.e., defined with " = default") will have /// @c !Implicit && ImplicitlyDefined. bool ImplicitlyDefined : 1; + + /// ImplicitMustBeDefined - Implicit constructor was used to create an + /// object of its class type. It must be defined. + bool ImplicitMustBeDefined : 1; /// FIXME: Add support for base and member initializers. @@ -648,7 +652,8 @@ class CXXConstructorDecl : public CXXMethodDecl { DeclarationName N, QualType T, bool isExplicit, bool isInline, bool isImplicitlyDeclared) : CXXMethodDecl(CXXConstructor, RD, L, N, T, false, isInline), - Explicit(isExplicit), ImplicitlyDefined(false) { + Explicit(isExplicit), ImplicitlyDefined(false), + ImplicitMustBeDefined(false) { setImplicit(isImplicitlyDeclared); } @@ -679,6 +684,17 @@ public: ImplicitlyDefined = ID; } + /// isImplicitMustBeDefined - Whether a definition must be synthesized for + /// the implicit constructor. + bool isImplicitMustBeDefined() const { + return isImplicit() && ImplicitMustBeDefined; + } + + /// setImplicitMustBeDefined - constructor must be implicitly defined. + void setImplicitMustBeDefined() { + ImplicitMustBeDefined = true; + } + /// isDefaultConstructor - Whether this constructor is a default /// constructor (C++ [class.ctor]p5), which can be used to /// default-initialize a class of this type. @@ -1033,6 +1049,61 @@ public: } static bool classof(const NamespaceAliasDecl *D) { return true; } }; + +/// UsingDecl - Represents a C++ using-declaration. For example: +/// using someNameSpace::someIdentifier; +class UsingDecl : public NamedDecl { + + /// \brief The source range that covers the nested-name-specifier + /// preceding the declaration name. + SourceRange NestedNameRange; + /// \brief The source location of the target declaration name. + SourceLocation TargetNameLocation; + /// \brief The source location of the "using" location itself. + SourceLocation UsingLocation; + /// \brief Target declaration. + NamedDecl* TargetDecl; + /// \brief Target declaration. + NestedNameSpecifier* TargetNestedNameDecl; + + // Had 'typename' keyword. + bool IsTypeName; + + UsingDecl(DeclContext *DC, SourceLocation L, SourceRange NNR, + SourceLocation TargetNL, SourceLocation UL, NamedDecl* Target, + NestedNameSpecifier* TargetNNS, bool IsTypeNameArg) + : NamedDecl(Decl::Using, DC, L, Target->getDeclName()), + NestedNameRange(NNR), TargetNameLocation(TargetNL), + UsingLocation(UL), TargetDecl(Target), + TargetNestedNameDecl(TargetNNS), IsTypeName(IsTypeNameArg) { + this->IdentifierNamespace = TargetDecl->getIdentifierNamespace(); + } + +public: + /// \brief Returns the source range that covers the nested-name-specifier + /// preceding the namespace name. + SourceRange getNestedNameRange() { return(NestedNameRange); } + /// \brief Returns the source location of the target declaration name. + SourceLocation getTargetNameLocation() { return(TargetNameLocation); } + /// \brief Returns the source location of the "using" location itself. + SourceLocation getUsingLocation() { return(UsingLocation); } + /// \brief getTargetDecl - Returns target specified by using-decl. + NamedDecl *getTargetDecl() { return(TargetDecl); } + /// \brief Get target nested name declaration. + NestedNameSpecifier* getTargetNestedNameDecl() { return(TargetNestedNameDecl); } + /// isTypeName - Return true if using decl had 'typename'. + bool isTypeName() const { return(IsTypeName); } + + static UsingDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, SourceRange NNR, SourceLocation TargetNL, + SourceLocation UL, NamedDecl* Target, + NestedNameSpecifier* TargetNNS, bool IsTypeNameArg); + + static bool classof(const Decl *D) { + return D->getKind() == Decl::Using; + } + static bool classof(const UsingDecl *D) { return true; } +}; /// StaticAssertDecl - Represents a C++0x static_assert declaration. class StaticAssertDecl : public Decl { diff --git a/include/clang/AST/DeclNodes.def b/include/clang/AST/DeclNodes.def index d1b921a4cb65..1e4440357b65 100644 --- a/include/clang/AST/DeclNodes.def +++ b/include/clang/AST/DeclNodes.def @@ -108,6 +108,7 @@ ABSTRACT_DECL(Named, Decl) DECL(FunctionTemplate, TemplateDecl) DECL(ClassTemplate, TemplateDecl) DECL(TemplateTemplateParm, TemplateDecl) + DECL(Using, NamedDecl) DECL(ObjCMethod, NamedDecl) DECL(ObjCContainer, NamedDecl) DECL(ObjCCategory, ObjCContainerDecl) diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index a480f54394c6..af06965f84e9 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -18,6 +18,7 @@ #include "llvm/ADT/APSInt.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/PointerUnion.h" +#include <limits> namespace clang { @@ -404,6 +405,11 @@ class TemplateArgument { char Value[sizeof(llvm::APSInt)]; void *Type; } Integer; + struct { + TemplateArgument *Args; + unsigned NumArgs; + bool CopyArgs; + } Args; }; /// \brief Location of the beginning of this template argument. @@ -413,7 +419,7 @@ public: /// \brief The type of template argument we're storing. enum ArgKind { Null = 0, - /// The template argument is a type. It's value is stored in the + /// The template argument is a type. Its value is stored in the /// TypeOrValue field. Type = 1, /// The template argument is a declaration @@ -422,7 +428,11 @@ public: Integral = 3, /// The template argument is a value- or type-dependent expression /// stored in an Expr*. - Expression = 4 + Expression = 4, + + /// The template argument is actually a parameter pack. Arguments are stored + /// in the Args struct. + Pack = 5 } Kind; /// \brief Construct an empty, invalid template argument. @@ -459,11 +469,20 @@ public: /// occur in a non-dependent, canonical template argument list. TemplateArgument(Expr *E); + /// \brief Construct a template argument pack. + TemplateArgument(SourceLocation Loc, TemplateArgument *Args, + unsigned NumArgs, bool CopyArgs); + /// \brief Copy constructor for a template argument. TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) { if (Kind == Integral) { new (Integer.Value) llvm::APSInt(*Other.getAsIntegral()); Integer.Type = Other.Integer.Type; + } else if (Kind == Pack) { + Args.NumArgs = Other.Args.NumArgs; + Args.Args = new TemplateArgument[Args.NumArgs]; + for (unsigned I = 0; I != Args.NumArgs; ++I) + Args.Args[I] = Other.Args.Args[I]; } else TypeOrValue = Other.TypeOrValue; @@ -475,6 +494,10 @@ public: // safety. using llvm::APSInt; + // FIXME: Handle Packs + assert(Kind != Pack && "FIXME: Handle packs"); + assert(Other.Kind != Pack && "FIXME: Handle packs"); + if (Kind == Other.Kind && Kind == Integral) { // Copy integral values. *this->getAsIntegral() = *Other.getAsIntegral(); @@ -502,6 +525,8 @@ public: if (Kind == Integral) getAsIntegral()->~APSInt(); + else if (Kind == Pack && Args.CopyArgs) + delete[] Args.Args; } /// \brief Return the kind of stored template argument. @@ -586,34 +611,44 @@ public: // FIXME: We need a canonical representation of expressions. ID.AddPointer(getAsExpr()); break; + + case Pack: + ID.AddInteger(Args.NumArgs); + for (unsigned I = 0; I != Args.NumArgs; ++I) + Args.Args[I].Profile(ID); } } }; /// \brief A helper class for making template argument lists. class TemplateArgumentListBuilder { - /// Args - contains the template arguments. - llvm::SmallVector<TemplateArgument, 16> Args; + /// FlatArgs - contains the template arguments in flat form. + llvm::SmallVector<TemplateArgument, 16> FlatArgs; - llvm::SmallVector<unsigned, 32> Indices; + llvm::SmallVector<TemplateArgument, 16> StructuredArgs; ASTContext &Context; + unsigned PackBeginIndex; + /// isAddingFromParameterPack - Returns whether we're adding arguments from /// a parameter pack. - bool isAddingFromParameterPack() const { return Indices.size() % 2; } + bool isAddingFromParameterPack() const { + return PackBeginIndex != std::numeric_limits<unsigned>::max(); + } public: - TemplateArgumentListBuilder(ASTContext &Context) : Context(Context) { } + TemplateArgumentListBuilder(ASTContext &Context) : Context(Context), + PackBeginIndex(std::numeric_limits<unsigned>::max()) { } - size_t size() const { + size_t structuredSize() const { assert(!isAddingFromParameterPack() && "Size is not valid when adding from a parameter pack"); - return Indices.size() / 2; + return StructuredArgs.size(); } - size_t flatSize() const { return Args.size(); } + size_t flatSize() const { return FlatArgs.size(); } void push_back(const TemplateArgument& Arg); @@ -623,8 +658,12 @@ public: /// EndParameterPack - Finish adding arguments from a parameter pack. void EndParameterPack(); - const TemplateArgument *getFlatArgumentList() const { return Args.data(); } - TemplateArgument *getFlatArgumentList() { return Args.data(); } + const TemplateArgument *getFlatArgumentList() const { + return FlatArgs.data(); + } + TemplateArgument *getFlatArgumentList() { + return FlatArgs.data(); + } }; /// \brief A template argument list. @@ -657,13 +696,6 @@ public: } /// \brief Retrieve the template argument at a given index. - TemplateArgument &get(unsigned Idx) { - assert(Idx < NumArguments && "Invalid template argument index"); - return getFlatArgumentList()[Idx]; - } - - /// \brief Retrieve the template argument at a given index. - TemplateArgument &operator[](unsigned Idx) { return get(Idx); } const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); } /// \brief Retrieve the number of template arguments in this @@ -675,9 +707,6 @@ public: unsigned flat_size() const { return NumArguments; } /// \brief Retrieve the flattened template argument list. - TemplateArgument *getFlatArgumentList() { - return Arguments.getPointer(); - } const TemplateArgument *getFlatArgumentList() const { return Arguments.getPointer(); } diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 98de5f9d382e..2ed91124758d 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -124,7 +124,7 @@ public: /// with location to warn on and the source range[s] to report with the /// warning. bool isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, - SourceRange &R2) const; + SourceRange &R2, ASTContext &Context) const; /// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or /// incomplete type other than void. Nonarray expressions that can be lvalues: @@ -2463,10 +2463,13 @@ public: class BlockDeclRefExpr : public Expr { ValueDecl *D; SourceLocation Loc; - bool IsByRef; + bool IsByRef : 1; + bool ConstQualAdded : 1; public: - BlockDeclRefExpr(ValueDecl *d, QualType t, SourceLocation l, bool ByRef) : - Expr(BlockDeclRefExprClass, t), D(d), Loc(l), IsByRef(ByRef) {} + BlockDeclRefExpr(ValueDecl *d, QualType t, SourceLocation l, bool ByRef, + bool constAdded = false) : + Expr(BlockDeclRefExprClass, t), D(d), Loc(l), IsByRef(ByRef), + ConstQualAdded(constAdded) {} // \brief Build an empty reference to a declared variable in a // block. @@ -2484,6 +2487,9 @@ public: bool isByRef() const { return IsByRef; } void setByRef(bool BR) { IsByRef = BR; } + + bool isConstQualAdded() const { return ConstQualAdded; } + void setConstQualAdded(bool C) { ConstQualAdded = C; } static bool classof(const Stmt *T) { return T->getStmtClass() == BlockDeclRefExprClass; diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index e44ccca0bd74..f9f5da129142 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -1023,17 +1023,16 @@ class CXXExprWithTemporaries : public Expr { CXXTemporary **Temps; unsigned NumTemps; - bool DestroyTemps; + bool ShouldDestroyTemps; CXXExprWithTemporaries(Expr *SubExpr, CXXTemporary **Temps, - unsigned NumTemps, bool DestroyTemps); + unsigned NumTemps, bool ShouldDestroyTemps); ~CXXExprWithTemporaries(); public: static CXXExprWithTemporaries *Create(ASTContext &C, Expr *SubExpr, - CXXTemporary **Temps, - unsigned NumTemps, - bool DestroyTems); + CXXTemporary **Temps, unsigned NumTemps, + bool ShouldDestroyTemporaries); void Destroy(ASTContext &C); unsigned getNumTemporaries() const { return NumTemps; } @@ -1046,6 +1045,8 @@ public: return Temps[i]; } + bool shouldDestroyTemporaries() const { return ShouldDestroyTemps; } + void removeLastTemporary() { NumTemps--; } Expr *getSubExpr() { return cast<Expr>(SubExpr); } diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index ef78c4081e34..e00833b5820e 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -138,20 +138,20 @@ public: /// obj conformsToProtocol:@protocol(foo)] /// The return type is "Protocol*". class ObjCProtocolExpr : public Expr { - ObjCProtocolDecl *Protocol; + ObjCProtocolDecl *TheProtocol; SourceLocation AtLoc, RParenLoc; public: ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, SourceLocation at, SourceLocation rp) - : Expr(ObjCProtocolExprClass, T), Protocol(protocol), + : Expr(ObjCProtocolExprClass, T), TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {} explicit ObjCProtocolExpr(EmptyShell Empty) : Expr(ObjCProtocolExprClass, Empty) {} ObjCProtocolExpr *Clone(ASTContext &C) const; - ObjCProtocolDecl *getProtocol() const { return Protocol; } - void setProtocol(ObjCProtocolDecl *P) { Protocol = P; } + ObjCProtocolDecl *getProtocol() const { return TheProtocol; } + void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; } SourceLocation getAtLoc() const { return AtLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 1b012385c9f2..ca55ea670b24 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -393,6 +393,7 @@ public: bool isComplexIntegerType() const; // GCC _Complex integer type. bool isVectorType() const; // GCC vector type. bool isExtVectorType() const; // Extended vector type. + bool isObjCObjectPointerType() const; // Pointer to *any* ObjC object. bool isObjCInterfaceType() const; // NSString or NSString<foo> bool isObjCQualifiedInterfaceType() const; // NSString<foo> bool isObjCQualifiedIdType() const; // id<foo> @@ -439,9 +440,10 @@ public: const ComplexType *getAsComplexType() const; const ComplexType *getAsComplexIntegerType() const; // GCC complex int type. const ExtVectorType *getAsExtVectorType() const; // Extended vector type. + const ObjCObjectPointerType *getAsObjCObjectPointerType() const; const ObjCInterfaceType *getAsObjCInterfaceType() const; const ObjCQualifiedInterfaceType *getAsObjCQualifiedInterfaceType() const; - const ObjCQualifiedIdType *getAsObjCQualifiedIdType() const; + const ObjCObjectPointerType *getAsObjCQualifiedIdType() const; const TemplateTypeParmType *getAsTemplateTypeParmType() const; const TemplateSpecializationType * @@ -992,6 +994,41 @@ public: } }; +/// DependentSizedExtVectorType - This type represent an extended vector type +/// where either the type or size is dependent. For example: +/// @code +/// template<typename T, int Size> +/// class vector { +/// typedef T __attribute__((ext_vector_type(Size))) type; +/// } +/// @endcode +class DependentSizedExtVectorType : public Type { + Expr *SizeExpr; + /// ElementType - The element type of the array. + QualType ElementType; + SourceLocation loc; + + DependentSizedExtVectorType(QualType ElementType, QualType can, + Expr *SizeExpr, SourceLocation loc) + : Type (DependentSizedExtVector, can, true), + SizeExpr(SizeExpr), ElementType(ElementType), loc(loc) {} + friend class ASTContext; + virtual void Destroy(ASTContext& C); + +public: + const Expr *getSizeExpr() const { return SizeExpr; } + QualType getElementType() const { return ElementType; } + SourceLocation getAttributeLoc() const { return loc; } + + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + + static bool classof(const Type *T) { + return T->getTypeClass() == DependentSizedExtVector; + } + static bool classof(const DependentSizedExtVectorType *) { return true; } +}; + + /// VectorType - GCC generic vector type. This type is created using /// __attribute__((vector_size(n)), where "n" specifies the vector size in /// bytes. Since the constructor takes the number of vector elements, the @@ -1403,36 +1440,40 @@ public: }; class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { - unsigned Depth : 16; + unsigned Depth : 15; unsigned Index : 16; + unsigned ParameterPack : 1; IdentifierInfo *Name; - TemplateTypeParmType(unsigned D, unsigned I, IdentifierInfo *N, + TemplateTypeParmType(unsigned D, unsigned I, bool PP, IdentifierInfo *N, QualType Canon) : Type(TemplateTypeParm, Canon, /*Dependent=*/true), - Depth(D), Index(I), Name(N) { } + Depth(D), Index(I), ParameterPack(PP), Name(N) { } - TemplateTypeParmType(unsigned D, unsigned I) + TemplateTypeParmType(unsigned D, unsigned I, bool PP) : Type(TemplateTypeParm, QualType(this, 0), /*Dependent=*/true), - Depth(D), Index(I), Name(0) { } + Depth(D), Index(I), ParameterPack(PP), Name(0) { } friend class ASTContext; // ASTContext creates these public: unsigned getDepth() const { return Depth; } unsigned getIndex() const { return Index; } + bool isParameterPack() const { return ParameterPack; } IdentifierInfo *getName() const { return Name; } virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, Depth, Index, Name); + Profile(ID, Depth, Index, ParameterPack, Name); } static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth, - unsigned Index, IdentifierInfo *Name) { + unsigned Index, bool ParameterPack, + IdentifierInfo *Name) { ID.AddInteger(Depth); ID.AddInteger(Index); + ID.AddBoolean(ParameterPack); ID.AddPointer(Name); } @@ -1644,6 +1685,53 @@ public: static bool classof(const TypenameType *T) { return true; } }; +/// ObjCObjectPointerType - Used to represent 'id', 'Interface *', 'id <p>', +/// and 'Interface <p> *'. +/// +/// Duplicate protocols are removed and protocol list is canonicalized to be in +/// alphabetical order. +class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { + ObjCInterfaceDecl *Decl; + // List of protocols for this protocol conforming object type + // List is sorted on protocol name. No protocol is entered more than once. + llvm::SmallVector<ObjCProtocolDecl*, 8> Protocols; + + ObjCObjectPointerType(ObjCInterfaceDecl *D, + ObjCProtocolDecl **Protos, unsigned NumP) : + Type(ObjCObjectPointer, QualType(), /*Dependent=*/false), + Decl(D), Protocols(Protos, Protos+NumP) { } + friend class ASTContext; // ASTContext creates these. + +public: + ObjCInterfaceDecl *getDecl() const { return Decl; } + + /// isObjCQualifiedIdType - true for "id <p>". + bool isObjCQualifiedIdType() const { return Decl == 0 && Protocols.size(); } + + /// qual_iterator and friends: this provides access to the (potentially empty) + /// list of protocols qualifying this interface. + typedef llvm::SmallVector<ObjCProtocolDecl*, 8>::const_iterator qual_iterator; + + qual_iterator qual_begin() const { return Protocols.begin(); } + qual_iterator qual_end() const { return Protocols.end(); } + bool qual_empty() const { return Protocols.size() == 0; } + + /// getNumProtocols - Return the number of qualifying protocols in this + /// interface type, or 0 if there are none. + unsigned getNumProtocols() const { return Protocols.size(); } + + void Profile(llvm::FoldingSetNodeID &ID); + static void Profile(llvm::FoldingSetNodeID &ID, + const ObjCInterfaceDecl *Decl, + ObjCProtocolDecl **protocols, unsigned NumProtocols); + virtual void getAsStringInternal(std::string &InnerString, + const PrintingPolicy &Policy) const; + static bool classof(const Type *T) { + return T->getTypeClass() == ObjCObjectPointer; + } + static bool classof(const ObjCObjectPointerType *) { return true; } +}; + /// ObjCInterfaceType - Interfaces are the core concept in Objective-C for /// object oriented design. They basically correspond to C++ classes. There /// are two kinds of interface types, normal interfaces like "NSString" and @@ -1742,44 +1830,6 @@ inline unsigned ObjCInterfaceType::getNumProtocols() const { return 0; } -/// ObjCQualifiedIdType - to represent id<protocol-list>. -/// -/// Duplicate protocols are removed and protocol list is canonicalized to be in -/// alphabetical order. -class ObjCQualifiedIdType : public Type, - public llvm::FoldingSetNode { - // List of protocols for this protocol conforming 'id' type - // List is sorted on protocol name. No protocol is enterred more than once. - llvm::SmallVector<ObjCProtocolDecl*, 8> Protocols; - - ObjCQualifiedIdType(ObjCProtocolDecl **Protos, unsigned NumP) - : Type(ObjCQualifiedId, QualType()/*these are always canonical*/, - /*Dependent=*/false), - Protocols(Protos, Protos+NumP) { } - friend class ASTContext; // ASTContext creates these. -public: - - unsigned getNumProtocols() const { - return Protocols.size(); - } - - typedef llvm::SmallVector<ObjCProtocolDecl*, 8>::const_iterator qual_iterator; - qual_iterator qual_begin() const { return Protocols.begin(); } - qual_iterator qual_end() const { return Protocols.end(); } - - virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; - - void Profile(llvm::FoldingSetNodeID &ID); - static void Profile(llvm::FoldingSetNodeID &ID, - ObjCProtocolDecl **protocols, unsigned NumProtocols); - - static bool classof(const Type *T) { - return T->getTypeClass() == ObjCQualifiedId; - } - static bool classof(const ObjCQualifiedIdType *) { return true; } - -}; - // Inline function definitions. /// getUnqualifiedType - Return the type without any qualifiers. @@ -1926,6 +1976,9 @@ inline bool Type::isVectorType() const { inline bool Type::isExtVectorType() const { return isa<ExtVectorType>(CanonicalType.getUnqualifiedType()); } +inline bool Type::isObjCObjectPointerType() const { + return isa<ObjCObjectPointerType>(CanonicalType.getUnqualifiedType()); +} inline bool Type::isObjCInterfaceType() const { return isa<ObjCInterfaceType>(CanonicalType.getUnqualifiedType()); } @@ -1933,7 +1986,10 @@ inline bool Type::isObjCQualifiedInterfaceType() const { return isa<ObjCQualifiedInterfaceType>(CanonicalType.getUnqualifiedType()); } inline bool Type::isObjCQualifiedIdType() const { - return isa<ObjCQualifiedIdType>(CanonicalType.getUnqualifiedType()); + if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType()) { + return OPT->isObjCQualifiedIdType(); + } + return false; } inline bool Type::isTemplateTypeParmType() const { return isa<TemplateTypeParmType>(CanonicalType.getUnqualifiedType()); diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def index 76cbed311d79..5555a9b0ae7e 100644 --- a/include/clang/AST/TypeNodes.def +++ b/include/clang/AST/TypeNodes.def @@ -60,6 +60,7 @@ TYPE(ConstantArray, ArrayType) TYPE(IncompleteArray, ArrayType) TYPE(VariableArray, ArrayType) DEPENDENT_TYPE(DependentSizedArray, ArrayType) +DEPENDENT_TYPE(DependentSizedExtVector, Type) TYPE(Vector, Type) TYPE(ExtVector, VectorType) ABSTRACT_TYPE(Function, Type) @@ -76,8 +77,8 @@ TYPE(TemplateSpecialization, Type) NON_CANONICAL_TYPE(QualifiedName, Type) DEPENDENT_TYPE(Typename, Type) TYPE(ObjCInterface, Type) +TYPE(ObjCObjectPointer, Type) TYPE(ObjCQualifiedInterface, ObjCInterfaceType) -TYPE(ObjCQualifiedId, Type) #undef DEPENDENT_TYPE #undef NON_CANONICAL_TYPE diff --git a/include/clang/AST/TypeVisitor.h b/include/clang/AST/TypeVisitor.h new file mode 100644 index 000000000000..a02e39b3f34e --- /dev/null +++ b/include/clang/AST/TypeVisitor.h @@ -0,0 +1,50 @@ +//===--- TypeVisitor.h - Visitor for Stmt subclasses ------------*- 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 TypeVisitor interface. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_TYPEVISITOR_H +#define LLVM_CLANG_AST_TYPEVISITOR_H + +#include "clang/AST/Type.h" + +namespace clang { + +#define DISPATCH(CLASS) \ + return static_cast<ImplClass*>(this)->Visit ## CLASS(static_cast<CLASS*>(T)) + +template<typename ImplClass, typename RetTy=void> +class TypeVisitor { +public: + RetTy Visit(Type *T) { + // Top switch stmt: dispatch to VisitFooStmt for each FooStmt. + switch (T->getTypeClass()) { + default: assert(0 && "Unknown type class!"); +#define ABSTRACT_TYPE(CLASS, PARENT) +#define TYPE(CLASS, PARENT) case Type::CLASS: DISPATCH(CLASS##Type); +#include "clang/AST/TypeNodes.def" + } + } + + // If the implementation chooses not to implement a certain visit method, fall + // back on superclass. +#define TYPE(CLASS, PARENT) RetTy Visit##CLASS##Type(CLASS##Type *T) { DISPATCH(PARENT); } +#include "clang/AST/TypeNodes.def" + + // Base case, ignore it. :) + RetTy VisitType(Type*) { return RetTy(); } +}; + +#undef DISPATCH + +} // end namespace clang + +#endif diff --git a/include/clang/Analysis/PathSensitive/ConstraintManager.h b/include/clang/Analysis/PathSensitive/ConstraintManager.h index c8e5e85c8a1a..eb519e0e7431 100644 --- a/include/clang/Analysis/PathSensitive/ConstraintManager.h +++ b/include/clang/Analysis/PathSensitive/ConstraintManager.h @@ -30,26 +30,25 @@ class SVal; class ConstraintManager { public: virtual ~ConstraintManager(); - virtual const GRState* Assume(const GRState* St, SVal Cond, - bool Assumption, bool& isFeasible) = 0; + virtual const GRState *Assume(const GRState *state, SVal Cond, + bool Assumption) = 0; - virtual const GRState* AssumeInBound(const GRState* St, SVal Idx, - SVal UpperBound, bool Assumption, - bool& isFeasible) = 0; + virtual const GRState *AssumeInBound(const GRState *state, SVal Idx, + SVal UpperBound, bool Assumption) = 0; - virtual const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym) - const = 0; + virtual const llvm::APSInt* getSymVal(const GRState *state, + SymbolRef sym) const = 0; - virtual bool isEqual(const GRState* St, SymbolRef sym, + virtual bool isEqual(const GRState *state, SymbolRef sym, const llvm::APSInt& V) const = 0; - virtual const GRState* RemoveDeadBindings(const GRState* St, + virtual const GRState *RemoveDeadBindings(const GRState *state, SymbolReaper& SymReaper) = 0; - virtual void print(const GRState* St, std::ostream& Out, + virtual void print(const GRState *state, std::ostream& Out, const char* nl, const char *sep) = 0; - virtual void EndPath(const GRState* St) {} + virtual void EndPath(const GRState *state) {} /// canReasonAbout - Not all ConstraintManagers can accurately reason about /// all SVal values. This method returns true if the ConstraintManager can diff --git a/include/clang/Analysis/PathSensitive/Environment.h b/include/clang/Analysis/PathSensitive/Environment.h index fde8b167f3c7..0fc49f5a586e 100644 --- a/include/clang/Analysis/PathSensitive/Environment.h +++ b/include/clang/Analysis/PathSensitive/Environment.h @@ -30,13 +30,12 @@ class EnvironmentManager; class BasicValueFactory; class LiveVariables; -class Environment : public llvm::FoldingSetNode { +class Environment { private: - friend class EnvironmentManager; // Type definitions. - typedef llvm::ImmutableMap<Stmt*,SVal> BindingsTy; + typedef llvm::ImmutableMap<const Stmt*,SVal> BindingsTy; // Data. BindingsTy SubExprBindings; @@ -55,25 +54,25 @@ public: beb_iterator beb_begin() const { return BlkExprBindings.begin(); } beb_iterator beb_end() const { return BlkExprBindings.end(); } - SVal LookupSubExpr(Stmt* E) const { + SVal LookupSubExpr(const Stmt* E) const { const SVal* X = SubExprBindings.lookup(cast<Expr>(E)); return X ? *X : UnknownVal(); } - SVal LookupBlkExpr(Stmt* E) const { + SVal LookupBlkExpr(const Stmt* E) const { const SVal* X = BlkExprBindings.lookup(E); return X ? *X : UnknownVal(); } - SVal LookupExpr(Stmt* E) const { + SVal LookupExpr(const Stmt* E) const { const SVal* X = SubExprBindings.lookup(E); if (X) return *X; X = BlkExprBindings.lookup(E); return X ? *X : UnknownVal(); } - SVal GetSVal(Stmt* Ex, BasicValueFactory& BasicVals) const; - SVal GetBlkExprSVal(Stmt* Ex, BasicValueFactory& BasicVals) const; + SVal GetSVal(const Stmt* Ex, BasicValueFactory& BasicVals) const; + SVal GetBlkExprSVal(const Stmt* Ex, BasicValueFactory& BasicVals) const; /// Profile - Profile the contents of an Environment object for use /// in a FoldingSet. @@ -109,19 +108,19 @@ public: /// removed. This method only removes bindings for block-level expressions. /// Using this method on a non-block level expression will return the /// same environment object. - Environment RemoveBlkExpr(const Environment& Env, Stmt* E) { + Environment RemoveBlkExpr(const Environment& Env, const Stmt* E) { return Environment(Env.SubExprBindings, F.Remove(Env.BlkExprBindings, E)); } - Environment RemoveSubExpr(const Environment& Env, Stmt* E) { + Environment RemoveSubExpr(const Environment& Env, const Stmt* E) { return Environment(F.Remove(Env.SubExprBindings, E), Env.BlkExprBindings); } - Environment AddBlkExpr(const Environment& Env, Stmt* E, SVal V) { + Environment AddBlkExpr(const Environment& Env, const Stmt *E, SVal V) { return Environment(Env.SubExprBindings, F.Add(Env.BlkExprBindings, E, V)); } - Environment AddSubExpr(const Environment& Env, Stmt* E, SVal V) { + Environment AddSubExpr(const Environment& Env, const Stmt *E, SVal V) { return Environment(F.Add(Env.SubExprBindings, E, V), Env.BlkExprBindings); } @@ -136,7 +135,7 @@ public: return Environment(F.GetEmptyMap(), F.GetEmptyMap()); } - Environment BindExpr(const Environment& Env, Stmt* E, SVal V, + Environment BindExpr(const Environment& Env, const Stmt* E, SVal V, bool isBlkExpr, bool Invalidate); Environment diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 2068b1beaa13..4af8a7c845a7 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -477,67 +477,14 @@ public: const SymbolManager& getSymbolManager() const { return SymMgr; } protected: - const GRState* GetState(NodeTy* N) { return N == EntryNode ? CleanedState : N->getState(); } -public: - - const GRState* BindExpr(const GRState* St, Expr* Ex, SVal V) { - return StateMgr.BindExpr(St, Ex, V); - } - - const GRState* BindExpr(const GRState* St, const Expr* Ex, SVal V) { - return BindExpr(St, const_cast<Expr*>(Ex), V); - } - -protected: - - const GRState* BindBlkExpr(const GRState* St, Expr* Ex, SVal V) { - return StateMgr.BindExpr(St, Ex, V, true, false); - } - - const GRState* BindLoc(const GRState* St, Loc LV, SVal V) { - return StateMgr.BindLoc(St, LV, V); - } - - SVal GetSVal(const GRState* St, Stmt* Ex) { - return StateMgr.GetSVal(St, Ex); - } - - SVal GetSVal(const GRState* St, const Stmt* Ex) { - return GetSVal(St, const_cast<Stmt*>(Ex)); - } - - SVal GetBlkExprSVal(const GRState* St, Stmt* Ex) { - return StateMgr.GetBlkExprSVal(St, Ex); - } - - SVal GetSVal(const GRState* St, Loc LV, QualType T = QualType()) { - return StateMgr.GetSVal(St, LV, T); - } - +public: inline NonLoc MakeConstantVal(uint64_t X, Expr* Ex) { return NonLoc::MakeVal(getBasicVals(), X, Ex->getType()); - } - - /// Assume - Create new state by assuming that a given expression - /// is true or false. - const GRState* Assume(const GRState* St, SVal Cond, bool Assumption, - bool& isFeasible) { - return StateMgr.Assume(St, Cond, Assumption, isFeasible); - } - - const GRState* Assume(const GRState* St, Loc Cond, bool Assumption, - bool& isFeasible) { - return StateMgr.Assume(St, Cond, Assumption, isFeasible); - } - - const GRState* AssumeInBound(const GRState* St, SVal Idx, SVal UpperBound, - bool Assumption, bool& isFeasible) { - return StateMgr.AssumeInBound(St, Idx, UpperBound, Assumption, isFeasible); - } + } public: NodeTy* MakeNode(NodeSet& Dst, Stmt* S, NodeTy* Pred, const GRState* St, diff --git a/include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h b/include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h index 6c23745de23a..0f3a1372a0f0 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h @@ -83,11 +83,9 @@ public: Dst.Add(Pred); } } - - GRStateRef getState() { - return GRStateRef(state, Eng.getStateManager()); - } + const GRState *getState() { return state; } + GRStateManager& getStateManager() { return Eng.getStateManager(); } diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index d61feea4819e..6f95c6ff4ab0 100644 --- a/include/clang/Analysis/PathSensitive/GRState.h +++ b/include/clang/Analysis/PathSensitive/GRState.h @@ -64,6 +64,8 @@ template <typename T> struct GRStateTrait { //===----------------------------------------------------------------------===// // GRState- An ImmutableMap type Stmt*/Decl*/Symbols to SVals. //===----------------------------------------------------------------------===// + +class GRStateManager; /// GRState - This class encapsulates the actual data values for /// for a "state" in our symbolic value tracking. It is intended to be @@ -81,7 +83,8 @@ private: void operator=(const GRState& R) const; friend class GRStateManager; - + + GRStateManager *Mgr; Environment Env; Store St; @@ -92,8 +95,10 @@ public: public: /// This ctor is used when creating the first GRState object. - GRState(const Environment& env, Store st, GenericDataMap gdm) - : Env(env), + GRState(GRStateManager *mgr, const Environment& env, Store st, + GenericDataMap gdm) + : Mgr(mgr), + Env(env), St(st), GDM(gdm) {} @@ -101,10 +106,14 @@ public: /// in FoldingSetNode will also get copied. GRState(const GRState& RHS) : llvm::FoldingSetNode(), + Mgr(RHS.Mgr), Env(RHS.Env), St(RHS.St), GDM(RHS.GDM) {} + /// getStateManager - Return the GRStateManager associated with this state. + GRStateManager &getStateManager() const { return *Mgr; } + /// getEnvironment - Return the environment associated with this state. /// The environment is the mapping from expressions to values. const Environment& getEnvironment() const { return Env; } @@ -134,6 +143,10 @@ public: return Env.LookupExpr(E); } + /// makeWithStore - Return a GRState with the same values as the current + /// state with the exception of using the specified Store. + const GRState *makeWithStore(Store store) const; + // Iterators. typedef Environment::seb_iterator seb_iterator; seb_iterator seb_begin() const { return Env.seb_begin(); } @@ -142,10 +155,119 @@ public: typedef Environment::beb_iterator beb_iterator; beb_iterator beb_begin() const { return Env.beb_begin(); } beb_iterator beb_end() const { return Env.beb_end(); } + + BasicValueFactory &getBasicVals() const; + SymbolManager &getSymbolManager() const; + GRTransferFuncs &getTransferFuncs() const; + + //==---------------------------------------------------------------------==// + // Constraints on values. + //==---------------------------------------------------------------------==// + // + // Each GRState records constraints on symbolic values. These constraints + // are managed using the ConstraintManager associated with a GRStateManager. + // As constraints gradually accrue on symbolic values, added constraints + // may conflict and indicate that a state is infeasible (as no real values + // could satisfy all the constraints). This is the principal mechanism + // for modeling path-sensitivity in GRExprEngine/GRState. + // + // Various "Assume" methods form the interface for adding constraints to + // symbolic values. A call to "Assume" indicates an assumption being placed + // on one or symbolic values. Assume methods take the following inputs: + // + // (1) A GRState object representing the current state. + // + // (2) The assumed constraint (which is specific to a given "Assume" method). + // + // (3) A binary value "Assumption" that indicates whether the constraint is + // assumed to be true or false. + // + // The output of "Assume" are two values: + // + // (a) "isFeasible" is set to true or false to indicate whether or not + // the assumption is feasible. + // + // (b) A new GRState object with the added constraints. + // + // FIXME: (a) should probably disappear since it is redundant with (b). + // (i.e., (b) could just be set to NULL). + // + + const GRState *assume(SVal condition, bool assumption) const; + + const GRState *assumeInBound(SVal idx, SVal upperBound, + bool assumption) const; + + //==---------------------------------------------------------------------==// + // Binding and retrieving values to/from the environment and symbolic store. + //==---------------------------------------------------------------------==// + + /// BindCompoundLiteral - Return the state that has the bindings currently + /// in 'state' plus the bindings for the CompoundLiteral. 'R' is the region + /// for the compound literal and 'BegInit' and 'EndInit' represent an + /// array of initializer values. + const GRState* bindCompoundLiteral(const CompoundLiteralExpr* CL, + SVal V) const; + + const GRState *bindExpr(const Stmt* Ex, SVal V, bool isBlkExpr, + bool Invalidate) const; + + const GRState *bindExpr(const Stmt* Ex, SVal V, bool Invalidate = true) const; + + const GRState *bindBlkExpr(const Stmt *Ex, SVal V) const { + return bindExpr(Ex, V, true, false); + } + + const GRState *bindLoc(Loc location, SVal V) const; + + const GRState *bindLoc(SVal location, SVal V) const; + + const GRState *unbindLoc(Loc LV) const; + + /// Get the lvalue for a variable reference. + SVal getLValue(const VarDecl *decl) const; + + /// Get the lvalue for a StringLiteral. + SVal getLValue(const StringLiteral *literal) const; + + SVal getLValue(const CompoundLiteralExpr *literal) const; + + /// Get the lvalue for an ivar reference. + SVal getLValue(const ObjCIvarDecl *decl, SVal base) const; + + /// Get the lvalue for a field reference. + SVal getLValue(SVal Base, const FieldDecl *decl) const; + + /// Get the lvalue for an array index. + SVal getLValue(QualType ElementType, SVal Base, SVal Idx) const; + + const llvm::APSInt *getSymVal(SymbolRef sym) const; + + SVal getSVal(const Stmt* Ex) const; + + SVal getBlkExprSVal(const Stmt* Ex) const; + + SVal getSValAsScalarOrLoc(const Stmt *Ex) const; + + SVal getSVal(Loc LV, QualType T = QualType()) const; + + SVal getSVal(const MemRegion* R) const; + + SVal getSValAsScalarOrLoc(const MemRegion *R) const; + + bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const; + + template <typename CB> CB scanReachableSymbols(SVal val) const; + + //==---------------------------------------------------------------------==// + // Accessing the Generic Data Map (GDM). + //==---------------------------------------------------------------------==// - // Trait based GDM dispatch. void* const* FindGDM(void* K) const; + template<typename T> + const GRState *add(typename GRStateTrait<T>::key_type K) const; + template <typename T> typename GRStateTrait<T>::data_type get() const { @@ -159,6 +281,29 @@ public: return GRStateTrait<T>::Lookup(GRStateTrait<T>::MakeData(d), key); } + template <typename T> + typename GRStateTrait<T>::context_type get_context() const; + + + template<typename T> + const GRState *remove(typename GRStateTrait<T>::key_type K) const; + + template<typename T> + const GRState *remove(typename GRStateTrait<T>::key_type K, + typename GRStateTrait<T>::context_type C) const; + + template<typename T> + const GRState *set(typename GRStateTrait<T>::data_type D) const; + + template<typename T> + const GRState *set(typename GRStateTrait<T>::key_type K, + typename GRStateTrait<T>::value_type E) const; + + template<typename T> + const GRState *set(typename GRStateTrait<T>::key_type K, + typename GRStateTrait<T>::value_type E, + typename GRStateTrait<T>::context_type C) const; + template<typename T> bool contains(typename GRStateTrait<T>::key_type key) const { void* const* d = FindGDM(GRStateTrait<T>::GDMIndex()); @@ -172,11 +317,14 @@ public: virtual void Print(std::ostream& Out, const GRState* state, const char* nl, const char* sep) = 0; }; + + // Pretty-printing. + void print(std::ostream& Out, const char *nl = "\n", + const char *sep = "") const; - void print(std::ostream& Out, StoreManager& StoreMgr, - ConstraintManager& ConstraintMgr, - Printer **Beg = 0, Printer **End = 0, - const char* nl = "\n", const char *sep = "") const; + void printStdErr() const; + + void printDOT(std::ostream& Out) const; // Tags used for the Generic Data Map. struct NullDerefTag { @@ -233,11 +381,9 @@ public: // GRStateManager - Factory object for GRStates. //===----------------------------------------------------------------------===// -class GRStateRef; - class GRStateManager { friend class GRExprEngine; - friend class GRStateRef; + friend class GRState; private: EnvironmentManager EnvMgr; @@ -361,15 +507,6 @@ public: // Store manager should return a persistent state. return StoreMgr->BindDeclWithNoInit(St, VD); } - - /// BindCompoundLiteral - Return the state that has the bindings currently - /// in 'state' plus the bindings for the CompoundLiteral. 'R' is the region - /// for the compound literal and 'BegInit' and 'EndInit' represent an - /// array of initializer values. - const GRState* BindCompoundLiteral(const GRState* St, - const CompoundLiteralExpr* CL, SVal V) { - return StoreMgr->BindCompoundLiteral(St, CL, V); - } const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc, SymbolReaper& SymReaper); @@ -391,38 +528,10 @@ public: return StoreMgr->getSelfRegion(state->getStore()); } - // Get the lvalue for a variable reference. - SVal GetLValue(const GRState* St, const VarDecl* D) { - return StoreMgr->getLValueVar(St, D); - } - - // Get the lvalue for a StringLiteral. - SVal GetLValue(const GRState* St, const StringLiteral* E) { - return StoreMgr->getLValueString(St, E); - } - - SVal GetLValue(const GRState* St, const CompoundLiteralExpr* CL) { - return StoreMgr->getLValueCompoundLiteral(St, CL); - } - - // Get the lvalue for an ivar reference. - SVal GetLValue(const GRState* St, const ObjCIvarDecl* D, SVal Base) { - return StoreMgr->getLValueIvar(St, D, Base); - } - - // Get the lvalue for a field reference. - SVal GetLValue(const GRState* St, SVal Base, const FieldDecl* D) { - return StoreMgr->getLValueField(St, Base, D); - } - - // Get the lvalue for an array index. - SVal GetLValue(const GRState* St, QualType ElementType, SVal Base, SVal Idx) { - return StoreMgr->getLValueElement(St, ElementType, Base, Idx); - } +private: - // Methods that query & manipulate the Environment. - - SVal GetSVal(const GRState* St, Stmt* Ex) { + // Methods that query & manipulate the Environment. + SVal GetSVal(const GRState* St, const Stmt* Ex) { return St->getEnvironment().GetSVal(Ex, getBasicVals()); } @@ -435,19 +544,12 @@ public: return UnknownVal(); } - - SVal GetSVal(const GRState* St, const Stmt* Ex) { - return St->getEnvironment().GetSVal(const_cast<Stmt*>(Ex), getBasicVals()); - } - - SVal GetBlkExprSVal(const GRState* St, Stmt* Ex) { + SVal GetBlkExprSVal(const GRState* St, const Stmt* Ex) { return St->getEnvironment().GetBlkExprSVal(Ex, getBasicVals()); } - - - const GRState* BindExpr(const GRState* St, Stmt* Ex, SVal V, + const GRState* BindExpr(const GRState* St, const Stmt* Ex, SVal V, bool isBlkExpr, bool Invalidate) { const Environment& OldEnv = St->getEnvironment(); @@ -461,7 +563,7 @@ public: return getPersistentState(NewSt); } - const GRState* BindExpr(const GRState* St, Stmt* Ex, SVal V, + const GRState* BindExpr(const GRState* St, const Stmt* Ex, SVal V, bool Invalidate = true) { bool isBlkExpr = false; @@ -478,6 +580,8 @@ public: return BindExpr(St, Ex, V, isBlkExpr, Invalidate); } +public: + SVal ArrayToPointer(Loc Array) { return StoreMgr->ArrayToPointer(Array); } @@ -533,13 +637,9 @@ public: const GRState* getPersistentState(GRState& Impl); - // MakeStateWithStore - get a persistent state with the new store. - const GRState* MakeStateWithStore(const GRState* St, Store store); - bool isEqual(const GRState* state, Expr* Ex, const llvm::APSInt& V); bool isEqual(const GRState* state, Expr* Ex, uint64_t); - //==---------------------------------------------------------------------==// // Generic Data Map methods. //==---------------------------------------------------------------------==// @@ -605,56 +705,6 @@ public: return GRStateTrait<T>::MakeContext(p); } - - //==---------------------------------------------------------------------==// - // Constraints on values. - //==---------------------------------------------------------------------==// - // - // Each GRState records constraints on symbolic values. These constraints - // are managed using the ConstraintManager associated with a GRStateManager. - // As constraints gradually accrue on symbolic values, added constraints - // may conflict and indicate that a state is infeasible (as no real values - // could satisfy all the constraints). This is the principal mechanism - // for modeling path-sensitivity in GRExprEngine/GRState. - // - // Various "Assume" methods form the interface for adding constraints to - // symbolic values. A call to "Assume" indicates an assumption being placed - // on one or symbolic values. Assume methods take the following inputs: - // - // (1) A GRState object representing the current state. - // - // (2) The assumed constraint (which is specific to a given "Assume" method). - // - // (3) A binary value "Assumption" that indicates whether the constraint is - // assumed to be true or false. - // - // The output of "Assume" are two values: - // - // (a) "isFeasible" is set to true or false to indicate whether or not - // the assumption is feasible. - // - // (b) A new GRState object with the added constraints. - // - // FIXME: (a) should probably disappear since it is redundant with (b). - // (i.e., (b) could just be set to NULL). - // - - const GRState* Assume(const GRState* St, SVal Cond, bool Assumption, - bool& isFeasible) { - const GRState *state = - ConstraintMgr->Assume(St, Cond, Assumption, isFeasible); - assert(!isFeasible || state); - return isFeasible ? state : NULL; - } - - const GRState* AssumeInBound(const GRState* St, SVal Idx, SVal UpperBound, - bool Assumption, bool& isFeasible) { - const GRState *state = - ConstraintMgr->AssumeInBound(St, Idx, UpperBound, Assumption, - isFeasible); - assert(!isFeasible || state); - return isFeasible ? state : NULL; - } const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym) { return ConstraintMgr->getSymVal(St, sym); @@ -663,157 +713,158 @@ public: void EndPath(const GRState* St) { ConstraintMgr->EndPath(St); } - - bool scanReachableSymbols(SVal val, const GRState* state, - SymbolVisitor& visitor); }; + //===----------------------------------------------------------------------===// -// GRStateRef - A "fat" reference to GRState that also bundles GRStateManager. +// Out-of-line method definitions for GRState. //===----------------------------------------------------------------------===// - -class GRStateRef { - const GRState* St; - GRStateManager* Mgr; -public: - GRStateRef(const GRState* st, GRStateManager& mgr) : St(st), Mgr(&mgr) {} - - const GRState* getState() const { return St; } - operator const GRState*() const { return St; } - GRStateManager& getManager() const { return *Mgr; } - - SVal GetSVal(Expr* Ex) { - return Mgr->GetSVal(St, Ex); - } - - SVal GetBlkExprSVal(Expr* Ex) { - return Mgr->GetBlkExprSVal(St, Ex); - } - - SVal GetSValAsScalarOrLoc(const Expr *Ex) { - return Mgr->GetSValAsScalarOrLoc(St, Ex); - } - - SVal GetSVal(Loc LV, QualType T = QualType()) { - return Mgr->GetSVal(St, LV, T); - } - - SVal GetSVal(const MemRegion* R) { - return Mgr->GetSVal(St, R); - } - - SVal GetSValAsScalarOrLoc(const MemRegion *R) { - return Mgr->GetSValAsScalarOrLoc(St, R); - } - - GRStateRef BindExpr(Stmt* Ex, SVal V, bool isBlkExpr, bool Invalidate) { - return GRStateRef(Mgr->BindExpr(St, Ex, V, isBlkExpr, Invalidate), *Mgr); - } - - GRStateRef BindExpr(Stmt* Ex, SVal V, bool Invalidate = true) { - return GRStateRef(Mgr->BindExpr(St, Ex, V, Invalidate), *Mgr); - } - - GRStateRef BindDecl(const VarDecl* VD, SVal InitVal) { - return GRStateRef(Mgr->BindDecl(St, VD, InitVal), *Mgr); - } - - GRStateRef BindLoc(Loc LV, SVal V) { - return GRStateRef(Mgr->BindLoc(St, LV, V), *Mgr); - } - - GRStateRef BindLoc(SVal LV, SVal V) { - if (!isa<Loc>(LV)) return *this; - return BindLoc(cast<Loc>(LV), V); - } - - GRStateRef Unbind(Loc LV) { - return GRStateRef(Mgr->Unbind(St, LV), *Mgr); - } - - // Trait based GDM dispatch. - template<typename T> - typename GRStateTrait<T>::data_type get() const { - return St->get<T>(); - } - - template<typename T> - typename GRStateTrait<T>::lookup_type - get(typename GRStateTrait<T>::key_type key) const { - return St->get<T>(key); - } - - template<typename T> - GRStateRef set(typename GRStateTrait<T>::data_type D) { - return GRStateRef(Mgr->set<T>(St, D), *Mgr); - } - template <typename T> - typename GRStateTrait<T>::context_type get_context() { - return Mgr->get_context<T>(); - } - - template<typename T> - GRStateRef set(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::value_type E, - typename GRStateTrait<T>::context_type C) { - return GRStateRef(Mgr->set<T>(St, K, E, C), *Mgr); - } - - template<typename T> - GRStateRef set(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::value_type E) { - return GRStateRef(Mgr->set<T>(St, K, E, get_context<T>()), *Mgr); - } - - template<typename T> - GRStateRef add(typename GRStateTrait<T>::key_type K) { - return GRStateRef(Mgr->add<T>(St, K, get_context<T>()), *Mgr); - } - - template<typename T> - GRStateRef remove(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::context_type C) { - return GRStateRef(Mgr->remove<T>(St, K, C), *Mgr); - } - - template<typename T> - GRStateRef remove(typename GRStateTrait<T>::key_type K) { - return GRStateRef(Mgr->remove<T>(St, K, get_context<T>()), *Mgr); - } - - template<typename T> - bool contains(typename GRStateTrait<T>::key_type key) const { - return St->contains<T>(key); - } - - // Lvalue methods. - SVal GetLValue(const VarDecl* VD) { - return Mgr->GetLValue(St, VD); - } - - GRStateRef Assume(SVal Cond, bool Assumption, bool& isFeasible) { - return GRStateRef(Mgr->Assume(St, Cond, Assumption, isFeasible), *Mgr); - } - - template <typename CB> - CB scanReachableSymbols(SVal val) { - CB cb(*this); - Mgr->scanReachableSymbols(val, St, cb); - return cb; - } - - SymbolManager& getSymbolManager() { return Mgr->getSymbolManager(); } - BasicValueFactory& getBasicVals() { return Mgr->getBasicVals(); } - - // Pretty-printing. - void print(std::ostream& Out, const char* nl = "\n", - const char *sep = "") const; - - void printStdErr() const; - - void printDOT(std::ostream& Out) const; -}; +inline const GRState *GRState::assume(SVal Cond, bool Assumption) const { + return Mgr->ConstraintMgr->Assume(this, Cond, Assumption); +} + +inline const GRState *GRState::assumeInBound(SVal Idx, SVal UpperBound, + bool Assumption) const { + return Mgr->ConstraintMgr->AssumeInBound(this, Idx, UpperBound, Assumption); +} + +inline const GRState *GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL, + SVal V) const { + 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::bindExpr(const Stmt* Ex, SVal V, + bool Invalidate) const { + return Mgr->BindExpr(this, Ex, V, Invalidate); +} + +inline const GRState *GRState::bindLoc(Loc LV, SVal V) const { + return Mgr->BindLoc(this, LV, V); +} + +inline const GRState *GRState::bindLoc(SVal LV, SVal V) const { + return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V); +} + +inline SVal GRState::getLValue(const VarDecl* VD) const { + return Mgr->StoreMgr->getLValueVar(this, VD); +} + +inline SVal GRState::getLValue(const StringLiteral *literal) const { + return Mgr->StoreMgr->getLValueString(this, literal); +} + +inline SVal GRState::getLValue(const CompoundLiteralExpr *literal) const { + return Mgr->StoreMgr->getLValueCompoundLiteral(this, literal); +} + +inline SVal GRState::getLValue(const ObjCIvarDecl *D, SVal Base) const { + return Mgr->StoreMgr->getLValueIvar(this, D, Base); +} + +inline SVal GRState::getLValue(SVal Base, const FieldDecl* D) const { + return Mgr->StoreMgr->getLValueField(this, Base, D); +} + +inline SVal GRState::getLValue(QualType ElementType, SVal Base, SVal Idx) const{ + return Mgr->StoreMgr->getLValueElement(this, ElementType, Base, Idx); +} + +inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) const { + return Mgr->getSymVal(this, sym); +} + +inline SVal GRState::getSVal(const Stmt* Ex) const { + return Mgr->GetSVal(this, Ex); +} + +inline SVal GRState::getBlkExprSVal(const Stmt* Ex) const { + return Mgr->GetBlkExprSVal(this, Ex); +} + +inline SVal GRState::getSValAsScalarOrLoc(const Stmt *Ex) const { + return Mgr->GetSValAsScalarOrLoc(this, Ex); +} + +inline SVal GRState::getSVal(Loc LV, QualType T) const { + return Mgr->GetSVal(this, LV, T); +} + +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); +} + +inline BasicValueFactory &GRState::getBasicVals() const { + return Mgr->getBasicVals(); +} + +inline SymbolManager &GRState::getSymbolManager() const { + return Mgr->getSymbolManager(); +} + +inline GRTransferFuncs &GRState::getTransferFuncs() const { + return Mgr->getTransferFuncs(); +} + +template<typename T> +const GRState *GRState::add(typename GRStateTrait<T>::key_type K) const { + return Mgr->add<T>(this, K, get_context<T>()); +} + +template <typename T> +typename GRStateTrait<T>::context_type GRState::get_context() const { + return Mgr->get_context<T>(); +} + +template<typename T> +const GRState *GRState::remove(typename GRStateTrait<T>::key_type K) const { + return Mgr->remove<T>(this, K, get_context<T>()); +} + +template<typename T> +const GRState *GRState::remove(typename GRStateTrait<T>::key_type K, + typename GRStateTrait<T>::context_type C) const { + return Mgr->remove<T>(this, K, C); +} + +template<typename T> +const GRState *GRState::set(typename GRStateTrait<T>::data_type D) const { + return Mgr->set<T>(this, D); +} + +template<typename T> +const GRState *GRState::set(typename GRStateTrait<T>::key_type K, + typename GRStateTrait<T>::value_type E) const { + return Mgr->set<T>(this, K, E, get_context<T>()); +} + +template<typename T> +const GRState *GRState::set(typename GRStateTrait<T>::key_type K, + typename GRStateTrait<T>::value_type E, + typename GRStateTrait<T>::context_type C) const { + return Mgr->set<T>(this, K, E, C); +} + +template <typename CB> +CB GRState::scanReachableSymbols(SVal val) const { + CB cb(this); + 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 0f353d07004f..c2f8f5aae0e9 100644 --- a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h +++ b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h @@ -110,11 +110,9 @@ public: // Assumptions. - virtual const GRState* EvalAssume(GRStateManager& VMgr, - const GRState* St, - SVal Cond, bool Assumption, - bool& isFeasible) { - return St; + virtual const GRState* EvalAssume(const GRState *state, + SVal Cond, bool Assumption) { + return state; } }; diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h index 0e8da2aee318..8afcc4c2414f 100644 --- a/include/clang/Analysis/PathSensitive/MemRegion.h +++ b/include/clang/Analysis/PathSensitive/MemRegion.h @@ -620,7 +620,7 @@ public: /// getElementRegion - Retrieve the memory region associated with the /// associated element type, index, and super region. ElementRegion* getElementRegion(QualType elementType, SVal Idx, - const MemRegion* superRegion); + const MemRegion* superRegion,ASTContext &Ctx); /// getFieldRegion - Retrieve or create the memory region associated with /// a specified FieldDecl. 'superRegion' corresponds to the containing diff --git a/include/clang/Analysis/PathSensitive/SVals.h b/include/clang/Analysis/PathSensitive/SVals.h index ee6d4dcf1f37..c9d1e25da789 100644 --- a/include/clang/Analysis/PathSensitive/SVals.h +++ b/include/clang/Analysis/PathSensitive/SVals.h @@ -181,7 +181,7 @@ public: static NonLoc MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T); - static NonLoc MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I); + static NonLoc MakeVal(BasicValueFactory& BasicVals, const IntegerLiteral *I); static NonLoc MakeVal(BasicValueFactory& BasicVals, const llvm::APInt& I, bool isUnsigned); @@ -212,7 +212,7 @@ public: static Loc MakeVal(const MemRegion* R); - static Loc MakeVal(AddrLabelExpr* E); + static Loc MakeVal(const AddrLabelExpr* E); static Loc MakeNull(BasicValueFactory &BasicVals); diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index 1f081f4eb0d0..0c5df2e98e17 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -14,12 +14,12 @@ #ifndef LLVM_CLANG_ANALYSIS_STORE_H #define LLVM_CLANG_ANALYSIS_STORE_H -#include "clang/Analysis/PathSensitive/SVals.h" #include "clang/Analysis/PathSensitive/MemRegion.h" +#include "clang/Analysis/PathSensitive/SVals.h" #include "clang/Analysis/PathSensitive/ValueManager.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" -#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallVector.h" #include <iosfwd> @@ -45,10 +45,10 @@ protected: StoreManager(GRStateManager &stateMgr); protected: - virtual const GRState* AddRegionView(const GRState* St, - const MemRegion* View, - const MemRegion* Base) { - return St; + virtual const GRState *AddRegionView(const GRState *state, + const MemRegion *view, + const MemRegion *base) { + return state; } public: @@ -61,7 +61,7 @@ public: /// expected type of the returned value. This is used if the value is /// lazily computed. /// \return The value bound to the location \c loc. - virtual SVal Retrieve(const GRState* state, Loc loc, + virtual SVal Retrieve(const GRState *state, Loc loc, QualType T = QualType()) = 0; /// Return a state with the specified value bound to the given location. @@ -71,7 +71,7 @@ public: /// \return A pointer to a GRState object that contains the same bindings as /// \c state with the addition of having the value specified by \c val bound /// to the location given for \c loc. - virtual const GRState* Bind(const GRState* state, Loc loc, SVal val) = 0; + virtual const GRState *Bind(const GRState *state, Loc loc, SVal val) = 0; virtual Store Remove(Store St, Loc L) = 0; @@ -79,9 +79,9 @@ public: /// in 'store' plus the bindings for the CompoundLiteral. 'R' is the region /// for the compound literal and 'BegInit' and 'EndInit' represent an /// array of initializer values. - virtual const GRState* BindCompoundLiteral(const GRState* St, - const CompoundLiteralExpr* CL, - SVal V) = 0; + virtual const GRState *BindCompoundLiteral(const GRState *state, + const CompoundLiteralExpr* cl, + SVal v) = 0; /// getInitialStore - Returns the initial "empty" store representing the /// value bindings upon entry to an analyzed function. @@ -94,51 +94,52 @@ public: /// getSubRegionMap - Returns an opaque map object that clients can query /// to get the subregions of a given MemRegion object. It is the // caller's responsibility to 'delete' the returned map. - virtual SubRegionMap* getSubRegionMap(const GRState *state) = 0; + virtual SubRegionMap *getSubRegionMap(const GRState *state) = 0; - virtual SVal getLValueVar(const GRState* St, const VarDecl* VD) = 0; + virtual SVal getLValueVar(const GRState *state, const VarDecl *vd) = 0; - virtual SVal getLValueString(const GRState* St, const StringLiteral* S) = 0; + virtual SVal getLValueString(const GRState *state, + const StringLiteral* sl) = 0; - virtual SVal getLValueCompoundLiteral(const GRState* St, - const CompoundLiteralExpr* CL) = 0; + virtual SVal getLValueCompoundLiteral(const GRState *state, + const CompoundLiteralExpr* cl) = 0; - virtual SVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D, - SVal Base) = 0; + virtual SVal getLValueIvar(const GRState *state, const ObjCIvarDecl* decl, + SVal base) = 0; - virtual SVal getLValueField(const GRState* St, SVal Base, + virtual SVal getLValueField(const GRState *state, SVal base, const FieldDecl* D) = 0; - virtual SVal getLValueElement(const GRState* St, QualType elementType, - SVal Base, SVal Offset) = 0; + virtual SVal getLValueElement(const GRState *state, QualType elementType, + SVal base, SVal offset) = 0; - virtual SVal getSizeInElements(const GRState* St, const MemRegion* R) { + // FIXME: Make out-of-line. + virtual SVal getSizeInElements(const GRState *state, const MemRegion *region){ return UnknownVal(); } /// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit /// conversions between arrays and pointers. virtual SVal ArrayToPointer(Loc Array) = 0; - class CastResult { - const GRState* State; - const MemRegion* R; + const GRState *state; + const MemRegion *region; public: - const GRState* getState() const { return State; } - const MemRegion* getRegion() const { return R; } - CastResult(const GRState* s, const MemRegion* r = 0) : State(s), R(r) {} + const GRState *getState() const { return state; } + const MemRegion* getRegion() const { return region; } + CastResult(const GRState *s, const MemRegion* r = 0) : state(s), region(r){} }; /// CastRegion - Used by GRExprEngine::VisitCast to handle casts from /// a MemRegion* to a specific location type. 'R' is the region being /// casted and 'CastToTy' the result type of the cast. - virtual CastResult CastRegion(const GRState* state, const MemRegion* R, + virtual CastResult CastRegion(const GRState *state, const MemRegion *region, QualType CastToTy); /// EvalBinOp - Perform pointer arithmetic. - virtual SVal EvalBinOp(const GRState *state, - BinaryOperator::Opcode Op, Loc L, NonLoc R) { + virtual SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op, + Loc lhs, NonLoc rhs) { return UnknownVal(); } @@ -147,24 +148,27 @@ public: /// method returns NULL. virtual const MemRegion* getSelfRegion(Store store) = 0; - virtual Store - RemoveDeadBindings(const GRState* state, Stmt* Loc, SymbolReaper& SymReaper, - llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0; + virtual Store RemoveDeadBindings(const GRState *state, + Stmt* Loc, SymbolReaper& SymReaper, + llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0; - virtual const GRState* BindDecl(const GRState* St, const VarDecl* VD, - SVal InitVal) = 0; + virtual const GRState *BindDecl(const GRState *state, const VarDecl *vd, + SVal initVal) = 0; - virtual const GRState* BindDeclWithNoInit(const GRState* St, - const VarDecl* VD) = 0; + virtual const GRState *BindDeclWithNoInit(const GRState *state, + const VarDecl *vd) = 0; - virtual const GRState* setExtent(const GRState* St, - const MemRegion* R, SVal Extent) { - return St; + // FIXME: Make out-of-line. + virtual const GRState *setExtent(const GRState *state, + const MemRegion *region, SVal extent) { + return state; } - virtual const GRState* setDefaultValue(const GRState* St, - const MemRegion* R, SVal V) { - return St; + // FIXME: Make out-of-line. + virtual const GRState *setDefaultValue(const GRState *state, + const MemRegion *region, + SVal val) { + return state; } virtual void print(Store store, std::ostream& Out, @@ -174,13 +178,14 @@ public: public: virtual ~BindingsHandler(); virtual bool HandleBinding(StoreManager& SMgr, Store store, - const MemRegion* R, SVal val) = 0; + const MemRegion *region, SVal val) = 0; }; /// iterBindings - Iterate over the bindings in the Store. virtual void iterBindings(Store store, BindingsHandler& f) = 0; }; +// FIXME: Do we still need this? /// SubRegionMap - An abstract interface that represents a queryable map /// between MemRegion objects and their subregions. class SubRegionMap { @@ -193,12 +198,14 @@ public: virtual bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) = 0; }; - virtual bool iterSubRegions(const MemRegion* R, Visitor& V) const = 0; + virtual bool iterSubRegions(const MemRegion *region, Visitor& V) const = 0; }; - -StoreManager* CreateBasicStoreManager(GRStateManager& StMgr); -StoreManager* CreateRegionStoreManager(GRStateManager& StMgr); - + +// FIXME: Do we need to pass GRStateManager anymore? +StoreManager *CreateBasicStoreManager(GRStateManager& StMgr); +StoreManager *CreateRegionStoreManager(GRStateManager& StMgr); +StoreManager *CreateFieldsOnlyRegionStoreManager(GRStateManager& StMgr); + } // end clang namespace #endif diff --git a/include/clang/Analysis/PathSensitive/SymbolManager.h b/include/clang/Analysis/PathSensitive/SymbolManager.h index d424526d4eb0..d074e30333d4 100644 --- a/include/clang/Analysis/PathSensitive/SymbolManager.h +++ b/include/clang/Analysis/PathSensitive/SymbolManager.h @@ -83,19 +83,25 @@ typedef const SymbolData* SymbolRef; class SymbolRegionValue : public SymbolData { const MemRegion *R; + // We may cast the region to another type, so the expected type of the symbol + // may be different from the region's original type. + QualType T; + public: - SymbolRegionValue(SymbolID sym, const MemRegion *r) - : SymbolData(RegionValueKind, sym), R(r) {} + SymbolRegionValue(SymbolID sym, const MemRegion *r, QualType t = QualType()) + : SymbolData(RegionValueKind, sym), R(r), T(t) {} const MemRegion* getRegion() const { return R; } - static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion* R) { + static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion* R, + QualType T) { profile.AddInteger((unsigned) RegionValueKind); profile.AddPointer(R); + T.Profile(profile); } virtual void Profile(llvm::FoldingSetNodeID& profile) { - Profile(profile, R); + Profile(profile, R, T); } QualType getType(ASTContext&) const; @@ -240,7 +246,8 @@ public: static bool canSymbolicate(QualType T); /// Make a unique symbol for MemRegion R according to its kind. - const SymbolRegionValue* getRegionValueSymbol(const MemRegion* R); + const SymbolRegionValue* getRegionValueSymbol(const MemRegion* R, + QualType T = QualType()); const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T, unsigned VisitCount, const void* SymbolTag = 0); diff --git a/include/clang/Analysis/PathSensitive/ValueManager.h b/include/clang/Analysis/PathSensitive/ValueManager.h index 89af975de7af..b86f4e875304 100644 --- a/include/clang/Analysis/PathSensitive/ValueManager.h +++ b/include/clang/Analysis/PathSensitive/ValueManager.h @@ -81,7 +81,7 @@ public: SVal makeZeroArrayIndex(); /// GetRegionValueSymbolVal - make a unique symbol for value of R. - SVal getRegionValueSymbolVal(const MemRegion* R); + SVal getRegionValueSymbolVal(const MemRegion* R, QualType T = QualType()); SVal getConjuredSymbolVal(const Expr *E, unsigned Count); SVal getConjuredSymbolVal(const Expr* E, QualType T, unsigned Count); diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h index 6463a4f6e51b..f770c5089eec 100644 --- a/include/clang/Basic/Builtins.h +++ b/include/clang/Basic/Builtins.h @@ -53,13 +53,12 @@ class Context { const Info *TSRecords; unsigned NumTSRecords; public: - Context() : TSRecords(0), NumTSRecords(0) {} + Context(const TargetInfo &Target); /// InitializeBuiltins - Mark the identifiers for all the builtins with their /// appropriate builtin ID # and mark any non-portable builtin identifiers as /// such. - void InitializeBuiltins(IdentifierTable &Table, const TargetInfo &Target, - bool NoBuiltins = false); + void InitializeBuiltins(IdentifierTable &Table, bool NoBuiltins = false); /// \brief Popular the vector with the names of all of the builtins. void GetBuiltinNames(llvm::SmallVectorImpl<const char *> &Names, diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 501807df77a3..2896f7988c01 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -30,6 +30,7 @@ def : DiagGroup<"conversion">; def : DiagGroup<"declaration-after-statement">; def : DiagGroup<"disabled-optimization">; def : DiagGroup<"discard-qual">; +def : DiagGroup<"div-by-zero">; def EmptyBody : DiagGroup<"empty-body">; def ExtraTokens : DiagGroup<"extra-tokens">; @@ -40,6 +41,7 @@ def FourByteMultiChar : DiagGroup<"four-char-constants">; def : DiagGroup<"init-self">; def : DiagGroup<"inline">; def : DiagGroup<"int-to-pointer-cast">; +def : DiagGroup<"invalid-pch">; def : DiagGroup<"missing-braces">; def : DiagGroup<"missing-declarations">; def : DiagGroup<"missing-format-attribute">; @@ -91,6 +93,8 @@ def UnusedLabel : DiagGroup<"unused-label">; def UnusedParameter : DiagGroup<"unused-parameter">; def UnusedValue : DiagGroup<"unused-value">; def UnusedVariable : DiagGroup<"unused-variable">; +def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">; +def UndeclaredSelector : DiagGroup<"undeclared-selector">; def : DiagGroup<"variadic-macros">; def VectorConversions : DiagGroup<"vector-conversions">; // clang specific def VolatileRegisterVar : DiagGroup<"volatile-register-var">; @@ -112,7 +116,9 @@ def Format2 : DiagGroup<"format=2", [FormatNonLiteral, FormatSecurity, FormatY2K]>; -def Extra : DiagGroup<"extra">; +def Extra : DiagGroup<"extra", [ + UnusedParameter + ]>; def Most : DiagGroup<"most", [ Comment, @@ -127,7 +133,9 @@ def Most : DiagGroup<"most", [ UnusedValue, UnusedVariable, VectorConversions, - VolatileRegisterVar + VolatileRegisterVar, + ReadOnlySetterAttrs, + UndeclaredSelector ]>; // -Wall is -Wmost -Wparentheses diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index e2b9eb7a20b8..d65a97eb7067 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -108,6 +108,8 @@ def err_expected_semi_after_method_proto : Error< "expected ';' after method prototype">; def err_expected_semi_after_namespace_name : Error< "expected ';' after namespace name">; +def err_unexpected_namespace_attributes_alias : Error< + "attributes can not be specified on namespace alias">; def err_expected_semi_after_attribute_list : Error< "expected ';' after attribute list">; def err_expected_semi_after_static_assert : Error< @@ -152,6 +154,10 @@ def err_unknown_typename : Error< "unknown type name %0">; def err_use_of_tag_name_without_tag : Error< "use of tagged type %0 without '%1' tag">; +def err_expected_ident_in_using : Error< + "expected an identifier in using directive">; +def err_unexpected_template_spec_in_using : Error< + "use of template specialization in using directive not allowed">; /// Objective-C parser diagnostics @@ -212,6 +218,8 @@ def ext_ellipsis_exception_spec : Extension< "exception specification of '...' is a Microsoft extension">; def err_expected_catch : Error<"expected catch">; def err_expected_lbrace_or_comma : Error<"expected '{' or ','">; +def err_using_namespace_in_class : Error< + "'using namespace' in class not allowed">; // C++ derived classes def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">; @@ -287,5 +295,5 @@ def warn_pragma_unused_expected_var : Warning< "expected '#pragma unused' argument to be a variable name">; def warn_pragma_unused_expected_punc : Warning< "expected ')' or ',' in '#pragma unused'">; - + } // end of Parser diagnostics diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index fa4f430591b2..755cfce4d85b 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -72,6 +72,8 @@ def ext_anon_param_requires_type_specifier : Extension< def err_bad_variable_name : Error< "'%0' cannot be the name of a variable or data member">; def err_parameter_name_omitted : Error<"parameter name omitted">; +def warn_unused_parameter : Warning<"unused parameter %0">, + InGroup<UnusedParameter>, DefaultIgnore; def warn_decl_in_param_list : Warning< "declaration of %0 will not be visible outside of this function">; @@ -90,6 +92,10 @@ def warn_use_out_of_scope_declaration : Warning< "use of out-of-scope declaration of %0">; def err_inline_non_function : Error< "'inline' can only appear on functions">; +def err_using_requires_qualname : Error< + "using declaration requires a qualified name">; +def err_using_typename_non_type : Error< + "'typename' keyword used on a non-type">; def err_invalid_thread : Error< "'__thread' is only allowed on variable declarations">; @@ -240,7 +246,9 @@ def error_duplicate_ivar_use : Error< def error_property_implemented : Error<"property %0 is already implemented">; def warn_objc_property_attr_mutually_exclusive : Warning< "property attributes '%0' and '%1' are mutually exclusive">, - InGroup<DiagGroup<"readonly-setter-attrs">>, DefaultIgnore; + InGroup<ReadOnlySetterAttrs>, DefaultIgnore; +def warn_undeclared_selector : Warning< + "undeclared selector %0">, InGroup<UndeclaredSelector>, DefaultIgnore; // C++ declarations def err_static_assert_expression_is_not_constant : Error< @@ -571,6 +579,14 @@ def err_param_default_argument_references_this : Error< def err_param_default_argument_nonfunc : Error< "default arguments can only be specified for parameters in a function " "declaration">; +def err_defining_default_ctor : Error< + "cannot define the default constructor for %0, because %select{base class|member}1 " + "%2 does not have any implicit default constructor">; +def note_previous_class_decl : Note< + "%0 declared 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">; def err_use_of_default_argument_to_function_declared_later : Error< "use of default argument to function %0 that is declared later in class %1">; diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h index 2405c2fe7db7..7d78087d9db5 100644 --- a/include/clang/Basic/SourceLocation.h +++ b/include/clang/Basic/SourceLocation.h @@ -145,6 +145,10 @@ inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) { return LHS.getRawEncoding() < RHS.getRawEncoding(); } +inline bool operator<=(const SourceLocation &LHS, const SourceLocation &RHS) { + return LHS.getRawEncoding() <= RHS.getRawEncoding(); +} + /// SourceRange - a trival tuple used to represent a source range. class SourceRange { SourceLocation B; diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index 57ae9a45114d..bcfb83b8942c 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -68,7 +68,12 @@ namespace SrcMgr { /// NumLines - The number of lines in this ContentCache. This is only valid /// if SourceLineCache is non-null. unsigned NumLines; - + + /// FirstFID - First FileID that was created for this ContentCache. + /// Represents the first source inclusion of the file associated with this + /// ContentCache. + mutable FileID FirstFID; + /// getBuffer - Returns the memory buffer for the associated content. const llvm::MemoryBuffer *getBuffer() const; @@ -624,6 +629,13 @@ public: //===--------------------------------------------------------------------===// // Other miscellaneous methods. //===--------------------------------------------------------------------===// + + /// \brief Get the source location for the given file:line:col triplet. + /// + /// If the source file is included multiple times, the source location will + /// be based upon the first inclusion. + SourceLocation getLocation(const FileEntry *SourceFile, + unsigned Line, unsigned Col) const; // Iterators over FileInfos. typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> diff --git a/include/clang/Driver/Options.def b/include/clang/Driver/Options.def index 7045f145ee51..abd07a92b1a2 100644 --- a/include/clang/Driver/Options.def +++ b/include/clang/Driver/Options.def @@ -565,9 +565,9 @@ OPTION("-print-file-name=", print_file_name_EQ, Joined, INVALID, INVALID, "", 0, OPTION("-print-ivar-layout", print_ivar_layout, Flag, INVALID, INVALID, "", 0, 0, 0) OPTION("-print-libgcc-file-name", print_libgcc_file_name, Flag, INVALID, INVALID, "", 0, "Print the library path for \"libgcc.a\"", 0) -OPTION("-print-multi-directory", print_multi_directory, Flag, INVALID, INVALID, "u", 0, 0, 0) -OPTION("-print-multi-lib", print_multi_lib, Flag, INVALID, INVALID, "u", 0, 0, 0) -OPTION("-print-multi-os-directory", print_multi_os_directory, Flag, INVALID, INVALID, "u", 0, 0, 0) +OPTION("-print-multi-directory", print_multi_directory, Flag, INVALID, INVALID, "", 0, 0, 0) +OPTION("-print-multi-lib", print_multi_lib, Flag, INVALID, INVALID, "", 0, 0, 0) +OPTION("-print-multi-os-directory", print_multi_os_directory, Flag, INVALID, INVALID, "", 0, 0, 0) OPTION("-print-prog-name=", print_prog_name_EQ, Joined, INVALID, INVALID, "", 0, "Print the full program path of <name>", "<name>") OPTION("-print-search-dirs", print_search_dirs, Flag, INVALID, INVALID, "", 0, diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h index 6196c130266d..c9d0ef197dae 100644 --- a/include/clang/Driver/ToolChain.h +++ b/include/clang/Driver/ToolChain.h @@ -50,6 +50,8 @@ public: // Accessors const HostInfo &getHost() const { return Host; } + const llvm::Triple &getTriple() const { return Triple; } + std::string getArchName() const { return Triple.getArchName(); } std::string getPlatform() const { return Triple.getVendorName(); } std::string getOS() const { return Triple.getOSName(); } diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h new file mode 100644 index 000000000000..68c06f5dcee6 --- /dev/null +++ b/include/clang/Frontend/ASTUnit.h @@ -0,0 +1,75 @@ +//===--- ASTUnit.h - ASTUnit utility ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// ASTUnit utility class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_ASTUNIT_H +#define LLVM_CLANG_FRONTEND_ASTUNIT_H + +#include "llvm/ADT/OwningPtr.h" +#include <string> + +namespace clang { + class FileManager; + class FileEntry; + class SourceManager; + class DiagnosticClient; + class Diagnostic; + class HeaderSearch; + class TargetInfo; + class Preprocessor; + class ASTContext; + class Decl; + +/// \brief Utility class for loading a ASTContext from a PCH file. +/// +class ASTUnit { + llvm::OwningPtr<SourceManager> SourceMgr; + llvm::OwningPtr<DiagnosticClient> DiagClient; + llvm::OwningPtr<Diagnostic> Diags; + llvm::OwningPtr<HeaderSearch> HeaderInfo; + llvm::OwningPtr<TargetInfo> Target; + llvm::OwningPtr<Preprocessor> PP; + llvm::OwningPtr<ASTContext> Ctx; + + ASTUnit(const ASTUnit&); // do not implement + ASTUnit &operator=(const ASTUnit &); // do not implement + ASTUnit(); + +public: + ~ASTUnit(); + + const SourceManager &getSourceManager() const { return *SourceMgr.get(); } + SourceManager &getSourceManager() { return *SourceMgr.get(); } + + const Preprocessor &getPreprocessor() const { return *PP.get(); } + Preprocessor &getPreprocessor() { return *PP.get(); } + + const ASTContext &getASTContext() const { return *Ctx.get(); } + ASTContext &getASTContext() { return *Ctx.get(); } + + /// \brief Create a ASTUnit from a PCH file. + /// + /// \param Filename PCH filename + /// + /// \param FileMgr The FileManager to use + /// + /// \param ErrMsg Error message to report if the PCH file could not be loaded + /// + /// \returns the initialized ASTUnit or NULL if the PCH failed to load + static ASTUnit *LoadFromPCHFile(const std::string &Filename, + FileManager &FileMgr, + std::string *ErrMsg = 0); +}; + +} // namespace clang + +#endif diff --git a/include/clang/Frontend/DeclContextXML.def b/include/clang/Frontend/DeclContextXML.def new file mode 100644 index 000000000000..39ed5f9432b6 --- /dev/null +++ b/include/clang/Frontend/DeclContextXML.def @@ -0,0 +1,113 @@ +//===-- DeclContextXML.def - Metadata about Context XML nodes ---*- 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 XML context info database as written in the +// <ReferenceSection>/<Contexts> sub-nodes of the XML document. Type nodes +// are referred by "context" reference attributes throughout the document. +// A context node never contains sub-nodes. +// The semantics of the attributes and enums are mostly self-documenting +// by looking at the appropriate internally used functions and values. +// The following macros are used: +// +// NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete +// context of class CLASS where CLASS is a class name used internally by clang. +// After a NODE_XML the definition of all (optional) attributes of that context +// node and possible sub-nodes follows. +// +// END_NODE_XML - Closes the attribute definition of the current node. +// +// ID_ATTRIBUTE_XML - Context nodes have an "id" attribute containing a +// string, which value uniquely identify that statement. Other nodes may refer +// by "context" attributes to this value. +// +// TYPE_ATTRIBUTE_XML( FN ) - Context nodes may refer to the ids of type +// nodes by a "type" attribute, if they create a type during declaration. +// For instance 'struct S;' creates both a context 'S::' and a type 'S'. +// Contexts and types always have different ids, however declarations and +// contexts may share the same ids. FN is internally used by clang. +// +// ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally +// used by clang. A boolean attribute have the values "0" or "1". +// +// ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value +// is an enumeration defined with ENUM_XML macros immediately following after +// that macro. An optional attribute is ommited, if the particular enum is the +// empty string. FN is internally used by clang. +// +// ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is +// internally used by clang. +// +// END_ENUM_XML - Closes the enumeration definition of the current attribute. +// +//===----------------------------------------------------------------------===// + +#ifndef TYPE_ATTRIBUTE_XML +# define TYPE_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "type") +#endif + +#ifndef CONTEXT_ATTRIBUTE_XML +# define CONTEXT_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "context") +#endif + +NODE_XML(TranslationUnitDecl, "TranslationUnit") + ID_ATTRIBUTE_XML +END_NODE_XML + +NODE_XML(FunctionDecl, "Function") + ID_ATTRIBUTE_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") + TYPE_ATTRIBUTE_XML(getType()->getAsFunctionType()) +END_NODE_XML + +NODE_XML(NamespaceDecl, "Namespace") + ID_ATTRIBUTE_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") +END_NODE_XML + +NODE_XML(RecordDecl, "Record") + ID_ATTRIBUTE_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") + TYPE_ATTRIBUTE_XML(getTypeForDecl()) +END_NODE_XML + +NODE_XML(EnumDecl, "Enum") + ID_ATTRIBUTE_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") + TYPE_ATTRIBUTE_XML(getTypeForDecl()) +END_NODE_XML + +NODE_XML(LinkageSpecDecl, "LinkageSpec") + ID_ATTRIBUTE_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_ENUM_OPT_XML(getLanguage(), "lang") + ENUM_XML(LinkageSpecDecl::lang_c, "C") + ENUM_XML(LinkageSpecDecl::lang_cxx, "CXX") + END_ENUM_XML +END_NODE_XML + +//===----------------------------------------------------------------------===// +#undef NODE_XML +#undef ID_ATTRIBUTE_XML +#undef TYPE_ATTRIBUTE_XML +#undef ATTRIBUTE_XML +#undef ATTRIBUTE_SPECIAL_XML +#undef ATTRIBUTE_OPT_XML +#undef ATTRIBUTE_ENUM_XML +#undef ATTRIBUTE_ENUM_OPT_XML +#undef ATTRIBUTE_FILE_LOCATION_XML +#undef ENUM_XML +#undef END_ENUM_XML +#undef END_NODE_XML +#undef SUB_NODE_XML +#undef SUB_NODE_SEQUENCE_XML +#undef SUB_NODE_OPT_XML diff --git a/include/clang/Frontend/DeclXML.def b/include/clang/Frontend/DeclXML.def new file mode 100644 index 000000000000..956d9719f9f4 --- /dev/null +++ b/include/clang/Frontend/DeclXML.def @@ -0,0 +1,250 @@ +//===-- DeclXML.def - Metadata about Decl XML nodes ------------*- 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 XML statement database structure as written in +// <TranslationUnit> sub-nodes of the XML document. +// The semantics of the attributes and enums are mostly self-documenting +// by looking at the appropriate internally used functions and values. +// The following macros are used: +// +// NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete +// statement of class CLASS where CLASS is a class name used internally by clang. +// After a NODE_XML the definition of all (optional) attributes of that statement +// node and possible sub-nodes follows. +// +// END_NODE_XML - Closes the attribute definition of the current node. +// +// ID_ATTRIBUTE_XML - Some statement nodes have an "id" attribute containing a +// string, which value uniquely identify that statement. Other nodes may refer +// by reference attributes to this value (currently used only for Label). +// +// TYPE_ATTRIBUTE_XML( FN ) - Type nodes refer to the result type id of an +// expression by a "type" attribute. FN is internally used by clang. +// +// ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally +// used by clang. A boolean attribute have the values "0" or "1". +// +// ATTRIBUTE_SPECIAL_XML( FN, NAME ) - An attribute named NAME which deserves +// a special handling. See the appropriate documentations. +// +// ATTRIBUTE_FILE_LOCATION_XML - A bunch of attributes denoting the location of +// a statement in the source file(s). +// +// ATTRIBUTE_OPT_XML( FN, NAME ) - An optional attribute named NAME. +// Optional attributes are omitted for boolean types, if the value is false, +// for integral types, if the value is null and for strings, +// if the value is the empty string. FN is internally used by clang. +// +// ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value +// is an enumeration defined with ENUM_XML macros immediately following after +// that macro. An optional attribute is ommited, if the particular enum is the +// empty string. FN is internally used by clang. +// +// ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is +// internally used by clang. +// +// END_ENUM_XML - Closes the enumeration definition of the current attribute. +// +// SUB_NODE_XML( CLASS ) - A mandatory sub-node of class CLASS or its sub-classes. +// +// SUB_NODE_OPT_XML( CLASS ) - An optional sub-node of class CLASS or its sub-classes. +// +// SUB_NODE_SEQUENCE_XML( CLASS ) - Zero or more sub-nodes of class CLASS or +// its sub-classes. +// +//===----------------------------------------------------------------------===// + +#ifndef ATTRIBUTE_FILE_LOCATION_XML +# define ATTRIBUTE_FILE_LOCATION_XML \ + ATTRIBUTE_XML(getFilename(), "file") \ + ATTRIBUTE_XML(getLine(), "line") \ + ATTRIBUTE_XML(getColumn(), "col") \ + ATTRIBUTE_OPT_XML(getFilename(), "endfile") \ + ATTRIBUTE_OPT_XML(getLine(), "endline") \ + ATTRIBUTE_OPT_XML(getColumn(), "endcol") +#endif + +#ifndef TYPE_ATTRIBUTE_XML +# define TYPE_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "type") +#endif + +#ifndef CONTEXT_ATTRIBUTE_XML +# define CONTEXT_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "context") +#endif + +//NODE_XML(TranslationUnitDecl, "TranslationUnit") +// SUB_NODE_SEQUENCE_XML(Decl) +//END_NODE_XML + +NODE_XML(Decl, "FIXME_Decl") + ATTRIBUTE_FILE_LOCATION_XML +END_NODE_XML + +NODE_XML(FunctionDecl, "Function") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") + TYPE_ATTRIBUTE_XML(getType()->getAsFunctionType()->getResultType()) + ATTRIBUTE_XML(getType()->getAsFunctionType(), "function_type") + ATTRIBUTE_ENUM_OPT_XML(getStorageClass(), "storage_class") + ENUM_XML(FunctionDecl::None, "") + ENUM_XML(FunctionDecl::Extern, "extern") + ENUM_XML(FunctionDecl::Static, "static") + ENUM_XML(FunctionDecl::PrivateExtern, "__private_extern__") + END_ENUM_XML + ATTRIBUTE_OPT_XML(isInline(), "inline") + //ATTRIBUTE_OPT_XML(isVariadic(), "variadic") // in the type reference + ATTRIBUTE_XML(getNumParams(), "num_args") + SUB_NODE_SEQUENCE_XML(ParmVarDecl) + //SUB_NODE_OPT_XML("Body") +END_NODE_XML + +NODE_XML(CXXMethodDecl, "CXXMethodDecl") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") + TYPE_ATTRIBUTE_XML(getType()->getAsFunctionType()->getResultType()) + ATTRIBUTE_XML(getType()->getAsFunctionType(), "function_type") + ATTRIBUTE_OPT_XML(isInline(), "inline") + ATTRIBUTE_OPT_XML(isStatic(), "static") + ATTRIBUTE_OPT_XML(isVirtual(), "virtual") + ATTRIBUTE_XML(getNumParams(), "num_args") + SUB_NODE_SEQUENCE_XML(ParmVarDecl) + //SUB_NODE_OPT_XML("Body") +END_NODE_XML + +//NODE_XML("Body") +// SUB_NODE_XML(Stmt) +//END_NODE_XML + +NODE_XML(NamespaceDecl, "Namespace") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") +END_NODE_XML + +NODE_XML(UsingDirectiveDecl, "UsingDirective") + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") + ATTRIBUTE_XML(getNominatedNamespace(), "ref") +END_NODE_XML + +NODE_XML(NamespaceAliasDecl, "NamespaceAlias") + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") + ATTRIBUTE_XML(getNamespace(), "ref") +END_NODE_XML + +NODE_XML(RecordDecl, "Record") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") + ATTRIBUTE_OPT_XML(isDefinition() == false, "forward") + ATTRIBUTE_XML(getTypeForDecl(), "type") // refers to the type this decl creates + SUB_NODE_SEQUENCE_XML(FieldDecl) +END_NODE_XML + +NODE_XML(EnumDecl, "Enum") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") + ATTRIBUTE_OPT_XML(isDefinition() == false, "forward") + ATTRIBUTE_SPECIAL_XML(getIntegerType(), "type") // is NULL in pure declarations thus deserves special handling + SUB_NODE_SEQUENCE_XML(EnumConstantDecl) // only present in definition +END_NODE_XML + +NODE_XML(EnumConstantDecl, "EnumConstant") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_XML(getInitVal().toString(10, true), "value") // integer + SUB_NODE_OPT_XML(Expr) // init expr of this constant +END_NODE_XML + +NODE_XML(FieldDecl, "Field") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_OPT_XML(isMutable(), "mutable") + ATTRIBUTE_OPT_XML(isBitField(), "bitfield") + SUB_NODE_OPT_XML(Expr) // init expr of a bit field +END_NODE_XML + +NODE_XML(TypedefDecl, "Typedef") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") + TYPE_ATTRIBUTE_XML(getUnderlyingType()) +END_NODE_XML + +NODE_XML(VarDecl, "Var") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_ENUM_OPT_XML(getStorageClass(), "storage_class") + ENUM_XML(VarDecl::None, "") + ENUM_XML(VarDecl::Auto, "auto") + ENUM_XML(VarDecl::Register, "register") + ENUM_XML(VarDecl::Extern, "extern") + ENUM_XML(VarDecl::Static, "static") + ENUM_XML(VarDecl::PrivateExtern, "__private_extern__") + END_ENUM_XML + SUB_NODE_OPT_XML(Expr) // init expr +END_NODE_XML + +NODE_XML(ParmVarDecl, "ParmVar") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_XML(getNameAsString(), "name") + TYPE_ATTRIBUTE_XML(getType()) + SUB_NODE_OPT_XML(Expr) // default argument expression +END_NODE_XML + +NODE_XML(LinkageSpecDecl, "LinkageSpec") + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getDeclContext(), "context") + ATTRIBUTE_ENUM_OPT_XML(getLanguage(), "lang") + ENUM_XML(LinkageSpecDecl::lang_c, "C") + ENUM_XML(LinkageSpecDecl::lang_cxx, "CXX") + END_ENUM_XML +END_NODE_XML + + +//===----------------------------------------------------------------------===// +#undef NODE_XML +#undef ID_ATTRIBUTE_XML +#undef TYPE_ATTRIBUTE_XML +#undef ATTRIBUTE_XML +#undef ATTRIBUTE_SPECIAL_XML +#undef ATTRIBUTE_OPT_XML +#undef ATTRIBUTE_ENUM_XML +#undef ATTRIBUTE_ENUM_OPT_XML +#undef ATTRIBUTE_FILE_LOCATION_XML +#undef ENUM_XML +#undef END_ENUM_XML +#undef END_NODE_XML +#undef SUB_NODE_XML +#undef SUB_NODE_SEQUENCE_XML +#undef SUB_NODE_OPT_XML diff --git a/include/clang/Frontend/DocumentXML.def b/include/clang/Frontend/DocumentXML.def new file mode 100644 index 000000000000..4c52bd84422f --- /dev/null +++ b/include/clang/Frontend/DocumentXML.def @@ -0,0 +1,75 @@ +//===-- DocumentXML.def - Metadata about Document XML nodes -----*- 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 XML root database structure as written in +// an AST XML document. +// The following macros are used: +// +// NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete +// statement of class CLASS where CLASS is a class name used internally by clang. +// After a NODE_XML the definition of all (optional) attributes of that statement +// node and possible sub-nodes follows. +// +// END_NODE_XML - Closes the attribute definition of the current node. +// +// ID_ATTRIBUTE_XML - Some nodes have an "id" attribute containing a +// string, which value uniquely identify the entity represented by that node. +// Other nodes may refer by reference attributes to this value. +// +// ATTRIBUTE_SPECIAL_XML( FN, NAME ) - An attribute named NAME which deserves +// a special handling. See the appropriate documentations. +// +// SUB_NODE_XML( CLASS ) - A mandatory sub-node of class CLASS or its sub-classes. +// +// SUB_NODE_SEQUENCE_XML( CLASS ) - Zero or more sub-nodes of class CLASS or +// its sub-classes. +// +//===----------------------------------------------------------------------===// + +ROOT_NODE_XML("CLANG_XML") + ATTRIBUTE_SPECIAL_XML(ignore, "version") // special retrieving needed + SUB_NODE_XML("TranslationUnit") + SUB_NODE_XML("ReferenceSection") +END_NODE_XML + +NODE_XML("TranslationUnit") + SUB_NODE_SEQUENCE_XML(Decl) +END_NODE_XML + +NODE_XML("ReferenceSection") + SUB_NODE_XML("Types") + SUB_NODE_XML("Contexts") + SUB_NODE_XML("Files") +END_NODE_XML + +NODE_XML("Types") + SUB_NODE_SEQUENCE_XML(Type) +END_NODE_XML + +NODE_XML("Contexts") + SUB_NODE_SEQUENCE_XML(DeclContext) +END_NODE_XML + +NODE_XML("Files") + SUB_NODE_SEQUENCE_XML("File") +END_NODE_XML + +NODE_XML("File") + ID_ATTRIBUTE_XML + ATTRIBUTE_SPECIAL_XML(ignore, "name") // special retrieving needed, denotes the source file name +END_NODE_XML + + +//===----------------------------------------------------------------------===// +#undef NODE_XML +#undef ID_ATTRIBUTE_XML +#undef ATTRIBUTE_SPECIAL_XML +#undef END_NODE_XML +#undef SUB_NODE_XML +#undef SUB_NODE_SEQUENCE_XML diff --git a/include/clang/Frontend/DocumentXML.h b/include/clang/Frontend/DocumentXML.h index 99db717190dd..4ed11e153ce3 100644 --- a/include/clang/Frontend/DocumentXML.h +++ b/include/clang/Frontend/DocumentXML.h @@ -17,6 +17,7 @@ #include <string> #include <map> +#include <stack> #include "clang/AST/Type.h" #include "clang/AST/TypeOrdering.h" #include "llvm/Support/raw_ostream.h" @@ -30,6 +31,7 @@ class Decl; class NamedDecl; class FunctionDecl; class ASTContext; +class LabelStmt; //--------------------------------------------------------- namespace XML @@ -50,26 +52,37 @@ class DocumentXML { public: DocumentXML(const std::string& rootName, llvm::raw_ostream& out); - ~DocumentXML(); void initialize(ASTContext &Context); void PrintDecl(Decl *D); void PrintStmt(const Stmt *S); // defined in StmtXML.cpp - void finalize(); DocumentXML& addSubNode(const std::string& name); // also enters the sub node, returns *this DocumentXML& toParent(); // returns *this + void addAttribute(const char* pName, const QualType& pType); + void addAttribute(const char* pName, bool value); + + template<class T> + void addAttribute(const char* pName, const T* value) + { + addPtrAttribute(pName, value); + } + + template<class T> + void addAttribute(const char* pName, T* value) + { + addPtrAttribute(pName, value); + } + template<class T> void addAttribute(const char* pName, const T& value); - void addTypeAttribute(const QualType& pType); - void addRefAttribute(const NamedDecl* D); + template<class T> + void addAttributeOptional(const char* pName, const T& value); - enum tContextUsage { CONTEXT_AS_CONTEXT, CONTEXT_AS_ID }; - void addContextAttribute(const DeclContext *DC, tContextUsage usage = CONTEXT_AS_CONTEXT); void addSourceFileAttribute(const std::string& fileName); PresumedLoc addLocation(const SourceLocation& Loc); @@ -81,13 +94,9 @@ private: DocumentXML(const DocumentXML&); // not defined DocumentXML& operator=(const DocumentXML&); // not defined - struct NodeXML; - - NodeXML* Root; - NodeXML* CurrentNode; // always after Root + std::stack<std::string> NodeStack; llvm::raw_ostream& Out; ASTContext *Ctx; - int CurrentIndent; bool HasCurrentNodeSubNodes; @@ -96,15 +105,38 @@ private: XML::IdMap<const Type*> BasicTypes; XML::IdMap<std::string> SourceFiles; XML::IdMap<const NamedDecl*> Decls; + XML::IdMap<const LabelStmt*> Labels; void addContextsRecursively(const DeclContext *DC); - void addBasicTypeRecursively(const Type* pType); + void addTypeRecursively(const Type* pType); void addTypeRecursively(const QualType& pType); - void PrintFunctionDecl(FunctionDecl *FD); - void addDeclIdAttribute(const NamedDecl* D); - void addTypeIdAttribute(const Type* pType); void Indent(); + + // forced pointer dispatch: + void addPtrAttribute(const char* pName, const Type* pType); + void addPtrAttribute(const char* pName, const NamedDecl* D); + void addPtrAttribute(const char* pName, const DeclContext* D); + void addPtrAttribute(const char* pName, const NamespaceDecl* D); // disambiguation + void addPtrAttribute(const char* pName, const LabelStmt* L); + void addPtrAttribute(const char* pName, const char* text); + + // defined in TypeXML.cpp: + void addParentTypes(const Type* pType); + void writeTypeToXML(const Type* pType); + void writeTypeToXML(const QualType& pType); + class TypeAdder; + friend class TypeAdder; + + // defined in DeclXML.cpp: + void writeDeclToXML(Decl *D); + class DeclPrinter; + friend class DeclPrinter; + + // for addAttributeOptional: + static bool isDefault(unsigned value) { return value == 0; } + static bool isDefault(bool value) { return !value; } + static bool isDefault(const std::string& value) { return value.empty(); } }; //--------------------------------------------------------- inlines @@ -122,6 +154,28 @@ inline void DocumentXML::addAttribute(const char* pName, const T& value) } //--------------------------------------------------------- +inline void DocumentXML::addPtrAttribute(const char* pName, const char* text) +{ + Out << ' ' << pName << "=\"" << text << "\""; +} + +//--------------------------------------------------------- +inline void DocumentXML::addAttribute(const char* pName, bool value) +{ + addPtrAttribute(pName, value ? "1" : "0"); +} + +//--------------------------------------------------------- +template<class T> +inline void DocumentXML::addAttributeOptional(const char* pName, const T& value) +{ + if (!isDefault(value)) + { + addAttribute(pName, value); + } +} + +//--------------------------------------------------------- } //namespace clang diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index 0862cd6390f4..e546a12c49e9 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -386,8 +386,8 @@ namespace clang { TYPE_OBJC_INTERFACE = 21, /// \brief An ObjCQualifiedInterfaceType record. TYPE_OBJC_QUALIFIED_INTERFACE = 22, - /// \brief An ObjCQualifiedIdType record. - TYPE_OBJC_QUALIFIED_ID = 23 + /// \brief An ObjCObjectPointerType record. + TYPE_OBJC_OBJECT_POINTER = 23 }; /// \brief The type IDs for special types constructed by semantic diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h index 1e00ae34137d..b3ed36434312 100644 --- a/include/clang/Frontend/PCHReader.h +++ b/include/clang/Frontend/PCHReader.h @@ -53,6 +53,82 @@ class NamedDecl; class Preprocessor; class Sema; class SwitchCase; +class PCHReader; +class HeaderFileInfo; + +/// \brief Abstract interface for callback invocations by the PCHReader. +/// +/// While reading a PCH file, the PCHReader will call the methods of the +/// listener to pass on specific information. Some of the listener methods can +/// return true to indicate to the PCHReader that the information (and +/// consequently the PCH file) is invalid. +class PCHReaderListener { +public: + virtual ~PCHReaderListener(); + + /// \brief Receives the language options. + /// + /// \returns true to indicate the options are invalid or false otherwise. + virtual bool ReadLanguageOptions(const LangOptions &LangOpts) { + return false; + } + + /// \brief Receives the target triple. + /// + /// \returns true to indicate the target triple is invalid or false otherwise. + virtual bool ReadTargetTriple(const std::string &Triple) { + return false; + } + + /// \brief Receives the contents of the predefines buffer. + /// + /// \param PCHPredef The start of the predefines buffer in the PCH + /// file. + /// + /// \param PCHPredefLen The length of the predefines buffer in the PCH + /// file. + /// + /// \param PCHBufferID The FileID for the PCH predefines buffer. + /// + /// \param SuggestedPredefines If necessary, additional definitions are added + /// here. + /// + /// \returns true to indicate the predefines are invalid or false otherwise. + virtual bool ReadPredefinesBuffer(const char *PCHPredef, + unsigned PCHPredefLen, + FileID PCHBufferID, + std::string &SuggestedPredefines) { + return false; + } + + /// \brief Receives a HeaderFileInfo entry. + virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI) {} + + /// \brief Receives __COUNTER__ value. + virtual void ReadCounter(unsigned Value) {} +}; + +/// \brief PCHReaderListener implementation to validate the information of +/// the PCH file against an initialized Preprocessor. +class PCHValidator : public PCHReaderListener { + Preprocessor &PP; + PCHReader &Reader; + + unsigned NumHeaderInfos; + +public: + PCHValidator(Preprocessor &PP, PCHReader &Reader) + : PP(PP), Reader(Reader), NumHeaderInfos(0) {} + + virtual bool ReadLanguageOptions(const LangOptions &LangOpts); + virtual bool ReadTargetTriple(const std::string &Triple); + virtual bool ReadPredefinesBuffer(const char *PCHPredef, + unsigned PCHPredefLen, + FileID PCHBufferID, + std::string &SuggestedPredefines); + virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI); + virtual void ReadCounter(unsigned Value); +}; /// \brief Reads a precompiled head containing the contents of a /// translation unit. @@ -75,12 +151,19 @@ public: enum PCHReadResult { Success, Failure, IgnorePCH }; private: + /// \ brief The receiver of some callbacks invoked by PCHReader. + llvm::OwningPtr<PCHReaderListener> Listener; + + SourceManager &SourceMgr; + FileManager &FileMgr; + Diagnostic &Diags; + /// \brief The semantic analysis object that will be processing the /// PCH file and the translation unit that uses it. Sema *SemaObj; /// \brief The preprocessor that will be loading the source file. - Preprocessor &PP; + Preprocessor *PP; /// \brief The AST context into which we'll read the PCH file. ASTContext *Context; @@ -328,12 +411,33 @@ private: public: typedef llvm::SmallVector<uint64_t, 64> RecordData; - explicit PCHReader(Preprocessor &PP, ASTContext *Context); + /// \brief Load the PCH file and validate its contents against the given + /// Preprocessor. + PCHReader(Preprocessor &PP, ASTContext *Context); + + /// \brief Load the PCH file without using any pre-initialized Preprocessor. + /// + /// The necessary information to initialize a Preprocessor later can be + /// obtained by setting a PCHReaderListener. + PCHReader(SourceManager &SourceMgr, FileManager &FileMgr, Diagnostic &Diags); ~PCHReader(); /// \brief Load the precompiled header designated by the given file /// name. PCHReadResult ReadPCH(const std::string &FileName); + + /// \brief Set the PCH callbacks listener. + void setListener(PCHReaderListener *listener) { + Listener.reset(listener); + } + + /// \brief Set the Preprocessor to use. + void setPreprocessor(Preprocessor &pp) { + PP = &pp; + } + + /// \brief Sets and initializes the given Context. + void InitializeContext(ASTContext &Context); /// \brief Retrieve the name of the original source file name const std::string &getOriginalSourceFile() { return OriginalFileName; } diff --git a/include/clang/Frontend/StmtXML.def b/include/clang/Frontend/StmtXML.def new file mode 100644 index 000000000000..26430f740d91 --- /dev/null +++ b/include/clang/Frontend/StmtXML.def @@ -0,0 +1,517 @@ +//===-- StmtXML.def - Metadata about Stmt XML nodes ------------*- 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 XML statement database structure as written in +// <TranslationUnit> sub-nodes of the XML document. +// The semantics of the attributes and enums are mostly self-documenting +// by looking at the appropriate internally used functions and values. +// The following macros are used: +// +// NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete +// statement of class CLASS where CLASS is a class name used internally by clang. +// After a NODE_XML the definition of all (optional) attributes of that statement +// node and possible sub-nodes follows. +// +// END_NODE_XML - Closes the attribute definition of the current node. +// +// ID_ATTRIBUTE_XML - Some statement nodes have an "id" attribute containing a +// string, which value uniquely identify that statement. Other nodes may refer +// by reference attributes to this value (currently used only for Label). +// +// TYPE_ATTRIBUTE_XML( FN ) - Type nodes refer to the result type id of an +// expression by a "type" attribute. FN is internally used by clang. +// +// ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally +// used by clang. A boolean attribute have the values "0" or "1". +// +// ATTRIBUTE_SPECIAL_XML( FN, NAME ) - An attribute named NAME which deserves +// a special handling. See the appropriate documentations. +// +// ATTRIBUTE_FILE_LOCATION_XML - A bunch of attributes denoting the location of +// a statement in the source file(s). +// +// ATTRIBUTE_OPT_XML( FN, NAME ) - An optional attribute named NAME. +// Optional attributes are omitted for boolean types, if the value is false, +// for integral types, if the value is null and for strings, +// if the value is the empty string. FN is internally used by clang. +// +// ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value +// is an enumeration defined with ENUM_XML macros immediately following after +// that macro. An optional attribute is ommited, if the particular enum is the +// empty string. FN is internally used by clang. +// +// ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is +// internally used by clang. +// +// END_ENUM_XML - Closes the enumeration definition of the current attribute. +// +// SUB_NODE_XML( CLASS ) - A mandatory sub-node of class CLASS or its sub-classes. +// +// SUB_NODE_OPT_XML( CLASS ) - An optional sub-node of class CLASS or its sub-classes. +// +// SUB_NODE_SEQUENCE_XML( CLASS ) - Zero or more sub-nodes of class CLASS or +// its sub-classes. +// +//===----------------------------------------------------------------------===// + +#ifndef ATTRIBUTE_FILE_LOCATION_XML +# define ATTRIBUTE_FILE_LOCATION_XML \ + ATTRIBUTE_XML(getFilename(), "file") \ + ATTRIBUTE_XML(getLine(), "line") \ + ATTRIBUTE_XML(getColumn(), "col") \ + ATTRIBUTE_OPT_XML(getFilename(), "endfile") \ + ATTRIBUTE_OPT_XML(getLine(), "endline") \ + ATTRIBUTE_OPT_XML(getColumn(), "endcol") +#endif + +#ifndef TYPE_ATTRIBUTE_XML +# define TYPE_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "type") +#endif + +#ifndef CONTEXT_ATTRIBUTE_XML +# define CONTEXT_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "context") +#endif + + +NODE_XML(NullStmt, "NullStmt") + ATTRIBUTE_FILE_LOCATION_XML +END_NODE_XML + +NODE_XML(CompoundStmt, "CompoundStmt") + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(size(), "num_stmts") + SUB_NODE_SEQUENCE_XML(Stmt) +END_NODE_XML + +NODE_XML(CaseStmt, "CaseStmt") // case expr: body; + ATTRIBUTE_FILE_LOCATION_XML + SUB_NODE_XML(Stmt) // body + SUB_NODE_XML(Expr) // expr + SUB_NODE_XML(Expr) // rhs expr in gc extension: case expr .. expr: body; +END_NODE_XML + +NODE_XML(DefaultStmt, "DefaultStmt") // default: body; + ATTRIBUTE_FILE_LOCATION_XML + SUB_NODE_XML(Stmt) // body +END_NODE_XML + +NODE_XML(LabelStmt, "LabelStmt") // Label: body; + ID_ATTRIBUTE_XML + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getName(), "name") // string + SUB_NODE_XML(Stmt) // body +END_NODE_XML + +NODE_XML(IfStmt, "IfStmt") // if (cond) stmt1; else stmt2; + ATTRIBUTE_FILE_LOCATION_XML + SUB_NODE_XML(Expr) // cond + SUB_NODE_XML(Stmt) // stmt1 + SUB_NODE_XML(Stmt) // stmt2 +END_NODE_XML + +NODE_XML(SwitchStmt, "SwitchStmt") // switch (cond) body; + ATTRIBUTE_FILE_LOCATION_XML + SUB_NODE_XML(Expr) // cond + SUB_NODE_XML(Stmt) // body +END_NODE_XML + +NODE_XML(WhileStmt, "WhileStmt") // while (cond) body; + ATTRIBUTE_FILE_LOCATION_XML + SUB_NODE_XML(Expr) // cond + SUB_NODE_XML(Stmt) // body +END_NODE_XML + +NODE_XML(DoStmt, "DoStmt") // do body while (cond); + ATTRIBUTE_FILE_LOCATION_XML + SUB_NODE_XML(Expr) // cond + SUB_NODE_XML(Stmt) // body +END_NODE_XML + +NODE_XML(ForStmt, "ForStmt") // for (init; cond; inc) body; + ATTRIBUTE_FILE_LOCATION_XML + SUB_NODE_XML(Stmt) // init + SUB_NODE_XML(Expr) // cond + SUB_NODE_XML(Expr) // inc + SUB_NODE_XML(Stmt) // body +END_NODE_XML + +NODE_XML(GotoStmt, "GotoStmt") // goto label; + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getLabel()->getName(), "name") // informal string + ATTRIBUTE_XML(getLabel(), "ref") // id string +END_NODE_XML + +NODE_XML(IndirectGotoStmt, "IndirectGotoStmt") // goto expr; + ATTRIBUTE_FILE_LOCATION_XML + SUB_NODE_XML(Expr) // expr +END_NODE_XML + +NODE_XML(ContinueStmt, "ContinueStmt") // continue + ATTRIBUTE_FILE_LOCATION_XML +END_NODE_XML + +NODE_XML(BreakStmt, "BreakStmt") // break + ATTRIBUTE_FILE_LOCATION_XML +END_NODE_XML + +NODE_XML(ReturnStmt, "ReturnStmt") // return expr; + ATTRIBUTE_FILE_LOCATION_XML + SUB_NODE_XML(Expr) // expr +END_NODE_XML + +NODE_XML(AsmStmt, "AsmStmt") // GNU inline-assembly statement extension + ATTRIBUTE_FILE_LOCATION_XML + // FIXME +END_NODE_XML + +NODE_XML(DeclStmt, "DeclStmt") // a declaration statement + ATTRIBUTE_FILE_LOCATION_XML + SUB_NODE_SEQUENCE_XML(Decl) +END_NODE_XML + +// C++ statements +NODE_XML(CXXTryStmt, "CXXTryStmt") // try CompoundStmt CXXCatchStmt1 CXXCatchStmt2 .. + ATTRIBUTE_FILE_LOCATION_XML + ATTRIBUTE_XML(getNumHandlers(), "num_handlers") + SUB_NODE_XML(CompoundStmt) + SUB_NODE_SEQUENCE_XML(CXXCatchStmt) +END_NODE_XML + +NODE_XML(CXXCatchStmt, "CXXCatchStmt") // catch (decl) Stmt + ATTRIBUTE_FILE_LOCATION_XML + SUB_NODE_XML(VarDecl) + SUB_NODE_XML(Stmt) +END_NODE_XML + +// Expressions +NODE_XML(PredefinedExpr, "PredefinedExpr") + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_ENUM_XML(getIdentType(), "kind") + ENUM_XML(PredefinedExpr::Func, "__func__") + ENUM_XML(PredefinedExpr::Function, "__FUNCTION__") + ENUM_XML(PredefinedExpr::PrettyFunction, "__PRETTY_FUNCTION__") + END_ENUM_XML +END_NODE_XML + +NODE_XML(DeclRefExpr, "DeclRefExpr") // an expression referring to a declared entity + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_XML(getDecl(), "ref") // id string of the declaration + ATTRIBUTE_XML(getDecl()->getNameAsString(), "name") // informal + //ATTRIBUTE_ENUM_XML(getDecl()->getKind(), "kind") // really needed here? +END_NODE_XML + +NODE_XML(IntegerLiteral, "IntegerLiteral") + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_XML(getValue(), "value") // (signed) integer +END_NODE_XML + +NODE_XML(CharacterLiteral, "CharacterLiteral") + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_XML(getValue(), "value") // unsigned +END_NODE_XML + +NODE_XML(FloatingLiteral, "FloatingLiteral") + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + // FIXME: output float as written in source (no approximation or the like) + //ATTRIBUTE_XML(getValueAsApproximateDouble(), "value") // float +END_NODE_XML + +NODE_XML(StringLiteral, "StringLiteral") + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_SPECIAL_XML(getStrData(), "value") // string, special handling for escaping needed + ATTRIBUTE_OPT_XML(isWide(), "is_wide") // boolean +END_NODE_XML + +NODE_XML(UnaryOperator, "UnaryOperator") // op(expr) or (expr)op + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_ENUM_XML(getOpcode(), "kind") + ENUM_XML(UnaryOperator::PostInc, "postinc") + ENUM_XML(UnaryOperator::PostDec, "postdec") + ENUM_XML(UnaryOperator::PreInc, "preinc") + ENUM_XML(UnaryOperator::PreDec, "predec") + ENUM_XML(UnaryOperator::AddrOf, "addrof") + ENUM_XML(UnaryOperator::Deref, "deref") + ENUM_XML(UnaryOperator::Plus, "plus") + ENUM_XML(UnaryOperator::Minus, "minus") + ENUM_XML(UnaryOperator::Not, "not") // bitwise not + ENUM_XML(UnaryOperator::LNot, "lnot") // boolean not + ENUM_XML(UnaryOperator::Real, "__real") + ENUM_XML(UnaryOperator::Imag, "__imag") + ENUM_XML(UnaryOperator::Extension, "__extension__") + ENUM_XML(UnaryOperator::OffsetOf, "__builtin_offsetof") + END_ENUM_XML + SUB_NODE_XML(Expr) // expr +END_NODE_XML + +NODE_XML(BinaryOperator, "BinaryOperator") // (expr1) op (expr2) + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_ENUM_XML(getOpcode(), "kind") + ENUM_XML(BinaryOperator::PtrMemD , "ptrmemd") + ENUM_XML(BinaryOperator::PtrMemI , "ptrmemi") + ENUM_XML(BinaryOperator::Mul , "mul") + ENUM_XML(BinaryOperator::Div , "div") + ENUM_XML(BinaryOperator::Rem , "rem") + ENUM_XML(BinaryOperator::Add , "add") + ENUM_XML(BinaryOperator::Sub , "sub") + ENUM_XML(BinaryOperator::Shl , "shl") + ENUM_XML(BinaryOperator::Shr , "shr") + ENUM_XML(BinaryOperator::LT , "lt") + ENUM_XML(BinaryOperator::GT , "gt") + ENUM_XML(BinaryOperator::LE , "le") + ENUM_XML(BinaryOperator::GE , "ge") + ENUM_XML(BinaryOperator::EQ , "eq") + ENUM_XML(BinaryOperator::NE , "ne") + ENUM_XML(BinaryOperator::And , "and") // bitwise and + ENUM_XML(BinaryOperator::Xor , "xor") + ENUM_XML(BinaryOperator::Or , "or") // bitwise or + ENUM_XML(BinaryOperator::LAnd , "land") // boolean and + ENUM_XML(BinaryOperator::LOr , "lor") // boolean or + ENUM_XML(BinaryOperator::Assign , "assign") + ENUM_XML(BinaryOperator::MulAssign, "mulassign") + ENUM_XML(BinaryOperator::DivAssign, "divassign") + ENUM_XML(BinaryOperator::RemAssign, "remassign") + ENUM_XML(BinaryOperator::AddAssign, "addassign") + ENUM_XML(BinaryOperator::SubAssign, "subassign") + ENUM_XML(BinaryOperator::ShlAssign, "shlassign") + ENUM_XML(BinaryOperator::ShrAssign, "shrassign") + ENUM_XML(BinaryOperator::AndAssign, "andassign") + ENUM_XML(BinaryOperator::XorAssign, "xorassign") + ENUM_XML(BinaryOperator::OrAssign , "orassign") + ENUM_XML(BinaryOperator::Comma , "comma") + END_ENUM_XML + SUB_NODE_XML(Expr) // expr1 + SUB_NODE_XML(Expr) // expr2 +END_NODE_XML + +// FIXME: is there a special class needed or is BinaryOperator sufficient? +//NODE_XML(CompoundAssignOperator, "CompoundAssignOperator") + +NODE_XML(ConditionalOperator, "ConditionalOperator") // expr1 ? expr2 : expr3 + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + SUB_NODE_XML(Expr) // expr1 + SUB_NODE_XML(Expr) // expr2 + SUB_NODE_XML(Expr) // expr3 +END_NODE_XML + +NODE_XML(SizeOfAlignOfExpr, "SizeOfAlignOfExpr") // sizeof(expr) or alignof(expr) + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_XML(isSizeOf(), "is_sizeof") + ATTRIBUTE_XML(isArgumentType(), "is_type") // "1" if expr denotes a type + ATTRIBUTE_SPECIAL_XML(getArgumentType(), "type_ref") // optional, denotes the type of expr, if is_type=="1", special handling needed since getArgumentType() could assert + SUB_NODE_OPT_XML(Expr) // expr, if is_type=="0" +END_NODE_XML + +NODE_XML(ArraySubscriptExpr, "ArraySubscriptExpr") // expr1[expr2] + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + SUB_NODE_XML(Expr) // expr1 + SUB_NODE_XML(Expr) // expr2 +END_NODE_XML + +NODE_XML(CallExpr, "CallExpr") // fnexpr(arg1, arg2, ...) + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_XML(getNumArgs(), "num_args") // unsigned + SUB_NODE_XML(Expr) // fnexpr + SUB_NODE_SEQUENCE_XML(Expr) // arg1..argN +END_NODE_XML + +NODE_XML(MemberExpr, "MemberExpr") // expr->F or expr.F + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_XML(isArrow(), "is_deref") + ATTRIBUTE_XML(getMemberDecl(), "ref") // refers to F + ATTRIBUTE_XML(getMemberDecl()->getNameAsString(), "name") // informal + SUB_NODE_XML(Expr) // expr +END_NODE_XML + +NODE_XML(CStyleCastExpr, "CStyleCastExpr") // (type)expr + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_XML(getTypeAsWritten(), "type_ref") // denotes the type as written in the source code + SUB_NODE_XML(Expr) // expr +END_NODE_XML + +NODE_XML(ImplicitCastExpr, "ImplicitCastExpr") + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + SUB_NODE_XML(Expr) +END_NODE_XML + +NODE_XML(CompoundLiteralExpr, "CompoundLiteralExpr") // [C99 6.5.2.5] + SUB_NODE_XML(Expr) // init +END_NODE_XML + +NODE_XML(ExtVectorElementExpr, "ExtVectorElementExpr") + SUB_NODE_XML(Expr) // base +END_NODE_XML + +NODE_XML(InitListExpr, "InitListExpr") // struct foo x = { expr1, { expr2, expr3 } }; + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_OPT_XML(getInitializedFieldInUnion(), "field_ref") // if a union is initialized, this refers to the initialized union field id + ATTRIBUTE_XML(getNumInits(), "num_inits") // unsigned + SUB_NODE_SEQUENCE_XML(Expr) // expr1..exprN +END_NODE_XML + +NODE_XML(DesignatedInitExpr, "DesignatedInitExpr") + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) +END_NODE_XML + +NODE_XML(ImplicitValueInitExpr, "ImplicitValueInitExpr") // Implicit value initializations occur within InitListExpr + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) +END_NODE_XML + +NODE_XML(VAArgExpr, "VAArgExpr") // used for the builtin function __builtin_va_start(expr) + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + SUB_NODE_XML(Expr) // expr +END_NODE_XML + +NODE_XML(ParenExpr, "ParenExpr") // this represents a parethesized expression "(expr)". Only formed if full location information is requested. + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + SUB_NODE_XML(Expr) // expr +END_NODE_XML + +// GNU Extensions +NODE_XML(AddrLabelExpr, "AddrLabelExpr") // the GNU address of label extension, representing &&label. + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_XML(getLabel(), "ref") // id string + SUB_NODE_XML(LabelStmt) // expr +END_NODE_XML + +NODE_XML(StmtExpr, "StmtExpr") // StmtExpr contains a single CompoundStmt node, which it evaluates and takes the value of the last subexpression. + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + SUB_NODE_XML(CompoundStmt) +END_NODE_XML + +NODE_XML(TypesCompatibleExpr, "TypesCompatibleExpr") // GNU builtin-in function __builtin_types_compatible_p + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_XML(getArgType1(), "type1_ref") // id of type1 + ATTRIBUTE_XML(getArgType2(), "type2_ref") // id of type2 +END_NODE_XML + +NODE_XML(ChooseExpr, "ChooseExpr") // GNU builtin-in function __builtin_choose_expr(expr1, expr2, expr3) + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + SUB_NODE_XML(Expr) // expr1 + SUB_NODE_XML(Expr) // expr2 + SUB_NODE_XML(Expr) // expr3 +END_NODE_XML + +NODE_XML(GNUNullExpr, "GNUNullExpr") // GNU __null extension + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) +END_NODE_XML + +// C++ Expressions +NODE_XML(CXXOperatorCallExpr, "CXXOperatorCallExpr") // fnexpr(arg1, arg2, ...) + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_XML(getNumArgs(), "num_args") // unsigned + SUB_NODE_XML(Expr) // fnexpr + SUB_NODE_SEQUENCE_XML(Expr) // arg1..argN +END_NODE_XML + +NODE_XML(CXXNamedCastExpr, "CXXNamedCastExpr") // xxx_cast<type>(expr) + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_ENUM_XML(getStmtClass(), "kind") + ENUM_XML(Stmt::CXXStaticCastExprClass, "static_cast") + ENUM_XML(Stmt::CXXDynamicCastExprClass, "dynamic_cast") + ENUM_XML(Stmt::CXXReinterpretCastExprClass, "reinterpret_cast") + ENUM_XML(Stmt::CXXConstCastExprClass, "const_cast") + END_ENUM_XML + ATTRIBUTE_XML(getTypeAsWritten(), "type_ref") // denotes the type as written in the source code + SUB_NODE_XML(Expr) // expr +END_NODE_XML + +NODE_XML(CXXMemberCallExpr, "CXXMemberCallExpr") // fnexpr(arg1, arg2, ...) + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_XML(getNumArgs(), "num_args") // unsigned + SUB_NODE_XML(Expr) // fnexpr + SUB_NODE_SEQUENCE_XML(Expr) // arg1..argN +END_NODE_XML + +NODE_XML(CXXBoolLiteralExpr, "CXXBoolLiteralExpr") + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_XML(getValue(), "value") // boolean +END_NODE_XML + +NODE_XML(CXXNullPtrLiteralExpr, "CXXNullPtrLiteralExpr") // [C++0x 2.14.7] C++ Pointer Literal + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) +END_NODE_XML + +NODE_XML(CXXTypeidExpr, "CXXTypeidExpr") // typeid(expr) + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_XML(isTypeOperand(), "is_type") // "1" if expr denotes a type + ATTRIBUTE_SPECIAL_XML(getTypeOperand(), "type_ref") // optional, denotes the type of expr, if is_type=="1", special handling needed since getTypeOperand() could assert + SUB_NODE_OPT_XML(Expr) // expr, if is_type=="0" +END_NODE_XML + +NODE_XML(CXXThisExpr, "CXXThisExpr") // this + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) +END_NODE_XML + +NODE_XML(CXXThrowExpr, "CXXThrowExpr") // throw (expr); + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + SUB_NODE_XML(Expr) // NULL in case of "throw;" +END_NODE_XML + +NODE_XML(CXXDefaultArgExpr, "CXXDefaultArgExpr") + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + ATTRIBUTE_XML(getParam(), "ref") // id of the parameter declaration (the expression is a subnode of the declaration) +END_NODE_XML + +NODE_XML(CXXConditionDeclExpr, "CXXConditionDeclExpr") + ATTRIBUTE_FILE_LOCATION_XML + TYPE_ATTRIBUTE_XML(getType()) + SUB_NODE_XML(VarDecl) // a CXXConditionDeclExpr owns the declaration +END_NODE_XML + + +//===----------------------------------------------------------------------===// +#undef NODE_XML +#undef ID_ATTRIBUTE_XML +#undef TYPE_ATTRIBUTE_XML +#undef ATTRIBUTE_XML +#undef ATTRIBUTE_SPECIAL_XML +#undef ATTRIBUTE_OPT_XML +#undef ATTRIBUTE_ENUM_XML +#undef ATTRIBUTE_ENUM_OPT_XML +#undef ATTRIBUTE_FILE_LOCATION_XML +#undef ENUM_XML +#undef END_ENUM_XML +#undef END_NODE_XML +#undef SUB_NODE_XML +#undef SUB_NODE_SEQUENCE_XML +#undef SUB_NODE_OPT_XML diff --git a/include/clang/Frontend/TypeXML.def b/include/clang/Frontend/TypeXML.def new file mode 100644 index 000000000000..2a78fd9f75b1 --- /dev/null +++ b/include/clang/Frontend/TypeXML.def @@ -0,0 +1,277 @@ +//===-- TypeXML.def - Metadata about Type XML nodes ------------*- 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 XML type info database as written in the +// <ReferenceSection>/<Types> sub-nodes of the XML document. Type nodes +// are referred by "type" reference attributes throughout the document. +// A type node never contains sub-nodes. +// The semantics of the attributes and enums are mostly self-documenting +// by looking at the appropriate internally used functions and values. +// The following macros are used: +// +// NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete +// type of class CLASS where CLASS is a class name used internally by clang. +// After a NODE_XML the definition of all (optional) attributes of that type +// node follows. +// +// END_NODE_XML - Closes the attribute definition of the current node. +// +// ID_ATTRIBUTE_XML - Each type node has an "id" attribute containing a +// string, which value uniquely identify the type. Other nodes may refer +// by "type" reference attributes to this value. +// +// TYPE_ATTRIBUTE_XML( FN ) - Type nodes may refer to the ids of other type +// nodes by a "type" attribute. FN is internally used by clang. +// +// CONTEXT_ATTRIBUTE_XML( FN ) - Type nodes may refer to the ids of their +// declaration contexts by a "context" attribute. FN is internally used by +// clang. +// +// ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally +// used by clang. A boolean attribute have the values "0" or "1". +// +// ATTRIBUTE_OPT_XML( FN, NAME ) - An optional attribute named NAME. +// Optional attributes are omitted for boolean types, if the value is false, +// for integral types, if the value is null and for strings, +// if the value is the empty string. FN is internally used by clang. +// +// ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value +// is an enumeration defined with ENUM_XML macros immediately following after +// that macro. An optional attribute is ommited, if the particular enum is the +// empty string. FN is internally used by clang. +// +// ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is +// internally used by clang. +// +// END_ENUM_XML - Closes the enumeration definition of the current attribute. +// +//===----------------------------------------------------------------------===// + +#ifndef TYPE_ATTRIBUTE_XML +# define TYPE_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "type") +#endif + +#ifndef CONTEXT_ATTRIBUTE_XML +# define CONTEXT_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "context") +#endif + + +NODE_XML(QualType, "CvQualifiedType") + ID_ATTRIBUTE_XML + TYPE_ATTRIBUTE_XML(getTypePtr()) // the qualified type, e.g. for 'T* const' it's 'T*' + ATTRIBUTE_OPT_XML(isConstQualified(), "const") // boolean + ATTRIBUTE_OPT_XML(isVolatileQualified(), "volatile") // boolean + ATTRIBUTE_OPT_XML(isRestrictQualified(), "restrict") // boolean +END_NODE_XML + +NODE_XML(ExtQualType, "ExtQualType") + ID_ATTRIBUTE_XML + TYPE_ATTRIBUTE_XML(getBaseType()) + ATTRIBUTE_OPT_XML(getAddressSpace(), "adress_space") // unsigned: Address Space ID - The address space ID this type is qualified with. + ATTRIBUTE_ENUM_OPT_XML(getObjCGCAttr(), "objc_gc") // GC __weak/__strong attributes + ENUM_XML(QualType::GCNone, "") + ENUM_XML(QualType::Weak, "weak") + ENUM_XML(QualType::Strong, "strong") + END_ENUM_XML +END_NODE_XML + +NODE_XML(BuiltinType, "FundamentalType") + ID_ATTRIBUTE_XML + ATTRIBUTE_ENUM_XML(getKind(), "kind") + ENUM_XML(BuiltinType::Void, "void") + ENUM_XML(BuiltinType::Bool, "bool") + ENUM_XML(BuiltinType::Char_U, "char") // not explicitely qualified char, depends on target platform + ENUM_XML(BuiltinType::Char_S, "char") // not explicitely qualified char, depends on target platform + ENUM_XML(BuiltinType::SChar, "signed char") + ENUM_XML(BuiltinType::Short, "short"); + ENUM_XML(BuiltinType::Int, "int"); + ENUM_XML(BuiltinType::Long, "long"); + ENUM_XML(BuiltinType::LongLong, "long long"); + ENUM_XML(BuiltinType::Int128, "__int128_t"); + ENUM_XML(BuiltinType::UChar, "unsigned char"); + ENUM_XML(BuiltinType::UShort, "unsigned short"); + ENUM_XML(BuiltinType::UInt, "unsigned int"); + ENUM_XML(BuiltinType::ULong, "unsigned long"); + ENUM_XML(BuiltinType::ULongLong, "unsigned long long"); + ENUM_XML(BuiltinType::UInt128, "__uint128_t"); + ENUM_XML(BuiltinType::Float, "float"); + ENUM_XML(BuiltinType::Double, "double"); + ENUM_XML(BuiltinType::LongDouble, "long double"); + ENUM_XML(BuiltinType::WChar, "wchar_t"); + ENUM_XML(BuiltinType::NullPtr, "nullptr_t"); // This is the type of C++0x 'nullptr'. + ENUM_XML(BuiltinType::Overload, "overloaded"); + ENUM_XML(BuiltinType::Dependent, "dependent"); + END_ENUM_XML +END_NODE_XML + +NODE_XML(FixedWidthIntType, "FixedWidthIntType") + ID_ATTRIBUTE_XML + ATTRIBUTE_XML(getWidth(), "width") // unsigned + ATTRIBUTE_XML(isSigned(), "is_signed") // boolean +END_NODE_XML + +NODE_XML(PointerType, "PointerType") + ID_ATTRIBUTE_XML + TYPE_ATTRIBUTE_XML(getPointeeType()) +END_NODE_XML + +NODE_XML(LValueReferenceType, "ReferenceType") + ID_ATTRIBUTE_XML + TYPE_ATTRIBUTE_XML(getPointeeType()) +END_NODE_XML + +NODE_XML(RValueReferenceType, "ReferenceType") + ID_ATTRIBUTE_XML + TYPE_ATTRIBUTE_XML(getPointeeType()) +END_NODE_XML + +NODE_XML(FunctionNoProtoType, "FunctionNoProtoType") + ID_ATTRIBUTE_XML +END_NODE_XML + +NODE_XML(FunctionProtoType, "FunctionType") + ID_ATTRIBUTE_XML + ATTRIBUTE_XML(getResultType(), "result_type") + ATTRIBUTE_OPT_XML(isVariadic(), "variadic") +END_NODE_XML + +NODE_XML(TypedefType, "Typedef") + ID_ATTRIBUTE_XML + TYPE_ATTRIBUTE_XML(getDecl()->getUnderlyingType()) + ATTRIBUTE_XML(getDecl()->getNameAsString(), "name") // string + CONTEXT_ATTRIBUTE_XML(getDecl()->getDeclContext()) +END_NODE_XML + +NODE_XML(ComplexType, "ComplexType") // C99 complex types (_Complex float etc) + ID_ATTRIBUTE_XML + TYPE_ATTRIBUTE_XML(getElementType()) +END_NODE_XML + +NODE_XML(BlockPointerType, "BlockPointerType") + ID_ATTRIBUTE_XML + TYPE_ATTRIBUTE_XML(getPointeeType()) // alway refers to a function type +END_NODE_XML + +NODE_XML(MemberPointerType, "MemberPointerType") + ID_ATTRIBUTE_XML + TYPE_ATTRIBUTE_XML(getPointeeType()) + ATTRIBUTE_XML(getClass(), "class_type") // refers to the class type id of which the pointee is a member +END_NODE_XML + +NODE_XML(ConstantArrayType, "ArrayType") + ID_ATTRIBUTE_XML + TYPE_ATTRIBUTE_XML(getElementType()) + ATTRIBUTE_XML(getSize(), "size") // unsigned + ATTRIBUTE_ENUM_OPT_XML(getSizeModifier(), "size_modifier") + ENUM_XML(ArrayType::Normal, "") + ENUM_XML(ArrayType::Static, "static") + ENUM_XML(ArrayType::Star, "star") + END_ENUM_XML + ATTRIBUTE_OPT_XML(getIndexTypeQualifier(), "index_type_qualifier") // unsigned +END_NODE_XML + +NODE_XML(IncompleteArrayType, "IncompleteArrayType") + ID_ATTRIBUTE_XML + TYPE_ATTRIBUTE_XML(getElementType()) +END_NODE_XML + +NODE_XML(VariableArrayType, "VariableArrayType") + ID_ATTRIBUTE_XML + TYPE_ATTRIBUTE_XML(getElementType()) + // note: the size expression is print at the point of declaration +END_NODE_XML + +NODE_XML(DependentSizedArrayType, "DependentSizedArrayType") + ID_ATTRIBUTE_XML + TYPE_ATTRIBUTE_XML(getElementType()) + // FIXME: how to deal with size expression? +END_NODE_XML + +NODE_XML(VectorType, "VectorType") + ID_ATTRIBUTE_XML + TYPE_ATTRIBUTE_XML(getElementType()) + ATTRIBUTE_XML(getNumElements(), "size") // unsigned +END_NODE_XML + +NODE_XML(ExtVectorType, "ExtVectorType") + ID_ATTRIBUTE_XML + TYPE_ATTRIBUTE_XML(getElementType()) + ATTRIBUTE_XML(getNumElements(), "size") // unsigned +END_NODE_XML + +NODE_XML(TypeOfExprType, "TypeOfExprType") + ID_ATTRIBUTE_XML + // note: the typeof expression is print at the point of use +END_NODE_XML + +NODE_XML(TypeOfType, "TypeOfType") + ID_ATTRIBUTE_XML + TYPE_ATTRIBUTE_XML(getUnderlyingType()) +END_NODE_XML + + +NODE_XML(RecordType, "Record") + ID_ATTRIBUTE_XML + ATTRIBUTE_XML(getDecl()->getNameAsString(), "name") // string + ATTRIBUTE_ENUM_XML(getDecl()->getTagKind(), "kind") + ENUM_XML(TagDecl::TK_struct, "struct") + ENUM_XML(TagDecl::TK_union, "union") + ENUM_XML(TagDecl::TK_class, "class") + END_ENUM_XML + CONTEXT_ATTRIBUTE_XML(getDecl()->getDeclContext()) +END_NODE_XML + +NODE_XML(EnumType, "Enum") + ID_ATTRIBUTE_XML + ATTRIBUTE_XML(getDecl()->getNameAsString(), "name") // string + CONTEXT_ATTRIBUTE_XML(getDecl()->getDeclContext()) +END_NODE_XML + +NODE_XML(TemplateTypeParmType, "TemplateTypeParmType") + ID_ATTRIBUTE_XML +END_NODE_XML + +NODE_XML(TemplateSpecializationType, "TemplateSpecializationType") + ID_ATTRIBUTE_XML +END_NODE_XML + +NODE_XML(QualifiedNameType, "QualifiedNameType") + ID_ATTRIBUTE_XML + TYPE_ATTRIBUTE_XML(getNamedType()) +END_NODE_XML + +NODE_XML(TypenameType, "TypenameType") + ID_ATTRIBUTE_XML +END_NODE_XML + +NODE_XML(ObjCInterfaceType, "ObjCInterfaceType") + ID_ATTRIBUTE_XML +END_NODE_XML + +NODE_XML(ObjCQualifiedInterfaceType, "ObjCQualifiedInterfaceType") + ID_ATTRIBUTE_XML +END_NODE_XML + +NODE_XML(ObjCObjectPointerType, "ObjCObjectPointerType") + ID_ATTRIBUTE_XML +END_NODE_XML + + +//===----------------------------------------------------------------------===// +#undef NODE_XML +#undef ID_ATTRIBUTE_XML +#undef TYPE_ATTRIBUTE_XML +#undef CONTEXT_ATTRIBUTE_XML +#undef ATTRIBUTE_XML +#undef ATTRIBUTE_OPT_XML +#undef ATTRIBUTE_ENUM_XML +#undef ATTRIBUTE_ENUM_OPT_XML +#undef ENUM_XML +#undef END_ENUM_XML +#undef END_NODE_XML diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index f1207e4f0f73..5b57521f6751 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -248,6 +248,19 @@ public: virtual void ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS) { } + /// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse an + /// initializer for the declaration 'Dcl'. + /// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a + /// static data member of class X, names should be looked up in the scope of + /// class X. + virtual void ActOnCXXEnterDeclInitializer(Scope *S, DeclPtrTy Dcl) { + } + + /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an + /// initializer for the declaration 'Dcl'. + virtual void ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl) { + } + /// ActOnDeclarator - This callback is invoked when a declarator is parsed and /// 'Init' specifies the initializer if any. This is for things like: /// "int X = 4" or "typedef int foo". @@ -624,6 +637,18 @@ public: // Expression Parsing Callbacks. //===--------------------------------------------------------------------===// + /// \brief Notifies the action when the parser is processing an unevaluated + /// operand. + /// + /// \param UnevaluatedOperand true to indicate that the parser is processing + /// an unevaluated operand, or false otherwise. + /// + /// \returns whether the the action module was previously in an unevaluated + /// operand. + virtual bool setUnevaluatedOperand(bool UnevaluatedOperand) { + return false; + } + // Primary Expressions. /// \brief Retrieve the source range that corresponds to the given @@ -907,6 +932,15 @@ public: IdentifierInfo *Ident) { return DeclPtrTy(); } + + /// 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); /// ActOnParamDefaultArgument - Parse default argument for function parameter virtual void ActOnParamDefaultArgument(DeclPtrTy param, diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index d613ae132935..75458d821e8e 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -105,6 +105,24 @@ class Parser { } }; + /// \brief RAII object that enters an unevaluated operand. + class EnterUnevaluatedOperand { + /// \brief The action object. + Action &Actions; + + /// \brief Whether we were previously within an unevaluated operand. + bool PreviouslyInUnevaluatedOperand; + + public: + explicit EnterUnevaluatedOperand(Action &Actions) : Actions(Actions) { + PreviouslyInUnevaluatedOperand = Actions.setUnevaluatedOperand(true); + } + + ~EnterUnevaluatedOperand() { + Actions.setUnevaluatedOperand(PreviouslyInUnevaluatedOperand); + } + }; + public: Parser(Preprocessor &PP, Action &Actions); ~Parser(); |