summaryrefslogtreecommitdiffstats
path: root/include/clang/AST/Decl.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/Decl.h')
-rw-r--r--include/clang/AST/Decl.h765
1 files changed, 504 insertions, 261 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 69a5286..7c326de 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -16,6 +16,7 @@
#include "clang/AST/APValue.h"
#include "clang/AST/DeclBase.h"
+#include "clang/AST/Redeclarable.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
@@ -26,23 +27,45 @@ class Stmt;
class CompoundStmt;
class StringLiteral;
class TemplateArgumentList;
+class MemberSpecializationInfo;
class FunctionTemplateSpecializationInfo;
-
+class TypeLoc;
+
+/// \brief A container of type source information.
+///
+/// A client can read the relevant info using TypeLoc wrappers, e.g:
+/// @code
+/// TypeLoc TL = DeclaratorInfo->getTypeLoc();
+/// if (PointerLoc *PL = dyn_cast<PointerLoc>(&TL))
+/// PL->getStarLoc().print(OS, SrcMgr);
+/// @endcode
+///
+class DeclaratorInfo {
+ QualType Ty;
+ // Contains a memory block after the class, used for type source information,
+ // allocated by ASTContext.
+ friend class ASTContext;
+ DeclaratorInfo(QualType ty) : Ty(ty) { }
+public:
+ /// \brief Return the TypeLoc wrapper for the type source info.
+ TypeLoc getTypeLoc() const;
+};
+
/// TranslationUnitDecl - The top declaration context.
class TranslationUnitDecl : public Decl, public DeclContext {
ASTContext &Ctx;
-
+
explicit TranslationUnitDecl(ASTContext &ctx)
: Decl(TranslationUnit, 0, SourceLocation()),
DeclContext(TranslationUnit),
Ctx(ctx) {}
public:
ASTContext &getASTContext() const { return Ctx; }
-
+
static TranslationUnitDecl *Create(ASTContext &C);
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == TranslationUnit; }
- static bool classof(const TranslationUnitDecl *D) { return true; }
+ static bool classof(const TranslationUnitDecl *D) { return true; }
static DeclContext *castToDeclContext(const TranslationUnitDecl *D) {
return static_cast<DeclContext *>(const_cast<TranslationUnitDecl*>(D));
}
@@ -91,7 +114,7 @@ public:
/// manipulation, so it should be called only when performance doesn't matter.
/// For simple declarations, getNameAsCString() should suffice.
std::string getNameAsString() const { return Name.getAsString(); }
-
+
/// getQualifiedNameAsString - Returns human-readable qualified name for
/// declaration, like A::B::i, for i being member of namespace A::B.
/// If declaration is not member of context which can be named (record,
@@ -99,6 +122,25 @@ public:
/// Creating this name is expensive, so it should be called only when
/// performance doesn't matter.
std::string getQualifiedNameAsString() const;
+ std::string getQualifiedNameAsString(const PrintingPolicy &Policy) const;
+
+ /// getNameForDiagnostic - Appends a human-readable name for this
+ /// declaration into the given string.
+ ///
+ /// This is the method invoked by Sema when displaying a NamedDecl
+ /// in a diagnostic. It does not necessarily produce the same
+ /// result as getNameAsString(); for example, class template
+ /// specializations are printed with their template arguments.
+ ///
+ /// TODO: use an API that doesn't require so many temporary strings
+ virtual void getNameForDiagnostic(std::string &S,
+ const PrintingPolicy &Policy,
+ bool Qualified) const {
+ if (Qualified)
+ S += getQualifiedNameAsString(Policy);
+ else
+ S += getNameAsString();
+ }
/// declarationReplaces - Determine whether this declaration, if
/// known to be well-formed within its context, will replace the
@@ -118,7 +160,7 @@ public:
const NamedDecl *getUnderlyingDecl() const {
return const_cast<NamedDecl*>(this)->getUnderlyingDecl();
}
-
+
static bool classof(const Decl *D) {
return D->getKind() >= NamedFirst && D->getKind() <= NamedLast;
}
@@ -128,7 +170,7 @@ public:
/// NamespaceDecl - Represent a C++ namespace.
class NamespaceDecl : public NamedDecl, public DeclContext {
SourceLocation LBracLoc, RBracLoc;
-
+
// For extended namespace definitions:
//
// namespace A { int x; }
@@ -139,7 +181,7 @@ class NamespaceDecl : public NamedDecl, public DeclContext {
// OrigNamespace points to the original namespace declaration.
// OrigNamespace of the first namespace decl points to itself.
NamespaceDecl *OrigNamespace, *NextNamespace;
-
+
NamespaceDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
: NamedDecl(Namespace, DC, L, Id), DeclContext(Namespace) {
OrigNamespace = this;
@@ -148,9 +190,20 @@ class NamespaceDecl : public NamedDecl, public DeclContext {
public:
static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id);
-
+
virtual void Destroy(ASTContext& C);
+ // \brief Returns true if this is an anonymous namespace declaration.
+ //
+ // For example:
+ // namespace {
+ // ...
+ // };
+ // q.v. C++ [namespace.unnamed]
+ bool isAnonymousNamespace() const {
+ return !getIdentifier();
+ }
+
NamespaceDecl *getNextNamespace() { return NextNamespace; }
const NamespaceDecl *getNextNamespace() const { return NextNamespace; }
void setNextNamespace(NamespaceDecl *ND) { NextNamespace = ND; }
@@ -159,7 +212,9 @@ public:
return OrigNamespace;
}
void setOriginalNamespace(NamespaceDecl *ND) { OrigNamespace = ND; }
-
+
+ virtual NamespaceDecl *getCanonicalDecl() { return OrigNamespace; }
+
virtual SourceRange getSourceRange() const {
return SourceRange(getLocation(), RBracLoc);
}
@@ -168,7 +223,7 @@ public:
SourceLocation getRBracLoc() const { return RBracLoc; }
void setLBracLoc(SourceLocation LBrace) { LBracLoc = LBrace; }
void setRBracLoc(SourceLocation RBrace) { RBracLoc = RBrace; }
-
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == Namespace; }
static bool classof(const NamespaceDecl *D) { return true; }
@@ -180,20 +235,20 @@ public:
}
};
-/// ValueDecl - Represent the declaration of a variable (in which case it is
+/// ValueDecl - Represent the declaration of a variable (in which case it is
/// an lvalue) a function (in which case it is a function designator) or
-/// an enum constant.
+/// an enum constant.
class ValueDecl : public NamedDecl {
QualType DeclType;
protected:
ValueDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName N, QualType T)
+ DeclarationName N, QualType T)
: NamedDecl(DK, DC, L, N), DeclType(T) {}
public:
QualType getType() const { return DeclType; }
void setType(QualType newType) { DeclType = newType; }
-
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= ValueFirst && D->getKind() <= ValueLast;
@@ -201,6 +256,29 @@ public:
static bool classof(const ValueDecl *D) { return true; }
};
+/// \brief Represents a ValueDecl that came out of a declarator.
+/// Contains type source information through DeclaratorInfo.
+class DeclaratorDecl : public ValueDecl {
+ DeclaratorInfo *DeclInfo;
+
+protected:
+ DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L,
+ DeclarationName N, QualType T, DeclaratorInfo *DInfo)
+ : ValueDecl(DK, DC, L, N, T), DeclInfo(DInfo) {}
+
+public:
+ DeclaratorInfo *getDeclaratorInfo() const { return DeclInfo; }
+ void setDeclaratorInfo(DeclaratorInfo *DInfo) { DeclInfo = DInfo; }
+
+ SourceLocation getTypeSpecStartLoc() const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) {
+ return D->getKind() >= DeclaratorFirst && D->getKind() <= DeclaratorLast;
+ }
+ static bool classof(const DeclaratorDecl *D) { return true; }
+};
+
/// \brief Structure used to store a statement, the constant value to
/// which it was evaluated (if any), and whether or not the statement
/// is an integral constant expression (if known).
@@ -222,9 +300,32 @@ struct EvaluatedStmt {
APValue Evaluated;
};
+// \brief Describes the kind of template specialization that a
+// particular template specialization declaration represents.
+enum TemplateSpecializationKind {
+ /// This template specialization was formed from a template-id but
+ /// has not yet been declared, defined, or instantiated.
+ TSK_Undeclared = 0,
+ /// This template specialization was implicitly instantiated from a
+ /// template. (C++ [temp.inst]).
+ TSK_ImplicitInstantiation,
+ /// This template specialization was declared or defined by an
+ /// explicit specialization (C++ [temp.expl.spec]) or partial
+ /// specialization (C++ [temp.class.spec]).
+ TSK_ExplicitSpecialization,
+ /// This template specialization was instantiated from a template
+ /// due to an explicit instantiation declaration request
+ /// (C++0x [temp.explicit]).
+ TSK_ExplicitInstantiationDeclaration,
+ /// This template specialization was instantiated from a template
+ /// due to an explicit instantiation definition request
+ /// (C++ [temp.explicit]).
+ TSK_ExplicitInstantiationDefinition
+};
+
/// VarDecl - An instance of this class is created to represent a variable
/// declaration or definition.
-class VarDecl : public ValueDecl {
+class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
public:
enum StorageClass {
None, Auto, Register, Extern, Static, PrivateExtern
@@ -236,81 +337,108 @@ public:
/// It is illegal to call this function with SC == None.
static const char *getStorageClassSpecifierString(StorageClass SC);
+protected:
+ /// \brief Placeholder type used in Init to denote an unparsed C++ default
+ /// argument.
+ struct UnparsedDefaultArgument;
+
+ /// \brief Placeholder type used in Init to denote an uninstantiated C++
+ /// default argument.
+ struct UninstantiatedDefaultArgument;
+
+ typedef llvm::PointerUnion4<Stmt *, EvaluatedStmt *,
+ UnparsedDefaultArgument *,
+ UninstantiatedDefaultArgument *> InitType;
+
+ /// \brief The initializer for this variable or, for a ParmVarDecl, the
+ /// C++ default argument.
+ mutable InitType Init;
+
private:
- mutable llvm::PointerUnion<Stmt *, EvaluatedStmt *> Init;
// FIXME: This can be packed into the bitfields in Decl.
unsigned SClass : 3;
bool ThreadSpecified : 1;
- bool HasCXXDirectInit : 1;
+ bool HasCXXDirectInit : 1;
/// DeclaredInCondition - Whether this variable was declared in a
/// condition, e.g., if (int x = foo()) { ... }.
bool DeclaredInCondition : 1;
- /// \brief The previous declaration of this variable.
- VarDecl *PreviousDeclaration;
-
- // Move to DeclGroup when it is implemented.
- SourceLocation TypeSpecStartLoc;
friend class StmtIteratorBase;
protected:
VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- QualType T, StorageClass SC, SourceLocation TSSL = SourceLocation())
- : ValueDecl(DK, DC, L, Id, T), Init(),
+ QualType T, DeclaratorInfo *DInfo, StorageClass SC)
+ : DeclaratorDecl(DK, DC, L, Id, T, DInfo), Init(),
ThreadSpecified(false), HasCXXDirectInit(false),
- DeclaredInCondition(false), PreviousDeclaration(0),
- TypeSpecStartLoc(TSSL) {
- SClass = SC;
+ DeclaredInCondition(false) {
+ SClass = SC;
}
+
+ typedef Redeclarable<VarDecl> redeclarable_base;
+ virtual VarDecl *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 VarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
- QualType T, StorageClass S,
- SourceLocation TypeSpecStartLoc = SourceLocation());
+ QualType T, DeclaratorInfo *DInfo, StorageClass S);
virtual ~VarDecl();
virtual void Destroy(ASTContext& C);
StorageClass getStorageClass() const { return (StorageClass)SClass; }
void setStorageClass(StorageClass SC) { SClass = SC; }
-
- virtual SourceRange getSourceRange() const;
- SourceLocation getTypeSpecStartLoc() const { return TypeSpecStartLoc; }
- void setTypeSpecStartLoc(SourceLocation SL) {
- TypeSpecStartLoc = SL;
- }
+ virtual SourceRange getSourceRange() const;
- const Expr *getInit() const {
+ const Expr *getInit() const {
if (Init.isNull())
return 0;
const Stmt *S = Init.dyn_cast<Stmt *>();
- if (!S)
- S = Init.get<EvaluatedStmt *>()->Value;
-
- return (const Expr*) S;
+ if (!S) {
+ if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>())
+ S = ES->Value;
+ }
+ return (const Expr*) S;
}
- Expr *getInit() {
+ Expr *getInit() {
if (Init.isNull())
return 0;
Stmt *S = Init.dyn_cast<Stmt *>();
- if (!S)
- S = Init.get<EvaluatedStmt *>()->Value;
+ if (!S) {
+ if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>())
+ S = ES->Value;
+ }
- return (Expr*) S;
+ return (Expr*) S;
}
/// \brief Retrieve the address of the initializer expression.
Stmt **getInitAddress() {
- if (Init.is<Stmt *>())
- return reinterpret_cast<Stmt **>(&Init); // FIXME: ugly hack
- return &Init.get<EvaluatedStmt *>()->Value;
+ if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>())
+ return &ES->Value;
+
+ // This union hack tip-toes around strict-aliasing rules.
+ union {
+ InitType *InitPtr;
+ Stmt **StmtPtr;
+ };
+
+ InitPtr = &Init;
+ return StmtPtr;
}
void setInit(ASTContext &C, Expr *I);
-
+
/// \brief Note that constant evaluation has computed the given
/// value for this variable's initializer.
void setEvaluatedValue(ASTContext &C, const APValue &Value) const {
@@ -325,7 +453,7 @@ public:
Eval->WasEvaluated = true;
Eval->Evaluated = Value;
}
-
+
/// \brief Return the already-evaluated value of this variable's
/// initializer, or NULL if the value is not yet known.
APValue *getEvaluatedValue() const {
@@ -350,7 +478,7 @@ public:
///
/// \pre isInitKnownICE()
bool isInitICE() const {
- assert(isInitKnownICE() &&
+ assert(isInitKnownICE() &&
"Check whether we already know that the initializer is an ICE");
return Init.get<EvaluatedStmt *>()->IsICE;
}
@@ -392,7 +520,7 @@ public:
bool hasCXXDirectInitializer() const {
return HasCXXDirectInit;
}
-
+
/// isDeclaredInCondition - Whether this variable was declared as
/// part of a condition in an if/switch/while statement, e.g.,
/// @code
@@ -401,27 +529,21 @@ public:
bool isDeclaredInCondition() const {
return DeclaredInCondition;
}
- void setDeclaredInCondition(bool InCondition) {
- DeclaredInCondition = InCondition;
+ void setDeclaredInCondition(bool InCondition) {
+ DeclaredInCondition = InCondition;
}
- /// getPreviousDeclaration - Return the previous declaration of this
- /// variable.
- const VarDecl *getPreviousDeclaration() const { return PreviousDeclaration; }
-
- void setPreviousDeclaration(VarDecl *PrevDecl) {
- PreviousDeclaration = PrevDecl;
- }
+ virtual VarDecl *getCanonicalDecl();
/// hasLocalStorage - Returns true if a variable with function scope
/// is a non-static local variable.
bool hasLocalStorage() const {
if (getStorageClass() == None)
return !isFileVarDecl();
-
+
// Return true for: Auto, Register.
// Return false for: Extern, Static, PrivateExtern.
-
+
return getStorageClass() <= Register;
}
@@ -448,7 +570,7 @@ public:
return DC->getLookupContext()->isFunctionOrMethod();
return false;
}
-
+
/// \brief Determines whether this is a static data member.
///
/// This will only be true in C++, and applies to, e.g., the
@@ -462,6 +584,24 @@ public:
return getDeclContext()->isRecord();
}
+ /// \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.
+ VarDecl *getInstantiatedFromStaticDataMember();
+
+ /// \brief If this variable is a static data member, determine what kind of
+ /// template specialization or instantiation this is.
+ TemplateSpecializationKind getTemplateSpecializationKind();
+
+ /// \brief If this variable is an instantiation of a static data member of a
+ /// class template specialization, retrieves the member specialization
+ /// information.
+ MemberSpecializationInfo *getMemberSpecializationInfo();
+
+ /// \brief For a static data member that was instantiated from a static
+ /// data member of a class template, set the template specialiation kind.
+ void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
+
/// isFileVarDecl - Returns true for file scoped variable declaration.
bool isFileVarDecl() const {
if (getKind() != Decl::Var)
@@ -471,16 +611,19 @@ public:
if (isa<TranslationUnitDecl>(Ctx) || isa<NamespaceDecl>(Ctx) )
return true;
}
+ if (isStaticDataMember())
+ return true;
+
return false;
}
/// \brief Determine whether this is a tentative definition of a
/// variable in C.
bool isTentativeDefinition(ASTContext &Context) const;
-
+
/// \brief Determines whether this variable is a variable with
/// external, C linkage.
- bool isExternC(ASTContext &Context) const;
+ bool isExternC() const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
@@ -492,12 +635,12 @@ public:
class ImplicitParamDecl : public VarDecl {
protected:
ImplicitParamDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType Tw)
- : VarDecl(DK, DC, L, Id, Tw, VarDecl::None) {}
+ IdentifierInfo *Id, QualType Tw)
+ : VarDecl(DK, DC, L, Id, Tw, /*DInfo=*/0, VarDecl::None) {}
public:
static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- QualType T);
+ SourceLocation L, IdentifierInfo *Id,
+ QualType T);
// Implement isa/cast/dyncast/etc.
static bool classof(const ImplicitParamDecl *D) { return true; }
static bool classof(const Decl *D) { return D->getKind() == ImplicitParam; }
@@ -509,44 +652,72 @@ class ParmVarDecl : public VarDecl {
/// FIXME: Also can be paced into the bitfields in Decl.
/// in, inout, etc.
unsigned objcDeclQualifier : 6;
-
- /// Default argument, if any. [C++ Only]
- Expr *DefaultArg;
+
+ /// \brief Retrieves the fake "value" of an unparsed
+ static Expr *getUnparsedDefaultArgValue() {
+ uintptr_t Value = (uintptr_t)-1;
+ // Mask off the low bits
+ Value &= ~(uintptr_t)0x07;
+ return reinterpret_cast<Expr*> (Value);
+ }
+
protected:
ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T, StorageClass S,
- Expr *DefArg)
- : VarDecl(DK, DC, L, Id, T, S),
- objcDeclQualifier(OBJC_TQ_None), DefaultArg(DefArg) {}
+ IdentifierInfo *Id, QualType T, DeclaratorInfo *DInfo,
+ StorageClass S, Expr *DefArg)
+ : VarDecl(DK, DC, L, Id, T, DInfo, S), objcDeclQualifier(OBJC_TQ_None) {
+ setDefaultArg(DefArg);
+ }
public:
static ParmVarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,IdentifierInfo *Id,
- QualType T, StorageClass S, Expr *DefArg);
-
+ QualType T, DeclaratorInfo *DInfo,
+ StorageClass S, Expr *DefArg);
+
ObjCDeclQualifier getObjCDeclQualifier() const {
return ObjCDeclQualifier(objcDeclQualifier);
}
void setObjCDeclQualifier(ObjCDeclQualifier QTVal) {
objcDeclQualifier = QTVal;
}
-
- const Expr *getDefaultArg() const {
+
+ const Expr *getDefaultArg() const {
assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!");
- return DefaultArg;
+ assert(!hasUninstantiatedDefaultArg() &&
+ "Default argument is not yet instantiated!");
+ return getInit();
}
- Expr *getDefaultArg() {
+ Expr *getDefaultArg() {
assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!");
- return DefaultArg;
+ assert(!hasUninstantiatedDefaultArg() &&
+ "Default argument is not yet instantiated!");
+ return getInit();
+ }
+ void setDefaultArg(Expr *defarg) {
+ Init = reinterpret_cast<Stmt *>(defarg);
+ }
+
+ /// \brief Retrieve the source range that covers the entire default
+ /// argument.
+ SourceRange getDefaultArgRange() const;
+ void setUninstantiatedDefaultArg(Expr *arg) {
+ Init = reinterpret_cast<UninstantiatedDefaultArgument *>(arg);
+ }
+ Expr *getUninstantiatedDefaultArg() {
+ return (Expr *)Init.get<UninstantiatedDefaultArgument *>();
+ }
+ const Expr *getUninstantiatedDefaultArg() const {
+ return (const Expr *)Init.get<UninstantiatedDefaultArgument *>();
}
- void setDefaultArg(Expr *defarg) { DefaultArg = defarg; }
/// hasDefaultArg - Determines whether this parameter has a default argument,
/// either parsed or not.
bool hasDefaultArg() const {
- return DefaultArg != 0;
+ return getInit() || hasUnparsedDefaultArg() ||
+ hasUninstantiatedDefaultArg();
}
-
+
/// hasUnparsedDefaultArg - Determines whether this parameter has a
/// default argument that has not yet been parsed. This will occur
/// during the processing of a C++ class whose member functions have
@@ -558,7 +729,11 @@ public:
/// }; // x has a regular default argument now
/// @endcode
bool hasUnparsedDefaultArg() const {
- return DefaultArg == reinterpret_cast<Expr *>(-1);
+ return Init.is<UnparsedDefaultArgument*>();
+ }
+
+ bool hasUninstantiatedDefaultArg() const {
+ return Init.is<UninstantiatedDefaultArgument*>();
}
/// setUnparsedDefaultArg - Specify that this parameter has an
@@ -566,10 +741,12 @@ public:
/// real default argument via setDefaultArg when the class
/// definition enclosing the function declaration that owns this
/// default argument is completed.
- void setUnparsedDefaultArg() { DefaultArg = reinterpret_cast<Expr *>(-1); }
+ void setUnparsedDefaultArg() {
+ Init = (UnparsedDefaultArgument *)0;
+ }
QualType getOriginalType() const;
-
+
/// setOwningFunction - Sets the function declaration that owns this
/// ParmVarDecl. Since ParmVarDecls are often created before the
/// FunctionDecls that own them, this routine is required to update
@@ -577,9 +754,9 @@ public:
void setOwningFunction(DeclContext *FD) { setDeclContext(FD); }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
+ static bool classof(const Decl *D) {
return (D->getKind() == ParmVar ||
- D->getKind() == OriginalParmVar);
+ D->getKind() == OriginalParmVar);
}
static bool classof(const ParmVarDecl *D) { return true; }
};
@@ -594,15 +771,17 @@ protected:
QualType OriginalType;
private:
OriginalParmVarDecl(DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T,
+ IdentifierInfo *Id, QualType T,
+ DeclaratorInfo *DInfo,
QualType OT, StorageClass S,
Expr *DefArg)
- : ParmVarDecl(OriginalParmVar, DC, L, Id, T, S, DefArg), OriginalType(OT) {}
+ : ParmVarDecl(OriginalParmVar, DC, L, Id, T, DInfo, S, DefArg),
+ OriginalType(OT) {}
public:
static OriginalParmVarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,IdentifierInfo *Id,
- QualType T, QualType OT,
- StorageClass S, Expr *DefArg);
+ QualType T, DeclaratorInfo *DInfo,
+ QualType OT, StorageClass S, Expr *DefArg);
void setOriginalType(QualType T) { OriginalType = T; }
@@ -610,9 +789,9 @@ public:
static bool classof(const Decl *D) { return D->getKind() == OriginalParmVar; }
static bool classof(const OriginalParmVarDecl *D) { return true; }
};
-
+
/// FunctionDecl - An instance of this class is created to represent a
-/// function declaration or definition.
+/// function declaration or definition.
///
/// Since a given function can be declared several times in a program,
/// there may be several FunctionDecls that correspond to that
@@ -621,46 +800,35 @@ public:
/// FunctionDecl (e.g., the translation unit); this FunctionDecl
/// contains all of the information known about the function. Other,
/// previous declarations of the function are available via the
-/// getPreviousDeclaration() chain.
-class FunctionDecl : public ValueDecl, public DeclContext {
+/// getPreviousDeclaration() chain.
+class FunctionDecl : public DeclaratorDecl, public DeclContext,
+ public Redeclarable<FunctionDecl> {
public:
enum StorageClass {
None, Extern, Static, PrivateExtern
};
-
-private:
+
+private:
/// ParamInfo - new[]'d array of pointers to VarDecls for the formal
/// parameters of this function. This is null if a prototype or if there are
/// no formals.
ParmVarDecl **ParamInfo;
-
+
LazyDeclStmtPtr Body;
-
- /// PreviousDeclaration - A link to the previous declaration of this
- /// same function, NULL if this is the first declaration. For
- /// example, in the following code, the PreviousDeclaration can be
- /// traversed several times to see all three declarations of the
- /// function "f", the last of which is also a definition.
- ///
- /// int f(int x, int y = 1);
- /// int f(int x = 0, int y);
- /// int f(int x, int y) { return x + y; }
- FunctionDecl *PreviousDeclaration;
// FIXME: This can be packed into the bitfields in Decl.
// NOTE: VC++ treats enums as signed, avoid using the StorageClass enum
unsigned SClass : 2;
bool IsInline : 1;
- bool C99InlineDefinition : 1;
bool IsVirtualAsWritten : 1;
bool IsPure : 1;
bool HasInheritedPrototype : 1;
bool HasWrittenPrototype : 1;
bool IsDeleted : 1;
+ bool IsTrivial : 1; // sunk from CXXMethodDecl
+ bool IsCopyAssignment : 1; // sunk from CXXMethodDecl
+ bool HasImplicitReturnZero : 1;
- // Move to DeclGroup when it is implemented.
- SourceLocation TypeSpecStartLoc;
-
/// \brief End part of this FunctionDecl's source range.
///
/// We could compute the full range in getSourceRange(). However, when we're
@@ -672,42 +840,59 @@ private:
/// \brief The template or declaration that this declaration
/// describes or was instantiated from, respectively.
- ///
+ ///
/// For non-templates, this value will be NULL. For function
/// declarations that describe a function template, this will be a
/// pointer to a FunctionTemplateDecl. For member functions
- /// of class template specializations, this will be the
- /// FunctionDecl from which the member function was instantiated.
- /// For function template specializations, this will be a
+ /// of class template specializations, this will be a MemberSpecializationInfo
+ /// pointer containing information about the specialization.
+ /// For function template specializations, this will be a
/// FunctionTemplateSpecializationInfo, which contains information about
- /// the template being specialized and the template arguments involved in
+ /// the template being specialized and the template arguments involved in
/// that specialization.
- llvm::PointerUnion3<FunctionTemplateDecl*, FunctionDecl*,
- FunctionTemplateSpecializationInfo*>
+ llvm::PointerUnion3<FunctionTemplateDecl *,
+ MemberSpecializationInfo *,
+ FunctionTemplateSpecializationInfo *>
TemplateOrSpecialization;
protected:
FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName N, QualType T,
- StorageClass S, bool isInline,
- SourceLocation TSSL = SourceLocation())
- : ValueDecl(DK, DC, L, N, T),
+ DeclarationName N, QualType T, DeclaratorInfo *DInfo,
+ StorageClass S, bool isInline)
+ : DeclaratorDecl(DK, DC, L, N, T, DInfo),
DeclContext(DK),
- ParamInfo(0), Body(), PreviousDeclaration(0),
- SClass(S), IsInline(isInline), C99InlineDefinition(false),
- IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
- HasWrittenPrototype(true), IsDeleted(false), TypeSpecStartLoc(TSSL),
+ ParamInfo(0), Body(),
+ SClass(S), IsInline(isInline),
+ IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
+ HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
+ IsCopyAssignment(false),
+ HasImplicitReturnZero(false),
EndRangeLoc(L), TemplateOrSpecialization() {}
virtual ~FunctionDecl() {}
virtual void Destroy(ASTContext& C);
+ typedef Redeclarable<FunctionDecl> redeclarable_base;
+ virtual FunctionDecl *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 FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
- DeclarationName N, QualType T,
+ DeclarationName N, QualType T,
+ DeclaratorInfo *DInfo,
StorageClass S = None, bool isInline = false,
- bool hasWrittenPrototype = true,
- SourceLocation TSStartLoc = SourceLocation());
+ bool hasWrittenPrototype = true);
+
+ virtual void getNameForDiagnostic(std::string &S,
+ const PrintingPolicy &Policy,
+ bool Qualified) const;
virtual SourceRange getSourceRange() const {
return SourceRange(getLocation(), EndRangeLoc);
@@ -715,9 +900,6 @@ public:
void setLocEnd(SourceLocation E) {
EndRangeLoc = E;
}
-
- SourceLocation getTypeSpecStartLoc() const { return TypeSpecStartLoc; }
- void setTypeSpecStartLoc(SourceLocation TS) { TypeSpecStartLoc = TS; }
/// getBody - Retrieve the body (definition) of the function. The
/// function body might be in any of the (re-)declarations of this
@@ -731,10 +913,6 @@ public:
return getBody(Definition);
}
- /// \brief If the function has a body that is immediately available,
- /// return it.
- Stmt *getBodyIfAvailable() const;
-
/// isThisDeclarationADefinition - Returns whether this specific
/// declaration of the function is also a definition. This does not
/// determine whether the function has been defined (e.g., in a
@@ -755,14 +933,30 @@ public:
bool isPure() const { return IsPure; }
void setPure(bool P = true) { IsPure = P; }
+ /// Whether this function is "trivial" in some specialized C++ senses.
+ /// Can only be true for default constructors, copy constructors,
+ /// copy assignment operators, and destructors. Not meaningful until
+ /// the class has been fully built by Sema.
+ bool isTrivial() const { return IsTrivial; }
+ void setTrivial(bool IT) { IsTrivial = IT; }
+
+ bool isCopyAssignment() const { return IsCopyAssignment; }
+ void setCopyAssignment(bool CA) { IsCopyAssignment = CA; }
+
+ /// Whether falling off this function implicitly returns null/zero.
+ /// If a more specific implicit return value is required, front-ends
+ /// should synthesize the appropriate return statements.
+ bool hasImplicitReturnZero() const { return HasImplicitReturnZero; }
+ void setHasImplicitReturnZero(bool IRZ) { HasImplicitReturnZero = IRZ; }
+
/// \brief Whether this function has a prototype, either because one
/// was explicitly written or because it was "inherited" by merging
/// a declaration without a prototype with a declaration that has a
/// prototype.
- bool hasPrototype() const {
- return HasWrittenPrototype || HasInheritedPrototype;
+ bool hasPrototype() const {
+ return HasWrittenPrototype || HasInheritedPrototype;
}
-
+
bool hasWrittenPrototype() const { return HasWrittenPrototype; }
void setHasWrittenPrototype(bool P) { HasWrittenPrototype = P; }
@@ -798,39 +992,36 @@ public:
/// \brief Determines whether this function is a function with
/// external, C linkage.
- bool isExternC(ASTContext &Context) const;
+ bool isExternC() const;
/// \brief Determines whether this is a global function.
bool isGlobal() const;
- /// getPreviousDeclaration - Return the previous declaration of this
- /// function.
- const FunctionDecl *getPreviousDeclaration() const {
- return PreviousDeclaration;
- }
-
void setPreviousDeclaration(FunctionDecl * PrevDecl);
- unsigned getBuiltinID(ASTContext &Context) const;
+ virtual const FunctionDecl *getCanonicalDecl() const;
+ virtual FunctionDecl *getCanonicalDecl();
+
+ unsigned getBuiltinID() const;
unsigned getNumParmVarDeclsFromType() const;
-
+
// Iterator access to formal parameters.
unsigned param_size() const { return getNumParams(); }
typedef ParmVarDecl **param_iterator;
typedef ParmVarDecl * const *param_const_iterator;
-
+
param_iterator param_begin() { return ParamInfo; }
param_iterator param_end() { return ParamInfo+param_size(); }
-
+
param_const_iterator param_begin() const { return ParamInfo; }
param_const_iterator param_end() const { return ParamInfo+param_size(); }
-
+
/// getNumParams - Return the number of parameters this function must have
/// based on its functiontype. This is the length of the PararmInfo array
/// after it has been created.
unsigned getNumParams() const;
-
+
const ParmVarDecl *getParamDecl(unsigned i) const {
assert(i < getNumParams() && "Illegal param #");
return ParamInfo[i];
@@ -847,8 +1038,8 @@ public:
/// arguments (in C++).
unsigned getMinRequiredArguments() const;
- QualType getResultType() const {
- return getType()->getAsFunctionType()->getResultType();
+ QualType getResultType() const {
+ return getType()->getAs<FunctionType>()->getResultType();
}
StorageClass getStorageClass() const { return StorageClass(SClass); }
void setStorageClass(StorageClass SC) { SClass = SC; }
@@ -856,27 +1047,11 @@ public:
bool isInline() const { return IsInline; }
void setInline(bool I) { IsInline = I; }
- /// \brief Whether this function is an "inline definition" as
- /// defined by C99.
- bool isC99InlineDefinition() const { return C99InlineDefinition; }
- void setC99InlineDefinition(bool I) { C99InlineDefinition = I; }
-
- /// \brief Determines whether this function has a gnu_inline
- /// attribute that affects its semantics.
- ///
- /// The gnu_inline attribute only introduces GNU inline semantics
- /// when all of the inline declarations of the function are marked
- /// gnu_inline.
- bool hasActiveGNUInlineAttribute(ASTContext &Context) const;
-
- /// \brief Determines whether this function is a GNU "extern
- /// inline", which is roughly the opposite of a C99 "extern inline"
- /// function.
- bool isExternGNUInline(ASTContext &Context) const;
-
+ bool isInlineDefinitionExternallyVisible() const;
+
/// isOverloadedOperator - Whether this function declaration
/// represents an C++ overloaded operator, e.g., "operator+".
- bool isOverloadedOperator() const {
+ bool isOverloadedOperator() const {
return getOverloadedOperator() != OO_None;
};
@@ -903,15 +1078,17 @@ public:
/// the FunctionDecl X<T>::A. When a complete definition of
/// X<int>::A is required, it will be instantiated from the
/// declaration returned by getInstantiatedFromMemberFunction().
- FunctionDecl *getInstantiatedFromMemberFunction() const {
- return TemplateOrSpecialization.dyn_cast<FunctionDecl*>();
- }
+ FunctionDecl *getInstantiatedFromMemberFunction() const;
+ /// \brief If this function is an instantiation of a member function of a
+ /// class template specialization, retrieves the member specialization
+ /// information.
+ MemberSpecializationInfo *getMemberSpecializationInfo() const;
+
/// \brief Specify that this record is an instantiation of the
- /// member function RD.
- void setInstantiationOfMemberFunction(FunctionDecl *RD) {
- TemplateOrSpecialization = RD;
- }
+ /// member function FD.
+ void setInstantiationOfMemberFunction(FunctionDecl *FD,
+ TemplateSpecializationKind TSK);
/// \brief Retrieves the function template that is described by this
/// function declaration.
@@ -933,20 +1110,34 @@ public:
TemplateOrSpecialization = Template;
}
+ /// \brief Determine whether this function is a function template
+ /// specialization.
+ bool isFunctionTemplateSpecialization() const {
+ return getPrimaryTemplate() != 0;
+ }
+
+ /// \brief If this function is actually a function template specialization,
+ /// retrieve information about this function template specialization.
+ /// Otherwise, returns NULL.
+ FunctionTemplateSpecializationInfo *getTemplateSpecializationInfo() const {
+ return TemplateOrSpecialization.
+ dyn_cast<FunctionTemplateSpecializationInfo*>();
+ }
+
/// \brief Retrieve the primary template that this function template
/// specialization either specializes or was instantiated from.
///
/// If this function declaration is not a function template specialization,
/// returns NULL.
FunctionTemplateDecl *getPrimaryTemplate() const;
-
+
/// \brief Retrieve the template arguments used to produce this function
/// template specialization from the primary template.
///
/// If this function declaration is not a function template specialization,
/// returns NULL.
- const TemplateArgumentList *getTemplateSpecializationArgs() const;
-
+ const TemplateArgumentList *getTemplateSpecializationArgs() const;
+
/// \brief Specify that this function declaration is actually a function
/// template specialization.
///
@@ -957,19 +1148,30 @@ public:
///
/// \param TemplateArgs the template arguments that produced this
/// function template specialization from the template.
+ ///
+ /// \param InsertPos If non-NULL, the position in the function template
+ /// specialization set where the function template specialization data will
+ /// be inserted.
+ ///
+ /// \param TSK the kind of template specialization this is.
void setFunctionTemplateSpecialization(ASTContext &Context,
FunctionTemplateDecl *Template,
const TemplateArgumentList *TemplateArgs,
- void *InsertPos);
+ void *InsertPos,
+ TemplateSpecializationKind TSK = TSK_ImplicitInstantiation);
- /// \brief Determine whether this is an explicit specialization of a
- /// function template or a member function of a class template.
- bool isExplicitSpecialization() const;
+ /// \brief Determine what kind of template instantiation this function
+ /// represents.
+ TemplateSpecializationKind getTemplateSpecializationKind() const;
- /// \brief Note that this is an explicit specialization of a function template
- /// or a member function of a class template.
- void setExplicitSpecialization(bool ES);
-
+ /// \brief Determine what kind of template instantiation this function
+ /// represents.
+ void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
+
+ /// \brief Determine whether this is or was instantiated from an out-of-line
+ /// definition of a member function.
+ bool isOutOfLine() const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= FunctionFirst && D->getKind() <= FunctionLast;
@@ -984,22 +1186,23 @@ public:
};
-/// FieldDecl - An instance of this class is created by Sema::ActOnField to
+/// FieldDecl - An instance of this class is created by Sema::ActOnField to
/// represent a member of a struct/union/class.
-class FieldDecl : public ValueDecl {
+class FieldDecl : public DeclaratorDecl {
// FIXME: This can be packed into the bitfields in Decl.
bool Mutable : 1;
Expr *BitWidth;
protected:
- FieldDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T, Expr *BW, bool Mutable)
- : ValueDecl(DK, DC, L, Id, T), Mutable(Mutable), BitWidth(BW)
- { }
+ FieldDecl(Kind DK, DeclContext *DC, SourceLocation L,
+ IdentifierInfo *Id, QualType T, DeclaratorInfo *DInfo,
+ Expr *BW, bool Mutable)
+ : DeclaratorDecl(DK, DC, L, Id, T, DInfo), Mutable(Mutable), BitWidth(BW) {
+ }
public:
- static FieldDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T, Expr *BW,
- bool Mutable);
+ static FieldDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+ IdentifierInfo *Id, QualType T,
+ DeclaratorInfo *DInfo, Expr *BW, bool Mutable);
/// isMutable - Determines whether this field is mutable (C++ only).
bool isMutable() const { return Mutable; }
@@ -1049,7 +1252,7 @@ public:
SourceLocation L, IdentifierInfo *Id,
QualType T, Expr *E,
const llvm::APSInt &V);
-
+
virtual void Destroy(ASTContext& C);
const Expr *getInitExpr() const { return (const Expr*) Init; }
@@ -1058,11 +1261,11 @@ public:
void setInitExpr(Expr *E) { Init = (Stmt*) E; }
void setInitVal(const llvm::APSInt &V) { Val = V; }
-
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == EnumConstant; }
static bool classof(const EnumConstantDecl *D) { return true; }
-
+
friend class StmtIteratorBase;
};
@@ -1104,16 +1307,16 @@ class TypedefDecl : public TypeDecl {
/// UnderlyingType - This is the type the typedef is set to.
QualType UnderlyingType;
TypedefDecl(DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T)
+ IdentifierInfo *Id, QualType T)
: TypeDecl(Typedef, DC, L, Id), UnderlyingType(T) {}
virtual ~TypedefDecl() {}
public:
-
+
static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,IdentifierInfo *Id,
QualType T);
-
+
QualType getUnderlyingType() const { return UnderlyingType; }
void setUnderlyingType(QualType newType) { UnderlyingType = newType; }
@@ -1123,16 +1326,17 @@ public:
};
class TypedefDecl;
-
+
/// TagDecl - Represents the declaration of a struct/union/class/enum.
-class TagDecl : public TypeDecl, public DeclContext {
+class TagDecl
+ : public TypeDecl, public DeclContext, public Redeclarable<TagDecl> {
public:
- enum TagKind {
- TK_struct,
- TK_union,
- TK_class,
- TK_enum
- };
+ // 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;
private:
// FIXME: This can be packed into the bitfields in Decl.
@@ -1142,21 +1346,48 @@ private:
/// IsDefinition - True if this is a definition ("struct foo {};"), false if
/// it is a declaration ("struct foo;").
bool IsDefinition : 1;
-
+
/// TypedefForAnonDecl - If a TagDecl is anonymous and part of a typedef,
/// this points to the TypedefDecl. Used for mangling.
TypedefDecl *TypedefForAnonDecl;
-
+
+ SourceLocation TagKeywordLoc;
+ SourceLocation RBraceLoc;
+
protected:
TagDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id)
- : TypeDecl(DK, DC, L, Id), DeclContext(DK), TypedefForAnonDecl(0) {
+ IdentifierInfo *Id, TagDecl *PrevDecl,
+ SourceLocation TKL = SourceLocation())
+ : TypeDecl(DK, DC, L, Id), DeclContext(DK), TypedefForAnonDecl(0),
+ TagKeywordLoc(TKL) {
assert((DK != Enum || TK == TK_enum) &&"EnumDecl not matched with TK_enum");
TagDeclKind = TK;
IsDefinition = false;
+ setPreviousDeclaration(PrevDecl);
}
+
+ typedef Redeclarable<TagDecl> redeclarable_base;
+ virtual TagDecl *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();
+ }
+
+ SourceLocation getRBraceLoc() const { return RBraceLoc; }
+ void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
+
+ SourceLocation getTagKeywordLoc() const { return TagKeywordLoc; }
+ void setTagKeywordLoc(SourceLocation TKL) { TagKeywordLoc = TKL; }
+
+ virtual SourceRange getSourceRange() const;
+
+ virtual TagDecl* getCanonicalDecl();
+
/// isDefinition - Return true if this decl has its body specified.
bool isDefinition() const {
return IsDefinition;
@@ -1168,7 +1399,7 @@ public:
bool isDependentType() const { return isDependentContext(); }
/// @brief Starts the definition of this tag declaration.
- ///
+ ///
/// This method should be invoked at the beginning of the definition
/// of this tag declaration. It will set the tag type into a state
/// where it is in the process of being defined.
@@ -1177,7 +1408,7 @@ public:
/// @brief Completes the definition of this tag declaration.
void completeDefinition();
- /// getDefinition - Returns the TagDecl that actually defines this
+ /// getDefinition - Returns the TagDecl that actually defines this
/// struct/union/class/enum. When determining whether or not a
/// struct/union/class/enum is completely defined, one should use this method
/// as opposed to 'isDefinition'. 'isDefinition' indicates whether or not a
@@ -1185,17 +1416,16 @@ public:
/// struct/union/class/enum type is defined. This method returns NULL if
/// there is no TagDecl that defines the struct/union/class/enum.
TagDecl* getDefinition(ASTContext& C) const;
-
+
const char *getKindName() const {
- switch (getTagKind()) {
- 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";
- }
+ return ElaboratedType::getNameForTagKind(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);
}
@@ -1206,10 +1436,10 @@ public:
bool isClass() const { return getTagKind() == TK_class; }
bool isUnion() const { return getTagKind() == TK_union; }
bool isEnum() const { return getTagKind() == TK_enum; }
-
+
TypedefDecl *getTypedefForAnonDecl() const { return TypedefForAnonDecl; }
void setTypedefForAnonDecl(TypedefDecl *TDD) { TypedefForAnonDecl = TDD; }
-
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= TagFirst && D->getKind() <= TagLast;
@@ -1240,15 +1470,19 @@ class EnumDecl : public TagDecl {
EnumDecl *InstantiatedFrom;
EnumDecl(DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id)
- : TagDecl(Enum, TK_enum, DC, L, Id), InstantiatedFrom(0) {
+ IdentifierInfo *Id, EnumDecl *PrevDecl, SourceLocation TKL)
+ : TagDecl(Enum, TK_enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
IntegerType = QualType();
}
public:
+ EnumDecl *getCanonicalDecl() {
+ return cast<EnumDecl>(TagDecl::getCanonicalDecl());
+ }
+
static EnumDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
- EnumDecl *PrevDecl);
-
+ SourceLocation TKL, EnumDecl *PrevDecl);
+
virtual void Destroy(ASTContext& C);
/// completeDefinition - When created, the EnumDecl corresponds to a
@@ -1257,16 +1491,16 @@ public:
/// added (via DeclContext::addDecl). NewType is the new underlying
/// type of the enumeration type.
void completeDefinition(ASTContext &C, QualType NewType);
-
+
// enumerator_iterator - Iterates through the enumerators of this
// enumeration.
typedef specific_decl_iterator<EnumConstantDecl> enumerator_iterator;
- enumerator_iterator enumerator_begin() const {
+ enumerator_iterator enumerator_begin() const {
return enumerator_iterator(this->decls_begin());
}
- enumerator_iterator enumerator_end() const {
+ enumerator_iterator enumerator_end() const {
return enumerator_iterator(this->decls_end());
}
@@ -1307,18 +1541,24 @@ class RecordDecl : public TagDecl {
/// anonymous struct or union.
bool AnonymousStructOrUnion : 1;
+ /// HasObjectMember - This is true if this struct has at least one
+ /// member containing an object
+ bool HasObjectMember : 1;
+
protected:
RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id);
+ SourceLocation L, IdentifierInfo *Id,
+ RecordDecl *PrevDecl, SourceLocation TKL);
virtual ~RecordDecl();
public:
static RecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
+ SourceLocation TKL = SourceLocation(),
RecordDecl* PrevDecl = 0);
virtual void Destroy(ASTContext& C);
-
+
bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }
@@ -1328,7 +1568,7 @@ public:
/// type declared, e.g.,
/// @code
/// union { int i; float f; };
- /// @endcode
+ /// @endcode
/// is an anonymous union but neither of the following are:
/// @code
/// union X { int i; float f; };
@@ -1339,6 +1579,9 @@ public:
AnonymousStructOrUnion = Anon;
}
+ bool hasObjectMember() const { return HasObjectMember; }
+ void setHasObjectMember (bool val) { HasObjectMember = val; }
+
/// \brief Determines whether this declaration represents the
/// injected class name.
///
@@ -1354,7 +1597,7 @@ public:
/// \endcode
bool isInjectedClassName() const;
- /// getDefinition - Returns the RecordDecl that actually defines this
+ /// getDefinition - Returns the RecordDecl that actually defines this
/// struct/union/class. When determining whether or not a struct/union/class
/// is completely defined, one should use this method as opposed to
/// 'isDefinition'. 'isDefinition' indicates whether or not a specific
@@ -1364,7 +1607,7 @@ public:
RecordDecl* getDefinition(ASTContext& C) const {
return cast_or_null<RecordDecl>(TagDecl::getDefinition(C));
}
-
+
// Iterator access to field members. The field iterator only visits
// the non-static data members of this class, ignoring any static
// data members, functions, constructors, destructors, etc.
@@ -1379,7 +1622,7 @@ public:
// field_empty - Whether there are any fields (non-static data
// members) in this record.
- bool field_empty() const {
+ bool field_empty() const {
return field_begin() == field_end();
}
@@ -1408,7 +1651,7 @@ public:
static bool classof(const Decl *D) {
return D->getKind() == FileScopeAsm;
}
- static bool classof(const FileScopeAsmDecl *D) { return true; }
+ static bool classof(const FileScopeAsmDecl *D) { return true; }
};
/// BlockDecl - This represents a block literal declaration, which is like an
@@ -1423,12 +1666,12 @@ class BlockDecl : public Decl, public DeclContext {
/// no formals.
ParmVarDecl **ParamInfo;
unsigned NumParams;
-
+
Stmt *Body;
-
+
protected:
BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
- : Decl(Block, DC, CaretLoc), DeclContext(Block),
+ : Decl(Block, DC, CaretLoc), DeclContext(Block),
isVariadic(false), ParamInfo(0), NumParams(0), Body(0) {}
virtual ~BlockDecl();
@@ -1441,7 +1684,7 @@ public:
bool IsVariadic() const { return isVariadic; }
void setIsVariadic(bool value) { isVariadic = value; }
-
+
CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; }
Stmt *getBody() const { return (Stmt*) Body; }
void setBody(CompoundStmt *B) { Body = (Stmt*) B; }
@@ -1450,14 +1693,14 @@ public:
unsigned param_size() const { return getNumParams(); }
typedef ParmVarDecl **param_iterator;
typedef ParmVarDecl * const *param_const_iterator;
-
+
bool param_empty() const { return NumParams == 0; }
param_iterator param_begin() { return ParamInfo; }
param_iterator param_end() { return ParamInfo+param_size(); }
-
+
param_const_iterator param_begin() const { return ParamInfo; }
param_const_iterator param_end() const { return ParamInfo+param_size(); }
-
+
unsigned getNumParams() const;
const ParmVarDecl *getParamDecl(unsigned i) const {
assert(i < getNumParams() && "Illegal param #");
@@ -1468,10 +1711,10 @@ public:
return ParamInfo[i];
}
void setParams(ASTContext& C, ParmVarDecl **NewParamInfo, unsigned NumParams);
-
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == Block; }
- static bool classof(const BlockDecl *D) { return true; }
+ static bool classof(const BlockDecl *D) { return true; }
static DeclContext *castToDeclContext(const BlockDecl *D) {
return static_cast<DeclContext *>(const_cast<BlockDecl*>(D));
}
OpenPOWER on IntegriCloud