aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorEd Schouten <ed@FreeBSD.org>2009-06-22 08:08:35 +0000
committerEd Schouten <ed@FreeBSD.org>2009-06-22 08:08:35 +0000
commitb897c8660c4ff7037dde81b9645737bc1c992abe (patch)
treeb6403365e77095a79062d3379c9e6aea0df5f088 /include
parent7ef7bab7e3d06f660b059b903c231f100bb13cc5 (diff)
downloadsrc-b897c8660c4ff7037dde81b9645737bc1c992abe.tar.gz
src-b897c8660c4ff7037dde81b9645737bc1c992abe.zip
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')
-rw-r--r--include/clang/AST/ASTContext.h34
-rw-r--r--include/clang/AST/Decl.h26
-rw-r--r--include/clang/AST/DeclBase.h45
-rw-r--r--include/clang/AST/DeclCXX.h81
-rw-r--r--include/clang/AST/DeclNodes.def1
-rw-r--r--include/clang/AST/DeclTemplate.h73
-rw-r--r--include/clang/AST/Expr.h14
-rw-r--r--include/clang/AST/ExprCXX.h11
-rw-r--r--include/clang/AST/ExprObjC.h8
-rw-r--r--include/clang/AST/Type.h150
-rw-r--r--include/clang/AST/TypeNodes.def3
-rw-r--r--include/clang/AST/TypeVisitor.h50
-rw-r--r--include/clang/Analysis/PathSensitive/ConstraintManager.h21
-rw-r--r--include/clang/Analysis/PathSensitive/Environment.h25
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h57
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h6
-rw-r--r--include/clang/Analysis/PathSensitive/GRState.h573
-rw-r--r--include/clang/Analysis/PathSensitive/GRTransferFuncs.h8
-rw-r--r--include/clang/Analysis/PathSensitive/MemRegion.h2
-rw-r--r--include/clang/Analysis/PathSensitive/SVals.h4
-rw-r--r--include/clang/Analysis/PathSensitive/Store.h107
-rw-r--r--include/clang/Analysis/PathSensitive/SymbolManager.h17
-rw-r--r--include/clang/Analysis/PathSensitive/ValueManager.h2
-rw-r--r--include/clang/Basic/Builtins.h5
-rw-r--r--include/clang/Basic/DiagnosticGroups.td12
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td10
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td18
-rw-r--r--include/clang/Basic/SourceLocation.h4
-rw-r--r--include/clang/Basic/SourceManager.h14
-rw-r--r--include/clang/Driver/Options.def6
-rw-r--r--include/clang/Driver/ToolChain.h2
-rw-r--r--include/clang/Frontend/ASTUnit.h75
-rw-r--r--include/clang/Frontend/DeclContextXML.def113
-rw-r--r--include/clang/Frontend/DeclXML.def250
-rw-r--r--include/clang/Frontend/DocumentXML.def75
-rw-r--r--include/clang/Frontend/DocumentXML.h84
-rw-r--r--include/clang/Frontend/PCHBitCodes.h4
-rw-r--r--include/clang/Frontend/PCHReader.h108
-rw-r--r--include/clang/Frontend/StmtXML.def517
-rw-r--r--include/clang/Frontend/TypeXML.def277
-rw-r--r--include/clang/Parse/Action.h34
-rw-r--r--include/clang/Parse/Parser.h18
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();