summaryrefslogtreecommitdiffstats
path: root/include/clang/AST
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST')
-rw-r--r--include/clang/AST/ASTConsumer.h12
-rw-r--r--include/clang/AST/ASTContext.h56
-rw-r--r--include/clang/AST/Attr.h39
-rw-r--r--include/clang/AST/CMakeLists.txt5
-rw-r--r--include/clang/AST/CXXInheritance.h2
-rw-r--r--include/clang/AST/CanonicalType.h18
-rw-r--r--include/clang/AST/Decl.h142
-rw-r--r--include/clang/AST/DeclBase.h5
-rw-r--r--include/clang/AST/DeclCXX.h236
-rw-r--r--include/clang/AST/DeclContextInternals.h3
-rw-r--r--include/clang/AST/DeclObjC.h24
-rw-r--r--include/clang/AST/DeclTemplate.h51
-rw-r--r--include/clang/AST/DeclarationName.h5
-rw-r--r--include/clang/AST/Expr.h51
-rw-r--r--include/clang/AST/ExprCXX.h179
-rw-r--r--include/clang/AST/Makefile13
-rw-r--r--include/clang/AST/RecordLayout.h15
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h768
-rw-r--r--include/clang/AST/Stmt.h32
-rw-r--r--include/clang/AST/StmtNodes.td127
-rw-r--r--include/clang/AST/StmtVisitor.h6
-rw-r--r--include/clang/AST/TemplateBase.h6
-rw-r--r--include/clang/AST/TemplateName.h2
-rw-r--r--include/clang/AST/Type.h689
-rw-r--r--include/clang/AST/TypeLoc.h312
-rw-r--r--include/clang/AST/TypeLocBuilder.h14
-rw-r--r--include/clang/AST/TypeNodes.def4
-rw-r--r--include/clang/AST/TypeVisitor.h4
-rw-r--r--include/clang/AST/UnresolvedSet.h8
29 files changed, 2279 insertions, 549 deletions
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<TemplateTypeParmType> TemplateTypeParmTypes;
llvm::FoldingSet<SubstTemplateTypeParmType> SubstTemplateTypeParmTypes;
llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes;
- llvm::FoldingSet<QualifiedNameType> QualifiedNameTypes;
+ llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
llvm::FoldingSet<DependentNameType> DependentNameTypes;
- llvm::FoldingSet<ObjCInterfaceType> ObjCInterfaceTypes;
+ llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
- llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
llvm::FoldingSet<DependentTemplateName> 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<const Expr *, 8> &BDRDs);
+ llvm::SmallVectorImpl<const Expr *> &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<CharUnits, CharUnits> getTypeInfoInChars(const Type *T);
+ std::pair<CharUnits, CharUnits> 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<std::pair<void (*)(void*), void *>, 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<StoredDeclsMap*,1> 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<TemplateTypeParmType>
};
template<>
+struct CanProxyAdaptor<ObjCObjectType>
+ : public CanProxyBase<ObjCObjectType> {
+ 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<ObjCObjectPointerType>
: public CanProxyBase<ObjCObjectPointerType> {
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<NamespaceDecl *>(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<TypedefDecl> {
: TypeDecl(Typedef, DC, L, Id), TInfo(TInfo) {}
virtual ~TypedefDecl();
+
+protected:
+ typedef Redeclarable<TypedefDecl> 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<TagDecl> {
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<TypedefDecl*>();
}
- void setTypedefForAnonDecl(TypedefDecl *TDD) { TypedefDeclOrQualifier = TDD; }
-
+
+ void setTypedefForAnonDecl(TypedefDecl *TDD);
+
NestedNameSpecifier *getQualifier() const {
return hasExtInfo() ? TypedefDeclOrQualifier.get<ExtInfo*>()->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<RecordDecl*>(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<int>(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<unsigned>(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<VarDecl **>(this + 1)[I];
+ }
+ const VarDecl *getArrayIndex(unsigned I) const {
+ assert(I < getNumArrayIndices() && "Out of bounds member array index");
+ return reinterpret_cast<const VarDecl * const *>(this + 1)[I];
+ }
+ void setArrayIndex(unsigned I, VarDecl *Index) {
+ assert(I < getNumArrayIndices() && "Out of bounds member array index");
+ reinterpret_cast<VarDecl **>(this + 1)[I] = Index;
+ }
+
Expr *getInit() { return static_cast<Expr *>(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<UsingDirectiveDecl*>(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<NamespaceAliasDecl>(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<NamespaceAliasDecl>(ND) || isa<NamespaceDecl>(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<UsingShadowDecl*,8>::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<TemplateArgument, 4> 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<const TemplateArgument *, 1> FlatArguments;
/// \brief The number of template arguments in this template
@@ -175,14 +169,28 @@ class TemplateArgumentList {
llvm::PointerIntPair<const TemplateArgument *, 1> 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<ClassTemplatePartialSpecializationDecl *, 1, bool>
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<CXXSpecialName> *
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<const CXXBaseSpecifier> 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<TypeSourceInfo *>(); }
/// \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<TypeSourceInfo *>();
}
+
+ 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<Expr*>(Operand.get<Stmt *>());
}
-
- 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<Expr>(Op); }
Expr *getSubExpr() { return cast_or_null<Expr>(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<Expr **>(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<Expr **> (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<Expr>(SubExpr); }
Expr *getSubExpr() { return cast<Expr>(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<OverloadExpr*,1>(cast<OverloadExpr>(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<CXXExprWithTemporaries*>(this)->getTemporary(i);
}
+ void setTemporary(unsigned i, CXXTemporary *T) {
+ assert(i < NumTemps && "Index out of range");
+ Temps[i] = T;
+ }
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
const Expr *getSubExpr() const { return cast<Expr>(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<CLASS*>(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<typename Derived>
+class RecursiveASTVisitorImpl {
+public:
+ /// \brief Return a reference to the derived class.
+ Derived &getDerived() { return *static_cast<Derived*>(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<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::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<BinaryOperator>(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<UnaryOperator>(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<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::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<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::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<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::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<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::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<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::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<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitTemplateArguments(
+ const TemplateArgument *Args,
+ unsigned NumArgs) {
+ for (unsigned I = 0; I != NumArgs; ++I)
+ if (getDerived().VisitTemplateArgument(Args[I]))
+ return true;
+
+ return false;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::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<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitType(Type *T) {
+ return false;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitBuiltinType(BuiltinType *T) {
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitComplexType(ComplexType *T) {
+ if (Visit(T->getElementType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitPointerType(PointerType *T) {
+ if (Visit(T->getPointeeType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitBlockPointerType(
+ BlockPointerType *T) {
+ if (Visit(T->getPointeeType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitReferenceType(ReferenceType *T) {
+ if (Visit(T->getPointeeType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitLValueReferenceType(
+ LValueReferenceType *T) {
+ return getDerived().VisitReferenceType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitRValueReferenceType(
+ RValueReferenceType *T) {
+ return getDerived().VisitReferenceType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitMemberPointerType(
+ MemberPointerType *T) {
+ if (Visit(QualType(T->getClass(), 0)) || Visit(T->getPointeeType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitArrayType(ArrayType *T) {
+ if (Visit(T->getElementType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitConstantArrayType(
+ ConstantArrayType *T) {
+ return getDerived().VisitArrayType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitIncompleteArrayType(
+ IncompleteArrayType *T) {
+ return getDerived().VisitArrayType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitVariableArrayType(
+ VariableArrayType *T) {
+ if (Visit(T->getSizeExpr()))
+ return true;
+
+ return getDerived().VisitArrayType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitDependentSizedArrayType(
+ DependentSizedArrayType *T) {
+ if (T->getSizeExpr() && Visit(T->getSizeExpr()))
+ return true;
+
+ return getDerived().VisitArrayType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitDependentSizedExtVectorType(
+ DependentSizedExtVectorType *T) {
+ if ((T->getSizeExpr() && Visit(T->getSizeExpr())) ||
+ Visit(T->getElementType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitVectorType(VectorType *T) {
+ if (Visit(T->getElementType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitExtVectorType(ExtVectorType *T) {
+ return getDerived().VisitVectorType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitFunctionType(FunctionType *T) {
+ if (Visit(T->getResultType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitFunctionNoProtoType(
+ FunctionNoProtoType *T) {
+ return getDerived().VisitFunctionType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::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<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitUnresolvedUsingType(
+ UnresolvedUsingType *T) {
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitTypedefType(TypedefType *T) {
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitTypeOfExprType(TypeOfExprType *T) {
+ if (Visit(T->getUnderlyingExpr()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitTypeOfType(TypeOfType *T) {
+ if (Visit(T->getUnderlyingType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitDecltypeType(DecltypeType *T) {
+ if (Visit(T->getUnderlyingExpr()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitTagType(TagType *T) {
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitRecordType(RecordType *T) {
+ return getDerived().VisitTagType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitEnumType(EnumType *T) {
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitTemplateTypeParmType(
+ TemplateTypeParmType *T) {
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitSubstTemplateTypeParmType(
+ SubstTemplateTypeParmType *T) {
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitTemplateSpecializationType(
+ TemplateSpecializationType *T) {
+ if (getDerived().VisitTemplateName(T->getTemplateName()) ||
+ getDerived().VisitTemplateArguments(T->getArgs(), T->getNumArgs()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitInjectedClassNameType(
+ InjectedClassNameType *T) {
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitElaboratedType(ElaboratedType *T) {
+ if (T->getQualifier() &&
+ getDerived().VisitNestedNameSpecifier(T->getQualifier()))
+ return true;
+ if (Visit(T->getNamedType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitDependentNameType(
+ DependentNameType *T) {
+ if (T->getQualifier() &&
+ getDerived().VisitNestedNameSpecifier(T->getQualifier()))
+ return true;
+
+ if (T->getTemplateId() &&
+ getDerived().VisitTemplateSpecializationType(
+ const_cast<TemplateSpecializationType *>(T->getTemplateId())))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitObjCInterfaceType(
+ ObjCInterfaceType *T) {
+ return getDerived().VisitObjCObjectType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::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<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitObjCObjectPointerType(
+ ObjCObjectPointerType *T) {
+ if (Visit(T->getPointeeType()))
+ return true;
+
+ return getDerived().VisitType(T);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitorImpl<Derived>::VisitDecl(Decl *D) {
+ if (DeclContext *DC = dyn_cast<DeclContext>(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<typename Derived>
+class RecursiveASTVisitor : public RecursiveASTVisitorImpl<Derived> {
+ typedef RecursiveASTVisitorImpl<Derived> Impl;
+public:
+ typedef RecursiveASTVisitor<Derived> 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<typename Derived> \
+ bool RecursiveASTVisitor<Derived>::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 = 0> {
+ bit Abstract = abstract;
+}
+
+class DStmt<Stmt base, bit abstract = 0> : Stmt<abstract> {
+ 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<SwitchCase>;
+def DefaultStmt : DStmt<SwitchCase>;
+
+// 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<Expr>;
+def DeclRefExpr : DStmt<Expr>;
+def IntegerLiteral : DStmt<Expr>;
+def FloatingLiteral : DStmt<Expr>;
+def ImaginaryLiteral : DStmt<Expr>;
+def StringLiteral : DStmt<Expr>;
+def CharacterLiteral : DStmt<Expr>;
+def ParenExpr : DStmt<Expr>;
+def UnaryOperator : DStmt<Expr>;
+def OffsetOfExpr : DStmt<Expr>;
+def SizeOfAlignOfExpr : DStmt<Expr>;
+def ArraySubscriptExpr : DStmt<Expr>;
+def CallExpr : DStmt<Expr>;
+def MemberExpr : DStmt<Expr>;
+def CastExpr : DStmt<Expr, 1>;
+def BinaryOperator : DStmt<Expr>;
+def CompoundAssignOperator : DStmt<BinaryOperator>;
+def ConditionalOperator : DStmt<Expr>;
+def ImplicitCastExpr : DStmt<CastExpr>;
+def ExplicitCastExpr : DStmt<CastExpr, 1>;
+def CStyleCastExpr : DStmt<ExplicitCastExpr>;
+def CompoundLiteralExpr : DStmt<Expr>;
+def ExtVectorElementExpr : DStmt<Expr>;
+def InitListExpr : DStmt<Expr>;
+def DesignatedInitExpr : DStmt<Expr>;
+def ImplicitValueInitExpr : DStmt<Expr>;
+def ParenListExpr : DStmt<Expr>;
+def VAArgExpr : DStmt<Expr>;
+
+// GNU Extensions.
+def AddrLabelExpr : DStmt<Expr>;
+def StmtExpr : DStmt<Expr>;
+def TypesCompatibleExpr : DStmt<Expr>;
+def ChooseExpr : DStmt<Expr>;
+def GNUNullExpr : DStmt<Expr>;
+
+// C++ Expressions.
+def CXXOperatorCallExpr : DStmt<CallExpr>;
+def CXXMemberCallExpr : DStmt<CallExpr>;
+def CXXNamedCastExpr : DStmt<ExplicitCastExpr, 1>;
+def CXXStaticCastExpr : DStmt<CXXNamedCastExpr>;
+def CXXDynamicCastExpr : DStmt<CXXNamedCastExpr>;
+def CXXReinterpretCastExpr : DStmt<CXXNamedCastExpr>;
+def CXXConstCastExpr : DStmt<CXXNamedCastExpr>;
+def CXXFunctionalCastExpr : DStmt<ExplicitCastExpr>;
+def CXXTypeidExpr : DStmt<Expr>;
+def CXXBoolLiteralExpr : DStmt<Expr>;
+def CXXNullPtrLiteralExpr : DStmt<Expr>;
+def CXXThisExpr : DStmt<Expr>;
+def CXXThrowExpr : DStmt<Expr>;
+def CXXDefaultArgExpr : DStmt<Expr>;
+def CXXZeroInitValueExpr : DStmt<Expr>;
+def CXXNewExpr : DStmt<Expr>;
+def CXXDeleteExpr : DStmt<Expr>;
+def CXXPseudoDestructorExpr : DStmt<Expr>;
+def UnresolvedLookupExpr : DStmt<Expr>;
+def UnaryTypeTraitExpr : DStmt<Expr>;
+def DependentScopeDeclRefExpr : DStmt<Expr>;
+def CXXConstructExpr : DStmt<Expr>;
+def CXXBindTemporaryExpr : DStmt<Expr>;
+def CXXBindReferenceExpr : DStmt<Expr>;
+def CXXExprWithTemporaries : DStmt<Expr>;
+def CXXTemporaryObjectExpr : DStmt<CXXConstructExpr>;
+def CXXUnresolvedConstructExpr : DStmt<Expr>;
+def CXXDependentScopeMemberExpr : DStmt<Expr>;
+def UnresolvedMemberExpr : DStmt<Expr>;
+
+// Obj-C Expressions.
+def ObjCStringLiteral : DStmt<Expr>;
+def ObjCEncodeExpr : DStmt<Expr>;
+def ObjCMessageExpr : DStmt<Expr>;
+def ObjCSelectorExpr : DStmt<Expr>;
+def ObjCProtocolExpr : DStmt<Expr>;
+def ObjCIvarRefExpr : DStmt<Expr>;
+def ObjCPropertyRefExpr : DStmt<Expr>;
+def ObjCImplicitSetterGetterRefExpr : DStmt<Expr>;
+def ObjCSuperExpr : DStmt<Expr>;
+def ObjCIsaExpr : DStmt<Expr>;
+
+// Clang Extensions.
+def ShuffleVectorExpr : DStmt<Expr>;
+def BlockExpr : DStmt<Expr>;
+def BlockDeclRefExpr : DStmt<Expr>;
diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h
index 4986f08..8078451 100644
--- a/include/clang/AST/StmtVisitor.h
+++ b/include/clang/AST/StmtVisitor.h
@@ -105,10 +105,10 @@ public:
// Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
switch (S->getStmtClass()) {
default: assert(0 && "Unknown stmt kind!");
-#define ABSTRACT_EXPR(CLASS, PARENT)
+#define ABSTRACT_STMT(STMT)
#define STMT(CLASS, PARENT) \
case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS);
-#include "clang/AST/StmtNodes.def"
+#include "clang/AST/StmtNodes.inc"
}
}
@@ -116,7 +116,7 @@ public:
// back on VisitExpr or whatever else is the superclass.
#define STMT(CLASS, PARENT) \
RetTy Visit ## CLASS(CLASS *S) { DISPATCH(PARENT, PARENT); }
-#include "clang/AST/StmtNodes.def"
+#include "clang/AST/StmtNodes.inc"
// If the implementation doesn't implement binary operator methods, fall back
// on VisitBinaryOperator.
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 50a100c..8b38001 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -28,6 +28,7 @@ namespace llvm {
namespace clang {
class Decl;
+class DiagnosticBuilder;
class Expr;
class TypeSourceInfo;
@@ -473,6 +474,9 @@ public:
}
};
-}
+const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ const TemplateArgument &Arg);
+
+} // end namespace clang
#endif
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
index f3de9fa..2e3b6df 100644
--- a/include/clang/AST/TemplateName.h
+++ b/include/clang/AST/TemplateName.h
@@ -188,7 +188,7 @@ const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
/// declaration for "vector". The QualifiedTemplateName class is only
/// used to provide "sugar" for template names that were expressed
/// with a qualified name, and has no semantic meaning. In this
-/// manner, it is to TemplateName what QualifiedNameType is to Type,
+/// manner, it is to TemplateName what ElaboratedType is to Type,
/// providing extra syntactic sugar for downstream clients.
class QualifiedTemplateName : public llvm::FoldingSetNode {
/// \brief The nested name specifier that qualifies the template name.
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 030c74c..c24bddb 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -92,7 +92,7 @@ namespace clang {
class TemplateArgumentLoc;
class TemplateArgumentListInfo;
class Type;
- class QualifiedNameType;
+ class ElaboratedType;
struct PrintingPolicy;
template <typename> class CanQual;
@@ -396,7 +396,8 @@ enum CallingConv {
CC_Default,
CC_C, // __attribute__((cdecl))
CC_X86StdCall, // __attribute__((stdcall))
- CC_X86FastCall // __attribute__((fastcall))
+ CC_X86FastCall, // __attribute__((fastcall))
+ CC_X86ThisCall // __attribute__((thiscall))
};
@@ -755,6 +756,9 @@ public:
};
private:
+ Type(const Type&); // DO NOT IMPLEMENT.
+ void operator=(const Type&); // DO NOT IMPLEMENT.
+
QualType CanonicalType;
/// TypeClass bitfield - Enum that specifies what subclass this belongs to.
@@ -764,15 +768,25 @@ private:
/// Note that this should stay at the end of the ivars for Type so that
/// subclasses can pack their bitfields into the same word.
bool Dependent : 1;
-
- Type(const Type&); // DO NOT IMPLEMENT.
- void operator=(const Type&); // DO NOT IMPLEMENT.
+
+ /// \brief Whether the linkage of this type is already known.
+ mutable bool LinkageKnown : 1;
+
+ /// \brief Linkage of this type.
+ mutable unsigned CachedLinkage : 2;
+
protected:
+ /// \brief Compute the linkage of this type.
+ virtual Linkage getLinkageImpl() const;
+
+ enum { BitsRemainingInType = 20 };
+
// silence VC++ warning C4355: 'this' : used in base member initializer list
Type *this_() { return this; }
Type(TypeClass tc, QualType Canonical, bool dependent)
: CanonicalType(Canonical.isNull() ? QualType(this_(), 0) : Canonical),
- TC(tc), Dependent(dependent) {}
+ TC(tc), Dependent(dependent), LinkageKnown(false),
+ CachedLinkage(NoLinkage) {}
virtual ~Type() {}
virtual void Destroy(ASTContext& C);
friend class ASTContext;
@@ -879,7 +893,7 @@ public:
bool isObjCObjectPointerType() const; // Pointer to *any* ObjC object.
// FIXME: change this to 'raw' interface type, so we can used 'interface' type
// for the common case.
- bool isObjCInterfaceType() const; // NSString or NSString<foo>
+ bool isObjCObjectType() const; // NSString or typeof(*(id)0)
bool isObjCQualifiedInterfaceType() const; // NSString<foo>
bool isObjCQualifiedIdType() const; // id<foo>
bool isObjCQualifiedClassType() const; // Class<foo>
@@ -920,7 +934,7 @@ public:
// for object declared using an interface.
const ObjCObjectPointerType *getAsObjCInterfacePointerType() const;
const ObjCObjectPointerType *getAsObjCQualifiedIdType() const;
- const ObjCInterfaceType *getAsObjCQualifiedInterfaceType() const;
+ const ObjCObjectType *getAsObjCQualifiedInterfaceType() const;
const CXXRecordDecl *getCXXRecordDeclForPointerType() const;
/// \brief Retrieves the CXXRecordDecl that this type refers to, either
@@ -935,10 +949,6 @@ public:
// immediately following this class.
template <typename T> const T *getAs() const;
- /// getAsPointerToObjCInterfaceType - If this is a pointer to an ObjC
- /// interface, return the interface type, otherwise return null.
- const ObjCInterfaceType *getAsPointerToObjCInterfaceType() const;
-
/// getArrayElementTypeNoTypeQual - If this is an array type, return the
/// element type of the array, potentially with type qualifiers missing.
/// This method should never be used when type qualifiers are meaningful.
@@ -977,10 +987,13 @@ public:
/// set of type specifiers.
bool isSpecifierType() const;
- const char *getTypeClassName() const;
-
/// \brief Determine the linkage of this type.
- virtual Linkage getLinkage() const;
+ Linkage getLinkage() const;
+
+ /// \brief Note that the linkage is no longer known.
+ void ClearLinkageCache();
+
+ const char *getTypeClassName() const;
QualType getCanonicalTypeInternal() const {
return CanonicalType;
@@ -1040,12 +1053,25 @@ public:
UndeducedAuto, // In C++0x, this represents the type of an auto variable
// that has not been deduced yet.
- ObjCId, // This represents the ObjC 'id' type.
- ObjCClass, // This represents the ObjC 'Class' type.
+
+ /// The primitive Objective C 'id' type. The type pointed to by the
+ /// user-visible 'id' type. Only ever shows up in an AST as the base
+ /// type of an ObjCObjectType.
+ ObjCId,
+
+ /// The primitive Objective C 'Class' type. The type pointed to by the
+ /// user-visible 'Class' type. Only ever shows up in an AST as the
+ /// base type of an ObjCObjectType.
+ ObjCClass,
+
ObjCSel // This represents the ObjC 'SEL' type.
};
private:
Kind TypeKind;
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
public:
BuiltinType(Kind K)
: Type(Builtin, QualType(), /*Dependent=*/(K == Dependent)),
@@ -1073,8 +1099,6 @@ public:
return TypeKind >= Float && TypeKind <= LongDouble;
}
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
static bool classof(const BuiltinType *) { return true; }
};
@@ -1089,6 +1113,10 @@ class ComplexType : public Type, public llvm::FoldingSetNode {
ElementType(Element) {
}
friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
public:
QualType getElementType() const { return ElementType; }
@@ -1102,8 +1130,6 @@ public:
ID.AddPointer(Element.getAsOpaquePtr());
}
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
static bool classof(const ComplexType *) { return true; }
};
@@ -1117,6 +1143,10 @@ class PointerType : public Type, public llvm::FoldingSetNode {
Type(Pointer, CanonicalPtr, Pointee->isDependentType()), PointeeType(Pointee) {
}
friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
public:
QualType getPointeeType() const { return PointeeType; }
@@ -1131,8 +1161,6 @@ public:
ID.AddPointer(Pointee.getAsOpaquePtr());
}
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
static bool classof(const PointerType *) { return true; }
};
@@ -1148,6 +1176,10 @@ class BlockPointerType : public Type, public llvm::FoldingSetNode {
PointeeType(Pointee) {
}
friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
public:
// Get the pointee type. Pointee is required to always be a function type.
@@ -1163,8 +1195,6 @@ public:
ID.AddPointer(Pointee.getAsOpaquePtr());
}
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) {
return T->getTypeClass() == BlockPointer;
}
@@ -1200,6 +1230,9 @@ protected:
PointeeType(Referencee), SpelledAsLValue(SpelledAsLValue),
InnerRef(Referencee->isReferenceType()) {
}
+
+ virtual Linkage getLinkageImpl() const;
+
public:
bool isSpelledAsLValue() const { return SpelledAsLValue; }
bool isInnerRef() const { return InnerRef; }
@@ -1223,8 +1256,6 @@ public:
ID.AddBoolean(SpelledAsLValue);
}
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) {
return T->getTypeClass() == LValueReference ||
T->getTypeClass() == RValueReference;
@@ -1281,6 +1312,10 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
PointeeType(Pointee), Class(Cls) {
}
friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
public:
QualType getPointeeType() const { return PointeeType; }
@@ -1299,8 +1334,6 @@ public:
ID.AddPointer(Class);
}
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) {
return T->getTypeClass() == MemberPointer;
}
@@ -1342,6 +1375,9 @@ protected:
ElementType(et), SizeModifier(sm), IndexTypeQuals(tq) {}
friend class ASTContext; // ASTContext creates these.
+
+ virtual Linkage getLinkageImpl() const;
+
public:
QualType getElementType() const { return ElementType; }
ArraySizeModifier getSizeModifier() const {
@@ -1352,8 +1388,6 @@ public:
}
unsigned getIndexTypeCVRQualifiers() const { return IndexTypeQuals; }
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) {
return T->getTypeClass() == ConstantArray ||
T->getTypeClass() == VariableArray ||
@@ -1629,6 +1663,9 @@ protected:
: Type(tc, canonType, vecType->isDependentType()), ElementType(vecType),
NumElements(nElements), AltiVec(isAltiVec), Pixel(isPixel) {}
friend class ASTContext; // ASTContext creates these.
+
+ virtual Linkage getLinkageImpl() const;
+
public:
QualType getElementType() const { return ElementType; }
@@ -1655,8 +1692,6 @@ public:
ID.AddBoolean(isPixel);
}
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) {
return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
}
@@ -1733,6 +1768,8 @@ public:
/// class of FunctionNoProtoType and FunctionProtoType.
///
class FunctionType : public Type {
+ virtual void ANCHOR(); // Key function for FunctionType.
+
/// SubClassData - This field is owned by the subclass, put here to pack
/// tightly with the ivars in Type.
bool SubClassData : 1;
@@ -1753,7 +1790,7 @@ class FunctionType : public Type {
unsigned RegParm : 3;
/// CallConv - The calling convention used by the function.
- unsigned CallConv : 2;
+ unsigned CallConv : 3;
// The type returned by the function.
QualType ResultType;
@@ -1821,7 +1858,7 @@ class FunctionType : public Type {
// The value passed to __attribute__((regparm(x)))
unsigned RegParm;
// The calling convention as specified via
- // __attribute__((cdecl|stdcall||fastcall))
+ // __attribute__((cdecl|stdcall|fastcall|thiscall))
CallingConv CC;
};
@@ -1862,6 +1899,10 @@ class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
: FunctionType(FunctionNoProto, Result, false, 0, Canonical,
/*Dependent=*/false, Info) {}
friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
public:
// No additional state past what FunctionType provides.
@@ -1879,8 +1920,6 @@ public:
ID.AddPointer(ResultType.getAsOpaquePtr());
}
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionNoProto;
}
@@ -1944,6 +1983,9 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these.
+protected:
+ virtual Linkage getLinkageImpl() const;
+
public:
unsigned getNumArgs() const { return NumArgs; }
QualType getArgType(unsigned i) const {
@@ -1984,8 +2026,6 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionProto;
}
@@ -2190,6 +2230,8 @@ class TagType : public Type {
protected:
TagType(TypeClass TC, const TagDecl *D, QualType can);
+ virtual Linkage getLinkageImpl() const;
+
public:
TagDecl *getDecl() const { return decl.getPointer(); }
@@ -2198,8 +2240,6 @@ public:
bool isBeingDefined() const { return decl.getInt(); }
void setBeingDefined(bool Def) const { decl.setInt(Def? 1 : 0); }
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) {
return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
}
@@ -2264,68 +2304,6 @@ public:
static bool classof(const EnumType *) { return true; }
};
-/// ElaboratedType - A non-canonical type used to represents uses of
-/// elaborated type specifiers in C++. For example:
-///
-/// void foo(union MyUnion);
-/// ^^^^^^^^^^^^^
-///
-/// At the moment, for efficiency we do not create elaborated types in
-/// C, since outside of typedefs all references to structs would
-/// necessarily be elaborated.
-class ElaboratedType : public Type, public llvm::FoldingSetNode {
-public:
- enum TagKind {
- TK_struct,
- TK_union,
- TK_class,
- TK_enum
- };
-
-private:
- /// The tag that was used in this elaborated type specifier.
- TagKind Tag;
-
- /// The underlying type.
- QualType UnderlyingType;
-
- explicit ElaboratedType(QualType Ty, TagKind Tag, QualType Canon)
- : Type(Elaborated, Canon, Canon->isDependentType()),
- Tag(Tag), UnderlyingType(Ty) { }
- friend class ASTContext; // ASTContext creates these.
-
-public:
- TagKind getTagKind() const { return Tag; }
- QualType getUnderlyingType() const { return UnderlyingType; }
-
- /// \brief Remove a single level of sugar.
- QualType desugar() const { return getUnderlyingType(); }
-
- /// \brief Returns whether this type directly provides sugar.
- bool isSugared() const { return true; }
-
- static const char *getNameForTagKind(TagKind Kind) {
- switch (Kind) {
- default: assert(0 && "Unknown TagKind!");
- case TK_struct: return "struct";
- case TK_union: return "union";
- case TK_class: return "class";
- case TK_enum: return "enum";
- }
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getUnderlyingType(), getTagKind());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType T, TagKind Tag) {
- ID.AddPointer(T.getAsOpaquePtr());
- ID.AddInteger(Tag);
- }
-
- static bool classof(const ElaboratedType*) { return true; }
- static bool classof(const Type *T) { return T->getTypeClass() == Elaborated; }
-};
-
class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
unsigned Depth : 15;
unsigned Index : 16;
@@ -2592,46 +2570,116 @@ public:
static bool classof(const InjectedClassNameType *T) { return true; }
};
+/// \brief The kind of a tag type.
+enum TagTypeKind {
+ /// \brief The "struct" keyword.
+ TTK_Struct,
+ /// \brief The "union" keyword.
+ TTK_Union,
+ /// \brief The "class" keyword.
+ TTK_Class,
+ /// \brief The "enum" keyword.
+ TTK_Enum
+};
+
/// \brief The elaboration keyword that precedes a qualified type name or
/// introduces an elaborated-type-specifier.
enum ElaboratedTypeKeyword {
- /// \brief No keyword precedes the qualified type name.
- ETK_None,
- /// \brief The "typename" keyword precedes the qualified type name, e.g.,
- /// \c typename T::type.
- ETK_Typename,
- /// \brief The "class" keyword introduces the elaborated-type-specifier.
- ETK_Class,
/// \brief The "struct" keyword introduces the elaborated-type-specifier.
ETK_Struct,
/// \brief The "union" keyword introduces the elaborated-type-specifier.
ETK_Union,
+ /// \brief The "class" keyword introduces the elaborated-type-specifier.
+ ETK_Class,
/// \brief The "enum" keyword introduces the elaborated-type-specifier.
- ETK_Enum
+ ETK_Enum,
+ /// \brief The "typename" keyword precedes the qualified type name, e.g.,
+ /// \c typename T::type.
+ ETK_Typename,
+ /// \brief No keyword precedes the qualified type name.
+ ETK_None
};
-
-/// \brief Represents a type that was referred to via a qualified
-/// name, e.g., N::M::type.
+
+/// A helper class for Type nodes having an ElaboratedTypeKeyword.
+/// The keyword in stored in the free bits of the base class.
+/// Also provides a few static helpers for converting and printing
+/// elaborated type keyword and tag type kind enumerations.
+class TypeWithKeyword : public Type {
+ /// Keyword - Encodes an ElaboratedTypeKeyword enumeration constant.
+ unsigned Keyword : 3;
+
+protected:
+ TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
+ QualType Canonical, bool dependent)
+ : Type(tc, Canonical, dependent), Keyword(Keyword) {}
+
+public:
+ virtual ~TypeWithKeyword(); // pin vtable to Type.cpp
+
+ ElaboratedTypeKeyword getKeyword() const {
+ return static_cast<ElaboratedTypeKeyword>(Keyword);
+ }
+
+ /// getKeywordForTypeSpec - Converts a type specifier (DeclSpec::TST)
+ /// into an elaborated type keyword.
+ static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec);
+
+ /// getTagTypeKindForTypeSpec - Converts a type specifier (DeclSpec::TST)
+ /// into a tag type kind. It is an error to provide a type specifier
+ /// which *isn't* a tag kind here.
+ static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec);
+
+ /// getKeywordForTagDeclKind - Converts a TagTypeKind into an
+ /// elaborated type keyword.
+ static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag);
+
+ /// getTagTypeKindForKeyword - Converts an elaborated type keyword into
+ // a TagTypeKind. It is an error to provide an elaborated type keyword
+ /// which *isn't* a tag kind here.
+ static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword);
+
+ static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword);
+
+ static const char *getKeywordName(ElaboratedTypeKeyword Keyword);
+
+ static const char *getTagTypeKindName(TagTypeKind Kind) {
+ return getKeywordName(getKeywordForTagTypeKind(Kind));
+ }
+
+ class CannotCastToThisType {};
+ static CannotCastToThisType classof(const Type *);
+};
+
+/// \brief Represents a type that was referred to using an elaborated type
+/// keyword, e.g., struct S, or via a qualified name, e.g., N::M::type,
+/// or both.
///
/// This type is used to keep track of a type name as written in the
-/// source code, including any nested-name-specifiers. The type itself
-/// is always "sugar", used to express what was written in the source
-/// code but containing no additional semantic information.
-class QualifiedNameType : public Type, public llvm::FoldingSetNode {
+/// source code, including tag keywords and any nested-name-specifiers.
+/// The type itself is always "sugar", used to express what was written
+/// in the source code but containing no additional semantic information.
+class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
+
/// \brief The nested name specifier containing the qualifier.
NestedNameSpecifier *NNS;
/// \brief The type that this qualified name refers to.
QualType NamedType;
- QualifiedNameType(NestedNameSpecifier *NNS, QualType NamedType,
- QualType CanonType)
- : Type(QualifiedName, CanonType, NamedType->isDependentType()),
- NNS(NNS), NamedType(NamedType) { }
+ ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
+ QualType NamedType, QualType CanonType)
+ : TypeWithKeyword(Keyword, Elaborated, CanonType,
+ NamedType->isDependentType()),
+ NNS(NNS), NamedType(NamedType) {
+ assert(!(Keyword == ETK_None && NNS == 0) &&
+ "ElaboratedType cannot have elaborated type keyword "
+ "and name qualifier both null.");
+ }
friend class ASTContext; // ASTContext creates these
public:
+
/// \brief Retrieve the qualification on this type.
NestedNameSpecifier *getQualifier() const { return NNS; }
@@ -2645,19 +2693,20 @@ public:
bool isSugared() const { return true; }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, NNS, NamedType);
+ Profile(ID, getKeyword(), NNS, NamedType);
}
- static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
- QualType NamedType) {
+ static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS, QualType NamedType) {
+ ID.AddInteger(Keyword);
ID.AddPointer(NNS);
NamedType.Profile(ID);
}
static bool classof(const Type *T) {
- return T->getTypeClass() == QualifiedName;
+ return T->getTypeClass() == Elaborated;
}
- static bool classof(const QualifiedNameType *T) { return true; }
+ static bool classof(const ElaboratedType *T) { return true; }
};
/// \brief Represents a qualified type name for which the type name is
@@ -2669,10 +2718,8 @@ public:
/// typename-specifier), "class", "struct", "union", or "enum" (for a
/// dependent elaborated-type-specifier), or nothing (in contexts where we
/// know that we must be referring to a type, e.g., in a base class specifier).
-class DependentNameType : public Type, public llvm::FoldingSetNode {
- /// \brief The keyword used to elaborate this type.
- ElaboratedTypeKeyword Keyword;
-
+class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
+
/// \brief The nested name specifier containing the qualifier.
NestedNameSpecifier *NNS;
@@ -2684,16 +2731,16 @@ class DependentNameType : public Type, public llvm::FoldingSetNode {
DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
const IdentifierInfo *Name, QualType CanonType)
- : Type(DependentName, CanonType, true),
- Keyword(Keyword), NNS(NNS), Name(Name) {
+ : TypeWithKeyword(Keyword, DependentName, CanonType, true),
+ NNS(NNS), Name(Name) {
assert(NNS->isDependent() &&
"DependentNameType requires a dependent nested-name-specifier");
}
DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
const TemplateSpecializationType *Ty, QualType CanonType)
- : Type(DependentName, CanonType, true),
- Keyword(Keyword), NNS(NNS), Name(Ty) {
+ : TypeWithKeyword(Keyword, DependentName, CanonType, true),
+ NNS(NNS), Name(Ty) {
assert(NNS->isDependent() &&
"DependentNameType requires a dependent nested-name-specifier");
}
@@ -2701,9 +2748,7 @@ class DependentNameType : public Type, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
public:
- /// \brief Retrieve the keyword used to elaborate this type.
- ElaboratedTypeKeyword getKeyword() const { return Keyword; }
-
+
/// \brief Retrieve the qualification on this type.
NestedNameSpecifier *getQualifier() const { return NNS; }
@@ -2727,7 +2772,7 @@ public:
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Keyword, NNS, Name);
+ Profile(ID, getKeyword(), NNS, Name);
}
static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
@@ -2743,153 +2788,333 @@ public:
static bool classof(const DependentNameType *T) { return true; }
};
-/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for
-/// object oriented design. They basically correspond to C++ classes. There
-/// are two kinds of interface types, normal interfaces like "NSString" and
-/// qualified interfaces, which are qualified with a protocol list like
-/// "NSString<NSCopyable, NSAmazing>".
-class ObjCInterfaceType : public Type, public llvm::FoldingSetNode {
- ObjCInterfaceDecl *Decl;
+/// ObjCObjectType - Represents a class type in Objective C.
+/// Every Objective C type is a combination of a base type and a
+/// list of protocols.
+///
+/// Given the following declarations:
+/// @class C;
+/// @protocol P;
+///
+/// 'C' is an ObjCInterfaceType C. It is sugar for an ObjCObjectType
+/// with base C and no protocols.
+///
+/// 'C<P>' is an ObjCObjectType with base C and protocol list [P].
+///
+/// 'id' is a TypedefType which is sugar for an ObjCPointerType whose
+/// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType
+/// and no protocols.
+///
+/// 'id<P>' is an ObjCPointerType whose pointee is an ObjCObjecType
+/// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually
+/// this should get its own sugar class to better represent the source.
+class ObjCObjectType : public Type {
+ // Pad the bit count up so that NumProtocols is 2-byte aligned
+ unsigned : BitsRemainingInType - 16;
+
+ /// \brief The number of protocols stored after the
+ /// ObjCObjectPointerType node.
+ ///
+ /// These protocols are those written directly on the type. If
+ /// protocol qualifiers ever become additive, the iterators will
+ /// get kindof complicated.
+ ///
+ /// In the canonical object type, these are sorted alphabetically
+ /// and uniqued.
+ unsigned NumProtocols : 16;
- /// \brief The number of protocols stored after the ObjCInterfaceType node.
- /// The list of protocols is sorted on protocol name. No protocol is enterred
- /// more than once.
- unsigned NumProtocols;
+ /// Either a BuiltinType or an InterfaceType or sugar for either.
+ QualType BaseType;
- ObjCInterfaceType(QualType Canonical, ObjCInterfaceDecl *D,
- ObjCProtocolDecl **Protos, unsigned NumP);
- friend class ASTContext; // ASTContext creates these.
+ ObjCProtocolDecl * const *getProtocolStorage() const {
+ return const_cast<ObjCObjectType*>(this)->getProtocolStorage();
+ }
+
+ ObjCProtocolDecl **getProtocolStorage();
+
+protected:
+ ObjCObjectType(QualType Canonical, QualType Base,
+ ObjCProtocolDecl * const *Protocols, unsigned NumProtocols);
+
+ enum Nonce_ObjCInterface { Nonce_ObjCInterface };
+ ObjCObjectType(enum Nonce_ObjCInterface)
+ : Type(ObjCInterface, QualType(), false),
+ NumProtocols(0),
+ BaseType(QualType(this_(), 0)) {}
+
+protected:
+ Linkage getLinkageImpl() const; // key function
+
public:
- void Destroy(ASTContext& C);
+ /// getBaseType - Gets the base type of this object type. This is
+ /// always (possibly sugar for) one of:
+ /// - the 'id' builtin type (as opposed to the 'id' type visible to the
+ /// user, which is a typedef for an ObjCPointerType)
+ /// - the 'Class' builtin type (same caveat)
+ /// - an ObjCObjectType (currently always an ObjCInterfaceType)
+ QualType getBaseType() const { return BaseType; }
+
+ bool isObjCId() const {
+ return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId);
+ }
+ bool isObjCClass() const {
+ return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass);
+ }
+ bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); }
+ bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); }
+ bool isObjCUnqualifiedIdOrClass() const {
+ if (!qual_empty()) return false;
+ if (const BuiltinType *T = getBaseType()->getAs<BuiltinType>())
+ return T->getKind() == BuiltinType::ObjCId ||
+ T->getKind() == BuiltinType::ObjCClass;
+ return false;
+ }
+ bool isObjCQualifiedId() const { return !qual_empty() && isObjCId(); }
+ bool isObjCQualifiedClass() const { return !qual_empty() && isObjCClass(); }
- ObjCInterfaceDecl *getDecl() const { return Decl; }
+ /// Gets the interface declaration for this object type, if the base type
+ /// really is an interface.
+ ObjCInterfaceDecl *getInterface() const;
+
+ typedef ObjCProtocolDecl * const *qual_iterator;
+
+ qual_iterator qual_begin() const { return getProtocolStorage(); }
+ qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
+
+ bool qual_empty() const { return getNumProtocols() == 0; }
/// getNumProtocols - Return the number of qualifying protocols in this
/// interface type, or 0 if there are none.
unsigned getNumProtocols() const { return NumProtocols; }
- /// \brief Retrieve the Ith protocol.
+ /// \brief Fetch a protocol by index.
ObjCProtocolDecl *getProtocol(unsigned I) const {
assert(I < getNumProtocols() && "Out-of-range protocol access");
return qual_begin()[I];
}
- /// qual_iterator and friends: this provides access to the (potentially empty)
- /// list of protocols qualifying this interface.
- typedef ObjCProtocolDecl* const * qual_iterator;
- qual_iterator qual_begin() const {
- return reinterpret_cast<qual_iterator>(this + 1);
- }
- qual_iterator qual_end() const {
- return qual_begin() + NumProtocols;
- }
- bool qual_empty() const { return NumProtocols == 0; }
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == ObjCObject ||
+ T->getTypeClass() == ObjCInterface;
+ }
+ static bool classof(const ObjCObjectType *) { return true; }
+};
+
+/// ObjCObjectTypeImpl - A class providing a concrete implementation
+/// of ObjCObjectType, so as to not increase the footprint of
+/// ObjCInterfaceType. Code outside of ASTContext and the core type
+/// system should not reference this type.
+class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode {
+ friend class ASTContext;
+
+ // If anyone adds fields here, ObjCObjectType::getProtocolStorage()
+ // will need to be modified.
+
+ ObjCObjectTypeImpl(QualType Canonical, QualType Base,
+ ObjCProtocolDecl * const *Protocols,
+ unsigned NumProtocols)
+ : ObjCObjectType(Canonical, Base, Protocols, NumProtocols) {}
+
+public:
+ void Destroy(ASTContext& C); // key function
+
void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID,
- const ObjCInterfaceDecl *Decl,
- ObjCProtocolDecl * const *protocols,
- unsigned NumProtocols);
+ QualType Base,
+ ObjCProtocolDecl *const *protocols,
+ unsigned NumProtocols);
+};
- virtual Linkage getLinkage() const;
+inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() {
+ return reinterpret_cast<ObjCProtocolDecl**>(
+ static_cast<ObjCObjectTypeImpl*>(this) + 1);
+}
+
+/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for
+/// object oriented design. They basically correspond to C++ classes. There
+/// are two kinds of interface types, normal interfaces like "NSString" and
+/// qualified interfaces, which are qualified with a protocol list like
+/// "NSString<NSCopyable, NSAmazing>".
+///
+/// ObjCInterfaceType guarantees the following properties when considered
+/// as a subtype of its superclass, ObjCObjectType:
+/// - There are no protocol qualifiers. To reinforce this, code which
+/// tries to invoke the protocol methods via an ObjCInterfaceType will
+/// fail to compile.
+/// - It is its own base type. That is, if T is an ObjCInterfaceType*,
+/// T->getBaseType() == QualType(T, 0).
+class ObjCInterfaceType : public ObjCObjectType {
+ ObjCInterfaceDecl *Decl;
+
+ ObjCInterfaceType(const ObjCInterfaceDecl *D)
+ : ObjCObjectType(Nonce_ObjCInterface),
+ Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
+ friend class ASTContext; // ASTContext creates these.
+public:
+ void Destroy(ASTContext& C); // key function
+
+ /// getDecl - Get the declaration of this interface.
+ ObjCInterfaceDecl *getDecl() const { return Decl; }
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCInterface;
}
static bool classof(const ObjCInterfaceType *) { return true; }
+
+ // Nonsense to "hide" certain members of ObjCObjectType within this
+ // class. People asking for protocols on an ObjCInterfaceType are
+ // not going to get what they want: ObjCInterfaceTypes are
+ // guaranteed to have no protocols.
+ enum {
+ qual_iterator,
+ qual_begin,
+ qual_end,
+ getNumProtocols,
+ getProtocol
+ };
};
-/// ObjCObjectPointerType - Used to represent 'id', 'Interface *', 'id <p>',
-/// and 'Interface <p> *'.
+inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const {
+ if (const ObjCInterfaceType *T =
+ getBaseType()->getAs<ObjCInterfaceType>())
+ return T->getDecl();
+ return 0;
+}
+
+/// ObjCObjectPointerType - Used to represent a pointer to an
+/// Objective C object. These are constructed from pointer
+/// declarators when the pointee type is an ObjCObjectType (or sugar
+/// for one). In addition, the 'id' and 'Class' types are typedefs
+/// for these, and the protocol-qualified types 'id<P>' and 'Class<P>'
+/// are translated into these.
///
-/// Duplicate protocols are removed and protocol list is canonicalized to be in
-/// alphabetical order.
+/// Pointers to pointers to Objective C objects are still PointerTypes;
+/// only the first level of pointer gets it own type implementation.
class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
- QualType PointeeType; // A builtin or interface type.
-
- /// \brief The number of protocols stored after the ObjCObjectPointerType
- /// node.
- ///
- /// The list of protocols is sorted on protocol name. No protocol is enterred
- /// more than once.
- unsigned NumProtocols;
+ QualType PointeeType;
- ObjCObjectPointerType(QualType Canonical, QualType T,
- ObjCProtocolDecl **Protos, unsigned NumP);
+ ObjCObjectPointerType(QualType Canonical, QualType Pointee)
+ : Type(ObjCObjectPointer, Canonical, false),
+ PointeeType(Pointee) {}
friend class ASTContext; // ASTContext creates these.
+protected:
+ virtual Linkage getLinkageImpl() const;
+
public:
void Destroy(ASTContext& C);
- // Get the pointee type. Pointee will either be:
- // - a built-in type (for 'id' and 'Class').
- // - an interface type (for user-defined types).
- // - a TypedefType whose canonical type is an interface (as in 'T' below).
- // For example: typedef NSObject T; T *var;
+ /// getPointeeType - Gets the type pointed to by this ObjC pointer.
+ /// The result will always be an ObjCObjectType or sugar thereof.
QualType getPointeeType() const { return PointeeType; }
+ /// getObjCObjectType - Gets the type pointed to by this ObjC
+ /// pointer. This method always returns non-null.
+ ///
+ /// This method is equivalent to getPointeeType() except that
+ /// it discards any typedefs (or other sugar) between this
+ /// type and the "outermost" object type. So for:
+ /// @class A; @protocol P; @protocol Q;
+ /// typedef A<P> AP;
+ /// typedef A A1;
+ /// typedef A1<P> A1P;
+ /// typedef A1P<Q> A1PQ;
+ /// For 'A*', getObjectType() will return 'A'.
+ /// For 'A<P>*', getObjectType() will return 'A<P>'.
+ /// For 'AP*', getObjectType() will return 'A<P>'.
+ /// For 'A1*', getObjectType() will return 'A'.
+ /// For 'A1<P>*', getObjectType() will return 'A1<P>'.
+ /// For 'A1P*', getObjectType() will return 'A1<P>'.
+ /// For 'A1PQ*', getObjectType() will return 'A1<Q>', because
+ /// adding protocols to a protocol-qualified base discards the
+ /// old qualifiers (for now). But if it didn't, getObjectType()
+ /// would return 'A1P<Q>' (and we'd have to make iterating over
+ /// qualifiers more complicated).
+ const ObjCObjectType *getObjectType() const {
+ return PointeeType->getAs<ObjCObjectType>();
+ }
+
+ /// getInterfaceType - If this pointer points to an Objective C
+ /// @interface type, gets the type for that interface. Any protocol
+ /// qualifiers on the interface are ignored.
+ ///
+ /// \return null if the base type for this pointer is 'id' or 'Class'
const ObjCInterfaceType *getInterfaceType() const {
- return PointeeType->getAs<ObjCInterfaceType>();
+ return getObjectType()->getBaseType()->getAs<ObjCInterfaceType>();
}
- /// getInterfaceDecl - returns an interface decl for user-defined types.
+
+ /// getInterfaceDecl - If this pointer points to an Objective @interface
+ /// type, gets the declaration for that interface.
+ ///
+ /// \return null if the base type for this pointer is 'id' or 'Class'
ObjCInterfaceDecl *getInterfaceDecl() const {
- return getInterfaceType() ? getInterfaceType()->getDecl() : 0;
+ return getObjectType()->getInterface();
}
- /// isObjCIdType - true for "id".
+
+ /// isObjCIdType - True if this is equivalent to the 'id' type, i.e. if
+ /// its object type is the primitive 'id' type with no protocols.
bool isObjCIdType() const {
- return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
- !NumProtocols;
+ return getObjectType()->isObjCUnqualifiedId();
}
- /// isObjCClassType - true for "Class".
+
+ /// isObjCClassType - True if this is equivalent to the 'Class' type,
+ /// i.e. if its object tive is the primitive 'Class' type with no protocols.
bool isObjCClassType() const {
- return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) &&
- !NumProtocols;
+ return getObjectType()->isObjCUnqualifiedClass();
}
- /// isObjCQualifiedIdType - true for "id <p>".
+ /// isObjCQualifiedIdType - True if this is equivalent to 'id<P>' for some
+ /// non-empty set of protocols.
bool isObjCQualifiedIdType() const {
- return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
- NumProtocols;
+ return getObjectType()->isObjCQualifiedId();
}
- /// isObjCQualifiedClassType - true for "Class <p>".
+
+ /// isObjCQualifiedClassType - True if this is equivalent to 'Class<P>' for
+ /// some non-empty set of protocols.
bool isObjCQualifiedClassType() const {
- return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) &&
- NumProtocols;
+ return getObjectType()->isObjCQualifiedClass();
}
- /// qual_iterator and friends: this provides access to the (potentially empty)
- /// list of protocols qualifying this interface.
- typedef ObjCProtocolDecl* const * qual_iterator;
+
+ /// An iterator over the qualifiers on the object type. Provided
+ /// for convenience. This will always iterate over the full set of
+ /// protocols on a type, not just those provided directly.
+ typedef ObjCObjectType::qual_iterator qual_iterator;
qual_iterator qual_begin() const {
- return reinterpret_cast<qual_iterator> (this + 1);
+ return getObjectType()->qual_begin();
}
- qual_iterator qual_end() const {
- return qual_begin() + NumProtocols;
+ qual_iterator qual_end() const {
+ return getObjectType()->qual_end();
}
- bool qual_empty() const { return NumProtocols == 0; }
+ bool qual_empty() const { return getObjectType()->qual_empty(); }
- /// getNumProtocols - Return the number of qualifying protocols in this
- /// interface type, or 0 if there are none.
- unsigned getNumProtocols() const { return NumProtocols; }
+ /// getNumProtocols - Return the number of qualifying protocols on
+ /// the object type.
+ unsigned getNumProtocols() const {
+ return getObjectType()->getNumProtocols();
+ }
- /// \brief Retrieve the Ith protocol.
+ /// \brief Retrieve a qualifying protocol by index on the object
+ /// type.
ObjCProtocolDecl *getProtocol(unsigned I) const {
- assert(I < getNumProtocols() && "Out-of-range protocol access");
- return qual_begin()[I];
+ return getObjectType()->getProtocol(I);
}
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- virtual Linkage getLinkage() const;
-
- void Profile(llvm::FoldingSetNodeID &ID);
- static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
- ObjCProtocolDecl *const *protocols,
- unsigned NumProtocols);
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getPointeeType());
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
+ ID.AddPointer(T.getAsOpaquePtr());
+ }
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCObjectPointer;
}
@@ -3128,12 +3353,6 @@ inline QualType QualType::getNonReferenceType() const {
return *this;
}
-inline const ObjCInterfaceType *Type::getAsPointerToObjCInterfaceType() const {
- if (const PointerType *PT = getAs<PointerType>())
- return PT->getPointeeType()->getAs<ObjCInterfaceType>();
- return 0;
-}
-
inline bool Type::isFunctionType() const {
return isa<FunctionType>(CanonicalType);
}
@@ -3200,8 +3419,8 @@ inline bool Type::isExtVectorType() const {
inline bool Type::isObjCObjectPointerType() const {
return isa<ObjCObjectPointerType>(CanonicalType);
}
-inline bool Type::isObjCInterfaceType() const {
- return isa<ObjCInterfaceType>(CanonicalType);
+inline bool Type::isObjCObjectType() const {
+ return isa<ObjCObjectType>(CanonicalType);
}
inline bool Type::isObjCQualifiedIdType() const {
if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
@@ -3250,13 +3469,11 @@ inline bool Type::isOverloadableType() const {
inline bool Type::hasPointerRepresentation() const {
return (isPointerType() || isReferenceType() || isBlockPointerType() ||
- isObjCInterfaceType() || isObjCObjectPointerType() ||
- isObjCQualifiedInterfaceType() || isNullPtrType());
+ isObjCObjectPointerType() || isNullPtrType());
}
inline bool Type::hasObjCPointerRepresentation() const {
- return (isObjCInterfaceType() || isObjCObjectPointerType() ||
- isObjCQualifiedInterfaceType());
+ return isObjCObjectPointerType();
}
/// Insertion operator for diagnostics. This allows sending QualType's into a
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index a51da74..f988f0e 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_TYPELOC_H
#include "clang/AST/Type.h"
+#include "clang/AST/Decl.h"
#include "clang/AST/TemplateBase.h"
#include "clang/Basic/Specifiers.h"
@@ -84,21 +85,20 @@ public:
return Data;
}
+ /// \brief Get the begin source location.
+ SourceLocation getBeginLoc() const;
+
+ /// \brief Get the end source location.
+ SourceLocation getEndLoc() const;
+
/// \brief Get the full source range.
- SourceRange getFullSourceRange() const {
- SourceLocation End = getSourceRange().getEnd();
- TypeLoc Cur = *this;
- while (true) {
- TypeLoc Next = Cur.getNextTypeLoc();
- if (Next.isNull()) break;
- Cur = Next;
- }
- return SourceRange(Cur.getSourceRange().getBegin(), End);
+ SourceRange getSourceRange() const {
+ return SourceRange(getBeginLoc(), getEndLoc());
}
/// \brief Get the local source range.
- SourceRange getSourceRange() const {
- return getSourceRangeImpl(*this);
+ SourceRange getLocalSourceRange() const {
+ return getLocalSourceRangeImpl(*this);
}
/// \brief Returns the size of the type source info data block.
@@ -137,9 +137,14 @@ public:
private:
static void initializeImpl(TypeLoc TL, SourceLocation Loc);
static TypeLoc getNextTypeLocImpl(TypeLoc TL);
- static SourceRange getSourceRangeImpl(TypeLoc TL);
+ static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
};
+/// \brief Return the TypeLoc for a type source info.
+inline TypeLoc TypeSourceInfo::getTypeLoc() const {
+ return TypeLoc(Ty, (void*)(this + 1));
+}
+
/// \brief Wrapper of type source information for a type with
/// no direct quqlaifiers.
class UnqualTypeLoc : public TypeLoc {
@@ -168,7 +173,7 @@ public:
/// type qualifiers.
class QualifiedTypeLoc : public TypeLoc {
public:
- SourceRange getSourceRange() const {
+ SourceRange getLocalSourceRange() const {
return SourceRange();
}
@@ -263,6 +268,16 @@ public:
return TypeClass::classof(Ty);
}
+ static bool classof(const TypeLoc *TL) {
+ return Derived::classofType(TL->getTypePtr());
+ }
+ static bool classof(const UnqualTypeLoc *TL) {
+ return Derived::classofType(TL->getTypePtr());
+ }
+ static bool classof(const Derived *TL) {
+ return true;
+ }
+
TypeLoc getNextTypeLoc() const {
return getNextTypeLoc(asDerived()->getInnerType());
}
@@ -361,7 +376,7 @@ public:
void setNameLoc(SourceLocation Loc) {
this->getLocalData()->NameLoc = Loc;
}
- SourceRange getSourceRange() const {
+ SourceRange getLocalSourceRange() const {
return SourceRange(getNameLoc(), getNameLoc());
}
void initializeLocal(SourceLocation Loc) {
@@ -413,7 +428,7 @@ public:
return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
}
- SourceRange getSourceRange() const {
+ SourceRange getLocalSourceRange() const {
return SourceRange(getBuiltinLoc(), getBuiltinLoc());
}
@@ -553,6 +568,7 @@ class SubstTemplateTypeParmTypeLoc :
struct ObjCProtocolListLocInfo {
SourceLocation LAngleLoc;
SourceLocation RAngleLoc;
+ bool HasBaseTypeAsWritten;
};
// A helper class for defining ObjC TypeLocs that can qualified with
@@ -560,24 +576,15 @@ struct ObjCProtocolListLocInfo {
//
// TypeClass basically has to be either ObjCInterfaceType or
// ObjCObjectPointerType.
-template <class Derived, class TypeClass, class LocalData>
-class ObjCProtocolListTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- Derived,
- TypeClass,
- LocalData> {
+class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+ ObjCObjectTypeLoc,
+ ObjCObjectType,
+ ObjCProtocolListLocInfo> {
// SourceLocations are stored after Info, one for each Protocol.
SourceLocation *getProtocolLocArray() const {
return (SourceLocation*) this->getExtraLocalData();
}
-protected:
- void initializeLocalBase(SourceLocation Loc) {
- setLAngleLoc(Loc);
- setRAngleLoc(Loc);
- for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
- setProtocolLoc(i, Loc);
- }
-
public:
SourceLocation getLAngleLoc() const {
return this->getLocalData()->LAngleLoc;
@@ -611,29 +618,49 @@ public:
return *(this->getTypePtr()->qual_begin() + i);
}
- SourceRange getSourceRange() const {
+ bool hasBaseTypeAsWritten() const {
+ return getLocalData()->HasBaseTypeAsWritten;
+ }
+
+ void setHasBaseTypeAsWritten(bool HasBaseType) {
+ getLocalData()->HasBaseTypeAsWritten = HasBaseType;
+ }
+
+ TypeLoc getBaseLoc() const {
+ return getInnerTypeLoc();
+ }
+
+ SourceRange getLocalSourceRange() const {
return SourceRange(getLAngleLoc(), getRAngleLoc());
}
void initializeLocal(SourceLocation Loc) {
- initializeLocalBase(Loc);
+ setHasBaseTypeAsWritten(true);
+ setLAngleLoc(Loc);
+ setRAngleLoc(Loc);
+ for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
+ setProtocolLoc(i, Loc);
}
unsigned getExtraLocalDataSize() const {
return this->getNumProtocols() * sizeof(SourceLocation);
}
+
+ QualType getInnerType() const {
+ return getTypePtr()->getBaseType();
+ }
};
-struct ObjCInterfaceLocInfo : ObjCProtocolListLocInfo {
+struct ObjCInterfaceLocInfo {
SourceLocation NameLoc;
};
/// \brief Wrapper for source info for ObjC interfaces.
-class ObjCInterfaceTypeLoc :
- public ObjCProtocolListTypeLoc<ObjCInterfaceTypeLoc,
- ObjCInterfaceType,
- ObjCInterfaceLocInfo> {
+class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+ ObjCInterfaceTypeLoc,
+ ObjCInterfaceType,
+ ObjCInterfaceLocInfo> {
public:
ObjCInterfaceDecl *getIFaceDecl() const {
return getTypePtr()->getDecl();
@@ -647,85 +674,16 @@ public:
getLocalData()->NameLoc = Loc;
}
- SourceRange getSourceRange() const {
- if (getNumProtocols())
- return SourceRange(getNameLoc(), getRAngleLoc());
- else
- return SourceRange(getNameLoc(), getNameLoc());
+ SourceRange getLocalSourceRange() const {
+ return SourceRange(getNameLoc());
}
void initializeLocal(SourceLocation Loc) {
- initializeLocalBase(Loc);
setNameLoc(Loc);
}
};
-struct ObjCObjectPointerLocInfo : ObjCProtocolListLocInfo {
- SourceLocation StarLoc;
- bool HasProtocols;
- bool HasBaseType;
-};
-
-/// Wraps an ObjCPointerType with source location information. Note
-/// that not all ObjCPointerTypes actually have a star location; nor
-/// are protocol locations necessarily written in the source just
-/// because they're present on the type.
-class ObjCObjectPointerTypeLoc :
- public ObjCProtocolListTypeLoc<ObjCObjectPointerTypeLoc,
- ObjCObjectPointerType,
- ObjCObjectPointerLocInfo> {
-public:
- bool hasProtocolsAsWritten() const {
- return getLocalData()->HasProtocols;
- }
-
- void setHasProtocolsAsWritten(bool HasProtocols) {
- getLocalData()->HasProtocols = HasProtocols;
- }
-
- bool hasBaseTypeAsWritten() const {
- return getLocalData()->HasBaseType;
- }
-
- void setHasBaseTypeAsWritten(bool HasBaseType) {
- getLocalData()->HasBaseType = HasBaseType;
- }
-
- SourceLocation getStarLoc() const {
- return getLocalData()->StarLoc;
- }
-
- void setStarLoc(SourceLocation Loc) {
- getLocalData()->StarLoc = Loc;
- }
-
- SourceRange getSourceRange() const {
- // Being written with protocols is incompatible with being written
- // with a star.
- if (hasProtocolsAsWritten())
- return SourceRange(getLAngleLoc(), getRAngleLoc());
- else
- return SourceRange(getStarLoc(), getStarLoc());
- }
-
- void initializeLocal(SourceLocation Loc) {
- initializeLocalBase(Loc);
- setHasProtocolsAsWritten(false);
- setHasBaseTypeAsWritten(false);
- setStarLoc(Loc);
- }
-
- TypeLoc getBaseTypeLoc() const {
- return getInnerTypeLoc();
- }
-
- QualType getInnerType() const {
- return getTypePtr()->getPointeeType();
- }
-};
-
-
struct PointerLikeLocInfo {
SourceLocation StarLoc;
};
@@ -746,7 +704,7 @@ public:
return this->getInnerTypeLoc();
}
- SourceRange getSourceRange() const {
+ SourceRange getLocalSourceRange() const {
return SourceRange(getSigilLoc(), getSigilLoc());
}
@@ -798,6 +756,20 @@ public:
}
};
+/// Wraps an ObjCPointerType with source location information.
+class ObjCObjectPointerTypeLoc :
+ public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
+ ObjCObjectPointerType> {
+public:
+ SourceLocation getStarLoc() const {
+ return getSigilLoc();
+ }
+
+ void setStarLoc(SourceLocation Loc) {
+ setSigilLoc(Loc);
+ }
+};
+
class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
ReferenceType> {
@@ -871,13 +843,11 @@ public:
ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
- TypeLoc getArgLoc(unsigned i) const;
-
TypeLoc getResultLoc() const {
return getInnerTypeLoc();
}
- SourceRange getSourceRange() const {
+ SourceRange getLocalSourceRange() const {
return SourceRange(getLParenLoc(), getRParenLoc());
}
@@ -950,7 +920,7 @@ public:
return getInnerTypeLoc();
}
- SourceRange getSourceRange() const {
+ SourceRange getLocalSourceRange() const {
return SourceRange(getLBracketLoc(), getRBracketLoc());
}
@@ -1055,7 +1025,7 @@ public:
memcpy(Data, Loc.Data, size);
}
- SourceRange getSourceRange() const {
+ SourceRange getLocalSourceRange() const {
return SourceRange(getTemplateNameLoc(), getRAngleLoc());
}
@@ -1183,7 +1153,7 @@ public:
setRParenLoc(range.getEnd());
}
- SourceRange getSourceRange() const {
+ SourceRange getLocalSourceRange() const {
return SourceRange(getTypeofLoc(), getRParenLoc());
}
@@ -1204,7 +1174,7 @@ public:
// Reimplemented to account for GNU/C++ extension
// typeof unary-expression
// where there are no parentheses.
- SourceRange getSourceRange() const;
+ SourceRange getLocalSourceRange() const;
};
class TypeOfTypeLoc
@@ -1227,24 +1197,110 @@ class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
DecltypeType> {
};
-// FIXME: location of the tag keyword.
-class ElaboratedTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- ElaboratedTypeLoc,
- ElaboratedType> {
+struct ElaboratedLocInfo {
+ SourceLocation KeywordLoc;
+ SourceRange QualifierRange;
};
-// FIXME: locations for the nested name specifier; at the very least,
-// a SourceRange.
-class QualifiedNameTypeLoc :
- public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- QualifiedNameTypeLoc,
- QualifiedNameType> {
+class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+ ElaboratedTypeLoc,
+ ElaboratedType,
+ ElaboratedLocInfo> {
+public:
+ SourceLocation getKeywordLoc() const {
+ return this->getLocalData()->KeywordLoc;
+ }
+ void setKeywordLoc(SourceLocation Loc) {
+ this->getLocalData()->KeywordLoc = Loc;
+ }
+
+ SourceRange getQualifierRange() const {
+ return this->getLocalData()->QualifierRange;
+ }
+ void setQualifierRange(SourceRange Range) {
+ this->getLocalData()->QualifierRange = Range;
+ }
+
+ SourceRange getLocalSourceRange() const {
+ if (getKeywordLoc().isValid())
+ if (getQualifierRange().getEnd().isValid())
+ return SourceRange(getKeywordLoc(), getQualifierRange().getEnd());
+ else
+ return SourceRange(getKeywordLoc());
+ else
+ return getQualifierRange();
+ }
+
+ void initializeLocal(SourceLocation Loc) {
+ setKeywordLoc(Loc);
+ setQualifierRange(SourceRange(Loc));
+ }
+
+ TypeLoc getNamedTypeLoc() const {
+ return getInnerTypeLoc();
+ }
+
+ QualType getInnerType() const {
+ return getTypePtr()->getNamedType();
+ }
+
+ void copy(ElaboratedTypeLoc Loc) {
+ unsigned size = getFullDataSize();
+ assert(size == Loc.getFullDataSize());
+ memcpy(Data, Loc.Data, size);
+ }
};
-// FIXME: locations for the typename keyword and nested name specifier.
-class DependentNameTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- DependentNameTypeLoc,
- DependentNameType> {
+struct DependentNameLocInfo {
+ SourceLocation KeywordLoc;
+ SourceRange QualifierRange;
+ SourceLocation NameLoc;
+};
+
+class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+ DependentNameTypeLoc,
+ DependentNameType,
+ DependentNameLocInfo> {
+public:
+ SourceLocation getKeywordLoc() const {
+ return this->getLocalData()->KeywordLoc;
+ }
+ void setKeywordLoc(SourceLocation Loc) {
+ this->getLocalData()->KeywordLoc = Loc;
+ }
+
+ SourceRange getQualifierRange() const {
+ return this->getLocalData()->QualifierRange;
+ }
+ void setQualifierRange(SourceRange Range) {
+ this->getLocalData()->QualifierRange = Range;
+ }
+
+ SourceLocation getNameLoc() const {
+ return this->getLocalData()->NameLoc;
+ }
+ void setNameLoc(SourceLocation Loc) {
+ this->getLocalData()->NameLoc = Loc;
+ }
+
+ SourceRange getLocalSourceRange() const {
+ if (getKeywordLoc().isValid())
+ return SourceRange(getKeywordLoc(), getNameLoc());
+ else
+ return SourceRange(getQualifierRange().getBegin(), getNameLoc());
+ }
+
+ void copy(DependentNameTypeLoc Loc) {
+ unsigned size = getFullDataSize();
+ assert(size == Loc.getFullDataSize());
+ memcpy(Data, Loc.Data, size);
+ }
+
+ void initializeLocal(SourceLocation Loc) {
+ setKeywordLoc(Loc);
+ setQualifierRange(SourceRange(Loc));
+ setNameLoc(Loc);
+ }
};
}
diff --git a/include/clang/AST/TypeLocBuilder.h b/include/clang/AST/TypeLocBuilder.h
index c3b1c68..e729488 100644
--- a/include/clang/AST/TypeLocBuilder.h
+++ b/include/clang/AST/TypeLocBuilder.h
@@ -59,6 +59,20 @@ class TypeLocBuilder {
grow(Requested);
}
+ /// Pushes a copy of the given TypeLoc onto this builder. The builder
+ /// must be empty for this to work.
+ void pushFullCopy(TypeLoc L) {
+#ifndef NDEBUG
+ assert(LastTy.isNull() && "pushing copy on non-empty TypeLocBuilder");
+ LastTy = L.getNextTypeLoc().getType();
+#endif
+ assert(Index == Capacity && "pushing copy on non-empty TypeLocBuilder");
+
+ unsigned Size = L.getFullDataSize();
+ TypeLoc Copy = pushImpl(L.getType(), Size);
+ memcpy(Copy.getOpaqueData(), L.getOpaqueData(), Size);
+ }
+
/// Pushes space for a typespec TypeLoc. Invalidates any TypeLocs
/// previously retrieved from this builder.
TypeSpecTypeLoc pushTypeSpec(QualType T) {
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index c665073..02508af 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -90,10 +90,10 @@ NON_CANONICAL_TYPE(Elaborated, Type)
DEPENDENT_TYPE(TemplateTypeParm, Type)
NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
-NON_CANONICAL_TYPE(QualifiedName, Type)
DEPENDENT_TYPE(InjectedClassName, Type)
DEPENDENT_TYPE(DependentName, Type)
-TYPE(ObjCInterface, Type)
+TYPE(ObjCObject, Type)
+TYPE(ObjCInterface, ObjCObjectType)
TYPE(ObjCObjectPointer, Type)
#ifdef LAST_TYPE
diff --git a/include/clang/AST/TypeVisitor.h b/include/clang/AST/TypeVisitor.h
index 19f7f42..5c9c5285 100644
--- a/include/clang/AST/TypeVisitor.h
+++ b/include/clang/AST/TypeVisitor.h
@@ -1,4 +1,4 @@
-//===--- TypeVisitor.h - Visitor for Stmt subclasses ------------*- C++ -*-===//
+//===--- TypeVisitor.h - Visitor for Type subclasses ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -25,7 +25,7 @@ template<typename ImplClass, typename RetTy=void>
class TypeVisitor {
public:
RetTy Visit(Type *T) {
- // Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
+ // Top switch stmt: dispatch to VisitFooType for each FooType.
switch (T->getTypeClass()) {
default: assert(0 && "Unknown type class!");
#define ABSTRACT_TYPE(CLASS, PARENT)
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
index cbe0082..a548b0b 100644
--- a/include/clang/AST/UnresolvedSet.h
+++ b/include/clang/AST/UnresolvedSet.h
@@ -31,9 +31,13 @@ private:
IteratorTy ir;
friend class UnresolvedSetImpl;
+ friend class OverloadExpr;
explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {}
explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) :
ir(const_cast<DeclsTy::iterator>(ir)) {}
+
+ IteratorTy getIterator() const { return ir; }
+
public:
UnresolvedSetIterator() {}
@@ -81,9 +85,7 @@ public:
bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; }
};
-/// UnresolvedSet - A set of unresolved declarations. This is needed
-/// in a lot of places, but isn't really worth breaking into its own
-/// header right now.
+/// UnresolvedSet - A set of unresolved declarations.
class UnresolvedSetImpl {
typedef UnresolvedSetIterator::DeclsTy DeclsTy;
OpenPOWER on IntegriCloud