From 53992adde3eda3ccf9da63bc7e45673f043de18f Mon Sep 17 00:00:00 2001
From: rdivacky
In practice, the SourceLocation works together with the SourceManager class -to encode two pieces of information about a location: it's spelling location -and it's instantiation location. For most tokens, these will be the same. However, -for a macro expansion (or tokens that came from a _Pragma directive) these will -describe the location of the characters corresponding to the token and the -location where the token was used (i.e. the macro instantiation point or the -location of the _Pragma itself).
+to encode two pieces of information about a location: its spelling location +and its instantiation location. For most tokens, these will be the same. +However, for a macro expansion (or tokens that came from a _Pragma directive) +these will describe the location of the characters corresponding to the token +and the location where the token was used (i.e. the macro instantiation point +or the location of the _Pragma itself).The Clang front-end inherently depends on the location of a token being tracked correctly. If it is ever incorrect, the front-end may get confused and diff --git a/docs/UsersManual.html b/docs/UsersManual.html index 7d7f263..5c5f6f9 100644 --- a/docs/UsersManual.html +++ b/docs/UsersManual.html @@ -36,6 +36,7 @@ td {
For example, a format string warning will produce these three renditions +based on the setting of this option:
+ ++ t.c:3:11: warning: conversion specifies type 'char *' but the argument has type 'int' [-Wformat] + t.c:3:11: warning: conversion specifies type 'char *' but the argument has type 'int' [-Wformat,1] + t.c:3:11: warning: conversion specifies type 'char *' but the argument has type 'int' [-Wformat,Format String] ++ +
This category can be used by clients that want to group diagnostics by +category, so it should be a high level category. We want dozens of these, not +hundreds or thousands of them.
+For more information please see Formatting of Diagnostics.
+All diagnostics are mapped into one of these 5 classes:
@@ -420,7 +450,23 @@ Diagnostics.Though not shown by default, diagnostics may each be associated with a + high-level category. This category is intended to make it possible to triage + builds that produce a large number of errors or warnings in a grouped way. +
+ +Categories are not shown by default, but they can be turned on with the +-fdiagnostics-show-category option. +When set to "name", the category is printed textually in the diagnostic +output. When it is set to "id", a category number is printed. The +mapping of category names to category id's can be obtained by running 'clang + --print-diagnostic-categories'. +
+ +-W flags, -pedantic, etc
diff --git a/docs/tools/clang.pod b/docs/tools/clang.pod index 42cf8fa..0c1ab57 100644 --- a/docs/tools/clang.pod +++ b/docs/tools/clang.pod @@ -50,10 +50,13 @@ parse errors. The output of this stage is an "Abstract Syntax Tree" (AST). =item B
This stage translates an AST into low-level intermediate code (known as "LLVM
-IR") and ultimately to machine code (depending on the optimization level). This
-phase is responsible for optimizing the generated code and handling
-target-specfic code generation. The output of this stage is typically called a
-".s" file or "assembly" file.
+IR") and ultimately to machine code. This phase is responsible for optimizing
+the generated code and handling target-specfic code generation. The output of
+this stage is typically called a ".s" file or "assembly" file.
+
+Clang also supports the use of an integrated assembler, in which the code
+generator produces object files directly. This avoids the overhead of generating
+the ".s" file and of calling the target assembler.
=item B
@@ -325,17 +328,21 @@ Pass I to the assembler.
=item B<-Xclang> I
-Pass I to the clang compiler.
+Pass I to the clang compiler frontend.
=item B<-Xlinker> I
Pass I to the linker.
+=item B<-mllvm> I
+
+Pass I to the LLVM backend.
+
=item B<-Xpreprocessor> I
Pass I to the preprocessor.
-=item B<-o> I
+=item B<-o> I
Write output to I.
@@ -359,6 +366,12 @@ Print the paths used for finding libraries and programs.
Save intermediate compilation results.
+=item B<-integrated-as> B<-no-integrated-as>
+
+Used to enable and disable, respectively, the use of the integrated
+assembler. Whether the integrated assembler is on by default is target
+dependent.
+
=item B<-time>
Time individual commands.
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 1bf5a46..86926bd 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -343,6 +343,12 @@ CINDEX_LINKAGE CXSourceLocation clang_getRangeStart(CXSourceRange range);
CINDEX_LINKAGE CXSourceLocation clang_getRangeEnd(CXSourceRange range);
/**
+ * \brief Determine if the source location occurs within the main file
+ * of the translation unit (as opposed to an included header).
+ */
+CINDEX_LINKAGE unsigned clang_isFromMainFile(CXSourceLocation loc);
+
+/**
* @}
*/
@@ -648,7 +654,6 @@ CINDEX_LINKAGE void clang_disposeTranslationUnit(CXTranslationUnit);
*/
enum CXCursorKind {
/* Declarations */
- CXCursor_FirstDecl = 1,
/**
* \brief A declaration whose specific kind is not exposed via this
* interface.
@@ -700,11 +705,15 @@ enum CXCursorKind {
CXCursor_ObjCCategoryImplDecl = 19,
/** \brief A typedef */
CXCursor_TypedefDecl = 20,
-
/** \brief A C++ class method. */
CXCursor_CXXMethod = 21,
+ /** \brief A C++ namespace. */
+ CXCursor_Namespace = 22,
+ /** \brief A linkage specification, e.g. 'extern "C"'. */
+ CXCursor_LinkageSpec = 23,
- CXCursor_LastDecl = 21,
+ CXCursor_FirstDecl = CXCursor_UnexposedDecl,
+ CXCursor_LastDecl = CXCursor_LinkageSpec,
/* References */
CXCursor_FirstRef = 40, /* Decl references */
@@ -807,7 +816,8 @@ enum CXCursorKind {
CXCursor_IBActionAttr = 401,
CXCursor_IBOutletAttr = 402,
- CXCursor_LastAttr = CXCursor_IBOutletAttr,
+ CXCursor_IBOutletCollectionAttr = 403,
+ CXCursor_LastAttr = CXCursor_IBOutletCollectionAttr,
/* Preprocessing */
CXCursor_PreprocessingDirective = 500,
@@ -1021,6 +1031,124 @@ CINDEX_LINKAGE CXSourceRange clang_getCursorExtent(CXCursor);
*/
/**
+ * \defgroup CINDEX_TYPES Type information for CXCursors
+ *
+ * @{
+ */
+
+/**
+ * \brief Describes the kind of type
+ */
+enum CXTypeKind {
+ /**
+ * \brief Reprents an invalid type (e.g., where no type is available).
+ */
+ CXType_Invalid = 0,
+
+ /**
+ * \brief A type whose specific kind is not exposed via this
+ * interface.
+ */
+ CXType_Unexposed = 1,
+
+ /* Builtin types */
+ CXType_Void = 2,
+ CXType_Bool = 3,
+ CXType_Char_U = 4,
+ CXType_UChar = 5,
+ CXType_Char16 = 6,
+ CXType_Char32 = 7,
+ CXType_UShort = 8,
+ CXType_UInt = 9,
+ CXType_ULong = 10,
+ CXType_ULongLong = 11,
+ CXType_UInt128 = 12,
+ CXType_Char_S = 13,
+ CXType_SChar = 14,
+ CXType_WChar = 15,
+ CXType_Short = 16,
+ CXType_Int = 17,
+ CXType_Long = 18,
+ CXType_LongLong = 19,
+ CXType_Int128 = 20,
+ CXType_Float = 21,
+ CXType_Double = 22,
+ CXType_LongDouble = 23,
+ CXType_NullPtr = 24,
+ CXType_Overload = 25,
+ CXType_Dependent = 26,
+ CXType_ObjCId = 27,
+ CXType_ObjCClass = 28,
+ CXType_ObjCSel = 29,
+ CXType_FirstBuiltin = CXType_Void,
+ CXType_LastBuiltin = CXType_ObjCSel,
+
+ CXType_Complex = 100,
+ CXType_Pointer = 101,
+ CXType_BlockPointer = 102,
+ CXType_LValueReference = 103,
+ CXType_RValueReference = 104,
+ CXType_Record = 105,
+ CXType_Enum = 106,
+ CXType_Typedef = 107,
+ CXType_ObjCInterface = 108,
+ CXType_ObjCObjectPointer = 109
+};
+
+/**
+ * \brief The type of an element in the abstract syntax tree.
+ *
+ */
+typedef struct {
+ enum CXTypeKind kind;
+ void *data[2];
+} CXType;
+
+/**
+ * \brief Retrieve the type of a CXCursor (if any).
+ */
+CINDEX_LINKAGE CXType clang_getCursorType(CXCursor C);
+
+/**
+ * \determine Determine whether two CXTypes represent the same type.
+ *
+ * \returns non-zero if the CXTypes represent the same type and
+ zero otherwise.
+ */
+CINDEX_LINKAGE unsigned clang_equalTypes(CXType A, CXType B);
+
+/**
+ * \brief Return the canonical type for a CXType.
+ *
+ * Clang's type system explicitly models typedefs and all the ways
+ * a specific type can be represented. The canonical type is the underlying
+ * type with all the "sugar" removed. For example, if 'T' is a typedef
+ * for 'int', the canonical type for 'T' would be 'int'.
+ */
+CINDEX_LINKAGE CXType clang_getCanonicalType(CXType T);
+
+/**
+ * \brief For pointer types, returns the type of the pointee.
+ *
+ */
+CINDEX_LINKAGE CXType clang_getPointeeType(CXType T);
+
+/**
+ * \brief Return the cursor for the declaration of the given type.
+ */
+CINDEX_LINKAGE CXCursor clang_getTypeDeclaration(CXType T);
+
+
+/**
+ * \brief Retrieve the spelling of a given CXTypeKind.
+ */
+CINDEX_LINKAGE CXString clang_getTypeKindSpelling(enum CXTypeKind K);
+
+/**
+ * @}
+ */
+
+/**
* \defgroup CINDEX_CURSOR_TRAVERSAL Traversing the AST with cursors
*
* These routines provide the ability to traverse the abstract syntax tree
@@ -1220,6 +1348,24 @@ CINDEX_LINKAGE unsigned clang_isCursorDefinition(CXCursor);
*/
/**
+ * \defgroup CINDEX_CPP C++ AST introspection
+ *
+ * The routines in this group provide access information in the ASTs specific
+ * to C++ language features.
+ *
+ * @{
+ */
+
+/**
+ * \brief Determine if a C++ member function is declared 'static'.
+ */
+CINDEX_LINKAGE unsigned clang_CXXMethod_isStatic(CXCursor C);
+
+/**
+ * @}
+ */
+
+/**
* \defgroup CINDEX_LEX Token extraction and manipulation
*
* The routines in this group provide access to the tokens within a
@@ -1649,6 +1795,21 @@ CINDEX_LINKAGE unsigned
clang_getNumCompletionChunks(CXCompletionString completion_string);
/**
+ * \brief Determine the priority of this code completion.
+ *
+ * The priority of a code completion indicates how likely it is that this
+ * particular completion is the completion that the user will select. The
+ * priority is selected by various internal heuristics.
+ *
+ * \param completion_string The completion string to query.
+ *
+ * \returns The priority of this completion string. Smaller values indicate
+ * higher-priority (more likely) completions.
+ */
+CINDEX_LINKAGE unsigned
+clang_getCompletionPriority(CXCompletionString completion_string);
+
+/**
* \brief Contains the results of code-completion.
*
* This data structure contains the results of code completion, as
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index 53bb785..0611395 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -16,6 +16,7 @@
namespace clang {
class ASTContext;
+ class CXXRecordDecl;
class DeclGroupRef;
class TagDecl;
class HandleTagDeclDefinition;
@@ -68,6 +69,17 @@ public:
/// modified by the introduction of an implicit zero initializer.
virtual void CompleteTentativeDefinition(VarDecl *D) {}
+ /// \brief Callback involved at the end of a translation unit to
+ /// notify the consumer that a vtable for the given C++ class is
+ /// required.
+ ///
+ /// \param RD The class whose vtable was used.
+ ///
+ /// \param DefinitionRequired Whether a definition of this vtable is
+ /// required in this translation unit; otherwise, it is only needed if
+ /// it was actually used.
+ virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {}
+
/// PrintStats - If desired, print any statistics.
virtual void PrintStats() {}
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index f8a8f17..87a12cde 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -96,11 +96,10 @@ class ASTContext {
llvm::FoldingSet TemplateTypeParmTypes;
llvm::FoldingSet SubstTemplateTypeParmTypes;
llvm::FoldingSet TemplateSpecializationTypes;
- llvm::FoldingSet QualifiedNameTypes;
+ llvm::FoldingSet ElaboratedTypes;
llvm::FoldingSet DependentNameTypes;
- llvm::FoldingSet ObjCInterfaceTypes;
+ llvm::FoldingSet ObjCObjectTypes;
llvm::FoldingSet ObjCObjectPointerTypes;
- llvm::FoldingSet ElaboratedTypes;
llvm::FoldingSet QualifiedTemplateNames;
llvm::FoldingSet DependentTemplateNames;
@@ -483,7 +482,7 @@ public:
/// This gets the struct used to keep track of pointer to blocks, complete
/// with captured variables.
QualType getBlockParmType(bool BlockHasCopyDispose,
- llvm::SmallVector &BDRDs);
+ llvm::SmallVectorImpl &Layout);
/// This builds the struct used for __block variables.
QualType BuildByRefType(const char *DeclName, QualType Ty);
@@ -613,8 +612,9 @@ public:
const TemplateArgumentListInfo &Args,
QualType Canon = QualType());
- QualType getQualifiedNameType(NestedNameSpecifier *NNS,
- QualType NamedType);
+ QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS,
+ QualType NamedType);
QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,
const IdentifierInfo *Name,
@@ -623,19 +623,16 @@ public:
NestedNameSpecifier *NNS,
const TemplateSpecializationType *TemplateId,
QualType Canon = QualType());
- QualType getElaboratedType(QualType UnderlyingType,
- ElaboratedType::TagKind Tag);
- QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
- ObjCProtocolDecl **Protocols = 0,
- unsigned NumProtocols = 0);
+ QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl);
+
+ QualType getObjCObjectType(QualType Base,
+ ObjCProtocolDecl * const *Protocols,
+ unsigned NumProtocols);
- /// getObjCObjectPointerType - Return a ObjCObjectPointerType type for the
- /// given interface decl and the conforming protocol list.
- QualType getObjCObjectPointerType(QualType OIT,
- ObjCProtocolDecl **ProtocolList = 0,
- unsigned NumProtocols = 0,
- unsigned Quals = 0);
+ /// getObjCObjectPointerType - Return a ObjCObjectPointerType type
+ /// for the given ObjCObjectType.
+ QualType getObjCObjectPointerType(QualType OIT);
/// getTypeOfType - GCC extension.
QualType getTypeOfExprType(Expr *e);
@@ -913,6 +910,9 @@ public:
CharUnits getTypeAlignInChars(QualType T);
CharUnits getTypeAlignInChars(const Type *T);
+ std::pair getTypeInfoInChars(const Type *T);
+ std::pair getTypeInfoInChars(QualType T);
+
/// getPreferredTypeAlign - Return the "preferred" alignment of the specified
/// type for the current target in bits. This can be different than the ABI
/// alignment in cases where it is beneficial for performance to overalign
@@ -1184,8 +1184,8 @@ public:
// Check the safety of assignment from LHS to RHS
bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
const ObjCObjectPointerType *RHSOPT);
- bool canAssignObjCInterfaces(const ObjCInterfaceType *LHS,
- const ObjCInterfaceType *RHS);
+ bool canAssignObjCInterfaces(const ObjCObjectType *LHS,
+ const ObjCObjectType *RHS);
bool canAssignObjCInterfacesInBlockPointer(
const ObjCObjectPointerType *LHSOPT,
const ObjCObjectPointerType *RHSOPT);
@@ -1196,6 +1196,8 @@ public:
// Functions for calculating composite types
QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false);
QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false);
+
+ QualType mergeObjCGCQualifiers(QualType, QualType);
/// UsualArithmeticConversionsType - handles the various conversions
/// that are common to binary operators (C99 6.3.1.8, C++ [expr]p9)
@@ -1270,6 +1272,15 @@ public:
TypeSourceInfo *
getTrivialTypeSourceInfo(QualType T, SourceLocation Loc = SourceLocation());
+ /// \brief Add a deallocation callback that will be invoked when the
+ /// ASTContext is destroyed.
+ ///
+ /// \brief Callback A callback function that will be invoked on destruction.
+ ///
+ /// \brief Data Pointer data that will be provided to the callback function
+ /// when it is called.
+ void AddDeallocation(void (*Callback)(void*), void *Data);
+
private:
ASTContext(const ASTContext&); // DO NOT IMPLEMENT
void operator=(const ASTContext&); // DO NOT IMPLEMENT
@@ -1284,16 +1295,21 @@ private:
const FieldDecl *Field,
bool OutermostType = false,
bool EncodingProperty = false);
-
+
const ASTRecordLayout &getObjCLayout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl);
private:
+ /// \brief A set of deallocations that should be performed when the
+ /// ASTContext is destroyed.
+ llvm::SmallVector, 16> Deallocations;
+
// FIXME: This currently contains the set of StoredDeclMaps used
// by DeclContext objects. This probably should not be in ASTContext,
// but we include it here so that ASTContext can quickly deallocate them.
llvm::PointerIntPair LastSDM;
friend class DeclContext;
+ friend class DeclarationNameTable;
void ReleaseDeclContextMaps();
};
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 1974493..3240e50 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -23,9 +23,10 @@ using llvm::dyn_cast;
namespace clang {
class ASTContext;
+ class IdentifierInfo;
+ class ObjCInterfaceDecl;
}
-
// Defined in ASTContext.h
void *operator new(size_t Bytes, clang::ASTContext &C,
size_t Alignment = 16) throw ();
@@ -44,6 +45,7 @@ public:
enum Kind {
Alias,
Aligned,
+ AlignMac68k,
AlwaysInline,
AnalyzerNoReturn, // Clang-specific.
Annotate,
@@ -63,8 +65,10 @@ public:
GNUInline,
Hiding,
IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro.
+ IBOutletCollectionKind, // Clang-specific.
IBActionKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro.
Malloc,
+ MaxFieldAlignment,
NoDebug,
NoInline,
NonNull,
@@ -79,13 +83,13 @@ public:
NSReturnsNotRetained, // Clang/Checker-specific.
Overloadable, // Clang-specific
Packed,
- PragmaPack,
Pure,
Regparm,
ReqdWorkGroupSize, // OpenCL-specific
Section,
Sentinel,
StdCall,
+ ThisCall,
TransparentUnion,
Unavailable,
Unused,
@@ -183,11 +187,14 @@ public: \
DEF_SIMPLE_ATTR(Packed);
-class PragmaPackAttr : public Attr {
+/// \brief Attribute for specifying a maximum field alignment; this is only
+/// valid on record decls.
+class MaxFieldAlignmentAttr : public Attr {
unsigned Alignment;
public:
- PragmaPackAttr(unsigned alignment) : Attr(PragmaPack), Alignment(alignment) {}
+ MaxFieldAlignmentAttr(unsigned alignment)
+ : Attr(MaxFieldAlignment), Alignment(alignment) {}
/// getAlignment - The specified alignment in bits.
unsigned getAlignment() const { return Alignment; }
@@ -196,11 +203,13 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
- return A->getKind() == PragmaPack;
+ return A->getKind() == MaxFieldAlignment;
}
- static bool classof(const PragmaPackAttr *A) { return true; }
+ static bool classof(const MaxFieldAlignmentAttr *A) { return true; }
};
+DEF_SIMPLE_ATTR(AlignMac68k);
+
class AlignedAttr : public Attr {
unsigned Alignment;
public:
@@ -317,6 +326,23 @@ public:
static bool classof(const IBOutletAttr *A) { return true; }
};
+class IBOutletCollectionAttr : public Attr {
+ const ObjCInterfaceDecl *D;
+public:
+ IBOutletCollectionAttr(const ObjCInterfaceDecl *d = 0)
+ : Attr(IBOutletCollectionKind), D(d) {}
+
+ const ObjCInterfaceDecl *getClass() const { return D; }
+
+ virtual Attr *clone(ASTContext &C) const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) {
+ return A->getKind() == IBOutletCollectionKind;
+ }
+ static bool classof(const IBOutletCollectionAttr *A) { return true; }
+};
+
class IBActionAttr : public Attr {
public:
IBActionAttr() : Attr(IBActionKind) {}
@@ -457,6 +483,7 @@ public:
DEF_SIMPLE_ATTR(FastCall);
DEF_SIMPLE_ATTR(StdCall);
+DEF_SIMPLE_ATTR(ThisCall);
DEF_SIMPLE_ATTR(CDecl);
DEF_SIMPLE_ATTR(TransparentUnion);
DEF_SIMPLE_ATTR(ObjCNSObject);
diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt
new file mode 100644
index 0000000..c24ea06
--- /dev/null
+++ b/include/clang/AST/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(LLVM_TARGET_DEFINITIONS StmtNodes.td)
+tablegen(StmtNodes.inc
+ -gen-clang-stmt-nodes)
+add_custom_target(ClangStmtNodes
+ DEPENDS StmtNodes.inc)
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index edd633e..5a84e40 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -196,7 +196,7 @@ public:
/// \brief Determine whether the path from the most-derived type to the
/// given base type is ambiguous (i.e., it refers to multiple subobjects of
/// the same base type).
- bool isAmbiguous(QualType BaseType);
+ bool isAmbiguous(CanQualType BaseType);
/// \brief Whether we are finding multiple paths to detect ambiguities.
bool isFindingAmbiguities() const { return FindAmbiguities; }
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 93dcad7..4afb81d 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -643,6 +643,24 @@ struct CanProxyAdaptor
};
template<>
+struct CanProxyAdaptor
+ : public CanProxyBase {
+ LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *,
+ getInterface)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
+
+ typedef ObjCObjectPointerType::qual_iterator qual_iterator;
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
+};
+
+template<>
struct CanProxyAdaptor
: public CanProxyBase {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 834c9a0..7d5b66e 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -55,7 +55,7 @@ public:
QualType getType() const { return Ty; }
/// \brief Return the TypeLoc wrapper for the type source info.
- TypeLoc getTypeLoc() const;
+ TypeLoc getTypeLoc() const; // implemented in TypeLoc.h
};
/// TranslationUnitDecl - The top declaration context.
@@ -138,6 +138,8 @@ public:
// FIXME: Deprecated, move clients to getName().
std::string getNameAsString() const { return Name.getAsString(); }
+ void printName(llvm::raw_ostream &os) const { return Name.printName(os); }
+
/// getDeclName - Get the actual, stored name of the declaration,
/// which may be a special name.
DeclarationName getDeclName() const { return Name; }
@@ -265,18 +267,25 @@ public:
// \brief Returns true if this is an anonymous namespace declaration.
//
// For example:
+ /// \code
// namespace {
// ...
// };
+ // \endcode
// q.v. C++ [namespace.unnamed]
bool isAnonymousNamespace() const {
return !getIdentifier();
}
+ /// \brief Return the next extended namespace declaration or null if this
+ /// is none.
NamespaceDecl *getNextNamespace() { return NextNamespace; }
const NamespaceDecl *getNextNamespace() const { return NextNamespace; }
+
+ /// \brief Set the next extended namespace declaration.
void setNextNamespace(NamespaceDecl *ND) { NextNamespace = ND; }
+ /// \brief Get the original (first) namespace declaration.
NamespaceDecl *getOriginalNamespace() const {
if (OrigOrAnonNamespace.getInt())
return const_cast(this);
@@ -284,6 +293,14 @@ public:
return OrigOrAnonNamespace.getPointer();
}
+ /// \brief Return true if this declaration is an original (first) declaration
+ /// of the namespace. This is false for non-original (subsequent) namespace
+ /// declarations and anonymous namespaces.
+ bool isOriginalNamespace() const {
+ return getOriginalNamespace() == this;
+ }
+
+ /// \brief Set the original (first) namespace declaration.
void setOriginalNamespace(NamespaceDecl *ND) {
if (ND != this) {
OrigOrAnonNamespace.setPointer(ND);
@@ -502,6 +519,10 @@ private:
/// or an Objective-C @catch statement.
bool ExceptionVar : 1;
+ /// \brief Whether this local variable could be allocated in the return
+ /// slot of its function, enabling the named return value optimization (NRVO).
+ bool NRVOVariable : 1;
+
friend class StmtIteratorBase;
protected:
VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
@@ -509,7 +530,7 @@ protected:
StorageClass SCAsWritten)
: DeclaratorDecl(DK, DC, L, Id, T, TInfo), Init(),
ThreadSpecified(false), HasCXXDirectInit(false),
- DeclaredInCondition(false), ExceptionVar(false) {
+ DeclaredInCondition(false), ExceptionVar(false), NRVOVariable(false) {
SClass = SC;
SClassAsWritten = SCAsWritten;
}
@@ -852,6 +873,19 @@ public:
}
void setExceptionVariable(bool EV) { ExceptionVar = EV; }
+ /// \brief Determine whether this local variable can be used with the named
+ /// return value optimization (NRVO).
+ ///
+ /// The named return value optimization (NRVO) works by marking certain
+ /// non-volatile local variables of class type as NRVO objects. These
+ /// locals can be allocated within the return slot of their containing
+ /// function, in which case there is no need to copy the object to the
+ /// return slot when returning from the function. Within the function body,
+ /// each return that returns the NRVO object will have this variable as its
+ /// NRVO candidate.
+ bool isNRVOVariable() const { return NRVOVariable; }
+ void setNRVOVariable(bool NRVO) { NRVOVariable = NRVO; }
+
/// \brief If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
/// from which it was instantiated.
@@ -1390,6 +1424,16 @@ public:
/// returns NULL.
const TemplateArgumentList *getTemplateSpecializationArgs() const;
+ /// \brief Retrieve the template argument list as written in the sources,
+ /// if any.
+ ///
+ /// If this function declaration is not a function template specialization
+ /// or if it had no explicit template argument list, returns NULL.
+ /// Note that it an explicit template argument list may be written empty,
+ /// e.g., template<> void foo<>(char* s);
+ const TemplateArgumentListInfo*
+ getTemplateSpecializationArgsAsWritten() const;
+
/// \brief Specify that this function declaration is actually a function
/// template specialization.
///
@@ -1409,7 +1453,8 @@ public:
void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
const TemplateArgumentList *TemplateArgs,
void *InsertPos,
- TemplateSpecializationKind TSK = TSK_ImplicitInstantiation);
+ TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
+ const TemplateArgumentListInfo *TemplateArgsAsWritten = 0);
/// \brief Specifies that this function declaration is actually a
/// dependent function template specialization.
@@ -1593,7 +1638,19 @@ class TypedefDecl : public TypeDecl, public Redeclarable {
: TypeDecl(Typedef, DC, L, Id), TInfo(TInfo) {}
virtual ~TypedefDecl();
+
+protected:
+ typedef Redeclarable redeclarable_base;
+ virtual TypedefDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+
public:
+ typedef redeclarable_base::redecl_iterator redecl_iterator;
+ redecl_iterator redecls_begin() const {
+ return redeclarable_base::redecls_begin();
+ }
+ redecl_iterator redecls_end() const {
+ return redeclarable_base::redecls_end();
+ }
static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
@@ -1631,11 +1688,7 @@ class TagDecl
: public TypeDecl, public DeclContext, public Redeclarable {
public:
// This is really ugly.
- typedef ElaboratedType::TagKind TagKind;
- static const TagKind TK_struct = ElaboratedType::TK_struct;
- static const TagKind TK_union = ElaboratedType::TK_union;
- static const TagKind TK_class = ElaboratedType::TK_class;
- static const TagKind TK_enum = ElaboratedType::TK_enum;
+ typedef TagTypeKind TagKind;
private:
// FIXME: This can be packed into the bitfields in Decl.
@@ -1651,6 +1704,12 @@ private:
/// in the syntax of a declarator.
bool IsEmbeddedInDeclarator : 1;
+protected:
+ // These are used by (and only defined for) EnumDecl.
+ unsigned NumPositiveBits : 8;
+ unsigned NumNegativeBits : 8;
+
+private:
SourceLocation TagKeywordLoc;
SourceLocation RBraceLoc;
@@ -1680,7 +1739,8 @@ protected:
TagDecl *PrevDecl, SourceLocation TKL = SourceLocation())
: TypeDecl(DK, DC, L, Id), DeclContext(DK), TagKeywordLoc(TKL),
TypedefDeclOrQualifier((TypedefDecl*) 0) {
- assert((DK != Enum || TK == TK_enum) &&"EnumDecl not matched with TK_enum");
+ assert((DK != Enum || TK == TTK_Enum) &&
+ "EnumDecl not matched with TTK_Enum");
TagDeclKind = TK;
IsDefinition = false;
IsEmbeddedInDeclarator = false;
@@ -1753,30 +1813,26 @@ public:
void setDefinition(bool V) { IsDefinition = V; }
const char *getKindName() const {
- return ElaboratedType::getNameForTagKind(getTagKind());
+ return TypeWithKeyword::getTagTypeKindName(getTagKind());
}
- /// getTagKindForTypeSpec - Converts a type specifier (DeclSpec::TST)
- /// into a tag kind. It is an error to provide a type specifier
- /// which *isn't* a tag kind here.
- static TagKind getTagKindForTypeSpec(unsigned TypeSpec);
-
TagKind getTagKind() const {
return TagKind(TagDeclKind);
}
void setTagKind(TagKind TK) { TagDeclKind = TK; }
- bool isStruct() const { return getTagKind() == TK_struct; }
- bool isClass() const { return getTagKind() == TK_class; }
- bool isUnion() const { return getTagKind() == TK_union; }
- bool isEnum() const { return getTagKind() == TK_enum; }
+ bool isStruct() const { return getTagKind() == TTK_Struct; }
+ bool isClass() const { return getTagKind() == TTK_Class; }
+ bool isUnion() const { return getTagKind() == TTK_Union; }
+ bool isEnum() const { return getTagKind() == TTK_Enum; }
TypedefDecl *getTypedefForAnonDecl() const {
return hasExtInfo() ? 0 : TypedefDeclOrQualifier.get();
}
- void setTypedefForAnonDecl(TypedefDecl *TDD) { TypedefDeclOrQualifier = TDD; }
-
+
+ void setTypedefForAnonDecl(TypedefDecl *TDD);
+
NestedNameSpecifier *getQualifier() const {
return hasExtInfo() ? TypedefDeclOrQualifier.get()->NNS : 0;
}
@@ -1820,9 +1876,16 @@ class EnumDecl : public TagDecl {
/// enumeration declared within the template.
EnumDecl *InstantiatedFrom;
+ // The number of positive and negative bits required by the
+ // enumerators are stored in the SubclassBits field.
+ enum {
+ NumBitsWidth = 8,
+ NumBitsMask = (1 << NumBitsWidth) - 1
+ };
+
EnumDecl(DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, EnumDecl *PrevDecl, SourceLocation TKL)
- : TagDecl(Enum, TK_enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
+ : TagDecl(Enum, TTK_Enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
IntegerType = QualType();
}
public:
@@ -1845,7 +1908,9 @@ public:
/// added (via DeclContext::addDecl). NewType is the new underlying
/// type of the enumeration type.
void completeDefinition(QualType NewType,
- QualType PromotionType);
+ QualType PromotionType,
+ unsigned NumPositiveBits,
+ unsigned NumNegativeBits);
// enumerator_iterator - Iterates through the enumerators of this
// enumeration.
@@ -1873,6 +1938,32 @@ public:
/// \brief Set the underlying integer type.
void setIntegerType(QualType T) { IntegerType = T; }
+ /// \brief Returns the width in bits requred to store all the
+ /// non-negative enumerators of this enum.
+ unsigned getNumPositiveBits() const {
+ return NumPositiveBits;
+ }
+ void setNumPositiveBits(unsigned Num) {
+ NumPositiveBits = Num;
+ assert(NumPositiveBits == Num && "can't store this bitcount");
+ }
+
+ /// \brief Returns the width in bits requred to store all the
+ /// negative enumerators of this enum. These widths include
+ /// the rightmost leading 1; that is:
+ ///
+ /// MOST NEGATIVE ENUMERATOR PATTERN NUM NEGATIVE BITS
+ /// ------------------------ ------- -----------------
+ /// -1 1111111 1
+ /// -10 1110110 5
+ /// -101 1001011 8
+ unsigned getNumNegativeBits() const {
+ return NumNegativeBits;
+ }
+ void setNumNegativeBits(unsigned Num) {
+ NumNegativeBits = Num;
+ }
+
/// \brief Returns the enumeration (declared within the template)
/// from which this enumeration type was instantiated, or NULL if
/// this enumeration was not instantiated from any template.
@@ -1942,6 +2033,11 @@ public:
AnonymousStructOrUnion = Anon;
}
+ ValueDecl *getAnonymousStructOrUnionObject();
+ const ValueDecl *getAnonymousStructOrUnionObject() const {
+ return const_cast(this)->getAnonymousStructOrUnionObject();
+ }
+
bool hasObjectMember() const { return HasObjectMember; }
void setHasObjectMember (bool val) { HasObjectMember = val; }
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index a9b948e..c15aeef 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -76,6 +76,11 @@ public:
#include "clang/AST/DeclNodes.def"
};
+ /// \brief A placeholder type used to construct an empty shell of a
+ /// decl-derived type that will be filled in later (e.g., by some
+ /// deserialization method).
+ struct EmptyShell { };
+
/// IdentifierNamespace - The different namespaces in which
/// declarations may appear. According to C99 6.2.3, there are
/// four namespaces, labels, tags, members and ordinary
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index aa649c8..c19c200 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -1061,10 +1061,6 @@ class CXXBaseOrMemberInitializer {
/// In above example, BaseOrMember holds the field decl. for anonymous union
/// and AnonUnionMember holds field decl for au_i1.
FieldDecl *AnonUnionMember;
-
- /// IsVirtual - If the initializer is a base initializer, this keeps track
- /// of whether the base is virtual or not.
- bool IsVirtual;
/// LParenLoc - Location of the left paren of the ctor-initializer.
SourceLocation LParenLoc;
@@ -1072,6 +1068,28 @@ class CXXBaseOrMemberInitializer {
/// RParenLoc - Location of the right paren of the ctor-initializer.
SourceLocation RParenLoc;
+ /// IsVirtual - If the initializer is a base initializer, this keeps track
+ /// of whether the base is virtual or not.
+ bool IsVirtual : 1;
+
+ /// IsWritten - Whether or not the initializer is explicitly written
+ /// in the sources.
+ bool IsWritten : 1;
+ /// SourceOrderOrNumArrayIndices - If IsWritten is true, then this
+ /// number keeps track of the textual order of this initializer in the
+ /// original sources, counting from 0; otherwise, if IsWritten is false,
+ /// it stores the number of array index variables stored after this
+ /// object in memory.
+ unsigned SourceOrderOrNumArrayIndices : 14;
+
+ CXXBaseOrMemberInitializer(ASTContext &Context,
+ FieldDecl *Member, SourceLocation MemberLoc,
+ SourceLocation L,
+ Expr *Init,
+ SourceLocation R,
+ VarDecl **Indices,
+ unsigned NumIndices);
+
public:
/// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
explicit
@@ -1089,6 +1107,17 @@ public:
Expr *Init,
SourceLocation R);
+ /// \brief Creates a new member initializer that optionally contains
+ /// array indices used to describe an elementwise initialization.
+ static CXXBaseOrMemberInitializer *Create(ASTContext &Context,
+ FieldDecl *Member,
+ SourceLocation MemberLoc,
+ SourceLocation L,
+ Expr *Init,
+ SourceLocation R,
+ VarDecl **Indices,
+ unsigned NumIndices);
+
/// \brief Destroy the base or member initializer.
void Destroy(ASTContext &Context);
@@ -1146,6 +1175,30 @@ public:
/// \brief Determine the source range covering the entire initializer.
SourceRange getSourceRange() const;
+
+ /// isWritten - Returns true if this initializer is explicitly written
+ /// in the source code.
+ bool isWritten() const { return IsWritten; }
+
+ /// \brief Return the source position of the initializer, counting from 0.
+ /// If the initializer was implicit, -1 is returned.
+ int getSourceOrder() const {
+ return IsWritten ? static_cast(SourceOrderOrNumArrayIndices) : -1;
+ }
+
+ /// \brief Set the source order of this initializer. This method can only
+ /// be called once for each initializer; it cannot be called on an
+ /// initializer having a positive number of (implicit) array indices.
+ void setSourceOrder(int pos) {
+ assert(!IsWritten &&
+ "calling twice setSourceOrder() on the same initializer");
+ assert(SourceOrderOrNumArrayIndices == 0 &&
+ "setSourceOrder() used when there are implicit array indices");
+ assert(pos >= 0 &&
+ "setSourceOrder() used to make an initializer implicit");
+ IsWritten = true;
+ SourceOrderOrNumArrayIndices = static_cast(pos);
+ }
FieldDecl *getAnonUnionMember() const {
return AnonUnionMember;
@@ -1154,9 +1207,31 @@ public:
AnonUnionMember = anonMember;
}
+
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
+ /// \brief Determine the number of implicit array indices used while
+ /// described an array member initialization.
+ unsigned getNumArrayIndices() const {
+ return IsWritten ? 0 : SourceOrderOrNumArrayIndices;
+ }
+
+ /// \brief Retrieve a particular array index variable used to
+ /// describe an array member initialization.
+ VarDecl *getArrayIndex(unsigned I) {
+ assert(I < getNumArrayIndices() && "Out of bounds member array index");
+ return reinterpret_cast(this + 1)[I];
+ }
+ const VarDecl *getArrayIndex(unsigned I) const {
+ assert(I < getNumArrayIndices() && "Out of bounds member array index");
+ return reinterpret_cast(this + 1)[I];
+ }
+ void setArrayIndex(unsigned I, VarDecl *Index) {
+ assert(I < getNumArrayIndices() && "Out of bounds member array index");
+ reinterpret_cast(this + 1)[I] = Index;
+ }
+
Expr *getInit() { return static_cast(Init); }
};
@@ -1201,6 +1276,7 @@ class CXXConstructorDecl : public CXXMethodDecl {
virtual void Destroy(ASTContext& C);
public:
+ static CXXConstructorDecl *Create(ASTContext &C, EmptyShell Empty);
static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
QualType T, TypeSourceInfo *TInfo,
@@ -1343,6 +1419,7 @@ class CXXDestructorDecl : public CXXMethodDecl {
}
public:
+ static CXXDestructorDecl *Create(ASTContext& C, EmptyShell Empty);
static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
QualType T, bool isInline,
@@ -1398,6 +1475,7 @@ class CXXConversionDecl : public CXXMethodDecl {
IsExplicitSpecified(isExplicitSpecified) { }
public:
+ static CXXConversionDecl *Create(ASTContext &C, EmptyShell Empty);
static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
QualType T, TypeSourceInfo *TInfo,
@@ -1438,8 +1516,10 @@ public:
/// ASTs and cannot be changed without altering that abi. To help
/// ensure a stable abi for this, we choose the DW_LANG_ encodings
/// from the dwarf standard.
- enum LanguageIDs { lang_c = /* DW_LANG_C */ 0x0002,
- lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004 };
+ enum LanguageIDs {
+ lang_c = /* DW_LANG_C */ 0x0002,
+ lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004
+ };
private:
/// Language - The language for this linkage specification.
LanguageIDs Language;
@@ -1457,12 +1537,20 @@ public:
SourceLocation L, LanguageIDs Lang,
bool Braces);
+ /// \brief Return the language specified by this linkage specification.
LanguageIDs getLanguage() const { return Language; }
- /// hasBraces - Determines whether this linkage specification had
- /// braces in its syntactic form.
+ /// \brief Set the language specified by this linkage specification.
+ void setLanguage(LanguageIDs L) { Language = L; }
+
+ /// \brief Determines whether this linkage specification had braces in
+ /// its syntactic form.
bool hasBraces() const { return HadBraces; }
+ /// \brief Set whether this linkage specification has braces in its
+ /// syntactic form.
+ void setHasBraces(bool B) { HadBraces = B; }
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const LinkageSpecDecl *D) { return true; }
static bool classofKind(Kind K) { return K == LinkageSpec; }
@@ -1528,13 +1616,21 @@ class UsingDirectiveDecl : public NamedDecl {
public:
/// \brief Retrieve the source range of the nested-name-specifier
- /// that qualifiers the namespace name.
+ /// that qualifies the namespace name.
SourceRange getQualifierRange() const { return QualifierRange; }
+ /// \brief Set the source range of the nested-name-specifier that
+ /// qualifies the namespace name.
+ void setQualifierRange(SourceRange R) { QualifierRange = R; }
+
/// \brief Retrieve the nested-name-specifier that qualifies the
/// name of the namespace.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
+ /// \brief Set the nested-name-specifier that qualifes the name of the
+ /// namespace.
+ void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
+
NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; }
const NamedDecl *getNominatedNamespaceAsWritten() const {
return NominatedNamespace;
@@ -1547,17 +1643,32 @@ public:
return const_cast(this)->getNominatedNamespace();
}
- /// getCommonAncestor - returns common ancestor context of using-directive,
- /// and nominated by it namespace.
+ /// setNominatedNamespace - Set the namespace nominataed by the
+ /// using-directive.
+ void setNominatedNamespace(NamedDecl* NS);
+
+ /// \brief Returns the common ancestor context of this using-directive and
+ /// its nominated namespace.
DeclContext *getCommonAncestor() { return CommonAncestor; }
const DeclContext *getCommonAncestor() const { return CommonAncestor; }
+ /// \brief Set the common ancestor context of this using-directive and its
+ /// nominated namespace.
+ void setCommonAncestor(DeclContext* Cxt) { CommonAncestor = Cxt; }
+
+ // FIXME: Could omit 'Key' in name.
/// getNamespaceKeyLocation - Returns location of namespace keyword.
SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; }
+ /// setNamespaceKeyLocation - Set the the location of the namespacekeyword.
+ void setNamespaceKeyLocation(SourceLocation L) { NamespaceLoc = L; }
+
/// getIdentLocation - Returns location of identifier.
SourceLocation getIdentLocation() const { return IdentLoc; }
+ /// setIdentLocation - set the location of the identifier.
+ void setIdentLocation(SourceLocation L) { IdentLoc = L; }
+
static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
SourceLocation NamespaceLoc,
@@ -1591,7 +1702,7 @@ class NamespaceAliasDecl : public NamedDecl {
/// name, if any.
NestedNameSpecifier *Qualifier;
- /// IdentLoc - Location of namespace identifier.
+ /// IdentLoc - Location of namespace identifier. Accessed by TargetNameLoc.
SourceLocation IdentLoc;
/// Namespace - The Decl that this alias points to. Can either be a
@@ -1612,10 +1723,19 @@ public:
/// that qualifiers the namespace name.
SourceRange getQualifierRange() const { return QualifierRange; }
+ /// \brief Set the source range of the nested-name-specifier that qualifies
+ /// the namespace name.
+ void setQualifierRange(SourceRange R) { QualifierRange = R; }
+
/// \brief Retrieve the nested-name-specifier that qualifies the
/// name of the namespace.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
+ /// \brief Set the nested-name-specifier that qualifies the name of the
+ /// namespace.
+ void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
+
+ /// \brief Retrieve the namespace declaration aliased by this directive.
NamespaceDecl *getNamespace() {
if (NamespaceAliasDecl *AD = dyn_cast(Namespace))
return AD->getNamespace();
@@ -1631,16 +1751,31 @@ public:
/// "namespace foo = ns::bar;".
SourceLocation getAliasLoc() const { return AliasLoc; }
+ /// Set the location o;f the alias name, e.e., 'foo' in
+ /// "namespace foo = ns::bar;".
+ void setAliasLoc(SourceLocation L) { AliasLoc = L; }
+
/// Returns the location of the 'namespace' keyword.
SourceLocation getNamespaceLoc() const { return getLocation(); }
/// Returns the location of the identifier in the named namespace.
SourceLocation getTargetNameLoc() const { return IdentLoc; }
+ /// Set the location of the identifier in the named namespace.
+ void setTargetNameLoc(SourceLocation L) { IdentLoc = L; }
+
/// \brief Retrieve the namespace that this alias refers to, which
/// may either be a NamespaceDecl or a NamespaceAliasDecl.
NamedDecl *getAliasedNamespace() const { return Namespace; }
+ /// \brief Set the namespace or namespace alias pointed to by this
+ /// alias decl.
+ void setAliasedNamespace(NamedDecl *ND) {
+ assert((isa(ND) || isa(ND)) &&
+ "expecting namespace or namespace alias decl");
+ Namespace = ND;
+ }
+
static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, SourceLocation AliasLoc,
IdentifierInfo *Alias,
@@ -1687,16 +1822,20 @@ public:
return new (C) UsingShadowDecl(DC, Loc, Using, Target);
}
- /// Gets the underlying declaration which has been brought into the
+ /// \brief Gets the underlying declaration which has been brought into the
/// local scope.
- NamedDecl *getTargetDecl() const {
- return Underlying;
- }
+ NamedDecl *getTargetDecl() const { return Underlying; }
- /// Gets the using declaration to which this declaration is tied.
- UsingDecl *getUsingDecl() const {
- return Using;
- }
+ /// \brief Sets the underlying declaration which has been brought into the
+ /// local scope.
+ void setTargetDecl(NamedDecl* ND) { Underlying = ND; }
+
+ /// \brief Gets the using declaration to which this declaration is tied.
+ UsingDecl *getUsingDecl() const { return Using; }
+
+ /// \brief Sets the using declaration that introduces this target
+ /// declaration.
+ void setUsingDecl(UsingDecl* UD) { Using = UD; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingShadowDecl *D) { return true; }
@@ -1733,21 +1872,39 @@ class UsingDecl : public NamedDecl {
}
public:
+ // FIXME: Should be const?
/// \brief Returns the source range that covers the nested-name-specifier
/// preceding the namespace name.
SourceRange getNestedNameRange() { return NestedNameRange; }
- /// \brief Returns the source location of the "using" location itself.
+ /// \brief Set the source range of the nested-name-specifier.
+ void setNestedNameRange(SourceRange R) { NestedNameRange = R; }
+
+ // FIXME; Should be const?
+ // FIXME: Naming is inconsistent with other get*Loc functions.
+ /// \brief Returns the source location of the "using" keyword.
SourceLocation getUsingLocation() { return UsingLocation; }
- /// \brief Get target nested name declaration.
+ /// \brief Set the source location of the 'using' keyword.
+ void setUsingLocation(SourceLocation L) { UsingLocation = L; }
+
+
+ /// \brief Get the target nested name declaration.
NestedNameSpecifier* getTargetNestedNameDecl() {
return TargetNestedName;
}
- /// isTypeName - Return true if using decl has 'typename'.
+ /// \brief Set the target nested name declaration.
+ void setTargetNestedNameDecl(NestedNameSpecifier *NNS) {
+ TargetNestedName = NNS;
+ }
+
+ /// \brief Return true if the using declaration has 'typename'.
bool isTypeName() const { return IsTypeName; }
+ /// \brief Sets whether the using declaration has 'typename'.
+ void setTypeName(bool TN) { IsTypeName = TN; }
+
typedef llvm::SmallPtrSet::const_iterator shadow_iterator;
shadow_iterator shadow_begin() const { return Shadows.begin(); }
shadow_iterator shadow_end() const { return Shadows.end(); }
@@ -1765,6 +1922,12 @@ public:
}
}
+ /// \brief Return the number of shadowed declarations associated with this
+ /// using declaration.
+ unsigned getNumShadowDecls() const {
+ return Shadows.size();
+ }
+
static UsingDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL,
NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg);
@@ -1807,14 +1970,26 @@ public:
/// preceding the namespace name.
SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
+ /// \brief Set the source range coverting the nested-name-specifier preceding
+ /// the namespace name.
+ void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; }
+
/// \brief Get target nested name declaration.
NestedNameSpecifier* getTargetNestedNameSpecifier() {
return TargetNestedNameSpecifier;
}
+ /// \brief Set the nested name declaration.
+ void setTargetNestedNameSpecifier(NestedNameSpecifier* NNS) {
+ TargetNestedNameSpecifier = NNS;
+ }
+
/// \brief Returns the source location of the 'using' keyword.
SourceLocation getUsingLoc() const { return UsingLocation; }
+ /// \brief Set the source location of the 'using' keyword.
+ void setUsingLoc(SourceLocation L) { UsingLocation = L; }
+
static UnresolvedUsingValueDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
@@ -1861,17 +2036,32 @@ public:
/// preceding the namespace name.
SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
+ /// \brief Set the source range coverting the nested-name-specifier preceding
+ /// the namespace name.
+ void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; }
+
/// \brief Get target nested name declaration.
NestedNameSpecifier* getTargetNestedNameSpecifier() {
return TargetNestedNameSpecifier;
}
+ /// \brief Set the nested name declaration.
+ void setTargetNestedNameSpecifier(NestedNameSpecifier* NNS) {
+ TargetNestedNameSpecifier = NNS;
+ }
+
/// \brief Returns the source location of the 'using' keyword.
SourceLocation getUsingLoc() const { return UsingLocation; }
+ /// \brief Set the source location of the 'using' keyword.
+ void setUsingLoc(SourceLocation L) { UsingLocation = L; }
+
/// \brief Returns the source location of the 'typename' keyword.
SourceLocation getTypenameLoc() const { return TypenameLocation; }
+ /// \brief Set the source location of the 'typename' keyword.
+ void setTypenameLoc(SourceLocation L) { TypenameLocation = L; }
+
static UnresolvedUsingTypenameDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
SourceLocation TypenameLoc,
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
index 2a4b12a..9602b67 100644
--- a/include/clang/AST/DeclContextInternals.h
+++ b/include/clang/AST/DeclContextInternals.h
@@ -156,7 +156,8 @@ public:
/// represents.
DeclContext::lookup_result getLookupResult(ASTContext &Context) {
if (isNull())
- return DeclContext::lookup_result(0, 0);
+ return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
+ DeclContext::lookup_iterator(0));
if (hasDeclarationIDs())
materializeDecls(Context);
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index e34ec9f..97d1656 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -1421,13 +1421,21 @@ private:
/// Null for @dynamic. Required for @synthesize.
ObjCIvarDecl *PropertyIvarDecl;
+
+ /// Null for @dynamic. Non-null if property must be copy-constructed in getter
+ Expr *GetterCXXConstructor;
+
+ /// Null for @dynamic. Non-null if property has assignment operator to call
+ /// in Setter synthesis.
+ Expr *SetterCXXAssignment;
ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
ObjCPropertyDecl *property,
Kind PK,
ObjCIvarDecl *ivarDecl)
: Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
- PropertyDecl(property), PropertyIvarDecl(ivarDecl) {
+ PropertyDecl(property), PropertyIvarDecl(ivarDecl),
+ GetterCXXConstructor(0), SetterCXXAssignment(0) {
assert (PK == Dynamic || PropertyIvarDecl);
}
@@ -1457,7 +1465,21 @@ public:
return PropertyIvarDecl;
}
void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { PropertyIvarDecl = Ivar; }
+
+ Expr *getGetterCXXConstructor() const {
+ return GetterCXXConstructor;
+ }
+ void setGetterCXXConstructor(Expr *getterCXXConstructor) {
+ GetterCXXConstructor = getterCXXConstructor;
+ }
+ Expr *getSetterCXXAssignment() const {
+ return SetterCXXAssignment;
+ }
+ void setSetterCXXAssignment(Expr *setterCXXAssignment) {
+ SetterCXXAssignment = setterCXXAssignment;
+ }
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCPropertyImplDecl *D) { return true; }
static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 1ec38ba..b7b90b1 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -112,7 +112,7 @@ class TemplateArgumentListBuilder {
unsigned MaxStructuredArgs;
unsigned NumStructuredArgs;
- TemplateArgument *FlatArgs;
+ llvm::SmallVector FlatArgs;
unsigned MaxFlatArgs;
unsigned NumFlatArgs;
@@ -127,18 +127,12 @@ public:
MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
AddingToPack(false), PackBeginIndex(0) { }
- void Append(const TemplateArgument& Arg);
+ void Append(const TemplateArgument &Arg);
void BeginPack();
void EndPack();
- void ReleaseArgs();
-
- unsigned flatSize() const {
- return NumFlatArgs;
- }
- const TemplateArgument *getFlatArguments() const {
- return FlatArgs;
- }
+ unsigned flatSize() const { return FlatArgs.size(); }
+ const TemplateArgument *getFlatArguments() const { return FlatArgs.data(); }
unsigned structuredSize() const {
// If we don't have any structured args, just reuse the flat size.
@@ -165,7 +159,7 @@ class TemplateArgumentList {
/// \brief The template argument list.
///
/// The integer value will be non-zero to indicate that this
- /// template argument list does not own the pointer.
+ /// template argument list does own the pointer.
llvm::PointerIntPair FlatArguments;
/// \brief The number of template arguments in this template
@@ -175,14 +169,28 @@ class TemplateArgumentList {
llvm::PointerIntPair StructuredArguments;
unsigned NumStructuredArguments;
+ TemplateArgumentList(const TemplateArgumentList &Other); // DO NOT IMPL
+ void operator=(const TemplateArgumentList &Other); // DO NOT IMPL
public:
+ /// TemplateArgumentList - If this constructor is passed "true" for 'TakeArgs'
+ /// it copies them into a locally new[]'d array. If passed "false", then it
+ /// just references the array passed in. This is only safe if the builder
+ /// outlives it, but saves a copy.
TemplateArgumentList(ASTContext &Context,
TemplateArgumentListBuilder &Builder,
bool TakeArgs);
- /// \brief Produces a shallow copy of the given template argument list
- TemplateArgumentList(const TemplateArgumentList &Other);
+ /// Produces a shallow copy of the given template argument list. This
+ /// assumes that the input argument list outlives it. This takes the list as
+ /// a pointer to avoid looking like a copy constructor, since this really
+ /// really isn't safe to use that way.
+ explicit TemplateArgumentList(const TemplateArgumentList *Other);
+ /// Used to release the memory associated with a TemplateArgumentList
+ /// object. FIXME: This is currently not called anywhere, but the
+ /// memory will still be freed when using a BumpPtrAllocator.
+ void Destroy(ASTContext &C);
+
~TemplateArgumentList();
/// \brief Retrieve the template argument at a given index.
@@ -280,6 +288,9 @@ public:
/// specialization from the function template.
const TemplateArgumentList *TemplateArguments;
+ /// \brief The template arguments as written in the sources, if provided.
+ const TemplateArgumentListInfo *TemplateArgumentsAsWritten;
+
/// \brief The point at which this function template specialization was
/// first instantiated.
SourceLocation PointOfInstantiation;
@@ -454,6 +465,8 @@ public:
/// Declaration of a template function.
class FunctionTemplateDecl : public TemplateDecl {
+ static void DeallocateCommon(void *Ptr);
+
protected:
/// \brief Data that is common to all of the declarations of a given
/// function template.
@@ -862,7 +875,7 @@ class ClassTemplateSpecializationDecl
unsigned SpecializationKind : 3;
protected:
- ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
+ ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
@@ -870,7 +883,7 @@ protected:
public:
static ClassTemplateSpecializationDecl *
- Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
+ Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
ClassTemplateSpecializationDecl *PrevDecl);
@@ -1024,7 +1037,7 @@ class ClassTemplatePartialSpecializationDecl
llvm::PointerIntPair
InstantiatedFromMember;
- ClassTemplatePartialSpecializationDecl(ASTContext &Context,
+ ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
DeclContext *DC, SourceLocation L,
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
@@ -1035,7 +1048,7 @@ class ClassTemplatePartialSpecializationDecl
unsigned SequenceNumber)
: ClassTemplateSpecializationDecl(Context,
ClassTemplatePartialSpecialization,
- DC, L, SpecializedTemplate, Builder,
+ TK, DC, L, SpecializedTemplate, Builder,
PrevDecl),
TemplateParams(Params), ArgsAsWritten(ArgInfos),
NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
@@ -1043,7 +1056,7 @@ class ClassTemplatePartialSpecializationDecl
public:
static ClassTemplatePartialSpecializationDecl *
- Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
+ Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L,
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
@@ -1158,6 +1171,8 @@ public:
/// Declaration of a class template.
class ClassTemplateDecl : public TemplateDecl {
+ static void DeallocateCommon(void *Ptr);
+
protected:
/// \brief Data that is common to all of the declarations of a given
/// class template.
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 9401786..8a771d5 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -314,15 +314,16 @@ inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
/// retrieved using its member functions (e.g.,
/// getCXXConstructorName).
class DeclarationNameTable {
+ ASTContext &Ctx;
void *CXXSpecialNamesImpl; // Actually a FoldingSet *
CXXOperatorIdName *CXXOperatorNames; // Operator names
- void *CXXLiteralOperatorNames; // Actually a FoldingSet<...> *
+ void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName*
DeclarationNameTable(const DeclarationNameTable&); // NONCOPYABLE
DeclarationNameTable& operator=(const DeclarationNameTable&); // NONCOPYABLE
public:
- DeclarationNameTable();
+ DeclarationNameTable(ASTContext &C);
~DeclarationNameTable();
/// getIdentifier - Create a declaration name that is a simple
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 2946e46..66639e2 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -51,6 +51,7 @@ typedef UsuallyTinyPtrVector CXXBaseSpecifierArray;
class Expr : public Stmt {
QualType TR;
+ virtual void ANCHOR(); // key function.
protected:
/// TypeDependent - Whether this expression is type-dependent
/// (C++ [temp.dep.expr]).
@@ -247,6 +248,15 @@ public:
SourceLocation DiagLoc;
EvalResult() : HasSideEffects(false), Diag(0), DiagExpr(0) {}
+
+ // isGlobalLValue - Return true if the evaluated lvalue expression
+ // is global.
+ bool isGlobalLValue() const;
+ // hasSideEffects - Return true if the evaluated expression has
+ // side effects.
+ bool hasSideEffects() const {
+ return HasSideEffects;
+ }
};
/// Evaluate - Return true if this is a constant which we can fold using
@@ -255,10 +265,6 @@ public:
/// in Result.
bool Evaluate(EvalResult &Result, ASTContext &Ctx) const;
- /// EvaluateAsAny - The same as Evaluate, except that it also succeeds on
- /// stack based objects.
- bool EvaluateAsAny(EvalResult &Result, ASTContext &Ctx) const;
-
/// EvaluateAsBooleanCondition - Return true if this is a constant
/// which we we can fold and convert to a boolean condition using
/// any crazy technique that we want to.
@@ -282,8 +288,7 @@ public:
/// with link time known address.
bool EvaluateAsLValue(EvalResult &Result, ASTContext &Ctx) const;
- /// EvaluateAsAnyLValue - The same as EvaluateAsLValue, except that it
- /// also succeeds on stack based, immutable address lvalues.
+ /// EvaluateAsLValue - Evaluate an expression to see if it's a lvalue.
bool EvaluateAsAnyLValue(EvalResult &Result, ASTContext &Ctx) const;
/// \brief Enumeration used to describe how \c isNullPointerConstant()
@@ -321,6 +326,10 @@ public:
/// or CastExprs, returning their operand.
Expr *IgnoreParenCasts();
+ /// IgnoreParenImpCasts - Ignore parentheses and implicit casts. Strip off any
+ /// ParenExpr or ImplicitCastExprs, returning their operand.
+ Expr *IgnoreParenImpCasts();
+
/// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
/// value (including ptr->int casts of the same size). Strip off any
/// ParenExpr or CastExprs, returning their operand.
@@ -1468,13 +1477,10 @@ public:
}
static bool classof(const Stmt *T) {
- return T->getStmtClass() == CallExprClass ||
- T->getStmtClass() == CXXOperatorCallExprClass ||
- T->getStmtClass() == CXXMemberCallExprClass;
+ return T->getStmtClass() >= firstCallExprConstant &&
+ T->getStmtClass() <= lastCallExprConstant;
}
static bool classof(const CallExpr *) { return true; }
- static bool classof(const CXXOperatorCallExpr *) { return true; }
- static bool classof(const CXXMemberCallExpr *) { return true; }
// Iterators
virtual child_iterator child_begin();
@@ -1933,14 +1939,8 @@ public:
const CXXBaseSpecifierArray& getBasePath() const { return BasePath; }
static bool classof(const Stmt *T) {
- StmtClass SC = T->getStmtClass();
- if (SC >= CXXStaticCastExprClass && SC <= CXXFunctionalCastExprClass)
- return true;
-
- if (SC >= ImplicitCastExprClass && SC <= CStyleCastExprClass)
- return true;
-
- return false;
+ return T->getStmtClass() >= firstCastExprConstant &&
+ T->getStmtClass() <= lastCastExprConstant;
}
static bool classof(const CastExpr *) { return true; }
@@ -2037,13 +2037,8 @@ public:
QualType getTypeAsWritten() const { return TInfo->getType(); }
static bool classof(const Stmt *T) {
- StmtClass SC = T->getStmtClass();
- if (SC >= CStyleCastExprClass && SC <= CStyleCastExprClass)
- return true;
- if (SC >= CXXStaticCastExprClass && SC <= CXXFunctionalCastExprClass)
- return true;
-
- return false;
+ return T->getStmtClass() >= firstExplicitCastExprConstant &&
+ T->getStmtClass() <= lastExplicitCastExprConstant;
}
static bool classof(const ExplicitCastExpr *) { return true; }
};
@@ -2198,8 +2193,8 @@ public:
bool isShiftAssignOp() const { return Opc == ShlAssign || Opc == ShrAssign; }
static bool classof(const Stmt *S) {
- return S->getStmtClass() == BinaryOperatorClass ||
- S->getStmtClass() == CompoundAssignOperatorClass;
+ return S->getStmtClass() >= firstBinaryOperatorConstant &&
+ S->getStmtClass() <= lastBinaryOperatorConstant;
}
static bool classof(const BinaryOperator *) { return true; }
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index f9ca78a..0c493f3 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -88,10 +88,13 @@ public:
/// the object argument).
class CXXMemberCallExpr : public CallExpr {
public:
- CXXMemberCallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs,
+ CXXMemberCallExpr(ASTContext &C, Expr *fn, Expr **args, unsigned numargs,
QualType t, SourceLocation rparenloc)
: CallExpr(C, CXXMemberCallExprClass, fn, args, numargs, t, rparenloc) {}
+ CXXMemberCallExpr(ASTContext &C, EmptyShell Empty)
+ : CallExpr(C, CXXMemberCallExprClass, Empty) { }
+
/// getImplicitObjectArgument - Retrieves the implicit object
/// argument for the member call. For example, in "x.f(5)", this
/// operation would return "x".
@@ -318,6 +321,14 @@ public:
Operand->isTypeDependent() || Operand->isValueDependent()),
Operand(Operand), Range(R) { }
+ CXXTypeidExpr(EmptyShell Empty, bool isExpr)
+ : Expr(CXXTypeidExprClass, Empty) {
+ if (isExpr)
+ Operand = (Expr*)0;
+ else
+ Operand = (TypeSourceInfo*)0;
+ }
+
bool isTypeOperand() const { return Operand.is(); }
/// \brief Retrieves the type operand of this typeid() expression after
@@ -329,15 +340,25 @@ public:
assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
return Operand.get();
}
+
+ void setTypeOperandSourceInfo(TypeSourceInfo *TSI) {
+ assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
+ Operand = TSI;
+ }
- Expr* getExprOperand() const {
+ Expr *getExprOperand() const {
assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
return static_cast(Operand.get());
}
-
- virtual SourceRange getSourceRange() const {
- return Range;
+
+ void setExprOperand(Expr *E) {
+ assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
+ Operand = E;
}
+
+ virtual SourceRange getSourceRange() const { return Range; }
+ void setSourceRange(SourceRange R) { Range = R; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXTypeidExprClass;
}
@@ -371,6 +392,11 @@ public:
Type->isDependentType(), Type->isDependentType()),
Loc(L), Implicit(isImplicit) { }
+ CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {}
+
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
+
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
bool isImplicit() const { return Implicit; }
@@ -399,6 +425,8 @@ public:
// can by null, if the optional expression to throw isn't present.
CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l) :
Expr(CXXThrowExprClass, Ty, false, false), Op(expr), ThrowLoc(l) {}
+ CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
+
const Expr *getSubExpr() const { return cast_or_null(Op); }
Expr *getSubExpr() { return cast_or_null(Op); }
void setSubExpr(Expr *E) { Op = E; }
@@ -448,8 +476,7 @@ protected:
CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param,
Expr *SubExpr)
- : Expr(SC, SubExpr->getType(), false, false), Param(param, true), Loc(Loc)
- {
+ : Expr(SC, SubExpr->getType(), false, false), Param(param, true), Loc(Loc) {
*reinterpret_cast(this + 1) = SubExpr;
}
@@ -457,6 +484,9 @@ protected:
virtual void DoDestroy(ASTContext &C);
public:
+ CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {}
+
+
// Param is the parameter whose default argument is used by this
// expression.
static CXXDefaultArgExpr *Create(ASTContext &C, SourceLocation Loc,
@@ -475,6 +505,9 @@ public:
const ParmVarDecl *getParam() const { return Param.getPointer(); }
ParmVarDecl *getParam() { return Param.getPointer(); }
+ /// isExprStored - Return true if this expression owns the expression.
+ bool isExprStored() const { return Param.getInt(); }
+
// Retrieve the actual argument to the function call.
const Expr *getExpr() const {
if (Param.getInt())
@@ -486,10 +519,16 @@ public:
return *reinterpret_cast (this + 1);
return getParam()->getDefaultArg();
}
+
+ void setExpr(Expr *E) {
+ Param.setInt(true);
+ Param.setPointer((ParmVarDecl*)E);
+ }
/// \brief Retrieve the location where this default argument was actually
/// used.
SourceLocation getUsedLocation() const { return Loc; }
+ void setUsedLocation(SourceLocation L) { Loc = L; }
virtual SourceRange getSourceRange() const {
// Default argument expressions have no representation in the
@@ -525,8 +564,20 @@ public:
const CXXDestructorDecl *getDestructor() const { return Destructor; }
};
-/// CXXBindTemporaryExpr - Represents binding an expression to a temporary,
-/// so its destructor can be called later.
+/// \brief Represents binding an expression to a temporary.
+///
+/// This ensures the destructor is called for the temporary. It should only be
+/// needed for non-POD, non-trivially destructable class types. For example:
+///
+/// \code
+/// struct S {
+/// S() { } // User defined constructor makes S non-POD.
+/// ~S() { } // User defined destructor makes it non-trivial.
+/// };
+/// void test() {
+/// const S &s_ref = S(); // Requires a CXXBindTemporaryExpr.
+/// }
+/// \endcode
class CXXBindTemporaryExpr : public Expr {
CXXTemporary *Temp;
@@ -541,11 +592,15 @@ protected:
virtual void DoDestroy(ASTContext &C);
public:
+ CXXBindTemporaryExpr(EmptyShell Empty)
+ : Expr(CXXBindTemporaryExprClass, Empty), Temp(0), SubExpr(0) {}
+
static CXXBindTemporaryExpr *Create(ASTContext &C, CXXTemporary *Temp,
Expr* SubExpr);
CXXTemporary *getTemporary() { return Temp; }
const CXXTemporary *getTemporary() const { return Temp; }
+ void setTemporary(CXXTemporary *T) { Temp = T; }
const Expr *getSubExpr() const { return cast(SubExpr); }
Expr *getSubExpr() { return cast(SubExpr); }
@@ -572,8 +627,8 @@ public:
/// const int &i = 10;
///
/// a bind reference expression is inserted to indicate that 10 is bound to
-/// a reference. (Ans also that a temporary needs to be created to hold the
-/// value).
+/// a reference, and that a temporary needs to be created to hold the
+/// value.
class CXXBindReferenceExpr : public Expr {
// SubExpr - The expression being bound.
Stmt *SubExpr;
@@ -827,10 +882,15 @@ public:
SourceLocation rParenLoc ) :
Expr(CXXZeroInitValueExprClass, ty, false, false),
TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
+ explicit CXXZeroInitValueExpr(EmptyShell Shell)
+ : Expr(CXXZeroInitValueExprClass, Shell) { }
SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
+ void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
/// @brief Whether this initialization expression was
/// implicitly-generated.
bool isImplicit() const {
@@ -891,6 +951,11 @@ public:
Expr **constructorArgs, unsigned numConsArgs,
FunctionDecl *operatorDelete, QualType ty,
SourceLocation startLoc, SourceLocation endLoc);
+ explicit CXXNewExpr(EmptyShell Shell)
+ : Expr(CXXNewExprClass, Shell), SubExprs(0) { }
+
+ void AllocateArgsArray(ASTContext &C, bool isArray, unsigned numPlaceArgs,
+ unsigned numConsArgs);
virtual void DoDestroy(ASTContext &C);
@@ -900,8 +965,11 @@ public:
}
FunctionDecl *getOperatorNew() const { return OperatorNew; }
+ void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
+ void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
CXXConstructorDecl *getConstructor() const { return Constructor; }
+ void setConstructor(CXXConstructorDecl *D) { Constructor = D; }
bool isArray() const { return Array; }
Expr *getArraySize() {
@@ -922,8 +990,11 @@ public:
}
bool isGlobalNew() const { return GlobalNew; }
+ void setGlobalNew(bool V) { GlobalNew = V; }
bool isParenTypeId() const { return ParenTypeId; }
+ void setParenTypeId(bool V) { ParenTypeId = V; }
bool hasInitializer() const { return Initializer; }
+ void setHasInitializer(bool V) { Initializer = V; }
unsigned getNumConstructorArgs() const { return NumConstructorArgs; }
Expr *getConstructorArg(unsigned i) {
@@ -963,7 +1034,21 @@ public:
const_arg_iterator constructor_arg_end() const {
return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
}
+
+ typedef Stmt **raw_arg_iterator;
+ raw_arg_iterator raw_arg_begin() { return SubExprs; }
+ raw_arg_iterator raw_arg_end() {
+ return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
+ }
+ const_arg_iterator raw_arg_begin() const { return SubExprs; }
+ const_arg_iterator raw_arg_end() const { return constructor_arg_end(); }
+
+ SourceLocation getStartLoc() const { return StartLoc; }
+ void setStartLoc(SourceLocation L) { StartLoc = L; }
+ SourceLocation getEndLoc() const { return EndLoc; }
+ void setEndLoc(SourceLocation L) { EndLoc = L; }
+
virtual SourceRange getSourceRange() const {
return SourceRange(StartLoc, EndLoc);
}
@@ -1260,7 +1345,9 @@ class OverloadExpr : public Expr {
/// The results. These are undesugared, which is to say, they may
/// include UsingShadowDecls. Access is relative to the naming
/// class.
- UnresolvedSet<4> Results;
+ // FIXME: Allocate this data after the OverloadExpr subclass.
+ DeclAccessPair *Results;
+ unsigned NumResults;
/// The common name of these declarations.
DeclarationName Name;
@@ -1278,14 +1365,11 @@ class OverloadExpr : public Expr {
bool HasExplicitTemplateArgs;
protected:
- OverloadExpr(StmtClass K, QualType T, bool Dependent,
+ OverloadExpr(StmtClass K, ASTContext &C, QualType T, bool Dependent,
NestedNameSpecifier *Qualifier, SourceRange QRange,
DeclarationName Name, SourceLocation NameLoc,
- bool HasTemplateArgs)
- : Expr(K, T, Dependent, Dependent),
- Name(Name), Qualifier(Qualifier), QualifierRange(QRange),
- NameLoc(NameLoc), HasExplicitTemplateArgs(HasTemplateArgs)
- {}
+ bool HasTemplateArgs,
+ UnresolvedSetIterator Begin, UnresolvedSetIterator End);
public:
/// Computes whether an unresolved lookup on the given declarations
@@ -1309,22 +1393,17 @@ public:
return llvm::PointerIntPair(cast(E), op);
}
- void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) {
- Results.append(Begin, End);
- }
-
/// Gets the naming class of this lookup, if any.
CXXRecordDecl *getNamingClass() const;
typedef UnresolvedSetImpl::iterator decls_iterator;
- decls_iterator decls_begin() const { return Results.begin(); }
- decls_iterator decls_end() const { return Results.end(); }
-
- /// Gets the decls as an unresolved set.
- const UnresolvedSetImpl &getDecls() { return Results; }
+ decls_iterator decls_begin() const { return UnresolvedSetIterator(Results); }
+ decls_iterator decls_end() const {
+ return UnresolvedSetIterator(Results + NumResults);
+ }
/// Gets the number of declarations in the unresolved set.
- unsigned getNumDecls() const { return Results.size(); }
+ unsigned getNumDecls() const { return NumResults; }
/// Gets the name looked up.
DeclarationName getName() const { return Name; }
@@ -1390,12 +1469,14 @@ class UnresolvedLookupExpr : public OverloadExpr {
/// against the qualified-lookup bits.
CXXRecordDecl *NamingClass;
- UnresolvedLookupExpr(QualType T, bool Dependent, CXXRecordDecl *NamingClass,
+ UnresolvedLookupExpr(ASTContext &C, QualType T, bool Dependent,
+ CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier, SourceRange QRange,
DeclarationName Name, SourceLocation NameLoc,
- bool RequiresADL, bool Overloaded, bool HasTemplateArgs)
- : OverloadExpr(UnresolvedLookupExprClass, T, Dependent, Qualifier, QRange,
- Name, NameLoc, HasTemplateArgs),
+ bool RequiresADL, bool Overloaded, bool HasTemplateArgs,
+ UnresolvedSetIterator Begin, UnresolvedSetIterator End)
+ : OverloadExpr(UnresolvedLookupExprClass, C, T, Dependent, Qualifier,
+ QRange, Name, NameLoc, HasTemplateArgs, Begin, End),
RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass)
{}
@@ -1407,11 +1488,15 @@ public:
SourceRange QualifierRange,
DeclarationName Name,
SourceLocation NameLoc,
- bool ADL, bool Overloaded) {
- return new(C) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
+ bool ADL, bool Overloaded,
+ UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End) {
+ return new(C) UnresolvedLookupExpr(C,
+ Dependent ? C.DependentTy : C.OverloadTy,
Dependent, NamingClass,
Qualifier, QualifierRange,
- Name, NameLoc, ADL, Overloaded, false);
+ Name, NameLoc, ADL, Overloaded, false,
+ Begin, End);
}
static UnresolvedLookupExpr *Create(ASTContext &C,
@@ -1422,7 +1507,9 @@ public:
DeclarationName Name,
SourceLocation NameLoc,
bool ADL,
- const TemplateArgumentListInfo &Args);
+ const TemplateArgumentListInfo &Args,
+ UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End);
/// True if this declaration should be extended by
/// argument-dependent lookup.
@@ -1611,7 +1698,7 @@ class CXXExprWithTemporaries : public Expr {
CXXTemporary **Temps;
unsigned NumTemps;
- CXXExprWithTemporaries(Expr *SubExpr, CXXTemporary **Temps,
+ CXXExprWithTemporaries(ASTContext &C, Expr *SubExpr, CXXTemporary **Temps,
unsigned NumTemps);
~CXXExprWithTemporaries();
@@ -1619,11 +1706,17 @@ protected:
virtual void DoDestroy(ASTContext &C);
public:
+ CXXExprWithTemporaries(EmptyShell Empty)
+ : Expr(CXXExprWithTemporariesClass, Empty),
+ SubExpr(0), Temps(0), NumTemps(0) {}
+
static CXXExprWithTemporaries *Create(ASTContext &C, Expr *SubExpr,
CXXTemporary **Temps,
unsigned NumTemps);
unsigned getNumTemporaries() const { return NumTemps; }
+ void setNumTemporaries(ASTContext &C, unsigned N);
+
CXXTemporary *getTemporary(unsigned i) {
assert(i < NumTemps && "Index out of range");
return Temps[i];
@@ -1631,6 +1724,10 @@ public:
const CXXTemporary *getTemporary(unsigned i) const {
return const_cast(this)->getTemporary(i);
}
+ void setTemporary(unsigned i, CXXTemporary *T) {
+ assert(i < NumTemps && "Index out of range");
+ Temps[i] = T;
+ }
Expr *getSubExpr() { return cast(SubExpr); }
const Expr *getSubExpr() const { return cast(SubExpr); }
@@ -2020,7 +2117,7 @@ class UnresolvedMemberExpr : public OverloadExpr {
/// \brief The location of the '->' or '.' operator.
SourceLocation OperatorLoc;
- UnresolvedMemberExpr(QualType T, bool Dependent,
+ UnresolvedMemberExpr(ASTContext &C, QualType T, bool Dependent,
bool HasUnresolvedUsing,
Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
@@ -2028,7 +2125,8 @@ class UnresolvedMemberExpr : public OverloadExpr {
SourceRange QualifierRange,
DeclarationName Member,
SourceLocation MemberLoc,
- const TemplateArgumentListInfo *TemplateArgs);
+ const TemplateArgumentListInfo *TemplateArgs,
+ UnresolvedSetIterator Begin, UnresolvedSetIterator End);
public:
static UnresolvedMemberExpr *
@@ -2039,7 +2137,8 @@ public:
SourceRange QualifierRange,
DeclarationName Member,
SourceLocation MemberLoc,
- const TemplateArgumentListInfo *TemplateArgs);
+ const TemplateArgumentListInfo *TemplateArgs,
+ UnresolvedSetIterator Begin, UnresolvedSetIterator End);
/// \brief True if this is an implicit access, i.e. one in which the
/// member being accessed was not written in the source. The source
diff --git a/include/clang/AST/Makefile b/include/clang/AST/Makefile
new file mode 100644
index 0000000..a25977c
--- /dev/null
+++ b/include/clang/AST/Makefile
@@ -0,0 +1,13 @@
+LEVEL = ../../../../..
+BUILT_SOURCES = StmtNodes.inc
+
+TABLEGEN_INC_FILES_COMMON = 1
+
+include $(LEVEL)/Makefile.common
+
+INPUT_TDS = $(PROJ_SRC_DIR)/StmtNodes.td
+
+$(ObjDir)/StmtNodes.inc.tmp : StmtNodes.td $(TBLGEN) $(ObjDir)/.dir
+ $(Echo) "Building Clang statement node tables with tblgen"
+ $(Verb) $(TableGen) -gen-clang-stmt-nodes -o $(call SYSPATH, $@) $<
+
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index e78476e..2b3229e 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -109,6 +109,11 @@ private:
/// which is the alignment of the object without virtual bases.
uint64_t NonVirtualAlign;
+ /// SizeOfLargestEmptySubobject - The size of the largest empty subobject
+ /// (either a base or a member). Will be zero if the class doesn't contain
+ /// any empty subobjects.
+ uint64_t SizeOfLargestEmptySubobject;
+
/// PrimaryBase - The primary base info for this record.
PrimaryBaseInfo PrimaryBase;
@@ -127,7 +132,6 @@ private:
CXXRecordLayoutInfo *CXXInfo;
friend class ASTContext;
- friend class ASTRecordLayoutBuilder;
ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignment,
unsigned datasize, const uint64_t *fieldoffsets,
@@ -139,7 +143,9 @@ private:
uint64_t size, unsigned alignment, uint64_t datasize,
const uint64_t *fieldoffsets, unsigned fieldcount,
uint64_t nonvirtualsize, unsigned nonvirtualalign,
- const PrimaryBaseInfo &PrimaryBase,
+ uint64_t SizeOfLargestEmptySubobject,
+ const CXXRecordDecl *PrimaryBase,
+ bool PrimaryBaseIsVirtual,
const BaseOffsetsMapTy& BaseOffsets,
const BaseOffsetsMapTy& VBaseOffsets);
@@ -222,6 +228,11 @@ public:
return CXXInfo->VBaseOffsets[VBase];
}
+ uint64_t getSizeOfLargestEmptySubobject() const {
+ assert(CXXInfo && "Record layout does not have C++ specific info!");
+ return CXXInfo->SizeOfLargestEmptySubobject;
+ }
+
primary_base_info_iterator primary_base_begin() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
new file mode 100644
index 0000000..07865e0
--- /dev/null
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -0,0 +1,768 @@
+//===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the RecursiveASTVisitor interface, which recursively
+// traverses the entire AST.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
+#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
+
+namespace clang {
+
+#define DISPATCH(NAME, CLASS, Var) \
+return getDerived().Visit ## NAME(static_cast(Var))
+
+// We use preprocessor meta-programming to generate the Visit*()
+// methods for all subclasses of Stmt, Decl, and Type. Some of the
+// generated definitions, however, need to be customized. The
+// meta-programming technique we use doesn't let us select which
+// methods to generate. Therefore we have to generate ALL of them in
+// a helper class RecursiveASTVisitorImpl, and override the ones we
+// don't like in a child class RecursiveASTVisitor (C++ doesn't allow
+// overriding a method in the same class).
+//
+// Do not use this class directly - use RecursiveASTVisitor instead.
+template
+class RecursiveASTVisitorImpl {
+public:
+ /// \brief Return a reference to the derived class.
+ Derived &getDerived() { return *static_cast(this); }
+
+ /// \brief Recursively visit a statement or expression, by
+ /// dispatching to Visit*() based on the argument's dynamic type.
+ /// This is NOT meant to be overridden by a subclass.
+ ///
+ /// \returns true if the visitation was terminated early, false
+ /// otherwise (including when the argument is NULL).
+ bool Visit(Stmt *S);
+
+ /// \brief Recursively visit a type, by dispatching to
+ /// Visit*Type() based on the argument's getTypeClass() property.
+ /// This is NOT meant to be overridden by a subclass.
+ ///
+ /// \returns true if the visitation was terminated early, false
+ /// otherwise (including when the argument is a Null type).
+ bool Visit(QualType T);
+
+ /// \brief Recursively visit a declaration, by dispatching to
+ /// Visit*Decl() based on the argument's dynamic type. This is
+ /// NOT meant to be overridden by a subclass.
+ ///
+ /// \returns true if the visitation was terminated early, false
+ /// otherwise (including when the argument is NULL).
+ bool Visit(Decl *D);
+
+ /// \brief Recursively visit a C++ nested-name-specifier.
+ ///
+ /// \returns true if the visitation was terminated early, false otherwise.
+ bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS);
+
+ /// \brief Recursively visit a template name.
+ ///
+ /// \returns true if the visitation was terminated early, false otherwise.
+ bool VisitTemplateName(TemplateName Template);
+
+ /// \brief Recursively visit a template argument.
+ ///
+ /// \returns true if the visitation was terminated early, false otherwise.
+ bool VisitTemplateArgument(const TemplateArgument &Arg);
+
+ /// \brief Recursively visit a set of template arguments.
+ ///
+ /// \returns true if the visitation was terminated early, false otherwise.
+ bool VisitTemplateArguments(const TemplateArgument *Args, unsigned NumArgs);
+
+ // If the implementation chooses not to implement a certain visit method, fall
+ // back on VisitExpr or whatever else is the superclass.
+#define STMT(CLASS, PARENT) \
+bool Visit ## CLASS(CLASS *S) { DISPATCH(PARENT, PARENT, S); }
+#include "clang/AST/StmtNodes.inc"
+
+ // If the implementation doesn't implement binary operator methods, fall back
+ // on VisitBinaryOperator.
+#define BINOP_FALLBACK(NAME) \
+bool VisitBin ## NAME(BinaryOperator *S) { \
+DISPATCH(BinaryOperator, BinaryOperator, S); \
+}
+ BINOP_FALLBACK(PtrMemD) BINOP_FALLBACK(PtrMemI)
+ BINOP_FALLBACK(Mul) BINOP_FALLBACK(Div) BINOP_FALLBACK(Rem)
+ BINOP_FALLBACK(Add) BINOP_FALLBACK(Sub) BINOP_FALLBACK(Shl)
+ BINOP_FALLBACK(Shr)
+
+ BINOP_FALLBACK(LT) BINOP_FALLBACK(GT) BINOP_FALLBACK(LE)
+ BINOP_FALLBACK(GE) BINOP_FALLBACK(EQ) BINOP_FALLBACK(NE)
+ BINOP_FALLBACK(And) BINOP_FALLBACK(Xor) BINOP_FALLBACK(Or)
+ BINOP_FALLBACK(LAnd) BINOP_FALLBACK(LOr)
+
+ BINOP_FALLBACK(Assign)
+ BINOP_FALLBACK(Comma)
+#undef BINOP_FALLBACK
+
+ // If the implementation doesn't implement compound assignment operator
+ // methods, fall back on VisitCompoundAssignOperator.
+#define CAO_FALLBACK(NAME) \
+bool VisitBin ## NAME(CompoundAssignOperator *S) { \
+DISPATCH(CompoundAssignOperator, CompoundAssignOperator, S); \
+}
+ CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign)
+ CAO_FALLBACK(AddAssign) CAO_FALLBACK(SubAssign) CAO_FALLBACK(ShlAssign)
+ CAO_FALLBACK(ShrAssign) CAO_FALLBACK(AndAssign) CAO_FALLBACK(OrAssign)
+ CAO_FALLBACK(XorAssign)
+#undef CAO_FALLBACK
+
+ // If the implementation doesn't implement unary operator methods, fall back
+ // on VisitUnaryOperator.
+#define UNARYOP_FALLBACK(NAME) \
+bool VisitUnary ## NAME(UnaryOperator *S) { \
+DISPATCH(UnaryOperator, UnaryOperator, S); \
+}
+ UNARYOP_FALLBACK(PostInc) UNARYOP_FALLBACK(PostDec)
+ UNARYOP_FALLBACK(PreInc) UNARYOP_FALLBACK(PreDec)
+ UNARYOP_FALLBACK(AddrOf) UNARYOP_FALLBACK(Deref)
+
+ UNARYOP_FALLBACK(Plus) UNARYOP_FALLBACK(Minus)
+ UNARYOP_FALLBACK(Not) UNARYOP_FALLBACK(LNot)
+ UNARYOP_FALLBACK(Real) UNARYOP_FALLBACK(Imag)
+ UNARYOP_FALLBACK(Extension) UNARYOP_FALLBACK(OffsetOf)
+#undef UNARYOP_FALLBACK
+
+ /// \brief Basis for statement and expression visitation, which
+ /// visits all of the substatements and subexpressions.
+ ///
+ /// The relation between Visit(Stmt *S) and this method is that
+ /// the former dispatches to Visit*() based on S's dynamic type,
+ /// which forwards the call up the inheritance chain until
+ /// reaching VisitStmt(), which then calls Visit() on each
+ /// substatement/subexpression.
+ bool VisitStmt(Stmt *S);
+
+ /// \brief Basis for type visitation, which by default does nothing.
+ ///
+ /// The relation between Visit(QualType T) and this method is
+ /// that the former dispatches to Visit*Type(), which forwards the
+ /// call up the inheritance chain until reaching VisitType().
+ bool VisitType(Type *T);
+
+#define TYPE(Class, Base) \
+ bool Visit##Class##Type(Class##Type *T);
+#include "clang/AST/TypeNodes.def"
+
+ /// \brief Basis for declaration and definition visitation, which
+ /// visits all of the subnodes.
+ ///
+ /// The relation between Visit(Decl *) and this method is that the
+ /// former dispatches to Visit*Decl(), which forwards the call up
+ /// the inheritance chain until reaching VisitDecl().
+ bool VisitDecl(Decl *D);
+
+#define DECL(Class, Base) \
+ bool Visit##Class##Decl(Class##Decl *D) { \
+ return getDerived().Visit##Base(D); \
+ }
+#define ABSTRACT_DECL(Class, Base) DECL(Class, Base)
+#include "clang/AST/DeclNodes.def"
+};
+
+template
+bool RecursiveASTVisitorImpl::Visit(Stmt *S) {
+ if (!S)
+ return false;
+
+ // If we have a binary expr, dispatch to the subcode of the binop. A smart
+ // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
+ // below.
+ if (BinaryOperator *BinOp = dyn_cast(S)) {
+ switch (BinOp->getOpcode()) {
+ case BinaryOperator::PtrMemD: DISPATCH(BinPtrMemD, BinaryOperator, S);
+ case BinaryOperator::PtrMemI: DISPATCH(BinPtrMemI, BinaryOperator, S);
+ case BinaryOperator::Mul: DISPATCH(BinMul, BinaryOperator, S);
+ case BinaryOperator::Div: DISPATCH(BinDiv, BinaryOperator, S);
+ case BinaryOperator::Rem: DISPATCH(BinRem, BinaryOperator, S);
+ case BinaryOperator::Add: DISPATCH(BinAdd, BinaryOperator, S);
+ case BinaryOperator::Sub: DISPATCH(BinSub, BinaryOperator, S);
+ case BinaryOperator::Shl: DISPATCH(BinShl, BinaryOperator, S);
+ case BinaryOperator::Shr: DISPATCH(BinShr, BinaryOperator, S);
+
+ case BinaryOperator::LT: DISPATCH(BinLT, BinaryOperator, S);
+ case BinaryOperator::GT: DISPATCH(BinGT, BinaryOperator, S);
+ case BinaryOperator::LE: DISPATCH(BinLE, BinaryOperator, S);
+ case BinaryOperator::GE: DISPATCH(BinGE, BinaryOperator, S);
+ case BinaryOperator::EQ: DISPATCH(BinEQ, BinaryOperator, S);
+ case BinaryOperator::NE: DISPATCH(BinNE, BinaryOperator, S);
+
+ case BinaryOperator::And: DISPATCH(BinAnd, BinaryOperator, S);
+ case BinaryOperator::Xor: DISPATCH(BinXor, BinaryOperator, S);
+ case BinaryOperator::Or : DISPATCH(BinOr, BinaryOperator, S);
+ case BinaryOperator::LAnd: DISPATCH(BinLAnd, BinaryOperator, S);
+ case BinaryOperator::LOr : DISPATCH(BinLOr, BinaryOperator, S);
+ case BinaryOperator::Assign: DISPATCH(BinAssign, BinaryOperator, S);
+ case BinaryOperator::MulAssign:
+ DISPATCH(BinMulAssign, CompoundAssignOperator, S);
+ case BinaryOperator::DivAssign:
+ DISPATCH(BinDivAssign, CompoundAssignOperator, S);
+ case BinaryOperator::RemAssign:
+ DISPATCH(BinRemAssign, CompoundAssignOperator, S);
+ case BinaryOperator::AddAssign:
+ DISPATCH(BinAddAssign, CompoundAssignOperator, S);
+ case BinaryOperator::SubAssign:
+ DISPATCH(BinSubAssign, CompoundAssignOperator, S);
+ case BinaryOperator::ShlAssign:
+ DISPATCH(BinShlAssign, CompoundAssignOperator, S);
+ case BinaryOperator::ShrAssign:
+ DISPATCH(BinShrAssign, CompoundAssignOperator, S);
+ case BinaryOperator::AndAssign:
+ DISPATCH(BinAndAssign, CompoundAssignOperator, S);
+ case BinaryOperator::OrAssign:
+ DISPATCH(BinOrAssign, CompoundAssignOperator, S);
+ case BinaryOperator::XorAssign:
+ DISPATCH(BinXorAssign, CompoundAssignOperator, S);
+ case BinaryOperator::Comma: DISPATCH(BinComma, BinaryOperator, S);
+ }
+ } else if (UnaryOperator *UnOp = dyn_cast(S)) {
+ switch (UnOp->getOpcode()) {
+ case UnaryOperator::PostInc: DISPATCH(UnaryPostInc, UnaryOperator, S);
+ case UnaryOperator::PostDec: DISPATCH(UnaryPostDec, UnaryOperator, S);
+ case UnaryOperator::PreInc: DISPATCH(UnaryPreInc, UnaryOperator, S);
+ case UnaryOperator::PreDec: DISPATCH(UnaryPreDec, UnaryOperator, S);
+ case UnaryOperator::AddrOf: DISPATCH(UnaryAddrOf, UnaryOperator, S);
+ case UnaryOperator::Deref: DISPATCH(UnaryDeref, UnaryOperator, S);
+ case UnaryOperator::Plus: DISPATCH(UnaryPlus, UnaryOperator, S);
+ case UnaryOperator::Minus: DISPATCH(UnaryMinus, UnaryOperator, S);
+ case UnaryOperator::Not: DISPATCH(UnaryNot, UnaryOperator, S);
+ case UnaryOperator::LNot: DISPATCH(UnaryLNot, UnaryOperator, S);
+ case UnaryOperator::Real: DISPATCH(UnaryReal, UnaryOperator, S);
+ case UnaryOperator::Imag: DISPATCH(UnaryImag, UnaryOperator, S);
+ case UnaryOperator::Extension: DISPATCH(UnaryExtension, UnaryOperator, S);
+ case UnaryOperator::OffsetOf: DISPATCH(UnaryOffsetOf, UnaryOperator, S);
+ }
+ }
+
+ // Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
+ switch (S->getStmtClass()) {
+ case Stmt::NoStmtClass: break;
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT) \
+case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS, S);
+#include "clang/AST/StmtNodes.inc"
+ }
+
+ return false;
+}
+
+template
+bool RecursiveASTVisitorImpl::Visit(QualType T) {
+ if (T.isNull())
+ return false;
+
+ switch (T->getTypeClass()) {
+#define ABSTRACT_TYPE(Class, Base)
+#define TYPE(Class, Base) \
+ case Type::Class: DISPATCH(Class##Type, Class##Type, T.getTypePtr());
+#include "clang/AST/TypeNodes.def"
+ }
+
+ return false;
+}
+
+template
+bool RecursiveASTVisitorImpl::Visit(Decl *D) {
+ if (!D)
+ return false;
+
+ switch (D->getKind()) {
+#define ABSTRACT_DECL(Class, Base)
+#define DECL(Class, Base) \
+ case Decl::Class: DISPATCH(Class##Decl, Class##Decl, D);
+#include "clang/AST/DeclNodes.def"
+ }
+
+ return false;
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitNestedNameSpecifier(
+ NestedNameSpecifier *NNS) {
+ if (NNS->getPrefix() &&
+ getDerived().VisitNestedNameSpecifier(NNS->getPrefix()))
+ return true;
+
+ switch (NNS->getKind()) {
+ case NestedNameSpecifier::Identifier:
+ case NestedNameSpecifier::Namespace:
+ case NestedNameSpecifier::Global:
+ return false;
+
+ case NestedNameSpecifier::TypeSpec:
+ case NestedNameSpecifier::TypeSpecWithTemplate:
+ return Visit(QualType(NNS->getAsType(), 0));
+ }
+
+ return false;
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitTemplateName(TemplateName Template) {
+ if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
+ return DTN->getQualifier() &&
+ getDerived().VisitNestedNameSpecifier(DTN->getQualifier());
+
+ if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
+ return getDerived().VisitNestedNameSpecifier(QTN->getQualifier());
+
+ return false;
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitTemplateArgument(
+ const TemplateArgument &Arg) {
+ switch (Arg.getKind()) {
+ case TemplateArgument::Null:
+ case TemplateArgument::Declaration:
+ case TemplateArgument::Integral:
+ return false;
+
+ case TemplateArgument::Type:
+ return Visit(Arg.getAsType());
+
+ case TemplateArgument::Template:
+ return getDerived().VisitTemplateName(Arg.getAsTemplate());
+
+ case TemplateArgument::Expression:
+ return getDerived().Visit(Arg.getAsExpr());
+
+ case TemplateArgument::Pack:
+ return getDerived().VisitTemplateArguments(Arg.pack_begin(),
+ Arg.pack_size());
+ }
+
+ return false;
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitTemplateArguments(
+ const TemplateArgument *Args,
+ unsigned NumArgs) {
+ for (unsigned I = 0; I != NumArgs; ++I)
+ if (getDerived().VisitTemplateArgument(Args[I]))
+ return true;
+
+ return false;
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitStmt(Stmt *Node) {
+ for (Stmt::child_iterator C = Node->child_begin(), CEnd = Node->child_end();
+ C != CEnd; ++C) {
+ if (Visit(*C))
+ return true;
+ }
+
+ return false;
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitType(Type *T) {
+ return false;
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitBuiltinType(BuiltinType *T) {
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitComplexType(ComplexType *T) {
+ if (Visit(T->getElementType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitPointerType(PointerType *T) {
+ if (Visit(T->getPointeeType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitBlockPointerType(
+ BlockPointerType *T) {
+ if (Visit(T->getPointeeType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitReferenceType(ReferenceType *T) {
+ if (Visit(T->getPointeeType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitLValueReferenceType(
+ LValueReferenceType *T) {
+ return getDerived().VisitReferenceType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitRValueReferenceType(
+ RValueReferenceType *T) {
+ return getDerived().VisitReferenceType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitMemberPointerType(
+ MemberPointerType *T) {
+ if (Visit(QualType(T->getClass(), 0)) || Visit(T->getPointeeType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitArrayType(ArrayType *T) {
+ if (Visit(T->getElementType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitConstantArrayType(
+ ConstantArrayType *T) {
+ return getDerived().VisitArrayType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitIncompleteArrayType(
+ IncompleteArrayType *T) {
+ return getDerived().VisitArrayType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitVariableArrayType(
+ VariableArrayType *T) {
+ if (Visit(T->getSizeExpr()))
+ return true;
+
+ return getDerived().VisitArrayType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitDependentSizedArrayType(
+ DependentSizedArrayType *T) {
+ if (T->getSizeExpr() && Visit(T->getSizeExpr()))
+ return true;
+
+ return getDerived().VisitArrayType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitDependentSizedExtVectorType(
+ DependentSizedExtVectorType *T) {
+ if ((T->getSizeExpr() && Visit(T->getSizeExpr())) ||
+ Visit(T->getElementType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitVectorType(VectorType *T) {
+ if (Visit(T->getElementType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitExtVectorType(ExtVectorType *T) {
+ return getDerived().VisitVectorType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitFunctionType(FunctionType *T) {
+ if (Visit(T->getResultType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitFunctionNoProtoType(
+ FunctionNoProtoType *T) {
+ return getDerived().VisitFunctionType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitFunctionProtoType(
+ FunctionProtoType *T) {
+ for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
+ AEnd = T->arg_type_end();
+ A != AEnd; ++A) {
+ if (Visit(*A))
+ return true;
+ }
+
+ for (FunctionProtoType::exception_iterator E = T->exception_begin(),
+ EEnd = T->exception_end();
+ E != EEnd; ++E) {
+ if (Visit(*E))
+ return true;
+ }
+
+ return getDerived().VisitFunctionType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitUnresolvedUsingType(
+ UnresolvedUsingType *T) {
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitTypedefType(TypedefType *T) {
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitTypeOfExprType(TypeOfExprType *T) {
+ if (Visit(T->getUnderlyingExpr()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitTypeOfType(TypeOfType *T) {
+ if (Visit(T->getUnderlyingType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitDecltypeType(DecltypeType *T) {
+ if (Visit(T->getUnderlyingExpr()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitTagType(TagType *T) {
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitRecordType(RecordType *T) {
+ return getDerived().VisitTagType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitEnumType(EnumType *T) {
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitTemplateTypeParmType(
+ TemplateTypeParmType *T) {
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitSubstTemplateTypeParmType(
+ SubstTemplateTypeParmType *T) {
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitTemplateSpecializationType(
+ TemplateSpecializationType *T) {
+ if (getDerived().VisitTemplateName(T->getTemplateName()) ||
+ getDerived().VisitTemplateArguments(T->getArgs(), T->getNumArgs()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitInjectedClassNameType(
+ InjectedClassNameType *T) {
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitElaboratedType(ElaboratedType *T) {
+ if (T->getQualifier() &&
+ getDerived().VisitNestedNameSpecifier(T->getQualifier()))
+ return true;
+ if (Visit(T->getNamedType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitDependentNameType(
+ DependentNameType *T) {
+ if (T->getQualifier() &&
+ getDerived().VisitNestedNameSpecifier(T->getQualifier()))
+ return true;
+
+ if (T->getTemplateId() &&
+ getDerived().VisitTemplateSpecializationType(
+ const_cast(T->getTemplateId())))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitObjCInterfaceType(
+ ObjCInterfaceType *T) {
+ return getDerived().VisitObjCObjectType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitObjCObjectType(ObjCObjectType *T) {
+ // We have to watch out here because an ObjCInterfaceType's base
+ // type is itself.
+ if (T->getBaseType().getTypePtr() != T)
+ if (Visit(T->getBaseType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitObjCObjectPointerType(
+ ObjCObjectPointerType *T) {
+ if (Visit(T->getPointeeType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template
+bool RecursiveASTVisitorImpl::VisitDecl(Decl *D) {
+ if (DeclContext *DC = dyn_cast(D)) {
+ for (DeclContext::decl_iterator Child = DC->decls_begin(),
+ ChildEnd = DC->decls_end();
+ Child != ChildEnd; ++Child)
+ if (Visit(*Child))
+ return true;
+
+ return false;
+ }
+
+ return false;
+}
+
+/// \brief A visitor that recursively walks the entire Clang AST.
+///
+/// Clients of this visitor should subclass the visitor (providing
+/// themselves as the template argument, using the curiously
+/// recurring template pattern) and override any of the Visit*
+/// methods (except Visit()) for declaration, type, statement,
+/// expression, or other AST nodes where the visitor should customize
+/// behavior. Returning "true" from one of these overridden functions
+/// will abort the entire traversal. An overridden Visit* method
+/// will not descend further into the AST for that node unless
+/// Base::Visit* is called.
+template
+class RecursiveASTVisitor : public RecursiveASTVisitorImpl {
+ typedef RecursiveASTVisitorImpl Impl;
+public:
+ typedef RecursiveASTVisitor Base;
+
+ bool VisitDeclaratorDecl(DeclaratorDecl *D);
+ bool VisitFunctionDecl(FunctionDecl *D);
+ bool VisitVarDecl(VarDecl *D);
+ bool VisitBlockDecl(BlockDecl *D);
+ bool VisitDeclStmt(DeclStmt *S);
+ bool VisitFunctionType(FunctionType *F);
+ bool VisitFunctionProtoType(FunctionProtoType *F);
+};
+
+#define DEFINE_VISIT(Type, Name, Statement) \
+ template \
+ bool RecursiveASTVisitor::Visit ## Type (Type *Name) { \
+ if (Impl::Visit ## Type (Name)) return true; \
+ { Statement; } \
+ return false; \
+ }
+
+DEFINE_VISIT(DeclaratorDecl, D, {
+ if (TypeSourceInfo *TInfo = D->getTypeSourceInfo())
+ return this->Visit(TInfo->getType());
+ })
+
+DEFINE_VISIT(FunctionDecl, D, {
+ if (D->isThisDeclarationADefinition())
+ return this->Visit(D->getBody());
+ })
+
+DEFINE_VISIT(VarDecl, D, return this->Visit(D->getInit()))
+
+DEFINE_VISIT(BlockDecl, D, return this->Visit(D->getBody()))
+
+DEFINE_VISIT(DeclStmt, S, {
+ for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();
+ I != E; ++I) {
+ if (this->Visit(*I))
+ return true;
+ }
+ })
+
+// FunctionType is the common base class of FunctionNoProtoType (a
+// K&R-style function declaration that has no information about
+// its arguments) and FunctionProtoType.
+DEFINE_VISIT(FunctionType, F, return this->Visit(F->getResultType()))
+
+DEFINE_VISIT(FunctionProtoType, F, {
+ for (unsigned i = 0; i != F->getNumArgs(); ++i) {
+ if (this->Visit(F->getArgType(i)))
+ return true;
+ }
+ for (unsigned i = 0; i != F->getNumExceptions(); ++i) {
+ if (this->Visit(F->getExceptionType(i)))
+ return true;
+ }
+ })
+
+#undef DEFINE_VISIT
+
+#undef DISPATCH
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 0b68a40..9deae15 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -98,12 +98,14 @@ public:
enum StmtClass {
NoStmtClass = 0,
#define STMT(CLASS, PARENT) CLASS##Class,
-#define FIRST_STMT(CLASS) firstStmtConstant = CLASS##Class,
-#define LAST_STMT(CLASS) lastStmtConstant = CLASS##Class,
-#define FIRST_EXPR(CLASS) firstExprConstant = CLASS##Class,
-#define LAST_EXPR(CLASS) lastExprConstant = CLASS##Class
-#define ABSTRACT_EXPR(CLASS, PARENT)
-#include "clang/AST/StmtNodes.def"
+#define STMT_RANGE(BASE, FIRST, LAST) \
+ first##BASE##Constant = FIRST##Class, \
+ last##BASE##Constant = LAST##Class,
+#define LAST_STMT_RANGE(BASE, FIRST, LAST) \
+ first##BASE##Constant = FIRST##Class, \
+ last##BASE##Constant = LAST##Class
+#define ABSTRACT_STMT(STMT)
+#include "clang/AST/StmtNodes.inc"
};
private:
/// \brief The statement class.
@@ -1083,9 +1085,15 @@ public:
class ReturnStmt : public Stmt {
Stmt *RetExpr;
SourceLocation RetLoc;
+ const VarDecl *NRVOCandidate;
+
public:
- ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass),
- RetExpr((Stmt*) E), RetLoc(RL) {}
+ ReturnStmt(SourceLocation RL)
+ : Stmt(ReturnStmtClass), RetExpr(0), RetLoc(RL), NRVOCandidate(0) { }
+
+ ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
+ : Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL),
+ NRVOCandidate(NRVOCandidate) {}
/// \brief Build an empty return expression.
explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { }
@@ -1097,6 +1105,14 @@ public:
SourceLocation getReturnLoc() const { return RetLoc; }
void setReturnLoc(SourceLocation L) { RetLoc = L; }
+ /// \brief Retrieve the variable that might be used for the named return
+ /// value optimization.
+ ///
+ /// The optimization itself can only be performed if the variable is
+ /// also marked as an NRVO object.
+ const VarDecl *getNRVOCandidate() const { return NRVOCandidate; }
+ void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; }
+
virtual SourceRange getSourceRange() const;
static bool classof(const Stmt *T) {
diff --git a/include/clang/AST/StmtNodes.td b/include/clang/AST/StmtNodes.td
new file mode 100644
index 0000000..60c94a6
--- /dev/null
+++ b/include/clang/AST/StmtNodes.td
@@ -0,0 +1,127 @@
+class Stmt {
+ bit Abstract = abstract;
+}
+
+class DStmt : Stmt {
+ Stmt Base = base;
+}
+
+// Statements
+def NullStmt : Stmt;
+def CompoundStmt : Stmt;
+def LabelStmt : Stmt;
+def IfStmt : Stmt;
+def SwitchStmt : Stmt;
+def WhileStmt : Stmt;
+def DoStmt : Stmt;
+def ForStmt : Stmt;
+def GotoStmt : Stmt;
+def IndirectGotoStmt : Stmt;
+def ContinueStmt : Stmt;
+def BreakStmt : Stmt;
+def ReturnStmt : Stmt;
+def DeclStmt : Stmt;
+def SwitchCase : Stmt;
+def CaseStmt : DStmt;
+def DefaultStmt : DStmt;
+
+// GNU Extensions
+def AsmStmt : Stmt;
+
+// Obj-C statements
+def ObjCAtTryStmt : Stmt;
+def ObjCAtCatchStmt : Stmt;
+def ObjCAtFinallyStmt : Stmt;
+def ObjCAtThrowStmt : Stmt;
+def ObjCAtSynchronizedStmt : Stmt;
+def ObjCForCollectionStmt : Stmt;
+
+// C++ statments
+def CXXCatchStmt : Stmt;
+def CXXTryStmt : Stmt;
+
+// Expressions
+def Expr : Stmt<1>;
+def PredefinedExpr : DStmt;
+def DeclRefExpr : DStmt;
+def IntegerLiteral : DStmt;
+def FloatingLiteral : DStmt;
+def ImaginaryLiteral : DStmt;
+def StringLiteral : DStmt;
+def CharacterLiteral : DStmt;
+def ParenExpr : DStmt;
+def UnaryOperator : DStmt;
+def OffsetOfExpr : DStmt;
+def SizeOfAlignOfExpr : DStmt;
+def ArraySubscriptExpr : DStmt;
+def CallExpr : DStmt;
+def MemberExpr : DStmt;
+def CastExpr : DStmt;
+def BinaryOperator : DStmt;
+def CompoundAssignOperator : DStmt;
+def ConditionalOperator : DStmt;
+def ImplicitCastExpr : DStmt;
+def ExplicitCastExpr : DStmt;
+def CStyleCastExpr : DStmt;
+def CompoundLiteralExpr : DStmt;
+def ExtVectorElementExpr : DStmt;
+def InitListExpr : DStmt;
+def DesignatedInitExpr : DStmt;
+def ImplicitValueInitExpr : DStmt;
+def ParenListExpr : DStmt;
+def VAArgExpr : DStmt;
+
+// GNU Extensions.
+def AddrLabelExpr : DStmt;
+def StmtExpr : DStmt;
+def TypesCompatibleExpr : DStmt;
+def ChooseExpr : DStmt;
+def GNUNullExpr : DStmt;
+
+// C++ Expressions.
+def CXXOperatorCallExpr : DStmt;
+def CXXMemberCallExpr : DStmt;
+def CXXNamedCastExpr : DStmt;
+def CXXStaticCastExpr : DStmt;
+def CXXDynamicCastExpr : DStmt;
+def CXXReinterpretCastExpr : DStmt;
+def CXXConstCastExpr : DStmt;
+def CXXFunctionalCastExpr : DStmt;
+def CXXTypeidExpr : DStmt;
+def CXXBoolLiteralExpr : DStmt;
+def CXXNullPtrLiteralExpr : DStmt;
+def CXXThisExpr : DStmt;
+def CXXThrowExpr : DStmt;
+def CXXDefaultArgExpr : DStmt;
+def CXXZeroInitValueExpr : DStmt;
+def CXXNewExpr : DStmt;
+def CXXDeleteExpr : DStmt;
+def CXXPseudoDestructorExpr : DStmt;
+def UnresolvedLookupExpr : DStmt;
+def UnaryTypeTraitExpr : DStmt;
+def DependentScopeDeclRefExpr : DStmt;
+def CXXConstructExpr : DStmt;
+def CXXBindTemporaryExpr : DStmt;
+def CXXBindReferenceExpr : DStmt;
+def CXXExprWithTemporaries : DStmt;
+def CXXTemporaryObjectExpr : DStmt;
+def CXXUnresolvedConstructExpr : DStmt;
+def CXXDependentScopeMemberExpr : DStmt;
+def UnresolvedMemberExpr : DStmt;
+
+// Obj-C Expressions.
+def ObjCStringLiteral : DStmt;
+def ObjCEncodeExpr : DStmt;
+def ObjCMessageExpr : DStmt;
+def ObjCSelectorExpr : DStmt;
+def ObjCProtocolExpr : DStmt;
+def ObjCIvarRefExpr : DStmt