зеркало из https://github.com/microsoft/clang-1.git
Reuse VarDecl::Init to store the default argument of a ParmVarDecl,
reducing the size of ParmVarDecl by one pointer. Also means that we'll properly (de-)serialize default arguments in C++ PCH files. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76487 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
ba02486ef0
Коммит
75f1af0209
|
@ -237,8 +237,17 @@ 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 The initializer for this variable or, for a ParmVarDecl, the
|
||||
/// C++ default argument.
|
||||
mutable llvm::PointerUnion3<Stmt *, EvaluatedStmt *, UnparsedDefaultArgument*>
|
||||
Init;
|
||||
|
||||
private:
|
||||
mutable llvm::PointerUnion<Stmt *, EvaluatedStmt *> Init;
|
||||
// FIXME: This can be packed into the bitfields in Decl.
|
||||
unsigned SClass : 3;
|
||||
bool ThreadSpecified : 1;
|
||||
|
@ -295,9 +304,10 @@ public:
|
|||
return 0;
|
||||
|
||||
const 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 (const Expr*) S;
|
||||
}
|
||||
Expr *getInit() {
|
||||
|
@ -305,17 +315,19 @@ public:
|
|||
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;
|
||||
}
|
||||
|
||||
/// \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;
|
||||
return reinterpret_cast<Stmt **>(&Init); // FIXME: ugly hack
|
||||
}
|
||||
|
||||
void setInit(ASTContext &C, Expr *I);
|
||||
|
@ -495,12 +507,12 @@ public:
|
|||
class ImplicitParamDecl : public VarDecl {
|
||||
protected:
|
||||
ImplicitParamDecl(Kind DK, DeclContext *DC, SourceLocation L,
|
||||
IdentifierInfo *Id, QualType Tw)
|
||||
IdentifierInfo *Id, QualType Tw)
|
||||
: VarDecl(DK, DC, L, Id, Tw, 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; }
|
||||
|
@ -513,14 +525,21 @@ class ParmVarDecl : public VarDecl {
|
|||
/// 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) {}
|
||||
: VarDecl(DK, DC, L, Id, T, S), objcDeclQualifier(OBJC_TQ_None) {
|
||||
setDefaultArg(DefArg);
|
||||
}
|
||||
|
||||
public:
|
||||
static ParmVarDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
|
@ -536,18 +555,20 @@ public:
|
|||
|
||||
const Expr *getDefaultArg() const {
|
||||
assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!");
|
||||
return DefaultArg;
|
||||
return getInit();
|
||||
}
|
||||
Expr *getDefaultArg() {
|
||||
assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!");
|
||||
return DefaultArg;
|
||||
return getInit();
|
||||
}
|
||||
void setDefaultArg(Expr *defarg) {
|
||||
Init = reinterpret_cast<Stmt *>(defarg);
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
/// hasUnparsedDefaultArg - Determines whether this parameter has a
|
||||
|
@ -561,7 +582,7 @@ public:
|
|||
/// }; // x has a regular default argument now
|
||||
/// @endcode
|
||||
bool hasUnparsedDefaultArg() const {
|
||||
return DefaultArg == reinterpret_cast<Expr *>(-1);
|
||||
return Init.is<UnparsedDefaultArgument*>();
|
||||
}
|
||||
|
||||
/// setUnparsedDefaultArg - Specify that this parameter has an
|
||||
|
@ -569,7 +590,9 @@ 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;
|
||||
|
||||
|
|
|
@ -358,7 +358,6 @@ void PCHDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) {
|
|||
void PCHDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
|
||||
VisitVarDecl(PD);
|
||||
PD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
|
||||
// FIXME: default argument (C++ only)
|
||||
}
|
||||
|
||||
void PCHDeclReader::VisitOriginalParmVarDecl(OriginalParmVarDecl *PD) {
|
||||
|
|
|
@ -354,9 +354,6 @@ void PCHDeclWriter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
|
|||
void PCHDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
|
||||
VisitVarDecl(D);
|
||||
Record.push_back(D->getObjCDeclQualifier()); // FIXME: stable encoding
|
||||
// FIXME: emit default argument (C++)
|
||||
// FIXME: why isn't the "default argument" just stored as the initializer
|
||||
// in VarDecl?
|
||||
Code = pch::DECL_PARM_VAR;
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче